You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by pl...@apache.org on 2017/04/19 06:37:34 UTC
directory-kerby git commit: DIRKRB-621 0x502 version keytab with
multiple entries are not read properly. Contributed by Attila Sasvari.
Repository: directory-kerby
Updated Branches:
refs/heads/trunk 38c50aa73 -> bfc00c357
DIRKRB-621 0x502 version keytab with multiple entries are not read properly. Contributed by Attila Sasvari.
Project: http://git-wip-us.apache.org/repos/asf/directory-kerby/repo
Commit: http://git-wip-us.apache.org/repos/asf/directory-kerby/commit/bfc00c35
Tree: http://git-wip-us.apache.org/repos/asf/directory-kerby/tree/bfc00c35
Diff: http://git-wip-us.apache.org/repos/asf/directory-kerby/diff/bfc00c35
Branch: refs/heads/trunk
Commit: bfc00c357264d817cc0a97c9d685cb58a3c9b3c4
Parents: 38c50aa
Author: plusplusjiajia <ji...@intel.com>
Authored: Wed Apr 19 14:44:55 2017 +0800
Committer: plusplusjiajia <ji...@intel.com>
Committed: Wed Apr 19 14:44:55 2017 +0800
----------------------------------------------------------------------
kerby-kerb/kerb-util/pom.xml | 11 +++
.../kerby/kerberos/kerb/keytab/Keytab.java | 22 +++---
.../kerby/kerberos/kerb/keytab/KeytabEntry.java | 32 +++++++--
.../kerberos/kerb/keytab/KeytabInputStream.java | 8 +--
.../kerberos/kerb/keytab/KeytabEntryTest.java | 67 +++++++++++++++++
.../kerby/kerberos/kerb/util/KeytabTest.java | 71 +++++++++++++++----
.../resources/test_multiple_principles.keytab | Bin 0 -> 1202 bytes
7 files changed, 180 insertions(+), 31 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/bfc00c35/kerby-kerb/kerb-util/pom.xml
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-util/pom.xml b/kerby-kerb/kerb-util/pom.xml
index ab64ad6..3d6fc94 100644
--- a/kerby-kerb/kerb-util/pom.xml
+++ b/kerby-kerb/kerb-util/pom.xml
@@ -42,5 +42,16 @@
<artifactId>kerb-crypto</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <version>1.9.0</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/bfc00c35/kerby-kerb/kerb-util/src/main/java/org/apache/kerby/kerberos/kerb/keytab/Keytab.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-util/src/main/java/org/apache/kerby/kerberos/kerb/keytab/Keytab.java b/kerby-kerb/kerb-util/src/main/java/org/apache/kerby/kerberos/kerb/keytab/Keytab.java
index e7d6251..460f1aa 100644
--- a/kerby-kerb/kerb-util/src/main/java/org/apache/kerby/kerberos/kerb/keytab/Keytab.java
+++ b/kerby-kerb/kerb-util/src/main/java/org/apache/kerby/kerberos/kerb/keytab/Keytab.java
@@ -6,16 +6,16 @@
* 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.
- *
+ * under the License.
+ *
*/
package org.apache.kerby.kerberos.kerb.keytab;
@@ -181,21 +181,27 @@ public final class Keytab implements KrbKeytab {
private List<KeytabEntry> readEntries(KeytabInputStream kis) throws IOException {
List<KeytabEntry> entries = new ArrayList<KeytabEntry>();
- while (kis.available() > 0) {
+ int bytesLeft = kis.available();
+ while (bytesLeft > 0) {
int entrySize = kis.readInt();
if (kis.available() < entrySize) {
throw new IOException("Bad input stream with less data than expected: " + entrySize);
}
- KeytabEntry entry = readEntry(kis);
+ KeytabEntry entry = readEntry(kis, entrySize);
entries.add(entry);
+ int bytesReadForEntry = bytesLeft - kis.available();
+ if (bytesReadForEntry != entrySize) {
+ kis.skipBytes(entrySize - bytesReadForEntry); // reposition to the next keytab entry
+ }
+ bytesLeft = kis.available();
}
return entries;
}
- private KeytabEntry readEntry(KeytabInputStream kis) throws IOException {
+ private KeytabEntry readEntry(KeytabInputStream kis, int entrySize) throws IOException {
KeytabEntry entry = new KeytabEntry();
- entry.load(kis, version);
+ entry.load(kis, version, entrySize);
return entry;
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/bfc00c35/kerby-kerb/kerb-util/src/main/java/org/apache/kerby/kerberos/kerb/keytab/KeytabEntry.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-util/src/main/java/org/apache/kerby/kerberos/kerb/keytab/KeytabEntry.java b/kerby-kerb/kerb-util/src/main/java/org/apache/kerby/kerberos/kerb/keytab/KeytabEntry.java
index 2744aad..8f6f1bd 100644
--- a/kerby-kerb/kerb-util/src/main/java/org/apache/kerby/kerberos/kerb/keytab/KeytabEntry.java
+++ b/kerby-kerb/kerb-util/src/main/java/org/apache/kerby/kerberos/kerb/keytab/KeytabEntry.java
@@ -6,16 +6,16 @@
* 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.
- *
+ * under the License.
+ *
*/
package org.apache.kerby.kerberos.kerb.keytab;
@@ -44,7 +44,8 @@ public class KeytabEntry {
}
- public void load(KeytabInputStream kis, int version) throws IOException {
+ void load(KeytabInputStream kis, int version, int entrySize) throws IOException {
+ int bytesLeft = kis.available();
this.principal = kis.readPrincipal(version);
this.timestamp = kis.readTime();
@@ -52,9 +53,26 @@ public class KeytabEntry {
this.kvno = kis.readByte();
this.key = kis.readKey();
+
+ int entryBytesRead = bytesLeft - kis.available();
+
+ // Some implementations of Kerberos recognize a 32-bit key version at the end of an entry, if record length is
+ // at least 4 bytes longer than the entry and the value of those 32 bits is not 0. If present, this key version
+ // supersedes the 8-bit key version.
+ if (entryBytesRead + 4 <= entrySize) {
+ int tmp = kis.readInt();
+
+ if (tmp != 0) {
+ this.kvno = tmp;
+ }
+ } else if (entryBytesRead != entrySize) {
+ throw new IOException(
+ String.format("Bad input stream with less data read [%d] than expected [%d] for keytab entry.",
+ entryBytesRead, entrySize));
+ }
}
- public void store(KeytabOutputStream kos) throws IOException {
+ void store(KeytabOutputStream kos) throws IOException {
byte[] body = null;
// compute entry body content first so that to get and write the size
@@ -84,7 +102,7 @@ public class KeytabEntry {
return timestamp;
}
- public void writeBody(KeytabOutputStream kos, int version) throws IOException {
+ void writeBody(KeytabOutputStream kos, int version) throws IOException {
kos.writePrincipal(principal, version);
kos.writeTime(timestamp);
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/bfc00c35/kerby-kerb/kerb-util/src/main/java/org/apache/kerby/kerberos/kerb/keytab/KeytabInputStream.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-util/src/main/java/org/apache/kerby/kerberos/kerb/keytab/KeytabInputStream.java b/kerby-kerb/kerb-util/src/main/java/org/apache/kerby/kerberos/kerb/keytab/KeytabInputStream.java
index 111ad14..0b839c7 100644
--- a/kerby-kerb/kerb-util/src/main/java/org/apache/kerby/kerberos/kerb/keytab/KeytabInputStream.java
+++ b/kerby-kerb/kerb-util/src/main/java/org/apache/kerby/kerberos/kerb/keytab/KeytabInputStream.java
@@ -6,16 +6,16 @@
* 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.
- *
+ * under the License.
+ *
*/
package org.apache.kerby.kerberos.kerb.keytab;
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/bfc00c35/kerby-kerb/kerb-util/src/test/java/org/apache/kerby/kerberos/kerb/keytab/KeytabEntryTest.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-util/src/test/java/org/apache/kerby/kerberos/kerb/keytab/KeytabEntryTest.java b/kerby-kerb/kerb-util/src/test/java/org/apache/kerby/kerberos/kerb/keytab/KeytabEntryTest.java
new file mode 100644
index 0000000..2afc33f
--- /dev/null
+++ b/kerby-kerb/kerb-util/src/test/java/org/apache/kerby/kerberos/kerb/keytab/KeytabEntryTest.java
@@ -0,0 +1,67 @@
+/**
+ * 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.kerby.kerberos.kerb.keytab;
+
+import org.apache.kerby.kerberos.kerb.type.KerberosTime;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Matchers;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.mockito.stubbing.Answer;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+@RunWith(MockitoJUnitRunner.class)
+public class KeytabEntryTest {
+ @Test(expected = IOException.class)
+ public void exceptionThrownWhenLoadingInvalidKeytabEntry() throws Exception {
+ KeytabInputStream mockKeytabInputStream = spy(
+ new KeytabInputStream(
+ new ByteArrayInputStream(new String("randomtestarray").getBytes())));
+
+ doAnswer(new Answer<Integer>() {
+ private boolean isFirstCall = true;
+
+ @Override
+ public Integer answer(InvocationOnMock invocationOnMock) throws Throwable {
+ if (isFirstCall) {
+ isFirstCall = false;
+ return 200;
+ }
+ return 20;
+ }
+ }).when(mockKeytabInputStream).available();
+ doReturn(120).when(mockKeytabInputStream).readOctetsCount();
+ doReturn(new byte[]{}).when(mockKeytabInputStream).readCountedOctets();
+ doReturn(null).when(mockKeytabInputStream).readPrincipal(Matchers.any(Integer.class));
+ doReturn(new KerberosTime()).when(mockKeytabInputStream).readTime();
+
+ KeytabEntry keytabEntry = new KeytabEntry();
+ keytabEntry.load(mockKeytabInputStream, 0x502, 100);
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/bfc00c35/kerby-kerb/kerb-util/src/test/java/org/apache/kerby/kerberos/kerb/util/KeytabTest.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-util/src/test/java/org/apache/kerby/kerberos/kerb/util/KeytabTest.java b/kerby-kerb/kerb-util/src/test/java/org/apache/kerby/kerberos/kerb/util/KeytabTest.java
index 11d434a..c312d59 100644
--- a/kerby-kerb/kerb-util/src/test/java/org/apache/kerby/kerberos/kerb/util/KeytabTest.java
+++ b/kerby-kerb/kerb-util/src/test/java/org/apache/kerby/kerberos/kerb/util/KeytabTest.java
@@ -22,15 +22,18 @@ package org.apache.kerby.kerberos.kerb.util;
import org.apache.kerby.kerberos.kerb.keytab.Keytab;
import org.apache.kerby.kerberos.kerb.keytab.KeytabEntry;
import org.apache.kerby.kerberos.kerb.type.base.PrincipalName;
-import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
+import static junit.framework.TestCase.assertEquals;
import static org.assertj.core.api.Assertions.assertThat;
+public class KeytabTest {
+ @Test
+ public void testKeytab() throws IOException {
/*
The principal was created with password '123456'
@@ -45,18 +48,8 @@ KVNO Principal
1 test@SH.INTEL.COM (camellia256-cts-cmac)
1 test@SH.INTEL.COM (camellia128-cts-cmac)
*/
-public class KeytabTest {
-
- private Keytab keytab;
-
- @Before
- public void setUp() throws IOException {
InputStream kis = KeytabTest.class.getResourceAsStream("/test.keytab");
- keytab = Keytab.loadKeytab(kis);
- }
-
- @Test
- public void testKeytab() {
+ Keytab keytab = Keytab.loadKeytab(kis);
assertThat(keytab).isNotNull();
List<PrincipalName> principals = keytab.getPrincipals();
@@ -65,6 +58,60 @@ public class KeytabTest {
for (KeytabEntry ke : entries) {
assertThat(ke.getKvno() == 1).isTrue();
}
+ assertEquals(8, entries.size());
+ }
+
+ @Test
+ public void testKeytabWithMultiplePrinciples() throws IOException {
+/*
+The principal was created with password 'test'
+
+Keytab name: FILE:test.keytab
+KVNO Timestamp Principal
+---- ----------------- --------------------------------------------------------
+ 3 04/11/17 14:16:34 test/examples.com@EXAMPLE.COM (aes256-cts-hmac-sha1-96)
+ 3 04/11/17 14:16:34 test/examples.com@EXAMPLE.COM (aes128-cts-hmac-sha1-96)
+ 3 04/11/17 14:16:34 test/examples.com@EXAMPLE.COM (des3-cbc-sha1)
+ 3 04/11/17 14:16:34 test/examples.com@EXAMPLE.COM (arcfour-hmac)
+ 3 04/11/17 14:16:34 test/examples.com@EXAMPLE.COM (camellia256-cts-cmac)
+ 3 04/11/17 14:16:34 test/examples.com@EXAMPLE.COM (camellia128-cts-cmac)
+ 3 04/11/17 14:16:34 test/examples.com@EXAMPLE.COM (des-hmac-sha1)
+ 3 04/11/17 14:16:34 test/examples.com@EXAMPLE.COM (des-cbc-md5)
+ 3 04/11/17 14:16:51 HTTP/examples.com@EXAMPLE.COM (aes256-cts-hmac-sha1-96)
+ 3 04/11/17 14:16:52 HTTP/examples.com@EXAMPLE.COM (aes128-cts-hmac-sha1-96)
+ 3 04/11/17 14:16:52 HTTP/examples.com@EXAMPLE.COM (des3-cbc-sha1)
+ 3 04/11/17 14:16:52 HTTP/examples.com@EXAMPLE.COM (arcfour-hmac)
+ 3 04/11/17 14:16:52 HTTP/examples.com@EXAMPLE.COM (camellia256-cts-cmac)
+ 3 04/11/17 14:16:52 HTTP/examples.com@EXAMPLE.COM (camellia128-cts-cmac)
+ 3 04/11/17 14:16:52 HTTP/examples.com@EXAMPLE.COM (des-hmac-sha1)
+ 3 04/11/17 14:16:52 HTTP/examples.com@EXAMPLE.COM (des-cbc-md5)
+ */
+ InputStream kis = KeytabTest.class.getResourceAsStream("/test_multiple_principles.keytab");
+ Keytab keytab = Keytab.loadKeytab(kis);
+ assertThat(keytab).isNotNull();
+
+ List<PrincipalName> principals = keytab.getPrincipals();
+ assertEquals(2, keytab.getPrincipals().size());
+
+ int numEntries = keytab.getKeytabEntries(principals.get(0)).size()
+ + keytab.getKeytabEntries(principals.get(1)).size();
+ assertEquals(16, numEntries);
+ }
+
+ @Test
+ public void testSKeytab() throws IOException {
+
+ InputStream kis = KeytabTest.class.getResourceAsStream("/test_multiple_principles.keytab");
+
+ Keytab keytab = Keytab.loadKeytab(kis);
+ assertThat(keytab).isNotNull();
+
+ List<PrincipalName> principals = keytab.getPrincipals();
+ assertEquals(2, keytab.getPrincipals().size());
+
+ int numEntries = keytab.getKeytabEntries(principals.get(0)).size()
+ + keytab.getKeytabEntries(principals.get(1)).size();
+ assertEquals(16, numEntries);
}
public static void main(String[] args) throws IOException {
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/bfc00c35/kerby-kerb/kerb-util/src/test/resources/test_multiple_principles.keytab
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-util/src/test/resources/test_multiple_principles.keytab b/kerby-kerb/kerb-util/src/test/resources/test_multiple_principles.keytab
new file mode 100644
index 0000000..5e4b64b
Binary files /dev/null and b/kerby-kerb/kerb-util/src/test/resources/test_multiple_principles.keytab differ