summaryrefslogtreecommitdiff
path: root/readconf.c
diff options
context:
space:
mode:
Diffstat (limited to 'readconf.c')
-rw-r--r--readconf.c169
1 files changed, 130 insertions, 39 deletions
diff --git a/readconf.c b/readconf.c
index aca5b8eff..963b706aa 100644
--- a/readconf.c
+++ b/readconf.c
@@ -12,7 +12,7 @@
12 */ 12 */
13 13
14#include "includes.h" 14#include "includes.h"
15RCSID("$OpenBSD: readconf.c,v 1.134 2004/07/11 17:48:47 deraadt Exp $"); 15RCSID("$OpenBSD: readconf.c,v 1.137 2005/03/04 08:48:06 djm Exp $");
16 16
17#include "ssh.h" 17#include "ssh.h"
18#include "xmalloc.h" 18#include "xmalloc.h"
@@ -106,7 +106,7 @@ typedef enum {
106 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, 106 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
107 oAddressFamily, oGssAuthentication, oGssDelegateCreds, 107 oAddressFamily, oGssAuthentication, oGssDelegateCreds,
108 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, 108 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
109 oSendEnv, oControlPath, oControlMaster, 109 oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
110 oProtocolKeepAlives, oSetupTimeOut, 110 oProtocolKeepAlives, oSetupTimeOut,
111 oDeprecated, oUnsupported 111 oDeprecated, oUnsupported
112} OpCodes; 112} OpCodes;
@@ -198,6 +198,7 @@ static struct {
198 { "sendenv", oSendEnv }, 198 { "sendenv", oSendEnv },
199 { "controlpath", oControlPath }, 199 { "controlpath", oControlPath },
200 { "controlmaster", oControlMaster }, 200 { "controlmaster", oControlMaster },
201 { "hashknownhosts", oHashKnownHosts },
201 { "protocolkeepalives", oProtocolKeepAlives }, 202 { "protocolkeepalives", oProtocolKeepAlives },
202 { "setuptimeout", oSetupTimeOut }, 203 { "setuptimeout", oSetupTimeOut },
203 { NULL, oBadOption } 204 { NULL, oBadOption }
@@ -209,21 +210,23 @@ static struct {
209 */ 210 */
210 211
211void 212void
212add_local_forward(Options *options, u_short port, const char *host, 213add_local_forward(Options *options, const Forward *newfwd)
213 u_short host_port)
214{ 214{
215 Forward *fwd; 215 Forward *fwd;
216#ifndef NO_IPPORT_RESERVED_CONCEPT 216#ifndef NO_IPPORT_RESERVED_CONCEPT
217 extern uid_t original_real_uid; 217 extern uid_t original_real_uid;
218 if (port < IPPORT_RESERVED && original_real_uid != 0) 218 if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0)
219 fatal("Privileged ports can only be forwarded by root."); 219 fatal("Privileged ports can only be forwarded by root.");
220#endif 220#endif
221 if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) 221 if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
222 fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION); 222 fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
223 fwd = &options->local_forwards[options->num_local_forwards++]; 223 fwd = &options->local_forwards[options->num_local_forwards++];
224 fwd->port = port; 224
225 fwd->host = xstrdup(host); 225 fwd->listen_host = (newfwd->listen_host == NULL) ?
226 fwd->host_port = host_port; 226 NULL : xstrdup(newfwd->listen_host);
227 fwd->listen_port = newfwd->listen_port;
228 fwd->connect_host = xstrdup(newfwd->connect_host);
229 fwd->connect_port = newfwd->connect_port;
227} 230}
228 231
229/* 232/*
@@ -232,17 +235,19 @@ add_local_forward(Options *options, u_short port, const char *host,
232 */ 235 */
233 236
234void 237void
235add_remote_forward(Options *options, u_short port, const char *host, 238add_remote_forward(Options *options, const Forward *newfwd)
236 u_short host_port)
237{ 239{
238 Forward *fwd; 240 Forward *fwd;
239 if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) 241 if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
240 fatal("Too many remote forwards (max %d).", 242 fatal("Too many remote forwards (max %d).",
241 SSH_MAX_FORWARDS_PER_DIRECTION); 243 SSH_MAX_FORWARDS_PER_DIRECTION);
242 fwd = &options->remote_forwards[options->num_remote_forwards++]; 244 fwd = &options->remote_forwards[options->num_remote_forwards++];
243 fwd->port = port; 245
244 fwd->host = xstrdup(host); 246 fwd->listen_host = (newfwd->listen_host == NULL) ?
245 fwd->host_port = host_port; 247 NULL : xstrdup(newfwd->listen_host);
248 fwd->listen_port = newfwd->listen_port;
249 fwd->connect_host = xstrdup(newfwd->connect_host);
250 fwd->connect_port = newfwd->connect_port;
246} 251}
247 252
248static void 253static void
@@ -250,11 +255,15 @@ clear_forwardings(Options *options)
250{ 255{
251 int i; 256 int i;
252 257
253 for (i = 0; i < options->num_local_forwards; i++) 258 for (i = 0; i < options->num_local_forwards; i++) {
254 xfree(options->local_forwards[i].host); 259 xfree(options->local_forwards[i].listen_host);
260 xfree(options->local_forwards[i].connect_host);
261 }
255 options->num_local_forwards = 0; 262 options->num_local_forwards = 0;
256 for (i = 0; i < options->num_remote_forwards; i++) 263 for (i = 0; i < options->num_remote_forwards; i++) {
257 xfree(options->remote_forwards[i].host); 264 xfree(options->remote_forwards[i].listen_host);
265 xfree(options->remote_forwards[i].connect_host);
266 }
258 options->num_remote_forwards = 0; 267 options->num_remote_forwards = 0;
259} 268}
260 269
@@ -287,11 +296,10 @@ process_config_line(Options *options, const char *host,
287 char *line, const char *filename, int linenum, 296 char *line, const char *filename, int linenum,
288 int *activep) 297 int *activep)
289{ 298{
290 char buf[256], *s, **charptr, *endofnumber, *keyword, *arg; 299 char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256];
291 int opcode, *intptr, value; 300 int opcode, *intptr, value;
292 size_t len; 301 size_t len;
293 u_short fwd_port, fwd_host_port; 302 Forward fwd;
294 char sfwd_host_port[6];
295 303
296 /* Strip trailing whitespace */ 304 /* Strip trailing whitespace */
297 for(len = strlen(line) - 1; len > 0; len--) { 305 for(len = strlen(line) - 1; len > 0; len--) {
@@ -648,30 +656,26 @@ parse_int:
648 case oLocalForward: 656 case oLocalForward:
649 case oRemoteForward: 657 case oRemoteForward:
650 arg = strdelim(&s); 658 arg = strdelim(&s);
651 if (!arg || *arg == '\0') 659 if (arg == NULL || *arg == '\0')
652 fatal("%.200s line %d: Missing port argument.", 660 fatal("%.200s line %d: Missing port argument.",
653 filename, linenum); 661 filename, linenum);
654 if ((fwd_port = a2port(arg)) == 0) 662 arg2 = strdelim(&s);
655 fatal("%.200s line %d: Bad listen port.", 663 if (arg2 == NULL || *arg2 == '\0')
664 fatal("%.200s line %d: Missing target argument.",
656 filename, linenum); 665 filename, linenum);
657 arg = strdelim(&s); 666
658 if (!arg || *arg == '\0') 667 /* construct a string for parse_forward */
659 fatal("%.200s line %d: Missing second argument.", 668 snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
660 filename, linenum); 669
661 if (sscanf(arg, "%255[^:]:%5[0-9]", buf, sfwd_host_port) != 2 && 670 if (parse_forward(&fwd, fwdarg) == 0)
662 sscanf(arg, "%255[^/]/%5[0-9]", buf, sfwd_host_port) != 2)
663 fatal("%.200s line %d: Bad forwarding specification.", 671 fatal("%.200s line %d: Bad forwarding specification.",
664 filename, linenum); 672 filename, linenum);
665 if ((fwd_host_port = a2port(sfwd_host_port)) == 0) 673
666 fatal("%.200s line %d: Bad forwarding port.",
667 filename, linenum);
668 if (*activep) { 674 if (*activep) {
669 if (opcode == oLocalForward) 675 if (opcode == oLocalForward)
670 add_local_forward(options, fwd_port, buf, 676 add_local_forward(options, &fwd);
671 fwd_host_port);
672 else if (opcode == oRemoteForward) 677 else if (opcode == oRemoteForward)
673 add_remote_forward(options, fwd_port, buf, 678 add_remote_forward(options, &fwd);
674 fwd_host_port);
675 } 679 }
676 break; 680 break;
677 681
@@ -680,12 +684,25 @@ parse_int:
680 if (!arg || *arg == '\0') 684 if (!arg || *arg == '\0')
681 fatal("%.200s line %d: Missing port argument.", 685 fatal("%.200s line %d: Missing port argument.",
682 filename, linenum); 686 filename, linenum);
683 fwd_port = a2port(arg); 687 memset(&fwd, '\0', sizeof(fwd));
684 if (fwd_port == 0) 688 fwd.connect_host = "socks";
689 fwd.listen_host = hpdelim(&arg);
690 if (fwd.listen_host == NULL ||
691 strlen(fwd.listen_host) >= NI_MAXHOST)
692 fatal("%.200s line %d: Bad forwarding specification.",
693 filename, linenum);
694 if (arg) {
695 fwd.listen_port = a2port(arg);
696 fwd.listen_host = cleanhostname(fwd.listen_host);
697 } else {
698 fwd.listen_port = a2port(fwd.listen_host);
699 fwd.listen_host = "";
700 }
701 if (fwd.listen_port == 0)
685 fatal("%.200s line %d: Badly formatted port number.", 702 fatal("%.200s line %d: Badly formatted port number.",
686 filename, linenum); 703 filename, linenum);
687 if (*activep) 704 if (*activep)
688 add_local_forward(options, fwd_port, "socks", 0); 705 add_local_forward(options, &fwd);
689 break; 706 break;
690 707
691 case oClearAllForwardings: 708 case oClearAllForwardings:
@@ -762,6 +779,8 @@ parse_int:
762 if (strchr(arg, '=') != NULL) 779 if (strchr(arg, '=') != NULL)
763 fatal("%s line %d: Invalid environment name.", 780 fatal("%s line %d: Invalid environment name.",
764 filename, linenum); 781 filename, linenum);
782 if (!*activep)
783 continue;
765 if (options->num_send_env >= MAX_SEND_ENV) 784 if (options->num_send_env >= MAX_SEND_ENV)
766 fatal("%s line %d: too many send env.", 785 fatal("%s line %d: too many send env.",
767 filename, linenum); 786 filename, linenum);
@@ -778,6 +797,10 @@ parse_int:
778 intptr = &options->control_master; 797 intptr = &options->control_master;
779 goto parse_yesnoask; 798 goto parse_yesnoask;
780 799
800 case oHashKnownHosts:
801 intptr = &options->hash_known_hosts;
802 goto parse_flag;
803
781 case oSetupTimeOut: 804 case oSetupTimeOut:
782 intptr = &options->setuptimeout; 805 intptr = &options->setuptimeout;
783 goto parse_int; 806 goto parse_int;
@@ -926,6 +949,7 @@ initialize_options(Options * options)
926 options->num_send_env = 0; 949 options->num_send_env = 0;
927 options->control_path = NULL; 950 options->control_path = NULL;
928 options->control_master = -1; 951 options->control_master = -1;
952 options->hash_known_hosts = -1;
929} 953}
930 954
931/* 955/*
@@ -1053,6 +1077,8 @@ fill_default_options(Options * options)
1053 options->server_alive_count_max = 3; 1077 options->server_alive_count_max = 3;
1054 if (options->control_master == -1) 1078 if (options->control_master == -1)
1055 options->control_master = 0; 1079 options->control_master = 0;
1080 if (options->hash_known_hosts == -1)
1081 options->hash_known_hosts = 0;
1056 if (options->setuptimeout == -1) { 1082 if (options->setuptimeout == -1) {
1057 /* in batch mode, default is 5mins */ 1083 /* in batch mode, default is 5mins */
1058 if (options->batch_mode == 1) 1084 if (options->batch_mode == 1)
@@ -1066,3 +1092,68 @@ fill_default_options(Options * options)
1066 /* options->host_key_alias should not be set by default */ 1092 /* options->host_key_alias should not be set by default */
1067 /* options->preferred_authentications will be set in ssh */ 1093 /* options->preferred_authentications will be set in ssh */
1068} 1094}
1095
1096/*
1097 * parse_forward
1098 * parses a string containing a port forwarding specification of the form:
1099 * [listenhost:]listenport:connecthost:connectport
1100 * returns number of arguments parsed or zero on error
1101 */
1102int
1103parse_forward(Forward *fwd, const char *fwdspec)
1104{
1105 int i;
1106 char *p, *cp, *fwdarg[4];
1107
1108 memset(fwd, '\0', sizeof(*fwd));
1109
1110 cp = p = xstrdup(fwdspec);
1111
1112 /* skip leading spaces */
1113 while (*cp && isspace(*cp))
1114 cp++;
1115
1116 for (i = 0; i < 4; ++i)
1117 if ((fwdarg[i] = hpdelim(&cp)) == NULL)
1118 break;
1119
1120 /* Check for trailing garbage in 4-arg case*/
1121 if (cp != NULL)
1122 i = 0; /* failure */
1123
1124 switch (i) {
1125 case 3:
1126 fwd->listen_host = NULL;
1127 fwd->listen_port = a2port(fwdarg[0]);
1128 fwd->connect_host = xstrdup(cleanhostname(fwdarg[1]));
1129 fwd->connect_port = a2port(fwdarg[2]);
1130 break;
1131
1132 case 4:
1133 fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
1134 fwd->listen_port = a2port(fwdarg[1]);
1135 fwd->connect_host = xstrdup(cleanhostname(fwdarg[2]));
1136 fwd->connect_port = a2port(fwdarg[3]);
1137 break;
1138 default:
1139 i = 0; /* failure */
1140 }
1141
1142 xfree(p);
1143
1144 if (fwd->listen_port == 0 && fwd->connect_port == 0)
1145 goto fail_free;
1146
1147 if (fwd->connect_host != NULL &&
1148 strlen(fwd->connect_host) >= NI_MAXHOST)
1149 goto fail_free;
1150
1151 return (i);
1152
1153 fail_free:
1154 if (fwd->connect_host != NULL)
1155 xfree(fwd->connect_host);
1156 if (fwd->listen_host != NULL)
1157 xfree(fwd->listen_host);
1158 return (0);
1159}