66e22979f926eec8c6ae490f408edeeac522deef
[dragonfly.git] / crypto / openssh-5 / servconf.c
1 /* $OpenBSD: servconf.c,v 1.186 2008/07/04 03:44:59 djm 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 = 1024;
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_ALL },
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         struct passwd *pw;
529
530         if (user == NULL)
531                 goto out;
532
533         if ((pw = getpwnam(user)) == NULL) {
534                 debug("Can't match group at line %d because user %.100s does "
535                     "not exist", line, user);
536         } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
537                 debug("Can't Match group because user %.100s not in any group "
538                     "at line %d", user, line);
539         } else if (ga_match_pattern_list(grps) != 1) {
540                 debug("user %.100s does not match group list %.100s at line %d",
541                     user, grps, line);
542         } else {
543                 debug("user %.100s matched group list %.100s at line %d", user,
544                     grps, line);
545                 result = 1;
546         }
547 out:
548         ga_free();
549         return result;
550 }
551
552 static int
553 match_cfg_line(char **condition, int line, const char *user, const char *host,
554     const char *address)
555 {
556         int result = 1;
557         char *arg, *attrib, *cp = *condition;
558         size_t len;
559
560         if (user == NULL)
561                 debug3("checking syntax for 'Match %s'", cp);
562         else
563                 debug3("checking match for '%s' user %s host %s addr %s", cp,
564                     user ? user : "(null)", host ? host : "(null)",
565                     address ? address : "(null)");
566
567         while ((attrib = strdelim(&cp)) && *attrib != '\0') {
568                 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
569                         error("Missing Match criteria for %s", attrib);
570                         return -1;
571                 }
572                 len = strlen(arg);
573                 if (strcasecmp(attrib, "user") == 0) {
574                         if (!user) {
575                                 result = 0;
576                                 continue;
577                         }
578                         if (match_pattern_list(user, arg, len, 0) != 1)
579                                 result = 0;
580                         else
581                                 debug("user %.100s matched 'User %.100s' at "
582                                     "line %d", user, arg, line);
583                 } else if (strcasecmp(attrib, "group") == 0) {
584                         switch (match_cfg_line_group(arg, line, user)) {
585                         case -1:
586                                 return -1;
587                         case 0:
588                                 result = 0;
589                         }
590                 } else if (strcasecmp(attrib, "host") == 0) {
591                         if (!host) {
592                                 result = 0;
593                                 continue;
594                         }
595                         if (match_hostname(host, arg, len) != 1)
596                                 result = 0;
597                         else
598                                 debug("connection from %.100s matched 'Host "
599                                     "%.100s' at line %d", host, arg, line);
600                 } else if (strcasecmp(attrib, "address") == 0) {
601                         switch (addr_match_list(address, arg)) {
602                         case 1:
603                                 debug("connection from %.100s matched 'Address "
604                                     "%.100s' at line %d", address, arg, line);
605                                 break;
606                         case 0:
607                         case -1:
608                                 result = 0;
609                                 break;
610                         case -2:
611                                 return -1;
612                         }
613                 } else {
614                         error("Unsupported Match attribute %s", attrib);
615                         return -1;
616                 }
617         }
618         if (user != NULL)
619                 debug3("match %sfound", result ? "" : "not ");
620         *condition = cp;
621         return result;
622 }
623
624 #define WHITESPACE " \t\r\n"
625
626 int
627 process_server_config_line(ServerOptions *options, char *line,
628     const char *filename, int linenum, int *activep, const char *user,
629     const char *host, const char *address)
630 {
631         char *cp, **charptr, *arg, *p;
632         int cmdline = 0, *intptr, value, n;
633         SyslogFacility *log_facility_ptr;
634         LogLevel *log_level_ptr;
635         ServerOpCodes opcode;
636         u_short port;
637         u_int i, flags = 0;
638         size_t len;
639
640         cp = line;
641         if ((arg = strdelim(&cp)) == NULL)
642                 return 0;
643         /* Ignore leading whitespace */
644         if (*arg == '\0')
645                 arg = strdelim(&cp);
646         if (!arg || !*arg || *arg == '#')
647                 return 0;
648         intptr = NULL;
649         charptr = NULL;
650         opcode = parse_token(arg, filename, linenum, &flags);
651
652         if (activep == NULL) { /* We are processing a command line directive */
653                 cmdline = 1;
654                 activep = &cmdline;
655         }
656         if (*activep && opcode != sMatch)
657                 debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
658         if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
659                 if (user == NULL) {
660                         fatal("%s line %d: Directive '%s' is not allowed "
661                             "within a Match block", filename, linenum, arg);
662                 } else { /* this is a directive we have already processed */
663                         while (arg)
664                                 arg = strdelim(&cp);
665                         return 0;
666                 }
667         }
668
669         switch (opcode) {
670         /* Portable-specific options */
671         case sUsePAM:
672                 intptr = &options->use_pam;
673                 goto parse_flag;
674
675         /* Standard Options */
676         case sBadOption:
677                 return -1;
678         case sPort:
679                 /* ignore ports from configfile if cmdline specifies ports */
680                 if (options->ports_from_cmdline)
681                         return 0;
682                 if (options->listen_addrs != NULL)
683                         fatal("%s line %d: ports must be specified before "
684                             "ListenAddress.", filename, linenum);
685                 if (options->num_ports >= MAX_PORTS)
686                         fatal("%s line %d: too many ports.",
687                             filename, linenum);
688                 arg = strdelim(&cp);
689                 if (!arg || *arg == '\0')
690                         fatal("%s line %d: missing port number.",
691                             filename, linenum);
692                 options->ports[options->num_ports++] = a2port(arg);
693                 if (options->ports[options->num_ports-1] == 0)
694                         fatal("%s line %d: Badly formatted port number.",
695                             filename, linenum);
696                 break;
697
698         case sServerKeyBits:
699                 intptr = &options->server_key_bits;
700  parse_int:
701                 arg = strdelim(&cp);
702                 if (!arg || *arg == '\0')
703                         fatal("%s line %d: missing integer value.",
704                             filename, linenum);
705                 value = atoi(arg);
706                 if (*activep && *intptr == -1)
707                         *intptr = value;
708                 break;
709
710         case sLoginGraceTime:
711                 intptr = &options->login_grace_time;
712  parse_time:
713                 arg = strdelim(&cp);
714                 if (!arg || *arg == '\0')
715                         fatal("%s line %d: missing time value.",
716                             filename, linenum);
717                 if ((value = convtime(arg)) == -1)
718                         fatal("%s line %d: invalid time value.",
719                             filename, linenum);
720                 if (*intptr == -1)
721                         *intptr = value;
722                 break;
723
724         case sKeyRegenerationTime:
725                 intptr = &options->key_regeneration_time;
726                 goto parse_time;
727
728         case sListenAddress:
729                 arg = strdelim(&cp);
730                 if (arg == NULL || *arg == '\0')
731                         fatal("%s line %d: missing address",
732                             filename, linenum);
733                 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
734                 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
735                     && strchr(p+1, ':') != NULL) {
736                         add_listen_addr(options, arg, 0);
737                         break;
738                 }
739                 p = hpdelim(&arg);
740                 if (p == NULL)
741                         fatal("%s line %d: bad address:port usage",
742                             filename, linenum);
743                 p = cleanhostname(p);
744                 if (arg == NULL)
745                         port = 0;
746                 else if ((port = a2port(arg)) == 0)
747                         fatal("%s line %d: bad port number", filename, linenum);
748
749                 add_listen_addr(options, p, port);
750
751                 break;
752
753         case sAddressFamily:
754                 arg = strdelim(&cp);
755                 if (!arg || *arg == '\0')
756                         fatal("%s line %d: missing address family.",
757                             filename, linenum);
758                 intptr = &options->address_family;
759                 if (options->listen_addrs != NULL)
760                         fatal("%s line %d: address family must be specified before "
761                             "ListenAddress.", filename, linenum);
762                 if (strcasecmp(arg, "inet") == 0)
763                         value = AF_INET;
764                 else if (strcasecmp(arg, "inet6") == 0)
765                         value = AF_INET6;
766                 else if (strcasecmp(arg, "any") == 0)
767                         value = AF_UNSPEC;
768                 else
769                         fatal("%s line %d: unsupported address family \"%s\".",
770                             filename, linenum, arg);
771                 if (*intptr == -1)
772                         *intptr = value;
773                 break;
774
775         case sHostKeyFile:
776                 intptr = &options->num_host_key_files;
777                 if (*intptr >= MAX_HOSTKEYS)
778                         fatal("%s line %d: too many host keys specified (max %d).",
779                             filename, linenum, MAX_HOSTKEYS);
780                 charptr = &options->host_key_files[*intptr];
781  parse_filename:
782                 arg = strdelim(&cp);
783                 if (!arg || *arg == '\0')
784                         fatal("%s line %d: missing file name.",
785                             filename, linenum);
786                 if (*activep && *charptr == NULL) {
787                         *charptr = tilde_expand_filename(arg, getuid());
788                         /* increase optional counter */
789                         if (intptr != NULL)
790                                 *intptr = *intptr + 1;
791                 }
792                 break;
793
794         case sPidFile:
795                 charptr = &options->pid_file;
796                 goto parse_filename;
797
798         case sPermitRootLogin:
799                 intptr = &options->permit_root_login;
800                 arg = strdelim(&cp);
801                 if (!arg || *arg == '\0')
802                         fatal("%s line %d: missing yes/"
803                             "without-password/forced-commands-only/no "
804                             "argument.", filename, linenum);
805                 value = 0;      /* silence compiler */
806                 if (strcmp(arg, "without-password") == 0)
807                         value = PERMIT_NO_PASSWD;
808                 else if (strcmp(arg, "forced-commands-only") == 0)
809                         value = PERMIT_FORCED_ONLY;
810                 else if (strcmp(arg, "yes") == 0)
811                         value = PERMIT_YES;
812                 else if (strcmp(arg, "no") == 0)
813                         value = PERMIT_NO;
814                 else
815                         fatal("%s line %d: Bad yes/"
816                             "without-password/forced-commands-only/no "
817                             "argument: %s", filename, linenum, arg);
818                 if (*activep && *intptr == -1)
819                         *intptr = value;
820                 break;
821
822         case sIgnoreRhosts:
823                 intptr = &options->ignore_rhosts;
824  parse_flag:
825                 arg = strdelim(&cp);
826                 if (!arg || *arg == '\0')
827                         fatal("%s line %d: missing yes/no argument.",
828                             filename, linenum);
829                 value = 0;      /* silence compiler */
830                 if (strcmp(arg, "yes") == 0)
831                         value = 1;
832                 else if (strcmp(arg, "no") == 0)
833                         value = 0;
834                 else
835                         fatal("%s line %d: Bad yes/no argument: %s",
836                                 filename, linenum, arg);
837                 if (*activep && *intptr == -1)
838                         *intptr = value;
839                 break;
840
841         case sIgnoreUserKnownHosts:
842                 intptr = &options->ignore_user_known_hosts;
843                 goto parse_flag;
844
845         case sRhostsRSAAuthentication:
846                 intptr = &options->rhosts_rsa_authentication;
847                 goto parse_flag;
848
849         case sHostbasedAuthentication:
850                 intptr = &options->hostbased_authentication;
851                 goto parse_flag;
852
853         case sHostbasedUsesNameFromPacketOnly:
854                 intptr = &options->hostbased_uses_name_from_packet_only;
855                 goto parse_flag;
856
857         case sRSAAuthentication:
858                 intptr = &options->rsa_authentication;
859                 goto parse_flag;
860
861         case sPubkeyAuthentication:
862                 intptr = &options->pubkey_authentication;
863                 goto parse_flag;
864
865         case sKerberosAuthentication:
866                 intptr = &options->kerberos_authentication;
867                 goto parse_flag;
868
869         case sKerberosOrLocalPasswd:
870                 intptr = &options->kerberos_or_local_passwd;
871                 goto parse_flag;
872
873         case sKerberosTicketCleanup:
874                 intptr = &options->kerberos_ticket_cleanup;
875                 goto parse_flag;
876
877         case sKerberosGetAFSToken:
878                 intptr = &options->kerberos_get_afs_token;
879                 goto parse_flag;
880
881         case sGssAuthentication:
882                 intptr = &options->gss_authentication;
883                 goto parse_flag;
884
885         case sGssCleanupCreds:
886                 intptr = &options->gss_cleanup_creds;
887                 goto parse_flag;
888
889         case sPasswordAuthentication:
890                 intptr = &options->password_authentication;
891                 goto parse_flag;
892
893         case sKbdInteractiveAuthentication:
894                 intptr = &options->kbd_interactive_authentication;
895                 goto parse_flag;
896
897         case sChallengeResponseAuthentication:
898                 intptr = &options->challenge_response_authentication;
899                 goto parse_flag;
900
901         case sPrintMotd:
902                 intptr = &options->print_motd;
903                 goto parse_flag;
904
905         case sPrintLastLog:
906                 intptr = &options->print_lastlog;
907                 goto parse_flag;
908
909         case sX11Forwarding:
910                 intptr = &options->x11_forwarding;
911                 goto parse_flag;
912
913         case sX11DisplayOffset:
914                 intptr = &options->x11_display_offset;
915                 goto parse_int;
916
917         case sX11UseLocalhost:
918                 intptr = &options->x11_use_localhost;
919                 goto parse_flag;
920
921         case sXAuthLocation:
922                 charptr = &options->xauth_location;
923                 goto parse_filename;
924
925         case sStrictModes:
926                 intptr = &options->strict_modes;
927                 goto parse_flag;
928
929         case sTCPKeepAlive:
930                 intptr = &options->tcp_keep_alive;
931                 goto parse_flag;
932
933         case sEmptyPasswd:
934                 intptr = &options->permit_empty_passwd;
935                 goto parse_flag;
936
937         case sPermitUserEnvironment:
938                 intptr = &options->permit_user_env;
939                 goto parse_flag;
940
941         case sUseLogin:
942                 intptr = &options->use_login;
943                 goto parse_flag;
944
945         case sCompression:
946                 intptr = &options->compression;
947                 arg = strdelim(&cp);
948                 if (!arg || *arg == '\0')
949                         fatal("%s line %d: missing yes/no/delayed "
950                             "argument.", filename, linenum);
951                 value = 0;      /* silence compiler */
952                 if (strcmp(arg, "delayed") == 0)
953                         value = COMP_DELAYED;
954                 else if (strcmp(arg, "yes") == 0)
955                         value = COMP_ZLIB;
956                 else if (strcmp(arg, "no") == 0)
957                         value = COMP_NONE;
958                 else
959                         fatal("%s line %d: Bad yes/no/delayed "
960                             "argument: %s", filename, linenum, arg);
961                 if (*intptr == -1)
962                         *intptr = value;
963                 break;
964
965         case sGatewayPorts:
966                 intptr = &options->gateway_ports;
967                 arg = strdelim(&cp);
968                 if (!arg || *arg == '\0')
969                         fatal("%s line %d: missing yes/no/clientspecified "
970                             "argument.", filename, linenum);
971                 value = 0;      /* silence compiler */
972                 if (strcmp(arg, "clientspecified") == 0)
973                         value = 2;
974                 else if (strcmp(arg, "yes") == 0)
975                         value = 1;
976                 else if (strcmp(arg, "no") == 0)
977                         value = 0;
978                 else
979                         fatal("%s line %d: Bad yes/no/clientspecified "
980                             "argument: %s", filename, linenum, arg);
981                 if (*activep && *intptr == -1)
982                         *intptr = value;
983                 break;
984
985         case sUseDNS:
986                 intptr = &options->use_dns;
987                 goto parse_flag;
988
989         case sLogFacility:
990                 log_facility_ptr = &options->log_facility;
991                 arg = strdelim(&cp);
992                 value = log_facility_number(arg);
993                 if (value == SYSLOG_FACILITY_NOT_SET)
994                         fatal("%.200s line %d: unsupported log facility '%s'",
995                             filename, linenum, arg ? arg : "<NONE>");
996                 if (*log_facility_ptr == -1)
997                         *log_facility_ptr = (SyslogFacility) value;
998                 break;
999
1000         case sLogLevel:
1001                 log_level_ptr = &options->log_level;
1002                 arg = strdelim(&cp);
1003                 value = log_level_number(arg);
1004                 if (value == SYSLOG_LEVEL_NOT_SET)
1005                         fatal("%.200s line %d: unsupported log level '%s'",
1006                             filename, linenum, arg ? arg : "<NONE>");
1007                 if (*log_level_ptr == -1)
1008                         *log_level_ptr = (LogLevel) value;
1009                 break;
1010
1011         case sAllowTcpForwarding:
1012                 intptr = &options->allow_tcp_forwarding;
1013                 goto parse_flag;
1014
1015         case sAllowAgentForwarding:
1016                 intptr = &options->allow_agent_forwarding;
1017                 goto parse_flag;
1018
1019         case sUsePrivilegeSeparation:
1020                 intptr = &use_privsep;
1021                 goto parse_flag;
1022
1023         case sAllowUsers:
1024                 while ((arg = strdelim(&cp)) && *arg != '\0') {
1025                         if (options->num_allow_users >= MAX_ALLOW_USERS)
1026                                 fatal("%s line %d: too many allow users.",
1027                                     filename, linenum);
1028                         options->allow_users[options->num_allow_users++] =
1029                             xstrdup(arg);
1030                 }
1031                 break;
1032
1033         case sDenyUsers:
1034                 while ((arg = strdelim(&cp)) && *arg != '\0') {
1035                         if (options->num_deny_users >= MAX_DENY_USERS)
1036                                 fatal("%s line %d: too many deny users.",
1037                                     filename, linenum);
1038                         options->deny_users[options->num_deny_users++] =
1039                             xstrdup(arg);
1040                 }
1041                 break;
1042
1043         case sAllowGroups:
1044                 while ((arg = strdelim(&cp)) && *arg != '\0') {
1045                         if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
1046                                 fatal("%s line %d: too many allow groups.",
1047                                     filename, linenum);
1048                         options->allow_groups[options->num_allow_groups++] =
1049                             xstrdup(arg);
1050                 }
1051                 break;
1052
1053         case sDenyGroups:
1054                 while ((arg = strdelim(&cp)) && *arg != '\0') {
1055                         if (options->num_deny_groups >= MAX_DENY_GROUPS)
1056                                 fatal("%s line %d: too many deny groups.",
1057                                     filename, linenum);
1058                         options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
1059                 }
1060                 break;
1061
1062         case sCiphers:
1063                 arg = strdelim(&cp);
1064                 if (!arg || *arg == '\0')
1065                         fatal("%s line %d: Missing argument.", filename, linenum);
1066                 if (!ciphers_valid(arg))
1067                         fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
1068                             filename, linenum, arg ? arg : "<NONE>");
1069                 if (options->ciphers == NULL)
1070                         options->ciphers = xstrdup(arg);
1071                 break;
1072
1073         case sMacs:
1074                 arg = strdelim(&cp);
1075                 if (!arg || *arg == '\0')
1076                         fatal("%s line %d: Missing argument.", filename, linenum);
1077                 if (!mac_valid(arg))
1078                         fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1079                             filename, linenum, arg ? arg : "<NONE>");
1080                 if (options->macs == NULL)
1081                         options->macs = xstrdup(arg);
1082                 break;
1083
1084         case sProtocol:
1085                 intptr = &options->protocol;
1086                 arg = strdelim(&cp);
1087                 if (!arg || *arg == '\0')
1088                         fatal("%s line %d: Missing argument.", filename, linenum);
1089                 value = proto_spec(arg);
1090                 if (value == SSH_PROTO_UNKNOWN)
1091                         fatal("%s line %d: Bad protocol spec '%s'.",
1092                             filename, linenum, arg ? arg : "<NONE>");
1093                 if (*intptr == SSH_PROTO_UNKNOWN)
1094                         *intptr = value;
1095                 break;
1096
1097         case sSubsystem:
1098                 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1099                         fatal("%s line %d: too many subsystems defined.",
1100                             filename, linenum);
1101                 }
1102                 arg = strdelim(&cp);
1103                 if (!arg || *arg == '\0')
1104                         fatal("%s line %d: Missing subsystem name.",
1105                             filename, linenum);
1106                 if (!*activep) {
1107                         arg = strdelim(&cp);
1108                         break;
1109                 }
1110                 for (i = 0; i < options->num_subsystems; i++)
1111                         if (strcmp(arg, options->subsystem_name[i]) == 0)
1112                                 fatal("%s line %d: Subsystem '%s' already defined.",
1113                                     filename, linenum, arg);
1114                 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1115                 arg = strdelim(&cp);
1116                 if (!arg || *arg == '\0')
1117                         fatal("%s line %d: Missing subsystem command.",
1118                             filename, linenum);
1119                 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1120
1121                 /* Collect arguments (separate to executable) */
1122                 p = xstrdup(arg);
1123                 len = strlen(p) + 1;
1124                 while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1125                         len += 1 + strlen(arg);
1126                         p = xrealloc(p, 1, len);
1127                         strlcat(p, " ", len);
1128                         strlcat(p, arg, len);
1129                 }
1130                 options->subsystem_args[options->num_subsystems] = p;
1131                 options->num_subsystems++;
1132                 break;
1133
1134         case sMaxStartups:
1135                 arg = strdelim(&cp);
1136                 if (!arg || *arg == '\0')
1137                         fatal("%s line %d: Missing MaxStartups spec.",
1138                             filename, linenum);
1139                 if ((n = sscanf(arg, "%d:%d:%d",
1140                     &options->max_startups_begin,
1141                     &options->max_startups_rate,
1142                     &options->max_startups)) == 3) {
1143                         if (options->max_startups_begin >
1144                             options->max_startups ||
1145                             options->max_startups_rate > 100 ||
1146                             options->max_startups_rate < 1)
1147                                 fatal("%s line %d: Illegal MaxStartups spec.",
1148                                     filename, linenum);
1149                 } else if (n != 1)
1150                         fatal("%s line %d: Illegal MaxStartups spec.",
1151                             filename, linenum);
1152                 else
1153                         options->max_startups = options->max_startups_begin;
1154                 break;
1155
1156         case sMaxAuthTries:
1157                 intptr = &options->max_authtries;
1158                 goto parse_int;
1159
1160         case sMaxSessions:
1161                 intptr = &options->max_sessions;
1162                 goto parse_int;
1163
1164         case sBanner:
1165                 charptr = &options->banner;
1166                 goto parse_filename;
1167
1168         /*
1169          * These options can contain %X options expanded at
1170          * connect time, so that you can specify paths like:
1171          *
1172          * AuthorizedKeysFile   /etc/ssh_keys/%u
1173          */
1174         case sAuthorizedKeysFile:
1175         case sAuthorizedKeysFile2:
1176                 charptr = (opcode == sAuthorizedKeysFile) ?
1177                     &options->authorized_keys_file :
1178                     &options->authorized_keys_file2;
1179                 goto parse_filename;
1180
1181         case sClientAliveInterval:
1182                 intptr = &options->client_alive_interval;
1183                 goto parse_time;
1184
1185         case sClientAliveCountMax:
1186                 intptr = &options->client_alive_count_max;
1187                 goto parse_int;
1188
1189         case sAcceptEnv:
1190                 while ((arg = strdelim(&cp)) && *arg != '\0') {
1191                         if (strchr(arg, '=') != NULL)
1192                                 fatal("%s line %d: Invalid environment name.",
1193                                     filename, linenum);
1194                         if (options->num_accept_env >= MAX_ACCEPT_ENV)
1195                                 fatal("%s line %d: too many allow env.",
1196                                     filename, linenum);
1197                         if (!*activep)
1198                                 break;
1199                         options->accept_env[options->num_accept_env++] =
1200                             xstrdup(arg);
1201                 }
1202                 break;
1203
1204         case sPermitTunnel:
1205                 intptr = &options->permit_tun;
1206                 arg = strdelim(&cp);
1207                 if (!arg || *arg == '\0')
1208                         fatal("%s line %d: Missing yes/point-to-point/"
1209                             "ethernet/no argument.", filename, linenum);
1210                 value = -1;
1211                 for (i = 0; tunmode_desc[i].val != -1; i++)
1212                         if (strcmp(tunmode_desc[i].text, arg) == 0) {
1213                                 value = tunmode_desc[i].val;
1214                                 break;
1215                         }
1216                 if (value == -1)
1217                         fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1218                             "no argument: %s", filename, linenum, arg);
1219                 if (*intptr == -1)
1220                         *intptr = value;
1221                 break;
1222
1223         case sMatch:
1224                 if (cmdline)
1225                         fatal("Match directive not supported as a command-line "
1226                            "option");
1227                 value = match_cfg_line(&cp, linenum, user, host, address);
1228                 if (value < 0)
1229                         fatal("%s line %d: Bad Match condition", filename,
1230                             linenum);
1231                 *activep = value;
1232                 break;
1233
1234         case sPermitOpen:
1235                 arg = strdelim(&cp);
1236                 if (!arg || *arg == '\0')
1237                         fatal("%s line %d: missing PermitOpen specification",
1238                             filename, linenum);
1239                 n = options->num_permitted_opens;       /* modified later */
1240                 if (strcmp(arg, "any") == 0) {
1241                         if (*activep && n == -1) {
1242                                 channel_clear_adm_permitted_opens();
1243                                 options->num_permitted_opens = 0;
1244                         }
1245                         break;
1246                 }
1247                 if (*activep && n == -1)
1248                         channel_clear_adm_permitted_opens();
1249                 for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
1250                         p = hpdelim(&arg);
1251                         if (p == NULL)
1252                                 fatal("%s line %d: missing host in PermitOpen",
1253                                     filename, linenum);
1254                         p = cleanhostname(p);
1255                         if (arg == NULL || (port = a2port(arg)) == 0)
1256                                 fatal("%s line %d: bad port number in "
1257                                     "PermitOpen", filename, linenum);
1258                         if (*activep && n == -1)
1259                                 options->num_permitted_opens =
1260                                     channel_add_adm_permitted_opens(p, port);
1261                 }
1262                 break;
1263
1264         case sForceCommand:
1265                 if (cp == NULL)
1266                         fatal("%.200s line %d: Missing argument.", filename,
1267                             linenum);
1268                 len = strspn(cp, WHITESPACE);
1269                 if (*activep && options->adm_forced_command == NULL)
1270                         options->adm_forced_command = xstrdup(cp + len);
1271                 return 0;
1272
1273         case sChrootDirectory:
1274                 charptr = &options->chroot_directory;
1275
1276                 arg = strdelim(&cp);
1277                 if (!arg || *arg == '\0')
1278                         fatal("%s line %d: missing file name.",
1279                             filename, linenum);
1280                 if (*activep && *charptr == NULL)
1281                         *charptr = xstrdup(arg);
1282                 break;
1283
1284         case sDeprecated:
1285                 logit("%s line %d: Deprecated option %s",
1286                     filename, linenum, arg);
1287                 while (arg)
1288                     arg = strdelim(&cp);
1289                 break;
1290
1291         case sUnsupported:
1292                 logit("%s line %d: Unsupported option %s",
1293                     filename, linenum, arg);
1294                 while (arg)
1295                     arg = strdelim(&cp);
1296                 break;
1297
1298         default:
1299                 fatal("%s line %d: Missing handler for opcode %s (%d)",
1300                     filename, linenum, arg, opcode);
1301         }
1302         if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1303                 fatal("%s line %d: garbage at end of line; \"%.200s\".",
1304                     filename, linenum, arg);
1305         return 0;
1306 }
1307
1308 /* Reads the server configuration file. */
1309
1310 void
1311 load_server_config(const char *filename, Buffer *conf)
1312 {
1313         char line[1024], *cp;
1314         FILE *f;
1315
1316         debug2("%s: filename %s", __func__, filename);
1317         if ((f = fopen(filename, "r")) == NULL) {
1318                 perror(filename);
1319                 exit(1);
1320         }
1321         buffer_clear(conf);
1322         while (fgets(line, sizeof(line), f)) {
1323                 /*
1324                  * Trim out comments and strip whitespace
1325                  * NB - preserve newlines, they are needed to reproduce
1326                  * line numbers later for error messages
1327                  */
1328                 if ((cp = strchr(line, '#')) != NULL)
1329                         memcpy(cp, "\n", 2);
1330                 cp = line + strspn(line, " \t\r");
1331
1332                 buffer_append(conf, cp, strlen(cp));
1333         }
1334         buffer_append(conf, "\0", 1);
1335         fclose(f);
1336         debug2("%s: done config len = %d", __func__, buffer_len(conf));
1337 }
1338
1339 void
1340 parse_server_match_config(ServerOptions *options, const char *user,
1341     const char *host, const char *address)
1342 {
1343         ServerOptions mo;
1344
1345         initialize_server_options(&mo);
1346         parse_server_config(&mo, "reprocess config", &cfg, user, host, address);
1347         copy_set_server_options(options, &mo, 0);
1348 }
1349
1350 /* Helper macros */
1351 #define M_CP_INTOPT(n) do {\
1352         if (src->n != -1) \
1353                 dst->n = src->n; \
1354 } while (0)
1355 #define M_CP_STROPT(n) do {\
1356         if (src->n != NULL) { \
1357                 if (dst->n != NULL) \
1358                         xfree(dst->n); \
1359                 dst->n = src->n; \
1360         } \
1361 } while(0)
1362
1363 /*
1364  * Copy any supported values that are set.
1365  *
1366  * If the preauth flag is set, we do not bother copying the the string or
1367  * array values that are not used pre-authentication, because any that we
1368  * do use must be explictly sent in mm_getpwnamallow().
1369  */
1370 void
1371 copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
1372 {
1373         M_CP_INTOPT(password_authentication);
1374         M_CP_INTOPT(gss_authentication);
1375         M_CP_INTOPT(rsa_authentication);
1376         M_CP_INTOPT(pubkey_authentication);
1377         M_CP_INTOPT(kerberos_authentication);
1378         M_CP_INTOPT(hostbased_authentication);
1379         M_CP_INTOPT(kbd_interactive_authentication);
1380         M_CP_INTOPT(permit_root_login);
1381
1382         M_CP_INTOPT(allow_tcp_forwarding);
1383         M_CP_INTOPT(allow_agent_forwarding);
1384         M_CP_INTOPT(gateway_ports);
1385         M_CP_INTOPT(x11_display_offset);
1386         M_CP_INTOPT(x11_forwarding);
1387         M_CP_INTOPT(x11_use_localhost);
1388         M_CP_INTOPT(max_sessions);
1389         M_CP_INTOPT(max_authtries);
1390
1391         M_CP_STROPT(banner);
1392         if (preauth)
1393                 return;
1394         M_CP_STROPT(adm_forced_command);
1395         M_CP_STROPT(chroot_directory);
1396 }
1397
1398 #undef M_CP_INTOPT
1399 #undef M_CP_STROPT
1400
1401 void
1402 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1403     const char *user, const char *host, const char *address)
1404 {
1405         int active, linenum, bad_options = 0;
1406         char *cp, *obuf, *cbuf;
1407
1408         debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1409
1410         obuf = cbuf = xstrdup(buffer_ptr(conf));
1411         active = user ? 0 : 1;
1412         linenum = 1;
1413         while ((cp = strsep(&cbuf, "\n")) != NULL) {
1414                 if (process_server_config_line(options, cp, filename,
1415                     linenum++, &active, user, host, address) != 0)
1416                         bad_options++;
1417         }
1418         xfree(obuf);
1419         if (bad_options > 0)
1420                 fatal("%s: terminating, %d bad configuration options",
1421                     filename, bad_options);
1422 }
1423
1424 static const char *
1425 fmt_intarg(ServerOpCodes code, int val)
1426 {
1427         if (code == sAddressFamily) {
1428                 switch (val) {
1429                 case AF_INET:
1430                         return "inet";
1431                 case AF_INET6:
1432                         return "inet6";
1433                 case AF_UNSPEC:
1434                         return "any";
1435                 default:
1436                         return "UNKNOWN";
1437                 }
1438         }
1439         if (code == sPermitRootLogin) {
1440                 switch (val) {
1441                 case PERMIT_NO_PASSWD:
1442                         return "without-passord";
1443                 case PERMIT_FORCED_ONLY:
1444                         return "forced-commands-only";
1445                 case PERMIT_YES:
1446                         return "yes";
1447                 }
1448         }
1449         if (code == sProtocol) {
1450                 switch (val) {
1451                 case SSH_PROTO_1:
1452                         return "1";
1453                 case SSH_PROTO_2:
1454                         return "2";
1455                 case (SSH_PROTO_1|SSH_PROTO_2):
1456                         return "2,1";
1457                 default:
1458                         return "UNKNOWN";
1459                 }
1460         }
1461         if (code == sGatewayPorts && val == 2)
1462                 return "clientspecified";
1463         if (code == sCompression && val == COMP_DELAYED)
1464                 return "delayed";
1465         switch (val) {
1466         case -1:
1467                 return "unset";
1468         case 0:
1469                 return "no";
1470         case 1:
1471                 return "yes";
1472         }
1473         return "UNKNOWN";
1474 }
1475
1476 static const char *
1477 lookup_opcode_name(ServerOpCodes code)
1478 {
1479         u_int i;
1480
1481         for (i = 0; keywords[i].name != NULL; i++)
1482                 if (keywords[i].opcode == code)
1483                         return(keywords[i].name);
1484         return "UNKNOWN";
1485 }
1486
1487 static void
1488 dump_cfg_int(ServerOpCodes code, int val)
1489 {
1490         printf("%s %d\n", lookup_opcode_name(code), val);
1491 }
1492
1493 static void
1494 dump_cfg_fmtint(ServerOpCodes code, int val)
1495 {
1496         printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
1497 }
1498
1499 static void
1500 dump_cfg_string(ServerOpCodes code, const char *val)
1501 {
1502         if (val == NULL)
1503                 return;
1504         printf("%s %s\n", lookup_opcode_name(code), val);
1505 }
1506
1507 static void
1508 dump_cfg_strarray(ServerOpCodes code, u_int count, char **vals)
1509 {
1510         u_int i;
1511
1512         for (i = 0; i < count; i++)
1513                 printf("%s %s\n", lookup_opcode_name(code),  vals[i]);
1514 }
1515
1516 void
1517 dump_config(ServerOptions *o)
1518 {
1519         u_int i;
1520         int ret;
1521         struct addrinfo *ai;
1522         char addr[NI_MAXHOST], port[NI_MAXSERV], *s = NULL;
1523
1524         /* these are usually at the top of the config */
1525         for (i = 0; i < o->num_ports; i++)
1526                 printf("port %d\n", o->ports[i]);
1527         dump_cfg_fmtint(sProtocol, o->protocol);
1528         dump_cfg_fmtint(sAddressFamily, o->address_family);
1529
1530         /* ListenAddress must be after Port */
1531         for (ai = o->listen_addrs; ai; ai = ai->ai_next) {
1532                 if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr,
1533                     sizeof(addr), port, sizeof(port),
1534                     NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
1535                         error("getnameinfo failed: %.100s",
1536                             (ret != EAI_SYSTEM) ? gai_strerror(ret) :
1537                             strerror(errno));
1538                 } else {
1539                         if (ai->ai_family == AF_INET6)
1540                                 printf("listenaddress [%s]:%s\n", addr, port);
1541                         else
1542                                 printf("listenaddress %s:%s\n", addr, port);
1543                 }
1544         }
1545
1546         /* integer arguments */
1547         dump_cfg_int(sServerKeyBits, o->server_key_bits);
1548         dump_cfg_int(sLoginGraceTime, o->login_grace_time);
1549         dump_cfg_int(sKeyRegenerationTime, o->key_regeneration_time);
1550         dump_cfg_int(sX11DisplayOffset, o->x11_display_offset);
1551         dump_cfg_int(sMaxAuthTries, o->max_authtries);
1552         dump_cfg_int(sClientAliveInterval, o->client_alive_interval);
1553         dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max);
1554
1555         /* formatted integer arguments */
1556         dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login);
1557         dump_cfg_fmtint(sIgnoreRhosts, o->ignore_rhosts);
1558         dump_cfg_fmtint(sIgnoreUserKnownHosts, o->ignore_user_known_hosts);
1559         dump_cfg_fmtint(sRhostsRSAAuthentication, o->rhosts_rsa_authentication);
1560         dump_cfg_fmtint(sHostbasedAuthentication, o->hostbased_authentication);
1561         dump_cfg_fmtint(sHostbasedUsesNameFromPacketOnly,
1562             o->hostbased_uses_name_from_packet_only);
1563         dump_cfg_fmtint(sRSAAuthentication, o->rsa_authentication);
1564         dump_cfg_fmtint(sPubkeyAuthentication, o->pubkey_authentication);
1565         dump_cfg_fmtint(sKerberosAuthentication, o->kerberos_authentication);
1566         dump_cfg_fmtint(sKerberosOrLocalPasswd, o->kerberos_or_local_passwd);
1567         dump_cfg_fmtint(sKerberosTicketCleanup, o->kerberos_ticket_cleanup);
1568         dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token);
1569         dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
1570         dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds);
1571         dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
1572         dump_cfg_fmtint(sKbdInteractiveAuthentication,
1573             o->kbd_interactive_authentication);
1574         dump_cfg_fmtint(sChallengeResponseAuthentication,
1575             o->challenge_response_authentication);
1576         dump_cfg_fmtint(sPrintMotd, o->print_motd);
1577         dump_cfg_fmtint(sPrintLastLog, o->print_lastlog);
1578         dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding);
1579         dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost);
1580         dump_cfg_fmtint(sStrictModes, o->strict_modes);
1581         dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive);
1582         dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd);
1583         dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env);
1584         dump_cfg_fmtint(sUseLogin, o->use_login);
1585         dump_cfg_fmtint(sCompression, o->compression);
1586         dump_cfg_fmtint(sGatewayPorts, o->gateway_ports);
1587         dump_cfg_fmtint(sUseDNS, o->use_dns);
1588         dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
1589         dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep);
1590
1591         /* string arguments */
1592         dump_cfg_string(sPidFile, o->pid_file);
1593         dump_cfg_string(sXAuthLocation, o->xauth_location);
1594         dump_cfg_string(sCiphers, o->ciphers);
1595         dump_cfg_string(sMacs, o->macs);
1596         dump_cfg_string(sBanner, o->banner);
1597         dump_cfg_string(sAuthorizedKeysFile, o->authorized_keys_file);
1598         dump_cfg_string(sAuthorizedKeysFile2, o->authorized_keys_file2);
1599         dump_cfg_string(sForceCommand, o->adm_forced_command);
1600
1601         /* string arguments requiring a lookup */
1602         dump_cfg_string(sLogLevel, log_level_name(o->log_level));
1603         dump_cfg_string(sLogFacility, log_facility_name(o->log_facility));
1604
1605         /* string array arguments */
1606         dump_cfg_strarray(sHostKeyFile, o->num_host_key_files,
1607              o->host_key_files);
1608         dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users);
1609         dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users);
1610         dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups);
1611         dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups);
1612         dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env);
1613
1614         /* other arguments */
1615         for (i = 0; i < o->num_subsystems; i++)
1616                 printf("subsystem %s %s\n", o->subsystem_name[i],
1617                     o->subsystem_args[i]);
1618
1619         printf("maxstartups %d:%d:%d\n", o->max_startups_begin,
1620             o->max_startups_rate, o->max_startups);
1621
1622         for (i = 0; tunmode_desc[i].val != -1; i++)
1623                 if (tunmode_desc[i].val == o->permit_tun) {
1624                         s = tunmode_desc[i].text;
1625                         break;
1626                 }
1627         dump_cfg_string(sPermitTunnel, s);
1628
1629         printf("permitopen");
1630         channel_print_adm_permitted_opens();
1631         printf("\n");
1632 }