From da954c2c5ee85bcbe2f5ad9f507a6306b0f5f8b9 Mon Sep 17 00:00:00 2001 From: Aris Adamantiadis Date: Tue, 19 Jul 2011 22:16:28 +0200 Subject: [PATCH] Fixes the ssh_log issue on ssh_bind handles. --- include/libssh/bind.h | 7 ++--- include/libssh/priv.h | 12 +++++--- include/libssh/session.h | 13 +++++--- src/bind.c | 6 ++-- src/callbacks.c | 2 +- src/client.c | 4 +-- src/error.c | 9 +++--- src/keyfiles.c | 14 ++++----- src/log.c | 64 ++++++++++++++++++++++++++++------------ src/messages.c | 8 ++--- src/options.c | 16 +++++----- src/server.c | 4 +-- src/session.c | 2 +- 13 files changed, 97 insertions(+), 64 deletions(-) diff --git a/include/libssh/bind.h b/include/libssh/bind.h index 705d2759..ef3a0e82 100644 --- a/include/libssh/bind.h +++ b/include/libssh/bind.h @@ -23,11 +23,10 @@ #define BIND_H_ #include "libssh/priv.h" +#include "libssh/session.h" struct ssh_bind_struct { - struct error_struct error; - - ssh_callbacks callbacks; /* Callbacks to user functions */ + struct ssh_common_struct common; /* stuff common to ssh_bind and ssh_session */ struct ssh_bind_callbacks_struct *bind_callbacks; void *bind_callbacks_userdata; @@ -40,8 +39,6 @@ struct ssh_bind_struct { char *bindaddr; socket_t bindfd; unsigned int bindport; - unsigned int log_verbosity; - int blocking; int toaccept; }; diff --git a/include/libssh/priv.h b/include/libssh/priv.h index de965f51..0859f4b9 100644 --- a/include/libssh/priv.h +++ b/include/libssh/priv.h @@ -141,6 +141,7 @@ struct ssh_keys_struct { }; struct ssh_message_struct; +struct ssh_common_struct; /* server data */ @@ -216,6 +217,9 @@ int match_hostname(const char *host, const char *pattern, unsigned int len); int message_handle(ssh_session session, void *user, uint8_t type, ssh_buffer packet); /* log.c */ +void ssh_log_common(struct ssh_common_struct *common, int verbosity, + const char *format, ...) PRINTF_ATTRIBUTE(3, 4); + /* misc.c */ #ifdef _WIN32 int gettimeofday(struct timeval *__p, void *__t); @@ -229,16 +233,16 @@ int gettimeofday(struct timeval *__p, void *__t); #define _enter_function(sess) \ do {\ - if((sess)->log_verbosity >= SSH_LOG_FUNCTIONS){ \ + if((sess)->common.log_verbosity >= SSH_LOG_FUNCTIONS){ \ ssh_log((sess),SSH_LOG_FUNCTIONS,"entering function %s line %d in " __FILE__ , __FUNCTION__,__LINE__);\ - (sess)->log_indent++; \ + (sess)->common.log_indent++; \ } \ } while(0) #define _leave_function(sess) \ do { \ - if((sess)->log_verbosity >= SSH_LOG_FUNCTIONS){ \ - (sess)->log_indent--; \ + if((sess)->common.log_verbosity >= SSH_LOG_FUNCTIONS){ \ + (sess)->common.log_indent--; \ ssh_log((sess),SSH_LOG_FUNCTIONS,"leaving function %s line %d in " __FILE__ , __FUNCTION__,__LINE__);\ }\ } while(0) diff --git a/include/libssh/session.h b/include/libssh/session.h index 2d4b05bc..3b79f428 100644 --- a/include/libssh/session.h +++ b/include/libssh/session.h @@ -62,8 +62,16 @@ enum ssh_pending_call_e { /* libssh calls may block an undefined amount of time */ #define SSH_SESSION_FLAG_BLOCKING 1 -struct ssh_session_struct { +/* members that are common to ssh_session and ssh_bind */ +struct ssh_common_struct { struct error_struct error; + ssh_callbacks callbacks; /* Callbacks to user functions */ + int log_verbosity; /* verbosity of the log functions */ + int log_indent; /* indentation level in enter_function logs */ +}; + +struct ssh_session_struct { + struct ssh_common_struct common; struct ssh_socket_struct *socket; char *serverbanner; char *clientbanner; @@ -129,11 +137,8 @@ struct ssh_session_struct { struct ssh_list *ssh_message_list; /* list of delayed SSH messages */ int (*ssh_message_callback)( struct ssh_session_struct *session, ssh_message msg, void *userdata); void *ssh_message_callback_data; - int log_verbosity; /*cached copy of the option structure */ - int log_indent; /* indentation level in enter_function logs */ void (*ssh_connection_callback)( struct ssh_session_struct *session); - ssh_callbacks callbacks; /* Callbacks to user functions */ struct ssh_packet_callbacks_struct default_packet_callbacks; struct ssh_list *packet_callbacks; struct ssh_socket_callbacks_struct socket_callbacks; diff --git a/src/bind.c b/src/bind.c index 54dbb23d..cc79f8eb 100644 --- a/src/bind.c +++ b/src/bind.c @@ -150,7 +150,7 @@ ssh_bind ssh_bind_new(void) { ZERO_STRUCTP(ptr); ptr->bindfd = SSH_INVALID_SOCKET; ptr->bindport= 22; - ptr->log_verbosity = 0; + ptr->common.log_verbosity = 0; return ptr; } @@ -359,7 +359,7 @@ int ssh_bind_accept(ssh_bind sshbind, ssh_session session) { } } - session->log_verbosity = sshbind->log_verbosity; + session->common.log_verbosity = sshbind->common.log_verbosity; ssh_socket_free(session->socket); session->socket = ssh_socket_new(session); @@ -375,7 +375,7 @@ int ssh_bind_accept(ssh_bind sshbind, ssh_session session) { session->dsa_key = dsa; session->rsa_key = rsa; -return SSH_OK; + return SSH_OK; } diff --git a/src/callbacks.c b/src/callbacks.c index bb42b4be..5a61180d 100644 --- a/src/callbacks.c +++ b/src/callbacks.c @@ -37,7 +37,7 @@ int ssh_set_callbacks(ssh_session session, ssh_callbacks cb) { leave_function(); return SSH_ERROR; } - session->callbacks = cb; + session->common.callbacks = cb; leave_function(); return 0; } diff --git a/src/client.c b/src/client.c index 426dd2b3..78f417c0 100644 --- a/src/client.c +++ b/src/client.c @@ -41,8 +41,8 @@ #include "libssh/misc.h" #define set_status(session, status) do {\ - if (session->callbacks && session->callbacks->connect_status_function) \ - session->callbacks->connect_status_function(session->callbacks->userdata, status); \ + if (session->common.callbacks && session->common.callbacks->connect_status_function) \ + session->common.callbacks->connect_status_function(session->common.callbacks->userdata, status); \ } while (0) /** diff --git a/src/error.c b/src/error.c index e2d02ce7..46d6382d 100644 --- a/src/error.c +++ b/src/error.c @@ -24,6 +24,7 @@ #include #include #include "libssh/priv.h" +#include "libssh/session.h" /** * @defgroup libssh_error The SSH error functions. @@ -48,13 +49,13 @@ * @param ... The arguments for the format string. */ void ssh_set_error(void *error, int code, const char *descr, ...) { - struct error_struct *err = error; + struct ssh_common_struct *err = error; va_list va; va_start(va, descr); - vsnprintf(err->error_buffer, ERROR_BUFFERLEN, descr, va); + vsnprintf(err->error.error_buffer, ERROR_BUFFERLEN, descr, va); va_end(va); - err->error_code = code; - ssh_log(error,SSH_LOG_RARE,"Error : %s",err->error_buffer); + err->error.error_code = code; + ssh_log_common(err,SSH_LOG_RARE,"Error : %s",err->error.error_buffer); } /** diff --git a/src/keyfiles.c b/src/keyfiles.c index 6d8ced68..0540a5d1 100644 --- a/src/keyfiles.c +++ b/src/keyfiles.c @@ -995,7 +995,7 @@ ssh_private_key privatekey_from_base64(ssh_session session, const char *b64_pkey ssh_log(session, SSH_LOG_RARE, "Trying to read privkey type=%s, passphase=%s, authcb=%s", type ? type == SSH_KEYTYPE_DSS ? "ssh-dss" : "ssh-rsa": "unknown", passphrase ? "true" : "false", - session->callbacks && session->callbacks->auth_function ? "true" : "false"); + session->common.callbacks && session->common.callbacks->auth_function ? "true" : "false"); if (type == 0) { type = privatekey_type_from_string(b64_pkey); @@ -1008,9 +1008,9 @@ ssh_private_key privatekey_from_base64(ssh_session session, const char *b64_pkey case SSH_KEYTYPE_DSS: #ifdef HAVE_LIBGCRYPT if (passphrase == NULL) { - if (session->callbacks && session->callbacks->auth_function) { - auth_cb = session->callbacks->auth_function; - auth_ud = session->callbacks->userdata; + if (session->common.callbacks && session->common.callbacks->auth_function) { + auth_cb = session->common.callbacks->auth_function; + auth_ud = session->common.callbacks->userdata; valid = b64decode_dsa_privatekey(b64_pkey, &dsa, auth_cb, auth_ud, "Passphrase for private key:"); @@ -1052,9 +1052,9 @@ ssh_private_key privatekey_from_base64(ssh_session session, const char *b64_pkey case SSH_KEYTYPE_RSA: #ifdef HAVE_LIBGCRYPT if (passphrase == NULL) { - if (session->callbacks && session->callbacks->auth_function) { - auth_cb = session->callbacks->auth_function; - auth_ud = session->callbacks->userdata; + if (session->common.callbacks && session->common.callbacks->auth_function) { + auth_cb = session->common.callbacks->auth_function; + auth_ud = session->common.callbacks->userdata; valid = b64decode_rsa_privatekey(b64_pkey, &rsa, auth_cb, auth_ud, "Passphrase for private key:"); } else { /* authcb */ diff --git a/src/log.c b/src/log.c index 6ec5a8ea..509b8abc 100644 --- a/src/log.c +++ b/src/log.c @@ -37,6 +37,33 @@ * @{ */ +/** @internal + * @brief do the actual work of logging an event + */ + +static void do_ssh_log(struct ssh_common_struct *common, int verbosity, + const char *buffer){ + char indent[256]; + int min; + if (common->callbacks && common->callbacks->log_function) { + common->callbacks->log_function((ssh_session)common, verbosity, buffer, + common->callbacks->userdata); + } else if (verbosity == SSH_LOG_FUNCTIONS) { + if (common->log_indent > 255) { + min = 255; + } else { + min = common->log_indent; + } + + memset(indent, ' ', min); + indent[min] = '\0'; + + fprintf(stderr, "[func] %s%s\n", indent, buffer); + } else { + fprintf(stderr, "[%d] %s\n", verbosity, buffer); + } +} + /** * @brief Log a SSH event. * @@ -48,32 +75,31 @@ */ void ssh_log(ssh_session session, int verbosity, const char *format, ...) { char buffer[1024]; - char indent[256]; - int min; va_list va; - if (verbosity <= session->log_verbosity) { + if (verbosity <= session->common.log_verbosity) { va_start(va, format); vsnprintf(buffer, sizeof(buffer), format, va); va_end(va); + do_ssh_log(&session->common, verbosity, buffer); + } +} - if (session->callbacks && session->callbacks->log_function) { - session->callbacks->log_function(session, verbosity, buffer, - session->callbacks->userdata); - } else if (verbosity == SSH_LOG_FUNCTIONS) { - if (session->log_indent > 255) { - min = 255; - } else { - min = session->log_indent; - } +/** @internal + * @brief log a SSH event with a common pointer + * @param common The SSH/bind session. + * @param verbosity The verbosity of the event. + * @param format The format string of the log entry. + */ +void ssh_log_common(struct ssh_common_struct *common, int verbosity, const char *format, ...){ + char buffer[1024]; + va_list va; - memset(indent, ' ', min); - indent[min] = '\0'; - - fprintf(stderr, "[func] %s%s\n", indent, buffer); - } else { - fprintf(stderr, "[%d] %s\n", verbosity, buffer); - } + if (verbosity <= common->log_verbosity) { + va_start(va, format); + vsnprintf(buffer, sizeof(buffer), format, va); + va_end(va); + do_ssh_log(common, verbosity, buffer); } } diff --git a/src/messages.c b/src/messages.c index 656da77b..bbd9d1f3 100644 --- a/src/messages.c +++ b/src/messages.c @@ -1156,9 +1156,9 @@ SSH_PACKET_CALLBACK(ssh_packet_global_request){ ssh_log(session, SSH_LOG_PROTOCOL, "Received SSH_MSG_GLOBAL_REQUEST %s %d %s:%d", request, want_reply, bind_addr, bind_port); - if(ssh_callbacks_exists(session->callbacks, global_request_function)) { + if(ssh_callbacks_exists(session->common.callbacks, global_request_function)) { ssh_log(session, SSH_LOG_PROTOCOL, "Calling callback for SSH_MSG_GLOBAL_REQUEST %s %d %s:%d", request, want_reply, bind_addr, bind_port); - session->callbacks->global_request_function(session, msg, session->callbacks->userdata); + session->common.callbacks->global_request_function(session, msg, session->common.callbacks->userdata); } else { ssh_message_reply_default(msg); } @@ -1178,8 +1178,8 @@ SSH_PACKET_CALLBACK(ssh_packet_global_request){ ssh_log(session, SSH_LOG_PROTOCOL, "Received SSH_MSG_GLOBAL_REQUEST %s %d %s:%d", request, want_reply, bind_addr, bind_port); - if(ssh_callbacks_exists(session->callbacks, global_request_function)) { - session->callbacks->global_request_function(session, msg, session->callbacks->userdata); + if(ssh_callbacks_exists(session->common.callbacks, global_request_function)) { + session->common.callbacks->global_request_function(session, msg, session->common.callbacks->userdata); } else { ssh_message_reply_default(msg); } diff --git a/src/options.c b/src/options.c index d111f726..fa6c4d6a 100644 --- a/src/options.c +++ b/src/options.c @@ -139,12 +139,12 @@ int ssh_options_copy(ssh_session src, ssh_session *dest) { } new->fd = src->fd; new->port = src->port; - new->callbacks = src->callbacks; + new->common.callbacks = src->common.callbacks; new->timeout = src->timeout; new->timeout_usec = src->timeout_usec; new->ssh2 = src->ssh2; new->ssh1 = src->ssh1; - new->log_verbosity = src->log_verbosity; + new->common.log_verbosity = src->common.log_verbosity; new->compressionlevel = src->compressionlevel; return 0; @@ -549,12 +549,12 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type, } else { int *x = (int *) value; - session->log_verbosity = *x & 0xffff; + session->common.log_verbosity = *x & 0xffff; } break; case SSH_OPTIONS_LOG_VERBOSITY_STR: if (value == NULL) { - session->log_verbosity = 0 & 0xffff; + session->common.log_verbosity = 0 & 0xffff; } else { q = strdup(value); if (q == NULL) { @@ -567,7 +567,7 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type, } SAFE_FREE(q); - session->log_verbosity = i & 0xffff; + session->common.log_verbosity = i & 0xffff; } break; case SSH_OPTIONS_CIPHERS_C_S: @@ -1120,12 +1120,12 @@ int ssh_bind_options_set(ssh_bind sshbind, enum ssh_bind_options_e type, return -1; } else { int *x = (int *) value; - sshbind->log_verbosity = *x & 0xffff; + sshbind->common.log_verbosity = *x & 0xffff; } break; case SSH_BIND_OPTIONS_LOG_VERBOSITY_STR: if (value == NULL) { - sshbind->log_verbosity = 0; + sshbind->common.log_verbosity = 0; } else { q = strdup(value); if (q == NULL) { @@ -1138,7 +1138,7 @@ int ssh_bind_options_set(ssh_bind sshbind, enum ssh_bind_options_e type, } SAFE_FREE(q); - sshbind->log_verbosity = i & 0xffff; + sshbind->common.log_verbosity = i & 0xffff; } break; case SSH_BIND_OPTIONS_DSAKEY: diff --git a/src/server.c b/src/server.c index e693fe95..9877ed86 100644 --- a/src/server.c +++ b/src/server.c @@ -59,8 +59,8 @@ #include "libssh/messages.h" #define set_status(session, status) do {\ - if (session->callbacks && session->callbacks->connect_status_function) \ - session->callbacks->connect_status_function(session->callbacks->userdata, status); \ + if (session->common.callbacks && session->common.callbacks->connect_status_function) \ + session->common.callbacks->connect_status_function(session->common.callbacks->userdata, status); \ } while (0) static int dh_handshake_server(ssh_session session); diff --git a/src/session.c b/src/session.c index 968c0894..ab12e0db 100644 --- a/src/session.c +++ b/src/session.c @@ -86,7 +86,7 @@ ssh_session ssh_new(void) { session->alive = 0; session->auth_methods = 0; ssh_set_blocking(session, 1); - session->log_indent = 0; + session->common.log_indent = 0; session->maxchannel = FIRST_CHANNEL; /* options */