I’m not sure about this and wonder it may not work. But I have no idea for now 
how to extract the TGT correctly.
encKdcRepPart = new EncAsRepPart();
encKdcRepPart.setAuthTime(cred.getAuthTime());
encKdcRepPart.setCaddr(cred.getClientAddresses());
encKdcRepPart.setEndTime(cred.getEndTime());
encKdcRepPart.setFlags(cred.getTicketFlags());
encKdcRepPart.setKey(cred.getKey());
encKdcRepPart.setRenewTill(cred.getRenewTill());
encKdcRepPart.setSname(cred.getServerName());
encKdcRepPart.setSrealm(cred.getServerName().getRealm());
encKdcRepPart.setStartTime(cred.getStartTime());

From: Christopher Lamb [mailto:christopher.l...@ch.ibm.com]
Sent: Tuesday, May 09, 2017 1:34 PM
To: kerby@directory.apache.org
Subject: Re: Using Kerby kerb-client as an alternative for GSS-API.... Sgt 
Request fails


Hi all

I can now retrieve the Tgt from the creds-cache, and request a Sgt. However I 
am now bouncing between 2 errors. "ERR BAD OPTION" and "ERR GENERIC".

If I create the Tgt with the clientPrincipal, the request is rejected by the 
KDC with "ERR BAD OPTION".

Examining the request with Wireshark shows a cname element in the req-body. 
This is not present in successful requests via GSS-API.

cname
name-type: kRB5-NT-PRINCIPAL (1)
cname-string: 1 item
CNameString: lamb

The KDC log shows "TGT NOT PROXIABLE:" for the failed request.


On the other hand, if I fill the clientPrincipal on the Tgt with null the 
request is rejected by the KDC with "ERR GENERIC".

The cname element is no longer present in the request body (which now looks 
identical that made by GSS-API).

The KDC logs show "ASN.1 structure is missing a required field". I suspect this 
refers to the encrypted "app-req/authenticator/cname",
which debugging shows is now null!


private TgtTicket retrieveCachedTicket(File ccacheFile) throws KrbException {

Ticket ticket = null;
PrincipalName clientPrincipal = null;
EncAsRepPart encKdcRepPart = null;

if (ccacheFile.exists() && ccacheFile.canRead()) {
CredentialCache cCache = new CredentialCache();
try {
cCache.load(ccacheFile);

List<Credential> credentials = cCache.getCredentials();

for (Credential cred : credentials) {
//we only want a tgt
if (cred.getServerName().toString().startsWith("krbtgt")) {
ticket = cred.getTicket();
clientPrincipal = cred.getClientName();

encKdcRepPart = new EncAsRepPart();
encKdcRepPart.setAuthTime(cred.getAuthTime());
encKdcRepPart.setCaddr(cred.getClientAddresses());
encKdcRepPart.setEndTime(cred.getEndTime());
encKdcRepPart.setFlags(cred.getTicketFlags());
encKdcRepPart.setKey(cred.getKey());
encKdcRepPart.setRenewTill(cred.getRenewTill());
encKdcRepPart.setSname(cred.getServerName());
encKdcRepPart.setSrealm(cred.getServerName().getRealm());
encKdcRepPart.setStartTime(cred.getStartTime());
}
}

} catch (IOException e) {
throw new KrbException("Failed to load credentials", e);
}
} else {
throw new IllegalArgumentException("Invalid ccache file, "
+ "does not exist, or is not readable: " + ccacheFile.getAbsolutePath());
}
return new TgtTicket(ticket, encKdcRepPart, clientPrincipal);
}


private void getKerbyServiceTicket() {
try {
File confFileDir = new File("/home/lamb/OTMS/kerberosTesting/");
KrbClient krbClient = new KrbClient(confFileDir);

krbClient.setKdcHost("kdc.acme.com");
krbClient.setAllowUdp(true);
krbClient.setAllowTcp(true);
krbClient.setKdcUdpPort(88);
krbClient.setKdcTcpPort(88);
krbClient.init();

File credsCache = new File("/tmp/krb5cc_9337");

TgtTicket tgtTicket = retrieveCachedTicket(credsCache);

KOptions requestOptions = new KOptions();
requestOptions.add(KrbKdcOption.PROXIABLE, true);
requestOptions.add(KrbKdcOption.FORWARDABLE);
requestOptions.add(KrbKdcOption.CANONICALIZE, true);
requestOptions.add(KrbKdcOption.RENEWABLE_OK, false);
requestOptions.add(KrbOption.USE_TGT, tgtTicket);

requestOptions.add(KrbOption.SERVER_PRINCIPAL, 
"HTTP/app-srv.acme....@acme.com<mailto:HTTP/app-srv.acme....@acme.com>");

SgtTicket sgtTicket = krbClient.requestSgt(requestOptions);


} catch (KrbException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

Rejected Request "BAD OPTION":

tgs-req
pvno: 5
msg-type: krb-tgs-req (12)
padata: 1 item
PA-DATA PA-TGS-REQ
padata-type: kRB5-PADATA-TGS-REQ (1)
padata-value: 6e82023b30820237a003020105a10302010ea20703050000...
ap-req
pvno: 5
msg-type: krb-ap-req (14)
Padding: 0
ap-options: 00000000
0... .... = reserved: False
.0.. .... = use-session-key: False
..0. .... = mutual-required: False
ticket
tkt-vno: 5
realm: ACME.COM
sname
name-type: kRB5-NT-PRINCIPAL (1)
sname-string: 2 items
SNameString: krbtgt
SNameString: ACME.COM
enc-part
etype: eTYPE-AES256-CTS-HMAC-SHA1-96 (18)
kvno: 1
cipher: c2da50b960fdfdc44e098ee243f0aa698cfad82b8867fb98...
authenticator
etype: eTYPE-AES256-CTS-HMAC-SHA1-96 (18)
cipher: 5e944cb16b72c6cb12b830b91e83ca84b3b7eadfb364e7da...
req-body
Padding: 0
kdc-options: 50010000 (forwardable, proxiable, canonicalize)
0... .... = reserved: False
.1.. .... = forwardable: True
..0. .... = forwarded: False
...1 .... = proxiable: True
.... 0... = proxy: False
.... .0.. = allow-postdate: False
.... ..0. = postdated: False
.... ...0 = unused7: False
0... .... = renewable: False
.0.. .... = unused9: False
..0. .... = unused10: False
...0 .... = opt-hardware-auth: False
.... ..0. = request-anonymous: False
.... ...1 = canonicalize: True
0... .... = constrained-delegation: False
..0. .... = disable-transited-check: False
...0 .... = renewable-ok: False
.... 0... = enc-tkt-in-skey: False
.... ..0. = renew: False
.... ...0 = validate: False
cname
name-type: kRB5-NT-PRINCIPAL (1)
cname-string: 1 item
CNameString: lamb
realm: ACME.COM
sname
name-type: kRB5-NT-PRINCIPAL (1)
sname-string: 2 items
SNameString: HTTP
SNameString: app-srv.acme.com
from: 2017-05-09 04:42:12 (UTC)
till: 2017-05-09 12:42:12 (UTC)
nonce: 589063260
etype: 3 items
ENCTYPE: eTYPE-ARCFOUR-HMAC-MD5 (23)
ENCTYPE: eTYPE-AES256-CTS-HMAC-SHA1-96 (18)
ENCTYPE: eTYPE-AES128-CTS-HMAC-SHA1-96 (17)


Thanks

Chris

[Inactive hide details for Christopher Lamb---08/05/2017 18:43:05---Hi Kai With 
the following code I can successfully retrieve a]Christopher Lamb---08/05/2017 
18:43:05---Hi Kai With the following code I can successfully retrieve a TGT 
from my existing

From: Christopher Lamb/Switzerland/IBM@IBMCH
To: kerby@directory.apache.org<mailto:kerby@directory.apache.org>
Date: 08/05/2017 18:43
Subject: Re: Using Kerby kerb-client as an alternative for GSS-API for Kerberos 
Single Sign On.

________________________________



Hi Kai

With the following code I can successfully retrieve a TGT from my existing 
credential cache and use it to request a service ticket!.

Unfortunately the Service Ticket Request is currently failing with "KDC cannot 
accommodate requested option".


private TgtTicket retrieveCachedTicket(File ccacheFile) throws KrbException {

Ticket ticket = null;
PrincipalName clientPrincipal = null;
EncAsRepPart encKdcRepPart = null;

if (ccacheFile.exists() && ccacheFile.canRead()) {
CredentialCache cCache = new CredentialCache();
try {
cCache.load(ccacheFile);

List<Credential> credentials = cCache.getCredentials();

for (Credential cred : credentials) {
//we only want a tgt
if (cred.getServerName().toString().startsWith("krbtgt")) {
ticket = cred.getTicket();
clientPrincipal = cred.getClientName();

encKdcRepPart = new EncAsRepPart();
encKdcRepPart.setAuthTime(cred.getAuthTime());
encKdcRepPart.setCaddr(cred.getClientAddresses());
encKdcRepPart.setEndTime(cred.getEndTime());
encKdcRepPart.setFlags(cred.getTicketFlags());
encKdcRepPart.setKey(cred.getKey());
//encKdcRepPart.setKeyExpiration(); //no method to get from cred
//encKdcRepPart.setLastReq(); //no method to get from cred
//encKdcRepPart.setNonce(); //no method to get from cred
encKdcRepPart.setRenewTill(cred.getRenewTill());
encKdcRepPart.setSname(cred.getServerName());
encKdcRepPart.setSrealm(cred.getServerName().getRealm());
encKdcRepPart.setStartTime(cred.getStartTime());
}
}

} catch (IOException e) {
throw new KrbException("Failed to load credentials", e);
}
} else {
throw new IllegalArgumentException("Invalid ccache file, "
+ "does not exist, or is not readable: " + ccacheFile.getAbsolutePath());
}
return new TgtTicket(ticket, encKdcRepPart, clientPrincipal);
}


private void getKerbyServiceTicket() {
try {
File confFileDir = new File("/home/lamb/OTMS/kerberosTesting/");
KrbClient krbClient = new KrbClient(confFileDir);

krbClient.setKdcHost("kdc.acme.com");
krbClient.setAllowUdp(true);
krbClient.setAllowTcp(true);
krbClient.setKdcUdpPort(88);
krbClient.setKdcTcpPort(88);
krbClient.init();

File credsCache = new File("/tmp/krb5cc_9337");

TgtTicket tgtTicket = retrieveCachedTicket(credsCache);

KOptions requestOptions = new KOptions();
requestOptions.add(KrbKdcOption.PROXIABLE);
requestOptions.add(KrbKdcOption.FORWARDABLE);
requestOptions.add(KrbKdcOption.RENEWABLE_OK);
requestOptions.add(KrbOption.USE_TGT, tgtTicket);
requestOptions.add(KrbOption.SERVER_PRINCIPAL, 
"HTTP/app-srv.acme....@acme.com<mailto:HTTP/app-srv.acme....@acme.com>");

SgtTicket sgtTicket = krbClient.requestSgt(requestOptions);


} catch (KrbException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

Below are extracts from the KDC logs for a failed request from my kerb-client 
code above, and 2 successful requests from GSS-API


Rejected request from Java kerby kerb-client
94117:May 08 17:16:26 kdc.acme.com krb5kdc[2177](info): TGS_REQ (3 etypes {23 
18 17}) 9.164.27.87: TGT NOT PROXIABLE: authtime 0, 
l...@acme.com<mailto:l...@acme.com> for 
HTTP/app-srv.acme....@acme.com<mailto:HTTP/app-srv.acme....@acme.com>, KDC 
can't fulfill requested option

Successful request from Java GSS-API
77320:May 07 08:51:56 kdc.acme.com krb5kdc[2177](info): TGS_REQ (4 etypes {18 
17 16 23}) 9.83.236.240: ISSUE: authtime 1494139147, etypes {rep=18 tkt=18 
ses=18}, l...@acme.com<mailto:l...@acme.com> for 
HTTP/app-srv.acme....@acme.com<mailto:HTTP/app-srv.acme....@acme.com>

Successful request from Python GSS-API
94221:May 08 17:24:18 kdc.acme.com krb5kdc[2177](info): TGS_REQ (8 etypes {18 
17 20 19 16 23 25 26}) 9.164.27.87: ISSUE: authtime 1494256163, etypes {rep=18 
tkt=18 ses=18}, l...@acme.com<mailto:l...@acme.com> for 
HTTP/app-srv.acme....@acme.com<mailto:HTTP/app-srv.acme....@acme.com>


Cheers

Chris




"Zheng, Kai" ---08/05/2017 14:32:29---Got your point. Please read credential 
cache utility codes and see if any API doing so. Sent from iP

From: "Zheng, Kai" <kai.zh...@intel.com<mailto:kai.zh...@intel.com>>
To: "kerby@directory.apache.org<mailto:kerby@directory.apache.org>" 
<kerby@directory.apache.org<mailto:kerby@directory.apache.org>>
Date: 08/05/2017 14:32
Subject: Re: Using Kerby kerb-client as an alternative for GSS-API for Kerberos 
Single Sign On.
________________________________



Got your point. Please read credential cache utility codes and see if any API 
doing so.

Sent from iPhone

在 2017年5月8日,下午8:13,Christopher Lamb 
<christopher.l...@ch.ibm.com<mailto:christopher.l...@ch.ibm.com>> 写道:


Hi Kai

Browsing further through the kerby code, I think I need the opposite of 
KrbClientBase.storeTicket(): for instance a " Public TgtTicket 
retrieveCachedTicket(File ccacheFile)"

Let me see if I can knock something together based on storeTicket()....

Cheers

Chris

[Inactive hide details for "Zheng, Kai" ---08/05/2017 13:09:19---If I remember 
correctly, it first generates a cache with a TGT,]"Zheng, Kai" ---08/05/2017 
13:09:19---If I remember correctly, it first generates a cache with a TGT, then 
do the login test with the tick

From: "Zheng, Kai" <kai.zh...@intel.com<mailto:kai.zh...@intel.com>>
To: "kerby@directory.apache.org<mailto:kerby@directory.apache.org>" 
<kerby@directory.apache.org<mailto:kerby@directory.apache.org>>
Date: 08/05/2017 13:09
Subject: RE: Using Kerby kerb-client as an alternative for GSS-API for Kerberos 
Single Sign On.

________________________________



If I remember correctly, it first generates a cache with a TGT, then do the 
login test with the ticket cache. In your case, you would need to know where is 
the cache file and point it to Kerby client, as the test did.

Regards,
Kai

From: Christopher Lamb [mailto:christopher.l...@ch.ibm.com]
Sent: Monday, May 08, 2017 7:05 PM
To: kerby@directory.apache.org<mailto:kerby@directory.apache.org>
Subject: RE: Using Kerby kerb-client as an alternative for GSS-API for Kerberos 
Single Sign On.


Hi Kai

Thanks, example code is always best.

TicketCacheLoginTest looks like part of the answer, especially the 
storeTicket() function. However (unless I have completely misread the 
test-case), the TGT is not retrieved from the cache, it is only stored there.

In my Single-Sign-On case, the user already has a TGT, which was obtained on 
log in to the workstation (or by kinit), prior to starting my java client. I am 
assuming it should be possible for kerby to use the existing TGT.

Cheers

Chris

[Inactive hide details for "Zheng, Kai" ---08/05/2017 12:45:22---Hi Chris, Both 
dev list should be OK as Kerby folks are also in]"Zheng, Kai" ---08/05/2017 
12:45:22---Hi Chris, Both dev list should be OK as Kerby folks are also in the 
parent one.

From: "Zheng, Kai" 
<kai.zh...@intel.com<mailto:kai.zh...@intel.com><mailto:kai.zh...@intel.com>>
To: 
"kerby@directory.apache.org<mailto:kerby@directory.apache.org><mailto:kerby@directory.apache.org>"
 
<kerby@directory.apache.org<mailto:kerby@directory.apache.org><mailto:kerby@directory.apache.org>>
Date: 08/05/2017 12:45
Subject: RE: Using Kerby kerb-client as an alternative for GSS-API for Kerberos 
Single Sign On.

________________________________



Hi Chris,

Both dev list should be OK as Kerby folks are also in the parent one.

I haven't read your details fully (will do it later), but would make sure if 
you have already checked out the test of TicketCacheLoginTest in the kerby code 
base. In one word, Kerby client surely can consume and use a credential cache 
generated by other tools like MIT kinit. If you see any issue, please report it.

Regards,
Kai

-----Original Message-----
From: Christopher Lamb [mailto:christopher.l...@ch.ibm.com]
Sent: Monday, May 08, 2017 5:09 PM
To: 
kerby@directory.apache.org<mailto:kerby@directory.apache.org><mailto:kerby@directory.apache.org>
Subject: Using Kerby kerb-client as an alternative for GSS-API for Kerberos 
Single Sign On.


Hi all

I hope this is the appropriate mailing list for this type of question. Or would 
it be better on the Directory Developers’ list?

I am considering using Kerby kerb-client as an alternative to Java GSS-API for 
a Java client application in a Kerberos single sign on environment.

In my proof of concept setup I am using FreeIPA clients and servers.  When the 
user logs on to his workstation he is authenticated by the FreeIPA KDC, and  
gets a TGT which is cached in the default credentials cache. When he wishes to 
access services from the application server (which is a Service Principal), the 
TGT in the credentials cache is used to get a Service Ticket, which should also 
be cached in the credentials cache for future use.

With a throwaway Python GSS-API client this worked perfectly. "klist" shows 
both the TGT and the SGT in the credentials cache. But trying to do the same 
thing with Java GSS-API I ran into problems. While the Client is able to 
retrieve a Service Ticket, and thus login to the Service Principal, the SGT is 
not cached. Thus every request to the Service Principal requires KDC 
interaction. Not good.

In my search for alternatives, I came across Kerby kerb-client, and am 
experimenting with it, but so far without success despite much debugging and 
scanning of Kerby code.

Here is the question: Can the Kerby kerb-client be configured to access an 
existing Kerberos credential cache (as opposed to a KeyTab), and to use the TGT 
ticket within, and to cache new service tickets? In this case the existing 
credentials cache is from

So far I have found no config to do so. Searching through the Kerby code I find 
references to things like  ‘credCache’, ‘KRB5_CACHE’, ‘ARMOR_CACHE’.
However in AbstractInternalKrbClient.requestTGT() I can’t find any USE_xxx 
options that seem appropriate for using a credentials cache.

Have I missed something obvious? If so, which options should I be configuring?

Thanks

Chris









Reply via email to