int ssh_init(SSH * pSsh, char * pIp,char * pUsername, char * pPassword) { int ret; int type; const char * fingerprint; size_t len; if (NULL==pSsh) { return 0; } pSsh->sock_fd=socket(AF_INET, SOCK_STREAM, 0); pSsh->sin.sin_family = AF_INET; pSsh->sin.sin_port = htons(22); pSsh->sin.sin_addr.s_addr = inet_addr(pIp); ret = libssh2_init (0); if (ret != 0) { fprintf (stderr, "libssh2 initialization failed (%d)\n", ret); return 1; } if (connect(pSsh->sock_fd, (struct sockaddr*)(&pSsh->sin), sizeof(struct sockaddr_in)) != 0) { fprintf(stderr, "failed to connect!\n"); return -1; } pSsh->session=libssh2_session_init(); if (!pSsh->session) return 0; libssh2_session_set_blocking(pSsh->session, 0); while ((ret = libssh2_session_handshake(pSsh->session, pSsh->sock_fd)) == LIBSSH2_ERROR_EAGAIN); if (ret) { fprintf(stderr, "Failure establishing SSH session: %d\n", ret); return -1; } pSsh->nh = libssh2_knownhost_init(pSsh->session); if(!pSsh->nh) { /* eeek, do cleanup here */ return 2; } libssh2_knownhost_readfile(pSsh->nh, "known_hosts", LIBSSH2_KNOWNHOST_FILE_OPENSSH); libssh2_knownhost_writefile(pSsh->nh, "dumpfile", LIBSSH2_KNOWNHOST_FILE_OPENSSH); fingerprint = libssh2_session_hostkey(pSsh->session, &len, &type); if(fingerprint) { struct libssh2_knownhost *host; int check = libssh2_knownhost_checkp(pSsh->nh, pIp, 22, fingerprint, len, LIBSSH2_KNOWNHOST_TYPE_PLAIN| LIBSSH2_KNOWNHOST_KEYENC_RAW, &host); fprintf(stderr, "Host check: %d, key: %s\n", check, (check <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)? host->key:"<none>"); /***** * At this point, we could verify that 'check' tells us the key is * fine or bail out. *****/ } else { /* eeek, do cleanup here */ return 3; } libssh2_knownhost_free(pSsh->nh); if ( strlen(pPassword) != 0 ) { /* We could authenticate via password */ while ((ret = libssh2_userauth_password(pSsh->session, pUsername, pPassword)) == LIBSSH2_ERROR_EAGAIN); if (ret) { fprintf(stderr, "Authentication by password failed.\n"); //goto shutdown; } } else { /* Or by public key */ while ((ret = libssh2_userauth_publickey_fromfile(pSsh->session, pUsername, "/home/user/" ".ssh/id_rsa.pub", "/home/user/" ".ssh/id_rsa", pPassword)) == LIBSSH2_ERROR_EAGAIN); if (ret) { fprintf(stderr, "\tAuthentication by public key failed\n"); //goto shutdown; } } fprintf(stderr,"ssh_init\n"); return 0; }
int main(int argc, char *argv[]) { const char *hostname = "127.0.0.1"; const char *commandline = "uptime"; const char *username = "******"; const char *password = "******"; unsigned long hostaddr; int sock; struct sockaddr_in sin; const char *fingerprint; LIBSSH2_SESSION *session; LIBSSH2_CHANNEL *channel; int rc; int exitcode; char *exitsignal=(char *)"none"; int bytecount = 0; size_t len; LIBSSH2_KNOWNHOSTS *nh; int type; #ifdef WIN32 WSADATA wsadata; int err; err = WSAStartup(MAKEWORD(2,0), &wsadata); if (err != 0) { fprintf(stderr, "WSAStartup failed with error: %d\n", err); return 1; } #endif if (argc > 1) /* must be ip address only */ hostname = argv[1]; if (argc > 2) { username = argv[2]; } if (argc > 3) { password = argv[3]; } if (argc > 4) { commandline = argv[4]; } rc = libssh2_init (0); if (rc != 0) { fprintf (stderr, "libssh2 initialization failed (%d)\n", rc); return 1; } hostaddr = inet_addr(hostname); /* Ultra basic "connect to port 22 on localhost" * Your code is responsible for creating the socket establishing the * connection */ sock = socket(AF_INET, SOCK_STREAM, 0); sin.sin_family = AF_INET; sin.sin_port = htons(22); sin.sin_addr.s_addr = hostaddr; if (connect(sock, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in)) != 0) { fprintf(stderr, "failed to connect!\n"); return -1; } /* Create a session instance */ session = libssh2_session_init(); if (!session) return -1; /* tell libssh2 we want it all done non-blocking */ libssh2_session_set_blocking(session, 0); /* ... start it up. This will trade welcome banners, exchange keys, * and setup crypto, compression, and MAC layers */ while ((rc = libssh2_session_handshake(session, sock)) == LIBSSH2_ERROR_EAGAIN); if (rc) { fprintf(stderr, "Failure establishing SSH session: %d\n", rc); return -1; } nh = libssh2_knownhost_init(session); if(!nh) { /* eeek, do cleanup here */ return 2; } /* read all hosts from here */ libssh2_knownhost_readfile(nh, "known_hosts", LIBSSH2_KNOWNHOST_FILE_OPENSSH); /* store all known hosts to here */ libssh2_knownhost_writefile(nh, "dumpfile", LIBSSH2_KNOWNHOST_FILE_OPENSSH); fingerprint = libssh2_session_hostkey(session, &len, &type); if(fingerprint) { struct libssh2_knownhost *host; #if LIBSSH2_VERSION_NUM >= 0x010206 /* introduced in 1.2.6 */ int check = libssh2_knownhost_checkp(nh, hostname, 22, fingerprint, len, LIBSSH2_KNOWNHOST_TYPE_PLAIN| LIBSSH2_KNOWNHOST_KEYENC_RAW, &host); #else /* 1.2.5 or older */ int check = libssh2_knownhost_check(nh, hostname, fingerprint, len, LIBSSH2_KNOWNHOST_TYPE_PLAIN| LIBSSH2_KNOWNHOST_KEYENC_RAW, &host); #endif fprintf(stderr, "Host check: %d, key: %s\n", check, (check <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)? host->key:"<none>"); /***** * At this point, we could verify that 'check' tells us the key is * fine or bail out. *****/ } else { /* eeek, do cleanup here */ return 3; } libssh2_knownhost_free(nh); if ( strlen(password) != 0 ) { /* We could authenticate via password */ while ((rc = libssh2_userauth_password(session, username, password)) == LIBSSH2_ERROR_EAGAIN); if (rc) { fprintf(stderr, "Authentication by password failed.\n"); goto shutdown; } } else { /* Or by public key */ while ((rc = libssh2_userauth_publickey_fromfile(session, username, "/home/user/" ".ssh/id_rsa.pub", "/home/user/" ".ssh/id_rsa", password)) == LIBSSH2_ERROR_EAGAIN); if (rc) { fprintf(stderr, "\tAuthentication by public key failed\n"); goto shutdown; } } #if 0 libssh2_trace(session, ~0 ); #endif /* Exec non-blocking on the remove host */ while( (channel = libssh2_channel_open_session(session)) == NULL && libssh2_session_last_error(session,NULL,NULL,0) == LIBSSH2_ERROR_EAGAIN ) { waitsocket(sock, session); } if( channel == NULL ) { fprintf(stderr,"Error\n"); exit( 1 ); } while( (rc = libssh2_channel_exec(channel, commandline)) == LIBSSH2_ERROR_EAGAIN ) { waitsocket(sock, session); } if( rc != 0 ) { fprintf(stderr,"Error\n"); exit( 1 ); } for( ;; ) { /* loop until we block */ int rc; do { char buffer[0x4000]; rc = libssh2_channel_read( channel, buffer, sizeof(buffer) ); if( rc > 0 ) { int i; bytecount += rc; fprintf(stderr, "We read:\n"); for( i=0; i < rc; ++i ) fputc( buffer[i], stderr); fprintf(stderr, "\n"); } else { if( rc != LIBSSH2_ERROR_EAGAIN ) /* no need to output this for the EAGAIN case */ fprintf(stderr, "libssh2_channel_read returned %d\n", rc); } } while( rc > 0 ); /* this is due to blocking that would occur otherwise so we loop on this condition */ if( rc == LIBSSH2_ERROR_EAGAIN ) { waitsocket(sock, session); } else break; } exitcode = 127; while( (rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN ) waitsocket(sock, session); if( rc == 0 ) { exitcode = libssh2_channel_get_exit_status( channel ); libssh2_channel_get_exit_signal(channel, &exitsignal, NULL, NULL, NULL, NULL, NULL); } if (exitsignal) fprintf(stderr, "\nGot signal: %s\n", exitsignal); else fprintf(stderr, "\nEXIT: %d bytecount: %d\n", exitcode, bytecount); libssh2_channel_free(channel); channel = NULL; shutdown: libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing"); libssh2_session_free(session); #ifdef WIN32 closesocket(sock); #else close(sock); #endif fprintf(stderr, "all done\n"); libssh2_exit(); return 0; }
void CLibssh2::set_known_hosts() { int type; int check; size_t len; struct libssh2_knownhost* known_host; LIBSSH2_SESSION* session = static_cast<LIBSSH2_SESSION*>(_session); LIBSSH2_KNOWNHOSTS* known_hosts = libssh2_knownhost_init(session); if (NULL == known_hosts) { THROW_EXCEPTION(get_session_errmsg(), get_session_errcode()); } try { // read all hosts from here libssh2_knownhost_readfile(known_hosts, "known_hosts", LIBSSH2_KNOWNHOST_FILE_OPENSSH); // store all known hosts to here libssh2_knownhost_writefile(known_hosts, "dumpfile", LIBSSH2_KNOWNHOST_FILE_OPENSSH); const char* fingerprint = libssh2_session_hostkey(session, &len, &type); if (NULL == fingerprint) { THROW_EXCEPTION(get_session_errmsg(), get_session_errcode()); } #if LIBSSH2_VERSION_NUM >= 0x010206 // introduced in 1.2.6 check = libssh2_knownhost_checkp( known_hosts, _ip.c_str(), _port, fingerprint, len, LIBSSH2_KNOWNHOST_TYPE_PLAIN|LIBSSH2_KNOWNHOST_KEYENC_RAW, &known_host); #else // 1.2.5 or older check = libssh2_knownhost_check( known_hosts, _ip.c_str(), fingerprint, len, LIBSSH2_KNOWNHOST_TYPE_PLAIN|LIBSSH2_KNOWNHOST_KEYENC_RAW, &known_host); #endif // LIBSSH2_VERSION_NUM libssh2_knownhost_free(known_hosts); } catch (...) { libssh2_knownhost_free(known_hosts); throw; } }
lv_libssh2_status_t lv_libssh2_knownhosts_read_file( lv_libssh2_knownhosts_t* handle, const char* file, size_t* count ) { if (handle == NULL) { return LV_LIBSSH2_STATUS_ERROR_NULL_VALUE; } if (file == NULL) { return LV_LIBSSH2_STATUS_ERROR_NULL_VALUE; } int result = libssh2_knownhost_readfile( handle->inner, file, LIBSSH2_KNOWNHOST_FILE_OPENSSH ); if (result < 0) { return lv_libssh2_status_from_result(result); } *count = result; return LV_LIBSSH2_STATUS_OK; }
static int check_host_key_knownhosts(BDRVSSHState *s, const char *host, int port, Error **errp) { const char *home; char *knh_file = NULL; LIBSSH2_KNOWNHOSTS *knh = NULL; struct libssh2_knownhost *found; int ret, r; const char *hostkey; size_t len; int type; hostkey = libssh2_session_hostkey(s->session, &len, &type); if (!hostkey) { ret = -EINVAL; session_error_setg(errp, s, "failed to read remote host key"); goto out; } knh = libssh2_knownhost_init(s->session); if (!knh) { ret = -EINVAL; session_error_setg(errp, s, "failed to initialize known hosts support"); goto out; } home = getenv("HOME"); if (home) { knh_file = g_strdup_printf("%s/.ssh/known_hosts", home); } else { knh_file = g_strdup_printf("/root/.ssh/known_hosts"); } /* Read all known hosts from OpenSSH-style known_hosts file. */ libssh2_knownhost_readfile(knh, knh_file, LIBSSH2_KNOWNHOST_FILE_OPENSSH); r = libssh2_knownhost_checkp(knh, host, port, hostkey, len, LIBSSH2_KNOWNHOST_TYPE_PLAIN| LIBSSH2_KNOWNHOST_KEYENC_RAW, &found); switch (r) { case LIBSSH2_KNOWNHOST_CHECK_MATCH: /* OK */ DPRINTF("host key OK: %s", found->key); break; case LIBSSH2_KNOWNHOST_CHECK_MISMATCH: ret = -EINVAL; session_error_setg(errp, s, "host key does not match the one in known_hosts" " (found key %s)", found->key); goto out; case LIBSSH2_KNOWNHOST_CHECK_NOTFOUND: ret = -EINVAL; session_error_setg(errp, s, "no host key was found in known_hosts"); goto out; case LIBSSH2_KNOWNHOST_CHECK_FAILURE: ret = -EINVAL; session_error_setg(errp, s, "failure matching the host key with known_hosts"); goto out; default: ret = -EINVAL; session_error_setg(errp, s, "unknown error matching the host key" " with known_hosts (%d)", r); goto out; } /* known_hosts checking successful. */ ret = 0; out: if (knh != NULL) { libssh2_knownhost_free(knh); } g_free(knh_file); return ret; }
int execute_command(struct remote *rm) { /* Sets up the pthread functionality of gcrypt * libssh2 doesn't do this for us so we have to do it ourselves*/ gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); openlog("remote-monitor-base",LOG_PID|LOG_CONS,LOG_USER); syslog(LOG_DEBUG,"Starting SSH execution on rm->hostname: %s with rm->username: %s and port: %d",rm->hostname,rm->username,rm->port); size_t len; int type; unsigned long hostaddress; int sock; const char *fingerprint; int bytecount = 0; struct sockaddr_in sin; LIBSSH2_SESSION *session; LIBSSH2_CHANNEL *channel; LIBSSH2_KNOWNHOSTS *nh; /* results stores the output from the commands after they're executed * Each command has a corresponding result so the results array is set to the same length as the commands array */ rm->results = malloc(rm->num_commands * sizeof(char*)); for(int i = 0; i < rm->num_commands; i++) rm->results[i] = malloc(2048 * sizeof(char)); /* Initialise libssh2 and check to see if it was initialized properly * libssh2_init isn't thread safe so we need to lock the thread while it executes*/ pthread_mutex_lock(&sshinit_lock); int rc = libssh2_init(0); pthread_mutex_unlock(&sshinit_lock); if(rc!=0) { syslog(LOG_ERR,"libssh2 initilization failed"); return 1; } /* Creates a socket connection to the specified host on the specified port */ hostaddress = inet_addr(rm->hostname); sock = socket(AF_INET, SOCK_STREAM, 0); sin.sin_family = AF_INET; sin.sin_port = htons(rm->port); sin.sin_addr.s_addr = hostaddress; /* Check to see if the connection was successful */ if(connect(sock, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in)) != 0) { syslog(LOG_ERR,"Failed to connect to %s on port %d", rm->hostname, rm->port); return 1; } /* Initialise the session and check for success */ session = libssh2_session_init(); if(!session) { syslog(LOG_ERR,"Error creating session on host %s", rm->hostname); return 1; } /* Disable blocking for this session */ libssh2_session_set_blocking(session,0); /* Start the session on the specified socket and check for success */ while( (rc = libssh2_session_startup(session,sock)) == LIBSSH2_ERROR_EAGAIN); if(rc) { syslog(LOG_ERR,"Failure establishing SSH session %d on host %s", rc, rm->hostname); goto error; } /* Get the current host key and check to see if it matches with any known hosts */ nh = libssh2_knownhost_init(session); if(!nh) { syslog(LOG_ERR,"Error while initialising known hosts collection on host %s",rm->hostname); goto error; } libssh2_knownhost_readfile(nh,"known_hosts",LIBSSH2_KNOWNHOST_FILE_OPENSSH); //libssh2_knownhost_writefile(nh,"dumpfile",LIBSSH2_KNOWNHOST_FILE_OPENSSH); fingerprint = libssh2_session_hostkey(session,&len,&type); if(fingerprint) { struct libssh2_knownhost *host; int check = libssh2_knownhost_checkp(nh,rm->hostname,rm->port,fingerprint,len ,LIBSSH2_KNOWNHOST_TYPE_PLAIN|LIBSSH2_KNOWNHOST_KEYENC_RAW,&host); if(check == LIBSSH2_KNOWNHOST_CHECK_MATCH) syslog(LOG_DEBUG,"Found matching host key for host %s",rm->hostname); else if(check == LIBSSH2_KNOWNHOST_CHECK_MISMATCH) syslog(LOG_ERR,"Host key was found but the key's didn't match for host %s",rm->hostname); //TODO Some sort of critical error will need to be generated here else if(check == LIBSSH2_KNOWNHOST_CHECK_NOTFOUND) syslog(LOG_ERR,"No host match was found for %s",rm->hostname); //TODO Have the ability to add the host key here else syslog(LOG_ERR,"There was a failure while attempting to match host keys for host %s",rm->hostname); } else { syslog(LOG_ERR,"Couldn't get host key for host: %s",rm->hostname); goto error; } libssh2_knownhost_free(nh); /* Authenticate with the specified rm->username and passwod and check for success */ // TODO Add ability to authenticate with a private key if( (strlen(rm->password)) != 0 ) { syslog(LOG_DEBUG,"Using rm->password authentication for host %s",rm->hostname); while( (rc = libssh2_userauth_password(session,rm->username,rm->password)) == LIBSSH2_ERROR_EAGAIN); if(rc) { syslog(LOG_ERR,"Authentication to host %s failed",rm->hostname); goto error; } } else if( ( (strlen(rm->publickey)) != 0 ) && ( ( strlen(rm->privatekey)) != 0) ) { syslog(LOG_DEBUG,"Using public key authentication for host %s",rm->hostname); while( (rc = libssh2_userauth_publickey_fromfile(session,rm->username,rm->publickey,rm->privatekey,NULL)) == LIBSSH2_ERROR_EAGAIN); switch(rc) { case 0: break; case LIBSSH2_ERROR_AUTHENTICATION_FAILED: syslog(LOG_ERR,"Authentication using the supplied key for host %s was not accepted",rm->hostname); goto error; case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED: syslog(LOG_ERR,"The rm->username/public key combination was invalid for host %s",rm->hostname); goto error; default: syslog(LOG_ERR,"Authentication to host %s failed",rm->hostname); goto error; } } /* Open a session for each command */ for(int i = 0; i < rm->num_commands; i++) { /* Open a channel on the current channel and check for success */ while( (channel = libssh2_channel_open_session(session)) == NULL && libssh2_session_last_error(session,NULL,NULL,0) == LIBSSH2_ERROR_EAGAIN) { waitsocket(sock,session); } if(channel == NULL) { syslog(LOG_ERR,"Error opening SSH channel on host %s",rm->hostname); asprintf(&(rm->results[i]),NULL); break; } /* Execute the command and check for success */ while( (rc = libssh2_channel_exec(channel,rm->commands[i])) == LIBSSH2_ERROR_EAGAIN) { waitsocket(sock,session); } if(rc!=0) { syslog(LOG_ERR,"Error while executing %s in channel on host %s",rm->commands[i],rm->hostname); asprintf(&(rm->results[i]),NULL); break; } /* Continuously read the returned stream and break once the stream has been read */ for(;;) { int rc; do { char buffer[2048]; rc = libssh2_channel_read(channel,buffer,sizeof(buffer)); if(rc > 0) { bytecount += rc; char *output; output = buffer; syslog(LOG_ERR,"Got output from command %s on host %s:%s",rm->commands[i],rm->hostname,output); /* Store the output in the results array */ asprintf(&(rm->results[i]),"%s",output); memset(buffer,0,2048); } } while(rc > 0); if(rc == LIBSSH2_ERROR_EAGAIN) { waitsocket(sock,session); } else break; } /* Close the channel and check for success */ while( (rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN) { waitsocket(sock,session); } if( (libssh2_channel_free(channel)) < 0) syslog(LOG_ERR,"Error while freeing channel on host %s",rm->hostname); channel = NULL; } shutdown: syslog(LOG_DEBUG,"Disconnecting SSH session for host %s",rm->hostname); libssh2_session_disconnect(session,"Normal SSH disconnection"); libssh2_session_free(session); close(sock); libssh2_exit(); closelog(); return 0; error: syslog(LOG_DEBUG,"Disconnection SSH session for host %s",rm->hostname); libssh2_session_disconnect(session,"Normal SSH disconnection"); libssh2_session_free(session); close(sock); libssh2_exit(); closelog(); return 1; }
static int uwsgi_init_ssh_session( struct uwsgi_ssh_mountpoint *usm, int* socket_fd, LIBSSH2_SESSION **session) { int sock = uwsgi_connect(usm->remote, ulibssh2.ssh_timeout, 1); if (sock < 0) { uwsgi_error("uwsgi_init_ssh_session()/uwsgi_connect()"); return 1; } int rc = libssh2_init(0); if (rc) { uwsgi_error("uwsgi_init_ssh_session()/libssh2_init()"); goto shutdown; } *session = libssh2_session_init(); if (!session) { uwsgi_error("uwsgi_init_ssh_session()/libssh2_session_init()"); goto shutdown; } libssh2_session_set_blocking(*session, 0); while ((rc = libssh2_session_handshake(*session, sock)) == LIBSSH2_ERROR_EAGAIN) { uwsgi_ssh_waitsocket(sock, *session); } if (rc) { uwsgi_error("uwsgi_init_ssh_session()/libssh2_session_handshake()"); goto shutdown; } if (!ulibssh2.disable_remote_fingerprint_check) { LIBSSH2_KNOWNHOSTS *nh = libssh2_knownhost_init(*session); if (!nh) { uwsgi_error("uwsgi_init_ssh_session()/libssh2_knownhost_init()"); goto shutdown; } if (libssh2_knownhost_readfile(nh, ulibssh2.known_hosts_path, LIBSSH2_KNOWNHOST_FILE_OPENSSH) < 0) { uwsgi_error("uwsgi_init_ssh_session()/libssh2_knownhost_readfile()"); } size_t len; int type; const char *fingerprint = libssh2_session_hostkey(*session, &len, &type); if (!fingerprint) { uwsgi_error("uwsgi_init_ssh_session()/libssh2_session_hostkey()"); libssh2_knownhost_free(nh); goto shutdown; } char *remoteaddr_str = uwsgi_str(usm->remote); char *port_str = strchr(remoteaddr_str, ':'); int port = SSH_DEFAULT_PORT; if (port_str) { port_str[0] = 0; port_str++; port = atoi(port_str); } struct libssh2_knownhost *host; int check = libssh2_knownhost_checkp( nh, remoteaddr_str, port, fingerprint, len, LIBSSH2_KNOWNHOST_TYPE_PLAIN|LIBSSH2_KNOWNHOST_KEYENC_RAW, &host ); free(remoteaddr_str); if (check != LIBSSH2_KNOWNHOST_CHECK_MATCH) { uwsgi_log("[SSH] Remote fingerprint check failed!\n"); libssh2_knownhost_free(nh); goto shutdown; } libssh2_knownhost_free(nh); } // If specified, username and password are honored if (usm->username && usm->password) { while ((rc = libssh2_userauth_password( *session, usm->username, usm->password) ) == LIBSSH2_ERROR_EAGAIN) { uwsgi_ssh_waitsocket(sock, *session); } if (rc) { uwsgi_error("uwsgi_init_ssh_session()/libssh2_userauth_password()"); goto shutdown; } else { goto end; } // Else, let's try the fallback authentication methods: } else if (usm->username || ulibssh2.username) { // Let's choose which username to use char* auth_user = ulibssh2.username; if (usm->username) { auth_user = usm->username; } // Password authentication if (ulibssh2.auth_pw && ulibssh2.password) { while ((rc = libssh2_userauth_password( *session, auth_user, ulibssh2.password) ) == LIBSSH2_ERROR_EAGAIN) { uwsgi_ssh_waitsocket(sock, *session); } if (rc) { uwsgi_error("uwsgi_init_ssh_session()/libssh2_userauth_password()"); // goto shutdown; } else { goto end; } } // SSH agent authentication if (usm->ssh_agent || ulibssh2.auth_ssh_agent) { if (uwsgi_ssh_agent_auth(*session, sock, auth_user)) { uwsgi_error("uwsgi_init_ssh_session()/uwsgi_ssh_agent_auth()"); // goto shutdown; } else { goto end; } } // Public key authentication if ((ulibssh2.private_key_path && ulibssh2.private_key_passphrase) || (usm->priv_key_path && usm->priv_key_passphrase)) { char *actual_pubk_path = ulibssh2.public_key_path; if (usm->pub_key_path) { actual_pubk_path = usm->pub_key_path; } char *actual_privk_path = ulibssh2.private_key_path; if (usm->priv_key_path) { actual_privk_path = usm->priv_key_path; } char *actual_passphrase = ulibssh2.private_key_passphrase; if (usm->priv_key_passphrase) { actual_passphrase = usm->priv_key_passphrase; } while ((rc = libssh2_userauth_publickey_fromfile( *session, auth_user, actual_pubk_path, actual_privk_path, actual_passphrase) ) == LIBSSH2_ERROR_EAGAIN) { uwsgi_ssh_waitsocket(sock, *session); } if (rc == LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED) { uwsgi_log("[SSH] ssh authentication failed (bad passphrase)\n"); // goto shutdown; } else if (rc) { uwsgi_error("uwsgi_init_ssh_session()/libssh2_userauth_publickey_fromfile()"); // goto shutdown; } else { goto end; } } } // If we arrive here, something went wrong. uwsgi_log("[SSH] session initialization failed (no authentication method worked)\n"); shutdown: close(sock); return 1; end: // Otherwise, we're fine! *socket_fd = sock; return 0; }
/** * seashell_tunnel_connect_password (const char* host, const char* user, const char* password, int* error) * Connects to the host via SSH on port 22, and launches a Seashell backend instance for that user * on the host. * * Consults /etc/seashell_hosts for host's SSH public keys. If this file does not exist, * this function will fail for security reasons. /etc/seashell_hosts is a standard * OpenSSH known_hosts file. * * Arguments: * host - Host to connect to. * user - User to run as. * password - User's password. * error - [optional] denotes error on failure. * remote_addr - Address to which the remote IP address will * be written. Reserve 128 bytes. * family - Address family. * target - Target to execute. * * Returns: * Handle to connection object on success, NULL otherwise. * If error is NOT null, error will hold more detailed error information. */ struct seashell_connection* seashell_tunnel_connect_password (const char* host, const char* user, const char* password, int* error, char * remote_addr, int* family, char* target) { struct addrinfo hints; struct addrinfo *results, *rp; int sockfd; int i, e; struct seashell_connection* result = NULL; /* Resolve the host's address. * See getaddrinfo(3) for how this works. */ memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = 0; hints.ai_protocol = 0; e = getaddrinfo(host, "22", &hints, &results); if (e != 0) { SET_ERROR(TUNNEL_ERROR_RESOLV); return NULL; } for (rp = results; rp != NULL; rp = rp->ai_next) { sockfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (sockfd == -1) continue; if (connect(sockfd, rp->ai_addr, rp->ai_addrlen) != -1) break; close(sockfd); } /* Write address that we're connecting to into * remote_addr. */ if(rp != NULL) { *family = rp->ai_family; switch(rp->ai_family) { case AF_INET: if(inet_ntop(rp->ai_family, &((struct sockaddr_in *)rp->ai_addr)->sin_addr, remote_addr, 128) == NULL) { SET_ERROR(TUNNEL_ERROR_RESOLV); return NULL; } break; case AF_INET6: if(inet_ntop(rp->ai_family, &((struct sockaddr_in6 *)rp->ai_addr)->sin6_addr, remote_addr, 128) == NULL) { SET_ERROR(TUNNEL_ERROR_RESOLV); return NULL; } break; default: SET_ERROR(TUNNEL_ERROR_RESOLV); return NULL; } } freeaddrinfo(results); /* Either rp == NULL, in which case we failed at connecting, * or sockfd holds our socket. */ if (rp == NULL) { SET_ERROR(TUNNEL_ERROR_CONNECT); return NULL; } /** Set up the session */ LIBSSH2_SESSION* session; LIBSSH2_CHANNEL* channel; LIBSSH2_KNOWNHOSTS* hosts; size_t len; int type; session = libssh2_session_init(); if (!session) { SET_ERROR(TUNNEL_ERROR_SESSION_START); goto session_teardown; } e = libssh2_session_handshake(session, sockfd); if (e) { SET_ERROR(TUNNEL_ERROR_SESSION_HANDSHAKE); goto session_teardown; } hosts = libssh2_knownhost_init(session); if (!hosts) { SET_ERROR(TUNNEL_ERROR_HOSTS_FILE); goto session_teardown; } if (!IS_INSTALLED() && access(DEBUG_HOSTS_FILE, F_OK) != -1) { libssh2_knownhost_readfile(hosts, DEBUG_HOSTS_FILE, LIBSSH2_KNOWNHOST_FILE_OPENSSH); } else { libssh2_knownhost_readfile(hosts, HOSTS_FILE, LIBSSH2_KNOWNHOST_FILE_OPENSSH); } const char* fingerprint = libssh2_session_hostkey(session, &len, &type); if (!fingerprint || type == LIBSSH2_HOSTKEY_TYPE_UNKNOWN) { libssh2_knownhost_free(hosts); SET_ERROR(TUNNEL_ERROR_HOST); goto session_teardown; } struct libssh2_knownhost *hostkey; /** NOTE: Documentation is buggy. hostkey MUST be passed. */ int check = libssh2_knownhost_check(hosts, host, fingerprint, len, LIBSSH2_KNOWNHOST_TYPE_PLAIN | LIBSSH2_KNOWNHOST_KEYENC_RAW, &hostkey); if (check != LIBSSH2_KNOWNHOST_CHECK_MATCH) { int keytype = 0; switch (type) { case LIBSSH2_HOSTKEY_TYPE_RSA: keytype = LIBSSH2_KNOWNHOST_KEY_SSHRSA; break; case LIBSSH2_HOSTKEY_TYPE_DSS: keytype = LIBSSH2_KNOWNHOST_KEY_SSHRSA; break; } if (keytype) { libssh2_knownhost_addc(hosts, host, NULL, fingerprint, len, "Generated from Seashell Tunnel", strlen("Generated from Seashell Tunnel"), LIBSSH2_KNOWNHOST_TYPE_PLAIN | LIBSSH2_KNOWNHOST_KEYENC_RAW | (type == LIBSSH2_HOSTKEY_TYPE_RSA ? LIBSSH2_KNOWNHOST_KEY_SSHRSA : LIBSSH2_KNOWNHOST_KEY_SSHDSS), NULL); libssh2_knownhost_writefile(hosts, DUMP_FILE, LIBSSH2_KNOWNHOST_FILE_OPENSSH); fprintf(stderr, "%s: Check SSH key for %s! Keys written to %s\n", user, host, DUMP_FILE); } else { fprintf(stderr, "%s: Check SSH key for %s!\n", user, host, DUMP_FILE); fprintf(stderr, "%s: Keys not written to file - contact Seashell Maintainers to add support for the LibSSH2 key format %d\n", user, type); } libssh2_knownhost_free(hosts); SET_ERROR(TUNNEL_ERROR_HOST); goto session_teardown; } libssh2_knownhost_free(hosts); FPRINTF_IF_DEBUG(stderr, "%s: Host check passed for %s (fingerprint type %d) - ", user, host, type); for(i = 0; i < 20; i++) { FPRINTF_IF_DEBUG(stderr, "%02X ", (unsigned char)fingerprint[i]); } FPRINTF_IF_DEBUG(stderr, "\n"); e = libssh2_userauth_password(session, user, password); if (e) { FPRINTF_IF_DEBUG(stderr, "%s: Error authenticating: %d\n", user, e); SET_ERROR(TUNNEL_ERROR_CREDS); goto session_teardown; } channel = libssh2_channel_open_session(session); if (!channel) { SET_ERROR(TUNNEL_ERROR_CHANNEL_OPEN); goto session_teardown; } /** * Ideally we'd have a subsystem configured, * as I don't see a good way of pulling out of ssh2 * if the target does not exist. */ e = libssh2_channel_exec(channel, target); if (e) { SET_ERROR(TUNNEL_ERROR_LAUNCH_SEASHELL); goto channel_teardown; } result = malloc(sizeof(struct seashell_connection)); if (!result) { SET_ERROR(TUNNEL_ERROR_SESSION_START); goto channel_teardown; } result->sockfd = sockfd; result->session = session; result->channel = channel; goto end; channel_teardown: libssh2_channel_free(channel); session_teardown: libssh2_session_free(session); close(sockfd); end: return result; }
void sshsocket::socket_connected_slot() { rc = libssh2_init (0); sock = socket->socketDescriptor() ; session = libssh2_session_init(); libssh2_session_set_blocking(session, 0); while ((rc = libssh2_session_startup(session, sock)) == LIBSSH2_ERROR_EAGAIN); if (rc) { emit error("Failure establishing SSH session!") ; libssh2_session_free(session); } nh = libssh2_knownhost_init(session); if(!nh) { /* eeek, do cleanup here */ } QString known_host_dir = QDesktopServices::storageLocation(QDesktopServices::DataLocation) + "known_hosts" ; libssh2_knownhost_readfile(nh, known_host_dir.toAscii(), LIBSSH2_KNOWNHOST_FILE_OPENSSH); fingerprint = libssh2_session_hostkey(session, &len, &type); if(fingerprint) { #if LIBSSH2_VERSION_NUM >= 0x010206 /* introduced in 1.2.6 */ struct libssh2_knownhost *known_host; int check = libssh2_knownhost_checkp(nh, host->hostname().toAscii(), host->port(), fingerprint, len, LIBSSH2_KNOWNHOST_TYPE_PLAIN| LIBSSH2_KNOWNHOST_KEYENC_RAW, &known_host); #else /* 1.2.5 or older */ int check = libssh2_knownhost_check(nh, host->hostname().toAscii(), fingerprint, len, LIBSSH2_KNOWNHOST_TYPE_PLAIN| LIBSSH2_KNOWNHOST_KEYENC_RAW, &known_host); #endif if (check == LIBSSH2_KNOWNHOST_CHECK_NOTFOUND) { const char *finger = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1); QString fingerkey ; fingerkey.append("Server's SHA-1 fingerprint is ") ; int i=0 ; for (i=0; i < 20; i++) { if (i != 19) { QString str ; str.sprintf("%02X:", (unsigned char)finger[i]) ; fingerkey.append(str) ; } else { QString str ; str.sprintf("%02X", (unsigned char)finger[i]) ; fingerkey.append(str) ; } if (i == 10) { fingerkey.append("<br>") ; } } if (mode == 0) { emit accept_fingerprint(fingerkey); } else { emit accept_fingerprint_edit(fingerkey); } setMode(0); } if (check == LIBSSH2_KNOWNHOST_CHECK_MATCH) { if (mode == 0) { emit insertHost(); } else { emit insertHost_edit(); } setMode(0); } } }
int ssh::login(const string & user_name, const string & password) { const char *fingerprint; int rc; int type; size_t len; /* Create a session instance */ session = libssh2_session_init(); if (!session){ cout << "session init error!" <<std::endl; return -1; } /* tell libssh2 we want it all done non-blocking */ libssh2_session_set_blocking(session, 0); /* ... start it up. This will trade welcome banners, exchange keys, * and setup crypto, compression, and MAC layers */ while ((rc = libssh2_session_handshake(session, _sock_fd)) == LIBSSH2_ERROR_EAGAIN); if (rc) { cout << "Failure establishing SSH session: "<< rc <<std::endl; return -1; } nh = libssh2_knownhost_init(session); if(!nh) { /* eeek, do cleanup here */ return 2; } /* read all hosts from here */ libssh2_knownhost_readfile(nh, _full_kownhost.c_str(), LIBSSH2_KNOWNHOST_FILE_OPENSSH); /* store all known hosts to here */ /* libssh2_knownhost_writefile(nh, "dumpfile", LIBSSH2_KNOWNHOST_FILE_OPENSSH);*/ fingerprint = libssh2_session_hostkey(session, &len, &type); if(fingerprint) { struct libssh2_knownhost *host; #if LIBSSH2_VERSION_NUM >= 0x010206 /* introduced in 1.2.6 */ int check = libssh2_knownhost_checkp(nh, _ip_addr.c_str(), 22, fingerprint, len, LIBSSH2_KNOWNHOST_TYPE_PLAIN| LIBSSH2_KNOWNHOST_KEYENC_RAW, &host); #else /* 1.2.5 or older */ int check = libssh2_knownhost_check(nh, _ip_addr.c_str(), fingerprint, len, LIBSSH2_KNOWNHOST_TYPE_PLAIN| LIBSSH2_KNOWNHOST_KEYENC_RAW, &host); #endif check = check; /*cout << "Host check: " << check << ", key: " << (check <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH ) ? host->key : "<none>";*/ /*cout << "Host check: " << check << ", key: " << host->key; cout << std::endl;*/ /***** * At this point, we could verify that 'check' tells us the key is * fine or bail out. *****/ } else { /* eeek, do cleanup here */ return 3; } libssh2_knownhost_free(nh); if ( password.size() != 0 ) { /* We could authenticate via password */ while ((rc = libssh2_userauth_password(session, user_name.c_str(), password.c_str())) == LIBSSH2_ERROR_EAGAIN); if (rc) { cout << "Authentication by password failed. " << std::endl; quit(); return -1; } } else { /* Or by public key */ while ((rc = libssh2_userauth_publickey_fromfile(session, user_name.c_str(), _full_dpublicfile.c_str(), _full_dprivatefile.c_str(), password.c_str())) == LIBSSH2_ERROR_EAGAIN); if (rc) { //cout << "\tAuthentication by public key failed " << std::endl; while ((rc = libssh2_userauth_publickey_fromfile(session, user_name.c_str(), _full_rpublicfile.c_str(), _full_rprivatefile.c_str(), password.c_str())) == LIBSSH2_ERROR_EAGAIN); if (rc) { cout << "\tAuthentication by public key failed " << std::endl; quit(); return -1; } } } #if 0 libssh2_trace(session, ~0 ); #endif return 0; }
void CEasyssh::ConnectAP(const std::string str_usr, std::string str_passwd) { WSADATA wsadata; WSAStartup(MAKEWORD(2,0), &wsadata); int rc = libssh2_init(0); if (rc != 0) { TRACE(_T("libssh2_init Error\n")); m_bIsErr = true; return; } unsigned long hostaddr = inet_addr(m_strIP.c_str()); m_sock = socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in sin; sin.sin_family = AF_INET; sin.sin_port = htons(22); sin.sin_addr.s_addr = hostaddr; if (connect(m_sock, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in)) != 0) { TRACE(_T("connect socket Error\n")); m_bIsErr = true; return; } /* Create a session instance */ m_ssh_session = libssh2_session_init(); if (!m_ssh_session) { TRACE(_T("libssh2_session_init Error\n")); m_bIsErr = true; return; } /* tell libssh2 we want it all done non-blocking */ libssh2_session_set_blocking(m_ssh_session, 0); /* ... start it up. This will trade welcome banners, exchange keys, * and setup crypto, compression, and MAC layers */ while ((rc = libssh2_session_handshake(m_ssh_session, m_sock)) == LIBSSH2_ERROR_EAGAIN); if (rc) { TRACE(_T("libssh2_session_handshake Error\n")); m_bIsErr = true; return; } LIBSSH2_KNOWNHOSTS *nh = libssh2_knownhost_init(m_ssh_session); if(!nh) { /* eeek, do cleanup here */ TRACE(_T("libssh2_knownhost_init Error\n")); m_bIsErr = true; return; } /* read all hosts from here */ libssh2_knownhost_readfile(nh, "known_hosts", LIBSSH2_KNOWNHOST_FILE_OPENSSH); /* store all known hosts to here */ libssh2_knownhost_writefile(nh, "dumpfile",LIBSSH2_KNOWNHOST_FILE_OPENSSH); libssh2_knownhost_free(nh); while ((rc = libssh2_userauth_password(m_ssh_session, str_usr.c_str(), str_passwd.c_str())) == LIBSSH2_ERROR_EAGAIN); if (rc) { TRACE(_T("libssh2_userauth_password Error\n")); m_bIsErr = true; libssh2_session_disconnect(m_ssh_session, "Normal Shutdown, Thank you for playing"); libssh2_session_free(m_ssh_session); closesocket(m_sock); libssh2_exit(); } m_bIsErr = false; }