/** * @brief tests the privatekey_from_file function with passphrase */ static void torture_privatekey_from_file_passphrase(void **state) { ssh_session session = *state; ssh_private_key key = NULL; key = privatekey_from_file(session, LIBSSH_RSA_TESTKEY, SSH_KEYTYPE_RSA, LIBSSH_PASSPHRASE); assert_true(key != NULL); if (key != NULL) { privatekey_free(key); key = NULL; } key = privatekey_from_file(session, LIBSSH_DSA_TESTKEY, SSH_KEYTYPE_DSS, LIBSSH_PASSPHRASE); assert_true(key != NULL); if (key != NULL) { privatekey_free(key); key = NULL; } /* Test the automatic type discovery */ key = privatekey_from_file(session, LIBSSH_RSA_TESTKEY, 0, LIBSSH_PASSPHRASE); assert_true(key != NULL); if (key != NULL) { privatekey_free(key); key = NULL; } key = privatekey_from_file(session, LIBSSH_DSA_TESTKEY, 0, LIBSSH_PASSPHRASE); assert_true(key != NULL); if (key != NULL) { privatekey_free(key); key = NULL; } }
/** * Authenticate in the SSH server with key * @param QString private_key the private key to use for connect in the SSH server * @param QString password the password to use for connect in the SSH server (passphrase of the private key) * @return bool true if it's ok, false else * @todo test with a private key with passphrase */ bool Kssh::authenticateKey(QString private_key, QString password) { ssh_string public_key_to_use; ssh_private_key private_key_to_use; int auth; private_key_to_use = privatekey_from_file(this->m_session, private_key.toStdString().c_str(), 0, password.toStdString().c_str()); if (private_key_to_use == NULL) { Klog::error(QString("Fatal error while get the private key : ") + QString(ssh_get_error(this->m_session))); return false; } // get the public key public_key_to_use = publickey_to_string(publickey_from_privatekey(private_key_to_use)); // try to authenticate auth = ssh_userauth_pubkey(this->m_session, NULL, public_key_to_use, private_key_to_use); if (auth == SSH_AUTH_SUCCESS) { // clear the keys of the memory privatekey_free(private_key_to_use); string_free(public_key_to_use); // it's ok return true; } else if (auth == SSH_AUTH_DENIED || auth == SSH_AUTH_PARTIAL) { Klog::warning(QString("Authenticated denied with this key")); return false; } else if (auth == SSH_AUTH_ERROR) { Klog::error(QString("Fatal error in authenticated with key : ") + QString(ssh_get_error(this->m_session))); return false; } return false; }
static void torture_pubkey_generate_from_privkey(void **state) { ssh_session session = *state; ssh_private_key privkey = NULL; ssh_public_key pubkey = NULL; ssh_string pubkey_orig = NULL; ssh_string pubkey_new = NULL; char pubkey_line_orig[512] = {0}; char pubkey_line_new[512] = {0}; int type_orig = 0; int type_new = 0; int rc; /* read the publickey */ rc = ssh_try_publickey_from_file(session, LIBSSH_RSA_TESTKEY, &pubkey_orig, &type_orig); assert_true(rc == 0); assert_true(pubkey_orig != NULL); rc = torture_read_one_line(LIBSSH_RSA_TESTKEY ".pub", pubkey_line_orig, sizeof(pubkey_line_orig)); assert_true(rc == 0); /* remove the public key, generate it from the private key and write it. */ unlink(LIBSSH_RSA_TESTKEY ".pub"); privkey = privatekey_from_file(session, LIBSSH_RSA_TESTKEY, 0, NULL); assert_true(privkey != NULL); pubkey = publickey_from_privatekey(privkey); assert_true(pubkey != NULL); type_new = privkey->type; privatekey_free(privkey); pubkey_new = publickey_to_string(pubkey); publickey_free(pubkey); assert_true(pubkey_new != NULL); assert_true(ssh_string_len(pubkey_orig) == ssh_string_len(pubkey_new)); assert_memory_equal(ssh_string_data(pubkey_orig), ssh_string_data(pubkey_new), ssh_string_len(pubkey_orig)); rc = ssh_publickey_to_file(session, LIBSSH_RSA_TESTKEY ".pub", pubkey_new, type_new); assert_true(rc == 0); rc = torture_read_one_line(LIBSSH_RSA_TESTKEY ".pub", pubkey_line_new, sizeof(pubkey_line_new)); assert_true(rc == 0); assert_string_equal(pubkey_line_orig, pubkey_line_new); ssh_string_free(pubkey_orig); ssh_string_free(pubkey_new); }
// Connect to a SSH server. // When the connection is established, read data from stdin and send it to the server. void client_pipe(char *host, int port) { ssh_session s = ssh_new(); ssh_options_set(s, SSH_OPTIONS_HOST, host); ssh_options_set(s, SSH_OPTIONS_PORT, &port); ssh_options_set(s, SSH_OPTIONS_USER, "xya"); //ssh_options_set(s, SSH_OPTIONS_LOG_VERBOSITY_STR, "5"); if(ssh_connect(s) != SSH_OK) return session_error(s, "connect"); char *hash = pubkey_hash(ssh_get_pubkey(s)); if(authenticate(hash, 0)) { session_event(s, "authenticated", hash); free(hash); } else { free(hash); exit(1); } int keytype; ssh_string pub = publickey_from_file(s, "test-client-key.pub", &keytype); if(!pub) session_error(s, "open-public-key"); if(SSH_AUTH_SUCCESS != ssh_userauth_offer_pubkey(s, NULL, keytype, pub)) session_error(s, "offer-public-key"); ssh_private_key priv = privatekey_from_file(s, "test-client-key", keytype, NULL); if(!priv) session_error(s, "open-private-key"); if(SSH_AUTH_SUCCESS != ssh_userauth_pubkey(s, NULL, pub, priv)) session_error(s, "user-auth"); string_free(pub); privatekey_free(priv); ssh_channel chan = channel_new(s); if(!chan) session_error(s, "create-channel"); if(channel_open_session(chan) < 0) session_error(s, "open-channel"); session_event(s, "channel-opened", NULL); channel_from_file(chan, 0); channel_free(chan); ssh_disconnect(s); ssh_finalize(); }
gboolean remmina_nx_session_open(RemminaNXSession *nx, const gchar *server, guint port, const gchar *private_key_file, RemminaNXPassphraseCallback passphrase_func, gpointer userdata) { gint ret; ssh_private_key privkey; ssh_public_key pubkey; ssh_string pubkeystr; gint keytype; gboolean encrypted; gchar *passphrase = NULL; gchar tmpfile[L_tmpnam + 1]; nx ->session = ssh_new(); ssh_options_set(nx->session, SSH_OPTIONS_HOST, server); ssh_options_set(nx->session, SSH_OPTIONS_PORT, &port); ssh_options_set(nx->session, SSH_OPTIONS_USER, "nx"); if (private_key_file && private_key_file[0]) { if (!remmina_get_keytype(private_key_file, &keytype, &encrypted)) { remmina_nx_session_set_application_error(nx, "Invalid private key file."); return FALSE; } if (encrypted && !passphrase_func(&passphrase, userdata)) { return FALSE; } privkey = privatekey_from_file(nx->session, private_key_file, keytype, (passphrase ? passphrase : "")); g_free(passphrase); } else { /* Use NoMachine's default nx private key */ if ((tmpnam(tmpfile)) == NULL || !g_file_set_contents(tmpfile, nx_default_private_key, -1, NULL)) { remmina_nx_session_set_application_error(nx, "Failed to create temporary private key file."); return FALSE; } privkey = privatekey_from_file(nx->session, tmpfile, REMMINA_SSH_TYPE_DSS, ""); g_unlink(tmpfile); } if (privkey == NULL) { remmina_nx_session_set_error(nx, "Invalid private key file: %s"); return FALSE; } pubkey = publickey_from_privatekey(privkey); pubkeystr = publickey_to_string(pubkey); publickey_free(pubkey); if (ssh_connect(nx->session)) { string_free(pubkeystr); privatekey_free(privkey); remmina_nx_session_set_error(nx, "Failed to startup SSH session: %s"); return FALSE; } ret = ssh_userauth_pubkey(nx->session, NULL, pubkeystr, privkey); string_free(pubkeystr); privatekey_free(privkey); if (ret != SSH_AUTH_SUCCESS) { remmina_nx_session_set_error(nx, "NX SSH authentication failed: %s"); return FALSE; } if ((nx->channel = channel_new(nx->session)) == NULL || channel_open_session(nx->channel)) { return FALSE; } if (channel_request_shell(nx->channel)) { return FALSE; } /* NX server starts the session with an initial 105 status */ if (!remmina_nx_session_expect_status(nx, 105)) return FALSE; /* Say hello to the NX server */ remmina_nx_session_send_command(nx, "HELLO NXCLIENT - Version %s", nx->version); if (!remmina_nx_session_expect_status(nx, 105)) return FALSE; /* Set the NX session environment */ remmina_nx_session_send_command(nx, "SET SHELL_MODE SHELL"); if (!remmina_nx_session_expect_status(nx, 105)) return FALSE; remmina_nx_session_send_command(nx, "SET AUTH_MODE PASSWORD"); if (!remmina_nx_session_expect_status(nx, 105)) return FALSE; nx->server = g_strdup(server); return TRUE; }
static int dh_handshake_server(ssh_session session) { ssh_string f; ssh_string pubkey; ssh_string sign; ssh_public_key pub; ssh_private_key prv; if (dh_generate_y(session) < 0) { ssh_set_error(session, SSH_FATAL, "Could not create y number"); return -1; } if (dh_generate_f(session) < 0) { ssh_set_error(session, SSH_FATAL, "Could not create f number"); return -1; } f = dh_get_f(session); if (f == NULL) { ssh_set_error(session, SSH_FATAL, "Could not get the f number"); return -1; } switch(session->hostkeys){ case SSH_KEYTYPE_DSS: prv = session->dsa_key; break; case SSH_KEYTYPE_RSA: prv = session->rsa_key; break; default: prv = NULL; } pub = publickey_from_privatekey(prv); if (pub == NULL) { ssh_set_error(session, SSH_FATAL, "Could not get the public key from the private key"); ssh_string_free(f); return -1; } pubkey = publickey_to_string(pub); publickey_free(pub); if (pubkey == NULL) { ssh_set_error(session, SSH_FATAL, "Not enough space"); ssh_string_free(f); return -1; } dh_import_pubkey(session, pubkey); if (dh_build_k(session) < 0) { ssh_set_error(session, SSH_FATAL, "Could not import the public key"); ssh_string_free(f); return -1; } if (make_sessionid(session) != SSH_OK) { ssh_set_error(session, SSH_FATAL, "Could not create a session id"); ssh_string_free(f); return -1; } sign = ssh_sign_session_id(session, prv); if (sign == NULL) { ssh_set_error(session, SSH_FATAL, "Could not sign the session id"); ssh_string_free(f); return -1; } /* Free private keys as they should not be readable after this point */ if (session->rsa_key) { privatekey_free(session->rsa_key); session->rsa_key = NULL; } if (session->dsa_key) { privatekey_free(session->dsa_key); session->dsa_key = NULL; } if (buffer_add_u8(session->out_buffer, SSH2_MSG_KEXDH_REPLY) < 0 || buffer_add_ssh_string(session->out_buffer, pubkey) < 0 || buffer_add_ssh_string(session->out_buffer, f) < 0 || buffer_add_ssh_string(session->out_buffer, sign) < 0) { ssh_set_error(session, SSH_FATAL, "Not enough space"); buffer_reinit(session->out_buffer); ssh_string_free(f); ssh_string_free(sign); return -1; } ssh_string_free(f); ssh_string_free(sign); if (packet_send(session) == SSH_ERROR) { return -1; } if (buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS) < 0) { buffer_reinit(session->out_buffer); return -1; } if (packet_send(session) == SSH_ERROR) { return -1; } ssh_log(session, SSH_LOG_PACKET, "SSH_MSG_NEWKEYS sent"); session->dh_handshake_state=DH_STATE_NEWKEYS_SENT; return 0; }
static int dh_handshake_server(SSH_SESSION *session) { STRING *e; STRING *f; STRING *pubkey; STRING *sign; PUBLIC_KEY *pub; PRIVATE_KEY *prv; if (packet_wait(session, SSH2_MSG_KEXDH_INIT, 1) != SSH_OK) { return -1; } e = buffer_get_ssh_string(session->in_buffer); if (e == NULL) { ssh_set_error(session, SSH_FATAL, "No e number in client request"); return -1; } if (dh_import_e(session, e) < 0) { ssh_set_error(session, SSH_FATAL, "Cannot import e number"); string_free(e); return -1; } string_free(e); if (dh_generate_y(session) < 0) { ssh_set_error(session, SSH_FATAL, "Could not create y number"); return -1; } if (dh_generate_f(session) < 0) { ssh_set_error(session, SSH_FATAL, "Could not create f number"); return -1; } f = dh_get_f(session); if (f == NULL) { ssh_set_error(session, SSH_FATAL, "Could not get the f number"); return -1; } switch(session->hostkeys){ case TYPE_DSS: prv = session->dsa_key; break; case TYPE_RSA: prv = session->rsa_key; break; default: prv = NULL; } pub = publickey_from_privatekey(prv); if (pub == NULL) { ssh_set_error(session, SSH_FATAL, "Could not get the public key from the private key"); string_free(f); return -1; } pubkey = publickey_to_string(pub); publickey_free(pub); if (pubkey == NULL) { ssh_set_error(session, SSH_FATAL, "Not enough space"); string_free(f); return -1; } dh_import_pubkey(session, pubkey); if (dh_build_k(session) < 0) { ssh_set_error(session, SSH_FATAL, "Could not import the public key"); string_free(f); return -1; } if (make_sessionid(session) != SSH_OK) { ssh_set_error(session, SSH_FATAL, "Could not create a session id"); string_free(f); return -1; } sign = ssh_sign_session_id(session, prv); if (sign == NULL) { ssh_set_error(session, SSH_FATAL, "Could not sign the session id"); string_free(f); return -1; } /* Free private keys as they should not be readable after this point */ if (session->rsa_key) { privatekey_free(session->rsa_key); session->rsa_key = NULL; } if (session->dsa_key) { privatekey_free(session->dsa_key); session->dsa_key = NULL; } if (buffer_add_u8(session->out_buffer, SSH2_MSG_KEXDH_REPLY) < 0 || buffer_add_ssh_string(session->out_buffer, pubkey) < 0 || buffer_add_ssh_string(session->out_buffer, f) < 0 || buffer_add_ssh_string(session->out_buffer, sign) < 0) { ssh_set_error(session, SSH_FATAL, "Not enough space"); buffer_free(session->out_buffer); string_free(f); string_free(sign); return -1; } string_free(f); string_free(sign); if (packet_send(session) != SSH_OK) { return -1; } if (buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS) < 0) { buffer_free(session->out_buffer); return -1; } if (packet_send(session) != SSH_OK) { return -1; } ssh_log(session, SSH_LOG_PACKET, "SSH_MSG_NEWKEYS sent"); if (packet_wait(session, SSH2_MSG_NEWKEYS, 1) != SSH_OK) { return -1; } ssh_log(session, SSH_LOG_PACKET, "Got SSH_MSG_NEWKEYS"); if (generate_session_keys(session) < 0) { return -1; } /* * Once we got SSH2_MSG_NEWKEYS we can switch next_crypto and * current_crypto */ if (session->current_crypto) { crypto_free(session->current_crypto); } /* FIXME TODO later, include a function to change keys */ session->current_crypto = session->next_crypto; session->next_crypto = crypto_new(); if (session->next_crypto == NULL) { return -1; } return 0; }
SSH_SESSION *ssh_bind_accept(SSH_BIND *ssh_bind) { SSH_SESSION *session; PRIVATE_KEY *dsa = NULL; PRIVATE_KEY *rsa = NULL; int fd = -1; if (ssh_bind->bindfd < 0) { ssh_set_error(ssh_bind, SSH_FATAL, "Can't accept new clients on a not bound socket."); return NULL; } if (ssh_bind->options->dsakey == NULL || ssh_bind->options->rsakey == NULL) { ssh_set_error(ssh_bind, SSH_FATAL, "DSA or RSA host key file must be set before accept()"); return NULL; } if (ssh_bind->options->dsakey) { dsa = _privatekey_from_file(ssh_bind, ssh_bind->options->dsakey, TYPE_DSS); if (dsa == NULL) { return NULL; } } if (ssh_bind->options->rsakey) { rsa = _privatekey_from_file(ssh_bind, ssh_bind->options->rsakey, TYPE_RSA); if (rsa == NULL) { privatekey_free(dsa); return NULL; } } fd = accept(ssh_bind->bindfd, NULL, NULL); if (fd < 0) { ssh_set_error(ssh_bind, SSH_FATAL, "Accepting a new connection: %s", strerror(errno)); privatekey_free(dsa); privatekey_free(rsa); return NULL; } session = ssh_new(); if (session == NULL) { ssh_set_error(ssh_bind, SSH_FATAL, "Not enough space"); privatekey_free(dsa); privatekey_free(rsa); return NULL; } session->server = 1; session->version = 2; session->options = ssh_options_copy(ssh_bind->options); if (session->options == NULL) { ssh_set_error(ssh_bind, SSH_FATAL, "No space left"); privatekey_free(dsa); privatekey_free(rsa); ssh_cleanup(session); return NULL; } ssh_socket_free(session->socket); session->socket = ssh_socket_new(session); if (session->socket == NULL) { privatekey_free(dsa); privatekey_free(rsa); ssh_cleanup(session); return NULL; } ssh_socket_set_fd(session->socket,fd); session->dsa_key = dsa; session->rsa_key = rsa; return session; }
int ssh_bind_listen(ssh_bind sshbind) { const char *host; socket_t fd; sshbind->dsa = NULL; sshbind->rsa = NULL; if (ssh_init() < 0) { ssh_set_error(sshbind, SSH_FATAL, "ssh_init() failed"); return -1; } if (sshbind->dsakey) { if (sshbind->dsakey == NULL && sshbind->rsakey == NULL) { ssh_set_error(sshbind, SSH_FATAL, "DSA or RSA host key file must be set before listen()"); return SSH_ERROR; } sshbind->dsa = _privatekey_from_file( sshbind, sshbind->dsakey, SSH_KEYTYPE_DSS ); if (sshbind->dsa == NULL) { return -1; } } if (sshbind->rsakey) { sshbind->rsa = _privatekey_from_file( sshbind, sshbind->rsakey, SSH_KEYTYPE_RSA ); if (sshbind->rsa == NULL) { privatekey_free(sshbind->dsa); return -1; } } host = sshbind->bindaddr; if (host == NULL) { host = "0.0.0.0"; } fd = bind_socket(sshbind, host, sshbind->bindport); if (fd == SSH_INVALID_SOCKET) { privatekey_free(sshbind->dsa); privatekey_free(sshbind->rsa); return -1; } sshbind->bindfd = fd; if (listen(fd, 10) < 0) { ssh_set_error(sshbind, SSH_FATAL, "Listening to socket %d: %s", fd, strerror(errno)); close(fd); privatekey_free(sshbind->dsa); privatekey_free(sshbind->rsa); return -1; } return 0; }
/** * @brief Tries to automaticaly authenticate with public key and "none" * * It may fail, for instance it doesn't ask for a password and uses a default * asker for passphrases (in case the private key is encrypted). * * @param session The ssh session to authenticate with. * * @param passphrase Use this passphrase to unlock the privatekey. Use NULL * if you don't want to use a passphrase or the user * should be asked. * * @returns SSH_AUTH_ERROR: A serious error happened\n * SSH_AUTH_DENIED: Authentication failed: use another method\n * SSH_AUTH_PARTIAL: You've been partially authenticated, you still * have to use another method\n * SSH_AUTH_SUCCESS: Authentication success * * @see ssh_userauth_kbdint() * @see ssh_userauth_password() */ int ssh_userauth_autopubkey(ssh_session session, const char *passphrase) { struct ssh_iterator *it; ssh_private_key privkey; ssh_public_key pubkey; ssh_string pubkey_string; int type = 0; int rc; enter_function(); /* Always test none authentication */ rc = ssh_userauth_none(session, NULL); if (rc == SSH_AUTH_ERROR || rc == SSH_AUTH_SUCCESS) { leave_function(); return rc; } /* Try authentication with ssh-agent first */ #ifndef _WIN32 if (agent_is_running(session)) { char *privkey_file = NULL; ssh_log(session, SSH_LOG_RARE, "Trying to authenticate with SSH agent keys as user: %s", session->username); for (pubkey = agent_get_first_ident(session, &privkey_file); pubkey != NULL; pubkey = agent_get_next_ident(session, &privkey_file)) { ssh_log(session, SSH_LOG_RARE, "Trying identity %s", privkey_file); pubkey_string = publickey_to_string(pubkey); if (pubkey_string) { rc = ssh_userauth_offer_pubkey(session, NULL, pubkey->type, pubkey_string); string_free(pubkey_string); if (rc == SSH_AUTH_ERROR) { SAFE_FREE(privkey_file); publickey_free(pubkey); leave_function(); return rc; } else if (rc != SSH_AUTH_SUCCESS) { ssh_log(session, SSH_LOG_PROTOCOL, "Public key refused by server"); SAFE_FREE(privkey_file); publickey_free(pubkey); continue; } ssh_log(session, SSH_LOG_RARE, "Public key accepted"); /* pubkey accepted by server ! */ rc = ssh_userauth_agent_pubkey(session, NULL, pubkey); if (rc == SSH_AUTH_ERROR) { SAFE_FREE(privkey_file); publickey_free(pubkey); leave_function(); return rc; } else if (rc != SSH_AUTH_SUCCESS) { ssh_log(session, SSH_LOG_RARE, "Server accepted public key but refused the signature ;" " It might be a bug of libssh"); SAFE_FREE(privkey_file); publickey_free(pubkey); continue; } /* auth success */ ssh_log(session, SSH_LOG_PROTOCOL, "Authentication using %s success", privkey_file); SAFE_FREE(privkey_file); publickey_free(pubkey); leave_function(); return SSH_AUTH_SUCCESS; } /* if pubkey */ SAFE_FREE(privkey_file); publickey_free(pubkey); } /* for each privkey */ } /* if agent is running */ #endif for (it = ssh_list_get_iterator(session->identity); it != NULL; it = it->next) { const char *privkey_file = it->data; int privkey_open = 0; privkey = NULL; ssh_log(session, SSH_LOG_PROTOCOL, "Trying to read privatekey %s", privkey_file); rc = ssh_try_publickey_from_file(session, privkey_file, &pubkey_string, &type); if (rc == 1) { char *publickey_file; size_t len; privkey = privatekey_from_file(session, privkey_file, type, passphrase); if (privkey == NULL) { ssh_log(session, SSH_LOG_RARE, "Reading private key %s failed (bad passphrase ?)", privkey_file); leave_function(); return SSH_AUTH_ERROR; } privkey_open = 1; pubkey = publickey_from_privatekey(privkey); if (pubkey == NULL) { privatekey_free(privkey); ssh_set_error_oom(session); leave_function(); return SSH_AUTH_ERROR; } pubkey_string = publickey_to_string(pubkey); type = pubkey->type; publickey_free(pubkey); if (pubkey_string == NULL) { ssh_set_error_oom(session); leave_function(); return SSH_AUTH_ERROR; } len = strlen(privkey_file) + 5; publickey_file = malloc(len); if (publickey_file == NULL) { ssh_set_error_oom(session); leave_function(); return SSH_AUTH_ERROR; } snprintf(publickey_file, len, "%s.pub", privkey_file); rc = ssh_publickey_to_file(session, publickey_file, pubkey_string, type); if (rc < 0) { ssh_log(session, SSH_LOG_PACKET, "Could not write public key to file: %s", publickey_file); } SAFE_FREE(publickey_file); } else if (rc < 0) { continue; } rc = ssh_userauth_offer_pubkey(session, NULL, type, pubkey_string); if (rc == SSH_AUTH_ERROR){ string_free(pubkey_string); ssh_log(session, SSH_LOG_RARE, "Publickey authentication error"); leave_function(); return rc; } else { if (rc != SSH_AUTH_SUCCESS){ ssh_log(session, SSH_LOG_PROTOCOL, "Publickey refused by server"); string_free(pubkey_string); continue; } } /* Public key accepted by server! */ if (!privkey_open) { ssh_log(session, SSH_LOG_PROTOCOL, "Trying to read privatekey %s", privkey_file); privkey = privatekey_from_file(session, privkey_file, type, passphrase); if (privkey == NULL) { ssh_log(session, SSH_LOG_RARE, "Reading private key %s failed (bad passphrase ?)", privkey_file); string_free(pubkey_string); continue; /* continue the loop with other pubkey */ } } rc = ssh_userauth_pubkey(session, NULL, pubkey_string, privkey); if (rc == SSH_AUTH_ERROR) { string_free(pubkey_string); privatekey_free(privkey); leave_function(); return rc; } else { if (rc != SSH_AUTH_SUCCESS){ ssh_log(session, SSH_LOG_FUNCTIONS, "The server accepted the public key but refused the signature"); string_free(pubkey_string); privatekey_free(privkey); continue; } } /* auth success */ ssh_log(session, SSH_LOG_PROTOCOL, "Successfully authenticated using %s", privkey_file); string_free(pubkey_string); privatekey_free(privkey); leave_function(); return SSH_AUTH_SUCCESS; } /* at this point, pubkey is NULL and so is privkeyfile */ ssh_log(session, SSH_LOG_FUNCTIONS, "Tried every public key, none matched"); ssh_set_error(session,SSH_NO_ERROR,"No public key matched"); leave_function(); return SSH_AUTH_DENIED; }
int ssh_bind_accept(ssh_bind sshbind, ssh_session session) { ssh_private_key dsa = NULL; ssh_private_key rsa = NULL; socket_t fd = SSH_INVALID_SOCKET; int i; if (sshbind->bindfd == SSH_INVALID_SOCKET) { ssh_set_error(sshbind, SSH_FATAL, "Can't accept new clients on a not bound socket."); return SSH_ERROR; } if(session == NULL){ ssh_set_error(sshbind, SSH_FATAL,"session is null"); return SSH_ERROR; } if (sshbind->dsakey == NULL && sshbind->rsakey == NULL) { ssh_set_error(sshbind, SSH_FATAL, "DSA or RSA host key file must be set before accept()"); return SSH_ERROR; } if (sshbind->dsakey) { dsa = _privatekey_from_file(sshbind, sshbind->dsakey, SSH_KEYTYPE_DSS); if (dsa == NULL) { return SSH_ERROR; } } if (sshbind->rsakey) { rsa = _privatekey_from_file(sshbind, sshbind->rsakey, SSH_KEYTYPE_RSA); if (rsa == NULL) { privatekey_free(dsa); return SSH_ERROR; } } fd = accept(sshbind->bindfd, NULL, NULL); if (fd == SSH_INVALID_SOCKET) { ssh_set_error(sshbind, SSH_FATAL, "Accepting a new connection: %s", strerror(errno)); privatekey_free(dsa); privatekey_free(rsa); return SSH_ERROR; } session->server = 1; session->version = 2; /* copy options */ for (i = 0; i < 10; ++i) { if (sshbind->wanted_methods[i]) { session->wanted_methods[i] = strdup(sshbind->wanted_methods[i]); if (session->wanted_methods[i] == NULL) { privatekey_free(dsa); privatekey_free(rsa); return SSH_ERROR; } } } if (sshbind->bindaddr == NULL) session->bindaddr = NULL; else { SAFE_FREE(session->bindaddr); session->bindaddr = strdup(sshbind->bindaddr); if (session->bindaddr == NULL) { privatekey_free(dsa); privatekey_free(rsa); return SSH_ERROR; } } session->log_verbosity = sshbind->log_verbosity; ssh_socket_free(session->socket); session->socket = ssh_socket_new(session); if (session->socket == NULL) { /* perhaps it may be better to copy the error from session to sshbind */ ssh_set_error_oom(sshbind); privatekey_free(dsa); privatekey_free(rsa); return SSH_ERROR; } ssh_socket_set_fd(session->socket, fd); ssh_socket_get_poll_handle_out(session->socket); session->dsa_key = dsa; session->rsa_key = rsa; return SSH_OK; }