static void test_ssh_channel_request_x11(void **state) { struct hostkey_state *h = (struct hostkey_state *)*state; int rc, event_rc; pthread_t client_pthread; ssh_bind sshbind; ssh_session server; ssh_event event; struct channel_data channel_data; struct ssh_channel_callbacks_struct channel_cb = { .userdata = &channel_data, .channel_x11_req_function = ssh_channel_x11_req }; struct ssh_server_callbacks_struct server_cb = { .userdata = &channel_cb, .auth_password_function = auth_password_accept, .channel_open_request_session_function = channel_open }; memset(&channel_data, 0, sizeof(channel_data)); ssh_callbacks_init(&channel_cb); ssh_callbacks_init(&server_cb); /* Create server */ sshbind = torture_ssh_bind("localhost", TEST_SERVER_PORT, h->key_type, h->hostkey_path); assert_non_null(sshbind); /* Get client to connect */ rc = pthread_create(&client_pthread, NULL, client_thread, NULL); assert_return_code(rc, errno); server = ssh_new(); assert_true(server != NULL); rc = ssh_bind_accept(sshbind, server); assert_int_equal(rc, SSH_OK); /* Handle client connection */ ssh_set_server_callbacks(server, &server_cb); rc = ssh_handle_key_exchange(server); assert_int_equal(rc, SSH_OK); event = ssh_event_new(); assert_true(event != NULL); ssh_event_add_session(event, server); event_rc = SSH_OK; while (!channel_data.req_seen && event_rc == SSH_OK) { event_rc = ssh_event_dopoll(event, -1); } /* Cleanup */ ssh_event_free(event); ssh_free(server); ssh_bind_free(sshbind); rc = pthread_join(client_pthread, NULL); assert_int_equal(rc, 0); assert_true(channel_data.req_seen); assert_int_equal(channel_data.screen_number, x11_screen_number); }
static void handle_session(ssh_event event, ssh_session session) { int n; int rc = 0; /* Structure for storing the pty size. */ struct winsize wsize = { .ws_row = 0, .ws_col = 0, .ws_xpixel = 0, .ws_ypixel = 0 }; /* Our struct holding information about the channel. */ struct channel_data_struct cdata = { .pid = 0, .pty_master = -1, .pty_slave = -1, .child_stdin = -1, .child_stdout = -1, .child_stderr = -1, .event = NULL, .winsize = &wsize }; /* Our struct holding information about the session. */ struct session_data_struct sdata = { .channel = NULL, .auth_attempts = 0, .authenticated = 0 }; struct ssh_channel_callbacks_struct channel_cb = { .userdata = &cdata, .channel_pty_request_function = pty_request, .channel_pty_window_change_function = pty_resize, .channel_shell_request_function = shell_request, .channel_exec_request_function = exec_request, .channel_data_function = data_function, .channel_subsystem_request_function = subsystem_request }; struct ssh_server_callbacks_struct server_cb = { .userdata = &sdata, .auth_password_function = auth_password, .channel_open_request_session_function = channel_open, }; if (authorizedkeys[0]) { server_cb.auth_pubkey_function = auth_publickey; ssh_set_auth_methods(session, SSH_AUTH_METHOD_PASSWORD | SSH_AUTH_METHOD_PUBLICKEY); } else ssh_set_auth_methods(session, SSH_AUTH_METHOD_PASSWORD); ssh_callbacks_init(&server_cb); ssh_callbacks_init(&channel_cb); ssh_set_server_callbacks(session, &server_cb); if (ssh_handle_key_exchange(session) != SSH_OK) { fprintf(stderr, "%s\n", ssh_get_error(session)); return; } ssh_event_add_session(event, session); n = 0; while (sdata.authenticated == 0 || sdata.channel == NULL) { /* If the user has used up all attempts, or if he hasn't been able to * authenticate in 10 seconds (n * 100ms), disconnect. */ if (sdata.auth_attempts >= 3 || n >= 100) { return; } if (ssh_event_dopoll(event, 100) == SSH_ERROR) { fprintf(stderr, "%s\n", ssh_get_error(session)); return; } n++; } ssh_set_channel_callbacks(sdata.channel, &channel_cb); do { /* Poll the main event which takes care of the session, the channel and * even our child process's stdout/stderr (once it's started). */ if (ssh_event_dopoll(event, -1) == SSH_ERROR) { ssh_channel_close(sdata.channel); } /* If child process's stdout/stderr has been registered with the event, * or the child process hasn't started yet, continue. */ if (cdata.event != NULL || cdata.pid == 0) { continue; } /* Executed only once, once the child process starts. */ cdata.event = event; /* If stdout valid, add stdout to be monitored by the poll event. */ if (cdata.child_stdout != -1) { if (ssh_event_add_fd(event, cdata.child_stdout, POLLIN, process_stdout, sdata.channel) != SSH_OK) { fprintf(stderr, "Failed to register stdout to poll context\n"); ssh_channel_close(sdata.channel); } } /* If stderr valid, add stderr to be monitored by the poll event. */ if (cdata.child_stderr != -1){ if (ssh_event_add_fd(event, cdata.child_stderr, POLLIN, process_stderr, sdata.channel) != SSH_OK) { fprintf(stderr, "Failed to register stderr to poll context\n"); ssh_channel_close(sdata.channel); } } } while(ssh_channel_is_open(sdata.channel) && (cdata.pid == 0 || waitpid(cdata.pid, &rc, WNOHANG) == 0)); close(cdata.pty_master); close(cdata.child_stdin); close(cdata.child_stdout); close(cdata.child_stderr); /* Remove the descriptors from the polling context, since they are now * closed, they will always trigger during the poll calls. */ ssh_event_remove_fd(event, cdata.child_stdout); ssh_event_remove_fd(event, cdata.child_stderr); /* If the child process exited. */ if (kill(cdata.pid, 0) < 0 && WIFEXITED(rc)) { rc = WEXITSTATUS(rc); ssh_channel_request_send_exit_status(sdata.channel, rc); /* If client terminated the channel or the process did not exit nicely, * but only if something has been forked. */ } else if (cdata.pid > 0) { kill(cdata.pid, SIGKILL); } ssh_channel_send_eof(sdata.channel); ssh_channel_close(sdata.channel); /* Wait up to 5 seconds for the client to terminate the session. */ for (n = 0; n < 50 && (ssh_get_status(session) & SESSION_END) == 0; n++) { ssh_event_dopoll(event, 100); } } /* SIGCHLD handler for cleaning up dead children. */ static void sigchld_handler(int signo) { (void) signo; while (waitpid(-1, NULL, WNOHANG) > 0); } int main(int argc, char **argv) { ssh_bind sshbind; ssh_session session; ssh_event event; struct sigaction sa; int rc; /* Set up SIGCHLD handler. */ sa.sa_handler = sigchld_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART | SA_NOCLDSTOP; if (sigaction(SIGCHLD, &sa, NULL) != 0) { fprintf(stderr, "Failed to register SIGCHLD handler\n"); return 1; } rc = ssh_init(); if (rc < 0) { fprintf(stderr, "ssh_init failed\n"); return 1; } sshbind = ssh_bind_new(); if (sshbind == NULL) { fprintf(stderr, "ssh_bind_new failed\n"); return 1; } #ifdef HAVE_ARGP_H argp_parse(&argp, argc, argv, 0, 0, sshbind); #else (void) argc; (void) argv; set_default_keys(sshbind, 0, 0, 0); #endif /* HAVE_ARGP_H */ if(ssh_bind_listen(sshbind) < 0) { fprintf(stderr, "%s\n", ssh_get_error(sshbind)); return 1; } while (1) { session = ssh_new(); if (session == NULL) { fprintf(stderr, "Failed to allocate session\n"); continue; } /* Blocks until there is a new incoming connection. */ if(ssh_bind_accept(sshbind, session) != SSH_ERROR) { switch(fork()) { case 0: /* Remove the SIGCHLD handler inherited from parent. */ sa.sa_handler = SIG_DFL; sigaction(SIGCHLD, &sa, NULL); /* Remove socket binding, which allows us to restart the * parent process, without terminating existing sessions. */ ssh_bind_free(sshbind); event = ssh_event_new(); if (event != NULL) { /* Blocks until the SSH session ends by either * child process exiting, or client disconnecting. */ handle_session(event, session); ssh_event_free(event); } else { fprintf(stderr, "Could not create polling context\n"); } ssh_disconnect(session); ssh_free(session); exit(0); case -1: fprintf(stderr, "Failed to fork\n"); } } else { fprintf(stderr, "%s\n", ssh_get_error(sshbind)); } /* Since the session has been passed to a child fork, do some cleaning * up at the parent process. */ ssh_disconnect(session); ssh_free(session); } ssh_bind_free(sshbind); ssh_finalize(); return 0; }
static int pkd_exec_hello(int fd, struct pkd_daemon_args *args) { int rc = -1; ssh_bind b = NULL; ssh_session s = NULL; ssh_event e = NULL; ssh_channel c = NULL; enum ssh_bind_options_e opts = -1; int level = args->opts.libssh_log_level; enum pkd_hostkey_type_e type = args->type; const char *hostkeypath = args->hostkeypath; pkd_state.eof_received = 0; pkd_state.close_received = 0; pkd_state.req_exec_received = 0; b = ssh_bind_new(); if (b == NULL) { pkderr("ssh_bind_new\n"); goto outclose; } if (type == PKD_RSA) { opts = SSH_BIND_OPTIONS_RSAKEY; } else if (type == PKD_ED25519) { opts = SSH_BIND_OPTIONS_HOSTKEY; #ifdef HAVE_DSA } else if (type == PKD_DSA) { opts = SSH_BIND_OPTIONS_DSAKEY; #endif } else if (type == PKD_ECDSA) { opts = SSH_BIND_OPTIONS_ECDSAKEY; } else { pkderr("unknown kex algorithm: %d\n", type); rc = -1; goto outclose; } rc = ssh_bind_options_set(b, opts, hostkeypath); if (rc != 0) { pkderr("ssh_bind_options_set: %s\n", ssh_get_error(b)); goto outclose; } rc = ssh_bind_options_set(b, SSH_BIND_OPTIONS_LOG_VERBOSITY, &level); if (rc != 0) { pkderr("ssh_bind_options_set log verbosity: %s\n", ssh_get_error(b)); goto outclose; } s = ssh_new(); if (s == NULL) { pkderr("ssh_new\n"); goto outclose; } /* * ssh_bind_accept loads host key as side-effect. If this * succeeds, the given 'fd' will be closed upon 'ssh_free(s)'. */ rc = ssh_bind_accept_fd(b, s, fd); if (rc != SSH_OK) { pkderr("ssh_bind_accept_fd: %s\n", ssh_get_error(b)); goto outclose; } /* accept only publickey-based auth */ ssh_set_auth_methods(s, SSH_AUTH_METHOD_PUBLICKEY); /* initialize callbacks */ ssh_callbacks_init(&pkd_server_cb); pkd_server_cb.userdata = &c; rc = ssh_set_server_callbacks(s, &pkd_server_cb); if (rc != SSH_OK) { pkderr("ssh_set_server_callbacks: %s\n", ssh_get_error(s)); goto out; } /* first do key exchange */ rc = ssh_handle_key_exchange(s); if (rc != SSH_OK) { pkderr("ssh_handle_key_exchange: %s\n", ssh_get_error(s)); goto out; } /* setup and pump event to carry out exec channel */ e = ssh_event_new(); if (e == NULL) { pkderr("ssh_event_new\n"); goto out; } rc = ssh_event_add_session(e, s); if (rc != SSH_OK) { pkderr("ssh_event_add_session\n"); goto out; } /* poll until exec channel established */ while ((ctx.keep_going != 0) && (rc != SSH_ERROR) && (pkd_state.req_exec_received == 0)) { rc = ssh_event_dopoll(e, -1 /* infinite timeout */); } if (rc == SSH_ERROR) { pkderr("ssh_event_dopoll\n"); goto out; } else if (c == NULL) { pkderr("poll loop exited but exec channel not ready\n"); rc = -1; goto out; } rc = ssh_channel_write(c, "hello\n", 6); /* XXX: customizable payloads */ if (rc != 6) { pkderr("ssh_channel_write partial (%d)\n", rc); } rc = ssh_channel_request_send_exit_status(c, 0); if (rc != SSH_OK) { pkderr("ssh_channel_request_send_exit_status: %s\n", ssh_get_error(s)); goto out; } rc = ssh_channel_send_eof(c); if (rc != SSH_OK) { pkderr("ssh_channel_send_eof: %s\n", ssh_get_error(s)); goto out; } rc = ssh_channel_close(c); if (rc != SSH_OK) { pkderr("ssh_channel_close: %s\n", ssh_get_error(s)); goto out; } while ((ctx.keep_going != 0) && (pkd_state.eof_received == 0) && (pkd_state.close_received == 0)) { rc = ssh_event_dopoll(e, 1000 /* milliseconds */); if (rc == SSH_ERROR) { /* log, but don't consider this fatal */ pkdout("ssh_event_dopoll for eof + close: %s\n", ssh_get_error(s)); rc = 0; break; } else { rc = 0; } } while ((ctx.keep_going != 0) && (ssh_is_connected(s))) { rc = ssh_event_dopoll(e, 1000 /* milliseconds */); if (rc == SSH_ERROR) { /* log, but don't consider this fatal */ pkdout("ssh_event_dopoll for session connection: %s\n", ssh_get_error(s)); rc = 0; break; } else { rc = 0; } } goto out; outclose: close(fd); out: if (c != NULL) { ssh_channel_free(c); } if (e != NULL) { ssh_event_remove_session(e, s); ssh_event_free(e); } if (s != NULL) { ssh_disconnect(s); ssh_free(s); } if (b != NULL) { ssh_bind_free(b); } return rc; }
int SSHThread( void *data ) { // TODO: Hogne was here, disabling this problem child.. :) return 0; #ifdef ENABLE_SSH ssh_session session = NULL; ssh_bind sshbind = NULL; ssh_event mainloop; 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 }; char buf[2048]; int i; int r; DEBUG("Starting SSH Process\n"); SSHServer *ts = (SSHServer *)data; if( !ts ) return 0; ts->sshs_FriendHome = getenv( "FRIEND_HOME" ); int len = strlen( ts->sshs_FriendHome ); ts->sshs_RSAKeyHome = calloc( len+64, sizeof(char) ); ts->sshs_DSAKeyHome = calloc( len+64, sizeof(char) ); strcpy( ts->sshs_RSAKeyHome, ts->sshs_FriendHome ); strcpy( ts->sshs_DSAKeyHome, ts->sshs_FriendHome ); strcat( ts->sshs_RSAKeyHome, "keys/ssh_host_rsa_key" ); strcat( ts->sshs_DSAKeyHome, "keys/ssh_host_dsa_key" ); //DEBUG("SSH sshs_RSAKeyHome set to %s\n", ts->sshs_RSAKeyHome ); sshbind = ssh_bind_new(); BOOL welcomeMessage = FALSE; ssh_bind_options_set( sshbind, SSH_BIND_OPTIONS_DSAKEY, ts->sshs_DSAKeyHome ); ssh_bind_options_set( sshbind, SSH_BIND_OPTIONS_RSAKEY, ts->sshs_RSAKeyHome ); //ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, arg); //DEBUG("IMPORT RSA KEY %s\n", ts->sshs_RSAKeyHome ); ssh_bind_options_set( sshbind, SSH_BIND_OPTIONS_BINDPORT_STR, SSH_SERVER_PORT ); //verbose ssh_bind_options_set( sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR, "2" ); ssh_bind_options_set( sshbind, SSH_BIND_OPTIONS_BINDADDR, "127.0.0.1" ); if( ts->sshs_RSAKeyHome ) free( ts->sshs_RSAKeyHome ); if( ts->sshs_DSAKeyHome ) free( ts->sshs_DSAKeyHome ); // TODO: ts->sshs_Quit sometimes can not be read! while( ts != NULL && !ts->sshs_Quit ) { DEBUG("Server options set\n"); #ifdef WITH_PCAP set_pcap(session); #endif DEBUG("Server before bind\n"); if( ssh_bind_listen( sshbind )<0 ) { ERROR("Error listening to socket: %s\n",ssh_get_error(sshbind) ); break; } DEBUG("Server before accept\n"); session=ssh_new(); r = ssh_bind_accept( sshbind , session ); if( r==SSH_ERROR ) { ERROR("error accepting a connection : %s\n",ssh_get_error(sshbind)); break; } ssh_callbacks_init( &cb ); SSHSession *sess = calloc( 1, sizeof( SSHSession ) ); sess->sshs_Session = session; cb.userdata = sess; DEBUG("User data set\n"); ssh_set_server_callbacks( session, &cb ); if ( ssh_handle_key_exchange( session ) ) { ERROR("ssh_handle_key_exchange: %s\n", ssh_get_error(session)); continue; //goto disconnect; } DEBUG("Connection accepted\n"); ssh_set_auth_methods( session,SSH_AUTH_METHOD_PASSWORD | SSH_AUTH_METHOD_GSSAPI_MIC ); // // New session/connection put it into thread // switch( fork() ) { case 0: // Remove the SIGCHLD handler inherited from parent signal(SIGCHLD, SIG_DFL); mainloop = ssh_event_new(); ssh_event_add_session( mainloop, session ); while( !(sess->sshs_Authenticated && sess->sshs_Chan != NULL) ) { if( sess->sshs_Error ) { ERROR("SSHSession error %d\n", sess->sshs_Error ); break; } r = ssh_event_dopoll( mainloop, -1 ); if( r == SSH_ERROR ) { ERROR("Error : %s\n",ssh_get_error( session ) ); ssh_disconnect( session ); return 1; } strcpy( buf, "------------------------------------------------------\n\r" \ "--- Welcome in FC server, use help to work with me ---\n\r" \ "------------------------------------------------------\n\r" ); ssh_channel_write( sess->sshs_Chan, buf, strlen( buf ) ); if( sess->sshs_Path == NULL ) { sess->sshs_Path = calloc( 1024, sizeof(char) ); sess->sshs_DispText = calloc( 1024+48, sizeof(char) ); } strcpy( sess->sshs_Path, "/" ); if( sess->sshs_Usr ) { sprintf( sess->sshs_DispText, "%s:%s ", sess->sshs_Usr->u_Name, sess->sshs_Path ); }else{ sprintf( sess->sshs_DispText, ":%s ", sess->sshs_Path ); } int i = 0; do { ssh_channel_write( sess->sshs_Chan, sess->sshs_DispText, strlen( sess->sshs_DispText ) ); i = ssh_channel_read( sess->sshs_Chan, buf, 2048, 0 ); if( i > 0 ) { DEBUG("READING FROM CHANNEL %d - size %d %d %c -n %d\n", i, strlen( buf ), buf[0], buf[0], '\n' ); //ssh_channel_write( sess->sshs_Chan, buf, 1 ); handleSSHCommands( sess, buf, i ); } if( sess->sshs_Quit ) { break; } } while( i>0 ); if( sess->sshs_Quit ) break; } DEBUG("Closing ssh connection\n"); ssh_event_free( mainloop ); ssh_disconnect( session ); ssh_free( session ); if( sess->sshs_DispText ) { FFree( sess->sshs_DispText ); } if( sess->sshs_Path ) { FFree( sess->sshs_Path ); } DEBUG("Connection released\n"); FFree( sess ); abort(); DEBUG("AUTH\n"); break; case -1: ERROR("Cannot create fork!\n"); break; } #ifdef WITH_PCAP cleanup_pcap(); #endif } // main loop disconnect: DEBUG("DISCONNECTED\n"); #endif // ENABLE_SSH return 0; }
static void client_bootstrap(struct tmate_session *_session) { struct tmate_ssh_client *client = &_session->ssh_client; int grace_period = TMATE_SSH_GRACE_PERIOD; ssh_event mainloop; ssh_session session = client->session; tmate_notice("Bootstrapping ssh client ip=%s", client->ip_address); _session->ev_base = osdep_event_init(); /* new process group, we don't want to die with our parent (upstart) */ setpgid(0, 0); { int flag = 1; setsockopt(ssh_get_fd(session), IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag)); } signal(SIGALRM, handle_sigalrm); alarm(grace_period); /* * We should die early if we can't connect to proxy. This way the * tmate daemon will pick another server to work on. */ _session->proxy_fd = -1; if (tmate_has_proxy()) _session->proxy_fd = tmate_connect_to_proxy(); ssh_server_cb.userdata = client; ssh_callbacks_init(&ssh_server_cb); ssh_set_server_callbacks(client->session, &ssh_server_cb); ssh_options_set(session, SSH_OPTIONS_TIMEOUT, &grace_period); ssh_options_set(session, SSH_OPTIONS_COMPRESSION, "yes"); ssh_set_auth_methods(client->session, SSH_AUTH_METHOD_PUBLICKEY); tmate_info("Exchanging DH keys"); if (ssh_handle_key_exchange(session) < 0) tmate_fatal("Error doing the key exchange: %s", ssh_get_error(session)); mainloop = ssh_event_new(); ssh_event_add_session(mainloop, session); while (!client->role) { if (ssh_event_dopoll(mainloop, -1) == SSH_ERROR) tmate_fatal("Error polling ssh socket: %s", ssh_get_error(session)); } alarm(0); /* The latency is callback set later */ tmate_start_ssh_latency_probes(client, &ssh_server_cb, TMATE_SSH_KEEPALIVE * 1000); register_on_ssh_read(client); tmate_spawn(_session); /* never reached */ }
int set_server_callbacks(ssh_session session, ssh_server_callbacks callbacks) { ssh_callbacks_init(callbacks); return ssh_set_server_callbacks(session, callbacks); }
int main(int argc, char **argv){ ssh_session session; ssh_bind sshbind; ssh_event mainloop; 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 }; char buf[2048]; 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 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; } ssh_callbacks_init(&cb); ssh_set_server_callbacks(session, &cb); if (ssh_handle_key_exchange(session)) { printf("ssh_handle_key_exchange: %s\n", ssh_get_error(session)); return 1; } ssh_set_auth_methods(session,SSH_AUTH_METHOD_PASSWORD | SSH_AUTH_METHOD_GSSAPI_MIC); mainloop = ssh_event_new(); ssh_event_add_session(mainloop, session); while (!(authenticated && chan != NULL)){ if(error) break; r = ssh_event_dopoll(mainloop, -1); if (r == SSH_ERROR){ printf("Error : %s\n",ssh_get_error(session)); ssh_disconnect(session); return 1; } } if(error){ printf("Error, exiting loop\n"); } else printf("Authenticated and got a channel\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; } if (buf[0] == '\x0d') { if (write(1, "\n", 1) < 0) { printf("error writing to buffer\n"); return 1; } ssh_channel_write(chan, "\n", 1); } } } while (i>0); ssh_disconnect(session); ssh_bind_free(sshbind); ssh_finalize(); return 0; }
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; }