Ejemplo n.º 1
0
/**
 * @internal
 *
 * @brief Pop a message from the message list and dequeue it.
 *
 * @param[in]  session  The SSH session to pop the message.
 *
 * @returns             The head message or NULL if it doesn't exist.
 */
ssh_message ssh_message_pop_head(ssh_session session){
  ssh_message msg=NULL;
  struct ssh_iterator *i;
  if(session->ssh_message_list == NULL)
    return NULL;
  i=ssh_list_get_iterator(session->ssh_message_list);
  if(i != NULL){
    msg=ssh_iterator_value(ssh_message,i);
    ssh_list_remove(session->ssh_message_list,i);
  }
  return msg;
}
Ejemplo n.º 2
0
/**
 * @brief  Remove a session object from an event context.
 *
 * @param  event        The ssh_event object.
 * @param  session      The session to remove.
 *
 * @returns SSH_OK      on success
 *          SSH_ERROR   on failure
 */
int ssh_event_remove_session(ssh_event event, ssh_session session) {
    ssh_poll_handle p;
    register size_t i, used;
    int rc = SSH_ERROR;
#ifdef WITH_SERVER
    struct ssh_iterator *iterator;
#endif

    if(event == NULL || event->ctx == NULL || session == NULL) {
        return SSH_ERROR;
    }

    used = event->ctx->polls_used;
    for(i = 0; i < used; i++) {
    	p = event->ctx->pollptrs[i];
    	if(p->session == session){
            /*
             * ssh_poll_ctx_remove() decrements
             * event->ctx->polls_used
             */
            ssh_poll_ctx_remove(event->ctx, p);
            p->session = NULL;
            ssh_poll_ctx_add(session->default_poll_ctx, p);
            rc = SSH_OK;
            /*
             * Restart the loop!
             * A session can initially have two pollhandlers.
             */
            used = event->ctx->polls_used;
            i = 0;

        }
    }
#ifdef WITH_SERVER
    iterator = ssh_list_get_iterator(event->sessions);
    while(iterator != NULL) {
        if((ssh_session)iterator->data == session) {
            ssh_list_remove(event->sessions, iterator);
            /* there should be only one instance of this session */
            break;
        }
        iterator = iterator->next;
    }
#endif

    return rc;
}
Ejemplo n.º 3
0
int ssh_remove_channel_callbacks(ssh_channel channel, ssh_channel_callbacks cb)
{
    struct ssh_iterator *it;

    if (channel == NULL || channel->callbacks == NULL){
        return SSH_ERROR;
    }

    it = ssh_list_find(channel->callbacks, cb);
    if (it == NULL){
        return SSH_ERROR;
    }

    ssh_list_remove(channel->callbacks, it);

    return SSH_OK;
}
Ejemplo n.º 4
0
/**
 * @brief  Remove a session object from an event context.
 *
 * @param  event        The ssh_event object.
 * @param  session      The session to remove.
 *
 * @returns SSH_OK      on success
 *          SSH_ERROR   on failure
 */
int ssh_event_remove_session(ssh_event event, ssh_session session) {
    ssh_poll_handle p;
    register size_t i, used;
    int rc = SSH_ERROR;
    socket_t session_fd;
#ifdef WITH_SERVER
    struct ssh_iterator *iterator;
#endif

    if(event == NULL || event->ctx == NULL || session == NULL) {
        return SSH_ERROR;
    }

    session_fd = ssh_get_fd(session);
    used = event->ctx->polls_used;
    for(i = 0; i < used; i++) {
        if(session_fd == event->ctx->pollfds[i].fd) {
            p = event->ctx->pollptrs[i];
            ssh_poll_ctx_remove(event->ctx, p);
            ssh_poll_ctx_add(session->default_poll_ctx, p);
            rc = SSH_OK;
        }
    }
#ifdef WITH_SERVER
    iterator = ssh_list_get_iterator(event->sessions);
    while(iterator != NULL) {
        if((ssh_session)iterator->data == session) {
            ssh_list_remove(event->sessions, iterator);
            /* there should be only one instance of this session */
            break;
        }
        iterator = iterator->next;
    }
#endif

    return rc;
}
Ejemplo n.º 5
0
/**
 * @brief Disconnect from a session (client or server).
 * The session can then be reused to open a new session.
 *
 * @param[in]  session  The SSH session to use.
 */
void ssh_disconnect(ssh_session session) {
  ssh_string str = NULL;
  struct ssh_iterator *it;

  if (session == NULL) {
    return;
  }

  if (session->socket != NULL && ssh_socket_is_open(session->socket)) {
    if (buffer_add_u8(session->out_buffer, SSH2_MSG_DISCONNECT) < 0) {
      goto error;
    }
    if (buffer_add_u32(session->out_buffer,
          htonl(SSH2_DISCONNECT_BY_APPLICATION)) < 0) {
      goto error;
    }

    str = ssh_string_from_char("Bye Bye");
    if (str == NULL) {
      goto error;
    }

    if (buffer_add_ssh_string(session->out_buffer,str) < 0) {
      ssh_string_free(str);
      goto error;
    }
    ssh_string_free(str);

    packet_send(session);
    ssh_socket_close(session->socket);
  }
error:
  session->alive = 0;
  if (session->socket != NULL){
    ssh_socket_reset(session->socket);
  }
  session->opts.fd = SSH_INVALID_SOCKET;
  session->session_state=SSH_SESSION_STATE_DISCONNECTED;

  while ((it=ssh_list_get_iterator(session->channels)) != NULL) {
    ssh_channel_do_free(ssh_iterator_value(ssh_channel,it));
    ssh_list_remove(session->channels, it);
  }
  if(session->current_crypto){
    crypto_free(session->current_crypto);
    session->current_crypto=NULL;
  }
  if (session->in_buffer) {
    ssh_buffer_reinit(session->in_buffer);
  }
  if (session->out_buffer) {
    ssh_buffer_reinit(session->out_buffer);
  }
  if (session->in_hashbuf) {
    ssh_buffer_reinit(session->in_hashbuf);
  }
  if (session->out_hashbuf) {
    ssh_buffer_reinit(session->out_hashbuf);
  }
  session->auth_methods = 0;
  SAFE_FREE(session->serverbanner);
  SAFE_FREE(session->clientbanner);

  if(session->ssh_message_list){
    ssh_message msg;
    while((msg=ssh_list_pop_head(ssh_message ,session->ssh_message_list))
        != NULL){
      ssh_message_free(msg);
    }
    ssh_list_free(session->ssh_message_list);
    session->ssh_message_list=NULL;
  }

  if (session->packet_callbacks){
    ssh_list_free(session->packet_callbacks);
    session->packet_callbacks=NULL;
  }
}
Ejemplo n.º 6
0
/**
 * @brief Deallocate a SSH session handle.
 *
 * @param[in] session   The SSH session to free.
 *
 * @see ssh_disconnect()
 * @see ssh_new()
 */
void ssh_free(ssh_session session) {
  int i;
  struct ssh_iterator *it;

  if (session == NULL) {
    return;
  }

  /*
   * Delete all channels
   *
   * This needs the first thing we clean up cause if there is still an open
   * channel we call ssh_channel_close() first. So we need a working socket
   * and poll context for it.
   */
  for (it = ssh_list_get_iterator(session->channels);
       it != NULL;
       it = ssh_list_get_iterator(session->channels)) {
      ssh_channel_do_free(ssh_iterator_value(ssh_channel,it));
      ssh_list_remove(session->channels, it);
  }
  ssh_list_free(session->channels);
  session->channels = NULL;

#ifdef WITH_PCAP
  if (session->pcap_ctx) {
      ssh_pcap_context_free(session->pcap_ctx);
      session->pcap_ctx = NULL;
  }
#endif

  ssh_socket_free(session->socket);
  session->socket = NULL;

  if (session->default_poll_ctx) {
      ssh_poll_ctx_free(session->default_poll_ctx);
  }

  ssh_buffer_free(session->in_buffer);
  ssh_buffer_free(session->out_buffer);
  session->in_buffer = session->out_buffer = NULL;

  if (session->in_hashbuf != NULL) {
      ssh_buffer_free(session->in_hashbuf);
  }
  if (session->out_hashbuf != NULL) {
      ssh_buffer_free(session->out_hashbuf);
  }

  crypto_free(session->current_crypto);
  crypto_free(session->next_crypto);

#ifndef _WIN32
  agent_free(session->agent);
#endif /* _WIN32 */

  ssh_key_free(session->srv.dsa_key);
  ssh_key_free(session->srv.rsa_key);

  if (session->ssh_message_list) {
      ssh_message msg;

      for (msg = ssh_list_pop_head(ssh_message, session->ssh_message_list);
           msg != NULL;
           msg = ssh_list_pop_head(ssh_message, session->ssh_message_list)) {
          ssh_message_free(msg);
      }
      ssh_list_free(session->ssh_message_list);
  }

  if (session->packet_callbacks) {
    ssh_list_free(session->packet_callbacks);
  }

  /* options */
  if (session->opts.identity) {
      char *id;

      for (id = ssh_list_pop_head(char *, session->opts.identity);
           id != NULL;
           id = ssh_list_pop_head(char *, session->opts.identity)) {
          SAFE_FREE(id);
      }
      ssh_list_free(session->opts.identity);
  }
Ejemplo n.º 7
0
static void torture_knownhosts_precheck(void **state)
{
    struct torture_state *s = *state;
    ssh_session session = s->ssh.session;
    struct ssh_list *algo_list = NULL;
    struct ssh_iterator *it = NULL;
    size_t algo_count;
    const char *algo = NULL;
    char known_hosts_file[1024] = {0};
    FILE *file;
    int rc;

    snprintf(known_hosts_file,
             sizeof(known_hosts_file),
             "%s/%s",
             s->socket_dir,
             TORTURE_KNOWN_HOSTS_FILE);

    file = fopen(known_hosts_file, "w");
    assert_non_null(file);
    fprintf(file,
            "127.0.0.10 %s\n",
            torture_get_testkey_pub(SSH_KEYTYPE_RSA));

    fprintf(file,
            "127.0.0.10 %s\n",
            torture_get_testkey_pub(SSH_KEYTYPE_ED25519));

    fprintf(file,
            "127.0.0.10 %s\n",
            torture_get_testkey_pub(SSH_KEYTYPE_ECDSA_P521));

    fclose(file);

    rc = ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, known_hosts_file);
    assert_ssh_return_code(session, rc);

    algo_list = ssh_known_hosts_get_algorithms(session);
    assert_non_null(algo_list);

    algo_count = ssh_list_count(algo_list);
    assert_int_equal(algo_count, 3);

    it = ssh_list_get_iterator(algo_list);
    assert_non_null(it);
    algo = ssh_iterator_value(const char *, it);
    assert_string_equal(algo, "ssh-rsa");

    ssh_list_remove(algo_list, it);

    it = ssh_list_get_iterator(algo_list);
    assert_non_null(it);
    algo = ssh_iterator_value(const char *, it);
    assert_string_equal(algo, "ssh-ed25519");

    ssh_list_remove(algo_list, it);

    it = ssh_list_get_iterator(algo_list);
    assert_non_null(it);
    algo = ssh_iterator_value(const char *, it);
    assert_string_equal(algo, "ecdsa-sha2-nistp521");

    ssh_list_free(algo_list);
}
Ejemplo n.º 8
0
/**
 * @brief Disconnect from a session (client or server).
 * The session can then be reused to open a new session.
 *
 * @param[in]  session  The SSH session to use.
 */
void ssh_disconnect(ssh_session session) {
  struct ssh_iterator *it;
  int rc;

  if (session == NULL) {
    return;
  }

  if (session->socket != NULL && ssh_socket_is_open(session->socket)) {
    rc = ssh_buffer_pack(session->out_buffer,
                         "bdss",
                         SSH2_MSG_DISCONNECT,
                         SSH2_DISCONNECT_BY_APPLICATION,
                         "Bye Bye",
                         ""); /* language tag */
    if (rc != SSH_OK){
      ssh_set_error_oom(session);
      goto error;
    }

    ssh_packet_send(session);
    ssh_socket_close(session->socket);
  }
error:
  session->recv_seq = 0;
  session->send_seq = 0;
  session->alive = 0;
  if (session->socket != NULL){
    ssh_socket_reset(session->socket);
  }
  session->opts.fd = SSH_INVALID_SOCKET;
  session->session_state=SSH_SESSION_STATE_DISCONNECTED;

  while ((it=ssh_list_get_iterator(session->channels)) != NULL) {
    ssh_channel_do_free(ssh_iterator_value(ssh_channel,it));
    ssh_list_remove(session->channels, it);
  }
  if(session->current_crypto){
    crypto_free(session->current_crypto);
    session->current_crypto=NULL;
  }
  if (session->next_crypto) {
    crypto_free(session->next_crypto);
    session->next_crypto = crypto_new();
    if (session->next_crypto == NULL) {
      ssh_set_error_oom(session);
    }
  }
  if (session->in_buffer) {
    ssh_buffer_reinit(session->in_buffer);
  }
  if (session->out_buffer) {
    ssh_buffer_reinit(session->out_buffer);
  }
  if (session->in_hashbuf) {
    ssh_buffer_reinit(session->in_hashbuf);
  }
  if (session->out_hashbuf) {
    ssh_buffer_reinit(session->out_hashbuf);
  }
  session->auth.supported_methods = 0;
  SAFE_FREE(session->serverbanner);
  SAFE_FREE(session->clientbanner);

  if(session->ssh_message_list){
    ssh_message msg;
    while((msg=ssh_list_pop_head(ssh_message ,session->ssh_message_list))
        != NULL){
      ssh_message_free(msg);
    }
    ssh_list_free(session->ssh_message_list);
    session->ssh_message_list=NULL;
  }

  if (session->packet_callbacks){
    ssh_list_free(session->packet_callbacks);
    session->packet_callbacks=NULL;
  }
}