home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / cku200.tar / ck_ssl.c < prev    next >
C/C++ Source or Header  |  2001-12-03  |  127KB  |  3,820 lines

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