static void torture_callbacks_iterate(void **state){ struct ssh_list *list = ssh_list_new(); int v = 0, w = 0; struct ssh_channel_callbacks_struct c1 = { .channel_eof_function = cb1, .channel_shell_request_function = cb3, .userdata = &v }; struct ssh_channel_callbacks_struct c2 = { .channel_eof_function = cb1, .channel_shell_request_function = cb3, .userdata = &v }; (void)state; /* unused */ ssh_callbacks_init(&c1); ssh_callbacks_init(&c2); ssh_list_append(list, &c1); ssh_list_append(list, &c2); ssh_callbacks_iterate(list, ssh_channel_callbacks, channel_eof_function){ ssh_callbacks_iterate_exec(channel_eof_function, NULL, NULL); }
static int ssh_add_set_channel_callbacks(ssh_channel channel, ssh_channel_callbacks cb, int prepend) { ssh_session session = NULL; int rc; if (channel == NULL || cb == NULL) { return SSH_ERROR; } session = channel->session; if (is_callback_valid(session, cb)) { ssh_set_error(session, SSH_FATAL, "Invalid callback passed in (badly initialized)"); return SSH_ERROR; }; if (channel->callbacks == NULL) { channel->callbacks = ssh_list_new(); if (channel->callbacks == NULL){ ssh_set_error_oom(session); return SSH_ERROR; } } if (prepend) { rc = ssh_list_prepend(channel->callbacks, cb); } else { rc = ssh_list_append(channel->callbacks, cb); } return rc; }
/** * @brief remove the poll handle from session and assign them to a event, * when used in blocking mode. * * @param event The ssh_event object * @param session The session to add to the event. * * @returns SSH_OK on success * SSH_ERROR on failure */ int ssh_event_add_session(ssh_event event, ssh_session session) { unsigned int i; ssh_poll_handle p; #ifdef WITH_SERVER struct ssh_iterator *iterator; #endif if(event == NULL || event->ctx == NULL || session == NULL) { return SSH_ERROR; } if(session->default_poll_ctx == NULL) { return SSH_ERROR; } for(i = 0; i < session->default_poll_ctx->polls_used; i++) { p = session->default_poll_ctx->pollptrs[i]; ssh_poll_ctx_remove(session->default_poll_ctx, p); ssh_poll_ctx_add(event->ctx, p); } #ifdef WITH_SERVER iterator = ssh_list_get_iterator(event->sessions); while(iterator != NULL) { if((ssh_session)iterator->data == session) { /* allow only one instance of this session */ return SSH_OK; } iterator = iterator->next; } if(ssh_list_append(event->sessions, session) == SSH_ERROR) { return SSH_ERROR; } #endif return SSH_OK; }
/** * @internal * * @brief Add a message to the current queue of messages to be parsed and/or call * the various callback functions. * * @param[in] session The SSH session to add the message. * * @param[in] message The message to add to the queue. */ void ssh_message_queue(ssh_session session, ssh_message message){ if (message != NULL) { #ifdef WITH_SERVER int ret; /* probably not the best place to execute server callbacks, but still better * than nothing. */ ret = ssh_execute_server_callbacks(session, message); if (ret == SSH_OK){ ssh_message_free(message); return; } #endif /* WITH_SERVER */ if(session->ssh_message_callback != NULL) { ssh_execute_message_callback(session, message); return; } if (session->server_callbacks != NULL){ /* if we have server callbacks, but nothing was executed, it means we are * in non-synchronous mode, and we just don't care about the message we * received. Just send a default response. Do not queue it. */ ssh_message_reply_default(message); ssh_message_free(message); return; } if(session->ssh_message_list == NULL) { session->ssh_message_list = ssh_list_new(); } if (session->ssh_message_list != NULL) { ssh_list_append(session->ssh_message_list, message); } } }
/** @internal * @brief sets the callbacks for the packet layer */ void ssh_packet_set_callbacks(ssh_session session, ssh_packet_callbacks callbacks){ if(session->packet_callbacks == NULL){ session->packet_callbacks = ssh_list_new(); } if (session->packet_callbacks != NULL) { ssh_list_append(session->packet_callbacks, callbacks); } }
/** * @internal * * @brief Add a message to the current queue of messages to be parsed. * * @param[in] session The SSH session to add the message. * * @param[in] message The message to add to the queue. */ void ssh_message_queue(ssh_session session, ssh_message message){ if(message){ if(session->ssh_message_list == NULL){ session->ssh_message_list=ssh_list_new(); } ssh_list_append(session->ssh_message_list, message); } }
/** * @internal * * @brief Add a message to the current queue of messages to be parsed. * * @param[in] session The SSH session to add the message. * * @param[in] message The message to add to the queue. */ void ssh_message_queue(ssh_session session, ssh_message message){ if(message) { if(session->ssh_message_list == NULL) { if(session->ssh_message_callback != NULL) { ssh_execute_message_callback(session, message); return; } session->ssh_message_list = ssh_list_new(); } ssh_list_append(session->ssh_message_list, message); } }
/** * @brief remove the poll handle from session and assign them to a event, * when used in blocking mode. * * @param event The ssh_event object * @param session The session to add to the event. * * @returns SSH_OK on success * SSH_ERROR on failure */ int ssh_event_add_session(ssh_event event, ssh_session session) { ssh_poll_handle p; #ifdef WITH_SERVER struct ssh_iterator *iterator; #endif if(event == NULL || event->ctx == NULL || session == NULL) { return SSH_ERROR; } if(session->default_poll_ctx == NULL) { return SSH_ERROR; } while (session->default_poll_ctx->polls_used > 0) { p = session->default_poll_ctx->pollptrs[0]; /* * ssh_poll_ctx_remove() decrements * session->default_poll_ctx->polls_used */ ssh_poll_ctx_remove(session->default_poll_ctx, p); ssh_poll_ctx_add(event->ctx, p); /* associate the pollhandler with a session so we can put it back * at ssh_event_free() */ p->session = session; } #ifdef WITH_SERVER iterator = ssh_list_get_iterator(event->sessions); while(iterator != NULL) { if((ssh_session)iterator->data == session) { /* allow only one instance of this session */ return SSH_OK; } iterator = iterator->next; } if(ssh_list_append(event->sessions, session) == SSH_ERROR) { return SSH_ERROR; } #endif return SSH_OK; }
/** * @brief Create a new ssh session. * * @returns A new ssh_session pointer, NULL on error. */ ssh_session ssh_new(void) { ssh_session session; char *id = NULL; int rc; session = malloc(sizeof (struct ssh_session_struct)); if (session == NULL) { return NULL; } ZERO_STRUCTP(session); session->next_crypto = crypto_new(); if (session->next_crypto == NULL) { goto err; } session->socket = ssh_socket_new(session); if (session->socket == NULL) { goto err; } session->out_buffer = ssh_buffer_new(); if (session->out_buffer == NULL) { goto err; } session->in_buffer=ssh_buffer_new(); if (session->in_buffer == NULL) { goto err; } session->alive = 0; session->auth_methods = 0; ssh_set_blocking(session, 1); session->common.log_indent = 0; session->maxchannel = FIRST_CHANNEL; #ifndef _WIN32 session->agent = agent_new(session); if (session->agent == NULL) { goto err; } #endif /* _WIN32 */ /* OPTIONS */ session->opts.StrictHostKeyChecking = 1; session->opts.port = 22; session->opts.fd = -1; session->opts.ssh2 = 1; session->opts.compressionlevel=7; #ifdef WITH_SSH1 session->opts.ssh1 = 1; #else session->opts.ssh1 = 0; #endif session->opts.identity = ssh_list_new(); if (session->opts.identity == NULL) { goto err; } id = strdup("%d/id_rsa"); if (id == NULL) { goto err; } rc = ssh_list_append(session->opts.identity, id); if (rc == SSH_ERROR) { goto err; } id = strdup("%d/id_dsa"); if (id == NULL) { goto err; } rc = ssh_list_append(session->opts.identity, id); if (rc == SSH_ERROR) { goto err; } id = strdup("%d/identity"); if (id == NULL) { goto err; } rc = ssh_list_append(session->opts.identity, id); if (rc == SSH_ERROR) { goto err; } return session; err: free(id); ssh_free(session); return NULL; }
/** * @brief Create a new ssh session. * * @returns A new ssh_session pointer, NULL on error. */ ssh_session ssh_new(void) { ssh_session session; char *id = NULL; int rc; session = malloc(sizeof (struct ssh_session_struct)); if (session == NULL) { return NULL; } ZERO_STRUCTP(session); session->next_crypto = crypto_new(); if (session->next_crypto == NULL) { goto err; } session->socket = ssh_socket_new(session); if (session->socket == NULL) { goto err; } session->out_buffer = ssh_buffer_new(); if (session->out_buffer == NULL) { goto err; } session->in_buffer=ssh_buffer_new(); if (session->in_buffer == NULL) { goto err; } session->alive = 0; session->auth_methods = 0; ssh_set_blocking(session, 1); session->maxchannel = FIRST_CHANNEL; #ifndef _WIN32 session->agent = ssh_agent_new(session); if (session->agent == NULL) { goto err; } #endif /* _WIN32 */ /* OPTIONS */ session->opts.StrictHostKeyChecking = 1; session->opts.port = 0; session->opts.fd = -1; session->opts.compressionlevel=7; session->opts.nodelay = 0; session->opts.flags = SSH_OPT_FLAG_PASSWORD_AUTH | SSH_OPT_FLAG_PUBKEY_AUTH | SSH_OPT_FLAG_KBDINT_AUTH | SSH_OPT_FLAG_GSSAPI_AUTH; session->opts.identity = ssh_list_new(); if (session->opts.identity == NULL) { goto err; } id = strdup("%d/id_ed25519"); if (id == NULL) { goto err; } rc = ssh_list_append(session->opts.identity, id); if (rc == SSH_ERROR) { goto err; } #ifdef HAVE_ECC id = strdup("%d/id_ecdsa"); if (id == NULL) { goto err; } rc = ssh_list_append(session->opts.identity, id); if (rc == SSH_ERROR) { goto err; } #endif id = strdup("%d/id_rsa"); if (id == NULL) { goto err; } rc = ssh_list_append(session->opts.identity, id); if (rc == SSH_ERROR) { goto err; } #ifdef HAVE_DSA id = strdup("%d/id_dsa"); if (id == NULL) { goto err; } rc = ssh_list_append(session->opts.identity, id); if (rc == SSH_ERROR) { goto err; } #endif return session; err: free(id); ssh_free(session); return NULL; }
static void torture_callbacks_execute_list(void **state){ struct ssh_list *list = ssh_list_new(); int v = 0, w = 0; struct ssh_channel_callbacks_struct c1 = { .channel_eof_function = cb1, .userdata = &v }; struct ssh_channel_callbacks_struct c2 = { .channel_exit_status_function = cb2, .userdata = &v }; struct ssh_channel_callbacks_struct c3 = { .channel_eof_function = cb1, .channel_exit_status_function = cb2, .userdata = &w }; (void)state; ssh_callbacks_init(&c1); ssh_callbacks_init(&c2); ssh_callbacks_init(&c3); ssh_list_append(list, &c1); ssh_callbacks_execute_list(list, ssh_channel_callbacks, channel_eof_function, NULL, NULL); assert_int_equal(v, 1); v = 0; ssh_list_append(list, &c2); ssh_callbacks_execute_list(list, ssh_channel_callbacks, channel_eof_function, NULL, NULL); assert_int_equal(v, 1); ssh_callbacks_execute_list(list, ssh_channel_callbacks, channel_exit_status_function, NULL, NULL, 0); assert_int_equal(v, 11); v = 0; w = 0; ssh_list_append(list, &c3); ssh_callbacks_execute_list(list, ssh_channel_callbacks, channel_eof_function, NULL, NULL); assert_int_equal(v, 1); assert_int_equal(w, 1); ssh_callbacks_execute_list(list, ssh_channel_callbacks, channel_exit_status_function, NULL, NULL, 0); assert_int_equal(v, 11); assert_int_equal(w, 11); ssh_list_free(list); }