
/*
 * $\Id$
 *
 * © Copyright IBM Corp. 2007
 *
 * THIS FILE IS PROVIDED UNDER THE TERMS OF THE ECLIPSE PUBLIC LICENSE
 * ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE
 * CONSTITUTES RECIPIENTS ACCEPTANCE OF THE AGREEMENT.
 *
 * You can obtain a current copy of the Eclipse Public License from
 * http://www.opensource.org/licenses/eclipse-1.0.php
 *
 * Author:        Sven Schuetz <sven@de.ibm.com>
 *
 * Description:   indication listener implementation
 *                Most of the network and http code is taken from sfcb
 *                and written by Adrian Schuur / Viktor Mihajlovski
 */


#include "nativeCimXml.h"
#include "utilft.h"
#include "cimXmlParser.h"

#include <pthread.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>

static int do_listen=1;

#define SOCKBUFSZ 32768
#define hdrBufsize 5000
#define hdrLimmit 5000

#ifdef __APPLE__
# define __SOCKADDR_ARG   struct sockaddr *__restrict
#endif

typedef struct _buffer {
   char *data, *content;
   int length, size, ptr, content_length,trailers;
   char *httpHdr, *authorization, *content_type, *host, *useragent;
   char *principal;
   char *protocol;
} Buffer;

typedef struct commHndl {
  int   socket;
  FILE *file;
  void *buf;
} CommHndl;


static void freeBuffer(Buffer * b)
{
   Buffer emptyBuf = { NULL, NULL, 0, 0, 0, 0, 0 ,0};
   if (b->data)
      free(b->data);
   if (b->content)
      free(b->content);
   *b=emptyBuf;   
}


int commWrite(CommHndl to, void *data, size_t count)
{
   int rc=0;
  
    if (to.file == NULL) { 
        rc = write(to.socket,data,count);
    } else {
        rc = fwrite(data,count,1,to.file);
        if (rc == 1) {
        /* return number of bytes written */
        rc = count;
        }
    }
    
    return rc;
}

int commRead(CommHndl from, void *data, size_t count)
{
    int rc=0;
    
    rc = read(from.socket,data,count);
    
    return rc;
}

void commClose(CommHndl hndl)
{
    if (hndl.file == NULL) {
        close(hndl.socket);
    } else {
        fclose(hndl.file);
        if (hndl.buf) {
            free(hndl.buf);
        }
    }
}

void commFlush(CommHndl hndl)
{
    if (hndl.file) {
        fflush(hndl.file);
    }
}

static void add2buffer(Buffer * b, char *str, size_t len)
{
   if (b->size == 0) {
      b->size = len + 500;
      b->length = 0;
      b->data = (char *) malloc(b->size);
   }
   else if (b->length + len >= b->size) {
      b->size = b->length + len + 500;
      b->data = (char *) realloc((void *) b->data, b->size);
   }
   memmove(&((b->data)[b->length]), str, len);
   b->length += len;
   (b->data)[b->length] = 0;
}

static void genError(CommHndl conn_fd, Buffer * b, int status, char *title,
                     char *more)
{
    char head[1000];
    char server[] = "Server: sfcc indListener\r\n";
    char clength[] = "Content-Length: 0\r\n";
    char cclose[] = "Connection: close\r\n";
    char end[] = "\r\n";

    snprintf(head, sizeof(head), "%s %d %s\r\n", b->protocol, status, title);
    commWrite(conn_fd, head, strlen(head));
    if (more) {
        commWrite(conn_fd, more, strlen(more));
    }
    commWrite(conn_fd, server, strlen(server));
    commWrite(conn_fd, clength, strlen(clength));
    commWrite(conn_fd, cclose, strlen(cclose));

    commWrite(conn_fd, end, strlen(end));
    commFlush(conn_fd);
}

static char *getNextHdr(Buffer * b)
{
    int i;
    char c;

    for (i = b->ptr; b->ptr < b->length; ++b->ptr) {
        c = b->data[b->ptr];
        if (c == '\n' || c == '\r') {
            b->data[b->ptr] = 0;
            ++b->ptr;
            if (c == '\r' && b->ptr < b->length && b->data[b->ptr] == '\n') {
                b->data[b->ptr] = 0;
                ++b->ptr;
            }
            return &(b->data[i]);
        }
    }
    return NULL;
}

static int readData(CommHndl conn_fd, char *into, int length)
{
    int c = 0, r;

    while (c < length) {
        r = commRead(conn_fd, into + c, length - c);
        if (r < 0 && (errno == EINTR || errno == EAGAIN)) {
            continue;
        }
        c += r;
    }
    return c;
}

static void getPayload(CommHndl conn_fd, Buffer * b)
{
    int c = b->length - b->ptr;
    b->content = (char *) malloc(b->content_length + 8);
    if (c) memcpy(b->content, (b->data) + b->ptr, c);

    readData(conn_fd, (b->content) + c, b->content_length - c);
    *((b->content) + b->content_length) = 0;
}

static int  getHdrs(CommHndl conn_fd, Buffer * b, char *cmd)
{
   int first=1,total=0,isReady;
   struct timeval httpTimeout;
   fd_set httpfds;
   int state=0;
   
   FD_ZERO(&httpfds);
   FD_SET(conn_fd.socket,&httpfds);
   httpTimeout.tv_sec=5;
   httpTimeout.tv_usec=0;
   isReady = select(conn_fd.socket+1,&httpfds,NULL,NULL,&httpTimeout);
   if (isReady == 0) return 3;
    
   for (;;) {
      char buf[hdrBufsize];
      int r = commRead(conn_fd, buf, sizeof(buf));
      
      if (r < 0 && (errno == EINTR || errno == EAGAIN)) continue;
      if (r <= 0) break;
      
      add2buffer(b, buf, r);
      total+=r;
      if (r && first) {
         if (strncasecmp(buf,cmd,strlen(cmd)) != 0) { 
       /* not what we expected - still continue to read to
          not confuse the client */
       state = 1;
     }
         first=0;
      }
      
      if (strstr(b->data, "\r\n\r\n") != NULL ||
          strstr(b->data, "\n\n") != NULL) {
         break;
      }
      
      if (total>=hdrLimmit) {
        fprintf(stderr, "-#- Possible DOS attempt detected\n");
        state = 2;
        break;
      }
   }
   return state;
}

static void processIndication(struct native_indicationlistener *i, char *xml)
{
    ResponseHdr rh;
    
    CIMCInstance *inst;
    
    rh = scanCimXmlResponse(xml, NULL);
    
    if (rh.errCode != 0) {
        free(rh.description);
        rh.rvArray->ft->release(rh.rvArray);
        return;
    }
   
    inst = (CIMCInstance*)rh.rvArray->ft->getElementAt(rh.rvArray, 0, NULL).value.inst;
    
    if(inst) {
        i->sendIndicationInstance(inst->ft->clone(inst, NULL));
    }
    
    rh.rvArray->ft->release(rh.rvArray);
}

static void handleConnection(int connFd, struct native_indicationlistener *i)
{
    Buffer inBuf = { NULL, NULL, 0, 0, 0, 0, 0 ,0};
    int badReq = 0;
    int discardInput=0;
    char *path, *hdr;
    char *cp;
    CommHndl conn_fd;
    int rc;
    
    inBuf.authorization = "";
    inBuf.protocol="HTTP/1.1";
    inBuf.content_type = NULL;
    inBuf.content_length = -1;
    inBuf.host = NULL;
    inBuf.useragent = "";
    
    conn_fd.socket=connFd;
    conn_fd.file=fdopen(connFd,"a");
    conn_fd.buf = NULL;
    if (conn_fd.file == NULL) {
        /* failed to create socket stream - continue with raw socket */
    } else {
        conn_fd.buf = malloc(SOCKBUFSZ);
    if (conn_fd.buf) {
        setbuffer(conn_fd.file,conn_fd.buf,SOCKBUFSZ);
    } else {
           /* failed to create socket buffer - continue unbuffered */
        }
    }

    rc=getHdrs(conn_fd, &inBuf,"POST ");
    
    if (rc==1) { 
        genError(conn_fd, &inBuf, 501, "Not Implemented", NULL);
        /* we continue to parse headers and empty the socket
        to be graceful with the client */
        discardInput=1;
    }
    else if (rc==2) {
        genError(conn_fd, &inBuf, 400, "Bad Request", NULL);
        discardInput=2;
        /* potential DOS attempt discovered */      
    }
    else if (rc==3) {
        genError(conn_fd, &inBuf, 400, "Bad Request", NULL);
        /* exiting after request timeout */
        commClose(conn_fd);
        exit(1);
    }
            
    if (inBuf.size == 0) {
        /* no buffer data - end of file - quit */   
        commClose(conn_fd);
        exit(1);
    }
    
    inBuf.httpHdr = getNextHdr(&inBuf);
    for (badReq = 1;;) {
        if (inBuf.httpHdr == NULL) {
            break;
        }
        path = strpbrk(inBuf.httpHdr, " \t\r\n");
        if (path == NULL) {
            break;
        }
        *path++ = 0;
        path += strspn(path, " \t\r\n");
        inBuf.protocol = strpbrk(path, " \t\r\n");
        *inBuf.protocol++ = 0;
        if (inBuf.protocol == NULL) {
            break;
        }
        badReq = 0;
    }
    
    while ((hdr = getNextHdr(&inBuf)) != NULL) {
        if (hdr[0] == 0) {
            break;
        }
        else if (strncasecmp(hdr, "Authorization:", 14) == 0) {
            cp = &hdr[14];
            cp += strspn(cp, " \t");
            inBuf.authorization = cp;
        }
        else if (strncasecmp(hdr, "Content-Length:", 15) == 0) {
            cp = &hdr[15];
            cp += strspn(cp, " \t");
            inBuf.content_length = atol(cp);
        }
        else if (strncasecmp(hdr, "Content-Type:", 13) == 0) {
            cp = &hdr[13];
            cp += strspn(cp, " \t");
            inBuf.content_type = cp;
        }
        else if (strncasecmp(hdr, "Host:", 5) == 0) {
            cp = &hdr[5];
            cp += strspn(cp, " \t");
            inBuf.host = cp;
            if (strchr(inBuf.host, '/') != NULL || inBuf.host[0] == '.') {
                if (!discardInput) {
                    genError(conn_fd, &inBuf, 400, "Bad Request", NULL);
                    discardInput=2;
                }
            }
        }
        else if (strncasecmp(hdr, "User-Agent:", 11) == 0) {
            cp = &hdr[11];
            cp += strspn(cp, " \t");
            inBuf.useragent = cp;
        }
        else if (strncasecmp(hdr, "TE:", 3) == 0) {
            char *cp = &hdr[3];
            cp += strspn(cp, " \t");
            if (strncasecmp(cp,"trailers",8)==0)
            inBuf.trailers=1;
        }
        else if (strncasecmp(hdr, "Expect:", 7) == 0) {
            if (!discardInput) {
                genError(conn_fd, &inBuf, 417, "Expectation Failed", NULL);
                discardInput=2;
            }
        }
    }
    
    if (inBuf.content_length < 0) {
        if (!discardInput) {
            genError(conn_fd, &inBuf, 411, "Length Required", NULL);
        }      
        commClose(conn_fd);
        exit(1);
    }

    getPayload(conn_fd, &inBuf);
    if (discardInput) {
        freeBuffer(&inBuf);
        return;
    }
    
    /* well, not really an error ... op successful */
    genError(conn_fd, &inBuf, 200, "OK", NULL);
    
    processIndication(i, inBuf.content);
    
    freeBuffer(&inBuf);
    free(conn_fd.buf);
}

static void* establish_listener(int sslMode, int port, struct native_indicationlistener *i)
{
    struct sockaddr_in sin;
    socklen_t sz,sin_len;
    int listenFd, connFd;
    int ru;
    struct timeval timeout;
    fd_set socksset;
    int dataRead;
    char *xml;

    listenFd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    sin_len = sizeof(sin);

    memset(&sin, 0, sin_len);
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = INADDR_ANY;
    sin.sin_port = htons(port);
    
    ru = 1;
    setsockopt(listenFd, SOL_SOCKET, SO_REUSEADDR, (char *) &ru, sizeof(ru));
    
    if (bind(listenFd, (struct sockaddr *) &sin, sin_len) ||
        listen(listenFd, 0)) {
      exit(0);
    }
    
    sz = sizeof(sin);
    listen(listenFd, 1);
    
    while(do_listen) {
    
        timeout.tv_sec = 3;
        timeout.tv_usec = 0;
        FD_ZERO(&socksset);
        FD_SET(listenFd,&socksset);
        
        dataRead = select(listenFd+1, &socksset, NULL, NULL, &timeout);
        
        if(dataRead < 0) {
            fprintf(stderr, "Error during select(), return value was: %d\n", dataRead);
        }
        else if(dataRead == 0) {
            /* timed out, trying again */
        } else {
            if ((connFd = accept(listenFd, (__SOCKADDR_ARG) & sin, &sz))<0) {
                fprintf(stderr, "Error during accept(), return value was: %d\n", connFd);
                exit(0);
            }
            handleConnection(connFd, i);
            close(connFd);
        }
    }

    return NULL;
}

static void* start_listen_thread(void *parms)
{
    struct native_indicationlistener* i;
    i = (struct native_indicationlistener*) parms;
    establish_listener(i->sslMode, i->port, i);   
    return NULL;
}

static CIMCStatus _ilft_release(CIMCIndicationListener* il)
{
    struct native_indicationlistener* i = (struct native_indicationlistener*)
                                          il;
                                          
    if(i) {
        free(i);
    }
    CIMCStatus ret;
    ret.rc = CIMC_RC_OK;
    ret.msg = NULL;
    return ret;
}

static CIMCIndicationListener* _ilft_clone(CIMCIndicationListener* il,
                                           CIMCStatus* rc)
{
    /* not yet implemented. function is just here to comply with the default
     * function tables. it is questionable if a clone is needed for an
     * indication listener */
    return NULL;
}

static CIMCStatus _ilft_start(CIMCIndicationListener* il)
{
    pthread_t id;
    struct native_indicationlistener* i;
    
    i = (struct native_indicationlistener*) il;
    
    do_listen = 1;
    
    pthread_create(&id, NULL, &start_listen_thread, i);

    CIMCStatus ret;
    ret.rc = CIMC_RC_OK;
    ret.msg = NULL;
    return ret;
}

static CIMCStatus _ilft_stop(CIMCIndicationListener* il)
{
    do_listen = 0;

    CIMCStatus ret;
    ret.rc = CIMC_RC_OK;
    ret.msg = NULL;
    return ret;
}

CIMCIndicationListener *newCIMCIndicationListener(int sslMode,
                                                  int *portNumber,
                                                  void (*fp) (CIMCInstance *indInstance),
                                                  CIMCStatus *rc)
{
    static CIMCIndicationListenerFT ilft = {
        NATIVECIMXML_FT_VERSION,
        _ilft_release,
        _ilft_clone,
        _ilft_start,
        _ilft_stop
    };
    
    static CIMCIndicationListener il = {
        "CIMCIndicationListener",
        &ilft
    };
    
    struct native_indicationlistener  * indicationlistener =
                (struct native_indicationlistener*) calloc(1,
                   sizeof(struct native_indicationlistener));
                           
    indicationlistener->il = il;
    indicationlistener->port = *portNumber;
    indicationlistener->sslMode = sslMode;
    indicationlistener->sendIndicationInstance = fp;
    
    return (CIMCIndicationListener*) indicationlistener;
}
