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