static int auth_publickey(ssh_session session, const char *user, struct ssh_key_struct *pubkey, char signature_state, void *userdata) { struct session_data_struct *sdata = (struct session_data_struct *) userdata; (void) user; (void) session; if (signature_state == SSH_PUBLICKEY_STATE_NONE) { return SSH_AUTH_SUCCESS; } if (signature_state != SSH_PUBLICKEY_STATE_VALID) { return SSH_AUTH_DENIED; } // valid so far. Now look through authorized keys for a match if (authorizedkeys[0]) { ssh_key key = NULL; int result; struct stat buf; if (stat(authorizedkeys, &buf) == 0) { result = ssh_pki_import_pubkey_file( authorizedkeys, &key ); if ((result != SSH_OK) || (key==NULL)) { fprintf(stderr, "Unable to import public key file %s\n", authorizedkeys); } else { result = ssh_key_cmp( key, pubkey, SSH_KEY_CMP_PUBLIC ); ssh_key_free(key); if (result == 0) { sdata->authenticated = 1; return SSH_AUTH_SUCCESS; } } } } // no matches sdata->authenticated = 0; return SSH_AUTH_DENIED; }
static void torture_pki_duplicate_key_ecdsa(void **state) { int rc; char *b64_key; char *b64_key_gen; ssh_key pubkey; ssh_key privkey; ssh_key privkey_dup; (void) state; rc = ssh_pki_import_pubkey_file(LIBSSH_ECDSA_TESTKEY ".pub", &pubkey); assert_true(rc == 0); rc = ssh_pki_export_pubkey_base64(pubkey, &b64_key); assert_true(rc == 0); ssh_key_free(pubkey); rc = ssh_pki_import_privkey_file(LIBSSH_ECDSA_TESTKEY, NULL, NULL, NULL, &privkey); assert_true(rc == 0); privkey_dup = ssh_key_dup(privkey); assert_true(privkey_dup != NULL); rc = ssh_pki_export_privkey_to_pubkey(privkey, &pubkey); assert_true(rc == SSH_OK); rc = ssh_pki_export_pubkey_base64(pubkey, &b64_key_gen); assert_true(rc == 0); assert_string_equal(b64_key, b64_key_gen); rc = ssh_key_cmp(privkey, privkey_dup, SSH_KEY_CMP_PRIVATE); assert_true(rc == 0); ssh_key_free(pubkey); ssh_key_free(privkey); ssh_key_free(privkey_dup); ssh_string_free_char(b64_key); ssh_string_free_char(b64_key_gen); }
static int _import_public_key(t_credentials *credentials, const char *credentials_dirpath, char *buf) { sprintf(buf, "%s/id_rsa.pub", credentials_dirpath); credentials->public_key_filepath = xstrdup(buf); if (!credentials->public_key_filepath) return (1); if (access(buf, R_OK) != 0) { fprintf(stderr, "Failed to access public key (%s)\n", strerror(errno)); return (1); } if (ssh_pki_import_pubkey_file(buf, &(credentials->public_key)) != SSH_OK) { fprintf(stderr, "Failed to import public key\n"); return (1); } return (0); }
/** * @brief Import a certificate from the given filename. * * @param[in] filename The path to the certificate. * * @param[out] pkey A pointer to store the allocated certificate. You need to * free the memory. * * @returns SSH_OK on success, SSH_EOF if the file doesn't exist or permission * denied, SSH_ERROR otherwise. * * @see ssh_key_free() */ int ssh_pki_import_cert_file(const char *filename, ssh_key *pkey) { return ssh_pki_import_pubkey_file(filename, pkey); }
static gint mock_ssh_server (const gchar *server_addr, gint server_port, const gchar *user, const gchar *password, gboolean multi_step) { char portname[16]; char addrname[16]; struct sockaddr_storage addr; socklen_t addrlen; ssh_bind sshbind; const char *msg; int r; gint rounds = 0; state.event = ssh_event_new (); if (state.event == NULL) g_return_val_if_reached (-1); sshbind = ssh_bind_new (); state.session = ssh_new (); if (server_addr == NULL) server_addr = "127.0.0.1"; ssh_bind_options_set (sshbind, SSH_BIND_OPTIONS_BINDADDR, server_addr); ssh_bind_options_set (sshbind, SSH_BIND_OPTIONS_BINDPORT, &server_port); ssh_bind_options_set (sshbind, SSH_BIND_OPTIONS_RSAKEY, SRCDIR "/src/ws/mock_rsa_key"); ssh_bind_options_set (sshbind, SSH_BIND_OPTIONS_DSAKEY, SRCDIR "/src/ws/mock_dsa_key"); if (ssh_bind_listen (sshbind) < 0) { g_critical ("couldn't listen on socket: %s", ssh_get_error (sshbind)); return 1; } state.bind_fd = ssh_bind_get_fd (sshbind); state.user = user; state.password = password; state.multi_step = multi_step; ssh_pki_import_pubkey_file (SRCDIR "/src/ws/test_rsa.pub", &state.pkey); state.buffer = g_byte_array_new (); /* Print out the port */ if (server_port == 0) { addrlen = sizeof (addr); if (getsockname (state.bind_fd, (struct sockaddr *)&addr, &addrlen) < 0) { g_critical ("couldn't get local address: %s", g_strerror (errno)); return 1; } r = getnameinfo ((struct sockaddr *)&addr, addrlen, addrname, sizeof (addrname), portname, sizeof (portname), NI_NUMERICHOST | NI_NUMERICSERV); if (r != 0) { g_critical ("couldn't get local port: %s", gai_strerror (r)); return 1; } /* Caller wants to know the port */ g_print ("%s\n", portname); } /* Close stdout (once above info is printed) */ close (1); ssh_set_message_callback (state.session, authenticate_callback, &rounds); r = ssh_bind_accept (sshbind, state.session); if (r == SSH_ERROR) { g_critical ("accepting connection failed: %s", ssh_get_error (sshbind)); return 1; } state.session_fd = ssh_get_fd (state.session); if (ssh_handle_key_exchange (state.session)) { msg = ssh_get_error (state.session); if (!strstr (msg, "_DISCONNECT")) g_critical ("key exchange failed: %s", msg); return 1; } if (ssh_event_add_session (state.event, state.session) != SSH_OK) g_return_val_if_reached (-1); do { ssh_event_dopoll (state.event, 10000); } while (ssh_is_connected (state.session)); ssh_event_remove_session (state.event, state.session); ssh_event_free (state.event); ssh_free (state.session); ssh_key_free (state.pkey); g_byte_array_free (state.buffer, TRUE); ssh_bind_free (sshbind); return 0; }