Loading lib/ssh.c +126 −112 Original line number Diff line number Diff line Loading @@ -504,100 +504,16 @@ static int sshkeycallback(CURL *easy, #define libssh2_session_startup(x,y) libssh2_session_handshake(x,y) #endif /* * ssh_statemach_act() runs the SSH state machine as far as it can without * blocking and without reaching the end. The data the pointer 'block' points * to will be set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN * meaning it wants to be called again when the socket is ready */ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) static CURLcode ssh_knownhost(struct connectdata *conn) { CURLcode result = CURLE_OK; struct SessionHandle *data = conn->data; struct SSHPROTO *sftp_scp = data->state.proto.ssh; struct ssh_conn *sshc = &conn->proto.sshc; curl_socket_t sock = conn->sock[FIRSTSOCKET]; #ifdef CURL_LIBSSH2_DEBUG const char *fingerprint; #endif /* CURL_LIBSSH2_DEBUG */ const char *host_public_key_md5; int rc = LIBSSH2_ERROR_NONE, i; int err; int seekerr = CURL_SEEKFUNC_OK; *block = 0; /* we're not blocking by default */ do { switch(sshc->state) { case SSH_S_STARTUP: sshc->secondCreateDirs = 0; sshc->nextstate = SSH_NO_STATE; sshc->actualcode = CURLE_OK; rc = libssh2_session_startup(sshc->ssh_session, sock); if(rc == LIBSSH2_ERROR_EAGAIN) { break; } else if(rc) { failf(data, "Failure establishing ssh session"); state(conn, SSH_SESSION_FREE); sshc->actualcode = CURLE_FAILED_INIT; break; } /* Set libssh2 to non-blocking, since everything internally is non-blocking */ libssh2_session_set_blocking(sshc->ssh_session, 0); state(conn, SSH_HOSTKEY); /* fall-through */ case SSH_HOSTKEY: #ifdef CURL_LIBSSH2_DEBUG /* * Before we authenticate we should check the hostkey's fingerprint * against our known hosts. How that is handled (reading from file, * whatever) is up to us. As for know not much is implemented, besides * showing how to get the fingerprint. */ fingerprint = libssh2_hostkey_hash(sshc->ssh_session, LIBSSH2_HOSTKEY_HASH_MD5); /* The fingerprint points to static storage (!), don't free() it. */ infof(data, "Fingerprint: "); for(rc = 0; rc < 16; rc++) infof(data, "%02X ", (unsigned char) fingerprint[rc]); infof(data, "\n"); #endif /* CURL_LIBSSH2_DEBUG */ /* Before we authenticate we check the hostkey's MD5 fingerprint * against a known fingerprint, if available. This implementation pulls * it from the curl option. */ if(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5] && strlen(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) == 32) { char buf[33]; host_public_key_md5 = libssh2_hostkey_hash(sshc->ssh_session, LIBSSH2_HOSTKEY_HASH_MD5); for(i = 0; i < 16; i++) snprintf(&buf[i*2], 3, "%02x", (unsigned char) host_public_key_md5[i]); if(!strequal(buf, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5])) { failf(data, "Denied establishing ssh session: mismatch md5 fingerprint. " "Remote %s is not equal to %s", buf, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]); state(conn, SSH_SESSION_FREE); sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION; break; } } CURLcode result = CURLE_OK; #ifdef HAVE_LIBSSH2_KNOWNHOST_API if(data->set.str[STRING_SSH_KNOWNHOSTS]) { /* we're asked to verify the host against a file */ struct ssh_conn *sshc = &conn->proto.sshc; int rc; int keytype; size_t keylen; const char *remotekey = libssh2_session_hostkey(sshc->ssh_session, Loading Loading @@ -704,8 +620,106 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) break; } } #endif /* HAVE_LIBSSH2_KNOWNHOST_API */ #else /* HAVE_LIBSSH2_KNOWNHOST_API */ (void)conn; #endif return result; } /* * ssh_statemach_act() runs the SSH state machine as far as it can without * blocking and without reaching the end. The data the pointer 'block' points * to will be set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN * meaning it wants to be called again when the socket is ready */ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) { CURLcode result = CURLE_OK; struct SessionHandle *data = conn->data; struct SSHPROTO *sftp_scp = data->state.proto.ssh; struct ssh_conn *sshc = &conn->proto.sshc; curl_socket_t sock = conn->sock[FIRSTSOCKET]; #ifdef CURL_LIBSSH2_DEBUG const char *fingerprint; #endif /* CURL_LIBSSH2_DEBUG */ const char *host_public_key_md5; int rc = LIBSSH2_ERROR_NONE, i; int err; int seekerr = CURL_SEEKFUNC_OK; *block = 0; /* we're not blocking by default */ do { switch(sshc->state) { case SSH_S_STARTUP: sshc->secondCreateDirs = 0; sshc->nextstate = SSH_NO_STATE; sshc->actualcode = CURLE_OK; rc = libssh2_session_startup(sshc->ssh_session, sock); if(rc == LIBSSH2_ERROR_EAGAIN) { break; } else if(rc) { failf(data, "Failure establishing ssh session"); state(conn, SSH_SESSION_FREE); sshc->actualcode = CURLE_FAILED_INIT; break; } /* Set libssh2 to non-blocking, since everything internally is non-blocking */ libssh2_session_set_blocking(sshc->ssh_session, 0); state(conn, SSH_HOSTKEY); /* fall-through */ case SSH_HOSTKEY: #ifdef CURL_LIBSSH2_DEBUG /* * Before we authenticate we should check the hostkey's fingerprint * against our known hosts. How that is handled (reading from file, * whatever) is up to us. As for know not much is implemented, besides * showing how to get the fingerprint. */ fingerprint = libssh2_hostkey_hash(sshc->ssh_session, LIBSSH2_HOSTKEY_HASH_MD5); /* The fingerprint points to static storage (!), don't free() it. */ infof(data, "Fingerprint: "); for(rc = 0; rc < 16; rc++) infof(data, "%02X ", (unsigned char) fingerprint[rc]); infof(data, "\n"); #endif /* CURL_LIBSSH2_DEBUG */ /* Before we authenticate we check the hostkey's MD5 fingerprint * against a known fingerprint, if available. This implementation pulls * it from the curl option. */ if(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5] && strlen(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) == 32) { char buf[33]; host_public_key_md5 = libssh2_hostkey_hash(sshc->ssh_session, LIBSSH2_HOSTKEY_HASH_MD5); for(i = 0; i < 16; i++) snprintf(&buf[i*2], 3, "%02x", (unsigned char) host_public_key_md5[i]); if(!strequal(buf, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5])) { failf(data, "Denied establishing ssh session: mismatch md5 fingerprint. " "Remote %s is not equal to %s", buf, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]); state(conn, SSH_SESSION_FREE); sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION; break; } } result = ssh_knownhost(conn); if(!result) state(conn, SSH_AUTHLIST); break; Loading Loading
lib/ssh.c +126 −112 Original line number Diff line number Diff line Loading @@ -504,100 +504,16 @@ static int sshkeycallback(CURL *easy, #define libssh2_session_startup(x,y) libssh2_session_handshake(x,y) #endif /* * ssh_statemach_act() runs the SSH state machine as far as it can without * blocking and without reaching the end. The data the pointer 'block' points * to will be set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN * meaning it wants to be called again when the socket is ready */ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) static CURLcode ssh_knownhost(struct connectdata *conn) { CURLcode result = CURLE_OK; struct SessionHandle *data = conn->data; struct SSHPROTO *sftp_scp = data->state.proto.ssh; struct ssh_conn *sshc = &conn->proto.sshc; curl_socket_t sock = conn->sock[FIRSTSOCKET]; #ifdef CURL_LIBSSH2_DEBUG const char *fingerprint; #endif /* CURL_LIBSSH2_DEBUG */ const char *host_public_key_md5; int rc = LIBSSH2_ERROR_NONE, i; int err; int seekerr = CURL_SEEKFUNC_OK; *block = 0; /* we're not blocking by default */ do { switch(sshc->state) { case SSH_S_STARTUP: sshc->secondCreateDirs = 0; sshc->nextstate = SSH_NO_STATE; sshc->actualcode = CURLE_OK; rc = libssh2_session_startup(sshc->ssh_session, sock); if(rc == LIBSSH2_ERROR_EAGAIN) { break; } else if(rc) { failf(data, "Failure establishing ssh session"); state(conn, SSH_SESSION_FREE); sshc->actualcode = CURLE_FAILED_INIT; break; } /* Set libssh2 to non-blocking, since everything internally is non-blocking */ libssh2_session_set_blocking(sshc->ssh_session, 0); state(conn, SSH_HOSTKEY); /* fall-through */ case SSH_HOSTKEY: #ifdef CURL_LIBSSH2_DEBUG /* * Before we authenticate we should check the hostkey's fingerprint * against our known hosts. How that is handled (reading from file, * whatever) is up to us. As for know not much is implemented, besides * showing how to get the fingerprint. */ fingerprint = libssh2_hostkey_hash(sshc->ssh_session, LIBSSH2_HOSTKEY_HASH_MD5); /* The fingerprint points to static storage (!), don't free() it. */ infof(data, "Fingerprint: "); for(rc = 0; rc < 16; rc++) infof(data, "%02X ", (unsigned char) fingerprint[rc]); infof(data, "\n"); #endif /* CURL_LIBSSH2_DEBUG */ /* Before we authenticate we check the hostkey's MD5 fingerprint * against a known fingerprint, if available. This implementation pulls * it from the curl option. */ if(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5] && strlen(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) == 32) { char buf[33]; host_public_key_md5 = libssh2_hostkey_hash(sshc->ssh_session, LIBSSH2_HOSTKEY_HASH_MD5); for(i = 0; i < 16; i++) snprintf(&buf[i*2], 3, "%02x", (unsigned char) host_public_key_md5[i]); if(!strequal(buf, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5])) { failf(data, "Denied establishing ssh session: mismatch md5 fingerprint. " "Remote %s is not equal to %s", buf, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]); state(conn, SSH_SESSION_FREE); sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION; break; } } CURLcode result = CURLE_OK; #ifdef HAVE_LIBSSH2_KNOWNHOST_API if(data->set.str[STRING_SSH_KNOWNHOSTS]) { /* we're asked to verify the host against a file */ struct ssh_conn *sshc = &conn->proto.sshc; int rc; int keytype; size_t keylen; const char *remotekey = libssh2_session_hostkey(sshc->ssh_session, Loading Loading @@ -704,8 +620,106 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) break; } } #endif /* HAVE_LIBSSH2_KNOWNHOST_API */ #else /* HAVE_LIBSSH2_KNOWNHOST_API */ (void)conn; #endif return result; } /* * ssh_statemach_act() runs the SSH state machine as far as it can without * blocking and without reaching the end. The data the pointer 'block' points * to will be set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN * meaning it wants to be called again when the socket is ready */ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) { CURLcode result = CURLE_OK; struct SessionHandle *data = conn->data; struct SSHPROTO *sftp_scp = data->state.proto.ssh; struct ssh_conn *sshc = &conn->proto.sshc; curl_socket_t sock = conn->sock[FIRSTSOCKET]; #ifdef CURL_LIBSSH2_DEBUG const char *fingerprint; #endif /* CURL_LIBSSH2_DEBUG */ const char *host_public_key_md5; int rc = LIBSSH2_ERROR_NONE, i; int err; int seekerr = CURL_SEEKFUNC_OK; *block = 0; /* we're not blocking by default */ do { switch(sshc->state) { case SSH_S_STARTUP: sshc->secondCreateDirs = 0; sshc->nextstate = SSH_NO_STATE; sshc->actualcode = CURLE_OK; rc = libssh2_session_startup(sshc->ssh_session, sock); if(rc == LIBSSH2_ERROR_EAGAIN) { break; } else if(rc) { failf(data, "Failure establishing ssh session"); state(conn, SSH_SESSION_FREE); sshc->actualcode = CURLE_FAILED_INIT; break; } /* Set libssh2 to non-blocking, since everything internally is non-blocking */ libssh2_session_set_blocking(sshc->ssh_session, 0); state(conn, SSH_HOSTKEY); /* fall-through */ case SSH_HOSTKEY: #ifdef CURL_LIBSSH2_DEBUG /* * Before we authenticate we should check the hostkey's fingerprint * against our known hosts. How that is handled (reading from file, * whatever) is up to us. As for know not much is implemented, besides * showing how to get the fingerprint. */ fingerprint = libssh2_hostkey_hash(sshc->ssh_session, LIBSSH2_HOSTKEY_HASH_MD5); /* The fingerprint points to static storage (!), don't free() it. */ infof(data, "Fingerprint: "); for(rc = 0; rc < 16; rc++) infof(data, "%02X ", (unsigned char) fingerprint[rc]); infof(data, "\n"); #endif /* CURL_LIBSSH2_DEBUG */ /* Before we authenticate we check the hostkey's MD5 fingerprint * against a known fingerprint, if available. This implementation pulls * it from the curl option. */ if(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5] && strlen(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) == 32) { char buf[33]; host_public_key_md5 = libssh2_hostkey_hash(sshc->ssh_session, LIBSSH2_HOSTKEY_HASH_MD5); for(i = 0; i < 16; i++) snprintf(&buf[i*2], 3, "%02x", (unsigned char) host_public_key_md5[i]); if(!strequal(buf, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5])) { failf(data, "Denied establishing ssh session: mismatch md5 fingerprint. " "Remote %s is not equal to %s", buf, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]); state(conn, SSH_SESSION_FREE); sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION; break; } } result = ssh_knownhost(conn); if(!result) state(conn, SSH_AUTHLIST); break; Loading