mirror of
https://github.com/openssl/openssl.git
synced 2024-11-24 10:34:12 +08:00
Changes to the Kerberos SSL code by Jeffrey Altman <jaltman@columbia.edu>
His comments are: . adds use of replay cache to protect against replay attacks . adds functions kssl_tgt_is_available() and kssl_keytab_is_available() which are used within s3_lib.c and ssl_lib.c to determine at runtime whether or not KRB5 ciphers can be supported during the current session.
This commit is contained in:
parent
af436bc158
commit
a5224c3420
203
ssl/kssl.c
203
ssl/kssl.c
@ -71,7 +71,6 @@
|
||||
#define _XOPEN_SOURCE /* glibc2 needs this to declare strptime() */
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/evp.h>
|
||||
@ -127,6 +126,9 @@
|
||||
#define valid_cksumtype kssl_valid_cksumtype
|
||||
#define krb5_checksum_size kssl_krb5_checksum_size
|
||||
#define krb5_kt_free_entry kssl_krb5_kt_free_entry
|
||||
#define krb5_auth_con_setrcache kssl_krb5_auth_con_setrcache
|
||||
#define krb5_auth_con_getrcache kssl_krb5_auth_con_getrcache
|
||||
#define krb5_get_server_rcache kssl_krb5_get_server_rcache
|
||||
|
||||
/* Prototypes for built in stubs */
|
||||
void kssl_krb5_free_data_contents(krb5_context, krb5_data *);
|
||||
@ -172,6 +174,15 @@ krb5_error_code kssl_krb5_auth_con_free(krb5_context,krb5_auth_context);
|
||||
size_t kssl_krb5_checksum_size(krb5_context context,krb5_cksumtype ctype);
|
||||
krb5_boolean kssl_valid_cksumtype(krb5_cksumtype ctype);
|
||||
krb5_error_code krb5_kt_free_entry(krb5_context,krb5_keytab_entry FAR * );
|
||||
krb5_error_code kssl_krb5_auth_con_setrcache(krb5_context,
|
||||
krb5_auth_context,
|
||||
krb5_rcache);
|
||||
krb5_error_code kssl_krb5_get_server_rcache(krb5_context,
|
||||
krb5_const krb5_data *,
|
||||
krb5_rcache *);
|
||||
krb5_error_code kssl_krb5_auth_con_getrcache(krb5_context,
|
||||
krb5_auth_context,
|
||||
krb5_rcache *);
|
||||
|
||||
/* Function pointers (almost all Kerberos functions are _stdcall) */
|
||||
static void (_stdcall *p_krb5_free_data_contents)(krb5_context, krb5_data *)
|
||||
@ -232,6 +243,15 @@ static size_t (_stdcall *p_krb5_checksum_size)(krb5_context context,krb5_cksumty
|
||||
static krb5_boolean (_stdcall *p_valid_cksumtype)(krb5_cksumtype ctype)=NULL;
|
||||
static krb5_error_code (_stdcall *p_krb5_kt_free_entry)
|
||||
(krb5_context,krb5_keytab_entry * )=NULL;
|
||||
static krb5_error_code (_stdcall * p_krb5_auth_con_setrcache)(krb5_context,
|
||||
krb5_auth_context,
|
||||
krb5_rcache)=NULL;
|
||||
static krb5_error_code (_stdcall * p_krb5_get_server_rcache)(krb5_context,
|
||||
krb5_const krb5_data *,
|
||||
krb5_rcache *)=NULL;
|
||||
static krb5_error_code (* p_krb5_auth_con_getrcache)(krb5_context,
|
||||
krb5_auth_context,
|
||||
krb5_rcache *)=NULL;
|
||||
static int krb5_loaded = 0; /* only attempt to initialize func ptrs once */
|
||||
|
||||
/* Function to Load the Kerberos 5 DLL and initialize function pointers */
|
||||
@ -295,6 +315,12 @@ load_krb5_dll(void)
|
||||
GetProcAddress( hKRB5_32, "krb5_checksum_size" );
|
||||
(FARPROC) p_krb5_kt_free_entry =
|
||||
GetProcAddress( hKRB5_32, "krb5_kt_free_entry" );
|
||||
(FARPROC) p_krb5_auth_con_setrcache =
|
||||
GetProcAddress( hKRB5_32, "krb5_auth_con_setrcache" );
|
||||
(FARPROC) p_krb5_get_server_rcache =
|
||||
GetProcAddress( hKRB5_32, "krb5_get_server_rcache" );
|
||||
(FARPROC) p_krb5_auth_con_getrcache =
|
||||
GetProcAddress( hKRB5_32, "krb5_auth_con_getrcache" );
|
||||
}
|
||||
|
||||
/* Stubs for each function to be dynamicly loaded */
|
||||
@ -666,7 +692,36 @@ kssl_krb5_cc_get_principal
|
||||
return(krb5_x
|
||||
((cache)->ops->get_princ,(context, cache, principal)));
|
||||
}
|
||||
#else
|
||||
|
||||
krb5_error_code
|
||||
kssl_krb5_auth_con_setrcache(krb5_context con, krb5_auth_context acon,
|
||||
krb5_rcache rcache)
|
||||
{
|
||||
if ( p_krb5_auth_con_setrcache )
|
||||
return(p_krb5_auth_con_setrcache(con,acon,rcache));
|
||||
else
|
||||
return KRB5KRB_ERR_GENERIC;
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
kssl_krb5_get_server_rcache(krb5_context con, krb5_const krb5_data * data,
|
||||
krb5_rcache * rcache)
|
||||
{
|
||||
if ( p_krb5_get_server_rcache )
|
||||
return(p_krb5_get_server_rcache(con,data,rcache));
|
||||
else
|
||||
return KRB5KRB_ERR_GENERIC;
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
kssl_krb5_auth_con_getrcache(krb5_context con, krb5_auth_context acon,
|
||||
krb5_rcache * prcache)
|
||||
{
|
||||
if ( p_krb5_auth_con_getrcache )
|
||||
return(p_krb5_auth_con_getrcache(con,acon, prcache));
|
||||
else
|
||||
return KRB5KRB_ERR_GENERIC;
|
||||
}
|
||||
#endif /* OPENSSL_SYS_WINDOWS || OPENSSL_SYS_WIN32 */
|
||||
|
||||
char
|
||||
@ -1064,7 +1119,7 @@ kssl_cget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx,
|
||||
|
||||
if (ap_req) KRB5_APREQ_free((KRB5_APREQ *) ap_req);
|
||||
if (krb5_app_req.length)
|
||||
krb5_free_data_contents(krb5context,&krb5_app_req);
|
||||
kssl_krb5_free_data_contents(krb5context,&krb5_app_req);
|
||||
}
|
||||
#ifdef KRB5_HEIMDAL
|
||||
if (kssl_ctx_setkey(kssl_ctx, &krb5credsp->session))
|
||||
@ -1204,13 +1259,14 @@ kssl_sget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx,
|
||||
krb5_keytab krb5keytab = NULL;
|
||||
krb5_keytab_entry kt_entry;
|
||||
krb5_principal krb5server;
|
||||
krb5_rcache rcache = NULL;
|
||||
|
||||
kssl_err_set(kssl_err, 0, "");
|
||||
|
||||
if (!kssl_ctx)
|
||||
{
|
||||
kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
|
||||
"No kssl_ctx defined.\n");
|
||||
"No kssl_ctx defined.\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
@ -1240,6 +1296,15 @@ kssl_sget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx,
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
||||
if ((krb5rc = krb5_auth_con_getrcache(krb5context, krb5auth_context,
|
||||
&rcache)))
|
||||
{
|
||||
kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
|
||||
"krb5_auth_con_getrcache() fails.\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((krb5rc = krb5_sname_to_principal(krb5context, NULL,
|
||||
(kssl_ctx->service_name)? kssl_ctx->service_name: KRB5SVC,
|
||||
KRB5_NT_SRV_HST, &krb5server)) != 0)
|
||||
@ -1249,6 +1314,26 @@ kssl_sget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx,
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (rcache == NULL)
|
||||
{
|
||||
if ((krb5rc = krb5_get_server_rcache(krb5context,
|
||||
krb5_princ_component(krb5context, krb5server, 0),
|
||||
&rcache)))
|
||||
{
|
||||
kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
|
||||
"krb5_get_server_rcache() fails.\n");
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if ((krb5rc = krb5_auth_con_setrcache(krb5context, krb5auth_context, rcache)))
|
||||
{
|
||||
kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
|
||||
"krb5_auth_con_setrcache() fails.\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
||||
/* kssl_ctx->keytab_file == NULL ==> use Kerberos default
|
||||
*/
|
||||
if (kssl_ctx->keytab_file)
|
||||
@ -1569,7 +1654,7 @@ kssl_ctx_setkey(KSSL_CTX *kssl_ctx, krb5_keyblock *session)
|
||||
void
|
||||
kssl_ctx_show(KSSL_CTX *kssl_ctx)
|
||||
{
|
||||
unsigned int i;
|
||||
int i;
|
||||
|
||||
printf("kssl_ctx: ");
|
||||
if (kssl_ctx == NULL)
|
||||
@ -1599,12 +1684,118 @@ kssl_ctx_show(KSSL_CTX *kssl_ctx)
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
kssl_keytab_is_available(KSSL_CTX *kssl_ctx)
|
||||
{
|
||||
krb5_context krb5context = NULL;
|
||||
krb5_keytab krb5keytab = NULL;
|
||||
krb5_keytab_entry entry;
|
||||
krb5_principal princ = NULL;
|
||||
krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC;
|
||||
int rc = 0;
|
||||
|
||||
if ((krb5rc = krb5_init_context(&krb5context)))
|
||||
return(0);
|
||||
|
||||
/* kssl_ctx->keytab_file == NULL ==> use Kerberos default
|
||||
*/
|
||||
if (kssl_ctx->keytab_file)
|
||||
{
|
||||
krb5rc = krb5_kt_resolve(krb5context, kssl_ctx->keytab_file,
|
||||
&krb5keytab);
|
||||
if (krb5rc)
|
||||
goto exit;
|
||||
}
|
||||
else
|
||||
{
|
||||
krb5rc = krb5_kt_default(krb5context,&krb5keytab);
|
||||
if (krb5rc)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* the host key we are looking for */
|
||||
krb5rc = krb5_sname_to_principal(krb5context, NULL,
|
||||
kssl_ctx->service_name ? kssl_ctx->service_name: KRB5SVC,
|
||||
KRB5_NT_SRV_HST, &princ);
|
||||
|
||||
krb5rc = krb5_kt_get_entry(krb5context, krb5keytab,
|
||||
princ,
|
||||
0 /* IGNORE_VNO */,
|
||||
0 /* IGNORE_ENCTYPE */,
|
||||
&entry);
|
||||
if ( krb5rc == KRB5_KT_NOTFOUND ) {
|
||||
rc = 1;
|
||||
goto exit;
|
||||
} else if ( krb5rc )
|
||||
goto exit;
|
||||
|
||||
krb5_kt_free_entry(krb5context, &entry);
|
||||
rc = 1;
|
||||
|
||||
exit:
|
||||
if (krb5keytab) krb5_kt_close(krb5context, krb5keytab);
|
||||
if (princ) krb5_free_principal(krb5context, princ);
|
||||
if (krb5context) krb5_free_context(krb5context);
|
||||
return(rc);
|
||||
}
|
||||
|
||||
int
|
||||
kssl_tgt_is_available(KSSL_CTX *kssl_ctx)
|
||||
{
|
||||
krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC;
|
||||
krb5_context krb5context = NULL;
|
||||
krb5_ccache krb5ccdef = NULL;
|
||||
krb5_creds krb5creds, *krb5credsp = NULL;
|
||||
int rc = 0;
|
||||
|
||||
memset((char *)&krb5creds, 0, sizeof(krb5creds));
|
||||
|
||||
if (!kssl_ctx)
|
||||
return(0);
|
||||
|
||||
if (!kssl_ctx->service_host)
|
||||
return(0);
|
||||
|
||||
if ((krb5rc = krb5_init_context(&krb5context)) != 0)
|
||||
goto err;
|
||||
|
||||
if ((krb5rc = krb5_sname_to_principal(krb5context,
|
||||
kssl_ctx->service_host,
|
||||
(kssl_ctx->service_name)? kssl_ctx->service_name: KRB5SVC,
|
||||
KRB5_NT_SRV_HST, &krb5creds.server)) != 0)
|
||||
goto err;
|
||||
|
||||
if ((krb5rc = krb5_cc_default(krb5context, &krb5ccdef)) != 0)
|
||||
goto err;
|
||||
|
||||
if ((krb5rc = krb5_cc_get_principal(krb5context, krb5ccdef,
|
||||
&krb5creds.client)) != 0)
|
||||
goto err;
|
||||
|
||||
if ((krb5rc = krb5_get_credentials(krb5context, 0, krb5ccdef,
|
||||
&krb5creds, &krb5credsp)) != 0)
|
||||
goto err;
|
||||
|
||||
rc = 1;
|
||||
|
||||
err:
|
||||
#ifdef KSSL_DEBUG
|
||||
kssl_ctx_show(kssl_ctx);
|
||||
#endif /* KSSL_DEBUG */
|
||||
|
||||
if (krb5creds.client) krb5_free_principal(krb5context, krb5creds.client);
|
||||
if (krb5creds.server) krb5_free_principal(krb5context, krb5creds.server);
|
||||
if (krb5context) krb5_free_context(krb5context);
|
||||
return(rc);
|
||||
}
|
||||
|
||||
#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_WIN32)
|
||||
void kssl_krb5_free_data_contents(krb5_context context, krb5_data *data)
|
||||
{
|
||||
#ifdef KRB5_HEIMDAL
|
||||
data->length = 0;
|
||||
free(data->if (data->data) data);
|
||||
if (data->data)
|
||||
free(data->data);
|
||||
#elif defined(KRB5_MIT_OLD11)
|
||||
if (data->data) {
|
||||
krb5_xfree(data->data);
|
||||
|
@ -152,6 +152,8 @@ char *knumber(int len, krb5_octet *contents);
|
||||
|
||||
EVP_CIPHER *kssl_map_enc(krb5_enctype enctype);
|
||||
|
||||
int kssl_keytab_is_available(KSSL_CTX *kssl_ctx);
|
||||
int kssl_tgt_is_available(KSSL_CTX *kssl_ctx);
|
||||
|
||||
/* Public (for use by applications that use OpenSSL with Kerberos 5 support */
|
||||
krb5_error_code kssl_ctx_setstring(KSSL_CTX *kssl_ctx, int which, char *text);
|
||||
|
@ -1423,6 +1423,13 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
|
||||
#endif /* KSSL_DEBUG */
|
||||
|
||||
alg=c->algorithms&(SSL_MKEY_MASK|SSL_AUTH_MASK);
|
||||
#ifndef OPENSSL_NO_KRB5
|
||||
if (alg & SSL_KRB5)
|
||||
{
|
||||
if ( !kssl_keytab_is_available(s->kssl_ctx) )
|
||||
continue;
|
||||
}
|
||||
#endif /* OPENSSL_NO_KRB5 */
|
||||
if (SSL_C_IS_EXPORT(c))
|
||||
{
|
||||
ok=((alg & emask) == alg)?1:0;
|
||||
|
@ -1058,6 +1058,9 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p)
|
||||
int i,j=0;
|
||||
SSL_CIPHER *c;
|
||||
unsigned char *q;
|
||||
#ifndef OPENSSL_NO_KRB5
|
||||
int nokrb5 = !kssl_tgt_is_available(s->kssl_ctx);
|
||||
#endif /* OPENSSL_NO_KRB5 */
|
||||
|
||||
if (sk == NULL) return(0);
|
||||
q=p;
|
||||
@ -1065,6 +1068,10 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p)
|
||||
for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
|
||||
{
|
||||
c=sk_SSL_CIPHER_value(sk,i);
|
||||
#ifndef OPENSSL_NO_KRB5
|
||||
if ((c->algorithms & SSL_KRB5) && nokrb5)
|
||||
continue;
|
||||
#endif /* OPENSSL_NO_KRB5 */
|
||||
j=ssl_put_cipher_by_char(s,c,p);
|
||||
p+=j;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user