Example #1
0
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);
    }
Example #2
0
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;
}
Example #3
0
/**
 * @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;
}
Example #4
0
/**
 * @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);
        }
    }
}
Example #5
0
/** @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);
  }
}
Example #6
0
/**
 * @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);
  }
}
Example #7
0
/**
 * @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);
    }
}
Example #8
0
/**
 * @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;
}
Example #9
0
/**
 * @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;
}
Example #10
0
/**
 * @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;
}
Example #11
0
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);

}