On 04.01.2012 00:47, Peter Krempa wrote: > This patch enables virNetSocket to be used as an ssh client when > properly configured. > > Fucntion virNetSocketNewConnectLibSSH() is added, that takes all needed > parameters and creates a libssh2 session context and performs steps > needed to open the connection. > > * src/libvirt_private.syms: Export the new symbol. > * src/rpc/virnetsocket.c: Add virNetSocketNewConnectLibSSH > * src/rpc/virnetsocket.h: Add header. > --- > src/libvirt_private.syms | 1 + > src/rpc/virnetsocket.c | 136 +++++++++++++++++++++++++++++++++++++++++++++- > src/rpc/virnetsocket.h | 12 ++++ > 3 files changed, 148 insertions(+), 1 deletions(-) > > diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms > index ac2c52e..0c6066a 100644 > --- a/src/libvirt_private.syms > +++ b/src/libvirt_private.syms > @@ -1315,6 +1315,7 @@ virNetSocketGetFD; > virNetSocketHasPassFD; > virNetSocketIsLocal; > virNetSocketListen; > +virNetSocketNewConnectLibSSH; > virNetSocketNewConnectTCP; > virNetSocketNewListenUNIX; > virNetSocketRecvFD; > diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c > index af4fc5e..df7e88b 100644 > --- a/src/rpc/virnetsocket.c > +++ b/src/rpc/virnetsocket.c > @@ -46,6 +46,10 @@ > > #include "passfd.h" > > +#if HAVE_LIBSSH2 > +# include "virnetlibsshcontext.h" > +#endif > + > #define VIR_FROM_THIS VIR_FROM_RPC > > #define virNetError(code, ...) \ > @@ -85,6 +89,9 @@ struct _virNetSocket { > size_t saslEncodedLength; > size_t saslEncodedOffset; > #endif > +#if HAVE_LIBSSH2 > + virNetLibSSHSessionPtr sshSession; > +#endif > }; > > > @@ -684,6 +691,97 @@ int virNetSocketNewConnectSSH(const char *nodename, > return virNetSocketNewConnectCommand(cmd, retsock); > } > > +#if HAVE_LIBSSH2 > +int virNetSocketNewConnectLibSSH(const char *host, > + const char *port, > + const char *username, > + const char *password, > + const char *command, > + const char *knownHostsFile, > + const char *hostkeyVerify, > + const char *privkey, > + virConnectAuthPtr auth, > + virNetSocketPtr *retsock) > +{ > + virNetSocketPtr sock = NULL; > + virNetLibSSHSessionPtr sess = NULL; > + int ret = -1; > + int portN; > + virNetLibSSHHostkeyVerify verify = VIR_NET_LIBSSH_HOSTKEY_VERIFY_NORMAL; > + > + > + if ((ret = virNetSocketNewConnectTCP(host, port, &sock)) < 0) > + goto error; > + > + if (!(sess = virNetLibSSHSessionNew())) { > + ret = -1; > + goto error; > + } > + > + /* configure libssh2 session */ > + if ((ret = virNetLibSSHSessionSetCredentials(sess, > + username, > + password)) != 0) > + goto error; > + > + virNetLibSSHSessionSetAuthCallback(sess, auth); /* allways succeeds */ > + > + > + if ((ret = virNetLibSSHSessionSetChannelCommand(sess, command)) != 0) > + goto error; > + > + if ((ret = virNetLibSSHSessionSetPrivateKey(sess, privkey)) != 0) > + goto error; > + > + /* port was verified while opening the socket */ > + sscanf(port, "%d", &portN); > + > + if (hostkeyVerify) { > + if (STRCASEEQ("auto", hostkeyVerify)) > + verify = VIR_NET_LIBSSH_HOSTKEY_VERIFY_AUTO_ADD; > + else if (STRCASEEQ("ignore", hostkeyVerify)) > + verify = VIR_NET_LIBSSH_HOSTKEY_VERIFY_IGNORE; > + } > + > + if ((ret = virNetLibSSHSessionSetHostKeyVerification(sess, > + host, > + portN, > + knownHostsFile, > + false, > + verify) != 0)) > + goto error; > + > + /* connect to the host using ssh */ > + if ((ret = virNetLibSSHSessionConnect(sess, virNetSocketGetFD(sock))) != 0) > + goto error; > + > + sock->sshSession = sess; > + *retsock = sock; > + > + return 0; > + > +error: > + virNetSocketFree(sock); > + virNetLibSSHSessionFree(sess); > + return ret; Funky indentation > +} > +#else > +int virNetSocketNewConnectLibSSH(const char *host ATTRIBUTE_UNUSED, > + const char *port ATTRIBUTE_UNUSED, > + const char *username ATTRIBUTE_UNUSED, > + const char *password ATTRIBUTE_UNUSED, > + const char *command ATTRIBUTE_UNUSED, > + const char *knownHostsFile ATTRIBUTE_UNUSED, > + const char *hostkeyVerify ATTRIBUTE_UNUSED, > + const char *privkey ATTRIBUTE_UNUSED, > + virConnectAuthPtr auth ATTRIBUTE_UNUSED, > + virNetSocketPtr *retsock ATTRIBUTE_UNUSED) > +{ > + virReportSystemError(ENOSYS, > + _("libssh2 transport support was not enabled in this build")); > + return -1; > +} > +#endif /* HAVE_LIBSSH2 */ > > int virNetSocketNewConnectExternal(const char **cmdargv, > virNetSocketPtr *retsock) > @@ -749,6 +847,10 @@ void virNetSocketFree(virNetSocketPtr sock) > virNetSASLSessionFree(sock->saslSession); > #endif > > +#if HAVE_LIBSSH2 > + virNetLibSSHSessionFree(sock->sshSession); > +#endif > + > VIR_FORCE_CLOSE(sock->fd); > VIR_FORCE_CLOSE(sock->errfd); > > @@ -930,6 +1032,12 @@ bool virNetSocketHasCachedData(virNetSocketPtr sock ATTRIBUTE_UNUSED) > { > bool hasCached = false; > virMutexLock(&sock->lock); > + > +#if HAVE_LIBSSH2 > + if (virNetLibSSHHasCachedData(sock->sshSession)) > + hasCached = true; > +#endif > + > #if HAVE_SASL > if (sock->saslDecoded) > hasCached = true; > @@ -938,6 +1046,21 @@ bool virNetSocketHasCachedData(virNetSocketPtr sock ATTRIBUTE_UNUSED) > return hasCached; > } > > +#if HAVE_LIBSSH2 > +static ssize_t virNetSocketLibSSHRead(virNetSocketPtr sock, > + char *buf, > + size_t len) > +{ > + return virNetLibSSHChannelRead(sock->sshSession, buf, len); > +} > + > +static ssize_t virNetSocketLibSSHWrite(virNetSocketPtr sock, > + const char *buf, > + size_t len) > +{ > + return virNetLibSSHChannelWrite(sock->sshSession, buf, len); > +} > +#endif > > bool virNetSocketHasPendingData(virNetSocketPtr sock ATTRIBUTE_UNUSED) > { > @@ -956,6 +1079,12 @@ static ssize_t virNetSocketReadWire(virNetSocketPtr sock, char *buf, size_t len) > { > char *errout = NULL; > ssize_t ret; > + > +#if HAVE_LIBSSH2 > + if (sock->sshSession) > + return virNetSocketLibSSHRead(sock, buf, len); > +#endif > + > reread: > if (sock->tlsSession && > virNetTLSSessionGetHandshakeStatus(sock->tlsSession) == > @@ -1004,6 +1133,12 @@ reread: > static ssize_t virNetSocketWriteWire(virNetSocketPtr sock, const char *buf, size_t len) > { > ssize_t ret; > + > +#if HAVE_LIBSSH2 > + if (sock->sshSession) > + return virNetSocketLibSSHWrite(sock, buf, len); > +#endif > + > rewrite: > if (sock->tlsSession && > virNetTLSSessionGetHandshakeStatus(sock->tlsSession) == > @@ -1132,7 +1267,6 @@ static ssize_t virNetSocketWriteSASL(virNetSocketPtr sock, const char *buf, size > } > #endif > > - > ssize_t virNetSocketRead(virNetSocketPtr sock, char *buf, size_t len) > { > ssize_t ret; > diff --git a/src/rpc/virnetsocket.h b/src/rpc/virnetsocket.h > index ef9baa8..d04945d 100644 > --- a/src/rpc/virnetsocket.h > +++ b/src/rpc/virnetsocket.h > @@ -74,6 +74,17 @@ int virNetSocketNewConnectSSH(const char *nodename, > const char *path, > virNetSocketPtr *addr); > > +int virNetSocketNewConnectLibSSH(const char *host, > + const char *port, > + const char *username, > + const char *password, > + const char *command, > + const char *knownHostsFile, > + const char *hostkeyVerify, > + const char *privkey, > + virConnectAuthPtr auth, > + virNetSocketPtr *retsock); > + > int virNetSocketNewConnectExternal(const char **cmdargv, > virNetSocketPtr *addr); > > @@ -101,6 +112,7 @@ int virNetSocketRecvFD(virNetSocketPtr sock, int *fd); > > void virNetSocketSetTLSSession(virNetSocketPtr sock, > virNetTLSSessionPtr sess); > + > # ifdef HAVE_SASL > void virNetSocketSetSASLSession(virNetSocketPtr sock, > virNetSASLSessionPtr sess); -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list