static int message_callback(ssh_session session, ssh_message message, void *userdata) { ssh_channel channel; int socket_fd, *pFd; struct ssh_channel_callbacks_struct *cb_chan; struct event_fd_data_struct *event_fd_data; (void)session; (void)message; (void)userdata; _ssh_log(SSH_LOG_PACKET, "=== message_callback", "Message type: %d", ssh_message_type(message)); _ssh_log(SSH_LOG_PACKET, "=== message_callback", "Message Subtype: %d", ssh_message_subtype(message)); if (ssh_message_type(message) == SSH_REQUEST_CHANNEL_OPEN) { _ssh_log(SSH_LOG_PROTOCOL, "=== message_callback", "channel_request_open"); if (ssh_message_subtype(message) == SSH_CHANNEL_DIRECT_TCPIP) { channel = ssh_message_channel_request_open_reply_accept(message); if (channel == NULL) { _ssh_log(SSH_LOG_WARNING, "=== message_callback", "Accepting direct-tcpip channel failed!"); return 1; } else { _ssh_log(SSH_LOG_PROTOCOL, "=== message_callback", "Connected to channel!"); socket_fd = open_tcp_socket(message); if (-1 == socket_fd) { return 1; } pFd = malloc(sizeof *pFd); cb_chan = malloc(sizeof *cb_chan); event_fd_data = malloc(sizeof *event_fd_data); (*pFd) = socket_fd; event_fd_data->channel = channel; event_fd_data->p_fd = pFd; event_fd_data->stacked = 0; event_fd_data->cb_chan = cb_chan; cb_chan->userdata = event_fd_data; cb_chan->channel_eof_function = my_channel_eof_function; cb_chan->channel_close_function = my_channel_close_function; cb_chan->channel_data_function = my_channel_data_function; cb_chan->channel_exit_status_function = my_channel_exit_status_function; ssh_callbacks_init(cb_chan); ssh_set_channel_callbacks(channel, cb_chan); ssh_event_add_fd(mainloop, (socket_t)*pFd, POLLIN, my_fd_data_function, event_fd_data); return 0; } } } return 1; }
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 channel_request_callback (ssh_session session, ssh_message message, gpointer user_data) { const gchar *cmd; /* wait for a shell */ switch (ssh_message_type (message)) { case SSH_REQUEST_CHANNEL: switch (ssh_message_subtype (message)) { case SSH_CHANNEL_REQUEST_SHELL: if (do_shell (state.event, state.channel) < 0) goto deny; goto accept_end; case SSH_CHANNEL_REQUEST_EXEC: cmd = ssh_message_channel_request_command (message); if (do_exec (state.event, state.channel, cmd) < 0) goto deny; goto accept_end; case SSH_CHANNEL_REQUEST_PTY: case SSH_CHANNEL_REQUEST_ENV: goto accept; default: g_message ("message subtype unknown: %d", ssh_message_subtype (message)); goto deny; } default: g_message ("message type unknown: %d", ssh_message_type (message)); goto deny; } deny: return 1; accept_end: accept: ssh_message_channel_request_reply_success (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; }
CHANNEL *recv_channel(SSH_SESSION *session){ CHANNEL *chan=NULL; SSH_MESSAGE *message; int sftp=0; do { message=ssh_message_get(session); if(message){ switch(ssh_message_type(message)){ case SSH_CHANNEL_REQUEST_OPEN: if(ssh_message_subtype(message)==SSH_CHANNEL_SESSION){ chan=ssh_message_channel_request_open_reply_accept(message); break; } default: ssh_message_reply_default(message); } ssh_message_free(message); } } while(message && !chan); if(!chan) return NULL; do { message=ssh_message_get(session); if(message && ssh_message_type(message)==SSH_CHANNEL_REQUEST && ssh_message_subtype(message)==SSH_CHANNEL_REQUEST_SUBSYSTEM){ if(!strcmp(ssh_message_channel_request_subsystem(message),"sftp")){ sftp=1; ssh_message_channel_request_reply_success(message); break; } } if(!sftp){ ssh_message_reply_default(message); } ssh_message_free(message); } while (message && !sftp); if(!message) return NULL; return chan; }
static int authenticate(ssh_session session) { ssh_message message; do { message=ssh_message_get(session); if(!message) break; switch(ssh_message_type(message)){ case SSH_REQUEST_AUTH: switch(ssh_message_subtype(message)){ case SSH_AUTH_METHOD_PASSWORD: printf("User %s wants to auth with pass %s\n", ssh_message_auth_user(message), ssh_message_auth_password(message)); if(auth_password(ssh_message_auth_user(message), ssh_message_auth_password(message))){ ssh_message_auth_reply_success(message,0); ssh_message_free(message); return 1; } ssh_message_auth_set_methods(message, SSH_AUTH_METHOD_PASSWORD | SSH_AUTH_METHOD_INTERACTIVE); // not authenticated, send default message ssh_message_reply_default(message); break; case SSH_AUTH_METHOD_NONE: default: printf("User %s wants to auth with unknown auth %d\n", ssh_message_auth_user(message), ssh_message_subtype(message)); ssh_message_auth_set_methods(message, SSH_AUTH_METHOD_PASSWORD | SSH_AUTH_METHOD_INTERACTIVE); ssh_message_reply_default(message); break; } break; default: ssh_message_auth_set_methods(message, SSH_AUTH_METHOD_PASSWORD | SSH_AUTH_METHOD_INTERACTIVE); ssh_message_reply_default(message); } ssh_message_free(message); } while (1); return 0; }
static int on_ssh_message_callback(__unused ssh_session _session, ssh_message msg, void *arg) { struct tmate_session *session = arg; if (ssh_message_type(msg) == SSH_REQUEST_CHANNEL && ssh_message_subtype(msg) == SSH_CHANNEL_REQUEST_WINDOW_CHANGE) { struct winsize ws; ws.ws_col = ssh_message_channel_request_pty_width(msg); ws.ws_row = ssh_message_channel_request_pty_height(msg); ioctl(session->pty, TIOCSWINSZ, &ws); client_signal(SIGWINCH); return 1; } return 0; }
// Listen for incoming SSH connections. // When a connection is established, write all data received to stdout. void server_pipe(char *host, int port) { ssh_bind b = ssh_bind_new(); ssh_session s = ssh_new(); ssh_bind_options_set(b, SSH_BIND_OPTIONS_BINDADDR, host); ssh_bind_options_set(b, SSH_BIND_OPTIONS_BINDPORT, &port); ssh_bind_options_set(b, SSH_BIND_OPTIONS_RSAKEY, "test-server-key"); ssh_bind_options_set(b, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR, "5"); if(ssh_bind_listen(b) < 0) session_error(b, "listen"); if(ssh_bind_accept(b, s) != SSH_OK) session_error(b, "accept"); if(ssh_accept(s) < 0) session_error(s, "handshake"); int state = SERVER_CONNECTED; while(1) { ssh_message m = ssh_message_get(s); if(m) { int type = ssh_message_type(m); int subtype = ssh_message_subtype(m); ssh_message_auth_set_methods(m, SSH_AUTH_METHOD_PUBLICKEY); server_handle_message(s, m, type, subtype, &state); ssh_message_free(m); if(state == SERVER_CLOSED) { ssh_disconnect(s); ssh_bind_free(b); ssh_finalize(); return; } } else { session_error(s, "session"); } } }
int main(int argc, char **argv){ ssh_session session; ssh_bind sshbind; ssh_message message; ssh_channel chan=0; char buf[2048]; int auth=0; int sftp=0; int i; int r; sshbind=ssh_bind_new(); session=ssh_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 #ifdef WITH_PCAP set_pcap(session); #endif if(ssh_bind_listen(sshbind)<0){ printf("Error listening to socket: %s\n",ssh_get_error(sshbind)); return 1; } r=ssh_bind_accept(sshbind,session); if(r==SSH_ERROR){ printf("error accepting a connection : %s\n",ssh_get_error(sshbind)); return 1; } if (ssh_handle_key_exchange(session)) { printf("ssh_handle_key_exchange: %s\n", ssh_get_error(session)); return 1; } do { message=ssh_message_get(session); if(!message) break; switch(ssh_message_type(message)){ case SSH_REQUEST_AUTH: switch(ssh_message_subtype(message)){ case SSH_AUTH_METHOD_PASSWORD: printf("User %s wants to auth with pass %s\n", ssh_message_auth_user(message), ssh_message_auth_password(message)); if(auth_password(ssh_message_auth_user(message), ssh_message_auth_password(message))){ auth=1; ssh_message_auth_reply_success(message,0); break; } // not authenticated, send default message case SSH_AUTH_METHOD_NONE: default: ssh_message_auth_set_methods(message,SSH_AUTH_METHOD_PASSWORD); ssh_message_reply_default(message); break; } break; default: ssh_message_reply_default(message); } ssh_message_free(message); } while (!auth); if(!auth){ printf("auth error: %s\n",ssh_get_error(session)); ssh_disconnect(session); return 1; } do { message=ssh_message_get(session); if(message){ switch(ssh_message_type(message)){ case SSH_REQUEST_CHANNEL_OPEN: if(ssh_message_subtype(message)==SSH_CHANNEL_SESSION){ chan=ssh_message_channel_request_open_reply_accept(message); break; } default: ssh_message_reply_default(message); } ssh_message_free(message); } } while(message && !chan); if(!chan){ printf("error : %s\n",ssh_get_error(session)); ssh_finalize(); return 1; } do { message=ssh_message_get(session); if(message && ssh_message_type(message)==SSH_REQUEST_CHANNEL && ssh_message_subtype(message)==SSH_CHANNEL_REQUEST_SHELL){ // if(!strcmp(ssh_message_channel_request_subsystem(message),"sftp")){ sftp=1; ssh_message_channel_request_reply_success(message); break; // } } if(!sftp){ ssh_message_reply_default(message); } ssh_message_free(message); } while (message && !sftp); if(!sftp){ printf("error : %s\n",ssh_get_error(session)); return 1; } printf("it works !\n"); do{ i=ssh_channel_read(chan,buf, 2048, 0); if(i>0) { ssh_channel_write(chan, buf, i); if (write(1,buf,i) < 0) { printf("error writing to buffer\n"); return 1; } } } while (i>0); ssh_disconnect(session); ssh_bind_free(sshbind); #ifdef WITH_PCAP cleanup_pcap(); #endif ssh_finalize(); return 0; }
int main(int argc, char **argv){ ssh_session session; ssh_bind sshbind; ssh_message message; ssh_channel chan=0; char buf[2048]; int auth=0; int shell=0; int i; int r; sshbind=ssh_bind_new(); session=ssh_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 #ifdef WITH_PCAP set_pcap(session); #endif if(ssh_bind_listen(sshbind)<0){ printf("Error listening to socket: %s\n", ssh_get_error(sshbind)); return 1; } printf("Started sample libssh sshd on port %d\n", port); printf("You can login as the user %s with the password %s\n", SSHD_USER, SSHD_PASSWORD); r = ssh_bind_accept(sshbind, session); if(r==SSH_ERROR){ printf("Error accepting a connection: %s\n", ssh_get_error(sshbind)); return 1; } if (ssh_handle_key_exchange(session)) { printf("ssh_handle_key_exchange: %s\n", ssh_get_error(session)); return 1; } /* proceed to authentication */ auth = authenticate(session); if (!auth || !authenticated) { printf("Authentication error: %s\n", ssh_get_error(session)); ssh_disconnect(session); return 1; } /* wait for a channel session */ do { message = ssh_message_get(session); if(message){ if(ssh_message_type(message) == SSH_REQUEST_CHANNEL_OPEN && ssh_message_subtype(message) == SSH_CHANNEL_SESSION) { chan = ssh_message_channel_request_open_reply_accept(message); ssh_message_free(message); break; } else { ssh_message_reply_default(message); ssh_message_free(message); } } else { break; } } while(!chan); if(!chan) { printf("Error: cleint did not ask for a channel session (%s)\n", ssh_get_error(session)); ssh_finalize(); return 1; } /* wait for a shell */ do { message = ssh_message_get(session); if(message != NULL) { if(ssh_message_type(message) == SSH_REQUEST_CHANNEL && ssh_message_subtype(message) == SSH_CHANNEL_REQUEST_SHELL) { shell = 1; ssh_message_channel_request_reply_success(message); ssh_message_free(message); break; } ssh_message_reply_default(message); ssh_message_free(message); } else { break; } } while(!shell); if(!shell) { printf("Error: No shell requested (%s)\n", ssh_get_error(session)); return 1; } printf("it works !\n"); do{ i=ssh_channel_read(chan,buf, 2048, 0); if(i>0) { if(*buf == '' || *buf == '') break; if(i == 1 && *buf == '\r') ssh_channel_write(chan, "\r\n", 2); else ssh_channel_write(chan, buf, i); if (write(1,buf,i) < 0) { printf("error writing to buffer\n"); return 1; } } } while (i>0); ssh_channel_close(chan); ssh_disconnect(session); ssh_bind_free(sshbind); #ifdef WITH_PCAP cleanup_pcap(); #endif ssh_finalize(); return 0; }
static int authenticate(ssh_session session) { ssh_message message; name = "\n\nKeyboard-Interactive Fancy Authentication\n"; instruction = "Please enter your real name and your password"; prompts[0] = "Real name: "; prompts[1] = "Password: "******"User %s wants to auth with pass %s\n", ssh_message_auth_user(message), ssh_message_auth_password(message)); if(auth_password(ssh_message_auth_user(message), ssh_message_auth_password(message))){ ssh_message_auth_reply_success(message,0); ssh_message_free(message); return 1; } ssh_message_auth_set_methods(message, SSH_AUTH_METHOD_PASSWORD | SSH_AUTH_METHOD_INTERACTIVE); // not authenticated, send default message ssh_message_reply_default(message); break; case SSH_AUTH_METHOD_INTERACTIVE: if(!ssh_message_auth_kbdint_is_response(message)) { printf("User %s wants to auth with kbdint\n", ssh_message_auth_user(message)); ssh_message_auth_interactive_request(message, name, instruction, 2, prompts, echo); } else { if(kbdint_check_response(session)) { ssh_message_auth_reply_success(message,0); ssh_message_free(message); return 1; } ssh_message_auth_set_methods(message, SSH_AUTH_METHOD_PASSWORD | SSH_AUTH_METHOD_INTERACTIVE); ssh_message_reply_default(message); } break; case SSH_AUTH_METHOD_NONE: default: printf("User %s wants to auth with unknown auth %d\n", ssh_message_auth_user(message), ssh_message_subtype(message)); ssh_message_auth_set_methods(message, SSH_AUTH_METHOD_PASSWORD | SSH_AUTH_METHOD_INTERACTIVE); ssh_message_reply_default(message); break; } break; default: ssh_message_auth_set_methods(message, SSH_AUTH_METHOD_PASSWORD | SSH_AUTH_METHOD_INTERACTIVE); ssh_message_reply_default(message); } ssh_message_free(message); } while (1); return 0; }
// Parse an SSH command message and do something bool SSHServer::processSSHMessage(ssh_message message) { if (!message) { return false; } switch(ssh_message_type(message)){ case SSH_REQUEST_AUTH: switch(ssh_message_subtype(message)) { // not authenticated, send default message case SSH_AUTH_METHOD_NONE: break; case SSH_AUTH_METHOD_PASSWORD: { log_debug(_("User %s wants to auth with pass %s\n"), ssh_message_auth_user(message), ssh_message_auth_password(message)); string user = ssh_message_auth_user(message); string passwd = ssh_message_auth_password(message); if (authPassword(user, passwd)){ // auth=1; ssh_message_auth_reply_success(message,0); break; } break; } case SSH_AUTH_METHOD_HOSTBASED: break; case SSH_AUTH_METHOD_PUBLICKEY: break; case SSH_AUTH_METHOD_INTERACTIVE: break; case SSH_AUTH_METHOD_UNKNOWN: break; default: ssh_message_auth_set_methods(message,SSH_AUTH_METHOD_PASSWORD); ssh_message_reply_default(message); break; } case SSH_REQUEST_CHANNEL_OPEN: if(ssh_message_subtype(message)==SSH_CHANNEL_SESSION){ _channel = ssh_message_channel_request_open_reply_accept(message); break; } break; // case SSH_CHANNEL_REQUEST_EXEC: // break; case SSH_CHANNEL_REQUEST_ENV: break; case SSH_CHANNEL_REQUEST_SUBSYSTEM: break; case SSH_CHANNEL_REQUEST_WINDOW_CHANGE: break; case SSH_CHANNEL_REQUEST_UNKNOWN: break; default: ssh_message_reply_default(message); } ssh_message_free(message); return false; }
static void global_request(ssh_session session, ssh_message message, void *userdata) { (void)session; (void)userdata; _ssh_log(SSH_LOG_PROTOCOL, "=== global_request", "Global request, message type: %d", ssh_message_type(message)); }