/*******************************************************************************
 * Copyright (C) 2004-2006 Intel Corp. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  - Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 *  - Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 *  - Neither the name of Intel Corp. nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL Intel Corp. OR THE CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *******************************************************************************/

/**
 * @author Anas Nashif
 * @author Vadim Revyakin
 * @author Liang Hou
 */

#define _GNU_SOURCE
#ifdef HAVE_CONFIG_H
#include "wsman_config.h"
#endif

#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <sys/stat.h>
#include <assert.h>

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

#ifndef WIN32
#include <dlfcn.h>
#endif

#include "u/libu.h"
#include "wsman-xml-api.h"
#include "wsman-soap.h"
#include "wsman-soap-envelope.h"

#include "wsman-xml.h"
#include "wsman-xml-serializer.h"
#include "wsman-dispatcher.h"


#include "shttpd.h"
#include "adapter.h"

#include "wsman-plugins.h"
#include "wsmand-listener.h"
#include "wsmand-daemon.h"
#include "wsman-server.h"
#include "wsman-server-api.h"
#include "wsman-plugins.h"
#ifdef ENABLE_EVENTING_SUPPORT
#include "wsman-cimindication-processor.h"
#endif


#ifdef HAVE_PTHREAD_H
#include <pthread.h>
#endif
#include <sys/socket.h>


static pthread_mutex_t shttpd_mutex;
static pthread_cond_t shttpd_cond;
int continue_working = 1;
static int (*basic_callback) (char *, char *) = NULL;

struct thread {
    struct thread       *next;
    struct shttpd_ctx   *ctx;
};

static struct thread    *threads;   /* List of worker threads */

typedef struct {
	char *response;
	int length;
	int ind;
} ShttpMessage;

#ifdef SHTTPD_GSS
char * gss_decrypt(struct shttpd_arg *arg, char *data, int len);
int gss_encrypt(struct shttpd_arg *arg, char *input, int inlen, char **output, int *outlen);
#endif

/* Check HTTP headers */
static
int check_request_content_type(struct shttpd_arg *arg) {
	const char *content_type;
	int status = WSMAN_STATUS_OK;

	content_type = shttpd_get_header(arg, "Content-Type");
	if (content_type && strncmp(content_type,
				    SOAP_CONTENT_TYPE,
				    strlen(SOAP_CONTENT_TYPE)) != 0) {
		status = WSMAN_STATUS_UNSUPPORTED_MEDIA_TYPE;
	}
	return status;
}

static
char *get_request_encoding(struct shttpd_arg *arg) {
	const char *content_type;
	char *p;
	char *encoding = "UTF-8";

	content_type = shttpd_get_header(arg, "Content-Type");
	if(content_type ) {
		if(( p = strstr(content_type, "charset")) != NULL ) {
			p += strlen("charset");
			p++;
			encoding = p;
		}
	}
	return encoding;
}

static
void server_callback(struct shttpd_arg *arg)
{
	char *encoding = "UTF-8";
	const char  *s;
	SoapH soap;
	int k;
	int status = WSMAN_STATUS_OK;
	char *request_uri;

	char *fault_reason = NULL;
	struct state {
        	size_t  cl;     /* Content-Length   */
	        size_t  nread;      /* Number of bytes read */
	 	u_buf_t *request;
	 	char    *response;
		size_t  len;
		int     index;
		int     type;
	} *state;


	/* If the connection was broken prematurely, cleanup */
	if ( (arg->flags & SHTTPD_CONNECTION_ERROR ) && arg->state) {
        	free(arg->state);
		return;
	} else if ((s = shttpd_get_header(arg, "Content-Length")) == NULL) {
        	shttpd_printf(arg, "HTTP/1.0 411 Length Required\n\n");
	        arg->flags |= SHTTPD_END_OF_OUTPUT;
		return;
	} else if (arg->state == NULL) {
        	/* New request. Allocate a state structure */
        	arg->state = state = calloc(1, sizeof(*state));
	        state->cl = strtoul(s, NULL, 10);
		u_buf_create(&(state->request));
	}

	state = arg->state;
	if ( state->response ) {
		goto CONTINUE;
	}

	if (state->nread>0 )
		u_buf_append(state->request, arg->in.buf, arg->in.len);
	else
		u_buf_set(state->request, arg->in.buf, arg->in.len);

	state->nread += arg->in.len;
	arg->in.num_bytes = arg->in.len;
	if (state->nread >= state->cl) {
		debug("Done reading request");
	} else {
		return;
	}
#ifdef SHTTPD_GSS
	const char *ct = shttpd_get_header(arg, "Content-Type");
	char *payload = 0; // used for gss encrypt

	if (ct && !memcmp(ct, "multipart/encrypted", 19)) {
	        // we have a encrypted payload. decrypt it 
        	payload = gss_decrypt(arg, u_buf_ptr(state->request), u_buf_len(state->request));
	}
#endif
	request_uri = (char *)shttpd_get_env(arg, "REQUEST_URI");
	if (strcmp(request_uri, "/wsman") == 0 ) {

		/* Here we must handle the initial request */
		WsmanMessage *wsman_msg = wsman_soap_message_new();
#ifdef SHTTPD_GSS
	        if(payload == 0) {
#endif
			if ( (status = check_request_content_type(arg) ) != WSMAN_STATUS_OK ) {
				wsman_soap_message_destroy(wsman_msg);
				goto DONE;
			}
			encoding = get_request_encoding(arg);

			u_buf_set(wsman_msg->request, u_buf_ptr(state->request), u_buf_len(state->request));
#ifdef SHTTPD_GSS
	        }
		else {
			u_buf_set(wsman_msg->request, payload, strlen(payload));
		}
#endif
	        wsman_msg->charset = u_strdup(encoding);
		soap = (SoapH) arg->user_data;
		wsman_msg->status.fault_code = WSMAN_RC_OK;

		/*
		 * some plugins can use credentials for their own authentication
		 * works only with basic authentication
		 */
		shttpd_get_credentials(arg, &wsman_msg->auth_data.username,
				&wsman_msg->auth_data.password);

		/* Call dispatcher. Real request handling */
		if (status == WSMAN_STATUS_OK) {
			/* dispatch if we didn't find out any error */
			char *idfile = wsmand_options_get_identify_file();
			if (idfile && wsman_check_identify(wsman_msg) == 1) {
				if (u_buf_load(wsman_msg->response, idfile)) {
					dispatch_inbound_call(soap, wsman_msg, NULL);
					status = wsman_msg->http_code;
				}
			} else {
				dispatch_inbound_call(soap, wsman_msg, NULL);
				status = wsman_msg->http_code;
			}
		}
		if (wsman_msg->request) {
#ifdef SHTTPD_GSS
			if (payload) {
				free(payload);
				/* note that payload is stiil set - this is used as a flag later */
			}
			else {
#endif
				u_buf_free(wsman_msg->request);
#ifdef SHTTPD_GSS
			}
#endif
			wsman_msg->request = NULL;
		}

		state->len =  u_buf_len(wsman_msg->response);;
		state->response = u_buf_steal(wsman_msg->response);
		state->index = 0;
		state->type = 0;

		wsman_soap_message_destroy(wsman_msg);
#ifdef ENABLE_EVENTING_SUPPORT
	} else if (strncmp(request_uri, DEFAULT_CIMINDICATION_PATH, strlen(DEFAULT_CIMINDICATION_PATH)) == 0 ) {
		status = CIMXML_STATUS_OK;
		int cim_error_code = 0;
		char *cim_error = NULL;
		char *fault_reason = NULL;
		char *uuid = NULL, *tmp, *end;
		cimxml_context *cntx = NULL;
		SoapH soap = NULL;
		CimxmlMessage *cimxml_msg = cimxml_message_new();
		tmp = (char *)shttpd_get_env(arg, "REQUEST_URI");
		if (tmp && ( end = strrchr(tmp, '/')) != NULL ) {
			uuid = &end[1];
		}
	        encoding = get_request_encoding(arg);
		cimxml_msg->charset = u_strdup(encoding);
		const char *cimexport = shttpd_get_header(arg, "CIMExport");
		const char *cimexportmethod = shttpd_get_header(arg, "CIMExportMethod");
		if ( cimexportmethod && cimexport ) {
			if(strncmp(cimexport, "MethodRequest", strlen("MethodRequest")) ||
					strncmp(cimexportmethod, "ExportIndication", strlen("ExportIndication"))) {
			}
		} else {
			status = WSMAN_STATUS_FORBIDDEN;
			cim_error_code = CIMXML_STATUS_UNSUPPORTED_OPERATION;
			cim_error = "unsupported-operation";
			goto DONE;
		}
		soap = (SoapH) arg->user_data;
		u_buf_set(cimxml_msg->request, u_buf_ptr(state->request), u_buf_len(state->request));
		cntx = u_malloc(sizeof(cimxml_context));
		cntx->soap = soap;
		cntx->uuid = uuid;
		CIM_Indication_call(cntx, cimxml_msg, NULL);
		status = cimxml_msg->http_code;
		cim_error_code = cimxml_msg->status.code;
		cim_error = cimxml_msg->status.fault_msg;
		if (cim_error) {
			shttpd_printf(arg, "HTTP/1.1 %d %s\r\n", status, fault_reason);
			shttpd_printf(arg, "CIMError: %s\r\n", cim_error);
			cimxml_message_destroy(cimxml_msg);
			goto CONTINUE;
		}
		state->len =  u_buf_len(cimxml_msg->response);;
		state->response = u_buf_steal(cimxml_msg->response);
		state->index = 0;
		state->type = 1;
		cimxml_message_destroy(cimxml_msg);
#endif

	} else if (strcmp(request_uri, ANON_IDENTIFY_PATH) == 0 ) {
		char *idfile = wsmand_options_get_anon_identify_file();
		u_buf_t *id;
		u_buf_create(&id);
		if (idfile && u_buf_load(id, idfile) == 0 ) {
			state->len =  u_buf_len(id);;
			state->response = u_buf_steal(id);
			state->index = 0;
			u_buf_free(id);
		} else {
			shttpd_printf(arg, "HTTP/1.0 404 Not foundn\n");
			arg->flags |= SHTTPD_END_OF_OUTPUT;
			u_buf_free(id);
			return;
		}
	} else {
		shttpd_printf(arg, "HTTP/1.0 404 Not foundn\n");
		arg->flags |= SHTTPD_END_OF_OUTPUT;
		return;
	}

DONE:

	if (fault_reason == NULL) {
		fault_reason = shttpd_reason_phrase(status);
	}
	debug("Response status=%d (%s)", status, fault_reason);

	/*
	 * Here we begin to create the http response.
	 * Create the headers at first.
	 */

	shttpd_printf(arg, "HTTP/1.1 %d %s\r\n", status, fault_reason);
	shttpd_printf(arg, "Server: %s/%s\r\n", PACKAGE_NAME, PACKAGE_VERSION);
#ifdef SHTTPD_GSS
	if(payload) {
		// we had an encrypted message so now we have to encypt the reply
		char *enc;
		int enclen;
		gss_encrypt(arg, state->response, state->len, &enc, &enclen);
		u_free(state->response);
		state->response = enc;
		state->len = enclen;
		payload = 0; // and reset the indicator so that if we send in packates we dont do this again
		shttpd_printf(arg, "Content-Type: multipart/encrypted;protocol=\"application/HTTP-Kerberos-session-encrypted\";boundary=\"Encrypted Boundary\"\r\n");
		shttpd_printf(arg, "Content-Length: %d\r\n", state->len);
	}
	else {
#endif
		if (state->type == 1) { /* eventing */
			shttpd_printf(arg, "Content-Type: application/xml; charset=\"utf-8\"\r\n");
			shttpd_printf(arg, "CIMExport: MethodResponse\r\n");
		} else {
			shttpd_printf(arg, "Content-Type: application/soap+xml;charset=%s\r\n", encoding);
		}
    		shttpd_printf(arg, "Content-Length: %d\r\n", state->len);
#ifdef SHTTPD_GSS
	}
#endif
	shttpd_printf(arg,"Connection: Close\r\n");
  
        /* separate header from message-body */
	shttpd_printf(arg, "\r\n");

	/* add response body to output buffer */
CONTINUE:


	k = arg->out.len - arg->out.num_bytes;
	if (k <= state->len - state->index) {
		 memcpy(arg->out.buf + arg->out.num_bytes, state->response + state->index, k );
		 state->index += k ;
		 arg->out.num_bytes += k;
		 return;
	}
	else {
	         int l = state->len - state->index;
		 memcpy(arg->out.buf + arg->out.num_bytes, state->response + state->index, l);
		 state->index += l ;
		 arg->out.num_bytes += l;
	}

	u_buf_free(state->request);
	u_free(state->response);
	u_free(state);
	arg->flags |= SHTTPD_END_OF_OUTPUT;
	return;
}

static void listener_shutdown_handler(void *p)
{
	int *a = (int *) p;
	debug("listener_shutdown_handler started");
	*a = 0;
}

static void protect_uri(struct shttpd_ctx *ctx, char *uri)
{
	if (wsmand_options_get_digest_password_file()) {
		shttpd_protect_uri(ctx, uri,
                   wsmand_options_get_digest_password_file(),NULL, 1);
		debug("Using Digest Authorization for %s:", uri);
	}
	if (basic_callback) {
		shttpd_protect_uri(ctx, uri, wsmand_options_get_basic_password_file(),
						basic_callback, 0);
		debug("Using Basic Authorization %s for %s",
		      wsmand_option_get_basic_authenticator()?
		      wsmand_option_get_basic_authenticator() :
		      wsmand_default_basic_authenticator(), uri);
	}
}

static struct shttpd_ctx *create_shttpd_context(SoapH soap)
{
	struct shttpd_ctx *ctx;
	if (wsmand_options_get_use_ssl()) {
		message("ssl certificate: %s", wsmand_options_get_ssl_cert_file());
		message("Using SSL");
		ctx = shttpd_init(NULL,
				  "ssl_certificate",
				  wsmand_options_get_ssl_cert_file(),
				  "auth_realm",
				  AUTHENTICATION_REALM,
				  NULL);
	} else {
		ctx = shttpd_init(NULL,
				  "auth_realm", AUTHENTICATION_REALM,
				   NULL);
	}
	if (ctx == NULL) {
		return NULL;
	}
	shttpd_register_uri(ctx, wsmand_options_get_service_path(),
			    server_callback, (void *) soap);
	shttpd_register_uri(ctx, ANON_IDENTIFY_PATH,
			    server_callback, (void *) soap);

#ifdef ENABLE_EVENTING_SUPPORT
	message("Registered CIM Indication Listener: %s", DEFAULT_CIMINDICATION_PATH "/*");
	shttpd_register_uri(ctx, DEFAULT_CIMINDICATION_PATH "/*", server_callback,(void *)soap);
	protect_uri( ctx, DEFAULT_CIMINDICATION_PATH );
#endif

	protect_uri( ctx, wsmand_options_get_service_path());

	return ctx;
}


static int initialize_basic_authenticator(void)
{
	char *auth;
	char *arg;
	void *hnd;
	int (*init) (char *);
	char *name;
	int should_return = 0;
	int res = 0;

	if (wsmand_options_get_basic_password_file() != NULL) {
		if ((wsmand_option_get_basic_authenticator() &&
		     (strcmp(wsmand_default_basic_authenticator(),
			     wsmand_option_get_basic_authenticator()))) ||
		    wsmand_option_get_basic_authenticator_arg()) {
			fprintf(stderr,
				"basic authentication is ambigious in config file\n");
			return 1;
		}
		auth = wsmand_default_basic_authenticator();
		arg = wsmand_options_get_basic_password_file();
	} else {
		auth = wsmand_option_get_basic_authenticator();
		arg = wsmand_option_get_basic_authenticator_arg();
	}

	if (auth == NULL) {
		/* No basic authenticationame */
		return 0;
	}

	if (auth[0] == '/') {
		name = auth;
	} else {
		name = u_strdup_printf("%s/%s", PACKAGE_AUTH_DIR, auth);
		should_return = 1;
	}

	hnd = dlopen(name, RTLD_LAZY | RTLD_GLOBAL);
	if (hnd == NULL) {
		fprintf(stderr, "Could not dlopen %s\n", name);
		res = 1;
		goto DONE;
	}
	basic_callback = dlsym(hnd, "authorize");
	if (basic_callback == NULL) {
		fprintf(stderr, "Could not resolve authorize() in %s\n",
			name);
		res = 1;
		goto DONE;
	}

	init = dlsym(hnd, "initialize");
	if (init != NULL) {
		res = init(arg);
	}
      DONE:
	if (should_return) {
		u_free(name);
	}
	return res;
}


static int get_server_auth(void) {
	if (initialize_basic_authenticator()) {
		return 0;
	}

	if (wsmand_options_get_digest_password_file()) {
		message("Using Digest Authorization");
	}
	if (basic_callback) {
		message("Using Basic Authorization %s",
			wsmand_option_get_basic_authenticator()?
			wsmand_option_get_basic_authenticator() :
			wsmand_default_basic_authenticator());
	}

	if ((wsmand_options_get_digest_password_file() == NULL) &&
		    (basic_callback == NULL)) {
		error("Server does not work without authentication");
		return 0;
	}
	return 1;
}

static int get_server_port(void) {
	int port = 0;
	int use_ssl = wsmand_options_get_use_ssl();
	if (use_ssl) {
		message("Using SSL");
		if (wsmand_options_get_ssl_cert_file() &&
		    wsmand_options_get_ssl_key_file() &&
		    (wsmand_options_get_server_ssl_port() > 0)) {
			port = wsmand_options_get_server_ssl_port();
		} else {
			error("Not enough data to use SSL port");
			return 0;
		}
	} else {
		port = wsmand_options_get_server_port();
	}
	return port;
}


static int wsman_setup_thread(pthread_attr_t *pattrs) {
	int r;
	int ret = 0;
	if ((r = pthread_cond_init(&shttpd_cond, NULL)) != 0) {
		debug("pthread_cond_init failed = %d", r);
		return ret;
	}
	if ((r = pthread_mutex_init(&shttpd_mutex, NULL)) != 0) {
		debug("pthread_mutex_init failed = %d", r);
		return ret;
	}

	if ((r = pthread_attr_init(pattrs)) != 0) {
		debug("pthread_attr_init failed = %d", r);
		return ret;
	}

	if ((r = pthread_attr_setdetachstate(pattrs, PTHREAD_CREATE_DETACHED)) != 0) {
		debug("pthread_attr_setdetachstate = %d", r);
		return ret;
	}
	return 1;
        size_t thread_stack_size = wsmand_options_get_thread_stack_size();
        if(thread_stack_size){
                if(( r = pthread_attr_setstacksize(pattrs, thread_stack_size)) !=0) {
                        debug("pthread_attr_setstacksize failed = %d", r);
                        return ret;
                }
        }
}

static void *thread_function(void *param)
{
    struct thread *thread = param;

    for (;;)
        shttpd_poll(thread->ctx, 1000);

    return NULL;
}


static struct thread *
spawn_new_thread(pthread_attr_t pattrs, SoapH soap)
{
    struct shttpd_ctx   *ctx;
    struct thread       *thread;
    pthread_t           tid;
	debug("spawning new thread");

    thread  = malloc(sizeof(*thread));
    ctx = create_shttpd_context(soap);

    assert(ctx != NULL);
    assert(thread != NULL);

    thread->ctx = ctx;
    thread->next    = threads;
    threads     = thread;

	pthread_create(&tid, &pattrs, thread_function, thread);

    return (thread);
}


static struct thread *
find_not_busy_thread(int *num_threads, int max_connections_per_thread)
{
    struct thread   *thread;

    for (thread = threads, *num_threads=0; thread != NULL; thread = thread->next) {
	debug("Active sockets: %d, Thread Number: %d", shttpd_active(thread->ctx), *num_threads );
        (*num_threads)++;
        if (shttpd_active(thread->ctx) < max_connections_per_thread)
            return (thread);
	}

    return (NULL);
}


WsManListenerH *wsmand_start_server(dictionary * ini)
{
	int lsn, port, sock;
	struct thread       *thread;
	pthread_t tid;
#ifdef ENABLE_EVENTING_SUPPORT
	pthread_t notificationManager_id;
#endif
	pthread_attr_t pattrs;
	int use_ssl = wsmand_options_get_use_ssl();
	struct shttpd_ctx   *httpd_ctx;

	WsManListenerH *listener = wsman_dispatch_list_new();
	listener->config = ini;
	WsContextH cntx = wsman_init_plugins(listener);
        int num_threads=0;
        int max_threads=wsmand_options_get_max_threads();
        int max_connections_per_thread = wsmand_options_get_max_connections_per_thread();
        if(max_threads && !max_connections_per_thread){
                error("max_threads: %d and max_connections_per_thread : %d", max_threads, max_connections_per_thread);
                return listener;
        }

#ifdef ENABLE_EVENTING_SUPPORT
	wsman_event_init(cntx->soap);
#endif

	if (cntx == NULL) {
		return listener;
	}
#ifndef HAVE_SSL
	if (use_ssl) {
		error("Server configured without SSL support");
		return listener;
	}
#endif
	SoapH soap = ws_context_get_runtime(cntx);
	ws_set_context_enumIdleTimeout(cntx,wsmand_options_get_enumIdleTimeout());


	if ((port = get_server_port()) == 0  )
		return listener;
#ifdef ENABLE_IPV6
	if (wsmand_options_get_use_ipv6()) {
		message("     Working on IPv6 port %d", port);
	}
	else {
#endif
		message("     Working on IPv4 port %d", port);
#ifdef ENABLE_IPV6
	}
#endif
	if (!get_server_auth())
		return listener;

	wsmand_shutdown_add_handler(listener_shutdown_handler,
				    &continue_working);

	httpd_ctx = create_shttpd_context(soap);

	lsn = shttpd_listen(httpd_ctx, port, use_ssl);

	if (wsman_setup_thread(&pattrs) == 0 )
		return listener;
	pthread_create(&tid, &pattrs, wsman_server_auxiliary_loop_thread, cntx);

#ifdef ENABLE_EVENTING_SUPPORT
	pthread_create(&notificationManager_id, &pattrs, wsman_notification_manager, cntx);
#endif

	while (continue_working) {
		if ((sock = shttpd_accept(lsn, 1000)) == -1) {
			continue;
		}
		debug("Sock %d accepted", sock);
                if ((thread = find_not_busy_thread(&num_threads, max_connections_per_thread)) == NULL){
                        if(max_threads){
                                if(num_threads < max_threads){
                                        thread = spawn_new_thread(pattrs, soap);
                                }
                                else{
                                        continue;
                                }
                        }
                        else{
                                thread = spawn_new_thread(pattrs, soap);
                        }
		}
                shttpd_add_socket(thread->ctx, sock, use_ssl);
        }
        return listener;
}
