OSDN Git Service

Define HAVE_ATTRIBUTE__SENTINEL__ to 1.
[android-x86/external-openssh.git] / readconf.c
index ebbf219..cd01482 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.c,v 1.232 2015/02/16 22:13:32 djm Exp $ */
+/* $OpenBSD: readconf.c,v 1.239 2015/07/30 00:01:34 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -157,6 +157,7 @@ typedef enum {
        oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
        oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys,
        oFingerprintHash, oUpdateHostkeys, oHostbasedKeyTypes,
+       oPubkeyAcceptedKeyTypes,
        oIgnoredUnknownOption, oDeprecated, oUnsupported
 } OpCodes;
 
@@ -275,6 +276,7 @@ static struct {
        { "fingerprinthash", oFingerprintHash },
        { "updatehostkeys", oUpdateHostkeys },
        { "hostbasedkeytypes", oHostbasedKeyTypes },
+       { "pubkeyacceptedkeytypes", oPubkeyAcceptedKeyTypes },
        { "ignoreunknown", oIgnoreUnknown },
 
        { NULL, oBadOption }
@@ -295,7 +297,7 @@ add_local_forward(Options *options, const struct Forward *newfwd)
            newfwd->listen_path == NULL)
                fatal("Privileged ports can only be forwarded by root.");
 #endif
-       options->local_forwards = xrealloc(options->local_forwards,
+       options->local_forwards = xreallocarray(options->local_forwards,
            options->num_local_forwards + 1,
            sizeof(*options->local_forwards));
        fwd = &options->local_forwards[options->num_local_forwards++];
@@ -318,7 +320,7 @@ add_remote_forward(Options *options, const struct Forward *newfwd)
 {
        struct Forward *fwd;
 
-       options->remote_forwards = xrealloc(options->remote_forwards,
+       options->remote_forwards = xreallocarray(options->remote_forwards,
            options->num_remote_forwards + 1,
            sizeof(*options->remote_forwards));
        fwd = &options->remote_forwards[options->num_remote_forwards++];
@@ -492,7 +494,6 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw,
        char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria;
        const char *ruser;
        int r, port, this_result, result = 1, attributes = 0, negate;
-       size_t len;
        char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
 
        /*
@@ -545,25 +546,24 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw,
                        result = -1;
                        goto out;
                }
-               len = strlen(arg);
                if (strcasecmp(attrib, "host") == 0) {
                        criteria = xstrdup(host);
-                       r = match_hostname(host, arg, len) == 1;
+                       r = match_hostname(host, arg) == 1;
                        if (r == (negate ? 1 : 0))
                                this_result = result = 0;
                } else if (strcasecmp(attrib, "originalhost") == 0) {
                        criteria = xstrdup(original_host);
-                       r = match_hostname(original_host, arg, len) == 1;
+                       r = match_hostname(original_host, arg) == 1;
                        if (r == (negate ? 1 : 0))
                                this_result = result = 0;
                } else if (strcasecmp(attrib, "user") == 0) {
                        criteria = xstrdup(ruser);
-                       r = match_pattern_list(ruser, arg, len, 0) == 1;
+                       r = match_pattern_list(ruser, arg, 0) == 1;
                        if (r == (negate ? 1 : 0))
                                this_result = result = 0;
                } else if (strcasecmp(attrib, "localuser") == 0) {
                        criteria = xstrdup(pw->pw_name);
-                       r = match_pattern_list(pw->pw_name, arg, len, 0) == 1;
+                       r = match_pattern_list(pw->pw_name, arg, 0) == 1;
                        if (r == (negate ? 1 : 0))
                                this_result = result = 0;
                } else if (strcasecmp(attrib, "exec") == 0) {
@@ -665,8 +665,8 @@ parse_token(const char *cp, const char *filename, int linenum,
        for (i = 0; keywords[i].name; i++)
                if (strcmp(cp, keywords[i].name) == 0)
                        return keywords[i].opcode;
-       if (ignored_unknown != NULL && match_pattern_list(cp, ignored_unknown,
-           strlen(ignored_unknown), 1) == 1)
+       if (ignored_unknown != NULL &&
+           match_pattern_list(cp, ignored_unknown, 1) == 1)
                return oIgnoredUnknownOption;
        error("%s: line %d: Bad configuration option: %s",
            filename, linenum, cp);
@@ -763,7 +763,9 @@ process_config_line(Options *options, struct passwd *pw, const char *host,
        }
 
        /* Strip trailing whitespace */
-       for (len = strlen(line) - 1; len > 0; len--) {
+       if ((len = strlen(line)) == 0)
+               return 0;
+       for (len--; len > 0; len--) {
                if (strchr(WHITESPACE, line[len]) == NULL)
                        break;
                line[len] = '\0';
@@ -1084,7 +1086,7 @@ parse_int:
                arg = strdelim(&s);
                if (!arg || *arg == '\0')
                        fatal("%.200s line %d: Missing argument.", filename, linenum);
-               if (!ciphers_valid(arg))
+               if (!ciphers_valid(*arg == '+' ? arg + 1 : arg))
                        fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
                            filename, linenum, arg ? arg : "<NONE>");
                if (*activep && options->ciphers == NULL)
@@ -1095,7 +1097,7 @@ parse_int:
                arg = strdelim(&s);
                if (!arg || *arg == '\0')
                        fatal("%.200s line %d: Missing argument.", filename, linenum);
-               if (!mac_valid(arg))
+               if (!mac_valid(*arg == '+' ? arg + 1 : arg))
                        fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
                            filename, linenum, arg ? arg : "<NONE>");
                if (*activep && options->macs == NULL)
@@ -1107,7 +1109,7 @@ parse_int:
                if (!arg || *arg == '\0')
                        fatal("%.200s line %d: Missing argument.",
                            filename, linenum);
-               if (!kex_names_valid(arg))
+               if (!kex_names_valid(*arg == '+' ? arg + 1 : arg))
                        fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
                            filename, linenum, arg ? arg : "<NONE>");
                if (*activep && options->kex_algorithms == NULL)
@@ -1115,14 +1117,17 @@ parse_int:
                break;
 
        case oHostKeyAlgorithms:
+               charptr = &options->hostkeyalgorithms;
+parse_keytypes:
                arg = strdelim(&s);
                if (!arg || *arg == '\0')
-                       fatal("%.200s line %d: Missing argument.", filename, linenum);
-               if (!sshkey_names_valid2(arg, 1))
-                       fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
-                           filename, linenum, arg ? arg : "<NONE>");
-               if (*activep && options->hostkeyalgorithms == NULL)
-                       options->hostkeyalgorithms = xstrdup(arg);
+                       fatal("%.200s line %d: Missing argument.",
+                           filename, linenum);
+               if (!sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1))
+                       fatal("%s line %d: Bad key types '%s'.",
+                               filename, linenum, arg ? arg : "<NONE>");
+               if (*activep && *charptr == NULL)
+                       *charptr = xstrdup(arg);
                break;
 
        case oProtocol:
@@ -1236,13 +1241,13 @@ parse_int:
                arg = strdelim(&s);
                if (!arg || *arg == '\0')
                        fatal("%.200s line %d: Missing argument.", filename, linenum);
-               if (arg[0] == '^' && arg[2] == 0 &&
+               if (strcmp(arg, "none") == 0)
+                       value = SSH_ESCAPECHAR_NONE;
+               else if (arg[1] == '\0')
+                       value = (u_char) arg[0];
+               else if (arg[0] == '^' && arg[2] == 0 &&
                    (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
                        value = (u_char) arg[1] & 31;
-               else if (strlen(arg) == 1)
-                       value = (u_char) arg[0];
-               else if (strcmp(arg, "none") == 0)
-                       value = SSH_ESCAPECHAR_NONE;
                else {
                        fatal("%.200s line %d: Bad escape character.",
                            filename, linenum);
@@ -1485,16 +1490,11 @@ parse_int:
 
        case oHostbasedKeyTypes:
                charptr = &options->hostbased_key_types;
-               arg = strdelim(&s);
-               if (!arg || *arg == '\0')
-                       fatal("%.200s line %d: Missing argument.",
-                           filename, linenum);
-               if (!sshkey_names_valid2(arg, 1))
-                       fatal("%s line %d: Bad key types '%s'.",
-                               filename, linenum, arg ? arg : "<NONE>");
-               if (*activep && *charptr == NULL)
-                       *charptr = xstrdup(arg);
-               break;
+               goto parse_keytypes;
+
+       case oPubkeyAcceptedKeyTypes:
+               charptr = &options->pubkey_key_types;
+               goto parse_keytypes;
 
        case oDeprecated:
                debug("%s line %d: Deprecated option \"%s\"",
@@ -1676,6 +1676,7 @@ initialize_options(Options * options)
        options->fingerprint_hash = -1;
        options->update_hostkeys = -1;
        options->hostbased_key_types = NULL;
+       options->pubkey_key_types = NULL;
 }
 
 /*
@@ -1761,9 +1762,6 @@ fill_default_options(Options * options)
        /* Selected in ssh_login(). */
        if (options->cipher == -1)
                options->cipher = SSH_CIPHER_NOT_SET;
-       /* options->ciphers, default set in myproposals.h */
-       /* options->macs, default set in myproposals.h */
-       /* options->kex_algorithms, default set in myproposals.h */
        /* options->hostkeyalgorithms, default set in myproposals.h */
        if (options->protocol == SSH_PROTO_UNKNOWN)
                options->protocol = SSH_PROTO_2;
@@ -1856,8 +1854,14 @@ fill_default_options(Options * options)
                options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
        if (options->update_hostkeys == -1)
                options->update_hostkeys = 0;
-       if (options->hostbased_key_types == NULL)
-               options->hostbased_key_types = xstrdup("*");
+       if (kex_assemble_names(KEX_CLIENT_ENCRYPT, &options->ciphers) != 0 ||
+           kex_assemble_names(KEX_CLIENT_MAC, &options->macs) != 0 ||
+           kex_assemble_names(KEX_CLIENT_KEX, &options->kex_algorithms) != 0 ||
+           kex_assemble_names(KEX_DEFAULT_PK_ALG,
+           &options->hostbased_key_types) != 0 ||
+           kex_assemble_names(KEX_DEFAULT_PK_ALG,
+           &options->pubkey_key_types) != 0)
+               fatal("%s: kex_assemble_names failed", __func__);
 
 #define CLEAR_ON_NONE(v) \
        do { \
@@ -1926,7 +1930,8 @@ parse_fwd_field(char **p, struct fwdarg *fwd)
                switch (*cp) {
                case '\\':
                        memmove(cp, cp + 1, strlen(cp + 1) + 1);
-                       cp++;
+                       if (*cp == '\0')
+                               return -1;
                        break;
                case '/':
                        ispath = 1;