📄 whackinit.c
字号:
setuid(getuid()); /* give up any group priveledges, if we had any */ setgid(getgid()); return sock;}/* This is a hack for initiating ISAKMP exchanges. */intmain(int argc, char **argv){ struct whack_message msg; lset_t opts_seen = LEMPTY, cd_seen = LEMPTY; char xauthname[128]; char xauthpass[128]; int xauthnamelen, xauthpasslen; bool gotxauthname = FALSE, gotxauthpass = FALSE; int sock; /* get socket, and then drop root */ sock = setup_socket(); /* check division of numbering space */ assert(OPT_LAST - OPT_FIRST < (sizeof cd_seen * BITS_PER_BYTE)); zero(&msg); clear_end(&msg.right); /* left set from this after --to */ msg.name = NULL; msg.keyid = NULL; msg.keyval.ptr = NULL; msg.esp = NULL; msg.ike = NULL; msg.pfsgroup = NULL; msg.sa_ike_life_seconds = OAKLEY_ISAKMP_SA_LIFETIME_DEFAULT; msg.sa_ipsec_life_seconds = PLUTO_SA_LIFE_DURATION_DEFAULT; msg.sa_rekey_margin = SA_REPLACEMENT_MARGIN_DEFAULT; msg.sa_rekey_fuzz = SA_REPLACEMENT_FUZZ_DEFAULT; msg.sa_keying_tries = SA_REPLACEMENT_RETRIES_DEFAULT; msg.addr_family = AF_INET; msg.tunnel_addr_family = AF_INET; for (;;) { int long_index; unsigned long opt_whole; /* numeric argument for some flags */ /* Note: we don't like the way short options get parsed * by getopt_long, so we simply pass an empty string as * the list. It could be "hp:d:c:o:eatfs" "NARXPECK". */ int c = getopt_long(argc, argv, "", long_opts, &long_index) - OPTION_OFFSET; int aux = 0; /* decode a numeric argument, if expected */ if (0 <= c) { if (c & NUMERIC_ARG) { char *endptr; c -= NUMERIC_ARG; opt_whole = strtoul(optarg, &endptr, 0); if (*endptr != '\0' || endptr == optarg) diagq("badly formed numeric argument", optarg); } if (c >= (1 << AUX_SHIFT)) { aux = c >> AUX_SHIFT; c -= aux << AUX_SHIFT; } } /* per-class option processing */ if (0 <= c && c < OPT_LAST) { /* OPT_* options get added opts_seen. * Reject repeated options (unless later code intervenes). */ lset_t f = LELEM(c); if (opts_seen & f) diagq("duplicated flag", long_opts[long_index].name); opts_seen |= f; } /* Note: "break"ing from switch terminates loop. * most cases should end with "continue". */ switch (c) { case EOF - OPTION_OFFSET: /* end of flags */ break; case 0 - OPTION_OFFSET: /* long option already handled */ continue; case ':' - OPTION_OFFSET: /* diagnostic already printed by getopt_long */ case '?' - OPTION_OFFSET: /* diagnostic already printed by getopt_long */ diag(NULL); /* print no additional diagnostic, but exit sadly */ break; /* not actually reached */ case 'h' - OPTION_OFFSET: /* --help */ help(); return 0; /* GNU coding standards say to stop here */ case 'v' - OPTION_OFFSET: /* --version */ { const char **sp = ipsec_copyright_notice(); printf("%s\n", ipsec_version_string()); for (; *sp != NULL; sp++) puts(*sp); } return 0; /* GNU coding standards say to stop here */ case 'l' - OPTION_OFFSET: /* --label <string> */ label = optarg; /* remember for diagnostics */ continue; /* the rest of the options combine in complex ways */ case OPT_NAME: /* --name <connection-name> */ name = optarg; msg.name = optarg; continue; case OPT_INITIATE: /* --initiate */ msg.whack_initiate = TRUE; continue; case OPT_TERMINATE: /* --terminate */ msg.whack_terminate = TRUE; continue; case OPT_STATUS: /* --status */ msg.whack_status = TRUE; continue;#if 0 /* hmm */ case OPT_OPPO_HERE: /* --oppohere <ip-address> */ tunnel_af_used_by = long_opts[long_index].name; diagq(ttoaddr(optarg, 0, msg.tunnel_addr_family, &msg.oppo_my_client), optarg); if (isanyaddr(&msg.oppo_my_client)) diagq("0.0.0.0 or 0::0 isn't a valid client address", optarg); continue; case OPT_OPPO_THERE: /* --oppohere <ip-address> */ tunnel_af_used_by = long_opts[long_index].name; diagq(ttoaddr(optarg, 0, msg.tunnel_addr_family, &msg.oppo_peer_client), optarg); if (isanyaddr(&msg.oppo_peer_client)) diagq("0.0.0.0 or 0::0 isn't a valid client address", optarg); continue;#endif case OPT_ASYNC: msg.whack_async = TRUE; continue; case OPT_XAUTHNAME: gotxauthname = TRUE; xauthname[0]='\0'; strncat(xauthname, optarg, sizeof(xauthname)); xauthnamelen = strlen(xauthname)+1; continue; case OPT_XAUTHPASS: gotxauthpass = TRUE; xauthpass[0]='\0'; strncat(xauthpass, optarg, sizeof(xauthpass)); xauthpasslen = strlen(xauthpass)+1; continue; default: assert(FALSE); /* unknown return value */ } break; } if (optind != argc) { /* If you see this message unexpectedly, perhaps the * case for the previous option ended with "break" * instead of "continue" */ diagq("unexpected argument", argv[optind]); } /* For each possible form of the command, figure out if an argument * suggests whether that form was intended, and if so, whether all * required information was supplied. */#if 0 /* check opportunistic initiation simulation request */ switch (opts_seen & (LELEM(OPT_OPPO_HERE) | LELEM(OPT_OPPO_THERE))) { case LELEM(OPT_OPPO_HERE): case LELEM(OPT_OPPO_THERE): diag("--oppohere and --oppothere must be used together"); /*NOTREACHED*/ case LELEM(OPT_OPPO_HERE) | LELEM(OPT_OPPO_THERE): msg.whack_oppo_initiate = TRUE; if (LIN(cd_seen, LELEM(CD_TUNNELIPV4 - CD_FIRST) | LELEM(CD_TUNNELIPV6 - CD_FIRST))) opts_seen &= ~LELEM(OPT_CD); break; }#endif /* decide whether --name is mandatory or forbidden */ if (LELEM(OPT_INITIATE) | LELEM(OPT_TERMINATE)) { if (!LHAS(opts_seen, OPT_NAME)) diag("missing --name <connection_name>"); } else if (!msg.whack_options) { if (LHAS(opts_seen, OPT_NAME)) diag("no reason for --name"); } if (!(msg.whack_initiate || msg.whack_terminate || msg.whack_status)) { diag("no action specified; try --help for hints"); } /* pack strings for inclusion in message */ next_str = msg.string; str_roof = &msg.string[sizeof(msg.string)]; if (!pack_str(&msg.name) /* string 1 */ || str_roof - next_str < (ptrdiff_t)msg.keyval.len) /* chunk (sort of string 5) */ diag("too many bytes of strings to fit in message to pluto"); memcpy(next_str, msg.keyval.ptr, msg.keyval.len); msg.keyval.ptr = NULL; next_str += msg.keyval.len; msg.magic = ((opts_seen & ~(LELEM(OPT_STATUS)))) != LEMPTY || msg.whack_options ? WHACK_MAGIC : WHACK_BASIC_MAGIC; { int exit_status = 0; ssize_t len = next_str - (char *)&msg; if (write(sock, &msg, len) != len) { int e = errno; fprintf(stderr, "whack: write() failed (%d %s)\n", e, strerror(e)); exit(RC_WHACK_PROBLEM); } /* for now, just copy reply back to stdout */ { char buf[4097]; /* arbitrary limit on log line length */ char *be = buf; for (;;) { char *ls = buf; ssize_t rl = read(sock, be, (buf + sizeof(buf)-1) - be); if (rl < 0) { int e = errno; fprintf(stderr, "whack: read() failed (%d %s)\n", e, strerror(e)); exit(RC_WHACK_PROBLEM); } if (rl == 0) { if (be != buf) fprintf(stderr, "whack: last line from pluto too long or unterminated\n"); break; } be += rl; *be = '\0'; for (;;) { char *le = strchr(ls, '\n'); if (le == NULL) { /* move last, partial line to start of buffer */ memmove(buf, ls, be-ls); be -= ls - buf; break; } le++; /* include NL in line */ write(1, ls, le - ls); /* figure out prefix number * and how it should affect our exit status */ { unsigned long s = strtoul(ls, NULL, 10); switch (s) { case RC_COMMENT: case RC_LOG: /* ignore */ break; case RC_SUCCESS: /* be happy */ exit_status = 0; break; case RC_ENTERSECRET: if(!gotxauthpass) { xauthpasslen = get_secret(xauthpass , sizeof(xauthpass)); } send_reply(sock, xauthpass, xauthpasslen); break; case RC_XAUTHPROMPT: if(!gotxauthname) { xauthnamelen = get_value(xauthname , sizeof(xauthname)); } send_reply(sock, xauthname, xauthnamelen); break; /* case RC_LOG_SERIOUS: */ default: /* pass through */ exit_status = s; break; } } ls = le; } } } return exit_status; }}/* * Local Variables: * c-basic-offset:4 * c-style: pluto * End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -