home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / ckermit.tar.Z / ckermit.tar / ck_ssl.c < prev    next >
C/C++ Source or Header  |  2004-03-14  |  145KB  |  4,243 lines

  1. char *cksslv = "SSL/TLS support, 8.0.221, 26 Feb 2004";
  2. /*
  3.   C K _ S S L . C --  OpenSSL Interface for C-Kermit
  4.  
  5.   Copyright (C) 1985, 2004,
  6.     Trustees of Columbia University in the City of New York.
  7.     All rights reserved.  See the C-Kermit COPYING.TXT file or the
  8.     copyright text in the ckcmai.c module for disclaimer and permissions.
  9.  
  10.     Author:  Jeffrey E Altman (jaltman@secure-endpoints.com)
  11.                Secure Endpoints Inc., New York City
  12.  
  13.   Provides:
  14.  
  15.   . Telnet Auth SSL option compatible with Tim Hudson's hack.
  16.   . Telnet START_TLS option
  17.   . Configuration of certificate and key files
  18.   . Certificate verification and revocation list checks
  19.   . Client certificate to user id routine
  20.  
  21.   Note: This code is written to be compatible with OpenSSL 0.9.6[abcdefgh]
  22.   and 0.9.7 beta 5.
  23.   It will also compile with version 0.9.5 although that is discouraged
  24.   due to security weaknesses in that release.
  25. */
  26.  
  27. #include "ckcsym.h"
  28. #include "ckcdeb.h"
  29.  
  30. #ifdef CK_SSL
  31. #include "ckcnet.h"
  32. #include "ckuath.h"
  33.  
  34. #include <stdlib.h>
  35. #include <string.h>
  36. #ifdef UNIX
  37. #include <netinet/in.h>
  38. #ifndef FREEBSD4
  39. #include <arpa/inet.h>
  40. #endif /* FREEBSD4 */
  41. #endif /* UNIX */
  42.  
  43. #ifdef DEC_TCPIP
  44. #include <time.h>
  45. #include <inet.h>
  46. #endif /* DEC_TCPIP */
  47.  
  48. #ifdef OS2
  49. extern char exedir[];
  50. #ifdef NT
  51. char * GetAppData(int);
  52. #endif
  53. #endif /* OS2 */
  54.  
  55. static int ssl_installed = 1;
  56. #endif /* CK_SSL */
  57. int
  58. ck_ssh_is_installed()
  59. {
  60. #ifdef SSHBUILTIN
  61. #ifdef SSLDLL
  62. #ifdef NT
  63.     extern HINSTANCE hCRYPTO;
  64. #else /* NT */
  65.     extern HMODULE hCRYPTO;
  66. #endif /* NT */
  67.     debug(F111,"ck_ssh_is_installed","hCRYPTO",hCRYPTO);
  68.     return(ssl_installed && (hCRYPTO != NULL));
  69. #else /* SSLDLL */
  70.     return(ssl_installed);
  71. #endif /* SSLDLL */
  72. #else
  73.     return 0;
  74. #endif
  75. }
  76.  
  77. int
  78. #ifdef CK_ANSIC
  79. ck_ssleay_is_installed(void)
  80. #else
  81. ck_ssleay_is_installed()
  82. #endif
  83. {
  84. #ifdef CK_SSL
  85. #ifdef SSLDLL
  86. #ifdef NT
  87.     extern HINSTANCE hSSL, hCRYPTO;
  88. #else /* NT */
  89.     extern HMODULE hSSL, hCRYPTO;
  90. #endif /* NT */
  91.     debug(F111,"ck_ssleay_is_installed","hSSL",hSSL);
  92.     debug(F111,"ck_ssleay_is_installed","hCRYPTO",hCRYPTO);
  93.     return(ssl_installed && (hSSL != NULL) && (hCRYPTO != NULL));
  94. #else /* SSLDLL */
  95.     return(ssl_installed);
  96. #endif /* SSLDLL */
  97. #else /* CK_SSL */
  98.     return(0);
  99. #endif /* CK_SSL */
  100. }
  101.  
  102. #ifdef CK_SSL
  103. #include "ckcker.h"
  104. #include "ckucmd.h"                             /* For struct keytab */
  105. #include "ckctel.h"
  106. #include "ck_ssl.h"
  107. #ifdef UNIX
  108. #include <pwd.h>                    /* Password file for home directory */
  109. #endif /* UNIX */
  110. #ifdef OS2
  111. #include <process.h>
  112. #endif /* OS2 */
  113. #ifdef OS2ONLY
  114. #include "ckotcp.h"
  115. #endif /* OS2ONLY */
  116.  
  117. #ifdef SSLDLL
  118. int ssl_finished_messages = 0;
  119. #else /* SSLDLL */
  120. #ifdef OPENSSL_VERSION_NUMBER
  121. int ssl_finished_messages = (OPENSSL_VERSION_NUMBER >= 0x0090581fL);
  122. #else
  123. !ERROR This module requires OpenSSL 0.9.5a or higher
  124. #endif /* OPENSSL_VERSION_NUMBER */
  125. #endif /* SSLDLL */
  126.  
  127. static int auth_ssl_valid = 0;
  128. static char *auth_ssl_name = 0;    /* this holds the oneline name */
  129. char ssl_err[SSL_ERR_BFSZ]="";
  130.  
  131. BIO *bio_err=NULL;
  132. X509_STORE *crl_store = NULL;
  133.  
  134. #ifndef NOFTP
  135. #ifndef SYSFTP
  136. SSL *ssl_ftp_con             = NULL;
  137. SSL_CTX *ssl_ftp_ctx         = NULL;
  138. SSL *ssl_ftp_data_con        = NULL;
  139. int ssl_ftp_active_flag      = 0;
  140. int ssl_ftp_data_active_flag = 0;
  141. #endif /* SYSFTP */
  142. #endif /* NOFTP */
  143.  
  144. #ifndef NOHTTP
  145. SSL *tls_http_con            = NULL;
  146. SSL_CTX *tls_http_ctx        = NULL;
  147. int tls_http_active_flag     = 0;
  148. int ssl_http_initialized = 0;
  149. #endif /* NOHTTP */
  150.  
  151. SSL_CTX *ssl_ctx = NULL;
  152. SSL *ssl_con = NULL;
  153. int ssl_debug_flag = 0;
  154. int ssl_verbose_flag = 0;
  155. int ssl_only_flag = 0;
  156. int ssl_active_flag = 0;
  157. int ssl_verify_flag = SSL_VERIFY_PEER;
  158. int ssl_certsok_flag = 0;
  159. char *ssl_rsa_cert_file = NULL;
  160. char *ssl_rsa_cert_chain_file = NULL;
  161. char *ssl_rsa_key_file = NULL;
  162. char *ssl_dsa_cert_file = NULL;
  163. char *ssl_dsa_cert_chain_file = NULL;
  164. char *ssl_dh_key_file = NULL;
  165. char *ssl_crl_file = NULL;
  166. char *ssl_crl_dir = NULL;
  167. char *ssl_verify_file = NULL;
  168. char *ssl_verify_dir = NULL;
  169. char *ssl_dh_param_file = NULL;
  170. char *ssl_cipher_list = NULL;
  171. char *ssl_rnd_file = NULL;
  172.  
  173. SSL_CTX *tls_ctx = NULL;
  174. SSL *tls_con = NULL;
  175. int tls_only_flag = 0;
  176. int tls_active_flag = 0;
  177.  
  178. int ssl_initialized = 0;
  179. int ssl_verify_depth = -1; /* used to track depth in verify routines */
  180.  
  181. /* compile this set to 1 to negotiate SSL/TLS but not actually start it */
  182. int ssl_dummy_flag=0;
  183.  
  184. extern int inserver;
  185. extern int debses;
  186. extern int accept_complete;
  187. extern char szHostName[], szUserNameRequested[], szUserNameAuthenticated[];
  188.  
  189. _PROTOTYP(int X509_to_user,(X509 *, char *, int));
  190.  
  191. int
  192. #ifdef CK_ANSIC
  193. ssl_server_verify_callback(int ok, X509_STORE_CTX * ctx)
  194. #else /* CK_ANSIC */
  195. ssl_server_verify_callback(ok, ctx)
  196. int ok;
  197. X509_STORE_CTX *ctx;
  198. #endif /* CK_ANSIC */
  199. {
  200.     static char *saved_subject=NULL;
  201.     char *subject=NULL, *issuer=NULL;
  202.     int depth,error;
  203.     X509 *xs = NULL;
  204.  
  205.     if ( ssl_certsok_flag )
  206.         return(1);
  207.  
  208.     error=X509_STORE_CTX_get_error(ctx);
  209.     depth=X509_STORE_CTX_get_error_depth(ctx);
  210.     xs=X509_STORE_CTX_get_current_cert(ctx);
  211.  
  212.     if (depth==0) {
  213.         /* clear things */
  214.         if (saved_subject!=NULL) {
  215.             free(saved_subject);
  216.             saved_subject=NULL;
  217.         }
  218.         if (auth_ssl_name!=NULL) {
  219.             free(auth_ssl_name);
  220.             auth_ssl_name=NULL;
  221.         }
  222.     }
  223.  
  224.  
  225.     if (ssl_debug_flag && !inserver) {
  226.         printf("ssl:server_verify_callback:depth=%d ok=%d err=%d-%s\r\n",
  227.             depth,ok,error,X509_verify_cert_error_string(error));
  228.     }
  229.  
  230.     /* first thing is to have a meaningful name for the current
  231.      * certificate that is being verified ... and if we cannot
  232.      * determine that then something is seriously wrong!
  233.      */
  234.     makestr(&subject,
  235.             (char *)X509_NAME_oneline(X509_get_subject_name(xs),NULL,0));
  236.     makestr(&issuer,
  237.             (char *)X509_NAME_oneline(X509_get_issuer_name(xs),NULL,0));
  238.     if (!subject || !subject[0] || !issuer || !issuer[0]) {
  239.         ok = 0;
  240.         goto return_time;
  241.     }
  242.  
  243.     if (ssl_verbose_flag && !inserver && depth != ssl_verify_depth) {
  244.         printf("[%d] Certificate Subject:\r\n%s\r\n",depth,subject);
  245.         printf("[%d] Certificate Issuer:\r\n%s\r\n",depth,issuer);
  246.         ssl_verify_depth = depth;
  247.     }
  248.  
  249.     /* make sure that the certificate that has been presented */
  250.     /* has not been revoked (if we have been given a CRL.     */
  251.     ok =  ssl_verify_crl(ok, ctx);
  252.  
  253.     /* if we have any form of error in secure mode we reject the connection */
  254.     if (error!=X509_V_OK) {
  255.         if (inserver) {
  256. #ifdef CKSYSLOG
  257.             if (ckxsyslog >= SYSLG_LI && ckxlogging) {
  258.                 cksyslog(SYSLG_LI, 0,
  259.                           "X.509 Certificate verify failure",
  260.                           (char *) subject,
  261.                           (char *)X509_verify_cert_error_string(error)
  262.                           );
  263.             }
  264. #endif /* CKSYSLOG */
  265.  
  266.         } else {
  267.             if ( ssl_verify_flag &
  268.                  (SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT))
  269.                 printf("Error: ");
  270.             else
  271.                 printf("Warning: ");
  272.             switch (error) {
  273.             case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
  274.                 printf("Certificate is self signed.\r\n");
  275.                 break;
  276.             case X509_V_ERR_CERT_HAS_EXPIRED:
  277.                 printf("Certificate has expired.\r\n");
  278.                 break;
  279.             case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
  280.                 printf(
  281.   "Certificate issuer's certificate isn't available locally.\r\n");
  282.                 break;
  283.             case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
  284.                 printf("Unable to verify leaf signature.\r\n");
  285.                 break;
  286.             case X509_V_ERR_CERT_REVOKED:
  287.                 printf("Certificate revoked.\r\n");
  288.                 break;
  289.             default:
  290.                 printf("Error %d while verifying certificate.\r\n",
  291.                        ctx->error);
  292.                 break;
  293.             }
  294.         }
  295.         ok = !(ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT);
  296.     } else {
  297.         /* if we got all the way to the top of the tree then
  298.          * we *can* use this certificate for a username to
  299.          * match ... in all other cases we must not!
  300.          */
  301.         auth_ssl_name = saved_subject;
  302.         saved_subject = NULL;
  303.     }
  304.  
  305.   return_time:
  306.  
  307.     /* save the name if at least the first level is okay */
  308.     if (depth == 0 && ok)
  309.         makestr(&saved_subject,subject);
  310.  
  311.     /* clean up things */
  312.     if (subject!=NULL)
  313.         free(subject);
  314.     if (issuer!=NULL)
  315.         free(issuer);
  316.  
  317.     return ok;
  318. }
  319.  
  320. int
  321. #ifdef CK_ANSIC
  322. ssl_client_verify_callback(int ok, X509_STORE_CTX * ctx)
  323. #else
  324. ssl_client_verify_callback(ok, ctx)
  325. int ok;
  326. X509_STORE_CTX *ctx;
  327. #endif
  328. {
  329.     char subject[256]="", issuer[256]="";
  330.     int depth, error, len;
  331.     X509 *xs;
  332.  
  333.     xs=X509_STORE_CTX_get_current_cert(ctx);
  334.     error=X509_STORE_CTX_get_error(ctx);
  335.     depth=X509_STORE_CTX_get_error_depth(ctx);
  336.  
  337.     if ( ssl_debug_flag )
  338.         printf("ssl:client_verify_callback:depth=%d ok=%d err=%d-%s\r\n",
  339.                 depth,ok,error,X509_verify_cert_error_string(error));
  340.  
  341.     if ( ssl_certsok_flag ) {
  342.         ok = 1;
  343.     }
  344.  
  345.     /* first thing is to have a meaningful name for the current
  346.      * certificate that is being verified ... and if we cannot
  347.      * determine that then something is seriously wrong!
  348.      */
  349. #ifdef XN_FLAG_SEP_MULTILINE
  350.     X509_NAME_print_ex(bio_err,X509_get_subject_name(xs),4,
  351.                         XN_FLAG_SEP_MULTILINE);
  352.     len = BIO_read(bio_err,subject,256);
  353.     subject[len < 256 ? len : 255] = '\0';
  354.     if (!subject[0]) {
  355.         ERR_print_errors(bio_err);
  356.         len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
  357.         ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
  358.         uq_ok("X.509 Subject Name unavailable", ssl_err, 1, NULL, 0);
  359.         ok=0;
  360.         goto return_time;
  361.     }
  362.  
  363.     X509_NAME_print_ex(bio_err,X509_get_issuer_name(xs),4,
  364.                         XN_FLAG_SEP_MULTILINE);
  365.     len = BIO_read(bio_err,issuer,256);
  366.     issuer[len < 256 ? len : 255] = '\0';
  367.     if (!issuer[0]) {
  368.         ERR_print_errors(bio_err);
  369.         len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
  370.         ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
  371.         uq_ok("X.509 Issuer Name unavailable", ssl_err, 1, NULL, 0);
  372.         ok=0;
  373.         goto return_time;
  374.     }
  375. #else /* XN_FLAG_SEP_MULTILINE */
  376.     X509_NAME_oneline(X509_get_subject_name(xs),subject,256);
  377.     if (!subject[0]) {
  378.         int len;
  379.         ERR_print_errors(bio_err);
  380.         len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
  381.         ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
  382.         uq_ok("X.509 Subject Name unavailable", ssl_err, 1, NULL, 0);
  383.         ok=0;
  384.         goto return_time;
  385.     }
  386.  
  387.     X509_NAME_oneline(X509_get_issuer_name(xs),issuer,256);
  388.     if (!issuer[0]) {
  389.         int len;
  390.         ERR_print_errors(bio_err);
  391.         len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
  392.         ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
  393.         uq_ok("X.509 Issuer Name unavailable", ssl_err, 1, NULL, 0);
  394.         ok=0;
  395.         goto return_time;
  396.     }
  397. #endif /* XN_FLAG_SEP_MULTILINE */
  398.  
  399.     if (ssl_verbose_flag && depth != ssl_verify_depth) {
  400.         printf("[%d] Certificate Subject:\r\n%s\r\n",depth,subject);
  401.         printf("[%d] Certificate Issuer:\r\n%s\r\n",depth,issuer);
  402.         ssl_verify_depth = depth;
  403.     }
  404.  
  405.     ok = ssl_verify_crl(ok, ctx);
  406.  
  407.     if ( !ok ) {
  408.         char prefix[1024];
  409.         /* if the server is using a self signed certificate then
  410.          * we need to decide if that is good enough for us to
  411.          * accept ...
  412.          */
  413.  
  414.         switch ( error ) {
  415.         case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: {
  416.             if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
  417.                 /* make 100% sure that in secure more we drop the
  418.                  * connection if the server does not have a
  419.                  * real certificate!
  420.                  */
  421.                 ckmakxmsg(prefix,1024,
  422.                            "Error: Server has a self-signed certificate\n",
  423.                            "[",ckitoa(depth),"] Certificate Subject=\n",subject,
  424.                            "\n[",ckitoa(depth),"] Certificate Issuer=\n",issuer,
  425.                            NULL,NULL,NULL);
  426.  
  427.                 uq_ok(prefix, "Rejecting Connection", 1, NULL, 0);
  428.  
  429.                 /* sometimes it is really handy to be able to debug things
  430.                 * and still get a connection!
  431.                 */
  432.                 if (ssl_debug_flag) {
  433.                     printf("SSL: debug -> ignoring cert required!\r\n");
  434.                     ok=1;
  435.                 } else {
  436.                     ok=0;
  437.                 }
  438.                 goto return_time;
  439.             } else if (ssl_verify_flag != SSL_VERIFY_NONE) {
  440.                 ckmakxmsg(prefix,1024,
  441.                            "Warning: Server has a self-signed certificate\n",
  442.                            "[",ckitoa(depth),"] Certificate Subject=\n",subject,
  443.                            "\n[",ckitoa(depth),"] Certificate Issuer=\n",issuer,
  444.                            NULL,NULL,NULL);
  445.  
  446.                 ok = uq_ok(prefix,
  447.                            "Continue? (Y/N) ",
  448.                            3, NULL, 0);
  449.                 if ( ok < 0 )
  450.                     ok = 0;
  451.                 goto return_time;
  452.             }
  453.         }
  454.         case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
  455.             if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
  456.                 /* make 100% sure that in secure more we drop the
  457.                  * connection if the server does not have a
  458.                  * real certificate!
  459.                  */
  460.                 ckmakxmsg(prefix,1024,
  461.                            "Error: ",
  462.                            (char *)X509_verify_cert_error_string(error),
  463.                            "\nCertificate Issuer=\n",issuer,
  464.                            NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
  465.                 uq_ok(prefix, "Rejecting Connection", 1, NULL, 0);
  466.  
  467.                 /* sometimes it is really handy to be able to debug things
  468.                 * and still get a connection!
  469.                 */
  470.                 if (ssl_debug_flag) {
  471.                     printf("SSL: debug -> ignoring cert required!\r\n");
  472.                     ok=1;
  473.                 } else {
  474.                     ok=0;
  475.                 }
  476.                 goto return_time;
  477.             } else if (ssl_verify_flag != SSL_VERIFY_NONE) {
  478.                 ckmakxmsg(prefix,1024,
  479.                            "Warning: ",
  480.                            (char *)X509_verify_cert_error_string(error),
  481.                            "\nCertificate Issuer=\n",issuer,
  482.                            NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
  483.                 ok = uq_ok(prefix, "Continue (Y/N)", 3, NULL, 0);
  484.                 goto return_time;
  485.             }
  486.             break;
  487.         case X509_V_ERR_CERT_NOT_YET_VALID:
  488.         case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
  489.             if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
  490.                 int len;
  491.                 /* make 100% sure that in secure more we drop the
  492.                  * connection if the server does not have a
  493.                  * real certificate!
  494.                  */
  495.                 ASN1_TIME_print(bio_err,X509_get_notBefore(xs));
  496.                 len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
  497.                 ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
  498.                 ckmakxmsg(prefix,1024,
  499.                            "Error: ",
  500.                            (char *)X509_verify_cert_error_string(error),
  501.                            "\nCertificate Subject=\n",subject,
  502.                            "\nnotBefore=",ssl_err,
  503.                            NULL,NULL,NULL,NULL,NULL,NULL);
  504.                 uq_ok(prefix, "Rejecting Connection", 1, NULL, 0);
  505.                 /* sometimes it is really handy to be able to debug things
  506.                 * and still get a connection!
  507.                 */
  508.                 if (ssl_debug_flag) {
  509.                     printf("SSL: debug -> ignoring cert required!\r\n");
  510.                     ok=1;
  511.                 } else {
  512.                     ok=0;
  513.                 }
  514.                 goto return_time;
  515.             } else if (ssl_verify_flag != SSL_VERIFY_NONE) {
  516.                 int len;
  517.                 ASN1_TIME_print(bio_err,X509_get_notBefore(xs));
  518.                 len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
  519.                 ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
  520.                 ckmakxmsg(prefix,1024,
  521.                            "Warning: ",
  522.                            (char *)X509_verify_cert_error_string(error),
  523.                            "\nCertificate Subject=\n",subject,
  524.                            "\n    notBefore=",ssl_err,
  525.                            NULL,NULL,NULL,NULL,NULL,NULL);
  526.                 ok = uq_ok(prefix, "Continue (Y/N)", 3, NULL, 0);
  527.             }
  528.             break;
  529.         case X509_V_ERR_CERT_HAS_EXPIRED:
  530.         case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
  531.             if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
  532.                 int len;
  533.                 /* make 100% sure that in secure more we drop the
  534.                  * connection if the server does not have a
  535.                  * real certificate!
  536.                  */
  537.                 ASN1_TIME_print(bio_err,X509_get_notAfter(xs));
  538.                 len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
  539.                 ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
  540.  
  541.                 ckmakxmsg(prefix,1024,
  542.                            "Error: ",
  543.                            (char *)X509_verify_cert_error_string(error),
  544.                            "\nCertificate Subject=\n",subject,
  545.                            "\n    notAfter=",ssl_err,
  546.                            NULL,NULL,NULL,NULL,NULL,NULL);
  547.                 uq_ok(prefix, "Rejecting Connection", 1, NULL, 0);
  548.    
  549.                 /* sometimes it is really handy to be able to debug things
  550.                 * and still get a connection!
  551.                 */
  552.                 if (ssl_debug_flag) {
  553.                     printf("SSL: debug -> ignoring cert required!\r\n");
  554.                     ok=1;
  555.                 } else {
  556.                     ok=0;
  557.                 }
  558.                 goto return_time;
  559.             } else if (ssl_verify_flag != SSL_VERIFY_NONE) {
  560.                 int len;
  561.                 ASN1_TIME_print(bio_err,X509_get_notAfter(xs));
  562.                 len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
  563.                 ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
  564.                 ckmakxmsg(prefix,1024,
  565.                            "Warning: ",
  566.                            (char *)X509_verify_cert_error_string(error),
  567.                            "\nCertificate Subject=\n",subject,
  568.                            "\n    notAfter=",ssl_err,
  569.                            NULL,NULL,NULL,NULL,NULL,NULL);
  570.                 ok = uq_ok(prefix, "Continue (Y/N)", 3, NULL, 0);
  571.             }
  572.             break;
  573.         case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
  574.         case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
  575.             /*
  576.              * When an SSL server sends its certificates to the client there
  577.              * are two" conventions": one is to send the complete certificate
  578.              * chain and the other is to send the whole chain apart from the
  579.              * root.
  580.              *
  581.              * You don't usually need the root because the root is normally
  582.              * stored and trusted locally.
  583.              *
  584.              * So if you get the whole chain it will complain about the self
  585.              * signed certificate whereas if the root is missing it says it
  586.              * can't find the issuer certificate.
  587.              */
  588.             if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
  589.                 /* make 100% sure that in secure more we drop the
  590.                  * connection if the server does not have a
  591.                  * real certificate!
  592.                  */
  593.                 ckmakxmsg(prefix,1024,
  594.                            "Error: ",
  595.                            (char *)X509_verify_cert_error_string(error),
  596.                            "\nCertificate Issuer=\n",issuer,
  597.                            NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
  598.                 uq_ok(prefix, "Rejecting Connection", 1, NULL, 0);
  599.                 /* sometimes it is really handy to be able to debug things
  600.                 * and still get a connection!
  601.                 */
  602.                 if (ssl_debug_flag) {
  603.                     printf("SSL: debug -> ignoring cert required!\r\n");
  604.                     ok=1;
  605.                 } else {
  606.                     ok=0;
  607.                 }
  608.                 goto return_time;
  609.             } else if (ssl_verify_flag != SSL_VERIFY_NONE) {
  610.                 ckmakxmsg(prefix,1024,
  611.                            "Warning: ",
  612.                            (char *)X509_verify_cert_error_string(error),
  613.                            "\nCertificate Issuer=\n",issuer,
  614.                            NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
  615.                 ok = uq_ok(prefix, "Continue (Y/N)", 3, NULL, 0);
  616. #ifdef NT
  617.                 if (ok) {
  618.                     /* if the user decides to accept the certificate
  619.                      * offer to store it for future connections in 
  620.                      * the user's private store
  621.                      */
  622.                     ok = uq_ok(
  623.   "Do you wish to store the certificate to verify future connections?",
  624.                                "Continue (Y/N)", 3, NULL, 0);
  625.                     if (ok)
  626.                         ck_X509_save_cert_to_user_store(xs);
  627.                 }
  628. #endif /* NT */
  629.             }
  630.             break;
  631.         case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
  632.         case X509_V_ERR_UNABLE_TO_GET_CRL:
  633.         case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
  634.         case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
  635.         case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
  636.         case X509_V_ERR_CERT_SIGNATURE_FAILURE:
  637.         case X509_V_ERR_CRL_SIGNATURE_FAILURE:
  638.         case X509_V_ERR_CRL_NOT_YET_VALID:
  639.         case X509_V_ERR_CRL_HAS_EXPIRED:
  640.         case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
  641.         case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
  642.         case X509_V_ERR_OUT_OF_MEM:
  643.         case X509_V_ERR_CERT_CHAIN_TOO_LONG:
  644.         case X509_V_ERR_CERT_REVOKED:
  645.         case X509_V_ERR_APPLICATION_VERIFICATION:
  646.         default:
  647.             if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
  648.                 /* make 100% sure that in secure mode we drop the
  649.                  * connection if the server does not have a
  650.                  * real certificate!
  651.                  */
  652.                 ckmakxmsg(prefix,1024,
  653.                            "Error: ",
  654.                            (char *)X509_verify_cert_error_string(error),
  655.                            "\nCertificate Subject=\n",subject,
  656.                            NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
  657.                 uq_ok(prefix, "Rejecting Connection", 1, NULL, 0);
  658.  
  659.                 /* sometimes it is really handy to be able to debug things
  660.                 * and still get a connection!
  661.                 */
  662.                 if (ssl_debug_flag) {
  663.                     printf("SSL: debug -> ignoring cert required!\r\n");
  664.                     ok=1;
  665.                 } else {
  666.                     ok=0;
  667.                 }
  668.                 goto return_time;
  669.             } else if (ssl_verify_flag != SSL_VERIFY_NONE) {
  670.                 ckmakxmsg(prefix,1024,
  671.                            "Warning: ",
  672.                            (char *)X509_verify_cert_error_string(error),
  673.                            "\nCertificate Subject=\n",subject,
  674.                            NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
  675.                 ok = uq_ok(prefix, "Continue (Y/N)", 3, NULL, 0);
  676.             }
  677.             break;
  678.         }
  679.     }
  680.  
  681.   return_time:
  682.     if ( ssl_debug_flag )
  683.         printf("ssl:client_verify_callback => ok: %d\r\n",ok);
  684.     return ok;
  685. }
  686.  
  687. VOID
  688. #ifdef CK_ANSIC
  689. ssl_client_info_callback(const SSL *s, int where, int ret)
  690. #else
  691. ssl_client_info_callback(s,where,ret)
  692. const SSL *s;
  693. int where;
  694. int ret;
  695. #endif /* CK_ANSIC */
  696. {
  697.     if (inserver || !ssl_debug_flag)
  698.         return;
  699.  
  700.     switch ( where ) {
  701.     case SSL_CB_CONNECT_LOOP:
  702.         printf("SSL_connect:%s %s\r\n",
  703.                 SSL_state_string((SSL *)s),SSL_state_string_long((SSL *)s));
  704.         break;
  705.     case SSL_CB_CONNECT_EXIT:
  706.         if (ret == 0) {
  707.             printf("SSL_connect:failed in %s %s\r\n",
  708.                     SSL_state_string((SSL *)s),SSL_state_string_long((SSL *)s));
  709.         } else if (ret < 0) {
  710.             printf("SSL_connect:error in %s %s\r\n",
  711.                     SSL_state_string((SSL *)s),SSL_state_string_long((SSL *)s));
  712.         }
  713.         break;
  714.     case SSL_CB_ACCEPT_LOOP:
  715.         printf("SSL_accept:%s %s\r\n",
  716.                 SSL_state_string((SSL *)s),SSL_state_string_long((SSL *)s));
  717.         break;
  718.     case SSL_CB_ACCEPT_EXIT:
  719.         if (ret == 0) {
  720.             printf("SSL_accept:failed in %s %s\r\n",
  721.                     SSL_state_string((SSL *)s),SSL_state_string_long((SSL *)s));
  722.         } else if (ret < 0) {
  723.             printf("SSL_accept:error in %s %s\r\n",
  724.                     SSL_state_string((SSL *)s),SSL_state_string_long((SSL *)s));
  725.         }
  726.         break;
  727.     case SSL_CB_READ_ALERT:
  728.         printf("SSL_read_alert\r\n");
  729.         break;
  730.     case SSL_CB_WRITE_ALERT:
  731.         printf("SSL_write_alert\r\n");
  732.         break;
  733.     case SSL_CB_HANDSHAKE_START:
  734.         printf("SSL_handshake:%s %s\r\n",
  735.                 SSL_state_string((SSL *)s),SSL_state_string_long((SSL *)s));
  736.         break;
  737.     case SSL_CB_HANDSHAKE_DONE:
  738.         printf("SSL_handshake:%s %s\r\n",
  739.                 SSL_state_string((SSL *)s),SSL_state_string_long((SSL *)s));
  740.         break;
  741.     }
  742. }
  743.  
  744. #ifdef USE_CERT_CB
  745. /* Return 1, client cert is available */
  746. /* Return 0, no client cert is available */
  747. /* Return -1, callback must be called again. SSL_want_x509_lookup() == 1 */
  748. int
  749. #ifdef CK_ANSIC
  750. ssl_client_cert_callback(SSL * s, X509 ** x509, EVP_PKEY ** pkey)
  751. #else /* CK_ANSIC */
  752. ssl_client_cert_callback(s, x509, pkey)
  753.     SSL * s;
  754.     X509 ** x509;
  755.     EVP_PKEY ** pkey;
  756. #endif /* CK_ANSIC */
  757. {
  758.     if ( ssl_debug_flag ) {
  759.         const char * cipher_list=SSL_get_cipher(s);
  760.         printf("ssl_client_cert_callback called (%s)\r\n",
  761.                 cipher_list?cipher_list:"UNKNOWN");
  762.     }
  763. #ifdef COMMENT
  764.     if ( s == tls_con ) {
  765.         if (tls_load_certs(tls_cts,tls_con,0)) {
  766.             *x509 = SSL_get_certificate(s);
  767.             *pkey = SSL_get_privatekey(s);
  768.             return(1);
  769.         }
  770.     } else if ( s == ssl_con ) {
  771.         if (tls_load_certs(ssl_ctx,ssl_con,0)) {
  772.             *x509 = SSL_get_certificate(s);
  773.             *pkey = SSL_get_privatekey(s);
  774.             return(1);
  775.         }
  776.     }
  777.     return(0);
  778. #else /* COMMENT */
  779.     return(0);
  780. #endif /* COMMENT */
  781. }
  782. #endif /* USE_CERT_CB */
  783.  
  784. #ifndef MS_CALLBACK
  785. #define MS_CALLBACK
  786. #endif /* MS_CALLBACK */
  787.  
  788. static RSA MS_CALLBACK *
  789. #ifdef CK_ANSIC
  790. tmp_rsa_cb(SSL * s, int export, int keylength)
  791. #else /* CK_ANSIC */
  792. tmp_rsa_cb(s,export,keylength)
  793. SSL *s;
  794. int export;
  795. int keylength;
  796. #endif /* CK_ANSIC */
  797. {
  798.     static RSA *rsa_tmp=NULL;
  799.     extern int quiet;
  800.  
  801. #ifndef NO_RSA
  802.     if (rsa_tmp == NULL)
  803.     {
  804.         if (ssl_debug_flag)
  805.             printf("Generating temporary (%d bit) RSA key...\r\n",keylength);
  806.  
  807.         rsa_tmp=RSA_generate_key(keylength,RSA_F4,NULL,NULL);
  808.  
  809.         if (ssl_debug_flag)
  810.             printf("\r\n");
  811.     }
  812. #else /* NO_RSA */
  813.     if (ssl_debug_flag)
  814.         printf("Unable to generate temporary RSA key...\r\n");
  815. #endif
  816.     return(rsa_tmp);
  817. }
  818.  
  819.  
  820. #ifndef NO_DH
  821. static unsigned char dh512_p[]={
  822.     0xE9,0x4E,0x3A,0x64,0xFA,0x65,0x5F,0xA6,0x44,0xC7,0xFC,0xF1,
  823.     0x16,0x8B,0x11,0x11,0x7A,0xF0,0xB2,0x49,0x80,0x56,0xA3,0xF8,
  824.     0x0F,0x7D,0x01,0x68,0x5D,0xF6,0x8A,0xEA,0x8C,0xDD,0x01,0xDC,
  825.     0x43,0x18,0xE0,0xC4,0x89,0x80,0xE6,0x2D,0x44,0x77,0x45,0xFD,
  826.     0xBA,0xFC,0x43,0x35,0x12,0xC0,0xED,0x32,0xD3,0x16,0xEF,0x51,
  827.     0x09,0x44,0xA2,0xDB,
  828. };
  829. static unsigned char dh512_g[]={
  830.     0x05,
  831. };
  832.  
  833. static unsigned char dh768_p[]={
  834.     0x8B,0x2A,0x8C,0x6C,0x0F,0x87,0xC7,0x34,0xEE,0x2E,0xFB,0x60,
  835.     0x94,0xB3,0xBF,0x95,0xBA,0x84,0x74,0x86,0xEA,0xE0,0xA4,0x33,
  836.     0xE0,0x8F,0x7C,0x79,0x5C,0x62,0xE2,0x91,0xC5,0x6D,0x68,0xB9,
  837.     0x6C,0x5E,0x4E,0x94,0x0C,0x8E,0x56,0x8E,0xEB,0x98,0x7C,0x6E,
  838.     0x0E,0xF2,0xD5,0xAA,0x22,0x27,0x3F,0x0F,0xAF,0x10,0xB5,0x0B,
  839.     0x16,0xCC,0x05,0x27,0xBB,0x58,0x6D,0x61,0x4B,0x2B,0xAB,0xDC,
  840.     0x6A,0x15,0xBC,0x36,0x75,0x4D,0xEC,0xAB,0xFA,0xB6,0xE1,0xB1,
  841.     0x13,0x70,0xD8,0x77,0xCD,0x5E,0x51,0x77,0x81,0x0D,0x77,0x43,
  842. };
  843. static unsigned char dh768_g[]={
  844.     0x05,
  845. };
  846.  
  847. static unsigned char dh1024_p[]={
  848.     0xA4,0x75,0xCF,0x35,0x00,0xAF,0x3C,0x17,0xCE,0xB0,0xD0,0x52,
  849.     0x43,0xA0,0x0E,0xFA,0xA2,0xC9,0xBE,0x0B,0x76,0x7A,0xD9,0x2E,
  850.     0xF4,0x97,0xAC,0x02,0x24,0x69,0xF6,0x36,0x4F,0xAB,0xCC,0x43,
  851.     0xC1,0x74,0xFF,0xA3,0xD4,0x04,0x0F,0x11,0x2B,0x6D,0x8C,0x47,
  852.     0xC9,0xCF,0x40,0x93,0x9B,0x7D,0x1E,0x52,0x85,0xB2,0x17,0x55,
  853.     0x9C,0xF2,0x41,0x02,0x2A,0x9D,0x5F,0x24,0x22,0xC6,0x04,0xC4,
  854.     0xAB,0x92,0x6D,0xC7,0xC8,0xF3,0x41,0x58,0x6C,0x86,0xFD,0xB8,
  855.     0x0F,0x2D,0xDD,0xBF,0xA8,0x40,0x0C,0x58,0xC8,0xF2,0x3F,0x18,
  856.     0xEF,0xF1,0x93,0x3E,0xBA,0x16,0x41,0xBE,0x32,0x6C,0xC5,0x63,
  857.     0xFF,0x8A,0x02,0x3D,0xAC,0xD5,0x5A,0x49,0x64,0x34,0x14,0x2E,
  858.     0xFB,0x2E,0xE7,0x39,0x1A,0x0F,0x3C,0x33,
  859. };
  860. static unsigned char dh1024_g[]={
  861.     0x05,
  862. };
  863.  
  864. static unsigned char dh1536_p[]={
  865.     0xA3,0x2B,0x75,0x0E,0x7B,0x31,0x82,0xCA,0xF2,0xFC,0xF3,0x3D,
  866.     0xCE,0x5F,0xCD,0x5B,0x95,0xF6,0x2F,0xA4,0x5D,0x08,0x26,0xD2,
  867.     0x5F,0xC0,0x3F,0xC5,0xD8,0xA2,0xFE,0x83,0x26,0xBC,0xEB,0x7D,
  868.     0xF0,0x4E,0xD2,0xA6,0xBB,0x3C,0x88,0x63,0xCE,0x98,0xDE,0x08,
  869.     0xE2,0xE1,0xAF,0xE2,0x38,0xA8,0xFA,0x68,0x76,0x8D,0xBF,0xDF,
  870.     0xBB,0x30,0x15,0xFE,0xBD,0x22,0xCC,0x03,0x4E,0x5E,0x33,0xA3,
  871.     0x6D,0xD6,0x68,0x12,0x97,0x17,0x4B,0xB5,0x84,0x5F,0x5F,0xA3,
  872.     0x5C,0x2F,0xA4,0x10,0xC1,0xAD,0xBF,0xAC,0x30,0xCA,0x47,0x64,
  873.     0x63,0xFE,0xEE,0xEE,0xA1,0x64,0x73,0x70,0xAA,0xF9,0xFE,0xC6,
  874.     0xAD,0x5E,0xF6,0xF3,0x9C,0xDF,0x34,0x53,0x34,0x72,0xA6,0xA4,
  875.     0xBB,0x81,0x5A,0x43,0x41,0xFD,0x41,0x05,0x5B,0x77,0x7B,0x84,
  876.     0x03,0xFA,0x8A,0xFA,0xF7,0x8E,0x0F,0xCB,0x51,0xA2,0xB8,0x45,
  877.     0xFF,0x59,0x42,0xEF,0xCF,0xF6,0x25,0x37,0xE2,0x6D,0xFF,0x69,
  878.     0x11,0xF5,0x77,0x59,0x79,0x1C,0x5F,0x05,0xFC,0x7A,0x65,0x81,
  879.     0x03,0x4A,0x78,0xC6,0xE9,0x48,0x73,0xF6,0x10,0xBC,0x99,0x1C,
  880.     0xEE,0x44,0x2F,0x8B,0x70,0xCA,0xA8,0xB6,0x02,0x83,0x3E,0x0B,
  881. };
  882. static unsigned char dh1536_g[]={
  883.     0x05,
  884. };
  885.  
  886. static unsigned char dh2048_p[]={
  887.     0xFA,0x4E,0xE4,0x3B,0xFA,0xC1,0x87,0xDD,0xE7,0xC6,0x8B,0xE6,
  888.     0x13,0x85,0xBC,0x9B,0x2B,0x8B,0x5B,0x46,0xBB,0x8B,0x86,0x6D,
  889.     0xD7,0xB6,0xD5,0x49,0xC5,0x54,0xF2,0x3E,0xD2,0x39,0x64,0x9B,
  890.     0x0E,0x33,0x39,0x8F,0xFA,0xFA,0xD9,0x78,0xED,0x34,0x82,0x29,
  891.     0x37,0x58,0x4D,0x5D,0x40,0xCB,0x69,0xE3,0x8A,0x9F,0x17,0x0C,
  892.     0x01,0x23,0x6B,0x05,0x01,0xAF,0x33,0xDE,0xDF,0x1A,0xBB,0x7B,
  893.     0x6A,0x9F,0xD8,0xED,0x8D,0x5E,0x44,0x19,0x5B,0xE0,0xB6,0x23,
  894.     0xF9,0x7A,0x96,0x6E,0x94,0x33,0x31,0x49,0xBA,0x84,0xD5,0x12,
  895.     0xD7,0x6D,0xDC,0x35,0x54,0x64,0xA3,0xD8,0x04,0x26,0xC5,0xAF,
  896.     0x7F,0xE3,0xFE,0x6F,0xBE,0xD5,0x17,0x72,0x4B,0xA6,0xD0,0xA7,
  897.     0x5F,0x18,0xF5,0xF0,0x2D,0x11,0x9A,0xF6,0xD5,0x3B,0x6C,0x61,
  898.     0x3C,0x6F,0x8E,0x09,0x4F,0x2C,0xE1,0x26,0x06,0x51,0xB3,0x19,
  899.     0x85,0x85,0x13,0xF9,0xC2,0x6E,0x80,0x28,0x9E,0x8A,0xA0,0x01,
  900.     0x46,0xD1,0x85,0x44,0x8C,0xE6,0xEE,0x7E,0x1E,0x17,0x3D,0xBA,
  901.     0x54,0xFF,0xE8,0x0E,0xDD,0x51,0xF3,0x74,0x7F,0x0D,0x0B,0xAB,
  902.     0xCA,0x84,0x8D,0x24,0x5D,0x56,0xD4,0x47,0x02,0xFC,0x93,0x9F,
  903.     0xAE,0x9B,0x5C,0xDB,0x63,0xEB,0x65,0x01,0x38,0xC2,0x7B,0x30,
  904.     0x1E,0x17,0x1C,0x75,0xF5,0x16,0x3B,0x4F,0x5F,0x41,0x32,0xB5,
  905.     0xFF,0x9E,0x61,0xFD,0xD2,0x62,0x6E,0xFD,0x8A,0x28,0x93,0x59,
  906.     0x2D,0x70,0x14,0x4D,0xE1,0x86,0xD5,0x90,0xB4,0xDF,0x72,0x71,
  907.     0xE0,0xB4,0xD0,0xD6,0x82,0x3A,0x4A,0x04,0x58,0x32,0x0B,0xD3,
  908.     0x51,0x13,0x32,0x63,
  909. };
  910. static unsigned char dh2048_g[]={
  911.     0x02,
  912. };
  913.  
  914. static DH *
  915. get_dh512()
  916. {
  917.     DH *dh=NULL;
  918.  
  919.     if ((dh=DH_new()) == NULL)
  920.         return(NULL);
  921.     dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL);
  922.     dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL);
  923.     if ((dh->p == NULL) || (dh->g == NULL))
  924.         return(NULL);
  925.     return(dh);
  926. }
  927.  
  928. static DH *
  929. get_dh768()
  930. {
  931.     DH *dh=NULL;
  932.  
  933.     if ((dh=DH_new()) == NULL)
  934.         return(NULL);
  935.     dh->p=BN_bin2bn(dh768_p,sizeof(dh768_p),NULL);
  936.     dh->g=BN_bin2bn(dh768_g,sizeof(dh768_g),NULL);
  937.     if ((dh->p == NULL) || (dh->g == NULL))
  938.         return(NULL);
  939.     return(dh);
  940. }
  941.  
  942. static DH *
  943. get_dh1024()
  944. {
  945.     DH *dh=NULL;
  946.  
  947.     if ((dh=DH_new()) == NULL)
  948.         return(NULL);
  949.     dh->p=BN_bin2bn(dh1024_p,sizeof(dh1024_p),NULL);
  950.     dh->g=BN_bin2bn(dh1024_g,sizeof(dh1024_g),NULL);
  951.     if ((dh->p == NULL) || (dh->g == NULL))
  952.         return(NULL);
  953.     return(dh);
  954. }
  955.  
  956. static DH *
  957. get_dh1536()
  958. {
  959.     DH *dh=NULL;
  960.  
  961.     if ((dh=DH_new()) == NULL)
  962.         return(NULL);
  963.     dh->p=BN_bin2bn(dh1536_p,sizeof(dh1536_p),NULL);
  964.     dh->g=BN_bin2bn(dh1536_g,sizeof(dh1536_g),NULL);
  965.     if ((dh->p == NULL) || (dh->g == NULL))
  966.         return(NULL);
  967.     return(dh);
  968. }
  969.  
  970. static DH *
  971. get_dh2048()
  972. {
  973.     DH *dh=NULL;
  974.  
  975.     if ((dh=DH_new()) == NULL)
  976.         return(NULL);
  977.     dh->p=BN_bin2bn(dh2048_p,sizeof(dh2048_p),NULL);
  978.     dh->g=BN_bin2bn(dh2048_g,sizeof(dh2048_g),NULL);
  979.     if ((dh->p == NULL) || (dh->g == NULL))
  980.         return(NULL);
  981.     return(dh);
  982. }
  983. #endif /* NO_DH */
  984.  
  985. static DH MS_CALLBACK *
  986. #ifdef CK_ANSIC
  987. tmp_dh_cb(SSL * s, int export, int keylength)
  988. #else /* CK_ANSIC */
  989. tmp_dh_cb(s,export,keylength)
  990. SSL *s;
  991. int export;
  992. int keylength;
  993. #endif /* CK_ANSIC */
  994. {
  995.     static DH *dh_tmp=NULL;
  996.     BIO *bio=NULL;
  997.     extern int quiet;
  998.  
  999. #ifndef NO_DH
  1000.     if (dh_tmp == NULL)
  1001.     {
  1002.         if (ssl_dh_param_file  &&
  1003.              (bio=BIO_new_file(ssl_dh_param_file,"r")) != NULL)
  1004.             dh_tmp=PEM_read_bio_DHparams(bio,NULL,NULL,NULL);
  1005.         if (bio != NULL)
  1006.             BIO_free(bio);
  1007.  
  1008.         if ( dh_tmp == NULL ) {
  1009.             if ( keylength < 768 )
  1010.                 dh_tmp = get_dh512();
  1011.             else if ( keylength < 1024 )
  1012.                 dh_tmp = get_dh768();
  1013.             else if ( keylength < 1536 )
  1014.                 dh_tmp = get_dh1024();
  1015.             else if ( keylength < 2048 )
  1016.                 dh_tmp = get_dh1536();
  1017.             else
  1018.                 dh_tmp = get_dh2048();
  1019.         }
  1020.     }
  1021. #else /* NO_DH */
  1022.     if (ssl_debug_flag)
  1023.         printf("DH not supported...\r\n");
  1024. #endif /* NO_DH */
  1025.     return(dh_tmp);
  1026. }
  1027.  
  1028. static void
  1029. ssl_display_comp(SSL * ssl)
  1030. {
  1031.     if ( !ck_ssleay_is_installed() )
  1032.         return;
  1033.  
  1034.     if (ssl == NULL)
  1035.         return;
  1036.  
  1037.     if (ssl->expand == NULL || ssl->expand->meth == NULL)
  1038.         printf("Compression: None\r\n");
  1039.     else {
  1040.         printf("Compression: %s\r\n",ssl->expand->meth->name);
  1041.     }
  1042. }
  1043.  
  1044. int
  1045. #ifdef CK_ANSIC
  1046. ssl_display_connect_details(SSL * ssl_con, int server, int verbose)
  1047. #else /* CK_ANSIC */
  1048. ssl_display_connect_details(ssl_con,server,verbose)
  1049. SSL *ssl_con;
  1050. int server;
  1051. int verbose;
  1052. #endif /* CK_ANSIC */
  1053. {
  1054.     X509 *peer;
  1055.     SSL_CIPHER * cipher;
  1056.     const char *cipher_list;
  1057.     char buf[512]="";
  1058.  
  1059.     if ( !ck_ssleay_is_installed() )
  1060.         return(0);
  1061.  
  1062.     if ( inserver && !tn_deb )
  1063.         return(0);
  1064.  
  1065.     /* the cipher list *can* be NULL ... useless but it happens! */
  1066.     cipher = SSL_get_current_cipher(ssl_con);
  1067.     cipher_list = SSL_CIPHER_get_name(cipher);
  1068.     SSL_CIPHER_description(cipher,buf,sizeof(buf));
  1069.     if (cipher_list==NULL)
  1070.         cipher_list="<NULL>";
  1071.     printf("[TLS - %s",buf);
  1072.     ssl_display_comp(ssl_con);
  1073.  
  1074.     if ( server ) {
  1075.         cipher_list=SSL_get_shared_ciphers(ssl_con,buf,512);
  1076.         if (cipher_list==NULL)
  1077.             cipher_list="<NULL>";
  1078.         printf("[TLS - shared ciphers=%s]\r\n",
  1079.                 cipher_list);
  1080.         }       
  1081.     if ( server || tn_deb ) {
  1082.         peer=SSL_get_peer_certificate(ssl_con);
  1083.         if (peer != NULL) {
  1084.             X509_NAME_oneline(X509_get_subject_name(peer),buf,512);
  1085.             printf("[TLS - subject=%s]\r\n",buf);
  1086.             X509_NAME_oneline(X509_get_issuer_name(peer),buf,512);
  1087.             printf("[TLS - issuer=%s]\r\n",buf);
  1088.             /* X509_free(peer); */
  1089.         } else if (!tls_is_krb5(0)) {
  1090.             if ( !sstelnet && !tcp_incoming ) {
  1091.                 printf("[TLS - No certificate provided.]\r\n");
  1092.                 printf(
  1093.      "[TLS - The identity of the host could not be verified.]\r\n");
  1094.             }
  1095.         }
  1096.     }
  1097.     return(0);
  1098. }
  1099.  
  1100. /*
  1101.  * Use SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *, void * userdata)
  1102.  * to set the value of the userdata.  We are going to use it to store the
  1103.  * prompt.
  1104.  */
  1105.  
  1106. int
  1107. #ifdef CK_ANSIC
  1108. ssl_passwd_callback(char *buf, int len, int rwflag, VOID * userdata)
  1109. #else /* CK_ANSIC */
  1110. ssl_passwd_callback(buf,len,rwflag,userdata)
  1111.     char * buf; int len; int rwflag; VOID *userdata;
  1112. #endif /* CK_ANSIC */
  1113. {
  1114.     extern char pwbuf[];
  1115.     extern int  pwflg, pwcrypt;
  1116.     int   ok;
  1117.     char *prompt=NULL;
  1118.  
  1119.     if ( pwbuf[0] && pwflg ) {
  1120.         int n;
  1121.         n = ckstrncpy(buf,pwbuf,len);
  1122. #ifdef OS2
  1123.         if ( pwcrypt )
  1124.             ck_encrypt((char *)buf);
  1125. #endif /* OS2 */
  1126.         return(n);
  1127.     }
  1128.  
  1129.     if ( userdata == NULL )
  1130.         prompt="Enter certificate passphrase: ";
  1131.     else
  1132.         prompt=(char*)userdata;
  1133.     ok = uq_txt(NULL,prompt,2,NULL,buf,len,NULL,DEFAULT_UQ_TIMEOUT);
  1134.     return(ok > 0 ? strlen(buf) : 0);
  1135. }
  1136.  
  1137.  
  1138. /* Attempts to load certificate data into the TLS context structures */
  1139. /* Returns 1 on success; 0 on failure */
  1140. int
  1141. tls_load_certs(SSL_CTX * ctx, SSL * con, int server)
  1142. {
  1143.     int rc = 1;
  1144.     extern int quiet;
  1145.  
  1146.     if ( !ck_ssleay_is_installed() )
  1147.         return(0);
  1148.  
  1149.     debug(F111,"tls_load_certs","SSL_CTX",ctx);
  1150.     debug(F111,"tls_load_certs","SSL",con);
  1151.     debug(F111,"tls_load_certs","server",server);
  1152.  
  1153.     if ( con ) {
  1154.         if (ssl_rsa_cert_file) {
  1155.             if ( ssl_debug_flag )
  1156.                 printf("Loading RSA certificate into SSL\r\n");
  1157.  
  1158.             rc = SSL_use_certificate_file(con, ssl_rsa_cert_file,
  1159.                                                X509_FILETYPE_PEM);
  1160.             if (!rc)
  1161.             {
  1162.                 if ( !quiet || ssl_debug_flag )
  1163.                     printf("Error loading certificate from %s\r\n",
  1164.                             ssl_rsa_cert_file);
  1165.             } else {
  1166.                 if (!ssl_rsa_key_file || !ssl_rsa_key_file[0])
  1167.                     makestr(&ssl_rsa_key_file,ssl_rsa_cert_file);
  1168.  
  1169.                 rc = SSL_use_PrivateKey_file(con, ssl_rsa_key_file,
  1170.                                                   X509_FILETYPE_PEM);
  1171.                 if (!rc)
  1172.                     rc = SSL_use_PrivateKey_file(con, ssl_rsa_cert_file,
  1173.                                                       X509_FILETYPE_PEM);
  1174.                 if (!rc)
  1175.                 {
  1176.                     if ( !quiet || ssl_debug_flag )
  1177.                         printf("Error loading key from %s\r\n",
  1178.                                 ssl_rsa_key_file);
  1179.                 } else {
  1180.                     rc = SSL_check_private_key(con);
  1181.                     if (!rc)
  1182.                     {
  1183.                         if ( ssl_debug_flag )
  1184.                             printf(
  1185.                 "Private key does not match the certificate public key\r\n");
  1186.                     }
  1187.                 }
  1188.             }
  1189.         }
  1190.  
  1191.         if (ssl_dsa_cert_file) {
  1192.             if ( ssl_debug_flag )
  1193.                 printf("Loading DSA certificate into SSL\r\n");
  1194.  
  1195.             rc = SSL_use_certificate_file(con, ssl_dsa_cert_file,
  1196.                                                X509_FILETYPE_PEM);
  1197.             if (!rc)
  1198.             {
  1199.                 if ( ssl_debug_flag ) {
  1200.                     printf("Error loading certificate from %s\r\n",
  1201.                             ssl_dsa_cert_file);
  1202.                 }
  1203.             } else {
  1204.                 if (!ssl_dh_key_file || !ssl_dh_key_file[0])
  1205.                     makestr(&ssl_dh_key_file,ssl_dsa_cert_file);
  1206.                 rc = SSL_use_PrivateKey_file(con, ssl_dh_key_file,
  1207.                                                   X509_FILETYPE_PEM);
  1208.                 if (!rc)
  1209.                     rc = SSL_use_PrivateKey_file(con, ssl_dsa_cert_file,
  1210.                                                       X509_FILETYPE_PEM);
  1211.                 if (!rc)
  1212.                 {
  1213.                     if ( !quiet || ssl_debug_flag ) {
  1214.                         printf("Error loading key from %s\r\n",
  1215.                                 ssl_dh_key_file);
  1216.                     }
  1217.                 } else {
  1218.                     rc = SSL_check_private_key(con);
  1219.                     if (!rc)
  1220.                     {
  1221.                         if ( ssl_debug_flag )
  1222.                             printf(
  1223.                    "Private key does not match the certificate public key\n");
  1224.                     }
  1225.                 }
  1226.             }
  1227.         }
  1228.     } else {
  1229.         if (ssl_rsa_cert_file) {
  1230.             if ( ssl_debug_flag )
  1231.                 printf("Loading RSA certificate into SSL\r\n");
  1232.  
  1233.             rc = SSL_CTX_use_certificate_file(ctx, ssl_rsa_cert_file,
  1234.                                        X509_FILETYPE_PEM);
  1235.             if (!rc)
  1236.             {
  1237.                 if ( !quiet || ssl_debug_flag )
  1238.                     printf("Error loading certificate from %s\r\n",
  1239.                             ssl_rsa_cert_file);
  1240.             } else {
  1241.                 if (!ssl_rsa_key_file || !ssl_rsa_key_file[0])
  1242.                     makestr(&ssl_rsa_key_file,ssl_rsa_cert_file);
  1243.  
  1244.                 rc = SSL_CTX_use_PrivateKey_file(ctx, ssl_rsa_key_file,
  1245.                                                   X509_FILETYPE_PEM);
  1246.                 if (!rc)
  1247.                   rc = SSL_CTX_use_PrivateKey_file(ctx, ssl_rsa_cert_file,
  1248.                                                    X509_FILETYPE_PEM);
  1249.                 if (!rc) {
  1250.                     if ( ssl_debug_flag )
  1251.                       printf("Error loading key from %s\r\n",ssl_rsa_key_file);
  1252.                 } else {
  1253.                     rc = SSL_CTX_check_private_key(ctx);
  1254.                     if (!rc) {
  1255.                         if ( ssl_debug_flag )
  1256.                           printf(
  1257.                 "Private key does not match the certificate public key\r\n");
  1258.                     }
  1259.                 }
  1260.             }
  1261.         }
  1262.         if (ssl_dsa_cert_file) {
  1263.             if ( ssl_debug_flag )
  1264.               printf("Loading DSA certificate into SSL\r\n");
  1265.  
  1266.             rc = SSL_CTX_use_certificate_file(ctx, ssl_dsa_cert_file,
  1267.                                               X509_FILETYPE_PEM);
  1268.             if (!rc) {
  1269.                 if ( ssl_debug_flag ) {
  1270.                     printf("Error loading certificate from %s\r\n",
  1271.                            ssl_dsa_cert_file);
  1272.                 }
  1273.             } else {
  1274.                 if (!ssl_dh_key_file || !ssl_dh_key_file[0])
  1275.                     makestr(&ssl_dh_key_file,ssl_dsa_cert_file);
  1276.                 rc = SSL_CTX_use_PrivateKey_file(ctx, ssl_dh_key_file,
  1277.                                                   X509_FILETYPE_PEM);
  1278.                 if (!rc)
  1279.                   rc = SSL_CTX_use_PrivateKey_file(ctx, ssl_dsa_cert_file,
  1280.                                                       X509_FILETYPE_PEM);
  1281.                 if (!rc) {
  1282.                     if ( ssl_debug_flag )
  1283.                       printf("Error loading key from %s\r\n",ssl_dh_key_file);
  1284.                 } else {
  1285.                     rc = SSL_CTX_check_private_key(ctx);
  1286.                     if (!rc) {
  1287.                         if ( ssl_debug_flag )
  1288.                           printf(
  1289.                    "Private key does not match the certificate public key\n");
  1290.                     }
  1291.                 }
  1292.             }
  1293.         }
  1294.     }
  1295.  
  1296.     if (ssl_rsa_cert_chain_file && server) {
  1297.         int skip1st = 0;
  1298.         if (ssl_debug_flag)
  1299.             printf("Loading RSA Certificate Chain into SSL\r\n");
  1300.         if (!ckstrcmp(ssl_rsa_cert_chain_file,ssl_rsa_cert_file,-1,
  1301. #ifdef OS2
  1302.                        0
  1303. #else
  1304.                        1
  1305. #endif /* OS2 */
  1306.                        ))
  1307.             skip1st = 1;
  1308.         rc = SSL_CTX_use_certificate_chain_file(ctx,ssl_rsa_cert_chain_file);
  1309.         if (!rc && ssl_debug_flag)
  1310.                 printf("Error loading RSA Certificate Chain into SSL\r\n");
  1311.     }
  1312.     if (ssl_dsa_cert_chain_file && server) {
  1313.         int skip1st = 0;
  1314.         if (ssl_debug_flag)
  1315.             printf("Loading DSA Certificate Chain into SSL\r\n");
  1316.         if (!ckstrcmp(ssl_dsa_cert_chain_file,ssl_dsa_cert_file,-1,
  1317. #ifdef OS2
  1318.                        0
  1319. #else
  1320.                        1
  1321. #endif /* OS2 */
  1322.                        ))
  1323.             skip1st = 1;
  1324.         rc = SSL_CTX_use_certificate_chain_file(ctx,ssl_dsa_cert_chain_file);
  1325.         if (!rc && ssl_debug_flag)
  1326.                 printf("Error loading DSA Certificate Chain into SSL\r\n");
  1327.     }
  1328.     return(rc);
  1329. }
  1330.  
  1331. VOID
  1332. #ifdef CK_ANSIC
  1333. ssl_once_init(void)
  1334. #else
  1335. ssl_once_init()
  1336. #endif /* CK_ANSIC */
  1337. {
  1338.     COMP_METHOD * cm;
  1339.  
  1340.     if ( !ck_ssleay_is_installed() )
  1341.         return;
  1342.  
  1343.     debug(F111,"Kermit built for OpenSSL",OPENSSL_VERSION_TEXT,SSLEAY_VERSION_NUMBER);
  1344. #ifndef OS2ONLY
  1345.     debug(F111,"OpenSSL Library",SSLeay_version(SSLEAY_VERSION),
  1346.            SSLeay());
  1347.     debug(F110,"OpenSSL Library",SSLeay_version(SSLEAY_BUILT_ON),0);
  1348.     debug(F110,"OpenSSL Library",SSLeay_version(SSLEAY_CFLAGS),0);
  1349.     debug(F110,"OpenSSL Library",SSLeay_version(SSLEAY_PLATFORM),0);
  1350.  
  1351.     /* The following test is suggested by Richard Levitte */
  1352.     if (((OPENSSL_VERSION_NUMBER ^ SSLeay()) & 0xffffff0f) 
  1353. #ifdef OS2
  1354.          || ckstrcmp(OPENSSL_VERSION_TEXT,(char *)SSLeay_version(SSLEAY_VERSION),-1,1)
  1355. #endif /* OS2 */
  1356.          ) {
  1357.         ssl_installed = 0;
  1358.         debug(F111,"OpenSSL Version does not match.  Built with",
  1359.                SSLeay_version(SSLEAY_VERSION),SSLEAY_VERSION_NUMBER);
  1360.         printf("?OpenSSL libraries do not match required version.");
  1361.         printf("  SSL\\TLS support disabled\r\n\r\n");
  1362.         bleep(BP_FAIL);
  1363. #ifdef SSLDLL
  1364.         ck_ssl_unloaddll();
  1365.         ck_crypto_unloaddll();
  1366. #endif /* SSLDLL */
  1367.         return;
  1368.     }
  1369. #endif /* OS2ONLY */
  1370.  
  1371.     /* init things so we will get meaningful error messages
  1372.     * rather than numbers
  1373.     */
  1374.     SSL_load_error_strings();
  1375.  
  1376. #ifdef SSHBUILTIN
  1377.     OPENSSL_add_all_algorithms_noconf();
  1378. #else
  1379.     /* SSL_library_init() only loads those ciphers needs for SSL  */
  1380.     /* These happen to be a similar set to those required for SSH */
  1381.     /* but they are not a complete set of ciphers provided by the */
  1382.     /* crypto library.                                            */
  1383.     SSL_library_init();
  1384. #endif /* SSHBUILTIN */
  1385.  
  1386. #ifdef ZLIB
  1387.     cm = COMP_zlib();
  1388.     if (cm != NULL && cm->type != NID_undef) {
  1389.         SSL_COMP_add_compression_method(0xe0, cm); /* EAY's ZLIB ID */
  1390.     }
  1391. #endif /* ZLIB */
  1392.     cm = COMP_rle();
  1393.     if (cm != NULL && cm->type != NID_undef)
  1394.         SSL_COMP_add_compression_method(0xe1, cm); /* EAY's RLE ID */
  1395.  
  1396.     /* Ensure the Random number generator has enough entropy */
  1397.     if ( !RAND_status() ) {
  1398.         char buffer[256]="";
  1399.         char randombytes[256];
  1400.         int rc1 = -1, rc2 = 1;  /* assume failure and success */
  1401.  
  1402.         debug(F110,"ssl_once_init","!RAND_status()",0);
  1403.  
  1404.         if ( ssl_rnd_file == NULL ) {
  1405.             debug(F110,"ssl_rnd_file","ssl_rnd_file is NULL",0);
  1406.             RAND_file_name(buffer,256);
  1407.             if ( buffer[0] )
  1408.                 makestr(&ssl_rnd_file, buffer);
  1409.             else
  1410.                 makestr(&ssl_rnd_file,".rnd");
  1411.         }
  1412.         debug(F110,"ssl_rnd_file",ssl_rnd_file,0);
  1413.  
  1414.         rc1 = RAND_egd(ssl_rnd_file);
  1415.         debug(F111,"ssl_once_init","RAND_egd()",rc1);
  1416.         if ( rc1 <= 0 ) {
  1417.             rc2 = RAND_load_file(ssl_rnd_file, -1);
  1418.             debug(F111,"ssl_once_init","RAND_load_file()",rc1);
  1419.         }
  1420.  
  1421.         if ( rc1 <= 0 && !rc2 )
  1422.         {
  1423.             time_t t = time(NULL);
  1424.             int tlen = sizeof(time_t);
  1425.             int pid = getpid();
  1426.             int plen = sizeof(int);
  1427.             int n;
  1428. #ifndef RAND_MAX
  1429. #define RAND_MAX 0x7FFF
  1430. #endif
  1431.             debug(F110,"ssl_once_init","calling RAND_seed()",0);
  1432.  
  1433.             RAND_seed((unsigned char *)&t, tlen);
  1434.             RAND_seed((unsigned char *)&pid, plen);
  1435.  
  1436.             srand((unsigned int)t);
  1437.             sprintf(buffer, "%.0f", (((double)(rand()%RAND_MAX)/RAND_MAX)*
  1438.                                       (sizeof(randombytes)-128-1)));
  1439.             n = (atoi(buffer)+1)%(sizeof(randombytes)-128-1);
  1440.             RAND_seed(randombytes, 128);
  1441.         }
  1442.  
  1443.         if ( !RAND_status() ) {
  1444.             debug(F110,"ssl_once_init","Unable to initialize PRNG",0);
  1445.             printf(" Unable to load 'random state'\n");
  1446.             printf(" SSL and TLS are unavailble.\n");
  1447.             printf(" Use SET AUTH SSL RANDOM-FILE <file> command to provide random data.\n");
  1448.             printf(" Specified file will be overwritten with new random data after use.\n");
  1449.             return;
  1450.         }
  1451.  
  1452.         if ( ssl_rnd_file ) {
  1453.             int rc = RAND_write_file(ssl_rnd_file);
  1454.             debug(F111,"ssl_once_init","RAND_write_file()",rc);
  1455.         }
  1456.     }
  1457.  
  1458. #ifdef NT
  1459.     // Initialize additional OID types for use when saving certs to a file
  1460.     OBJ_create("2.99999.3","SET.ex3","SET x509v3 extension 3");
  1461. #endif /* NT */
  1462.  
  1463.     /* make sure we have somewhere we can log errors to */
  1464.     bio_err=BIO_new(BIO_s_mem());
  1465.  
  1466.     debug(F100,"ssl_once_init() complete","",0);
  1467. }
  1468.  
  1469. int
  1470. #ifdef CK_ANSIC
  1471. ssl_tn_init(int mode)
  1472. #else
  1473. ssl_tn_init(mode) int mode;
  1474. #endif /* CK_ANSIC */
  1475. {
  1476. #ifdef KRB5
  1477.     extern char * k5_keytab;
  1478.     extern char * krb5_d_srv;
  1479. #endif /* KRB5 */
  1480.     static int last_ssl_mode = -1;
  1481.     SSL * ssl_conx=NULL, * tls_conx=NULL;
  1482.  
  1483.     ssl_initialized = 0;
  1484.  
  1485.     if ( !ck_ssleay_is_installed() )
  1486.         return(0);
  1487.  
  1488.     debug(F111,"ssl_tn_init","mode",mode);
  1489.  
  1490.     if (ssl_debug_flag)
  1491.         printf("SSL_DEBUG_FLAG on\r\n");
  1492.  
  1493.     if (last_ssl_mode != mode) {
  1494.         if (ssl_ctx) {
  1495.             SSL_CTX_free(ssl_ctx);
  1496.             ssl_ctx = NULL;
  1497.         }
  1498.         if (tls_ctx) {
  1499.             SSL_CTX_free(tls_ctx);
  1500.             tls_ctx = NULL;
  1501.         }
  1502.     }
  1503.  
  1504.     if ( (last_ssl_mode != mode) || !ssl_ctx || !tls_ctx ) {
  1505.         if ( mode == SSL_CLIENT ) {
  1506.             ssl_ctx=(SSL_CTX *)SSL_CTX_new(SSLv23_client_method());
  1507.             /* This can fail because we do not have RSA available */
  1508.             if ( !ssl_ctx ) {
  1509.                 debug(F110,"ssl_tn_init","SSLv23_client_method failed",0);
  1510.                 ssl_ctx=(SSL_CTX *)SSL_CTX_new(SSLv3_client_method());
  1511.             }
  1512.             if ( !ssl_ctx ) {
  1513.                 debug(F110,"ssl_tn_init","SSLv3_client_method failed",0);
  1514.                 last_ssl_mode = -1;
  1515.                 return(0);
  1516.             }
  1517. #ifndef COMMENT
  1518.             tls_ctx=(SSL_CTX *)SSL_CTX_new(TLSv1_client_method());
  1519. #else /* COMMENT */
  1520.             tls_ctx=(SSL_CTX *)SSL_CTX_new(SSLv23_client_method());
  1521.             /* This can fail because we do not have RSA available */
  1522.             if ( !tls_ctx ) {
  1523.                 debug(F110,"ssl_tn_init","SSLv23_client_method failed",0);
  1524.                 tls_ctx=(SSL_CTX *)SSL_CTX_new(SSLv3_client_method());
  1525.             }
  1526. #endif /* COMMENT */
  1527.             if ( !tls_ctx ) {
  1528.                 debug(F110,"ssl_tn_init","TLSv1_client_method failed",0);
  1529.                 last_ssl_mode = -1;
  1530.                 return(0);
  1531.             }
  1532. #ifdef USE_CERT_CB
  1533.             SSL_CTX_set_client_cert_cb(ssl_ctx,ssl_client_cert_callback);
  1534.             SSL_CTX_set_client_cert_cb(tls_ctx,ssl_client_cert_callback);
  1535. #endif /* USE_CERT_CB */
  1536.         } else if (mode == SSL_SERVER) {
  1537.             /* We are a server */
  1538.             ssl_ctx=(SSL_CTX *)SSL_CTX_new(SSLv23_server_method());
  1539.             /* This can fail because we do not have RSA available */
  1540.             if ( !ssl_ctx ) {
  1541.                 debug(F110,"ssl_tn_init","SSLv23_server_method failed",0);
  1542.                 ssl_ctx=(SSL_CTX *)SSL_CTX_new(SSLv3_server_method());
  1543.             }
  1544.             if ( !ssl_ctx ) {
  1545.                 debug(F110,"ssl_tn_init","SSLv3_server_method failed",0);
  1546.                 last_ssl_mode = -1;
  1547.                 return(0);
  1548.             }
  1549. #ifdef COMMENT
  1550.             tls_ctx=(SSL_CTX *)SSL_CTX_new(TLSv1_server_method());
  1551. #else /* COMMENT */
  1552.             tls_ctx=(SSL_CTX *)SSL_CTX_new(SSLv23_server_method());
  1553.             /* This can fail because we do not have RSA available */
  1554.             if ( !tls_ctx ) {
  1555.                 debug(F110,"ssl_tn_init","SSLv23_server_method failed",0);
  1556.                 tls_ctx=(SSL_CTX *)SSL_CTX_new(TLSv1_server_method());
  1557.             }
  1558. #endif /* COMMENT */
  1559.             if ( !tls_ctx ) {
  1560.                 debug(F110,"ssl_tn_init","TLSv1_server_method failed",0);
  1561.                 last_ssl_mode = -1;
  1562.                 return(0);
  1563.             }
  1564.         } else /* Unknown mode */
  1565.             return(0);
  1566.  
  1567.         if ( !inserver ) {
  1568.             SSL_CTX_set_default_passwd_cb(ssl_ctx,
  1569.                                    (pem_password_cb *)ssl_passwd_callback);
  1570.             SSL_CTX_set_default_passwd_cb(tls_ctx,
  1571.                                    (pem_password_cb *)ssl_passwd_callback);
  1572.         }
  1573.  
  1574.         /* for SSL switch on all the interoperability and bug
  1575.          * workarounds so that we will communicate with people
  1576.          * that cannot read poorly written specs :-)
  1577.          * for TLS be sure to prevent use of SSLv2
  1578.          */
  1579.         SSL_CTX_set_options(ssl_ctx,SSL_OP_ALL|SSL_OP_NO_SSLv2);
  1580.         SSL_CTX_set_options(tls_ctx,
  1581.                  SSL_OP_NO_SSLv2|SSL_OP_SINGLE_DH_USE|SSL_OP_EPHEMERAL_RSA);
  1582.  
  1583.         SSL_CTX_set_info_callback(ssl_ctx,ssl_client_info_callback);
  1584.         SSL_CTX_set_info_callback(tls_ctx,ssl_client_info_callback);
  1585.  
  1586. #ifndef COMMENT
  1587.         /* Set the proper caching mode */
  1588.         if ( mode == SSL_SERVER ) {
  1589.             SSL_CTX_set_session_cache_mode(ssl_ctx,SSL_SESS_CACHE_SERVER);
  1590.             SSL_CTX_set_session_cache_mode(tls_ctx,SSL_SESS_CACHE_SERVER);
  1591.         } else {
  1592.             SSL_CTX_set_session_cache_mode(ssl_ctx,SSL_SESS_CACHE_CLIENT);
  1593.             SSL_CTX_set_session_cache_mode(tls_ctx,SSL_SESS_CACHE_CLIENT);
  1594.         }
  1595.         SSL_CTX_set_session_id_context(ssl_ctx,(CHAR *)"1",1);
  1596.         SSL_CTX_set_session_id_context(tls_ctx,(CHAR *)"2",1);
  1597. #else /* COMMENT */
  1598.         SSL_CTX_set_session_cache_mode(ssl_ctx,SSL_SESS_CACHE_OFF);
  1599.         SSL_CTX_set_session_cache_mode(tls_ctx,SSL_SESS_CACHE_OFF);
  1600. #endif /* COMMENT */
  1601.     }
  1602.  
  1603.     /* The server uses defaults for the certificate files. */
  1604.     /* The client does not.                                */
  1605.     if (mode == SSL_SERVER) {
  1606.         char cert_filepath[1024];
  1607.         const char * defdir = NULL;
  1608.         DH * dh = NULL;
  1609.  
  1610.         defdir = getenv("SSL_CERT_DIR");
  1611.         if ( !defdir ) {
  1612. #ifdef OS2
  1613.             defdir = exedir;
  1614. #else /* OS2 */
  1615.             defdir = X509_get_default_cert_dir();
  1616. #endif /* OS2 */
  1617.             debug(F110,"ssl_tn_init - setting default directory to",defdir,0);
  1618.         }
  1619.         if ( !defdir )
  1620.             defdir = "";
  1621.  
  1622.         if (!ssl_rsa_cert_file) {
  1623.             /* we need to know the fullpath to the location of the
  1624.             * certificate that we will be running with as we cannot
  1625.             * be sure of the cwd when we are launched
  1626.             */
  1627.             sprintf(cert_filepath,"%s/%s",defdir,"telnetd-rsa.pem");
  1628.             if (zchki(cert_filepath) > 0)
  1629.                 makestr(&ssl_rsa_cert_file,cert_filepath);
  1630.         }
  1631.         if (ssl_rsa_cert_file && !ssl_rsa_key_file) {
  1632.             /* we need to know the fullpath to the location of the
  1633.             * certificate that we will be running with as we cannot
  1634.             * be sure of the cwd when we are launched
  1635.             */
  1636.             sprintf(cert_filepath,"%s/%s",defdir,"telnetd-rsa-key.pem");
  1637.             if (zchki(cert_filepath) > 0)
  1638.                 makestr(&ssl_rsa_key_file,cert_filepath);
  1639.         }
  1640.         if (!ssl_dsa_cert_file) {
  1641.             /* we need to know the fullpath to the location of the
  1642.             * certificate that we will be running with as we cannot
  1643.             * be sure of the cwd when we are launched
  1644.             */
  1645.             sprintf(cert_filepath,"%s/%s",defdir,"telnetd-dsa.pem");
  1646.             if (zchki(cert_filepath) > 0)
  1647.                 makestr(&ssl_dsa_cert_file,cert_filepath);
  1648.         }
  1649.         if (ssl_dsa_cert_file && !ssl_dh_key_file) {
  1650.             /* we need to know the fullpath to the location of the
  1651.             * certificate that we will be running with as we cannot
  1652.             * be sure of the cwd when we are launched
  1653.             */
  1654.             sprintf(cert_filepath,"%s/%s",defdir,"telnetd-dsa-key.pem");
  1655.             if (zchki(cert_filepath) > 0)
  1656.                 makestr(&ssl_dh_key_file,cert_filepath);
  1657.         }
  1658.         if (!ssl_crl_dir) {
  1659.             /* we need to know the fullpath to the location of the
  1660.             * certificate that we will be running with as we cannot
  1661.             * be sure of the cwd when we are launched
  1662.             */
  1663.             sprintf(cert_filepath,"%s/crl",defdir);
  1664.             if (zchki(cert_filepath) > 0)
  1665.                 makestr(&ssl_crl_dir,cert_filepath);
  1666.         }
  1667.  
  1668.         if (ssl_only_flag && !tls_load_certs(ssl_ctx,ssl_con,1)) {
  1669.             debug(F110,"ssl_tn_init","Unable to load SSL certs",0);
  1670.             last_ssl_mode = -1;
  1671.             return(0);
  1672.         }
  1673.         if (tls_only_flag && !tls_load_certs(tls_ctx,tls_con,1)) {
  1674.             debug(F110,"ssl_tn_init","Unable to load TLS certs",0);
  1675.             last_ssl_mode = -1;
  1676.             return(0);
  1677.         }
  1678.  
  1679.         if ( (last_ssl_mode != mode) || !ssl_ctx || !tls_ctx ) {
  1680.             /* we may require a temp 512 bit RSA key because of the
  1681.              * wonderful way export things work ... if so we generate
  1682.              * one now!
  1683.              */
  1684.  
  1685.             SSL_CTX_set_tmp_rsa_callback(ssl_ctx, tmp_rsa_cb);
  1686.             SSL_CTX_set_tmp_dh_callback( ssl_ctx, tmp_dh_cb);
  1687.             SSL_CTX_set_tmp_rsa_callback(tls_ctx, tmp_rsa_cb);
  1688.             SSL_CTX_set_tmp_dh_callback( tls_ctx, tmp_dh_cb);
  1689.  
  1690.             dh = tmp_dh_cb(NULL,0,512);
  1691.             SSL_CTX_set_tmp_dh(ssl_ctx,dh);
  1692.             SSL_CTX_set_tmp_dh(tls_ctx,dh);
  1693.  
  1694.             /* The following code is only called if we are using a
  1695.              * certificate with an RSA public key and where the
  1696.              * certificate has a key length less than 512 bits or is
  1697.              * marked for signing only.  This is so we can support
  1698.              * the greatest legal privacy level with exportable clients.
  1699.              */
  1700.  
  1701.             if (SSL_CTX_need_tmp_RSA(ssl_ctx) ||
  1702.                  SSL_CTX_need_tmp_RSA(tls_ctx))
  1703.             {
  1704.                 RSA *rsa;
  1705.  
  1706.                 if ( ssl_debug_flag )
  1707.                     printf("Generating temp (512 bit) RSA key ...\r\n");
  1708.                 rsa=RSA_generate_key(512,RSA_F4,NULL,NULL);
  1709.                 if ( ssl_debug_flag )
  1710.                     printf("Generation of temp (512 bit) RSA key done\r\n");
  1711.  
  1712.                 if (SSL_CTX_need_tmp_RSA(ssl_ctx)) {
  1713.                     if (!SSL_CTX_set_tmp_rsa(ssl_ctx,rsa)) {
  1714.                         if ( ssl_debug_flag )
  1715.                             printf(
  1716.   "Failed to assign generated temp RSA key to SSL!\r\n");
  1717.                     }
  1718.                 }
  1719.                 if (SSL_CTX_need_tmp_RSA(tls_ctx)) {
  1720.                     if (!SSL_CTX_set_tmp_rsa(tls_ctx,rsa)) {
  1721.                         if ( ssl_debug_flag )
  1722.                             printf(
  1723.   "Failed to assign generated temp RSA key to TLS!\r\n");
  1724.                     }
  1725.                 }
  1726.                 RSA_free(rsa);
  1727.                 if ( ssl_debug_flag )
  1728.                     printf("Assigned temp (512 bit) RSA key\r\n");
  1729.             }
  1730.         }
  1731.     }
  1732.  
  1733.     /* make sure we will find certificates in the standard
  1734.      * location ... otherwise we don't look anywhere for
  1735.      * these things which is going to make client certificate
  1736.      * exchange rather useless :-)
  1737.      * In OS2, default values for ssl_verify_file and ssl_verify_path.
  1738.      */
  1739.  
  1740. #ifdef OS2
  1741. #ifdef NT
  1742.     {
  1743.         /* The defaults in the SSL crypto library are not appropriate for OS/2 */
  1744.         char path[CKMAXPATH];
  1745.  
  1746.         ckmakmsg(path,CKMAXPATH,exedir,"certs",NULL,NULL);
  1747.         if (isdir(path) && 
  1748.             SSL_CTX_load_verify_locations(tls_ctx,NULL,path) == 1)  {
  1749.             debug(F110,"ssl_tn_init certificate verify dir",path,0);
  1750.             if (ssl_debug_flag)
  1751.                 printf("  Certificate Verification Directory: %s\r\n",path);
  1752.             SSL_CTX_load_verify_locations(ssl_ctx,NULL,path);
  1753.         }
  1754.         ckmakmsg(path,CKMAXPATH,GetAppData(1),"kermit 95/certs",NULL,NULL);
  1755.         if (isdir(path) &&
  1756.             SSL_CTX_load_verify_locations(tls_ctx,NULL,path) == 1)  {
  1757.             debug(F110,"ssl_tn_init certificate verify dir",path,0);
  1758.             if (ssl_debug_flag)
  1759.                 printf("  Certificate Verification Directory: %s\r\n",path);
  1760.             SSL_CTX_load_verify_locations(ssl_ctx,NULL,path);
  1761.         }
  1762.         ckmakmsg(path,CKMAXPATH,GetAppData(0),"kermit 95/certs",NULL,NULL);
  1763.         if (isdir(path) &&
  1764.             SSL_CTX_load_verify_locations(tls_ctx,NULL,path) == 1)  {
  1765.             debug(F110,"ssl_tn_init certificate verify dir",path,0);
  1766.             if (ssl_debug_flag)
  1767.                 printf("  Certificate Verification Directory: %s\r\n",path);
  1768.             SSL_CTX_load_verify_locations(ssl_ctx,NULL,path);
  1769.         }
  1770.         ckmakmsg(path,CKMAXPATH,exedir,"ca_certs.pem",NULL,NULL);
  1771.         if (zchki(path) > 0 && 
  1772.             SSL_CTX_load_verify_locations(tls_ctx,path,NULL) == 1) {
  1773.             debug(F110,"ssl_tn_init certificate verify file",path,0);
  1774.             if (ssl_debug_flag)
  1775.                 printf("  Certificate Verification File: %s\r\n",path);
  1776.             SSL_CTX_load_verify_locations(ssl_ctx,path,NULL);
  1777.         }
  1778.         ckmakmsg(path,CKMAXPATH,GetAppData(1),"kermit 95/ca_certs.pem",NULL,NULL);
  1779.         if (zchki(path) > 0 && 
  1780.             SSL_CTX_load_verify_locations(tls_ctx,path,NULL) == 1) {
  1781.             debug(F110,"ssl_tn_init certificate verify file",path,0);
  1782.             if (ssl_debug_flag)
  1783.                 printf("  Certificate Verification File: %s\r\n",path);
  1784.             SSL_CTX_load_verify_locations(ssl_ctx,path,NULL);
  1785.         }
  1786.         ckmakmsg(path,CKMAXPATH,GetAppData(0),"kermit 95/ca_certs.pem",NULL,NULL);
  1787.         if (zchki(path) > 0 && 
  1788.             SSL_CTX_load_verify_locations(tls_ctx,path,NULL) == 1) {
  1789.             debug(F110,"ssl_tn_init certificate verify file",path,0);
  1790.             if (ssl_debug_flag)
  1791.                 printf("  Certificate Verification File: %s\r\n",path);
  1792.             SSL_CTX_load_verify_locations(ssl_ctx,path,NULL);
  1793.         }
  1794.     }
  1795. #else /* NT */
  1796.     {
  1797.         /* The defaults in the SSL crypto library are not appropriate for OS/2 */
  1798.         char path[CKMAXPATH];
  1799.  
  1800.         ckmakmsg(path,CKMAXPATH,exedir,"certs",NULL,NULL);
  1801.         if (isdir(path) && 
  1802.             SSL_CTX_load_verify_locations(tls_ctx,NULL,path) == 1)  {
  1803.             debug(F110,"ssl_tn_init certificate verify dir",path,0);
  1804.             if (ssl_debug_flag)
  1805.                 printf("  Certificate Verification Directory: %s\r\n",path);
  1806.             SSL_CTX_load_verify_locations(ssl_ctx,NULL,path);
  1807.         }
  1808.         ckmakmsg(path,CKMAXPATH,exedir,"ca_certs.pem",NULL,NULL);
  1809.         if (zchki(path) > 0 && 
  1810.             SSL_CTX_load_verify_locations(tls_ctx,path,NULL) == 1) {
  1811.             debug(F110,"ssl_tn_init certificate verify file",path,0);
  1812.             if (ssl_debug_flag)
  1813.                 printf("  Certificate Verification File: %s\r\n",path);
  1814.             SSL_CTX_load_verify_locations(ssl_ctx,path,NULL);
  1815.         }
  1816.     }
  1817. #endif /* NT */
  1818. #else /* OS2 */
  1819.     SSL_CTX_set_default_verify_paths(ssl_ctx);
  1820.     SSL_CTX_set_default_verify_paths(tls_ctx);
  1821. #endif /* OS2 */
  1822.  
  1823.     if (ssl_verify_file) {
  1824.         if (zchki(ssl_verify_file) > 0 && 
  1825.             SSL_CTX_load_verify_locations(tls_ctx,ssl_verify_file,NULL) == 1) {
  1826.             debug(F110,"ssl_tn_init certificate verify file",ssl_verify_file,0);
  1827.             if (ssl_debug_flag)
  1828.                 printf("  Certificate Verification File: %s\r\n",ssl_verify_file);
  1829.             SSL_CTX_load_verify_locations(ssl_ctx,ssl_verify_file,NULL);
  1830.         }
  1831.     }
  1832.     if (ssl_verify_dir && isdir(ssl_verify_dir)) {
  1833.         if (SSL_CTX_load_verify_locations(tls_ctx,NULL,ssl_verify_dir) == 1)  {
  1834.             debug(F110,"ssl_tn_init certificate verify dir",ssl_verify_dir,0);
  1835.             if (ssl_debug_flag)
  1836.                 printf("  Certificate Verification Directory: %s\r\n",ssl_verify_dir);
  1837.             SSL_CTX_load_verify_locations(ssl_ctx,NULL,ssl_verify_dir);
  1838.         }
  1839.     }
  1840.     if (mode == SSL_SERVER) {
  1841.         SSL_CTX_set_verify(ssl_ctx,
  1842.                      ssl_verify_flag?ssl_verify_flag|SSL_VERIFY_CLIENT_ONCE:0,
  1843.                            ssl_server_verify_callback);
  1844.         SSL_CTX_set_verify(tls_ctx,
  1845.                      ssl_verify_flag?ssl_verify_flag|SSL_VERIFY_CLIENT_ONCE:0,
  1846.                            ssl_server_verify_callback);
  1847.     } else {
  1848.         SSL_CTX_set_verify(ssl_ctx,ssl_verify_flag,
  1849.                            ssl_client_verify_callback);
  1850.         SSL_CTX_set_verify(tls_ctx,ssl_verify_flag,
  1851.                            ssl_client_verify_callback);
  1852.     }
  1853.  
  1854.     /* Free the existing CRL Store */
  1855.     if (crl_store) {
  1856.         X509_STORE_free(crl_store);
  1857.         crl_store = NULL;
  1858.     }
  1859.  
  1860.     /* set up the new CRL Store */
  1861.     crl_store = X509_STORE_new();
  1862.     if (crl_store) {
  1863. #ifdef OS2
  1864.         char path[CKMAXPATH];
  1865.  
  1866.         ckmakmsg(path,CKMAXPATH,exedir,"crls",NULL,NULL);
  1867.         if (isdir(path) &&
  1868.             X509_STORE_load_locations(crl_store,NULL,path) == 1) {
  1869.             debug(F110,"ssl_tn_init crl dir",path,0);
  1870.             if (ssl_debug_flag)
  1871.                 printf("  CRL Directory: %s\r\n",path);
  1872.         }
  1873. #ifdef NT
  1874.         ckmakmsg(path,CKMAXPATH,GetAppData(1),"kermit 95/crls",NULL,NULL);
  1875.         if (isdir(path) && 
  1876.             X509_STORE_load_locations(crl_store,NULL,path) == 1) {
  1877.             debug(F110,"ssl_tn_init crl dir",path,0);
  1878.             if (ssl_debug_flag)
  1879.                 printf("  CRL Directory: %s\r\n",path);
  1880.         }
  1881.         ckmakmsg(path,CKMAXPATH,GetAppData(0),"kermit 95/crls",NULL,NULL);
  1882.         if (isdir(path) && 
  1883.             X509_STORE_load_locations(crl_store,NULL,path) == 1) {
  1884.             debug(F110,"ssl_tn_init crl dir",path,0);
  1885.             if (ssl_debug_flag)
  1886.                 printf("  CRL Directory: %s\r\n",path);
  1887.         }
  1888. #endif /* NT */
  1889.         
  1890.         ckmakmsg(path,CKMAXPATH,exedir,"ca_crls.pem",NULL,NULL);
  1891.         if (zchki(path) > 0 && 
  1892.             X509_STORE_load_locations(crl_store,path,NULL) == 1) {
  1893.             debug(F110,"ssl_tn_init crl file",path,0);
  1894.             if (ssl_debug_flag)
  1895.                 printf("  CRL File: %s\r\n",path);
  1896.         }
  1897. #ifdef NT
  1898.         ckmakmsg(path,CKMAXPATH,GetAppData(1),"kermit 95/ca_crls.pem",NULL,NULL);
  1899.         if (zchki(path) > 0 && 
  1900.             X509_STORE_load_locations(crl_store,path,NULL) == 1) {
  1901.             debug(F110,"ssl_tn_init crl file",path,0);
  1902.             if (ssl_debug_flag)
  1903.                 printf("  CRL File: %s\r\n",path);
  1904.         }
  1905.         ckmakmsg(path,CKMAXPATH,GetAppData(0),"kermit 95/ca_crls.pem",NULL,NULL);
  1906.         if (zchki(path) > 0 && 
  1907.             X509_STORE_load_locations(crl_store,path,NULL) == 1) {
  1908.             debug(F110,"ssl_tn_init crl file",path,0);
  1909.             if (ssl_debug_flag)
  1910.                 printf("  CRL File: %s\r\n",path);
  1911.         }
  1912. #endif /* NT */
  1913. #endif /* OS2 */
  1914.  
  1915.         if (ssl_crl_file || ssl_crl_dir) {
  1916.             if (ssl_crl_file && zchki(ssl_crl_file) > 0 && 
  1917.                 X509_STORE_load_locations(crl_store,ssl_crl_file,NULL) == 1) {
  1918.                 debug(F110,"ssl_tn_init crl file",ssl_crl_file,0);
  1919.                 if (ssl_debug_flag)
  1920.                     printf("  CRL File: %s\r\n",ssl_crl_file);
  1921.             }
  1922.             if (ssl_crl_dir && isdir(ssl_crl_dir) &&
  1923.                 X509_STORE_load_locations(crl_store,NULL,ssl_crl_dir) == 1) {
  1924.                 debug(F110,"ssl_tn_init crl dir",ssl_crl_dir,0);
  1925.                 if (ssl_debug_flag)
  1926.                     printf("  CRL Directory: %s\r\n",ssl_crl_dir);
  1927.             }
  1928.         } 
  1929. #ifndef OS2
  1930.         else {
  1931.             X509_STORE_set_default_paths(crl_store);
  1932.         }
  1933. #endif /* OS2 */
  1934.     }
  1935.  
  1936. #ifndef COMMENT
  1937.     ssl_conx = ssl_con;
  1938.     ssl_con=(SSL *)SSL_new(ssl_ctx);
  1939.     if ( !ssl_con ) {
  1940.         debug(F110,"ssl_tn_init","SSL_new(ssl_con) failed",0);
  1941.         last_ssl_mode = -1;
  1942.         ssl_con = ssl_conx;
  1943.         return(0);
  1944.     }
  1945.     if (ssl_conx) {
  1946.         if ( mode == SSL_CLIENT ) {
  1947.             SSL_set_session(ssl_con, SSL_get_session(ssl_conx));
  1948.         }
  1949. #ifdef SSL_KRB5
  1950.         if (ssl_conx->kssl_ctx) {
  1951.             kssl_ctx_free(ssl_conx->kssl_ctx);
  1952.             ssl_conx->kssl_ctx = NULL;
  1953.         }
  1954. #endif /* SSL_KRB5 */
  1955.         SSL_free(ssl_conx);
  1956.         ssl_conx = NULL;
  1957.     }
  1958.     tls_conx = tls_con;
  1959.     tls_con=(SSL *)SSL_new(tls_ctx);
  1960.     if ( !tls_con ) {
  1961.         debug(F110,"ssl_tn_init","SSL_new(tls_con) failed",0);
  1962.         last_ssl_mode = -1;
  1963.         tls_con = tls_conx;
  1964.         return(0);
  1965.     }
  1966.     if (tls_conx) {
  1967.         if ( mode == SSL_CLIENT )
  1968.             SSL_set_session(tls_con, SSL_get_session(tls_conx));
  1969. #ifdef SSL_KRB5
  1970.         if (tls_conx->kssl_ctx) {
  1971.             kssl_ctx_free(tls_conx->kssl_ctx);
  1972.             tls_conx->kssl_ctx = NULL;
  1973.         }
  1974. #endif /* SSL_KRB5 */
  1975.         SSL_free(tls_conx);
  1976.         tls_conx = NULL;
  1977.     }
  1978. #else /* COMMENT */
  1979.     /* I don't know why this does not work to reuse the connection. */
  1980.     if ( ssl_con ) {
  1981.         SSL_clear(ssl_con);
  1982.         SSL_set_session(ssl_con,NULL);
  1983.         SSL_set_accept_state(ssl_con) ;
  1984.     } else {
  1985.         ssl_con=(SSL *)SSL_new(ssl_ctx);
  1986.         if (!ssl_con) {
  1987.             debug(F110,"ssl_tn_init","SSL_new(ssl_ctx) failed",0);
  1988.             last_ssl_mode = -1;
  1989.             ssl_con = ssl_conx;
  1990.             return(0);
  1991.         }
  1992.     }
  1993.  
  1994.     if ( tls_con ) {
  1995.         SSL_clear(tls_con);
  1996.         SSL_set_session(tls_con,NULL);
  1997.         SSL_set_accept_state(tls_con) ;
  1998.     } else {
  1999.         tls_con=(SSL *)SSL_new(tls_ctx);
  2000.         if ( !tls_con ) {
  2001.             debug(F110,"ssl_tn_init","SSL_new(tls_ctx) failed",0);
  2002.             last_ssl_mode = -1;
  2003.             tls_con = tls_conx;
  2004.             return(0);
  2005.         }
  2006.     }
  2007. #endif /* COMMENT */
  2008.  
  2009. #ifdef SSL_KRB5
  2010. #ifndef KRB5_SERVICE_NAME
  2011. #define KRB5_SERVICE_NAME    "host"
  2012. #endif
  2013.  
  2014.     if (ssl_con->kssl_ctx == NULL)
  2015.         ssl_con->kssl_ctx = kssl_ctx_new();
  2016.     if (tls_con->kssl_ctx == NULL)
  2017.     tls_con->kssl_ctx = kssl_ctx_new();
  2018.     if (mode == SSL_SERVER) {
  2019.         if (ssl_con->kssl_ctx != NULL)
  2020.             kssl_ctx_setstring(ssl_con->kssl_ctx, KSSL_KEYTAB, k5_keytab);
  2021.         if (tls_con->kssl_ctx != NULL)
  2022.             kssl_ctx_setstring(tls_con->kssl_ctx, KSSL_KEYTAB, k5_keytab);
  2023.     } else {
  2024.         if (ssl_con->kssl_ctx != NULL)
  2025.             kssl_ctx_setstring(ssl_con->kssl_ctx, KSSL_SERVER, szHostName);
  2026.         if (tls_con->kssl_ctx != NULL)
  2027.             kssl_ctx_setstring(tls_con->kssl_ctx, KSSL_SERVER, szHostName);
  2028.     }
  2029.     kssl_ctx_setstring(ssl_con->kssl_ctx, KSSL_SERVICE,
  2030.                         krb5_d_srv ? krb5_d_srv : KRB5_SERVICE_NAME);
  2031.     kssl_ctx_setstring(tls_con->kssl_ctx, KSSL_SERVICE,
  2032.                         krb5_d_srv ? krb5_d_srv : KRB5_SERVICE_NAME);
  2033. #endif /* SSL_KRB5 */
  2034.  
  2035.     if (ssl_cipher_list) {
  2036.         SSL_set_cipher_list(ssl_con,ssl_cipher_list);
  2037.         SSL_set_cipher_list(tls_con,ssl_cipher_list);
  2038.     } else {
  2039.         char * p;
  2040.         if (p = getenv("SSL_CIPHER")) {
  2041.             SSL_set_cipher_list(ssl_con,p);
  2042.             SSL_set_cipher_list(tls_con,p);
  2043.         } else {
  2044.             SSL_set_cipher_list(ssl_con,DEFAULT_CIPHER_LIST);
  2045.             SSL_set_cipher_list(tls_con,DEFAULT_CIPHER_LIST);
  2046.         }
  2047.     }
  2048.  
  2049.     ssl_verify_depth = -1;
  2050.  
  2051.     if ( ssl_debug_flag )
  2052.         printf("SSL/TLS init done!\r\n");
  2053.  
  2054.     ssl_initialized = 1;
  2055.     last_ssl_mode = mode;
  2056.     debug(F110,"ssl_tn_init","done",0);
  2057.     return(1);
  2058. }
  2059.  
  2060. #ifndef NOHTTP
  2061. int
  2062. #ifdef CK_ANSIC
  2063. ssl_http_init(char * hostname)
  2064. #else
  2065. ssl_http_init(hostname) char * hostname;
  2066. #endif /* CK_ANSIC */
  2067. {
  2068. #ifdef KRB5
  2069.     extern char * k5_keytab;
  2070.     extern char * krb5_d_srv;
  2071. #endif /* KRB5 */
  2072.     SSL * tls_conx=NULL;
  2073.  
  2074.     ssl_http_initialized = 0;
  2075.  
  2076.     if ( !ck_ssleay_is_installed() )
  2077.         return(0);
  2078.     debug(F110,"ssl_http_init",hostname,0);
  2079.  
  2080.     if (ssl_debug_flag)
  2081.         printf("SSL_DEBUG_FLAG on\r\n");
  2082.  
  2083.     if (!tls_http_ctx ) {
  2084. #ifdef COMMENT
  2085.         /* too many web servers still do not support TLSv1 */
  2086.         tls_http_ctx=(SSL_CTX *)SSL_CTX_new(TLSv1_client_method());
  2087. #else /* COMMENT */
  2088.         tls_http_ctx=(SSL_CTX *)SSL_CTX_new(SSLv23_client_method());
  2089.         /* This can fail because we do not have RSA available */
  2090.         if ( !tls_http_ctx ) {
  2091.             debug(F110,"ssl_http_init","SSLv23_client_method failed",0);
  2092.             tls_http_ctx=(SSL_CTX *)SSL_CTX_new(SSLv3_client_method());
  2093.         }
  2094. #endif /* COMMENT */
  2095.         if ( !tls_http_ctx ) {
  2096.             debug(F110,"ssl_http_init","TLSv1_client_method failed",0);
  2097.             return(0);
  2098.         }
  2099. #ifdef USE_CERT_CB
  2100.         SSL_CTX_set_client_cert_cb(tls_http_ctx,ssl_client_cert_callback);
  2101. #endif /* USE_CERT_CB */
  2102.     }
  2103.  
  2104.     SSL_CTX_set_default_passwd_cb(tls_http_ctx,
  2105.                                   (pem_password_cb *)ssl_passwd_callback);
  2106.  
  2107.     /* for SSL switch on all the interoperability and bug
  2108.      * workarounds so that we will communicate with people
  2109.      * that cannot read poorly written specs :-)
  2110.      * for TLS be sure to prevent use of SSLv2
  2111.      */
  2112.     SSL_CTX_set_options(tls_http_ctx,
  2113.             SSL_OP_NO_SSLv2|SSL_OP_SINGLE_DH_USE|SSL_OP_EPHEMERAL_RSA);
  2114.  
  2115.     SSL_CTX_set_info_callback(tls_http_ctx,ssl_client_info_callback);
  2116.  
  2117. #ifndef COMMENT
  2118.     SSL_CTX_set_session_cache_mode(tls_http_ctx,SSL_SESS_CACHE_CLIENT);
  2119.     SSL_CTX_set_session_id_context(tls_http_ctx,(CHAR *)"3",1);
  2120. #else /* COMMENT */
  2121.     SSL_CTX_set_session_cache_mode(tls_http_ctx,SSL_SESS_CACHE_OFF);
  2122. #endif /* COMMENT */
  2123.  
  2124.     /* make sure we will find certificates in the standard
  2125.      * location ... otherwise we don't look anywhere for
  2126.      * these things which is going to make client certificate
  2127.      * exchange rather useless :-)
  2128.      */
  2129.  
  2130. #ifdef OS2
  2131. #ifdef NT
  2132.     {
  2133.         /* The defaults in the SSL crypto library are not appropriate for OS/2 */
  2134.         char path[CKMAXPATH];
  2135.  
  2136.         ckmakmsg(path,CKMAXPATH,exedir,"certs",NULL,NULL);
  2137.         if (SSL_CTX_load_verify_locations(tls_http_ctx,NULL,path) == 0)  {
  2138.             debug(F110,"ssl_http_init unable to load path",path,0);
  2139.             if (ssl_debug_flag)
  2140.                 printf("?Unable to load verify-dir: %s\r\n",path);
  2141.         }
  2142.  
  2143.         ckmakmsg(path,CKMAXPATH,GetAppData(1),"kermit 95/certs",NULL,NULL);
  2144.         if (SSL_CTX_load_verify_locations(tls_http_ctx,NULL,path) == 0)  {
  2145.             debug(F110,"ssl_http_init unable to load path",path,0);
  2146.             if (ssl_debug_flag)
  2147.                 printf("?Unable to load verify-dir: %s\r\n",path);
  2148.         }
  2149.  
  2150.         ckmakmsg(path,CKMAXPATH,GetAppData(0),"kermit 95/certs",NULL,NULL);
  2151.         if (SSL_CTX_load_verify_locations(tls_http_ctx,NULL,path) == 0)  {
  2152.             debug(F110,"ssl_http_init unable to load path",path,0);
  2153.             if (ssl_debug_flag)
  2154.                 printf("?Unable to load verify-dir: %s\r\n",path);
  2155.         }
  2156.  
  2157.         ckmakmsg(path,CKMAXPATH,exedir,"ca_certs.pem",NULL,NULL);
  2158.         if (SSL_CTX_load_verify_locations(tls_http_ctx,path,NULL) == 0) {
  2159.             debug(F110,"ssl_http_init unable to load path",path,0);
  2160.             if (ssl_debug_flag)
  2161.                 printf("?Unable to load verify-file: %s\r\n",path);
  2162.         }
  2163.  
  2164.         ckmakmsg(path,CKMAXPATH,GetAppData(1),"kermit 95/ca_certs.pem",NULL,NULL);
  2165.         if (SSL_CTX_load_verify_locations(tls_http_ctx,path,NULL) == 0) {
  2166.             debug(F110,"ssl_http_init unable to load path",path,0);
  2167.             if (ssl_debug_flag)
  2168.                 printf("?Unable to load verify-file: %s\r\n",path);
  2169.         }
  2170.  
  2171.         ckmakmsg(path,CKMAXPATH,GetAppData(0),"kermit 95/ca_certs.pem",NULL,NULL);
  2172.         if (SSL_CTX_load_verify_locations(tls_http_ctx,path,NULL) == 0) {
  2173.             debug(F110,"ssl_http_init unable to load path",path,0);
  2174.             if (ssl_debug_flag)
  2175.                 printf("?Unable to load verify-file: %s\r\n",path);
  2176.         }
  2177.     }
  2178. #else /* NT */
  2179.     {
  2180.         /* The defaults in the SSL crypto library are not appropriate for OS/2 */
  2181.         char path[CKMAXPATH];
  2182.  
  2183.         ckmakmsg(path,CKMAXPATH,exedir,"certs",NULL,NULL);
  2184.         if (SSL_CTX_load_verify_locations(tls_http_ctx,NULL,path) == 0)  {
  2185.             debug(F110,"ssl_http_init unable to load path",path,0);
  2186.             if (ssl_debug_flag)
  2187.                 printf("?Unable to load verify-dir: %s\r\n",path);
  2188.         }
  2189.         ckmakmsg(path,CKMAXPATH,exedir,"ca_certs.pem",NULL,NULL);
  2190.         if (SSL_CTX_load_verify_locations(tls_http_ctx,path,NULL) == 0) {
  2191.             debug(F110,"ssl_http_init unable to load path",path,0);
  2192.             if (ssl_debug_flag)
  2193.                 printf("?Unable to load verify-file: %s\r\n",path);
  2194.         }
  2195.     }
  2196. #endif /* NT */
  2197. #else /* OS2 */
  2198.     SSL_CTX_set_default_verify_paths(tls_http_ctx);
  2199. #endif /* OS2 */
  2200.  
  2201.     if (ssl_verify_file &&
  2202.         SSL_CTX_load_verify_locations(tls_http_ctx,ssl_verify_file,NULL) == 0)  {
  2203.         debug(F110,"ssl_http_init unable to load ssl_verify_file",ssl_verify_file,0);
  2204.         if (ssl_debug_flag)
  2205.             printf("?Unable to load verify-file: %s\r\n",ssl_verify_file);
  2206.     }
  2207.     if (ssl_verify_dir &&
  2208.         SSL_CTX_load_verify_locations(tls_http_ctx,NULL,ssl_verify_dir) == 0)  {
  2209.         debug(F110,"ssl_http_init unable to load ssl_verify_dir",ssl_verify_dir,0);
  2210.         if (ssl_debug_flag)
  2211.             printf("?Unable to load verify-dir: %s\r\n",ssl_verify_dir);
  2212.     }
  2213.  
  2214.     SSL_CTX_set_verify(tls_http_ctx,ssl_verify_flag,
  2215.                            ssl_client_verify_callback);
  2216.  
  2217.     /* Free the existing CRL Store */
  2218.     if (crl_store) {
  2219.         X509_STORE_free(crl_store);
  2220.         crl_store = NULL;
  2221.     }
  2222.  
  2223.     /* set up the new CRL Store */
  2224.     crl_store = X509_STORE_new();
  2225.     if (crl_store) {
  2226. #ifdef OS2
  2227.         char path[CKMAXPATH];
  2228.  
  2229.         ckmakmsg(path,CKMAXPATH,exedir,"crls",NULL,NULL);
  2230.         if (X509_STORE_load_locations(crl_store,NULL,path) == 0) {
  2231.             debug(F110,"ssl_http_init unable to load dir",path,0);
  2232.             if (ssl_debug_flag)
  2233.                 printf("?Unable to load crl-dir: %s\r\n",path);
  2234.         }
  2235. #ifdef NT
  2236.         ckmakmsg(path,CKMAXPATH,GetAppData(1),"kermit 95/crls",NULL,NULL);
  2237.         if (X509_STORE_load_locations(crl_store,NULL,path) == 0) {
  2238.             debug(F110,"ssl_http_init unable to load dir",path,0);
  2239.             if (ssl_debug_flag)
  2240.                 printf("?Unable to load crl-dir: %s\r\n",path);
  2241.         }
  2242.         ckmakmsg(path,CKMAXPATH,GetAppData(0),"kermit 95/crls",NULL,NULL);
  2243.         if (X509_STORE_load_locations(crl_store,NULL,path) == 0) {
  2244.             debug(F110,"ssl_http_init unable to load dir",path,0);
  2245.             if (ssl_debug_flag)
  2246.                 printf("?Unable to load crl-dir: %s\r\n",path);
  2247.         }
  2248. #endif /* NT */
  2249.         
  2250.         ckmakmsg(path,CKMAXPATH,exedir,"ca_crls.pem",NULL,NULL);
  2251.         if (X509_STORE_load_locations(crl_store,path,NULL) == 0) {
  2252.             debug(F110,"ssl_http_init unable to load file",path,0);
  2253.             if (ssl_debug_flag)
  2254.                 printf("?Unable to load crl-file: %s\r\n",path);
  2255.         }
  2256. #ifdef NT
  2257.         ckmakmsg(path,CKMAXPATH,GetAppData(1),"kermit 95/ca_crls.pem",NULL,NULL);
  2258.         if (X509_STORE_load_locations(crl_store,path,NULL) == 0) {
  2259.             debug(F110,"ssl_http_init unable to load file",path,0);
  2260.             if (ssl_debug_flag)
  2261.                 printf("?Unable to load crl-file: %s\r\n",path);
  2262.         }
  2263.         ckmakmsg(path,CKMAXPATH,GetAppData(0),"kermit 95/ca_crls.pem",NULL,NULL);
  2264.         if (X509_STORE_load_locations(crl_store,path,NULL) == 0) {
  2265.             debug(F110,"ssl_http_init unable to load file",path,0);
  2266.             if (ssl_debug_flag)
  2267.                 printf("?Unable to load crl-file: %s\r\n",path);
  2268.         }
  2269. #endif /* NT */
  2270. #endif /* OS2 */
  2271.  
  2272.         if (ssl_crl_file || ssl_crl_dir) {
  2273.             if (ssl_crl_file &&
  2274.                 X509_STORE_load_locations(crl_store,ssl_crl_file,NULL) == 0) {
  2275.                 debug(F110,"ssl_http_init unable to load ssl_crl_file",ssl_crl_file,0);
  2276.                 if (ssl_debug_flag)
  2277.                     printf("?Unable to load crl-file: %s\r\n",ssl_crl_file);
  2278.             }
  2279.             if (ssl_crl_dir &&
  2280.                 X509_STORE_load_locations(crl_store,NULL,ssl_crl_dir) == 0) {
  2281.                 debug(F110,"ssl_http_init unable to load ssl_crl_dir",ssl_crl_dir,0);
  2282.                 if (ssl_debug_flag)
  2283.                     printf("?Unable to load crl-dir: %s\r\n",ssl_crl_dir);
  2284.             }
  2285.         } else {
  2286.             X509_STORE_set_default_paths(crl_store);
  2287.         }
  2288.     }
  2289.  
  2290. #ifndef COMMENT
  2291.     tls_conx = tls_http_con;
  2292.     tls_http_con=(SSL *)SSL_new(tls_http_ctx);
  2293.     if ( !tls_http_con ) {
  2294.         debug(F110,"ssl_http_init","SSL_new(tls_http_con) failed",0);
  2295.         tls_http_con = tls_conx;
  2296.         return(0);
  2297.     }
  2298.     if (tls_conx) {
  2299.         SSL_set_session(tls_http_con, SSL_get_session(tls_conx));
  2300. #ifdef SSL_KRB5
  2301.         if (tls_conx->kssl_ctx) {
  2302.             kssl_ctx_free(tls_conx->kssl_ctx);
  2303.             tls_conx->kssl_ctx = NULL;
  2304.         }
  2305. #endif /* SSL_KRB5 */
  2306.         SSL_free(tls_conx);
  2307.         tls_conx = NULL;
  2308.     }
  2309. #else /* COMMENT */
  2310.     /* I don't know why this does not work to reuse the connection. */
  2311.     if ( tls_http_con ) {
  2312.         SSL_clear(tls_http_con);
  2313.         SSL_set_session(tls_http_con,NULL);
  2314.         SSL_set_accept_state(tls_http_con) ;
  2315.     } else {
  2316.         tls_http_con=(SSL *)SSL_new(tls_http_ctx);
  2317.         if ( !tls_http_con ) {
  2318.             debug(F110,"ssl_http_init","SSL_new(tls_http_ctx) failed",0);
  2319.             tls_http_con = tls_conx;
  2320.             return(0);
  2321.         }
  2322.     }
  2323. #endif /* COMMENT */
  2324.  
  2325. #ifdef SSL_KRB5
  2326. #ifndef KRB5_SERVICE_NAME
  2327. #define KRB5_SERVICE_NAME    "host"
  2328. #endif
  2329.  
  2330.     if (tls_http_con->kssl_ctx == NULL)
  2331.     tls_http_con->kssl_ctx = kssl_ctx_new();
  2332.     if (tls_http_con->kssl_ctx != NULL)
  2333.         kssl_ctx_setstring(tls_http_con->kssl_ctx, KSSL_SERVER, hostname);
  2334.  
  2335.     kssl_ctx_setstring(tls_http_con->kssl_ctx, KSSL_SERVICE,
  2336.                         krb5_d_srv ? krb5_d_srv : KRB5_SERVICE_NAME);
  2337. #endif /* SSL_KRB5 */
  2338.  
  2339.     if (ssl_cipher_list)
  2340.         SSL_set_cipher_list(tls_http_con,ssl_cipher_list);
  2341.     else {
  2342.         char * p;
  2343.         if (p = getenv("SSL_CIPHER")) {
  2344.             SSL_set_cipher_list(tls_http_con,p);
  2345.         } else {
  2346.             SSL_set_cipher_list(tls_http_con,DEFAULT_CIPHER_LIST);
  2347.         }
  2348.     }
  2349.  
  2350.     ssl_verify_depth = -1;
  2351.  
  2352.     if ( ssl_debug_flag )
  2353.         printf("SSL/TLS init done!\r\n");
  2354.  
  2355.     ssl_http_initialized = 1;
  2356.     return(1);
  2357. }
  2358. #endif /* NOHTTP */
  2359.  
  2360. char *
  2361. ssl_get_dNSName(ssl) SSL * ssl;
  2362. {
  2363.     static char *dns = NULL;
  2364.     X509 *server_cert = NULL;
  2365.     int i;
  2366.     X509_EXTENSION *ext = NULL;
  2367.     STACK_OF(GENERAL_NAME) *ialt = NULL;
  2368.     GENERAL_NAME *gen = NULL;
  2369.  
  2370.     if ( dns ) {
  2371.         free(dns);
  2372.         dns = NULL;
  2373.     }
  2374.  
  2375.     if (server_cert = SSL_get_peer_certificate(ssl)) {
  2376.         if ((i = X509_get_ext_by_NID(server_cert, NID_subject_alt_name, -1))<0)
  2377.             return NULL;
  2378.         if (!(ext = X509_get_ext(server_cert, i)))
  2379.             return NULL;
  2380.         X509V3_add_standard_extensions();
  2381.         if (!(ialt = X509V3_EXT_d2i(ext)))
  2382.             return NULL;
  2383.         for (i = 0; i < sk_GENERAL_NAME_num(ialt); i++) {
  2384.             gen = sk_GENERAL_NAME_value(ialt, i);
  2385.             if (gen->type == GEN_DNS) {
  2386.                 if(!gen->d.ia5 || !gen->d.ia5->length)
  2387.                     break;
  2388.                 dns = malloc(gen->d.ia5->length + 1);
  2389.                 if (dns) {
  2390.                     memcpy(dns, gen->d.ia5->data, gen->d.ia5->length);
  2391.                     dns[gen->d.ia5->length] = 0;
  2392.                 }
  2393.                 break;
  2394.             }
  2395.         }
  2396.         X509V3_EXT_cleanup();
  2397.     }
  2398. cleanup:
  2399.     if (ialt)           sk_GENERAL_NAME_free(ialt);
  2400.     if (server_cert)    X509_free(server_cert);
  2401.     return dns;
  2402. }
  2403.  
  2404. char *
  2405. ssl_get_commonName(ssl) SSL * ssl;
  2406. {
  2407.     static char name[256];
  2408.     int err;
  2409.     X509 *server_cert;
  2410.  
  2411.     if (server_cert = SSL_get_peer_certificate(ssl)) {
  2412.         err = X509_NAME_get_text_by_NID(X509_get_subject_name(server_cert),
  2413.                 NID_commonName, name, sizeof(name));
  2414.         X509_free(server_cert);
  2415.     }
  2416.     if (err > 0)
  2417.         return name;
  2418.     else
  2419.         return NULL;
  2420. }
  2421.  
  2422. char *
  2423. ssl_get_issuer_name(ssl) SSL * ssl;
  2424. {
  2425.     static char name[256];
  2426.     X509 *server_cert;
  2427.  
  2428.     name[0] = '\0';
  2429.     if (server_cert = SSL_get_peer_certificate(ssl)) {
  2430.         X509_NAME_oneline(X509_get_issuer_name(server_cert),name,sizeof(name));
  2431.         X509_free(server_cert);
  2432.         return name;
  2433.     }
  2434.     else {
  2435. #ifdef COMMENT
  2436.       fprintf(stderr, "Warning: No certificate from server!\r\n");
  2437. #endif /* COMMENT */
  2438.         return NULL;
  2439.     }
  2440. }
  2441.  
  2442. char *
  2443. ssl_get_subject_name(ssl) SSL * ssl;
  2444. {
  2445.     static char name[256];
  2446.     X509 *server_cert;
  2447.  
  2448.     name[0] = '\0';
  2449.     if (server_cert = SSL_get_peer_certificate(ssl)) {
  2450.        X509_NAME_oneline(X509_get_subject_name(server_cert),name,sizeof(name));
  2451.        X509_free(server_cert);
  2452.        return name;
  2453.     }
  2454.     else
  2455.         return NULL;
  2456. }
  2457.  
  2458. #ifdef COMMENT
  2459. #ifdef CK_SSL
  2460.             && !(ck_ssleay_is_installed() &&
  2461.                (tls_active_flag || ssl_active_flag) &&
  2462.                ssl_anonymous_cipher(tls_active_flag?tls_con:ssl_con))
  2463. #endif /* CK_SSL */
  2464.  
  2465. int
  2466. ssl_anonymous_cipher(ssl) SSL * ssl;
  2467. {
  2468.     X509 * cert;
  2469.  
  2470.     if (sstelnet)
  2471.         cert = SSL_get_certificate(ssl);
  2472.     else
  2473.         cert = SSL_get_peer_certificate(ssl);
  2474.  
  2475.     if ( cert ) {
  2476.         X509_free(cert);
  2477.         return 0;
  2478.     }
  2479.     return 1;
  2480. }
  2481. #endif /* COMMENT */
  2482.  
  2483. /*
  2484.   This one is (very much!) based on work by
  2485.   Ralf S. Engelschall <rse@engelschall.com>.
  2486.   Comments by Ralf.
  2487. */
  2488. int
  2489. ssl_verify_crl(int ok, X509_STORE_CTX *ctx)
  2490. {
  2491.     X509_OBJECT obj;
  2492.     X509_NAME *subject = NULL;
  2493.     X509_NAME *issuer = NULL;
  2494.     X509 *xs = NULL;
  2495.     X509_CRL *crl = NULL;
  2496.     X509_REVOKED *revoked = NULL;
  2497.     X509_STORE_CTX * store_ctx = NULL;
  2498.     long serial;
  2499.     BIO *bio = NULL;
  2500.     int i, n, rc;
  2501.     char *cp;
  2502.     char *cp2;
  2503.  
  2504.     /*
  2505.      * Unless a revocation store for CRLs was created we
  2506.      * cannot do any CRL-based verification, of course.
  2507.      */
  2508.     if (!crl_store)
  2509.         return ok;
  2510.  
  2511.     store_ctx = X509_STORE_CTX_new();
  2512.     if ( !store_ctx )
  2513.         return(ok);
  2514.  
  2515.     /*
  2516.      * Determine certificate ingredients in advance
  2517.      */
  2518.     xs      = X509_STORE_CTX_get_current_cert(ctx);
  2519.     subject = X509_get_subject_name(xs);
  2520.     issuer  = X509_get_issuer_name(xs);
  2521.  
  2522.     /*
  2523.      * OpenSSL provides the general mechanism to deal with CRLs but does not
  2524.      * use them automatically when verifying certificates, so we do it
  2525.      * explicitly here. We will check the CRL for the currently checked
  2526.      * certificate, if there is such a CRL in the store.
  2527.      *
  2528.      * We come through this procedure for each certificate in the certificate
  2529.      * chain, starting with the root-CA's certificate. At each step we've to
  2530.      * both verify the signature on the CRL (to make sure it's a valid CRL)
  2531.      * and it's revocation list (to make sure the current certificate isn't
  2532.      * revoked).  But because to check the signature on the CRL we need the
  2533.      * public key of the issuing CA certificate (which was already processed
  2534.      * one round before), we've a little problem. But we can both solve it and
  2535.      * at the same time optimize the processing by using the following
  2536.      * verification scheme (idea and code snippets borrowed from the GLOBUS
  2537.      * project):
  2538.      *
  2539.      * 1. We'll check the signature of a CRL in each step when we find a CRL
  2540.      *    through the _subject_ name of the current certificate. This CRL
  2541.      *    itself will be needed the first time in the next round, of course.
  2542.      *    But we do the signature processing one round before this where the
  2543.      *    public key of the CA is available.
  2544.      *
  2545.      * 2. We'll check the revocation list of a CRL in each step when
  2546.      *    we find a CRL through the _issuer_ name of the current certificate.
  2547.      *    This CRLs signature was then already verified one round before.
  2548.      *
  2549.      * This verification scheme allows a CA to revoke its own certificate as
  2550.      * well, of course.
  2551.      */
  2552.  
  2553.     /*
  2554.      * Try to retrieve a CRL corresponding to the _subject_ of
  2555.      * the current certificate in order to verify it's integrity.
  2556.      */
  2557.     memset((char *)&obj, 0, sizeof(obj));
  2558.     X509_STORE_CTX_init(store_ctx, crl_store, NULL, NULL);
  2559.     rc = X509_STORE_get_by_subject(store_ctx, X509_LU_CRL, subject, &obj);
  2560.     X509_STORE_CTX_cleanup(store_ctx);
  2561.     crl = obj.data.crl;
  2562.     if (rc > 0 && crl != NULL) {
  2563.         /*
  2564.          * Verify the signature on this CRL
  2565.          */
  2566.         if (X509_CRL_verify(crl, X509_get_pubkey(xs)) <= 0) {
  2567.             fprintf(stderr, "Invalid signature on CRL!\n");
  2568.             X509_STORE_CTX_set_error(ctx, X509_V_ERR_CRL_SIGNATURE_FAILURE);
  2569.             X509_OBJECT_free_contents(&obj);
  2570.             X509_STORE_CTX_free(store_ctx);
  2571.             return 0;
  2572.         }
  2573.  
  2574.         /*
  2575.          * Check date of CRL to make sure it's not expired
  2576.          */
  2577.         i = X509_cmp_current_time(X509_CRL_get_nextUpdate(crl));
  2578.         if (i == 0) {
  2579.             fprintf(stderr, "Found CRL has invalid nextUpdate field.\n");
  2580.             X509_STORE_CTX_set_error(ctx,
  2581.                                     X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD);
  2582.             X509_OBJECT_free_contents(&obj);
  2583.             X509_STORE_CTX_free(store_ctx);
  2584.             return 0;
  2585.         }
  2586.         if (i < 0) {
  2587.             fprintf(stderr,
  2588. "Found CRL is expired - revoking all certificates until you get updated CRL.\n"
  2589.                     );
  2590.             X509_STORE_CTX_set_error(ctx, X509_V_ERR_CRL_HAS_EXPIRED);
  2591.             X509_OBJECT_free_contents(&obj);
  2592.             X509_STORE_CTX_free(store_ctx);
  2593.             return 0;
  2594.         }
  2595.         X509_OBJECT_free_contents(&obj);
  2596.     }
  2597.  
  2598.     /*
  2599.      * Try to retrieve a CRL corresponding to the _issuer_ of
  2600.      * the current certificate in order to check for revocation.
  2601.      */
  2602.     memset((char *)&obj, 0, sizeof(obj));
  2603.     X509_STORE_CTX_init(store_ctx, crl_store, NULL, NULL);
  2604.     rc = X509_STORE_get_by_subject(store_ctx, X509_LU_CRL, issuer, &obj);
  2605.     X509_STORE_CTX_free(store_ctx);        /* calls X509_STORE_CTX_cleanup() */
  2606.     crl = obj.data.crl;
  2607.     if (rc > 0 && crl != NULL) {
  2608.         /*
  2609.          * Check if the current certificate is revoked by this CRL
  2610.          */
  2611.         n = sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl));
  2612.         for (i = 0; i < n; i++) {
  2613.             revoked = sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i);
  2614.             if (ASN1_INTEGER_cmp(revoked->serialNumber,
  2615.                                  X509_get_serialNumber(xs)) == 0) {
  2616.  
  2617.                 serial = ASN1_INTEGER_get(revoked->serialNumber);
  2618.                 cp = X509_NAME_oneline(issuer, NULL, 0);
  2619.                 free(cp);
  2620.  
  2621.                 X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REVOKED);
  2622.                 X509_OBJECT_free_contents(&obj);
  2623.                 return 0;
  2624.             }
  2625.         }
  2626.         X509_OBJECT_free_contents(&obj);
  2627.     }
  2628.     return ok;
  2629. }
  2630.  
  2631. char *
  2632. tls_userid_from_client_cert(ssl) SSL * ssl;
  2633. {
  2634.     static char cn[256];
  2635.     static char *r = cn;
  2636.     int err;
  2637.     X509 *client_cert;
  2638.  
  2639.     if (client_cert = SSL_get_peer_certificate(ssl)) {
  2640.         /* call the custom function */
  2641.         err = X509_to_user(client_cert, cn, sizeof(cn));
  2642.         X509_free(client_cert);
  2643.         if (err)
  2644.             return r = NULL;
  2645.         else
  2646.             return r;
  2647.     }
  2648.     else
  2649.         return r = NULL;
  2650. }
  2651.  
  2652. unsigned char **
  2653. tls_get_SAN_objs(SSL * ssl, int type)
  2654. /* returns NULL or an array of malloc'ed objects of type `type' from the server's
  2655.  * subjectAltName, remember to free() them all!
  2656.  */
  2657. {
  2658. #define NUM_SAN_OBJS 64
  2659.     static unsigned char *objs[NUM_SAN_OBJS];
  2660.     unsigned char **rv = NULL;
  2661.     X509 *server_cert = NULL;
  2662.     int i, j;
  2663.     X509_EXTENSION *ext = NULL;
  2664.     STACK_OF(GENERAL_NAME) *ialt = NULL;
  2665.     GENERAL_NAME *gen = NULL;
  2666.  
  2667.     memset(objs, 0, sizeof(objs));
  2668.     if (server_cert = SSL_get_peer_certificate(ssl)) {
  2669.         if ((i = X509_get_ext_by_NID(server_cert, NID_subject_alt_name, -1)) < 0)
  2670.             goto eject;
  2671.         if (!(ext = X509_get_ext(server_cert, i)))
  2672.             goto eject;
  2673.         X509V3_add_standard_extensions();
  2674.         if (!(ialt = X509V3_EXT_d2i(ext)))
  2675.             goto eject;
  2676.         rv = objs;
  2677.         for (i = 0, j = 0; i < sk_GENERAL_NAME_num(ialt) && j < NUM_SAN_OBJS - 2; i++) {
  2678.             gen = sk_GENERAL_NAME_value(ialt, i);
  2679.             /* The use of V_ASN1_CONTEXT_SPECIFIC is because OpenSSL 0.9.6 defined its
  2680.              * types | V_ASN1_CONTEXT_SPECIFIC.  0.9.7 does not.  In case, we are built
  2681.              * with one and linked to the other we use this hack.
  2682.              */
  2683.             if ((gen->type | V_ASN1_CONTEXT_SPECIFIC) == (type | V_ASN1_CONTEXT_SPECIFIC)) {
  2684.                 if(!gen->d.ia5 || !gen->d.ia5->length)
  2685.                     break;
  2686.                 objs[j] = malloc(gen->d.ia5->length + 1);
  2687.                 if (objs[j]) {
  2688.                     memcpy(objs[j], gen->d.ia5->data, gen->d.ia5->length);
  2689.                     objs[j][gen->d.ia5->length] = 0;
  2690.                     j++;
  2691.                 }
  2692.             }
  2693.         }
  2694.         X509V3_EXT_cleanup();
  2695.     }
  2696. eject:
  2697.     if (ialt)           sk_GENERAL_NAME_free(ialt);
  2698.     if (server_cert)    X509_free(server_cert);
  2699.     return rv;
  2700. }
  2701.  
  2702.  
  2703. static int
  2704. dNSName_cmp(const char *host, const char *dNSName)
  2705. {
  2706.     int c1 = 0, c2 = 0, num_comp, rv = -1;
  2707.     char *p, *p1, *p2, *host_copy=NULL, *dNSName_copy=NULL;
  2708.  
  2709.     /* first we count the number of domain name components in both parameters.
  2710.      * they should be equal many, or it's not a match
  2711.      */
  2712.     p = (char *) host;
  2713.     while (p = strstr(p, ".")) {
  2714.         c1++;
  2715.         p++;
  2716.     }
  2717.     p = (char *) dNSName;
  2718.     while (p = strstr(p, ".")) {
  2719.         c2++;
  2720.         p++;
  2721.     }
  2722.     if (c1 != c2)
  2723.         return -1;
  2724.     num_comp = c1;
  2725.  
  2726.     makestr(&host_copy,host);
  2727.     makestr(&dNSName_copy,dNSName);
  2728.     if (host_copy == NULL || dNSName_copy == NULL)
  2729.         goto eject;
  2730.     /* make substrings by replacing '.' with '\0' */
  2731.     p = dNSName_copy;
  2732.     while (p = strstr(p, ".")) {
  2733.         *p = '\0';
  2734.         p++;
  2735.     }
  2736.     p = host_copy;
  2737.     while (p = strstr(p, ".")) {
  2738.         *p = '\0';
  2739.         p++;
  2740.     }
  2741.  
  2742.     /* compare each component */
  2743.     p1 = host_copy;
  2744.     p2 = dNSName_copy;
  2745.     for (; num_comp; num_comp--) {
  2746.         if (!ckmatch(p2, p1,0,1))
  2747.             /* failed match */
  2748.             goto eject;
  2749.         p1 += strlen(p1) + 1;
  2750.         p2 += strlen(p2) + 1;
  2751.     }
  2752.     /* match ok */
  2753.     rv = 0;
  2754.  
  2755.   eject:
  2756.     if (dNSName_copy)   free(dNSName_copy);
  2757.     if (host_copy)      free(host_copy);
  2758.     return rv;
  2759. }
  2760.  
  2761.  
  2762.  
  2763. static int
  2764. show_hostname_warning(char *s1, char *s2)
  2765. {
  2766.     char prefix[1024];
  2767.     int ok = 1;
  2768.     ckmakxmsg(prefix,1024,
  2769.               "Warning: Hostname (\"", s1, 
  2770.               "\") does not match server's certificate (\"", s2, "\")",
  2771.               NULL,NULL,NULL,NULL,NULL,NULL,NULL);
  2772.     if (ssl_verify_flag)
  2773.         ok = uq_ok(prefix,
  2774.                     "Continue? (Y/N) ",
  2775.                     3, NULL, 0);
  2776.     else if (ssl_verbose_flag)
  2777.         printf(prefix);
  2778.     return(ok);
  2779. }
  2780.  
  2781. #ifndef HPUX10
  2782. #ifndef HPUX1100
  2783. #ifndef SCO_OSR505
  2784. #ifndef OpenBSD
  2785. #ifndef FREEBSD4
  2786. #ifndef LINUX
  2787. #ifndef AIX41
  2788. #ifndef UW7
  2789. #ifndef SOLARIS9
  2790. #ifndef SOLARIS8
  2791. #ifndef SOLARIS7
  2792. #ifdef DEC_TCPIP
  2793. #define inet_aton INET_ATON
  2794. #endif /* DEC_TCPIP */
  2795. static int
  2796. inet_aton(char * ipaddress, struct in_addr * ia) {
  2797.     struct stringarray * q;
  2798.     union {
  2799.         unsigned long l;
  2800.         unsigned char b[4];
  2801.     } dummy;
  2802.  
  2803.     q = cksplit(1,0,ipaddress,".","0123456789abcdefACDEF",8,0,0);
  2804.     if (q->a_size == 4) {
  2805.         dummy.b[0] = atoi(q->a_head[1]);
  2806.         dummy.b[1] = atoi(q->a_head[2]);
  2807.         dummy.b[2] = atoi(q->a_head[3]);
  2808.         dummy.b[3] = atoi(q->a_head[4]);
  2809.         ia->s_addr = dummy.l;
  2810.         return(ia->s_addr != 0);
  2811.     }
  2812.     return(0);
  2813. }
  2814. #endif /* SOLARIS7 */
  2815. #endif /* SOLARIS8 */
  2816. #endif /* SOLARIS9 */
  2817. #endif /* UW7 */
  2818. #endif /* AIX41 */
  2819. #endif /* LINUX */
  2820. #endif /* FREEBSD4 */
  2821. #endif /* OpenBSD */
  2822. #endif /* SCO_OSR505 */
  2823. #endif /* HPUX1100 */
  2824. #endif /* HPUX10 */
  2825.  
  2826. int
  2827. ssl_check_server_name(SSL * ssl, char * hostname)
  2828. /* returns 0 if hostname and server's cert matches, else -1 */
  2829. {
  2830.     char * commonName;
  2831.     unsigned char ** dNSName;
  2832.     unsigned char ** ipAddress;
  2833.     struct in_addr ia;
  2834.     int rv;
  2835.  
  2836.     if (ssl_verbose_flag && !inserver) {
  2837.         if (dNSName = tls_get_SAN_objs(ssl,GEN_DNS)) {
  2838.             int i = 0;
  2839.             for (i = 0; dNSName[i]; i++) {
  2840.                 printf("Certificate[0] altSubjectName DNS=%s\r\n",dNSName[i]);
  2841.                 free(dNSName[i]);
  2842.             }
  2843.         }
  2844.         if (ipAddress = tls_get_SAN_objs(ssl,GEN_IPADD)) {
  2845.             int i = 0;
  2846.             char *server_ip;
  2847.             struct in_addr ia;
  2848.  
  2849.             for (i = 0; ipAddress[i]; i++) {
  2850.                 if (ipAddress[i]) {
  2851.                     ia.s_addr = *(unsigned long *)ipAddress[i];
  2852.                     server_ip = inet_ntoa(ia);
  2853.                     printf("Certificate[0] altSubjectName IPAddr=%s\r\n",server_ip);
  2854.                 }
  2855.                 free(ipAddress[i]);
  2856.             }
  2857.             /* ipAddress points to a static - don't free */
  2858.         }
  2859.         if (dNSName = tls_get_SAN_objs(ssl,GEN_EMAIL)) {
  2860.             int i = 0;
  2861.             for (i = 0; dNSName[i]; i++) {
  2862.                 printf("Certificate[0] altSubjectName Email=%s\r\n",dNSName[i]);
  2863.                 free(dNSName[i]);
  2864.             }
  2865.         }
  2866.         if (dNSName = tls_get_SAN_objs(ssl,GEN_URI)) {
  2867.             int i = 0;
  2868.             for (i = 0; dNSName[i]; i++) {
  2869.                 printf("Certificate[0] altSubjectName URI=%s\r\n",dNSName[i]);
  2870.                 free(dNSName[i]);
  2871.             }
  2872.         }
  2873.         if (dNSName = tls_get_SAN_objs(ssl,GEN_OTHERNAME)) {
  2874.             int i = 0;
  2875.             for (i = 0; dNSName[i]; i++) {
  2876.                 printf("Certificate[0] altSubjectName Other=%s\r\n",dNSName[i]);
  2877.                 free(dNSName[i]);
  2878.             }
  2879.         }
  2880.     }
  2881.  
  2882.     /* first we check if `hostname' is in fact an ip address */
  2883.     if (inet_aton(hostname, &ia)) {
  2884.         ipAddress = tls_get_SAN_objs(ssl,GEN_IPADD);
  2885.         if (ipAddress) {
  2886.             int i = 0;
  2887.             char *server_ip = "UNKNOWN";
  2888.  
  2889.             for (i = 0; ipAddress[i]; i++)
  2890.                 if (*(unsigned long *)ipAddress[i] == ia.s_addr)
  2891.                     return 0;
  2892.  
  2893.             if (ipAddress[i - 1]) {
  2894.                 ia.s_addr = *(unsigned long *)ipAddress[i - 1];
  2895.                 server_ip = inet_ntoa(ia);
  2896.             }
  2897.             rv = show_hostname_warning(hostname, server_ip) ? 0 : -1;
  2898.             for (i = 0; ipAddress[i]; i++)
  2899.                 free(ipAddress[i]);
  2900.         } else {
  2901.             rv = show_hostname_warning(hostname, "NO IP IN CERT") ? 0 : -1;
  2902.         }
  2903.         return(rv);
  2904.     }
  2905.  
  2906.     /* look for dNSName(s) in subjectAltName in the server's certificate */
  2907.     dNSName = tls_get_SAN_objs(ssl,GEN_DNS);
  2908.     if (dNSName) {
  2909.         int i = 0;
  2910.         for (i = 0; dNSName[i]; i++) {
  2911.             if (!dNSName_cmp(hostname,(char *)dNSName[i]))
  2912.                 return 0;
  2913.         }
  2914.         rv = show_hostname_warning(hostname,
  2915.                    (char *)((dNSName[i - 1] == NULL) ? 
  2916.                        (char *)"UNKNOWN" : (char *)dNSName[i - 1]))
  2917.          ? 0 : -1;
  2918.         for (i = 0; dNSName[i]; i++)
  2919.             free(dNSName[i]);
  2920.         return rv;
  2921.     } else if ((commonName = ssl_get_commonName(ssl))) {
  2922.        /* so the server didn't have any dNSName's, check the commonName */
  2923.        if (!dNSName_cmp(hostname, commonName))
  2924.            return 0;
  2925.        else
  2926.            return (show_hostname_warning(hostname, commonName) ? 0 : -1);
  2927.     }
  2928.     return -1;
  2929. }
  2930.  
  2931. /* Is 'user' authorized to access the system without a login */
  2932. int
  2933. tls_is_user_valid(SSL * ssl, const char *user)
  2934. {
  2935.     X509 *client_cert;
  2936.     int r = 0;
  2937.  
  2938.     if ( !ssl || !user || !user[0] )
  2939.         return(0);
  2940.  
  2941.     if (!(client_cert = SSL_get_peer_certificate(ssl)))
  2942.         return 0;
  2943.  
  2944.     /* Use user supplied function */
  2945.     r = X509_userok(client_cert,user);
  2946.  
  2947.     X509_free(client_cert);
  2948.     return r;
  2949. }
  2950.  
  2951. int
  2952. tls_is_anon(int x)
  2953. {
  2954.     char buf[128];
  2955.     SSL_CIPHER * cipher;
  2956.     SSL * ssl = NULL;
  2957.  
  2958.     switch ( x ) {
  2959. #ifndef NOFTP
  2960. #ifndef SYSFTP
  2961.     case 1:     /* ftp command */
  2962.         if ( ssl_ftp_active_flag )
  2963.             ssl = ssl_ftp_con;
  2964.         else
  2965.             return(0);
  2966.         break;
  2967.     case 2:     /* ftp data */
  2968.         if ( ssl_ftp_data_active_flag )
  2969.             ssl = ssl_ftp_data_con;
  2970.         else
  2971.             return(0);
  2972.         break;
  2973. #endif /* SYSFTP */
  2974. #endif /* NOFTP */
  2975.     default:
  2976.         if (tls_active_flag)
  2977.             ssl = tls_con;
  2978.         else if (ssl_active_flag)
  2979.             ssl = ssl_con;
  2980.         else
  2981.             return(0);
  2982.     }
  2983.  
  2984.     cipher = SSL_get_current_cipher(ssl);
  2985.     if (SSL_CIPHER_description(cipher,buf,sizeof(buf))) {
  2986.         if (ckindex("Au=None",buf,0,0,0) != 0)
  2987.             return(1);                  /* anonymous */
  2988.         return(0);                  /* known */
  2989.     } else {
  2990.         /* could not get cipher description.  Assume anonymous */
  2991.         return(1);
  2992.     }
  2993. }
  2994.  
  2995. int
  2996. tls_is_krb5(int x)
  2997. {
  2998.     char buf[128];
  2999.     SSL_CIPHER * cipher;
  3000.     SSL * ssl = NULL;
  3001.  
  3002.     switch ( x ) {
  3003. #ifndef NOFTP
  3004. #ifndef SYSFTP
  3005.     case 1:     /* ftp command */
  3006.         if ( ssl_ftp_active_flag )
  3007.             ssl = ssl_ftp_con;
  3008.         else
  3009.             return(0);
  3010.         break;
  3011.     case 2:     /* ftp data */
  3012.         if ( ssl_ftp_data_active_flag )
  3013.             ssl = ssl_ftp_data_con;
  3014.         else
  3015.             return(0);
  3016.         break;
  3017. #endif /* SYSFTP */
  3018. #endif /* NOFTP */
  3019. #ifndef NOHTTP
  3020.     case 3:
  3021.         if ( tls_http_active_flag )
  3022.             ssl = tls_http_con;
  3023.         break;
  3024. #endif /* NOHTTP */
  3025.     default:
  3026.         if (tls_active_flag)
  3027.             ssl = tls_con;
  3028.         else if (ssl_active_flag)
  3029.             ssl = ssl_con;
  3030.         else
  3031.             return(0);
  3032.     }
  3033.  
  3034.     cipher = SSL_get_current_cipher(ssl);
  3035.     if (cipher && SSL_CIPHER_description(cipher,buf,sizeof(buf))) {
  3036.         if (ckindex("Au=KRB5",buf,0,0,0) != 0)
  3037.             return(1);                  /* krb5 */
  3038.     }
  3039.     return(0);                          /* not */
  3040. }
  3041.  
  3042. int
  3043. ssl_get_client_finished(char *buf, int count)
  3044. {
  3045. #ifdef NO_GET_FINISHED
  3046.     return(0);
  3047. #else
  3048.     if (sstelnet || tcp_incoming) {
  3049.         return(SSL_get_peer_finished(ssl_active_flag?ssl_con:tls_con,
  3050.                                       buf,count));
  3051.     } else {
  3052.         return(SSL_get_finished(ssl_active_flag?ssl_con:tls_con,
  3053.                                       buf,count));
  3054.     }
  3055. #endif /* NO_GET_FINISHED */
  3056. }
  3057.  
  3058. int
  3059. ssl_get_server_finished(char *buf, int count)
  3060. {
  3061. #ifdef NO_GET_FINISHED
  3062.     return(0);
  3063. #else
  3064.     if (sstelnet || tcp_incoming) {
  3065.         return(SSL_get_finished(ssl_active_flag?ssl_con:tls_con,
  3066.                                       buf,count));
  3067.     } else {
  3068.         return(SSL_get_peer_finished(ssl_active_flag?ssl_con:tls_con,
  3069.                                       buf,count));
  3070.     }
  3071. #endif /* NO_GET_FINISHED */
  3072. }
  3073.  
  3074.  
  3075. #ifdef CK_AUTHENTICATION
  3076. int
  3077. #ifdef CK_ANSIC
  3078. ssl_reply(int how, unsigned char *data, int cnt)
  3079. #else
  3080. ssl_reply(how,data,cnt) int how; unsigned char *data; int cnt;
  3081. #endif
  3082. {
  3083.     char * str=NULL;
  3084.  
  3085.     data += 4;                          /* Point to status byte */
  3086.     cnt  -= 4;
  3087.  
  3088.     if(cnt-- < 1) {
  3089.         auth_finished(AUTH_REJECT);
  3090.         return AUTH_FAILURE;
  3091.     }
  3092.  
  3093.     switch(*data++) {
  3094.     case SSL_ACCEPT:
  3095.         if (tn_deb || debses)
  3096.             tn_debug("[SSL - handshake starting]");
  3097.         else if ( ssl_verbose_flag )
  3098.             printf("[SSL - handshake starting]\r\n");
  3099.         debug(F110,"ssl_reply","[SSL - handshake starting]",0);
  3100.  
  3101.         /* right ... now we drop into the SSL library */
  3102.         if (!ssl_only_flag) {
  3103.             if (ssl_dummy_flag) {
  3104.                 if (tn_deb || debses)
  3105.                     tn_debug("[SSL - Dummy Connected]");
  3106.                 else if ( ssl_verbose_flag ) {
  3107.                     printf("[SSL - Dummy Connected]\r\n");
  3108.                 }
  3109.                 debug(F110,"ssl_reply","[SSL - Dummy Connected]",0);
  3110.                 auth_finished(AUTH_UNKNOWN);
  3111.                 accept_complete = 1;
  3112.                 return AUTH_SUCCESS;
  3113.             }
  3114.  
  3115.             if (SSL_connect(ssl_con) <= 0) {
  3116.                 int len;
  3117.                 if (tn_deb || debses) {
  3118.                     tn_debug("[SSL - FAILED]");
  3119.                     ERR_print_errors(bio_err);
  3120.                     len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
  3121.                     ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
  3122.                     printf(ssl_err);
  3123.                 } else if ( ssl_verbose_flag ) {
  3124.                     printf("[SSL - FAILED]\r\n");
  3125.                     ERR_print_errors(bio_err);
  3126.                     len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
  3127.                     ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
  3128.                     printf(ssl_err);
  3129.                 }
  3130.                 debug(F110,"ssl_reply","[SSL - FAILED]",0);
  3131.                 auth_finished(AUTH_REJECT);
  3132.                 ttclos(0);
  3133.                 return AUTH_FAILURE;
  3134.             } else {
  3135.                 if (tn_deb || debses)
  3136.                     tn_debug("[SSL - OK]");
  3137.                 else if ( ssl_verbose_flag ) {
  3138.                     printf("[SSL - OK]\r\n");
  3139.                 }
  3140.                 debug(F110,"ssl_reply","[SSL - OK]",0);
  3141.  
  3142.                 ssl_active_flag = 1;
  3143.                 ssl_display_connect_details(ssl_con,0,ssl_verbose_flag);
  3144.             }
  3145.         }
  3146.         auth_finished(AUTH_UNKNOWN);
  3147.         accept_complete = 1;
  3148.         break;
  3149.  
  3150.     case SSL_REJECT:
  3151.         if (tn_deb || debses) {
  3152.             tn_debug(
  3153.                  "[SSL - failed to switch on SSL - trying plaintext login]");
  3154.         } else if ( ssl_verbose_flag ) {
  3155.             printf("[SSL - failed to switch on SSL]\r\n");
  3156.             printf("Trying plaintext login:\r\n");
  3157.         }
  3158.         debug(F110,"ssl_reply","[SSL - failed to switch on SSL]",0);
  3159.         auth_finished(AUTH_REJECT);
  3160.         return AUTH_FAILURE;
  3161.  
  3162.     default:
  3163.         return AUTH_FAILURE;
  3164.     }
  3165.     return AUTH_SUCCESS;
  3166. }
  3167.  
  3168. int
  3169. #ifdef CK_ANSIC
  3170. ssl_is(unsigned char *data, int cnt)
  3171. #else
  3172. ssl_is(data,cnt) unsigned char *data; int cnt;
  3173. #endif
  3174. {
  3175.     if ((cnt -= 4) < 1)
  3176.         return AUTH_FAILURE;
  3177.  
  3178.     data += 4;
  3179.     switch(*data++) {
  3180.     case SSL_START:
  3181.         /* server starts the SSL stuff now ... */
  3182.         if (!ssl_only_flag) {
  3183.             if ( !tls_load_certs(ssl_ctx,ssl_con,1) ) {
  3184.                 auth_finished(AUTH_REJECT);
  3185.                 return AUTH_FAILURE;
  3186.             }
  3187.  
  3188.             if (tn_deb || debses)
  3189.                 tn_debug("[SSL - handshake starting]");
  3190.             else if ( ssl_verbose_flag )
  3191.                 printf("[SSL - handshake starting]\r\n");
  3192.             debug(F110,"ssl_is","[SSL - handshake starting]",0);
  3193.  
  3194.             SendSSLAuthSB(SSL_ACCEPT, (void *)0, 0);
  3195.  
  3196.             auth_ssl_valid = 1;
  3197.  
  3198.             if (ssl_dummy_flag) {
  3199.                 if (tn_deb || debses)
  3200.                     tn_debug("[SSL - Dummy Connected]");
  3201.                 else if ( ssl_verbose_flag ) {
  3202.                     printf("[SSL - Dummy Connected]\r\n");
  3203.                 }
  3204.                 debug(F110,"ssl_is","[SSL - Dummy Connected]",0);
  3205.                 accept_complete = 1;
  3206.                 auth_finished(AUTH_UNKNOWN);
  3207.                 return AUTH_SUCCESS;
  3208.             }
  3209.  
  3210.             if (SSL_accept(ssl_con) <= 0) {
  3211.                 char errbuf[1024];
  3212.  
  3213.                 sprintf(errbuf,"[SSL - SSL_accept error: %s",
  3214.                          ERR_error_string(ERR_get_error(),NULL));
  3215.  
  3216.                 if (tn_deb || debses)
  3217.                     tn_debug(errbuf);
  3218.                 else if ( ssl_debug_flag )
  3219.                     printf("%s\r\n",errbuf);
  3220.                 else if ( ssl_verbose_flag )
  3221.                     printf("[SSL - SSL_accept error]\r\n");
  3222.  
  3223.                 debug(F110,"ssl_is",errbuf,0);
  3224.  
  3225.                 auth_finished(AUTH_REJECT);
  3226.                 ttclos(0);
  3227.                 return AUTH_FAILURE;
  3228.             }
  3229.  
  3230.             if (tn_deb || debses)
  3231.                 tn_debug("[SSL - OK]");
  3232.             else if ( ssl_verbose_flag ) {
  3233.                 printf("[SSL - OK]\r\n");
  3234.             }
  3235.             debug(F110,"ssl_is","[SSL - OK]",0);
  3236.             ssl_active_flag = 1;
  3237.             ssl_display_connect_details(ssl_con,1,ssl_verbose_flag);
  3238.  
  3239.             /* now check to see that we got exactly what we
  3240.             * wanted from the caller ... if a certificate is
  3241.             * required then we make 100% sure that we were
  3242.             * given one during the handshake (as it is an optional
  3243.             * part of SSL)
  3244.             */
  3245.  
  3246. #ifdef SSL_KRB5
  3247.             if ( tls_is_krb5(0) ) {
  3248.                 if (ssl_con->kssl_ctx->client_princ)
  3249.                     debug(F110,"ssl_is KRB5",ssl_con->kssl_ctx->client_princ,0);
  3250.             } else
  3251. #endif /* SSL_KRB5 */
  3252.             if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
  3253.                 X509 * peer = SSL_get_peer_certificate(ssl_con);
  3254.                 if (peer == NULL) {
  3255.                     if (tn_deb || debses)
  3256.                         tn_debug("[SSL - peer check failed]");
  3257.                     else if (ssl_debug_flag)
  3258.                         printf("[SSL - peer check failed]\r\n");
  3259.                     debug(F110,"ssl_is","[SSL - peer check failed]",0);
  3260.  
  3261.                     /* LOGGING REQUIRED HERE! */
  3262.                     auth_finished(AUTH_REJECT);
  3263.                     return AUTH_FAILURE;
  3264.                 }
  3265.             }
  3266.             auth_finished(AUTH_UNKNOWN);
  3267.             accept_complete = 1;
  3268.         }
  3269.         break;
  3270.  
  3271.     default:
  3272.         SendSSLAuthSB(SSL_REJECT, (void *) "Unknown option received", -1);
  3273.         if (tn_deb || debses)
  3274.             tn_debug("[SSL - Unknown option received]");
  3275.         else
  3276.             printf("Unknown SSL option %d\r\n", data[-1]);
  3277.         debug(F111,"ssl_is","[SSL - Unknown option received]",data[-1]);
  3278.         auth_ssl_valid = 0;
  3279.         auth_finished(AUTH_REJECT);
  3280.         return(AUTH_FAILURE);
  3281.     }
  3282.     return AUTH_SUCCESS;
  3283. }
  3284.  
  3285. #endif /* CK_AUTHENTICATION */
  3286.  
  3287. int
  3288. ck_tn_tls_negotiate(VOID)
  3289. {
  3290.     X509 * peer = NULL;
  3291.     char str[256], *uid=NULL;
  3292.     extern int sstelnet;
  3293.  
  3294.     if ( !ck_ssleay_is_installed() )
  3295.         return(-1);
  3296.  
  3297.     if (sstelnet) {
  3298.         /* server starts the TLS stuff now ... */
  3299.         if (!tls_only_flag) {
  3300.             if ( !tls_load_certs(tls_ctx,tls_con,1) ) {
  3301.                 auth_finished(AUTH_REJECT);
  3302.                 return -1;
  3303.             }
  3304.  
  3305.             if (tn_deb || debses)
  3306.                 tn_debug("[TLS - handshake starting]");
  3307.             else if ( ssl_verbose_flag )
  3308.                 printf("[TLS - handshake starting]\r\n");
  3309.             debug(F110,"ck_tn_tls_negotiate","[TLS - handshake starting]",0);
  3310.  
  3311.             if (ssl_dummy_flag) {
  3312.                 if (tn_deb || debses)
  3313.                     tn_debug("[TLS - Dummy Connected]");
  3314.                 else if ( ssl_verbose_flag ) {
  3315.                     printf("[TLS - Dummy Connected]\r\n");
  3316.                 }
  3317.                 debug(F110,"ck_tn_tls_negotiate","[TLS - Dummy Connected]",0);
  3318.                 accept_complete = 1;
  3319.                 auth_finished(AUTH_REJECT);
  3320.                 return 0;
  3321.             }
  3322.  
  3323.             if (SSL_accept(tls_con) <= 0) {
  3324.                 char errbuf[1024];
  3325.  
  3326.                 sprintf(errbuf,"[TLS - SSL_accept error: %s",
  3327.                          ERR_error_string(ERR_get_error(),NULL));
  3328.  
  3329.                 if (tn_deb || debses)
  3330.                     tn_debug(errbuf);
  3331.                 else if ( ssl_debug_flag )
  3332.                     printf("%s\r\n",errbuf);
  3333.                 else if ( ssl_verbose_flag )
  3334.                     printf("[TLS - SSL_accept error]\r\n");
  3335.  
  3336.                 debug(F110,"ck_tn_tls_negotiate",errbuf,0);
  3337.                 auth_finished(AUTH_REJECT);
  3338.                 return -1;
  3339.             }
  3340.  
  3341.             if (tn_deb || debses)
  3342.                 tn_debug("[TLS - OK]");
  3343.             else if ( ssl_verbose_flag ) {
  3344.                 printf("[TLS - OK]\r\n");
  3345.             }
  3346.  
  3347.             debug(F110,"ck_tn_tls_negotiate","[TLS - OK]",0);
  3348.             tls_active_flag = 1;
  3349.             ssl_display_connect_details(tls_con,1,ssl_verbose_flag);
  3350.  
  3351.  
  3352. #ifdef SSL_KRB5
  3353.             if ( tls_is_krb5(0) ) {
  3354.                 if (tls_con->kssl_ctx->client_princ) {
  3355.                     char *p;
  3356.                     ckstrncpy(szUserNameAuthenticated,
  3357.                                tls_con->kssl_ctx->client_princ,
  3358.                                UIDBUFLEN);
  3359.                     ckstrncpy(szUserNameRequested,
  3360.                                tls_con->kssl_ctx->client_princ,
  3361.                                UIDBUFLEN);
  3362.                     for ( p = szUserNameRequested; *p ; p++ ) {
  3363.                         if ( *p == '@' || *p == '/' ) {
  3364.                             *p = '\0';
  3365.                             break;
  3366.                         }
  3367.                     }
  3368.                 } else {
  3369.                     szUserNameRequested[0] = '\0';
  3370.                     szUserNameAuthenticated[0] = '\0';
  3371.                 }
  3372. #ifdef CK_LOGIN
  3373.                 if (zvuser(szUserNameRequested))
  3374.                     auth_finished(AUTH_VALID);
  3375.                 else
  3376. #endif /* CK_LOGIN */
  3377.                     auth_finished(AUTH_USER);
  3378.             } else
  3379. #endif /* SSL_KRB5 */
  3380.             {
  3381.             /* now check to see that we got exactly what we
  3382.             * wanted from the caller ... if a certificate is
  3383.             * required then we make 100% sure that we were
  3384.             * given one during the handshake (as it is an optional
  3385.             * part of TLS)
  3386.             */
  3387.             peer=SSL_get_peer_certificate(tls_con);
  3388.             if (peer == NULL) {
  3389.                 debug(F100,"SSL_get_peer_certificate() == NULL","",0);
  3390.                 auth_finished(AUTH_REJECT);
  3391.                 if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
  3392.                     if (tn_deb || debses)
  3393.                         tn_debug("[TLS - peer check failed]");
  3394.                     else if (ssl_debug_flag) {
  3395.                         printf("[TLS - peer check failed]\r\n");
  3396.                     }
  3397.                     debug(F110,
  3398.                            "ck_tn_tls_negotiate",
  3399.                            "[TLS - peer check failed]",
  3400.                            0
  3401.                            );
  3402.                     /* LOGGING REQUIRED HERE! */
  3403.                     return -1;
  3404.                 }
  3405.             } else {
  3406.                 debug(F100,"SSL_get_peer_certificate() != NULL","",0);
  3407.                 X509_NAME_get_text_by_NID(X509_get_subject_name(peer),
  3408.                                            NID_commonName,str,
  3409.                                            256
  3410.                                            );
  3411.                 if ( ssl_verbose_flag )
  3412.                     printf("[TLS - commonName=%s]\r\n",str);
  3413.  
  3414.                 X509_NAME_get_text_by_NID(X509_get_subject_name(peer),
  3415. #ifndef NID_x500UniqueIdentifier
  3416.                                            NID_uniqueIdentifier,
  3417. #else
  3418.                                            NID_x500UniqueIdentifier,
  3419. #endif
  3420.                                            str,
  3421.                                            256
  3422.                                            );
  3423.                 if ( ssl_verbose_flag )
  3424.                     printf("[TLS - uniqueIdentifier=%s]\r\n",str);
  3425.  
  3426.                 /* Try to determine user name */
  3427.                 uid = tls_userid_from_client_cert(tls_con);
  3428.                 if ( uid ) {
  3429.                     /* This code is very questionable.
  3430.                      * How should it behave?
  3431.                      * The client has presented a certificate that
  3432.                      * contains a username.  We have validated the
  3433.                      * certificate but we do not automatically
  3434.                      * log the user in unless there is a .tlslogin
  3435.                      * file.
  3436.                      */
  3437.  
  3438.                     ckstrncpy(szUserNameRequested,uid,UIDBUFLEN);
  3439. #ifdef CK_LOGIN
  3440.                     if (zvuser(uid))
  3441.                         auth_finished(AUTH_VALID);
  3442.                     else
  3443. #endif /* CK_LOGIN */
  3444.                         auth_finished(AUTH_USER);
  3445.                 }
  3446.                 else {
  3447.                     szUserNameRequested[0] = '\0';
  3448.                     auth_finished(AUTH_REJECT);
  3449.                 }
  3450.             }
  3451.             }
  3452.         }
  3453.     } else {
  3454.         char * str=NULL;
  3455.  
  3456.         if (tn_deb || debses)
  3457.             tn_debug("[TLS - handshake starting]");
  3458.         else if ( ssl_verbose_flag )
  3459.             printf("[TLS - handshake starting]\r\n");
  3460.         debug(F110,"ck_tn_tls_negotiate","[TLS - handshake starting]",0);
  3461.  
  3462.         /* right ... now we drop into the SSL library */
  3463.         if (!tls_only_flag) {
  3464.             char *subject=NULL, *issuer=NULL, *commonName=NULL, *dNSName=NULL;
  3465.  
  3466.             if (ssl_dummy_flag) {
  3467.                 if (tn_deb || debses)
  3468.                     tn_debug("[TLS - Dummy Connected]");
  3469.                 else if ( ssl_verbose_flag ) {
  3470.                     printf("[TLS - Dummy Connected]\r\n");
  3471.                 }
  3472.                 debug(F110,"ck_tn_tls_negotiate","[TLS - Dummy Connected]",0);
  3473.                 auth_finished(AUTH_REJECT);
  3474.                 accept_complete = 1;
  3475.                 return 0;
  3476.             }
  3477.  
  3478. #ifndef USE_CERT_CB
  3479.             if (!tls_load_certs(tls_ctx,tls_con,0))
  3480.                 return(-1);
  3481. #endif /* USE_CERT_CB */
  3482.             if (SSL_connect(tls_con) <= 0) {
  3483.                 int len;
  3484.                 if (tn_deb || debses) {
  3485.                     tn_debug("[TLS - FAILED]");
  3486.                     ERR_print_errors(bio_err);
  3487.                     len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
  3488.                     ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
  3489.                     printf(ssl_err);
  3490.                 } else if ( ssl_verbose_flag ) {
  3491.                     printf("[TLS - FAILED]\r\n");
  3492.                     ERR_print_errors(bio_err);
  3493.                     len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
  3494.                     ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
  3495.                     printf(ssl_err);
  3496.                 }
  3497.                 debug(F110,"ck_tn_tls_negotiate","[TLS - FAILED]",0);
  3498.                 auth_finished(AUTH_REJECT);
  3499.                 return -1;
  3500.             }
  3501.  
  3502.             tls_active_flag = 1;
  3503.             if ( !ssl_certsok_flag && (ssl_verify_flag & SSL_VERIFY_PEER)
  3504.                  && !tls_is_krb5(0)) {
  3505.                 char prmpt[1024];
  3506.                 subject = ssl_get_subject_name(tls_con);
  3507.  
  3508.                 if (!subject) {
  3509.                     if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
  3510.                     {
  3511.                         if (tn_deb || debses)
  3512.                             tn_debug("[TLS - FAILED]");
  3513.                         else if ( ssl_verbose_flag )
  3514.                             printf("[TLS - FAILED]\r\n");
  3515.                         debug(F110,"ck_tn_tls_negotiate","[TLS - FAILED]",0);
  3516.                         auth_finished(AUTH_REJECT);
  3517.                         return -1;
  3518.                     } else {
  3519.                         int ok;
  3520.                         ok = uq_ok("Warning: Server didn't provide a certificate",
  3521.                                    "Continue? (Y/N)", 3, NULL, 0);
  3522.                         if (!ok) {
  3523.                             if (tn_deb || debses)
  3524.                                 tn_debug("[TLS - FAILED]");
  3525.                             else if ( ssl_verbose_flag )
  3526.                                 printf("[TLS - FAILED]\r\n");
  3527.                             debug(F110,
  3528.                                    "ck_tn_tls_negotiate","[TLS - FAILED]",0);
  3529.                             auth_finished(AUTH_REJECT);
  3530.                             return -1;
  3531.                         }
  3532.                     }
  3533.                 } else if (ssl_check_server_name(tls_con, szHostName)) {
  3534.                     if (tn_deb || debses)
  3535.                         tn_debug("[TLS - FAILED]");
  3536.                     else if ( ssl_verbose_flag )
  3537.                         printf("[TLS - FAILED]\r\n");
  3538.                     debug(F110,
  3539.                            "ck_tn_tls_negotiate","[TLS - FAILED]",0);
  3540.                     auth_finished(AUTH_REJECT);
  3541.                     return -1;
  3542.                 }
  3543.             }
  3544.  
  3545.             if ( ssl_debug_flag && ssl_finished_messages) {
  3546.                 char msg[32];
  3547.                 int i, len=32;
  3548.                 extern char tn_msg[], hexbuf[];
  3549.  
  3550.                 tn_msg[0] = '\0';
  3551.                 len = ssl_get_client_finished(msg,len);
  3552.                 if ( len > 0 ) {
  3553.                     for ( i=0;i<len;i++ ) {
  3554.                         sprintf(hexbuf,"%02X ",msg[i]);
  3555.                         ckstrncat(tn_msg,hexbuf,TN_MSG_LEN);
  3556.                     }
  3557.                     printf("TLS client finished: %s\r\n",tn_msg);
  3558.                 }
  3559.                 tn_msg[0] = '\0';
  3560.                 len = ssl_get_server_finished(msg,len);
  3561.                 if ( len > 0 ) {
  3562.                     for ( i=0;i<len;i++ ) {
  3563.                         sprintf(hexbuf,"%02X ",msg[i]);
  3564.                         ckstrncat(tn_msg,hexbuf,TN_MSG_LEN);
  3565.                     }
  3566.                     printf("TLS server finished: %s\r\n",tn_msg);
  3567.                 }
  3568.             }
  3569.  
  3570.             if (tn_deb || debses)
  3571.                 tn_debug("[TLS - OK]");
  3572.             else if ( ssl_verbose_flag )
  3573.                 printf("[TLS - OK]\r\n");
  3574.             debug(F110,"ck_tn_tls_negotiate","[TLS - OK]",0);
  3575.  
  3576.             ssl_display_connect_details(tls_con,0,ssl_verbose_flag);
  3577.         }
  3578.         auth_finished(AUTH_REJECT);
  3579.     }
  3580.     accept_complete = 1;
  3581.     auth_ssl_valid = 1;
  3582.     return(0);
  3583. }
  3584.  
  3585. int
  3586. ck_ssl_incoming(fd) int fd;
  3587. {
  3588.     /* if we are not running in debug then any error
  3589.     * stuff from SSL debug *must* not go down
  3590.     * the socket (which 0,1,2 are all pointing to by
  3591.     * default)
  3592.     */
  3593.  
  3594.     int timo = 2000;
  3595.  
  3596.     if ( !ck_ssleay_is_installed() )
  3597.         return(-1);
  3598.  
  3599.     /* do the SSL stuff now ... before we play with pty's */
  3600.     SSL_set_fd(ssl_con,fd);
  3601.     SSL_set_fd(tls_con,fd);
  3602.  
  3603.     if (tls_only_flag) {
  3604.         if (tn_deb || debses)
  3605.             tn_debug("[TLS - handshake starting]");
  3606.         else if ( ssl_verbose_flag )
  3607.             printf("[TLS - handshake starting]\r\n");
  3608.         debug(F110,"ck_ssl_incoming","[TLS - handshake starting]",0);
  3609.  
  3610.         /* hmm ... only when running talking to things like
  3611.         * https servers should we hit this code and then
  3612.         * we really don't care *who* we talk to :-)
  3613.         */
  3614.         if (SSL_accept(tls_con) <= 0) {
  3615.             char errbuf[1024];
  3616.  
  3617.             sprintf(errbuf,"[TLS - SSL_accept error: %s",
  3618.                      ERR_error_string(ERR_get_error(),NULL));
  3619.  
  3620.             if (tn_deb || debses)
  3621.                 tn_debug(errbuf);
  3622.             else if ( ssl_debug_flag )
  3623.                 printf("%s\r\n",errbuf);
  3624.             else if ( ssl_verbose_flag )
  3625.                 printf("[TLS - SSL_accept error]\r\n");
  3626.  
  3627.             debug(F110,"ck_ssl_incoming",errbuf,0);
  3628.             return(-1);
  3629.         } else {
  3630.             if (tn_deb || debses)
  3631.                 tn_debug("[TLS - OK]");
  3632.             else if ( ssl_verbose_flag )
  3633.                 printf("[TLS - OK]\r\n");
  3634.             debug(F110,"ck_ssl_incoming","[TLS - OK]",0);
  3635.             tls_active_flag = 1;
  3636.         }
  3637.     } else if (ssl_only_flag) {
  3638.         if (tn_deb || debses)
  3639.             tn_debug("[SSL - handshake starting]");
  3640.         else if ( ssl_verbose_flag )
  3641.             printf("[SSL - handshake starting]\r\n");
  3642.         debug(F110,"ck_ssl_incoming","[SSL - handshake starting]",0);
  3643.  
  3644.         /* hmm ... only when running talking to things like
  3645.          * https servers should we hit this code and then
  3646.          * we really don't care *who* we talk to :-)
  3647.          */
  3648.         if (SSL_accept(ssl_con) <= 0) {
  3649.             char errbuf[1024];
  3650.  
  3651.             sprintf(errbuf,"[SSL - SSL_accept error: %s",
  3652.                      ERR_error_string(ERR_get_error(),NULL));
  3653.  
  3654.             if (tn_deb || debses)
  3655.                 tn_debug(errbuf);
  3656.             else if ( ssl_debug_flag )
  3657.                 printf("%s\r\n",errbuf);
  3658.             else if ( ssl_verbose_flag )
  3659.                 printf("[SSL - SSL_accept error]\r\n");
  3660.  
  3661.             debug(F110,"ck_ssl_incoming",errbuf,0);
  3662.             return(-1);
  3663.         } else {
  3664.             if (tn_deb || debses)
  3665.                 tn_debug("[SSL - OK]");
  3666.             else if ( ssl_verbose_flag )
  3667.             printf("[SSL - OK]\r\n");
  3668.             debug(F110,"ssl_is","[SSL - OK]",0);
  3669.             ssl_active_flag = 1;
  3670.         }
  3671.     }
  3672.     if (ssl_active_flag || tls_active_flag) {
  3673.         X509 *peer;
  3674.         char str[256], *uid=NULL;
  3675.  
  3676.         /* now check to see that we got exactly what we
  3677.          * wanted from the caller ... if a certificate is
  3678.          * required then we make 100% sure that we were
  3679.          * given on during the handshake (as it is an optional
  3680.          * part of SSL and TLS)
  3681.          */
  3682.  
  3683.         if ( tls_active_flag ) {
  3684.             peer=SSL_get_peer_certificate(tls_con);
  3685.         } else if ( ssl_active_flag ) {
  3686.             peer=SSL_get_peer_certificate(ssl_con);
  3687.         }
  3688.  
  3689.         if (peer == NULL) {
  3690.             debug(F100,"SSL_get_peer_certificate() == NULL","",0);
  3691.             auth_finished(AUTH_REJECT);
  3692.  
  3693.             if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
  3694.                 if (tn_deb || debses)
  3695.                     tn_debug("[SSL/TLS - peer check failed]");
  3696.                 else if (ssl_debug_flag) {
  3697.                     printf("[SSL/TLS - peer check failed]\r\n");
  3698.                 }
  3699.                 debug(F110,
  3700.                        "ck_tn_tls_negotiate",
  3701.                        "[SSL/TLS - peer check failed]",
  3702.                        0
  3703.                        );
  3704.                 /* LOGGING REQUIRED HERE! */
  3705.                 return -1;
  3706.             }
  3707.  
  3708.         } else {
  3709.             debug(F100,"SSL_get_peer_certificate() != NULL","",0);
  3710.             X509_NAME_get_text_by_NID(X509_get_subject_name(peer),
  3711.                                        NID_commonName,str,
  3712.                                        256
  3713.                                        );
  3714.             printf("[TLS - commonName=%s]\r\n",str);
  3715.  
  3716.             X509_NAME_get_text_by_NID(X509_get_subject_name(peer),
  3717. #ifndef NID_x500UniqueIdentifier
  3718.                                        NID_uniqueIdentifier,
  3719. #else   
  3720.                                        NID_x500UniqueIdentifier,
  3721. #endif
  3722.                                        str,256
  3723.                                        );
  3724.             printf("[TLS - uniqueIdentifier=%s]\r\n",str);
  3725.  
  3726.             /* Try to determine user name */
  3727.             uid = tls_userid_from_client_cert(tls_con);
  3728.             if ( uid ) {
  3729.                 /* This code is very questionable.
  3730.                 * How should it behave?
  3731.                 * The client has presented a certificate that
  3732.                 * contains a username.  We have validated the
  3733.                 * certificate but we do not automatically
  3734.                 * log the user in unless there is a .tlslogin
  3735.                 * file.
  3736.                 */
  3737.  
  3738.                 ckstrncpy(szUserNameRequested,uid,UIDBUFLEN);
  3739. #ifdef CK_LOGIN
  3740.                 if (zvuser(uid))
  3741.                     auth_finished(AUTH_VALID);
  3742.                 else
  3743. #endif /* CK_LOGIN */
  3744.                     auth_finished(AUTH_USER);
  3745.             }
  3746.             else {
  3747.                 szUserNameRequested[0] = '\0';
  3748.                 auth_finished(AUTH_REJECT);
  3749.             }
  3750.         }
  3751.     }
  3752.     return(0);  /* success */
  3753. }
  3754.  
  3755. int
  3756. ck_ssl_outgoing(fd) int fd;
  3757. {
  3758.     int timo = 2000;
  3759.  
  3760.     if ( !ck_ssleay_is_installed() )
  3761.         return(-1);
  3762.  
  3763.     /* bind in the network descriptor */
  3764.     SSL_set_fd(ssl_con,fd);
  3765.     SSL_set_fd(tls_con,fd);
  3766.  
  3767.     /* If we are doing raw TLS then start it now ... */
  3768.     if (tls_only_flag) {
  3769. #ifndef USE_CERT_CB
  3770.         if (!tls_load_certs(tls_ctx,tls_con,0)) {
  3771.             debug(F110,"ck_ssl_outgoing","tls_load_certs() failed",0);
  3772.             return(-1);
  3773.         }
  3774. #endif /* USE_CERT_CB */
  3775.         if (tn_deb || debses)
  3776.             tn_debug("[TLS - handshake starting]");
  3777.         else if (ssl_verbose_flag)
  3778.             printf("[TLS - handshake starting]\r\n");
  3779.         debug(F110,"ck_ssl_outgoing","[TLS - handshake starting]",0);
  3780.         if (SSL_connect(tls_con) <= 0) {
  3781.             char errbuf[1024];
  3782.  
  3783.             sprintf(errbuf,"[TLS - SSL_connect error: %s",
  3784.                      ERR_error_string(ERR_get_error(),NULL));
  3785.  
  3786.             if (tn_deb || debses)
  3787.                 tn_debug(errbuf);
  3788.             else if ( ssl_debug_flag )
  3789.                 printf("%s\r\n",errbuf);
  3790.  
  3791.             if (tn_deb || debses)
  3792.                 tn_debug("[TLS - FAILED]");
  3793.             else if ( ssl_verbose_flag )
  3794.                 printf("[TLS - FAILED]\r\n");
  3795.             debug(F110,"ck_ssl_outgoing","[TLS - FAILED]",0);
  3796.             netclos();
  3797.             return(-1);
  3798.         } else {
  3799.             tls_active_flag = 1;
  3800.             if ( !ssl_certsok_flag && (ssl_verify_flag & SSL_VERIFY_PEER) && 
  3801.                  !tls_is_krb5(0) ) {
  3802.                 char *subject = ssl_get_subject_name(tls_con);
  3803.  
  3804.                 if (!subject) {
  3805.                     if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
  3806.                     {
  3807.                         if (tn_deb || debses)
  3808.                             tn_debug("[TLS - FAILED]");
  3809.                         else if ( ssl_verbose_flag )
  3810.                             printf("[TLS - FAILED]\r\n");
  3811.                         debug(F110,"ck_tn_tls_negotiate","[TLS - FAILED]",0);
  3812.  
  3813.                         auth_finished(AUTH_REJECT);
  3814.                         return -1;
  3815.                     } else {
  3816.                         char prmpt[1024];
  3817.                         int ok;
  3818.                         ok = uq_ok("Warning: Server didn't provide a certificate",
  3819.                                    "Continue? (Y/N)", 3, NULL, 0);
  3820.                         if (!ok) {
  3821.                             if (tn_deb || debses)
  3822.                                 tn_debug("[TLS - FAILED]");
  3823.                             else if ( ssl_verbose_flag )
  3824.                                 printf("[TLS - FAILED]\r\n");
  3825.                             debug(F110,
  3826.                                    "ck_tn_tls_negotiate","[TLS - FAILED]",0);
  3827.                             auth_finished(AUTH_REJECT);
  3828.                             return -1;
  3829.                         }
  3830.                     }
  3831.                 } else if (ssl_check_server_name(tls_con, szHostName)) {
  3832.                     if (tn_deb || debses)
  3833.                         tn_debug("[TLS - FAILED]");
  3834.                     else if ( ssl_verbose_flag )
  3835.                         printf("[TLS - FAILED]\r\n");
  3836.                     debug(F110,
  3837.                            "ck_tn_tls_negotiate","[TLS - FAILED]",0);
  3838.                     auth_finished(AUTH_REJECT);
  3839.                     return -1;
  3840.                 }
  3841.             }
  3842.  
  3843.             printf("[TLS - OK]\r\n");
  3844.             if (tn_deb || debses)
  3845.                 tn_debug("[TLS - OK]");
  3846.             debug(F110,"ck_ssl_outgoing","[TLS - OK]",0);
  3847.             ssl_display_connect_details(tls_con,0,ssl_verbose_flag);
  3848.         }
  3849.     }
  3850.     /* if we are doing raw SSL then start it now ... */
  3851.     else if (ssl_only_flag) {
  3852. #ifndef USE_CERT_CB
  3853.         if (!tls_load_certs(ssl_ctx,ssl_con,0))
  3854.             return(-1);
  3855. #endif /* USE_CERT_CB */
  3856.         if (tn_deb || debses)
  3857.             tn_debug("[SSL - handshake starting]");
  3858.         else if ( ssl_verbose_flag )
  3859.             printf("[SSL - handshake starting]\r\n");
  3860.         debug(F110,"ck_ssl_outgoing","[SSL - handshake starting]",0);
  3861.         if (SSL_connect(ssl_con) <= 0) {
  3862.             if ( ssl_debug_flag ) {
  3863.                 char errbuf[1024];
  3864.  
  3865.                 sprintf(errbuf,"[SSL - SSL_connect error: %s",
  3866.                          ERR_error_string(ERR_get_error(),NULL));
  3867.                 printf("%s\r\n",errbuf);
  3868.             }
  3869.             if (tn_deb || debses)
  3870.                 tn_debug("[SSL - FAILED]");
  3871.             else if ( ssl_verbose_flag )
  3872.                 printf("[SSL - FAILED]\r\n");
  3873.             debug(F110,"ck_ssl_outgoing","[SSL - FAILED]",0);
  3874.             return(-1);
  3875.         } else {
  3876.             ssl_active_flag = 1;
  3877.  
  3878.             if ( !ssl_certsok_flag && (ssl_verify_flag & SSL_VERIFY_PEER) &&
  3879.                  !tls_is_krb5(0)) {
  3880.                 char *subject = ssl_get_subject_name(ssl_con);
  3881.  
  3882.                 if (!subject) {
  3883.                     if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
  3884.                     {
  3885.                         if (tn_deb || debses)
  3886.                             tn_debug("[SSL - FAILED]");
  3887.                         else if ( ssl_verbose_flag )
  3888.                             printf("[SSL - FAILED]\r\n");
  3889.                         debug(F110,"ck_tn_tls_negotiate","[SSL - FAILED]",0);
  3890.  
  3891.                         auth_finished(AUTH_REJECT);
  3892.                         return -1;
  3893.                     } else {
  3894.                         char prmpt[1024];
  3895.                         int ok;
  3896.                         ok = uq_ok("Warning: Server didn't provide a certificate",
  3897.                                    "Continue? (Y/N)", 3, NULL, 0);
  3898.                         if (!ok) {
  3899.                             if (tn_deb || debses)
  3900.                                 tn_debug("[SSL - FAILED]");
  3901.                             else if ( ssl_verbose_flag )
  3902.                                 printf("[SSL - FAILED]\r\n");
  3903.                             debug(F110,
  3904.                                    "ck_tn_tls_negotiate","[SSL - FAILED]",0);
  3905.                             auth_finished(AUTH_REJECT);
  3906.                             return -1;
  3907.                         }
  3908.                     }
  3909.                 } else if (ssl_check_server_name(ssl_con, szHostName)) {
  3910.                     if (tn_deb || debses)
  3911.                         tn_debug("[SSL - FAILED]");
  3912.                     else if ( ssl_verbose_flag )
  3913.                         printf("[SSL - FAILED]\r\n");
  3914.                     debug(F110, "ck_tn_tls_negotiate","[SSL - FAILED]",0);
  3915.                     auth_finished(AUTH_REJECT);
  3916.                     return -1;
  3917.                 }
  3918.             }
  3919.  
  3920.             printf("[SSL - OK]\r\n");
  3921.             if (tn_deb || debses)
  3922.                 tn_debug("[SSL - OK]");
  3923.             debug(F110,"ck_ssl_outgoing","[SSL - OK]",0);
  3924.             ssl_display_connect_details(ssl_con,0,ssl_verbose_flag);
  3925.         }
  3926.     }
  3927.     return(0);  /* success */
  3928. }
  3929.  
  3930. #ifndef NOHTTP
  3931. int
  3932. ck_ssl_http_client(fd, hostname) int fd; char * hostname;
  3933. {
  3934.     int timo = 2000;
  3935.  
  3936.     if ( !ck_ssleay_is_installed() )
  3937.         return(-1);
  3938.  
  3939.     /* bind in the network descriptor */
  3940.     SSL_set_fd(tls_http_con,fd);
  3941.  
  3942.     /* If we are doing raw TLS then start it now ... */
  3943.     if (1) {
  3944. #ifndef USE_CERT_CB
  3945.         if (!tls_load_certs(tls_http_ctx,tls_http_con,0)) {
  3946.             debug(F110,"ck_ssl_http_client","tls_load_certs() failed",0);
  3947.             return(-1);
  3948.         }
  3949. #endif /* USE_CERT_CB */
  3950.         if (tn_deb || debses)
  3951.             tn_debug("[TLS - handshake starting]");
  3952.         else if (ssl_verbose_flag)
  3953.             printf("[TLS - handshake starting]\r\n");
  3954.         debug(F110,"ck_ssl_outgoing","[TLS - handshake starting]",0);
  3955.         if (SSL_connect(tls_http_con) <= 0) {
  3956.             char errbuf[1024];
  3957.  
  3958.             sprintf(errbuf,"[TLS - SSL_connect error: %s",
  3959.                      ERR_error_string(ERR_get_error(),NULL));
  3960.  
  3961.             if (tn_deb || debses)
  3962.                 tn_debug(errbuf);
  3963.             else if ( ssl_debug_flag )
  3964.                 printf("%s\r\n",errbuf);
  3965.  
  3966.             if (tn_deb || debses)
  3967.                 tn_debug("[TLS - FAILED]");
  3968.             else if ( ssl_verbose_flag )
  3969.                 printf("[TLS - FAILED]\r\n");
  3970.             debug(F110,"ck_ssl_http_client","[TLS - FAILED]",0);
  3971.             http_close();
  3972.             return(-1);
  3973.         } else {
  3974.             tls_http_active_flag = 1;
  3975.             if ( !ssl_certsok_flag && (ssl_verify_flag & SSL_VERIFY_PEER) &&
  3976.                  !tls_is_krb5(3) ) {
  3977.                 char *subject = ssl_get_subject_name(tls_http_con);
  3978.  
  3979.                 if (!subject) {
  3980.                     if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
  3981.                     {
  3982.                         if (tn_deb || debses)
  3983.                             tn_debug("[TLS - FAILED]");
  3984.                         else if ( ssl_verbose_flag )
  3985.                             printf("[TLS - FAILED]\r\n");
  3986.                         debug(F110,"ck_tn_tls_negotiate","[TLS - FAILED]",0);
  3987.                         return -1;
  3988.                     } else {
  3989.                         char prmpt[1024];
  3990.                         int ok;
  3991.                         ok = uq_ok("Warning: Server didn't provide a certificate",
  3992.                                    "Continue? (Y/N)", 3, NULL, 0);
  3993.                         if (!ok) {
  3994.                             if (tn_deb || debses)
  3995.                                 tn_debug("[TLS - FAILED]");
  3996.                             else if ( ssl_verbose_flag )
  3997.                                 printf("[TLS - FAILED]\r\n");
  3998.                             debug(F110,
  3999.                                    "ck_tn_tls_negotiate","[TLS - FAILED]",0);
  4000.                             return -1;
  4001.                         }
  4002.                     }
  4003.                 } else if (ssl_check_server_name(tls_http_con, hostname)) {
  4004.                     if (tn_deb || debses)
  4005.                         tn_debug("[TLS - FAILED]");
  4006.                     else if ( ssl_verbose_flag )
  4007.                         printf("[TLS - FAILED]\r\n");
  4008.                     debug(F110,
  4009.                            "ck_tn_tls_negotiate","[TLS - FAILED]",0);
  4010.                     return -1;
  4011.                 }
  4012.             }
  4013.  
  4014.             printf("[TLS - OK]\r\n");
  4015.             if (tn_deb || debses)
  4016.                 tn_debug("[TLS - OK]");
  4017.             debug(F110,"ck_ssl_outgoing","[TLS - OK]",0);
  4018.             ssl_display_connect_details(tls_http_con,0,ssl_verbose_flag);
  4019.         }
  4020.     }
  4021.     return(0);  /* success */
  4022. }
  4023. #endif /* NOHTTP */
  4024. int
  4025. ck_ssl_renegotiate_ciphers()
  4026. {
  4027.  
  4028.     if ( !ck_ssleay_is_installed() )
  4029.         return(0);
  4030.  
  4031.     if ( !sstelnet )
  4032.         return(0);
  4033.  
  4034.     if ( ssl_active_flag )
  4035.         return SSL_renegotiate(ssl_con);
  4036.     else if ( tls_active_flag )
  4037.         return SSL_renegotiate(tls_con);
  4038.     return(0);
  4039. }
  4040.  
  4041. #ifdef NT
  4042. int 
  4043. ck_X509_save_cert_to_user_store(X509 *cert)
  4044. {
  4045. #ifdef X509V3_EXT_DUMP_UNKNOWN
  4046.     char path[CKMAXPATH];
  4047.     char hash[16];
  4048.     char * GetAppData(int);
  4049.     BIO * out=NULL;
  4050.  
  4051.     if ( cert == NULL )
  4052.         return(0);
  4053.  
  4054.     sprintf(hash,"%08lx",X509_subject_name_hash(cert));
  4055.     ckmakmsg(path,CKMAXPATH,GetAppData(0),"kermit 95/certs/",
  4056.              hash,".0");
  4057.  
  4058.     
  4059.     out=BIO_new(BIO_s_file());
  4060.     if (out == NULL)
  4061.     {
  4062.         ERR_print_errors(bio_err);
  4063.         return(0);
  4064.     }
  4065.     if (BIO_write_filename(out,path) <= 0) {
  4066.         perror(path);
  4067.         return(0);
  4068.     }
  4069.  
  4070.     X509_print_ex(out, cert, XN_FLAG_SEP_MULTILINE, X509V3_EXT_DUMP_UNKNOWN);
  4071.     if (!PEM_write_bio_X509(out,cert)) {
  4072.         BIO_printf(bio_err,"unable to write certificate\n");
  4073.         ERR_print_errors(bio_err);
  4074.         BIO_free_all(out);
  4075.         return(0);
  4076.     }
  4077.     BIO_free_all(out);
  4078.     return(1);
  4079. #else /* X509V3_EXT_DUMP_UNKNOWN */
  4080.     return(0);
  4081. #endif /* X509V3_EXT_DUMP_UNKNOWN */
  4082. }
  4083. #endif /* NT */
  4084.  
  4085. #ifndef OS2
  4086. /* The following function should be replaced by institution specific */
  4087. /* code that will convert an X509 cert structure to a userid for the */
  4088. /* purposes of client to host login.  The example code included      */
  4089. /* simply returns the UID field of the Subject if it exists.         */
  4090.  
  4091. /* X509_to_user() returns 0 if valid userid in 'userid', else -1 */
  4092. int
  4093. X509_to_user(X509 *peer_cert, char *userid, int len)
  4094. {
  4095. #ifdef X509_UID_TO_USER
  4096.     /* BEGIN EXAMPLE */
  4097.     int err;
  4098.  
  4099.     if (!(peer_cert && userid) || len <= 0)
  4100.         return -1;
  4101.  
  4102.     userid[0] = '\0';
  4103.     debug(F110,"X509_to_user() subject",
  4104.            X509_NAME_oneline(X509_get_subject_name(peer_cert),NULL,0),0);
  4105.  
  4106.     /* userid is in cert subject /UID */
  4107.     err = X509_NAME_get_text_by_NID(X509_get_subject_name(peer_cert),
  4108. #ifndef NID_x500UniqueIdentifier
  4109.                                      NID_uniqueIdentifier,
  4110. #else
  4111.                                      NID_x500UniqueIdentifier,
  4112. #endif
  4113.                                      userid, len);
  4114.  
  4115.     debug(F111,"X509_to_user() userid",userid,err);
  4116.     if (err > 0)
  4117.         return 0;
  4118.  
  4119.     /* END EXAMPLE */
  4120. #else /* X509_UID_TO_USER */
  4121. #ifdef X509_SUBJECT_ALT_NAME_TO_USER
  4122.     /* BEGIN EXAMPLE */
  4123.     int i;
  4124.     X509_EXTENSION *ext = NULL;
  4125.     STACK_OF(GENERAL_NAME) *ialt = NULL;
  4126.     GENERAL_NAME *gen = NULL;
  4127.     char email[256];
  4128.  
  4129.     if (!(peer_cert && userid) || len <= 0)
  4130.         return -1;
  4131.  
  4132.     userid[0] = '\0';
  4133.     email[0] = '\0';
  4134.     debug(F110,"X509_to_user() subject",
  4135.            X509_NAME_oneline(X509_get_subject_name(peer_cert),NULL,0),0);
  4136.  
  4137.     if ((i = X509_get_ext_by_NID(peer_cert, NID_subject_alt_name, -1))<0)
  4138.         return -1;
  4139.     if (!(ext = X509_get_ext(peer_cert, i)))
  4140.         return -1;
  4141.     X509V3_add_standard_extensions();
  4142.     if (!(ialt = X509V3_EXT_d2i(ext)))
  4143.         return -1;
  4144.     for (i = 0; i < sk_GENERAL_NAME_num(ialt); i++) {
  4145.         gen = sk_GENERAL_NAME_value(ialt, i);
  4146.         if (gen->type == GEN_DNS) {
  4147.             if(!gen->d.ia5 || !gen->d.ia5->length)
  4148.                 break;
  4149.             if ( gen->d.ia5->length + 1 > sizeof(email) ) {
  4150.                 goto cleanup;
  4151.             }
  4152.             memcpy(email, gen->d.ia5->data, gen->d.ia5->length);
  4153.             email[gen->d.ia5->length] = 0;
  4154.             break;
  4155.         }
  4156.     }
  4157.   cleanup:
  4158.     X509V3_EXT_cleanup();
  4159.     if (ialt)
  4160.         sk_GENERAL_NAME_free(ialt);
  4161.  
  4162.     debug(F110,"X509_to_user() email",email,0);
  4163.  
  4164.     if ( email[0] ) {
  4165.         char * domain = NULL;
  4166.  
  4167.         /* Find domain */
  4168.         for ( i=0 ; email[i] ; i++ ) {
  4169.             if ( email[i] == '@' ) {
  4170.                 email[i] = '\0';
  4171.                 domain = &email[i+1];
  4172.                 break;
  4173.             }
  4174.         }
  4175.  
  4176.         if ( domain ) {
  4177.             /* XXX - Put code to Verify domain here */
  4178.  
  4179.             if ( /* domain is okay */ 1 )
  4180.                 ckstrncpy(userid,email,len);
  4181.         }
  4182.     }
  4183.  
  4184.     return(userid[0] ? 0 : -1);
  4185.     /* END EXAMPLE */
  4186. #endif /* X509_SUBJECT_ALT_NAME_TO_USER */
  4187. #endif /* X509_UID_TO_USER */
  4188.     return -1;
  4189. }
  4190.  
  4191. /* The following function should be replaced by institution specific */
  4192. /* code that will determine whether or not the combination of the    */
  4193. /* provided X509 certificate and username is valid for automatic     */
  4194. /* login.   Whereas X509_to_user() is used to provide authentication */
  4195. /* of the user, the X509_userok() function is used to provide        */
  4196. /* authorization.  The certificate passed into X509_userok() does    */
  4197. /* need to map to a userid; nor would the userid it would map to     */
  4198. /* need to match the userid provided to the function.  There are     */
  4199. /* numerous circumstances in which it is beneficial to have the ability */
  4200. /* for multiple users to gain access to a common account such as     */
  4201. /* 'root' on Unix; or a class account on a web server.  In Unix we   */
  4202. /* implement this capability with the ~userid/.tlslogin file which   */
  4203. /* a list of X509 certificates which may be used to access the       */
  4204. /* account 'userid'.                                                 */
  4205.  
  4206. /* X509_to_user() returns 0 if access is denied; 1 is access is permitted */
  4207. int
  4208. X509_userok(X509 * peer_cert, const char * userid)
  4209. {
  4210. #ifndef VMS
  4211.     /* check if clients cert is in "user"'s ~/.tlslogin file */
  4212.     char buf[512];
  4213.     int r = 0;
  4214.     FILE *fp;
  4215.     struct passwd *pwd;
  4216.     X509 *file_cert;
  4217.  
  4218.     if ( peer_cert == NULL )
  4219.         return(0);
  4220.  
  4221.     if (!(pwd = getpwnam(userid)))
  4222.        return 0;
  4223.     if (strlen(pwd->pw_dir) > 500)
  4224.        return(0);
  4225.     sprintf(buf, "%s/.tlslogin", pwd->pw_dir);
  4226.  
  4227.     if (!(fp = fopen(buf, "r")))
  4228.         return 0;
  4229.     while (!r && (file_cert = PEM_read_X509(fp, NULL, NULL, NULL))) {
  4230.         if (!ASN1_STRING_cmp(peer_cert->signature, file_cert->signature))
  4231.             r = 1;
  4232.         X509_free(file_cert);
  4233.     }
  4234.     fclose(fp);
  4235.     return(r);
  4236. #else /* VMS */
  4237.     /* Need to implement an appropriate function for VMS */
  4238.     return(0);
  4239. #endif /* VMS */
  4240. }
  4241. #endif /* OS2 */
  4242. #endif /* CK_SSL */
  4243.