/* sniffer.c
 *
 * Copyright (C) 2006-2012 Sawtooth Consulting Ltd.
 *
 * This file is part of CyaSSL.
 *
 * CyaSSL is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * CyaSSL is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 */


#ifdef CYASSL_SNIFFER

#ifdef HAVE_CONFIG_H
    #include <config.h>
#endif

#include <assert.h>
#include <time.h>

#ifndef _WIN32
  #include <arpa/inet.h>
#endif

#ifdef _WIN32
    #define SNPRINTF _snprintf
#else
    #define SNPRINTF snprintf
#endif

#include <cyassl/openssl/ssl.h>
#include <cyassl/internal.h>
#include <cyassl/error.h>
#include <cyassl/sniffer.h>
#include <cyassl/sniffer_error.h>


#ifndef min

static INLINE word32 min(word32 a, word32 b)
{
    return a > b ? b : a;
}

#endif


/* Misc constants */
enum {
    MAX_SERVER_ADDRESS = 128, /* maximum server address length */
    MAX_ERROR_LEN      = 80,  /* maximum error length */
    ETHER_IF_ADDR_LEN  = 6,   /* ethernet interface address length */
    LOCAL_IF_ADDR_LEN  = 4,   /* localhost interface address length, !windows */
    TCP_PROTO          = 6,   /* TCP_PROTOCOL */
    IP_HDR_SZ          = 20,  /* IP header legnth, min */
    TCP_HDR_SZ         = 20,  /* TCP header legnth, min */
    IPV4               = 4,   /* IP version 4 */
    TCP_PROTOCOL       = 6,   /* TCP Protocol id */
    TRACE_MSG_SZ       = 80,  /* Trace Message buffer size */
    HASH_SIZE          = 499, /* Session Hash Table Rows */
    PSEUDO_HDR_SZ      = 12,  /* TCP Pseudo Header size in bytes */
    FATAL_ERROR_STATE  =  1,  /* SnifferSession fatal error state */
    SNIFFER_TIMEOUT    = 900, /* Cache unclosed Sessions for 15 minutes */
    TICKET_HINT_LEN    = 4,   /* Session Ticket Hint length */
    EXT_TYPE_SZ        = 2,   /* Extension length */
    TICKET_EXT_ID      = 0x23 /* Session Ticket Extension ID */
};


#ifdef _WIN32

static HMODULE dllModule;  /* for error string resources */

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
	static int didInit = 0;

    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
		if (didInit == 0) {
            dllModule = hModule;
			ssl_InitSniffer();
			didInit = 1;
		}
        break;
    case DLL_THREAD_ATTACH:
        break;
    case DLL_THREAD_DETACH:
        break;
    case DLL_PROCESS_DETACH:
		if (didInit) {
			ssl_FreeSniffer();
			didInit = 0;
		}
        break;
    }
    return TRUE;
}

#endif /* _WIN32 */


static int TraceOn = 0;         /* Trace is off by default */
static FILE* TraceFile = 0;


/* windows uses .rc table for this */
#ifndef _WIN32

static const char* const msgTable[] =
{
    /* 1 */
    "Out of Memory",
    "New SSL Sniffer Server Registered",
    "Checking IP Header",
    "SSL Sniffer Server Not Registered",
    "Checking TCP Header",

    /* 6 */
    "SSL Sniffer Server Port Not Registered",
    "RSA Private Decrypt Error",
    "RSA Private Decode Error",
    "Set Cipher Spec Error",
    "Server Hello Input Malformed",

    /* 11 */
    "Couldn't Resume Session Error",
    "Server Did Resumption",
    "Client Hello Input Malformed",
    "Client Trying to Resume",
    "Handshake Input Malformed",

    /* 16 */
    "Got Hello Verify msg",
    "Got Server Hello msg",
    "Got Cert Request msg",
    "Got Server Key Exchange msg",
    "Got Cert msg",

    /* 21 */
    "Got Server Hello Done msg",
    "Got Finished msg",
    "Got Client Hello msg",
    "Got Client Key Exchange msg",
    "Got Cert Verify msg",

    /* 26 */
    "Got Unknown Handshake msg",
    "New SSL Sniffer Session created",
    "Couldn't create new SSL",
    "Got a Packet to decode",
    "No data present",

    /* 31 */
    "Session Not Found",
    "Got an Old Client Hello msg",
    "Old Client Hello Input Malformed",
    "Old Client Hello OK",
    "Bad Old Client Hello",

    /* 36 */
    "Bad Record Header",
    "Record Header Input Malformed",
    "Got a HandShake msg",
    "Bad HandShake msg",
    "Got a Change Cipher Spec msg",

    /* 41 */
    "Got Application Data msg",
    "Bad Application Data",
    "Got an Alert msg",
    "Another msg to Process",
    "Removing Session From Table",
    
    /* 46 */
    "Bad Key File",
    "Wrong IP Version",
    "Wrong Protocol type",
    "Packet Short for header processing",
    "Got Unknown Record Type",
    
    /* 51 */
    "Can't Open Trace File",
    "Session in Fatal Error State",
    "Partial SSL record received",
    "Buffer Error, malformed input",
    "Added to Partial Input",
    
    /* 56 */
    "Received a Duplicate Packet",
    "Received an Out of Order Packet",
    "Received an Overlap Duplicate Packet",
    "Received an Overlap Reassembly Begin Duplicate Packet",
    "Received an Overlap Reassembly End Duplicate Packet",

    /* 61 */
    "Missed the Client Hello Entirely",
    "Got Hello Request msg",
    "Got Session Ticket msg",
    "Bad Input",
    "Bad Decrypt Type",

    /* 66 */
    "Bad Finished Message Processing",
    "Bad Compression Type"
};


/* *nix version uses table above */
static void GetError(int idx, char* str)
{
    XSTRNCPY(str, msgTable[idx - 1], MAX_ERROR_LEN);
}


#else /* _WIN32 */


/* Windows version uses .rc table */
static void GetError(int idx, char* buffer)
{
    if (!LoadStringA(dllModule, idx, buffer, MAX_ERROR_LEN))
        buffer[0] = 0;
}


#endif /* _WIN32 */


/* Packet Buffer for reassembly list and ready list */
typedef struct PacketBuffer {
    word32  begin;      /* relative sequence begin */
    word32  end;        /* relative sequence end   */
    byte*   data;       /* actual data             */
    struct PacketBuffer* next; /* next on reassembly list or ready list */
} PacketBuffer;


/* Sniffer Server holds info for each server/port monitored */
typedef struct SnifferServer {
    SSL_CTX*       ctx;                          /* SSL context */
    char           address[MAX_SERVER_ADDRESS];  /* passed in server address */
    word32         server;                       /* netowrk order address */
    int            port;                         /* server port */
    struct SnifferServer* next;                  /* for list */
} SnifferServer;


/* Session Flags */
typedef struct Flags {
    byte           side;            /* which end is current packet headed */
    byte           serverCipherOn;  /* indicates whether cipher is active */
    byte           clientCipherOn;  /* indicates whether cipher is active */
    byte           resuming;        /* did this session come from resumption */
    byte           cached;          /* have we cached this session yet */
    byte           clientHello;     /* processed client hello yet, for SSLv2 */
    byte           finCount;        /* get both FINs before removing */
    byte           fatalError;      /* fatal error state */
} Flags;


/* Out of Order FIN caputre */
typedef struct FinCaputre {
    word32 cliFinSeq;               /* client relative sequence FIN  0 is no */
    word32 srvFinSeq;               /* server relative sequence FIN, 0 is no */
    byte   cliCounted;              /* did we count yet, detects duplicates */
    byte   srvCounted;              /* did we count yet, detects duplicates */
} FinCaputre;


/* Sniffer Session holds info for each client/server SSL/TLS session */
typedef struct SnifferSession {
    SnifferServer* context;         /* server context */
    SSL*           sslServer;       /* SSL server side decode */
    SSL*           sslClient;       /* SSL client side decode */
    word32         server;          /* server address in network byte order */
    word32         client;          /* client address in network byte order */
    word16         srvPort;         /* server port */
    word16         cliPort;         /* client port */
    word32         cliSeqStart;     /* client start sequence */
    word32         srvSeqStart;     /* server start sequence */
    word32         cliExpected;     /* client expected sequence (relative) */
    word32         srvExpected;     /* server expected sequence (relative) */
    FinCaputre     finCaputre;      /* retain out of order FIN s */
    Flags          flags;           /* session flags */
    time_t         bornOn;          /* born on ticks */
    PacketBuffer*  cliReassemblyList; /* client out of order packets */
    PacketBuffer*  srvReassemblyList; /* server out of order packets */
    struct SnifferSession* next;      /* for hash table list */
    byte*          ticketID;          /* mac ID of session ticket */
} SnifferSession;


/* Sniffer Server List and mutex */
static SnifferServer* ServerList = 0;
static CyaSSL_Mutex ServerListMutex;


/* Session Hash Table, mutex, and count */
static SnifferSession* SessionTable[HASH_SIZE];
static CyaSSL_Mutex SessionMutex;
static int SessionCount = 0;


/* Initialize overall Sniffer */
void ssl_InitSniffer(void)
{
    CyaSSL_Init();
    InitMutex(&ServerListMutex);
    InitMutex(&SessionMutex);
}


/* Free Sniffer Server's resources/self */
static void FreeSnifferServer(SnifferServer* srv)
{
    if (srv)
        SSL_CTX_free(srv->ctx);
    free(srv);
}


/* free PacketBuffer's resources/self */
static void FreePacketBuffer(PacketBuffer* del)
{
    if (del) {
        free(del->data);
        free(del);
    }
}


/* remove PacketBuffer List */
static void FreePacketList(PacketBuffer* in)
{
    if (in) {
        PacketBuffer* del;
        PacketBuffer* packet = in;
        
        while (packet) {
            del = packet;
            packet = packet->next;
            FreePacketBuffer(del);
        }
    }
}


/* Free Sniffer Session's resources/self */
static void FreeSnifferSession(SnifferSession* session)
{
    if (session) {
        SSL_free(session->sslClient);
        SSL_free(session->sslServer);
        
        FreePacketList(session->cliReassemblyList);
        FreePacketList(session->srvReassemblyList);

        free(session->ticketID);
    }
    free(session);
}


/* Free overall Sniffer */
void ssl_FreeSniffer(void)
{
    SnifferServer*  srv;
    SnifferServer*  removeServer;
    SnifferSession* session;
    SnifferSession* removeSession;
    int i;

    LockMutex(&ServerListMutex);
    LockMutex(&SessionMutex);
    
    srv = ServerList;
    while (srv) {
        removeServer = srv;
        srv = srv->next;
        FreeSnifferServer(removeServer);
    }

    for (i = 0; i < HASH_SIZE; i++) {
        session = SessionTable[i];
        while (session) {
            removeSession = session;
            session = session->next;
            FreeSnifferSession(removeSession);
        }
    }

    UnLockMutex(&SessionMutex);
    UnLockMutex(&ServerListMutex);

    FreeMutex(&SessionMutex);
    FreeMutex(&ServerListMutex);
    CyaSSL_Cleanup();
}


/* Initialize a SnifferServer */
static void InitSnifferServer(SnifferServer* sniffer)
{
    sniffer->ctx = 0;
    XMEMSET(sniffer->address, 0, MAX_SERVER_ADDRESS);
    sniffer->server   = 0;
    sniffer->port     = 0;
    sniffer->next     = 0;
}


/* Initialize session flags */
static void InitFlags(Flags* flags)
{
    flags->side           = 0;
    flags->serverCipherOn = 0;
    flags->clientCipherOn = 0;
    flags->resuming       = 0;
    flags->cached         = 0;
    flags->clientHello    = 0;
    flags->finCount       = 0;
    flags->fatalError     = 0;
}


/* Initialize FIN Capture */
static void InitFinCapture(FinCaputre* cap)
{
    cap->cliFinSeq  = 0;
    cap->srvFinSeq  = 0;
    cap->cliCounted = 0;
    cap->srvCounted = 0;
}


/* Initialize a Sniffer Session */
static void InitSession(SnifferSession* session)
{
    session->context        = 0;
    session->sslServer      = 0;
    session->sslClient      = 0;
    session->server         = 0;
    session->client         = 0;
    session->srvPort        = 0;
    session->cliPort        = 0;
    session->cliSeqStart    = 0;
    session->srvSeqStart    = 0;
    session->cliExpected    = 0;
    session->srvExpected    = 0;
    session->bornOn         = 0;
    session->cliReassemblyList = 0;
    session->srvReassemblyList = 0;
    session->next           = 0;
    session->ticketID       = 0;
    
    InitFlags(&session->flags);
    InitFinCapture(&session->finCaputre);
}


/* IP Info from IP Header */
typedef struct IpInfo {
    int    length;        /* length of this header */
    int    total;         /* total length of fragment */
    word32 src;           /* network order source address */
    word32 dst;           /* network order destination address */
} IpInfo;


/* TCP Info from TCP Header */
typedef struct TcpInfo {
    int    srcPort;       /* source port */
    int    dstPort;       /* source port */
    int    length;        /* length of this header */
    word32 sequence;      /* sequence number */
    byte   fin;           /* FIN set */
    byte   rst;           /* RST set */
    byte   syn;           /* SYN set */
    byte   ack;           /* ACK set */
} TcpInfo;


/* Tcp Pseudo Header for Checksum calculation */
typedef struct TcpPseudoHdr {
    word32  src;        /* source address */
    word32  dst;        /* destination address */
    byte    rsv;        /* reserved, always 0 */
    byte    protocol;   /* IP protocol */
    word16  legnth;     /* tcp header length + data length (doesn't include */
                        /* pseudo header length) network order */
} TcpPseudoHdr;


/* Password Setting Callback */
static int SetPassword(char* passwd, int sz, int rw, void* userdata)
{
    (void)rw;
    XSTRNCPY(passwd, userdata, sz);
    return XSTRLEN(userdata);
}


/* Ethernet Header */
typedef struct EthernetHdr {
    byte   dst[ETHER_IF_ADDR_LEN];    /* destination host address */ 
    byte   src[ETHER_IF_ADDR_LEN];    /* source  host address */ 
    word16 type;                      /* IP, ARP, etc */ 
} EthernetHdr;


/* IP Header */
typedef struct IpHdr {
    byte    ver_hl;              /* version/header length */
    byte    tos;                 /* type of service */
    word16  length;              /* total length */
    word16  id;                  /* identification */
    word16  offset;              /* fragment offset field */
    byte    ttl;                 /* time to live */
    byte    protocol;            /* protocol */
    word16  sum;                 /* checksum */
    word32  src;                 /* source address */
    word32  dst;                 /* destination address */
} IpHdr;


#define IP_HL(ip)      ( (((ip)->ver_hl) & 0x0f) * 4)
#define IP_V(ip)       ( ((ip)->ver_hl) >> 4)

/* TCP Header */
typedef struct TcpHdr {
    word16  srcPort;            /* source port */
    word16  dstPort;            /* destination port */
    word32  sequence;           /* sequence number */ 
    word32  ack;                /* acknoledgment number */ 
    byte    offset;             /* data offset, reserved */
    byte    flags;              /* option flags */
    word16  window;             /* window */
    word16  sum;                /* checksum */
    word16  urgent;             /* urgent pointer */
} TcpHdr;

#define TCP_LEN(tcp)  ( (((tcp)->offset & 0xf0) >> 4) * 4)
#define TCP_FIN 0x01
#define TCP_SYN 0x02
#define TCP_RST 0x04
#define TCP_ACK 0x10





/* Use platform specific GetError to write to tracfile if tracing */ 
static void Trace(int idx) 
{
    if (TraceOn) {
        char myBuffer[MAX_ERROR_LEN];
        GetError(idx, myBuffer);
        fprintf(TraceFile, "\t%s\n", myBuffer);
#ifdef DEBUG_SNIFFER
        fprintf(stderr,    "\t%s\n", myBuffer);
#endif
    }
}


/* Show TimeStamp for beginning of packet Trace */
static void TraceHeader(void)
{
    if (TraceOn) {
        time_t ticks = time(NULL);
        fprintf(TraceFile, "\n%s", ctime(&ticks));
    }
}


/* Show Set Server info for Trace */
static void TraceSetServer(const char* srv, int port, const char* keyFile)
{
    if (TraceOn) {
        fprintf(TraceFile, "\tTrying to install a new Sniffer Server with\n");
        fprintf(TraceFile, "\tserver: %s, port: %d, keyFile: %s\n", srv, port,
                                                                    keyFile);
    }
}


/* Trace got packet number */
static void TracePacket(void)
{
    if (TraceOn) {
        static word32 packetNumber = 0;
        fprintf(TraceFile, "\tGot a Packet to decode, packet %u\n",
                ++packetNumber);
    }
}


/* Convert network byte order address into human readable */
static char* IpToS(word32 addr, char* str)
{
    byte* p = (byte*)&addr;
    
    SNPRINTF(str, TRACE_MSG_SZ, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
    
    return str;
}


/* Show destination and source address from Ip Hdr for packet Trace */
static void TraceIP(IpHdr* iphdr)
{
    if (TraceOn) {
        char src[TRACE_MSG_SZ];
        char dst[TRACE_MSG_SZ];
        fprintf(TraceFile, "\tdst:%s src:%s\n", IpToS(iphdr->dst, dst),
                IpToS(iphdr->src, src));
    }
}


/* Show destination and source port from Tcp Hdr for packet Trace */
static void TraceTcp(TcpHdr* tcphdr)
{
    if (TraceOn) {
        fprintf(TraceFile, "\tdstPort:%u srcPort:%u\n", ntohs(tcphdr->dstPort),
                ntohs(tcphdr->srcPort));
    }
}


/* Show sequence and payload length for Trace */
static void TraceSequence(word32 seq, int len)
{
    if (TraceOn) {
        fprintf(TraceFile, "\tSequence:%u, payload length:%d\n", seq, len);
    }
}


/* Show relative expected and relative received sequences */
static void TraceRelativeSequence(word32 expected, word32 got)
{
    if (TraceOn) {
        fprintf(TraceFile, "\tExpected sequence:%u, received sequence:%u\n",
                expected, got);
    }
}


/* Show server sequence startup from SYN */
static void TraceServerSyn(word32 seq)
{
    if (TraceOn) {
        fprintf(TraceFile, "\tServer SYN, Sequence Start:%u\n", seq);
    }
}


/* Show client sequence startup from SYN */
static void TraceClientSyn(word32 seq)
{
    if (TraceOn) {
        fprintf(TraceFile, "\tClient SYN, Sequence Start:%u\n", seq);
    }
}


/* Show client FIN capture */
static void TraceClientFin(word32 finSeq, word32 relSeq)
{
    if (TraceOn) {
        fprintf(TraceFile, "\tClient FIN capture:%u, current SEQ:%u\n",
                finSeq, relSeq);
    }
}


/* Show server FIN capture */
static void TraceServerFin(word32 finSeq, word32 relSeq)
{
    if (TraceOn) {
        fprintf(TraceFile, "\tServer FIN capture:%u, current SEQ:%u\n",
                finSeq, relSeq);
    }
}


/* Show number of SSL data bytes decoded, could be 0 (ok) */
static void TraceGotData(int bytes)
{
    if (TraceOn) {
        fprintf(TraceFile, "\t%d bytes of SSL App data processed\n", bytes);
    }
}


/* Show bytes added to old SSL App data */
static void TraceAddedData(int newBytes, int existingBytes)
{
    if (TraceOn) {
        fprintf(TraceFile,
                "\t%d bytes added to %d exisiting bytes in User Buffer\n",
                newBytes, existingBytes);
    }
}


/* Show Stale Session */
static void TraceStaleSession(void)
{
    if (TraceOn) {
        fprintf(TraceFile, "\tFound a stale session\n");
    }
}


/* Show Finding Stale Sessions */
static void TraceFindingStale(void)
{
    if (TraceOn) {
        fprintf(TraceFile, "\tTrying to find Stale Sessions\n");
    }
}


/* Show Removed Session */
static void TraceRemovedSession(void)
{
    if (TraceOn) {
        fprintf(TraceFile, "\tRemoved it\n");
    }
}


/* Set user error string */
static void SetError(int idx, char* error, SnifferSession* session, int fatal)
{
    GetError(idx, error);
    Trace(idx);
    if (session && fatal == FATAL_ERROR_STATE)
        session->flags.fatalError = 1;
}


/* See if this IPV4 network order address has been registered */
/* return 1 is true, 0 is false */
static int IsServerRegistered(word32 addr)
{
    int ret = 0;     /* false */
    SnifferServer* sniffer;

    LockMutex(&ServerListMutex);
    
    sniffer = ServerList;
    while (sniffer) {
        if (sniffer->server == addr) {
            ret = 1;
            break;
        }
        sniffer = sniffer->next;
    }
    
    UnLockMutex(&ServerListMutex);

    return ret;
}


/* See if this port has been registered to watch */
/* return 1 is true, 0 is false */
static int IsPortRegistered(word32 port)
{
    int ret = 0;    /* false */
    SnifferServer* sniffer;
    
    LockMutex(&ServerListMutex);
    
    sniffer = ServerList;
    while (sniffer) {
        if (sniffer->port == (int)port) {
            ret = 1; 
            break;
        }
        sniffer = sniffer->next;
    }
    
    UnLockMutex(&ServerListMutex);

    return ret;
}


/* Get SnifferServer from IP and Port */
static SnifferServer* GetSnifferServer(IpInfo* ipInfo, TcpInfo* tcpInfo)
{
    SnifferServer* sniffer;
    
    LockMutex(&ServerListMutex);
    
    sniffer = ServerList;
    while (sniffer) {
        if (sniffer->port == tcpInfo->srcPort && sniffer->server == ipInfo->src)
            break;
        if (sniffer->port == tcpInfo->dstPort && sniffer->server == ipInfo->dst)
            break;
        sniffer = sniffer->next;
    }
    
    UnLockMutex(&ServerListMutex);
    
    return sniffer;
}


/* Hash the Session Info, return hash row */
static word32 SessionHash(IpInfo* ipInfo, TcpInfo* tcpInfo)
{
    word32 hash = ipInfo->src * ipInfo->dst;
    hash *= tcpInfo->srcPort * tcpInfo->dstPort;
    
    return hash % HASH_SIZE;
}


/* Get Exisiting SnifferSession from IP and Port */
static SnifferSession* GetSnifferSession(IpInfo* ipInfo, TcpInfo* tcpInfo)
{
    SnifferSession* session;
    
    word32 row = SessionHash(ipInfo, tcpInfo);
    assert(row >= 0 && row <= HASH_SIZE);
    
    LockMutex(&SessionMutex);
    
    session = SessionTable[row];
    while (session) {
        if (session->server == ipInfo->src && session->client == ipInfo->dst &&
                    session->srvPort == tcpInfo->srcPort &&
                    session->cliPort == tcpInfo->dstPort)
            break;
        if (session->client == ipInfo->src && session->server == ipInfo->dst &&
                    session->cliPort == tcpInfo->srcPort &&
                    session->srvPort == tcpInfo->dstPort)
            break;
        
        session = session->next;
    }
    
    UnLockMutex(&SessionMutex);
    
    /* determine side */
    if (session) {
        if (ipInfo->dst == session->context->server &&
            tcpInfo->dstPort == session->context->port)
            session->flags.side = SERVER_END;
        else
            session->flags.side = CLIENT_END;
    }    
    
    return session;
}


/* Sets the private key for a specific server and port  */
/* returns 0 on success, -1 on error */
int ssl_SetPrivateKey(const char* serverAddress, int port, const char* keyFile,
                      int typeKey, const char* password, char* error)
{
    int            ret;
    int            type = (typeKey == FILETYPE_PEM) ? SSL_FILETYPE_PEM :
                                                      SSL_FILETYPE_ASN1;
    SnifferServer* sniffer;
    
    TraceHeader();
    TraceSetServer(serverAddress, port, keyFile);

    sniffer = (SnifferServer*)malloc(sizeof(SnifferServer));
    if (sniffer == NULL) {
        SetError(MEMORY_STR, error, NULL, 0);
        return -1;
    }
    InitSnifferServer(sniffer);

    XSTRNCPY(sniffer->address, serverAddress, MAX_SERVER_ADDRESS);
    sniffer->server = inet_addr(sniffer->address);
    sniffer->port = port;
    
    /* start in client mode since SSL_new needs a cert for server */
    sniffer->ctx = SSL_CTX_new(SSLv3_client_method());
    if (!sniffer->ctx) {
        SetError(MEMORY_STR, error, NULL, 0);
        FreeSnifferServer(sniffer);
        return -1;
    }

    if (password){
        SSL_CTX_set_default_passwd_cb(sniffer->ctx, SetPassword);
        SSL_CTX_set_default_passwd_cb_userdata(sniffer->ctx, (void*)password);
    }
    ret = SSL_CTX_use_PrivateKey_file(sniffer->ctx, keyFile, type);
    if (ret != SSL_SUCCESS) {
        SetError(KEY_FILE_STR, error, NULL, 0);
        FreeSnifferServer(sniffer);
        return -1;
    }
    Trace(NEW_SERVER_STR);
    
    LockMutex(&ServerListMutex);
    
    sniffer->next = ServerList;
    ServerList = sniffer;
    
    UnLockMutex(&ServerListMutex);
    
    return 0;
}


/* Check IP Header for IPV4, TCP, and a registered server address */
/* returns 0 on success, -1 on error */
static int CheckIpHdr(IpHdr* iphdr, IpInfo* info, char* error)
{
    int    version = IP_V(iphdr);

    TraceIP(iphdr);
    Trace(IP_CHECK_STR);
    if (version != IPV4) {
        SetError(BAD_IPVER_STR, error, NULL, 0); 
        return -1;
    }

    if (iphdr->protocol != TCP_PROTOCOL) { 
        SetError(BAD_PROTO_STR, error, NULL, 0);
        return -1;
    }

    if (!IsServerRegistered(iphdr->src) && !IsServerRegistered(iphdr->dst)) {
        SetError(SERVER_NOT_REG_STR, error, NULL, 0);
        return -1;
    }

    info->length  = IP_HL(iphdr);
    info->total   = ntohs(iphdr->length);
    info->src     = iphdr->src;
    info->dst     = iphdr->dst;

    return 0;
}


/* Check TCP Header for a registered port */
/* returns 0 on success, -1 on error */
static int CheckTcpHdr(TcpHdr* tcphdr, TcpInfo* info, char* error)
{
    TraceTcp(tcphdr);
    Trace(TCP_CHECK_STR);
    info->srcPort   = ntohs(tcphdr->srcPort);
    info->dstPort   = ntohs(tcphdr->dstPort);
    info->length    = TCP_LEN(tcphdr);
    info->sequence  = ntohl(tcphdr->sequence);
    info->fin       = tcphdr->flags & TCP_FIN;
    info->rst       = tcphdr->flags & TCP_RST;
    info->syn       = tcphdr->flags & TCP_SYN;
    info->ack       = tcphdr->flags & TCP_ACK;

    if (!IsPortRegistered(info->srcPort) && !IsPortRegistered(info->dstPort)) {
        SetError(SERVER_PORT_NOT_REG_STR, error, NULL, 0);
        return -1;
    }

    return 0;
}


/* Decode Record Layer Header */
static int GetRecordHeader(const byte* input, RecordLayerHeader* rh, int* size)
{
    XMEMCPY(rh, input, RECORD_HEADER_SZ);
    *size = (rh->length[0] << 8) | rh->length[1];

    if (*size > (RECORD_SIZE + MAX_COMP_EXTRA + MAX_MSG_EXTRA))
        return LENGTH_ERROR;

    return 0;
}


/* Process Client Key Exchange, RSA only */
static int ProcessClientKeyExchange(const byte* input, int* sslBytes,
                                    SnifferSession* session, char* error)
{
    word32 idx = 0;
    RsaKey key;
    int    ret;

    InitRsaKey(&key, 0);
   
    ret = RsaPrivateKeyDecode(session->context->ctx->privateKey.buffer,
                          &idx, &key, session->context->ctx->privateKey.length);
    if (ret == 0) {
        int length = RsaEncryptSize(&key);
        
        if (IsTLS(session->sslServer)) 
            input += 2;     /* tls pre length */
       
        if (length > *sslBytes) { 
            SetError(PARTIAL_INPUT_STR, error, session, FATAL_ERROR_STATE);
            FreeRsaKey(&key);
            return -1;
        }
        ret = RsaPrivateDecrypt(input, length, 
                  session->sslServer->arrays.preMasterSecret, SECRET_LEN, &key);
        
        if (ret != SECRET_LEN) {
            SetError(RSA_DECRYPT_STR, error, session, FATAL_ERROR_STATE);
            FreeRsaKey(&key);
            return -1;
        }
        ret = 0;  /* not in error state */
        session->sslServer->arrays.preMasterSz = SECRET_LEN;
        
        /* store for client side as well */
        XMEMCPY(session->sslClient->arrays.preMasterSecret,
               session->sslServer->arrays.preMasterSecret, SECRET_LEN);
        session->sslClient->arrays.preMasterSz = SECRET_LEN;
        
        #ifdef SHOW_SECRETS
        {
            int i;
            printf("pre master secret: ");
            for (i = 0; i < SECRET_LEN; i++)
                printf("%02x", session->sslServer->arrays.preMasterSecret[i]);
            printf("\n");
        }
        #endif
    }
    else {
        SetError(RSA_DECODE_STR, error, session, FATAL_ERROR_STATE);
        FreeRsaKey(&key);
        return -1;
    }
    
    if (SetCipherSpecs(session->sslServer) != 0) {
        SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE);
        FreeRsaKey(&key);
        return -1;
    }
   
    if (SetCipherSpecs(session->sslClient) != 0) {
        SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE);
        FreeRsaKey(&key);
        return -1;
    }

    MakeMasterSecret(session->sslServer);
    MakeMasterSecret(session->sslClient);
#ifdef SHOW_SECRETS
    {
        int i;
        printf("server master secret: ");
        for (i = 0; i < SECRET_LEN; i++)
            printf("%02x", session->sslServer->arrays.masterSecret[i]);
        printf("\n");
        
        printf("client master secret: ");
        for (i = 0; i < SECRET_LEN; i++)
            printf("%02x", session->sslClient->arrays.masterSecret[i]);
        printf("\n");

        printf("server suite = %d\n", session->sslServer->options.cipherSuite);
        printf("client suite = %d\n", session->sslClient->options.cipherSuite);
    }
#endif   
    
    FreeRsaKey(&key);
    return ret;
}


/* Process Session Ticket */
static int ProcessSessionTicket(const byte* input, int* sslBytes,
                                SnifferSession* session, char* error)
{
    word16 len;

    /* make sure can read through hint and len */
    if (TICKET_HINT_LEN + LENGTH_SZ > *sslBytes) {
        SetError(BAD_INPUT_STR, error, session, FATAL_ERROR_STATE);
        return -1;
    }
    
    input     += TICKET_HINT_LEN;  /* skip over hint */
    *sslBytes -= TICKET_HINT_LEN;

    len = (input[0] << 8) | input[1];
    input     += LENGTH_SZ;
    *sslBytes -= LENGTH_SZ;

    /* make sure can read through ticket */
    if (len > *sslBytes || len < ID_LEN) {
        SetError(BAD_INPUT_STR, error, session, FATAL_ERROR_STATE);
        return -1;
    }

    /* store session with macID as sessionID */
    session->sslServer->options.haveSessionId = 1;
    XMEMCPY(session->sslServer->arrays.sessionID, input + len - ID_LEN, ID_LEN);
    
    return 0;
}


/* Process Server Hello */
static int ProcessServerHello(const byte* input, int* sslBytes,
                              SnifferSession* session, char* error)
{
    ProtocolVersion pv;
    byte            b;
    int             toRead = sizeof(ProtocolVersion) + RAN_LEN + ENUM_LEN;
    int             doResume     = 0;
    
    /* make sure we didn't miss ClientHello */
    if (session->flags.clientHello == 0) {
        SetError(MISSED_CLIENT_HELLO_STR, error, session, FATAL_ERROR_STATE);
        return -1;
    }

    /* make sure can read through session len */
    if (toRead > *sslBytes) {
        SetError(SERVER_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
        return -1;
    }
    
    XMEMCPY(&pv, input, sizeof(ProtocolVersion));
    input     += sizeof(ProtocolVersion);
    *sslBytes -= sizeof(ProtocolVersion);
           
    session->sslServer->version = pv;
    session->sslClient->version = pv;
           
    XMEMCPY(session->sslServer->arrays.serverRandom, input, RAN_LEN);
    XMEMCPY(session->sslClient->arrays.serverRandom, input, RAN_LEN);
    input    += RAN_LEN;
    *sslBytes -= RAN_LEN;
    
    b = *input++;
    *sslBytes -= 1;
    
    /* make sure can read through compression */
    if ( (b + SUITE_LEN + ENUM_LEN) > *sslBytes) {
        SetError(SERVER_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
        return -1;
    }
    if (b) {
        XMEMCPY(session->sslServer->arrays.sessionID, input, ID_LEN);
        session->sslServer->options.haveSessionId = 1;
    }
    input     += b;
    *sslBytes -= b;
   
    /* cipher suite */ 
    (void)*input++;  /* eat first byte, always 0 */
    b = *input++;
    session->sslServer->options.cipherSuite = b;
    session->sslClient->options.cipherSuite = b;
    *sslBytes -= SUITE_LEN;

    /* compression */
    b = *input++;
    *sslBytes -= ENUM_LEN;

    if (b) {
        SetError(BAD_COMPRESSION_STR, error, session, FATAL_ERROR_STATE);
        return -1;
    }
   
    if (session->sslServer->options.haveSessionId &&
            XMEMCMP(session->sslServer->arrays.sessionID,
                    session->sslClient->arrays.sessionID, ID_LEN) == 0)
        doResume = 1;
    else if (session->sslClient->options.haveSessionId == 0 &&
             session->sslServer->options.haveSessionId == 0 &&
             session->ticketID)
        doResume = 1;

    if (session->ticketID && doResume) {
        /* use ticketID to retrieve from session */
        XMEMCPY(session->sslServer->arrays.sessionID, session->ticketID,ID_LEN);
    }

    if (doResume ) {
        SSL_SESSION* resume = GetSession(session->sslServer,
                                       session->sslServer->arrays.masterSecret);
        if (resume == NULL) {
            SetError(BAD_SESSION_RESUME_STR, error, session, FATAL_ERROR_STATE);
            return -1;
        }
        /* make sure client has master secret too */
        XMEMCPY(session->sslClient->arrays.masterSecret,
               session->sslServer->arrays.masterSecret, SECRET_LEN);
        session->flags.resuming = 1;
        
        Trace(SERVER_DID_RESUMPTION_STR);
        if (SetCipherSpecs(session->sslServer) != 0) {
            SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE);
            return -1;
        }
        
        if (SetCipherSpecs(session->sslClient) != 0) {
            SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE);
            return -1;
        }
        
        if (session->sslServer->options.tls) {
            DeriveTlsKeys(session->sslServer);
            DeriveTlsKeys(session->sslClient);
        }
        else {
            DeriveKeys(session->sslServer);
            DeriveKeys(session->sslClient);
        }
    }
#ifdef SHOW_SECRETS
    {
        int i;
        printf("cipher suite = 0x%02x\n",
               session->sslServer->options.cipherSuite);
        printf("server random: ");
        for (i = 0; i < RAN_LEN; i++)
            printf("%02x", session->sslServer->arrays.serverRandom[i]);
        printf("\n");
    }
#endif   
    return 0;
}


/* Process normal Client Hello */
static int ProcessClientHello(const byte* input, int* sslBytes, 
                              SnifferSession* session, char* error)
{
    byte   bLen;
    word16 len;
    int    toRead = sizeof(ProtocolVersion) + RAN_LEN + ENUM_LEN;
    
    session->flags.clientHello = 1;  /* don't process again */
    
    /* make sure can read up to session len */
    if (toRead > *sslBytes) {
        SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
        return -1;
    }
    
    /* skip, get negotiated one from server hello */
    input     += sizeof(ProtocolVersion);
    *sslBytes -= sizeof(ProtocolVersion);
    
    XMEMCPY(session->sslServer->arrays.clientRandom, input, RAN_LEN);
    XMEMCPY(session->sslClient->arrays.clientRandom, input, RAN_LEN);
    
    input     += RAN_LEN;
    *sslBytes -= RAN_LEN;
    
    /* store session in case trying to resume */
    bLen = *input++;
    *sslBytes -= ENUM_LEN;
    if (bLen) {
        if (ID_LEN > *sslBytes) {
            SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
            return -1;
        }
        Trace(CLIENT_RESUME_TRY_STR);
        XMEMCPY(session->sslClient->arrays.sessionID, input, ID_LEN);
        session->sslClient->options.haveSessionId = 1;
    }
#ifdef SHOW_SECRETS
    {
        int i;
        printf("client random: ");
        for (i = 0; i < RAN_LEN; i++)
            printf("%02x", session->sslServer->arrays.clientRandom[i]);
        printf("\n");
    }
#endif

    input     += bLen;
    *sslBytes -= bLen;

    /* skip cipher suites */
    /* make sure can read len */
    if (SUITE_LEN > *sslBytes) {
        SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
        return -1;
    }
    len = (input[0] << 8) | input[1];
    input     += SUITE_LEN;
    *sslBytes -= SUITE_LEN;
    /* make sure can read suites + comp len */
    if (len + ENUM_LEN > *sslBytes) {
        SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
        return -1;
    }
    input     += len;
    *sslBytes -= len;

    /* skip compression */
    bLen       = *input++;
    *sslBytes -= ENUM_LEN;
    /* make sure can read len */
    if (bLen > *sslBytes) {
        SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
        return -1;
    }
    input     += bLen;
    *sslBytes -= bLen;
  
    if (*sslBytes == 0) {
        /* no extensions */
        return 0;
    }
    
    /* skip extensions until session ticket */
    /* make sure can read len */
    if (SUITE_LEN > *sslBytes) {
        SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
        return -1;
    }
    len = (input[0] << 8) | input[1];
    input     += SUITE_LEN;
    *sslBytes -= SUITE_LEN;
    /* make sure can read through all extensions */
    if (len > *sslBytes) {
        SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
        return -1;
    }

    while (len > EXT_TYPE_SZ + LENGTH_SZ) {
        byte   extType[EXT_TYPE_SZ];
        word16 extLen;

        extType[0] = input[0];
        extType[1] = input[1];
        input     += EXT_TYPE_SZ;
        *sslBytes -= EXT_TYPE_SZ;

        extLen = (input[0] << 8) | input[1];
        input     += LENGTH_SZ;
        *sslBytes -= LENGTH_SZ;

        /* make sure can read through individual extension */
        if (extLen > *sslBytes) {
            SetError(CLIENT_HELLO_INPUT_STR, error, session, FATAL_ERROR_STATE);
            return -1;
        }

        if (extType[0] == 0x00 && extType[1] == TICKET_EXT_ID) {

            /* make sure can read through ticket if there is a non blank one */
            if (extLen && extLen < ID_LEN) {
                SetError(CLIENT_HELLO_INPUT_STR, error, session,
                         FATAL_ERROR_STATE);
                return -1;
            }

            if (extLen) {
                if (session->ticketID == 0) {
                    session->ticketID = (byte*)malloc(ID_LEN);
                    if (session->ticketID == 0) {
                        SetError(MEMORY_STR, error, session,
                                 FATAL_ERROR_STATE);
                        return -1;
                    }
                }
                XMEMCPY(session->ticketID, input + extLen - ID_LEN, ID_LEN);
            }
        }

        input     += extLen;
        *sslBytes -= extLen;
        len       -= extLen + EXT_TYPE_SZ + LENGTH_SZ;
    }

    return 0;
}


/* Process Finished */
static int ProcessFinished(const byte* input, int* sslBytes, 
                           SnifferSession* session, char* error)
{
    SSL*   ssl;
    word32 inOutIdx = 0;
    int    ret;
                
    if (session->flags.side == SERVER_END)
        ssl = session->sslServer;
    else
        ssl = session->sslClient;
    ret = DoFinished(ssl, input, &inOutIdx, SNIFF);
    *sslBytes -= (int)inOutIdx;

    if (ret < 0) {
        SetError(BAD_FINISHED_MSG, error, session, FATAL_ERROR_STATE);
        return ret;
    }
                
    if (ret == 0 && session->flags.cached == 0) {
        if (session->sslServer->options.haveSessionId) {
            CYASSL_SESSION* sess = GetSession(session->sslServer, NULL);
            if (sess == NULL)
                AddSession(session->sslServer);  /* don't re add */
            session->flags.cached = 1;
         }
    }


    return ret;
}


/* Process HandShake input */
static int DoHandShake(const byte* input, int* sslBytes,
                       SnifferSession* session, char* error)
{
    byte type;
    int  size;
    int  ret = 0;
    
    if (*sslBytes < HANDSHAKE_HEADER_SZ) {
        SetError(HANDSHAKE_INPUT_STR, error, session, FATAL_ERROR_STATE);
        return -1;
    }
    type = input[0];
    size = (input[1] << 16) | (input[2] << 8) | input[3];
    
    input     += HANDSHAKE_HEADER_SZ;
    *sslBytes -= HANDSHAKE_HEADER_SZ;
    
    if (*sslBytes < size) {
        SetError(HANDSHAKE_INPUT_STR, error, session, FATAL_ERROR_STATE);
        return -1;
    }
    
    switch (type) {
        case hello_verify_request:
            Trace(GOT_HELLO_VERIFY_STR);
            break;
        case hello_request:
            Trace(GOT_HELLO_REQUEST_STR);
            break;
        case session_ticket:
            Trace(GOT_SESSION_TICKET_STR);
            ret = ProcessSessionTicket(input, sslBytes, session, error);
            break;
        case server_hello:
            Trace(GOT_SERVER_HELLO_STR);
            ret = ProcessServerHello(input, sslBytes, session, error);
            break;
        case certificate_request:
            Trace(GOT_CERT_REQ_STR);
            break;
        case server_key_exchange:
            Trace(GOT_SERVER_KEY_EX_STR);
            /* can't know temp key passively */
            SetError(BAD_CIPHER_SPEC_STR, error, session, FATAL_ERROR_STATE);
            ret = -1;
            break;
        case certificate:
            Trace(GOT_CERT_STR);
            break;
        case server_hello_done:
            Trace(GOT_SERVER_HELLO_DONE_STR);
            break;
        case finished:
            Trace(GOT_FINISHED_STR);
            ret = ProcessFinished(input, sslBytes, session, error);
            break;
        case client_hello:
            Trace(GOT_CLIENT_HELLO_STR);
            ret = ProcessClientHello(input, sslBytes, session, error);
            break;
        case client_key_exchange:
            Trace(GOT_CLIENT_KEY_EX_STR);
            ret = ProcessClientKeyExchange(input, sslBytes, session, error);
            break;
        case certificate_verify:
            Trace(GOT_CERT_VER_STR);
            break;
        default:
            SetError(GOT_UNKNOWN_HANDSHAKE_STR, error, session, 0);
            return -1;
    }   

    return ret;
}


/* Decrypt input into plain output */
static void Decrypt(SSL* ssl, byte* output, const byte* input, word32 sz)
{
    switch (ssl->specs.bulk_cipher_algorithm) {
        #ifdef BUILD_ARC4
        case rc4:
            Arc4Process(&ssl->decrypt.arc4, output, input, sz);
            break;
        #endif
            
        #ifdef BUILD_DES3
        case triple_des:
            Des3_CbcDecrypt(&ssl->decrypt.des3, output, input, sz);
            break;
        #endif
            
        #ifdef BUILD_AES
        case aes:
            AesCbcDecrypt(&ssl->decrypt.aes, output, input, sz);
            break;
        #endif
            
        #ifdef HAVE_HC128
        case hc128:
            Hc128_Process(&ssl->decrypt.hc128, output, input, sz);
            break;
        #endif
            
        #ifdef BUILD_RABBIT
        case rabbit:
            RabbitProcess(&ssl->decrypt.rabbit, output, input, sz);
            break;
        #endif

        default:
            Trace(BAD_DECRYPT_TYPE);
            break;
    }
}


/* Decrypt input message into output, adjust output steam if needed */
static const byte* DecryptMessage(SSL* ssl, const byte* input, word32 sz,
                                  byte* output)
{
    Decrypt(ssl, output, input, sz);
    ssl->keys.encryptSz = sz;
    if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
        return output + ssl->specs.block_size;     /* go past TLSv1.1 IV */
    
    return output;
}


/* remove session from table, use rowHint if no info (means we have a lock) */
static void RemoveSession(SnifferSession* session, IpInfo* ipInfo,
                        TcpInfo* tcpInfo, word32 rowHint)
{
    SnifferSession* previous = 0;
    SnifferSession* current;
    word32          row = rowHint;
    int             haveLock = 0;
   
    if (ipInfo && tcpInfo)
        row = SessionHash(ipInfo, tcpInfo);
    else
        haveLock = 1;
    
    assert(row >= 0 && row <= HASH_SIZE);
    Trace(REMOVE_SESSION_STR);
    
    if (!haveLock)
        LockMutex(&SessionMutex);
    
    current = SessionTable[row];
    
    while (current) {
        if (current == session) {
            if (previous)
                previous->next = current->next;
            else
                SessionTable[row] = current->next;
            FreeSnifferSession(session);
            TraceRemovedSession();
            break;
        }
        previous = current;
        current  = current->next;
    }
    
    if (!haveLock)
        UnLockMutex(&SessionMutex);
}


/* Remove stale sessions from the Session Table, have a lock */
static void RemoveStaleSessions(void)
{
    word32 i;
    SnifferSession* session;
    
    for (i = 0; i < HASH_SIZE; i++) {
        session = SessionTable[i];
        while (session) {
            SnifferSession* next = session->next; 
            if (time(NULL) >= session->bornOn + SNIFFER_TIMEOUT) {
                TraceStaleSession();
                RemoveSession(session, NULL, NULL, i);
            }
            session = next;
        }
    }
}


/* Create a new Sniffer Session */
static SnifferSession* CreateSession(IpInfo* ipInfo, TcpInfo* tcpInfo,
                                     char* error)
{
    SnifferSession* session = 0;
    int row;
        
    Trace(NEW_SESSION_STR);
    /* create a new one */
    session = (SnifferSession*)malloc(sizeof(SnifferSession));
    if (session == NULL) {
        SetError(MEMORY_STR, error, NULL, 0);
        return 0;
    }
    InitSession(session);
    session->server  = ipInfo->dst;
    session->client  = ipInfo->src;
    session->srvPort = tcpInfo->dstPort;
    session->cliPort = tcpInfo->srcPort;
    session->cliSeqStart = tcpInfo->sequence;
    session->cliExpected = 1;  /* relative */
    session->bornOn = time(NULL);
                
    session->context = GetSnifferServer(ipInfo, tcpInfo);
    if (session->context == NULL) {
        SetError(SERVER_NOT_REG_STR, error, NULL, 0);
        free(session);
        return 0;
    }
        
    session->sslServer = SSL_new(session->context->ctx);
    session->sslClient = SSL_new(session->context->ctx);
    if (session->sslClient == NULL) {
        if (session->sslServer) {
            SSL_free(session->sslClient);
            session->sslClient = 0;
        }
        SetError(BAD_NEW_SSL_STR, error, session, FATAL_ERROR_STATE);
        free(session);
        return 0;
    }
    /* put server back into server mode */
    session->sslServer->options.side = SERVER_END;
        
    row = SessionHash(ipInfo, tcpInfo);
    
    /* add it to the session table */
    LockMutex(&SessionMutex);
        
    session->next = SessionTable[row];
    SessionTable[row] = session;
    
    SessionCount++;
    
    if ( (SessionCount % HASH_SIZE) == 0) {
        TraceFindingStale();
        RemoveStaleSessions();
    }
        
    UnLockMutex(&SessionMutex);
        
    /* determine headed side */
    if (ipInfo->dst == session->context->server &&
        tcpInfo->dstPort == session->context->port)
        session->flags.side = SERVER_END;
    else
        session->flags.side = CLIENT_END;        
    
    return session;
}


/* Process Old Client Hello Input */
static int DoOldHello(SnifferSession* session, const byte* sslFrame,
                      int* rhSize, int* sslBytes, char* error)
{
    const byte* input = sslFrame;
    byte        b0, b1;
    word32      idx = 0;
    int         ret;

    Trace(GOT_OLD_CLIENT_HELLO_STR);
    session->flags.clientHello = 1;    /* don't process again */
    b0 = *input++;
    b1 = *input++;
    *sslBytes -= 2;
    *rhSize = ((b0 & 0x7f) << 8) | b1;

    if (*rhSize > *sslBytes) {
        SetError(OLD_CLIENT_INPUT_STR, error, session, FATAL_ERROR_STATE);
        return -1;
    }

    ret = ProcessOldClientHello(session->sslServer, input, &idx, *sslBytes,
                                *rhSize);    
    if (ret < 0) {
        SetError(BAD_OLD_CLIENT_STR, error, session, FATAL_ERROR_STATE);
        return -1;
    }
    
    Trace(OLD_CLIENT_OK_STR);
    XMEMCPY(session->sslClient->arrays.clientRandom,
           session->sslServer->arrays.clientRandom, RAN_LEN);
    
    *sslBytes -= *rhSize;
    return 0;
}


#if 0
/* Calculate the TCP checksum, see RFC 1071 */
/* return 0 for success, -1 on error */
/* can be called from decode() with
   TcpChecksum(&ipInfo, &tcpInfo, sslBytes, packet + ipInfo.length);
   could also add a 64bit version if type available and using this
*/
int TcpChecksum(IpInfo* ipInfo, TcpInfo* tcpInfo, int dataLen,
                const byte* packet)
{
    TcpPseudoHdr  pseudo;
    int           count = PSEUDO_HDR_SZ;
    const word16* data = (word16*)&pseudo;
    word32        sum = 0;
    word16        checksum;
    
    pseudo.src = ipInfo->src;
    pseudo.dst = ipInfo->dst;
    pseudo.rsv = 0;
    pseudo.protocol = TCP_PROTO;
    pseudo.legnth = htons(tcpInfo->length + dataLen);
    
    /* pseudo header sum */
    while (count >= 2) {
        sum   += *data++;
        count -= 2;
    }
    
    count = tcpInfo->length + dataLen;
    data = (word16*)packet;
    
    /* main sum */
    while (count > 1) {
        sum   += *data++;
        count -=2;
    }
    
    /* get left-over, if any */
    packet = (byte*)data;
    if (count > 0) {
        sum += *packet;
    }
    
    /* fold 32bit sum into 16 bits */
    while (sum >> 16)
        sum = (sum & 0xffff) + (sum >> 16);
    
    checksum = (word16)~sum;
    /* checksum should now equal 0, since included already calcd checksum */
    /* field, but tcp checksum offloading could negate calculation */
    if (checksum == 0)
        return 0;
    return -1;
}
#endif


/* Check IP and TCP headers, set payload */
/* returns 0 on success, -1 on error */
static int CheckHeaders(IpInfo* ipInfo, TcpInfo* tcpInfo, const byte* packet,
                  int length, const byte** sslFrame, int* sslBytes, char* error)
{
    TraceHeader();
    TracePacket();
    if (length < IP_HDR_SZ) {
        SetError(PACKET_HDR_SHORT_STR, error, NULL, 0);
        return -1;
    }
    if (CheckIpHdr((IpHdr*)packet, ipInfo, error) != 0)
        return -1;
    
    if (length < (ipInfo->length + TCP_HDR_SZ)) {
        SetError(PACKET_HDR_SHORT_STR, error, NULL, 0);
        return -1;
    }
    if (CheckTcpHdr((TcpHdr*)(packet + ipInfo->length), tcpInfo, error) != 0)
        return -1;
    
    *sslFrame = packet + ipInfo->length + tcpInfo->length;
    if (*sslFrame > packet + length) {
        SetError(PACKET_HDR_SHORT_STR, error, NULL, 0);
        return -1;
    }
    *sslBytes = packet + length - *sslFrame;
    
    return 0;
}


/* Create or Find existing session */
/* returns 0 on success (continue), -1 on error, 1 on success (end) */
static int CheckSession(IpInfo* ipInfo, TcpInfo* tcpInfo, int sslBytes,
                        SnifferSession** session, char* error)
{
    /* create a new SnifferSession on client SYN */
    if (tcpInfo->syn && !tcpInfo->ack) {
        TraceClientSyn(tcpInfo->sequence);
        *session = CreateSession(ipInfo, tcpInfo, error);
        if (*session == NULL) {
            *session = GetSnifferSession(ipInfo, tcpInfo);
            /* already had exisiting, so OK */
            if (*session)
                return 1;
            
            SetError(MEMORY_STR, error, NULL, 0);
            return -1;
        }
        return 1;
    }
    /* get existing sniffer session */
    else {
        *session = GetSnifferSession(ipInfo, tcpInfo);
        if (*session == NULL) {
            /* don't worry about extraneous RST or duplicate FINs */
            if (tcpInfo->fin || tcpInfo->rst)
                return 1;
            /* don't worry about duplicate ACKs either */
            if (sslBytes == 0 && tcpInfo->ack)
                return 1;
            
            SetError(BAD_SESSION_STR, error, NULL, 0);
            return -1;
        }        
    }
    return 0;
}


/* Create a Packet Buffer from *begin - end, adjust new *begin and bytesLeft */
static PacketBuffer* CreateBuffer(word32* begin, word32 end, const byte* data,
                                  int* bytesLeft)
{
    PacketBuffer* pb;
    
    int added = end - *begin + 1;
    assert(*begin <= end);
    
    pb = (PacketBuffer*)malloc(sizeof(PacketBuffer));
    if (pb == NULL) return NULL;
    
    pb->next  = 0;
    pb->begin = *begin;
    pb->end   = end;
    pb->data = (byte*)malloc(added);
    
    if (pb->data == NULL) {
        free(pb);
        return NULL;
    }
    XMEMCPY(pb->data, data, added);
    
    *bytesLeft -= added;
    *begin      = pb->end + 1;
    
    return pb;
}


/* Add sslFrame to Reassembly List */
/* returns 1 (end) on success, -1, on error */
static int AddToReassembly(byte from, word32 seq, const byte* sslFrame,
                           int sslBytes, SnifferSession* session, char* error)
{
    PacketBuffer*  add;
    PacketBuffer** front = (from == SERVER_END) ? &session->cliReassemblyList:
                                                  &session->srvReassemblyList;
    PacketBuffer*  curr = *front;
    PacketBuffer*  prev = curr;
    
    word32  startSeq = seq;
    word32  added;
    int     bytesLeft = sslBytes;  /* could be overlapping fragment */

    /* if list is empty add full frame to front */
    if (!curr) {
        add = CreateBuffer(&seq, seq + sslBytes - 1, sslFrame, &bytesLeft);
        if (add == NULL) {
            SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
            return -1;
        }
        *front = add;
        return 1;
    }
    
    /* add to front if before current front, up to next->begin */
    if (seq < curr->begin) {
        word32 end = seq + sslBytes - 1;
        
        if (end >= curr->begin)
            end = curr->begin - 1;
        
        add = CreateBuffer(&seq, end, sslFrame, &bytesLeft);
        if (add == NULL) {
            SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
            return -1;
        }
        add->next = curr;
        *front = add;
    }
    
    /* while we have bytes left, try to find a gap to fill */
    while (bytesLeft > 0) {
        /* get previous packet in list */
        while (curr && (seq >= curr->begin)) {
            prev = curr;
            curr = curr->next;
        }
        
        /* don't add  duplicate data */
        if (prev->end >= seq) {
            if ( (seq + bytesLeft - 1) <= prev->end)
                return 1;
            seq = prev->end + 1;
            bytesLeft = startSeq + sslBytes - seq;
        }
        
        if (!curr)
            /* we're at the end */
            added = bytesLeft;
        else 
            /* we're in between two frames */
            added = min((word32)bytesLeft, curr->begin - seq);
        
        /* data already there */
        if (added == 0)
            continue;
        
        add = CreateBuffer(&seq, seq + added - 1, &sslFrame[seq - startSeq],
                           &bytesLeft);
        if (add == NULL) {
            SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
            return -1;
        }
        add->next  = prev->next;
        prev->next = add;
    }
    return 1;
}


/* Add out of order FIN capture */
/* returns 1 for success (end) */
static int AddFinCapture(SnifferSession* session, word32 sequence)
{
    if (session->flags.side == SERVER_END) {
        if (session->finCaputre.cliCounted == 0)
            session->finCaputre.cliFinSeq = sequence;
    }
    else {
        if (session->finCaputre.srvCounted == 0)
            session->finCaputre.srvFinSeq = sequence;
    }
    return 1;
}


/* Adjust incoming sequence based on side */
/* returns 0 on success (continue), -1 on error, 1 on success (end) */
static int AdjustSequence(TcpInfo* tcpInfo, SnifferSession* session,
                          int* sslBytes, const byte** sslFrame, char* error)
{
    word32  seqStart = (session->flags.side == SERVER_END) ? 
                                     session->cliSeqStart :session->srvSeqStart;
    word32  real     = tcpInfo->sequence - seqStart;
    word32* expected = (session->flags.side == SERVER_END) ?
                                  &session->cliExpected : &session->srvExpected;
    PacketBuffer* reassemblyList = (session->flags.side == SERVER_END) ?
                        session->cliReassemblyList : session->srvReassemblyList;
    
    /* handle rollover of sequence */
    if (tcpInfo->sequence < seqStart)
        real = 0xffffffffU - seqStart + tcpInfo->sequence;
        
    TraceRelativeSequence(*expected, real);
    
    if (real < *expected) {
        Trace(DUPLICATE_STR);
        if (real + *sslBytes > *expected) {
            int overlap = *expected - real;
            Trace(OVERLAP_DUPLICATE_STR);
                
            /* adjust to expected, remove duplicate */
            *sslFrame += overlap;
            *sslBytes -= overlap;
                
            if (reassemblyList) {
                word32 newEnd = *expected + *sslBytes;
                    
                if (newEnd > reassemblyList->begin) {
                    Trace(OVERLAP_REASSEMBLY_BEGIN_STR);
                    
                    /* remove bytes already on reassembly list */
                    *sslBytes -= newEnd - reassemblyList->begin;
                }
                if (newEnd > reassemblyList->end) {
                    Trace(OVERLAP_REASSEMBLY_END_STR);
                    
                    /* may be past reassembly list end (could have more on list)
                       so try to add what's past the front->end */
                    AddToReassembly(session->flags.side, reassemblyList->end +1,
                                *sslFrame + reassemblyList->end - *expected + 1,
                                 newEnd - reassemblyList->end, session, error);
                }
            }
        }
        else
            return 1;
    }
    else if (real > *expected) {
        Trace(OUT_OF_ORDER_STR);
        if (*sslBytes > 0)
            return AddToReassembly(session->flags.side, real, *sslFrame,
                                   *sslBytes, session, error);
        else if (tcpInfo->fin)
            return AddFinCapture(session, real);
    }
    /* got expected sequence */
    *expected += *sslBytes;
    if (tcpInfo->fin)
        *expected += 1;
    
    return 0;
}


/* Check TCP Sequence status */
/* returns 0 on success (continue), -1 on error, 1 on success (end) */
static int CheckSequence(IpInfo* ipInfo, TcpInfo* tcpInfo,
                         SnifferSession* session, int* sslBytes,
                         const byte** sslFrame, char* error)
{
    int actualLen;
    
    /* init SEQ from server to client */
    if (tcpInfo->syn && tcpInfo->ack) {
        session->srvSeqStart = tcpInfo->sequence;
        session->srvExpected = 1;
        TraceServerSyn(tcpInfo->sequence);
        return 1;
    }
    
    /* adjust potential ethernet trailer */
    actualLen = ipInfo->total - ipInfo->length - tcpInfo->length;
    if (*sslBytes > actualLen) {
        *sslBytes = actualLen;
    }
    
    TraceSequence(tcpInfo->sequence, *sslBytes);
    
    return AdjustSequence(tcpInfo, session, sslBytes, sslFrame, error);    
}


/* Check Status before record processing */
/* returns 0 on success (continue), -1 on error, 1 on success (end) */
static int CheckPreRecord(IpInfo* ipInfo, TcpInfo* tcpInfo,
                          const byte** sslFrame, SnifferSession* session,
                          int* sslBytes, const byte** end, char* error)
{
    word32 length;
    SSL*   ssl = (session->flags.side == SERVER_END) ? session->sslServer :
                                                       session->sslClient;
    /* remove SnifferSession on 2nd FIN or RST */
    if (tcpInfo->fin || tcpInfo->rst) {
        /* flag FIN and RST */
        if (tcpInfo->fin)
            session->flags.finCount += 1;
        else if (tcpInfo->rst)
            session->flags.finCount += 2;
        
        if (session->flags.finCount >= 2) {
            RemoveSession(session, ipInfo, tcpInfo, 0);
            return 1;
        }
    }
    
    if (session->flags.fatalError == FATAL_ERROR_STATE) {
        SetError(FATAL_ERROR_STR, error, NULL, 0);
        return -1;
    }
    
    if (*sslBytes == 0) {
        Trace(NO_DATA_STR);
        return 1;
    }
    
    /* if current partial data, add to end of partial */
    if ( (length = ssl->buffers.inputBuffer.length) ) {
        Trace(PARTIAL_ADD_STR);
        
        if ( (*sslBytes + length) > ssl->buffers.inputBuffer.bufferSize) {
            SetError(BUFFER_ERROR_STR, error, session, FATAL_ERROR_STATE);
            return -1;
        }
        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) {
        int rhSize;
        int ret = DoOldHello(session, *sslFrame, &rhSize, sslBytes, error);
        if (ret < 0)
            return -1;  /* error already set */
        if (*sslBytes <= 0)
            return 1;
    }
    
    return 0;
}


/* See if input on the reassembly list is ready for consuming */
/* returns 1 for TRUE, 0 for FALSE */
static int HaveMoreInput(SnifferSession* session, const byte** sslFrame,
                         int* sslBytes, const byte** end)
{
    /* sequence and reassembly based on from, not to */
    int            moreInput = 0;
    PacketBuffer** front = (session->flags.side == SERVER_END) ?
                      &session->cliReassemblyList : &session->srvReassemblyList;
    word32*        expected = (session->flags.side == SERVER_END) ?
                                  &session->cliExpected : &session->srvExpected;
    /* buffer is on receiving end */
    word32*        length = (session->flags.side == SERVER_END) ?
                               &session->sslServer->buffers.inputBuffer.length :
                               &session->sslClient->buffers.inputBuffer.length;
    byte*          myBuffer = (session->flags.side == SERVER_END) ?
                                session->sslServer->buffers.inputBuffer.buffer :
                                session->sslClient->buffers.inputBuffer.buffer;
    
    while (*front && ((*front)->begin == *expected) ) {
        word32 room = STATIC_BUFFER_LEN - *length;
        word32 packetLen = (*front)->end - (*front)->begin + 1;
        
        if (packetLen <= room) {
            PacketBuffer* del = *front;
            
            XMEMCPY(&myBuffer[*length], (*front)->data, packetLen);
            *length   += packetLen;
            *expected += packetLen;
            
            /* remove used packet */
            *front = (*front)->next;
            FreePacketBuffer(del);
            
            moreInput = 1;
        }
        else
            break;
    }
    if (moreInput) {
        *sslFrame = myBuffer;
        *sslBytes = *length;
        *end      = myBuffer + *length;
    }
    return moreInput;
}
                         


/* Process Message(s) from sslFrame */
/* return Number of bytes on success, 0 for no data yet, and -1 on error */
static int ProcessMessage(const byte* sslFrame, SnifferSession* session,
                          int sslBytes, byte* data, const byte* end,char* error)
{
    const byte*       sslBegin = sslFrame;
    const byte*       tmp;
    RecordLayerHeader rh;
    int               rhSize;
    int               ret;
    int               decoded = 0;      /* bytes stored for user in data */
    int               notEnough;        /* notEnough bytes yet flag */
    SSL*              ssl = (session->flags.side == SERVER_END) ?
                                        session->sslServer : session->sslClient;
doMessage:
    notEnough = 0;
    if (sslBytes >= RECORD_HEADER_SZ) {
        if (GetRecordHeader(sslFrame, &rh, &rhSize) != 0) {
            SetError(BAD_RECORD_HDR_STR, error, session, FATAL_ERROR_STATE);
            return -1;
        }
    }
    else
        notEnough = 1;

    if (notEnough || rhSize > (sslBytes - RECORD_HEADER_SZ)) {
        /* don't have enough input yet to process full SSL record */
        Trace(PARTIAL_INPUT_STR);
        
        /* store partial if not there already or we advanced */
        if (ssl->buffers.inputBuffer.length == 0 || sslBegin != sslFrame) {
            if (sslBytes > (int)ssl->buffers.inputBuffer.bufferSize) {
                SetError(BUFFER_ERROR_STR, error, session, FATAL_ERROR_STATE);
                return -1;
            }
            XMEMCPY(ssl->buffers.inputBuffer.buffer, sslFrame, sslBytes);
            ssl->buffers.inputBuffer.length = sslBytes;
        }
        if (HaveMoreInput(session, &sslFrame, &sslBytes, &end))
            goto doMessage;
        return decoded;
    }
    sslFrame += RECORD_HEADER_SZ;
    sslBytes -= RECORD_HEADER_SZ;
    tmp = sslFrame + rhSize;   /* may have more than one record to process */
    
    /* decrypt if needed */
    if (session->flags.side == SERVER_END && session->flags.serverCipherOn)
        sslFrame = DecryptMessage(ssl, sslFrame, rhSize,
                                  ssl->buffers.outputBuffer.buffer);
    else if (session->flags.side == CLIENT_END && session->flags.clientCipherOn)
        sslFrame = DecryptMessage(ssl, sslFrame, rhSize,
                                  ssl->buffers.outputBuffer.buffer);
            
    switch ((enum ContentType)rh.type) {
        case handshake:
            Trace(GOT_HANDSHAKE_STR);
            ret = DoHandShake(sslFrame, &sslBytes, session, error);
            if (ret != 0) {
                if (session->flags.fatalError == 0)
                    SetError(BAD_HANDSHAKE_STR,error,session,FATAL_ERROR_STATE);
                return -1;
            }
            break;
        case change_cipher_spec:
            if (session->flags.side == SERVER_END)
                session->flags.serverCipherOn = 1;
            else
                session->flags.clientCipherOn = 1;
            Trace(GOT_CHANGE_CIPHER_STR);
            break;
        case application_data:
            Trace(GOT_APP_DATA_STR);
            {
                word32 inOutIdx = 0;
                    
                ret = DoApplicationData(ssl, (byte*)sslFrame, &inOutIdx);
                if (ret == 0) {
                    ret = ssl->buffers.clearOutputBuffer.length;
                    TraceGotData(ret);
                    if (ret) {  /* may be blank message */
                        XMEMCPY(&data[decoded],
                               ssl->buffers.clearOutputBuffer.buffer, ret);
                        TraceAddedData(ret, decoded);
                        decoded += ret;
                        ssl->buffers.clearOutputBuffer.length = 0;
                    }
                }
                else {
                    SetError(BAD_APP_DATA_STR, error,session,FATAL_ERROR_STATE);
                    return -1;
                }
            }
            break;
        case alert:
            Trace(GOT_ALERT_STR);
            break;
        case no_type:
        default:
            SetError(GOT_UNKNOWN_RECORD_STR, error, session, FATAL_ERROR_STATE);
            return -1;
    }
    
    if (tmp < end) {
        Trace(ANOTHER_MSG_STR);
        sslFrame = tmp;
        sslBytes = end - tmp;
        goto doMessage;
    }
    
    /* clear used input */
    ssl->buffers.inputBuffer.length = 0;
    
    /* could have more input ready now */
    if (HaveMoreInput(session, &sslFrame, &sslBytes, &end))
        goto doMessage;
    
    return decoded;
}


/* See if we need to process any pending FIN captures */
static void CheckFinCapture(IpInfo* ipInfo, TcpInfo* tcpInfo, 
                            SnifferSession* session)
{
    if (session->finCaputre.cliFinSeq && session->finCaputre.cliFinSeq <= 
                                         session->cliExpected) {
        if (session->finCaputre.cliCounted == 0) {
            session->flags.finCount += 1;
            session->finCaputre.cliCounted = 1;
            TraceClientFin(session->finCaputre.cliFinSeq, session->cliExpected);
        }
    }
        
    if (session->finCaputre.srvFinSeq && session->finCaputre.srvFinSeq <= 
                                         session->srvExpected) {
        if (session->finCaputre.srvCounted == 0) {
            session->flags.finCount += 1;
            session->finCaputre.srvCounted = 1;
            TraceServerFin(session->finCaputre.srvFinSeq, session->srvExpected);
        }
    }
                
    if (session->flags.finCount >= 2) 
        RemoveSession(session, ipInfo, tcpInfo, 0);
}


/* Passes in an IP/TCP packet for decoding (ethernet/localhost frame) removed */
/* returns Number of bytes on success, 0 for no data yet, and -1 on error */
int ssl_DecodePacket(const byte* packet, int length, byte* data, char* error)
{
    TcpInfo           tcpInfo;
    IpInfo            ipInfo;
    const byte*       sslFrame;
    const byte*       end = packet + length;
    int               sslBytes;                /* ssl bytes unconsumed */
    int               ret;
    SnifferSession*   session = 0;

    if (CheckHeaders(&ipInfo, &tcpInfo, packet, length, &sslFrame, &sslBytes,
                     error) != 0)
        return -1;
    
    ret = CheckSession(&ipInfo, &tcpInfo, sslBytes, &session, error);
    if (ret == -1)     return -1;
    else if (ret == 1) return  0;   /* done for now */
    
    ret = CheckSequence(&ipInfo, &tcpInfo, session, &sslBytes, &sslFrame,error);
    if (ret == -1)     return -1;
    else if (ret == 1) return  0;   /* done for now */
    
    ret = CheckPreRecord(&ipInfo, &tcpInfo, &sslFrame, session, &sslBytes,
                         &end, error);
    if (ret == -1)     return -1;
    else if (ret == 1) return  0;   /* done for now */

    ret = ProcessMessage(sslFrame, session, sslBytes, data, end, error);
    CheckFinCapture(&ipInfo, &tcpInfo, session);
    return ret;
}


/* Enables (if traceFile)/ Disables debug tracing */
/* returns 0 on success, -1 on error */
int ssl_Trace(const char* traceFile, char* error)
{
    if (traceFile) {
        TraceFile = fopen(traceFile, "a");
        if (!TraceFile) {
            SetError(BAD_TRACE_FILE_STR, error, NULL, 0);
            return -1;
        }
        TraceOn = 1;
    }
    else 
        TraceOn = 0;

    return 0;
}




#endif /* CYASSL_SNIFFER */
