Logo Search packages:      
Sourcecode: gsoap version File versions

sslserver.c

/*    sslserver.c

      Example stand-alone secure gSOAP Web service.

      Copyright (C) 2000-2003 Robert A. van Engelen, Genivia inc.
      All Rights Reserved.
*/

#include "soapH.h"
#include "ssl.nsmap"
#include <unistd.h>           /* defines _POSIX_THREADS if pthreads are available */
#ifdef _POSIX_THREADS
# include <pthread.h>
#endif
#include <signal.h>           /* defines SIGPIPE */

/******************************************************************************\
 *
 *    Forward decls
 *
\******************************************************************************/

void *process_request(void*);
int CRYPTO_thread_setup();
void CRYPTO_thread_cleanup();
void sigpipe_handle(int);

/******************************************************************************\
 *
 *    Main
 *
\******************************************************************************/

int main()
{ int m, s; /* master and slave sockets */
  pthread_t tid;
  struct soap soap, *tsoap;
  /* Need SIGPIPE handler on Unix/Linux systems to catch broken pipes: */
  signal(SIGPIPE, sigpipe_handle);
  if (CRYPTO_thread_setup())
  { fprintf(stderr, "Cannot setup thread mutex\n");
    exit(1);
  }
  soap_init(&soap);
  if (soap_ssl_server_context(&soap,
    SOAP_SSL_DEFAULT,
    "server.pem", /* keyfile: see SSL docs on how to obtain this file */
    "password",         /* password to read the key file */
    NULL,         /* cacert file to store trusted certificates (to authenticate clients) */
    NULL,         /* capath */
    "dh512.pem",  /* DH file, if NULL use RSA */
    NULL,         /* if randfile!=NULL: use a file with random data to seed randomness */ 
    "sslserver"         /* server identification for SSL session cache (unique server name, e.g. use argv[0]) */
  ))
  { soap_print_fault(&soap, stderr);
    exit(1);
  }
  soap.accept_timeout = 60;   /* server times out after 10 minutes of inactivity */
  soap.recv_timeout = 30;     /* if read stalls, then timeout after 60 seconds */
  m = soap_bind(&soap, NULL, 18081, 100);
  if (m < 0)
  { soap_print_fault(&soap, stderr);
    exit(1);
  }
  fprintf(stderr, "Socket connection successful: master socket = %d\n", m);
  for (;;)
  { s = soap_accept(&soap);
    fprintf(stderr, "Socket connection successful: slave socket = %d\n", s);
    if (s < 0)
    { if (soap.errnum)
        soap_print_fault(&soap, stderr);
      else
        fprintf(stderr, "Server timed out\n");
      break;
    }
    fprintf(stderr, "Socket %d connection from IP %d.%d.%d.%d\n", s, (int)(soap.ip>>24)&0xFF, (int)(soap.ip>>16)&0xFF, (int)(soap.ip>>8)&0xFF, (int)soap.ip&0xFF);
    tsoap = soap_copy(&soap);
    if (!tsoap)
    { soap_closesock(&soap);
      continue;
    }
    if (soap_ssl_accept(tsoap))
    { soap_print_fault(tsoap, stderr);
      fprintf(stderr, "SSL request failed, continue with next call...\n");
      soap_done(tsoap);
      free(tsoap);
      continue;
    }
    pthread_create(&tid, NULL, &process_request, (void*)tsoap);
  }
  soap_done(&soap); /* MUST call after CRYPTO_thread_cleanup */
  CRYPTO_thread_cleanup();
  return 0;
} 

void *process_request(void *soap)
{ pthread_detach(pthread_self());
  soap_serve((struct soap*)soap);
  soap_destroy((struct soap*)soap); /* for C++ */
  soap_end((struct soap*)soap);
  soap_done((struct soap*)soap);
  free(soap);
  return NULL;
}

/******************************************************************************\
 *
 *    Service methods
 *
\******************************************************************************/

int ns__add(struct soap *soap, double a, double b, double *result)
{ *result = a + b;
  return SOAP_OK;
} 

/******************************************************************************\
 *
 *    OpenSSL
 *
\******************************************************************************/

#ifdef WITH_OPENSSL

#if defined(WIN32)
# define MUTEX_TYPE           HANDLE
# define MUTEX_SETUP(x)       (x) = CreateMutex(NULL, FALSE, NULL)
# define MUTEX_CLEANUP(x)     CloseHandle(x)
# define MUTEX_LOCK(x)        WaitForSingleObject((x), INFINITE)
# define MUTEX_UNLOCK(x)      ReleaseMutex(x)
# define THREAD_ID            GetCurrentThreadID()
#elif defined(_POSIX_THREADS)
# define MUTEX_TYPE           pthread_mutex_t
# define MUTEX_SETUP(x)       pthread_mutex_init(&(x), NULL)
# define MUTEX_CLEANUP(x)     pthread_mutex_destroy(&(x))
# define MUTEX_LOCK(x)        pthread_mutex_lock(&(x))
# define MUTEX_UNLOCK(x)      pthread_mutex_unlock(&(x))
# define THREAD_ID            pthread_self()
#else
# error "You must define mutex operations appropriate for your platform"
# error     "See OpenSSL /threads/th-lock.c on how to implement mutex on your platform"
#endif

struct CRYPTO_dynlock_value
{ MUTEX_TYPE mutex;
};

static MUTEX_TYPE *mutex_buf;

static struct CRYPTO_dynlock_value *dyn_create_function(const char *file, int line)
{ struct CRYPTO_dynlock_value *value;
  value = (struct CRYPTO_dynlock_value*)malloc(sizeof(struct CRYPTO_dynlock_value));
  if (value)
    MUTEX_SETUP(value->mutex);
  return value;
}

static void dyn_lock_function(int mode, struct CRYPTO_dynlock_value *l, const char *file, int line)
{ if (mode & CRYPTO_LOCK)
    MUTEX_LOCK(l->mutex);
  else
    MUTEX_UNLOCK(l->mutex);
}

static void dyn_destroy_function(struct CRYPTO_dynlock_value *l, const char *file, int line)
{ MUTEX_CLEANUP(l->mutex);
  free(l);
}

void locking_function(int mode, int n, const char *file, int line)
{ if (mode & CRYPTO_LOCK)
    MUTEX_LOCK(mutex_buf[n]);
  else
    MUTEX_UNLOCK(mutex_buf[n]);
}

unsigned long id_function()
{ return (unsigned long)THREAD_ID;
}

int CRYPTO_thread_setup()
{ int i;
  mutex_buf = (MUTEX_TYPE*)malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
  if (!mutex_buf)
    return SOAP_EOM;
  for (i = 0; i < CRYPTO_num_locks(); i++)
    MUTEX_SETUP(mutex_buf[i]);
  CRYPTO_set_id_callback(id_function);
  CRYPTO_set_locking_callback(locking_function);
  CRYPTO_set_dynlock_create_callback(dyn_create_function);
  CRYPTO_set_dynlock_lock_callback(dyn_lock_function);
  CRYPTO_set_dynlock_destroy_callback(dyn_destroy_function);
  return SOAP_OK;
}

void CRYPTO_thread_cleanup()
{ int i;
  if (!mutex_buf)
    return;
  CRYPTO_set_id_callback(NULL);
  CRYPTO_set_locking_callback(NULL);
  CRYPTO_set_dynlock_create_callback(NULL);
  CRYPTO_set_dynlock_lock_callback(NULL);
  CRYPTO_set_dynlock_destroy_callback(NULL);
  for (i = 0; i < CRYPTO_num_locks(); i++)
    MUTEX_CLEANUP(mutex_buf[i]);
  free(mutex_buf);
  mutex_buf = NULL;
}

#endif

/******************************************************************************\
 *
 *    SIGPIPE
 *
\******************************************************************************/

void sigpipe_handle(int x) { }


Generated by  Doxygen 1.6.0   Back to index