comparison cli-runopts.c @ 487:2e17f82a7330

Add multihop 'onion-forwarding' mode. Needs refinement, works.
author Matt Johnston <matt@ucc.asn.au>
date Thu, 18 Sep 2008 14:47:02 +0000
parents d59f628e7baa
children 79c657a673ec
comparison
equal deleted inserted replaced
486:d59f628e7baa 487:2e17f82a7330
31 #include "tcpfwd.h" 31 #include "tcpfwd.h"
32 32
33 cli_runopts cli_opts; /* GLOBAL */ 33 cli_runopts cli_opts; /* GLOBAL */
34 34
35 static void printhelp(); 35 static void printhelp();
36 static void parsehostname(const char* orighostarg); 36 static void parsehostname(const char* orighostarg, const char* argv0);
37 static void fill_own_user(); 37 static void fill_own_user();
38 #ifdef ENABLE_CLI_PUBKEY_AUTH 38 #ifdef ENABLE_CLI_PUBKEY_AUTH
39 static void loadidentityfile(const char* filename); 39 static void loadidentityfile(const char* filename);
40 #endif 40 #endif
41 #ifdef ENABLE_CLI_ANYTCPFWD 41 #ifdef ENABLE_CLI_ANYTCPFWD
289 289
290 /* Either the hostname or commands */ 290 /* Either the hostname or commands */
291 291
292 if (cli_opts.remotehost == NULL) { 292 if (cli_opts.remotehost == NULL) {
293 293
294 parsehostname(argv[i]); 294 parsehostname(argv[i], argv[0]);
295 295
296 } else { 296 } else {
297 297
298 /* this is part of the commands to send - after this we 298 /* this is part of the commands to send - after this we
299 * don't parse any more options, and flags are sent as the 299 * don't parse any more options, and flags are sent as the
317 break; 317 break;
318 } 318 }
319 } 319 }
320 } 320 }
321 321
322 /* And now a few sanity checks and setup */
323
322 if (cli_opts.remotehost == NULL) { 324 if (cli_opts.remotehost == NULL) {
323 printhelp(); 325 printhelp();
324 exit(EXIT_FAILURE); 326 exit(EXIT_FAILURE);
325 } 327 }
326 328
353 opts.keepalive_secs = strtoul(keepalive_arg, NULL, 10); 355 opts.keepalive_secs = strtoul(keepalive_arg, NULL, 10);
354 if (opts.keepalive_secs == 0 && errno == EINVAL) { 356 if (opts.keepalive_secs == 0 && errno == EINVAL) {
355 dropbear_exit("Bad keepalive '%s'", keepalive_arg); 357 dropbear_exit("Bad keepalive '%s'", keepalive_arg);
356 } 358 }
357 } 359 }
360
361 #ifdef ENABLE_CLI_NETCAT
362 if (cli_opts.cmd && cli_opts.netcat_host) {
363 dropbear_log(LOG_INFO, "Ignoring command '%s' in netcat mode", cli_opts.cmd);
364 }
365 #endif
358 366
359 } 367 }
360 368
361 #ifdef ENABLE_CLI_PUBKEY_AUTH 369 #ifdef ENABLE_CLI_PUBKEY_AUTH
362 static void loadidentityfile(const char* filename) { 370 static void loadidentityfile(const char* filename) {
381 cli_opts.privkeys = nextkey; 389 cli_opts.privkeys = nextkey;
382 } 390 }
383 } 391 }
384 #endif 392 #endif
385 393
386 394 #ifdef ENABLE_CLI_MULTIHOP
387 /* Parses a [user@]hostname argument. orighostarg is the argv[i] corresponding */ 395
388 static void parsehostname(const char* orighostarg) { 396 /* Sets up 'onion-forwarding' connections.
389 397 * As an example, if the cmdline is
390 uid_t uid; 398 * dbclient wrt,madako,canyons
391 struct passwd *pw = NULL; 399 * then we want to run:
400 * dbclient -J "dbclient -B canyons:22 wrt,madako" canyons
401 * and then the inner dbclient will recursively run:
402 * dbclient -J "dbclient -B madako:22 wrt" madako
403 * etc for as many hosts as we want.
404 */
405 static void parsehostname(const char* orighostarg, const char* argv0) {
392 char *userhostarg = NULL; 406 char *userhostarg = NULL;
407 char *last_hop = NULL;;
408 char *remainder = NULL;
393 409
394 userhostarg = m_strdup(orighostarg); 410 userhostarg = m_strdup(orighostarg);
411
412 last_hop = strrchr(userhostarg, ',');
413 if (last_hop) {
414 if (last_hop == userhostarg) {
415 dropbear_exit("Bad multi-hop hostnames");
416 }
417 *last_hop = '\0';
418 last_hop++;
419 remainder = userhostarg;
420 userhostarg = last_hop;
421 }
395 422
396 cli_opts.remotehost = strchr(userhostarg, '@'); 423 cli_opts.remotehost = strchr(userhostarg, '@');
397 if (cli_opts.remotehost == NULL) { 424 if (cli_opts.remotehost == NULL) {
398 /* no username portion, the cli-auth.c code can figure the 425 /* no username portion, the cli-auth.c code can figure the
399 * local user's name */ 426 * local user's name */
409 } 436 }
410 437
411 if (cli_opts.remotehost[0] == '\0') { 438 if (cli_opts.remotehost[0] == '\0') {
412 dropbear_exit("Bad hostname"); 439 dropbear_exit("Bad hostname");
413 } 440 }
414 } 441
442 if (last_hop) {
443 /* Set up the proxycmd */
444 unsigned int cmd_len = 0;
445 if (cli_opts.proxycmd) {
446 dropbear_exit("-J can't be used with multihop mode");
447 }
448 if (cli_opts.remoteport == NULL) {
449 cli_opts.remoteport = "22";
450 }
451 cmd_len = strlen(remainder)
452 + strlen(cli_opts.remotehost) + strlen(cli_opts.remoteport)
453 + strlen(argv0) + 30;
454 cli_opts.proxycmd = m_malloc(cmd_len);
455 snprintf(cli_opts.proxycmd, cmd_len, "%s -B %s:%s %s",
456 argv0, cli_opts.remotehost, cli_opts.remoteport, remainder);
457 dropbear_log(LOG_INFO, "proxycmd: '%s'", cli_opts.proxycmd);
458 }
459 }
460
461 #else /* !ENABLE_CLI_MULTIHOP */
462
463 /* Parses a [user@]hostname argument. orighostarg is the argv[i] corresponding */
464 static void parsehostname(const char* orighostarg, const char* argv0) {
465 char *userhostarg = NULL;
466
467 userhostarg = m_strdup(orighostarg);
468
469 cli_opts.remotehost = strchr(userhostarg, '@');
470 if (cli_opts.remotehost == NULL) {
471 /* no username portion, the cli-auth.c code can figure the
472 * local user's name */
473 cli_opts.remotehost = userhostarg;
474 } else {
475 cli_opts.remotehost[0] = '\0'; /* Split the user/host */
476 cli_opts.remotehost++;
477 cli_opts.username = userhostarg;
478 }
479
480 if (cli_opts.username == NULL) {
481 cli_opts.username = m_strdup(cli_opts.own_user);
482 }
483
484 if (cli_opts.remotehost[0] == '\0') {
485 dropbear_exit("Bad hostname");
486 }
487 }
488
489 #endif /* !ENABLE_CLI_MULTIHOP */
415 490
416 #ifdef ENABLE_CLI_NETCAT 491 #ifdef ENABLE_CLI_NETCAT
417 static void add_netcat(const char* origstr) { 492 static void add_netcat(const char* origstr) {
418 char *portstr = NULL; 493 char *portstr = NULL;
419 494