Пример #1
0
/*
 * initialize ssl methods
 */
static void
init_ssl_methods(void)
{
	LM_DBG("entered\n");

#ifndef OPENSSL_NO_SSL2
	ssl_methods[TLS_USE_SSLv2_cli - 1] = (SSL_METHOD*)SSLv2_client_method();
	ssl_methods[TLS_USE_SSLv2_srv - 1] = (SSL_METHOD*)SSLv2_server_method();
	ssl_methods[TLS_USE_SSLv2 - 1] = (SSL_METHOD*)SSLv2_method();
#endif

	ssl_methods[TLS_USE_SSLv3_cli - 1] = (SSL_METHOD*)SSLv3_client_method();
	ssl_methods[TLS_USE_SSLv3_srv - 1] = (SSL_METHOD*)SSLv3_server_method();
	ssl_methods[TLS_USE_SSLv3 - 1] = (SSL_METHOD*)SSLv3_method();

	ssl_methods[TLS_USE_TLSv1_cli - 1] = (SSL_METHOD*)TLSv1_client_method();
	ssl_methods[TLS_USE_TLSv1_srv - 1] = (SSL_METHOD*)TLSv1_server_method();
	ssl_methods[TLS_USE_TLSv1 - 1] = (SSL_METHOD*)TLSv1_method();

	ssl_methods[TLS_USE_SSLv23_cli - 1] = (SSL_METHOD*)SSLv23_client_method();
	ssl_methods[TLS_USE_SSLv23_srv - 1] = (SSL_METHOD*)SSLv23_server_method();
	ssl_methods[TLS_USE_SSLv23 - 1] = (SSL_METHOD*)SSLv23_method();

#if OPENSSL_VERSION_NUMBER >= 0x10001000L
	ssl_methods[TLS_USE_TLSv1_2_cli - 1] = (SSL_METHOD*)TLSv1_2_client_method();
	ssl_methods[TLS_USE_TLSv1_2_srv - 1] = (SSL_METHOD*)TLSv1_2_server_method();
	ssl_methods[TLS_USE_TLSv1_2 - 1] = (SSL_METHOD*)TLSv1_2_method();
#endif

}
Пример #2
0
const SSL_METHOD * hb_ssl_method_id_to_ptr( int n )
{
   const SSL_METHOD * p;

   switch( n )
   {
#if OPENSSL_VERSION_NUMBER < 0x10000000L
      case HB_SSL_CTX_NEW_METHOD_SSLV2:         p = SSLv2_method();         break;
      case HB_SSL_CTX_NEW_METHOD_SSLV2_SERVER:  p = SSLv2_server_method();  break;
      case HB_SSL_CTX_NEW_METHOD_SSLV2_CLIENT:  p = SSLv2_client_method();  break;
#endif
      case HB_SSL_CTX_NEW_METHOD_SSLV3:         p = SSLv3_method();         break;
      case HB_SSL_CTX_NEW_METHOD_SSLV3_SERVER:  p = SSLv3_server_method();  break;
      case HB_SSL_CTX_NEW_METHOD_SSLV3_CLIENT:  p = SSLv3_client_method();  break;
      case HB_SSL_CTX_NEW_METHOD_TLSV1:         p = TLSv1_method();         break;
      case HB_SSL_CTX_NEW_METHOD_TLSV1_SERVER:  p = TLSv1_server_method();  break;
      case HB_SSL_CTX_NEW_METHOD_TLSV1_CLIENT:  p = TLSv1_client_method();  break;
      case HB_SSL_CTX_NEW_METHOD_SSLV23:        p = SSLv23_method();        break;
      case HB_SSL_CTX_NEW_METHOD_SSLV23_SERVER: p = SSLv23_server_method(); break;
      case HB_SSL_CTX_NEW_METHOD_SSLV23_CLIENT: p = SSLv23_client_method(); break;
      default: p = SSLv23_method();
   }

   return p;
}
Пример #3
0
SSL_METHOD *sycSSLv2_server_method(void) {
   SSL_METHOD *result;
   Debug("SSLv2_server_method()");
   result = SSLv2_server_method();
   Debug1("SSLv2_server_method() -> %p", result);
   return result;
}
Пример #4
0
bool SSLSocket::setupCrypto(SSLSocket *session /* = NULL */) {
  if (m_handle) {
    raise_warning("SSL/TLS already set-up for this stream");
    return false;
  }

  /* need to do slightly different things, based on client/server method,
   * so lets remember which method was selected */
#if OPENSSL_VERSION_NUMBER < 0x00909000L
  SSL_METHOD *smethod;
#else
  const SSL_METHOD *smethod;
#endif
  switch (m_method) {
  case ClientSSLv23: m_client = true;  smethod = SSLv23_client_method(); break;
  case ClientSSLv3:  m_client = true;  smethod = SSLv3_client_method();  break;
  case ClientTLS:    m_client = true;  smethod = TLSv1_client_method();  break;
  case ServerSSLv23: m_client = false; smethod = SSLv23_server_method(); break;
  case ServerSSLv3:  m_client = false; smethod = SSLv3_server_method();  break;

  /* SSLv2 protocol might be disabled in the OpenSSL library */
#ifndef OPENSSL_NO_SSL2
  case ClientSSLv2:  m_client = true;  smethod = SSLv2_client_method();  break;
  case ServerSSLv2:  m_client = false; smethod = SSLv2_server_method();  break;
#else
  case ClientSSLv2:
  case ServerSSLv2:
    raise_warning("OpenSSL library does not support SSL2 protocol");
    return false;
  break;
#endif

  case ServerTLS:    m_client = false; smethod = TLSv1_server_method();  break;
  default:
    return false;
  }

  SSL_CTX *ctx = SSL_CTX_new(smethod);
  if (ctx == nullptr) {
    raise_warning("failed to create an SSL context");
    return false;
  }

  SSL_CTX_set_options(ctx, SSL_OP_ALL);
  m_handle = createSSL(ctx);
  if (m_handle == nullptr) {
    raise_warning("failed to create an SSL handle");
    SSL_CTX_free(ctx);
    return false;
  }

  if (!SSL_set_fd(m_handle, m_fd)) {
    handleError(0, true);
  }
  if (session) {
    SSL_copy_session_id(m_handle, session->m_handle);
  }
  return true;
}
Пример #5
0
	SSLContext::SSLContext(int _method){
#ifdef USE_EMBEDDED_CLASSNAMES
		setClassName(__xvr2_Net_SSLContext);
#endif
		__init_ssl_library(this);
		pem = 0;
		method = _method;
		ctx = 0;
		mydata = 0;
		switch(method){
			case SSL_V2:
				ctx = SSL_CTX_new(SSLv2_method());
				break;
			case SSL_V2_CLIENT:
				ctx = SSL_CTX_new(SSLv2_client_method());
				break;
			case SSL_V2_SERVER:
				ctx = SSL_CTX_new(SSLv2_server_method());
				break;
			case SSL_V3:
				ctx = SSL_CTX_new(SSLv3_method());
				break;
			case SSL_V3_CLIENT:
				ctx = SSL_CTX_new(SSLv3_client_method());
				break;
			case SSL_V3_SERVER:
				ctx = SSL_CTX_new(SSLv3_server_method());
				break;
			case SSL_V23_CLIENT:
				ctx = SSL_CTX_new(SSLv23_client_method());
				break;
			case SSL_V23_SERVER:
				ctx = SSL_CTX_new(SSLv23_server_method());
				break;
			case SSL_V23:
			default:
				ctx = SSL_CTX_new(SSLv23_method());
		}
		if(ctx == 0){
			throw SSLContextCreation();
		}
		//Initialize password callback
		__ssl_ctx_cb_args *x;
		x = new __ssl_ctx_cb_args(this, 0, 0);
		mydata = x;
#ifdef USE_DEBUG
		debugmsgln(this, "Initializing password callback...");
#endif
		SSL_CTX_set_default_passwd_cb((SSL_CTX *)ctx, passwdCB);
#ifdef USE_DEBUG
		debugmsgln(this, "Initializing default password callback userdata...");
#endif
		SSL_CTX_set_default_passwd_cb_userdata((SSL_CTX *)ctx, mydata);
	}
Пример #6
0
bool VSslServer::doOpen()
{
  VLock lock(stateOpenCs); // gilgil temp 2014.03.14

  //
  // Set server method
  //
  LOG_DEBUG("method=%s", qPrintable(methodType.str()));
  switch (methodType)
  {
    #ifdef _WIN32 // Linux openssl does not support SSLv2_server_method
    case VSslMethodType::mtSSLv2   : m_meth = (SSL_METHOD*)SSLv2_server_method();   break;
    #endif // _WIN32
    case VSslMethodType::mtSSLv3   : m_meth = (SSL_METHOD*)SSLv3_server_method();   break;
    case VSslMethodType::mtSSLv23  : m_meth = (SSL_METHOD*)SSLv23_server_method();  break;
    case VSslMethodType::mtTLSv1   : m_meth = (SSL_METHOD*)TLSv1_server_method();   break;
    case VSslMethodType::mtTLSv1_1 : m_meth = (SSL_METHOD*)TLSv1_1_server_method(); break;
    case VSslMethodType::mtTLSv1_2 : m_meth = (SSL_METHOD*)TLSv1_2_server_method(); break;
    case VSslMethodType::mtDTLSv1  : m_meth = (SSL_METHOD*)DTLSv1_server_method();  break;
    case VSslMethodType::mtNone    :
    default                        :
      SET_ERROR(VSslError, QString("client method error(%1)").arg(methodType.str()), VSslError::INVALID_SSL_METHOD);
      return false;
  }

  m_ctx = SSL_CTX_new(m_meth);
  if (!SSL_CTX_set_tlsext_servername_callback(m_ctx, ssl_servername_cb))
  {
    LOG_ERROR("SSL_CTX_set_tlsext_servername_callback return false");
  }
  if (!SSL_CTX_set_tlsext_servername_arg(m_ctx, this))
  {
    LOG_ERROR("SSL_CTX_set_tlsext_servername_arg return false");
  }

  if (defaultKeyCrtFileName != "")
  {
    QString fileName = certificatePath;
    QFileInfo fi(fileName);
    // if (!fi.isAbsolute()) fileName = VApp::_filePath() + fileName; // gilgil temp 2014.12.25
    if (!fi.isAbsolute()) fileName = QCoreApplication::applicationDirPath() + QDir::separator() + fileName; // gilgil temp 2014.12.25
    if (!fileName.endsWith('/') && !fileName.endsWith('\\'))
    {
      fileName += QDir::separator();
    }
    fileName += defaultKeyCrtFileName;
    if (!setup(fileName)) return false;
  }

  if (!VTcpServer::doOpen()) return false;

  return true;
}
Пример #7
0
static SSL_METHOD *ssl23_get_server_method(int ver)
	{
#ifndef OPENSSL_NO_SSL2
	if (ver == SSL2_VERSION)
		return(SSLv2_server_method());
#endif
	if (ver == SSL3_VERSION)
		return(SSLv3_server_method());
	else if (ver == TLS1_VERSION)
		return(TLSv1_server_method());
	else
		return(NULL);
	}
Пример #8
0
/*---------------------------------------------------------------------*/
SSL_CTX* InitServerCTX(void)
{   SSL_METHOD *method;
    SSL_CTX *ctx;

    OpenSSL_add_all_algorithms();		/* load & register all cryptos, etc. */
    SSL_load_error_strings();			/* load all error messages */
    method = SSLv2_server_method();		/* create new server-method instance */
    ctx = SSL_CTX_new(method);			/* create new context from method */
    if ( ctx == NULL )
    {
        ERR_print_errors_fp(stderr);
        abort();
    }
    return ctx;
}
Пример #9
0
/*------------------------------------------------------------------------*/
SSL_CTX* InitServerCTX(void) {
    SSL_METHOD *method;
    SSL_CTX *ctx;
    OpenSSL_add_all_algorithms();		
    SSL_load_error_strings();			
    method = SSLv2_server_method();		
    ctx = SSL_CTX_new(method);			
    if ( ctx == NULL ) {
        ERR_print_errors_fp(stderr);
        abort();
    }

    if (SSL_CTX_set_cipher_list(ctx, "DES-CBC3-MD5") == 1) {
        printf("Si se pudo establecer \n");
    } else {
        printf("No se pudo establecer \n");
    }
    return ctx;
}
Пример #10
0
int DoSSLServerNegotiation(STREAM *S, int Flags)
{
    int result=FALSE;
#ifdef HAVE_LIBSSL
    SSL_METHOD *Method;
    SSL_CTX *ctx;
    SSL *ssl;


    if (S)
    {
        INTERNAL_SSL_INIT();
        Method=SSLv23_server_method();
        if (! Method) Method=SSLv2_server_method();
        if (Method)
        {
            ctx=SSL_CTX_new(Method);

            if (ctx)
            {
                STREAM_INTERNAL_SSL_ADD_SECURE_KEYS(S,ctx);
                ssl=SSL_new(ctx);
                SSL_set_fd(ssl,S->in_fd);
                STREAMSetItem(S,"LIBUSEFUL-SSL-CTX",ssl);
                SSL_set_verify(ssl,SSL_VERIFY_NONE,NULL);
                SSL_set_accept_state(ssl);
                result=SSL_accept(ssl);
                if (result != TRUE)
                {
                    result=SSL_get_error(ssl,result);
                    result=ERR_get_error();
                    fprintf(stderr,"error: %s\n",ERR_error_string(result,NULL));
                    result=FALSE;
                }
                S->Flags|=SF_SSL;
            }
        }
    }

#endif
    return(result);
}
Пример #11
0
/*
 * initialize ssl methods 
 */
static void
init_ssl_methods(void)
{
	DBG("init_methods: Entered\n");
	ssl_methods[TLS_USE_SSLv2_cli - 1] = SSLv2_client_method();
	ssl_methods[TLS_USE_SSLv2_srv - 1] = SSLv2_server_method();
	ssl_methods[TLS_USE_SSLv2 - 1] = SSLv2_method();
	
	ssl_methods[TLS_USE_SSLv3_cli - 1] = SSLv3_client_method();
	ssl_methods[TLS_USE_SSLv3_srv - 1] = SSLv3_server_method();
	ssl_methods[TLS_USE_SSLv3 - 1] = SSLv3_method();
	
	ssl_methods[TLS_USE_TLSv1_cli - 1] = TLSv1_client_method();
	ssl_methods[TLS_USE_TLSv1_srv - 1] = TLSv1_server_method();
	ssl_methods[TLS_USE_TLSv1 - 1] = TLSv1_method();
	
	ssl_methods[TLS_USE_SSLv23_cli - 1] = SSLv23_client_method();
	ssl_methods[TLS_USE_SSLv23_srv - 1] = SSLv23_server_method();
	ssl_methods[TLS_USE_SSLv23 - 1] = SSLv23_method();
}
Пример #12
0
/**
 * Initialize open SSL engine
 * Returns valid SSL context or null if failed to create it.
 */
SSLWrapper* SSLWrapper_new(enum MethodType type)
{
    init_ssl();

    SSL_METHOD *method;
    SSL_CTX *ctx;

    if (type == Server) {
        method = SSLv2_server_method();     
    }
    else if (type == Client) {
        method = SSLv2_client_method();
    }
    else {
#ifdef DEBUG_OUTPUT
        fprintf(stderr, "Invalid method type received %d\n", type);
#endif
        return NULL;
    }

    ctx = SSL_CTX_new(method);

    if (ctx == NULL) {
#ifdef DEBUG_OUTPUT
        ERR_print_errors_fp(stderr);
#endif
    }

    SSLWrapper *wrapper = (SSLWrapper *)malloc(sizeof(SSLWrapper));
    wrapper->ctx = ctx;
    wrapper->ssl = NULL;
    wrapper->type = type;
    wrapper->state_set = 0;
    wrapper->sock_fd = 0;

    return wrapper;
}
Пример #13
0
int MaOpenSslConfig::start()
{
	const SSL_METHOD	*meth;
	char		        *hostName;

	if (keyFile == 0) {
		mprError(MPR_L, MPR_LOG, "OpenSSL: Cant start SSL: missing key file");
		return MPR_ERR_CANT_INITIALIZE;
	}
	if (certFile == 0) {
		mprError(MPR_L, MPR_LOG, "OpenSSL: Cant start SSL: missing certificate file");
		return MPR_ERR_CANT_INITIALIZE;
	}

	//
	//	Depending on the order in the configuration file, we may get called 
	//	by sslModule::start() before OpenSslModule::start has run. So we 
	//	must initialize here.
	//
	openSslModule->start();
	
	hostName = host->getName();
	
	if (protocols == MPR_HTTP_PROTO_SSLV2) {
		meth = SSLv2_server_method();
	} else {
		meth = SSLv23_server_method();
	}
	context = SSL_CTX_new(meth);
	mprAssert(context);
	if (context == 0) {
		mprError(MPR_L, MPR_LOG, "OpenSSL: Unable to create SSL context"); 
		return MPR_ERR_CANT_CREATE;
	}

    SSL_CTX_set_app_data(context, (void*) this);
	SSL_CTX_set_quiet_shutdown(context, 1);
	SSL_CTX_sess_set_cache_size(context, 512);

	//
	//	Configure the certificate for this host
	//
	if (configureCertificates(context, keyFile, certFile) != 0) {
		SSL_CTX_free(context);
		context = 0;
		return MPR_ERR_CANT_INITIALIZE;
	}

	mprLog(4, "SSL: %s: Using ciphers %s\n", hostName, ciphers);
	SSL_CTX_set_cipher_list(context, ciphers);

	//
	//	Configure the client verification certificate locations
	//
	if (verifyClient) {
		if (caFile == 0 && caPath == 0) {
			mprError(MPR_L, MPR_LOG, 
				"OpenSSL: Must define CA certificates if using client verification");
			SSL_CTX_free(context);
			context = 0;
			return MPR_ERR_BAD_STATE;
		}
		if (caFile || caPath) {
			if ((!SSL_CTX_load_verify_locations(context, caFile, caPath)) ||
					(!SSL_CTX_set_default_verify_paths(context))) {
				mprError(MPR_L, MPR_LOG, 
					"OpenSSL: Unable to set certificate locations"); 
				SSL_CTX_free(context);
				context = 0;
				return MPR_ERR_CANT_ACCESS;
			}
			if (caFile) {
				STACK_OF(X509_NAME) *certNames;
				certNames = SSL_load_client_CA_file(caFile);
				if (certNames == 0) {
				} else {
					//
					//	Define the list of CA certificates to send to the client
					//	before they send their client certificate for validation
					//
					SSL_CTX_set_client_CA_list(context, certNames);
				}
			}
		}
		mprLog(4, "SSL: %s: is verifying client connections\n", hostName);
		if (caFile) {
			mprLog(4, "SSL: %s: Using certificates from %s\n", hostName, 
				caFile);
		} else if (caPath) {
			mprLog(4, "SSL: %s: Using certificates from directory %s\n", 
				hostName, caPath);
		}
		SSL_CTX_set_verify(context, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verifyX509Certificate);
		SSL_CTX_set_verify_depth(context, verifyDepth);

	} else {
		SSL_CTX_set_verify(context, SSL_VERIFY_NONE, verifyX509Certificate);
	}

	//
	//	Define callbacks
	//
	SSL_CTX_set_tmp_rsa_callback(context, rsaCallback);
	SSL_CTX_set_tmp_dh_callback(context, dhCallback);

	//
	//	Enable all buggy client work-arounds 
	//
	SSL_CTX_set_options(context, SSL_OP_ALL);

#ifdef SSL_OP_NO_TICKET
    SSL_CTX_set_options(context, SSL_OP_NO_TICKET);
#endif
#ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
    SSL_CTX_set_options(context, SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
#endif
    SSL_CTX_set_mode(context, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_AUTO_RETRY);

	//
	//	Select the required protocols
	//
    SSL_CTX_set_options(context, SSL_OP_NO_SSLv2);
	if (!(protocols & MPR_HTTP_PROTO_SSLV3)) {
		SSL_CTX_set_options(context, SSL_OP_NO_SSLv3);
		mprLog(4, "SSL: %s: Disabling SSLv3\n", hostName);
	}
	if (!(protocols & MPR_HTTP_PROTO_TLSV1)) {
		SSL_CTX_set_options(context, SSL_OP_NO_TLSv1);
		mprLog(4, "SSL: %s: Disabling TLSv1\n", hostName);
	}

	//
	//	Ensure we generate a new private key for each connection
	//
    SSL_CTX_set_options(context, SSL_OP_SINGLE_DH_USE);

	//
	//	Pre-generate some keys that are slow to compute
	//
	rsaKey512 = RSA_generate_key(512, RSA_F4, 0, 0);
	rsaKey1024 = RSA_generate_key(1024, RSA_F4, 0, 0);

	dhKey512 = get_dh512();
	dhKey1024 = get_dh1024();

	return 0;
}
Пример #14
0
static void ssl_init_ctx_protocol(server_rec *s,
                                  apr_pool_t *p,
                                  apr_pool_t *ptemp,
                                  modssl_ctx_t *mctx)
{
    SSL_CTX *ctx = NULL;
    MODSSL_SSL_METHOD_CONST SSL_METHOD *method = NULL;
    char *cp;
    int protocol = mctx->protocol;

    /*
     *  Create the new per-server SSL context
     */
    if (protocol == SSL_PROTOCOL_NONE) {
        ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
                "No SSL protocols available [hint: SSLProtocol]");
        ssl_die();
    }

    cp = apr_pstrcat(p,
                     (protocol & SSL_PROTOCOL_SSLV2 ? "SSLv2, " : ""),
                     (protocol & SSL_PROTOCOL_SSLV3 ? "SSLv3, " : ""),
                     (protocol & SSL_PROTOCOL_TLSV1 ? "TLSv1, " : ""),
                     NULL);
    cp[strlen(cp)-2] = NUL;

    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
                 "Creating new SSL context (protocols: %s)", cp);

    if (protocol == SSL_PROTOCOL_SSLV2) {
        method = mctx->pkp ?
            SSLv2_client_method() : /* proxy */
            SSLv2_server_method();  /* server */
        ctx = SSL_CTX_new(method);  /* only SSLv2 is left */
    }
    else {
        method = mctx->pkp ?
            SSLv23_client_method() : /* proxy */
            SSLv23_server_method();  /* server */
        ctx = SSL_CTX_new(method); /* be more flexible */
    }

    mctx->ssl_ctx = ctx;

    SSL_CTX_set_options(ctx, SSL_OP_ALL);

    if (!(protocol & SSL_PROTOCOL_SSLV2)) {
        SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
    }

    if (!(protocol & SSL_PROTOCOL_SSLV3)) {
        SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3);
    }

    if (!(protocol & SSL_PROTOCOL_TLSV1)) {
        SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1);
    }

#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
    {
        SSLSrvConfigRec *sc = mySrvConfig(s);
        if (sc->cipher_server_pref == TRUE) {
            SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
        }
    }
#endif

    SSL_CTX_set_app_data(ctx, s);

    /*
     * Configure additional context ingredients
     */
    SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE);

#ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
    /*
     * Disallow a session from being resumed during a renegotiation,
     * so that an acceptable cipher suite can be negotiated.
     */
    SSL_CTX_set_options(ctx, SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
#endif
}
Пример #15
0
retcode_t tb_initSSL(Socket_t    S, 
										 enum ssl_mode  mode,       // SSL_CLIENT | SSL_SERVER
										 ssl_meth_t  method,     // SSL1 | SSL2 | SSL3 | TLS1
										 char      * CA_path,
										 char      * CA_file,
										 char      * cert,
										 char      * pwd,
										 char      * cipher) {
	SSL_METHOD * meth;
	sock_ssl_t m;

	tb_info("tb_initSSL in\n");

	if(!TB_VALID(S, TB_SOCKET)) {
		set_tb_errno(TB_ERR_INVALID_TB_OBJECT);
		return TB_ERR;
	}
	if(XSock(S)->ssl != NULL ) {
		tb_warn("tb_initSSL: Socket_t allready SSL initialized\n");
		set_tb_errno(TB_ERR_ALLREADY);
		return TB_ERR;
	}

	m = tb_xcalloc(1, sizeof(struct sock_ssl));
	XSock(S)->ssl = m;
	m->ssl_method = method;

	m->mode = method;


	if( CA_path ) m->CA_path = tb_xstrdup(CA_path);
	if( CA_file ) m->CA_file = tb_xstrdup(CA_file);
	if( cert ) 		m->cert    = tb_xstrdup(cert);
	if( pwd ) 		m->pwd     = tb_xstrdup(pwd);		
	if( cipher ) 	m->cipher  = tb_xstrdup(cipher);
	

	__tb_init_SSL_once();

	switch (m->ssl_method) {
  case 1:
		meth = (mode == SSL_CLIENT) ? SSLv23_client_method() : SSLv23_server_method();
    break;
  case 2:
		meth = (mode == SSL_CLIENT) ? SSLv2_client_method() : SSLv2_server_method();
    break;
  case 3:
		meth = (mode == SSL_CLIENT) ? SSLv3_client_method() : SSLv3_server_method();
    break;
  case 4:
		meth = (mode == SSL_CLIENT) ? TLSv1_client_method() : TLSv1_server_method();
    break;
	default:
		meth = NULL;
		goto err;
  }


	if (!(m->ctx = SSL_CTX_new(meth))) {
    tb_warn("tb_initSSL: Cannot create new SSL context\n");
    ERR_print_errors_fp(stderr);
		XSock(S)->status = TB_BROKEN;
		return TB_ERR; 
  }

	if(tb_errorlevel == TB_DEBUG) SSL_CTX_set_info_callback(m->ctx,info_cb);

  if(m->pwd) {
		SSL_CTX_set_default_passwd_cb(m->ctx, pass_cb);
		SSL_CTX_set_default_passwd_cb_userdata(m->ctx, S);
	}
	

	if(m->cert ) {
		if(SSL_CTX_use_certificate_file(m->ctx, m->cert, SSL_FILETYPE_PEM) <= 0) {
			ERR_print_errors_fp(stderr);
			goto err;
		}
		if (SSL_CTX_use_PrivateKey_file(m->ctx, m->cert, SSL_FILETYPE_PEM) <= 0) {
			tb_error("tb_initSSL: Unable to get private key from '%s'\n", 
							 m->cert);
			ERR_print_errors_fp(stderr);
			goto err;
		}
		tb_info("privkey loaded\n");		
		if (!SSL_CTX_check_private_key(m->ctx)) {
			tb_error("tb_initSSL: Private key does not match the certificate public key\n");
			goto err;
		}
		tb_info("tb_initSSL: privkey validated\n");
		tb_info("tb_initSSL: certificate loaded\n");
	}

	if(mode == SSL_CLIENT) {
		SSL_CTX_set_session_cache_mode(m->ctx, SSL_SESS_CACHE_CLIENT);
	} else {
		SSL_CTX_set_session_cache_mode(m->ctx, SSL_SESS_CACHE_SERVER);
		SSL_CTX_set_session_id_context(m->ctx,  "try this one", 12);
	}

  if(m->CA_file || m->CA_path) {
		tb_info("tb_initSSL: loading CAs ...\n");
    if(!SSL_CTX_load_verify_locations(m->ctx, m->CA_file, m->CA_path)) {
			XSock(S)->status = TB_BROKEN;
      tb_warn("tb_initSSL: Cannot load verify locations %s and %s\n",
              m->CA_file, m->CA_path);
      ERR_print_errors_fp(stderr);
			goto err;
    }
		tb_info("tb_initSSL: CA  <%s/%s> loaded\n", m->CA_path, m->CA_file);
		SSL_CTX_set_verify(m->ctx, SSL_VERIFY_PEER, verify_cb);
		SSL_CTX_set_default_verify_paths(m->ctx);
  }

 /* Create and configure SSL connection. */

  if (!(m->cx = (SSL *)SSL_new(m->ctx))) {
    tb_warn("tb_initSSL: Cannot create new SSL context\n");
    ERR_print_errors_fp(stderr);
		goto err;
  }
	tb_info("tb_initSSL: ssl ctx initialized\n");

  /* Use OpenSSL ciphers -v to see the cipher strings and their SSL
   * versions, key exchange, authentication, encryption, and message
   * digest algorithms, and key length restrictions.  See the OpenSSL
   * for the syntax to combine ciphers, e.g. !SSLv2:RC4-MD5:RC4-SHA.
   * If you don't specify anything, you get the same as "DEFAULT", which
   * means "ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP".
   */
  if(m->cipher) {
    if(!SSL_CTX_set_cipher_list(m->ctx, m->cipher)) {
      tb_warn("tb_inittSSL: Cannot use cipher list %s\n", m->cipher);
			goto err;
    }
		tb_info("tb_initSSL: cipher set to <%s>\n", m->cipher);
	}


	tb_info("tb_initSSL out\n");
	return TB_OK;

 err:
	// fixme: context not totally freed (CA_path, pwd ...)
	SSL_CTX_free(m->ctx);
	m->ctx = NULL;
	XSock(S)->status = TB_BROKEN;
	return TB_ERR;
}
Пример #16
0
eventer_ssl_ctx_t *
eventer_ssl_ctx_new(eventer_ssl_orientation_t type,
                    const char *layer,
                    const char *certificate, const char *key,
                    const char *ca, const char *ciphers) {
  char ssl_ctx_key[SSL_CTX_KEYLEN];
  eventer_ssl_ctx_t *ctx;
  const char *layer_str;
  char *ctx_layer, *opts;
  char *opts_fallback = DEFAULT_OPTS_STRING;
  time_t now;
  ctx = calloc(1, sizeof(*ctx));
  if(!ctx) return NULL;

  layer_str = layer ? layer : DEFAULT_LAYER_STRING;
  ctx_layer = alloca(strlen(layer_str)+1);
  memcpy(ctx_layer, layer_str, strlen(layer_str)+1);
  opts = strchr(ctx_layer,':');
  if(opts) *opts++ = '\0';
  else {
    opts = alloca(strlen(opts_fallback)+1);
    memcpy(opts, opts_fallback, strlen(opts_fallback)+1);
  }

  now = time(NULL);
  ssl_ctx_key_write(ssl_ctx_key, sizeof(ssl_ctx_key),
                    type, layer, certificate, key, ca, ciphers);
  ctx->ssl_ctx_cn = ssl_ctx_cache_get(ssl_ctx_key);
  if(ctx->ssl_ctx_cn) {
    if(now - ctx->ssl_ctx_cn->creation_time > ssl_ctx_cache_expiry ||
       (now - ctx->ssl_ctx_cn->last_stat_time > ssl_ctx_cache_finfo_expiry &&
           (validate_finfo(&ctx->ssl_ctx_cn->cert_finfo, certificate) ||
            validate_finfo(&ctx->ssl_ctx_cn->key_finfo, key) ||
            validate_finfo(&ctx->ssl_ctx_cn->ca_finfo, ca) || 
            (ctx->ssl_ctx_cn->last_stat_time = now) == 0))) { /* assignment */
      ssl_ctx_cache_remove(ssl_ctx_key);
      ssl_ctx_cache_node_free(ctx->ssl_ctx_cn);
      ctx->ssl_ctx_cn = NULL;
    }
  }

  if(!ctx->ssl_ctx_cn) {
    char *part = NULL, *brkt = NULL;
    long ctx_options = 0;
    ssl_ctx_cache_node *existing_ctx_cn;
    ctx->ssl_ctx_cn = calloc(1, sizeof(*ctx->ssl_ctx_cn));
    ctx->ssl_ctx_cn->key = strdup(ssl_ctx_key);
    ctx->ssl_ctx_cn->refcnt = 1;
    ctx->ssl_ctx_cn->creation_time = now;
    ctx->ssl_ctx_cn->last_stat_time = now;
    populate_finfo(&ctx->ssl_ctx_cn->cert_finfo, certificate);
    populate_finfo(&ctx->ssl_ctx_cn->key_finfo, key);
    populate_finfo(&ctx->ssl_ctx_cn->ca_finfo, ca);
    ctx->ssl_ctx = NULL;
    if(0)
      ;
#if defined(SSL_TXT_SSLV3) && defined(HAVE_SSLV3_SERVER) && defined(HAVE_SSLV3_CLIENT)
    else if(layer && !strcasecmp(layer, SSL_TXT_SSLV3))
      ctx->ssl_ctx = SSL_CTX_new(type == SSL_SERVER ?
                                 SSLv3_server_method() : SSLv3_client_method());
#endif
#if defined(SSL_TXT_SSLV2) && defined(HAVE_SSLV2_SERVER) && defined(HAVE_SSLV2_CLIENT)
    else if(layer && !strcasecmp(layer, SSL_TXT_SSLV2))
      ctx->ssl_ctx = SSL_CTX_new(type == SSL_SERVER ?
                                 SSLv2_server_method() : SSLv2_client_method());
#endif
#if defined(SSL_TXT_TLSV1) && defined(HAVE_TLSV1_SERVER) && defined(HAVE_TLSV1_CLIENT)
    else if(layer && !strcasecmp(layer, SSL_TXT_TLSV1))
      ctx->ssl_ctx = SSL_CTX_new(type == SSL_SERVER ?
                                 TLSv1_server_method() : TLSv1_client_method());
#endif
#if defined(SSL_TXT_TLSV1_1) && defined(HAVE_TLSV1_1_SERVER) && defined(HAVE_TLSV1_1_CLIENT)
    else if(layer && !strcasecmp(layer, SSL_TXT_TLSV1_1))
      ctx->ssl_ctx = SSL_CTX_new(type == SSL_SERVER ?
                                 TLSv1_1_server_method() : TLSv1_1_client_method());
#endif
#if defined(SSL_TXT_TLSV1_2) && defined(HAVE_TLSV1_2_SERVER) && defined(HAVE_TLSV1_2_CLIENT)
    else if(layer && !strcasecmp(layer, SSL_TXT_TLSV1_2))
      ctx->ssl_ctx = SSL_CTX_new(type == SSL_SERVER ?
                                 TLSv1_2_server_method() : TLSv1_2_client_method());
#endif
    if(ctx->ssl_ctx == NULL)
      ctx->ssl_ctx = SSL_CTX_new(type == SSL_SERVER ?
                                 SSLv23_server_method() : SSLv23_client_method());
    if(!ctx->ssl_ctx) goto bail;

    for(part = strtok_r(opts, ",", &brkt);
        part;
        part = strtok_r(NULL, ",", &brkt)) {
      char *optname = part;
      int neg = 0;
      if(*optname == '!') neg = 1, optname++;

#define SETBITOPT(name, neg, opt) \
  if(!strcasecmp(optname, name)) { \
    if(neg) ctx_options &= ~(opt); \
    else    ctx_options |= (opt); \
  }

      SETBITOPT("all", neg, SSL_OP_ALL)
#ifdef SSL_TXT_SSLV2
      else SETBITOPT(SSL_TXT_SSLV2, !neg, SSL_OP_NO_SSLv2)
#endif
#ifdef SSL_TXT_SSLV3
      else SETBITOPT(SSL_TXT_SSLV3, !neg, SSL_OP_NO_SSLv3)
#endif
#ifdef SSL_TXT_TLSV1
      else SETBITOPT(SSL_TXT_TLSV1, !neg, SSL_OP_NO_TLSv1)
#endif
#ifdef SSL_TXT_TLSV1_1
      else SETBITOPT(SSL_TXT_TLSV1_1, !neg, SSL_OP_NO_TLSv1_1)
#endif
#ifdef SSL_TXT_TLSV1_2
      else SETBITOPT(SSL_TXT_TLSV1_2, !neg, SSL_OP_NO_TLSv1_2)
#endif
#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
      else SETBITOPT("cipher_server_preference", neg, SSL_OP_CIPHER_SERVER_PREFERENCE)
#endif
      else {
        mtevL(mtev_error, "SSL layer part '%s' not understood.\n", optname);
      }
    }

    if (type == SSL_SERVER)
      SSL_CTX_set_session_id_context(ctx->ssl_ctx,
              (unsigned char *)EVENTER_SSL_DATANAME,
              sizeof(EVENTER_SSL_DATANAME)-1);
#ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
    ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
#endif
#ifdef SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
    ctx_options &= ~SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG;
#endif
#ifdef SSL_OP_NO_COMPRESSION
    ctx_options |= SSL_OP_NO_COMPRESSION;
#endif
#ifdef SSL_OP_NO_TICKET
    ctx_options |= SSL_OP_NO_TICKET;
#endif
#ifdef SSL_OP_SINGLE_DH_USE
    ctx_options |= SSL_OP_SINGLE_DH_USE;
#endif
#ifdef SSL_OP_SINGLE_ECDH_USE
    ctx_options |= SSL_OP_SINGLE_ECDH_USE;
#endif
    SSL_CTX_set_options(ctx->ssl_ctx, ctx_options);
#ifdef SSL_MODE_RELEASE_BUFFERS
    SSL_CTX_set_mode(ctx->ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
#endif
    if(certificate &&
       SSL_CTX_use_certificate_chain_file(ctx->ssl_ctx, certificate) != 1)
      goto bail;
    if(key &&
       SSL_CTX_use_RSAPrivateKey_file(ctx->ssl_ctx,key,
                                      SSL_FILETYPE_PEM) != 1)
      goto bail;
    if(ca) {
      STACK_OF(X509_NAME) *cert_stack;
      if(!SSL_CTX_load_verify_locations(ctx->ssl_ctx,ca,NULL) ||
         (cert_stack = SSL_load_client_CA_file(ca)) == NULL)
        goto bail;
      SSL_CTX_set_client_CA_list(ctx->ssl_ctx, cert_stack);
    }
    SSL_CTX_set_cipher_list(ctx->ssl_ctx, ciphers ? ciphers : "DEFAULT");
    SSL_CTX_set_verify(ctx->ssl_ctx, SSL_VERIFY_PEER, verify_cb);
#ifndef OPENSSL_NO_EC
#if defined(SSL_CTX_set_ecdh_auto)
    SSL_CTX_set_ecdh_auto(ctx->ssl_ctx, 1);
#elif defined(NID_X9_62_prime256v1)
    EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
    SSL_CTX_set_tmp_ecdh(ctx->ssl_ctx, ec_key);
    EC_KEY_free(ec_key);
#endif
#endif
    existing_ctx_cn = ssl_ctx_cache_set(ctx->ssl_ctx_cn);
    if(existing_ctx_cn != ctx->ssl_ctx_cn) {
      ssl_ctx_cache_node_free(ctx->ssl_ctx_cn);
      ctx->ssl_ctx_cn = existing_ctx_cn;
    }
  }
Пример #17
0
int MAIN(int argc, char **argv)
	{
	int ret=1,i;
	int verbose=0,Verbose=0;
	int use_supported = 0;
#ifndef OPENSSL_NO_SSL_TRACE
	int stdname = 0;
#endif
	const char **pp;
	const char *p;
	int badops=0;
	SSL_CTX *ctx=NULL;
	SSL *ssl=NULL;
	char *ciphers=NULL;
	const SSL_METHOD *meth=NULL;
	STACK_OF(SSL_CIPHER) *sk=NULL;
	char buf[512];
	BIO *STDout=NULL;

#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
	meth=SSLv23_server_method();
#elif !defined(OPENSSL_NO_SSL3)
	meth=SSLv3_server_method();
#elif !defined(OPENSSL_NO_SSL2)
	meth=SSLv2_server_method();
#endif

	apps_startup();

	if (bio_err == NULL)
		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
	STDout=BIO_new_fp(stdout,BIO_NOCLOSE);
#ifdef OPENSSL_SYS_VMS
	{
	BIO *tmpbio = BIO_new(BIO_f_linebuffer());
	STDout = BIO_push(tmpbio, STDout);
	}
#endif
	if (!load_config(bio_err, NULL))
		goto end;

	argc--;
	argv++;
	while (argc >= 1)
		{
		if (strcmp(*argv,"-v") == 0)
			verbose=1;
		else if (strcmp(*argv,"-V") == 0)
			verbose=Verbose=1;
		else if (strcmp(*argv,"-s") == 0)
			use_supported = 1;
#ifndef OPENSSL_NO_SSL_TRACE
		else if (strcmp(*argv,"-stdname") == 0)
			stdname=verbose=1;
#endif
#ifndef OPENSSL_NO_SSL2
		else if (strcmp(*argv,"-ssl2") == 0)
			meth=SSLv2_client_method();
#endif
#ifndef OPENSSL_NO_SSL3
		else if (strcmp(*argv,"-ssl3") == 0)
			meth=SSLv3_client_method();
#endif
#ifndef OPENSSL_NO_TLS1
		else if (strcmp(*argv,"-tls1") == 0)
			meth=TLSv1_client_method();
#endif
		else if ((strncmp(*argv,"-h",2) == 0) ||
			 (strcmp(*argv,"-?") == 0))
			{
			badops=1;
			break;
			}
		else
			{
			ciphers= *argv;
			}
		argc--;
		argv++;
		}

	if (badops)
		{
		for (pp=ciphers_usage; (*pp != NULL); pp++)
			BIO_printf(bio_err,"%s",*pp);
		goto end;
		}

	OpenSSL_add_ssl_algorithms();

	ctx=SSL_CTX_new(meth);
	if (ctx == NULL) goto err;
	if (ciphers != NULL) {
		if(!SSL_CTX_set_cipher_list(ctx,ciphers)) {
			BIO_printf(bio_err, "Error in cipher list\n");
			goto err;
		}
	}
	ssl=SSL_new(ctx);
	if (ssl == NULL) goto err;

	if (use_supported)
		sk=SSL_get1_supported_ciphers(ssl);
	else
		sk=SSL_get_ciphers(ssl);

	if (!verbose)
		{
		for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
			{
			SSL_CIPHER *c = sk_SSL_CIPHER_value(sk,i);
			p = SSL_CIPHER_get_name(c);
			if (p == NULL) break;
			if (i != 0) BIO_printf(STDout,":");
			BIO_printf(STDout,"%s",p);
			}
		BIO_printf(STDout,"\n");
		}
	else /* verbose */
		{

		for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
			{
			SSL_CIPHER *c;

			c = sk_SSL_CIPHER_value(sk,i);
			
			if (Verbose)
				{
				unsigned long id = SSL_CIPHER_get_id(c);
				int id0 = (int)(id >> 24);
				int id1 = (int)((id >> 16) & 0xffL);
				int id2 = (int)((id >> 8) & 0xffL);
				int id3 = (int)(id & 0xffL);
				
				if ((id & 0xff000000L) == 0x02000000L)
					BIO_printf(STDout, "     0x%02X,0x%02X,0x%02X - ", id1, id2, id3); /* SSL2 cipher */
				else if ((id & 0xff000000L) == 0x03000000L)
					BIO_printf(STDout, "          0x%02X,0x%02X - ", id2, id3); /* SSL3 cipher */
				else
					BIO_printf(STDout, "0x%02X,0x%02X,0x%02X,0x%02X - ", id0, id1, id2, id3); /* whatever */
				}
#ifndef OPENSSL_NO_SSL_TRACE
			if (stdname)
				{
				const char *nm = SSL_CIPHER_standard_name(c);
				if (nm == NULL)
					nm = "UNKNOWN";
				BIO_printf(STDout, "%s - ", nm);
				}
#endif
			BIO_puts(STDout,SSL_CIPHER_description(c,buf,sizeof buf));
			}
		}

	ret=0;
	if (0)
		{
err:
		SSL_load_error_strings();
		ERR_print_errors(bio_err);
		}
end:
	if (use_supported && sk)
		sk_SSL_CIPHER_free(sk);
	if (ctx != NULL) SSL_CTX_free(ctx);
	if (ssl != NULL) SSL_free(ssl);
	if (STDout != NULL) BIO_free_all(STDout);
	apps_shutdown();
	OPENSSL_EXIT(ret);
	}
Пример #18
0
int ssl23_get_client_hello(SSL *s)
	{
	char buf_space[11]; /* Request this many bytes in initial read.
	                     * We can detect SSL 3.0/TLS 1.0 Client Hellos
	                     * ('type == 3') correctly only when the following
	                     * is in a single record, which is not guaranteed by
	                     * the protocol specification:
	                     * Byte  Content
	                     *  0     type            \
	                     *  1/2   version          > record header
	                     *  3/4   length          /
	                     *  5     msg_type        \
	                     *  6-8   length           > Client Hello message
	                     *  9/10  client_version  /
	                     */
	char *buf= &(buf_space[0]);
	unsigned char *p,*d,*d_len,*dd;
	unsigned int i;
	unsigned int csl,sil,cl;
	int n=0,j;
	int type=0;
	int v[2];

	if (s->state ==	SSL23_ST_SR_CLNT_HELLO_A)
		{
		/* read the initial header */
		v[0]=v[1]=0;

		if (!ssl3_setup_buffers(s)) goto err;

		n=ssl23_read_bytes(s, sizeof buf_space);
		if (n != sizeof buf_space) return(n); /* n == -1 || n == 0 */

		p=s->packet;

		memcpy(buf,p,n);

		if ((p[0] & 0x80) && (p[2] == SSL2_MT_CLIENT_HELLO))
			{
			/*
			 * SSLv2 header
			 */
			if ((p[3] == 0x00) && (p[4] == 0x02))
				{
				v[0]=p[3]; v[1]=p[4];
				/* SSLv2 */
				if (!(s->options & SSL_OP_NO_SSLv2))
					type=1;
				}
			else if (p[3] == SSL3_VERSION_MAJOR)
				{
				v[0]=p[3]; v[1]=p[4];
				/* SSLv3/TLSv1 */
				if (p[4] >= TLS1_VERSION_MINOR)
					{
					if (!(s->options & SSL_OP_NO_TLSv1))
						{
						s->version=TLS1_VERSION;
						/* type=2; */ /* done later to survive restarts */
						s->state=SSL23_ST_SR_CLNT_HELLO_B;
						}
					else if (!(s->options & SSL_OP_NO_SSLv3))
						{
						s->version=SSL3_VERSION;
						/* type=2; */
						s->state=SSL23_ST_SR_CLNT_HELLO_B;
						}
					else if (!(s->options & SSL_OP_NO_SSLv2))
						{
						type=1;
						}
					}
				else if (!(s->options & SSL_OP_NO_SSLv3))
					{
					s->version=SSL3_VERSION;
					/* type=2; */
					s->state=SSL23_ST_SR_CLNT_HELLO_B;
					}
				else if (!(s->options & SSL_OP_NO_SSLv2))
					type=1;

				}
			}
		else if ((p[0] == SSL3_RT_HANDSHAKE) &&
			 (p[1] == SSL3_VERSION_MAJOR) &&
			 (p[5] == SSL3_MT_CLIENT_HELLO) &&
			 ((p[3] == 0 && p[4] < 5 /* silly record length? */)
				|| (p[9] >= p[1])))
			{
			/*
			 * SSLv3 or tls1 header
			 */
			
			v[0]=p[1]; /* major version (= SSL3_VERSION_MAJOR) */
			/* We must look at client_version inside the Client Hello message
			 * to get the correct minor version.
			 * However if we have only a pathologically small fragment of the
			 * Client Hello message, this would be difficult, and we'd have
			 * to read more records to find out.
			 * No known SSL 3.0 client fragments ClientHello like this,
			 * so we simply assume TLS 1.0 to avoid protocol version downgrade
			 * attacks. */
			if (p[3] == 0 && p[4] < 6)
				{
#if 0
				SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_TOO_SMALL);
				goto err;
#else
				v[1] = TLS1_VERSION_MINOR;
#endif
				}
			/* if major version number > 3 set minor to a value
			 * which will use the highest version 3 we support.
			 * If TLS 2.0 ever appears we will need to revise
			 * this....
			 */
			else if (p[9] > SSL3_VERSION_MAJOR)
				v[1]=0xff;
			else
				v[1]=p[10]; /* minor version according to client_version */
			if (v[1] >= TLS1_VERSION_MINOR)
				{
				if (!(s->options & SSL_OP_NO_TLSv1))
					{
					s->version=TLS1_VERSION;
					type=3;
					}
				else if (!(s->options & SSL_OP_NO_SSLv3))
					{
					s->version=SSL3_VERSION;
					type=3;
					}
				}
			else
				{
				/* client requests SSL 3.0 */
				if (!(s->options & SSL_OP_NO_SSLv3))
					{
					s->version=SSL3_VERSION;
					type=3;
					}
				else if (!(s->options & SSL_OP_NO_TLSv1))
					{
					/* we won't be able to use TLS of course,
					 * but this will send an appropriate alert */
					s->version=TLS1_VERSION;
					type=3;
					}
				}
			}
		else if ((strncmp("GET ", (char *)p,4) == 0) ||
			 (strncmp("POST ",(char *)p,5) == 0) ||
			 (strncmp("HEAD ",(char *)p,5) == 0) ||
			 (strncmp("PUT ", (char *)p,4) == 0))
			{
			SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_HTTP_REQUEST);
			goto err;
			}
		else if (strncmp("CONNECT",(char *)p,7) == 0)
			{
			SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_HTTPS_PROXY_REQUEST);
			goto err;
			}
		}

#ifdef OPENSSL_FIPS
	if (FIPS_mode() && (s->version < TLS1_VERSION))
		{
		SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,
					SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE);
		goto err;
		}
#endif

	if (s->state == SSL23_ST_SR_CLNT_HELLO_B)
		{
		/* we have SSLv3/TLSv1 in an SSLv2 header
		 * (other cases skip this state) */

		type=2;
		p=s->packet;
		v[0] = p[3]; /* == SSL3_VERSION_MAJOR */
		v[1] = p[4];

/* The SSL2 protocol allows n to be larger, just pick
 * a reasonable buffer size. */
#if SSL3_RT_DEFAULT_PACKET_SIZE < 1024*4 - SSL3_RT_DEFAULT_WRITE_OVERHEAD
#error "SSL3_RT_DEFAULT_PACKET_SIZE is too small."
#endif
		n=((p[0]&0x7f)<<8)|p[1];
		if (n > SSL3_RT_DEFAULT_PACKET_SIZE - 2)
			{
			SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_TOO_LARGE);
			goto err;
			}

		j=ssl23_read_bytes(s,n+2);
		if (j <= 0) return(j);

		ssl3_finish_mac(s, s->packet+2, s->packet_length-2);
		if (s->msg_callback)
			s->msg_callback(0, SSL2_VERSION, 0, s->packet+2, s->packet_length-2, s, s->msg_callback_arg); /* CLIENT-HELLO */

		p=s->packet;
		p+=5;
		n2s(p,csl);
		n2s(p,sil);
		n2s(p,cl);
		d=(unsigned char *)s->init_buf->data;
		if ((csl+sil+cl+11) != s->packet_length)
			{
			SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_LENGTH_MISMATCH);
			goto err;
			}

		/* record header: msg_type ... */
		*(d++) = SSL3_MT_CLIENT_HELLO;
		/* ... and length (actual value will be written later) */
		d_len = d;
		d += 3;

		/* client_version */
		*(d++) = SSL3_VERSION_MAJOR; /* == v[0] */
		*(d++) = v[1];

		/* lets populate the random area */
		/* get the challenge_length */
		i=(cl > SSL3_RANDOM_SIZE)?SSL3_RANDOM_SIZE:cl;
		memset(d,0,SSL3_RANDOM_SIZE);
		memcpy(&(d[SSL3_RANDOM_SIZE-i]),&(p[csl+sil]),i);
		d+=SSL3_RANDOM_SIZE;

		/* no session-id reuse */
		*(d++)=0;

		/* ciphers */
		j=0;
		dd=d;
		d+=2;
		for (i=0; i<csl; i+=3)
			{
			if (p[i] != 0) continue;
			*(d++)=p[i+1];
			*(d++)=p[i+2];
			j+=2;
			}
		s2n(j,dd);

		/* COMPRESSION */
		*(d++)=1;
		*(d++)=0;
		
		i = (d-(unsigned char *)s->init_buf->data) - 4;
		l2n3((long)i, d_len);

		/* get the data reused from the init_buf */
		s->s3->tmp.reuse_message=1;
		s->s3->tmp.message_type=SSL3_MT_CLIENT_HELLO;
		s->s3->tmp.message_size=i;
		}

	/* imaginary new state (for program structure): */
	/* s->state = SSL23_SR_CLNT_HELLO_C */

	if (type == 1)
		{
#ifdef OPENSSL_NO_SSL2
		SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_UNSUPPORTED_PROTOCOL);
		goto err;
#else
		/* we are talking sslv2 */
		/* we need to clean up the SSLv3/TLSv1 setup and put in the
		 * sslv2 stuff. */

		if (s->s2 == NULL)
			{
			if (!ssl2_new(s))
				goto err;
			}
		else
			ssl2_clear(s);

		if (s->s3 != NULL) ssl3_free(s);

		if (!BUF_MEM_grow_clean(s->init_buf,
			SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER))
			{
			goto err;
			}

		s->state=SSL2_ST_GET_CLIENT_HELLO_A;
		if (s->options & SSL_OP_NO_TLSv1 && s->options & SSL_OP_NO_SSLv3)
			s->s2->ssl2_rollback=0;
		else
			/* reject SSL 2.0 session if client supports SSL 3.0 or TLS 1.0
			 * (SSL 3.0 draft/RFC 2246, App. E.2) */
			s->s2->ssl2_rollback=1;

		/* setup the n bytes we have read so we get them from
		 * the sslv2 buffer */
		s->rstate=SSL_ST_READ_HEADER;
		s->packet_length=n;
		s->packet= &(s->s2->rbuf[0]);
		memcpy(s->packet,buf,n);
		s->s2->rbuf_left=n;
		s->s2->rbuf_offs=0;

		s->method=SSLv2_server_method();
		s->handshake_func=s->method->ssl_accept;
#endif
		}

	if ((type == 2) || (type == 3))
		{
		/* we have SSLv3/TLSv1 (type 2: SSL2 style, type 3: SSL3/TLS style) */

		if (!ssl_init_wbio_buffer(s,1)) goto err;

		/* we are in this state */
		s->state=SSL3_ST_SR_CLNT_HELLO_A;

		if (type == 3)
			{
			/* put the 'n' bytes we have read into the input buffer
			 * for SSLv3 */
			s->rstate=SSL_ST_READ_HEADER;
			s->packet_length=n;
			s->packet= &(s->s3->rbuf.buf[0]);
			memcpy(s->packet,buf,n);
			s->s3->rbuf.left=n;
			s->s3->rbuf.offset=0;
			}
		else
			{
			s->packet_length=0;
			s->s3->rbuf.left=0;
			s->s3->rbuf.offset=0;
			}

		if (s->version == TLS1_VERSION)
			s->method = TLSv1_server_method();
		else
			s->method = SSLv3_server_method();
#if 0 /* ssl3_get_client_hello does this */
		s->client_version=(v[0]<<8)|v[1];
#endif
		s->handshake_func=s->method->ssl_accept;
		}
	
	if ((type < 1) || (type > 3))
		{
		/* bad, very bad */
		SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_UNKNOWN_PROTOCOL);
		goto err;
		}
	s->init_num=0;

	if (buf != buf_space) OPENSSL_free(buf);
	return(SSL_accept(s));
err:
	if (buf != buf_space) OPENSSL_free(buf);
	return(-1);
	}
Пример #19
0
int MAIN(int argc, char **argv)
	{
	int ret=1,i;
	int verbose=0;
	char **pp;
	const char *p;
	int badops=0;
	SSL_CTX *ctx=NULL;
	SSL *ssl=NULL;
	char *ciphers=NULL;
	SSL_METHOD *meth=NULL;
	STACK_OF(SSL_CIPHER) *sk;
	char buf[512];
	BIO *STDout=NULL;

#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
	meth=SSLv23_server_method();
#elif !defined(OPENSSL_NO_SSL3)
	meth=SSLv3_server_method();
#elif !defined(OPENSSL_NO_SSL2)
	meth=SSLv2_server_method();
#endif

	apps_startup();

	if (bio_err == NULL)
		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
	STDout=BIO_new_fp(stdout,BIO_NOCLOSE);
#ifdef OPENSSL_SYS_VMS
	{
	BIO *tmpbio = BIO_new(BIO_f_linebuffer());
	STDout = BIO_push(tmpbio, STDout);
	}
#endif

	argc--;
	argv++;
	while (argc >= 1)
		{
		if (strcmp(*argv,"-v") == 0)
			verbose=1;
#ifndef OPENSSL_NO_SSL2
		else if (strcmp(*argv,"-ssl2") == 0)
			meth=SSLv2_client_method();
#endif
#ifndef OPENSSL_NO_SSL3
		else if (strcmp(*argv,"-ssl3") == 0)
			meth=SSLv3_client_method();
#endif
#ifndef OPENSSL_NO_TLS1
		else if (strcmp(*argv,"-tls1") == 0)
			meth=TLSv1_client_method();
#endif
		else if ((strncmp(*argv,"-h",2) == 0) ||
			 (strcmp(*argv,"-?") == 0))
			{
			badops=1;
			break;
			}
		else
			{
			ciphers= *argv;
			}
		argc--;
		argv++;
		}

	if (badops)
		{
		for (pp=ciphers_usage; (*pp != NULL); pp++)
			BIO_printf(bio_err,"%s",*pp);
		goto end;
		}

	OpenSSL_add_ssl_algorithms();

	ctx=SSL_CTX_new(meth);
	if (ctx == NULL) goto err;
	if (ciphers != NULL) {
		if(!SSL_CTX_set_cipher_list(ctx,ciphers)) {
			BIO_printf(bio_err, "Error in cipher list\n");
			goto err;
		}
	}
	ssl=SSL_new(ctx);
	if (ssl == NULL) goto err;


	if (!verbose)
		{
		for (i=0; ; i++)
			{
			p=SSL_get_cipher_list(ssl,i);
			if (p == NULL) break;
			if (i != 0) BIO_printf(STDout,":");
			BIO_printf(STDout,"%s",p);
			}
		BIO_printf(STDout,"\n");
		}
	else
		{
		sk=SSL_get_ciphers(ssl);

		for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
			{
			BIO_puts(STDout,SSL_CIPHER_description(
				sk_SSL_CIPHER_value(sk,i),
				buf,sizeof buf));
			}
		}

	ret=0;
	if (0)
		{
err:
		SSL_load_error_strings();
		ERR_print_errors(bio_err);
		}
end:
	if (ctx != NULL) SSL_CTX_free(ctx);
	if (ssl != NULL) SSL_free(ssl);
	if (STDout != NULL) BIO_free_all(STDout);
	apps_shutdown();
	OPENSSL_EXIT(ret);
	}
Пример #20
0
int main ( int argc, char **argv )
{
    int status, length;
    io_channel chan;
    struct rpc_msg msg;

	char *CApath=NULL,*CAfile=NULL;
	int badop=0;
	int ret=1;
	int client_auth=0;
	int server_auth=0;
	SSL_CTX *s_ctx=NULL;
    /*
     * Confirm logical link with initiating client.
     */
    LIB$INIT_TIMER();
    status = SYS$ASSIGN ( &sysnet, &chan, 0, 0, 0 );
    printf("status of assign to SYS$NET: %d\n", status );
    /*
     * Initialize standard out and error files.
     */
	if (bio_err == NULL)
		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE);
	if (bio_stdout == NULL)
		if ((bio_stdout=BIO_new(BIO_s_file())) != NULL)
			BIO_set_fp(bio_stdout,stdout,BIO_NOCLOSE);
    /*
     * get the preferred cipher list and other initialization
     */
	if (cipher == NULL) cipher=getenv("SSL_CIPHER");
	printf("cipher list: %s\n", cipher ? cipher : "{undefined}" );

	SSL_load_error_strings();
	OpenSSL_add_all_algorithms();

/* DRM, this was the original, but there is no such thing as SSLv2()
	s_ctx=SSL_CTX_new(SSLv2());
*/
	s_ctx=SSL_CTX_new(SSLv2_server_method());

	if (s_ctx == NULL) goto end;

	SSL_CTX_use_certificate_file(s_ctx,TEST_SERVER_CERT,SSL_FILETYPE_PEM);
	SSL_CTX_use_RSAPrivateKey_file(s_ctx,TEST_SERVER_CERT,SSL_FILETYPE_PEM);
	printf("Loaded server certificate: '%s'\n", TEST_SERVER_CERT );

    /*
     * Take commands from client until bad status.
     */
    LIB$SHOW_TIMER();
    status = doit ( chan, s_ctx );
    LIB$SHOW_TIMER();
    /*
     * do final cleanup and exit.
     */
end:
	if (s_ctx != NULL) SSL_CTX_free(s_ctx);
    LIB$SHOW_TIMER();
    return 1;
}
Пример #21
0
static int openssl_ssl_ctx_new(lua_State*L)
{
  const char* meth = luaL_optstring(L, 1, "TLSv1");
#if OPENSSL_VERSION_NUMBER >= 0x01000000L
  const
#endif
  SSL_METHOD* method = NULL;
  const char* ciphers;
  SSL_CTX* ctx;
  if (strcmp(meth, "SSLv3") == 0)
    method = SSLv3_method();    /* SSLv3 */
  else if (strcmp(meth, "SSLv3_server") == 0)
    method = SSLv3_server_method(); /* SSLv3 */
  else if (strcmp(meth, "SSLv3_client") == 0)
    method = SSLv3_client_method(); /* SSLv3 */
  else if (strcmp(meth, "SSLv23") == 0)
    method = SSLv23_method();   /* SSLv3 but can rollback to v2 */
  else if (strcmp(meth, "SSLv23_server") == 0)
    method = SSLv23_server_method();  /* SSLv3 but can rollback to v2 */
  else if (strcmp(meth, "SSLv23_client") == 0)
    method = SSLv23_client_method();  /* SSLv3 but can rollback to v2 */

  else if (strcmp(meth, "TLSv1_1") == 0)
    method = TLSv1_1_method();    /* TLSv1.0 */
  else if (strcmp(meth, "TLSv1_1_server") == 0)
    method = TLSv1_1_server_method(); /* TLSv1.0 */
  else if (strcmp(meth, "TLSv1_1_client") == 0)
    method = TLSv1_1_client_method(); /* TLSv1.0 */

  else if (strcmp(meth, "TLSv1_2") == 0)
    method = TLSv1_2_method();    /* TLSv1.0 */
  else if (strcmp(meth, "TLSv1_2_server") == 0)
    method = TLSv1_2_server_method(); /* TLSv1.0 */
  else if (strcmp(meth, "TLSv1_2_client") == 0)
    method = TLSv1_2_client_method(); /* TLSv1.0 */

  else if (strcmp(meth, "TLSv1") == 0)
    method = TLSv1_method();    /* TLSv1.0 */
  else if (strcmp(meth, "TLSv1_server") == 0)
    method = TLSv1_server_method(); /* TLSv1.0 */
  else if (strcmp(meth, "TLSv1_client") == 0)
    method = TLSv1_client_method(); /* TLSv1.0 */

  else if (strcmp(meth, "DTLSv1") == 0)
    method = DTLSv1_method();   /* DTLSv1.0 */
  else if (strcmp(meth, "DTLSv1_server") == 0)
    method = DTLSv1_server_method();  /* DTLSv1.0 */
  else if (strcmp(meth, "DTLSv1_client") == 0)
    method = DTLSv1_client_method();  /* DTLSv1.0 */
#ifndef OPENSSL_NO_SSL2
#if OPENSSL_VERSION_NUMBER < 0x10100000L
  else if (strcmp(meth, "SSLv2") == 0)
    method = SSLv2_method();    /* SSLv2 */
  else if (strcmp(meth, "SSLv2_server") == 0)
    method = SSLv2_server_method(); /* SSLv2 */
  else if (strcmp(meth, "SSLv2_client") == 0)
    method = SSLv2_client_method();
#endif
#ifdef LOAD_SSL_CUSTOM
  LOAD_SSL_CUSTOM
#endif

#endif
  else
    luaL_error(L, "#1:%s not supported\n"
               "Maybe SSLv3 SSLv23 TLSv1 TLSv1_1 TLSv1_2 DTLSv1 [SSLv2], option followed by _client or _server\n",
               "default is SSLv3",
               meth);
  ciphers = luaL_optstring(L, 2, SSL_DEFAULT_CIPHER_LIST);
  ctx = SSL_CTX_new(method);
  if (!ctx)
    luaL_error(L, "#1:%s not supported\n"
               "Maybe SSLv3 SSLv23 TLSv1 TLSv1_1 TLSv1_2 DTLSv1 [SSLv2], option followed by _client or _server\n",
               "default is SSLv3",
               meth);
  openssl_newvalue(L, ctx);
  SSL_CTX_set_cipher_list(ctx, ciphers);
  PUSH_OBJECT(ctx, "openssl.ssl_ctx");
  SSL_CTX_set_app_data(ctx, L);

  return 1;
}
Пример #22
0
int load_config(const char *file)
{
	FILE *f;
	char line[BUFSIZ];
	int ln = 1;
	struct passwd *p;

	if(file == (const char *) 0)
	{
		fprintf(stderr, "please supply a configuration file.\n");
		fprintf(stderr, "EASHD_CONFIG = %.100s\n", EASHD_CONFIG);
		exit(EXIT_FAILURE);
	}

	if((f = fopen(file, "r")) == (FILE *) 0)
	{
		fprintf(stderr, "%.100s: %.100s (%i)\n", file, strerror(errno), errno);
		exit(EXIT_FAILURE);
	}

	for(ln = 1; fgets(line, sizeof(line), f); ln++)
	{
		char key[1024];
		char val[1024];
		char *ptr;
		int x = 0;

		ptr = line;

		/* skip initial white space */
		while(isspace(*ptr))
			ptr++;

		if(strlen(ptr) <= 0)
			continue;

		if(*ptr == '#' || *ptr == '\n' || *ptr == '\r')
			continue;

		switch(sscanf(ptr, "%1000[^ \t]%1000s\n", (char *) &key, (char *) &val))
		{
			/* found both key and value pairs */
			case 2:
				switch(get_token(key))
				{
					case eHookTimeout:
						option.hook_timeout = atol(val);

						if(option.hook_timeout < 1 || option.hook_timeout > 65536)
						{
							fprintf(stderr, "[%.100s, line %i]: HookTimeout %i out of range.\n", file, ln, option.port);
							return(-1);
						}
						break;
					case ePort:
						option.port = atol(val);

						if(option.port < 1 || option.port > 65536)
						{
							fprintf(stderr, "[%.100s, line %i]: port %i out of range.\n", file, ln, option.port);
							return(-1);
						}
						break;
					case eListenAddress:
						option.listenaddress = strdup(val);
						break;
					case ePidFile:
						option.pidfile = strdup(val);
						if(can_create(file, ln, option.pidfile) < 0)
							return(-1);
						break;
					case eLogLevel:
						if(!strcasecmp(val, "info"))
							option.level = eINFO;
						else if(!strcasecmp(val, "debug1"))
							option.level = eDEBUG1;
						else if(!strcasecmp(val, "debug2"))
							option.level = eDEBUG2;
						else if(!strcasecmp(val, "debug3"))
							option.level = eDEBUG3;
						else
						{
							fprintf(stderr, "[%.100s, line %i]: invalid log level.\n", file, ln);
							return(-1);
						}
						break;
					case eSyslogFacility:
						if(!strcasecmp(val, "log_kern"))
							option.facility = LOG_KERN;
						else if(!strcasecmp(val, "log_user"))
							option.facility = LOG_USER;
						else if(!strcasecmp(val, "log_mail"))
							option.facility = LOG_MAIL;
						else if(!strcasecmp(val, "log_daemon"))
							option.facility = LOG_DAEMON;
						else if(!strcasecmp(val, "log_auth"))
							option.facility = LOG_AUTH;
						else if(!strcasecmp(val, "log_lpr"))
							option.facility = LOG_LPR;
						else if(!strcasecmp(val, "log_news"))
							option.facility = LOG_NEWS;
						else if(!strcasecmp(val, "log_uucp"))
							option.facility = LOG_UUCP;
						else if(!strcasecmp(val, "log_cron"))
							option.facility = LOG_CRON;
						else if(!strcasecmp(val, "log_local0"))
							option.facility = LOG_LOCAL0;
						else if(!strcasecmp(val, "log_local1"))
							option.facility = LOG_LOCAL1;
						else if(!strcasecmp(val, "log_local2"))
							option.facility = LOG_LOCAL2;
						else if(!strcasecmp(val, "log_local3"))
							option.facility = LOG_LOCAL3;
						else if(!strcasecmp(val, "log_local4"))
							option.facility = LOG_LOCAL4;
						else if(!strcasecmp(val, "log_local5"))
							option.facility = LOG_LOCAL5;
						else if(!strcasecmp(val, "log_local6"))
							option.facility = LOG_LOCAL6;
						else if(!strcasecmp(val, "log_local7"))
							option.facility = LOG_LOCAL7;
						else
						{
							fprintf(stderr, "[%.100s, line %i]: invalid syslog facility.\n", file, ln);
							return(-1);
						}
						break;
					case eSyslogPriority:
						if(!strcasecmp(val, "log_emerg"))
							option.priority = LOG_EMERG;
						else if(!strcasecmp(val, "log_alert"))
							option.priority = LOG_ALERT;
						else if(!strcasecmp(val, "log_crit"))
							option.priority = LOG_CRIT;
						else if(!strcasecmp(val, "log_err"))
							option.priority = LOG_ERR;
						else if(!strcasecmp(val, "log_warning"))
							option.priority = LOG_WARNING;
						else if(!strcasecmp(val, "log_notice"))
							option.priority = LOG_NOTICE;
						else if(!strcasecmp(val, "log_info"))
							option.priority = LOG_INFO;
						else if(!strcasecmp(val, "log_debug"))
							option.priority = LOG_DEBUG;
						else
						{
							fprintf(stderr, "[%.100s, line %i]: invalid syslog priority.\n", file, ln);
							return(-1);
						}
						break;
					case eCipher:
						option.cipher = strdup(val);
						break;
					case eMethod:
						if(!strcasecmp(val, "tlsv1"))
						{
							option.eash_method = TLSv1;
							option.method = TLSv1_server_method();
						}
						else if(!strcasecmp(val, "sslv2"))
						{
							option.eash_method = SSLv2;
							option.method = SSLv2_server_method();
						}
						else if(!strcasecmp(val, "sslv3"))
						{
							option.eash_method = SSLv3;
							option.method = SSLv3_server_method();
						}
						else if(!strcasecmp(val, "sslv23"))
						{
							option.eash_method = SSLv23;
							option.method = SSLv23_server_method();
						}
						else
						{
							fprintf(stderr, "[%.100s, line %i]: invalid SSL method.\n", file, ln);
							return(-1);
						}
						break;
					case eNotificationHook:
						option.hook = strdup(val);
						if(verify_file(file, ln, option.hook) < 0)
							return(-1);
						break;
					case ePrivateKey:
						option.pemfile = strdup(val);
						if(verify_file(file, ln, option.pemfile) < 0)
							return(-1);
						break;
					case eRandomFile:
						option.randomfile = strdup(val);
						if(verify_file(file, ln, option.randomfile) < 0)
							return(-1);
						break;
					case eEGDFile:
						option.egdfile = strdup(val);
						if(verify_file(file, ln, option.egdfile) < 0)
							return(-1);
						break;
					case eSessionDirectory:
						option.sessiondirectory = strdup(val);
						if(verify_file_silent(file, ln, option.sessiondirectory) < 0)
						{
							fprintf(stderr, "info: creating SessionDirectory %.100s\n", option.sessiondirectory);
							if(mkdir(option.sessiondirectory, 0700) < 0)
							{
								fprintf(stderr, "[%.100s, line %i]: mkdir: %.100s (%i)\n", file, ln, strerror(errno), errno);
								return(-1);
							}

							if(chmod(option.sessiondirectory, S_IRUSR | S_IWUSR | S_IXUSR) < 0)
							{
								fprintf(stderr, "[%.100s, line %i]: chmod: %.100s (%i)\n", file, ln, strerror(errno), errno);
								return(-1);
							}
						}
						snprintf(option.sessiondb, sizeof(option.sessiondb) - 1, "%s/db", option.sessiondirectory);
						break;
					case eCertificateAuthority:
						x = 0;

						while(option.cafiles[x] != NULL)
							x++;

						if(!(option.cafiles = realloc(option.cafiles, sizeof(char *) * (x + 2))))
						{
							fprintf(stderr, "realloc: %.100s (%i)\n", strerror(errno), errno);
							return(-1);
						}

						if(!(option.cafiles[x] = strdup(val)))
						{
							fprintf(stderr, "strdup: %.100s (%i)\n", strerror(errno), errno);
							return(-1);
						}

						option.cafiles[x + 1] = 0;
						break;
					case eUser:
						if(is_string(val))
						{
							if((p = getpwnam(val)) == (struct passwd *) 0)
							{
								fprintf(stderr, "[%.100s, line %i]: unknown username.\n", file, ln);
								return(-1);
							}
							else
							{
								option.uid = p->pw_uid;
								option.gid = p->pw_gid;
							}
						}
						else
						{
							if((p = getpwuid((uid_t) atol(val))) == (struct passwd *) 0)
							{
								fprintf(stderr, "[%.100s, line %i]: unknown UID.\n", file, ln);
								return(-1);
							}
							else
							{
								option.uid = p->pw_uid;
								option.gid = p->pw_gid;
							}
						}
						break;
					case eSync:
						if(!(strcasecmp(val, "_IONBF")))
							option.sync = _IONBF;
						else if(!(strcasecmp(val, "_IOLBF")))
							option.sync = _IOLBF;
						else if(!(strcasecmp(val, "_IOFBF")))
							option.sync = _IOFBF;
						else
						{
							fprintf(stderr, "[%.100s, line %i]: invalid argument.\n", file, ln);
							fprintf(stderr, " _IONBF unbuffered\n");
							fprintf(stderr, " _IOLBF line buffered\n");
							fprintf(stderr, " _IOFBF fully buffered\n");
							return(-1);
						}
						break;
					case eSignInode:
						if(!(strcasecmp(val, "yes")))
							option.strict_inode = 1;
						else if(!(strcasecmp(val, "no")))
							option.strict_inode = 0;
						else
						{
							fprintf(stderr, "[%.100s, line %i]: invalid argument.  yes or no.\n", file, ln);
							return(-1);
						}
						break;
					case eSignMode:
						if(!(strcasecmp(val, "yes")))
							option.strict_mode = 1;
						else if(!(strcasecmp(val, "no")))
							option.strict_mode = 0;
						else
						{
							fprintf(stderr, "[%.100s, line %i]: invalid argument.  yes or no.\n", file, ln);
							return(-1);
						}
						break;
					case eSignOwner:
						if(!(strcasecmp(val, "yes")))
							option.strict_owner = 1;
						else if(!(strcasecmp(val, "no")))
							option.strict_owner = 0;
						else
						{
							fprintf(stderr, "[%.100s, line %i]: invalid argument.  yes or no.\n", file, ln);
							return(-1);
						}
						break;
					case eSignCtime:
						if(!(strcasecmp(val, "yes")))
							option.strict_ctime = 1;
						else if(!(strcasecmp(val, "no")))
							option.strict_ctime = 0;
						else
						{
							fprintf(stderr, "[%.100s, line %i]: invalid argument.  yes or no.\n", file, ln);
							return(-1);
						}
						break;
					case eSignMtime:
						if(!(strcasecmp(val, "yes")))
							option.strict_mtime = 1;
						else if(!(strcasecmp(val, "no")))
							option.strict_mtime = 0;
						else
						{
							fprintf(stderr, "[%.100s, line %i]: invalid argument.  yes or no.\n", file, ln);
							return(-1);
						}
						break;
					case eHookFailureCritical:
						if(!(strcasecmp(val, "yes")))
							option.hook_failure_critical = 1;
						else if(!(strcasecmp(val, "no")))
							option.hook_failure_critical = 0;
						else
						{
							fprintf(stderr, "[%.100s, line %i]: invalid argument.  yes or no.\n", file, ln);
							return(-1);
						}
						break;
					case eKeepAlive:
						if(!(strcasecmp(val, "yes")))
							option.keepalive = 1;
						else if(!(strcasecmp(val, "no")))
							option.keepalive = 0;
						else
						{
							fprintf(stderr, "[%.100s, line %i]: invalid argument.  yes or no.\n", file, ln);
							return(-1);
						}
						break;
					case eIdleTimeout:
						option.idletimeout = atol(val);
						if(option.idletimeout == -1)
							s_log(eDEBUG1, "IdleTimeout = -1 -- disabling session timeout.");
						else if(option.idletimeout < 60)
						{
							fprintf(stderr, "[%.100s, line %i]: set a timeout over 60 seconds\n", file, ln);
							return(-1);
						}
						break;
					case eBadOption:
						fprintf(stderr, "[%.100s, line %i]: bad configuration option: %.63s\n", file, ln, key);
						return(-1);
						break;
                                        case emysql_IP:
                                                option.mysql_IP = strdup(val);
						break;
                                                
                                        case emysql_user:
                                                option.mysql_user = strdup(val);
						break;
                                                
                                        case emysql_pass:
                                                option.mysql_pass = strdup(val);
						break;
                                                
                                        case emysql_db:
                                                option.mysql_db = strdup(val);
						break;
                                                
                                        case emysql_port:
						option.mysql_port = atol(val);
						if(option.mysql_port < 1 || option.mysql_port > 65536)
						{
							fprintf(stderr, "[%.100s, line %i]: mysqlport %i out of range.\n", file, ln, option.port);
							return(-1);
						}
						break;
				}
				break;
			case 1:
				if(key[strlen(key)-1] == '\n')
					key[strlen(key)-1] = '\0';

				switch(get_token(key))
				{
					case eBadOption:
						fprintf(stderr, "[%.100s, line %i]: bad configuration option: %.63s\n", file, ln, key);
						return(-1);
						break;
					default:
						fprintf(stderr, "[%.100s, line %i]: missing arguement.\n", file, ln);
						return(-1);
						break;
				}
				break;
			default:
				fprintf(stderr, "[%.100s, line %i]: invalid syntax.\n", file, ln);
				return(-1);
				break;
		}
	}

	fclose(f);

	return(0);
}