diff options
author | Andreas Schneider <mail@cynapses.org> | 2010-02-28 22:51:21 +0100 |
---|---|---|
committer | Andreas Schneider <mail@cynapses.org> | 2010-03-04 20:41:17 +0100 |
commit | f34cd24f8073e87d09159b8a6c8e2fa48cd17227 (patch) | |
tree | 58215ba6907f70b7ed7155c643b423de608a0cfd /libssh/keyfiles.c | |
parent | 9cd5e97596aa10f349e960fb3ff5ca95634a1200 (diff) | |
download | libssh-f34cd24f8073e87d09159b8a6c8e2fa48cd17227.tar.gz libssh-f34cd24f8073e87d09159b8a6c8e2fa48cd17227.tar.xz libssh-f34cd24f8073e87d09159b8a6c8e2fa48cd17227.zip |
Fixed and added support for several identity files.
Diffstat (limited to 'libssh/keyfiles.c')
-rw-r--r-- | libssh/keyfiles.c | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/libssh/keyfiles.c b/libssh/keyfiles.c index ab2050e..40c6030 100644 --- a/libssh/keyfiles.c +++ b/libssh/keyfiles.c @@ -887,6 +887,79 @@ void privatekey_free(ssh_private_key prv) { SAFE_FREE(prv); } +/** + * @brief Write a public key to a file. + * + * @param[in] session The ssh session to use. + * + * @param[in] file The filename to write the key into. + * + * @param[in] pubkey The public key to write. + * + * @param[in] type The type of the public key. + * + * @return 0 on success, -1 on error. + */ +int ssh_publickey_to_file(ssh_session session, const char *file, + ssh_string pubkey, int type) { + FILE *fp; + char *user; + char buffer[1024]; + char host[256]; + unsigned char *pubkey_64; + size_t len; + int rc; + + pubkey_64 = bin_to_base64(pubkey->string, string_len(pubkey)); + if (pubkey_64 == NULL) { + return -1; + } + + user = ssh_get_local_username(session); + if (user == NULL) { + SAFE_FREE(pubkey_64); + return -1; + } + + rc = gethostname(host, sizeof(host)); + if (rc < 0) { + SAFE_FREE(user); + SAFE_FREE(pubkey_64); + return -1; + } + + snprintf(buffer, sizeof(buffer), "%s %s %s@%s\n", + ssh_type_to_char(type), + pubkey_64, + user, + host); + + SAFE_FREE(pubkey_64); + SAFE_FREE(user); + + ssh_log(session, SSH_LOG_RARE, "Trying to write public key file: %s", file); + ssh_log(session, SSH_LOG_PACKET, "public key file content: %s", buffer); + + fp = fopen(file, "w+"); + if (fp == NULL) { + ssh_set_error(session, SSH_REQUEST_DENIED, + "Error opening %s: %s", file, strerror(errno)); + return -1; + } + + len = strlen(buffer); + if (fwrite(buffer, len, 1, fp) != 1 || ferror(fp)) { + ssh_set_error(session, SSH_REQUEST_DENIED, + "Unable to write to %s", file); + fclose(fp); + unlink(file); + return -1; + } + + fclose(fp); + return 0; +} + /** \brief Retrieve a public key from a file * \param session the SSH session * \param filename Filename of the key @@ -964,6 +1037,79 @@ ssh_string publickey_from_file(ssh_session session, const char *filename, return str; } +/** + * @brief Try to read the public key from a given file. + * + * @param[in] session The ssh session to use. + * + * @param[in] keyfile The name of the private keyfile. + * + * @param[out] publickey A ssh_string to store the public key. + * + * @param[out] type A pointer to an integer to store the type. + * + * @return 0 on success, -1 on error or the private key doesn't + * exist, 1 if the public key doesn't exist. + */ +int ssh_try_publickey_from_file(ssh_session session, const char *keyfile, + ssh_string *publickey, int *type) { + char *pubkey_file; + size_t len; + ssh_string pubkey_string; + int pubkey_type; + + if (session == NULL || keyfile == NULL || publickey == NULL || type == NULL) { + return -1; + } + + if (session->sshdir == NULL) { + if (ssh_options_set(session, SSH_OPTIONS_SSH_DIR, NULL) < 0) { + return -1; + } + } + + ssh_log(session, SSH_LOG_PACKET, "Trying to open privatekey %s", keyfile); + if (!ssh_file_readaccess_ok(keyfile)) { + ssh_log(session, SSH_LOG_PACKET, "Failed to open privatekey %s", keyfile); + return -1; + } + + len = strlen(keyfile) + 5; + pubkey_file = malloc(len); + if (pubkey_file == NULL) { + return -1; + } + snprintf(pubkey_file, len, "%s.pub", keyfile); + + ssh_log(session, SSH_LOG_PACKET, "Trying to open publickey %s", + pubkey_file); + if (!ssh_file_readaccess_ok(pubkey_file)) { + ssh_log(session, SSH_LOG_PACKET, "Failed to open publickey %s", + pubkey_file); + return 1; + } + + ssh_log(session, SSH_LOG_PACKET, "Success opening public and private key"); + + /* + * We are sure both the private and public key file is readable. We return + * the public as a string, and the private filename as an argument + */ + pubkey_string = publickey_from_file(session, pubkey_file, &pubkey_type); + if (pubkey_string == NULL) { + ssh_log(session, SSH_LOG_PACKET, + "Wasn't able to open public key file %s: %s", + pubkey_file, + ssh_get_error(session)); + return -1; + } + + *publickey = pubkey_string; + *type = pubkey_type; + + return 0; +} + ssh_string try_publickey_from_file(ssh_session session, struct ssh_keys_struct keytab, char **privkeyfile, int *type) { char *public; |