/*
 * Copyright (C) Tildeslash Ltd. All rights reserved.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License version 3.
 *
 * This program 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 Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * In addition, as a special exception, the copyright holders give
 * permission to link the code of portions of this program with the
 * OpenSSL library under certain conditions as described in each
 * individual source file, and distribute linked combinations
 * including the two.
 *
 * You must obey the GNU Affero General Public License in all respects
 * for all of the code used other than OpenSSL.  
 */

#include "config.h"

#ifdef HAVE_STDIO_H
#include <stdio.h>
#endif

#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif

#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif

#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif

#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif

#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
#  include <sys/time.h>
# else
#  include <time.h>
# endif
#endif

#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif

#ifdef HAVE_STRING_H
#include <string.h>
#endif

#ifdef HAVE_CTYPE_H
#include <ctype.h>
#endif

#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif

#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif

#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif

#include "engine.h"
#include "socket.h"


/**
 *  A naive http 1.0 server. The server delegates handling of a HTTP
 *  request and response to the processor module.
 *
 *  NOTE
 *    This server does not use threads or forks; Requests are
 *    serialized and pending requests will be popped from the
 *    connection queue when the current request finish.
 *
 *    Since this server is written for monit, low traffic is expected.
 *    Connect from not-authenicated clients will be closed down
 *    promptly. The authentication schema or access control is based
 *    on client name/address/pam and only requests from known clients are
 *    accepted. Hosts allowed to connect to this server should be
 *    added to the access control list by calling add_host_allow().
 *
 *  @file 
 */


/* ------------------------------------------------------------- Definitions */


static int myServerSocket= 0;
static HostsAllow hostlist= NULL;
static volatile int stopped= FALSE;
ssl_server_connection *mySSLServerConnection= NULL;
static pthread_mutex_t hostlist_mutex= PTHREAD_MUTEX_INITIALIZER;
struct ulong_net {
  unsigned long network;
  unsigned long mask;
};


/* -------------------------------------------------------------- Prototypes */


static void check_Impl();
static void initialize_service();
static int  authenticate(const struct in_addr);
static int  is_host_allow(const struct in_addr);
static void destroy_host_allow(HostsAllow);
static Socket_T socket_producer(int, int, void*);
static int  parse_network(char *, struct ulong_net *);

/* ------------------------------------------------------------------ Public */


/**
 * Start the HTTPD server
 * @param port The Port number to start the server at
 * @param backlog The maximum length of the incomming connection queue 
 * @param bindAddr the local address the server will bind to
 */
void start_httpd(int port, int backlog, char *bindAddr) {

  Socket_T S= NULL;

  stopped= Run.stopped;

  if((myServerSocket= create_server_socket(port, backlog, bindAddr)) < 0) {
    
    LogError("http server: Could not create a server socket at port %d -- %s\n",
	port, STRERROR);
    
    LogError("monit HTTP server not available\n");
    
    if(Run.init) {
      
      sleep(1);
      kill_daemon(SIGTERM);
      
    }
    
  } else {
    
    initialize_service();
    
    if(Run.httpdssl) {
      
      mySSLServerConnection= init_ssl_server( Run.httpsslpem,
					      Run.httpsslclientpem);
      
      if(mySSLServerConnection == NULL) {
	
	LogError("http server: Could not initialize SSL engine\n");
	
	LogError("monit HTTP server not available\n");
	
	return;
      }
      
#ifdef HAVE_OPENSSL
      mySSLServerConnection->server_socket= myServerSocket;
#endif
    }
    
    while(! stopped) {
      
      if(!(S= socket_producer(myServerSocket, port, mySSLServerConnection))) {
	continue;
      }

      http_processor(S);
      
    }

    delete_ssl_server_socket(mySSLServerConnection);  
    close_socket(myServerSocket);

  }

}


/**
 * Stop the HTTPD server. 
 */
void stop_httpd() {

  stopped= TRUE;

}


/* -------------------------------------------------------------- Properties */


/**
 * Add hosts allowed to connect to this server.
 * @param name A hostname (A-Record) or IP address to be added to the
 * hosts allow list
 * @return FALSE if the given host does not resolve, otherwise TRUE
 */
int add_host_allow(char *name) {

  struct addrinfo hints;
  struct addrinfo *res;
  struct addrinfo *_res;

  ASSERT(name);

  memset(&hints, 0, sizeof(struct addrinfo));
  hints.ai_family = PF_INET; /* we support just IPv4 currently */

  if(getaddrinfo(name, NULL, &hints, &res) != 0)
    return FALSE;

  for(_res = res; _res; _res = _res->ai_next) {
    if(_res->ai_family == AF_INET) {
       HostsAllow h;
       struct sockaddr_in *sin = (struct sockaddr_in *)_res->ai_addr;

       NEW(h);      
       memcpy(&h->network, &sin->sin_addr, 4);
       h->mask=    0xffffffff;
       LOCK(hostlist_mutex)
       if(hostlist) {
         HostsAllow p, n;
         for(n= p= hostlist; p; n= p, p= p->next) {
           if((p->network == h->network) && ((p->mask == h->mask))) {
             DEBUG("%s: Debug: Skipping redundant host '%s'\n", prog, name); 
             destroy_host_allow(h);
             goto done;
           }
         }
         DEBUG("%s: Debug: Adding host allow '%s'\n", prog, name); 
         n->next= h;
       } else {
         DEBUG("%s: Debug: Adding host allow '%s'\n", prog, name);
        
         hostlist= h;
       }
       done:
       END_LOCK;
    }
  }

  freeaddrinfo(res);
  return TRUE;
}

/**
 * Add network allowed to connect to this server.
 * @param s_network A network identifier in IP/mask format to be added
 * to the hosts allow list
 * @return FALSE if no correct network identifier is provided,
 * otherwise TRUE
 */

int add_net_allow(char *s_network) {

  struct ulong_net net={0, 0};
  HostsAllow h;

  ASSERT(s_network);

  /* Add the network */

  if (!parse_network(s_network, &net)) {

    return FALSE;
    
  }

  NEW(h);

  h->network=net.network;
  h->mask=net.mask;
  
  LOCK(hostlist_mutex)
          
  if(hostlist) {
      
    HostsAllow p, n;
    
    for(n= p= hostlist; p; n= p, p= p->next) {
      
      if((p->network == net.network) && ((p->mask == net.mask))) {
	
        DEBUG("%s: Debug: Skipping redundant net '%s'.\n",
              prog, s_network); 
        destroy_host_allow(h);
        goto done;
	
      }
      
    }

    DEBUG("%s: Debug: Adding net allow '%s'.\n",
          prog, s_network); 
    
    n->next= h;
    
  } else {
    
    DEBUG("%s: Debug: Adding net allow '%s'.\n",
          prog, s_network); 

    hostlist= h;
    
  }

  done:
  END_LOCK;

  return TRUE;
}


/**
 * Are any hosts present in the host allow list?
 * @return TRUE if the host allow list is non-empty, otherwise FALSE
 */
int has_hosts_allow() {

  int rv;

  LOCK(hostlist_mutex)
      rv= (hostlist != NULL);
  END_LOCK;

  return rv;

}


/** 
 * Free the host allow list
 */
void destroy_hosts_allow() {

  if(has_hosts_allow()) {
    
    LOCK(hostlist_mutex)
	destroy_host_allow(hostlist);
        hostlist= NULL;
    END_LOCK;
    
  }

}

/* ----------------------------------------------------------------- Private */


/**
 * Setup the cervlet service and verify that a cervlet implementation
 * exist. Only one cervlet is supported in this version. In a standalone
 * versions this function will load cervlets from a repository and
 * initialize each cervlet.
 */
static void initialize_service() {

  init_service();
  check_Impl();

}


/**
 * Abort if no Service implementors are found
 */
static void check_Impl() {

  if((Impl.doGet == 0) || (Impl.doPost == 0)) {
    
    LogError("http server: Service Methods not implemented\n");
    _exit(1);
    
  }
  
}


/**
 * Returns TRUE if remote host is allowed to connect, otherwise return
 * FALSE. If allow Basic Authentication is defined in the Run.Auth
 * object, authentication is delegated to the processor module.
 */
static int authenticate(const struct in_addr addr) {

  if(is_host_allow(addr)) {

    return TRUE;
    
  }

  if(! has_hosts_allow() && (Run.credentials!=NULL)) {

    return TRUE;

  }

  LogError("%s: Denied connection from non-authorized client [%s]\n", prog,
      inet_ntoa(addr));
  
  return FALSE;

}


/**
 * Returns TRUE if host is allowed to connect to
 * this server
 */
static int is_host_allow(const struct in_addr addr) { 

  HostsAllow p;
  int rv= FALSE;

  LOCK(hostlist_mutex)
  
  for(p= hostlist; p; p= p->next) {

    if((p->network & p->mask) == (addr.s_addr & p->mask)) {

      rv= TRUE;
      break;
      
    }
    
  }

  END_LOCK;

  if (rv)
      return rv;
  
  return rv;

}


/**
 * Parse network string and return numeric IP and netmask
 * @param s_network A network identifier in IP/mask format to be parsed
 * @param net A structure holding IP and mask of the network
 * @return FALSE if parsing fails otherwise TRUE
 */
static int parse_network(char *s_network, struct ulong_net *net) {

  char *temp=NULL;
  char *copy=NULL;
  char *longmask=NULL;
  int   shortmask=0;
  int   slashcount=0;
  int   dotcount=0;
  int   count=0;
  int   rv=FALSE;
  struct in_addr inp;

  ASSERT(s_network);
  ASSERT(net);

  temp= copy= Str_dup(s_network);

  /* decide if we have xxx.xxx.xxx.xxx/yyy or
                       xxx.xxx.xxx.xxx/yyy.yyy.yyy.yyy */
  while (*temp!=0) {
    if (*temp=='/') {

      /* We have found a "/" -> we are preceeding to the netmask */
      
      if ((slashcount==1) || (dotcount !=3)) {

        /* We have already found a "/" or we haven't had enough dots
           before finding the slash -> Error! */
        
        goto done;
        
      }
      
      *temp=0;
      longmask= *(temp+1)?temp+1:NULL;
      count=0;
      slashcount=1;
      dotcount=0;

    } else if (*temp=='.') {

      /* We have found the next dot! */
      
      dotcount++;
      
    } else if (!isdigit((int)*temp)) {

      /* No number, "." or "/" -> Error! */
      
      goto done;
      
    }
    
    count++;
    temp++;
  }

  if (slashcount == 0) {

    /* We have just host portion */

    shortmask= 32;

  } else if ((dotcount==0) && (count > 1) && (count < 4)) {

    /* We have no dots but 1 or 2 numbers after the slash -> short netmask */

    if (longmask!=NULL) {
      
      shortmask=atoi(longmask);
      longmask=NULL;
      
    }
    
  } else if (dotcount != 3) {

    /* A long netmask requires three dots */
    
    goto done;
    
  }

  /* Parse the network */
  
  if (inet_aton(copy, &inp) == 0) {

    /* Failed! */
    goto done;

  }
  net->network=inp.s_addr;

  /* Convert short netmasks to integer */
  if (longmask==NULL) {
    
    if ((shortmask > 32) || (shortmask < 0)) {
      
      goto done;
      
    } else if ( shortmask == 32 ) {

      net->mask=-1;

    } else {
      
      net->mask= (1<<shortmask)-1;
      net->mask= htonl(net->mask<<(32-shortmask));

    }

  } else { 	 
  	 
    /* Parse long netmasks */ 	 
    if (inet_aton(longmask, &inp) == 0) { 	 

      goto done; 	 

    }

    net->mask=inp.s_addr;

  }

  /* Remove bogus network components */
  net->network&=net->mask;

  /* Everything went fine, so we return TRUE! */
  rv=TRUE;
  
  done:

  FREE(copy);
  return rv;
  
}

/* --------------------------------------------------------------- Factories */


/**
 * Accept connections from Clients and create a Socket_T object for
 * each successful accept. If accept fails, return a NULL object
 */
static Socket_T socket_producer(int server, int port, void *sslserver) {
  
  int client;
  struct sockaddr_in in;
  socklen_t len= sizeof(struct sockaddr_in);
  
  if(can_read(server, 1)) {
    
    if( (client= accept(server, (struct sockaddr*)&in, &len)) < 0) {

      if(stopped) {
        LogError("http server: service stopped\n");
      }  else {
        LogError("http server: cannot accept connection -- %s\n", STRERROR);
      }

      return NULL;

    }

  } else {

    /* If timeout or error occured, return NULL to allow the caller to
     * handle various states (such as stopped) which can occure in the
     * meantime */
    return NULL;

  }

  if(set_noblock(client) < 0) {
    goto error;
  }
  
  if(!check_socket(client)) {
    goto error;
  }
  
  if(! authenticate(in.sin_addr)) {
    goto error;
  }


  return socket_create_a(client, inet_ntoa(in.sin_addr), port, sslserver);

  error:
  close_socket(client);
  return NULL;

}


/* ----------------------------------------------------------------- Cleanup */


/**
 * Free a (linked list of) host_allow ojbect(s). 
 */
static void destroy_host_allow(HostsAllow p) {
  
  HostsAllow a= p; 
  
  if(a->next) {
    destroy_host_allow(a->next);
  }

  FREE(a);
 
}

