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