bool client_d::try_keyboard() { BOOST_ASSERT( m_session ); BOOST_ASSERT( uname.size() ); int ec = libssh2_userauth_keyboard_interactive(m_session, uname.c_str(), &client_d::kbd_callback); while( ec == LIBSSH2_ERROR_EAGAIN ) { wait_on_socket(); ec = libssh2_userauth_keyboard_interactive(m_session, uname.c_str(), &client_d::kbd_callback); } return !ec; }
int SshConnection::connectKeyboardInteractive() { QLOG_TRACE() << "SshConnection::connectKeyboardInteractive()"; int rc; CurrentServerName = m_hostname; for (int count = 0; count < 3; ++count) { while ((rc = libssh2_userauth_keyboard_interactive(m_session, m_username.toLatin1().data(), &KeyboardCallback)) == LIBSSH2_ERROR_EAGAIN); if (rc != LIBSSH2_ERROR_AUTHENTICATION_FAILED) break; } return rc; }
int main(int argc, char *argv[]) { unsigned long hostaddr; int rc, sock, i, auth_pw = 0; struct sockaddr_in sin; const char *fingerprint; char *userauthlist; LIBSSH2_SESSION *session; LIBSSH2_CHANNEL *channel; #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) { hostaddr = inet_addr(argv[1]); } else { hostaddr = htonl(0x7F000001); } if(argc > 2) { username = argv[2]; } if(argc > 3) { password = argv[3]; } rc = libssh2_init (0); if (rc != 0) { fprintf (stderr, "libssh2 initialization failed (%d)\n", rc); return 1; } /* 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 and start it up. This will trade welcome * banners, exchange keys, and setup crypto, compression, and MAC layers */ session = libssh2_session_init(); if (libssh2_session_handshake(session, sock)) { fprintf(stderr, "Failure establishing SSH session\n"); return -1; } /* At this point we havn't authenticated. The first thing to do is check * the hostkey's fingerprint against our known hosts Your app may have it * hard coded, may go to a file, may present it to the user, that's your * call */ fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1); fprintf(stderr, "Fingerprint: "); for(i = 0; i < 20; i++) { fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]); } fprintf(stderr, "\n"); /* check what authentication methods are available */ userauthlist = libssh2_userauth_list(session, username, strlen(username)); fprintf(stderr, "Authentication methods: %s\n", userauthlist); if (strstr(userauthlist, "password") != NULL) { auth_pw |= 1; } if (strstr(userauthlist, "keyboard-interactive") != NULL) { auth_pw |= 2; } if (strstr(userauthlist, "publickey") != NULL) { auth_pw |= 4; } /* if we got an 4. argument we set this option if supported */ if(argc > 4) { if ((auth_pw & 1) && !strcasecmp(argv[4], "-p")) { auth_pw = 1; } if ((auth_pw & 2) && !strcasecmp(argv[4], "-i")) { auth_pw = 2; } if ((auth_pw & 4) && !strcasecmp(argv[4], "-k")) { auth_pw = 4; } } if (auth_pw & 1) { /* We could authenticate via password */ if (libssh2_userauth_password(session, username, password)) { fprintf(stderr, "\tAuthentication by password failed!\n"); goto shutdown; } else { fprintf(stderr, "\tAuthentication by password succeeded.\n"); } } else if (auth_pw & 2) { /* Or via keyboard-interactive */ if (libssh2_userauth_keyboard_interactive(session, username, &kbd_callback) ) { fprintf(stderr, "\tAuthentication by keyboard-interactive failed!\n"); goto shutdown; } else { fprintf(stderr, "\tAuthentication by keyboard-interactive succeeded.\n"); } } else if (auth_pw & 4) { /* Or by public key */ if (libssh2_userauth_publickey_fromfile(session, username, keyfile1, keyfile2, password)) { fprintf(stderr, "\tAuthentication by public key failed!\n"); goto shutdown; } else { fprintf(stderr, "\tAuthentication by public key succeeded.\n"); } } else { fprintf(stderr, "No supported authentication methods found!\n"); goto shutdown; } /* Request a shell */ if (!(channel = libssh2_channel_open_session(session))) { fprintf(stderr, "Unable to open a session\n"); goto shutdown; } /* Some environment variables may be set, * It's up to the server which ones it'll allow though */ libssh2_channel_setenv(channel, "FOO", "bar"); /* Request a terminal with 'vanilla' terminal emulation * See /etc/termcap for more options */ if (libssh2_channel_request_pty(channel, "vanilla")) { fprintf(stderr, "Failed requesting pty\n"); goto skip_shell; } /* Open a SHELL on that pty */ if (libssh2_channel_shell(channel)) { fprintf(stderr, "Unable to request shell on allocated pty\n"); goto shutdown; } /* At this point the shell can be interacted with using * libssh2_channel_read() * libssh2_channel_read_stderr() * libssh2_channel_write() * libssh2_channel_write_stderr() * * Blocking mode may be (en|dis)abled with: libssh2_channel_set_blocking() * If the server send EOF, libssh2_channel_eof() will return non-0 * To send EOF to the server use: libssh2_channel_send_eof() * A channel can be closed with: libssh2_channel_close() * A channel can be freed with: libssh2_channel_free() */ skip_shell: if (channel) { libssh2_channel_free(channel); channel = NULL; } /* Other channel types are supported via: * libssh2_scp_send() * libssh2_scp_recv() * libssh2_channel_direct_tcpip() */ 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; }
/* example ssh.run["ls /"] */ static int ssh_run(DC_ITEM *item, AGENT_RESULT *result, const char *encoding) { const char *__function_name = "ssh_run"; zbx_sock_t s; LIBSSH2_SESSION *session; LIBSSH2_CHANNEL *channel; int auth_pw = 0, rc, ret = NOTSUPPORTED, exitcode, bytecount = 0; char buffer[MAX_BUFFER_LEN], buf[16], *userauthlist, *publickey = NULL, *privatekey = NULL, *ssherr; size_t sz; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (FAIL == zbx_tcp_connect(&s, CONFIG_SOURCE_IP, item->interface.addr, item->interface.port, 0)) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot connect to SSH server: %s", zbx_tcp_strerror())); goto close; } /* initializes an SSH session object */ if (NULL == (session = libssh2_session_init())) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot initialize SSH session")); goto tcp_close; } /* set blocking mode on session */ libssh2_session_set_blocking(session, 1); /* Create a session instance and start it up. This will trade welcome */ /* banners, exchange keys, and setup crypto, compression, and MAC layers */ if (0 != libssh2_session_startup(session, s.socket)) { libssh2_session_last_error(session, &ssherr, NULL, 0); SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot establish SSH session: %s", ssherr)); goto session_free; } /* check what authentication methods are available */ if (NULL != (userauthlist = libssh2_userauth_list(session, item->username, strlen(item->username)))) { if (NULL != strstr(userauthlist, "password")) auth_pw |= 1; if (NULL != strstr(userauthlist, "keyboard-interactive")) auth_pw |= 2; if (NULL != strstr(userauthlist, "publickey")) auth_pw |= 4; } else { libssh2_session_last_error(session, &ssherr, NULL, 0); SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain authentication methods: %s", ssherr)); goto session_close; } zabbix_log(LOG_LEVEL_DEBUG, "%s() supported authentication methods:'%s'", __function_name, userauthlist); switch (item->authtype) { case ITEM_AUTHTYPE_PASSWORD: if (auth_pw & 1) { /* we could authenticate via password */ if (0 != libssh2_userauth_password(session, item->username, item->password)) { libssh2_session_last_error(session, &ssherr, NULL, 0); SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Password authentication failed: %s", ssherr)); goto session_close; } else zabbix_log(LOG_LEVEL_DEBUG, "%s() password authentication succeeded", __function_name); } else if (auth_pw & 2) { /* or via keyboard-interactive */ password = item->password; if (0 != libssh2_userauth_keyboard_interactive(session, item->username, &kbd_callback)) { libssh2_session_last_error(session, &ssherr, NULL, 0); SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Keyboard-interactive authentication" " failed: %s", ssherr)); goto session_close; } else zabbix_log(LOG_LEVEL_DEBUG, "%s() keyboard-interactive authentication succeeded", __function_name); } else { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Unsupported authentication method." " Supported methods: %s", userauthlist)); goto session_close; } break; case ITEM_AUTHTYPE_PUBLICKEY: if (auth_pw & 4) { if (NULL == CONFIG_SSH_KEY_LOCATION) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Authentication by public key failed." " SSHKeyLocation option is not set")); goto session_close; } /* or by public key */ publickey = zbx_dsprintf(publickey, "%s/%s", CONFIG_SSH_KEY_LOCATION, item->publickey); privatekey = zbx_dsprintf(privatekey, "%s/%s", CONFIG_SSH_KEY_LOCATION, item->privatekey); if (SUCCEED != zbx_is_regular_file(publickey)) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot access public key file %s", publickey)); goto session_close; } if (SUCCEED != zbx_is_regular_file(privatekey)) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot access private key file %s", privatekey)); goto session_close; } rc = libssh2_userauth_publickey_fromfile(session, item->username, publickey, privatekey, item->password); zbx_free(publickey); zbx_free(privatekey); if (0 != rc) { libssh2_session_last_error(session, &ssherr, NULL, 0); SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Public key authentication failed:" " %s", ssherr)); goto session_close; } else zabbix_log(LOG_LEVEL_DEBUG, "%s() authentication by public key succeeded", __function_name); } else { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Unsupported authentication method." " Supported methods: %s", userauthlist)); goto session_close; } break; } /* exec non-blocking on the remove host */ while (NULL == (channel = libssh2_channel_open_session(session))) { switch (libssh2_session_last_error(session, NULL, NULL, 0)) { /* marked for non-blocking I/O but the call would block. */ case LIBSSH2_ERROR_EAGAIN: waitsocket(s.socket, session); continue; default: SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot establish generic session channel")); goto session_close; } } dos2unix(item->params); /* CR+LF (Windows) => LF (Unix) */ /* request a shell on a channel and execute command */ while (0 != (rc = libssh2_channel_exec(channel, item->params))) { switch (rc) { case LIBSSH2_ERROR_EAGAIN: waitsocket(s.socket, session); continue; default: SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot request a shell")); goto channel_close; } } for (;;) { /* loop until we block */ do { if (0 < (rc = libssh2_channel_read(channel, buf, sizeof(buf)))) { sz = (size_t)rc; if (sz > MAX_BUFFER_LEN - (bytecount + 1)) sz = MAX_BUFFER_LEN - (bytecount + 1); if (0 == sz) continue; memcpy(buffer + bytecount, buf, sz); bytecount += sz; } } while (rc > 0); /* this is due to blocking that would occur otherwise so we loop on * this condition */ if (LIBSSH2_ERROR_EAGAIN == rc) waitsocket(s.socket, session); else if (rc < 0) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot read data from SSH server")); goto channel_close; } else break; } buffer[bytecount] = '\0'; SET_STR_RESULT(result, convert_to_utf8(buffer, bytecount, encoding)); ret = SYSINFO_RET_OK; channel_close: /* close an active data channel */ exitcode = 127; while (0 != (rc = libssh2_channel_close(channel))) { switch (rc) { case LIBSSH2_ERROR_EAGAIN: waitsocket(s.socket, session); continue; default: libssh2_session_last_error(session, &ssherr, NULL, 0); zabbix_log(LOG_LEVEL_WARNING, "%s() cannot close generic session channel: %s", __function_name, ssherr); break; } } if (0 == rc) exitcode = libssh2_channel_get_exit_status(channel); zabbix_log(LOG_LEVEL_DEBUG, "%s() exitcode: %d bytecount: %d", __function_name, exitcode, bytecount); libssh2_channel_free(channel); channel = NULL; session_close: libssh2_session_disconnect(session, "Normal Shutdown"); session_free: libssh2_session_free(session); tcp_close: zbx_tcp_close(&s); close: zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
int FSSftp::CheckSession( int* err, FSCInfo* info ) { if ( sshSession ) { return 0; } try { unsigned ip; int e; if ( !GetHostIp( unicode_to_utf8( _operParam.server.Data() ).data(), &ip, &e ) ) { throw int( e ); } _sock.Create(); _sock.Connect( ntohl( ip ), _operParam.port ); sshSession = libssh2_session_init(); if ( !sshSession ) { throw int( SSH_INTERROR_X3 ); } libssh2_session_set_blocking( sshSession, 0 ); WHILE_EAGAIN_( e, libssh2_session_handshake( sshSession, _sock.Id() ) ); if ( e ) { throw int( e - 1000 ); } FSString userName = ""; if ( _operParam.user.Data()[0] ) { userName = _operParam.user.Data(); } else { #ifndef _WIN32 char* ret = getenv( "LOGNAME" ); if ( ret ) { userName = FSString( sys_charset_id, ret ); _operParam.user = userName.GetUnicode(); MutexLock infoLock( &infoMutex ); _infoParam.user = userName.GetUnicode(); } #endif }; char* authList = 0; char* charUserName = ( char* )userName.Get( _operParam.charset ); while ( true ) { authList = libssh2_userauth_list( sshSession, charUserName, strlen( charUserName ) ); if ( authList ) { break; } CheckSessionEagain(); WaitSocket( info ); } //publickey,password,keyboard-interactive static const char passId[] = "password"; static const char kInterId[] = "keyboard-interactive"; static unicode_t userSymbol = '@'; while ( true ) { if ( !strncmp( authList, passId, strlen( passId ) ) ) { FSPromptData data; data.visible = false; data.prompt = utf8_to_unicode( "Password:"******"SFTP_" ).data(), carray_cat<unicode_t>( userName.GetUnicode(), &userSymbol, _operParam.server.Data() ).data(), &data, 1 ) ) { throw int( SSH_INTERROR_STOPPED ); } int ret; WHILE_EAGAIN_( ret, libssh2_userauth_password( sshSession, ( char* )FSString( _operParam.user.Data() ).Get( _operParam.charset ), ( char* )FSString( data.prompt.Data() ).Get( _operParam.charset ) ) ); if ( ret ) { throw int( ret - 1000 ); } break; //!!! } else if ( !strncmp( authList, kInterId, strlen( kInterId ) ) ) { MutexLock lock( &kbdIntMutex ); kbdIntInfo = info; kbdIntParam = &_operParam; int ret; WHILE_EAGAIN_( ret, libssh2_userauth_keyboard_interactive( sshSession, ( char* )FSString( _operParam.user.Data() ).Get( _operParam.charset ), KbIntCallback ) ); if ( ret ) { throw int( ret - 1000 ); } break; //!!! } char* s = authList; while ( *s && *s != ',' ) { s++; } if ( !*s ) { break; } authList = s + 1; }; while ( true ) { sftpSession = libssh2_sftp_init( sshSession ); if ( sftpSession ) { break; } if ( !sftpSession ) { int e = libssh2_session_last_errno( sshSession ); if ( e != LIBSSH2_ERROR_EAGAIN ) { throw int( e - 1000 ); } } WaitSocket( info ); } return 0; } catch ( int e ) { if ( err ) { *err = e; } //if (sftpSession) ??? похоже закрытие сессии все решает if ( sshSession ) { libssh2_session_free( sshSession ); } sshSession = 0; sftpSession = 0; _sock.Close( false ); return ( e == -2 ) ? -2 : -1; } }
static int _git_ssh_authenticate_session( LIBSSH2_SESSION* session, git_cred* cred) { int rc; do { giterr_clear(); switch (cred->credtype) { case GIT_CREDTYPE_USERPASS_PLAINTEXT: { git_cred_userpass_plaintext *c = (git_cred_userpass_plaintext *)cred; rc = libssh2_userauth_password(session, c->username, c->password); break; } case GIT_CREDTYPE_SSH_KEY: { git_cred_ssh_key *c = (git_cred_ssh_key *)cred; if (c->privatekey) rc = libssh2_userauth_publickey_fromfile( session, c->username, c->publickey, c->privatekey, c->passphrase); else rc = ssh_agent_auth(session, c); break; } case GIT_CREDTYPE_SSH_CUSTOM: { git_cred_ssh_custom *c = (git_cred_ssh_custom *)cred; rc = libssh2_userauth_publickey( session, c->username, (const unsigned char *)c->publickey, c->publickey_len, c->sign_callback, &c->payload); break; } case GIT_CREDTYPE_SSH_INTERACTIVE: { void **abstract = libssh2_session_abstract(session); git_cred_ssh_interactive *c = (git_cred_ssh_interactive *)cred; /* ideally, we should be able to set this by calling * libssh2_session_init_ex() instead of libssh2_session_init(). * libssh2's API is inconsistent here i.e. libssh2_userauth_publickey() * allows you to pass the `abstract` as part of the call, whereas * libssh2_userauth_keyboard_interactive() does not! * * The only way to set the `abstract` pointer is by calling * libssh2_session_abstract(), which will replace the existing * pointer as is done below. This is safe for now (at time of writing), * but may not be valid in future. */ *abstract = c->payload; rc = libssh2_userauth_keyboard_interactive( session, c->username, c->prompt_callback); break; } #ifdef GIT_SSH_MEMORY_CREDENTIALS case GIT_CREDTYPE_SSH_MEMORY: { git_cred_ssh_key *c = (git_cred_ssh_key *)cred; assert(c->username); assert(c->privatekey); rc = libssh2_userauth_publickey_frommemory( session, c->username, strlen(c->username), c->publickey, c->publickey ? strlen(c->publickey) : 0, c->privatekey, strlen(c->privatekey), c->passphrase); break; } #endif default: rc = LIBSSH2_ERROR_AUTHENTICATION_FAILED; } } while (LIBSSH2_ERROR_EAGAIN == rc || LIBSSH2_ERROR_TIMEOUT == rc); if (rc == LIBSSH2_ERROR_PASSWORD_EXPIRED || rc == LIBSSH2_ERROR_AUTHENTICATION_FAILED) return GIT_EAUTH; if (rc != LIBSSH2_ERROR_NONE) { if (!giterr_last()) ssh_error(session, "Failed to authenticate SSH session"); return -1; } return 0; }
int main(int argc, char *argv[]) { int sock , i, auth_pw = 0, port = 22; struct sockaddr_in6 sin; const char *fingerprint; char *userauthlist; LIBSSH2_SESSION *session; int rc; LIBSSH2_SFTP *sftp_session; LIBSSH2_SFTP_HANDLE *sftp_handle; struct hostent *server; if (!strcmp(argv[1], "--help")) usage(); if (argc > 1) { inet_pton(AF_INET6,argv[1],sin.sin6_addr.s6_addr); } if (argc > 2) { port = atoi(argv[2]); } if (argc > 3) { username = argv[3]; } if (argc > 4) { password = argv[4]; } if (argc > 5) { sftppath = argv[5]; } if (argc > 6) { localpath = argv[6]; } sock = socket(AF_INET6, SOCK_STREAM, 0); server = gethostbyname2(argv[1],AF_INET6); if (server == NULL) { fprintf(stderr, "ERROR, no such host\n"); exit(0); } memset((char *) &sin, 0, sizeof(sin)); sin.sin6_flowinfo = 0; sin.sin6_family = AF_INET6; memmove((char *) &sin.sin6_addr.s6_addr, (char *) server->h_addr, server->h_length); sin.sin6_port = htons(port); if (connect(sock, (struct sockaddr *)(&sin), sizeof(struct sockaddr_in6)) != 0) { fprintf(stderr, "failed to connect!\n"); return -1; } session = libssh2_session_init(); if (!session) return -1; libssh2_session_set_blocking(session, 1); rc = libssh2_session_startup(session, sock); if (rc) { fprintf(stderr, "Failure establishing SSH session: %d\n", rc); return -1; } fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5); userauthlist = libssh2_userauth_list(session, username, strlen(username)); if (strstr(userauthlist, "password") != NULL) { auth_pw |= 1; } if (strstr(userauthlist, "keyboard-interactive") != NULL) { auth_pw |= 2; } if (strstr(userauthlist, "publickey") != NULL) { auth_pw |= 4; } /* if we got an 4. argument we set this option if supported */ if (argc > 5) { if ((auth_pw & 1) && !strcasecmp(argv[5], "-p")) { auth_pw = 1; } if ((auth_pw & 2) && !strcasecmp(argv[5], "-i")) { auth_pw = 2; } if ((auth_pw & 4) && !strcasecmp(argv[5], "-k")) { auth_pw = 4; } } if (auth_pw & 1) { if (libssh2_userauth_password(session, username, password)) { return 1; goto shutdown; } } else if (auth_pw & 2) { if (libssh2_userauth_keyboard_interactive(session, username, &kbd_callback)) { return 1; goto shutdown; } } else if (auth_pw & 4) { if (libssh2_userauth_publickey_fromfile(session, username, keyfile1, keyfile2, password)) { printf("\tAuthentication by public key failed!\n"); return 1; goto shutdown; } } else { printf("No supported authentication methods found!\n"); return 1; goto shutdown; } sftp_session = libssh2_sftp_init(session); if (!sftp_session) { fprintf(stderr, "Unable to init SFTP session\n"); return 1; goto shutdown; } sftp_handle = libssh2_sftp_open(sftp_session, sftppath, LIBSSH2_FXF_READ, 0); if (!sftp_handle) { return 2; goto shutdown; } FILE *fp = fopen(localpath, "w"); if (fp) { char mem [1024]; do { rc = libssh2_sftp_read(sftp_handle, mem, sizeof(mem)); if (rc > 0) { fwrite(mem, rc, 1, fp); } else { break; } } while (1); fclose(fp); } libssh2_sftp_close(sftp_handle); libssh2_sftp_shutdown(sftp_session); shutdown: libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing"); libssh2_session_free(session); #ifdef WIN32 closesocket(sock); #else close(sock); #endif return 0; }
redisContext *redisConnect(const char *ip, int port, const char *ssh_address, int ssh_port, const char *username, const char *password, const char *public_key, const char *private_key, const char *passphrase, int curMethod) { LIBSSH2_SESSION *session = NULL; if(ssh_address && curMethod != SSH_UNKNOWN){ int rc = libssh2_init(0); if (rc != 0) { return NULL; } struct sockaddr_in sin; /* Connect to SSH server */ int sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); sin.sin_family = AF_INET; if (INADDR_NONE == (sin.sin_addr.s_addr = inet_addr(ssh_address))) { return NULL; } sin.sin_port = htons(ssh_port); if (connect(sock, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in)) != 0) { return NULL; } /* Create a session instance */ session = libssh2_session_init(); if(!session) { return NULL; } /* ... start it up. This will trade welcome banners, exchange keys, * and setup crypto, compression, and MAC layers */ rc = libssh2_session_handshake(session, sock); if(rc) { return NULL; } int auth_pw = 0; libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1); char *userauthlist = libssh2_userauth_list(session, username, strlen(username)); if (strstr(userauthlist, "password") != NULL) { auth_pw |= 1; } if (strstr(userauthlist, "keyboard-interactive") != NULL) { auth_pw |= 2; } if (strstr(userauthlist, "publickey") != NULL) { auth_pw |= 4; } if (auth_pw & 1 && curMethod == SSH_PASSWORD) { /* We could authenticate via password */ if (libssh2_userauth_password(session, username, password)) { //"Authentication by password failed!"; return NULL; } } else if (auth_pw & 2) { /* Or via keyboard-interactive */ if (libssh2_userauth_keyboard_interactive(session, username, &kbd_callback) ) { //"Authentication by keyboard-interactive failed!"; return NULL; } } else if (auth_pw & 4 && curMethod == SSH_PUBLICKEY) { /* Or by public key */ if (libssh2_userauth_publickey_fromfile(session, username, public_key, private_key, passphrase)){ //"Authentication by public key failed!"; return NULL; } } else { //"No supported authentication methods found!"; return NULL; } } redisContext *c; c = redisContextInit(); if (c == NULL) return NULL; c->session = session; c->flags |= REDIS_BLOCK; redisContextConnectTcp(c,ip,port,NULL); return c; }
bool CSSHTunnelThread::Initialize() { int rc, auth = AUTH_NONE; const char *fingerprint; char *userauthlist; #ifdef WIN32 char sockopt; WSADATA wsadata; int err; err = WSAStartup(MAKEWORD(2, 0), &wsadata); if(err != 0) { wxLogInfo(wxT("WSAStartup failed with error: %d"), err); return false; } #else int sockopt; #endif wxArrayString arrTunnelHostIP; if (resolveDNS(m_tunnelhost.mb_str(), arrTunnelHostIP)) { rc = libssh2_init (0); if (rc != 0) { LogSSHTunnelErrors(wxString::Format(_("libssh2 initialization failed with error code %d"), rc), GetId()); return false; } /* Connect to SSH server */ m_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); m_sin.sin_family = AF_INET; if (INADDR_NONE == (m_sin.sin_addr.s_addr = inet_addr(arrTunnelHostIP.Item(0).mb_str()))) { LogSSHTunnelErrors(wxString::Format(_("SSH error: Error in inet address with error code %d"), wxSysErrorCode()), GetId()); return false; } m_sin.sin_port = htons(m_tunnelPort); if (connect(m_sock, (struct sockaddr *)(&m_sin), sizeof(struct sockaddr_in)) != 0) { LogSSHTunnelErrors(wxString::Format(_("SSH error: Could not connect to socket with error code %d"), wxSysErrorCode()), GetId()); return false; } /* Create a session instance */ m_session = libssh2_session_init(); if (!m_session) { LogSSHTunnelErrors(_("SSH error: Could not initialize SSH session!"), GetId()); return false; } /* ... start it up. This will trade welcome banners, exchange keys, * and setup crypto, compression, and MAC layers */ rc = libssh2_session_handshake(m_session, m_sock); if (rc) { LogSSHTunnelErrors(wxString::Format(_("SSH error: Error when starting up SSH session with error code %d"), rc), GetId()); return false; } /* At this point we havn't yet authenticated. The first thing to do * is check the hostkey's fingerprint against our known hosts Your app * may have it hard coded, may go to a file, may present it to the * user, that's your call */ fingerprint = libssh2_hostkey_hash(m_session, LIBSSH2_HOSTKEY_HASH_SHA1); wxString newHostKey = wxEmptyString; for(int i = 0; i < 20; i++) { newHostKey += wxString::Format(wxT("%02X "), (unsigned char)fingerprint[i]); } // Check if the SSH Host Key is verified if(!IsHostKeyVerified(newHostKey)) { Cleanup(); return false; } /* check what authentication methods are available */ userauthlist = libssh2_userauth_list(m_session, m_username.mb_str(), strlen(m_username.mb_str())); if (strstr(userauthlist, "password")) auth |= AUTH_PASSWORD; if(strstr(userauthlist, "keyboard-interactive")) auth |= AUTH_KEYBOARD_INTERACTIVE; if (strstr(userauthlist, "publickey")) auth |= AUTH_PUBLICKEY; if ((auth & AUTH_PASSWORD) && (m_enAuthMethod == AUTH_PASSWORD)) auth = AUTH_PASSWORD; else if ((auth & AUTH_KEYBOARD_INTERACTIVE) && (m_enAuthMethod == AUTH_PASSWORD)) auth = AUTH_KEYBOARD_INTERACTIVE; if ((auth & AUTH_PUBLICKEY) && (m_enAuthMethod == AUTH_PUBLICKEY)) auth = AUTH_PUBLICKEY; if (auth & AUTH_PASSWORD) { rc = libssh2_userauth_password(m_session, m_username.mb_str(), m_password.mb_str()); if (rc) { LogSSHTunnelErrors(wxString::Format(_("SSH error: Authentication by password failed with error code %d"), rc), GetId()); Cleanup(); return false; } } else if (auth & AUTH_KEYBOARD_INTERACTIVE) { rc = libssh2_userauth_keyboard_interactive(m_session, m_username.mb_str(), &CSSHTunnelThread::keyboard_interactive); if (rc) { LogSSHTunnelErrors(wxString::Format(_("SSH error: Authentication by password failed with error code %d"), rc), GetId()); Cleanup(); return false; } } else if (auth & AUTH_PUBLICKEY) { #ifdef HAVE_GCRYPT rc = libssh2_userauth_publickey_fromfile(m_session, m_username.mb_str(), m_publickey.mb_str(), m_privatekey.mb_str(), m_password.mb_str()); #else rc = libssh2_userauth_publickey_fromfile(m_session, m_username.mb_str(), NULL, m_privatekey.mb_str(), m_password.mb_str()); #endif if (rc) { LogSSHTunnelErrors(wxString::Format(_("SSH error: Authentication by identity file failed with error code %d"), rc), GetId()); Cleanup(); return false; } } else { LogSSHTunnelErrors(_("SSH error: No supported authentication methods found!"), GetId()); Cleanup(); return false; } // Get the IP Address of local machine wxArrayString arrLocalIP; if(resolveDNS("localhost", arrLocalIP)) { m_listensock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); memset(&m_sin, 0 , sizeof(m_sin)); m_sin.sin_family = AF_INET; // Give port no to 0 so that bind will automatically select the available port. m_sin.sin_port = htons(0); if (INADDR_NONE == (m_sin.sin_addr.s_addr = inet_addr(arrLocalIP.Item(0).mb_str()))) { Cleanup(); return false; } sockopt = 1; setsockopt(m_listensock, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof(sockopt)); m_sinlen = sizeof(m_sin); if (-1 == bind(m_listensock, (struct sockaddr *)&m_sin, m_sinlen)) { LogSSHTunnelErrors(wxString::Format(_("SSH error: bind failed with error code %d"), wxSysErrorCode()), GetId()); Cleanup(); return false; } if (getsockname(m_listensock, (struct sockaddr *)&m_sin, &m_sinlen) == -1) { LogSSHTunnelErrors(wxString::Format(_("SSH error: getsockname() failed with error code %d"), wxSysErrorCode()), GetId()); Cleanup(); return false; } if (-1 == listen(m_listensock, 2)) { LogSSHTunnelErrors(wxString::Format(_("SSH error: listen failed with error code %d"), wxSysErrorCode()), GetId()); Cleanup(); return false; } m_local_listenip = wxString(inet_ntoa(m_sin.sin_addr), wxConvLibc); m_local_listenport = ntohs(m_sin.sin_port); wxLogInfo(wxT("Waiting for TCP connection on %s:%d..."), m_local_listenip.c_str(), m_local_listenport); return true; } else { LogSSHTunnelErrors(_("SSH error: Unable to resolve localhost"), GetId()); } } else { LogSSHTunnelErrors(wxString::Format(_("SSH error: Unable to resolve host: %s"), m_tunnelhost.c_str()), GetId()); } return false; }
/** * Authenticates the user associated with the given session over SSH. All * required credentials must already be present within the user object * associated with the given session. * * @param session * The session associated with the user to be authenticated. * * @return * Zero if authentication succeeds, or non-zero if authentication has * failed. */ static int guac_common_ssh_authenticate(guac_common_ssh_session* common_session) { guac_client* client = common_session->client; guac_common_ssh_user* user = common_session->user; LIBSSH2_SESSION* session = common_session->session; /* Get user credentials */ char* username = user->username; char* password = user->password; guac_common_ssh_key* key = user->private_key; /* Get list of supported authentication methods */ char* user_authlist = libssh2_userauth_list(session, username, strlen(username)); guac_client_log(client, GUAC_LOG_DEBUG, "Supported authentication methods: %s", user_authlist); /* Authenticate with private key, if provided */ if (key != NULL) { /* Check if public key auth is supported on the server */ if (strstr(user_authlist, "publickey") == NULL) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_CLIENT_UNAUTHORIZED, "Public key authentication not supported"); return 1; } /* Attempt public key auth */ if (libssh2_userauth_publickey(session, username, (unsigned char*) key->public_key, key->public_key_length, guac_common_ssh_sign_callback, (void**) key)) { /* Abort on failure */ char* error_message; libssh2_session_last_error(session, &error_message, NULL, 0); guac_client_abort(client, GUAC_PROTOCOL_STATUS_CLIENT_UNAUTHORIZED, "Public key authentication failed: %s", error_message); return 1; } /* Private key authentication succeeded */ return 0; } /* Authenticate with password */ if (strstr(user_authlist, "password") != NULL) { guac_client_log(client, GUAC_LOG_DEBUG, "Using password authentication method"); return libssh2_userauth_password(session, username, password); } /* Authenticate with password via keyboard-interactive auth */ if (strstr(user_authlist, "keyboard-interactive") != NULL) { guac_client_log(client, GUAC_LOG_DEBUG, "Using keyboard-interactive authentication method"); return libssh2_userauth_keyboard_interactive(session, username, &guac_common_ssh_kbd_callback); } /* No known authentication types available */ guac_client_abort(client, GUAC_PROTOCOL_STATUS_CLIENT_BAD_TYPE, "No known authentication methods"); return 1; }
int main(int argc, char *argv[]) { unsigned long hostaddr; int sock, i, auth_pw = 0; struct sockaddr_in sin; const char *fingerprint; char *userauthlist; LIBSSH2_SESSION *session; int rc; LIBSSH2_SFTP *sftp_session; LIBSSH2_SFTP_HANDLE *sftp_handle; #ifdef WIN32 WSADATA wsadata; WSAStartup(MAKEWORD(2,0), &wsadata); #endif if (argc > 1) { hostaddr = inet_addr(argv[1]); } else { hostaddr = htonl(0x7F000001); } if(argc > 2) { username = argv[2]; } if(argc > 3) { password = argv[3]; } if(argc > 4) { sftppath = argv[4]; } rc = libssh2_init (0); if (rc != 0) { fprintf (stderr, "libssh2 initialization failed (%d)\n", rc); return 1; } /* * The application code is responsible for creating the socket * and 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; /* Since we have set non-blocking, tell libssh2 we are blocking */ libssh2_session_set_blocking(session, 1); /* ... start it up. This will trade welcome banners, exchange keys, * and setup crypto, compression, and MAC layers */ rc = libssh2_session_startup(session, sock); if(rc) { fprintf(stderr, "Failure establishing SSH session: %d\n", rc); return -1; } /* At this point we havn't yet authenticated. The first thing to do * is check the hostkey's fingerprint against our known hosts Your app * may have it hard coded, may go to a file, may present it to the * user, that's your call */ fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1); fprintf(stderr, "Fingerprint: "); for(i = 0; i < 20; i++) { fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]); } fprintf(stderr, "\n"); /* check what authentication methods are available */ userauthlist = libssh2_userauth_list(session, username, strlen(username)); printf("Authentication methods: %s\n", userauthlist); if (strstr(userauthlist, "password") != NULL) { auth_pw |= 1; } if (strstr(userauthlist, "keyboard-interactive") != NULL) { auth_pw |= 2; } if (strstr(userauthlist, "publickey") != NULL) { auth_pw |= 4; } /* if we got an 4. argument we set this option if supported */ if(argc > 5) { if ((auth_pw & 1) && !strcasecmp(argv[5], "-p")) { auth_pw = 1; } if ((auth_pw & 2) && !strcasecmp(argv[5], "-i")) { auth_pw = 2; } if ((auth_pw & 4) && !strcasecmp(argv[5], "-k")) { auth_pw = 4; } } if (auth_pw & 1) { /* We could authenticate via password */ if (libssh2_userauth_password(session, username, password)) { fprintf(stderr, "Authentication by password failed.\n"); goto shutdown; } } else if (auth_pw & 2) { /* Or via keyboard-interactive */ if (libssh2_userauth_keyboard_interactive(session, username, &kbd_callback) ) { printf("\tAuthentication by keyboard-interactive failed!\n"); goto shutdown; } else { printf("\tAuthentication by keyboard-interactive succeeded.\n"); } } else if (auth_pw & 4) { /* Or by public key */ if (libssh2_userauth_publickey_fromfile(session, username, keyfile1, keyfile2, password)) { printf("\tAuthentication by public key failed!\n"); goto shutdown; } else { printf("\tAuthentication by public key succeeded.\n"); } } else { printf("No supported authentication methods found!\n"); goto shutdown; } fprintf(stderr, "libssh2_sftp_init()!\n"); sftp_session = libssh2_sftp_init(session); if (!sftp_session) { fprintf(stderr, "Unable to init SFTP session\n"); goto shutdown; } fprintf(stderr, "libssh2_sftp_open()!\n"); /* Request a file via SFTP */ sftp_handle = libssh2_sftp_open(sftp_session, sftppath, LIBSSH2_FXF_READ, 0); if (!sftp_handle) { fprintf(stderr, "Unable to open file with SFTP: %ld\n", libssh2_sftp_last_error(sftp_session)); goto shutdown; } fprintf(stderr, "libssh2_sftp_open() is done, now receive data!\n"); do { char mem[1024]; /* loop until we fail */ fprintf(stderr, "libssh2_sftp_read()!\n"); rc = libssh2_sftp_read(sftp_handle, mem, sizeof(mem)); if (rc > 0) { write(1, mem, rc); } else { break; } } while (1); libssh2_sftp_close(sftp_handle); libssh2_sftp_shutdown(sftp_session); 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; }
int SSH2Utils::connect(const char *hostname, const char *username, const char *password) { unsigned long hostaddr; int rc, sock, auth_pw = 0; struct sockaddr_in sin; const char *fingerprint; char *userauthlist; LIBSSH2_SESSION *session; _password = password; 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"); m_errCode = 2; return -1; } /* Create a session instance */ session = libssh2_session_init(); if (!session) { m_errCode = 3; 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_startup(session, sock)) == LIBSSH2_ERROR_EAGAIN) ; if (rc) { fprintf(stderr, "Failure establishing SSH session: %d\n", rc); m_errCode = 4; return -1; } /* At this point we havn't authenticated. The first thing to do is check * the hostkey's fingerprint against our known hosts Your app may have it * hard coded, may go to a file, may present it to the user, that's your * call */ fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1); printf("Fingerprint: "); for(int i = 0; i < 20; i++) { printf("%02X ", (unsigned char)fingerprint[i]); } printf("\n"); /* check what authentication methods are available */ userauthlist = libssh2_userauth_list(session, username, strlen(username)); printf("Authentication methods: %s\n", userauthlist); if (strstr(userauthlist, "password") != NULL) { auth_pw |= 1; } if (strstr(userauthlist, "keyboard-interactive") != NULL) { auth_pw |= 2; } if (strstr(userauthlist, "publickey") != NULL) { auth_pw |= 4; } if (auth_pw & 1) { /* We could authenticate via password */ if (libssh2_userauth_password(session, username, password)) { printf("\tAuthentication by password failed!\n"); m_errCode = 5; goto shutdown; } else { printf("\tAuthentication by password succeeded.\n"); } } else if (auth_pw & 2) { /* Or via keyboard-interactive */ if (libssh2_userauth_keyboard_interactive(session, username, &SSH2Utils::kbd_callback) ) { printf("\tAuthentication by keyboard-interactive failed!\n"); m_errCode = 6; goto shutdown; } else { printf("\tAuthentication by keyboard-interactive succeeded.\n"); } } else if (auth_pw & 4) { /* Or by public key */ if (libssh2_userauth_publickey_fromfile(session, username, keyfile1, keyfile2, password)) { printf("\tAuthentication by public key failed!\n"); m_errCode = 7; goto shutdown; } else { printf("\tAuthentication by public key succeeded.\n"); } } else { printf("No supported authentication methods found!\n"); m_errCode = 8; goto shutdown; } m_sock = sock; m_session = session; return 0; shutdown: return -1; deconnect(); }