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; }
lv_libssh2_status_t lv_libssh2_knownhosts_check_and_get( lv_libssh2_knownhosts_t* handle, const char* host, const int port, const uint8_t* key, const size_t key_len, const lv_libssh2_knownhost_name_types_t type, const lv_libssh2_knownhost_key_encodings_t encoding, lv_libssh2_knownhost_t* known_host, lv_libssh2_knownhosts_check_results_t* result ) { if (handle == NULL) { return LV_LIBSSH2_STATUS_ERROR_NULL_VALUE; } if (host == NULL) { return LV_LIBSSH2_STATUS_ERROR_NULL_VALUE; } if (key == NULL) { return LV_LIBSSH2_STATUS_ERROR_NULL_VALUE; } if (known_host == NULL) { return LV_LIBSSH2_STATUS_ERROR_NULL_VALUE; } if (result == NULL) { return LV_LIBSSH2_STATUS_ERROR_NULL_VALUE; } int type_mask = 0; switch (type) { case LV_LIBSSH2_KNOWNHOST_NAME_TYPE_PLAIN: type_mask = LIBSSH2_KNOWNHOST_TYPE_PLAIN; break; case LV_LIBSSH2_KNOWNHOST_NAME_TYPE_SHA1: type_mask = LIBSSH2_KNOWNHOST_TYPE_SHA1; break; case LV_LIBSSH2_KNOWNHOST_NAME_TYPE_CUSTOM: type_mask = LIBSSH2_KNOWNHOST_TYPE_CUSTOM; break; default: return LV_LIBSSH2_STATUS_ERROR_UNKNOWN_NAME_TYPE; } switch (encoding) { case LV_LIBSSH2_KNOWNHOST_KEY_ENCODING_RAW: type_mask = type_mask | LIBSSH2_KNOWNHOST_KEYENC_RAW; break; case LV_LIBSSH2_KNOWNHOST_KEY_ENCODING_BASE64: type_mask = type_mask | LIBSSH2_KNOWNHOST_KEYENC_BASE64; break; default: return LV_LIBSSH2_STATUS_ERROR_UNKNOWN_KEY_ENCODING; } int inner_result = libssh2_knownhost_checkp( handle->inner, host, port, (char*)key, key_len, type_mask, &known_host->inner ); switch (inner_result) { case LIBSSH2_KNOWNHOST_CHECK_FAILURE: *result = LV_LIBSSH2_KNOWNHOSTS_CHECK_RESULT_FAILURE; break; case LIBSSH2_KNOWNHOST_CHECK_NOTFOUND: *result = LV_LIBSSH2_KNOWNHOSTS_CHECK_RESULT_NOT_FOUND; break; case LIBSSH2_KNOWNHOST_CHECK_MATCH: *result = LV_LIBSSH2_KNOWNHOSTS_CHECK_RESULT_MATCH; break; case LIBSSH2_KNOWNHOST_CHECK_MISMATCH: *result = LV_LIBSSH2_KNOWNHOSTS_CHECK_RESULT_MISMATCH; break; default: return lv_libssh2_status_from_result(inner_result); } return LV_LIBSSH2_STATUS_OK; }
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; } }
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; }
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; }