blob: 896a6403d60325f12d7e60968ffcbbb7f4054453 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.directory.kerberos.client;
import static org.apache.directory.kerberos.client.ChangePasswordResultCode.KRB5_KPASSWD_SUCCESS;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.File;
import org.apache.directory.api.ldap.model.entry.DefaultEntry;
import org.apache.directory.api.ldap.model.entry.Entry;
import org.apache.directory.api.ldap.model.name.Dn;
import org.apache.directory.kerberos.client.Kinit;
import org.apache.directory.kerberos.credentials.cache.CredentialsCache;
import org.apache.directory.server.annotations.CreateChngPwdServer;
import org.apache.directory.server.annotations.CreateKdcServer;
import org.apache.directory.server.annotations.CreateLdapServer;
import org.apache.directory.server.annotations.CreateTransport;
import org.apache.directory.server.core.annotations.ApplyLdifs;
import org.apache.directory.server.core.annotations.ContextEntry;
import org.apache.directory.server.core.annotations.CreateDS;
import org.apache.directory.server.core.annotations.CreatePartition;
import org.apache.directory.server.core.api.CoreSession;
import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
import org.apache.directory.server.core.integ.FrameworkRunner;
import org.apache.directory.server.core.kerberos.KeyDerivationInterceptor;
import org.apache.directory.server.kerberos.kdc.KerberosTestUtils;
import org.apache.directory.server.protocol.shared.transport.Transport;
import org.apache.directory.server.protocol.shared.transport.UdpTransport;
import org.apache.directory.shared.kerberos.exceptions.KerberosException;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(FrameworkRunner.class)
@CreateDS(name = "KdcConnectionTest-class", enableChangeLog = false,
partitions =
{
@CreatePartition(
name = "example",
suffix = "dc=example,dc=com",
contextEntry=@ContextEntry( entryLdif =
"dn: dc=example,dc=com\n" +
"objectClass: domain\n" +
"dc: example" ) )
},
additionalInterceptors =
{
KeyDerivationInterceptor.class
})
@CreateLdapServer(
transports =
{
@CreateTransport(protocol = "LDAP")
})
@CreateKdcServer(
searchBaseDn = "dc=example,dc=com",
transports =
{
@CreateTransport(protocol = "TCP"),
@CreateTransport(protocol = "UDP")
},
chngPwdServer = @CreateChngPwdServer
(
transports =
{
@CreateTransport(protocol = "TCP"),
@CreateTransport(protocol = "UDP")
}
))
@ApplyLdifs({
// krbtgt
"dn: uid=krbtgt,dc=example,dc=com",
"objectClass: top",
"objectClass: person",
"objectClass: inetOrgPerson",
"objectClass: krb5principal",
"objectClass: krb5kdcentry",
"cn: KDC Service",
"sn: Service",
"uid: krbtgt",
"userPassword: secret",
"krb5PrincipalName: krbtgt/EXAMPLE.COM@EXAMPLE.COM",
"krb5KeyVersionNumber: 0",
// changepwd
"dn: uid=kadmin,dc=example,dc=com",
"objectClass: top",
"objectClass: person",
"objectClass: inetOrgPerson",
"objectClass: krb5principal",
"objectClass: krb5kdcentry",
"cn: changepw Service",
"sn: Service",
"uid: kadmin",
"userPassword: secret",
"krb5PrincipalName: kadmin/changepw@EXAMPLE.COM",
"krb5KeyVersionNumber: 0",
// app service
"dn: uid=ldap,dc=example,dc=com",
"objectClass: top",
"objectClass: person",
"objectClass: inetOrgPerson",
"objectClass: krb5principal",
"objectClass: krb5kdcentry",
"cn: LDAP",
"sn: Service",
"uid: ldap",
"userPassword: randall",
"krb5PrincipalName: ldap/localhost@EXAMPLE.COM",
"krb5KeyVersionNumber: 0"
})
/**
* KDC connection tests
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
public class KdcConnectionTest extends AbstractLdapTestUnit
{
public static final String USERS_DN = "dc=example,dc=com";
private static CoreSession session;
private static KdcConnection conn;
private static String userPassword = "secret";
private static String principalName = "will@EXAMPLE.COM";
private static String serverPrincipal;
@Before
public void setup() throws Exception
{
kdcServer.setSearchBaseDn( USERS_DN );
if ( session == null )
{
session = kdcServer.getDirectoryService().getAdminSession();
createPrincipal( "will", userPassword, principalName );
}
if ( conn == null )
{
KdcConfig config = KdcConfig.getDefaultConfig();
config.setUseUdp( false );
config.setKdcPort( kdcServer.getTcpPort() );
config.setPasswdPort( kdcServer.getChangePwdServer().getTcpPort() );
config.setEncryptionTypes( kdcServer.getConfig().getEncryptionTypes() );
config.setTimeout( Integer.MAX_VALUE );
conn = new KdcConnection( config );
}
if ( serverPrincipal == null )
{
serverPrincipal = KerberosTestUtils.fixServicePrincipalName( "ldap/localhost@EXAMPLE.COM", new Dn(
"uid=ldap,dc=example,dc=com" ), getLdapServer() );
}
}
@Test
public void testGettingInitialTicketTcp() throws Exception
{
TgTicket tgt = conn.getTgt( principalName, userPassword );
assertNotNull( tgt );
assertFalse( tgt.isForwardable() );
}
@Test
public void testGettingInitialTicketUdp() throws Exception
{
KdcConfig config = new KdcConfig();
config.setKdcPort( getUdpPort() );
config.setEncryptionTypes( kdcServer.getConfig().getEncryptionTypes() );
config.setTimeout( Integer.MAX_VALUE );
KdcConnection udpConn = new KdcConnection( config );
TgTicket tgt = udpConn.getTgt( principalName, userPassword );
assertNotNull( tgt );
assertFalse( tgt.isForwardable() );
}
@Test
public void testTgtFlags() throws Exception
{
TgtRequest tgtReq = new TgtRequest();
tgtReq.setClientPrincipal( principalName );
tgtReq.setPassword( userPassword );
tgtReq.setForwardable( true );
TgTicket tgt = conn.getTgt( tgtReq );
assertNotNull( tgt );
assertTrue( tgt.isForwardable() );
}
@Test
public void testGetServiceTicket() throws Exception
{
ServiceTicket rep = conn.getServiceTicket( principalName, userPassword, serverPrincipal );
//System.out.println( rep );
assertNotNull( rep );
}
@Test
public void testKinit() throws Exception
{
File ccFile = File.createTempFile( "credCache-", ".cc" );
Kinit kinit = new Kinit( conn );
kinit.setCredCacheFile( ccFile );
kinit.kinit(principalName, userPassword);
//System.out.println( "Kinit generated file " + ccFile.getAbsolutePath() );
CredentialsCache credCache = CredentialsCache.load( ccFile );
assertNotNull( credCache );
}
@Test
public void testChangePassword() throws Exception
{
String uid = "kayyagari";
String principal = uid + "@EXAMPLE.COM";
createPrincipal( uid, userPassword, principal );
String newPassword = "newPassword";
ChangePasswordResult result = conn.changePassword( principal, userPassword, newPassword );
assertNotNull( result );
assertTrue( KRB5_KPASSWD_SUCCESS.getVal() == result.getCode().getVal() );
try
{
conn.getTgt( principal, userPassword );
fail( "should fail with kerberos exception cause of invalid password" );
}
catch( KerberosException e )
{
//e.printStackTrace();
}
TgTicket tgt = conn.getTgt( principal, newPassword );
assertNotNull( tgt );
}
private String createPrincipal( String uid, String userPassword, String principalName ) throws Exception
{
Entry entry = new DefaultEntry( session.getDirectoryService().getSchemaManager() );
entry.setDn( "uid=" + uid + "," + USERS_DN );
entry.add( "objectClass", "top", "person", "inetOrgPerson", "krb5principal", "krb5kdcentry" );
entry.add( "cn", uid );
entry.add( "sn", uid );
entry.add( "uid", uid );
entry.add( "userPassword", userPassword );
entry.add( "krb5PrincipalName", principalName );
entry.add( "krb5KeyVersionNumber", "0" );
session.add( entry );
return entry.getDn().getName();
}
private int getUdpPort()
{
for ( Transport t : kdcServer.getTransports() )
{
if ( t instanceof UdpTransport )
{
return t.getPort();
}
}
return -1;
}
}