[BACK]Return to auth-options.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Annotation of src/usr.bin/ssh/auth-options.c, Revision 1.2.2.4

1.2.2.2   jason       1: /*
                      2:  * Author: Tatu Ylonen <ylo@cs.hut.fi>
                      3:  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
                      4:  *                    All rights reserved
                      5:  * As far as I am concerned, the code I have written for this software
                      6:  * can be used freely for any purpose.  Any derived versions of this
                      7:  * software must be clearly marked as such, and if the derived work is
                      8:  * incompatible with the protocol description in the RFC file, it must be
                      9:  * called by a name other than "ssh" or "Secure Shell".
                     10:  */
                     11:
1.1       markus     12: #include "includes.h"
1.2.2.4 ! jason      13: RCSID("$OpenBSD: auth-options.c,v 1.16 2001/03/18 12:07:52 markus Exp $");
1.1       markus     14:
                     15: #include "packet.h"
                     16: #include "xmalloc.h"
                     17: #include "match.h"
1.2.2.3   jason      18: #include "log.h"
                     19: #include "canohost.h"
1.2.2.4 ! jason      20: #include "channels.h"
1.2.2.3   jason      21: #include "auth-options.h"
                     22: #include "servconf.h"
1.1       markus     23:
                     24: /* Flags set authorized_keys flags */
                     25: int no_port_forwarding_flag = 0;
                     26: int no_agent_forwarding_flag = 0;
                     27: int no_x11_forwarding_flag = 0;
                     28: int no_pty_flag = 0;
                     29:
                     30: /* "command=" option. */
                     31: char *forced_command = NULL;
                     32:
                     33: /* "environment=" options. */
                     34: struct envstring *custom_environment = NULL;
                     35:
1.2.2.3   jason      36: extern ServerOptions options;
                     37:
1.2.2.2   jason      38: void
                     39: auth_clear_options(void)
                     40: {
                     41:        no_agent_forwarding_flag = 0;
                     42:        no_port_forwarding_flag = 0;
                     43:        no_pty_flag = 0;
                     44:        no_x11_forwarding_flag = 0;
                     45:        while (custom_environment) {
                     46:                struct envstring *ce = custom_environment;
                     47:                custom_environment = ce->next;
                     48:                xfree(ce->s);
                     49:                xfree(ce);
                     50:        }
                     51:        if (forced_command) {
                     52:                xfree(forced_command);
                     53:                forced_command = NULL;
                     54:        }
1.2.2.4 ! jason      55:        channel_clear_permitted_opens();
1.2.2.2   jason      56: }
                     57:
1.2.2.3   jason      58: /*
                     59:  * return 1 if access is granted, 0 if not.
                     60:  * side effect: sets key option flags
                     61:  */
1.1       markus     62: int
1.2.2.3   jason      63: auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
1.1       markus     64: {
                     65:        const char *cp;
1.2.2.4 ! jason      66:        int i;
1.2.2.2   jason      67:
                     68:        /* reset options */
                     69:        auth_clear_options();
                     70:
1.2.2.3   jason      71:        if (!opts)
                     72:                return 1;
                     73:
                     74:        while (*opts && *opts != ' ' && *opts != '\t') {
1.1       markus     75:                cp = "no-port-forwarding";
1.2.2.3   jason      76:                if (strncasecmp(opts, cp, strlen(cp)) == 0) {
1.1       markus     77:                        packet_send_debug("Port forwarding disabled.");
                     78:                        no_port_forwarding_flag = 1;
1.2.2.3   jason      79:                        opts += strlen(cp);
1.1       markus     80:                        goto next_option;
                     81:                }
                     82:                cp = "no-agent-forwarding";
1.2.2.3   jason      83:                if (strncasecmp(opts, cp, strlen(cp)) == 0) {
1.1       markus     84:                        packet_send_debug("Agent forwarding disabled.");
                     85:                        no_agent_forwarding_flag = 1;
1.2.2.3   jason      86:                        opts += strlen(cp);
1.1       markus     87:                        goto next_option;
                     88:                }
                     89:                cp = "no-X11-forwarding";
1.2.2.3   jason      90:                if (strncasecmp(opts, cp, strlen(cp)) == 0) {
1.1       markus     91:                        packet_send_debug("X11 forwarding disabled.");
                     92:                        no_x11_forwarding_flag = 1;
1.2.2.3   jason      93:                        opts += strlen(cp);
1.1       markus     94:                        goto next_option;
                     95:                }
                     96:                cp = "no-pty";
1.2.2.3   jason      97:                if (strncasecmp(opts, cp, strlen(cp)) == 0) {
1.1       markus     98:                        packet_send_debug("Pty allocation disabled.");
                     99:                        no_pty_flag = 1;
1.2.2.3   jason     100:                        opts += strlen(cp);
1.1       markus    101:                        goto next_option;
                    102:                }
                    103:                cp = "command=\"";
1.2.2.3   jason     104:                if (strncasecmp(opts, cp, strlen(cp)) == 0) {
                    105:                        opts += strlen(cp);
                    106:                        forced_command = xmalloc(strlen(opts) + 1);
1.1       markus    107:                        i = 0;
1.2.2.3   jason     108:                        while (*opts) {
                    109:                                if (*opts == '"')
1.1       markus    110:                                        break;
1.2.2.3   jason     111:                                if (*opts == '\\' && opts[1] == '"') {
                    112:                                        opts += 2;
1.1       markus    113:                                        forced_command[i++] = '"';
                    114:                                        continue;
                    115:                                }
1.2.2.3   jason     116:                                forced_command[i++] = *opts++;
1.1       markus    117:                        }
1.2.2.3   jason     118:                        if (!*opts) {
1.1       markus    119:                                debug("%.100s, line %lu: missing end quote",
1.2.2.3   jason     120:                                    file, linenum);
1.1       markus    121:                                packet_send_debug("%.100s, line %lu: missing end quote",
1.2.2.3   jason     122:                                    file, linenum);
1.2.2.4 ! jason     123:                                xfree(forced_command);
        !           124:                                forced_command = NULL;
        !           125:                                goto bad_option;
1.1       markus    126:                        }
                    127:                        forced_command[i] = 0;
                    128:                        packet_send_debug("Forced command: %.900s", forced_command);
1.2.2.3   jason     129:                        opts++;
1.1       markus    130:                        goto next_option;
                    131:                }
                    132:                cp = "environment=\"";
1.2.2.3   jason     133:                if (strncasecmp(opts, cp, strlen(cp)) == 0) {
1.1       markus    134:                        char *s;
                    135:                        struct envstring *new_envstring;
1.2.2.4 ! jason     136:
1.2.2.3   jason     137:                        opts += strlen(cp);
                    138:                        s = xmalloc(strlen(opts) + 1);
1.1       markus    139:                        i = 0;
1.2.2.3   jason     140:                        while (*opts) {
                    141:                                if (*opts == '"')
1.1       markus    142:                                        break;
1.2.2.3   jason     143:                                if (*opts == '\\' && opts[1] == '"') {
                    144:                                        opts += 2;
1.1       markus    145:                                        s[i++] = '"';
                    146:                                        continue;
                    147:                                }
1.2.2.3   jason     148:                                s[i++] = *opts++;
1.1       markus    149:                        }
1.2.2.3   jason     150:                        if (!*opts) {
1.1       markus    151:                                debug("%.100s, line %lu: missing end quote",
1.2.2.3   jason     152:                                    file, linenum);
1.1       markus    153:                                packet_send_debug("%.100s, line %lu: missing end quote",
1.2.2.3   jason     154:                                    file, linenum);
1.2.2.4 ! jason     155:                                xfree(s);
        !           156:                                goto bad_option;
1.1       markus    157:                        }
                    158:                        s[i] = 0;
                    159:                        packet_send_debug("Adding to environment: %.900s", s);
                    160:                        debug("Adding to environment: %.900s", s);
1.2.2.3   jason     161:                        opts++;
1.1       markus    162:                        new_envstring = xmalloc(sizeof(struct envstring));
                    163:                        new_envstring->s = s;
                    164:                        new_envstring->next = custom_environment;
                    165:                        custom_environment = new_envstring;
                    166:                        goto next_option;
                    167:                }
                    168:                cp = "from=\"";
1.2.2.3   jason     169:                if (strncasecmp(opts, cp, strlen(cp)) == 0) {
1.1       markus    170:                        int mname, mip;
1.2.2.3   jason     171:                        const char *remote_ip = get_remote_ipaddr();
                    172:                        const char *remote_host = get_canonical_hostname(
                    173:                            options.reverse_mapping_check);
                    174:                        char *patterns = xmalloc(strlen(opts) + 1);
1.2.2.4 ! jason     175:
1.2.2.3   jason     176:                        opts += strlen(cp);
1.1       markus    177:                        i = 0;
1.2.2.3   jason     178:                        while (*opts) {
                    179:                                if (*opts == '"')
1.1       markus    180:                                        break;
1.2.2.3   jason     181:                                if (*opts == '\\' && opts[1] == '"') {
                    182:                                        opts += 2;
1.1       markus    183:                                        patterns[i++] = '"';
                    184:                                        continue;
                    185:                                }
1.2.2.3   jason     186:                                patterns[i++] = *opts++;
1.1       markus    187:                        }
1.2.2.3   jason     188:                        if (!*opts) {
1.1       markus    189:                                debug("%.100s, line %lu: missing end quote",
1.2.2.3   jason     190:                                    file, linenum);
1.1       markus    191:                                packet_send_debug("%.100s, line %lu: missing end quote",
1.2.2.3   jason     192:                                    file, linenum);
1.2.2.4 ! jason     193:                                xfree(patterns);
        !           194:                                goto bad_option;
1.1       markus    195:                        }
                    196:                        patterns[i] = 0;
1.2.2.3   jason     197:                        opts++;
1.1       markus    198:                        /*
                    199:                         * Deny access if we get a negative
                    200:                         * match for the hostname or the ip
                    201:                         * or if we get not match at all
                    202:                         */
1.2.2.3   jason     203:                        mname = match_hostname(remote_host, patterns,
                    204:                            strlen(patterns));
                    205:                        mip = match_hostname(remote_ip, patterns,
                    206:                            strlen(patterns));
1.1       markus    207:                        xfree(patterns);
                    208:                        if (mname == -1 || mip == -1 ||
                    209:                            (mname != 1 && mip != 1)) {
1.2.2.3   jason     210:                                log("Authentication tried for %.100s with "
                    211:                                    "correct key but not from a permitted "
                    212:                                    "host (host=%.200s, ip=%.200s).",
                    213:                                    pw->pw_name, remote_host, remote_ip);
                    214:                                packet_send_debug("Your host '%.200s' is not "
                    215:                                    "permitted to use this key for login.",
                    216:                                    remote_host);
1.1       markus    217:                                /* deny access */
                    218:                                return 0;
                    219:                        }
                    220:                        /* Host name matches. */
1.2.2.4 ! jason     221:                        goto next_option;
        !           222:                }
        !           223:                cp = "permitopen=\"";
        !           224:                if (strncasecmp(opts, cp, strlen(cp)) == 0) {
        !           225:                        u_short port;
        !           226:                        char *c, *ep;
        !           227:                        char *patterns = xmalloc(strlen(opts) + 1);
        !           228:
        !           229:                        opts += strlen(cp);
        !           230:                        i = 0;
        !           231:                        while (*opts) {
        !           232:                                if (*opts == '"')
        !           233:                                        break;
        !           234:                                if (*opts == '\\' && opts[1] == '"') {
        !           235:                                        opts += 2;
        !           236:                                        patterns[i++] = '"';
        !           237:                                        continue;
        !           238:                                }
        !           239:                                patterns[i++] = *opts++;
        !           240:                        }
        !           241:                        if (!*opts) {
        !           242:                                debug("%.100s, line %lu: missing end quote",
        !           243:                                    file, linenum);
        !           244:                                packet_send_debug("%.100s, line %lu: missing end quote",
        !           245:                                    file, linenum);
        !           246:                                xfree(patterns);
        !           247:                                goto bad_option;
        !           248:                        }
        !           249:                        patterns[i] = 0;
        !           250:                        opts++;
        !           251:                        c = strchr(patterns, ':');
        !           252:                        if (c == NULL) {
        !           253:                                debug("%.100s, line %lu: permitopen: missing colon <%.100s>",
        !           254:                                    file, linenum, patterns);
        !           255:                                packet_send_debug("%.100s, line %lu: missing colon",
        !           256:                                    file, linenum);
        !           257:                                xfree(patterns);
        !           258:                                goto bad_option;
        !           259:                        }
        !           260:                        *c = 0;
        !           261:                        c++;
        !           262:                        port = strtol(c, &ep, 0);
        !           263:                        if (c == ep) {
        !           264:                                debug("%.100s, line %lu: permitopen: missing port <%.100s>",
        !           265:                                    file, linenum, patterns);
        !           266:                                packet_send_debug("%.100s, line %lu: missing port",
        !           267:                                    file, linenum);
        !           268:                                xfree(patterns);
        !           269:                                goto bad_option;
        !           270:                        }
        !           271:                        if (options.allow_tcp_forwarding)
        !           272:                                channel_add_permitted_opens(patterns, port);
        !           273:                        xfree(patterns);
1.1       markus    274:                        goto next_option;
                    275:                }
                    276: next_option:
                    277:                /*
                    278:                 * Skip the comma, and move to the next option
                    279:                 * (or break out if there are no more).
                    280:                 */
1.2.2.3   jason     281:                if (!*opts)
1.1       markus    282:                        fatal("Bugs in auth-options.c option processing.");
1.2.2.3   jason     283:                if (*opts == ' ' || *opts == '\t')
1.1       markus    284:                        break;          /* End of options. */
1.2.2.3   jason     285:                if (*opts != ',')
1.1       markus    286:                        goto bad_option;
1.2.2.3   jason     287:                opts++;
1.1       markus    288:                /* Process the next option. */
                    289:        }
                    290:        /* grant access */
                    291:        return 1;
                    292:
                    293: bad_option:
                    294:        log("Bad options in %.100s file, line %lu: %.50s",
1.2.2.3   jason     295:            file, linenum, opts);
1.1       markus    296:        packet_send_debug("Bad options in %.100s file, line %lu: %.50s",
1.2.2.3   jason     297:            file, linenum, opts);
1.1       markus    298:        /* deny access */
                    299:        return 0;
                    300: }