| /* |
| * 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; |
| } |
| |
| } |