twisted: problem with sftp-client

K

Kristian Domke

Hello Folks,

I don't know, if it is ok to post large portions of code, but I have
really no idea where the problem lies, so I don't have much of a choice.

I am programming a tool, which in the end shall connect to an
sftp-server, take the list of files in a specified directory, searches
for some special names and mailes them to different persons.

I am only at the start at the moment. As orientation I use the cftp.py
programm from twisted.conch with some alterations because of not having
userinteraction.

At its current state the programm should do nothing but getting the
listing of files from a server. It works fine with the cfto.py, so the
server is ok.

But while the cftp.py script gets 'files' as an exceptions.EOFError
exeption in the StdioClient._cbReadFile at the end of the listing, I
just get another list and run into wall (aka Traceback):
2008/01/23 16:14 +0200 [SSHChannel session (0) on SSHService
ssh-connection on SimpleTransport,client] Unhandled Error
Traceback (most recent call last):
File "/usr/lib/python2.5/site-packages/twisted/python/log.py", > line 48, in callWithLogger
return callWithContext({"system": lp}, func, *args, **kw)
File "/usr/lib/python2.5/site-packages/twisted/python/log.py", > line 33, in callWithContext
return context.call({ILogContext: newCtx}, func, *args,
**kw)
File
"/usr/lib/python2.5/site-packages/twisted/python/context.py", line 59,
in callWithContext
return self.currentContext().callWithContext(ctx, func,
*args, **kw)
File
"/usr/lib/python2.5/site-packages/twisted/python/context.py", line 37,
in callWithContext
return func(*args,**kw)
--- <exception caught here> ---
File
"/usr/lib/python2.5/site-packages/twisted/conch/ssh/filetransfer.py",
line 52, in dataReceived
f(data)
File
"/usr/lib/python2.5/site-packages/twisted/conch/ssh/filetransfer.py",
line 694, in packet_STATUS
msg, data = getNS(data)
File
"/usr/lib/python2.5/site-packages/twisted/conch/ssh/common.py", line
39, in getNS
l, = struct.unpack('!L',s[c:c+4])
File "struct.py", line 87, in unpack
return o.unpack(s)
struct.error: unpack requires a string argument of length 4


I have no Idea, and hope here is someone who can help me.

Kristian
----------------------------------------
from twisted.internet import reactor, defer, protocol
from twisted.conch.ssh import connection, filetransfer, keys, userauth
from twisted.conch.ssh import channel, transport, common
from twisted.conch.client import options, default, connect
from twisted.python import log, failure

import sys, time

publicKey = 'some public key'
privateKey ='''some private key'''

USER = 'sftpuser'


def run():
opts = options.ConchOptions()
opts['host'] = 'localhost'
opts['user'] = USER
opts['port'] = 22

log.startLogging(sys.stdout)
log.msg('logging started')
protocol.ClientCreator(reactor,
SimpleTransport).connectTCP(opts['host'], opts['port'])
reactor.run() # start the event loop

def doConnect(options):
host = options['host']
user = options['user']
port = options['port']
conn = SSHConnection
vhk = default.verifyHostKey
uao = UserAuthClient(user, conn)
d = connect.connect(host, port, options, vhk, uao)
d.addErrback(_ebExit)
return d

def _ebExit(f):
if hasattr(f.value, 'value'):
s =f.value.value
else:
s = str(f)
log.msg( s )
try:
reactor.stop()
except:
pass

def _cleanExit():
try:
reactor.stop()
except:
pass

class SimpleTransport(transport.SSHClientTransport):
def verifyHostKey(self, hostKey, fingerprint):
log.msg('host key fingerprint: %s' % fingerprint)
return defer.succeed(1)

def connectionSecure(self):
self.requestService(
UserAuthClient(USER,
SSHConnection()))

class UserAuthClient(userauth.SSHUserAuthClient):
"""Simple User Authentication Client"""

def getPassword(self, prompt = None):
return
# this says we won't do password authentication

def getPublicKey(self):
return keys.getPublicKeyString(data = publicKey)

def getPrivateKey(self):
return defer.succeed(keys.getPrivateKeyObject(data = privateKey))

class SSHConnection(connection.SSHConnection):
def serviceStarted(self):
log.msg('Service started')
self.openChannel(SSHSession(conn = self))

class SSHSession(channel.SSHChannel):

name = 'session'

def channelOpen(self, irgnoreData):
log.msg('session %s is open' % self.id)
request = 'subsystem'
d = self.conn.sendRequest(self, request, common.NS('sftp'),
wantReply=1)
d.addCallback(self._cbSubsystem)
d.addErrback(_ebExit)
return d

def _cbSubsystem(self, result):
log.msg('Establishing Subsystem')
self.client = SFTPClient()
self.client.makeConnection(self)
self.dataReceived = self.client.dataReceived

def openFailed(self, reason):
log.err('Opening Session failed: %s' % reason)
_cleanExit()


class SFTPClient(filetransfer.FileTransferClient):

def __init__(self):
filetransfer.FileTransferClient.__init__(self)
self.currentDirectory = ''


def connectionMade(self):
log.msg('Connection with SFTPClient established')

self.realPath('').addCallback(self._cbSetCurDir).addErrback(_cleanExit)

def _cbSetCurDir(self, path):
self.currentDirectory = path
log.msg('currentDirectory set to %s.' % path)
#self.cmd_MKDIR('test')
self.cmd_LS(self.currentDirectory)

def cmd_MKDIR(self, path):
return self.makeDirectory(path, {}).addCallback(self._ignore)

def cmd_LS(self, path):
log.msg('List Stucture of %s' % path)
d = self.openDirectory(path)
d.addCallback(self._cbOpenList)

def _cbOpenList(self, directory):
files = []
log.msg('direc.:%s' % str(directory))
log.msg('direc.:%s' % type(directory))
log.msg('direc.:%s' % str(directory.parent))
log.msg('direc.:%s' % type(directory.parent))
d = directory.read()
d.addCallback(self._cbReadFile, files, directory)
d.addErrback(self._ebRaeadFile, files, directory)

def _ebReadFile(self, files, l, directory):
log.msg('**errback!**')
self._cbReadFile(files, l, directory)

def _cbReadFile(self, files, l, directory):
log.msg('ReadFile called')
log.msg('direc.:%s' % type(files))
if not isinstance(files, failure.Failure):
log.msg('if not')
l.extend(files)
d = directory.read()
#d.addCallback(self._ignore)
d.addBoth(self._cbReadFile, l, directory)
return d
else:
log.msg('else')
reason = files
reason.trap(EOFError)
directory.close()
return l

def _ignore(self, *args):
pass

if __name__ == "__main__":
run()
 

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

Forum statistics

Threads
473,808
Messages
2,569,684
Members
45,446
Latest member
TeddyScull

Latest Threads

Top