lftp_ssl_openssl_instance::lftp_ssl_openssl_instance()
{
   crl_store=0;
   ssl_ctx=0;

#ifdef WINDOWS
   RAND_screen();
#endif

   RAND_file_name(file,sizeof(file));

   if(RAND_load_file(file,-1) && RAND_status()!=0)
      atexit(lftp_ssl_write_rnd);

#if SSLEAY_VERSION_NUMBER < 0x0800
   ssl_ctx=SSL_CTX_new();
   X509_set_default_verify_paths(ssl_ctx->cert);
#else
   SSLeay_add_ssl_algorithms();
   ssl_ctx=SSL_CTX_new(SSLv23_client_method());
   long options=SSL_OP_ALL|SSL_OP_NO_TICKET|SSL_OP_NO_SSLv2;
   const char *priority=ResMgr::Query("ssl:priority", 0);
   if(priority && *priority)
   {
      static const struct ssl_option {
	 const char name[8];
	 long option;
      } opt_table[]={
	 {"-SSL3.0",SSL_OP_NO_SSLv3},
	 {"-TLS1.0",SSL_OP_NO_TLSv1},
	 {"-TLS1.1",SSL_OP_NO_TLSv1_1},
	 {"-TLS1.2",SSL_OP_NO_TLSv1_2},
	 {"",0}
      };
      char *to_parse=alloca_strdup(priority);
      for(char *ptr=strtok(to_parse,":"); ptr; ptr=strtok(NULL,":")) {
	 for(const ssl_option *opt=opt_table; opt->name[0]; opt++) {
	    if(!strcmp(ptr,opt->name)) {
	       options|=opt->option;
	       Log::global->Format(9,"ssl: applied %s option\n",ptr);
	       break;
	    }
	 }
      }
   }
   SSL_CTX_set_options(ssl_ctx, options);
   SSL_CTX_set_cipher_list(ssl_ctx, "ALL:!aNULL:!eNULL:!SSLv2:!LOW:!EXP:!MD5:@STRENGTH");
   SSL_CTX_set_verify(ssl_ctx,SSL_VERIFY_PEER,lftp_ssl_openssl::verify_callback);
//    SSL_CTX_set_default_passwd_cb(ssl_ctx,lftp_ssl_passwd_callback);

   const char *ca_file=ResMgr::Query("ssl:ca-file",0);
   const char *ca_path=ResMgr::Query("ssl:ca-path",0);
   if(ca_file && !*ca_file)
      ca_file=0;
   if(ca_path && !*ca_path)
      ca_path=0;
   if(ca_file || ca_path)
   {
      if(!SSL_CTX_load_verify_locations(ssl_ctx,ca_file,ca_path))
      {
	 fprintf(stderr,"WARNING: SSL_CTX_load_verify_locations(%s,%s) failed\n",
	    ca_file?ca_file:"NULL",
	    ca_path?ca_path:"NULL");
	 SSL_CTX_set_default_verify_paths(ssl_ctx);
      }
   }
   else
   {
      SSL_CTX_set_default_verify_paths(ssl_ctx);
   }

   const char *crl_file=ResMgr::Query("ssl:crl-file",0);
   const char *crl_path=ResMgr::Query("ssl:crl-path",0);
   if(crl_file && !*crl_file)
      crl_file=0;
   if(crl_path && !*crl_path)
      crl_path=0;
   if(crl_file || crl_path)
   {
      crl_store=X509_STORE_new();
      if(!X509_STORE_load_locations(crl_store,crl_file,crl_path))
      {
	 fprintf(stderr,"WARNING: X509_STORE_load_locations(%s,%s) failed\n",
	    crl_file?crl_file:"NULL",
	    crl_path?crl_path:"NULL");
      }
   }
#endif /* SSLEAY_VERSION_NUMBER < 0x0800 */
}
lftp_ssl_openssl_instance::lftp_ssl_openssl_instance()
{
   crl_store=0;
   ssl_ctx=0;

#ifdef WINDOWS
   RAND_screen();
#endif

   RAND_file_name(file,sizeof(file));

   if(RAND_load_file(file,-1) && RAND_status()!=0)
      atexit(lftp_ssl_write_rnd);

#if SSLEAY_VERSION_NUMBER < 0x0800
   ssl_ctx=SSL_CTX_new();
   X509_set_default_verify_paths(ssl_ctx->cert);
#else
   SSLeay_add_ssl_algorithms();
   ssl_ctx=SSL_CTX_new(SSLv23_client_method());
   long options=SSL_OP_ALL|SSL_OP_NO_TICKET|SSL_OP_NO_SSLv2;
   const char *priority=ResMgr::Query("ssl:priority", 0);
   if(priority && *priority)
   {
      static const struct ssl_option {
	 const char name[8];
	 long option;
      } opt_table[]={
	 {"-SSL3.0",SSL_OP_NO_SSLv3},
	 {"-TLS1.0",SSL_OP_NO_TLSv1},
	 {"-TLS1.1",SSL_OP_NO_TLSv1_1},
	 {"-TLS1.2",SSL_OP_NO_TLSv1_2},
	 {"",0}
      };
      char *to_parse=alloca_strdup(priority);
      for(char *ptr=strtok(to_parse,":"); ptr; ptr=strtok(NULL,":")) {
	 for(const ssl_option *opt=opt_table; opt->name[0]; opt++) {
	    if(!strcmp(ptr,opt->name)) {
	       options|=opt->option;
	       Log::global->Format(9,"ssl: applied %s option\n",ptr);
	       break;
	    }
	 }
      }
   }
   SSL_CTX_set_options(ssl_ctx, options);
   SSL_CTX_set_cipher_list(ssl_ctx, "ALL:!aNULL:!eNULL:!SSLv2:!LOW:!EXP:!MD5:@STRENGTH");
   SSL_CTX_set_verify(ssl_ctx,SSL_VERIFY_PEER,lftp_ssl_openssl::verify_callback);
 

   const char *ca_file=ResMgr::Query("ssl:ca-file",0);
   const char *ca_path=ResMgr::Query("ssl:ca-path",0);
   if(ca_file && !*ca_file)
      ca_file=0;
   if(ca_path && !*ca_path)
      ca_path=0;
   if(ca_file || ca_path)
   {
      if(!SSL_CTX_load_verify_locations(ssl_ctx,ca_file,ca_path))
      {
	 fprintf(stderr,"WARNING: SSL_CTX_load_verify_locations(%s,%s) failed\n",
	    ca_file?ca_file:"NULL",
	    ca_path?ca_path:"NULL");
	 SSL_CTX_set_default_verify_paths(ssl_ctx);
      }
   }
   else
   {
      SSL_CTX_set_default_verify_paths(ssl_ctx);
   }

   const char *crl_file=ResMgr::Query("ssl:crl-file",0);
   const char *crl_path=ResMgr::Query("ssl:crl-path",0);
   if(crl_file && !*crl_file)
      crl_file=0;
   if(crl_path && !*crl_path)
      crl_path=0;
   if(crl_file || crl_path)
   {
      crl_store=X509_STORE_new();
      if(!X509_STORE_load_locations(crl_store,crl_file,crl_path))
      {
	 fprintf(stderr,"WARNING: X509_STORE_load_locations(%s,%s) failed\n",
	    crl_file?crl_file:"NULL",
	    crl_path?crl_path:"NULL");
      }
   }
#endif  
}