[libvirt] [PATCH RFCv2 2/5] libssh2_transport: add ssh context support to virNetSocket

Michal Privoznik mprivozn at redhat.com
Wed Jan 18 14:58:47 UTC 2012


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);




More information about the libvir-list mailing list