static int channel_open_callback (ssh_session session, ssh_message message, gpointer user_data) { ssh_channel *channel = user_data; /* wait for a channel session */ switch (ssh_message_type (message)) { case SSH_REQUEST_CHANNEL_OPEN: switch (ssh_message_subtype (message)) { case SSH_CHANNEL_SESSION: goto accept; default: goto deny; } default: goto deny; } deny: return 1; accept: ssh_set_message_callback (state.session, channel_request_callback, NULL); *channel = ssh_message_channel_request_open_reply_accept (message); return 0; }
static int authenticate_callback (ssh_session session, ssh_message message, gpointer user_data) { switch (ssh_message_type (message)) { case SSH_REQUEST_AUTH: switch (ssh_message_subtype (message)) { case SSH_AUTH_METHOD_PASSWORD: if ((auth_methods & SSH_AUTH_METHOD_PASSWORD) && auth_password (ssh_message_auth_user (message), ssh_message_auth_password (message))) goto accept; ssh_message_auth_set_methods (message, auth_methods); goto deny; case SSH_AUTH_METHOD_PUBLICKEY: if (auth_methods & SSH_AUTH_METHOD_PUBLICKEY) { int result = auth_publickey (message); if (result == 1) { goto accept; } else if (result == 0) { ssh_message_auth_reply_pk_ok_simple (message); return 0; } } ssh_message_auth_set_methods (message, auth_methods); goto deny; case SSH_AUTH_METHOD_NONE: default: ssh_message_auth_set_methods (message, auth_methods); goto deny; } default: ssh_message_auth_set_methods (message, auth_methods); goto deny; } deny: return 1; accept: ssh_set_message_callback (state.session, channel_open_callback, &state.channel); ssh_message_auth_reply_success (message, 0); return 0; }
void tmate_client_pty_init(struct tmate_session *session) { struct tmate_ssh_client *client = &session->ssh_client; ioctl(session->pty, TIOCSWINSZ, &session->ssh_client.winsize_pty); memset(&client->channel_cb, 0, sizeof(client->channel_cb)); ssh_callbacks_init(&client->channel_cb); client->channel_cb.userdata = session; client->channel_cb.channel_data_function = on_ssh_channel_read, ssh_set_channel_callbacks(client->channel, &client->channel_cb); ssh_set_message_callback(session->ssh_client.session, on_ssh_message_callback, session); setblocking(session->pty, 0); event_set(&session->ev_pty, session->pty, EV_READ | EV_PERSIST, __on_pty_event, session); event_add(&session->ev_pty, NULL); tmate_add_ssh_latency_callback(client, on_latency_callback, session); }
static gint mock_ssh_server (const gchar *server_addr, gint server_port, const gchar *user, const gchar *password, gboolean multi_step) { char portname[16]; char addrname[16]; struct sockaddr_storage addr; socklen_t addrlen; ssh_bind sshbind; const char *msg; int r; gint rounds = 0; state.event = ssh_event_new (); if (state.event == NULL) g_return_val_if_reached (-1); sshbind = ssh_bind_new (); state.session = ssh_new (); if (server_addr == NULL) server_addr = "127.0.0.1"; ssh_bind_options_set (sshbind, SSH_BIND_OPTIONS_BINDADDR, server_addr); ssh_bind_options_set (sshbind, SSH_BIND_OPTIONS_BINDPORT, &server_port); ssh_bind_options_set (sshbind, SSH_BIND_OPTIONS_RSAKEY, SRCDIR "/src/ws/mock_rsa_key"); ssh_bind_options_set (sshbind, SSH_BIND_OPTIONS_DSAKEY, SRCDIR "/src/ws/mock_dsa_key"); if (ssh_bind_listen (sshbind) < 0) { g_critical ("couldn't listen on socket: %s", ssh_get_error (sshbind)); return 1; } state.bind_fd = ssh_bind_get_fd (sshbind); state.user = user; state.password = password; state.multi_step = multi_step; ssh_pki_import_pubkey_file (SRCDIR "/src/ws/test_rsa.pub", &state.pkey); state.buffer = g_byte_array_new (); /* Print out the port */ if (server_port == 0) { addrlen = sizeof (addr); if (getsockname (state.bind_fd, (struct sockaddr *)&addr, &addrlen) < 0) { g_critical ("couldn't get local address: %s", g_strerror (errno)); return 1; } r = getnameinfo ((struct sockaddr *)&addr, addrlen, addrname, sizeof (addrname), portname, sizeof (portname), NI_NUMERICHOST | NI_NUMERICSERV); if (r != 0) { g_critical ("couldn't get local port: %s", gai_strerror (r)); return 1; } /* Caller wants to know the port */ g_print ("%s\n", portname); } /* Close stdout (once above info is printed) */ close (1); ssh_set_message_callback (state.session, authenticate_callback, &rounds); r = ssh_bind_accept (sshbind, state.session); if (r == SSH_ERROR) { g_critical ("accepting connection failed: %s", ssh_get_error (sshbind)); return 1; } state.session_fd = ssh_get_fd (state.session); if (ssh_handle_key_exchange (state.session)) { msg = ssh_get_error (state.session); if (!strstr (msg, "_DISCONNECT")) g_critical ("key exchange failed: %s", msg); return 1; } if (ssh_event_add_session (state.event, state.session) != SSH_OK) g_return_val_if_reached (-1); do { ssh_event_dopoll (state.event, 10000); } while (ssh_is_connected (state.session)); ssh_event_remove_session (state.event, state.session); ssh_event_free (state.event); ssh_free (state.session); ssh_key_free (state.pkey); g_byte_array_free (state.buffer, TRUE); ssh_bind_free (sshbind); return 0; }
void set_session_message_callback(ssh_session session, void *userdata) { ssh_set_message_callback(session, bind_message_callback, userdata); }
int main(int argc, char **argv){ ssh_session session; ssh_bind sshbind; struct ssh_server_callbacks_struct cb = { .userdata = NULL, .auth_password_function = auth_password, .auth_gssapi_mic_function = auth_gssapi_mic, .channel_open_request_session_function = new_session_channel, .service_request_function = service_request }; struct ssh_callbacks_struct cb_gen = { .userdata = NULL, .global_request_function = global_request }; int ret = 1; sshbind = ssh_bind_new(); session = ssh_new(); mainloop = ssh_event_new(); ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, KEYS_FOLDER "ssh_host_dsa_key"); ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, KEYS_FOLDER "ssh_host_rsa_key"); #ifdef HAVE_ARGP_H /* * Parse our arguments; every option seen by parse_opt will * be reflected in arguments. */ argp_parse (&argp, argc, argv, 0, 0, sshbind); #else (void)argc; (void)argv; #endif if (ssh_bind_listen(sshbind) < 0) { printf("Error listening to socket: %s\n", ssh_get_error(sshbind)); return 1; } if (ssh_bind_accept(sshbind, session) == SSH_ERROR) { printf("error accepting a connection : %s\n", ssh_get_error(sshbind)); ret = 1; goto shutdown; } ssh_callbacks_init(&cb); ssh_callbacks_init(&cb_gen); ssh_set_server_callbacks(session, &cb); ssh_set_callbacks(session, &cb_gen); ssh_set_message_callback(session, message_callback, (void *)NULL); if (ssh_handle_key_exchange(session)) { printf("ssh_handle_key_exchange: %s\n", ssh_get_error(session)); ret = 1; goto shutdown; } ssh_set_auth_methods(session, SSH_AUTH_METHOD_PASSWORD | SSH_AUTH_METHOD_GSSAPI_MIC); ssh_event_add_session(mainloop, session); while (!authenticated) { if (error_set) { break; } if (ssh_event_dopoll(mainloop, -1) == SSH_ERROR) { printf("Error : %s\n", ssh_get_error(session)); ret = 1; goto shutdown; } } if (error_set) { printf("Error, exiting loop\n"); } else { printf("Authenticated and got a channel\n"); while (!error_set) { if (ssh_event_dopoll(mainloop, 100) == SSH_ERROR) { printf("Error : %s\n", ssh_get_error(session)); ret = 1; goto shutdown; } do_cleanup(&cleanup_stack); } } shutdown: ssh_disconnect(session); ssh_bind_free(sshbind); ssh_finalize(); return ret; }