SSH and Windows

I

Isaac Raway

Hello. I'm writing a Python program that connects to servers through
telnetlib to execute a few commands. I've discovered that some of the
servers that I have to connect to with this program run only SSH, so I
need to add support for SSH to the program. I'm looking for a library
that behaves similarly to telnetlib for SSH connections. Does anyone
know of one? I was going to try using pexpect to control the Windows
telnet command, but pexpect only works on Unix.

Any help is appreciated.
 
P

Peter Hansen

Isaac said:
Hello. I'm writing a Python program that connects to servers through
telnetlib to execute a few commands. I've discovered that some of the
servers that I have to connect to with this program run only SSH, so I
need to add support for SSH to the program. I'm looking for a library
that behaves similarly to telnetlib for SSH connections. Does anyone
know of one? I was going to try using pexpect to control the Windows
telnet command, but pexpect only works on Unix.

If it's just to execute a few commands, consider downloading PLink
(from the PuTTY site) and use it via os.system(). It works well.

-Peter
 
I

Isaac Raway

Peter Hansen said:
If it's just to execute a few commands, consider downloading PLink
(from the PuTTY site) and use it via os.system(). It works well.

Thank you, it worked perfectly. You have ended a week of headaces.
 
F

Fazer

Peter Hansen said:
If it's just to execute a few commands, consider downloading PLink
(from the PuTTY site) and use it via os.system(). It works well.

-Peter

Hmm...is there a *nix version for PLink? I checked PuTTY's site and
it's all for Windows. Or maybe an alternative for PLink for *nix?
 
P

Peter Hansen

Fazer said:
Hmm...is there a *nix version for PLink? I checked PuTTY's site and
it's all for Windows. Or maybe an alternative for PLink for *nix?

Maybe try this. Tested (mostly) under Python 1.5.2 (as I recall, under
Linux) and Python 2.0 under Windows:

import sys
import os
import time

True, False = 1, 0

class SshException(Exception): pass

class LinuxSshSession:

PAT_PASSWORD = '[pP]assword:'

def __init__(self, host, user, password, timeout=30):
self.host = host
self.user = user
self.password = password
self.timeout = timeout
self.verbose = True

def scp(self, src, dest):
import pexpect
user = self.user
host = self.host

if self.verbose:
sys.stdout.write('scp %(src)s %(user)s@%(host)s:%(dest)s ...' % locals())
sys.stdout.flush()
began = time.time()

try:
# use compression (not that that would help with a .tgz file
# and make sure we don't get messed up by the known_hosts file
child = pexpect.spawn('scp -C'
' -o UserKnownHostsFile=/dev/null'
' -o StrictHostKeyChecking=no'
' %(src)s %(user)s@%(host)s:%(dest)s' % locals())
state = 'authorizing'
while 1:
#~ print '%s: %r///%r' % (state, child.before, child.after)
if state == 'authorizing':
match = child.expect([pexpect.EOF, pexpect.TIMEOUT, self.PAT_PASSWORD],
timeout=self.timeout)
if match == 0:
raise SshException('failed to authenticate')
elif match == 1:
raise SshException('timeout waiting to authenticate')
elif match == 2:
child.sendline(self.password)
state = 'copying'

elif state == 'copying':
match = child.expect([pexpect.EOF, pexpect.TIMEOUT, 'stalled', 'ETA'],
timeout=self.timeout)
if match == 0:
break
elif match == 1:
raise SshException('timeout waiting for response')
elif match == 2:
state = 'stalled'

elif state == 'stalled':
match = child.expect([pexpect.EOF, pexpect.TIMEOUT, 'ETA'],
timeout=self.timeout)
if match == 0:
break
elif match == 1:
import pdb
pdb.set_trace()
raise SshException('stalled for too long, aborted copy')
elif match == 2:
state = 'copying'

finally:
if self.verbose:
elapsed = time.time() - began
try:
size = os.stat(src)[os.path.stat.ST_SIZE]
rate = size / elapsed
sys.stdout.write(' %.1fs (%d cps)\n' % (elapsed, rate))
except:
sys.stdout.write(' %.1fs\n' % (elapsed))


def ssh(self, cmd):
import pexpect
user = self.user
host = self.host

if self.verbose:
sys.stdout.write('ssh -l %(user)s %(host)s \"%(cmd)s\"\n' % locals())
sys.stdout.flush()

# use compression
# -o options make sure we don't get messed up by the known_hosts file
child = pexpect.spawn('ssh -C'
' -o UserKnownHostsFile=/dev/null'
' -o StrictHostKeyChecking=no'
' -l %(user)s %(host)s '
'\"%(cmd)s\"' % locals())
state = 'authorizing'
while 1:
if state == 'authorizing':
match = child.expect([pexpect.EOF, pexpect.TIMEOUT, self.PAT_PASSWORD],
timeout=self.timeout)
if match == 0:
raise SshException('failed to authenticate')
elif match == 1:
raise SshException('timeout waiting to authenticate')
elif match == 2:
child.sendline(self.password)
state = 'running'

elif state == 'running':
match = child.expect([pexpect.EOF, pexpect.TIMEOUT],
timeout=self.timeout)
if match == 0:
break
elif match == 1:
raise SshException('timeout waiting to finish')

return child.before


class WindowsSshSession:
def __init__(self, host, user, password, timeout=30):
self.host = host
self.user = user
self.password = password

def scp(self, src, dest):
user = self.user
host = self.host
password = self.password
return os.system('pscp -pw %(password)s %(src)s %(user)s@%(host)s:%(dest)s' % locals())

def ssh(self, cmd):
user = self.user
host = self.host
password = self.password
os.system('plink -pw %(password)s -ssh %(user)s@%(host)s "%(cmd)s"' % locals())


def SshSession(host, user, password, timeout=30):
if sys.platform == 'win32':
sessionClass = WindowsSshSession
else:
# assume we're on linux if platform is not windows
sessionClass = LinuxSshSession
return sessionClass(host, user, password, timeout)


-Peter
 
P

Peter Hansen

Peter said:
Maybe try this. Tested (mostly) under Python 1.5.2 (as I recall, under
Linux) and Python 2.0 under Windows:

elif state == 'stalled':
match = child.expect([pexpect.EOF, pexpect.TIMEOUT, 'ETA'],
timeout=self.timeout)
if match == 0:
break
elif match == 1:
import pdb
pdb.set_trace()
raise SshException('stalled for too long, aborted copy')

Ugh... remove the "import pdb" and subsequent pdb.set_trace() before attempting
to use the above... sorry about that. Must have checked a debugging version
in to CVS. :-(

-Peter
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top