static void esp_print_decodesecret(netdissect_options *ndo) { char *line; char *p; p = ndo->ndo_espsecret; while (ndo->ndo_espsecret && ndo->ndo_espsecret[0] != '\0') { /* pick out the first line or first thing until a comma */ if ((line = strsep(&ndo->ndo_espsecret, "\n,")) == NULL) { line = ndo->ndo_espsecret; ndo->ndo_espsecret = NULL; } esp_print_decode_onesecret(ndo, line); } }
static void esp_print_decodesecret(netdissect_options *ndo) { char *line; char *p; p = ndo->ndo_espsecret; while (ndo->ndo_espsecret && ndo->ndo_espsecret[0] != '\0') { if ((line = strsep(&ndo->ndo_espsecret, "\n,")) == NULL) { line = ndo->ndo_espsecret; ndo->ndo_espsecret = NULL; } esp_print_decode_onesecret(ndo, line); } }
/* * * special form: file /name * causes us to go read from this file instead. * */ static void esp_print_decode_onesecret(netdissect_options *ndo, char *line, const char *file, int lineno) { struct sa_list sa1; int sa_def; char *spikey; char *decode; spikey = strsep(&line, " \t"); sa_def = 0; memset(&sa1, 0, sizeof(struct sa_list)); /* if there is only one token, then it is an algo:key token */ if (line == NULL) { decode = spikey; spikey = NULL; /* memset(&sa1.daddr, 0, sizeof(sa1.daddr)); */ /* sa1.spi = 0; */ sa_def = 1; } else decode = line; if (spikey && strcasecmp(spikey, "file") == 0) { /* open file and read it */ FILE *secretfile; char fileline[1024]; int lineno=0; char *nl; char *filename = line; secretfile = fopen(filename, FOPEN_READ_TXT); if (secretfile == NULL) { perror(filename); exit(3); } while (fgets(fileline, sizeof(fileline)-1, secretfile) != NULL) { lineno++; /* remove newline from the line */ nl = strchr(fileline, '\n'); if (nl) *nl = '\0'; if (fileline[0] == '#') continue; if (fileline[0] == '\0') continue; esp_print_decode_onesecret(ndo, fileline, filename, lineno); } fclose(secretfile); return; } if (spikey && strcasecmp(spikey, "ikev2") == 0) { esp_print_decode_ikeline(ndo, line, file, lineno); return; } if (spikey) { char *spistr, *foo; u_int32_t spino; struct sockaddr_in *sin; #ifdef INET6 struct sockaddr_in6 *sin6; #endif spistr = strsep(&spikey, "@"); spino = strtoul(spistr, &foo, 0); if (spistr == foo || !spikey) { (*ndo->ndo_warning)(ndo, "print_esp: failed to decode spi# %s\n", foo); return; } sa1.spi = spino; sin = (struct sockaddr_in *)&sa1.daddr; #ifdef INET6 sin6 = (struct sockaddr_in6 *)&sa1.daddr; if (inet_pton(AF_INET6, spikey, &sin6->sin6_addr) == 1) { #ifdef HAVE_SOCKADDR_SA_LEN sin6->sin6_len = sizeof(struct sockaddr_in6); #endif sin6->sin6_family = AF_INET6; } else #endif if (inet_pton(AF_INET, spikey, &sin->sin_addr) == 1) { #ifdef HAVE_SOCKADDR_SA_LEN sin->sin_len = sizeof(struct sockaddr_in); #endif sin->sin_family = AF_INET; } else { (*ndo->ndo_warning)(ndo, "print_esp: can not decode IP# %s\n", spikey); return; } } if (decode) { /* skip any blank spaces */ while (isspace((unsigned char)*decode)) decode++; if(!espprint_decode_encalgo(ndo, decode, &sa1)) { return; } } esp_print_addsa(ndo, &sa1, sa_def); }
/* * decode the form: SPINUM@IP <tab> ALGONAME:0xsecret * * special form: file /name * causes us to go read from this file instead. * */ static void esp_print_decode_onesecret(netdissect_options *ndo, char *line) { struct sa_list sa1; int sa_def; char *spikey; char *decode; spikey = strsep(&line, " \t"); sa_def = 0; memset(&sa1, 0, sizeof(struct sa_list)); /* if there is only one token, then it is an algo:key token */ if (line == NULL) { decode = spikey; spikey = NULL; /* memset(&sa1.daddr, 0, sizeof(sa1.daddr)); */ /* sa1.spi = 0; */ sa_def = 1; } else decode = line; if (spikey && strcasecmp(spikey, "file") == 0) { /* open file and read it */ FILE *secretfile; char fileline[1024]; char *nl; secretfile = fopen(line, FOPEN_READ_TXT); if (secretfile == NULL) { perror(line); exit(3); } while (fgets(fileline, sizeof(fileline)-1, secretfile) != NULL) { /* remove newline from the line */ nl = strchr(fileline, '\n'); if (nl) *nl = '\0'; if (fileline[0] == '#') continue; if (fileline[0] == '\0') continue; esp_print_decode_onesecret(ndo, fileline); } fclose(secretfile); return; } if (spikey) { char *spistr, *foo; u_int32_t spino; struct sockaddr_in *sin; #ifdef INET6 struct sockaddr_in6 *sin6; #endif spistr = strsep(&spikey, "@"); spino = strtoul(spistr, &foo, 0); if (spistr == foo || !spikey) { (*ndo->ndo_warning)(ndo, "print_esp: failed to decode spi# %s\n", foo); return; } sa1.spi = spino; sin = (struct sockaddr_in *)&sa1.daddr; #ifdef INET6 sin6 = (struct sockaddr_in6 *)&sa1.daddr; if (inet_pton(AF_INET6, spikey, &sin6->sin6_addr) == 1) { #ifdef HAVE_SOCKADDR_SA_LEN sin6->sin6_len = sizeof(struct sockaddr_in6); #endif sin6->sin6_family = AF_INET6; } else #endif if (inet_pton(AF_INET, spikey, &sin->sin_addr) == 1) { #ifdef HAVE_SOCKADDR_SA_LEN sin->sin_len = sizeof(struct sockaddr_in); #endif sin->sin_family = AF_INET; } else { (*ndo->ndo_warning)(ndo, "print_esp: can not decode IP# %s\n", spikey); return; } } if (decode) { char *colon, *p; u_char espsecret_key[256]; int len; size_t i; const EVP_CIPHER *evp; int authlen = 0; /* skip any blank spaces */ while (isspace((unsigned char)*decode)) decode++; colon = strchr(decode, ':'); if (colon == NULL) { (*ndo->ndo_warning)(ndo, "failed to decode espsecret: %s\n", decode); return; } *colon = '\0'; len = colon - decode; if (strlen(decode) > strlen("-hmac96") && !strcmp(decode + strlen(decode) - strlen("-hmac96"), "-hmac96")) { p = strstr(decode, "-hmac96"); *p = '\0'; authlen = 12; } if (strlen(decode) > strlen("-cbc") && !strcmp(decode + strlen(decode) - strlen("-cbc"), "-cbc")) { p = strstr(decode, "-cbc"); *p = '\0'; } evp = EVP_get_cipherbyname(decode); if (!evp) { (*ndo->ndo_warning)(ndo, "failed to find cipher algo %s\n", decode); sa1.evp = NULL; sa1.authlen = 0; sa1.ivlen = 0; return; } sa1.evp = evp; sa1.authlen = authlen; sa1.ivlen = EVP_CIPHER_iv_length(evp); colon++; if (colon[0] == '0' && colon[1] == 'x') { /* decode some hex! */ colon += 2; len = strlen(colon) / 2; if (len > 256) { (*ndo->ndo_warning)(ndo, "secret is too big: %d\n", len); return; } i = 0; while (colon[0] != '\0' && colon[1]!='\0') { espsecret_key[i] = hex2byte(ndo, colon); colon += 2; i++; } memcpy(sa1.secret, espsecret_key, i); sa1.secretlen = i; } else { i = strlen(colon); if (i < sizeof(sa1.secret)) { memcpy(sa1.secret, colon, i); sa1.secretlen = i; } else { memcpy(sa1.secret, colon, sizeof(sa1.secret)); sa1.secretlen = sizeof(sa1.secret); } } } esp_print_addsa(ndo, &sa1, sa_def); }
/* * * special form: file /name * causes us to go read from this file instead. * */ static void esp_print_decode_onesecret(netdissect_options *ndo, char *line, const char *file, int lineno) { struct sa_list sa1; int sa_def; char *spikey; char *decode; spikey = strsep(&line, " \t"); sa_def = 0; memset(&sa1, 0, sizeof(struct sa_list)); /* if there is only one token, then it is an algo:key token */ if (line == NULL) { decode = spikey; spikey = NULL; /* sa1.daddr.version = 0; */ /* memset(&sa1.daddr, 0, sizeof(sa1.daddr)); */ /* sa1.spi = 0; */ sa_def = 1; } else decode = line; if (spikey && ascii_strcasecmp(spikey, "file") == 0) { /* open file and read it */ FILE *secretfile; char fileline[1024]; int subfile_lineno=0; char *nl; char *filename = line; secretfile = fopen(filename, FOPEN_READ_TXT); if (secretfile == NULL) { perror(filename); exit(3); } while (fgets(fileline, sizeof(fileline)-1, secretfile) != NULL) { subfile_lineno++; /* remove newline from the line */ nl = strchr(fileline, '\n'); if (nl) *nl = '\0'; if (fileline[0] == '#') continue; if (fileline[0] == '\0') continue; esp_print_decode_onesecret(ndo, fileline, filename, subfile_lineno); } fclose(secretfile); return; } if (spikey && ascii_strcasecmp(spikey, "ikev2") == 0) { esp_print_decode_ikeline(ndo, line, file, lineno); return; } if (spikey) { char *spistr, *foo; uint32_t spino; spistr = strsep(&spikey, "@"); spino = strtoul(spistr, &foo, 0); if (spistr == foo || !spikey) { (*ndo->ndo_warning)(ndo, "print_esp: failed to decode spi# %s\n", foo); return; } sa1.spi = spino; if (strtoaddr6(spikey, &sa1.daddr.in6) == 1) { sa1.daddr_version = 6; } else if (strtoaddr(spikey, &sa1.daddr.in4) == 1) { sa1.daddr_version = 4; } else { (*ndo->ndo_warning)(ndo, "print_esp: can not decode IP# %s\n", spikey); return; } } if (decode) { /* skip any blank spaces */ while (isspace((unsigned char)*decode)) decode++; if(!espprint_decode_encalgo(ndo, decode, &sa1)) { return; } } esp_print_addsa(ndo, &sa1, sa_def); }