]> andersk Git - openssh.git/blob - servconf.c
- dtucker@cvs.openbsd.org 2008/06/10 04:50:25
[openssh.git] / servconf.c
1 /* $OpenBSD: servconf.c,v 1.182 2008/06/10 04:50:25 dtucker Exp $ */
2 /*
3  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4  *                    All rights reserved
5  *
6  * As far as I am concerned, the code I have written for this software
7  * can be used freely for any purpose.  Any derived versions of this
8  * software must be clearly marked as such, and if the derived work is
9  * incompatible with the protocol description in the RFC file, it must be
10  * called by a name other than "ssh" or "Secure Shell".
11  */
12
13 #include "includes.h"
14
15 #include <sys/types.h>
16 #include <sys/socket.h>
17
18 #include <netdb.h>
19 #include <pwd.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <signal.h>
24 #include <unistd.h>
25 #include <stdarg.h>
26 #include <errno.h>
27
28 #include "openbsd-compat/sys-queue.h"
29 #include "xmalloc.h"
30 #include "ssh.h"
31 #include "log.h"
32 #include "buffer.h"
33 #include "servconf.h"
34 #include "compat.h"
35 #include "pathnames.h"
36 #include "misc.h"
37 #include "cipher.h"
38 #include "key.h"
39 #include "kex.h"
40 #include "mac.h"
41 #include "match.h"
42 #include "channels.h"
43 #include "groupaccess.h"
44
45 static void add_listen_addr(ServerOptions *, char *, u_short);
46 static void add_one_listen_addr(ServerOptions *, char *, u_short);
47
48 /* Use of privilege separation or not */
49 extern int use_privsep;
50 extern Buffer cfg;
51
52 /* Initializes the server options to their default values. */
53
54 void
55 initialize_server_options(ServerOptions *options)
56 {
57         memset(options, 0, sizeof(*options));
58
59         /* Portable-specific options */
60         options->use_pam = -1;
61
62         /* Standard Options */
63         options->num_ports = 0;
64         options->ports_from_cmdline = 0;
65         options->listen_addrs = NULL;
66         options->address_family = -1;
67         options->num_host_key_files = 0;
68         options->pid_file = NULL;
69         options->server_key_bits = -1;
70         options->login_grace_time = -1;
71         options->key_regeneration_time = -1;
72         options->permit_root_login = PERMIT_NOT_SET;
73         options->ignore_rhosts = -1;
74         options->ignore_user_known_hosts = -1;
75         options->print_motd = -1;
76         options->print_lastlog = -1;
77         options->x11_forwarding = -1;
78         options->x11_display_offset = -1;
79         options->x11_use_localhost = -1;
80         options->xauth_location = NULL;
81         options->strict_modes = -1;
82         options->tcp_keep_alive = -1;
83         options->log_facility = SYSLOG_FACILITY_NOT_SET;
84         options->log_level = SYSLOG_LEVEL_NOT_SET;
85         options->rhosts_rsa_authentication = -1;
86         options->hostbased_authentication = -1;
87         options->hostbased_uses_name_from_packet_only = -1;
88         options->rsa_authentication = -1;
89         options->pubkey_authentication = -1;
90         options->kerberos_authentication = -1;
91         options->kerberos_or_local_passwd = -1;
92         options->kerberos_ticket_cleanup = -1;
93         options->kerberos_get_afs_token = -1;
94         options->gss_authentication=-1;
95         options->gss_cleanup_creds = -1;
96         options->password_authentication = -1;
97         options->kbd_interactive_authentication = -1;
98         options->challenge_response_authentication = -1;
99         options->permit_empty_passwd = -1;
100         options->permit_user_env = -1;
101         options->use_login = -1;
102         options->compression = -1;
103         options->allow_tcp_forwarding = -1;
104         options->allow_agent_forwarding = -1;
105         options->num_allow_users = 0;
106         options->num_deny_users = 0;
107         options->num_allow_groups = 0;
108         options->num_deny_groups = 0;
109         options->ciphers = NULL;
110         options->macs = NULL;
111         options->protocol = SSH_PROTO_UNKNOWN;
112         options->gateway_ports = -1;
113         options->num_subsystems = 0;
114         options->max_startups_begin = -1;
115         options->max_startups_rate = -1;
116         options->max_startups = -1;
117         options->max_authtries = -1;
118         options->max_sessions = -1;
119         options->banner = NULL;
120         options->use_dns = -1;
121         options->client_alive_interval = -1;
122         options->client_alive_count_max = -1;
123         options->authorized_keys_file = NULL;
124         options->authorized_keys_file2 = NULL;
125         options->num_accept_env = 0;
126         options->permit_tun = -1;
127         options->num_permitted_opens = -1;
128         options->adm_forced_command = NULL;
129         options->chroot_directory = NULL;
130 }
131
132 void
133 fill_default_server_options(ServerOptions *options)
134 {
135         /* Portable-specific options */
136         if (options->use_pam == -1)
137                 options->use_pam = 0;
138
139         /* Standard Options */
140         if (options->protocol == SSH_PROTO_UNKNOWN)
141                 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
142         if (options->num_host_key_files == 0) {
143                 /* fill default hostkeys for protocols */
144                 if (options->protocol & SSH_PROTO_1)
145                         options->host_key_files[options->num_host_key_files++] =
146                             _PATH_HOST_KEY_FILE;
147                 if (options->protocol & SSH_PROTO_2) {
148                         options->host_key_files[options->num_host_key_files++] =
149                             _PATH_HOST_RSA_KEY_FILE;
150                         options->host_key_files[options->num_host_key_files++] =
151                             _PATH_HOST_DSA_KEY_FILE;
152                 }
153         }
154         if (options->num_ports == 0)
155                 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
156         if (options->listen_addrs == NULL)
157                 add_listen_addr(options, NULL, 0);
158         if (options->pid_file == NULL)
159                 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
160         if (options->server_key_bits == -1)
161                 options->server_key_bits = 768;
162         if (options->login_grace_time == -1)
163                 options->login_grace_time = 120;
164         if (options->key_regeneration_time == -1)
165                 options->key_regeneration_time = 3600;
166         if (options->permit_root_login == PERMIT_NOT_SET)
167                 options->permit_root_login = PERMIT_YES;
168         if (options->ignore_rhosts == -1)
169                 options->ignore_rhosts = 1;
170         if (options->ignore_user_known_hosts == -1)
171                 options->ignore_user_known_hosts = 0;
172         if (options->print_motd == -1)
173                 options->print_motd = 1;
174         if (options->print_lastlog == -1)
175                 options->print_lastlog = 1;
176         if (options->x11_forwarding == -1)
177                 options->x11_forwarding = 0;
178         if (options->x11_display_offset == -1)
179                 options->x11_display_offset = 10;
180         if (options->x11_use_localhost == -1)
181                 options->x11_use_localhost = 1;
182         if (options->xauth_location == NULL)
183                 options->xauth_location = _PATH_XAUTH;
184         if (options->strict_modes == -1)
185                 options->strict_modes = 1;
186         if (options->tcp_keep_alive == -1)
187                 options->tcp_keep_alive = 1;
188         if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
189                 options->log_facility = SYSLOG_FACILITY_AUTH;
190         if (options->log_level == SYSLOG_LEVEL_NOT_SET)
191                 options->log_level = SYSLOG_LEVEL_INFO;
192         if (options->rhosts_rsa_authentication == -1)
193                 options->rhosts_rsa_authentication = 0;
194         if (options->hostbased_authentication == -1)
195                 options->hostbased_authentication = 0;
196         if (options->hostbased_uses_name_from_packet_only == -1)
197                 options->hostbased_uses_name_from_packet_only = 0;
198         if (options->rsa_authentication == -1)
199                 options->rsa_authentication = 1;
200         if (options->pubkey_authentication == -1)
201                 options->pubkey_authentication = 1;
202         if (options->kerberos_authentication == -1)
203                 options->kerberos_authentication = 0;
204         if (options->kerberos_or_local_passwd == -1)
205                 options->kerberos_or_local_passwd = 1;
206         if (options->kerberos_ticket_cleanup == -1)
207                 options->kerberos_ticket_cleanup = 1;
208         if (options->kerberos_get_afs_token == -1)
209                 options->kerberos_get_afs_token = 0;
210         if (options->gss_authentication == -1)
211                 options->gss_authentication = 0;
212         if (options->gss_cleanup_creds == -1)
213                 options->gss_cleanup_creds = 1;
214         if (options->password_authentication == -1)
215                 options->password_authentication = 1;
216         if (options->kbd_interactive_authentication == -1)
217                 options->kbd_interactive_authentication = 0;
218         if (options->challenge_response_authentication == -1)
219                 options->challenge_response_authentication = 1;
220         if (options->permit_empty_passwd == -1)
221                 options->permit_empty_passwd = 0;
222         if (options->permit_user_env == -1)
223                 options->permit_user_env = 0;
224         if (options->use_login == -1)
225                 options->use_login = 0;
226         if (options->compression == -1)
227                 options->compression = COMP_DELAYED;
228         if (options->allow_tcp_forwarding == -1)
229                 options->allow_tcp_forwarding = 1;
230         if (options->allow_agent_forwarding == -1)
231                 options->allow_agent_forwarding = 1;
232         if (options->gateway_ports == -1)
233                 options->gateway_ports = 0;
234         if (options->max_startups == -1)
235                 options->max_startups = 10;
236         if (options->max_startups_rate == -1)
237                 options->max_startups_rate = 100;               /* 100% */
238         if (options->max_startups_begin == -1)
239                 options->max_startups_begin = options->max_startups;
240         if (options->max_authtries == -1)
241                 options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
242         if (options->max_sessions == -1)
243                 options->max_sessions = DEFAULT_SESSIONS_MAX;
244         if (options->use_dns == -1)
245                 options->use_dns = 1;
246         if (options->client_alive_interval == -1)
247                 options->client_alive_interval = 0;
248         if (options->client_alive_count_max == -1)
249                 options->client_alive_count_max = 3;
250         if (options->authorized_keys_file2 == NULL) {
251                 /* authorized_keys_file2 falls back to authorized_keys_file */
252                 if (options->authorized_keys_file != NULL)
253                         options->authorized_keys_file2 = options->authorized_keys_file;
254                 else
255                         options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
256         }
257         if (options->authorized_keys_file == NULL)
258                 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
259         if (options->permit_tun == -1)
260                 options->permit_tun = SSH_TUNMODE_NO;
261
262         /* Turn privilege separation on by default */
263         if (use_privsep == -1)
264                 use_privsep = 1;
265
266 #ifndef HAVE_MMAP
267         if (use_privsep && options->compression == 1) {
268                 error("This platform does not support both privilege "
269                     "separation and compression");
270                 error("Compression disabled");
271                 options->compression = 0;
272         }
273 #endif
274
275 }
276
277 /* Keyword tokens. */
278 typedef enum {
279         sBadOption,             /* == unknown option */
280         /* Portable-specific options */
281         sUsePAM,
282         /* Standard Options */
283         sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
284         sPermitRootLogin, sLogFacility, sLogLevel,
285         sRhostsRSAAuthentication, sRSAAuthentication,
286         sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
287         sKerberosGetAFSToken,
288         sKerberosTgtPassing, sChallengeResponseAuthentication,
289         sPasswordAuthentication, sKbdInteractiveAuthentication,
290         sListenAddress, sAddressFamily,
291         sPrintMotd, sPrintLastLog, sIgnoreRhosts,
292         sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
293         sStrictModes, sEmptyPasswd, sTCPKeepAlive,
294         sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
295         sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
296         sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
297         sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
298         sMaxStartups, sMaxAuthTries, sMaxSessions,
299         sBanner, sUseDNS, sHostbasedAuthentication,
300         sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
301         sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
302         sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
303         sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
304         sUsePrivilegeSeparation, sAllowAgentForwarding,
305         sDeprecated, sUnsupported
306 } ServerOpCodes;
307
308 #define SSHCFG_GLOBAL   0x01    /* allowed in main section of sshd_config */
309 #define SSHCFG_MATCH    0x02    /* allowed inside a Match section */
310 #define SSHCFG_ALL      (SSHCFG_GLOBAL|SSHCFG_MATCH)
311
312 /* Textual representation of the tokens. */
313 static struct {
314         const char *name;
315         ServerOpCodes opcode;
316         u_int flags;
317 } keywords[] = {
318         /* Portable-specific options */
319 #ifdef USE_PAM
320         { "usepam", sUsePAM, SSHCFG_GLOBAL },
321 #else
322         { "usepam", sUnsupported, SSHCFG_GLOBAL },
323 #endif
324         { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
325         /* Standard Options */
326         { "port", sPort, SSHCFG_GLOBAL },
327         { "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
328         { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL },          /* alias */
329         { "pidfile", sPidFile, SSHCFG_GLOBAL },
330         { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
331         { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
332         { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
333         { "permitrootlogin", sPermitRootLogin, SSHCFG_ALL },
334         { "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
335         { "loglevel", sLogLevel, SSHCFG_GLOBAL },
336         { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
337         { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_ALL },
338         { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL },
339         { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_GLOBAL },
340         { "rsaauthentication", sRSAAuthentication, SSHCFG_ALL },
341         { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
342         { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL },  /* alias */
343 #ifdef KRB5
344         { "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL },
345         { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
346         { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
347 #ifdef USE_AFS
348         { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
349 #else
350         { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
351 #endif
352 #else
353         { "kerberosauthentication", sUnsupported, SSHCFG_ALL },
354         { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
355         { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
356         { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
357 #endif
358         { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
359         { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
360 #ifdef GSSAPI
361         { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
362         { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
363 #else
364         { "gssapiauthentication", sUnsupported, SSHCFG_ALL },
365         { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
366 #endif
367         { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
368         { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
369         { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
370         { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
371         { "checkmail", sDeprecated, SSHCFG_GLOBAL },
372         { "listenaddress", sListenAddress, SSHCFG_GLOBAL },
373         { "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
374         { "printmotd", sPrintMotd, SSHCFG_GLOBAL },
375         { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
376         { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
377         { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
378         { "x11forwarding", sX11Forwarding, SSHCFG_ALL },
379         { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
380         { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
381         { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
382         { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
383         { "permitemptypasswords", sEmptyPasswd, SSHCFG_GLOBAL },
384         { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
385         { "uselogin", sUseLogin, SSHCFG_GLOBAL },
386         { "compression", sCompression, SSHCFG_GLOBAL },
387         { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
388         { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL },  /* obsolete alias */
389         { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
390         { "allowagentforwarding", sAllowAgentForwarding, SSHCFG_ALL },
391         { "allowusers", sAllowUsers, SSHCFG_GLOBAL },
392         { "denyusers", sDenyUsers, SSHCFG_GLOBAL },
393         { "allowgroups", sAllowGroups, SSHCFG_GLOBAL },
394         { "denygroups", sDenyGroups, SSHCFG_GLOBAL },
395         { "ciphers", sCiphers, SSHCFG_GLOBAL },
396         { "macs", sMacs, SSHCFG_GLOBAL },
397         { "protocol", sProtocol, SSHCFG_GLOBAL },
398         { "gatewayports", sGatewayPorts, SSHCFG_ALL },
399         { "subsystem", sSubsystem, SSHCFG_GLOBAL },
400         { "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
401         { "maxauthtries", sMaxAuthTries, SSHCFG_GLOBAL },
402         { "maxsessions", sMaxSessions, SSHCFG_ALL },
403         { "banner", sBanner, SSHCFG_ALL },
404         { "usedns", sUseDNS, SSHCFG_GLOBAL },
405         { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
406         { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
407         { "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL },
408         { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
409         { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
410         { "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
411         { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL },
412         { "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
413         { "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
414         { "match", sMatch, SSHCFG_ALL },
415         { "permitopen", sPermitOpen, SSHCFG_ALL },
416         { "forcecommand", sForceCommand, SSHCFG_ALL },
417         { "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
418         { NULL, sBadOption, 0 }
419 };
420
421 static struct {
422         int val;
423         char *text;
424 } tunmode_desc[] = {
425         { SSH_TUNMODE_NO, "no" },
426         { SSH_TUNMODE_POINTOPOINT, "point-to-point" },
427         { SSH_TUNMODE_ETHERNET, "ethernet" },
428         { SSH_TUNMODE_YES, "yes" },
429         { -1, NULL }
430 };
431
432 /*
433  * Returns the number of the token pointed to by cp or sBadOption.
434  */
435
436 static ServerOpCodes
437 parse_token(const char *cp, const char *filename,
438             int linenum, u_int *flags)
439 {
440         u_int i;
441
442         for (i = 0; keywords[i].name; i++)
443                 if (strcasecmp(cp, keywords[i].name) == 0) {
444                         *flags = keywords[i].flags;
445                         return keywords[i].opcode;
446                 }
447
448         error("%s: line %d: Bad configuration option: %s",
449             filename, linenum, cp);
450         return sBadOption;
451 }
452
453 static void
454 add_listen_addr(ServerOptions *options, char *addr, u_short port)
455 {
456         u_int i;
457
458         if (options->num_ports == 0)
459                 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
460         if (options->address_family == -1)
461                 options->address_family = AF_UNSPEC;
462         if (port == 0)
463                 for (i = 0; i < options->num_ports; i++)
464                         add_one_listen_addr(options, addr, options->ports[i]);
465         else
466                 add_one_listen_addr(options, addr, port);
467 }
468
469 static void
470 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
471 {
472         struct addrinfo hints, *ai, *aitop;
473         char strport[NI_MAXSERV];
474         int gaierr;
475
476         memset(&hints, 0, sizeof(hints));
477         hints.ai_family = options->address_family;
478         hints.ai_socktype = SOCK_STREAM;
479         hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
480         snprintf(strport, sizeof strport, "%u", port);
481         if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
482                 fatal("bad addr or host: %s (%s)",
483                     addr ? addr : "<NULL>",
484                     ssh_gai_strerror(gaierr));
485         for (ai = aitop; ai->ai_next; ai = ai->ai_next)
486                 ;
487         ai->ai_next = options->listen_addrs;
488         options->listen_addrs = aitop;
489 }
490
491 /*
492  * The strategy for the Match blocks is that the config file is parsed twice.
493  *
494  * The first time is at startup.  activep is initialized to 1 and the
495  * directives in the global context are processed and acted on.  Hitting a
496  * Match directive unsets activep and the directives inside the block are
497  * checked for syntax only.
498  *
499  * The second time is after a connection has been established but before
500  * authentication.  activep is initialized to 2 and global config directives
501  * are ignored since they have already been processed.  If the criteria in a
502  * Match block is met, activep is set and the subsequent directives
503  * processed and actioned until EOF or another Match block unsets it.  Any
504  * options set are copied into the main server config.
505  *
506  * Potential additions/improvements:
507  *  - Add Match support for pre-kex directives, eg Protocol, Ciphers.
508  *
509  *  - Add a Tag directive (idea from David Leonard) ala pf, eg:
510  *      Match Address 192.168.0.*
511  *              Tag trusted
512  *      Match Group wheel
513  *              Tag trusted
514  *      Match Tag trusted
515  *              AllowTcpForwarding yes
516  *              GatewayPorts clientspecified
517  *              [...]
518  *
519  *  - Add a PermittedChannelRequests directive
520  *      Match Group shell
521  *              PermittedChannelRequests session,forwarded-tcpip
522  */
523
524 static int
525 match_cfg_line_group(const char *grps, int line, const char *user)
526 {
527         int result = 0;
528         u_int ngrps = 0;
529         char *arg, *p, *cp, *grplist[MAX_MATCH_GROUPS];
530         struct passwd *pw;
531
532         /*
533          * Even if we do not have a user yet, we still need to check for
534          * valid syntax.
535          */
536         arg = cp = xstrdup(grps);
537         while ((p = strsep(&cp, ",")) != NULL && *p != '\0') {
538                 if (ngrps >= MAX_MATCH_GROUPS) {
539                         error("line %d: too many groups in Match Group", line);
540                         result = -1;
541                         goto out;
542                 }
543                 grplist[ngrps++] = p;
544         }
545
546         if (user == NULL)
547                 goto out;
548
549         if ((pw = getpwnam(user)) == NULL) {
550                 debug("Can't match group at line %d because user %.100s does "
551                     "not exist", line, user);
552         } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
553                 debug("Can't Match group because user %.100s not in any group "
554                     "at line %d", user, line);
555         } else if (ga_match(grplist, ngrps) != 1) {
556                 debug("user %.100s does not match group %.100s at line %d",
557                     user, arg, line);
558         } else {
559                 debug("user %.100s matched group %.100s at line %d", user,
560                     arg, line);
561                 result = 1;
562         }
563 out:
564         ga_free();
565         xfree(arg);
566         return result;
567 }
568
569 static int
570 match_cfg_line(char **condition, int line, const char *user, const char *host,
571     const char *address)
572 {
573         int result = 1;
574         char *arg, *attrib, *cp = *condition;
575         size_t len;
576
577         if (user == NULL)
578                 debug3("checking syntax for 'Match %s'", cp);
579         else
580                 debug3("checking match for '%s' user %s host %s addr %s", cp,
581                     user ? user : "(null)", host ? host : "(null)",
582                     address ? address : "(null)");
583
584         while ((attrib = strdelim(&cp)) && *attrib != '\0') {
585                 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
586                         error("Missing Match criteria for %s", attrib);
587                         return -1;
588                 }
589                 len = strlen(arg);
590                 if (strcasecmp(attrib, "user") == 0) {
591                         if (!user) {
592                                 result = 0;
593                                 continue;
594                         }
595                         if (match_pattern_list(user, arg, len, 0) != 1)
596                                 result = 0;
597                         else
598                                 debug("user %.100s matched 'User %.100s' at "
599                                     "line %d", user, arg, line);
600                 } else if (strcasecmp(attrib, "group") == 0) {
601                         switch (match_cfg_line_group(arg, line, user)) {
602                         case -1:
603                                 return -1;
604                         case 0:
605                                 result = 0;
606                         }
607                 } else if (strcasecmp(attrib, "host") == 0) {
608                         if (!host) {
609                                 result = 0;
610                                 continue;
611                         }
612                         if (match_hostname(host, arg, len) != 1)
613                                 result = 0;
614                         else
615                                 debug("connection from %.100s matched 'Host "
616                                     "%.100s' at line %d", host, arg, line);
617                 } else if (strcasecmp(attrib, "address") == 0) {
618                         switch (addr_match_list(address, arg)) {
619                         case 1:
620                                 debug("connection from %.100s matched 'Address "
621                                     "%.100s' at line %d", address, arg, line);
622                                 break;
623                         case 0:
624                                 result = 0;
625                                 break;
626                         case -1:
627                                 return -1;
628                         }
629                 } else {
630                         error("Unsupported Match attribute %s", attrib);
631                         return -1;
632                 }
633         }
634         if (user != NULL)
635                 debug3("match %sfound", result ? "" : "not ");
636         *condition = cp;
637         return result;
638 }
639
640 #define WHITESPACE " \t\r\n"
641
642 int
643 process_server_config_line(ServerOptions *options, char *line,
644     const char *filename, int linenum, int *activep, const char *user,
645     const char *host, const char *address)
646 {
647         char *cp, **charptr, *arg, *p;
648         int cmdline = 0, *intptr, value, n;
649         SyslogFacility *log_facility_ptr;
650         LogLevel *log_level_ptr;
651         ServerOpCodes opcode;
652         u_short port;
653         u_int i, flags = 0;
654         size_t len;
655
656         cp = line;
657         if ((arg = strdelim(&cp)) == NULL)
658                 return 0;
659         /* Ignore leading whitespace */
660         if (*arg == '\0')
661                 arg = strdelim(&cp);
662         if (!arg || !*arg || *arg == '#')
663                 return 0;
664         intptr = NULL;
665         charptr = NULL;
666         opcode = parse_token(arg, filename, linenum, &flags);
667
668         if (activep == NULL) { /* We are processing a command line directive */
669                 cmdline = 1;
670                 activep = &cmdline;
671         }
672         if (*activep && opcode != sMatch)
673                 debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
674         if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
675                 if (user == NULL) {
676                         fatal("%s line %d: Directive '%s' is not allowed "
677                             "within a Match block", filename, linenum, arg);
678                 } else { /* this is a directive we have already processed */
679                         while (arg)
680                                 arg = strdelim(&cp);
681                         return 0;
682                 }
683         }
684
685         switch (opcode) {
686         /* Portable-specific options */
687         case sUsePAM:
688                 intptr = &options->use_pam;
689                 goto parse_flag;
690
691         /* Standard Options */
692         case sBadOption:
693                 return -1;
694         case sPort:
695                 /* ignore ports from configfile if cmdline specifies ports */
696                 if (options->ports_from_cmdline)
697                         return 0;
698                 if (options->listen_addrs != NULL)
699                         fatal("%s line %d: ports must be specified before "
700                             "ListenAddress.", filename, linenum);
701                 if (options->num_ports >= MAX_PORTS)
702                         fatal("%s line %d: too many ports.",
703                             filename, linenum);
704                 arg = strdelim(&cp);
705                 if (!arg || *arg == '\0')
706                         fatal("%s line %d: missing port number.",
707                             filename, linenum);
708                 options->ports[options->num_ports++] = a2port(arg);
709                 if (options->ports[options->num_ports-1] == 0)
710                         fatal("%s line %d: Badly formatted port number.",
711                             filename, linenum);
712                 break;
713
714         case sServerKeyBits:
715                 intptr = &options->server_key_bits;
716  parse_int:
717                 arg = strdelim(&cp);
718                 if (!arg || *arg == '\0')
719                         fatal("%s line %d: missing integer value.",
720                             filename, linenum);
721                 value = atoi(arg);
722                 if (*activep && *intptr == -1)
723                         *intptr = value;
724                 break;
725
726         case sLoginGraceTime:
727                 intptr = &options->login_grace_time;
728  parse_time:
729                 arg = strdelim(&cp);
730                 if (!arg || *arg == '\0')
731                         fatal("%s line %d: missing time value.",
732                             filename, linenum);
733                 if ((value = convtime(arg)) == -1)
734                         fatal("%s line %d: invalid time value.",
735                             filename, linenum);
736                 if (*intptr == -1)
737                         *intptr = value;
738                 break;
739
740         case sKeyRegenerationTime:
741                 intptr = &options->key_regeneration_time;
742                 goto parse_time;
743
744         case sListenAddress:
745                 arg = strdelim(&cp);
746                 if (arg == NULL || *arg == '\0')
747                         fatal("%s line %d: missing address",
748                             filename, linenum);
749                 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
750                 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
751                     && strchr(p+1, ':') != NULL) {
752                         add_listen_addr(options, arg, 0);
753                         break;
754                 }
755                 p = hpdelim(&arg);
756                 if (p == NULL)
757                         fatal("%s line %d: bad address:port usage",
758                             filename, linenum);
759                 p = cleanhostname(p);
760                 if (arg == NULL)
761                         port = 0;
762                 else if ((port = a2port(arg)) == 0)
763                         fatal("%s line %d: bad port number", filename, linenum);
764
765                 add_listen_addr(options, p, port);
766
767                 break;
768
769         case sAddressFamily:
770                 arg = strdelim(&cp);
771                 if (!arg || *arg == '\0')
772                         fatal("%s line %d: missing address family.",
773                             filename, linenum);
774                 intptr = &options->address_family;
775                 if (options->listen_addrs != NULL)
776                         fatal("%s line %d: address family must be specified before "
777                             "ListenAddress.", filename, linenum);
778                 if (strcasecmp(arg, "inet") == 0)
779                         value = AF_INET;
780                 else if (strcasecmp(arg, "inet6") == 0)
781                         value = AF_INET6;
782                 else if (strcasecmp(arg, "any") == 0)
783                         value = AF_UNSPEC;
784                 else
785                         fatal("%s line %d: unsupported address family \"%s\".",
786                             filename, linenum, arg);
787                 if (*intptr == -1)
788                         *intptr = value;
789                 break;
790
791         case sHostKeyFile:
792                 intptr = &options->num_host_key_files;
793                 if (*intptr >= MAX_HOSTKEYS)
794                         fatal("%s line %d: too many host keys specified (max %d).",
795                             filename, linenum, MAX_HOSTKEYS);
796                 charptr = &options->host_key_files[*intptr];
797  parse_filename:
798                 arg = strdelim(&cp);
799                 if (!arg || *arg == '\0')
800                         fatal("%s line %d: missing file name.",
801                             filename, linenum);
802                 if (*activep && *charptr == NULL) {
803                         *charptr = tilde_expand_filename(arg, getuid());
804                         /* increase optional counter */
805                         if (intptr != NULL)
806                                 *intptr = *intptr + 1;
807                 }
808                 break;
809
810         case sPidFile:
811                 charptr = &options->pid_file;
812                 goto parse_filename;
813
814         case sPermitRootLogin:
815                 intptr = &options->permit_root_login;
816                 arg = strdelim(&cp);
817                 if (!arg || *arg == '\0')
818                         fatal("%s line %d: missing yes/"
819                             "without-password/forced-commands-only/no "
820                             "argument.", filename, linenum);
821                 value = 0;      /* silence compiler */
822                 if (strcmp(arg, "without-password") == 0)
823                         value = PERMIT_NO_PASSWD;
824                 else if (strcmp(arg, "forced-commands-only") == 0)
825                         value = PERMIT_FORCED_ONLY;
826                 else if (strcmp(arg, "yes") == 0)
827                         value = PERMIT_YES;
828                 else if (strcmp(arg, "no") == 0)
829                         value = PERMIT_NO;
830                 else
831                         fatal("%s line %d: Bad yes/"
832                             "without-password/forced-commands-only/no "
833                             "argument: %s", filename, linenum, arg);
834                 if (*activep && *intptr == -1)
835                         *intptr = value;
836                 break;
837
838         case sIgnoreRhosts:
839                 intptr = &options->ignore_rhosts;
840  parse_flag:
841                 arg = strdelim(&cp);
842                 if (!arg || *arg == '\0')
843                         fatal("%s line %d: missing yes/no argument.",
844                             filename, linenum);
845                 value = 0;      /* silence compiler */
846                 if (strcmp(arg, "yes") == 0)
847                         value = 1;
848                 else if (strcmp(arg, "no") == 0)
849                         value = 0;
850                 else
851                         fatal("%s line %d: Bad yes/no argument: %s",
852                                 filename, linenum, arg);
853                 if (*activep && *intptr == -1)
854                         *intptr = value;
855                 break;
856
857         case sIgnoreUserKnownHosts:
858                 intptr = &options->ignore_user_known_hosts;
859                 goto parse_flag;
860
861         case sRhostsRSAAuthentication:
862                 intptr = &options->rhosts_rsa_authentication;
863                 goto parse_flag;
864
865         case sHostbasedAuthentication:
866                 intptr = &options->hostbased_authentication;
867                 goto parse_flag;
868
869         case sHostbasedUsesNameFromPacketOnly:
870                 intptr = &options->hostbased_uses_name_from_packet_only;
871                 goto parse_flag;
872
873         case sRSAAuthentication:
874                 intptr = &options->rsa_authentication;
875                 goto parse_flag;
876
877         case sPubkeyAuthentication:
878                 intptr = &options->pubkey_authentication;
879                 goto parse_flag;
880
881         case sKerberosAuthentication:
882                 intptr = &options->kerberos_authentication;
883                 goto parse_flag;
884
885         case sKerberosOrLocalPasswd:
886                 intptr = &options->kerberos_or_local_passwd;
887                 goto parse_flag;
888
889         case sKerberosTicketCleanup:
890                 intptr = &options->kerberos_ticket_cleanup;
891                 goto parse_flag;
892
893         case sKerberosGetAFSToken:
894                 intptr = &options->kerberos_get_afs_token;
895                 goto parse_flag;
896
897         case sGssAuthentication:
898                 intptr = &options->gss_authentication;
899                 goto parse_flag;
900
901         case sGssCleanupCreds:
902                 intptr = &options->gss_cleanup_creds;
903                 goto parse_flag;
904
905         case sPasswordAuthentication:
906                 intptr = &options->password_authentication;
907                 goto parse_flag;
908
909         case sKbdInteractiveAuthentication:
910                 intptr = &options->kbd_interactive_authentication;
911                 goto parse_flag;
912
913         case sChallengeResponseAuthentication:
914                 intptr = &options->challenge_response_authentication;
915                 goto parse_flag;
916
917         case sPrintMotd:
918                 intptr = &options->print_motd;
919                 goto parse_flag;
920
921         case sPrintLastLog:
922                 intptr = &options->print_lastlog;
923                 goto parse_flag;
924
925         case sX11Forwarding:
926                 intptr = &options->x11_forwarding;
927                 goto parse_flag;
928
929         case sX11DisplayOffset:
930                 intptr = &options->x11_display_offset;
931                 goto parse_int;
932
933         case sX11UseLocalhost:
934                 intptr = &options->x11_use_localhost;
935                 goto parse_flag;
936
937         case sXAuthLocation:
938                 charptr = &options->xauth_location;
939                 goto parse_filename;
940
941         case sStrictModes:
942                 intptr = &options->strict_modes;
943                 goto parse_flag;
944
945         case sTCPKeepAlive:
946                 intptr = &options->tcp_keep_alive;
947                 goto parse_flag;
948
949         case sEmptyPasswd:
950                 intptr = &options->permit_empty_passwd;
951                 goto parse_flag;
952
953         case sPermitUserEnvironment:
954                 intptr = &options->permit_user_env;
955                 goto parse_flag;
956
957         case sUseLogin:
958                 intptr = &options->use_login;
959                 goto parse_flag;
960
961         case sCompression:
962                 intptr = &options->compression;
963                 arg = strdelim(&cp);
964                 if (!arg || *arg == '\0')
965                         fatal("%s line %d: missing yes/no/delayed "
966                             "argument.", filename, linenum);
967                 value = 0;      /* silence compiler */
968                 if (strcmp(arg, "delayed") == 0)
969                         value = COMP_DELAYED;
970                 else if (strcmp(arg, "yes") == 0)
971                         value = COMP_ZLIB;
972                 else if (strcmp(arg, "no") == 0)
973                         value = COMP_NONE;
974                 else
975                         fatal("%s line %d: Bad yes/no/delayed "
976                             "argument: %s", filename, linenum, arg);
977                 if (*intptr == -1)
978                         *intptr = value;
979                 break;
980
981         case sGatewayPorts:
982                 intptr = &options->gateway_ports;
983                 arg = strdelim(&cp);
984                 if (!arg || *arg == '\0')
985                         fatal("%s line %d: missing yes/no/clientspecified "
986                             "argument.", filename, linenum);
987                 value = 0;      /* silence compiler */
988                 if (strcmp(arg, "clientspecified") == 0)
989                         value = 2;
990                 else if (strcmp(arg, "yes") == 0)
991                         value = 1;
992                 else if (strcmp(arg, "no") == 0)
993                         value = 0;
994                 else
995                         fatal("%s line %d: Bad yes/no/clientspecified "
996                             "argument: %s", filename, linenum, arg);
997                 if (*activep && *intptr == -1)
998                         *intptr = value;
999                 break;
1000
1001         case sUseDNS:
1002                 intptr = &options->use_dns;
1003                 goto parse_flag;
1004
1005         case sLogFacility:
1006                 log_facility_ptr = &options->log_facility;
1007                 arg = strdelim(&cp);
1008                 value = log_facility_number(arg);
1009                 if (value == SYSLOG_FACILITY_NOT_SET)
1010                         fatal("%.200s line %d: unsupported log facility '%s'",
1011                             filename, linenum, arg ? arg : "<NONE>");
1012                 if (*log_facility_ptr == -1)
1013                         *log_facility_ptr = (SyslogFacility) value;
1014                 break;
1015
1016         case sLogLevel:
1017                 log_level_ptr = &options->log_level;
1018                 arg = strdelim(&cp);
1019                 value = log_level_number(arg);
1020                 if (value == SYSLOG_LEVEL_NOT_SET)
1021                         fatal("%.200s line %d: unsupported log level '%s'",
1022                             filename, linenum, arg ? arg : "<NONE>");
1023                 if (*log_level_ptr == -1)
1024                         *log_level_ptr = (LogLevel) value;
1025                 break;
1026
1027         case sAllowTcpForwarding:
1028                 intptr = &options->allow_tcp_forwarding;
1029                 goto parse_flag;
1030
1031         case sAllowAgentForwarding:
1032                 intptr = &options->allow_agent_forwarding;
1033                 goto parse_flag;
1034
1035         case sUsePrivilegeSeparation:
1036                 intptr = &use_privsep;
1037                 goto parse_flag;
1038
1039         case sAllowUsers:
1040                 while ((arg = strdelim(&cp)) && *arg != '\0') {
1041                         if (options->num_allow_users >= MAX_ALLOW_USERS)
1042                                 fatal("%s line %d: too many allow users.",
1043                                     filename, linenum);
1044                         options->allow_users[options->num_allow_users++] =
1045                             xstrdup(arg);
1046                 }
1047                 break;
1048
1049         case sDenyUsers:
1050                 while ((arg = strdelim(&cp)) && *arg != '\0') {
1051                         if (options->num_deny_users >= MAX_DENY_USERS)
1052                                 fatal("%s line %d: too many deny users.",
1053                                     filename, linenum);
1054                         options->deny_users[options->num_deny_users++] =
1055                             xstrdup(arg);
1056                 }
1057                 break;
1058
1059         case sAllowGroups:
1060                 while ((arg = strdelim(&cp)) && *arg != '\0') {
1061                         if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
1062                                 fatal("%s line %d: too many allow groups.",
1063                                     filename, linenum);
1064                         options->allow_groups[options->num_allow_groups++] =
1065                             xstrdup(arg);
1066                 }
1067                 break;
1068
1069         case sDenyGroups:
1070                 while ((arg = strdelim(&cp)) && *arg != '\0') {
1071                         if (options->num_deny_groups >= MAX_DENY_GROUPS)
1072                                 fatal("%s line %d: too many deny groups.",
1073                                     filename, linenum);
1074                         options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
1075                 }
1076                 break;
1077
1078         case sCiphers:
1079                 arg = strdelim(&cp);
1080                 if (!arg || *arg == '\0')
1081                         fatal("%s line %d: Missing argument.", filename, linenum);
1082                 if (!ciphers_valid(arg))
1083                         fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
1084                             filename, linenum, arg ? arg : "<NONE>");
1085                 if (options->ciphers == NULL)
1086                         options->ciphers = xstrdup(arg);
1087                 break;
1088
1089         case sMacs:
1090                 arg = strdelim(&cp);
1091                 if (!arg || *arg == '\0')
1092                         fatal("%s line %d: Missing argument.", filename, linenum);
1093                 if (!mac_valid(arg))
1094                         fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1095                             filename, linenum, arg ? arg : "<NONE>");
1096                 if (options->macs == NULL)
1097                         options->macs = xstrdup(arg);
1098                 break;
1099
1100         case sProtocol:
1101                 intptr = &options->protocol;
1102                 arg = strdelim(&cp);
1103                 if (!arg || *arg == '\0')
1104                         fatal("%s line %d: Missing argument.", filename, linenum);
1105                 value = proto_spec(arg);
1106                 if (value == SSH_PROTO_UNKNOWN)
1107                         fatal("%s line %d: Bad protocol spec '%s'.",
1108                             filename, linenum, arg ? arg : "<NONE>");
1109                 if (*intptr == SSH_PROTO_UNKNOWN)
1110                         *intptr = value;
1111                 break;
1112
1113         case sSubsystem:
1114                 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1115                         fatal("%s line %d: too many subsystems defined.",
1116                             filename, linenum);
1117                 }
1118                 arg = strdelim(&cp);
1119                 if (!arg || *arg == '\0')
1120                         fatal("%s line %d: Missing subsystem name.",
1121                             filename, linenum);
1122                 if (!*activep) {
1123                         arg = strdelim(&cp);
1124                         break;
1125                 }
1126                 for (i = 0; i < options->num_subsystems; i++)
1127                         if (strcmp(arg, options->subsystem_name[i]) == 0)
1128                                 fatal("%s line %d: Subsystem '%s' already defined.",
1129                                     filename, linenum, arg);
1130                 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1131                 arg = strdelim(&cp);
1132                 if (!arg || *arg == '\0')
1133                         fatal("%s line %d: Missing subsystem command.",
1134                             filename, linenum);
1135                 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1136
1137                 /* Collect arguments (separate to executable) */
1138                 p = xstrdup(arg);
1139                 len = strlen(p) + 1;
1140                 while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1141                         len += 1 + strlen(arg);
1142                         p = xrealloc(p, 1, len);
1143                         strlcat(p, " ", len);
1144                         strlcat(p, arg, len);
1145                 }
1146                 options->subsystem_args[options->num_subsystems] = p;
1147                 options->num_subsystems++;
1148                 break;
1149
1150         case sMaxStartups:
1151                 arg = strdelim(&cp);
1152                 if (!arg || *arg == '\0')
1153                         fatal("%s line %d: Missing MaxStartups spec.",
1154                             filename, linenum);
1155                 if ((n = sscanf(arg, "%d:%d:%d",
1156                     &options->max_startups_begin,
1157                     &options->max_startups_rate,
1158                     &options->max_startups)) == 3) {
1159                         if (options->max_startups_begin >
1160                             options->max_startups ||
1161                             options->max_startups_rate > 100 ||
1162                             options->max_startups_rate < 1)
1163                                 fatal("%s line %d: Illegal MaxStartups spec.",
1164                                     filename, linenum);
1165                 } else if (n != 1)
1166                         fatal("%s line %d: Illegal MaxStartups spec.",
1167                             filename, linenum);
1168                 else
1169                         options->max_startups = options->max_startups_begin;
1170                 break;
1171
1172         case sMaxAuthTries:
1173                 intptr = &options->max_authtries;
1174                 goto parse_int;
1175
1176         case sMaxSessions:
1177                 intptr = &options->max_sessions;
1178                 goto parse_int;
1179
1180         case sBanner:
1181                 charptr = &options->banner;
1182                 goto parse_filename;
1183
1184         /*
1185          * These options can contain %X options expanded at
1186          * connect time, so that you can specify paths like:
1187          *
1188          * AuthorizedKeysFile   /etc/ssh_keys/%u
1189          */
1190         case sAuthorizedKeysFile:
1191         case sAuthorizedKeysFile2:
1192                 charptr = (opcode == sAuthorizedKeysFile) ?
1193                     &options->authorized_keys_file :
1194                     &options->authorized_keys_file2;
1195                 goto parse_filename;
1196
1197         case sClientAliveInterval:
1198                 intptr = &options->client_alive_interval;
1199                 goto parse_time;
1200
1201         case sClientAliveCountMax:
1202                 intptr = &options->client_alive_count_max;
1203                 goto parse_int;
1204
1205         case sAcceptEnv:
1206                 while ((arg = strdelim(&cp)) && *arg != '\0') {
1207                         if (strchr(arg, '=') != NULL)
1208                                 fatal("%s line %d: Invalid environment name.",
1209                                     filename, linenum);
1210                         if (options->num_accept_env >= MAX_ACCEPT_ENV)
1211                                 fatal("%s line %d: too many allow env.",
1212                                     filename, linenum);
1213                         if (!*activep)
1214                                 break;
1215                         options->accept_env[options->num_accept_env++] =
1216                             xstrdup(arg);
1217                 }
1218                 break;
1219
1220         case sPermitTunnel:
1221                 intptr = &options->permit_tun;
1222                 arg = strdelim(&cp);
1223                 if (!arg || *arg == '\0')
1224                         fatal("%s line %d: Missing yes/point-to-point/"
1225                             "ethernet/no argument.", filename, linenum);
1226                 value = -1;
1227                 for (i = 0; tunmode_desc[i].val != -1; i++)
1228                         if (strcmp(tunmode_desc[i].text, arg) == 0) {
1229                                 value = tunmode_desc[i].val;
1230                                 break;
1231                         }
1232                 if (value == -1)
1233                         fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1234                             "no argument: %s", filename, linenum, arg);
1235                 if (*intptr == -1)
1236                         *intptr = value;
1237                 break;
1238
1239         case sMatch:
1240                 if (cmdline)
1241                         fatal("Match directive not supported as a command-line "
1242                            "option");
1243                 value = match_cfg_line(&cp, linenum, user, host, address);
1244                 if (value < 0)
1245                         fatal("%s line %d: Bad Match condition", filename,
1246                             linenum);
1247                 *activep = value;
1248                 break;
1249
1250         case sPermitOpen:
1251                 arg = strdelim(&cp);
1252                 if (!arg || *arg == '\0')
1253                         fatal("%s line %d: missing PermitOpen specification",
1254                             filename, linenum);
1255                 n = options->num_permitted_opens;       /* modified later */
1256                 if (strcmp(arg, "any") == 0) {
1257                         if (*activep && n == -1) {
1258                                 channel_clear_adm_permitted_opens();
1259                                 options->num_permitted_opens = 0;
1260                         }
1261                         break;
1262                 }
1263                 if (*activep && n == -1)
1264                         channel_clear_adm_permitted_opens();
1265                 for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
1266                         p = hpdelim(&arg);
1267                         if (p == NULL)
1268                                 fatal("%s line %d: missing host in PermitOpen",
1269                                     filename, linenum);
1270                         p = cleanhostname(p);
1271                         if (arg == NULL || (port = a2port(arg)) == 0)
1272                                 fatal("%s line %d: bad port number in "
1273                                     "PermitOpen", filename, linenum);
1274                         if (*activep && n == -1)
1275                                 options->num_permitted_opens =
1276                                     channel_add_adm_permitted_opens(p, port);
1277                 }
1278                 break;
1279
1280         case sForceCommand:
1281                 if (cp == NULL)
1282                         fatal("%.200s line %d: Missing argument.", filename,
1283                             linenum);
1284                 len = strspn(cp, WHITESPACE);
1285                 if (*activep && options->adm_forced_command == NULL)
1286                         options->adm_forced_command = xstrdup(cp + len);
1287                 return 0;
1288
1289         case sChrootDirectory:
1290                 charptr = &options->chroot_directory;
1291
1292                 arg = strdelim(&cp);
1293                 if (!arg || *arg == '\0')
1294                         fatal("%s line %d: missing file name.",
1295                             filename, linenum);
1296                 if (*activep && *charptr == NULL)
1297                         *charptr = xstrdup(arg);
1298                 break;
1299
1300         case sDeprecated:
1301                 logit("%s line %d: Deprecated option %s",
1302                     filename, linenum, arg);
1303                 while (arg)
1304                     arg = strdelim(&cp);
1305                 break;
1306
1307         case sUnsupported:
1308                 logit("%s line %d: Unsupported option %s",
1309                     filename, linenum, arg);
1310                 while (arg)
1311                     arg = strdelim(&cp);
1312                 break;
1313
1314         default:
1315                 fatal("%s line %d: Missing handler for opcode %s (%d)",
1316                     filename, linenum, arg, opcode);
1317         }
1318         if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1319                 fatal("%s line %d: garbage at end of line; \"%.200s\".",
1320                     filename, linenum, arg);
1321         return 0;
1322 }
1323
1324 /* Reads the server configuration file. */
1325
1326 void
1327 load_server_config(const char *filename, Buffer *conf)
1328 {
1329         char line[1024], *cp;
1330         FILE *f;
1331
1332         debug2("%s: filename %s", __func__, filename);
1333         if ((f = fopen(filename, "r")) == NULL) {
1334                 perror(filename);
1335                 exit(1);
1336         }
1337         buffer_clear(conf);
1338         while (fgets(line, sizeof(line), f)) {
1339                 /*
1340                  * Trim out comments and strip whitespace
1341                  * NB - preserve newlines, they are needed to reproduce
1342                  * line numbers later for error messages
1343                  */
1344                 if ((cp = strchr(line, '#')) != NULL)
1345                         memcpy(cp, "\n", 2);
1346                 cp = line + strspn(line, " \t\r");
1347
1348                 buffer_append(conf, cp, strlen(cp));
1349         }
1350         buffer_append(conf, "\0", 1);
1351         fclose(f);
1352         debug2("%s: done config len = %d", __func__, buffer_len(conf));
1353 }
1354
1355 void
1356 parse_server_match_config(ServerOptions *options, const char *user,
1357     const char *host, const char *address)
1358 {
1359         ServerOptions mo;
1360
1361         initialize_server_options(&mo);
1362         parse_server_config(&mo, "reprocess config", &cfg, user, host, address);
1363         copy_set_server_options(options, &mo, 0);
1364 }
1365
1366 /* Helper macros */
1367 #define M_CP_INTOPT(n) do {\
1368         if (src->n != -1) \
1369                 dst->n = src->n; \
1370 } while (0)
1371 #define M_CP_STROPT(n) do {\
1372         if (src->n != NULL) { \
1373                 if (dst->n != NULL) \
1374                         xfree(dst->n); \
1375                 dst->n = src->n; \
1376         } \
1377 } while(0)
1378
1379 /*
1380  * Copy any supported values that are set.
1381  *
1382  * If the preauth flag is set, we do not bother copying the the string or
1383  * array values that are not used pre-authentication, because any that we
1384  * do use must be explictly sent in mm_getpwnamallow().
1385  */
1386 void
1387 copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
1388 {
1389         M_CP_INTOPT(password_authentication);
1390         M_CP_INTOPT(gss_authentication);
1391         M_CP_INTOPT(rsa_authentication);
1392         M_CP_INTOPT(pubkey_authentication);
1393         M_CP_INTOPT(kerberos_authentication);
1394         M_CP_INTOPT(hostbased_authentication);
1395         M_CP_INTOPT(kbd_interactive_authentication);
1396         M_CP_INTOPT(permit_root_login);
1397
1398         M_CP_INTOPT(allow_tcp_forwarding);
1399         M_CP_INTOPT(allow_agent_forwarding);
1400         M_CP_INTOPT(gateway_ports);
1401         M_CP_INTOPT(x11_display_offset);
1402         M_CP_INTOPT(x11_forwarding);
1403         M_CP_INTOPT(x11_use_localhost);
1404         M_CP_INTOPT(max_sessions);
1405
1406         M_CP_STROPT(banner);
1407         if (preauth)
1408                 return;
1409         M_CP_STROPT(adm_forced_command);
1410         M_CP_STROPT(chroot_directory);
1411 }
1412
1413 #undef M_CP_INTOPT
1414 #undef M_CP_STROPT
1415
1416 void
1417 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1418     const char *user, const char *host, const char *address)
1419 {
1420         int active, linenum, bad_options = 0;
1421         char *cp, *obuf, *cbuf;
1422
1423         debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1424
1425         obuf = cbuf = xstrdup(buffer_ptr(conf));
1426         active = user ? 0 : 1;
1427         linenum = 1;
1428         while ((cp = strsep(&cbuf, "\n")) != NULL) {
1429                 if (process_server_config_line(options, cp, filename,
1430                     linenum++, &active, user, host, address) != 0)
1431                         bad_options++;
1432         }
1433         xfree(obuf);
1434         if (bad_options > 0)
1435                 fatal("%s: terminating, %d bad configuration options",
1436                     filename, bad_options);
1437 }
1438
1439 static const char *
1440 fmt_intarg(ServerOpCodes code, int val)
1441 {
1442         if (code == sAddressFamily) {
1443                 switch (val) {
1444                 case AF_INET:
1445                         return "inet";
1446                 case AF_INET6:
1447                         return "inet6";
1448                 case AF_UNSPEC:
1449                         return "any";
1450                 default:
1451                         return "UNKNOWN";
1452                 }
1453         }
1454         if (code == sPermitRootLogin) {
1455                 switch (val) {
1456                 case PERMIT_NO_PASSWD:
1457                         return "without-passord";
1458                 case PERMIT_FORCED_ONLY:
1459                         return "forced-commands-only";
1460                 case PERMIT_YES:
1461                         return "yes";
1462                 }
1463         }
1464         if (code == sProtocol) {
1465                 switch (val) {
1466                 case SSH_PROTO_1:
1467                         return "1";
1468                 case SSH_PROTO_2:
1469                         return "2";
1470                 case (SSH_PROTO_1|SSH_PROTO_2):
1471                         return "2,1";
1472                 default:
1473                         return "UNKNOWN";
1474                 }
1475         }
1476         if (code == sGatewayPorts && val == 2)
1477                 return "clientspecified";
1478         if (code == sCompression && val == COMP_DELAYED)
1479                 return "delayed";
1480         switch (val) {
1481         case -1:
1482                 return "unset";
1483         case 0:
1484                 return "no";
1485         case 1:
1486                 return "yes";
1487         }
1488         return "UNKNOWN";
1489 }
1490
1491 static const char *
1492 lookup_opcode_name(ServerOpCodes code)
1493 {
1494         u_int i;
1495
1496         for (i = 0; keywords[i].name != NULL; i++)
1497                 if (keywords[i].opcode == code)
1498                         return(keywords[i].name);
1499         return "UNKNOWN";
1500 }
1501
1502 static void
1503 dump_cfg_int(ServerOpCodes code, int val)
1504 {
1505         printf("%s %d\n", lookup_opcode_name(code), val);
1506 }
1507
1508 static void
1509 dump_cfg_fmtint(ServerOpCodes code, int val)
1510 {
1511         printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
1512 }
1513
1514 static void
1515 dump_cfg_string(ServerOpCodes code, const char *val)
1516 {
1517         if (val == NULL)
1518                 return;
1519         printf("%s %s\n", lookup_opcode_name(code), val);
1520 }
1521
1522 static void
1523 dump_cfg_strarray(ServerOpCodes code, u_int count, char **vals)
1524 {
1525         u_int i;
1526
1527         for (i = 0; i < count; i++)
1528                 printf("%s %s\n", lookup_opcode_name(code),  vals[i]);
1529 }
1530
1531 void
1532 dump_config(ServerOptions *o)
1533 {
1534         u_int i;
1535         int ret;
1536         struct addrinfo *ai;
1537         char addr[NI_MAXHOST], port[NI_MAXSERV], *s = NULL;
1538
1539         /* these are usually at the top of the config */
1540         for (i = 0; i < o->num_ports; i++)
1541                 printf("port %d\n", o->ports[i]);
1542         dump_cfg_fmtint(sProtocol, o->protocol);
1543         dump_cfg_fmtint(sAddressFamily, o->address_family);
1544
1545         /* ListenAddress must be after Port */
1546         for (ai = o->listen_addrs; ai; ai = ai->ai_next) {
1547                 if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr,
1548                     sizeof(addr), port, sizeof(port),
1549                     NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
1550                         error("getnameinfo failed: %.100s",
1551                             (ret != EAI_SYSTEM) ? gai_strerror(ret) :
1552                             strerror(errno));
1553                 } else {
1554                         if (ai->ai_family == AF_INET6)
1555                                 printf("listenaddress [%s]:%s\n", addr, port);
1556                         else
1557                                 printf("listenaddress %s:%s\n", addr, port);
1558                 }
1559         }
1560
1561         /* integer arguments */
1562         dump_cfg_int(sServerKeyBits, o->server_key_bits);
1563         dump_cfg_int(sLoginGraceTime, o->login_grace_time);
1564         dump_cfg_int(sKeyRegenerationTime, o->key_regeneration_time);
1565         dump_cfg_int(sX11DisplayOffset, o->x11_display_offset);
1566         dump_cfg_int(sMaxAuthTries, o->max_authtries);
1567         dump_cfg_int(sClientAliveInterval, o->client_alive_interval);
1568         dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max);
1569
1570         /* formatted integer arguments */
1571         dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login);
1572         dump_cfg_fmtint(sIgnoreRhosts, o->ignore_rhosts);
1573         dump_cfg_fmtint(sIgnoreUserKnownHosts, o->ignore_user_known_hosts);
1574         dump_cfg_fmtint(sRhostsRSAAuthentication, o->rhosts_rsa_authentication);
1575         dump_cfg_fmtint(sHostbasedAuthentication, o->hostbased_authentication);
1576         dump_cfg_fmtint(sHostbasedUsesNameFromPacketOnly,
1577             o->hostbased_uses_name_from_packet_only);
1578         dump_cfg_fmtint(sRSAAuthentication, o->rsa_authentication);
1579         dump_cfg_fmtint(sPubkeyAuthentication, o->pubkey_authentication);
1580         dump_cfg_fmtint(sKerberosAuthentication, o->kerberos_authentication);
1581         dump_cfg_fmtint(sKerberosOrLocalPasswd, o->kerberos_or_local_passwd);
1582         dump_cfg_fmtint(sKerberosTicketCleanup, o->kerberos_ticket_cleanup);
1583         dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token);
1584         dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
1585         dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds);
1586         dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
1587         dump_cfg_fmtint(sKbdInteractiveAuthentication,
1588             o->kbd_interactive_authentication);
1589         dump_cfg_fmtint(sChallengeResponseAuthentication,
1590             o->challenge_response_authentication);
1591         dump_cfg_fmtint(sPrintMotd, o->print_motd);
1592         dump_cfg_fmtint(sPrintLastLog, o->print_lastlog);
1593         dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding);
1594         dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost);
1595         dump_cfg_fmtint(sStrictModes, o->strict_modes);
1596         dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive);
1597         dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd);
1598         dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env);
1599         dump_cfg_fmtint(sUseLogin, o->use_login);
1600         dump_cfg_fmtint(sCompression, o->compression);
1601         dump_cfg_fmtint(sGatewayPorts, o->gateway_ports);
1602         dump_cfg_fmtint(sUseDNS, o->use_dns);
1603         dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
1604         dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep);
1605
1606         /* string arguments */
1607         dump_cfg_string(sPidFile, o->pid_file);
1608         dump_cfg_string(sXAuthLocation, o->xauth_location);
1609         dump_cfg_string(sCiphers, o->ciphers);
1610         dump_cfg_string(sMacs, o->macs);
1611         dump_cfg_string(sBanner, o->banner);
1612         dump_cfg_string(sAuthorizedKeysFile, o->authorized_keys_file);
1613         dump_cfg_string(sAuthorizedKeysFile2, o->authorized_keys_file2);
1614         dump_cfg_string(sForceCommand, o->adm_forced_command);
1615
1616         /* string arguments requiring a lookup */
1617         dump_cfg_string(sLogLevel, log_level_name(o->log_level));
1618         dump_cfg_string(sLogFacility, log_facility_name(o->log_facility));
1619
1620         /* string array arguments */
1621         dump_cfg_strarray(sHostKeyFile, o->num_host_key_files,
1622              o->host_key_files);
1623         dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users);
1624         dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users);
1625         dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups);
1626         dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups);
1627         dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env);
1628
1629         /* other arguments */
1630         for (i = 0; i < o->num_subsystems; i++)
1631                 printf("subsystem %s %s\n", o->subsystem_name[i],
1632                     o->subsystem_args[i]);
1633
1634         printf("maxstartups %d:%d:%d\n", o->max_startups_begin,
1635             o->max_startups_rate, o->max_startups);
1636
1637         for (i = 0; tunmode_desc[i].val != -1; i++)
1638                 if (tunmode_desc[i].val == o->permit_tun) {
1639                         s = tunmode_desc[i].text;
1640                         break;
1641                 }
1642         dump_cfg_string(sPermitTunnel, s);
1643
1644         printf("permitopen");
1645         channel_print_adm_permitted_opens();
1646         printf("\n");
1647 }
This page took 0.198908 seconds and 5 git commands to generate.