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; }
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); }
/** @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; }
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; }
/** @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]); }