pylibssh2-1.0.0/0000755000175000017500000000000011370762106011610 5ustar sbzsbzpylibssh2-1.0.0/ChangeLog0000644000175000017500000000007511370003256013356 0ustar sbzsbz2010-02-09 Sofian Brabez * First release pylibssh2-1.0.0/PKG-INFO0000644000175000017500000000123111370762106012702 0ustar sbzsbzMetadata-Version: 1.0 Name: pylibssh2 Version: 1.0.0 Summary: Python binding for libssh2 library Home-page: http://github.com/wallix/pylibssh2 Author: Sofian Brabez Author-email: sbz@wallix.com License: LGPL Download-URL: http://github.com/wallix/pylibssh2/download/pylibssh2-1.0.0.tar.gz Description: Python binding for libssh2 library Platform: Linux Platform: BSD Classifier: Development Status :: 4 - Beta Classifier: License :: OSI Approved :: BSD License Classifier: Operating System :: POSIX Classifier: Programming Language :: C Classifier: Programming Language :: Python Classifier: Topic :: Security Classifier: Topic :: Software Development :: Libraries pylibssh2-1.0.0/README0000644000175000017500000000526211370761256012502 0ustar sbzsbz========= pylibssh2 ========= :libssh2: Python module :Copyright: Keyphrene, Wallix :License: LGPL :Homepage: http://www.wallix.org/index.php/category/pylibssh2 pylibssh2 1.0.0 ================ 1.0.0 release, X may 2010 What ---- pylibssh2 is a python binding for libssh2 library, it was forked and rewrote from scratch using old org.keyphrene (http://sourceforge.net/projects/orgkeyphrene/) bindings. I wrote this extension at Wallix (http://wallix.com) to provide an easy way to manage SSH2 connection through libssh2 library in python. This is a C extension module to provide a high level python API. libssh2 API is fairy well respected and export into a python API. Packaging and API is documented with epydoc format. Requirements ------------ - python 2.6+ (older version before 2.5 aren't supported and not recommended) - libssh2 1.2.1+ (older version after 0.18 can works too) Linux Debian/Ubuntu:: sudo aptitude install python2-6 libssh2-1 libssh2-1-dev FreeBSD:: sudo make -C /usr/ports/lang/python install clean sudo make -C /usr/ports/security/libssh2/ install clean License ------- Old parts from Keyphrene.org are licensied against GNU Lesser GPL (LGPL) and all new and rewritten parts from Wallix.com are licensied against LGPL License too. Portability ----------- I code and test this binding on Linux and FreeBSD. It would be works on all posix platforms but I haven't tried others. Bugs & Support --------------- Bug tracker is available at https://bugs.wallix.org/ Mailing list for support and discussions at http://www.wallix.org/mailman/listinfo/pylibssh2 Get the source code git clone http://github.com/wallix/pylibssh2.git Browse the source code at http://github.com/wallix/pylibssh2.git Download tarballs at http://pypi.python.org/packages/source/p/pylibssh2/ Example ------- :scp_upload.py: dummy version of scp upload file transfer with pylibssh2. :sftp_listdir.py: this example show how to use pylibssh2 to list remote directories through SFTP protocol. :ssh_exec.py: this example show how to execute a SSH remote command execution. :ssh.py: this example demonstrate how implement a partial ssh client to get a remote shell. :ssh_x11.py: this example show how to implement a X11 fowarding ssh client. Documentation ------------- API documentation can be generated with epydoc with following command line:: epydoc --no-private -n pylibssh2 -o doc libssh2 Install ------- See the INSTALL file for installation instructions. Don't hesitate to reports bugs and submit patches, or just mail author. pylibssh2-1.0.0/INSTALL0000644000175000017500000000155611370004041012633 0ustar sbzsbz========= pylibssh2 ========= .. Generate an HTML page with "rst2html.py INSTALL > install.html" .. rst2html.py is part of the docutils software suite. .. contents:: **Index** .. sectnum:: Prerequisites ============= Here is the list of prerequisite software to run pylibssh2. The versions are the ones I develop with. It may work with earlier versions, but I can't guaranty anything. * `libssh2 `_ 1.2.1+ * `python `_ 2.6+ Install the software ==================== Get the latest version of `pylibssh2`_. .. _ `pylibssh2`: http://pypi.python.org/packages/source/p/pylibssh2/ Untar the tarball in the directory of your choice:: $ tar zxvf pylibssh2-{version}.tar.gz Now enter in the pylibssh2-{version} directory. Run the following command:: # python setup.py install or $ sudo python setup.py install pylibssh2-1.0.0/setup.py0000755000175000017500000000530511370762044013331 0ustar sbzsbz# # pylibssh2 - python bindings for libssh2 library # # Copyright (C) 2010 Wallix Inc. # # This library is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by the # Free Software Foundation; either version 2.1 of the License, or (at your # option) any later version. # # This library is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License # along with this library; if not, write to the Free Software Foundation, Inc., # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ Installation script for the libssh2 module """ from distutils.core import setup, Extension import os, sys, glob sys.path.append('libssh2') import version as info version = info.__version__ url = info.__url__ author = info.__author__ author_email = info.__authoremail__ long_description = '''Python binding for libssh2 library''' classifiers = """Development Status :: 4 - Beta License :: OSI Approved :: BSD License Operating System :: POSIX Programming Language :: C Programming Language :: Python Topic :: Security Topic :: Software Development :: Libraries""".split('\n') libssh2_src = glob.glob('src/*.c') libssh2_dep = glob.glob('src/*.h') libssh2_incdir = None if 'bsd' in sys.platform[-1] or 'bsd' in os.uname()[0].lower(): libssh2_incdir = ['/usr/local/include/'] libssh2_libdir = ['/usr/local/lib/'] libssh2_lib = ['ssh2'] libssh2_libdir = None libssh2_compile_args = ['-ggdb'] module = Extension('_libssh2', define_macros = [ ('MAJOR_VERSION', version[0]), ('MINOR_VERSION', version[2]), ('PATCH_VERSION', version[4]) ], sources = libssh2_src, depends = libssh2_dep, include_dirs = libssh2_incdir, library_dirs = libssh2_libdir, libraries = libssh2_lib, extra_compile_args = libssh2_compile_args) setup(name='pylibssh2', version=version, packages = ['libssh2'], package_dir = { 'libssh2' : 'libssh2' }, description = long_description, author=author, author_email=author_email, url=url, download_url='%s/download/pylibssh2-%s.tar.gz' % (url, version), ext_modules = [module], license = 'LGPL', platforms = ['Linux', 'BSD'], long_description = long_description, classifiers=classifiers) pylibssh2-1.0.0/AUTHORS0000644000175000017500000000015611370756462012672 0ustar sbzsbzVincent Jaulin Sofian Brabez Olivier Hervieu pylibssh2-1.0.0/examples/0000755000175000017500000000000011370762106013426 5ustar sbzsbzpylibssh2-1.0.0/examples/ssh_exec.py0000755000175000017500000000514711370757047015623 0ustar sbzsbz#!/usr/bin/env python # # pylibssh2 - python bindings for libssh2 library # # Copyright (C) 2010 Wallix Inc. # # This library is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by the # Free Software Foundation; either version 2.1 of the License, or (at your # option) any later version. # # This library is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License # along with this library; if not, write to the Free Software Foundation, Inc., # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # import socket, sys import libssh2 DEBUG=False usage = """Do a SSH remote command with username@hostname Usage: sshcmd.py """ def my_print(args): if DEBUG: print(args) class SSHRemoteClient(object): def __init__(self, hostname, username, password, port=22): self.username = username self.password = password self.hostname = hostname self.port = port self.session = libssh2.Session() self.session.set_banner() try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((self.hostname,self.port)) self.session.startup(sock) my_print(self.session.last_error()) self.session.userauth_password(self.username,self.password) my_print(self.session.last_error()) except Exception, e: print str(e) raise Exception, self.session.last_error() self.channel = self.session.open_session() my_print(self.session.last_error()) def execute(self, command="uname -a"): datas = [] buffer = 4096 rc = self.channel.execute(command) my_print(rc) while True: data = self.channel.read(buffer) if data == '' or data is None: break my_print(type(data)) print data.strip() self.channel.close() def __del__(self): self.session.close() my_print(self.session.last_error()) if __name__ == '__main__': try: if len(sys.argv) == 1: print usage sys.exit(1) src = SSHRemoteClient(sys.argv[1], sys.argv[2], sys.argv[3]) src.execute(sys.argv[4]) except Exception, e: print str(e) except KeyboardInterrupt, e: sys.exit(1) pylibssh2-1.0.0/examples/sftp_listdir.py0000755000175000017500000000527711370756646016540 0ustar sbzsbz#!/usr/bin/env python # # pylibssh2 - python bindings for libssh2 library # # Copyright (C) 2010 Wallix Inc. # # This library is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by the # Free Software Foundation; either version 2.1 of the License, or (at your # option) any later version. # # This library is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License # along with this library; if not, write to the Free Software Foundation, Inc., # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # import socket, sys import libssh2 usage = """Do a SFTP file listing of with username@hostname Usage: sftp.py """ class MySFTPClient: def __init__(self, hostname, username, password, port=22): self.hostname = hostname self.username = username self.password = password self.port = port self._prepare_sock() def _prepare_sock(self): try: self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.connect((self.hostname, self.port)) self.sock.setblocking(1) except Exception, e: print "SockError: Can't connect socket to %s:%d" % (self.hostname, self.port) print e try: self.session = libssh2.Session() self.session.set_banner() self.session.startup(self.sock) self.session.userauth_password(self.username, self.password) except Exception, e: print "SSHError: Can't startup session" print e # use low level layer because we don't yet provide High layer for sftp self.sftp = self.session._session.sftp_init() def listdir(self, remote_path='/tmp'): handle = self.sftp.opendir(remote_path) if handle: while True: data = self.sftp.readdir(handle) if not data: break print data for file, attribute in self.sftp.listdir(handle): print file, attribute self.sftp.close(handle) def __del__(self): self.session.close() self.sock.close() if __name__ == '__main__' : if len(sys.argv) == 1: print usage sys.exit(1) mysftp = MySFTPClient( hostname=sys.argv[1], username=sys.argv[2], password=sys.argv[3] ) mysftp.listdir(sys.argv[4]) pylibssh2-1.0.0/examples/scp_upload.py0000755000175000017500000000510111370756616016142 0ustar sbzsbz#!/usr/bin/env python # # pylibssh2 - python bindings for libssh2 library # # Copyright (C) 2010 Wallix Inc. # # This library is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by the # Free Software Foundation; either version 2.1 of the License, or (at your # option) any later version. # # This library is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License # along with this library; if not, write to the Free Software Foundation, Inc., # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # import socket, sys import libssh2 usage = """Do a SCP send with username@hostname:/remote_path/ Usage: scp.py """ class MySCPClient: def __init__(self, hostname, username, password, port=22): self.hostname = hostname self.username = username self.password = password self.port = port self._prepare_sock() def _prepare_sock(self): try: self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.connect((self.hostname, self.port)) self.sock.setblocking(1) except Exception, e: print "SockError: Can't connect socket to %s:%d" % (self.hostname, self.port) print e try: self.session = libssh2.Session() self.session.set_banner() self.session.startup(self.sock) self.session.userauth_password(self.username, self.password) except Exception, e: print "SSHError: Can't startup session" print e def send(self, remote_path, mode=0644): datas="" f=file(remote_path, "rb") while True: data = f.readline() if len(data) == 0: break else: datas += data file_size = len(datas) channel = self.session.scp_send(remote_path, mode, file_size) channel.write(datas) channel.close() def __del__(self): self.session.close() self.sock.close() if __name__ == '__main__' : if len(sys.argv) == 1: print usage sys.exit(1) myscp = MySCPClient( hostname=sys.argv[1], username=sys.argv[2], password=sys.argv[3] ) myscp.send(sys.argv[4]) pylibssh2-1.0.0/examples/ssh_x11.py0000755000175000017500000001257511370757116015310 0ustar sbzsbz#!/usr/bin/env python # # pylibssh2 - python bindings for libssh2 library # # Copyright (C) 2010 Wallix Inc. # # This library is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by the # Free Software Foundation; either version 2.1 of the License, or (at your # option) any later version. # # This library is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License # along with this library; if not, write to the Free Software Foundation, Inc., # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # import atexit import fcntl import os import select, signal, struct, sys from socket import socket, AF_INET, AF_UNIX, SOCK_STREAM, SHUT_RDWR import tty, termios import libssh2 from libssh2 import SessionException, ChannelException usage = """Do a X11 SSH connection with username@hostname Usage: ssh_x11.py """ def remove_node(elem): x11_channels.remove(elem) def session_shutdown(session): session.close() del session def raw_mode(fd): tty.setraw(fd) def normal_mode(fd): termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) def x11_callback(session, channel, shost, sport, abstract): display = os.environ["DISPLAY"] display_port = display[display.index(":")+1] _path_unix_x = "/tmp/.X11-unix/X%s" % display_port if display[:5] == "unix:" or display[0] == ':': x11_sock = socket(AF_UNIX, SOCK_STREAM) x11_sock.connect(_path_unix_x) x11_channels.append(X11Channel(channel, x11_sock)) def x11_send_recieve(channel, sock): rc=0 rc = channel.poll(0, 1) if rc > 0: data = channel.read(buffsize) sock.sendall(data) r, w, x = select.select([sock], [], [], 0.01) if r: data = sock.recv(buffsize) if data is None: return -1 channel.write(data) if channel.eof(): return -1 else: return 0 def trace(session): if DEBUG and session: session.set_trace( libssh2.LIBSSH2_TRACE_TRANS| libssh2.LIBSSH2_TRACE_CONN| libssh2.LIBSSH2_TRACE_AUTH| libssh2.LIBSSH2_TRACE_ERROR ) class X11Channel(object): def __init__(self, chan, sock): self.chan = chan self.sock = sock if __name__ == '__main__': if len(sys.argv) == 1: print usage sys.exit(1) DEBUG=False x11_channels = [] buffsize = 8192 # save terminal settings fd = sys.stdin.fileno() old_settings = termios.tcgetattr(fd) hostname = sys.argv[1] username = sys.argv[2] password = sys.argv[3] port = int(sys.argv[4]) sock = socket(AF_INET, SOCK_STREAM) try: sock.connect((hostname, port)) sock.setblocking(1) except Exception, e: print "Can't connect socket to (%s:%d): %s" % ( hostname, port, e ) sys.exit(1) # start session session = libssh2.Session() try: session.set_banner() # trace session on stderr if DEBUG=True trace(session) session.startup(sock) except SessionException, e: print "Can't startup session: %s" % e sys.exit(1) # register X11 callback session.callback_set( libssh2.LIBSSH2_CALLBACK_X11, x11_callback ) try: session.userauth_password(username, password) except SessionException, e: print "Failed to authenticate user with %s %s" % ( username, password ) sys.exit(1) try: # open channel channel = session.open_session() # request pty channel.pty('xterm') # request X11 forwarding on display 0 channel.x11_req(0) # request shell channel.shell() # enable raw mode raw_mode(fd) while True: # XXX tty resize #win = struct.unpack( # 'hh', # fcntl.ioctl(fd, termios.TIOCGWINSZ, 4*' ') #) # width, height #channel.pty_resize(win[1], win[0]) # polling on tty channel rc = channel.poll(0, 1) if rc > 0: data = channel.read(buffsize) sys.stdout.write(data) else: sys.stdout.flush() # polling on x11 channels if len(x11_channels) != 0: for x11_channel in x11_channels: rc = x11_send_recieve(x11_channel.chan, x11_channel.sock) if rc == -1: x11_channel.sock.shutdown(SHUT_RDWR) x11_channel.sock.close() remove_node(x11_channel) r, w, x = select.select([fd], [], [], 0.01) if sys.stdin.fileno() in r: data = sys.stdin.read(1).replace('\n','\r\n') channel.write(data) if channel.eof(): break except ChannelException, e: print "Channel exception: %s" % e finally: channel.close() session_shutdown(session) sock.close() # restore terminal settings atexit.register( normal_mode, fd ) pylibssh2-1.0.0/examples/ssh.py0000755000175000017500000000717411370756714014621 0ustar sbzsbz#!/usr/bin/env python # # pylibssh2 - python bindings for libssh2 library # # Copyright (C) 2010 Wallix Inc. # # This library is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by the # Free Software Foundation; either version 2.1 of the License, or (at your # option) any later version. # # This library is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License # along with this library; if not, write to the Free Software Foundation, Inc., # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # import atexit import select, socket, sys import tty, termios import libssh2 usage = """Do a SSH connection with username@hostname Usage: ssh.py """ class MySSHClient: def __init__(self, hostname, username, password, port=22): self.hostname = hostname self.username = username self.password = password self.port = port self._prepare_sock() def _prepare_sock(self): try: self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.connect((self.hostname, self.port)) self.sock.setblocking(1) except Exception, e: print "SockError: Can't connect socket to %s:%d" % (self.hostname, self.port) print e try: self.session = libssh2.Session() self.session.set_banner() self.session.startup(self.sock) hash = self.session.hostkey_hash(2) #print "----" #import base64 #print base64.encodestring(hash) #print "----" # authentication self.session.userauth_password(self.username, self.password) except Exception, e: print "SSHError: Can't startup session" print e def run(self): try: # open channel channel = self.session.open_session() # request X11 Forwarding on display 0 channel.x11_req(0) # request pty channel.pty('vt100') # request shell channel.shell() channel.setblocking(0) # loop while True: data_to_disp = channel.poll(0, 1) if data_to_disp > 0: data = channel.read(1024) if data is not None: sys.stdout.write(data) else: break sys.stdout.flush() r,w,x = select.select([fd],[],[],0.01) if sys.stdin.fileno() in r: data = sys.stdin.read(1).replace('\n','\r\n') channel.write(data) except Exception,e: print e finally: channel.close() def __del__(self): self.session.close() self.sock.close() if __name__ == '__main__' : if len(sys.argv) == 1: print usage sys.exit(1) # save terminal settings fd = sys.stdin.fileno() old_settings = termios.tcgetattr(fd) # enable raw mode tty.setraw(fd) myssh = MySSHClient(sys.argv[1],sys.argv[2], sys.argv[3]) myssh.run() # restore terminal settings atexit.register( termios.tcsetattr, sys.stdin.fileno(), termios.TCSADRAIN, old_settings ) pylibssh2-1.0.0/libssh2/0000755000175000017500000000000011370762106013156 5ustar sbzsbzpylibssh2-1.0.0/libssh2/__init__.py0000644000175000017500000000260011370760326015267 0ustar sbzsbz# # pylibssh2 - python bindings for libssh2 library # # Copyright (C) 2010 Wallix Inc. # # This library is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by the # Free Software Foundation; either version 2.1 of the License, or (at your # option) any later version. # # This library is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License # along with this library; if not, write to the Free Software Foundation, Inc., # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # __doc__ = """Python binding for libssh2 library""" from version import * from channel import ChannelException, Channel from session import SessionException, Session from sftp import SftpException, Sftp __all__ = [ 'Channel', 'ChannelException', 'Session', 'SessionException', 'Sftp', 'SftpException' ] LIBSSH2_TRACE_TRANS = 1<<1 LIBSSH2_TRACE_KEX = 1<<2 LIBSSH2_TRACE_AUTH = 1<<3 LIBSSH2_TRACE_CONN = 1<<4 LIBSSH2_TRACE_SCP = 1<<5 LIBSSH2_TRACE_SFTP = 1<<6 LIBSSH2_TRACE_ERROR = 1<<7 LIBSSH2_TRACE_PUBLICKEY = 1<<8 LIBSSH2_TRACE_SOCKET = 1<<9 LIBSSH2_CALLBACK_X11 = 4 pylibssh2-1.0.0/libssh2/version.py0000644000175000017500000000204711370760507015223 0ustar sbzsbz# # pylibssh2 - python bindings for libssh2 library # # Copyright (C) 2010 Wallix Inc. # # This library is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by the # Free Software Foundation; either version 2.1 of the License, or (at your # option) any later version. # # This library is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License # along with this library; if not, write to the Free Software Foundation, Inc., # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # __doc__ = """Python binding for libssh2 library""" __version_info__ = (1, 0, 0) __version__ = '.'.join([ str(v) for v in __version_info__]) __url__ = 'http://github.com/wallix/pylibssh2' __author__ = 'Sofian Brabez' __authoremail__ = 'sbz@wallix.com' pylibssh2-1.0.0/libssh2/channel.py0000644000175000017500000001447011370760274015152 0ustar sbzsbz# # pylibssh2 - python bindings for libssh2 library # # Copyright (C) 2010 Wallix Inc. # # This library is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by the # Free Software Foundation; either version 2.1 of the License, or (at your # option) any later version. # # This library is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License # along with this library; if not, write to the Free Software Foundation, Inc., # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ Abstraction for libssh2 L{Channel} object """ class ChannelException(Exception): """ Exception raised when L{Channel} actions fails. """ pass class Channel(object): """ Channel object """ def __init__(self, _channel): """ Creates a new channel object with the given _channel. @param _channel: low level channel object @type _channel: L{_libssh2.Channel} """ self._channel = _channel self.closed = False self.flushed = False def close(self): """ Closes the active channel. @return: 0 on success or negative on failure @rtype: int """ self.closed = True return self._channel.close() def eof(self): """ Checks if the remote host has sent a EOF status. @return: 1 if the remote host has sent EOF otherwise 0 @rtype: int """ return self._channel.eof() def execute(self, command): """ Executes command on the channel. @param command: message data @type command: str @return: 0 on success or negative on failure @rtype: int """ self.closed = True return self._channel.execute(command) def exit_status(self): """ Gets the exit code raised by the process running on the remote host. @return: the exit status reported by remote host or 0 on failure @rtype: int """ return self._channel.exit_status() def flush(self): """ Flushs the read buffer on the channel. @return: 0 on sucess or negative on failure @rtype: int """ self.flushed = True return self._channel.flush() def poll(self, timeout, nfds): """ Polls for activity on the channel. @param timeout: remaining timeout @type timeout: int @param nfds: number of fds to poll @type nfds: int @return: number of fds with interesting events or negative on failure @rtype: int """ return self._channel.poll(timeout, nfds) def poll_read(self, extended): """ Checks if data is available on the channel. @param extended: if message channel datas is extended @type extended: int @return: 1 when data is available or 0 otherwise @rtype: int """ return self._channel.poll_read(extended) def pty(self, term="vt100"): """ Requests a pty with term type on the channel. @param term: terminal emulation type (vt100, ansi, etc...) @type term: str @return: 0 on success or negative on failure @rtype: int """ return self._channel.pty(term) def pty_resize(self, width, height): """ Requests a pty resize of the channel with given width and height. @param width: terminal width @type width: int @param height: terminal height @type height: int @return: 0 on success or negative on failure @rtype: int """ return self._channel.pty_resize(width, height) def read(self, size=4096): """ Reads size bytes on the channel. @param size: size of the buffer storage @type size: int @return: bytes readed or negative on failure @rtype: str """ return self._channel.read(size) def send_eof(self): """ Sends EOF status on the channel to remote server. @return: 0 on success or negative on failure @rtype: int """ self._channel.send_eof() def setblocking(self, mode=1): """ Sets blocking mode on the channel. Default mode is blocking. @param mode: blocking (1) or non blocking (0) mode @rtype: int """ return self._channel.setblocking(mode) def setenv(self, name, value): """ Sets envrionment variable on the channel. @param name: envrionment variable name @type name: str @param value: envrionment variable value @type value: str @return: 0 on success or negative on failure @rtype: int """ return self._channel.setenv(name, value) def shell(self): """ Requests a shell on the channel. @return: 0 on success or negative on failure @rtype: int """ return self._channel.shell() def window_read(self, read_avail, window_size_initial): """ Checks the status of the read window on the channel. @param read_avail: window limit to read @type read_avail: int @param window_size_initial: window initial size defined @type window_size_initial: int @return: the number of bytes which the remote end may send without overflowing the window limit @rtype: int """ return self._channel.window_read(read_avail, window_size_initial) def write(self, message): """ Writes data on the channel. @param message: data to write @type message: str @return: 0 on sucess or failure @rtype: int """ return self._channel.write(message) def x11_req(self, display): """ Requests a X11 Forwarding on the channel. @param display: screen number @param display: int @return: 0 on success or negative on failure @rtype: int """ return self._channel.x11_req(display) pylibssh2-1.0.0/libssh2/sftp.py0000644000175000017500000000505611370760407014514 0ustar sbzsbz# # pylibssh2 - python bindings for libssh2 library # # Copyright (C) 2010 Wallix Inc. # # This library is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by the # Free Software Foundation; either version 2.1 of the License, or (at your # option) any later version. # # This library is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License # along with this library; if not, write to the Free Software Foundation, Inc., # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ Abstraction for libssh2 L{Sftp} object """ class SftpException(Exception): """ Exception raised when L{Sftp} actions fails. """ pass class Sftp(object): """ Sftp object """ def __init__(self): """ Create a new Sftp object. """ pass def close(self): """ """ raise NotImplementedError() def opendir(self): """ """ raise NotImplementedError() def readdir(self): """ """ raise NotImplementedError() def listdir(self): """ """ raise NotImplementedError() def open(self): """ """ raise NotImplementedError() def shutdown(self): """ """ raise NotImplementedError() def read(self): """ """ raise NotImplementedError() def write(self): """ """ raise NotImplementedError() def tell(self): """ """ raise NotImplementedError() def seek(self): """ """ raise NotImplementedError() def unlink(self): """ """ raise NotImplementedError() def rename(self): """ """ raise NotImplementedError() def mkdir(self): """ """ raise NotImplementedError() def rmdir(self): """ """ raise NotImplementedError() def realpath(self): """ """ raise NotImplementedError() def symlink(self): """ """ raise NotImplementedError() def getstat(self): """ """ raise NotImplementedError() def setstat(self): """ """ raise NotImplementedError() pylibssh2-1.0.0/libssh2/session.py0000644000175000017500000002040411370760362015215 0ustar sbzsbz# # pylibssh2 - python bindings for libssh2 library # # Copyright (C) 2010 Wallix Inc. # # This library is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by the # Free Software Foundation; either version 2.1 of the License, or (at your # option) any later version. # # This library is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License # along with this library; if not, write to the Free Software Foundation, Inc., # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ Abstraction for libssh2 L{Session} object """ import _libssh2 from channel import Channel class SessionException(Exception): """ Exception raised when L{Session} actions fails. """ pass class Session(object): """ Session object """ def __init__(self): """ Create a new session object. """ self._session = _libssh2.Session() def callback_set(self, callback_type, callback): """ Sets callback on the session. @param callback_type: value of libssh2.LIBSSH2_CALLBACK_* constant @type callback_set: int @param callback: a callback Python object @type callback: function """ self._session.callback_set(callback_type, callback) def close(self, reason="Disconnect"): """ Closes the session. @param reason: human readable reason for disconnection @type reason: str @return: 0 on success or negative on failure @rtype: int """ self._session.close(reason) def direct_tcpip(self, host, port, shost, sport): """ Tunnels a TCP connection through the session. @param host: remote host @type host: str @param port: remote port @type port: int @param shost: local host @type shost: str @param sport: local port @type sport: int @return: new opened L{Channel} @rtype: L{Channel} """ return self._session.direct_tcpip(host, port, shost, sport) def forward_listen(self, host, port, bound_port, queue_maxsize): """ Forwards a TCP connection through the session. @param host: remote host @type host: str @param port: remote port @type port: int @param bound_port: populated with the actual port on the remote host @type bound_port: int @param queue_maxsize: maxium number of pending connections @type int @return: new L{Listener} instance on success or None on failure @rtype: L{Listener} """ return self._session.forward_listen( host, port, bound_port, queue_maxsize ) def hostkey_hash(self, hashtype): """ Returns the computed digest of the remote host's key. @param hashtype: values possible are 1 (HASH_MD5) or 2 (HASH_SHA1) @type hashtype: int @return: string representation of the computed hash value @rtype: str """ return self._session.hostkey_hash(hashtype) def last_error(self): """ Returns the last error in tuple format (code, message). @return: error tuple (int, str) @rtype: tuple """ return self._session.last_error() def open_session(self): """ Allocates a new L{Channel} for the session. @return: new channel opened @rtype: L{Channel} """ return Channel(self._session.open_session()) def set_trace(self, bitmask): """ Sets trace level on the session. @param bitmask: bitmask on libssh2.LIBSSH2_TRACE_* constant """ self._session.set_trace(bitmask) def scp_recv(self, remote_path): """ Gets a remote file via SCP Protocol. @param remote_path: absolute path of remote file to transfer @type remote_path: str @return: new channel opened @rtype: L{Channel} """ return Channel(self._session.scp_recv(remote_path)) def scp_send(self, path, mode, size): """ Sends a file to remote host via SCP protocol. @param path: absolute path of file to transfer @type path: str @param mode: file access mode to create file @type mode: int @param size: size of file being transmitted @type size: int @return: new channel opened @rtype: L{Channel} """ return Channel(self._session.scp_send(path, mode, size)) def session_method_pref(self, method_type, pref): """ Sets preferred methods to be negociated. Theses preferences must be prior to calling L{startup}. @param method_type: the method type constants @type method_type: int @param pref: coma delimited list of preferred methods @type pref: str @return: 0 on success or negative on failure @rtype: int """ self._session.session_methods(method_type, pref) def session_methods(self): """ Returns dictionnary with the current actives algorithms. CS keys is Client to Server and SC keys is Server to Client. @return: dictionnary with actual method negociated @rtype: dict """ return self.session_methods() def set_banner(self, banner=_libssh2.DEFAULT_BANNER): """ Sets the banner that will be sent to remote host. This is optional, the banner L{_libssh2.DEFAULT_BANNER} will be sent by default. @param banner: an user defined banner @type banner: str @return: 0 on success or negative on failure @rtype: int """ self._session.set_banner(banner) def sftp_init(self): """ Open an Sftp Channel. @return: new Sftp channel opened @rtype: L{Sftp} """ raise NotImplementedError() def startup(self, sock): """ Starts up the session form a socket created by a socket.socket() call. @param sock: a connected socket object @type sock: socket._socketobject @return: 0 on success or negative on failure @rtype: int """ self._session.startup(sock) def userauth_authenticated(self): """ Returns authentification status for the given session. @return: non-zero if authenticated or 0 if not @rtype: int """ return self._session.userauth_authenticated() def userauth_list(self, username): """ Lists the authentification methods supported by a server. @param username: username which will be used while authenticating @type username: str @return: string containing a comma-separated list of authentication methods @rtype: str """ self._session.userauth_list(username) def userauth_password(self, username, password): """ Authenticates a session with the given username and password. @param username: user to authenticate @type username: str @param password: password to use for the authentication @type password: str @return: 0 on success or negative on failure @rtype: int """ self._session.userauth_password(username, password) def userauth_publickey_fromfile( self, username, publickey, privatekey, passphrase ): """ Authenticates a session as username using a key pair found in the pulickey and privatekey files, and passphrase if provided. @param username: user to authenticate @type username: str @param publickey: path and name of public key file @type publickey: str @param privatekey: path and name of private key file @type privatekey: str @param passphrase: passphrase to use when decoding private file @type passphrase: str @return: 0 on success or negative on failure @rtype: int """ raise NotImplementedError() pylibssh2-1.0.0/src/0000755000175000017500000000000011370762106012377 5ustar sbzsbzpylibssh2-1.0.0/src/channel.c0000644000175000017500000004474511370760114014166 0ustar sbzsbz/*- * pylibssh2 - python bindings for libssh2 library * * Copyright (C) 2005 Keyphrene.com. * Copyright (C) 2010 Wallix Inc. * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation; either version 2.1 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #define PYLIBSSH2_MODULE #include "pylibssh2.h" /* {{{ PYLIBSSH2_Channel_close */ static char PYLIBSSH2_Channel_close_doc[] = "\n\ close() -> int\n\ \n\ Closes the active channel.\n\ \n\ @param channel\n\ @type libssh2.Channel\n\ \n\ @return 0 on success or negative on failure\n\ @rtype int"; static PyObject * PYLIBSSH2_Channel_close(PYLIBSSH2_CHANNEL *self, PyObject *args) { int rc; MY_BEGIN_ALLOW_THREADS(self->tstate); rc = libssh2_channel_close(self->channel); MY_END_ALLOW_THREADS(self->tstate); if (rc) { /* CLEAN: PYLIBSSH2_CHANNEL_CANT_CLOSE_MSG */ PyErr_SetString(PYLIBSSH2_Error, "Unable to close the channel."); Py_INCREF(Py_None); return Py_None; } return Py_BuildValue("i", rc); } /* }}} */ /* {{{ PYLIBSSH2_Channel_pty */ static char PYLIBSSH2_Channel_pty_doc[] = "\n\ pty(term) -> int\n\ \n\ Requests a pty with term type on a channel.\n\ \n\ @param term: terminal emulation type (vt100, ansi, etc...)\n\ @type term: str\n\ \n\ @return 0 on succes or negative on failure\n\ @rtype int"; /* * refer libssh2_channel_request_pty_ex() */ static PyObject * PYLIBSSH2_Channel_pty(PYLIBSSH2_CHANNEL *self, PyObject *args) { int rc; /* terminal type */ char *term; /* terminal type length */ int term_len; /* terminal modes capabilities */ char *modes = NULL; /* modes length */ int modes_len = 0; /* terminal dimensions in characters */ int width = 80, height = 24; /* default dimensions */ int width_px = 0, height_px = 0; if (!PyArg_ParseTuple(args, "s#|s#iiii:pty", &term, &term_len, &modes, &modes_len, &width, &height, &width_px, &height_px)) { return NULL; } MY_BEGIN_ALLOW_THREADS(self->tstate); rc = libssh2_channel_request_pty_ex(self->channel, term, term_len, modes, modes_len, width, height, width_px, height_px); MY_END_ALLOW_THREADS(self->tstate); if (rc) { /* CLEAN: PYLIBSSH2_CHANNEL_PTY_FAILED_MSG */ PyErr_SetString(PYLIBSSH2_Error, "Failed to request pty."); Py_INCREF(Py_None); return Py_None; } return Py_BuildValue("i", rc); } /* }}} */ /* {{{ PYLIBSSH2_Channel_pty_resize */ static char PYLIBSSH2_Channel_pty_resize_doc[] = "\n\ pty_resize(width, height) -> int\n\ \n\ Requests a pty resize on a channel with the given width and height.\n\ \n\ @param width: terminal width\n\ @type width: int\n\ @param height: terminal height\n\ @type height: int\n\ \n\ @return 0 on success or negative on failure\n\ @rtype int"; /* * refer libssh2_channel_request_pty_size_ex() */ static PyObject * PYLIBSSH2_Channel_pty_resize(PYLIBSSH2_CHANNEL *self, PyObject *args) { int rc = -1; /* terminal dimensions in characters */ int width = 80; int height = 24; /* terminal dimensions in pixels */ int width_px = 0; int height_px = 0; if (!PyArg_ParseTuple(args,"ii|ii:pty_resize", &width,&height, &width_px,&height_px)){ return NULL; } /* FIXME: For unknown reason, the activation of the two following methods * provokes a core dump of the lib with the following error: * PyEval_RestoreThread: NULL tstate */ /*MY_BEGIN_ALLOW_THREADS(self->tstate);*/ rc = libssh2_channel_request_pty_size_ex(self->channel, width, height, width_px, height_px); /*MY_END_ALLOW_THREADS(self->tstate);*/ if (rc) { PyErr_SetString(PYLIBSSH2_Error, "Failed to resize pty"); Py_INCREF(Py_None); return Py_None; } return Py_BuildValue("i",rc); } /* }}} */ /* {{{ PYLIBSSH2_Channel_shell */ static char PYLIBSSH2_Channel_shell_doc[] = "\n\ shell() -> int\n\ \n\ Requests a shell on the channel.\n\ \n\ @return 0 on success or negative on failure\n\ @rtype int"; static PyObject * PYLIBSSH2_Channel_shell(PYLIBSSH2_CHANNEL *self, PyObject *args) { int rc; MY_BEGIN_ALLOW_THREADS(self->tstate); rc = libssh2_channel_shell(self->channel); MY_END_ALLOW_THREADS(self->tstate); if (rc) { /* CLEAN: PYLIBSSH2_CHANNEL_CANT_REQUEST_SHELL_MSG */ PyErr_SetString(PYLIBSSH2_Error,"Unable to request shell on allocated pty."); Py_INCREF(Py_None); return Py_None; } return Py_BuildValue("i", rc); } /* }}} */ /* {{{ PYLIBSSH2_Channel_execute */ static char PYLIBSSH2_Channel_execute_doc[] = "\n\ execute(command) -> int\n\ \n\ Executes command on the channel.\n\ \n\ @param command: message data\n\ @type command: str\n\ \n\ @return 0 on success or negative on failure\n\ @rtype int"; static PyObject * PYLIBSSH2_Channel_execute(PYLIBSSH2_CHANNEL *self, PyObject *args) { int rc; /* command to execute */ char *command; if (!PyArg_ParseTuple(args, "s:execute", &command)) return NULL; MY_BEGIN_ALLOW_THREADS(self->tstate); rc = libssh2_channel_exec(self->channel, command); MY_END_ALLOW_THREADS(self->tstate); if (rc) { /* CLEAN: PYLIBSSH2_CANT_REQUEST_EXEC_COMMAND_MSG */ PyErr_SetString(PYLIBSSH2_Error, "Unable to request exec command."); Py_INCREF(Py_None); return Py_None; } return Py_BuildValue("i", rc); } /* }}} */ /* {{{ PYLIBSSH2_Channel_setenv */ static char PYLIBSSH2_Channel_setenv_doc[] = "\n\ setenv(name, value) -> int\n\ \n\ Sets envrionment variable on the channel.\n\ \n\ @param name: evironment variable name\n\ @type name: str\n\ @param value: evironment variable value\n\ @type value: str\n\ \n\ @return 0 on success or negative on failure\n\ @rtype int"; static PyObject * PYLIBSSH2_Channel_setenv(PYLIBSSH2_CHANNEL *self, PyObject *args) { int rc; /* variable envrionnement name */ char *env_key; /* variable envrionnement value */ char *env_val; if (!PyArg_ParseTuple(args, "ss:setenv", &env_key, &env_val)) return NULL; MY_BEGIN_ALLOW_THREADS(self->tstate); rc = libssh2_channel_setenv(self->channel, env_key, env_val); MY_END_ALLOW_THREADS(self->tstate); if (rc == -1) { /* CLEAN: PYLIBSSH2_CANT_SET_ENVRIONNEMENT_VARIABLE_MSG */ PyErr_SetString(PYLIBSSH2_Error,"Unable to set envrionnement variable."); Py_INCREF(Py_None); return Py_None; } return Py_BuildValue("i", rc); } /* }}} */ /* {{{ PYLIBSSH2_Channel_setblocking */ static char PYLIBSSH2_Channel_setblocking_doc[] = "\n\ setblocking([mode])\n\ \n\ Sets blocking mode on the channel. Default mode is blocking.\n\ \n\ @param mode: blocking (1) or non blocking (0) mode\n\ @type mode: int"; static PyObject * PYLIBSSH2_Channel_setblocking(PYLIBSSH2_CHANNEL *self, PyObject *args) { /* 1 blocking, 0 non blocking */ int block = 1; if (!PyArg_ParseTuple(args, "i:setblocking", &block)) return NULL; libssh2_channel_set_blocking(self->channel, block); Py_INCREF(Py_None); return Py_None; } /* }}} */ /* {{{ PYLIBSSH2_Channel_read */ static char PYLIBSSH2_Channel_read_doc[] = "\n\ read(size) -> str\n\ \n\ Reads size bytes on the channel.\n\ \n\ @param size: size of the buffer storage\n\ @type size: int\n\ \n\ @return bytes read or negative on failure\n\ @rtype str"; static PyObject * PYLIBSSH2_Channel_read(PYLIBSSH2_CHANNEL *self, PyObject *args) { int rc; int buffer_size; /* buffer to read as a python object */ PyObject *buffer; if (!PyArg_ParseTuple(args, "i|i:read", &buffer_size)) return NULL; buffer = PyString_FromStringAndSize(NULL, buffer_size); if (buffer == NULL) { return NULL; } if (libssh2_channel_eof(self->channel) != 1) { MY_BEGIN_ALLOW_THREADS(self->tstate); rc = libssh2_channel_read(self->channel, PyString_AsString(buffer), buffer_size); MY_END_ALLOW_THREADS(self->tstate); if (rc > 0) { if (rc != buffer_size && _PyString_Resize(&buffer, rc) < 0) return NULL; return buffer; } } Py_XDECREF(buffer); Py_INCREF(Py_None); return Py_None; } /* }}} */ /* {{{ PYLIBSSH2_Channel_write */ static char PYLIBSSH2_Channel_write_doc[] = "\n\ write(message) -> int\n\ \n\ Writes data on a channel.\n\ \n\ @param message: data to write\n\ @type message: str\n\ \n\ @return 0 on success or failure\n\ @rtype int"; static PyObject * PYLIBSSH2_Channel_write(PYLIBSSH2_CHANNEL *self, PyObject *args) { int rc; char *message; int message_len; if (!PyArg_ParseTuple(args, "s#:write", &message, &message_len)) return NULL; MY_BEGIN_ALLOW_THREADS(self->tstate); rc = libssh2_channel_write(self->channel, message, message_len); MY_END_ALLOW_THREADS(self->tstate); if (rc == -1) { /* CLEAN: PYLIBSSH2_CANT_WRITE_CHANNEL_MSG */ PyErr_SetString(PYLIBSSH2_Error,"Unable to write channel."); Py_INCREF(Py_None); return Py_None; } return Py_BuildValue("i", rc); } /* }}} */ /* {{{ PYLIBSSH2_Channel_flush */ static char PYLIBSSH2_Channel_flush_doc[] = "\n\ flush() -> int\n\ \n\ Flushs the read buffer for a given channel.\n\ \n\ @return 0 on success or negative on failure\n\ @rtype int"; static PyObject * PYLIBSSH2_Channel_flush(PYLIBSSH2_CHANNEL *self, PyObject *args) { int rc; MY_BEGIN_ALLOW_THREADS(self->tstate); rc = libssh2_channel_flush(self->channel); MY_END_ALLOW_THREADS(self->tstate); if (rc == -1) { /* CLEAN: PYLIBSSH2_CANT_FLUSH_CHANNEL_MSG */ PyErr_SetString(PYLIBSSH2_Error, "Unable to flush channel."); Py_INCREF(Py_None); return Py_None; } return Py_BuildValue("i", rc); } /* }}} */ /* {{{ PYLIBSSH2_Channel_exit_status */ static char PYLIBSSH2_Channel_exit_status_doc[] = "\n\ exit_status() -> int \n\ \n\ Gets the exit code raised by the process running on the remote host.\n\ \n\ @return the exit status reported by remote host or 0 on failure\n\ @rtype int"; static PyObject * PYLIBSSH2_Channel_exit_status(PYLIBSSH2_CHANNEL *self, PyObject *args) { return Py_BuildValue("i", libssh2_channel_get_exit_status(self->channel)); } /* }}} */ /* {{{ PYLIBSSH2_Channel_eof */ static char PYLIBSSH2_Channel_eof_doc[] = "\n\ eof() -> int\n\ \n\ Checks if the remote host has sent an EOF status.\n\ \n\ @return 1 if the remote host has sent EOF otherwise 0\n\ @rtype int"; static PyObject * PYLIBSSH2_Channel_eof(PYLIBSSH2_CHANNEL *self, PyObject *args) { return Py_BuildValue("i", libssh2_channel_eof(self->channel)); } /* }}} */ /* {{{ PYLIBSSH2_Channel_send_eof */ static char PYLIBSSH2_Channel_send_eof_doc[] = "\n\ send_eof() -> int\n\ \n\ Sends EOF status on the channel to remote server.\n\ \n\ @return 0 on success or negative on failure\n\ @rtype int"; static PyObject * PYLIBSSH2_Channel_send_eof(PYLIBSSH2_CHANNEL *self, PyObject *args) { int rc; MY_BEGIN_ALLOW_THREADS(self->tstate); rc = libssh2_channel_send_eof(self->channel); MY_END_ALLOW_THREADS(self->tstate); if (rc == -1) { /* CLEAN: PYLIBSSH2_CANT_SEND_EOF_MSG */ PyErr_SetString(PYLIBSSH2_Error, "Unable to send a EOF on channel."); Py_INCREF(Py_None); return Py_None; } return Py_BuildValue("i", rc); } /* }}} */ /* {{{ PYLIBSSH2_Channel_window_read */ static char PYLIBSSH2_Channel_window_read_doc[] = "\n\ window_read(read_avail, window_size_initial) -> int\n\ \n\ Checks the status of the read window.\n\ \n\ @param read_avail: \n\ @type read_avail: int\n\ @param window_size_initial: \n\ @type window_size_initial: int\n\ \n\ @return the number of bytes which the remote end may send without overflowing\n\ the window limit\n\ @rtype int"; static PyObject * PYLIBSSH2_Channel_window_read(PYLIBSSH2_CHANNEL *self, PyObject *args) { unsigned long rc; unsigned long read_avail; unsigned long window_size_initial; if (!PyArg_ParseTuple(args, "|ii:window_read", &read_avail, &window_size_initial)) { return NULL; } MY_BEGIN_ALLOW_THREADS(self->tstate); rc = libssh2_channel_window_read_ex(self->channel, &read_avail, &window_size_initial); MY_END_ALLOW_THREADS(self->tstate); return PyInt_FromLong(rc); } /* }}} */ /* {{{ PYLIBSSH2_Channel_poll */ static char PYLIBSSH2_Channel_poll_doc[] = "\n\ poll(timeout, [nfds]) -> int\n\ \n\ Polls for activity on the channel.\n\ \n\ @param timeout: remaining timeout\n\ @type timeout: int\n\ @param nfds: number of fds to poll\n\ @type nfds: int\n\ \n\ @return number of fds with interesting events or negative on failure\n\ @rtype int"; static PyObject * PYLIBSSH2_Channel_poll(PYLIBSSH2_CHANNEL *self, PyObject *args) { int rc; int nfds = 1; long timeout = 0; LIBSSH2_POLLFD fds; if (!PyArg_ParseTuple(args, "i|i:poll", &timeout, &nfds)) { return NULL; } fds.type = LIBSSH2_POLLFD_CHANNEL; fds.fd.channel = self->channel; /*see PYLIBSSH2_CHANNEL struct*/ fds.events = LIBSSH2_POLLFD_POLLIN; MY_BEGIN_ALLOW_THREADS(self->tstate); rc = libssh2_poll(&fds, nfds, timeout); MY_END_ALLOW_THREADS(self->tstate); return Py_BuildValue("i", rc); } /* }}} */ /* {{{ PYLIBSSH2_Channel_x11_req */ static char PYLIBSSH2_Channel_x11_req_doc[] = "\n\ x11_req([display]) -> int\n\ \n\ Requests an X11 Forwarding on the channel.\n\ \n\ @param display: screen number\n\ @param display: int\n\ \n\ @return 0 on success or negative on failure\n\ @rtype int"; static PyObject * PYLIBSSH2_Channel_x11_req(PYLIBSSH2_CHANNEL *self, PyObject *args) { int rc; int display = 0; if (!PyArg_ParseTuple(args, "|i:poll_x11_req", &display)) { return NULL; } MY_BEGIN_ALLOW_THREADS(self->tstate); rc = libssh2_channel_x11_req(self->channel, display); MY_END_ALLOW_THREADS(self->tstate); return Py_BuildValue("i", rc); } /* }}} */ /* {{{ PYLIBSSH2_Channel_poll_read */ static char PYLIBSSH2_Channel_poll_read_doc[] = "\n\ poll_read([extended]) -> int\n\ \n\ Checks if data is available on the channel.\n\ \n\ @param extended: if message channel datas is extended\n\ @type extended: int\n\ \n\ @return 1 when data is available or 0 otherwise\n\ @rtype int"; static PyObject * PYLIBSSH2_Channel_poll_read(PYLIBSSH2_CHANNEL *self, PyObject *args) { int rc; int extended = 0; if (!PyArg_ParseTuple(args, "|i:poll_read", &extended)) { return NULL; } MY_BEGIN_ALLOW_THREADS(self->tstate); rc = libssh2_poll_channel_read(self->channel, extended); MY_END_ALLOW_THREADS(self->tstate); return Py_BuildValue("i", rc); } /* }}} */ /* {{{ PYLIBSSH2_Channel_methods[] * * ADD_METHOD(name) expands to a correct PyMethodDef declaration * { 'name', (PyCFunction)PYLIBSSH2_Channel_name, METHOD_VARARGS } * for convenience */ #define ADD_METHOD(name) \ { #name, (PyCFunction)PYLIBSSH2_Channel_##name, METH_VARARGS, PYLIBSSH2_Channel_##name##_doc } static PyMethodDef PYLIBSSH2_Channel_methods[] = { ADD_METHOD(close), ADD_METHOD(pty), ADD_METHOD(pty_resize), ADD_METHOD(shell), ADD_METHOD(execute), ADD_METHOD(setenv), ADD_METHOD(setblocking), ADD_METHOD(read), ADD_METHOD(write), ADD_METHOD(flush), ADD_METHOD(eof), ADD_METHOD(send_eof), ADD_METHOD(window_read), ADD_METHOD(poll_read), ADD_METHOD(poll), ADD_METHOD(x11_req), ADD_METHOD(exit_status), { NULL, NULL } }; #undef ADD_METHOD /* }}} */ /* {{{ PYLIBSSH2_Channel_New */ PYLIBSSH2_CHANNEL * PYLIBSSH2_Channel_New(LIBSSH2_CHANNEL *channel, int dealloc) { PYLIBSSH2_CHANNEL *self; self = PyObject_New(PYLIBSSH2_CHANNEL, &PYLIBSSH2_Channel_Type); if (self == NULL) { return NULL; } self->channel = channel; self->tstate = NULL; self->dealloc = dealloc; return self; } /* }}} */ /* {{{ PYLIBSSH2_Channel_dealloc */ static void PYLIBSSH2_Channel_dealloc(PYLIBSSH2_CHANNEL *self) { PyObject_Del(self); } /* }}} */ /* {{{ PYLIBSSH2_Channel_getattr */ static PyObject * PYLIBSSH2_Channel_getattr(PYLIBSSH2_CHANNEL *self, char *name) { return Py_FindMethod(PYLIBSSH2_Channel_methods, (PyObject *)self, name); } /* }}} */ /* {{{ PYLIBSSH2_Channel_Type * see /usr/include/python2.5/object.h line 261 */ PyTypeObject PYLIBSSH2_Channel_Type = { PyObject_HEAD_INIT(NULL) 0, /* ob_size */ "Channel", /* tp_name */ sizeof(PYLIBSSH2_CHANNEL), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)PYLIBSSH2_Channel_dealloc, /* tp_dealloc */ 0, /* tp_print */ (getattrfunc)PYLIBSSH2_Channel_getattr, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ "Channel objects", /* tp_doc */ }; /* }}} */ /* {{{ init_libssh2_Channel */ int init_libssh2_Channel(PyObject *dict) { PYLIBSSH2_Channel_Type.ob_type = &PyType_Type; Py_XINCREF(&PYLIBSSH2_Channel_Type); PyDict_SetItemString(dict, "ChannelType", (PyObject *)&PYLIBSSH2_Channel_Type); return 1; } /* }}} */ pylibssh2-1.0.0/src/sftp.c0000644000175000017500000004663511370757466013552 0ustar sbzsbz/*- * pylibssh2 - python bindings for libssh2 library * * Copyright (C) 2005 Keyphrene.com. * Copyright (C) 2010 Wallix Inc. * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation; either version 2.1 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #define PYLIBSSH2_MODULE #include "pylibssh2.h" /* {{{ get_attrs */ PyObject * get_attrs(LIBSSH2_SFTP_ATTRIBUTES *attr) { PyObject *attrs=NULL; attrs = PyList_New(0); PyList_Append(attrs, PyLong_FromUnsignedLong( (unsigned long)attr->filesize)); PyList_Append(attrs, PyLong_FromUnsignedLong( (unsigned long)attr->uid)); PyList_Append(attrs, PyLong_FromUnsignedLong( (unsigned long)attr->gid)); PyList_Append(attrs, PyLong_FromUnsignedLong( (unsigned long)attr->permissions)); PyList_Append(attrs, PyLong_FromUnsignedLong( (unsigned long)attr->atime)); PyList_Append(attrs, PyLong_FromUnsignedLong( (unsigned long)attr->mtime)); return attrs; } /* }}} */ /* {{{ PYLIBSSH2_Sftp_close */ static char PYLIBSSH2_Sftp_close_doc[] = "\n\ myfunction(name, value) -> returnType \n\ \n\ Arguments:\n\ \n\ Returns:\n\ "; static PyObject * PYLIBSSH2_Sftp_close(PYLIBSSH2_SFTP *self, PyObject *args) { int rc; PYLIBSSH2_SFTPHANDLE *handle; if (!PyArg_ParseTuple(args, "O:close", &handle)) { return NULL; } MY_BEGIN_ALLOW_THREADS(self->tstate); rc = libssh2_sftp_close_handle(handle->sftphandle); MY_END_ALLOW_THREADS(self->tstate); if (rc) { /* CLEAN: PYLIBSSH2_SFTPHANDLE_CANT_CLOSE_MSG */ PyErr_SetString(PYLIBSSH2_Error, "Unable to close sftp handle."); Py_INCREF(Py_None); return Py_None; } return Py_BuildValue("i", rc); } /* }}} */ /* {{{ PYLIBSSH2_Sftp_opendir */ static char PYLIBSSH2_Sftp_opendir_doc[] = "\n\ \n\ Arguments:\n\ \n\ Returns:\n\ "; static PyObject * PYLIBSSH2_Sftp_opendir(PYLIBSSH2_SFTP *self, PyObject *args) { LIBSSH2_SFTP_HANDLE *handle; char *path; if (!PyArg_ParseTuple(args, "s:opendir", &path)) { return NULL; } MY_BEGIN_ALLOW_THREADS(self->tstate); handle = libssh2_sftp_opendir(self->sftp, path); MY_END_ALLOW_THREADS(self->tstate); if (handle == NULL) { /* CLEAN: PYLIBSSH2_SFTPHANDLE_CANT_OPENDIR_MSG */ PyErr_SetString(PYLIBSSH2_Error, "Unable to open sftp directory."); Py_INCREF(Py_None); return Py_None; } return (PyObject *)PYLIBSSH2_Sftphandle_New(handle, 1); } /* }}} */ /* {{{ PYLIBSSH2_Sftp_readdir */ static char PYLIBSSH2_Sftp_readdir_doc[] = "\n\ \n\ Arguments:\n\ \n\ Returns:\n\ "; static PyObject * PYLIBSSH2_Sftp_readdir(PYLIBSSH2_SFTP *self, PyObject *args) { LIBSSH2_SFTP_ATTRIBUTES attrs; PYLIBSSH2_SFTPHANDLE *handle; int buffer_maxlen = 0; int longentry_maxlen = 255; PyObject *buffer; PyObject *list; if (!PyArg_ParseTuple(args, "O:readdir", &handle)) { return NULL; } buffer = PyString_FromStringAndSize(NULL, longentry_maxlen); if (buffer == NULL) { Py_INCREF(Py_None); return Py_None; } MY_BEGIN_ALLOW_THREADS(self->tstate); buffer_maxlen = libssh2_sftp_readdir(handle->sftphandle, PyString_AsString(buffer), longentry_maxlen, &attrs); MY_END_ALLOW_THREADS(self->tstate); if (buffer_maxlen == 0) { Py_INCREF(Py_None); return Py_None; } else if ( buffer_maxlen == -1) { /* CLEAN: PYLIBSSH2_SFTPHANDLE_CANT_READDIR_MSG */ PyErr_SetString(PYLIBSSH2_Error, "Unable to readdir."); Py_INCREF(Py_None); return Py_None; } if (buffer_maxlen != longentry_maxlen && _PyString_Resize(&buffer, buffer_maxlen) < 0) { Py_INCREF(Py_None); return Py_None; } list = PyList_New(0); PyList_Append(list, buffer); PyList_Append(list, get_attrs(&attrs)); return list; } /* }}} */ /* {{{ PYLIBSSH2_Sftp_listdir */ static char PYLIBSSH2_Sftp_listdir_doc[] = "\n\ \n\ Arguments:\n\ \n\ Returns:\n\ "; static PyObject * PYLIBSSH2_Sftp_listdir(PYLIBSSH2_SFTP *self, PyObject *args) { LIBSSH2_SFTP_ATTRIBUTES attrs; PYLIBSSH2_SFTPHANDLE *handle; int buffer_maxlen = 0; int longentry_maxlen = 255; PyObject *buffer; PyObject *all = NULL; PyObject *list = NULL; if (!PyArg_ParseTuple(args, "O:listdir", &handle)) { return NULL; } all = PyList_New(0); while (1) { buffer = PyString_FromStringAndSize(NULL, longentry_maxlen); if (buffer == NULL) { Py_INCREF(Py_None); return Py_None; } MY_BEGIN_ALLOW_THREADS(self->tstate); buffer_maxlen = libssh2_sftp_readdir(handle->sftphandle, PyString_AsString(buffer), longentry_maxlen, &attrs); MY_END_ALLOW_THREADS(self->tstate); if (buffer_maxlen == 0) { break; } else if (buffer_maxlen == -1) { PyErr_SetString(PYLIBSSH2_Error, "Unable to listdir."); Py_INCREF(Py_None); return Py_None; } if ( buffer_maxlen != longentry_maxlen && _PyString_Resize(&buffer, buffer_maxlen) < 0) { Py_INCREF(Py_None); return Py_None; } list = PyList_New(0); PyList_Append(list, buffer); PyList_Append(list, get_attrs(&attrs)); PyList_Append(all, list); } return all; } /* }}} */ /* {{{ PYLIBSSH2_Sftp_open */ static char PYLIBSSH2_Sftp_open_doc[] = "\n\ \n\ Arguments:\n\ \n\ Returns:\n\ "; static PyObject * PYLIBSSH2_Sftp_open(PYLIBSSH2_SFTP *self, PyObject *args) { LIBSSH2_SFTP_HANDLE *handle; char *path; char *flags = "r"; long mode = 0755; if (!PyArg_ParseTuple(args, "s|si:open", &path, &flags, &mode)) { return NULL; } MY_BEGIN_ALLOW_THREADS(self->tstate); handle = libssh2_sftp_open(self->sftp, path, get_flags(flags), mode); MY_END_ALLOW_THREADS(self->tstate); if (handle == NULL) { /* CLEAN: PYLIBSSH2_SFTP_CANT_OPEN_MSG */ PyErr_SetString(PYLIBSSH2_Error, "Unable to sftp open."); Py_INCREF(Py_None); return Py_None; } return (PyObject *)PYLIBSSH2_Sftphandle_New(handle, 1); } /* }}} */ /* {{{ PYLIBSSH2_Sftp_shutdown */ static char PYLIBSSH2_Sftp_shutdown_doc[] = "\n\ \n\ Arguments:\n\ \n\ Returns:\n\ "; static PyObject * PYLIBSSH2_Sftp_shutdown(PYLIBSSH2_SFTP *self, PyObject *args) { int rc; rc=libssh2_sftp_shutdown(self->sftp); if (rc == -1) { /* CLEAN: PYLIBSSH2_SFTP_CANT_SHUTDOWN_MSG */ PyErr_SetString(PYLIBSSH2_Error, "Unable to shutdown sftp."); Py_INCREF(Py_None); return Py_None; } return Py_BuildValue("i", rc); } /* }}} */ /* {{{ PYLIBSSH2_Sftp_read */ static char PYLIBSSH2_Sftp_read_doc[] = "\n\ \n\ Arguments:\n\ \n\ Returns:\n\ "; static PyObject * PYLIBSSH2_Sftp_read(PYLIBSSH2_SFTP *self, PyObject *args) { int rc; int buffer_maxlen; PyObject *buffer; PYLIBSSH2_SFTPHANDLE *handle; if (!PyArg_ParseTuple(args, "Oi:read", &handle, &buffer_maxlen)) { return NULL; } buffer = PyString_FromStringAndSize(NULL, buffer_maxlen); if (buffer == NULL) { Py_INCREF(Py_None); return Py_None; } MY_BEGIN_ALLOW_THREADS(self->tstate); rc = libssh2_sftp_read(handle->sftphandle, PyString_AsString(buffer), buffer_maxlen); MY_END_ALLOW_THREADS(self->tstate); if (rc > 0) { if ( rc != buffer_maxlen && _PyString_Resize(&buffer, rc) < 0) { Py_INCREF(Py_None); return Py_None; } return buffer; } Py_XDECREF(buffer); Py_INCREF(Py_None); return Py_None; } /* }}} */ /* {{{ PYLIBSSH2_Sftp_write */ static char PYLIBSSH2_Sftp_write_doc[] = "\n\ \n\ Arguments:\n\ \n\ Returns:\n\ "; static PyObject * PYLIBSSH2_Sftp_write(PYLIBSSH2_SFTP *self, PyObject *args) { int rc, buffer_len; char *buffer; PYLIBSSH2_SFTPHANDLE *handle; if (!PyArg_ParseTuple(args, "Os#:write", &handle, &buffer, &buffer_len)) { return NULL; } MY_BEGIN_ALLOW_THREADS(self->tstate); rc = libssh2_sftp_write(handle->sftphandle, buffer, buffer_len); MY_END_ALLOW_THREADS(self->tstate); if (rc < 0) { /* CLEAN: PYLIBSSH2_Sftp_CANT_WRITE_MSG */ PyErr_Format(PYLIBSSH2_Error, "Unable to write sftp."); Py_INCREF(Py_None); return Py_None; } return Py_BuildValue("i", rc); } /* }}} */ /* {{{ PYLIBSSH2_Sftp_tell */ static char PYLIBSSH2_Sftp_tell_doc[] = "\n\ \n\ Arguments:\n\ \n\ Returns:\n\ "; static PyObject * PYLIBSSH2_Sftp_tell(PYLIBSSH2_SFTP *self, PyObject *args) { PYLIBSSH2_SFTPHANDLE *handle; if (!PyArg_ParseTuple(args, "O:tell", &handle)) { return NULL; } return PyInt_FromLong(libssh2_sftp_tell(handle->sftphandle)); } /* }}} */ /* {{{ PYLIBSSH2_Sftp_seek */ static char PYLIBSSH2_Sftp_seek_doc[] = "\n\ \n\ Arguments:\n\ \n\ Returns:\n\ "; static PyObject * PYLIBSSH2_Sftp_seek(PYLIBSSH2_SFTP *self, PyObject *args) { PYLIBSSH2_SFTPHANDLE *handle; unsigned long offset=0; if (!PyArg_ParseTuple(args, "Ok:seek", &handle, &offset)) { return NULL; } MY_BEGIN_ALLOW_THREADS(self->tstate); libssh2_sftp_seek(handle->sftphandle, offset); MY_END_ALLOW_THREADS(self->tstate); return PyInt_FromLong(1); } /* }}} */ /* {{{ PYLIBSSH2_Sftp_unlink */ static char PYLIBSSH2_Sftp_unlink_doc[] = "\n\ \n\ Arguments:\n\ \n\ Returns:\n\ "; static PyObject * PYLIBSSH2_Sftp_unlink(PYLIBSSH2_SFTP *self, PyObject *args) { int rc; char *path; if (!PyArg_ParseTuple(args, "s:unlink", &path)) { return NULL; } MY_BEGIN_ALLOW_THREADS(self->tstate); rc = libssh2_sftp_unlink(self->sftp, path); MY_END_ALLOW_THREADS(self->tstate); return Py_BuildValue("i", rc); } /* }}} */ /* {{{ PYLIBSSH2_Sftp_rename */ static char PYLIBSSH2_Sftp_rename_doc[] = "\n\ \n\ Arguments:\n\ \n\ Returns:\n\ "; static PyObject * PYLIBSSH2_Sftp_rename(PYLIBSSH2_SFTP *self, PyObject *args) { int rc; char *src, *dst; if (!PyArg_ParseTuple(args, "ss:rename", &src, &dst)) { return NULL; } MY_BEGIN_ALLOW_THREADS(self->tstate); rc = libssh2_sftp_rename(self->sftp, src, dst); MY_END_ALLOW_THREADS(self->tstate); return Py_BuildValue("i", rc); } /* }}} */ /* {{{ PYLIBSSH2_Sftp_mkdir */ static char PYLIBSSH2_Sftp_mkdir_doc[] = "\n\ \n\ Arguments:\n\ \n\ Returns:\n\ "; static PyObject * PYLIBSSH2_Sftp_mkdir(PYLIBSSH2_SFTP *self, PyObject *args) { int rc; char *path; long mode = 0755; if (!PyArg_ParseTuple(args, "s|i:mkdir", &path, &mode)) { return NULL; } MY_BEGIN_ALLOW_THREADS(self->tstate); rc = libssh2_sftp_mkdir(self->sftp, path, mode); MY_END_ALLOW_THREADS(self->tstate); return Py_BuildValue("i", rc); } /* }}} */ /* {{{ PYLIBSSH2_Sftp_rmdir */ static char PYLIBSSH2_Sftp_rmdir_doc[] = "\n\ \n\ Arguments:\n\ \n\ Returns:\n\ "; static PyObject * PYLIBSSH2_Sftp_rmdir(PYLIBSSH2_SFTP *self, PyObject *args) { int rc; char *path; if (!PyArg_ParseTuple(args, "s:rmdir", &path)) { return NULL; } MY_BEGIN_ALLOW_THREADS(self->tstate); rc = libssh2_sftp_rmdir(self->sftp, path); MY_END_ALLOW_THREADS(self->tstate); return Py_BuildValue("i", rc); } /* }}} */ /* {{{ PYLIBSSH2_Sftp_realpath */ static char PYLIBSSH2_Sftp_realpath_doc[] = "\n\ \n\ Arguments:\n\ \n\ Returns:\n\ "; static PyObject * PYLIBSSH2_Sftp_realpath(PYLIBSSH2_SFTP *self, PyObject *args) { int rc, path_len = 0, target_len = 1024; int type = LIBSSH2_SFTP_REALPATH; char *path; PyObject *target; if (!PyArg_ParseTuple(args, "s#|i:realpath", &path, &path_len, &type)) { return NULL; } target = PyString_FromStringAndSize(NULL, target_len); if (target == NULL) { Py_INCREF(Py_None); return Py_None; } MY_BEGIN_ALLOW_THREADS(self->tstate); rc = libssh2_sftp_symlink_ex(self->sftp, path, path_len, PyString_AsString(target), target_len, type); MY_END_ALLOW_THREADS(self->tstate); if (rc > 0) { if (rc != target_len && _PyString_Resize(&target, rc) < 0) { Py_INCREF(Py_None); return Py_None; } return target; } Py_XDECREF(target); Py_INCREF(Py_None); return Py_None; } /* }}} */ /* {{{ PYLIBSSH2_Sftp_symlink */ static char PYLIBSSH2_Sftp_symlink_doc[] = "\n\ \n\ Arguments:\n\ \n\ Returns:\n\ "; static PyObject * PYLIBSSH2_Sftp_symlink(PYLIBSSH2_SFTP *self, PyObject *args) { int rc; char *path, *target; if (!PyArg_ParseTuple(args, "ss:symlink", &path, &target)) { return NULL; } MY_BEGIN_ALLOW_THREADS(self->tstate); rc = libssh2_sftp_symlink(self->sftp, path, target); MY_END_ALLOW_THREADS(self->tstate); if (rc == -1) { /* CLEAN: PYLIBSSH2_SFTP_CANT_SYMLINK_MSG */ PyErr_SetString(PYLIBSSH2_Error, "Unable to sftp symlink."); Py_INCREF(Py_None); return Py_None; } return Py_BuildValue("i", rc); } /* }}} */ /* {{{ PYLIBSSH2_Sftp_get_stat */ static char PYLIBSSH2_Sftp_get_stat_doc[] = "\n\ \n\ Arguments:\n\ \n\ Returns:\n\ "; static PyObject * PYLIBSSH2_Sftp_get_stat(PYLIBSSH2_SFTP *self, PyObject *args) { int rc; char *path; int path_len = 0; int type = LIBSSH2_SFTP_STAT; LIBSSH2_SFTP_ATTRIBUTES attr; if (!PyArg_ParseTuple(args, "s#|i:get_stat", &path, &path_len, &type)) { return NULL; } MY_BEGIN_ALLOW_THREADS(self->tstate); rc = libssh2_sftp_stat_ex(self->sftp, path, path_len, type, &attr); MY_END_ALLOW_THREADS(self->tstate); if (rc == -1) { /* CLEAN: PYLIBSSH2_SFTP_CANT_GETSTAT_MSG */ PyErr_SetString(PYLIBSSH2_Error, "Unable to get stat."); Py_INCREF(Py_None); return Py_None; } return get_attrs(&attr); } /* }}} */ /* {{{ PYLIBSSH2_Sftp_set_stat */ static char PYLIBSSH2_Sftp_set_stat_doc[] = "\n\ \n\ Arguments:\n\ \n\ Returns:\n\ "; static PyObject * PYLIBSSH2_Sftp_set_stat(PYLIBSSH2_SFTP *self, PyObject *args) { int rc; char *path; LIBSSH2_SFTP_ATTRIBUTES attr; PyObject *attrs; if (!PyArg_ParseTuple(args, "sO:set_stat", &path, &attrs)) { return NULL; } attr.flags = 0; if (PyMapping_HasKeyString(attrs, "perms")) { attr.flags |= LIBSSH2_SFTP_ATTR_PERMISSIONS; attr.permissions = PyLong_AsLong(PyDict_GetItemString(attrs, "perms")); } if (PyMapping_HasKeyString(attrs, "uid") && PyMapping_HasKeyString(attrs, "gid")) { if (PyMapping_HasKeyString(attrs, "uid")) { attr.flags |= LIBSSH2_SFTP_ATTR_UIDGID; attr.uid = PyLong_AsLong(PyDict_GetItemString(attrs,"uid")); } if (PyMapping_HasKeyString(attrs, "gid")) { attr.flags |= LIBSSH2_SFTP_ATTR_UIDGID; attr.uid = PyLong_AsLong(PyDict_GetItemString(attrs,"gid")); } } if (PyMapping_HasKeyString(attrs, "atime") && PyMapping_HasKeyString(attrs, "mtime")) { if (PyMapping_HasKeyString(attrs, "atime")) { attr.flags |= LIBSSH2_SFTP_ATTR_ACMODTIME; attr.uid = PyLong_AsLong(PyDict_GetItemString(attrs,"atime")); } if (PyMapping_HasKeyString(attrs, "mtime")) { attr.flags |= LIBSSH2_SFTP_ATTR_ACMODTIME; attr.uid = PyLong_AsLong(PyDict_GetItemString(attrs,"mtime")); } } MY_BEGIN_ALLOW_THREADS(self->tstate); rc = libssh2_sftp_setstat(self->sftp, path, &attr); MY_END_ALLOW_THREADS(self->tstate); if (rc == -1) { PyErr_SetString(PYLIBSSH2_Error, "Unable to stat."); Py_INCREF(Py_None); return Py_None; } return Py_BuildValue("i", rc); } /* }}} */ /* {{{ PYLIBSSH2_Sftp_methods[] * * ADD_METHOD(name) expands to a correct PyMethodDef declaration * { 'name', (PyCFunction)PYLIBSSH2_Sftp_name, METH_VARARGS } * for convenience */ #define ADD_METHOD(name) \ { #name, (PyCFunction)PYLIBSSH2_Sftp_##name, METH_VARARGS, PYLIBSSH2_Sftp_##name##_doc } static PyMethodDef PYLIBSSH2_Sftp_methods[] = { ADD_METHOD(close), ADD_METHOD(opendir), ADD_METHOD(readdir), ADD_METHOD(listdir), ADD_METHOD(open), ADD_METHOD(shutdown), ADD_METHOD(read), ADD_METHOD(write), ADD_METHOD(tell), ADD_METHOD(seek), ADD_METHOD(unlink), ADD_METHOD(rename), ADD_METHOD(mkdir), ADD_METHOD(rmdir), ADD_METHOD(realpath), ADD_METHOD(symlink), ADD_METHOD(get_stat), ADD_METHOD(set_stat), { NULL, NULL } }; #undef ADD_METHOD /* }}} */ /* {{{ PYLIBSSH2_Sftp_New */ PYLIBSSH2_SFTP * PYLIBSSH2_Sftp_New(LIBSSH2_SFTP *sftp, int dealloc) { PYLIBSSH2_SFTP *self; self = PyObject_New(PYLIBSSH2_SFTP, &PYLIBSSH2_Sftp_Type); if (self == NULL) { return NULL; } self->sftp = sftp; self->dealloc = dealloc; self->tstate = NULL; return self; } /* }}} */ /* {{{ PYLIBSSH2_Sftp_dealloc */ static void PYLIBSSH2_Sftp_dealloc(PYLIBSSH2_SFTP *self) { PyObject_Del(self); } /* }}} */ /* {{{ PYLIBSSH2_Sftp_getattr */ static PyObject * PYLIBSSH2_Sftp_getattr(PYLIBSSH2_SFTP *self, char *name) { return Py_FindMethod(PYLIBSSH2_Sftp_methods, (PyObject *)self, name); } /* }}} */ /* {{{ PYLIBSSH2_Sftp_Type * * see /usr/include/python2.5/object.h line 261 */ PyTypeObject PYLIBSSH2_Sftp_Type = { PyObject_HEAD_INIT(NULL) 0, /* ob_size */ "Sftp", /* tp_name */ sizeof(PYLIBSSH2_SFTP), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)PYLIBSSH2_Sftp_dealloc, /* tp_dealloc */ 0, /* tp_print */ (getattrfunc)PYLIBSSH2_Sftp_getattr, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ "Sftp objects", /* tp_doc */ }; /* }}} */ /* {{{ init_libssh2_Sftp */ int init_libssh2_Sftp(PyObject *dict) { PYLIBSSH2_Sftp_Type.ob_type = &PyType_Type; Py_XINCREF(&PYLIBSSH2_Sftp_Type); PyDict_SetItemString(dict, "SFTPType", (PyObject *) &PYLIBSSH2_Sftp_Type); return 1; } /* }}} */ pylibssh2-1.0.0/src/sftphandle.c0000644000175000017500000000675511370757537014724 0ustar sbzsbz/*- * pylibssh2 - python bindings for libssh2 library * * Copyright (C) 2005 Keyphrene.com. * Copyright (C) 2010 Wallix Inc. * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation; either version 2.1 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #define PYLIBSSH2_MODULE #include "pylibssh2.h" /* * ADD_METHOD(name) expands to a correct PyMethodDef declaration * { 'name', (PyCFunction)PYLIBSSH2_Sftphandle_name, METH_VARARGS } * for convenience */ #define ADD_METHOD(name) \ { #name, (PyCFunction)PYLIBSSH2_Sftphandle_##name, METH_VARARGS, PYLIBSSH2_Sftphandle_##name##_doc } static PyMethodDef PYLIBSSH2_Sftphandle_methods[] = { { NULL, NULL } }; PYLIBSSH2_SFTPHANDLE * PYLIBSSH2_Sftphandle_New(LIBSSH2_SFTP_HANDLE *sftphandle, int dealloc) { PYLIBSSH2_SFTPHANDLE *self; self = PyObject_New(PYLIBSSH2_SFTPHANDLE, &PYLIBSSH2_Sftphandle_Type); if (self == NULL) { return NULL; } self->sftphandle = sftphandle; self->dealloc = dealloc; return self; } static void PYLIBSSH2_Sftphandle_dealloc(PYLIBSSH2_SFTPHANDLE *self) { PyObject_Del(self); } static PyObject * PYLIBSSH2_Sftphandle_getattr(PYLIBSSH2_SFTPHANDLE *self, char *name) { return Py_FindMethod(PYLIBSSH2_Sftphandle_methods, (PyObject *)self, name); } /* * see /usr/include/python2.5/object.c line 261 */ PyTypeObject PYLIBSSH2_Sftphandle_Type = { PyObject_HEAD_INIT(NULL) 0, /* ob_size */ "Sftphandle", /* tp_name */ sizeof(PYLIBSSH2_SFTPHANDLE), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)PYLIBSSH2_Sftphandle_dealloc, /* tp_dealloc */ 0, /* tp_print */ (getattrfunc)PYLIBSSH2_Sftphandle_getattr, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ "Sftphandle objects", /* tp_doc */ }; int init_libssh2_Sftphandle(PyObject *dict) { PYLIBSSH2_Sftphandle_Type.ob_type = &PyType_Type; Py_XINCREF(&PYLIBSSH2_Sftphandle_Type); PyDict_SetItemString(dict, "SftphandleType", (PyObject *)&PYLIBSSH2_Sftphandle_Type); return 1; } pylibssh2-1.0.0/src/sftphandle.h0000644000175000017500000000255511370760046014710 0ustar sbzsbz/*- * pylibssh2 - python bindings for libssh2 library * * Copyright (C) 2005 Keyphrene.com. * Copyright (C) 2010 Wallix Inc. * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation; either version 2.1 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _PYLIBSSH2_SFTPHANDLE_H_ #define _PYLIBSSH2_SFTPHANDLE_H_ #include #include extern int init_libssh2_Sftphandle(PyObject *); extern PyTypeObject PYLIBSSH2_Sftphandle_Type; #define PYLIBSSH2_Sftphandle_Check(v) ((v)->ob_type == &PYLIBSSH2_Sftphandle_Type) typedef struct { PyObject_HEAD LIBSSH2_SFTP_HANDLE *sftphandle; int dealloc; } PYLIBSSH2_SFTPHANDLE; PYLIBSSH2_SFTPHANDLE * PYLIBSSH2_Sftphandle_New(LIBSSH2_SFTP_HANDLE *, int); #endif /* _PYLIBSSH2_SFTPHANDLE_H_ */ pylibssh2-1.0.0/src/session.h0000644000175000017500000000254211370757754014253 0ustar sbzsbz/*- * pylibssh2 - python bindings for libssh2 library * * Copyright (C) 2005 Keyphrene.com. * Copyright (C) 2010 Wallix Inc. * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation; either version 2.1 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _PYLIBSSH2_SESSION_H_ #define _PYLIBSSH2_SESSION_H_ #include #include extern int init_libssh2_Session(PyObject *); extern PyTypeObject PYLIBSSH2_Session_Type; #define PYLIBSSH2_Session_Check(v) ((v)->ob_type == &PYLIBSSH2_Session_Type) typedef struct { PyObject_HEAD LIBSSH2_SESSION *session; PyObject *socket; PyThreadState *tstate; int dealloc; int opened; } PYLIBSSH2_SESSION; #endif /* _PYLIBSSH2_SESSION_H_ */ pylibssh2-1.0.0/src/session.c0000644000175000017500000006250311370757437014247 0ustar sbzsbz/*- * pylibssh2 - python bindings for libssh2 library * * Copyright (C) 2005 Keyphrene.com. * Copyright (C) 2010 Wallix Inc. * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation; either version 2.1 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #define PYLIBSSH2_MODULE #include "pylibssh2.h" /* {{{ PYLIBSSH2_Session_set_banner */ static char PYLIBSSH2_Session_set_banner_doc[] = "\ set_banner(banner) -> int\n\ \n\ Sets the banner that will be sent to remote host.\n\ This is optional, the banner libssh2.DEFAULT_BANNER will be sent by default.\n\ \n\ @param banner: an user defined banner\n\ @type banner: str\n\ \n\ @return 0 on success or negative on failure\n\ @rtype int"; static PyObject * PYLIBSSH2_Session_set_banner(PYLIBSSH2_SESSION *self, PyObject *args) { int rc; char *banner; if (!PyArg_ParseTuple(args, "s:set_banner", &banner)) { return NULL; } rc=libssh2_banner_set(self->session, banner); return Py_BuildValue("i", rc); } /* }}} */ /* {{{ PYLIBSSH2_Session_startup */ static char PYLIBSSH2_Session_startup_doc[] = "\ startup(socket) -> int\n\ \n\ Starts up the session from a socket created by socket.socket() call.\n\ \n\ @param socket: a connected socket object\n\ @type socket: socket._socketobject\n\ \n\ @return 0 on success or negative on failure\n\ @rtype int"; static PyObject * PYLIBSSH2_Session_startup(PYLIBSSH2_SESSION *self, PyObject *args) { int rc; int fd; char *last_error = ""; PyObject *socket; if (!PyArg_ParseTuple(args, "O:startup", &socket)) { return NULL; } Py_XINCREF(socket); self->socket = socket; fd = PyObject_AsFileDescriptor(socket); MY_BEGIN_ALLOW_THREADS(self->tstate); rc = libssh2_session_startup(self->session, fd); MY_END_ALLOW_THREADS(self->tstate); if (rc) { libssh2_session_last_error(self->session, &last_error, NULL, 0); /* CLEAN: PYLIBSSH2_SESSION_STARTUP_MSG */ PyErr_Format(PYLIBSSH2_Error, "SSH startup: %s", last_error); Py_INCREF(Py_None); return Py_None; } self->opened = 1; return Py_BuildValue("i", rc); } /* }}} */ /* {{{ PYLIBSSH2_Session_close */ static char PYLIBSSH2_Session_close_doc[] = "\ close([reason]) -> int \n\ \n\ Closes the session.\n\ \n\ @param reason: human readable reason for disconnection\n\ @type reason: str\n\ \n\ @return 0 on success or negative on failure\n\ @rtype int"; static PyObject * PYLIBSSH2_Session_close(PYLIBSSH2_SESSION *self, PyObject *args) { int rc; char *reason = "end"; if (!PyArg_ParseTuple(args, "|s:close", &reason)) { return NULL; } MY_BEGIN_ALLOW_THREADS(self->tstate); rc = libssh2_session_disconnect(self->session, reason); MY_END_ALLOW_THREADS(self->tstate); if (rc) { /* CLEAN: PYLIBSSH2_SESSION_CLOSE_MSG */ PyErr_SetString(PYLIBSSH2_Error, "SSH close error."); Py_INCREF(Py_None); return Py_None; } self->opened = 0; return Py_BuildValue("i", rc); } /* }}} */ /* {{{ PYLIBSSH2_Session_userauth_authenticated */ static char PYLIBSSH2_Session_userauth_authenticated_doc[] = "\ userauth_authenticated() -> int\n\ \n\ Returns authentification status for the given session.\n\ \n\ @return non-zero if authenticated or 0 if not\n\ @rtype int"; static PyObject * PYLIBSSH2_Session_userauth_authenticated(PYLIBSSH2_SESSION *self, PyObject *args) { return Py_BuildValue("i", libssh2_userauth_authenticated(self->session)); } /* }}} */ /* {{{ PYLIBSSH2_Session_userauth_list */ static char PYLIBSSH2_Session_userauth_list_doc[] = "\ userauth_list(username) -> str\n\ \n\ Lists the authentification methods supported by a server.\n\ \n\ @param username: username which will be used while authenticating\n\ @type username: str\n\ \n\ @return a string containing a comma-separated list of authentication methods\n\ @rtype str"; static PyObject * PYLIBSSH2_Session_userauth_list(PYLIBSSH2_SESSION *self, PyObject *args) { char *username; int username_len = 0; char *auth_list; if (!PyArg_ParseTuple(args, "s#:userauth_list", &username, &username_len)) { return NULL; } auth_list=libssh2_userauth_list(self->session, username, username_len); if (auth_list == NULL) { Py_INCREF(Py_None); return Py_None; } return PyString_FromString(auth_list); } /* }}} */ /* {{{ PYLIBSSH2_Session_hostkey_hash */ static char PYLIBSSH2_Session_hostkey_hash_doc[] = "\n\ hostkey_hash([hashtype]) -> str\n\ \n\ Returns the computed digest of the remote host's key.\n\ \n\ @param hashtype: values possible are 1 (HASH_MD5) or 2 (HASH_SHA1)\n\ @type hashtype: str\n\ \n\ @return string representation of the computed hash value\n\ @rtype str"; static PyObject * PYLIBSSH2_Session_hostkey_hash(PYLIBSSH2_SESSION *self, PyObject *args) { int hashtype = LIBSSH2_HOSTKEY_HASH_MD5; const char *hash; if (!PyArg_ParseTuple(args, "|i:hostkey_hash", &hashtype)) { return NULL; } MY_BEGIN_ALLOW_THREADS(self->tstate); hash = libssh2_hostkey_hash(self->session, hashtype); MY_END_ALLOW_THREADS(self->tstate); if (hash == NULL) { Py_INCREF(Py_None); return Py_None; } return PyString_FromString(hash); } /* }}} */ /* {{{ PYLIBSSH2_Session_userauth_password */ static char PYLIBSSH2_Session_userauth_password_doc[] = "\n\ userauth_password(username, password) -> int \n\ \n\ Authenticates a session with the given username and password.\n\ \n\ @param username: user to authenticate\n\ @type username: str\n\ @param password: password to use for the authentication\n\ @type password: str\n\ \n\ @return 0 on success or negative on failure\n\ @rtype int"; static PyObject * PYLIBSSH2_Session_userauth_password(PYLIBSSH2_SESSION *self, PyObject *args) { int rc; char *username; char *password; if (!PyArg_ParseTuple(args, "ss:userauth_password", &username, &password)) return NULL; MY_BEGIN_ALLOW_THREADS(self->tstate); rc = libssh2_userauth_password(self->session, username, password); MY_END_ALLOW_THREADS(self->tstate); if (rc) { /* CLEAN: PYLIBSSH2_SESSION_USERAUTH_PASSWORD_FAILED_MSG */ PyErr_SetString(PYLIBSSH2_Error, "Authentification by password failed."); Py_INCREF(Py_None); return Py_None; } return Py_BuildValue("i", rc); } /* }}} */ /* {{{ PYLIBSSH2_Session_userauth_publickey_fromfile */ static char PYLIBSSH2_Session_userauth_publickey_fromfile_doc[] = "\n\ userauth_publickey_fromfile(username, publickey, privatekey, passphrase) -> int\n\ \n\ Authenticates a session as username using a key pair found in the pulickey and\n\ privatekey files, and passphrase if provided.\n\ \n\ @param username: user to authenticate\n\ @type username: str\n\ @param publickey: path and name of public key file\n\ @type publickey: str\n\ @param privatekey: path and name of private key file\n\ @type privatekey: str\n\ @param passphrase: passphrase to use when decoding private file\n\ @type passphrase: str\n\ \n\ @return 0 on success or negative on failure\n\ @rtype int"; static PyObject * PYLIBSSH2_Session_userauth_publickey_fromfile(PYLIBSSH2_SESSION *self, PyObject *args) { int rc; char *username; char *publickey; char *privatekey; char *passphrase; char *last_error; if (!PyArg_ParseTuple(args, "sss|s:userauth_publickey_fromfile", &username, &publickey, &privatekey, &passphrase)) { return NULL; } MY_BEGIN_ALLOW_THREADS(self->tstate); rc = libssh2_userauth_publickey_fromfile(self->session, username, publickey, privatekey, passphrase); MY_END_ALLOW_THREADS(self->tstate); if (rc) { libssh2_session_last_error(self->session, &last_error, NULL, 0); PyErr_Format(PYLIBSSH2_Error, "Authentification by public key failed: %s", last_error); Py_INCREF(Py_None); return Py_None; } return Py_BuildValue("i", rc); } /* }}} */ /* {{{ PYLIBSSH2_Session_session_methods */ static char PYLIBSSH2_Session_session_methods_doc[] = "\n\ session_methods() -> dict\n\ \n\ Returns a dictionnary with the currently active algorithms. \n\ CS keys is Client to Server and SC keys is Server to Client.\n\ \n\ @return a dictionnary with actual method neogicated\n\ @rtype dict"; static PyObject * PYLIBSSH2_Session_session_methods(PYLIBSSH2_SESSION *self, PyObject *args) { /* cs = client-server, sc = server-client */ const char *kex, *hostkey; const char *crypt_cs, *crypt_sc; const char *mac_cs, *mac_sc; const char *comp_cs, *comp_sc; const char *lang_cs, *lang_sc; PyObject *methods; kex = libssh2_session_methods(self->session, LIBSSH2_METHOD_KEX); if (kex == NULL) { /* session has not yet been started no methods negociated */ Py_INCREF(Py_None); return Py_None; } hostkey = libssh2_session_methods(self->session, LIBSSH2_METHOD_HOSTKEY); crypt_cs = libssh2_session_methods(self->session, LIBSSH2_METHOD_CRYPT_CS); crypt_sc = libssh2_session_methods(self->session, LIBSSH2_METHOD_CRYPT_SC); mac_cs = libssh2_session_methods(self->session, LIBSSH2_METHOD_MAC_CS); mac_sc = libssh2_session_methods(self->session, LIBSSH2_METHOD_MAC_SC); comp_cs = libssh2_session_methods(self->session, LIBSSH2_METHOD_COMP_CS); comp_sc = libssh2_session_methods(self->session, LIBSSH2_METHOD_COMP_SC); lang_cs = libssh2_session_methods(self->session, LIBSSH2_METHOD_LANG_CS); lang_sc = libssh2_session_methods(self->session, LIBSSH2_METHOD_LANG_SC); /* create a python dictionnary to store cryptographic algorithms */ methods = PyDict_New(); PyDict_SetItemString(methods, "KEX", PyString_FromString(kex)); PyDict_SetItemString(methods, "HOSTKEY", PyString_FromString(hostkey)); PyDict_SetItemString(methods, "CRYPT_CS", PyString_FromString(crypt_cs)); PyDict_SetItemString(methods, "CRYPT_SC", PyString_FromString(crypt_sc)); PyDict_SetItemString(methods, "MAC_CS", PyString_FromString(mac_cs)); PyDict_SetItemString(methods, "MAC_SC", PyString_FromString(mac_sc)); PyDict_SetItemString(methods, "COMP_CS", PyString_FromString(comp_cs)); PyDict_SetItemString(methods, "COMP_SC", PyString_FromString(comp_sc)); PyDict_SetItemString(methods, "LANG_CS", PyString_FromString(lang_cs)); PyDict_SetItemString(methods, "LANG_SC", PyString_FromString(lang_sc)); return methods; } /* }}} */ /* {{{ PYLIBSSH2_Session_session_method_pref */ static char PYLIBSSH2_Session_session_method_pref_doc[] = "\n\ session_method_pref(method_type, pref) -> int\n\ \n\ Sets preferred methods to be negociated. Theses preferences must be\n\ prior to calling startup().\n\ \n\ @param method_type: the method type constants\n\ @type method_type: L{libssh2.METHOD}\n\ @param pref: coma delimited list of preferred methods\n\ @type pref: str\n\ \n\ @return 0 on success or negative on failure\n\ @rtype int"; static PyObject * PYLIBSSH2_Session_session_method_pref(PYLIBSSH2_SESSION *self, PyObject *args) { int method; char *pref; if (!PyArg_ParseTuple(args, "is:session_method_pref", &method, &pref)) { return NULL; } return PyInt_FromLong(libssh2_session_method_pref(self->session, method, pref)==0?1:0); } /* }}} */ /* {{{ PYLIBSSH2_Session_open_session */ static char PYLIBSSH2_Session_open_session_doc[] = "\n\ open_session() -> libssh2.Channel\n\ \n\ Allocates a new channel for the current session.\n\ \n\ @return new channel opened\n\ @rtype libssh2.Channel"; static PyObject * PYLIBSSH2_Session_open_session(PYLIBSSH2_SESSION *self, PyObject *args) { int dealloc = 1; if (!PyArg_ParseTuple(args, "|i:open_session", &dealloc)) { return NULL; } return (PyObject *)PYLIBSSH2_Channel_New(libssh2_channel_open_session(self->session), dealloc); } /* }}} */ /* {{{ PYLIBSSH2_Session_scp_recv */ static char PYLIBSSH2_Session_scp_recv_doc[] = "\n\ scp_recv(remote_path) -> libssh2.Channel\n\ \n\ Requests a remote file via SCP protocol.\n\ \n\ @param remote_path: absolute path of remote file to transfer\n\ @type remote_path: str\n\ \n\ @return new channel opened\n\ @rtype libssh2.Channel"; static PyObject * PYLIBSSH2_Session_scp_recv(PYLIBSSH2_SESSION *self, PyObject *args) { char *path; LIBSSH2_CHANNEL *channel; if (!PyArg_ParseTuple(args, "s:scp_recv", &path)) { return NULL; } channel = libssh2_scp_recv(self->session, path, NULL); if (channel == NULL) { /* CLEAN: PYLIBSSH2_CHANNEL_SCP_RECV_ERROR_MSG */ PyErr_SetString(PYLIBSSH2_Error, "SCP receive error."); Py_INCREF(Py_None); return Py_None; } return (PyObject *)PYLIBSSH2_Channel_New(channel, 1); } /* }}} */ /* {{{ PYLIBSSH2_Session_scp_send */ static char PYLIBSSH2_Session_scp_send_doc[] = "\n\ scp_send(path, mode, size) -> libssh2.Channel\n\ \n\ Sends a file to remote host via SCP protocol.\n\ \n\ @param path: absolute path of tile to transfer\n\ @type path: str\n\ @param mode: file access mode to create file\n\ @type mode: int\n\ @param size: size of file being transmitted\n\ @type size: int\n\ \n\ @return new channel opened\n\ @rtype libssh2.Channel"; static PyObject * PYLIBSSH2_Session_scp_send(PYLIBSSH2_SESSION *self, PyObject *args) { char *path; int mode; unsigned long filesize; LIBSSH2_CHANNEL *channel; if (!PyArg_ParseTuple(args, "sik:scp_send", &path, &mode, &filesize)) { return NULL; } channel = libssh2_scp_send(self->session, path, mode, filesize); if (channel == NULL) { /* CLEAN: PYLIBSSH2_CHANNEL_SCP_SEND_ERROR_MSG */ PyErr_SetString(PYLIBSSH2_Error, "SCP send error."); Py_INCREF(Py_None); return Py_None; } return (PyObject *)PYLIBSSH2_Channel_New(channel, 1); } /* }}} */ /* {{{ PYLIBSSH2_Session_sftp_init */ static char PYLIBSSH2_Session_sftp_init_doc[] = "\n\ sftp_init() -> libssh2.Sftp\n\ \n\ Opens an SFTP Channel.\n\ \n\ @return new opened SFTP channel\n\ @rtype libssh2.Sftp"; static PyObject * PYLIBSSH2_Session_sftp_init(PYLIBSSH2_SESSION *self, PyObject *args) { int dealloc = 1; if (!PyArg_ParseTuple(args, "|i:sftp_init", &dealloc)) { return NULL; } return (PyObject *)PYLIBSSH2_Sftp_New(libssh2_sftp_init(self->session), dealloc); } /* }}} */ /* {{{ PYLIBSSH2_Session_direct_tcpip */ static char PYLIBSSH2_Session_direct_tcpip_doc[] = "\n\ direct_tcpip(host, port, shost, sport) -> libssh2.Channel\n\ \n\ Tunnels a TCP connection through an SSH Session.\n\ \n\ @param host: remote host\n\ @type host: str\n\ @param port: remote port\n\ @type port: int\n\ @param shost: local host\n\ @type shost: str\n\ @param sport: local port\n\ @type sport: int\n\ \n\ @return new opened channel\n\ @rtype libssh2.Channel"; static PyObject * PYLIBSSH2_Session_direct_tcpip(PYLIBSSH2_SESSION *self, PyObject *args) { /* remote host */ char *host; /* local host */ char *shost = "127.0.0.1"; /* local port */ int sport = 22; /* remote port */ int port; LIBSSH2_CHANNEL *channel; char *last_error = ""; if (!PyArg_ParseTuple(args, "si|si:direct_tcpip", &host, &port, &shost, &sport)) { return NULL; } MY_BEGIN_ALLOW_THREADS(self->tstate); channel = libssh2_channel_direct_tcpip_ex(self->session, host, port, shost, sport); MY_END_ALLOW_THREADS(self->tstate); if (channel == NULL) { libssh2_session_last_error(self->session, &last_error, NULL, 0); /* CLEAN: PYLIBSSH2_SESSION_TCP_CONNECT_ERROR_MSG */ PyErr_SetString(PYLIBSSH2_Error, "Unable to create TCP connection."); Py_INCREF(Py_None); return Py_None; } return (PyObject *)channel; } /* }}} */ /* {{{ PYLIBSSH2_Session_forward_listen */ static char PYLIBSSH2_Session_forward_listen_doc[] = "\n\ forward_listen(host, port, bound_port, queue_maxsize) -> libssh2.Listener\n\ \n\ Forwards a TCP connection through an SSH Session.\n\ \n\ @param host: remote host\n\ @type host: str\n\ @param port: remote port\n\ @type port: int\n\ @param bound_port: populated with the actual port on the remote host\n\ @type bound_port: int\n\ @param queue_maxsize: maximum number of pending connections\n\ @type int\n\ \n\ @return new libssh2.Listener instance on succes or None on failure\n\ @rtype libssh2.Listener"; static PyObject * PYLIBSSH2_Session_forward_listen(PYLIBSSH2_SESSION *self, PyObject *args) { char *host; int port; int queue_maxsize; int *bound_port; LIBSSH2_LISTENER *listener; if (!PyArg_ParseTuple(args, "siii:forward_listen", &host, &port, &bound_port, &queue_maxsize)) { return NULL; } MY_BEGIN_ALLOW_THREADS(self->tstate); listener = libssh2_channel_forward_listen_ex(self->session, host, port, bound_port, queue_maxsize); MY_END_ALLOW_THREADS(self->tstate); if (listener == NULL) { /* CLEAN: PYLIBSSH2_SESSION_TCP_CONNECT_ERROR_MSG */ PyErr_SetString(PYLIBSSH2_Error, "Unable to forward listen connection."); Py_INCREF(Py_None); return Py_None; } return (PyObject *)PYLIBSSH2_Listener_New(listener, 0); } /* }}} */ /* {{{ PYLIBSSH2_Session_last_error */ static char PYLIBSSH2_Session_last_error_doc[] = "\n\ last_error() -> (int, str)\n\ \n\ Returns the last error in tuple format (code, message).\n\ \n\ @return error tuple (int, str)\n\ @rtype tuple"; static PyObject * PYLIBSSH2_Session_last_error(PYLIBSSH2_SESSION *self, PyObject *args) { char *errmsg; int rc,want_buf=0; MY_BEGIN_ALLOW_THREADS(self->tstate); rc=libssh2_session_last_error(self->session, &errmsg, NULL, want_buf); MY_END_ALLOW_THREADS(self->tstate); return Py_BuildValue("(i,s)", rc, errmsg); } /* }}} */ /* {{{ PYLIBSSH2_Session_callback_set */ static char PYLIBSSH2_Session_callback_set_doc[] = "\n\ callback_set(cbtype, callback)\n\ \n\ Set (or reset) a callback function\n\ \n\ @param cbtype\n\ @param callback\n\ @return\n\ @rtype "; /* void x11_callback(LIBSSH2_SESSION *session, LIBSSH2_CHANNEL *channel, const char *shost, int sport, void **abstract) */ static PyObject *py_callback_func = NULL; static void stub_callback_func(LIBSSH2_SESSION *session, LIBSSH2_CHANNEL *channel, const char *shost, int sport, void **abstract) { int rc=0; PYLIBSSH2_SESSION *pysession; PYLIBSSH2_CHANNEL *pychannel; PyObject *pyabstract; /* Ensure current thread is ready to call Python C API */ PyGILState_STATE gstate; gstate = PyGILState_Ensure(); PyObject *arglist; PyObject *result = NULL; pysession = PyObject_New(PYLIBSSH2_SESSION, &PYLIBSSH2_Session_Type); pysession->session = session; pysession->opened = 1; pysession->dealloc = 0; pysession->tstate = NULL; Py_INCREF(pysession); pychannel = PyObject_New(PYLIBSSH2_CHANNEL, &PYLIBSSH2_Channel_Type); pychannel->channel = channel; pychannel->dealloc = 0; pychannel->tstate = NULL; Py_INCREF(pychannel); pyabstract = Py_None; Py_INCREF(pyabstract); arglist = Py_BuildValue("(OOsiO)", pysession, pychannel, shost, sport, pyabstract ); Py_INCREF(arglist); /* Performing Python callback with C API */ result = PyEval_CallObject(py_callback_func, arglist); if (result && PyInt_Check(result)) { rc = PyInt_AsLong(result); } /* Restore previous thread state and release acquired resources */ PyGILState_Release(gstate); Py_DECREF(pysession); Py_DECREF(pychannel); Py_DECREF(pyabstract); Py_DECREF(arglist); } static PyObject * PYLIBSSH2_Session_callback_set(PYLIBSSH2_SESSION *self, PyObject *args) { PyObject *result = NULL; /* type of callback to register see libssh2.h LIBSSH2_CALLBACK_* */ int cbtype; /* callback is callable Python Object */ PyObject *cb; if (PyArg_ParseTuple(args, "iO:callback_set", &cbtype, &cb)) { if (!PyCallable_Check(cb)) { PyErr_SetString(PyExc_TypeError, "parameter must be callable"); return NULL; } Py_XINCREF(cb); Py_XINCREF(py_callback_func); py_callback_func = cb; MY_BEGIN_ALLOW_THREADS(self->tstate); libssh2_session_callback_set(self->session, cbtype, stub_callback_func); MY_END_ALLOW_THREADS(self->tstate); Py_INCREF(Py_None); result = Py_None; } return result; } /* }}} */ /* {{{ PYLIBSSH2_Session_set_trace */ static char PYLIBSSH2_Session_set_trace_doc[] = "\n\ set_trace(bitmask)\n\ \n\ Set the trace level\n\ \n\ @param bitmask\n\ @return\n\ @rtype "; static PyObject * PYLIBSSH2_Session_set_trace(PYLIBSSH2_SESSION *self, PyObject *args) { int rc=0; int bitmask; if (!PyArg_ParseTuple(args, "i:set_trace", &bitmask)) { return NULL; } MY_BEGIN_ALLOW_THREADS(self->tstate); libssh2_trace(self->session, bitmask); MY_END_ALLOW_THREADS(self->tstate); return Py_BuildValue("i", rc); } /* }}} */ /* {{{ PYLIBSSH2_Session_methods[] * * ADD_METHOD(name) expands to a correct PyMethodDef declaration * { 'name', (PyCFunction)PYLIBSSH2_Session_name, METHOD_VARARGS } * for convenience * */ #define ADD_METHOD(name) \ { #name, (PyCFunction)PYLIBSSH2_Session_##name, METH_VARARGS, PYLIBSSH2_Session_##name##_doc } static PyMethodDef PYLIBSSH2_Session_methods[] = { ADD_METHOD(set_banner), ADD_METHOD(startup), ADD_METHOD(close), ADD_METHOD(userauth_authenticated), ADD_METHOD(hostkey_hash), ADD_METHOD(userauth_list), ADD_METHOD(session_methods), ADD_METHOD(userauth_password), ADD_METHOD(userauth_publickey_fromfile), ADD_METHOD(session_method_pref), ADD_METHOD(open_session), ADD_METHOD(scp_recv), ADD_METHOD(scp_send), ADD_METHOD(sftp_init), ADD_METHOD(direct_tcpip), ADD_METHOD(forward_listen), ADD_METHOD(last_error), ADD_METHOD(callback_set), ADD_METHOD(set_trace), { NULL, NULL } }; #undef ADD_METHOD /* }}} */ /* {{{ PYLIBSSH2_Session_New */ PYLIBSSH2_SESSION * PYLIBSSH2_Session_New(LIBSSH2_SESSION *session, int dealloc) { PYLIBSSH2_SESSION *self; self = PyObject_New(PYLIBSSH2_SESSION, &PYLIBSSH2_Session_Type); if (self == NULL) { return NULL; } self->session = session; self->dealloc = dealloc; self->opened = 0; self->socket = NULL; self->tstate = NULL; libssh2_banner_set(session, LIBSSH2_SSH_DEFAULT_BANNER " Python"); return self; } /* }}} */ /* {{{ PYLIBSSH2_Session_dealloc */ static void PYLIBSSH2_Session_dealloc(PYLIBSSH2_SESSION *self) { if (self->opened) { libssh2_session_disconnect(self->session, "end"); } if (self->dealloc) { libssh2_session_free(self->session); } Py_XDECREF(self->socket); self->socket = NULL; if (self) { PyObject_Del(self); } } /* }}} */ /* {{{ PYLIBSSH2_Session_getattr */ static PyObject * PYLIBSSH2_Session_getattr(PYLIBSSH2_SESSION *self, char *name) { return Py_FindMethod(PYLIBSSH2_Session_methods, (PyObject *)self, name); } /* }}} */ /* {{{ PYLIBSSH2_Session_Type * * see /usr/include/python2.5/object.h line 261 */ PyTypeObject PYLIBSSH2_Session_Type = { PyObject_HEAD_INIT(NULL) 0, /* ob_size */ "Session", /* tp_name */ sizeof(PYLIBSSH2_SESSION), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)PYLIBSSH2_Session_dealloc, /* tp_dealloc */ 0, /* tp_print */ (getattrfunc)PYLIBSSH2_Session_getattr, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ "Sesssion objects", /* tp_doc */ }; /* }}} */ /* {{{ init_libssh2_Session */ int init_libssh2_Session(PyObject *dict) { PYLIBSSH2_Session_Type.ob_type = &PyType_Type; Py_XINCREF(&PYLIBSSH2_Session_Type); PyDict_SetItemString(dict, "SessionType", (PyObject *)&PYLIBSSH2_Session_Type); return 1; } pylibssh2-1.0.0/src/util.h0000644000175000017500000000211211370760101013512 0ustar sbzsbz/*- * pylibssh2 - python bindings for libssh2 library * * Copyright (C) 2005 Keyphrene.com. * Copyright (C) 2010 Wallix Inc. * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation; either version 2.1 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _PYLIBSSH2_UTIL_H_ #define _PYLIBSSH2_UTIL_H_ #include #include /* * Retrieve files attribute for sftp connection. */ unsigned long get_flags(char *mode); #endif /* _PYLIBSSH2_UTIL_H_ */ pylibssh2-1.0.0/src/pylibssh2.c0000644000175000017500000001676411370757376014515 0ustar sbzsbz/*- * pylibssh2 - python bindings for libssh2 library * * Copyright (C) 2005 Keyphrene.com. * Copyright (C) 2010 Wallix Inc. * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation; either version 2.1 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #define PYLIBSSH2_MODULE #include "pylibssh2.h" /* {{{ PYLIBSSH2_doc */ PyDoc_STRVAR(PYLIBSSH2_doc, "Python binding for libssh2 library\n\ \n\ pylibssh2 is a C extension module around C library libssh2. It provide an\n\ easy way to manage SSH connections in Python.\n\ \n\ The high-level API start with creation of an L{Session} object with a\n\ socket-like object connected. Then create a L{Channel} with L{open_session}\n\ method on the session instance.\n\ \n"); /* }}} */ PyObject *PYLIBSSH2_Error; /* {{{ PYLIBSSH2_Session */ PyDoc_STRVAR(PYLIBSSH2_Session_doc, "\n\ This class provide SSH Session operations.\n\ \n\ close() -- closes the session\n\ direct_tcpip() -- tunnels a TCP connection\n\ forward_listen() -- forwards a TCP connection\n\ hostkey_hash() -- returns the computed digest of the remote host key\n\ last_error() -- returns the last error in tuple format\n\ open_session() -- allocates a new channel\n\ scp_recv() -- requests a remote file via SCP protocol\n\ scp_send() -- sends a remote file via SCP protocol\n\ session_method_pref() -- sets preferred methods to be negociated\n\ session_methods() -- returns a dictionnary with the currently active algorithms\n\ set_banner() -- sets the banner that will be sent to remote host\n\ sftp_init() -- opens an SFTP Channel\n\ startup() -- starts up the session from a socket\n\ userauth_authenticated() -- returns authentification status\n\ userauth_list() -- lists the authentification methods\n\ userauth_password() -- authenticates a session with credentials\n\ userauth_publickey_fromfile() -- authenticates a session with publickey\n\ "); static PyObject * PYLIBSSH2_Session(PyObject *self, PyObject *args) { int dealloc = 1; if (!PyArg_ParseTuple(args, "|i:Session", &dealloc)) { return NULL; } return (PyObject *)PYLIBSSH2_Session_New(libssh2_session_init(), dealloc); } /* }}} */ /* {{{ PYLIBSSH2_Channel */ PyDoc_STRVAR(PYLIBSSH2_Channel_doc, "\n\ This class provide SSH Channel operations.\n\ \n\ close() -- closes the active channel\n\ eof() -- checks if the remote host has sent an EOF status\n\ execute() -- executes command of the channel\n\ exit_status() -- gets the exit code\n\ flush() -- flushs the read buffer\n\ poll() -- polls for activity on the channel\n\ poll_read() -- checks if data is available on the channel\n\ pty() -- requests a pty\n\ pty_resize() -- requests a pty resize\n\ read() -- reads bytes on the channel\n\ send_eof() -- sends EOF status\n\ setblocking() -- sets blocking mode\n\ setenv() -- sets envrionment variable\n\ shell() -- requests a shell\n\ window_read() -- checks the status of the read window\n\ write() -- writes data on a channel\n\ x11_req() -- requests an X11 Forwarding channel\n\ "); static PyObject * PYLIBSSH2_Channel(PyObject *self, PyObject *args) { PYLIBSSH2_SESSION *session; int dealloc = 1; if (!PyArg_ParseTuple(args, "O|i:Channel", &session, &dealloc)) { return NULL; } return (PyObject *)PYLIBSSH2_Channel_New(libssh2_channel_open_session( session->session), dealloc); } /* }}} */ /* {{{ PYLIBSSH2_Sftp */ static char PYLIBSSH2_Sftp_doc[] = "\n\ \n\ Arguments:\n\ \n\ Returns:\n\ "; static PyObject * PYLIBSSH2_Sftp(PyObject *self, PyObject *args) { PYLIBSSH2_SESSION *session; int dealloc = 1; if (!PyArg_ParseTuple(args, "O|i:Sftp", &session, &dealloc)) { return NULL; } return (PyObject *)PYLIBSSH2_Sftp_New(libssh2_sftp_init( session->session), dealloc); } /* }}} */ /* {{{ PYLIBSSH2_methods[] */ static PyMethodDef PYLIBSSH2_methods[] = { { "Session", (PyCFunction)PYLIBSSH2_Session, METH_VARARGS, PYLIBSSH2_Session_doc }, { "Channel", (PyCFunction)PYLIBSSH2_Channel, METH_VARARGS, PYLIBSSH2_Channel_doc }, { "Sftp", (PyCFunction)PYLIBSSH2_Sftp, METH_VARARGS, PYLIBSSH2_Sftp_doc }, { NULL, NULL } }; /* }}} */ /* {{{ init_libssh2 */ PyMODINIT_FUNC init_libssh2(void) { static void *PYLIBSSH2_API[PYLIBSSH2_API_pointers]; PyObject *c_api_object; PyObject *module, *dict; module = Py_InitModule3( PYLIBSSH2_MODULE_NAME, PYLIBSSH2_methods, PYLIBSSH2_doc ); if (module == NULL) { return; } PYLIBSSH2_API[PYLIBSSH2_Session_New_NUM] = (void *) PYLIBSSH2_Session_New; PYLIBSSH2_API[PYLIBSSH2_Channel_New_NUM] = (void *) PYLIBSSH2_Channel_New; PYLIBSSH2_API[PYLIBSSH2_Sftp_New_NUM] = (void *) PYLIBSSH2_Sftp_New; PYLIBSSH2_API[PYLIBSSH2_Sftphandle_New_NUM] = (void *) PYLIBSSH2_Sftphandle_New; c_api_object = PyCObject_FromVoidPtr((void *)PYLIBSSH2_API, NULL); if (c_api_object != NULL) { PyModule_AddObject(module, "_C_API", c_api_object); } PYLIBSSH2_Error = PyErr_NewException( PYLIBSSH2_MODULE_NAME".Error", NULL, NULL ); if (PYLIBSSH2_Error == NULL) { goto error; } if (PyModule_AddObject(module, "Error", PYLIBSSH2_Error) != 0) { goto error; } PyModule_AddIntConstant(module, "FINGERPRINT_MD5", 0x0000); PyModule_AddIntConstant(module, "FINGERPRINT_SHA1", 0x0001); PyModule_AddIntConstant(module, "FINGERPRINT_HEX", 0x0000); PyModule_AddIntConstant(module, "FINGERPRINT_RAW", 0x0002); PyModule_AddIntConstant(module, "METHOD_KEX", LIBSSH2_METHOD_KEX); PyModule_AddIntConstant(module, "METHOD_HOSTKEY", LIBSSH2_METHOD_HOSTKEY); PyModule_AddIntConstant(module, "METHOD_CRYPT_CS", LIBSSH2_METHOD_CRYPT_CS); PyModule_AddIntConstant(module, "METHOD_CRYPT_SC", LIBSSH2_METHOD_CRYPT_SC); PyModule_AddIntConstant(module, "METHOD_MAC_CS", LIBSSH2_METHOD_MAC_CS); PyModule_AddIntConstant(module, "METHOD_MAC_SC", LIBSSH2_METHOD_MAC_SC); PyModule_AddIntConstant(module, "METHOD_COMP_CS", LIBSSH2_METHOD_COMP_CS); PyModule_AddIntConstant(module, "METHOD_COMP_SC", LIBSSH2_METHOD_COMP_SC); PyModule_AddIntConstant(module, "SFTP_SYMLINK", LIBSSH2_SFTP_SYMLINK); PyModule_AddIntConstant(module, "SFTP_READLINK", LIBSSH2_SFTP_READLINK); PyModule_AddIntConstant(module, "SFTP_REALPATH", LIBSSH2_SFTP_REALPATH); PyModule_AddIntConstant(module, "SFTP_STAT", LIBSSH2_SFTP_STAT); PyModule_AddIntConstant(module, "SFTP_LSTAT", LIBSSH2_SFTP_LSTAT); PyModule_AddStringConstant(module, "DEFAULT_BANNER", LIBSSH2_SSH_DEFAULT_BANNER); PyModule_AddStringConstant(module, "LIBSSH2_VERSION", LIBSSH2_VERSION); dict = PyModule_GetDict(module); if (!init_libssh2_Session(dict)) { goto error; } if (!init_libssh2_Channel(dict)) { goto error; } if (!init_libssh2_Sftp(dict)) { goto error; } if (!init_libssh2_Sftphandle(dict)) { goto error; } error: ; } /* }}} */ pylibssh2-1.0.0/src/channel.h0000644000175000017500000000245111370757636014176 0ustar sbzsbz/*- * pylibssh2 - python bindings for libssh2 library * * Copyright (C) 2005 Keyphrene.com. * Copyright (C) 2010 Wallix Inc. * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation; either version 2.1 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _PYLIBSSH2_CHANNEL_H_ #define _PYLIBSSH2_CHANNEL_H_ #include #include extern int init_libssh2_Channel(PyObject *); extern PyTypeObject PYLIBSSH2_Channel_Type; #define PYLIBSSH2_Channel_Check(v) ((v)->ob_type == &PYLIBSSH2_Channel_Type) typedef struct { PyObject_HEAD LIBSSH2_CHANNEL *channel; PyThreadState *tstate; int dealloc; } PYLIBSSH2_CHANNEL; #endif /* _PYLIBSSH2_CHANNEL_H_ */ pylibssh2-1.0.0/src/listener.c0000644000175000017500000001156411370757341014404 0ustar sbzsbz/*- * pylibssh2 - python bindings for libssh2 library * * Copyright (C) 2005 Keyphrene.com. * Copyright (C) 2010 Wallix Inc. * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation; either version 2.1 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #define PYLIBSSH2_MODULE #include "pylibssh2.h" /* {{{ PYLIBSSH2_Listener_accept */ static char PYLIBSSH2_Listener_accept_doc[] = "\n\ \n\ Arguments:\n\ \n\ Returns:\n\ "; static PyObject * PYLIBSSH2_Listener_accept(PYLIBSSH2_LISTENER *self, PyObject *args) { LIBSSH2_CHANNEL *channel; MY_BEGIN_ALLOW_THREADS(self->tstate); channel = libssh2_channel_forward_accept(self->listener); MY_END_ALLOW_THREADS(self->tstate); if (channel == NULL) { PyErr_SetString(PYLIBSSH2_Error, "Unable to accept listener on channel."); Py_INCREF(Py_None); return Py_None; } return (PyObject *)PYLIBSSH2_Channel_New(channel, 1); } /* }}} */ /* {{{ PYLIBSSH2_Listener_cancel */ static char PYLIBSSH2_Listener_cancel_doc[] = "\n\ \n\ Arguments:\n\ \n\ Returns:\n\ "; static PyObject * PYLIBSSH2_Listener_cancel(PYLIBSSH2_LISTENER *self, PyObject *args) { int rc; MY_BEGIN_ALLOW_THREADS(self->tstate); rc = libssh2_channel_forward_cancel(self->listener); MY_END_ALLOW_THREADS(self->tstate); return Py_BuildValue("i", rc); } /* }}} */ /* {{{ PYLIBSSH2_Listener_methods[] * * ADD_METHOD(name) expands to a correct PyMethodDef declaration * { 'name', (PyCFunction)PYLIBSSH2_Listener_name, METHOD_VARARGS } * for convenience */ #define ADD_METHOD(name) \ { #name, (PyCFunction)PYLIBSSH2_Listener_##name, METH_VARARGS, PYLIBSSH2_Listener_##name##_doc } struct PyMethodDef PYLIBSSH2_Listener_methods[] = { ADD_METHOD(accept), ADD_METHOD(cancel), { NULL, NULL } }; #undef ADD_METHOD /* }}} */ /* {{{ PYLIBSSH2_Listener_New */ PYLIBSSH2_LISTENER * PYLIBSSH2_Listener_New(LIBSSH2_LISTENER *listener, int dealloc) { PYLIBSSH2_LISTENER *self; self = PyObject_New(PYLIBSSH2_LISTENER, &PYLIBSSH2_Listener_Type); if (self == NULL) { return NULL; } self->listener = listener; self->dealloc = dealloc; self->tstate = NULL; return self; } /* }}} */ /* {{{ PYLIBSSH2_Listener_dealloc */ static void PYLIBSSH2_Listener_dealloc(PYLIBSSH2_LISTENER *self) { if (self) { PyObject_Del(self); } } /* }}} */ /* {{{ PYLIBSSH2_Listener_getattr */ static PyObject * PYLIBSSH2_Listener_getattr(PYLIBSSH2_LISTENER *self, char *name) { return Py_FindMethod(PYLIBSSH2_Listener_methods, (PyObject *) self, name); } /* }}} */ /* {{{ PYLIBSSH2_Listener_Type * * see /usr/include/python2.5/object.h line 261 */ PyTypeObject PYLIBSSH2_Listener_Type = { PyObject_HEAD_INIT(NULL) 0, /* ob_size */ "Listener", /* tp_name */ sizeof(PYLIBSSH2_LISTENER), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)PYLIBSSH2_Listener_dealloc, /* tp_dealloc */ 0, /* tp_print */ (getattrfunc)PYLIBSSH2_Listener_getattr, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ "Listener objects", /* tp_doc */ }; /* }}} */ /* {{{ init_libssh2_Listener */ int init_libssh2_Listener(PyObject *dict) { PYLIBSSH2_Listener_Type.ob_type = &PyType_Type; Py_XINCREF(&PYLIBSSH2_Listener_Type); PyDict_SetItemString(dict, "ListenerType", (PyObject *)&PYLIBSSH2_Listener_Type); return 1; } /* }}} */ pylibssh2-1.0.0/src/util.c0000644000175000017500000000276011370757572013540 0ustar sbzsbz/*- * pylibssh2 - python bindings for libssh2 library * * Copyright (C) 2005 Keyphrene.com. * Copyright (C) 2010 Wallix Inc. * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation; either version 2.1 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "util.h" /* {{{ get_flags */ unsigned long get_flags(char *mode) { int i=0; unsigned long f=0; struct { char mode; unsigned long flags; } modeflags[5] = { {'a', LIBSSH2_FXF_APPEND }, {'w', LIBSSH2_FXF_WRITE | LIBSSH2_FXF_TRUNC | LIBSSH2_FXF_CREAT }, {'r', LIBSSH2_FXF_READ }, {'+', LIBSSH2_FXF_READ | LIBSSH2_FXF_WRITE }, {'x', LIBSSH2_FXF_WRITE | LIBSSH2_FXF_TRUNC | LIBSSH2_FXF_EXCL | LIBSSH2_FXF_CREAT } }; for(i=0; i<5; i++) { if(strchr(mode, modeflags[i].mode)) { f |= modeflags[i].flags; } } return f; } /* }}} */ pylibssh2-1.0.0/src/pylibssh2.h0000644000175000017500000001110511370757726014501 0ustar sbzsbz/*- * pylibssh2 - python bindings for libssh2 library * * Copyright (C) 2005 Keyphrene.com. * Copyright (C) 2010 Wallix Inc. * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation; either version 2.1 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _PYLIBSSH2_SSH2_H_ #define _PYLIBSSH2_SSH2_H_ #include #include #include #include #include "channel.h" #include "listener.h" #include "sftp.h" #include "sftphandle.h" #include "session.h" #include "util.h" /* pylibssh2 module version */ #define PYLIBSSH2_VERSION MAJOR_VERSION"."MINOR_VERSION"."PATCH_VERSION /* Python module name */ #define PYLIBSSH2_MODULE_NAME "_libssh2" /* Python module's Error */ extern PyObject *PYLIBSSH2_Error; /* Thread support * * WITH_THREAD is defined in /usr/include/python2.{4,5,6}/pyconfig.h * * */ #ifdef WITH_THREAD # define MY_BEGIN_ALLOW_THREADS(st) \ { st = PyEval_SaveThread(); } # define MY_END_ALLOW_THREADS(st) \ { PyEval_RestoreThread(st);} #else # define MY_BEGIN_ALLOW_THREADS(st) # define MY_END_ALLOW_THREADS(st) { st = NULL; } #endif #ifdef exception_from_error_queue # undef exception_from_error_queue #endif #define exception_from_error_queue() do { \ PyObject *errlist = error_queue_to_list(); \ PyErr_SetObject(PYLIBSSH2_Error, errlist); \ Py_DECREF(errlist); \ } while (0) #define PYLIBSSH2_Session_New_NUM 0 #define PYLIBSSH2_Session_New_RETURN PYLIBSSH2_SESSION * #define PYLIBSSH2_Session_New_PROTO (LIBSSH2_SESSION *, int) #define PYLIBSSH2_Channel_New_NUM 1 #define PYLIBSSH2_Channel_New_RETURN PYLIBSSH2_CHANNEL * #define PYLIBSSH2_Channel_New_PROTO (LIBSSH2_CHANNEL *, int) #define PYLIBSSH2_Sftp_New_NUM 2 #define PYLIBSSH2_Sftp_New_RETURN PYLIBSSH2_SFTP * #define PYLIBSSH2_Sftp_New_PROTO (LIBSSH2_SFTP *, int) #define PYLIBSSH2_Sftphandle_New_NUM 3 #define PYLIBSSH2_Sftphandle_New_RETURN PYLIBSSH2_SFTPHANDLE * #define PYLIBSSH2_Sftphandle_New_PROTO (LIBSSH2_SFTP_HANDLE *, int) #define PYLIBSSH2_Listener_New_NUM 4 #define PYLIBSSH2_Listener_New_RETURN PYLIBSSH2_LISTENER * #define PYLIBSSH2_Listener_New_PROTO (LIBSSH2_LISTENER *, int) #define PYLIBSSH2_API_pointers 5 #ifdef PYLIBSSH2_MODULE extern PYLIBSSH2_Session_New_RETURN PYLIBSSH2_Session_New PYLIBSSH2_Session_New_PROTO; extern PYLIBSSH2_Channel_New_RETURN PYLIBSSH2_Channel_New PYLIBSSH2_Channel_New_PROTO; extern PYLIBSSH2_Sftp_New_RETURN PYLIBSSH2_Sftp_New PYLIBSSH2_Sftp_New_PROTO; extern PYLIBSSH2_Sftphandle_New_RETURN PYLIBSSH2_Sftphandle_New PYLIBSSH2_Sftphandle_New_PROTO; extern PYLIBSSH2_Listener_New_RETURN PYLIBSSH2_Listener_New PYLIBSSH2_Listener_New_PROTO; #else extern void **PYLIBSSH2_API; /*#define PYLIBSSH2_Session_New (*(PYLIBSSH2_Session_New_RETURN (*)PYLIBSSH2_Session_New_PROTO) PYLIBSSH2_API[PYLIBSSH2_Session_New_NUM]) #define PYLIBSSH2_Channel_New (*(PYLIBSSH2_Channel_New_RETURN (*)PYLIBSSH2_Channel_New_PROTO) PYLIBSSH2_API[PYLIBSSH2_Channel_New_NUM]) #define PYLIBSSH2_Sftp_New (*(PYLIBSSH2_Sftp_New_RETURN (*)PYLIBSSH2_Sftp_New_PROTO) PYLIBSSH2_API[PYLIBSSH2_Sftp_New_NUM]) #define PYLIBSSH2_Sftphandle_New (*(PYLIBSSH2_Sftphandle_New_RETURN (*)PYLIBSSH2_Sftphandle_New_PROTO) PYLIBSSH2_API[PYLIBSSH2_Sftphandle_New_NUM]) #define PYLIBSSH2_Listener_New (*(PYLIBSSH2_Listener_New_RETURN (*)PYLIBSSH2_Listener_New_PROTO) PYLIBSSH2_API[PYLIBSSH2_Listener_New_NUM])*/ #define import_PYLIBSSH2() \ { \ PyObject *PYLIBSSH2_module = PyImport_ImportModule(PYLIBSSH2_MODULE_NAME); \ if (PYLIBSSH2_module != NULL) { \ PyObject *PYLIBSSH2_dict, *PYLIBSSH2_api_object; \ PYLIBSSH2_dict = PyModule_GetDict(PYLIBSSH2_module); \ PYLIBSSH2_api_object = PyDict_GetItemString(PYLIBSSH2_dict, "_C_API"); \ if (PyCObject_Check(PYLIBSSH2_api_object)) { \ PYLIBSSH2_API = (void **)PyCObject_AsVoidPtr(PYLIBSSH2_api_object); \ } \ } \ } #endif /* PYLIBSSH2_MODULE */ #endif /* _PYLIBSSH2_SSH2_H_ */ pylibssh2-1.0.0/src/sftp.h0000644000175000017500000000241611370760007013525 0ustar sbzsbz/*- * pylibssh2 - python bindings for libssh2 library * * Copyright (C) 2005 Keyphrene.com. * Copyright (C) 2010 Wallix Inc. * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation; either version 2.1 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _PYLIBSSH2_SFTP_H_ #define _PYLIBSSH2_SFTP_H_ #include #include extern int init_libssh2_Sftp(PyObject *); extern PyTypeObject PYLIBSSH2_Sftp_Type; #define PYLIBSSH2_Sftp_Check(v) ((v)->ob_type == &PYLIBSSH2_Sftp_Type) typedef struct { PyObject_HEAD LIBSSH2_SFTP *sftp; PyThreadState *tstate; int dealloc; } PYLIBSSH2_SFTP; #endif /* _PYLIBSSH2_SFTP_H_ */ pylibssh2-1.0.0/src/listener.h0000644000175000017500000000246511370757674014422 0ustar sbzsbz/*- * pylibssh2 - python bindings for libssh2 library * * Copyright (C) 2005 Keyphrene.com. * Copyright (C) 2010 Wallix Inc. * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation; either version 2.1 of the License, or (at your * option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _PYLIBSSH2_LISTENER_H_ #define _PYLIBSSH2_LISTENER_H_ #include #include extern int init_libssh2_Listener(PyObject *); extern PyTypeObject PYLIBSSH2_Listener_Type; #define PYLIBSSH2_Listener_Check(v) ((v)->ob_type == &PYLIBSSH2_Listener_Type) typedef struct { PyObject_HEAD LIBSSH2_LISTENER *listener; PyThreadState *tstate; int dealloc; } PYLIBSSH2_LISTENER; #endif /* _PYLIBSSH2_LISTENER_H_ */ pylibssh2-1.0.0/COPYING0000644000175000017500000006354011370002412012636 0ustar sbzsbz GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. ^L Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. ^L GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. ^L Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. ^L 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. ^L 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. ^L 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. ^L 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS ^L How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 2005 Keyphrene - Vincent Jaulin This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it!