static PyObject * PYLIBSSH2_Session_callback_set(PYLIBSSH2_SESSION *self, PyObject *args) { PyObject *result = NULL; /* type of callback to register see libssh2.h LIBSSH2_CALLBACK_* */ int cbtype; /* callback is callable Python Object */ PyObject *cb; if (PyArg_ParseTuple(args, "iO:callback_set", &cbtype, &cb)) { if (!PyCallable_Check(cb)) { PyErr_SetString(PyExc_TypeError, "parameter must be callable"); return NULL; } Py_XINCREF(cb); Py_XINCREF(py_callback_func); py_callback_func = cb; Py_BEGIN_ALLOW_THREADS libssh2_session_callback_set(self->session, cbtype, stub_callback_func); Py_END_ALLOW_THREADS Py_INCREF(Py_None); result = Py_None; } return result; }
/* {{{ php_ssh2_set_callback * Try to set a method if it's passed in with the hash table */ static int php_ssh2_set_callback(LIBSSH2_SESSION *session, HashTable *ht, char *callback, int callback_len, int callback_type, php_ssh2_session_data *data) { zval *handler, *copyval; void *internal_handler; zend_string *callback_zstring; callback_zstring = zend_string_init(callback, callback_len, 0); if ((handler = zend_hash_find(ht, callback_zstring)) == NULL) { zend_string_release(callback_zstring); return 0; } zend_string_release(callback_zstring); if (!zend_is_callable(handler, 0, NULL)) { return -1; } copyval = handler; zval_copy_ctor(copyval); switch (callback_type) { case LIBSSH2_CALLBACK_IGNORE: internal_handler = php_ssh2_ignore_cb; if (data->ignore_cb) { zval_ptr_dtor(data->ignore_cb); } data->ignore_cb = copyval; break; case LIBSSH2_CALLBACK_DEBUG: internal_handler = php_ssh2_debug_cb; if (data->debug_cb) { zval_ptr_dtor(data->debug_cb); } data->debug_cb = copyval; break; case LIBSSH2_CALLBACK_MACERROR: internal_handler = php_ssh2_macerror_cb; if (data->macerror_cb) { zval_ptr_dtor(data->macerror_cb); } data->macerror_cb = copyval; break; case LIBSSH2_CALLBACK_DISCONNECT: internal_handler = php_ssh2_disconnect_cb; if (data->disconnect_cb) { zval_ptr_dtor(data->disconnect_cb); } data->disconnect_cb = copyval; break; default: zval_ptr_dtor(copyval); return -1; } libssh2_session_callback_set(session, callback_type, internal_handler); return 0; }
static PyObject * session_callback_set(SSH2_SessionObj *self, PyObject *args) { int type; PyObject* new_callback; PyObject* old_callback; void *raw_callback; if (!PyArg_ParseTuple(args, "iO:callback_set", &type, &new_callback)) return NULL; if (new_callback != Py_None && !PyCallable_Check(new_callback)) return PyErr_Format(PyExc_TypeError, "'%s' is not callable", new_callback->ob_type->tp_name); switch (type) { case LIBSSH2_CALLBACK_IGNORE: old_callback = self->cb_ignore; self->cb_ignore = new_callback; raw_callback = ignore_callback; break; case LIBSSH2_CALLBACK_DEBUG: old_callback = self->cb_debug; self->cb_debug = new_callback; raw_callback = debug_callback; break; case LIBSSH2_CALLBACK_DISCONNECT: old_callback = self->cb_disconnect; self->cb_disconnect = new_callback; raw_callback = disconnect_callback; break; case LIBSSH2_CALLBACK_MACERROR: old_callback = self->cb_macerror; self->cb_macerror = new_callback; raw_callback = macerror_callback; break; case LIBSSH2_CALLBACK_X11: old_callback = self->cb_x11; self->cb_x11 = new_callback; raw_callback = x11_callback; break; default: PyErr_SetString(PyExc_ValueError, "invalid callback type"); return NULL; } libssh2_session_callback_set(self->session, type, new_callback != Py_None ? raw_callback : NULL); Py_INCREF(new_callback); return old_callback; }
void* ssh_client_thread(void* data) { guac_client* client = (guac_client*) data; ssh_guac_client_data* client_data = (ssh_guac_client_data*) client->data; char name[1024]; guac_socket* socket = client->socket; char buffer[8192]; int bytes_read = -1234; int socket_fd; int stdout_fd = client_data->term->stdout_pipe_fd[1]; pthread_t input_thread; libssh2_init(0); /* Get username */ if (client_data->username[0] == 0) prompt(client, "Login as: ", client_data->username, sizeof(client_data->username), true); /* Send new name */ snprintf(name, sizeof(name)-1, "%s@%s", client_data->username, client_data->hostname); guac_protocol_send_name(socket, name); /* If key specified, import */ if (client_data->key_base64[0] != 0) { /* Attempt to read key without passphrase */ client_data->key = ssh_key_alloc(client_data->key_base64, strlen(client_data->key_base64), ""); /* On failure, attempt with passphrase */ if (client_data->key == NULL) { /* Prompt for passphrase if missing */ if (client_data->key_passphrase[0] == 0) prompt(client, "Key passphrase: ", client_data->key_passphrase, sizeof(client_data->key_passphrase), false); /* Import key with passphrase */ client_data->key = ssh_key_alloc(client_data->key_base64, strlen(client_data->key_base64), client_data->key_passphrase); /* If still failing, give up */ if (client_data->key == NULL) { guac_client_log_error(client, "Auth key import failed."); return NULL; } } /* end decrypt key with passphrase */ /* Success */ guac_client_log_info(client, "Auth key successfully imported."); } /* end if key given */ /* Otherwise, get password if not provided */ else if (client_data->password[0] == 0) prompt(client, "Password: "******"\x1B[H\x1B[J", 6); /* Open SSH session */ client_data->session = __guac_ssh_create_session(client, &socket_fd); if (client_data->session == NULL) { /* Already aborted within __guac_ssh_create_session() */ return NULL; } /* Open channel for terminal */ client_data->term_channel = libssh2_channel_open_session(client_data->session); if (client_data->term_channel == NULL) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, "Unable to open terminal channel."); return NULL; } #ifdef ENABLE_SSH_AGENT /* Start SSH agent forwarding, if enabled */ if (client_data->enable_agent) { libssh2_session_callback_set(client_data->session, LIBSSH2_CALLBACK_AUTH_AGENT, (void*) ssh_auth_agent_callback); /* Request agent forwarding */ if (libssh2_channel_request_auth_agent(client_data->term_channel)) guac_client_log_error(client, "Agent forwarding request failed"); else guac_client_log_info(client, "Agent forwarding enabled."); } client_data->auth_agent = NULL; #endif /* Start SFTP session as well, if enabled */ if (client_data->enable_sftp) { /* Create SSH session specific for SFTP */ guac_client_log_info(client, "Reconnecting for SFTP..."); client_data->sftp_ssh_session = __guac_ssh_create_session(client, NULL); if (client_data->sftp_ssh_session == NULL) { /* Already aborted within __guac_ssh_create_session() */ return NULL; } /* Request SFTP */ client_data->sftp_session = libssh2_sftp_init(client_data->sftp_ssh_session); if (client_data->sftp_session == NULL) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, "Unable to start SFTP session."); return NULL; } /* Set file handler */ client->file_handler = guac_sftp_file_handler; guac_client_log_info(client, "SFTP session initialized"); } /* Request PTY */ if (libssh2_channel_request_pty_ex(client_data->term_channel, "linux", sizeof("linux")-1, NULL, 0, client_data->term->term_width, client_data->term->term_height, 0, 0)) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, "Unable to allocate PTY."); return NULL; } /* Request shell */ if (libssh2_channel_shell(client_data->term_channel)) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, "Unable to associate shell with PTY."); return NULL; } /* Logged in */ guac_client_log_info(client, "SSH connection successful."); /* Start input thread */ if (pthread_create(&(input_thread), NULL, ssh_input_thread, (void*) client)) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Unable to start input thread"); return NULL; } /* Set non-blocking */ libssh2_session_set_blocking(client_data->session, 0); /* While data available, write to terminal */ bytes_read = 0; while (!libssh2_channel_eof(client_data->term_channel)) { /* Track total amount of data read */ int total_read = 0; /* Read terminal data */ bytes_read = libssh2_channel_read(client_data->term_channel, buffer, sizeof(buffer)); /* Attempt to write data received. Exit on failure. */ if (bytes_read > 0) { int written = guac_terminal_write_all(stdout_fd, buffer, bytes_read); if (written < 0) break; total_read += bytes_read; } else if (bytes_read < 0 && bytes_read != LIBSSH2_ERROR_EAGAIN) break; #ifdef ENABLE_SSH_AGENT /* If agent open, handle any agent packets */ if (client_data->auth_agent != NULL) { bytes_read = ssh_auth_agent_read(client_data->auth_agent); if (bytes_read > 0) total_read += bytes_read; else if (bytes_read < 0 && bytes_read != LIBSSH2_ERROR_EAGAIN) client_data->auth_agent = NULL; } #endif /* Wait for more data if reads turn up empty */ if (total_read == 0) { fd_set fds; struct timeval timeout; FD_ZERO(&fds); FD_SET(socket_fd, &fds); /* Wait for one second */ timeout.tv_sec = 1; timeout.tv_usec = 0; if (select(socket_fd+1, &fds, NULL, NULL, &timeout) < 0) break; } } /* Kill client and Wait for input thread to die */ guac_client_stop(client); pthread_join(input_thread, NULL); guac_client_log_info(client, "SSH connection ended."); return NULL; }
void* ssh_client_thread(void* data) { guac_client* client = (guac_client*) data; ssh_guac_client_data* client_data = (ssh_guac_client_data*) client->data; guac_socket* socket = client->socket; char buffer[8192]; pthread_t input_thread; /* Init SSH base libraries */ if (guac_common_ssh_init(client)) return NULL; /* Get user and credentials */ client_data->user = guac_ssh_get_user(client); /* Send new name */ char name[1024]; snprintf(name, sizeof(name)-1, "%s@%s", client_data->username, client_data->hostname); guac_protocol_send_name(socket, name); /* Open SSH session */ client_data->session = guac_common_ssh_create_session(client, client_data->hostname, client_data->port, client_data->user); if (client_data->session == NULL) { /* Already aborted within guac_common_ssh_create_session() */ return NULL; } pthread_mutex_init(&client_data->term_channel_lock, NULL); /* Open channel for terminal */ client_data->term_channel = libssh2_channel_open_session(client_data->session->session); if (client_data->term_channel == NULL) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, "Unable to open terminal channel."); return NULL; } #ifdef ENABLE_SSH_AGENT /* Start SSH agent forwarding, if enabled */ if (client_data->enable_agent) { libssh2_session_callback_set(client_data->session, LIBSSH2_CALLBACK_AUTH_AGENT, (void*) ssh_auth_agent_callback); /* Request agent forwarding */ if (libssh2_channel_request_auth_agent(client_data->term_channel)) guac_client_log(client, GUAC_LOG_ERROR, "Agent forwarding request failed"); else guac_client_log(client, GUAC_LOG_INFO, "Agent forwarding enabled."); } client_data->auth_agent = NULL; #endif /* Start SFTP session as well, if enabled */ if (client_data->enable_sftp) { /* Create SSH session specific for SFTP */ guac_client_log(client, GUAC_LOG_DEBUG, "Reconnecting for SFTP..."); client_data->sftp_session = guac_common_ssh_create_session(client, client_data->hostname, client_data->port, client_data->user); if (client_data->sftp_session == NULL) { /* Already aborted within guac_common_ssh_create_session() */ return NULL; } /* Request SFTP */ client_data->sftp_filesystem = guac_common_ssh_create_sftp_filesystem( client_data->sftp_session, "/"); /* Set generic (non-filesystem) file upload handler */ client->file_handler = guac_sftp_file_handler; /* Init handlers for Guacamole-specific console codes */ client_data->term->upload_path_handler = guac_sftp_set_upload_path; client_data->term->file_download_handler = guac_sftp_download_file; guac_client_log(client, GUAC_LOG_DEBUG, "SFTP session initialized"); } /* Request PTY */ if (libssh2_channel_request_pty_ex(client_data->term_channel, "linux", sizeof("linux")-1, NULL, 0, client_data->term->term_width, client_data->term->term_height, 0, 0)) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, "Unable to allocate PTY."); return NULL; } /* Request shell */ if (libssh2_channel_shell(client_data->term_channel)) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, "Unable to associate shell with PTY."); return NULL; } /* Logged in */ guac_client_log(client, GUAC_LOG_INFO, "SSH connection successful."); /* Start input thread */ if (pthread_create(&(input_thread), NULL, ssh_input_thread, (void*) client)) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Unable to start input thread"); return NULL; } /* Set non-blocking */ libssh2_session_set_blocking(client_data->session->session, 0); /* While data available, write to terminal */ int bytes_read = 0; for (;;) { /* Track total amount of data read */ int total_read = 0; pthread_mutex_lock(&(client_data->term_channel_lock)); /* Stop reading at EOF */ if (libssh2_channel_eof(client_data->term_channel)) { pthread_mutex_unlock(&(client_data->term_channel_lock)); break; } /* Read terminal data */ bytes_read = libssh2_channel_read(client_data->term_channel, buffer, sizeof(buffer)); pthread_mutex_unlock(&(client_data->term_channel_lock)); /* Attempt to write data received. Exit on failure. */ if (bytes_read > 0) { int written = guac_terminal_write_stdout(client_data->term, buffer, bytes_read); if (written < 0) break; total_read += bytes_read; } else if (bytes_read < 0 && bytes_read != LIBSSH2_ERROR_EAGAIN) break; #ifdef ENABLE_SSH_AGENT /* If agent open, handle any agent packets */ if (client_data->auth_agent != NULL) { bytes_read = ssh_auth_agent_read(client_data->auth_agent); if (bytes_read > 0) total_read += bytes_read; else if (bytes_read < 0 && bytes_read != LIBSSH2_ERROR_EAGAIN) client_data->auth_agent = NULL; } #endif /* Wait for more data if reads turn up empty */ if (total_read == 0) { fd_set fds; struct timeval timeout; FD_ZERO(&fds); FD_SET(client_data->session->fd, &fds); /* Wait for one second */ timeout.tv_sec = 1; timeout.tv_usec = 0; if (select(client_data->session->fd + 1, &fds, NULL, NULL, &timeout) < 0) break; } } /* Kill client and Wait for input thread to die */ guac_client_stop(client); pthread_join(input_thread, NULL); pthread_mutex_destroy(&client_data->term_channel_lock); guac_client_log(client, GUAC_LOG_INFO, "SSH connection ended."); return NULL; }
void* ssh_client_thread(void* data) { guac_client* client = (guac_client*) data; guac_ssh_client* ssh_client = (guac_ssh_client*) client->data; guac_ssh_settings* settings = ssh_client->settings; char buffer[8192]; pthread_t input_thread; /* Init SSH base libraries */ if (guac_common_ssh_init(client)) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "SSH library initialization failed"); return NULL; } /* Set up screen recording, if requested */ if (settings->recording_path != NULL) { guac_common_recording_create(client, settings->recording_path, settings->recording_name, settings->create_recording_path); } /* Create terminal */ ssh_client->term = guac_terminal_create(client, settings->font_name, settings->font_size, settings->resolution, settings->width, settings->height, settings->color_scheme); /* Fail if terminal init failed */ if (ssh_client->term == NULL) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Terminal initialization failed"); return NULL; } /* Set up typescript, if requested */ if (settings->typescript_path != NULL) { guac_terminal_create_typescript(ssh_client->term, settings->typescript_path, settings->typescript_name, settings->create_typescript_path); } /* Get user and credentials */ ssh_client->user = guac_ssh_get_user(client); /* Open SSH session */ ssh_client->session = guac_common_ssh_create_session(client, settings->hostname, settings->port, ssh_client->user); if (ssh_client->session == NULL) { /* Already aborted within guac_common_ssh_create_session() */ return NULL; } pthread_mutex_init(&ssh_client->term_channel_lock, NULL); /* Open channel for terminal */ ssh_client->term_channel = libssh2_channel_open_session(ssh_client->session->session); if (ssh_client->term_channel == NULL) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, "Unable to open terminal channel."); return NULL; } #ifdef ENABLE_SSH_AGENT /* Start SSH agent forwarding, if enabled */ if (ssh_client->enable_agent) { libssh2_session_callback_set(ssh_client->session, LIBSSH2_CALLBACK_AUTH_AGENT, (void*) ssh_auth_agent_callback); /* Request agent forwarding */ if (libssh2_channel_request_auth_agent(ssh_client->term_channel)) guac_client_log(client, GUAC_LOG_ERROR, "Agent forwarding request failed"); else guac_client_log(client, GUAC_LOG_INFO, "Agent forwarding enabled."); } ssh_client->auth_agent = NULL; #endif /* Start SFTP session as well, if enabled */ if (settings->enable_sftp) { /* Create SSH session specific for SFTP */ guac_client_log(client, GUAC_LOG_DEBUG, "Reconnecting for SFTP..."); ssh_client->sftp_session = guac_common_ssh_create_session(client, settings->hostname, settings->port, ssh_client->user); if (ssh_client->sftp_session == NULL) { /* Already aborted within guac_common_ssh_create_session() */ return NULL; } /* Request SFTP */ ssh_client->sftp_filesystem = guac_common_ssh_create_sftp_filesystem( ssh_client->sftp_session, "/"); /* Expose filesystem to connection owner */ guac_client_for_owner(client, guac_common_ssh_expose_sftp_filesystem, ssh_client->sftp_filesystem); /* Init handlers for Guacamole-specific console codes */ ssh_client->term->upload_path_handler = guac_sftp_set_upload_path; ssh_client->term->file_download_handler = guac_sftp_download_file; guac_client_log(client, GUAC_LOG_DEBUG, "SFTP session initialized"); } /* Request PTY */ if (libssh2_channel_request_pty_ex(ssh_client->term_channel, "linux", sizeof("linux")-1, NULL, 0, ssh_client->term->term_width, ssh_client->term->term_height, 0, 0)) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, "Unable to allocate PTY."); return NULL; } /* If a command is specified, run that instead of a shell */ if (settings->command != NULL) { if (libssh2_channel_exec(ssh_client->term_channel, settings->command)) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, "Unable to execute command."); return NULL; } } /* Otherwise, request a shell */ else if (libssh2_channel_shell(ssh_client->term_channel)) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, "Unable to associate shell with PTY."); return NULL; } /* Logged in */ guac_client_log(client, GUAC_LOG_INFO, "SSH connection successful."); /* Start input thread */ if (pthread_create(&(input_thread), NULL, ssh_input_thread, (void*) client)) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Unable to start input thread"); return NULL; } /* Set non-blocking */ libssh2_session_set_blocking(ssh_client->session->session, 0); /* While data available, write to terminal */ int bytes_read = 0; for (;;) { /* Track total amount of data read */ int total_read = 0; pthread_mutex_lock(&(ssh_client->term_channel_lock)); /* Stop reading at EOF */ if (libssh2_channel_eof(ssh_client->term_channel)) { pthread_mutex_unlock(&(ssh_client->term_channel_lock)); break; } /* Read terminal data */ bytes_read = libssh2_channel_read(ssh_client->term_channel, buffer, sizeof(buffer)); pthread_mutex_unlock(&(ssh_client->term_channel_lock)); /* Attempt to write data received. Exit on failure. */ if (bytes_read > 0) { int written = guac_terminal_write_stdout(ssh_client->term, buffer, bytes_read); if (written < 0) break; total_read += bytes_read; } else if (bytes_read < 0 && bytes_read != LIBSSH2_ERROR_EAGAIN) break; #ifdef ENABLE_SSH_AGENT /* If agent open, handle any agent packets */ if (ssh_client->auth_agent != NULL) { bytes_read = ssh_auth_agent_read(ssh_client->auth_agent); if (bytes_read > 0) total_read += bytes_read; else if (bytes_read < 0 && bytes_read != LIBSSH2_ERROR_EAGAIN) ssh_client->auth_agent = NULL; } #endif /* Wait for more data if reads turn up empty */ if (total_read == 0) { fd_set fds; struct timeval timeout; FD_ZERO(&fds); FD_SET(ssh_client->session->fd, &fds); /* Wait for one second */ timeout.tv_sec = 1; timeout.tv_usec = 0; if (select(ssh_client->session->fd + 1, &fds, NULL, NULL, &timeout) < 0) break; } } /* Kill client and Wait for input thread to die */ guac_client_stop(client); pthread_join(input_thread, NULL); pthread_mutex_destroy(&ssh_client->term_channel_lock); guac_client_log(client, GUAC_LOG_INFO, "SSH connection ended."); return NULL; }
static int ssh_new_connection(obfsproxyssh_client_session_t *session, struct sockaddr_in *addr, const char *args) { obfsproxyssh_t *state = session->client->state; char addr_buf[INET_ADDRSTRLEN]; char *cached_arg; uint32_t tmp; bstring tmp_addr; int rval; evutil_inet_ntop(AF_INET, &addr->sin_addr, addr_buf, INET_ADDRSTRLEN); tmp_addr = bformat("%s:%d", addr_buf, ntohs(addr->sin_port)); if (0 == state->unsafe_logging) { tmp = ntohl(addr->sin_addr.s_addr); tmp &= 0x000000ff; session->ssh_addr = bformat("xxx.xxx.xxx.%d:%d", tmp, ntohs(addr->sin_port)); } else { session->ssh_addr = bstrcpy(tmp_addr); } log_f(state, "SOCKS: %s SOCKS 4 CONNECT -> %s", bdata(session->socks_addr), bdata(session->ssh_addr)); cached_arg = client_arg_cache(session->client, tmp_addr, args); bdestroy(tmp_addr); rval = ssh_parse_args(session, cached_arg); if (rval) { log_f(state, "SOCKS: Error: %s Invalid arguments in CONNECT", bdata(session->socks_addr)); return -1; } /* Note: Yes, this needs defered callbacks */ session->ssh_ev = bufferevent_socket_new(state->base, -1, BEV_OPT_CLOSE_ON_FREE | BEV_OPT_DEFER_CALLBACKS); if (NULL == session->ssh_ev) { log_f(state, "SOCKS: Error: %s Failed to allocate ssh event", bdata(session->socks_addr)); return -1; } bufferevent_setcb(session->ssh_ev, NULL, NULL, ssh_event_cb, session); rval = bufferevent_socket_connect(session->ssh_ev, (struct sockaddr *) addr, sizeof (struct sockaddr_in)); if (rval < 0) { log_f(state, "SOCKS: Error: %s Failed to connect ssh socket", bdata(session->socks_addr)); return -1; } session->ssh_session = libssh2_session_init_ex(NULL, NULL, NULL, session); if (NULL == session->ssh_session) { log_f(state, "SOCKS: Error: %s Failed to initialize libssh2 session", bdata(session->socks_addr)); return -1; } libssh2_session_callback_set(session->ssh_session, LIBSSH2_CALLBACK_RECV, libssh2_recv_cb); libssh2_session_callback_set(session->ssh_session, LIBSSH2_CALLBACK_SEND, libssh2_send_cb); libssh2_session_set_blocking(session->ssh_session, 0); rval = ssh_client_profile_set(session); if (rval < 0) { log_f(state, "SOCKS: Error: Failed to enable fingerprint resistance", bdata(session->socks_addr)); return -1; } /* * This only works with debug builds of libssh2 and creates an * astronomical amount of log spam. */ #ifdef TRACE_LIBSSH2 if (1 == state->unsafe_logging) { libssh2_trace(session->ssh_session, LIBSSH2_TRACE_SOCKET | LIBSSH2_TRACE_TRANS | LIBSSH2_TRACE_KEX | LIBSSH2_TRACE_AUTH | LIBSSH2_TRACE_CONN | LIBSSH2_TRACE_ERROR); libssh2_trace_sethandler(session->ssh_session, state, libssh2_trace_cb); } #endif return 0; }