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