static ssh_session create_ssh_connection(const char* hostname, const unsigned int port, const char* username, const char* password, const char* sshkey_path, const char* sshkey_passphrase) { ssh_session sshs; /* Open session and set options */ sshs = ssh_new(); if (sshs == NULL) { errmsg_print("Can't create ssh session"); return NULL; } if (!hostname) return NULL; if (ssh_options_set(sshs, SSH_OPTIONS_HOST, hostname)) { errmsg_print("Can't set the hostname: %s\n", hostname); goto failure; } if (port != 0) { if (ssh_options_set(sshs, SSH_OPTIONS_PORT, &port)) { errmsg_print("Can't set the port: %d\n", port); goto failure; } } if (!username) username = g_get_user_name(); if (ssh_options_set(sshs, SSH_OPTIONS_USER, username)) { errmsg_print("Can't set the username: %s\n", username); goto failure; } verbose_print("Opening ssh connection to %s@%s:%u\n", username, hostname, port); /* Connect to server */ if (ssh_connect(sshs) != SSH_OK) { errmsg_print("Error connecting to %s@%s:%u (%s)\n", username, hostname, port, ssh_get_error(sshs)); goto failure; } #ifdef HAVE_LIBSSH_USERAUTH_AGENT verbose_print("Connecting using ssh-agent..."); /* Try to authenticate using ssh agent */ if (ssh_userauth_agent(sshs, NULL) == SSH_AUTH_SUCCESS) { verbose_print("done\n"); return sshs; } verbose_print("failed\n"); #endif /* If a public key path has been provided, try to authenticate using it */ if (sshkey_path) { ssh_key pkey = ssh_key_new(); int ret; verbose_print("Connecting using public key in %s...", sshkey_path); ret = ssh_pki_import_privkey_file(sshkey_path, sshkey_passphrase, NULL, NULL, &pkey); if (ret == SSH_OK) { if (ssh_userauth_publickey(sshs, NULL, pkey) == SSH_AUTH_SUCCESS) { verbose_print("done\n"); ssh_key_free(pkey); return sshs; } } ssh_key_free(pkey); verbose_print("failed (%s)\n", ssh_get_error(sshs)); } /* Try to authenticate using standard public key */ verbose_print("Connecting using standard public key..."); if (ssh_userauth_publickey_auto(sshs, NULL, NULL) == SSH_AUTH_SUCCESS) { verbose_print("done\n"); return sshs; } verbose_print("failed\n"); /* If a password has been provided and all previous attempts failed, try to use it */ if (password) { verbose_print("Connecting using password..."); if (ssh_userauth_password(sshs, username, password) == SSH_AUTH_SUCCESS) { verbose_print("done\n"); return sshs; } verbose_print("failed\n"); } errmsg_print("Can't find a valid authentication. Disconnecting.\n"); /* All authentication failed. Disconnect and return */ ssh_disconnect(sshs); failure: ssh_free(sshs); return NULL; }
static int _import_private_key(t_credentials *credentials, const char *credentials_dirpath, char *buf, const char *password) { sprintf(buf, "%s/id_rsa", credentials_dirpath); credentials->private_key_filepath = xstrdup(buf); if (!credentials->private_key_filepath) return (1); if (access(buf, R_OK) != 0) { fprintf(stderr, "Failed to access private key (%s)\n", strerror(errno)); return (1); } if (ssh_pki_import_privkey_file(buf, password, NULL, NULL, &(credentials->private_key)) != SSH_OK) { fprintf(stderr, "Failed to import private key (incorrect password or invalid file)\n"); return (1); } return (0); }
ssh_private_key privatekey_from_file(ssh_session session, const char *filename, int type, const char *passphrase) { ssh_key key; ssh_private_key privkey; int rc; (void) type; /* unused */ rc = ssh_pki_import_privkey_file(session, filename, passphrase, &key); if (rc == SSH_ERROR) { return NULL; } privkey = malloc(sizeof(struct ssh_private_key_struct)); if (privkey == NULL) { ssh_key_free(key); return NULL; } privkey->type = key->type; privkey->dsa_priv = key->dsa; privkey->rsa_priv = key->rsa; return privkey; }
/* Test case for bug #147: Private ECDSA key duplication did not carry * over parts of the key that then caused subsequent key demotion to * fail. */ static void torture_pki_ecdsa_duplicate_then_demote(void **state) { ssh_key pubkey; ssh_key privkey; ssh_key privkey_dup; int rc; (void) state; 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); assert_int_equal(privkey->ecdsa_nid, privkey_dup->ecdsa_nid); rc = ssh_pki_export_privkey_to_pubkey(privkey_dup, &pubkey); assert_true(rc == 0); assert_int_equal(pubkey->ecdsa_nid, privkey->ecdsa_nid); ssh_key_free(pubkey); ssh_key_free(privkey); ssh_key_free(privkey_dup); }
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); }
static ssh_bind prepare_ssh(const char *keys_dir, const char *bind_addr, int port) { ssh_bind bind; char buffer[PATH_MAX]; int ssh_log_level; ssh_key rsakey = NULL; ssh_key ed25519key = NULL; ssh_log_level = SSH_LOG_WARNING + max(log_get_level() - LOG_NOTICE, 0); ssh_set_log_callback(ssh_log_function); bind = ssh_bind_new(); if (!bind) tmate_fatal("Cannot initialize ssh"); if (bind_addr) ssh_bind_options_set(bind, SSH_BIND_OPTIONS_BINDADDR, bind_addr); ssh_bind_options_set(bind, SSH_BIND_OPTIONS_BINDPORT, &port); ssh_bind_options_set(bind, SSH_BIND_OPTIONS_BANNER, TMATE_SSH_BANNER); ssh_bind_options_set(bind, SSH_BIND_OPTIONS_LOG_VERBOSITY, &ssh_log_level); sprintf(buffer, "%s/ssh_host_rsa_key", keys_dir); ssh_pki_import_privkey_file(buffer, NULL, NULL, NULL, &rsakey); ssh_bind_options_set(bind, SSH_BIND_OPTIONS_IMPORT_KEY, rsakey); sprintf(buffer, "%s/ssh_host_ed25519_key", keys_dir); ssh_pki_import_privkey_file(buffer, NULL, NULL, NULL, &ed25519key); ssh_bind_options_set(bind, SSH_BIND_OPTIONS_IMPORT_KEY, ed25519key); if (ssh_bind_listen(bind) < 0) tmate_fatal("Error listening to socket: %s\n", ssh_get_error(bind)); tmate_notice("Accepting connections on %s:%d", bind_addr ?: "", port); return bind; }
static void torture_auth_cert(void **state) { struct torture_state *s = *state; ssh_session session = s->ssh.session; ssh_key privkey = NULL; ssh_key cert = NULL; char bob_ssh_key[1024]; char bob_ssh_cert[2048]; struct passwd *pwd; int rc; pwd = getpwnam("bob"); assert_non_null(pwd); snprintf(bob_ssh_key, sizeof(bob_ssh_key), "%s/.ssh_cert/id_rsa", pwd->pw_dir); snprintf(bob_ssh_cert, sizeof(bob_ssh_cert), "%s-cert.pub", bob_ssh_key); /* cert has been signed for login as alice */ rc = ssh_options_set(session, SSH_OPTIONS_USER, TORTURE_SSH_USER_ALICE); assert_int_equal(rc, SSH_OK); rc = ssh_connect(session); assert_int_equal(rc, SSH_OK); rc = ssh_pki_import_privkey_file(bob_ssh_key, NULL, NULL, NULL, &privkey); assert_int_equal(rc, SSH_OK); rc = ssh_pki_import_cert_file(bob_ssh_cert, &cert); assert_int_equal(rc, SSH_OK); rc = ssh_pki_copy_cert_to_privkey(cert, privkey); assert_int_equal(rc, SSH_OK); rc = ssh_userauth_try_publickey(session, NULL, cert); assert_int_equal(rc, SSH_AUTH_SUCCESS); rc = ssh_userauth_publickey(session, NULL, privkey); assert_int_equal(rc, SSH_AUTH_SUCCESS); ssh_key_free(privkey); ssh_key_free(cert); }
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_generate_pubkey_from_privkey_ecdsa(void **state) { char pubkey_original[4096] = {0}; char pubkey_generated[4096] = {0}; ssh_key privkey; ssh_key pubkey; int rc; (void) state; /* unused */ rc = torture_read_one_line(LIBSSH_ECDSA_TESTKEY ".pub", pubkey_original, sizeof(pubkey_original)); assert_true(rc == 0); /* remove the public key, generate it from the private key and write it. */ unlink(LIBSSH_ECDSA_TESTKEY ".pub"); rc = ssh_pki_import_privkey_file(LIBSSH_ECDSA_TESTKEY, NULL, NULL, NULL, &privkey); assert_true(rc == 0); rc = ssh_pki_export_privkey_to_pubkey(privkey, &pubkey); assert_true(rc == SSH_OK); rc = ssh_pki_export_pubkey_file(pubkey, LIBSSH_ECDSA_TESTKEY ".pub"); assert_true(rc == 0); rc = torture_read_one_line(LIBSSH_ECDSA_TESTKEY ".pub", pubkey_generated, sizeof(pubkey_generated)); assert_true(rc == 0); assert_string_equal(pubkey_original, pubkey_generated); ssh_key_free(privkey); ssh_key_free(pubkey); }
static gint remmina_ssh_auth_pubkey (RemminaSSH *ssh) { gint ret; ssh_key priv_key; if (ssh->authenticated) return 1; if (ssh->privkeyfile == NULL) { ssh->error = g_strdup_printf(_("SSH public key authentication failed: %s"), _("SSH Key file not yet set.")); return 0; } if ( ssh_pki_import_privkey_file( ssh->privkeyfile, (ssh->password ? ssh->password : ""), NULL, NULL, &priv_key ) != SSH_OK ) { if (ssh->password == NULL || ssh->password[0] == '\0') return -1; remmina_ssh_set_error (ssh, _("SSH public key authentication failed: %s")); return 0; } ret = ssh_userauth_publickey (ssh->session, NULL, priv_key); ssh_key_free(priv_key); if (ret != SSH_AUTH_SUCCESS) { remmina_ssh_set_error (ssh, _("SSH public key authentication failed: %s")); return 0; } ssh->authenticated = TRUE; return 1; }
static int ssh_bind_import_keys(ssh_bind sshbind) { int rc; if (sshbind->ecdsakey == NULL && sshbind->dsakey == NULL && sshbind->rsakey == NULL) { ssh_set_error(sshbind, SSH_FATAL, "ECDSA, DSA, or RSA host key file must be set"); return SSH_ERROR; } #ifdef HAVE_ECC if (sshbind->ecdsa == NULL && sshbind->ecdsakey != NULL) { rc = ssh_pki_import_privkey_file(sshbind->ecdsakey, NULL, NULL, NULL, &sshbind->ecdsa); if (rc == SSH_ERROR || rc == SSH_EOF) { ssh_set_error(sshbind, SSH_FATAL, "Failed to import private ECDSA host key"); return SSH_ERROR; } if (ssh_key_type(sshbind->ecdsa) != SSH_KEYTYPE_ECDSA) { ssh_set_error(sshbind, SSH_FATAL, "The ECDSA host key has the wrong type"); ssh_key_free(sshbind->ecdsa); sshbind->ecdsa = NULL; return SSH_ERROR; } } #endif if (sshbind->dsa == NULL && sshbind->dsakey != NULL) { rc = ssh_pki_import_privkey_file(sshbind->dsakey, NULL, NULL, NULL, &sshbind->dsa); if (rc == SSH_ERROR || rc == SSH_EOF) { ssh_set_error(sshbind, SSH_FATAL, "Failed to import private DSA host key"); return SSH_ERROR; } if (ssh_key_type(sshbind->dsa) != SSH_KEYTYPE_DSS) { ssh_set_error(sshbind, SSH_FATAL, "The DSA host key has the wrong type: %d", ssh_key_type(sshbind->dsa)); ssh_key_free(sshbind->dsa); sshbind->dsa = NULL; return SSH_ERROR; } } if (sshbind->rsa == NULL && sshbind->rsakey != NULL) { rc = ssh_pki_import_privkey_file(sshbind->rsakey, NULL, NULL, NULL, &sshbind->rsa); if (rc == SSH_ERROR || rc == SSH_EOF) { ssh_set_error(sshbind, SSH_FATAL, "Failed to import private RSA host key"); return SSH_ERROR; } if (ssh_key_type(sshbind->rsa) != SSH_KEYTYPE_RSA && ssh_key_type(sshbind->rsa) != SSH_KEYTYPE_RSA1) { ssh_set_error(sshbind, SSH_FATAL, "The RSA host key has the wrong type"); ssh_key_free(sshbind->rsa); sshbind->rsa = NULL; return SSH_ERROR; } } return SSH_OK; }
int ssh_bind_listen(ssh_bind sshbind) { const char *host; socket_t fd; int rc; if (ssh_init() < 0) { ssh_set_error(sshbind, SSH_FATAL, "ssh_init() failed"); return -1; } 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; } if (sshbind->dsakey) { rc = ssh_pki_import_privkey_file(sshbind->dsakey, NULL, NULL, NULL, &sshbind->dsa); if (rc == SSH_ERROR) { ssh_set_error(sshbind, SSH_FATAL, "Failed to import private DSA host key"); return SSH_ERROR; } if (ssh_key_type(sshbind->dsa) != SSH_KEYTYPE_DSS) { ssh_set_error(sshbind, SSH_FATAL, "The DSA host key has the wrong type"); ssh_key_free(sshbind->dsa); return SSH_ERROR; } } if (sshbind->rsakey) { rc = ssh_pki_import_privkey_file(sshbind->rsakey, NULL, NULL, NULL, &sshbind->rsa); if (rc == SSH_ERROR) { ssh_set_error(sshbind, SSH_FATAL, "Failed to import private RSA host key"); return SSH_ERROR; } if (ssh_key_type(sshbind->rsa) != SSH_KEYTYPE_RSA && ssh_key_type(sshbind->rsa) != SSH_KEYTYPE_RSA1) { ssh_set_error(sshbind, SSH_FATAL, "The RSA host key has the wrong type"); ssh_key_free(sshbind->rsa); return SSH_ERROR; } } if (sshbind->bindfd == SSH_INVALID_SOCKET) { host = sshbind->bindaddr; if (host == NULL) { host = "0.0.0.0"; } fd = bind_socket(sshbind, host, sshbind->bindport); if (fd == SSH_INVALID_SOCKET) { ssh_key_free(sshbind->dsa); ssh_key_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); ssh_key_free(sshbind->dsa); ssh_key_free(sshbind->rsa); return -1; } } else { SSH_LOG(sshbind, SSH_LOG_INFO, "Using app-provided bind socket"); } return 0; }