krb5: Add name attributes to krb5_principal
We now have what we need in krb5_principal to implement much of RFC6680. Now we populate those fields so that they can be accessed by GSS-API RFC6680 name attributes functions. The next commit should add much of the GSS-API RFC6680 name attributes functions and functionality.
This commit is contained in:
		 Nicolas Williams
					Nicolas Williams
				
			
				
					committed by
					
						 Nico Williams
						Nico Williams
					
				
			
			
				
	
			
			
			 Nico Williams
						Nico Williams
					
				
			
						parent
						
							f3484d5e2e
						
					
				
				
					commit
					87f8c0d2b5
				
			| @@ -18,6 +18,7 @@ EXPORTS | ||||
| 	CKSUMTYPE, | ||||
| 	ChangePasswdDataMS, | ||||
| 	Checksum, | ||||
|         CompositePrincipal, | ||||
| 	ENCTYPE, | ||||
| 	ETYPE-INFO, | ||||
| 	ETYPE-INFO-ENTRY, | ||||
| @@ -440,9 +441,9 @@ Checksum ::= SEQUENCE { | ||||
| -- | ||||
| -- Attributes have three possible sources in Heimdal Kerberos at this time: | ||||
| -- | ||||
| --  - the EncKDCRepPart | ||||
| --  - the EncTicketPart | ||||
| --  - the Authenticator's AuthorizationData (if any) | ||||
| --  - the EncKDCRepPart (for the client's attributes on the client side) | ||||
| --  - the EncTicketPart (for the client's attributes on the server side) | ||||
| --  - the Authenticator's AuthorizationData (if any; server-side) | ||||
| -- | ||||
| -- In principle there can be more: | ||||
| -- | ||||
| @@ -464,15 +465,39 @@ PrincipalNameAttrs ::= SEQUENCE { | ||||
|         authenticated       [0]     BOOLEAN, | ||||
|         -- These are compiled from the Ticket and Authenticator: | ||||
|         source              [1]     PrincipalNameAttrSrc OPTIONAL, | ||||
|         authenticator-ad    [2]     AuthorizationData OPTIONAL | ||||
|         authenticator-ad    [2]     AuthorizationData OPTIONAL, | ||||
|         -- For the server on the client side we should keep track of the | ||||
|         -- transit path taken to reach it (if absent -> unknown). | ||||
|         -- | ||||
|         -- We don't learn much more about the server from the KDC. | ||||
|         peer-realm          [3]     Realm OPTIONAL, | ||||
|         transited           [4]     TransitedEncoding OPTIONAL, | ||||
|         pac-verified        [5]     BOOLEAN | ||||
|         -- TODO: Add requested attributes, for gss_set_name_attribute(), which | ||||
|         --       should cause corresponding authz-data elements to be added to | ||||
|         --       any TGS-REQ or to the AP-REQ's Authenticator as appropriate. | ||||
| } | ||||
| -- This is our type for exported composite name tokens for GSS [RFC6680]. | ||||
| -- It's the same as Principal (below) as decorated with (see krb5.opt file and | ||||
| -- asn1_compile usage), except it's not decorated, so the name attributes are | ||||
| -- encoded/decoded. | ||||
| CompositePrincipal ::= [APPLICATION 48] SEQUENCE { | ||||
| 	name[0]			PrincipalName, | ||||
| 	realm[1]		Realm, | ||||
|         nameattrs[2]            PrincipalNameAttrs OPTIONAL | ||||
| } | ||||
|  | ||||
| -- this is not part of RFC1510 | ||||
| -- This is not part of RFC1510/RFC4120.  We use this internally as our | ||||
| -- krb5_principal (which is a typedef of *Principal), and in HDB entries. | ||||
| Principal ::= SEQUENCE { | ||||
| 	name[0]			PrincipalName, | ||||
| 	realm[1]		Realm | ||||
|         -- This will be decorated with a name-attrs field of | ||||
|         -- PrincipalNameAttrs type that doesn't get encoded | ||||
|         -- This will be decorated with an optional nameattrs field of | ||||
|         -- PrincipalNameAttrs type that doesn't get encoded.  Same as | ||||
|         -- CompositePrincipal above, except that CompositePrincipal's | ||||
|         -- nameattrs field does get encoded, while Principal's does not: | ||||
|         -- | ||||
|         -- nameattrs[2]         PrincipalNameAttrs OPTIONAL | ||||
| } | ||||
|  | ||||
| Principals ::= SEQUENCE OF Principal | ||||
|   | ||||
| @@ -70,3 +70,93 @@ _krb5_principalname2krb5_principal (krb5_context context, | ||||
|     *principal = p; | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL | ||||
| _krb5_ticket2krb5_principal(krb5_context context, | ||||
|                             krb5_principal *principal, | ||||
|                             const EncTicketPart *ticket, | ||||
|                             const AuthorizationData *authenticator_ad) | ||||
| { | ||||
|     krb5_error_code ret; | ||||
|     krb5_principal p; | ||||
|  | ||||
|     *principal = NULL; | ||||
|  | ||||
|     ret = _krb5_principalname2krb5_principal(context, | ||||
|                                              &p, | ||||
|                                              ticket->cname, | ||||
|                                              ticket->crealm); | ||||
|     if (ret == 0 && | ||||
|         (p->nameattrs = calloc(1, sizeof(p->nameattrs[0]))) == NULL) | ||||
|         ret = krb5_enomem(context); | ||||
|     if (ret == 0) | ||||
|         p->nameattrs->authenticated = 1; | ||||
|     if (ret == 0 && | ||||
|         (p->nameattrs->source = | ||||
|          calloc(1, sizeof(p->nameattrs->source[0]))) == NULL) | ||||
|         ret = krb5_enomem(context); | ||||
|     if (ret == 0) { | ||||
|         p->nameattrs->source->element = | ||||
|             choice_PrincipalNameAttrSrc_enc_ticket_part; | ||||
|         ret = copy_EncTicketPart(ticket, | ||||
|                                  &p->nameattrs->source->u.enc_ticket_part); | ||||
|         /* NOTE: we don't want to keep a copy of the session key here! */ | ||||
|         if (ret == 0) | ||||
|             der_free_octet_string(&p->nameattrs->source->u.enc_ticket_part.key.keyvalue); | ||||
|     } | ||||
|     if (ret == 0 && authenticator_ad) { | ||||
|         p->nameattrs->authenticator_ad = | ||||
|             calloc(1, sizeof(p->nameattrs->authenticator_ad[0])); | ||||
|         if (p->nameattrs->authenticator_ad == NULL) | ||||
|             ret = krb5_enomem(context); | ||||
|         if (ret == 0) | ||||
|             ret = copy_AuthorizationData(authenticator_ad, | ||||
|                                          p->nameattrs->authenticator_ad); | ||||
|     } | ||||
|  | ||||
|     if (ret == 0) | ||||
|         *principal = p; | ||||
|     else | ||||
|         krb5_free_principal(context, p); | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
| KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL | ||||
| _krb5_kdcrep2krb5_principal(krb5_context context, | ||||
|                             krb5_principal *principal, | ||||
|                             const EncKDCRepPart *kdcrep) | ||||
| { | ||||
|     krb5_error_code ret; | ||||
|     krb5_principal p; | ||||
|  | ||||
|     *principal = NULL; | ||||
|  | ||||
|     ret = _krb5_principalname2krb5_principal(context, | ||||
|                                              &p, | ||||
|                                              kdcrep->sname, | ||||
|                                              kdcrep->srealm); | ||||
|     if (ret == 0 && | ||||
|         (p->nameattrs = calloc(1, sizeof(p->nameattrs[0]))) == NULL) | ||||
|         ret = krb5_enomem(context); | ||||
|     if (ret == 0) | ||||
|         p->nameattrs->authenticated = 1; | ||||
|     if (ret == 0 && | ||||
|         (p->nameattrs->source = | ||||
|          calloc(1, sizeof(p->nameattrs->source[0]))) == NULL) | ||||
|         ret = krb5_enomem(context); | ||||
|     if (ret == 0) { | ||||
|         p->nameattrs->source->element = | ||||
|             choice_PrincipalNameAttrSrc_enc_kdc_rep_part; | ||||
|         ret = copy_EncKDCRepPart(kdcrep, | ||||
|                                  &p->nameattrs->source->u.enc_kdc_rep_part); | ||||
|         /* NOTE: we don't want to keep a copy of the session key here! */ | ||||
|         if (ret == 0) | ||||
|             der_free_octet_string(&p->nameattrs->source->u.enc_kdc_rep_part.key.keyvalue); | ||||
|     } | ||||
|  | ||||
|     if (ret == 0) | ||||
|         *principal = p; | ||||
|     else | ||||
|         krb5_free_principal(context, p); | ||||
|     return ret; | ||||
| } | ||||
|   | ||||
| @@ -837,6 +837,8 @@ EXPORTS | ||||
| 	_krb5_enctype_requires_random_salt | ||||
| 	_krb5_principal2principalname | ||||
| 	_krb5_principalname2krb5_principal | ||||
| 	_krb5_kdcrep2krb5_principal | ||||
| 	_krb5_ticket2krb5_principal | ||||
| 	_krb5_put_int | ||||
| 	_krb5_s4u2self_to_checksumdata | ||||
| 	_krb5_HMAC_MD5_checksum | ||||
|   | ||||
| @@ -351,11 +351,6 @@ krb5_verify_ap_req2(krb5_context context, | ||||
| 					     ap_req->ticket.sname, | ||||
| 					     ap_req->ticket.realm); | ||||
|     if (ret) goto out; | ||||
|     ret = _krb5_principalname2krb5_principal(context, | ||||
| 					     &t->client, | ||||
| 					     t->ticket.cname, | ||||
| 					     t->ticket.crealm); | ||||
|     if (ret) goto out; | ||||
|  | ||||
|     ret = decrypt_authenticator (context, | ||||
| 				 &t->ticket.key, | ||||
| @@ -387,6 +382,27 @@ krb5_verify_ap_req2(krb5_context context, | ||||
| 	} | ||||
|     } | ||||
|  | ||||
|     /* | ||||
|      * The ticket authenticates the client, and conveys naming attributes that | ||||
|      * we want to expose in GSS using RFC6680 APIs. | ||||
|      * | ||||
|      * So we same the ticket enc-part in the client's krb5_principal object | ||||
|      * (note though that the session key will be absent in that copy of the | ||||
|      * ticket enc-part). | ||||
|      */ | ||||
|     ret = _krb5_ticket2krb5_principal(context, &t->client, &t->ticket, | ||||
|                                       ac->authenticator->authorization_data); | ||||
|     if (ret) goto out; | ||||
|  | ||||
|     t->client->nameattrs->peer_realm = | ||||
|         calloc(1, sizeof(t->client->nameattrs->peer_realm[0])); | ||||
|     if (t->client->nameattrs->peer_realm == NULL) { | ||||
|         ret = krb5_enomem(context); | ||||
|         goto out; | ||||
|     } | ||||
|     ret = copy_Realm(&ap_req->ticket.realm, t->client->nameattrs->peer_realm); | ||||
|     if (ret) goto out; | ||||
|  | ||||
|     /* check addresses */ | ||||
|  | ||||
|     if (t->ticket.caddr | ||||
| @@ -1042,6 +1058,8 @@ krb5_rd_req_ctx(krb5_context context, | ||||
| 				  o->ticket->client, | ||||
| 				  o->keyblock, | ||||
| 				  NULL); | ||||
|             if (ret == 0) | ||||
|                 o->ticket->client->nameattrs->pac_verified = 1; | ||||
| 	    if (ret == 0 && (context->flags & KRB5_CTX_F_REPORT_CANONICAL_CLIENT_NAME)) { | ||||
| 		krb5_error_code ret2; | ||||
| 		krb5_principal canon_name; | ||||
|   | ||||
| @@ -752,9 +752,9 @@ _krb5_extract_ticket(krb5_context context, | ||||
|  | ||||
|     /* compare client and save */ | ||||
|     ret = _krb5_principalname2krb5_principal(context, | ||||
| 					     &tmp_principal, | ||||
| 					     rep->kdc_rep.cname, | ||||
| 					     rep->kdc_rep.crealm); | ||||
|                                              &tmp_principal, | ||||
|                                              rep->kdc_rep.cname, | ||||
|                                              rep->kdc_rep.crealm); | ||||
|     if (ret) | ||||
| 	goto out; | ||||
|  | ||||
| @@ -785,12 +785,19 @@ _krb5_extract_ticket(krb5_context context, | ||||
|     creds->client = tmp_principal; | ||||
|  | ||||
|     /* check server referral and save principal */ | ||||
|     ret = _krb5_principalname2krb5_principal (context, | ||||
| 					      &tmp_principal, | ||||
| 					      rep->enc_part.sname, | ||||
| 					      rep->enc_part.srealm); | ||||
|     ret = _krb5_kdcrep2krb5_principal(context, &tmp_principal, &rep->enc_part); | ||||
|     if (ret) | ||||
| 	goto out; | ||||
|  | ||||
|     tmp_principal->nameattrs->peer_realm = | ||||
|         calloc(1, sizeof(tmp_principal->nameattrs->peer_realm[0])); | ||||
|     if (tmp_principal->nameattrs->peer_realm == NULL) { | ||||
|         ret = krb5_enomem(context); | ||||
|         goto out; | ||||
|     } | ||||
|     ret = copy_Realm(&creds->client->realm, tmp_principal->nameattrs->peer_realm); | ||||
|     if (ret) goto out; | ||||
|  | ||||
|     if((flags & EXTRACT_TICKET_ALLOW_SERVER_MISMATCH) == 0){ | ||||
| 	ret = check_server_referral(context, | ||||
| 				    rep, | ||||
|   | ||||
| @@ -828,6 +828,8 @@ HEIMDAL_KRB5_2.0 { | ||||
| 		_krb5_plugin_run_f; | ||||
| 		_krb5_principal2principalname; | ||||
| 		_krb5_principalname2krb5_principal; | ||||
| 		_krb5_kdcrep2krb5_principal; | ||||
| 		_krb5_ticket2krb5_principal; | ||||
| 		_krb5_put_int; | ||||
| 		_krb5_s4u2self_to_checksumdata; | ||||
| 		_krb5_HMAC_MD5_checksum; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user