Ejemplo n.º 1
0
static int ssh_execute_client_request(ssh_session session, ssh_message msg)
{
    ssh_channel channel = NULL;
    int rc = SSH_AGAIN;

    if (msg->type == SSH_REQUEST_CHANNEL_OPEN
        && msg->channel_request_open.type == SSH_CHANNEL_X11
        && ssh_callbacks_exists(session->common.callbacks, channel_open_request_x11_function)) {
        channel = session->common.callbacks->channel_open_request_x11_function (session,
                msg->channel_request_open.originator,
                msg->channel_request_open.originator_port,
                session->common.callbacks->userdata);
        if (channel != NULL) {
            rc = ssh_message_channel_request_open_reply_accept_channel(msg, channel);

            return rc;
        } else {
            ssh_message_reply_default(msg);
        }

        return SSH_OK;
    }

    return rc;
}
Ejemplo n.º 2
0
static void torture_callbacks_exists(void **state) {
    struct ssh_callbacks_struct *cb = *state;

    assert_int_not_equal(ssh_callbacks_exists(cb, auth_function), 0);
    assert_int_equal(ssh_callbacks_exists(cb, log_function), 0);

    /*
     * We redefine size so auth_function is outside the range of
     * callbacks->size.
     */
    cb->size = (unsigned char *) &cb->auth_function - (unsigned char *) cb;
    assert_int_equal(ssh_callbacks_exists(cb, auth_function), 0);

    /* Now make it one pointer bigger so we spill over the auth_function slot */
    cb->size += sizeof(void *);
    assert_int_not_equal(ssh_callbacks_exists(cb, auth_function), 0);
}
Ejemplo n.º 3
0
/** @internal
 * @brief callback being called by poll when an event happens
 *
 */
static int ssh_bind_poll_callback(ssh_poll_handle sshpoll,
    socket_t fd, int revents, void *user){
  ssh_bind sshbind=(ssh_bind)user;
  (void)sshpoll;
  (void)fd;

  if(revents & POLLIN){
    /* new incoming connection */
    if(ssh_callbacks_exists(sshbind->bind_callbacks,incoming_connection)){
      sshbind->bind_callbacks->incoming_connection(sshbind,
          sshbind->bind_callbacks_userdata);
    }
  }
  return 0;
}
Ejemplo n.º 4
0
static int ssh_execute_server_request(ssh_session session, ssh_message msg)
{
    ssh_channel channel = NULL;
    int rc;

    switch(msg->type) {
        case SSH_REQUEST_AUTH:
            if (msg->auth_request.method == SSH_AUTH_METHOD_PASSWORD &&
                ssh_callbacks_exists(session->server_callbacks, auth_password_function)) {
                rc = session->server_callbacks->auth_password_function(session,
                        msg->auth_request.username, msg->auth_request.password,
                        session->server_callbacks->userdata);
                if (rc == SSH_AUTH_SUCCESS || rc == SSH_AUTH_PARTIAL) {
                    ssh_message_auth_reply_success(msg, rc == SSH_AUTH_PARTIAL);
                } else {
                    ssh_message_reply_default(msg);
                }

                return SSH_OK;
            } else if(msg->auth_request.method == SSH_AUTH_METHOD_PUBLICKEY &&
                      ssh_callbacks_exists(session->server_callbacks, auth_pubkey_function)) {
               rc = session->server_callbacks->auth_pubkey_function(session,
                       msg->auth_request.username, msg->auth_request.pubkey,
                       msg->auth_request.signature_state,
                       session->server_callbacks->userdata);
               if (rc == SSH_AUTH_SUCCESS || rc == SSH_AUTH_PARTIAL){
                   ssh_message_auth_reply_success(msg, rc == SSH_AUTH_PARTIAL);
               } else {
                   ssh_message_reply_default(msg);
               }

               return SSH_OK;
            }
            break;
        case SSH_REQUEST_CHANNEL_OPEN:
            if (msg->channel_request_open.type == SSH_CHANNEL_SESSION &&
                ssh_callbacks_exists(session->server_callbacks, channel_open_request_session_function)) {
                channel = session->server_callbacks->channel_open_request_session_function(session,
                        session->server_callbacks->userdata);
                if (channel != NULL) {
                    rc = ssh_message_channel_request_open_reply_accept_channel(msg, channel);
                    return SSH_OK;
                } else {
                    ssh_message_reply_default(msg);
                }

                return SSH_OK;
            }
            break;
        case SSH_REQUEST_CHANNEL:
            channel = msg->channel_request.channel;

            if (msg->channel_request.type == SSH_CHANNEL_REQUEST_PTY &&
                ssh_callbacks_exists(channel->callbacks, channel_pty_request_function)) {
                rc = channel->callbacks->channel_pty_request_function(session, channel,
                        msg->channel_request.TERM,
                        msg->channel_request.width, msg->channel_request.height,
                        msg->channel_request.pxwidth, msg->channel_request.pxheight,
                        channel->callbacks->userdata);
                if (rc == 0) {
                    ssh_message_channel_request_reply_success(msg);
                } else {
                    ssh_message_reply_default(msg);
                }

                return SSH_OK;
            } else if (msg->channel_request.type == SSH_CHANNEL_REQUEST_SHELL &&
                      ssh_callbacks_exists(channel->callbacks, channel_shell_request_function)) {
                rc = channel->callbacks->channel_shell_request_function(session,
                                                                        channel,
                                                                        channel->callbacks->userdata);
                if (rc == 0) {
                    ssh_message_channel_request_reply_success(msg);
                } else {
                    ssh_message_reply_default(msg);
                }

                return SSH_OK;
            } else if (msg->channel_request.type == SSH_CHANNEL_REQUEST_X11 &&
                      ssh_callbacks_exists(channel->callbacks, channel_x11_req_function)) {
                channel->callbacks->channel_x11_req_function(session,
                                                             channel,
                                                             msg->channel_request.x11_single_connection,
                                                             msg->channel_request.x11_auth_protocol,
                                                             msg->channel_request.x11_auth_cookie,
                                                             msg->channel_request.x11_screen_number,
                                                             channel->callbacks->userdata);
                ssh_message_channel_request_reply_success(msg);

                return SSH_OK;
            } else if (msg->channel_request.type == SSH_CHANNEL_REQUEST_WINDOW_CHANGE &&
                       ssh_callbacks_exists(channel->callbacks, channel_pty_window_change_function)) {
                rc = channel->callbacks->channel_pty_window_change_function(session,
                                                                            channel,
                                                                            msg->channel_request.height, msg->channel_request.width,
                                                                            msg->channel_request.pxheight, msg->channel_request.pxwidth,
                                                                            channel->callbacks->userdata);
            } else if (msg->channel_request.type == SSH_CHANNEL_REQUEST_EXEC &&
                       ssh_callbacks_exists(channel->callbacks, channel_exec_request_function)) {
                rc = channel->callbacks->channel_exec_request_function(session,
                                                                       channel,
                                                                       msg->channel_request.command,
                                                                       channel->callbacks->userdata);
                if (rc == 0) {
                    ssh_message_channel_request_reply_success(msg);
                } else {
                    ssh_message_reply_default(msg);
                }

                return SSH_OK;
            } else if (msg->channel_request.type == SSH_CHANNEL_REQUEST_ENV &&
                       ssh_callbacks_exists(channel->callbacks, channel_env_request_function)) {
                rc = channel->callbacks->channel_env_request_function(session,
                                                                      channel,
                                                                      msg->channel_request.var_name, msg->channel_request.var_value,
                                                                      channel->callbacks->userdata);
                if (rc == 0) {
                    ssh_message_channel_request_reply_success(msg);
                } else {
                    ssh_message_reply_default(msg);
                }

                return SSH_OK;
            } else if (msg->channel_request.type == SSH_CHANNEL_REQUEST_SUBSYSTEM &&
                       ssh_callbacks_exists(channel->callbacks, channel_subsystem_request_function)) {
                rc = channel->callbacks->channel_subsystem_request_function(session,
                                                                            channel,
                                                                            msg->channel_request.subsystem,
                                                                            channel->callbacks->userdata);
                if (rc == 0) {
                    ssh_message_channel_request_reply_success(msg);
                } else {
                    ssh_message_reply_default(msg);
                }

                return SSH_OK;
            }
            break;
        case SSH_REQUEST_SERVICE:
            if (ssh_callbacks_exists(session->server_callbacks, service_request_function)) {
                rc = session->server_callbacks->service_request_function(session,
                        msg->service_request.service, session->server_callbacks->userdata);
                if (rc == 0) {
                    ssh_message_reply_default(msg);
                } else {
                    ssh_disconnect(session);
                }

                return SSH_OK;
            }

            return SSH_AGAIN;
        case SSH_REQUEST_GLOBAL:
            break;
    }

    return SSH_AGAIN;
}
Ejemplo n.º 5
0
/** @internal
 * @brief handles an user authentication using GSSAPI
 */
int ssh_gssapi_handle_userauth(ssh_session session, const char *user, uint32_t n_oid, ssh_string *oids){
    char service_name[]="host";
    gss_buffer_desc name_buf;
    gss_name_t server_name; /* local server fqdn */
    OM_uint32 maj_stat, min_stat;
    unsigned int i;
    char *ptr;
    gss_OID_set supported; /* oids supported by server */
    gss_OID_set both_supported; /* oids supported by both client and server */
    gss_OID_set selected; /* oid selected for authentication */
    int present=0;
    int oid_count=0;
    struct gss_OID_desc_struct oid;
    int rc;

    if (ssh_callbacks_exists(session->server_callbacks, gssapi_select_oid_function)){
        ssh_string oid_s = session->server_callbacks->gssapi_select_oid_function(session,
                user, n_oid, oids,
                session->server_callbacks->userdata);
        if (oid_s != NULL){
            if (ssh_gssapi_init(session) == SSH_ERROR)
                return SSH_ERROR;
            session->gssapi->state = SSH_GSSAPI_STATE_RCV_TOKEN;
            rc = ssh_gssapi_send_response(session, oid_s);
            ssh_string_free(oid_s);
            return rc;
        } else {
            return ssh_auth_reply_default(session,0);
        }
    }
    gss_create_empty_oid_set(&min_stat, &both_supported);

    maj_stat = gss_indicate_mechs(&min_stat, &supported);
    for (i=0; i < supported->count; ++i){
        ptr = ssh_get_hexa(supported->elements[i].elements, supported->elements[i].length);
        SSH_LOG(SSH_LOG_DEBUG, "Supported mech %d: %s\n", i, ptr);
        free(ptr);
    }

    for (i=0 ; i< n_oid ; ++i){
        unsigned char *oid_s = (unsigned char *) ssh_string_data(oids[i]);
        size_t len = ssh_string_len(oids[i]);
        if(len < 2 || oid_s[0] != SSH_OID_TAG || ((size_t)oid_s[1]) != len - 2){
            SSH_LOG(SSH_LOG_WARNING,"GSSAPI: received invalid OID");
            continue;
        }
        oid.elements = &oid_s[2];
        oid.length = len - 2;
        gss_test_oid_set_member(&min_stat,&oid,supported,&present);
        if(present){
            gss_add_oid_set_member(&min_stat,&oid,&both_supported);
            oid_count++;
        }
    }
    gss_release_oid_set(&min_stat, &supported);
    if (oid_count == 0){
        SSH_LOG(SSH_LOG_PROTOCOL,"GSSAPI: no OID match");
        ssh_auth_reply_default(session, 0);
        gss_release_oid_set(&min_stat, &both_supported);
        return SSH_OK;
    }
    /* from now we have room for context */
    if (ssh_gssapi_init(session) == SSH_ERROR)
        return SSH_ERROR;

    name_buf.value = service_name;
    name_buf.length = strlen(name_buf.value) + 1;
    maj_stat = gss_import_name(&min_stat, &name_buf,
            (gss_OID) GSS_C_NT_HOSTBASED_SERVICE, &server_name);
    if (maj_stat != GSS_S_COMPLETE) {
        SSH_LOG(SSH_LOG_WARNING, "importing name %d, %d", maj_stat, min_stat);
        ssh_gssapi_log_error(SSH_LOG_WARNING, "importing name", maj_stat);
        return -1;
    }

    maj_stat = gss_acquire_cred(&min_stat, server_name, 0,
            both_supported, GSS_C_ACCEPT,
            &session->gssapi->server_creds, &selected, NULL);
    gss_release_name(&min_stat, &server_name);
    gss_release_oid_set(&min_stat, &both_supported);

    if (maj_stat != GSS_S_COMPLETE) {
        SSH_LOG(SSH_LOG_WARNING, "error acquiring credentials %d, %d", maj_stat, min_stat);
        ssh_gssapi_log_error(SSH_LOG_WARNING, "acquiring creds", maj_stat);
        ssh_auth_reply_default(session,0);
        return SSH_ERROR;
    }

    SSH_LOG(SSH_LOG_PROTOCOL, "acquiring credentials %d, %d", maj_stat, min_stat);

    /* finding which OID from client we selected */
    for (i=0 ; i< n_oid ; ++i){
        unsigned char *oid_s = (unsigned char *) ssh_string_data(oids[i]);
        size_t len = ssh_string_len(oids[i]);
        if(len < 2 || oid_s[0] != SSH_OID_TAG || ((size_t)oid_s[1]) != len - 2){
            SSH_LOG(SSH_LOG_WARNING,"GSSAPI: received invalid OID");
            continue;
        }
        oid.elements = &oid_s[2];
        oid.length = len - 2;
        gss_test_oid_set_member(&min_stat,&oid,selected,&present);
        if(present){
            SSH_LOG(SSH_LOG_PACKET, "Selected oid %d", i);
            break;
        }
    }
    session->gssapi->mech.length = oid.length;
    session->gssapi->mech.elements = malloc(oid.length);
    if (session->gssapi->mech.elements == NULL){
        ssh_set_error_oom(session);
        return SSH_ERROR;
    }
    memcpy(session->gssapi->mech.elements, oid.elements, oid.length);
    gss_release_oid_set(&min_stat, &selected);
    session->gssapi->user = strdup(user);
    session->gssapi->service = service_name;
    session->gssapi->state = SSH_GSSAPI_STATE_RCV_TOKEN;
    return ssh_gssapi_send_response(session, oids[i]);
}