⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kssl.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 C
📖 第 1 页 / 共 5 页
字号:
		return KSSL_CTX_ERR;	else		strcpy(*string, text);	return KSSL_CTX_OK;        }/*	Copy the Kerberos session key from a (krb5_keyblock *) to a kssl_ctx**	struct.  Clear kssl_ctx->key if Kerberos session key is NULL.*/krb5_error_codekssl_ctx_setkey(KSSL_CTX *kssl_ctx, krb5_keyblock *session)        {	int 		length;	krb5_enctype	enctype;	krb5_octet FAR	*contents = NULL;	if (!kssl_ctx)  return KSSL_CTX_ERR;	if (kssl_ctx->key)                {		OPENSSL_cleanse(kssl_ctx->key, kssl_ctx->length);		free(kssl_ctx->key);		}	if (session)                {#ifdef KRB5_HEIMDAL		length = session->keyvalue->length;		enctype = session->keytype;		contents = session->keyvalue->contents;#else		length = session->length;		enctype = session->enctype;		contents = session->contents;#endif		kssl_ctx->enctype = enctype;		kssl_ctx->length  = length;		}	else                {		kssl_ctx->enctype = ENCTYPE_UNKNOWN;		kssl_ctx->length  = 0;		return KSSL_CTX_OK;		}	if ((kssl_ctx->key =                (krb5_octet FAR *) calloc(1, kssl_ctx->length)) == NULL)                {		kssl_ctx->length  = 0;		return KSSL_CTX_ERR;		}	else		memcpy(kssl_ctx->key, contents, length);	return KSSL_CTX_OK;        }/*	Display contents of kssl_ctx struct*/voidkssl_ctx_show(KSSL_CTX *kssl_ctx)        {	int 	i;	printf("kssl_ctx: ");	if (kssl_ctx == NULL)                {		printf("NULL\n");		return;		}	else		printf("%p\n", (void *)kssl_ctx);	printf("\tservice:\t%s\n",                (kssl_ctx->service_name)? kssl_ctx->service_name: "NULL");	printf("\tclient:\t%s\n",                (kssl_ctx->client_princ)? kssl_ctx->client_princ: "NULL");	printf("\tserver:\t%s\n",                (kssl_ctx->service_host)? kssl_ctx->service_host: "NULL");	printf("\tkeytab:\t%s\n",                (kssl_ctx->keytab_file)? kssl_ctx->keytab_file: "NULL");	printf("\tkey [%d:%d]:\t",                kssl_ctx->enctype, kssl_ctx->length);	for (i=0; i < kssl_ctx->length  &&  kssl_ctx->key; i++)                {		printf("%02x", kssl_ctx->key[i]);		}	printf("\n");	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;        if (data->data)            free(data->data);#elif defined(KRB5_MIT_OLD11)	if (data->data)  {		krb5_xfree(data->data);		data->data = 0;		}#else	krb5_free_data_contents(NULL, data);#endif	}#endif /* !OPENSSL_SYS_WINDOWS && !OPENSSL_SYS_WIN32 *//*  Given pointers to KerberosTime and struct tm structs, convert the**  KerberosTime string to struct tm.  Note that KerberosTime is a**  ASN1_GENERALIZEDTIME value, constrained to GMT with no fractional**  seconds as defined in RFC 1510.**  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)	{	char 		c, *p;	if (!k_tm)  return NULL;	if (gtime == NULL  ||  gtime->length < 14)  return NULL;	if (gtime->data == NULL)  return NULL;	p = (char *)&gtime->data[14];	c = *p;	 *p = '\0';  p -= 2;  k_tm->tm_sec  = atoi(p);      *(p+2) = c;	c = *p;	 *p = '\0';  p -= 2;  k_tm->tm_min  = atoi(p);      *(p+2) = c;	c = *p;	 *p = '\0';  p -= 2;  k_tm->tm_hour = atoi(p);      *(p+2) = c;	c = *p;	 *p = '\0';  p -= 2;  k_tm->tm_mday = atoi(p);      *(p+2) = c;	c = *p;	 *p = '\0';  p -= 2;  k_tm->tm_mon  = atoi(p)-1;    *(p+2) = c;	c = *p;	 *p = '\0';  p -= 4;  k_tm->tm_year = atoi(p)-1900; *(p+4) = c;	return k_tm;	}/*  Helper function for kssl_validate_times().**  We need context->clockskew, but krb5_context is an opaque struct.**  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)	{	krb5_rcache 	rc;	krb5_deltat 	clockskew;	if (krb5_rc_default(context, &rc))  return KSSL_CLOCKSKEW;	if (krb5_rc_initialize(context, rc, 0))  return KSSL_CLOCKSKEW;	if (krb5_rc_get_lifespan(context, rc, &clockskew))  {		clockskew = KSSL_CLOCKSKEW;		}	(void) krb5_rc_destroy(context, rc);	return clockskew;	}/*  kssl_validate_times() combines (and more importantly exposes)**  the MIT KRB5 internal function krb5_validate_times() and the**  in_clock_skew() macro.  The authenticator client time is checked**  to be within clockskew secs of the current time and the current**  time is checked to be within the ticket start and expire times.**  Either check may be omitted by supplying a NULL value.**  Returns 0 for valid times, SSL_R_KRB5* error codes otherwise.**  See Also: (Kerberos source)/krb5/lib/krb5/krb/valid_times.c**  20010420 VRS*/krb5_error_code  kssl_validate_times(	krb5_timestamp atime,					krb5_ticket_times *ttimes)	{	krb5_deltat 	skew;	krb5_timestamp	start, now;	krb5_error_code	rc;	krb5_context	context;	if ((rc = krb5_init_context(&context)))	 return SSL_R_KRB5_S_BAD_TICKET;	skew = get_rc_clockskew(context); 	if ((rc = krb5_timeofday(context,&now))) return SSL_R_KRB5_S_BAD_TICKET;	krb5_free_context(context);	if (atime  &&  labs(atime - now) >= skew)  return SSL_R_KRB5_S_TKT_SKEW;	if (! ttimes)  return 0;	start = (ttimes->starttime != 0)? ttimes->starttime: ttimes->authtime;	if (start - now > skew)  return SSL_R_KRB5_S_TKT_NYV;	if ((now - ttimes->endtime) > skew)  return SSL_R_KRB5_S_TKT_EXPIRED;#ifdef KSSL_DEBUG	printf("kssl_validate_times: %d |<-  | %d - %d | < %d  ->| %d\n",		start, atime, now, skew, ttimes->endtime);#endif	/* KSSL_DEBUG */	return 0;	}/*  Decode and decrypt given DER-encoded authenticator, then pass**  authenticator ctime back in *atimep (or 0 if time unavailable).**  Returns krb5_error_code and kssl_err on error.  A NULL **  authenticator (authentp->length == 0) is not considered an error.**  Note that kssl_check_authent() makes use of the KRB5 session key;**  you must call kssl_sget_tkt() to get the key before calling this routine.*/krb5_error_code  kssl_check_authent(			/* IN     */	KSSL_CTX	*kssl_ctx,                        /* IN     */   	krb5_data	*authentp,			/* OUT    */	krb5_timestamp	*atimep,			/* OUT    */    KSSL_ERR	*kssl_err  )	{        krb5_error_code		krb5rc = 0;	KRB5_ENCDATA		*dec_authent = NULL;	KRB5_AUTHENTBODY	*auth = NULL;	krb5_enctype		enctype;	EVP_CIPHER_CTX		ciph_ctx;	const EVP_CIPHER	*enc = NULL;	unsigned char		iv[EVP_MAX_IV_LENGTH];	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;	EVP_CIPHER_CTX_init(&ciph_ctx);	*atimep = 0;	kssl_err_set(kssl_err, 0, "");#ifndef KRB5CHECKAUTH	authentp = NULL;#else#if	KRB5CHECKAUTH == 0	authentp = NULL;#endif#endif	/* KRB5CHECKAUTH */	if (authentp == NULL  ||  authentp->length == 0)  return 0;#ifdef KSSL_DEBUG        {        unsigned int ui;	printf("kssl_check_authent: authenticator[%d]:\n",authentp->length);	p = authentp->data; 	for (ui=0; ui < authentp->length; ui++)  printf("%02x ",p[ui]);	printf("\n");        }#endif	/* KSSL_DEBUG */	unencbufsize = 2 * authentp->length;	if ((unenc_authent = calloc(1, unencbufsize)) == NULL)		{		kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,			"Unable to allocate authenticator buffer.\n");		krb5rc = KRB5KRB_ERR_GENERIC;		goto err;		}	p = (unsigned char *)authentp->data;	if ((dec_authent = d2i_KRB5_ENCDATA(NULL, &p,					(long) authentp->length)) == NULL) 		{		kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,                        "Error decoding authenticator.\n");		krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY;		goto err;		}	enctype = dec_authent->etype->data[0];	/* should = kssl_ctx->enctype */#if !defined(KRB5_MIT_OLD11)            switch ( enctype ) {            case ENCTYPE_DES3_CBC_SHA1:		/*    EVP_des_ede3_cbc();  */            case ENCTYPE_DES3_CBC_SHA:            case ENCTYPE_DES3_CBC_RAW:                krb5rc = 0;                     /* Skip, can't handle derived keys */                goto err;            }#endif	enc = kssl_map_enc(enctype);	memset(iv, 0, sizeof iv);       /* per RFC 1510 */	if (enc == NULL)		{		/*  Disable kssl_check_authent for ENCTYPE_DES3_CBC_SHA1.		**  This enctype indicates the authenticator was encrypted		**  using key-usage derived keys which openssl cannot decrypt.		*/		goto err;		}        if (!EVP_CipherInit(&ciph_ctx,enc,kssl_ctx->key,iv,0))                {                kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,                        "EVP_CipherInit error decrypting authenticator.\n");                krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY;                goto err;                }        outl = dec_authent->cipher->length;        if (!EVP_Cipher(&ciph_ctx,unenc_authent,dec_authent->cipher->data,outl))                {                kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,                        "EVP_Ci

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -