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