diff options
authorEd Ravin <>2006-05-18 17:50:27 -0400
committerJeffrey C. Ollie <>2008-02-13 14:42:18 -0600
commitdad4b5439a1add586454d6d429606124855bce35 (patch)
parentb73f299e731fbddae095c0b5eff04717b6dce1af (diff)
patch for "out of band" access to devicesusercmd
On Fri, May 12, 2006 at 10:47:49PM -0400, Ed Ravin wrote: > On Tue, Aug 16, 2005 at 03:56:04PM +1000, Andrew Pollock wrote: > ... > > So the only way of managing the devices is via SSHing to the Cyclades and > > getting on the console port. We can SSH directly to a specific port of the > > Cyclades, and after authenticating, get on the console attached to that > > port, and disconnect by way of the standard SSH disconnect break sequence > > when we're done. > > > > I'm wondering if RANCID has evolved over the last nearly 2 years to include > > such out of band access to devices, or if it's much of a muchness still? As I posted previously, I've implemented this, and I now think/hope it's clean enough to release a patch. Here's how it works in cloginrc: add method testrouter {usercmd} add usercmd testrouter {ssh} {-t} {termserver01} {cu -l /dev/tty01 -s 9600} add usercmd_chat testrouter {Connected.} {\r} The patches below to clogin define a new method, "usercmd" (i.e. instead of "telnet" or "ssh"), which tells clogin to use the exact text supplied in the "usercmd" directive for that router as the command to spawn. Note the way the command line args are delimited, the braces have to be used to mark off the arguments or the spawn command will fail. Since whatever out-of-band gizmo you're using to access the router might need some more interaction to let you get to the router, the usercmd_chat directive is a list of expect/send pairs - match something, send something, match the next something, send something, etc. This is pretty primitive but it should be enough to get through conserver, cu, kermit, or whatever you're using as the out-of-band connector. In the above case, usercmd_chat is defined to "wait for the string 'Connected.' and then send a CR". For Andrew's case above, he might have to do something like: add usercmd routeronc1 {ssh} {-t} {-p 12345} {cyclades01} add usercmd_chat routeronc1 {Login:} {operator\r} {Password:} {secret\r} {Connected.} {\r} to get past the authentication he describes, and then send a CR to the router to get it to display a prompt. I didn't code anything yet for the situation Andrew describes where he wants to send an SSH break sequence when he's done. The attached patch includes a fix to clogin so that it will hang up if it times out after it's already sent "exit" to the router - though it wastes a few more seconds timing out, it is a reliable way to close the connection in my environment. If it turns out someone needs to have more chat interaction upon exit, I'd be happy to code it in. The patch to clogin is attached. The first chunk may need to be applied by hand, since one of the surrounding lines is from my S/Key patches. -- Ed
1 files changed, 21 insertions, 1 deletions
diff --git a/bin/ b/bin/
index 4431f63..05f75d9 100644
--- a/bin/
+++ b/bin/
@@ -319,7 +319,7 @@ proc source_password_file { password_file } {
# returns: 0 on success, 1 on failure, -1 if rsh was used successfully
proc login { router user userpswd passwd enapasswd cmethod cyphertype } {
global command spawn_id in_proc do_command do_script platform
- global prompt u_prompt p_prompt e_prompt sshcmd
+ global prompt u_prompt p_prompt e_prompt sshcmd usercmd usercmd_chat
set in_proc 1
set uprompt_seen 0
@@ -350,6 +350,22 @@ proc login { router user userpswd passwd enapasswd cmethod cyphertype } {
send_user "\nError: $sshcmd failed: $reason\n"
return 1
+ } elseif [string match "usercmd" $prog] { # user supplies connect cmd
+ set retval [ catch {eval spawn $usercmd} reason ]
+ if { $retval } {
+ send_user "\nError: '$usercmd' failed: $reason\n"
+ exit 1
+ }
+ if { [llength $usercmd_chat] > 0 } {
+ #send_user "\nExecuting usercmd_chat: $usercmd_chat\n"
+ sleep 0.3
+ foreach {i j} $usercmd_chat {
+ expect {
+ -re $i { eval send "\"$j\""}
+ timeout { send "\r"; send_user "\nTimeout in usercmd_chat waiting for -re $i: punting with CR\n"; break }
+ }
+ }
+ }
} elseif ![string compare $prog "rsh"] {
if { ! $do_command } {
if { [llength $cmethod] == 1 } {
@@ -845,6 +861,10 @@ foreach router [lrange $argv $i end] {
set sshcmd [find sshcmd $router]
if { "$sshcmd" == "" } { set sshcmd {ssh} }
+ # If user provides a router-specific connection method, use it
+ set usercmd [find usercmd $router]
+ set usercmd_chat [find usercmd_chat $router]
# Login to the router
if {[login $router $ruser $userpswd $passwd $enapasswd $cmethod $cyphertype]} {
incr exitval