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