static int check_authorized_keys(struct ssh_key_struct *client_pubkey) { #define MAX_PUBKEY_SIZE 0x4000 const char *authorized_keys_path = tmate_settings->authorized_keys_path; const char *token_delim = " "; FILE *file; char key_buf[MAX_PUBKEY_SIZE], *key_type, *key_content; enum ssh_keytypes_e type; ssh_key pkey; if (authorized_keys_path == NULL) return SSH_AUTH_SUCCESS; file = fopen(authorized_keys_path, "rb"); if (file == NULL) { tmate_fatal("Could not open authorized_keys file: \"%s\"", authorized_keys_path); return SSH_AUTH_DENIED; } while (fgets(key_buf, MAX_PUBKEY_SIZE, file)) { if (key_buf[0] == '#' || key_buf[0] == '\0') continue; key_type = strtok(key_buf, token_delim); if (key_type == NULL) continue; type = ssh_key_type_from_name(key_type); if (type == SSH_KEYTYPE_UNKNOWN) continue; key_content = strtok(NULL, token_delim); if (key_content == NULL) continue; pkey = ssh_key_new(); if (ssh_pki_import_pubkey_base64(key_content, type, &pkey) != SSH_OK) { ssh_key_free(pkey); continue; } if (!ssh_key_cmp(pkey, client_pubkey, SSH_KEY_CMP_PUBLIC)) { ssh_key_free(pkey); fclose(file); return SSH_AUTH_SUCCESS; } ssh_key_free(pkey); } fclose(file); return SSH_AUTH_DENIED; }
static int auth_publickey (ssh_message message) { int ret = -1; int auth_state = ssh_message_auth_publickey_state (message); gboolean have = ssh_key_cmp (state.pkey, ssh_message_auth_pubkey (message), SSH_KEY_CMP_PUBLIC) == 0; if (have && auth_state == SSH_PUBLICKEY_STATE_VALID) ret = 1; else if (have && auth_state == SSH_PUBLICKEY_STATE_NONE) ret = 0; return ret; }
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 void torture_pki_write_privkey_rsa(void **state) { ssh_key origkey; ssh_key privkey; int rc; (void) state; /* unused */ ssh_set_log_level(5); rc = ssh_pki_import_privkey_file(LIBSSH_RSA_TESTKEY, NULL, NULL, NULL, &origkey); assert_true(rc == 0); unlink(LIBSSH_RSA_TESTKEY); rc = ssh_pki_export_privkey_file(origkey, "", NULL, NULL, LIBSSH_RSA_TESTKEY); assert_true(rc == 0); rc = ssh_pki_import_privkey_file(LIBSSH_RSA_TESTKEY, NULL, NULL, NULL, &privkey); assert_true(rc == 0); rc = ssh_key_cmp(origkey, privkey, SSH_KEY_CMP_PRIVATE); assert_true(rc == 0); ssh_key_free(origkey); ssh_key_free(privkey); }