diff options
author | Jakub Jelen <jjelen@redhat.com> | 2018-11-01 18:35:44 +0100 |
---|---|---|
committer | Andreas Schneider <asn@cryptomilk.org> | 2019-01-09 10:14:56 +0100 |
commit | 1a92c4bc6482c80eb6b2bccb03ed365cd0b54814 (patch) | |
tree | 0030ad2b5182f3c99454b28118f1a7020460d883 /src/config.c | |
parent | e973f95b373e6d9ef50da11171aecc2bdf1b5c4b (diff) | |
download | libssh-1a92c4bc6482c80eb6b2bccb03ed365cd0b54814.tar.gz libssh-1a92c4bc6482c80eb6b2bccb03ed365cd0b54814.tar.xz libssh-1a92c4bc6482c80eb6b2bccb03ed365cd0b54814.zip |
config: Parse rekey limits and apply them
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Daiki Ueno <dueno@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
Diffstat (limited to 'src/config.c')
-rw-r--r-- | src/config.c | 139 |
1 files changed, 138 insertions, 1 deletions
diff --git a/src/config.c b/src/config.c index f31665aa..2cbb6d5b 100644 --- a/src/config.c +++ b/src/config.c @@ -31,6 +31,7 @@ # include <glob.h> #endif #include <stdbool.h> +#include <limits.h> #include "libssh/config.h" #include "libssh/priv.h" @@ -109,7 +110,7 @@ static struct ssh_config_keyword_table_s ssh_config_keyword_table[] = { { "proxyjump", SOC_PROXYJUMP}, { "proxyusefdpass", SOC_UNSUPPORTED}, { "pubkeyacceptedtypes", SOC_PUBKEYACCEPTEDTYPES}, - { "rekeylimit", SOC_UNSUPPORTED}, + { "rekeylimit", SOC_REKEYLIMIT}, { "remotecommand", SOC_UNSUPPORTED}, { "revokedhostkeys", SOC_UNSUPPORTED}, { "rhostsrsaauthentication", SOC_UNSUPPORTED}, @@ -604,6 +605,7 @@ ssh_config_parse_line(ssh_session session, int i, rv; uint8_t *seen = session->opts.options_seen; long l; + long long ll; x = s = strdup(line); if (s == NULL) { @@ -966,6 +968,141 @@ ssh_config_parse_line(ssh_session session, ssh_options_set(session, SSH_OPTIONS_KEY_EXCHANGE, p); } break; + case SOC_REKEYLIMIT: + /* Parse the data limit */ + p = ssh_config_get_str_tok(&s, NULL); + if (p == NULL) { + break; + } else if (strcmp(p, "default") == 0) { + /* Default rekey limits enforced automaticaly */ + ll = 0; + } else { + char *endp = NULL; + ll = strtoll(p, &endp, 10); + if (p == endp || ll < 0) { + /* No number or negative */ + SSH_LOG(SSH_LOG_WARN, "Invalid argument to rekey limit"); + break; + } + switch (*endp) { + case 'G': + if (ll > LLONG_MAX / 1024) { + SSH_LOG(SSH_LOG_WARN, "Possible overflow of rekey limit"); + ll = -1; + break; + } + ll = ll * 1024; + FALL_THROUGH; + case 'M': + if (ll > LLONG_MAX / 1024) { + SSH_LOG(SSH_LOG_WARN, "Possible overflow of rekey limit"); + ll = -1; + break; + } + ll = ll * 1024; + FALL_THROUGH; + case 'K': + if (ll > LLONG_MAX / 1024) { + SSH_LOG(SSH_LOG_WARN, "Possible overflow of rekey limit"); + ll = -1; + break; + } + ll = ll * 1024; + endp++; + FALL_THROUGH; + case '\0': + /* just the number */ + break; + default: + /* Invalid suffix */ + ll = -1; + break; + } + if (*endp != ' ' && *endp != '\0') { + SSH_LOG(SSH_LOG_WARN, + "Invalid trailing characters after the rekey limit: %s", + endp); + break; + } + } + if (ll > -1 && *parsing) { + uint64_t v = (uint64_t)ll; + ssh_options_set(session, SSH_OPTIONS_REKEY_DATA, &v); + } + /* Parse the time limit */ + p = ssh_config_get_str_tok(&s, NULL); + if (p == NULL) { + break; + } else if (strcmp(p, "none") == 0) { + ll = 0; + } else { + char *endp = NULL; + ll = strtoll(p, &endp, 10); + if (p == endp || ll < 0) { + /* No number or negative */ + SSH_LOG(SSH_LOG_WARN, "Invalid argument to rekey limit"); + break; + } + switch (*endp) { + case 'w': + case 'W': + if (ll > LLONG_MAX / 7) { + SSH_LOG(SSH_LOG_WARN, "Possible overflow of rekey limit"); + ll = -1; + break; + } + ll = ll * 7; + FALL_THROUGH; + case 'd': + case 'D': + if (ll > LLONG_MAX / 24) { + SSH_LOG(SSH_LOG_WARN, "Possible overflow of rekey limit"); + ll = -1; + break; + } + ll = ll * 24; + FALL_THROUGH; + case 'h': + case 'H': + if (ll > LLONG_MAX / 60) { + SSH_LOG(SSH_LOG_WARN, "Possible overflow of rekey limit"); + ll = -1; + break; + } + ll = ll * 60; + FALL_THROUGH; + case 'm': + case 'M': + if (ll > LLONG_MAX / 60) { + SSH_LOG(SSH_LOG_WARN, "Possible overflow of rekey limit"); + ll = -1; + break; + } + ll = ll * 60; + FALL_THROUGH; + case 's': + case 'S': + endp++; + FALL_THROUGH; + case '\0': + /* just the number */ + break; + default: + /* Invalid suffix */ + ll = -1; + break; + } + if (*endp != '\0') { + SSH_LOG(SSH_LOG_WARN, "Invalid trailing characters after the" + " rekey limit: %s", endp); + break; + } + } + if (ll > -1 && *parsing) { + uint32_t v = (uint32_t)ll; + ssh_options_set(session, SSH_OPTIONS_REKEY_TIME, &v); + } + break; case SOC_GSSAPIAUTHENTICATION: case SOC_KBDINTERACTIVEAUTHENTICATION: case SOC_PASSWORDAUTHENTICATION: |