mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-30 10:47:28 +02:00
164
src/sniffer.c
164
src/sniffer.c
@ -4292,8 +4292,8 @@ static int KeyWatchCall(SnifferSession* session, const byte* data, int dataSz,
|
||||
char* error)
|
||||
{
|
||||
int ret;
|
||||
Sha256 sha;
|
||||
byte digest[SHA256_DIGEST_SIZE];
|
||||
wc_Sha256 sha;
|
||||
byte digest[WC_SHA256_DIGEST_SIZE];
|
||||
|
||||
if (WatchCb == NULL) {
|
||||
SetError(WATCH_CB_MISSING_STR, error, session, FATAL_ERROR_STATE);
|
||||
@ -6023,8 +6023,7 @@ static int CheckSequence(IpInfo* ipInfo, TcpInfo* tcpInfo,
|
||||
/* returns 0 on success (continue), -1 on error, 1 on success (end) */
|
||||
static int CheckPreRecord(IpInfo* ipInfo, TcpInfo* tcpInfo,
|
||||
const byte** sslFrame, SnifferSession** pSession,
|
||||
int* sslBytes, const byte** end,
|
||||
void* vChain, word32 chainSz, char* error)
|
||||
int* sslBytes, const byte** end, char* error)
|
||||
{
|
||||
word32 length;
|
||||
SnifferSession* session = *pSession;
|
||||
@ -6094,53 +6093,12 @@ static int CheckPreRecord(IpInfo* ipInfo, TcpInfo* tcpInfo,
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
if (vChain == NULL) {
|
||||
XMEMCPY(&ssl->buffers.inputBuffer.buffer[length],
|
||||
*sslFrame, *sslBytes);
|
||||
*sslBytes += length;
|
||||
ssl->buffers.inputBuffer.length = *sslBytes;
|
||||
*sslFrame = ssl->buffers.inputBuffer.buffer;
|
||||
*end = *sslFrame + *sslBytes;
|
||||
}
|
||||
else {
|
||||
#ifdef WOLFSSL_SNIFFER_CHAIN_INPUT
|
||||
struct iovec* chain = (struct iovec*)vChain;
|
||||
word32 i, offset, headerSz, qty, remainder;
|
||||
|
||||
Trace(CHAIN_INPUT_STR);
|
||||
headerSz = (word32)((const byte*)*sslFrame - (const byte*)chain[0].iov_base);
|
||||
remainder = *sslBytes;
|
||||
|
||||
if ( (*sslBytes + length) > ssl->buffers.inputBuffer.bufferSize) {
|
||||
if (GrowInputBuffer(ssl, *sslBytes, length) < 0) {
|
||||
SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
qty = min(*sslBytes, (word32)chain[0].iov_len - headerSz);
|
||||
XMEMCPY(&ssl->buffers.inputBuffer.buffer[length],
|
||||
(byte*)chain[0].iov_base + headerSz, qty);
|
||||
offset = length;
|
||||
for (i = 1; i < chainSz; i++) {
|
||||
offset += qty;
|
||||
remainder -= qty;
|
||||
|
||||
if (chain[i].iov_len > remainder)
|
||||
qty = remainder;
|
||||
else
|
||||
qty = (word32)chain[i].iov_len;
|
||||
XMEMCPY(ssl->buffers.inputBuffer.buffer + offset,
|
||||
chain[i].iov_base, qty);
|
||||
}
|
||||
|
||||
*sslBytes += length;
|
||||
ssl->buffers.inputBuffer.length = *sslBytes;
|
||||
*sslFrame = ssl->buffers.inputBuffer.buffer;
|
||||
*end = *sslFrame + *sslBytes;
|
||||
#endif
|
||||
(void)chainSz;
|
||||
}
|
||||
XMEMCPY(&ssl->buffers.inputBuffer.buffer[length],
|
||||
*sslFrame, *sslBytes);
|
||||
*sslBytes += length;
|
||||
ssl->buffers.inputBuffer.length = *sslBytes;
|
||||
*sslFrame = ssl->buffers.inputBuffer.buffer;
|
||||
*end = *sslFrame + *sslBytes;
|
||||
}
|
||||
|
||||
if (session->flags.clientHello == 0 && **sslFrame != handshake) {
|
||||
@ -6616,27 +6574,33 @@ static int ssl_DecodePacketInternal(const byte* packet, int length, int isChain,
|
||||
{
|
||||
TcpInfo tcpInfo;
|
||||
IpInfo ipInfo;
|
||||
byte* tmpPacket = NULL; /* Assemble the chain */
|
||||
const byte* sslFrame;
|
||||
const byte* end;
|
||||
int sslBytes; /* ssl bytes unconsumed */
|
||||
int ret;
|
||||
SnifferSession* session = NULL;
|
||||
void* vChain = NULL;
|
||||
word32 chainSz = 0;
|
||||
|
||||
if (isChain) {
|
||||
#ifdef WOLFSSL_SNIFFER_CHAIN_INPUT
|
||||
struct iovec* chain;
|
||||
word32 i;
|
||||
|
||||
vChain = (void*)packet;
|
||||
chainSz = (word32)length;
|
||||
word32 chainSz = (word32)length;
|
||||
|
||||
chain = (struct iovec*)vChain;
|
||||
chain = (struct iovec*)packet;
|
||||
length = 0;
|
||||
for (i = 0; i < chainSz; i++)
|
||||
for (i = 0; i < chainSz; i++) length += chain[i].iov_len;
|
||||
|
||||
tmpPacket = (byte*)XMALLOC(length, NULL, DYNAMIC_TYPE_SNIFFER_CHAIN_BUFFER);
|
||||
if (tmpPacket == NULL) return MEMORY_E;
|
||||
|
||||
length = 0;
|
||||
for (i = 0; i < chainSz; i++) {
|
||||
XMEMCPY(tmpPacket+length,chain[i].iov_base,chain[i].iov_len);
|
||||
length += chain[i].iov_len;
|
||||
packet = (const byte*)chain[0].iov_base;
|
||||
}
|
||||
packet = (const byte*)tmpPacket;
|
||||
#else
|
||||
SetError(BAD_INPUT_STR, error, session, FATAL_ERROR_STATE);
|
||||
return WOLFSSL_SNIFFER_ERROR;
|
||||
@ -6645,18 +6609,27 @@ static int ssl_DecodePacketInternal(const byte* packet, int length, int isChain,
|
||||
|
||||
if (CheckHeaders(&ipInfo, &tcpInfo, packet, length, &sslFrame, &sslBytes,
|
||||
error, 1, 1) != 0) {
|
||||
return WOLFSSL_SNIFFER_ERROR;
|
||||
ret = WOLFSSL_SNIFFER_ERROR;
|
||||
goto exit_decode;
|
||||
}
|
||||
|
||||
end = sslFrame + sslBytes;
|
||||
|
||||
ret = CheckSession(&ipInfo, &tcpInfo, sslBytes, &session, error);
|
||||
if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error))
|
||||
return WOLFSSL_SNIFFER_FATAL_ERROR;
|
||||
if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error)) {
|
||||
ret = WOLFSSL_SNIFFER_FATAL_ERROR;
|
||||
goto exit_decode;
|
||||
}
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
else if (ret == WC_NO_ERR_TRACE(WC_PENDING_E)) return WC_PENDING_E;
|
||||
else if (ret == WC_NO_ERR_TRACE(WC_PENDING_E)) {
|
||||
ret = WC_PENDING_E;
|
||||
goto exit_decode;
|
||||
}
|
||||
#endif
|
||||
else if (ret == -1) return WOLFSSL_SNIFFER_ERROR;
|
||||
else if (ret == -1) {
|
||||
ret = WOLFSSL_SNIFFER_ERROR;
|
||||
goto exit_decode;
|
||||
}
|
||||
else if (ret == 1) {
|
||||
#ifdef WOLFSSL_SNIFFER_STATS
|
||||
if (sslBytes > 0) {
|
||||
@ -6669,7 +6642,8 @@ static int ssl_DecodePacketInternal(const byte* packet, int length, int isChain,
|
||||
INC_STAT(SnifferStats.sslDecryptedPackets);
|
||||
}
|
||||
#endif
|
||||
return 0; /* done for now */
|
||||
ret = 0;
|
||||
goto exit_decode; /* done for now */
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
@ -6677,30 +6651,41 @@ static int ssl_DecodePacketInternal(const byte* packet, int length, int isChain,
|
||||
#endif
|
||||
|
||||
ret = CheckSequence(&ipInfo, &tcpInfo, session, &sslBytes, &sslFrame,error);
|
||||
if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error))
|
||||
return WOLFSSL_SNIFFER_FATAL_ERROR;
|
||||
else if (ret == -1) return WOLFSSL_SNIFFER_ERROR;
|
||||
if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error)) {
|
||||
ret = WOLFSSL_SNIFFER_FATAL_ERROR;
|
||||
goto exit_decode;
|
||||
}
|
||||
else if (ret == -1) {
|
||||
ret = WOLFSSL_SNIFFER_ERROR;
|
||||
goto exit_decode;
|
||||
}
|
||||
else if (ret == 1) {
|
||||
#ifdef WOLFSSL_SNIFFER_STATS
|
||||
INC_STAT(SnifferStats.sslDecryptedPackets);
|
||||
#endif
|
||||
return 0; /* done for now */
|
||||
ret = 0;
|
||||
goto exit_decode; /* done for now */
|
||||
}
|
||||
else if (ret != 0) {
|
||||
/* return specific error case */
|
||||
return ret;
|
||||
goto exit_decode; /* return specific error case */
|
||||
}
|
||||
|
||||
ret = CheckPreRecord(&ipInfo, &tcpInfo, &sslFrame, &session, &sslBytes,
|
||||
&end, vChain, chainSz, error);
|
||||
if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error))
|
||||
return WOLFSSL_SNIFFER_FATAL_ERROR;
|
||||
else if (ret == -1) return WOLFSSL_SNIFFER_ERROR;
|
||||
&end, error);
|
||||
if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error)) {
|
||||
ret = WOLFSSL_SNIFFER_FATAL_ERROR;
|
||||
goto exit_decode;
|
||||
}
|
||||
else if (ret == -1) {
|
||||
ret = WOLFSSL_SNIFFER_ERROR;
|
||||
goto exit_decode;
|
||||
}
|
||||
else if (ret == 1) {
|
||||
#ifdef WOLFSSL_SNIFFER_STATS
|
||||
INC_STAT(SnifferStats.sslDecryptedPackets);
|
||||
#endif
|
||||
return 0; /* done for now */
|
||||
ret = 0;
|
||||
goto exit_decode; /* done for now */
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
@ -6708,7 +6693,8 @@ static int ssl_DecodePacketInternal(const byte* packet, int length, int isChain,
|
||||
if (asyncOkay &&
|
||||
session->sslServer->error == WC_NO_ERR_TRACE(WC_PENDING_E) &&
|
||||
!session->flags.wasPolled) {
|
||||
return WC_PENDING_E;
|
||||
ret = WC_PENDING_E;
|
||||
goto exit_decode;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -6745,7 +6731,7 @@ static int ssl_DecodePacketInternal(const byte* packet, int length, int isChain,
|
||||
wolfSSL_AsyncPoll(session->sslServer, WOLF_POLL_FLAG_CHECK_HW);
|
||||
}
|
||||
else {
|
||||
return ret; /* return to caller */
|
||||
goto exit_decode; /* return to caller */
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -6756,12 +6742,18 @@ static int ssl_DecodePacketInternal(const byte* packet, int length, int isChain,
|
||||
(void)asyncOkay;
|
||||
#endif
|
||||
|
||||
if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error))
|
||||
return WOLFSSL_SNIFFER_FATAL_ERROR;
|
||||
if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error)) {
|
||||
ret = WOLFSSL_SNIFFER_FATAL_ERROR;
|
||||
goto exit_decode;
|
||||
}
|
||||
if (CheckFinCapture(&ipInfo, &tcpInfo, session) == 0) {
|
||||
CopySessionInfo(session, sslInfo);
|
||||
}
|
||||
|
||||
exit_decode:
|
||||
if (isChain) {
|
||||
XFREE(tmpPacket, NULL, DYNAMIC_TYPE_SNIFFER_CHAIN_BUFFER);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -6868,11 +6860,15 @@ int ssl_Trace(const char* traceFile, char* error)
|
||||
if (traceFile) {
|
||||
/* Don't try to reopen the file */
|
||||
if (TraceFile == NULL) {
|
||||
TraceFile = XFOPEN(traceFile, "a");
|
||||
if (!TraceFile) {
|
||||
SetError(BAD_TRACE_FILE_STR, error, NULL, 0);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
if (XSTRCMP(traceFile, "-") == 0) {
|
||||
TraceFile = stdout;
|
||||
} else {
|
||||
TraceFile = XFOPEN(traceFile, "a");
|
||||
if (!TraceFile) {
|
||||
SetError(BAD_TRACE_FILE_STR, error, NULL, 0);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
TraceOn = 1;
|
||||
}
|
||||
}
|
||||
|
@ -197,7 +197,7 @@ Frees all resources consumed by the wolfSSL sniffer and should be called when us
|
||||
int ssl_Trace(const char* traceFile, char* error);
|
||||
```
|
||||
|
||||
Enables Tracing when a file is passed in. Disables Tracing if previously on and a NULL value is passed in for the file.
|
||||
Enables Tracing when a file is passed in. When `traceFile` is "-", then the trace will be printed to STDOUT. Disables Tracing if previously on and a NULL value is passed in for the file.
|
||||
|
||||
Returns Values:
|
||||
|
||||
|
@ -145,7 +145,7 @@ enum {
|
||||
#endif
|
||||
|
||||
#define DEFAULT_SERVER_IP "127.0.0.1"
|
||||
#define DEFAULT_SERVER_PORT (443)
|
||||
#define DEFAULT_SERVER_PORT (11111)
|
||||
|
||||
#ifdef WOLFSSL_SNIFFER_WATCH
|
||||
static const byte rsaHash[] = {
|
||||
@ -166,6 +166,7 @@ static const byte eccHash[] = {
|
||||
static pcap_t* pcap = NULL;
|
||||
static pcap_if_t* alldevs = NULL;
|
||||
static struct bpf_program pcap_fp;
|
||||
static const char *traceFile = "./tracefile.txt";
|
||||
|
||||
static void FreeAll(void)
|
||||
{
|
||||
@ -377,7 +378,6 @@ static int load_key(const char* name, const char* server, int port,
|
||||
|
||||
if (loadCount == 0) {
|
||||
printf("Failed loading private key %s: ret %d\n", keyFile, ret);
|
||||
printf("Please run directly from wolfSSL root dir\n");
|
||||
ret = -1;
|
||||
}
|
||||
else {
|
||||
@ -843,7 +843,7 @@ static void* snifferWorker(void* arg)
|
||||
char err[PCAP_ERRBUF_SIZE];
|
||||
|
||||
ssl_InitSniffer_ex2(worker->id);
|
||||
ssl_Trace("./tracefile.txt", err);
|
||||
ssl_Trace(traceFile, err);
|
||||
ssl_EnableRecovery(1, -1, err);
|
||||
#ifdef WOLFSSL_SNIFFER_WATCH
|
||||
ssl_SetWatchKeyCallback(myWatchCb, err);
|
||||
@ -951,39 +951,90 @@ int main(int argc, char** argv)
|
||||
int i = 0, defDev = 0;
|
||||
int packetNumber = 0;
|
||||
int frame = ETHER_IF_FRAME_LEN;
|
||||
char cmdLineArg[128];
|
||||
char *pcapFile = NULL;
|
||||
char *deviceName = NULL;
|
||||
char err[PCAP_ERRBUF_SIZE];
|
||||
char filter[32];
|
||||
char filter[128];
|
||||
const char *keyFilesSrc = NULL;
|
||||
#ifdef WOLFSSL_SNIFFER_KEYLOGFILE
|
||||
const char *sslKeyLogFile = NULL;
|
||||
#endif /* WOLFSSL_SNIFFER_KEYLOGFILE */
|
||||
char keyFilesBuf[MAX_FILENAME_SZ];
|
||||
char keyFilesUser[MAX_FILENAME_SZ];
|
||||
const char *server = DEFAULT_SERVER_IP;
|
||||
int port = DEFAULT_SERVER_PORT;
|
||||
const char *server = NULL;
|
||||
int port = -1;
|
||||
const char *sniName = NULL;
|
||||
const char *passwd = NULL;
|
||||
pcap_if_t *d;
|
||||
pcap_addr_t *a;
|
||||
#ifdef THREADED_SNIFFTEST
|
||||
int workerThreadCount;
|
||||
#ifdef HAVE_SESSION_TICKET
|
||||
/* Multiple threads on resume not yet supported */
|
||||
workerThreadCount = 1;
|
||||
#else
|
||||
workerThreadCount = 5;
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_WOLFSSL
|
||||
wolfSSL_Debugging_ON();
|
||||
#endif
|
||||
|
||||
show_appinfo();
|
||||
|
||||
signal(SIGINT, sig_handler);
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "-pcap") == 0 && i + 1 < argc) {
|
||||
pcapFile = argv[++i];
|
||||
}
|
||||
else if (strcmp(argv[i], "-deviceName") == 0 && i + 1 < argc) {
|
||||
deviceName = argv[++i];
|
||||
}
|
||||
else if (strcmp(argv[i], "-key") == 0 && i + 1 < argc) {
|
||||
keyFilesSrc = argv[++i];
|
||||
}
|
||||
else if (strcmp(argv[i], "-server") == 0 && i + 1 < argc) {
|
||||
server = argv[++i];
|
||||
}
|
||||
else if (strcmp(argv[i], "-port") == 0 && i + 1 < argc) {
|
||||
port = XATOI(argv[++i]);
|
||||
}
|
||||
else if (strcmp(argv[i], "-password") == 0 && i + 1 < argc) {
|
||||
passwd = argv[++i];
|
||||
}
|
||||
else if (strcmp(argv[i], "-tracefile") == 0 && i + 1 < argc) {
|
||||
traceFile = argv[++i];
|
||||
}
|
||||
#if defined(WOLFSSL_SNIFFER_KEYLOGFILE)
|
||||
else if (strcmp(argv[i], "-keylogfile") == 0 && i + 1 < argc) {
|
||||
sslKeyLogFile = argv[++i];
|
||||
}
|
||||
#endif /* WOLFSSL_SNIFFER_KEYLOGFILE */
|
||||
#if defined(THREADED_SNIFFTEST)
|
||||
else if (strcmp(argv[i], "-threads") == 0 && i + 1 < argc) {
|
||||
workerThreadCount = XATOI(argv[++i]);
|
||||
}
|
||||
#endif /* THREADED_SNIFFTEST */
|
||||
else {
|
||||
fprintf(stderr, "Error parsing: %s\n", argv[i]);
|
||||
fprintf(stderr, "Usage: %s -pcap pcap_arg -key key_arg"
|
||||
" [-deviceName deviceName_arg]"
|
||||
" [-password password_arg] [-server server_arg]"
|
||||
" [-port port_arg]"
|
||||
" [-tracefile tracefile_arg]"
|
||||
#if defined(WOLFSSL_SNIFFER_KEYLOGFILE)
|
||||
" [-keylogfile keylogfile_arg]"
|
||||
#endif /* WOLFSSL_SNIFFER_KEYLOGFILE */
|
||||
#if defined(THREADED_SNIFFTEST)
|
||||
" [-threads threads_arg]"
|
||||
#endif /* THREADED_SNIFFTEST */
|
||||
"\n", argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef THREADED_SNIFFTEST
|
||||
#ifndef _WIN32
|
||||
ssl_InitSniffer(); /* dll load on Windows */
|
||||
#endif
|
||||
ssl_Trace("./tracefile.txt", err);
|
||||
ssl_Trace(traceFile, err);
|
||||
ssl_EnableRecovery(1, -1, err);
|
||||
#ifdef WOLFSSL_SNIFFER_WATCH
|
||||
ssl_SetWatchKeyCallback(myWatchCb, err);
|
||||
@ -991,101 +1042,175 @@ int main(int argc, char** argv)
|
||||
#ifdef WOLFSSL_SNIFFER_STORE_DATA_CB
|
||||
ssl_SetStoreDataCallback(myStoreDataCb);
|
||||
#endif
|
||||
#else
|
||||
#ifdef HAVE_SESSION_TICKET
|
||||
/* Multiple threads on resume not yet supported */
|
||||
workerThreadCount = 1;
|
||||
#else
|
||||
workerThreadCount = 5;
|
||||
#endif
|
||||
#endif
|
||||
SNPRINTF(filter, sizeof(filter), "(ip6 or ip) and tcp");
|
||||
|
||||
if (argc == 1) {
|
||||
char cmdLineArg[128];
|
||||
|
||||
if (pcapFile == NULL) {
|
||||
/* normal case, user chooses device and port */
|
||||
|
||||
if (pcap_findalldevs(&alldevs, err) == -1)
|
||||
err_sys("Error in pcap_findalldevs");
|
||||
|
||||
for (d = alldevs; d; d=d->next) {
|
||||
printf("%d. %s", ++i, d->name);
|
||||
if (strcmp(d->name, "lo0") == 0) {
|
||||
defDev = i;
|
||||
if (deviceName == NULL) {
|
||||
for (d = alldevs, i = 0; d; d=d->next) {
|
||||
printf("%d. %s", ++i, d->name);
|
||||
if (strcmp(d->name, "lo0") == 0) {
|
||||
defDev = i;
|
||||
}
|
||||
if (d->description)
|
||||
printf(" (%s)\n", d->description);
|
||||
else
|
||||
printf(" (No description available)\n");
|
||||
}
|
||||
|
||||
if (i == 0)
|
||||
err_sys("No interfaces found! Make sure pcap or WinPcap is"
|
||||
" installed correctly and you have sufficient permissions");
|
||||
|
||||
printf("Enter the interface number (1-%d) [default: %d]: ", i, defDev);
|
||||
XMEMSET(cmdLineArg, 0, sizeof(cmdLineArg));
|
||||
if (XFGETS(cmdLineArg, sizeof(cmdLineArg), stdin))
|
||||
inum = XATOI(cmdLineArg);
|
||||
if (inum == 0)
|
||||
inum = defDev;
|
||||
else if (inum < 1 || inum > i)
|
||||
err_sys("Interface number out of range");
|
||||
|
||||
/* Jump to the selected adapter */
|
||||
for (d = alldevs, i = 0; i < inum - 1; d = d->next, i++);
|
||||
} else {
|
||||
int deviceNameSz = (int)XSTRLEN(deviceName);
|
||||
for (d = alldevs; d; d = d->next) {
|
||||
if (XSTRNCMP(d->name,deviceName,deviceNameSz) == 0) {
|
||||
fprintf(stderr, "%s == %s\n", d->name, deviceName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (d == NULL) {
|
||||
err_sys("Can't find the device you're looking for");
|
||||
}
|
||||
if (d->description)
|
||||
printf(" (%s)\n", d->description);
|
||||
else
|
||||
printf(" (No description available)\n");
|
||||
}
|
||||
|
||||
if (i == 0)
|
||||
err_sys("No interfaces found! Make sure pcap or WinPcap is"
|
||||
" installed correctly and you have sufficient permissions");
|
||||
|
||||
printf("Enter the interface number (1-%d) [default: %d]: ", i, defDev);
|
||||
XMEMSET(cmdLineArg, 0, sizeof(cmdLineArg));
|
||||
if (XFGETS(cmdLineArg, sizeof(cmdLineArg), stdin))
|
||||
inum = XATOI(cmdLineArg);
|
||||
if (inum == 0)
|
||||
inum = defDev;
|
||||
else if (inum < 1 || inum > i)
|
||||
err_sys("Interface number out of range");
|
||||
|
||||
/* Jump to the selected adapter */
|
||||
for (d = alldevs, i = 0; i < inum - 1; d = d->next, i++);
|
||||
|
||||
printf("Selected %s\n", d->name);
|
||||
pcap = pcap_create(d->name, err);
|
||||
if (pcap == NULL) fprintf(stderr, "pcap_create failed %s\n", err);
|
||||
|
||||
if (pcap == NULL) printf("pcap_create failed %s\n", err);
|
||||
|
||||
/* print out addresses for selected interface */
|
||||
for (a = d->addresses; a; a = a->next) {
|
||||
if (a->addr->sa_family == AF_INET) {
|
||||
server =
|
||||
iptos(&((struct sockaddr_in *)a->addr)->sin_addr);
|
||||
printf("server = %s\n", server);
|
||||
}
|
||||
else if (a->addr->sa_family == AF_INET6) {
|
||||
server =
|
||||
ip6tos(&((struct sockaddr_in6 *)a->addr)->sin6_addr);
|
||||
printf("server = %s\n", server);
|
||||
if (server == NULL) {
|
||||
/* print out addresses for selected interface */
|
||||
for (a = d->addresses; a; a = a->next) {
|
||||
if (a->addr->sa_family == AF_INET) {
|
||||
server =
|
||||
iptos(&((struct sockaddr_in *)a->addr)->sin_addr);
|
||||
printf("server = %s\n", server);
|
||||
}
|
||||
else if (a->addr->sa_family == AF_INET6) {
|
||||
server =
|
||||
ip6tos(&((struct sockaddr_in6 *)a->addr)->sin6_addr);
|
||||
printf("server = %s\n", server);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (server == NULL)
|
||||
err_sys("Unable to get device IPv4 or IPv6 address");
|
||||
|
||||
ret = pcap_set_snaplen(pcap, 65536);
|
||||
if (ret != 0) printf("pcap_set_snaplen failed %s\n", pcap_geterr(pcap));
|
||||
if (ret != 0)
|
||||
fprintf(stderr, "pcap_set_snaplen failed %s\n", pcap_geterr(pcap));
|
||||
|
||||
ret = pcap_set_timeout(pcap, 1000);
|
||||
if (ret != 0) printf("pcap_set_timeout failed %s\n", pcap_geterr(pcap));
|
||||
if (ret != 0)
|
||||
fprintf(stderr, "pcap_set_timeout failed %s\n", pcap_geterr(pcap));
|
||||
|
||||
ret = pcap_set_buffer_size(pcap, 1000000);
|
||||
if (ret != 0)
|
||||
printf("pcap_set_buffer_size failed %s\n", pcap_geterr(pcap));
|
||||
fprintf(stderr, "pcap_set_buffer_size failed %s\n",
|
||||
pcap_geterr(pcap));
|
||||
|
||||
ret = pcap_set_promisc(pcap, 1);
|
||||
if (ret != 0) printf("pcap_set_promisc failed %s\n", pcap_geterr(pcap));
|
||||
if (ret != 0)
|
||||
fprintf(stderr,"pcap_set_promisc failed %s\n", pcap_geterr(pcap));
|
||||
|
||||
|
||||
ret = pcap_activate(pcap);
|
||||
if (ret != 0) printf("pcap_activate failed %s\n", pcap_geterr(pcap));
|
||||
if (ret != 0)
|
||||
fprintf(stderr, "pcap_activate failed %s\n", pcap_geterr(pcap));
|
||||
|
||||
printf("Enter the port to scan [default: 11111]: ");
|
||||
}
|
||||
else {
|
||||
saveFile = 1;
|
||||
pcap = pcap_open_offline(pcapFile , err);
|
||||
if (pcap == NULL) {
|
||||
fprintf(stderr, "pcap_open_offline failed %s\n", err);
|
||||
err_sys(err);
|
||||
}
|
||||
}
|
||||
|
||||
if (server == NULL) {
|
||||
server = DEFAULT_SERVER_IP;
|
||||
}
|
||||
|
||||
if (port < 0) {
|
||||
printf("Enter the port to scan [default: %d, '0' for all]: ",
|
||||
DEFAULT_SERVER_PORT);
|
||||
XMEMSET(cmdLineArg, 0, sizeof(cmdLineArg));
|
||||
if (XFGETS(cmdLineArg, sizeof(cmdLineArg), stdin)) {
|
||||
port = XATOI(cmdLineArg);
|
||||
}
|
||||
if (port <= 0)
|
||||
port = 11111;
|
||||
if ((port < 0) || (cmdLineArg[0] == '\n'))
|
||||
port = DEFAULT_SERVER_PORT;
|
||||
|
||||
SNPRINTF(filter, sizeof(filter), "tcp and port %d", port);
|
||||
}
|
||||
if (port > 0) {
|
||||
SNPRINTF(cmdLineArg, sizeof(filter), " and port %d", port);
|
||||
XSTRLCAT(filter, cmdLineArg, sizeof(filter));
|
||||
}
|
||||
|
||||
ret = pcap_compile(pcap, &pcap_fp, filter, 0, 0);
|
||||
if (ret != 0) printf("pcap_compile failed %s\n", pcap_geterr(pcap));
|
||||
#if defined(WOLFSSL_SNIFFER_KEYLOGFILE)
|
||||
/* If we offer keylog support, then user must provide EITHER a pubkey
|
||||
* OR a keylog file but NOT both */
|
||||
if (keyFilesSrc && sslKeyLogFile) {
|
||||
fprintf(stderr,
|
||||
"Error: either -key OR -keylogfile option but NOT both.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ret = pcap_setfilter(pcap, &pcap_fp);
|
||||
if (ret != 0) printf("pcap_setfilter failed %s\n", pcap_geterr(pcap));
|
||||
if (sslKeyLogFile != NULL) {
|
||||
ret = ssl_LoadSecretsFromKeyLogFile(sslKeyLogFile, err);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr,
|
||||
"ERROR=%d, unable to load secrets from keylog file\n",ret);
|
||||
err_sys(err);
|
||||
}
|
||||
|
||||
ret = ssl_CreateKeyLogSnifferServer(server, port, err);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr,
|
||||
"ERROR=%d, unable to create keylog sniffer server\n",ret);
|
||||
err_sys(err);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* WOLFSSL_SNIFFER_KEYLOGFILE */
|
||||
if (keyFilesSrc) {
|
||||
ret = load_key(NULL, server, port, keyFilesSrc, passwd, err);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "Failed to load key\n");
|
||||
err_sys(err);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* optionally enter the private key to use */
|
||||
#if defined(WOLFSSL_STATIC_EPHEMERAL) && defined(DEFAULT_SERVER_EPH_KEY)
|
||||
#if defined(WOLFSSL_STATIC_EPHEMERAL) && defined(DEFAULT_SERVER_EPH_KEY)
|
||||
keyFilesSrc = DEFAULT_SERVER_EPH_KEY;
|
||||
#else
|
||||
#else
|
||||
keyFilesSrc = DEFAULT_SERVER_KEY;
|
||||
#endif
|
||||
#endif
|
||||
printf("Enter the server key [default: %s]: ", keyFilesSrc);
|
||||
XMEMSET(keyFilesBuf, 0, sizeof(keyFilesBuf));
|
||||
XMEMSET(keyFilesUser, 0, sizeof(keyFilesUser));
|
||||
@ -1109,137 +1234,24 @@ int main(int argc, char** argv)
|
||||
}
|
||||
#endif /* !WOLFSSL_SNIFFER_WATCH && HAVE_SNI */
|
||||
|
||||
/* get IPv4 or IPv6 addresses for selected interface */
|
||||
for (a = d->addresses; a; a = a->next) {
|
||||
server = NULL;
|
||||
if (a->addr->sa_family == AF_INET) {
|
||||
server =
|
||||
iptos(&((struct sockaddr_in *)a->addr)->sin_addr);
|
||||
}
|
||||
else if (a->addr->sa_family == AF_INET6) {
|
||||
server =
|
||||
ip6tos(&((struct sockaddr_in6 *)a->addr)->sin6_addr);
|
||||
}
|
||||
|
||||
if (server) {
|
||||
XSTRNCPY(keyFilesBuf, keyFilesSrc, sizeof(keyFilesBuf));
|
||||
ret = load_key(sniName, server, port, keyFilesBuf, NULL, err);
|
||||
if (ret != 0) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
ret = load_key(sniName, server, port, keyFilesBuf, NULL, err);
|
||||
if (ret != 0) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
char *pcapFile = NULL;
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "-pcap") == 0 && i + 1 < argc) {
|
||||
pcapFile = argv[++i];
|
||||
}
|
||||
else if (strcmp(argv[i], "-key") == 0 && i + 1 < argc) {
|
||||
keyFilesSrc = argv[++i];
|
||||
}
|
||||
else if (strcmp(argv[i], "-server") == 0 && i + 1 < argc) {
|
||||
server = argv[++i];
|
||||
}
|
||||
else if (strcmp(argv[i], "-port") == 0 && i + 1 < argc) {
|
||||
port = XATOI(argv[++i]);
|
||||
}
|
||||
else if (strcmp(argv[i], "-password") == 0 && i + 1 < argc) {
|
||||
passwd = argv[++i];
|
||||
}
|
||||
#if defined(WOLFSSL_SNIFFER_KEYLOGFILE)
|
||||
else if (strcmp(argv[i], "-keylogfile") == 0 && i + 1 < argc) {
|
||||
sslKeyLogFile = argv[++i];
|
||||
}
|
||||
#endif /* WOLFSSL_SNIFFER_KEYLOGFILE */
|
||||
#if defined(THREADED_SNIFFTEST)
|
||||
else if (strcmp(argv[i], "-threads") == 0 && i + 1 < argc) {
|
||||
workerThreadCount = XATOI(argv[++i]);
|
||||
}
|
||||
#endif /* THREADED_SNIFFTEST */
|
||||
else {
|
||||
fprintf(stderr, "Invalid option or missing argument: %s\n", argv[i]);
|
||||
fprintf(stderr, "Usage: %s -pcap pcap_arg -key key_arg"
|
||||
" [-password password_arg] [-server server_arg] [-port port_arg]"
|
||||
#if defined(WOLFSSL_SNIFFER_KEYLOGFILE)
|
||||
" [-keylogfile keylogfile_arg]"
|
||||
#endif /* WOLFSSL_SNIFFER_KEYLOGFILE */
|
||||
#if defined(THREADED_SNIFFTEST)
|
||||
" [-threads threads_arg]"
|
||||
#endif /* THREADED_SNIFFTEST */
|
||||
"\n", argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
/* Only let through TCP/IP packets */
|
||||
printf("Using packet filter: %s\n", filter);
|
||||
ret = pcap_compile(pcap, &pcap_fp, filter, 0, 0);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "pcap_compile failed %s\n", pcap_geterr(pcap));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (!pcapFile) {
|
||||
fprintf(stderr, "Error: -pcap option is required.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
#if defined(WOLFSSL_SNIFFER_KEYLOGFILE)
|
||||
/* If we offer keylog support, then user must provide EITHER a pubkey
|
||||
* OR a keylog file but NOT both */
|
||||
if ((!keyFilesSrc && !sslKeyLogFile) || (keyFilesSrc && sslKeyLogFile)) {
|
||||
fprintf(stderr, "Error: either -key OR -keylogfile option required but NOT both.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
#else
|
||||
if (!keyFilesSrc) {
|
||||
fprintf(stderr, "Error: -key option is required.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
#endif
|
||||
|
||||
saveFile = 1;
|
||||
pcap = pcap_open_offline(pcapFile , err);
|
||||
if (pcap == NULL) {
|
||||
fprintf(stderr, "pcap_open_offline failed %s\n", err);
|
||||
err_sys(err);
|
||||
}
|
||||
else {
|
||||
#if defined(WOLFSSL_SNIFFER_KEYLOGFILE)
|
||||
if (sslKeyLogFile != NULL) {
|
||||
ret = ssl_LoadSecretsFromKeyLogFile(sslKeyLogFile, err);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "ERROR=%d, unable to load secrets from keylog file\n",ret);
|
||||
err_sys(err);
|
||||
}
|
||||
|
||||
ret = ssl_CreateKeyLogSnifferServer(server, port, err);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "ERROR=%d, unable to create keylog sniffer server\n",ret);
|
||||
err_sys(err);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* WOLFSSL_SNIFFER_KEYLOGFILE */
|
||||
{
|
||||
ret = load_key(NULL, server, port, keyFilesSrc, passwd, err);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "Failed to load key\n");
|
||||
err_sys(err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Only let through TCP/IP packets */
|
||||
ret = pcap_compile(pcap, &pcap_fp, "(ip6 or ip) and tcp", 0, 0);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "pcap_compile failed %s\n", pcap_geterr(pcap));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ret = pcap_setfilter(pcap, &pcap_fp);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "pcap_setfilter failed %s\n", pcap_geterr(pcap));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
ret = pcap_setfilter(pcap, &pcap_fp);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "pcap_setfilter failed %s\n", pcap_geterr(pcap));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (ret != 0)
|
||||
@ -1263,7 +1275,7 @@ int main(int argc, char** argv)
|
||||
#endif
|
||||
|
||||
while (1) {
|
||||
struct pcap_pkthdr header;
|
||||
struct pcap_pkthdr *header;
|
||||
const unsigned char* packet = NULL;
|
||||
byte* data = NULL; /* pointer to decrypted data */
|
||||
#ifdef THREADED_SNIFFTEST
|
||||
@ -1290,22 +1302,28 @@ int main(int argc, char** argv)
|
||||
if (data == NULL) {
|
||||
/* grab next pcap packet */
|
||||
packetNumber++;
|
||||
packet = pcap_next(pcap, &header);
|
||||
if(pcap_next_ex(pcap, &header, &packet) < 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (packet) {
|
||||
if (header.caplen > 40) { /* min ip(20) + min tcp(20) */
|
||||
if (header->caplen > 40) { /* min ip(20) + min tcp(20) */
|
||||
packet += frame;
|
||||
header.caplen -= frame;
|
||||
header->caplen -= frame;
|
||||
}
|
||||
else {
|
||||
/* packet doesn't contain minimum ip/tcp header */
|
||||
continue;
|
||||
}
|
||||
if (pcap_datalink(pcap) == DLT_LINUX_SLL) {
|
||||
packet += 2;
|
||||
header->caplen -= 2;
|
||||
}
|
||||
#ifdef THREADED_SNIFFTEST
|
||||
XMEMSET(&info, 0, sizeof(SnifferStreamInfo));
|
||||
|
||||
ret = ssl_DecodePacket_GetStream(&info, packet, header.caplen, err);
|
||||
ret = ssl_DecodePacket_GetStream(&info, packet, header->caplen, err);
|
||||
|
||||
/* calculate SnifferStreamInfo checksum */
|
||||
infoSum = 0;
|
||||
@ -1328,7 +1346,7 @@ int main(int argc, char** argv)
|
||||
|
||||
/* add the packet to the worker's linked list */
|
||||
if (SnifferWorkerPacketAdd(&workers[threadNum], ret, (byte*)packet,
|
||||
header.caplen, packetNumber)) {
|
||||
header->caplen, packetNumber)) {
|
||||
printf("Unable to add packet %d to worker", packetNumber);
|
||||
break;
|
||||
}
|
||||
@ -1337,7 +1355,7 @@ int main(int argc, char** argv)
|
||||
#else
|
||||
/* Decode Packet, ret value will indicate whether a
|
||||
* bad packet was encountered */
|
||||
hadBadPacket = DecodePacket((byte*)packet, header.caplen,
|
||||
hadBadPacket = DecodePacket((byte*)packet, header->caplen,
|
||||
packetNumber,err);
|
||||
#endif
|
||||
}
|
||||
|
@ -1114,15 +1114,16 @@ typedef struct w64wrapper {
|
||||
DYNAMIC_TYPE_LMS = 101,
|
||||
DYNAMIC_TYPE_BIO = 102,
|
||||
DYNAMIC_TYPE_X509_ACERT = 103,
|
||||
DYNAMIC_TYPE_SNIFFER_SERVER = 1000,
|
||||
DYNAMIC_TYPE_SNIFFER_SESSION = 1001,
|
||||
DYNAMIC_TYPE_SNIFFER_PB = 1002,
|
||||
DYNAMIC_TYPE_SNIFFER_PB_BUFFER = 1003,
|
||||
DYNAMIC_TYPE_SNIFFER_TICKET_ID = 1004,
|
||||
DYNAMIC_TYPE_SNIFFER_NAMED_KEY = 1005,
|
||||
DYNAMIC_TYPE_SNIFFER_KEY = 1006,
|
||||
DYNAMIC_TYPE_SNIFFER_KEYLOG_NODE = 1007,
|
||||
DYNAMIC_TYPE_AES_EAX = 1008
|
||||
DYNAMIC_TYPE_SNIFFER_SERVER = 1000,
|
||||
DYNAMIC_TYPE_SNIFFER_SESSION = 1001,
|
||||
DYNAMIC_TYPE_SNIFFER_PB = 1002,
|
||||
DYNAMIC_TYPE_SNIFFER_PB_BUFFER = 1003,
|
||||
DYNAMIC_TYPE_SNIFFER_TICKET_ID = 1004,
|
||||
DYNAMIC_TYPE_SNIFFER_NAMED_KEY = 1005,
|
||||
DYNAMIC_TYPE_SNIFFER_KEY = 1006,
|
||||
DYNAMIC_TYPE_SNIFFER_KEYLOG_NODE = 1007,
|
||||
DYNAMIC_TYPE_SNIFFER_CHAIN_BUFFER = 1008,
|
||||
DYNAMIC_TYPE_AES_EAX = 1009,
|
||||
};
|
||||
|
||||
/* max error buffer string size */
|
||||
|
Reference in New Issue
Block a user