SPNEGO / ActiveDirectory / AES256: Checksum failed - java

I am trying to use SPNEGO / Kerberos5 authentication with Active Directory 2008 and Java. I followed this guide: http://spnego.sourceforge.net/ - "preflight" went well, but later I get the famous exception:
Exception in thread "main" GSSException: Failure unspecified at GSS-API level (Mechanism level: Checksum failed)
at sun.security.jgss.krb5.Krb5Context.acceptSecContext(Krb5Context.java:856)
at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:342)
at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:285)
at sun.security.jgss.spnego.SpNegoContext.GSS_acceptSecContext(SpNegoContext.java:906)
at sun.security.jgss.spnego.SpNegoContext.acceptSecContext(SpNegoContext.java:556)
at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:342)
at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:285)
at de.meona.auth.spnego.TestSpnegoAes.main(TestSpnegoAes.java:45)
Caused by: KrbException: Checksum failed
at sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType.decrypt(Aes256CtsHmacSha1EType.java:102)
I had a close look at this post, as the problem seems similar:
checksum failed: Kerberos / Spring / Active Directory (2008)
In order to make the problems reproducible, I wrote a small Java class. I was able to single-step to the line where the exception happens. I think it is because the secret service key used for decryption is different from the secret service key the Active Directory used to encrypt the service ticket. How can this be?
public class TestSpnegoAes {
private static Oid spnegoOid = null;
private static String negotiate = "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";
private static GSSManager manager;
// -Dsun.security.krb5.debug=true
// -Djava.security.auth.login.config=login.conf
public static void main(String[] args) throws GSSException, LoginException, PrivilegedActionException {
spnegoOid = new Oid("1.3.6.1.5.5.2");
manager = GSSManager.getInstance();
LoginContext loginContext = new LoginContext("spnego-server");
loginContext.login();
Subject subject = loginContext.getSubject();
GSSCredential serviceCredentials = getServerCredential(subject);
GSSContext context = manager.createContext(serviceCredentials);
byte[] token = Base64.decode(negotiate);
context.acceptSecContext(token, 0, token.length);
}
static GSSCredential getServerCredential(final Subject subject) throws PrivilegedActionException {
final PrivilegedExceptionAction<GSSCredential> action = new PrivilegedExceptionAction<GSSCredential>() {
public GSSCredential run() throws GSSException {
return manager.createCredential(null, GSSCredential.INDEFINITE_LIFETIME, spnegoOid,
GSSCredential.ACCEPT_ONLY);
}
};
return Subject.doAs(subject, action);
}
}
This is my login.conf file:
spnego-server {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
storeKey=true
isInitiator=false
keyTab="file:///C:/Temp/krbtest/meona-service.keytab"
principal=meona-service;
};
I you would like to reproduce, I am happy to give the keytab file as well. It was produced on the PDC using "kpass /out keytab /princ meona-service#meona.intra /pass ... /crypto AES256-SHA1 /ptype KRB5_NT_PRINCIPAL".
As the LoginContext login succeeds, I think the key is recovered successfully.
This is the stdout:
Java config name: null
Native config name: C:\Windows\krb5.ini
Found KeyTab C:\Temp\krbtest\meona-service.keytab for meona-service#meona.intra
Found KeyTab C:\Temp\krbtest\meona-service.keytab for meona-service#meona.intra
Entered Krb5Context.acceptSecContext with state=STATE_NEW
>>> KeyTabInputStream, readName(): MEONA.INTRA
>>> KeyTabInputStream, readName(): meona-service
>>> KeyTab: load() entry length: 75; type: 18
Looking for keys for: meona-service#meona.intra
Added key: 18version: 1
>>> EType: sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType
Exception in thread "main" GSSException: Failure unspecified at GSS-API level (Mechanism level: Checksum failed)
at sun.security.jgss.krb5.Krb5Context.acceptSecContext(Krb5Context.java:856)
If I do not use a keytab, but use pre-authentication, I am able to recover the key, but get the same error later on.
Any ideas?
Here is the krb5.conf I used to generate the SPNEGO negotiate header.
[libdefaults]
default_tkt_enctypes = aes256-cts-hmac-sha1-96 aes128-cts rc4-hmac des3-cbc-sha1 des-cbc-md5 des-cbc-crc
default_tgs_enctypes = aes256-cts-hmac-sha1-96 aes128-cts rc4-hmac des3-cbc-sha1 des-cbc-md5 des-cbc-crc
permitted_enctypes = aes256-cts-hmac-sha1-96 aes128-cts rc4-hmac des3-cbc-sha1 des-cbc-md5 des-cbc-crc
default_realm = MEONA.INTRA
[realms]
MEONA.INTRA = {
kdc = pdc.meona.intra
default_domain = MEONA.INTRA
}
[domain_realm]
.MEONA.INTRA = MEONA.INTRA
I tried different variants (with/without ".intra", uppercase/lowercase), without success. But after changing the ticket encryption (using the settings of the AD service user) to ARC4/HMAC1, everything works as expected - what is the problem with AES256?

I seen this issue while using Java 17 and Spnego
My Keytab-file contained entries for AES128/256. We have enabled AES-token for the AD account through Support. Then I see a error "checksum failed" (KVN and password are not changed).
Support generates keytab via ktpass. I replace it on the server and after restarting the application the error was resolved.
I re-generated the keytab-file via ktab with the new kvn - keytab also worked.
After enabling AES, you need "refresh" the account in AD for change the KVN parameter. And then the integration will work.

Related

Connect to Postgres DB with Kerberos from Java/Windows7

I've looked everywhere and asked loads of people but no one is able to help me so far. I'm trying to connect to a postgres (9.6) database on a remote machine from my windows (7) laptop through a Java (8) application. We use Kerberos for securing access but i have a valid Kerberos account and can create tickets via de Ticket Manager. I can also log on to other 'services' which require Kerberos authentication, although not through java but via a browser.
But whatever i try, i can't get my java program to work. Here's what i've got:
krb5.ini
[libdefaults]
default_realm = <domain>
forwardable = true
kdc_timesync = 1
ccache_type = 4
proxiable = true
dns_lookup_kdc = true
dns_lookup_realm = true
[realms]
<domain>.NET = {
admin_server = <domain-server>
default_domain = <domain>
}
[domain_realm]
.<domain> = <domain>
<domain> = <domain>
.local.nl.<company>.com = <domain>
local.nl.<company>.com = <domain>
[login]
krb4_convert = true
krb4_get_tickets = false
jaas.conf:
pgjdbc {
com.sun.security.auth.module.Krb5LoginModule required
refreshKrb5Config=true
doNotPrompt=false
useTicketCache=false
renewTGT=false
useKeyTab=true
keyTab="<location>/<filename>.keytab"
debug=true
client=true
principal="<username>#<domain>";
};
.keytab file
public class KerberosPostgresClient {
static {
System.setProperty("java.security.krb5.conf","c:/tmp/krb5.ini");
System.setProperty("java.security.krb5.realm","<domain>");
System.setProperty("java.security.krb5.kdc","<domain>");
System.setProperty("javax.security.auth.useSubjectCredsOnly","false");
System.setProperty("java.security.auth.login.config","c:/tmp/jaas.conf"); }
#Test
public void test() throws Exception {
String url = "jdbc:postgresql://<hostname>:<port>/<database>";
Properties properties = new Properties();
properties.setProperty("JAASConfigName", "pgjdbc");
try (Connection conn = DriverManager.getConnection(url, connInfo)) {
conn.createStatement();
} catch (Exception e) {
e.printStackTrace();
}
}
}
The very simple java code can find the keytab, jaas.conf. I created the keytab file on a different machine but with the same principal and password.
When i run the program i see:
Debug is true storeKey false useTicketCache false useKeyTab true doNotPrompt false ticketCache is null isInitiator true KeyTab is c:/tmp/<username>.keytab refreshKrb5Config is true principal is <username>#<domain> tryFirstPass is false useFirstPass is false storePass is false clearPass is false
Refreshing Kerberos configuration
and after a short while i get an exception:
[Krb5LoginModule] authentication failed
Receive timed out
org.postgresql.util.PSQLException: GSS Authentication failed
at org.postgresql.gss.MakeGSS.authenticate(MakeGSS.java:65)
....
Caused by: java.net.SocketTimeoutException: Receive timed out
at java.net.DualStackPlainDatagramSocketImpl.socketReceiveOrPeekData(Native Method)
at java.net.DualStackPlainDatagramSocketImpl.receive0(DualStackPlainDatagramSocketImpl.java:120)
at java.net.AbstractPlainDatagramSocketImpl.receive(AbstractPlainDatagramSocketImpl.java:144)
at java.net.DatagramSocket.receive(DatagramSocket.java:812)
at sun.security.krb5.internal.UDPClient.receive(NetClient.java:206)
at sun.security.krb5.KdcComm$KdcCommunication.run(KdcComm.java:411)
at sun.security.krb5.KdcComm$KdcCommunication.run(KdcComm.java:364)
at java.security.AccessController.doPrivileged(Native Method)
at sun.security.krb5.KdcComm.send(KdcComm.java:348)
at sun.security.krb5.KdcComm.sendIfPossible(KdcComm.java:253)
at sun.security.krb5.KdcComm.send(KdcComm.java:229)
at sun.security.krb5.KdcComm.send(KdcComm.java:200)
at sun.security.krb5.KrbAsReqBuilder.send(KrbAsReqBuilder.java:316)
at sun.security.krb5.KrbAsReqBuilder.action(KrbAsReqBuilder.java:361)
at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:776)
... 45 more
I used to get other exceptions which indicated that it couldn't find the keytab file but with the above setup it seems to work. I can also ping the postgres database from my machine.
I found: Error connecting to PostgreSQL 9.4 with MIT Kerberos via JDBC vs CLI but has no solution
i finally got it working with the following settings in my jaas.conf:
pgjdbc {
com.sun.security.auth.module.Krb5LoginModule required
refreshKrb5Config=true
doNotPrompt=true
useTicketCache=true
renewTGT=true
useKeyTab=true
keyTab="c:/<locationto>/<user>.keytab"
debug=true
client=true
principal="<user>#<domain>";
};
namely the combination of doNotPrompt, useTicketCache, renewTGT finally got it working

Kerberos uses the IP instead of hostname

I'm writing a Java class to access to Solr (with SolrJ) in a Kerberized Cloudera Virtual Machine with a static IP address (I'm using VMWare) from a windows machine. The problem is that Kerberos returns me the following error: Server not found in Kerberos database (7) - UNKNOWN_SERVER.
This is the complete error:
KRBError:
cTime is Sun Mar 06 03:49:00 CET 1994 762922140000
sTime is Thu Dec 29 16:11:14 CET 2016 1483024274000
suSec is 413432
error code is 7
error Message is Server not found in Kerberos database
cname is cloudera#CLOUDERA
sname is HTTP/192.168.59.200#CLOUDERA
msgType is 30
The problem is that Kerberos uses the IP address of the Virtual Machines (in which Kerberos is installed) instead of the FQDN (= quickstart.cloudera). In fact in Kerberos exists only HTTP/quickstart.cloudera#CLOUDERA principal.
I also tried to rename the service principal from HTTP/quickstart.cloudera#CLOUDERA to HTTP/192.168.59.200#CLOUDERA and it worked, but I broke all cloudera's internal services that use the HTTP original principal.
In the windows hosts file I put: 192.168.59.200 quickstart.cloudera
This is my krb5.conf:
[libdefaults]
default_realm = CLOUDERA
rdns = true
dns_lookup_kdc = true
dns_lookup_realm = true
dns_canonicalize_hostname = true
ignore_acceptor_hostname = true
ticket_lifetime = 86400
renew_lifetime = 604800
forwardable = true
default_tgs_enctypes = rc4-hmac
default_tkt_enctypes = rc4-hmac
permitted_enctypes = rc4-hmac
udp_preference_limit = 1
kdc_timeout = 3000
[realms]
CLOUDERA = {
kdc = quickstart.cloudera
admin_server = quickstart.cloudera
default_domain = quickstart.cloudera
}
[domain_realm]
.cloudera = CLOUDERA
quickstart.cloudera = CLOUDERA
This is my jaas.conf:
com.sun.security.jgss.initiate {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
keyTab="C:/Binaries/Kerberos/cloudera.keytab"
doNotPrompt=true
useTicketCache=false
storeKey=true
debug=true
principal="cloudera#CLOUDERA";
};
And this is my java test code:
#Test
public void testSecureSolr() {
try {
System.setProperty("sun.security.krb5.debug", "true");
System.setProperty("java.security.krb5.conf","C:\\Binaries\\Kerberos\\krb5.conf");
System.setProperty("java.security.auth.login.config","C:\\Binaries\\Kerberos\\jaas.conf");
LOG.info("-------------------------------------------------");
LOG.info("------------------- TESTS SOLR ------------------");
LOG.info("-------------------------------------------------");
HttpClientUtil.setConfigurer(new Krb5HttpClientConfigurer());
SolrServer solrServer = new HttpSolrServer(CLUSTER_URI_SOLR);
SolrPingResponse pingResponse = solrServer.ping();
LOG.info("Solr Ping Status: "+ pingResponse.getStatus());
LOG.info("Solr Ping Time: "+ pingResponse.getQTime());
} catch (SolrServerException | IOException e) {
e.printStackTrace();
}
}
Any suggestion? Thanks.

SASL LOGIN authentication failed: UGFzc3dvcmQ6

CentOS6.6, Postfix, dovecot 2.0.9 and MySQL 5.1.73
dovecot configuration (/etc/dovecot/dovecot-sql.conf.ext):
driver = mysql
connect = host=127.0.0.1 dbname=postfix user=root password=lingo
default_pass_scheme = SHA512
password_query = SELECT email as user, password FROM virtual_user WHERE email='%u';
MySQL database:
mysql> SELECT email as user, password FROM virtual_user WHERE email='lingo.lin1#radicasys.com';
+--------------------------+------------------------------------------------------------------------------------------------------------+
| user | password |
+--------------------------+------------------------------------------------------------------------------------------------------------+
| lingo.lin1#example.com | 0da3b4b0385c432a800ca15eae1a8485e5f7abad7b70b4e1c2b9cf15f68afd256cedb2029c6f7cec09e1221e6b10142081e1bb8e5c |
+--------------------------+------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
The password is generated by commons-codec, Java code:
System.out.println(DigestUtils.sha512Hex("lingo".getBytes()));
//print :0da3b4b0385c432a800ca15eae1a8485e5f7abad7b70b4e1c2b9cf15f68afd256cedb2029c6f7cec09e1221e6b10142081e1bb8e5c
Now I wrote some Java-code to authenticate:
public static void sendEmail() throws EmailException, GeneralSecurityException {
SimpleEmail email = new SimpleEmail();
// smtp host
email.setHostName("192.168.15.139");
email.setSmtpPort(25);
email.setDebug(true);
// DigestUtils.sha512Hex("lingo".getBytes())
email.setAuthentication("lingo.lin1#example.com", "lingo");
email.setStartTLSEnabled(true);
MailSSLSocketFactory socketFactory = new MailSSLSocketFactory();
socketFactory.setTrustAllHosts(true);
Properties propsSSL = email.getMailSession().getProperties();
propsSSL.put("mail.smtp.port", "465");
propsSSL.put("mail.smtp.ssl.checkserveridentity", "false");
propsSSL.put("mail.smtp.ssl.socketFactory", socketFactory);
email.addTo("lingo.lin#qamail.rimanggis.com", "John Doe");
email.setFrom("lingo.lin#radicasys.com", "Me");
email.setSubject("Test message");
email.setMsg("This is a simple test of commons-email");
email.send();
System.out.println("success");
}
public static void main(String[] args) throws Exception {
SendEmailTest.sendEmail();
// System.out.println(DigestUtils.sha512Hex("lingo".getBytes()));
}
But it fails with following error:
Sep 12 13:30:51 localhost dovecot: auth: Debug: sql(lingo.lin1#radicasys.com,192.168.15.243): query: SELECT email as user, password FROM virtual_user WHERE email='lingo.lin1#radicasys.com';
Sep 12 13:30:51 localhost dovecot: auth: Error: sql(lingo.lin1#radicasys.com,192.168.15.243): Password in passdb is not in expected scheme SHA512
Sep 12 13:30:53 localhost postfix/smtpd[1872]: warning: unknown[192.168.15.243]: SASL LOGIN authentication failed: UGFzc3dvcmQ6
Sep 12 13:30:53 localhost dovecot: auth: Debug: client out: FAIL#0115#011user=lingo.lin1#radicasys.com
Sep 12 13:30:53 localhost postfix/smtpd[1872]: lost connection after AUTH from unknown[192.168.15.243]
Sep 12 13:30:53 localhost postfix/smtpd[1872]: disconnect from unknown[192.168.15.243]
How can I fix the authentication?
This is a dovecot configuration issue. Dovecot knows two hash encodings, the "traditional" hex encoding (ie. SHA512.HEX) and Base64-encoding (ie. SHA512.b64). The latter is more space-efficient when stored as strings and default in Dovecot. An example for generating the hash with sha512, sha512.b64 and sha512.hex encodings:
$ doveadm pw -p lingo -s sha512
{SHA512}DaO0sDhcQyqADKFerhqEheX3q617cLThwrnPFfaK/SVs7bICnG987AnhIh5rEBQggeG7jlyAL7l+g8iTwo2GFA==
$ doveadm pw -p lingo -s sha512.b64
{SHA512.b64}DaO0sDhcQyqADKFerhqEheX3q617cLThwrnPFfaK/SVs7bICnG987AnhIh5rEBQggeG7jlyAL7l+g8iTwo2GFA==
$ doveadm pw -p lingo -s sha512.hex
{SHA512.HEX}0da3b4b0385c432a800ca15eae1a8485e5f7abad7b70b4e1c2b9cf15f68afd256cedb2029c6f7cec09e1221e6b10142081e1bb8e5c802fb97e83c893c28d8614
Use default_pass_scheme = SHA512.HEX if you create hex-encoded passwords hashes in Java. The better solution would be to use Dovecot's {SCHEME}hash encoding instead of setting the default_pass_scheme, though: doing so, you can easily change/upgrade the hash method later without invalidating all user's passwords at once. An example for the hash you used in this scheme:
{SHA512.hex}0da3b4b0385c432a800ca15eae1a8485e5f7abad7b70b4e1c2b9cf15f68afd256cedb2029c6f7cec09e1221e6b10142081e1bb8e5c
Finally: plain hashing of passwords is never save, also not when using large SHA512 hashes. Never store unsalted password hashes, you're vulnerable to rainbow table attacks if the database leaks.
i generate by this code:
private String SHA(final String strText, final String strType) {
String strResult = null;
if (strText != null && strText.length() > 0) {
try {
MessageDigest messageDigest = MessageDigest.getInstance(strType);
messageDigest.update(strText.getBytes());
byte byteBuffer[] = messageDigest.digest();
StringBuffer strHexString = new StringBuffer();
for (int i = 0; i < byteBuffer.length; i++) {
String hex = Integer.toHexString(0xff & byteBuffer[i]);
if (hex.length() == 1) {
strHexString.append('0');
}
strHexString.append(hex);
}
strResult = strHexString.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
return strResult;
}
public static void main(String[] args) {
EncryptUtils et=new EncryptUtils();
String pas=et.SHA512("lingo");
System.out.println("{SHA512.HEX}"+pas);
}

Undefined CommonName in certificate

So far, I've been working with a certificate which I added to a SoapUI 5.2 project and which gave me access to a pre-production server. However, now that I'm ready to move to a production environment, I'm trying to check the new production certificate with SoapUI, but I'm getting the next error:
WARN:Using fallback method to load keystore/truststore due to: Invalid keystore format
ERROR:An error occurred [java.lang.NullPointerException], see error log for details
And the error log says:
ERROR:Could not load keystore/truststore
ERROR:java.lang.NullPointerException
java.lang.NullPointerException
at org.apache.commons.ssl.KeyStoreBuilder.build(KeyStoreBuilder.java:176)
at org.apache.commons.ssl.KeyStoreBuilder.build(KeyStoreBuilder.java:97)
at org.apache.commons.ssl.KeyStoreBuilder.build(KeyStoreBuilder.java:88)
at com.eviware.soapui.impl.wsdl.support.wss.crypto.KeyMaterialWssCrypto.fallbackLoad(KeyMaterialWssCrypto.java:206)
at com.eviware.soapui.impl.wsdl.support.wss.crypto.KeyMaterialWssCrypto.load(KeyMaterialWssCrypto.java:168)
at com.eviware.soapui.impl.wsdl.support.wss.crypto.KeyMaterialWssCrypto.getStatus(KeyMaterialWssCrypto.java:216)
at com.eviware.soapui.impl.wsdl.panels.project.WSSTabPanel$CryptoTableModel.getValueAt(WSSTabPanel.java:643)
at javax.swing.JTable.getValueAt(Unknown Source)
at javax.swing.JTable.prepareRenderer(Unknown Source)
...
The only difference I found between the pre-production and production certificates was that the latter did not have the CommonName field defined.
I know that field is not mandatory, so how is that possible? How can I solve this problem without asking for a new certificate? That's not an option.
Any suggestion would be appreciated.
I check the pom.xml of SOAPUI project for 5.2 versión, and it use not-yet-commons-ssl versión 0.3.11:
<dependency>
<groupId>commons-ssl</groupId>
<artifactId>not-yet-commons-ssl</artifactId>
<version>0.3.11</version>
</dependency>
And If you check the build method for org.apache.commons.ssl.KeyStoreBuilder class as the exception thrown in your error log you'll see:
public static KeyStore build(byte[] jksOrCerts, byte[] privateKey,
char[] jksPassword, char[] keyPassword)
throws IOException, CertificateException, KeyStoreException,
NoSuchAlgorithmException, InvalidKeyException,
NoSuchProviderException, ProbablyBadPasswordException,
UnrecoverableKeyException {
...
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(null, jksPassword);
Iterator keysIt = keys.iterator();
Iterator chainsIt = chains.iterator();
int i = 1;
while (keysIt.hasNext() && chainsIt.hasNext()) {
Key key = (Key) keysIt.next();
Certificate[] c = (Certificate[]) chainsIt.next();
X509Certificate theOne = buildChain(key, c);
String alias = "alias_" + i++;
// The theOne is not null, then our chain was probably altered.
// Need to trim out the newly introduced null entries at the end of
// our chain.
if (theOne != null) {
c = Certificates.trimChain(c);
alias = Certificates.getCN(theOne);
/* line 176 */ alias = alias.replace(' ', '_');
}
ks.setKeyEntry(alias, key, keyPassword, c);
}
return ks;
}
}
So seems that you're right and the problem is that your certificate has no common name, so org.apache.commons.ssl.Certificates.getCN(X509Certificate) returns null as alias and then alias.replace is throwing the NPE.
alias = Certificates.getCN(theOne);
/* line 176 */ alias = alias.replace(' ', '_');
I don't see nothing that says that Common Name is mandatory in RFC5280, however various code/software use it for different purposes as not-yet-commons-ssl does.
Your certificate is probably right but you can't use it with SOAPUI 5.2 version to test your environment if it hasn't the CN, so if you want to use SOAPUI to test your environment I think that you've to reissue the certificate generating a CSR with CN. Or you can report the problem to http://juliusdavies.ca/commons-ssl/ and then ask to SOAPUI to include the latest version...
Hope this helps,

KrbException "Message Stream Modified (41)" when connecting to SMB share using Kerberos

I'm having some issues with Kerberos authentication to perform file management with JCifs (Kerberos extension version 1.3.17)
This is my current configuration of krb5.conf:
[libdefaults]
default_realm = <REALM_NAME_UPPERCASE>
udp_preference_limit = 1
[realms]
<REALM_NAME_UPPERCASE> = {
kdc = <DOMAIN_NAME_UPPERCASE>:88
admin_server = <DOMAIN_NAME_UPPERCASE>
default_domain = <DOMAIN_NAME_UPPERCASE>
}
[domain_realm]
.<domain_name> = <REALM_NAME_UPPERCASE>
<domain_name> = <REALM_NAME_UPPERCASE>
[appdefaults]
kinit = {
renewable = true
forwardable = true
}
And this is code authenticating the user and then trying to find a file on a fileserver in the network:
public static void main (String[] args) throws Exception {
Subject subject = new Subject();
System.setProperty("java.security.krb5.conf", "C:/krb5.conf");
System.setProperty("sun.security.krb5.debug", "true");
Map<String, Object> state = new HashMap<String, Object>();
state.put("javax.security.auth.login.name", "USERNAME");
state.put("javax.security.auth.login.password", "PASSWORD".toCharArray());
Map<String, Object> options = new HashMap<String, Object>();
options.put("debug", "true");
options.put("useFirstPass", "true");
Krb5LoginModule login = new Krb5LoginModule();
login.initialize(subject, null, state, options);
if (login.login()) {
login.commit();
}
String path = "file://HOST/242269/"; // existing file server folder
Kerb5Authenticator kerberosAuthenticator = new Kerb5Authenticator(subject);
SmbFile smbFile = new SmbFile(path, kerberosAuthenticator);
SmbFile[] files = smbFile.listFiles();
for (SmbFile file : files) {
System.out.println(file);
}
}
Now, when I run this code, it says it can authenticate the user with those credentials (when I change the credentials, authentication fails) and it creates a ticket for this user.
When I later on try to retrieve the content of a file directory over CIFS, it gives me the following error:
GSSException: No valid credentials provided (Mechanism level: Message stream modified (41))
at sun.security.jgss.krb5.Krb5Context.initSecContext(Unknown Source)
at sun.security.jgss.GSSContextImpl.initSecContext(Unknown Source)
at sun.security.jgss.GSSContextImpl.initSecContext(Unknown Source)
at jcifs.smb.SpnegoContext.initSecContext(SpnegoContext.java:80)
at jcifs.smb.Kerb5Authenticator.setup(Kerb5Authenticator.java:196)
at jcifs.smb.Kerb5Authenticator.access$000(Kerb5Authenticator.java:30)
at jcifs.smb.Kerb5Authenticator$1.run(Kerb5Authenticator.java:168)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Unknown Source)
at jcifs.smb.Kerb5Authenticator.sessionSetup(Kerb5Authenticator.java:166)
at jcifs.smb.SmbSession.sessionSetup(SmbSession.java:320)
at jcifs.smb.SmbSession.send(SmbSession.java:239)
at jcifs.smb.SmbTree.treeConnect(SmbTree.java:176)
at jcifs.smb.SmbFile.doConnect(SmbFile.java:925)
at jcifs.smb.SmbFile.connect(SmbFile.java:974)
at jcifs.smb.SmbFile.connect0(SmbFile.java:890)
at jcifs.smb.SmbFile.resolveDfs(SmbFile.java:669)
at jcifs.smb.SmbFile.send(SmbFile.java:783)
at jcifs.smb.SmbFile.doFindFirstNext(SmbFile.java:2009)
at jcifs.smb.SmbFile.doEnum(SmbFile.java:1758)
at jcifs.smb.SmbFile.listFiles(SmbFile.java:1735)
at jcifs.smb.SmbFile.listFiles(SmbFile.java:1668)
You can find the complete error log here (some details are obfuscated)
Could someone please get me going in the right direction as to what I'm doing wrong here?
Uppercase of the realm is very important to avoid "Exception: krb_error 41 Message stream modified (41)".
See http://sourceforge.net/p/spnego/discussion/1003769/thread/99b3ff67/
Hate to necrobump but ran into the same problem when launching Spark and Zeppelin inside a Docker container, with the master being a remote Kerberos-enabled YARN cluster. However, in this case, the realm name uppercase/lowercase was not the problem.
After a few hours, I found this thread which suggests removing the following line from the krb5.conf file:
renew_lifetime = 7d
And that solved the issue. Hope this helps someone.
Alternative (and better) answer to removing the renew_lifetime = 7d line in the config, is by allowing the principal to do renewals. In CentOS 7, an example command would be the following:
kadmin -p admin/admin#EXAMPLE.COM
where I assume that admin/admin#EXAMPLE.COM is the Administrator principal, then:
modprinc -maxrenewlife 90day +allow_renewable your_service#EXAMPLE.COM
where I assume the principal for the service that causes the problems is your_service#EXAMPLE.COM; and the 90day renew life is arbitrary.
This solves the issue without removing the renew_lifetime=7d from the krb5.conf file!

Categories