From 70aa33c041b88573b32d67d0153c6472ce41ea8b Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Mon, 2 Feb 2009 14:41:44 +0000 Subject: [PATCH] Start with ssh agent implementation. This is work in progress. git-svn-id: svn+ssh://svn.berlios.de/svnroot/repos/libssh/trunk@200 7dcaeef0-15fb-0310-b436-a5af3365683c --- include/libssh/libssh.h | 1 + include/libssh/priv.h | 41 +++++++++++++++++++++++++++++++++++++++++ libssh/Makefile.am | 2 +- libssh/auth.c | 12 ++++++++++++ libssh/session.c | 3 +++ libssh/socket.c | 31 +++++++++++++++++++++++++++++++ 6 files changed, 89 insertions(+), 1 deletion(-) diff --git a/include/libssh/libssh.h b/include/libssh/libssh.h index cf637748..f3ad2f56 100644 --- a/include/libssh/libssh.h +++ b/include/libssh/libssh.h @@ -52,6 +52,7 @@ typedef struct public_key_struct PUBLIC_KEY; typedef struct private_key_struct PRIVATE_KEY; typedef struct ssh_options_struct SSH_OPTIONS; typedef struct channel_struct CHANNEL; +typedef struct agent_struct AGENT; typedef struct ssh_session SSH_SESSION; typedef struct ssh_kbdint SSH_KBDINT; diff --git a/include/libssh/priv.h b/include/libssh/priv.h index 34731a69..907fd19f 100644 --- a/include/libssh/priv.h +++ b/include/libssh/priv.h @@ -286,6 +286,12 @@ struct channel_struct { int blocking; }; +struct agent_struct { + struct socket *sock; + STRING *ident; + unsigned int count; +}; + struct ssh_session { struct error_struct error; struct socket *socket; @@ -337,6 +343,7 @@ struct ssh_session { int maxchannel; int exec_channel_opened; /* version 1 only. more info in channels1.c */ + AGENT *agent; /* ssh agent */ /* keyb interactive data */ struct ssh_kbdint *kbdint; @@ -417,6 +424,34 @@ struct ssh_message { struct ssh_channel_request channel_request; }; +/* agent.c */ +/** + * @brief Create a new ssh agent structure. + * + * @return An allocated ssh agent structure or NULL on error. + */ +struct agent_struct *agent_new(struct ssh_session *session); + +void agent_close(struct agent_struct *agent); +/** + * @brief Free an allocated ssh agent structure. + * + * @param agent The ssh agent structure to free. + */ +void agent_free(struct agent_struct *agent); +#ifndef _WIN32 +/** + * @brief Check if the ssh agent is running. + * + * @param session The ssh session to check for the agent. + * + * @return 1 if it is running, 0 if not. + */ +int agent_running(struct ssh_session *session); + +int agent_ident_count(struct ssh_session *session); +#endif + /* socket.c */ struct socket; @@ -425,6 +460,9 @@ struct socket *ssh_socket_new(SSH_SESSION *session); void ssh_socket_free(struct socket *s); void ssh_socket_set_fd(struct socket *s, socket_t fd); socket_t ssh_socket_get_fd(struct socket *s); +#ifndef _WIN32 +int ssh_socket_unix(struct socket *s, const char *path); +#endif void ssh_socket_close(struct socket *s); int ssh_socket_read(struct socket *s, void *buffer, int len); int ssh_socket_write(struct socket *s,const void *buffer, int len); @@ -637,6 +675,9 @@ int ssh_handle_packets(SSH_SESSION *session); #define enter_function() _enter_function(session) #define leave_function() _leave_function(session) +/** Free memory space */ +#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); x=NULL;} } while(0) + /** Zero a structure */ #define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x)) diff --git a/libssh/Makefile.am b/libssh/Makefile.am index bc71495a..db766ee7 100644 --- a/libssh/Makefile.am +++ b/libssh/Makefile.am @@ -1,6 +1,6 @@ lib_LTLIBRARIES = libssh.la -libssh_la_SOURCES = auth1.c auth.c base64.c buffer.c \ +libssh_la_SOURCES = agent.c auth1.c auth.c base64.c buffer.c \ channels1.c channels.c client.c connect.c \ crc32.c crypt.c dh.c error.c gcrypt_missing.c \ gzip.c init.c kex.c keyfiles.c \ diff --git a/libssh/auth.c b/libssh/auth.c index eb212f75..c2fc29f8 100644 --- a/libssh/auth.c +++ b/libssh/auth.c @@ -432,6 +432,18 @@ int ssh_userauth_autopubkey(SSH_SESSION *session, const char *passphrase) { leave_function(); return err; } + + /* try ssh-agent keys first */ +#ifndef _WIN32 +#if 0 + if (agent_running(session)) { + ssh_say(1, "SSH Agent is running\n"); + count = agent_ident_count(session); + ssh_say(1, "SSH Agent has %d key(s)\n", count); + } +#endif +#endif + if(session->options->identity){ ssh_say(2,"Trying identity file %s\n",session->options->identity); keys_path[0]=session->options->identity; diff --git a/libssh/session.c b/libssh/session.c index 877c44a1..8ac005b4 100644 --- a/libssh/session.c +++ b/libssh/session.c @@ -48,6 +48,7 @@ SSH_SESSION *ssh_new() { session->log_indent=0; session->out_buffer=buffer_new(); session->in_buffer=buffer_new(); + session->agent=agent_new(session); return session; } @@ -75,6 +76,8 @@ void ssh_cleanup(SSH_SESSION *session){ // delete all channels while(session->channels) channel_free(session->channels); + if (session->agent) + agent_free(session->agent); if(session->client_kex.methods) for(i=0;i<10;i++) if(session->client_kex.methods[i]) diff --git a/libssh/socket.c b/libssh/socket.c index 6765b36b..d4d8e800 100644 --- a/libssh/socket.c +++ b/libssh/socket.c @@ -27,8 +27,10 @@ #ifdef _WIN32 #include #else +#include #include #include +#include #endif #include "libssh/priv.h" @@ -104,6 +106,35 @@ void ssh_socket_free(struct socket *s){ free(s); } +#ifndef _WIN32 +int ssh_socket_unix(struct socket *s, const char *path) { + struct sockaddr_un sunaddr; + + sunaddr.sun_family = AF_UNIX; + snprintf(sunaddr.sun_path, sizeof(sunaddr.sun_path), "%s", path); + + s->fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (s->fd < 0) { + return -1; + } + + if (fcntl(s->fd, F_SETFD, 1) == -1) { + close(s->fd); + s->fd = -1; + return -1; + } + + if (connect(s->fd, (struct sockaddr *) &sunaddr, + sizeof(sunaddr)) < 0) { + close(s->fd); + s->fd = -1; + return -1; + } + + return 0; +} +#endif + /* \internal * \brief closes a socket */