wallix / pylibssh2 Goto Github PK
View Code? Open in Web Editor NEWpython bindings for libssh2 library
Home Page: http://www.wallix.org/pylibssh2-project/
License: GNU Lesser General Public License v2.1
python bindings for libssh2 library
Home Page: http://www.wallix.org/pylibssh2-project/
License: GNU Lesser General Public License v2.1
Passing additional integer to channel.read was just fine in the original version of library.
Fingerprint string at the Python side contains random bytes.
Patch below.
From 5700e11605f800cd7b257c8d7903178a260fe2c2 Mon Sep 17 00:00:00 2001
From: Marcin Szewczyk <[email protected]>
Date: Tue, 28 Jun 2011 22:16:47 +0200
Subject: [PATCH 2/2] Truncate hash to an appropriate length.
---
src/session.c | 20 +++++++++++++++++++-
1 files changed, 19 insertions(+), 1 deletions(-)
diff --git a/src/session.c b/src/session.c
index 81913b5..ccb6977 100644
--- a/src/session.c
+++ b/src/session.c
@@ -205,6 +205,8 @@ PYLIBSSH2_Session_hostkey_hash(PYLIBSSH2_SESSION *self, PyObject *args)
{
int hashtype = LIBSSH2_HOSTKEY_HASH_MD5;
const char *hash;
+ char buff[20+1];
+ size_t len;
if (!PyArg_ParseTuple(args, "|i:hostkey_hash", &hashtype)) {
return NULL;
@@ -219,7 +221,21 @@ PYLIBSSH2_Session_hostkey_hash(PYLIBSSH2_SESSION *self, PyObject *args)
return Py_None;
}
- return PyString_FromString(hash);
+ switch(hashtype) {
+ case LIBSSH2_HOSTKEY_HASH_MD5:
+ len = 16;
+ break;
+ case LIBSSH2_HOSTKEY_HASH_SHA1:
+ len = 20;
+ break;
+ default:
+ len = 0;
+ }
+
+ memcpy(buff, hash, len);
+ buff[len] = '\0';
+
+ return PyString_FromString(buff);
}
/* }}} */
@@ -915,3 +931,5 @@ init_libssh2_Session(PyObject *dict)
return 1;
}
+
+/* vim: set sw=4: */
--
1.7.5.4
Patch below...
From edd1a5a1aa904491cdd80d301c083e70a7e05cee Mon Sep 17 00:00:00 2001
From: Marcin Szewczyk <[email protected]>
Date: Tue, 28 Jun 2011 22:13:39 +0200
Subject: [PATCH 1/2] Return values as declared. Added _session in
session_methods.
---
libssh2/session.py | 14 +++++++-------
1 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/libssh2/session.py b/libssh2/session.py
index afed5e3..2b85dc5 100644
--- a/libssh2/session.py
+++ b/libssh2/session.py
@@ -62,7 +62,7 @@ class Session(object):
@return: 0 on success or negative on failure
@rtype: int
"""
- self._session.close(reason)
+ return self._session.close(reason)
def direct_tcpip(self, host, port, shost, sport):
"""
@@ -183,7 +183,7 @@ class Session(object):
@return: 0 on success or negative on failure
@rtype: int
"""
- self._session.session_methods(method_type, pref)
+ return self._session.session_methods(method_type, pref)
def session_methods(self):
"""
@@ -193,7 +193,7 @@ class Session(object):
@return: dictionnary with actual method negociated
@rtype: dict
"""
- return self.session_methods()
+ return self._session.session_methods()
def set_banner(self, banner=_libssh2.DEFAULT_BANNER):
"""
@@ -206,7 +206,7 @@ class Session(object):
@return: 0 on success or negative on failure
@rtype: int
"""
- self._session.set_banner(banner)
+ return self._session.set_banner(banner)
def sftp_init(self):
"""
@@ -227,7 +227,7 @@ class Session(object):
@return: 0 on success or negative on failure
@rtype: int
"""
- self._session.startup(sock)
+ return self._session.startup(sock)
def userauth_authenticated(self):
"""
@@ -249,7 +249,7 @@ class Session(object):
methods
@rtype: str
"""
- self._session.userauth_list(username)
+ return self._session.userauth_list(username)
def userauth_password(self, username, password):
"""
@@ -263,7 +263,7 @@ class Session(object):
@return: 0 on success or negative on failure
@rtype: int
"""
- self._session.userauth_password(username, password)
+ return self._session.userauth_password(username, password)
def userauth_publickey_fromfile(
self, username, publickey, privatekey, passphrase
--
1.7.5.4
When I use, per the documentation:
session.userauth_publickey_fromfile(
"stephane", os.path.expanduser('/.ssh/id_rsa.pub'), os.path.expanduser('/.ssh/id_rsa'), "secretphrase")
I get:
Traceback (most recent call last):
File "test.py", line 12, in
"stephane", os.path.expanduser('/.ssh/id_rsa.pub'), os.path.expanduser('/.ssh/id_rsa'), "secretphrase")
File "/usr/lib/pymodules/python2.6/libssh2/session.py", line 287, in userauth_publickey_fromfile
raise NotImplementedError()
NotImplementedError
Debian "squeeze" (the stable version) :
Python libssh2 1.0.0
Python 2.6.6 (r266:84292, Dec 27 2010, 00:02:40)
[GCC 4.4.5] on linux2
When i try to use userauth_agent method:
Error: Authentification by public key failed: No authorized key found in ssh-agent! (failed closing the agent socket)
<Greenlet at 0xd37910: runcmd('115.238.73.226')> failed with Error
But:
in the securecrt ssh forwarding is ok
Code:
ret = self.session.userauth_agent('root')
while ret == self.LIBSSH2_ERROR_EAGAIN:
_wait_select(self.session, self.sock)
ret = self.session.userauth_agent('root')
Thank you for your share!
Traceback (most recent call last):
File "test.py", line 94, in <module>
libssh2_upload()
File "test.py", line 92, in libssh2_upload
chan.close()
File "/usr/local/lib/python2.6/dist-packages/pylibssh2-1.0.1-py2.6-linux-x86_64.egg/libssh2/channel.py", line 53, in close
return self._channel.close()
_libssh2.Error: Unable to close the channel.
Code being used;
def libssh2_upload():
import libssh2
import tempfile
import os
import socket
host = "xxx"
user = "xxx"
file_to_send = "/tmp/lol"
fd, fpath = tempfile.mkstemp()
fh = os.fdopen(fd, 'w')
fh.write(key)
fh.close()
fd2, fpath2 = tempfile.mkstemp()
fh2 = os.fdopen(fd2, 'w')
fh2.write(pubkey)
fh2.close()
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host, 22))
sock.setblocking(1)
session = libssh2.Session()
session.set_banner()
session.startup(sock)
session.userauth_publickey_fromfile(user, fpath2, fpath, "")
fsize = os.path.getsize(file_to_send)
chan = session.scp_send(file_to_send, 0700, fsize)
sf = open(file_to_send, 'rb')
while True:
c = sf.read(512)
if not c:
break
chan.write(c)
chan.close()
libssh2_upload()
Also, the file is corrupt on the other side (md5 mismatch) and the size is very different.
Any ideas?
Thanks
I am building non-blocking sftp support for pylibssh2.
It works just fine except for one thing. When I do a sftp.open or sftp.opendir in non blocking mode, I have to call libssh2_session_last_error to see if this was a EGAIN or some genuine error.
I was not able to access session object from the sftp object in the sftp handle.
I have however worked around this problem by keeping pointer to session object in sftp handle.
Now on my local, sftp works beautifully in non blocking mode.
This is what the code for opendir looks like:
Py_BEGIN_ALLOW_THREADS handle = libssh2_sftp_opendir(self->sftp, path); Py_END_ALLOW_THREADS if (handle == NULL) { if (libssh2_session_last_error(self->session, NULL, NULL, 0) == LIBSSH2_ERROR_EAGAIN){ return Py_BuildValue(""); } else{ /* CLEAN: PYLIBSSH2_SFTPHANDLE_CANT_OPENDIR_MSG */ PyErr_SetString(PYLIBSSH2_Error, "Unable to open sftp directory."); return NULL; } }
Before I send in a merge request, I wanted to make sure if this approach is okay, or if there are other (better) ways to do this.
Hello,
I've used this lib on my Ubuntu -- all worked good, but I can't install on my new mac. There are compilation errors while installing.
clang -fno-strict-aliasing -fno-common -dynamic -g -Os -pipe -fno-common -fno-strict-aliasing -fwrapv -mno-fused-madd -DENABLE_DTRACE -DMACOSX -DNDEBUG -Wall -Wstrict-prototypes -Wshorten-64-to-32 -DNDEBUG -g -Os -Wall -Wstrict-prototypes -DENABLE_DTRACE -arch i386 -arch x86_64 -pipe -DMAJOR_VERSION=2 -DMINOR_VERSION=0 -DPATCH_VERSION=2 -I/opt/local/include/ -I/System/Library/Frameworks/Python.framework/Versions/2.6/include/python2.6 -c src/listener.c -o build/temp.macosx-10.8-intel-2.6/src/listener.o clang: warning: argument unused during compilation: '-mno-fused-madd' clang -fno-strict-aliasing -fno-common -dynamic -g -Os -pipe -fno-common -fno-strict-aliasing -fwrapv -mno-fused-madd -DENABLE_DTRACE -DMACOSX -DNDEBUG -Wall -Wstrict-prototypes -Wshorten-64-to-32 -DNDEBUG -g -Os -Wall -Wstrict-prototypes -DENABLE_DTRACE -arch i386 -arch x86_64 -pipe -DMAJOR_VERSION=2 -DMINOR_VERSION=0 -DPATCH_VERSION=2 -I/opt/local/include/ -I/System/Library/Frameworks/Python.framework/Versions/2.6/include/python2.6 -c src/pylibssh2.c -o build/temp.macosx-10.8-intel-2.6/src/pylibssh2.o clang: warning: argument unused during compilation: '-mno-fused-madd' src/pylibssh2.c:229:15: error: no member named 'st_atim' in 'struct stat' attr->st_atim.tv_sec + attr->st_mtim.tv_nsec * 0.000000001)); ~~~~ ^ src/pylibssh2.c:229:38: error: no member named 'st_mtim' in 'struct stat' attr->st_atim.tv_sec + attr->st_mtim.tv_nsec * 0.000000001)); ~~~~ ^ src/pylibssh2.c:231:15: error: no member named 'st_mtim' in 'struct stat' attr->st_mtim.tv_sec + attr->st_mtim.tv_nsec * 0.000000001)); ~~~~ ^ src/pylibssh2.c:231:38: error: no member named 'st_mtim' in 'struct stat' attr->st_mtim.tv_sec + attr->st_mtim.tv_nsec * 0.000000001)); ~~~~ ^ 4 errors generated. error: command 'clang' failed with exit status 1
I tried to implement local and remote port forwarding (ssh -L and -R option), using the direct_tcpip and forward_listen channel objects, but I did not succeed. If someone could post a hint or even a code example and add it to the examples section, I would be very grateful. Thank you!
Hi!
i got that error with old mikrotik
> system routerboard print
routerboard: yes
model: "SXT 5HnD"
serial-number: "292901552E3D"
current-firmware: "2.32"
upgrade-firmware: "2.32"
the code is
class SSHIOStream(IOStream):
SSH_KEY_PREFIX = os.path.join("var", "etc", "ssh")
def __init__(self, sock, cli, *args, **kwargs):
super(SSHIOStream, self).__init__(sock, *args, **kwargs)
self.cli = cli
self.script = self.cli.script
self.logger = cli.logger
self.session = libssh2.Session()
self.channel = None
@tornado.gen.coroutine
def startup(self):
"""
SSH session startup
"""
user = self.script.credentials["user"]
self.logger.debug("Startup ssh session")
try:
self.session.set_trace(libssh2.LIBSSH2_TRACE_SOCKET | libssh2.LIBSSH2_TRACE_TRANS)
self.session.session_method_pref(20,"diffie-hellman-group1-sha1")
self.session.startup(self.socket)
host_hash = self.session.hostkey_hash(2) # SHA1
self.logger.debug("Connected. Host fingerprint is %s",
host_hash.encode("hex"))
auth_methods = self.session.userauth_list(user).split(",")
self.logger.debug("Supported authentication methods: %s",
", ".join(auth_methods))
# Try to authenticate
authenticated = False
for method in auth_methods:
ah = getattr(self, "auth_%s" % method, None)
if ah:
authenticated |= ah()
if authenticated:
break
if authenticated:
self.logger.debug("User is authenticated")
else:
self.logger.error("Failed to authenticate user '%s'", user)
raise self.cli.CLIError("Failed to log in")
self.logger.debug("Open channel")
self.channel = self.session.open_session()
self.channel.pty("xterm")
self.channel.shell()
self.channel.setblocking(0)
except _libssh2.Error, why:
raise self.cli.CLIError("SSH Error: %s" % why)
i got error on
self.session.startup(self.socket)
because mikrotik wants old style packet. so in console i got
Protocol error: expected packet type 30, got 34
i am using python 2.7 and libssh2 from master branch and Debian 8.4
# dpkg -l | grep libssh2
ii libssh2-1:amd64 1.4.3-4.1+deb8u1 amd64 SSH2 client-side library
ii libssh2-1-dev:amd64 1.4.3-4.1+deb8u1 amd64 SSH2 client-side library (development headers)
Since I had some trouble getting scp working, I'd thought I'd better share my examples.
In the regular examples there is only a scp_update, which doesn't work, not on OpenBSD at least, and getting a scp_download working was even a bit more awkward. (it now looks so simple though, but I didn't want to use sftp at first...)
Because no EOF is set when downloading, I had to keep an eye on filesize. In the C examples of the libssh2 package, that is the way it is done anyhow.
One would expect that after reading the last block of a file the next read would return "", which could be used to detect the eof. But it doesn't. It just hangs somewhere in a waiting loop, and I couldn't determine how to prevent that.
channel.close() will close the channel, but might generate an error. This is caused by a bug in channel.c line 46, which schould be: if (rc && rc != LIBSSH2_ERROR_EAGAIN)
To upload a file I've rewritten the send routine in the scp_upload.py example as follows. Reading and writing blocks instead of lines.
import os
...
def send(self, remote_path, mode=0644):
file_size = os.path.getsize(remote_path)
channel = self.session.scp_send(remote_path, mode, file_size)
f=open(remote_path, "rb")
send = 0
while True:
data = f.read(1024)
channel.write(data)
send = send + len(data)
if send >= file_size:
break
f.close()
channel.close()
To download a file I used the same scp_upload.py example with putting in a receive routine, reading blocks over the channel.
The last block get an extra 0 - eof byte, increasing the filesize, so I strip that (checking if it really is a 0, which can probably be omitted)
The only problem now is to determine the filesize. In C, it comes with the scp_recv call, but pylibssh2 puts a NULL in the fileinfo field :-(. So it has to be done with sftp:
import os
def _prepare_sock(self):
...
self.sftp = self.session._session.sftp_init()
...
def receive(self, remote_path, mode=0644):
file_size = self.sftp.get_stat(remote_path)[0]
channel = self.session.scp_recv(remote_path)
f=open(remote_path, "wb")
got = 0
while True:
data = channel.read(1024)
got = got + len(data)
if got > file_size:
if (data[-1:]=="\0"): # probably not needed
f.write(data[:-1])
break
else:
f.write(data)
f.close()
channel.close()
os.chmod(remote_path,mode)
...
...
myscp.receive(sys.argv[4])
It would be nice if the regular examples can be updated with these.
Regards
Please, update the PyPi. We really miss the functionality introduced in the latest version.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.