diff options
author | Lukasz Marek <lukasz.m.luki@gmail.com> | 2014-01-20 22:57:57 +0100 |
---|---|---|
committer | Lukasz Marek <lukasz.m.luki@gmail.com> | 2014-01-22 00:41:13 +0100 |
commit | 7e8f3048464ff15d54b0e7d1972b3e3d2263cf7c (patch) | |
tree | 0efd8355b16b0d97c4488699559e6d2a510fe1e1 /libavformat/libssh.c | |
parent | 977abf9aedec429d9c384058a6e3f39a2969b459 (diff) | |
download | ffmpeg-7e8f3048464ff15d54b0e7d1972b3e3d2263cf7c.tar.gz |
lavf/libssh: add private_key option
Allows to specify private key to use during authorization.
Signed-off-by: Lukasz Marek <lukasz.m.luki@gmail.com>
Diffstat (limited to 'libavformat/libssh.c')
-rw-r--r-- | libavformat/libssh.c | 61 |
1 files changed, 51 insertions, 10 deletions
diff --git a/libavformat/libssh.c b/libavformat/libssh.c index aa9b060ee3..fabc024695 100644 --- a/libavformat/libssh.c +++ b/libavformat/libssh.c @@ -22,6 +22,7 @@ #include <libssh/sftp.h> #include "libavutil/avstring.h" #include "libavutil/opt.h" +#include "libavutil/attributes.h" #include "avformat.h" #include "internal.h" #include "url.h" @@ -34,8 +35,55 @@ typedef struct { int64_t filesize; int rw_timeout; int trunc; + char *priv_key; } LIBSSHContext; +static av_cold int libssh_authentication(LIBSSHContext *libssh, const char *user, const char *password) +{ + int authorized = 0; + int auth_methods; + + if (user) + ssh_options_set(libssh->session, SSH_OPTIONS_USER, user); + + auth_methods = ssh_userauth_list(libssh->session, NULL); + + if (auth_methods & SSH_AUTH_METHOD_PUBLICKEY) { + if (libssh->priv_key) { + ssh_string pub_key; + ssh_private_key priv_key; + int type; + if (!ssh_try_publickey_from_file(libssh->session, libssh->priv_key, &pub_key, &type)) { + priv_key = privatekey_from_file(libssh->session, libssh->priv_key, type, password); + if (ssh_userauth_pubkey(libssh->session, NULL, pub_key, priv_key) == SSH_AUTH_SUCCESS) { + av_log(libssh, AV_LOG_DEBUG, "Authentication successful with selected private key.\n"); + authorized = 1; + } + } else { + av_log(libssh, AV_LOG_DEBUG, "Invalid key is provided.\n"); + return AVERROR(EACCES); + } + } else if (ssh_userauth_autopubkey(libssh->session, password) == SSH_AUTH_SUCCESS) { + av_log(libssh, AV_LOG_DEBUG, "Authentication successful with auto selected key.\n"); + authorized = 1; + } + } + + if (!authorized && (auth_methods & SSH_AUTH_METHOD_PASSWORD)) { + if (ssh_userauth_password(libssh->session, NULL, password) == SSH_AUTH_SUCCESS) { + av_log(libssh, AV_LOG_DEBUG, "Authentication successful with password.\n"); + authorized = 1; + } + } + + if (!authorized) { + av_log(libssh, AV_LOG_ERROR, "Authentication failed.\n"); + return AVERROR(EACCES); + } + + return 0; +} + static int libssh_close(URLContext *h) { LIBSSHContext *s = h->priv_data; @@ -82,8 +130,6 @@ static int libssh_open(URLContext *h, const char *url, int flags) ssh_options_set(s->session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity); if (timeout > 0) ssh_options_set(s->session, SSH_OPTIONS_TIMEOUT_USEC, &timeout); - if (user) - ssh_options_set(s->session, SSH_OPTIONS_USER, user); if (ssh_connect(s->session) != SSH_OK) { av_log(h, AV_LOG_ERROR, "Connection failed. %s\n", ssh_get_error(s->session)); @@ -91,14 +137,8 @@ static int libssh_open(URLContext *h, const char *url, int flags) goto fail; } - if (ssh_userauth_autopubkey(s->session, pass) != SSH_AUTH_SUCCESS) { - av_log(s, AV_LOG_DEBUG, "Authentication using public key failed, trying password method.\n"); - if (ssh_userauth_password(s->session, NULL, pass) != SSH_AUTH_SUCCESS) { - av_log(h, AV_LOG_ERROR, "Authentication failed.\n"); - ret = AVERROR(EACCES); - goto fail; - } - } + if ((ret = libssh_authentication(s, user, pass)) < 0) + goto fail; if (!(s->sftp = sftp_new(s->session))) { av_log(h, AV_LOG_ERROR, "SFTP session creation failed: %s\n", ssh_get_error(s->session)); @@ -210,6 +250,7 @@ static int libssh_write(URLContext *h, const unsigned char *buf, int size) static const AVOption options[] = { {"timeout", "set timeout of socket I/O operations", OFFSET(rw_timeout), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, D|E }, {"truncate", "Truncate existing files on write", OFFSET(trunc), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, E }, + {"private_key", "set path to private key", OFFSET(priv_key), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, D|E }, {NULL} }; |