Add new function SSL_CTX_get_ssl_method().
[openssl.git] / ssl / kssl.c
index 51378897f6e244ce20b282b7ed0ca4f6bae6222f..fd7c67bb1fcb6406b99ec87190c5beefda44eb53 100644 (file)
 
 #include <openssl/opensslconf.h>
 
-#define _XOPEN_SOURCE /* glibc2 needs this to declare strptime() */
-#include <time.h>
-#undef _XOPEN_SOURCE /* To avoid clashes with anything else... */
 #include <string.h>
 
+#define KRB5_PRIVATE   1
+
 #include <openssl/ssl.h>
 #include <openssl/evp.h>
 #include <openssl/objects.h>
 #include <openssl/krb5_asn.h>
+#include "kssl_lcl.h"
 
 #ifndef OPENSSL_NO_KRB5
 
+#ifndef ENOMEM
+#define ENOMEM KRB5KRB_ERR_GENERIC
+#endif
+
 /* 
  * When OpenSSL is built on Windows, we do not want to require that
  * the Kerberos DLLs be available in order for the OpenSSL DLLs to
 #define krb5_principal_compare   kssl_krb5_principal_compare
 #define krb5_decrypt_tkt_part    kssl_krb5_decrypt_tkt_part
 #define krb5_timeofday           kssl_krb5_timeofday
-#define krb5_rc_default           kssl_krb5_rc_default
+#define krb5_rc_default          kssl_krb5_rc_default
 
 #ifdef krb5_rc_initialize
 #undef krb5_rc_initialize
@@ -289,7 +293,7 @@ load_krb5_dll(void)
        HANDLE hKRB5_32;
     
        krb5_loaded++;
-       hKRB5_32 = LoadLibrary("KRB5_32");
+       hKRB5_32 = LoadLibrary(TEXT("KRB5_32"));
        if (!hKRB5_32)
                return;
 
@@ -776,6 +780,25 @@ kssl_krb5_kt_get_entry(krb5_context context, krb5_keytab keytab,
         }
 #endif  /* OPENSSL_SYS_WINDOWS || OPENSSL_SYS_WIN32 */
 
+
+/* memory allocation functions for non-temporary storage
+ * (e.g. stuff that gets saved into the kssl context) */
+static void* kssl_calloc(size_t nmemb, size_t size)
+{
+       void* p;
+       
+       p=OPENSSL_malloc(nmemb*size);
+       if (p){
+               memset(p, 0, nmemb*size);
+       }
+       return p;
+}
+
+#define kssl_malloc(size) OPENSSL_malloc((size))
+#define kssl_realloc(ptr, size) OPENSSL_realloc(ptr, size)
+#define kssl_free(ptr) OPENSSL_free((ptr))
+
+
 char
 *kstring(char *string)
         {
@@ -817,7 +840,7 @@ kssl_map_enc(krb5_enctype enctype)
 **     "62 xx 30 yy" (APPLICATION-2, SEQUENCE), where xx-yy =~ 2, and
 **     xx and yy are possibly multi-byte length fields.
 */
-int    kssl_test_confound(unsigned char *p)
+static int     kssl_test_confound(unsigned char *p)
        {
        int     len = 2;
        int     xx = 0, yy = 0;
@@ -852,7 +875,7 @@ int         kssl_test_confound(unsigned char *p)
 **      what the highest assigned CKSUMTYPE_ constant is.  As of 1.2.2
 **      it is 0x000c (CKSUMTYPE_HMAC_SHA1_DES3).  So we will use 0x0010.
 */
-size_t  *populate_cksumlens(void)
+static size_t  *populate_cksumlens(void)
        {
        int             i, j, n;
        static size_t   *cklens = NULL;
@@ -919,7 +942,7 @@ kssl_err_set(KSSL_ERR *kssl_err, int reason, char *text)
        if (kssl_err == NULL)  return;
 
        kssl_err->reason = reason;
-       BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, text);
+       BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, "%s", text);
        return;
         }
 
@@ -932,7 +955,7 @@ print_krb5_data(char *label, krb5_data *kdata)
        int i;
 
        printf("%s[%d] ", label, kdata->length);
-       for (i=0; i < kdata->length; i++)
+       for (i=0; i < (int)kdata->length; i++)
                 {
                if (0 &&  isprint((int) kdata->data[i]))
                         printf(        "%c ",  kdata->data[i]);
@@ -984,14 +1007,14 @@ print_krb5_keyblock(char *label, krb5_keyblock *keyblk)
 #ifdef KRB5_HEIMDAL
        printf("%s\n\t[et%d:%d]: ", label, keyblk->keytype,
                                           keyblk->keyvalue->length);
-       for (i=0; i < keyblk->keyvalue->length; i++)
+       for (i=0; i < (int)keyblk->keyvalue->length; i++)
                 {
                printf("%02x",(unsigned char *)(keyblk->keyvalue->contents)[i]);
                }
        printf("\n");
 #else
        printf("%s\n\t[et%d:%d]: ", label, keyblk->enctype, keyblk->length);
-       for (i=0; i < keyblk->length; i++)
+       for (i=0; i < (int)keyblk->length; i++)
                 {
                printf("%02x",keyblk->contents[i]);
                }
@@ -1003,19 +1026,19 @@ print_krb5_keyblock(char *label, krb5_keyblock *keyblk)
 /*     Display contents of krb5_principal_data struct, for debugging
 **     (krb5_principal is typedef'd == krb5_principal_data *)
 */
-void
+static void
 print_krb5_princ(char *label, krb5_principal_data *princ)
         {
        int i, ui, uj;
 
        printf("%s principal Realm: ", label);
        if (princ == NULL)  return;
-       for (ui=0; ui < princ->realm.length; ui++)  putchar(princ->realm.data[ui]);
+       for (ui=0; ui < (int)princ->realm.length; ui++)  putchar(princ->realm.data[ui]);
        printf(" (nametype %d) has %d strings:\n", princ->type,princ->length);
-       for (i=0; i < princ->length; i++)
+       for (i=0; i < (int)princ->length; i++)
                 {
                printf("\t%d [%d]: ", i, princ->data[i].length);
-               for (uj=0; uj < princ->data[i].length; uj++)  {
+               for (uj=0; uj < (int)princ->data[i].length; uj++)  {
                        putchar(princ->data[i].data[uj]);
                        }
                printf("\n");
@@ -1124,7 +1147,7 @@ kssl_cget_tkt(    /* UPDATE */    KSSL_CTX *kssl_ctx,
        if (authenp)
                 {
                krb5_data       krb5in_data;
-               unsigned char   *p;
+               const unsigned char     *p;
                long            arlen;
                KRB5_APREQBODY  *ap_req;
 
@@ -1202,7 +1225,7 @@ kssl_cget_tkt(    /* UPDATE */    KSSL_CTX *kssl_ctx,
 **                             code here.  This tkt should alloc/free just
 **                             like the real thing.
 */
-krb5_error_code
+static krb5_error_code
 kssl_TKT2tkt(  /* IN     */    krb5_context    krb5context,
                /* IN     */    KRB5_TKTBODY    *asn1ticket,
                /* OUT    */    krb5_ticket     **krb5ticket,
@@ -1293,7 +1316,7 @@ kssl_sget_tkt(    /* UPDATE */    KSSL_CTX                *kssl_ctx,
        static krb5_auth_context        krb5auth_context = NULL;
        krb5_ticket                     *krb5ticket = NULL;
        KRB5_TKTBODY                    *asn1ticket = NULL;
-       unsigned char                   *p;
+       const unsigned char             *p;
        krb5_keytab                     krb5keytab = NULL;
        krb5_keytab_entry               kt_entry;
        krb5_principal                  krb5server;
@@ -1540,7 +1563,7 @@ kssl_sget_tkt(    /* UPDATE */    KSSL_CTX                *kssl_ctx,
 KSSL_CTX       *
 kssl_ctx_new(void)
         {
-       return ((KSSL_CTX *) calloc(1, sizeof(KSSL_CTX)));
+       return ((KSSL_CTX *) kssl_calloc(1, sizeof(KSSL_CTX)));
         }
 
 
@@ -1554,13 +1577,13 @@ kssl_ctx_free(KSSL_CTX *kssl_ctx)
 
        if (kssl_ctx->key)              OPENSSL_cleanse(kssl_ctx->key,
                                                              kssl_ctx->length);
-       if (kssl_ctx->key)              free(kssl_ctx->key);
-       if (kssl_ctx->client_princ)     free(kssl_ctx->client_princ);
-       if (kssl_ctx->service_host)     free(kssl_ctx->service_host);
-       if (kssl_ctx->service_name)     free(kssl_ctx->service_name);
-       if (kssl_ctx->keytab_file)      free(kssl_ctx->keytab_file);
+       if (kssl_ctx->key)              kssl_free(kssl_ctx->key);
+       if (kssl_ctx->client_princ)     kssl_free(kssl_ctx->client_princ);
+       if (kssl_ctx->service_host)     kssl_free(kssl_ctx->service_host);
+       if (kssl_ctx->service_name)     kssl_free(kssl_ctx->service_name);
+       if (kssl_ctx->keytab_file)      kssl_free(kssl_ctx->keytab_file);
 
-       free(kssl_ctx);
+       kssl_free(kssl_ctx);
        return (KSSL_CTX *) NULL;
         }
 
@@ -1585,7 +1608,7 @@ kssl_ctx_setprinc(KSSL_CTX *kssl_ctx, int which,
         case KSSL_SERVER:      princ = &kssl_ctx->service_host;        break;
         default:               return KSSL_CTX_ERR;                    break;
                }
-       if (*princ)  free(*princ);
+       if (*princ)  kssl_free(*princ);
 
        /* Add up all the entity->lengths */
        length = 0;
@@ -1598,7 +1621,7 @@ kssl_ctx_setprinc(KSSL_CTX *kssl_ctx, int which,
        /* Space for the ('@'+realm+NULL | NULL) */
        length += ((realm)? realm->length + 2: 1);
 
-       if ((*princ = calloc(1, length)) == NULL)
+       if ((*princ = kssl_calloc(1, length)) == NULL)
                return KSSL_CTX_ERR;
        else
                {
@@ -1641,7 +1664,7 @@ kssl_ctx_setstring(KSSL_CTX *kssl_ctx, int which, char *text)
         case KSSL_KEYTAB:      string = &kssl_ctx->keytab_file;        break;
         default:               return KSSL_CTX_ERR;                    break;
                }
-       if (*string)  free(*string);
+       if (*string)  kssl_free(*string);
 
        if (!text)
                 {
@@ -1649,7 +1672,7 @@ kssl_ctx_setstring(KSSL_CTX *kssl_ctx, int which, char *text)
                return KSSL_CTX_OK;
                }
 
-       if ((*string = calloc(1, strlen(text) + 1)) == NULL)
+       if ((*string = kssl_calloc(1, strlen(text) + 1)) == NULL)
                return KSSL_CTX_ERR;
        else
                strcpy(*string, text);
@@ -1673,7 +1696,7 @@ kssl_ctx_setkey(KSSL_CTX *kssl_ctx, krb5_keyblock *session)
        if (kssl_ctx->key)
                 {
                OPENSSL_cleanse(kssl_ctx->key, kssl_ctx->length);
-               free(kssl_ctx->key);
+               kssl_free(kssl_ctx->key);
                }
 
        if (session)
@@ -1699,7 +1722,7 @@ kssl_ctx_setkey(KSSL_CTX *kssl_ctx, krb5_keyblock *session)
                }
 
        if ((kssl_ctx->key =
-                (krb5_octet FAR *) calloc(1, kssl_ctx->length)) == NULL)
+                (krb5_octet FAR *) kssl_calloc(1, kssl_ctx->length)) == NULL)
                 {
                kssl_ctx->length  = 0;
                return KSSL_CTX_ERR;
@@ -1780,6 +1803,9 @@ kssl_ctx_show(KSSL_CTX *kssl_ctx)
                                      kssl_ctx->service_name ? kssl_ctx->service_name: KRB5SVC,
                                      KRB5_NT_SRV_HST, &princ);
 
+    if (krb5rc)
+       goto exit;
+
     krb5rc = krb5_kt_get_entry(krb5context, krb5keytab, 
                                 princ,
                                 0 /* IGNORE_VNO */,
@@ -1877,7 +1903,7 @@ void kssl_krb5_free_data_contents(krb5_context context, krb5_data *data)
 **  Return pointer to the (partially) filled in struct tm on success,
 **  return NULL on failure.
 */
-struct tm      *k_gmtime(ASN1_GENERALIZEDTIME *gtime, struct tm *k_tm)
+static struct tm *k_gmtime(ASN1_GENERALIZEDTIME *gtime, struct tm *k_tm)
        {
        char            c, *p;
 
@@ -1903,7 +1929,7 @@ struct tm *k_gmtime(ASN1_GENERALIZEDTIME *gtime, struct tm *k_tm)
 **  So we try to sneek the clockskew out through the replay cache.
 **     If that fails just return a likely default (300 seconds).
 */
-krb5_deltat    get_rc_clockskew(krb5_context context)
+static krb5_deltat get_rc_clockskew(krb5_context context)
        {
        krb5_rcache     rc;
        krb5_deltat     clockskew;
@@ -1978,7 +2004,8 @@ krb5_error_code  kssl_check_authent(
        EVP_CIPHER_CTX          ciph_ctx;
        const EVP_CIPHER        *enc = NULL;
        unsigned char           iv[EVP_MAX_IV_LENGTH];
-       unsigned char           *p, *unenc_authent;
+       const unsigned char     *p;
+       unsigned char           *unenc_authent;
        int                     outl, unencbufsize;
        struct tm               tm_time, *tm_l, *tm_g;
        time_t                  now, tl, tg, tr, tz_offset;
@@ -2066,9 +2093,12 @@ krb5_error_code  kssl_check_authent(
         EVP_CIPHER_CTX_cleanup(&ciph_ctx);
 
 #ifdef KSSL_DEBUG
+       {
+       int padl;
        printf("kssl_check_authent: decrypted authenticator[%d] =\n", outl);
        for (padl=0; padl < outl; padl++) printf("%02x ",unenc_authent[padl]);
        printf("\n");
+       }
 #endif /* KSSL_DEBUG */
 
        if ((p = kssl_skip_confound(enctype, unenc_authent)) == NULL)
@@ -2098,7 +2128,7 @@ krb5_error_code  kssl_check_authent(
                tm_g = gmtime(&now);            tg = mktime(tm_g);
                tz_offset = tg - tl;
 
-               *atimep = tr - tz_offset;
+               *atimep = (krb5_timestamp)(tr - tz_offset);
                }
 
 #ifdef KSSL_DEBUG
@@ -2164,11 +2194,27 @@ krb5_error_code  kssl_build_principal_2(
        return ENOMEM;
        }
 
+void SSL_set0_kssl_ctx(SSL *s, KSSL_CTX *kctx)
+       {
+       s->kssl_ctx = kctx;
+       } 
+
+KSSL_CTX * SSL_get0_kssl_ctx(SSL *s)
+       {
+       return s->kssl_ctx;
+       }
+
+char *kssl_ctx_get0_client_princ(KSSL_CTX *kctx)
+       {
+       if (kctx)
+               return kctx->client_princ;
+       return NULL;
+       }
 
 #else /* !OPENSSL_NO_KRB5 */
 
 #if defined(PEDANTIC) || defined(OPENSSL_SYS_VMS)
-static int dummy=(int)&dummy;
+static void *dummy=&dummy;
 #endif
 
 #endif /* !OPENSSL_NO_KRB5     */