Mercurial > dropbear
comparison cli-runopts.c @ 118:5312ca05ed48 private-rez
propagate of 717950f4061f1123659ee87c7c168805af920ab7 and 839f98f136788cc1466e4641bf796f96040a085d from branch 'matt.dbclient.authpam' to 'matt.dbclient.rez'
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sun, 12 Sep 2004 04:56:50 +0000 |
parents | 68b84c20ca1e |
children | 6b306ad5f5b5 |
comparison
equal
deleted
inserted
replaced
57:3b2a5a1c4347 | 118:5312ca05ed48 |
---|---|
26 #include "runopts.h" | 26 #include "runopts.h" |
27 #include "signkey.h" | 27 #include "signkey.h" |
28 #include "buffer.h" | 28 #include "buffer.h" |
29 #include "dbutil.h" | 29 #include "dbutil.h" |
30 #include "algo.h" | 30 #include "algo.h" |
31 #include "tcpfwd.h" | |
31 | 32 |
32 cli_runopts cli_opts; /* GLOBAL */ | 33 cli_runopts cli_opts; /* GLOBAL */ |
33 | 34 |
34 static void printhelp(); | 35 static void printhelp(); |
35 static void parsehostname(char* userhostarg); | 36 static void parsehostname(char* userhostarg); |
36 #ifdef DROPBEAR_PUBKEY_AUTH | 37 #ifdef ENABLE_CLI_PUBKEY_AUTH |
37 static void loadidentityfile(const char* filename); | 38 static void loadidentityfile(const char* filename); |
38 #endif | 39 #endif |
40 #ifdef ENABLE_CLI_ANYTCPFWD | |
41 static void addforward(char* str, struct TCPFwdList** fwdlist); | |
42 #endif | |
39 | 43 |
40 static void printhelp() { | 44 static void printhelp() { |
41 | 45 |
42 fprintf(stderr, "Dropbear client v%s\n" | 46 fprintf(stderr, "Dropbear client v%s\n" |
43 "Usage: %s [options] user@host\n" | 47 "Usage: %s [options] [user@]host\n" |
44 "Options are:\n" | 48 "Options are:\n" |
45 "-p <remoteport>\n" | 49 "-p <remoteport>\n" |
46 "-t Allocate a pty\n" | 50 "-t Allocate a pty\n" |
47 "-T Don't allocate a pty\n" | 51 "-T Don't allocate a pty\n" |
48 #ifdef DROPBEAR_PUBKEY_AUTH | 52 #ifdef ENABLE_CLI_PUBKEY_AUTH |
49 "-i <identityfile> (multiple allowed)\n" | 53 "-i <identityfile> (multiple allowed)\n" |
54 #endif | |
55 #ifdef ENABLE_CLI_LOCALTCPFWD | |
56 "-L <listenport:remotehsot:reportport> Local port forwarding\n" | |
57 #endif | |
58 #ifdef ENABLE_CLI_REMOTETCPFWD | |
59 "-R <listenport:remotehost:remoteport> Remote port forwarding\n" | |
60 #endif | |
61 "-l <username>\n" | |
62 #ifdef DEBUG_TRACE | |
63 "-v verbose\n" | |
50 #endif | 64 #endif |
51 ,DROPBEAR_VERSION, cli_opts.progname); | 65 ,DROPBEAR_VERSION, cli_opts.progname); |
52 } | 66 } |
53 | 67 |
54 void cli_getopts(int argc, char ** argv) { | 68 void cli_getopts(int argc, char ** argv) { |
55 | 69 |
56 unsigned int i, j; | 70 unsigned int i, j; |
57 char ** next = 0; | 71 char ** next = 0; |
58 unsigned int cmdlen; | 72 unsigned int cmdlen; |
59 #ifdef DROPBEAR_PUBKEY_AUTH | 73 #ifdef ENABLE_CLI_PUBKEY_AUTH |
60 int nextiskey = 0; /* A flag if the next argument is a keyfile */ | 74 int nextiskey = 0; /* A flag if the next argument is a keyfile */ |
61 #endif | 75 #endif |
62 | 76 #ifdef ENABLE_CLI_LOCALTCPFWD |
63 | 77 int nextislocal = 0; |
78 #endif | |
79 #ifdef ENABLE_CLI_REMOTETCPFWD | |
80 int nextisremote = 0; | |
81 #endif | |
82 char* dummy = NULL; /* Not used for anything real */ | |
64 | 83 |
65 /* see printhelp() for options */ | 84 /* see printhelp() for options */ |
66 cli_opts.progname = argv[0]; | 85 cli_opts.progname = argv[0]; |
67 cli_opts.remotehost = NULL; | 86 cli_opts.remotehost = NULL; |
68 cli_opts.remoteport = NULL; | 87 cli_opts.remoteport = NULL; |
69 cli_opts.username = NULL; | 88 cli_opts.username = NULL; |
70 cli_opts.cmd = NULL; | 89 cli_opts.cmd = NULL; |
71 cli_opts.wantpty = 9; /* 9 means "it hasn't been touched", gets set later */ | 90 cli_opts.wantpty = 9; /* 9 means "it hasn't been touched", gets set later */ |
72 #ifdef DROPBEAR_PUBKEY_AUTH | 91 #ifdef ENABLE_CLI_PUBKEY_AUTH |
73 cli_opts.pubkeys = NULL; | 92 cli_opts.pubkeys = NULL; |
93 #endif | |
94 #ifdef ENABLE_CLI_LOCALTCPFWD | |
95 cli_opts.localfwds = NULL; | |
96 #endif | |
97 #ifdef ENABLE_CLI_REMOTETCPFWD | |
98 cli_opts.remotefwds = NULL; | |
74 #endif | 99 #endif |
75 opts.nolocaltcp = 0; | 100 opts.nolocaltcp = 0; |
76 opts.noremotetcp = 0; | 101 opts.noremotetcp = 0; |
77 /* not yet | 102 /* not yet |
78 opts.ipv4 = 1; | 103 opts.ipv4 = 1; |
79 opts.ipv6 = 1; | 104 opts.ipv6 = 1; |
80 */ | 105 */ |
81 | 106 |
82 /* Iterate all the arguments */ | 107 /* Iterate all the arguments */ |
83 for (i = 1; i < (unsigned int)argc; i++) { | 108 for (i = 1; i < (unsigned int)argc; i++) { |
84 #ifdef DROPBEAR_PUBKEY_AUTH | 109 #ifdef ENABLE_CLI_PUBKEY_AUTH |
85 if (nextiskey) { | 110 if (nextiskey) { |
86 /* Load a hostkey since the previous argument was "-i" */ | 111 /* Load a hostkey since the previous argument was "-i" */ |
87 loadidentityfile(argv[i]); | 112 loadidentityfile(argv[i]); |
88 nextiskey = 0; | 113 nextiskey = 0; |
114 continue; | |
115 } | |
116 #endif | |
117 #ifdef ENABLE_CLI_REMOTETCPFWD | |
118 if (nextisremote) { | |
119 TRACE(("nextisremote true")); | |
120 addforward(argv[i], &cli_opts.remotefwds); | |
121 nextisremote = 0; | |
122 continue; | |
123 } | |
124 #endif | |
125 #ifdef ENABLE_CLI_LOCALTCPFWD | |
126 if (nextislocal) { | |
127 TRACE(("nextislocal true")); | |
128 addforward(argv[i], &cli_opts.localfwds); | |
129 nextislocal = 0; | |
89 continue; | 130 continue; |
90 } | 131 } |
91 #endif | 132 #endif |
92 if (next) { | 133 if (next) { |
93 /* The previous flag set a value to assign */ | 134 /* The previous flag set a value to assign */ |
104 | 145 |
105 switch (argv[i][1]) { | 146 switch (argv[i][1]) { |
106 case 'p': /* remoteport */ | 147 case 'p': /* remoteport */ |
107 next = &cli_opts.remoteport; | 148 next = &cli_opts.remoteport; |
108 break; | 149 break; |
109 #ifdef DROPBEAR_PUBKEY_AUTH | 150 #ifdef ENABLE_CLI_PUBKEY_AUTH |
110 case 'i': /* an identityfile */ | 151 case 'i': /* an identityfile */ |
111 nextiskey = 1; | 152 nextiskey = 1; |
112 break; | 153 break; |
113 #endif | 154 #endif |
114 case 't': /* we want a pty */ | 155 case 't': /* we want a pty */ |
115 cli_opts.wantpty = 1; | 156 cli_opts.wantpty = 1; |
116 break; | 157 break; |
117 case 'T': /* don't want a pty */ | 158 case 'T': /* don't want a pty */ |
118 cli_opts.wantpty = 0; | 159 cli_opts.wantpty = 0; |
119 break; | 160 break; |
161 #ifdef ENABLE_CLI_LOCALTCPFWD | |
162 case 'L': | |
163 nextislocal = 1; | |
164 break; | |
165 #endif | |
166 #ifdef ENABLE_CLI_REMOTETCPFWD | |
167 case 'R': | |
168 nextisremote = 1; | |
169 break; | |
170 #endif | |
171 case 'l': | |
172 next = &cli_opts.username; | |
173 break; | |
174 case 'h': | |
175 printhelp(); | |
176 exit(EXIT_SUCCESS); | |
177 break; | |
178 #ifdef DEBUG_TRACE | |
179 case 'v': | |
180 debug_trace = 1; | |
181 break; | |
182 #endif | |
183 case 'F': | |
184 case 'e': | |
185 case 'c': | |
186 case 'm': | |
187 case 'D': | |
188 #ifndef ENABLE_CLI_REMOTETCPFWD | |
189 case 'R': | |
190 #endif | |
191 #ifndef ENABLE_CLI_LOCALTCPFWD | |
192 case 'L': | |
193 #endif | |
194 case 'o': | |
195 case 'b': | |
196 next = &dummy; | |
120 default: | 197 default: |
121 fprintf(stderr, "Unknown argument '%s'\n", argv[i]); | 198 fprintf(stderr, |
122 printhelp(); | 199 "WARNING: Ignoring unknown argument '%s'\n", argv[i]); |
123 exit(EXIT_FAILURE); | |
124 break; | 200 break; |
125 } /* Switch */ | 201 } /* Switch */ |
202 | |
203 /* Now we handle args where they might be "-luser" (no spaces)*/ | |
204 if (next && strlen(argv[i]) > 2) { | |
205 *next = &argv[i][2]; | |
206 next = NULL; | |
207 } | |
126 | 208 |
127 continue; /* next argument */ | 209 continue; /* next argument */ |
128 | 210 |
129 } else { | 211 } else { |
130 TRACE(("non-flag arg")); | 212 TRACE(("non-flag arg: '%s'", argv[i])); |
131 | 213 |
132 /* Either the hostname or commands */ | 214 /* Either the hostname or commands */ |
133 | 215 |
134 if (cli_opts.remotehost == NULL) { | 216 if (cli_opts.remotehost == NULL) { |
135 | 217 |
160 } | 242 } |
161 } | 243 } |
162 } | 244 } |
163 | 245 |
164 if (cli_opts.remotehost == NULL) { | 246 if (cli_opts.remotehost == NULL) { |
165 dropbear_exit("Bad syntax"); | 247 printhelp(); |
248 exit(EXIT_FAILURE); | |
166 } | 249 } |
167 | 250 |
168 if (cli_opts.remoteport == NULL) { | 251 if (cli_opts.remoteport == NULL) { |
169 cli_opts.remoteport = "22"; | 252 cli_opts.remoteport = "22"; |
170 } | 253 } |
178 cli_opts.wantpty = 0; | 261 cli_opts.wantpty = 0; |
179 } | 262 } |
180 } | 263 } |
181 } | 264 } |
182 | 265 |
183 #ifdef DROPBEAR_PUBKEY_AUTH | 266 #ifdef ENABLE_CLI_PUBKEY_AUTH |
184 static void loadidentityfile(const char* filename) { | 267 static void loadidentityfile(const char* filename) { |
185 | 268 |
186 struct PubkeyList * nextkey; | 269 struct PubkeyList * nextkey; |
187 sign_key *key; | 270 sign_key *key; |
188 int keytype; | 271 int keytype; |
206 #endif | 289 #endif |
207 | 290 |
208 | 291 |
209 /* Parses a [user@]hostname argument. userhostarg is the argv[i] corresponding | 292 /* Parses a [user@]hostname argument. userhostarg is the argv[i] corresponding |
210 * - note that it will be modified */ | 293 * - note that it will be modified */ |
211 static void parsehostname(char* userhostarg) { | 294 static void parsehostname(char* orighostarg) { |
212 | 295 |
213 uid_t uid; | 296 uid_t uid; |
214 struct passwd *pw = NULL; | 297 struct passwd *pw = NULL; |
298 char *userhostarg = NULL; | |
299 | |
300 /* We probably don't want to be editing argvs */ | |
301 userhostarg = m_strdup(orighostarg); | |
215 | 302 |
216 cli_opts.remotehost = strchr(userhostarg, '@'); | 303 cli_opts.remotehost = strchr(userhostarg, '@'); |
217 if (cli_opts.remotehost == NULL) { | 304 if (cli_opts.remotehost == NULL) { |
218 /* no username portion, the cli-auth.c code can figure the | 305 /* no username portion, the cli-auth.c code can figure the |
219 * local user's name */ | 306 * local user's name */ |
237 | 324 |
238 if (cli_opts.remotehost[0] == '\0') { | 325 if (cli_opts.remotehost[0] == '\0') { |
239 dropbear_exit("Bad hostname"); | 326 dropbear_exit("Bad hostname"); |
240 } | 327 } |
241 } | 328 } |
329 | |
330 #ifdef ENABLE_CLI_ANYTCPFWD | |
331 /* Turn a "listenport:remoteaddr:remoteport" string into into a forwarding | |
332 * set, and add it to the forwarding list */ | |
333 static void addforward(char* origstr, struct TCPFwdList** fwdlist) { | |
334 | |
335 char * listenport = NULL; | |
336 char * connectport = NULL; | |
337 char * connectaddr = NULL; | |
338 struct TCPFwdList* newfwd = NULL; | |
339 char * str = NULL; | |
340 | |
341 TRACE(("enter addforward")); | |
342 | |
343 /* We probably don't want to be editing argvs */ | |
344 str = m_strdup(origstr); | |
345 | |
346 listenport = str; | |
347 | |
348 connectaddr = strchr(str, ':'); | |
349 if (connectaddr == NULL) { | |
350 TRACE(("connectaddr == NULL")); | |
351 goto fail; | |
352 } | |
353 | |
354 connectaddr[0] = '\0'; | |
355 connectaddr++; | |
356 | |
357 connectport = strchr(connectaddr, ':'); | |
358 if (connectport == NULL) { | |
359 TRACE(("connectport == NULL")); | |
360 goto fail; | |
361 } | |
362 | |
363 connectport[0] = '\0'; | |
364 connectport++; | |
365 | |
366 newfwd = (struct TCPFwdList*)m_malloc(sizeof(struct TCPFwdList)); | |
367 | |
368 /* Now we check the ports - note that the port ints are unsigned, | |
369 * the check later only checks for >= MAX_PORT */ | |
370 newfwd->listenport = strtol(listenport, NULL, 10); | |
371 if (errno != 0) { | |
372 TRACE(("bad listenport strtol")); | |
373 goto fail; | |
374 } | |
375 | |
376 newfwd->connectport = strtol(connectport, NULL, 10); | |
377 if (errno != 0) { | |
378 TRACE(("bad connectport strtol")); | |
379 goto fail; | |
380 } | |
381 | |
382 newfwd->connectaddr = connectaddr; | |
383 | |
384 if (newfwd->listenport > 65535) { | |
385 TRACE(("listenport > 65535")); | |
386 goto badport; | |
387 } | |
388 | |
389 if (newfwd->connectport > 65535) { | |
390 TRACE(("connectport > 65535")); | |
391 goto badport; | |
392 } | |
393 | |
394 newfwd->next = *fwdlist; | |
395 *fwdlist = newfwd; | |
396 | |
397 TRACE(("leave addforward: done")); | |
398 return; | |
399 | |
400 fail: | |
401 dropbear_exit("Bad TCP forward '%s'", origstr); | |
402 | |
403 badport: | |
404 dropbear_exit("Bad TCP port in '%s'", origstr); | |
405 } | |
406 #endif |