Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
812a3eaf
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
4
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_jdk
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
812a3eaf
编写于
4月 20, 2011
作者:
W
weijun
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
6894072: always refresh keytab
Reviewed-by: valeriep
上级
666a0d6c
变更
27
隐藏空白更改
内联
并排
Showing
27 changed file
with
1330 addition
and
368 deletion
+1330
-368
src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java
...classes/com/sun/security/auth/module/Krb5LoginModule.java
+90
-41
src/share/classes/javax/security/auth/kerberos/JavaxSecurityAuthKerberosAccessImpl.java
...ty/auth/kerberos/JavaxSecurityAuthKerberosAccessImpl.java
+38
-0
src/share/classes/javax/security/auth/kerberos/KerberosKey.java
...are/classes/javax/security/auth/kerberos/KerberosKey.java
+6
-4
src/share/classes/javax/security/auth/kerberos/KeyTab.java
src/share/classes/javax/security/auth/kerberos/KeyTab.java
+230
-0
src/share/classes/sun/misc/JavaxSecurityAuthKerberosAccess.java
...are/classes/sun/misc/JavaxSecurityAuthKerberosAccess.java
+43
-0
src/share/classes/sun/misc/SharedSecrets.java
src/share/classes/sun/misc/SharedSecrets.java
+14
-0
src/share/classes/sun/security/jgss/krb5/Krb5AcceptCredential.java
.../classes/sun/security/jgss/krb5/Krb5AcceptCredential.java
+15
-40
src/share/classes/sun/security/jgss/krb5/Krb5Util.java
src/share/classes/sun/security/jgss/krb5/Krb5Util.java
+164
-29
src/share/classes/sun/security/jgss/krb5/SubjectComber.java
src/share/classes/sun/security/jgss/krb5/SubjectComber.java
+43
-30
src/share/classes/sun/security/krb5/Config.java
src/share/classes/sun/security/krb5/Config.java
+0
-1
src/share/classes/sun/security/krb5/EncryptionKey.java
src/share/classes/sun/security/krb5/EncryptionKey.java
+2
-8
src/share/classes/sun/security/krb5/KrbAsRep.java
src/share/classes/sun/security/krb5/KrbAsRep.java
+21
-16
src/share/classes/sun/security/krb5/KrbAsReqBuilder.java
src/share/classes/sun/security/krb5/KrbAsReqBuilder.java
+48
-44
src/share/classes/sun/security/krb5/internal/ktab/KeyTab.java
...share/classes/sun/security/krb5/internal/ktab/KeyTab.java
+121
-96
src/share/classes/sun/security/ssl/ServerHandshaker.java
src/share/classes/sun/security/ssl/ServerHandshaker.java
+6
-5
src/share/classes/sun/security/ssl/krb5/Krb5ProxyImpl.java
src/share/classes/sun/security/ssl/krb5/Krb5ProxyImpl.java
+3
-3
src/windows/classes/sun/security/krb5/internal/tools/Kinit.java
...ndows/classes/sun/security/krb5/internal/tools/Kinit.java
+7
-13
src/windows/classes/sun/security/krb5/internal/tools/Klist.java
...ndows/classes/sun/security/krb5/internal/tools/Klist.java
+10
-10
src/windows/classes/sun/security/krb5/internal/tools/Ktab.java
...indows/classes/sun/security/krb5/internal/tools/Ktab.java
+2
-2
test/sun/security/krb5/auto/Context.java
test/sun/security/krb5/auto/Context.java
+33
-5
test/sun/security/krb5/auto/DynamicKeytab.java
test/sun/security/krb5/auto/DynamicKeytab.java
+140
-0
test/sun/security/krb5/auto/KDC.java
test/sun/security/krb5/auto/KDC.java
+44
-12
test/sun/security/krb5/auto/KeyTabCompat.java
test/sun/security/krb5/auto/KeyTabCompat.java
+90
-0
test/sun/security/krb5/auto/LoginModuleOptions.java
test/sun/security/krb5/auto/LoginModuleOptions.java
+2
-2
test/sun/security/krb5/auto/SSL.java
test/sun/security/krb5/auto/SSL.java
+55
-5
test/sun/security/krb5/auto/TwoPrinces.java
test/sun/security/krb5/auto/TwoPrinces.java
+102
-0
test/sun/security/krb5/ktab/KeyTabIndex.java
test/sun/security/krb5/ktab/KeyTabIndex.java
+1
-2
未找到文件。
src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java
浏览文件 @
812a3eaf
/*
/*
* Copyright (c) 2000, 201
0
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 201
1
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -395,7 +395,13 @@ public class Krb5LoginModule implements LoginModule {
...
@@ -395,7 +395,13 @@ public class Krb5LoginModule implements LoginModule {
private
boolean
succeeded
=
false
;
private
boolean
succeeded
=
false
;
private
boolean
commitSucceeded
=
false
;
private
boolean
commitSucceeded
=
false
;
private
String
username
;
private
String
username
;
// Encryption keys calculated from password. Assigned when storekey == true
// and useKeyTab == false (or true but not found)
private
EncryptionKey
[]
encKeys
=
null
;
private
EncryptionKey
[]
encKeys
=
null
;
KeyTab
ktab
=
null
;
private
Credentials
cred
=
null
;
private
Credentials
cred
=
null
;
private
PrincipalName
principal
=
null
;
private
PrincipalName
principal
=
null
;
...
@@ -663,28 +669,49 @@ public class Krb5LoginModule implements LoginModule {
...
@@ -663,28 +669,49 @@ public class Krb5LoginModule implements LoginModule {
(
krb5PrincName
.
toString
(),
(
krb5PrincName
.
toString
(),
PrincipalName
.
KRB_NT_PRINCIPAL
);
PrincipalName
.
KRB_NT_PRINCIPAL
);
}
}
/*
* Before dynamic KeyTab support (6894072), here we check if
* the keytab contains keys for the principal. If no, keytab
* will not be used and password is prompted for.
*
* After 6894072, we normally don't check it, and expect the
* keys can be populated until a real connection is made. The
* check is still done when isInitiator == true, where the keys
* will be used right now.
*
* Probably tricky relations:
*
* useKeyTab is config flag, but when it's true but the ktab
* does not contains keys for principal, we would use password
* and keep the flag unchanged (for reuse?). In this method,
* we use (ktab != null) to check whether keytab is used.
* After this method (and when storeKey == true), we use
* (encKeys == null) to check.
*/
if
(
useKeyTab
)
{
if
(
useKeyTab
)
{
encKeys
=
ktab
=
(
keyTabName
==
null
)
EncryptionKey
.
acquireSecretKeys
(
principal
,
keyTabName
);
?
KeyTab
.
getInstance
()
:
KeyTab
.
getInstance
(
new
File
(
keyTabName
));
if
(
debug
)
{
if
(
isInitiator
)
{
if
(
encKeys
!=
null
)
if
(
Krb5Util
.
keysFromJavaxKeyTab
(
ktab
,
principal
).
length
System
.
out
.
println
==
0
)
{
(
"principal's key obtained from the keytab"
);
ktab
=
null
;
else
if
(
debug
)
{
System
.
out
.
println
System
.
out
.
println
(
"Key for the principal "
+
(
"Key for the principal "
+
principal
+
principal
+
" not available in "
+
" not available in "
+
((
keyTabName
==
null
)
?
((
keyTabName
==
null
)
?
"default key tab"
:
keyTabName
));
"default key tab"
:
keyTabName
));
}
}
}
}
}
}
KrbAsReqBuilder
builder
;
KrbAsReqBuilder
builder
;
// We can't get the key from the keytab so prompt
if
(
encKeys
==
null
)
{
if
(
ktab
==
null
)
{
promptForPass
(
getPasswdFromSharedState
);
promptForPass
(
getPasswdFromSharedState
);
builder
=
new
KrbAsReqBuilder
(
principal
,
password
);
builder
=
new
KrbAsReqBuilder
(
principal
,
password
);
if
(
isInitiator
)
{
if
(
isInitiator
)
{
...
@@ -693,9 +720,13 @@ public class Krb5LoginModule implements LoginModule {
...
@@ -693,9 +720,13 @@ public class Krb5LoginModule implements LoginModule {
// updated with PA info
// updated with PA info
cred
=
builder
.
action
().
getCreds
();
cred
=
builder
.
action
().
getCreds
();
}
}
encKeys
=
builder
.
getKeys
();
if
(
storeKey
)
{
encKeys
=
builder
.
getKeys
();
// When encKeys is empty, the login actually fails.
// For compatibility, exception is thrown in commit().
}
}
else
{
}
else
{
builder
=
new
KrbAsReqBuilder
(
principal
,
encKeys
);
builder
=
new
KrbAsReqBuilder
(
principal
,
ktab
);
if
(
isInitiator
)
{
if
(
isInitiator
)
{
cred
=
builder
.
action
().
getCreds
();
cred
=
builder
.
action
().
getCreds
();
}
}
...
@@ -705,10 +736,15 @@ public class Krb5LoginModule implements LoginModule {
...
@@ -705,10 +736,15 @@ public class Krb5LoginModule implements LoginModule {
if
(
debug
)
{
if
(
debug
)
{
System
.
out
.
println
(
"principal is "
+
principal
);
System
.
out
.
println
(
"principal is "
+
principal
);
HexDumpEncoder
hd
=
new
HexDumpEncoder
();
HexDumpEncoder
hd
=
new
HexDumpEncoder
();
for
(
int
i
=
0
;
i
<
encKeys
.
length
;
i
++)
{
if
(
ktab
!=
null
)
{
System
.
out
.
println
(
"EncryptionKey: keyType="
+
System
.
out
.
println
(
"Will use keytab"
);
encKeys
[
i
].
getEType
()
+
" keyBytes (hex dump)="
+
}
else
if
(
storeKey
)
{
hd
.
encodeBuffer
(
encKeys
[
i
].
getBytes
()));
for
(
int
i
=
0
;
i
<
encKeys
.
length
;
i
++)
{
System
.
out
.
println
(
"EncryptionKey: keyType="
+
encKeys
[
i
].
getEType
()
+
" keyBytes (hex dump)="
+
hd
.
encodeBuffer
(
encKeys
[
i
].
getBytes
()));
}
}
}
}
}
...
@@ -989,8 +1025,8 @@ public class Krb5LoginModule implements LoginModule {
...
@@ -989,8 +1025,8 @@ public class Krb5LoginModule implements LoginModule {
kerbTicket
=
Krb5Util
.
credsToTicket
(
cred
);
kerbTicket
=
Krb5Util
.
credsToTicket
(
cred
);
}
}
if
(
storeKey
)
{
if
(
storeKey
&&
encKeys
!=
null
)
{
if
(
encKeys
==
null
||
encKeys
.
length
<
=
0
)
{
if
(
encKeys
.
length
=
=
0
)
{
succeeded
=
false
;
succeeded
=
false
;
throw
new
LoginException
(
"Null Server Key "
);
throw
new
LoginException
(
"Null Server Key "
);
}
}
...
@@ -1006,10 +1042,11 @@ public class Krb5LoginModule implements LoginModule {
...
@@ -1006,10 +1042,11 @@ public class Krb5LoginModule implements LoginModule {
}
}
}
}
// Let us add the kerbClientPrinc,kerbTicket and
k
erbKey (if
// Let us add the kerbClientPrinc,kerbTicket and
KeyTab/K
erbKey (if
// storeKey is true)
// storeKey is true)
if
(!
princSet
.
contains
(
kerbClientPrinc
))
if
(!
princSet
.
contains
(
kerbClientPrinc
))
{
princSet
.
add
(
kerbClientPrinc
);
princSet
.
add
(
kerbClientPrinc
);
}
// add the TGT
// add the TGT
if
(
kerbTicket
!=
null
)
{
if
(
kerbTicket
!=
null
)
{
...
@@ -1018,19 +1055,29 @@ public class Krb5LoginModule implements LoginModule {
...
@@ -1018,19 +1055,29 @@ public class Krb5LoginModule implements LoginModule {
}
}
if
(
storeKey
)
{
if
(
storeKey
)
{
for
(
int
i
=
0
;
i
<
kerbKeys
.
length
;
i
++)
{
if
(
encKeys
==
null
)
{
if
(!
privCredSet
.
contains
(
kerbKeys
[
i
]))
{
if
(!
privCredSet
.
contains
(
ktab
))
{
privCredSet
.
add
(
kerbKeys
[
i
]);
privCredSet
.
add
(
ktab
);
// Compatibility; also add keys to privCredSet
for
(
KerberosKey
key:
ktab
.
getKeys
(
kerbClientPrinc
))
{
privCredSet
.
add
(
new
Krb5Util
.
KeysFromKeyTab
(
key
));
}
}
}
encKeys
[
i
].
destroy
();
}
else
{
encKeys
[
i
]
=
null
;
for
(
int
i
=
0
;
i
<
kerbKeys
.
length
;
i
++)
{
if
(
debug
)
{
if
(!
privCredSet
.
contains
(
kerbKeys
[
i
]))
{
System
.
out
.
println
(
"Added server's key"
privCredSet
.
add
(
kerbKeys
[
i
]);
+
kerbKeys
[
i
]);
}
System
.
out
.
println
(
"\t\t[Krb5LoginModule] "
+
encKeys
[
i
].
destroy
();
"added Krb5Principal "
+
encKeys
[
i
]
=
null
;
kerbClientPrinc
.
toString
()
if
(
debug
)
{
+
" to Subject"
);
System
.
out
.
println
(
"Added server's key"
+
kerbKeys
[
i
]);
System
.
out
.
println
(
"\t\t[Krb5LoginModule] "
+
"added Krb5Principal "
+
kerbClientPrinc
.
toString
()
+
" to Subject"
);
}
}
}
}
}
}
}
...
@@ -1106,7 +1153,8 @@ public class Krb5LoginModule implements LoginModule {
...
@@ -1106,7 +1153,8 @@ public class Krb5LoginModule implements LoginModule {
while
(
it
.
hasNext
())
{
while
(
it
.
hasNext
())
{
Object
o
=
it
.
next
();
Object
o
=
it
.
next
();
if
(
o
instanceof
KerberosTicket
||
if
(
o
instanceof
KerberosTicket
||
o
instanceof
KerberosKey
)
{
o
instanceof
KerberosKey
||
o
instanceof
KeyTab
)
{
it
.
remove
();
it
.
remove
();
}
}
}
}
...
@@ -1161,6 +1209,7 @@ public class Krb5LoginModule implements LoginModule {
...
@@ -1161,6 +1209,7 @@ public class Krb5LoginModule implements LoginModule {
}
else
{
}
else
{
// remove temp results for the next try
// remove temp results for the next try
encKeys
=
null
;
encKeys
=
null
;
ktab
=
null
;
principal
=
null
;
principal
=
null
;
}
}
username
=
null
;
username
=
null
;
...
...
src/share/classes/javax/security/auth/kerberos/JavaxSecurityAuthKerberosAccessImpl.java
0 → 100644
浏览文件 @
812a3eaf
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package
javax.security.auth.kerberos
;
import
sun.misc.JavaxSecurityAuthKerberosAccess
;
import
sun.security.krb5.EncryptionKey
;
import
sun.security.krb5.PrincipalName
;
class
JavaxSecurityAuthKerberosAccessImpl
implements
JavaxSecurityAuthKerberosAccess
{
public
EncryptionKey
[]
keyTabGetEncryptionKeys
(
KeyTab
ktab
,
PrincipalName
principal
)
{
return
ktab
.
getEncryptionKeys
(
principal
);
}
}
src/share/classes/javax/security/auth/kerberos/KerberosKey.java
浏览文件 @
812a3eaf
/*
/*
* Copyright (c) 2000, 20
06
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 20
11
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -35,14 +35,16 @@ import javax.security.auth.DestroyFailedException;
...
@@ -35,14 +35,16 @@ import javax.security.auth.DestroyFailedException;
* principal.<p>
* principal.<p>
*
*
* All Kerberos JAAS login modules that obtain a principal's password and
* All Kerberos JAAS login modules that obtain a principal's password and
* generate the secret key from it should use this class. Where available,
* generate the secret key from it should use this class.
* the login module might even read this secret key directly from a
* Sometimes, such as when authenticating a server in
* Kerberos "keytab". Sometimes, such as when authenticating a server in
* the absence of user-to-user authentication, the login module will store
* the absence of user-to-user authentication, the login module will store
* an instance of this class in the private credential set of a
* an instance of this class in the private credential set of a
* {@link javax.security.auth.Subject Subject} during the commit phase of the
* {@link javax.security.auth.Subject Subject} during the commit phase of the
* authentication process.<p>
* authentication process.<p>
*
*
* A Kerberos service using a keytab to read secret keys should use
* the {@link KeyTab} class, where latest keys can be read when needed.<p>
*
* It might be necessary for the application to be granted a
* It might be necessary for the application to be granted a
* {@link javax.security.auth.PrivateCredentialPermission
* {@link javax.security.auth.PrivateCredentialPermission
* PrivateCredentialPermission} if it needs to access the KerberosKey
* PrivateCredentialPermission} if it needs to access the KerberosKey
...
...
src/share/classes/javax/security/auth/kerberos/KeyTab.java
0 → 100644
浏览文件 @
812a3eaf
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package
javax.security.auth.kerberos
;
import
java.io.File
;
import
java.util.Objects
;
import
sun.misc.SharedSecrets
;
import
sun.security.krb5.EncryptionKey
;
import
sun.security.krb5.PrincipalName
;
import
sun.security.krb5.RealmException
;
/**
* This class encapsulates a keytab file.
* <p>
* A Kerberos JAAS login module that obtains long term secret keys from a
* keytab file should use this class. The login module will store
* an instance of this class in the private credential set of a
* {@link javax.security.auth.Subject Subject} during the commit phase of the
* authentication process.
* <p>
* It might be necessary for the application to be granted a
* {@link javax.security.auth.PrivateCredentialPermission
* PrivateCredentialPermission} if it needs to access the KeyTab
* instance from a Subject. This permission is not needed when the
* application depends on the default JGSS Kerberos mechanism to access the
* KeyTab. In that case, however, the application will need an appropriate
* {@link javax.security.auth.kerberos.ServicePermission ServicePermission}.
* <p>
* The keytab file format is described at
* <a href="http://www.ioplex.com/utilities/keytab.txt">
* http://www.ioplex.com/utilities/keytab.txt</a>.
*
* @since 1.7
*/
public
final
class
KeyTab
{
/*
* Impl notes:
*
* This class is only a name, a permanent link to the keytab source
* (can be missing). Itself has no content. In order to read content,
* take a snapshot and read from it.
*
* The snapshot is of type sun.security.krb5.internal.ktab.KeyTab, which
* contains the content of the keytab file when the snapshot is taken.
* Itself has no refresh function and mostly an immutable class (except
* for the create/add/save methods only used by the ktab command).
*/
// Source, null if using the default one. Note that the default name
// is maintained in snapshot, this field is never "resolved".
private
final
File
file
;
// Set up JavaxSecurityAuthKerberosAccess in SharedSecrets
static
{
SharedSecrets
.
setJavaxSecurityAuthKerberosAccess
(
new
JavaxSecurityAuthKerberosAccessImpl
());
}
private
KeyTab
(
File
file
)
{
this
.
file
=
file
;
}
/**
* Returns a {@code KeyTab} instance from a {@code File} object.
* <p>
* The result of this method is never null. This method only associates
* the returned {@code KeyTab} object with the file and does not read it.
* @param file the keytab {@code File} object, must not be null
* @return the keytab instance
* @throws NullPointerException if the {@code file} argument is null
*/
public
static
KeyTab
getInstance
(
File
file
)
{
if
(
file
==
null
)
{
throw
new
NullPointerException
(
"file must be non null"
);
}
return
new
KeyTab
(
file
);
}
/**
* Returns the default {@code KeyTab} instance.
* <p>
* The result of this method is never null. This method only associates
* the returned {@code KeyTab} object with the default keytab file and
* does not read it.
* @return the default keytab instance.
*/
public
static
KeyTab
getInstance
()
{
return
new
KeyTab
(
null
);
}
//Takes a snapshot of the keytab content
private
sun
.
security
.
krb5
.
internal
.
ktab
.
KeyTab
takeSnapshot
()
{
return
sun
.
security
.
krb5
.
internal
.
ktab
.
KeyTab
.
getInstance
(
file
);
}
/**
* Returns fresh keys for the given Kerberos principal.
* <p>
* Implementation of this method should make sure the returned keys match
* the latest content of the keytab file. The result is a newly created
* copy that can be modified by the caller without modifying the keytab
* object. The caller should {@link KerberosKey#destroy() destroy} the
* result keys after they are used.
* <p>
* Please note that the keytab file can be created after the
* {@code KeyTab} object is instantiated and its content may change over
* time. Therefore, an application should call this method only when it
* needs to use the keys. Any previous result from an earlier invocation
* could potentially be expired.
* <p>
* If there is any error (say, I/O error or format error)
* during the reading process of the KeyTab file, a saved result should be
* returned. If there is no saved result (say, this is the first time this
* method is called, or, all previous read attempts failed), an empty array
* should be returned. This can make sure the result is not drastically
* changed during the (probably slow) update of the keytab file.
* <p>
* Each time this method is called and the reading of the file succeeds
* with no exception (say, I/O error or file format error),
* the result should be saved for {@code principal}. The implementation can
* also save keys for other principals having keys in the same keytab object
* if convenient.
* <p>
* Any unsupported key read from the keytab is ignored and not included
* in the result.
*
* @param principal the Kerberos principal, must not be null.
* @return the keys (never null, may be empty)
* @throws NullPointerException if the {@code principal}
* argument is null
* @throws SecurityException if a security manager exists and the read
* access to the keytab file is not permitted
*/
public
KerberosKey
[]
getKeys
(
KerberosPrincipal
principal
)
{
try
{
EncryptionKey
[]
keys
=
takeSnapshot
().
readServiceKeys
(
new
PrincipalName
(
principal
.
getName
()));
KerberosKey
[]
kks
=
new
KerberosKey
[
keys
.
length
];
for
(
int
i
=
0
;
i
<
kks
.
length
;
i
++)
{
Integer
tmp
=
keys
[
i
].
getKeyVersionNumber
();
kks
[
i
]
=
new
KerberosKey
(
principal
,
keys
[
i
].
getBytes
(),
keys
[
i
].
getEType
(),
tmp
==
null
?
0
:
tmp
.
intValue
());
keys
[
i
].
destroy
();
}
return
kks
;
}
catch
(
RealmException
re
)
{
return
new
KerberosKey
[
0
];
}
}
EncryptionKey
[]
getEncryptionKeys
(
PrincipalName
principal
)
{
return
takeSnapshot
().
readServiceKeys
(
principal
);
}
/**
* Checks if the keytab file exists. Implementation of this method
* should make sure that the result matches the latest status of the
* keytab file.
* <p>
* The caller can use the result to determine if it should fallback to
* another mechanism to read the keys.
* @return true if the keytab file exists; false otherwise.
* @throws SecurityException if a security manager exists and the read
* access to the keytab file is not permitted
*/
public
boolean
exists
()
{
return
!
takeSnapshot
().
isMissing
();
}
public
String
toString
()
{
return
file
==
null
?
"Default keytab"
:
file
.
toString
();
}
/**
* Returns a hashcode for this KeyTab.
*
* @return a hashCode() for the <code>KeyTab</code>
*/
public
int
hashCode
()
{
return
Objects
.
hash
(
file
);
}
/**
* Compares the specified Object with this KeyTab for equality.
* Returns true if the given object is also a
* <code>KeyTab</code> and the two
* <code>KeyTab</code> instances are equivalent.
*
* @param other the Object to compare to
* @return true if the specified object is equal to this KeyTab
*/
public
boolean
equals
(
Object
other
)
{
if
(
other
==
this
)
return
true
;
if
(!
(
other
instanceof
KeyTab
))
{
return
false
;
}
KeyTab
otherKtab
=
(
KeyTab
)
other
;
return
Objects
.
equals
(
otherKtab
.
file
,
file
);
}
}
src/share/classes/sun/misc/JavaxSecurityAuthKerberosAccess.java
0 → 100644
浏览文件 @
812a3eaf
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package
sun.misc
;
import
javax.security.auth.kerberos.KeyTab
;
import
sun.security.krb5.EncryptionKey
;
import
sun.security.krb5.PrincipalName
;
/**
* An unsafe tunnel to get non-public access to classes in the
* javax.security.auth.kerberos package.
*/
public
interface
JavaxSecurityAuthKerberosAccess
{
/**
* Returns keys for a principal in a keytab.
* @return the keys, never null, can be empty.
*/
public
EncryptionKey
[]
keyTabGetEncryptionKeys
(
KeyTab
ktab
,
PrincipalName
principal
);
}
src/share/classes/sun/misc/SharedSecrets.java
浏览文件 @
812a3eaf
...
@@ -29,6 +29,7 @@ import java.util.jar.JarFile;
...
@@ -29,6 +29,7 @@ import java.util.jar.JarFile;
import
java.io.Console
;
import
java.io.Console
;
import
java.io.FileDescriptor
;
import
java.io.FileDescriptor
;
import
java.security.ProtectionDomain
;
import
java.security.ProtectionDomain
;
import
javax.security.auth.kerberos.KeyTab
;
import
java.security.AccessController
;
import
java.security.AccessController
;
...
@@ -51,6 +52,7 @@ public class SharedSecrets {
...
@@ -51,6 +52,7 @@ public class SharedSecrets {
private
static
JavaIOFileDescriptorAccess
javaIOFileDescriptorAccess
;
private
static
JavaIOFileDescriptorAccess
javaIOFileDescriptorAccess
;
private
static
JavaSecurityProtectionDomainAccess
javaSecurityProtectionDomainAccess
;
private
static
JavaSecurityProtectionDomainAccess
javaSecurityProtectionDomainAccess
;
private
static
JavaSecurityAccess
javaSecurityAccess
;
private
static
JavaSecurityAccess
javaSecurityAccess
;
private
static
JavaxSecurityAuthKerberosAccess
javaxSecurityAuthKerberosAccess
;
public
static
JavaUtilJarAccess
javaUtilJarAccess
()
{
public
static
JavaUtilJarAccess
javaUtilJarAccess
()
{
if
(
javaUtilJarAccess
==
null
)
{
if
(
javaUtilJarAccess
==
null
)
{
...
@@ -139,4 +141,16 @@ public class SharedSecrets {
...
@@ -139,4 +141,16 @@ public class SharedSecrets {
}
}
return
javaSecurityAccess
;
return
javaSecurityAccess
;
}
}
public
static
void
setJavaxSecurityAuthKerberosAccess
(
JavaxSecurityAuthKerberosAccess
jsaka
)
{
javaxSecurityAuthKerberosAccess
=
jsaka
;
}
public
static
JavaxSecurityAuthKerberosAccess
getJavaxSecurityAuthKerberosAccess
()
{
if
(
javaxSecurityAuthKerberosAccess
==
null
)
unsafe
.
ensureClassInitialized
(
KeyTab
.
class
);
return
javaxSecurityAuthKerberosAccess
;
}
}
}
src/share/classes/sun/security/jgss/krb5/Krb5AcceptCredential.java
浏览文件 @
812a3eaf
/*
/*
* Copyright (c) 2000, 20
09
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 20
11
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -29,7 +29,6 @@ import org.ietf.jgss.*;
...
@@ -29,7 +29,6 @@ import org.ietf.jgss.*;
import
sun.security.jgss.GSSCaller
;
import
sun.security.jgss.GSSCaller
;
import
sun.security.jgss.spi.*
;
import
sun.security.jgss.spi.*
;
import
sun.security.krb5.*
;
import
sun.security.krb5.*
;
import
javax.security.auth.kerberos.*
;
import
java.security.PrivilegedActionException
;
import
java.security.PrivilegedActionException
;
import
java.security.PrivilegedExceptionAction
;
import
java.security.PrivilegedExceptionAction
;
import
java.security.AccessController
;
import
java.security.AccessController
;
...
@@ -43,40 +42,23 @@ import javax.security.auth.DestroyFailedException;
...
@@ -43,40 +42,23 @@ import javax.security.auth.DestroyFailedException;
* @since 1.4
* @since 1.4
*/
*/
public
class
Krb5AcceptCredential
public
class
Krb5AcceptCredential
extends
KerberosKey
implements
Krb5CredElement
{
implements
Krb5CredElement
{
private
static
final
long
serialVersionUID
=
7714332137352567952L
;
private
static
final
long
serialVersionUID
=
7714332137352567952L
;
private
Krb5NameElement
name
;
private
Krb5NameElement
name
;
/**
private
Krb5Util
.
ServiceCreds
screds
;
* We cache an EncryptionKey representation of this key because many
* Krb5 operation require a key in that form. At some point we might do
* away with EncryptionKey altogether and use the base class
* KerberosKey everywhere.
*/
private
EncryptionKey
[]
krb5EncryptionKeys
;
private
Krb5AcceptCredential
(
Krb5NameElement
name
,
K
erberosKey
[]
key
s
)
{
private
Krb5AcceptCredential
(
Krb5NameElement
name
,
K
rb5Util
.
ServiceCreds
cred
s
)
{
/*
/*
* Initialize this instance with the data from the acquired
* Initialize this instance with the data from the acquired
* KerberosKey. This class needs to be a KerberosKey too
* KerberosKey. This class needs to be a KerberosKey too
* hence we can't just store a reference.
* hence we can't just store a reference.
*/
*/
super
(
keys
[
0
].
getPrincipal
(),
keys
[
0
].
getEncoded
(),
keys
[
0
].
getKeyType
(),
keys
[
0
].
getVersionNumber
());
this
.
name
=
name
;
this
.
name
=
name
;
// Cache this for later use by the sun.security.krb5 package.
this
.
screds
=
creds
;
krb5EncryptionKeys
=
new
EncryptionKey
[
keys
.
length
];
for
(
int
i
=
0
;
i
<
keys
.
length
;
i
++)
{
krb5EncryptionKeys
[
i
]
=
new
EncryptionKey
(
keys
[
i
].
getEncoded
(),
keys
[
i
].
getKeyType
(),
new
Integer
(
keys
[
i
].
getVersionNumber
()));
}
}
}
static
Krb5AcceptCredential
getInstance
(
final
GSSCaller
caller
,
Krb5NameElement
name
)
static
Krb5AcceptCredential
getInstance
(
final
GSSCaller
caller
,
Krb5NameElement
name
)
...
@@ -86,12 +68,12 @@ public class Krb5AcceptCredential
...
@@ -86,12 +68,12 @@ public class Krb5AcceptCredential
name
.
getKrb5PrincipalName
().
getName
());
name
.
getKrb5PrincipalName
().
getName
());
final
AccessControlContext
acc
=
AccessController
.
getContext
();
final
AccessControlContext
acc
=
AccessController
.
getContext
();
K
erberosKey
[]
keys
;
K
rb5Util
.
ServiceCreds
creds
=
null
;
try
{
try
{
key
s
=
AccessController
.
doPrivileged
(
cred
s
=
AccessController
.
doPrivileged
(
new
PrivilegedExceptionAction
<
K
erberosKey
[]
>()
{
new
PrivilegedExceptionAction
<
K
rb5Util
.
ServiceCreds
>()
{
public
K
erberosKey
[]
run
()
throws
Exception
{
public
K
rb5Util
.
ServiceCreds
run
()
throws
Exception
{
return
Krb5Util
.
get
Key
s
(
return
Krb5Util
.
get
ServiceCred
s
(
caller
==
GSSCaller
.
CALLER_UNKNOWN
?
GSSCaller
.
CALLER_ACCEPT
:
caller
,
caller
==
GSSCaller
.
CALLER_UNKNOWN
?
GSSCaller
.
CALLER_ACCEPT
:
caller
,
serverPrinc
,
acc
);
serverPrinc
,
acc
);
}});
}});
...
@@ -103,17 +85,17 @@ public class Krb5AcceptCredential
...
@@ -103,17 +85,17 @@ public class Krb5AcceptCredential
throw
ge
;
throw
ge
;
}
}
if
(
keys
==
null
||
keys
.
length
==
0
)
if
(
creds
==
null
)
throw
new
GSSException
(
GSSException
.
NO_CRED
,
-
1
,
throw
new
GSSException
(
GSSException
.
NO_CRED
,
-
1
,
"Failed to find any Kerberos
Key
"
);
"Failed to find any Kerberos
credentails
"
);
if
(
name
==
null
)
{
if
(
name
==
null
)
{
String
fullName
=
keys
[
0
].
getPrincipal
()
.
getName
();
String
fullName
=
creds
.
getName
();
name
=
Krb5NameElement
.
getInstance
(
fullName
,
name
=
Krb5NameElement
.
getInstance
(
fullName
,
Krb5MechFactory
.
NT_GSS_KRB5_PRINCIPAL
);
Krb5MechFactory
.
NT_GSS_KRB5_PRINCIPAL
);
}
}
return
new
Krb5AcceptCredential
(
name
,
key
s
);
return
new
Krb5AcceptCredential
(
name
,
cred
s
);
}
}
/**
/**
...
@@ -171,7 +153,7 @@ public class Krb5AcceptCredential
...
@@ -171,7 +153,7 @@ public class Krb5AcceptCredential
}
}
EncryptionKey
[]
getKrb5EncryptionKeys
()
{
EncryptionKey
[]
getKrb5EncryptionKeys
()
{
return
krb5EncryptionKeys
;
return
screds
.
getEKeys
()
;
}
}
/**
/**
...
@@ -193,13 +175,6 @@ public class Krb5AcceptCredential
...
@@ -193,13 +175,6 @@ public class Krb5AcceptCredential
* destroy in the base class.
* destroy in the base class.
*/
*/
public
void
destroy
()
throws
DestroyFailedException
{
public
void
destroy
()
throws
DestroyFailedException
{
if
(
krb5EncryptionKeys
!=
null
)
{
screds
.
destroy
();
for
(
int
i
=
0
;
i
<
krb5EncryptionKeys
.
length
;
i
++)
{
krb5EncryptionKeys
[
i
].
destroy
();
}
krb5EncryptionKeys
=
null
;
}
super
.
destroy
();
}
}
}
}
src/share/classes/sun/security/jgss/krb5/Krb5Util.java
浏览文件 @
812a3eaf
/*
/*
* Copyright (c) 2003, 20
09
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 20
11
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -28,6 +28,7 @@ package sun.security.jgss.krb5;
...
@@ -28,6 +28,7 @@ package sun.security.jgss.krb5;
import
javax.security.auth.kerberos.KerberosTicket
;
import
javax.security.auth.kerberos.KerberosTicket
;
import
javax.security.auth.kerberos.KerberosKey
;
import
javax.security.auth.kerberos.KerberosKey
;
import
javax.security.auth.kerberos.KerberosPrincipal
;
import
javax.security.auth.kerberos.KerberosPrincipal
;
import
javax.security.auth.kerberos.KeyTab
;
import
javax.security.auth.Subject
;
import
javax.security.auth.Subject
;
import
javax.security.auth.login.LoginException
;
import
javax.security.auth.login.LoginException
;
import
java.security.AccessControlContext
;
import
java.security.AccessControlContext
;
...
@@ -38,7 +39,13 @@ import sun.security.krb5.Credentials;
...
@@ -38,7 +39,13 @@ import sun.security.krb5.Credentials;
import
sun.security.krb5.EncryptionKey
;
import
sun.security.krb5.EncryptionKey
;
import
sun.security.krb5.KrbException
;
import
sun.security.krb5.KrbException
;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.util.ArrayList
;
import
java.util.Iterator
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Objects
;
import
java.util.Set
;
import
sun.misc.SharedSecrets
;
import
sun.security.krb5.PrincipalName
;
/**
/**
* Utilities for obtaining and converting Kerberos tickets.
* Utilities for obtaining and converting Kerberos tickets.
*
*
...
@@ -75,7 +82,7 @@ public class Krb5Util {
...
@@ -75,7 +82,7 @@ public class Krb5Util {
// 1. Try to find service ticket in acc subject
// 1. Try to find service ticket in acc subject
Subject
accSubj
=
Subject
.
getSubject
(
acc
);
Subject
accSubj
=
Subject
.
getSubject
(
acc
);
KerberosTicket
ticket
=
(
KerberosTicket
)
SubjectComber
.
find
(
accSubj
,
KerberosTicket
ticket
=
SubjectComber
.
find
(
accSubj
,
serverPrincipal
,
clientPrincipal
,
KerberosTicket
.
class
);
serverPrincipal
,
clientPrincipal
,
KerberosTicket
.
class
);
if
(
ticket
!=
null
)
{
if
(
ticket
!=
null
)
{
...
@@ -87,7 +94,7 @@ public class Krb5Util {
...
@@ -87,7 +94,7 @@ public class Krb5Util {
// 2. Try to get ticket from login
// 2. Try to get ticket from login
try
{
try
{
loginSubj
=
GSSUtil
.
login
(
caller
,
GSSUtil
.
GSS_KRB5_MECH_OID
);
loginSubj
=
GSSUtil
.
login
(
caller
,
GSSUtil
.
GSS_KRB5_MECH_OID
);
ticket
=
(
KerberosTicket
)
SubjectComber
.
find
(
loginSubj
,
ticket
=
SubjectComber
.
find
(
loginSubj
,
serverPrincipal
,
clientPrincipal
,
KerberosTicket
.
class
);
serverPrincipal
,
clientPrincipal
,
KerberosTicket
.
class
);
if
(
ticket
!=
null
)
{
if
(
ticket
!=
null
)
{
return
ticket
;
// found it
return
ticket
;
// found it
...
@@ -102,13 +109,13 @@ public class Krb5Util {
...
@@ -102,13 +109,13 @@ public class Krb5Util {
// Try to get TGT to acquire service ticket
// Try to get TGT to acquire service ticket
// 3. Try to get TGT from acc subject
// 3. Try to get TGT from acc subject
KerberosTicket
tgt
=
(
KerberosTicket
)
SubjectComber
.
find
(
accSubj
,
KerberosTicket
tgt
=
SubjectComber
.
find
(
accSubj
,
tgsPrincipal
,
clientPrincipal
,
KerberosTicket
.
class
);
tgsPrincipal
,
clientPrincipal
,
KerberosTicket
.
class
);
boolean
fromAcc
;
boolean
fromAcc
;
if
(
tgt
==
null
&&
loginSubj
!=
null
)
{
if
(
tgt
==
null
&&
loginSubj
!=
null
)
{
// 4. Try to get TGT from login subject
// 4. Try to get TGT from login subject
tgt
=
(
KerberosTicket
)
SubjectComber
.
find
(
loginSubj
,
tgt
=
SubjectComber
.
find
(
loginSubj
,
tgsPrincipal
,
clientPrincipal
,
KerberosTicket
.
class
);
tgsPrincipal
,
clientPrincipal
,
KerberosTicket
.
class
);
fromAcc
=
false
;
fromAcc
=
false
;
}
else
{
}
else
{
...
@@ -145,14 +152,14 @@ public class Krb5Util {
...
@@ -145,14 +152,14 @@ public class Krb5Util {
// Try to get ticket from acc's Subject
// Try to get ticket from acc's Subject
Subject
accSubj
=
Subject
.
getSubject
(
acc
);
Subject
accSubj
=
Subject
.
getSubject
(
acc
);
KerberosTicket
ticket
=
(
KerberosTicket
)
KerberosTicket
ticket
=
SubjectComber
.
find
(
accSubj
,
serverPrincipal
,
clientPrincipal
,
SubjectComber
.
find
(
accSubj
,
serverPrincipal
,
clientPrincipal
,
KerberosTicket
.
class
);
KerberosTicket
.
class
);
// Try to get ticket from Subject obtained from GSSUtil
// Try to get ticket from Subject obtained from GSSUtil
if
(
ticket
==
null
&&
!
GSSUtil
.
useSubjectCredsOnly
(
caller
))
{
if
(
ticket
==
null
&&
!
GSSUtil
.
useSubjectCredsOnly
(
caller
))
{
Subject
subject
=
GSSUtil
.
login
(
caller
,
GSSUtil
.
GSS_KRB5_MECH_OID
);
Subject
subject
=
GSSUtil
.
login
(
caller
,
GSSUtil
.
GSS_KRB5_MECH_OID
);
ticket
=
(
KerberosTicket
)
SubjectComber
.
find
(
subject
,
ticket
=
SubjectComber
.
find
(
subject
,
serverPrincipal
,
clientPrincipal
,
KerberosTicket
.
class
);
serverPrincipal
,
clientPrincipal
,
KerberosTicket
.
class
);
}
}
return
ticket
;
return
ticket
;
...
@@ -182,37 +189,152 @@ public class Krb5Util {
...
@@ -182,37 +189,152 @@ public class Krb5Util {
return
subject
;
return
subject
;
}
}
// A special KerberosKey, used as keys read from a KeyTab object.
// Each time new keys are read from KeyTab objects in the private
// credentials set, old ones are removed and new ones added.
public
static
class
KeysFromKeyTab
extends
KerberosKey
{
public
KeysFromKeyTab
(
KerberosKey
key
)
{
super
(
key
.
getPrincipal
(),
key
.
getEncoded
(),
key
.
getKeyType
(),
key
.
getVersionNumber
());
}
}
/**
/**
*
Retrieves the keys for the specified server principal from
*
Credentials of a service, the private secret to authenticate its
*
the Subject in the specified AccessControlContext.
*
identity, which can be:
*
If the ticket can not be found in the Subject, and if
*
1. Some KerberosKeys (generated from password)
*
useSubjectCredsOnly is false, then obtain keys from
*
2. A KeyTab (for a typical service)
*
a LoginContext.
*
3. A TGT (for a user2user service. Not supported yet)
*
*
* NOTE: This method is used by JSSE Kerberos Cipher Suites
* Note that some creds can coexist. For example, a user2user service
* can use its keytab (or keys) if the client can successfully obtain a
* normal service ticket, otherwise, it can uses the TGT (actually, the
* session key of the TGT) if the client can only acquire a service ticket
* of ENC-TKT-IN-SKEY style.
*/
*/
public
static
KerberosKey
[]
getKeys
(
GSSCaller
caller
,
public
static
class
ServiceCreds
{
private
KerberosPrincipal
kp
;
private
List
<
KeyTab
>
ktabs
;
private
List
<
KerberosKey
>
kk
;
private
Subject
subj
;
//private KerberosTicket tgt; // user2user, not supported yet
private
static
ServiceCreds
getInstance
(
Subject
subj
,
String
serverPrincipal
)
{
ServiceCreds
sc
=
new
ServiceCreds
();
sc
.
subj
=
subj
;
for
(
KerberosPrincipal
p:
subj
.
getPrincipals
(
KerberosPrincipal
.
class
))
{
if
(
serverPrincipal
==
null
||
p
.
getName
().
equals
(
serverPrincipal
))
{
sc
.
kp
=
p
;
serverPrincipal
=
p
.
getName
();
break
;
}
}
if
(
sc
.
kp
==
null
)
{
// Compatibility with old behavior: even when there is no
// KerberosPrincipal, we can find one from KerberosKeys
List
<
KerberosKey
>
keys
=
SubjectComber
.
findMany
(
subj
,
null
,
null
,
KerberosKey
.
class
);
if
(!
keys
.
isEmpty
())
{
sc
.
kp
=
keys
.
get
(
0
).
getPrincipal
();
serverPrincipal
=
sc
.
kp
.
getName
();
if
(
DEBUG
)
{
System
.
out
.
println
(
">>> ServiceCreds: no kp?"
+
" find one from kk: "
+
serverPrincipal
);
}
}
else
{
return
null
;
}
}
sc
.
ktabs
=
SubjectComber
.
findMany
(
subj
,
null
,
null
,
KeyTab
.
class
);
sc
.
kk
=
SubjectComber
.
findMany
(
subj
,
serverPrincipal
,
null
,
KerberosKey
.
class
);
if
(
sc
.
ktabs
.
isEmpty
()
&&
sc
.
kk
.
isEmpty
())
{
return
null
;
}
return
sc
;
}
public
String
getName
()
{
return
kp
.
getName
();
}
public
KerberosKey
[]
getKKeys
()
{
if
(
ktabs
.
isEmpty
())
{
return
kk
.
toArray
(
new
KerberosKey
[
kk
.
size
()]);
}
else
{
List
<
KerberosKey
>
keys
=
new
ArrayList
<>();
for
(
KeyTab
ktab:
ktabs
)
{
for
(
KerberosKey
k:
ktab
.
getKeys
(
kp
))
{
keys
.
add
(
k
);
}
}
// Compatibility: also add keys to privCredSet. Remove old
// ones first, only remove those from keytab.
if
(!
subj
.
isReadOnly
())
{
Set
<
Object
>
pcs
=
subj
.
getPrivateCredentials
();
synchronized
(
pcs
)
{
Iterator
<
Object
>
iterator
=
pcs
.
iterator
();
while
(
iterator
.
hasNext
())
{
Object
obj
=
iterator
.
next
();
if
(
obj
instanceof
KeysFromKeyTab
)
{
KerberosKey
key
=
(
KerberosKey
)
obj
;
if
(
Objects
.
equals
(
key
.
getPrincipal
(),
kp
))
{
iterator
.
remove
();
}
}
}
}
for
(
KerberosKey
key:
keys
)
{
subj
.
getPrivateCredentials
().
add
(
new
KeysFromKeyTab
(
key
));
}
}
return
keys
.
toArray
(
new
KerberosKey
[
keys
.
size
()]);
}
}
public
EncryptionKey
[]
getEKeys
()
{
KerberosKey
[]
kkeys
=
getKKeys
();
EncryptionKey
[]
ekeys
=
new
EncryptionKey
[
kkeys
.
length
];
for
(
int
i
=
0
;
i
<
ekeys
.
length
;
i
++)
{
ekeys
[
i
]
=
new
EncryptionKey
(
kkeys
[
i
].
getEncoded
(),
kkeys
[
i
].
getKeyType
(),
new
Integer
(
kkeys
[
i
].
getVersionNumber
()));
}
return
ekeys
;
}
public
void
destroy
()
{
kp
=
null
;
ktabs
=
null
;
kk
=
null
;
}
}
/**
* Retrieves the ServiceCreds for the specified server principal from
* the Subject in the specified AccessControlContext. If not found, and if
* useSubjectCredsOnly is false, then obtain from a LoginContext.
*
* NOTE: This method is also used by JSSE Kerberos Cipher Suites
*/
public
static
ServiceCreds
getServiceCreds
(
GSSCaller
caller
,
String
serverPrincipal
,
AccessControlContext
acc
)
String
serverPrincipal
,
AccessControlContext
acc
)
throws
LoginException
{
throws
LoginException
{
Subject
accSubj
=
Subject
.
getSubject
(
acc
);
Subject
accSubj
=
Subject
.
getSubject
(
acc
);
List
<
KerberosKey
>
kkeys
=
(
List
<
KerberosKey
>)
SubjectComber
.
findMany
(
ServiceCreds
sc
=
null
;
accSubj
,
serverPrincipal
,
null
,
KerberosKey
.
class
);
if
(
accSubj
!=
null
)
{
sc
=
ServiceCreds
.
getInstance
(
accSubj
,
serverPrincipal
);
if
(
kkeys
==
null
&&
!
GSSUtil
.
useSubjectCredsOnly
(
caller
))
{
Subject
subject
=
GSSUtil
.
login
(
caller
,
GSSUtil
.
GSS_KRB5_MECH_OID
);
kkeys
=
(
List
<
KerberosKey
>)
SubjectComber
.
findMany
(
subject
,
serverPrincipal
,
null
,
KerberosKey
.
class
);
}
}
if
(
sc
==
null
&&
!
GSSUtil
.
useSubjectCredsOnly
(
caller
))
{
int
len
;
Subject
subject
=
GSSUtil
.
login
(
caller
,
GSSUtil
.
GSS_KRB5_MECH_OID
);
if
(
kkeys
!=
null
&&
(
len
=
kkeys
.
size
())
>
0
)
{
sc
=
ServiceCreds
.
getInstance
(
subject
,
serverPrincipal
);
KerberosKey
[]
keys
=
new
KerberosKey
[
len
];
kkeys
.
toArray
(
keys
);
return
keys
;
}
else
{
return
null
;
}
}
return
sc
;
}
}
public
static
KerberosTicket
credsToTicket
(
Credentials
serviceCreds
)
{
public
static
KerberosTicket
credsToTicket
(
Credentials
serviceCreds
)
{
...
@@ -247,4 +369,17 @@ public class Krb5Util {
...
@@ -247,4 +369,17 @@ public class Krb5Util {
kerbTicket
.
getRenewTill
(),
kerbTicket
.
getRenewTill
(),
kerbTicket
.
getClientAddresses
());
kerbTicket
.
getClientAddresses
());
}
}
/**
* A helper method to get EncryptionKeys from a javax..KeyTab
* @param ktab the javax..KeyTab class
* @param cname the PrincipalName
* @return the EKeys, never null, might be empty
*/
public
static
EncryptionKey
[]
keysFromJavaxKeyTab
(
KeyTab
ktab
,
PrincipalName
cname
)
{
return
SharedSecrets
.
getJavaxSecurityAuthKerberosAccess
().
keyTabGetEncryptionKeys
(
ktab
,
cname
);
}
}
}
src/share/classes/sun/security/jgss/krb5/SubjectComber.java
浏览文件 @
812a3eaf
/*
/*
* Copyright (c) 2002, 20
06
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 20
11
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -33,10 +33,11 @@ import java.util.Iterator;
...
@@ -33,10 +33,11 @@ import java.util.Iterator;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Set
;
import
java.util.Set
;
import
javax.security.auth.kerberos.KeyTab
;
/**
/**
* This utility looks through the current Subject and retrieves
a ticket or key
* This utility looks through the current Subject and retrieves
private
* for the desired client/server principals.
*
credentials
for the desired client/server principals.
*
*
* @author Ram Marti
* @author Ram Marti
* @since 1.4.2
* @since 1.4.2
...
@@ -52,58 +53,70 @@ class SubjectComber {
...
@@ -52,58 +53,70 @@ class SubjectComber {
private
SubjectComber
()
{
// Cannot create one of these
private
SubjectComber
()
{
// Cannot create one of these
}
}
static
Object
find
(
Subject
subject
,
String
serverPrincipal
,
static
<
T
>
T
find
(
Subject
subject
,
String
serverPrincipal
,
String
clientPrincipal
,
Class
credClass
)
{
String
clientPrincipal
,
Class
<
T
>
credClass
)
{
return
findAux
(
subject
,
serverPrincipal
,
clientPrincipal
,
credClass
,
return
(
T
)
findAux
(
subject
,
serverPrincipal
,
clientPrincipal
,
credClass
,
true
);
true
);
}
}
static
Object
findMany
(
Subject
subject
,
String
serverPrincipal
,
static
<
T
>
List
<
T
>
findMany
(
Subject
subject
,
String
serverPrincipal
,
String
clientPrincipal
,
Class
credClass
)
{
String
clientPrincipal
,
Class
<
T
>
credClass
)
{
return
findAux
(
subject
,
serverPrincipal
,
clientPrincipal
,
credClass
,
return
(
List
<
T
>)
findAux
(
subject
,
serverPrincipal
,
clientPrincipal
,
credClass
,
false
);
false
);
}
}
/**
/**
* Find
the ticket or key
for the specified client/server principals
* Find
private credentials
for the specified client/server principals
* in the subject. Returns null if the subject is null.
* in the subject. Returns null if the subject is null.
*
*
* @return the
ticket or key
* @return the
private credentials
*/
*/
private
static
Object
findAux
(
Subject
subject
,
String
serverPrincipal
,
private
static
<
T
>
Object
findAux
(
Subject
subject
,
String
serverPrincipal
,
String
clientPrincipal
,
Class
credClass
,
boolean
oneOnly
)
{
String
clientPrincipal
,
Class
<
T
>
credClass
,
boolean
oneOnly
)
{
if
(
subject
==
null
)
{
if
(
subject
==
null
)
{
return
null
;
return
null
;
}
else
{
}
else
{
List
<
Object
>
answer
=
(
oneOnly
?
null
:
new
ArrayList
<
Object
>());
List
<
T
>
answer
=
(
oneOnly
?
null
:
new
ArrayList
<
T
>());
if
(
credClass
==
KerberosKey
.
class
)
{
if
(
credClass
==
KeyTab
.
class
)
{
// Principal un-related
// We are looking for a KerberosKey credentials for the
// We are looking for credentials unrelated to serverPrincipal
// serverPrincipal
Iterator
<
T
>
iterator
=
Iterator
<
KerberosKey
>
iterator
=
subject
.
getPrivateCredentials
(
credClass
).
iterator
();
subject
.
getPrivateCredentials
(
KerberosKey
.
class
).
iterator
();
while
(
iterator
.
hasNext
())
{
while
(
iterator
.
hasNext
())
{
KerberosKey
key
=
iterator
.
next
();
T
t
=
iterator
.
next
();
if
(
serverPrincipal
==
null
||
if
(
DEBUG
)
{
serverPrincipal
.
equals
(
key
.
getPrincipal
().
getName
()))
{
System
.
out
.
println
(
"Found "
+
credClass
.
getSimpleName
());
}
if
(
oneOnly
)
{
return
t
;
}
else
{
answer
.
add
(
t
);
}
}
}
else
if
(
credClass
==
KerberosKey
.
class
)
{
// We are looking for credentials for the serverPrincipal
Iterator
<
T
>
iterator
=
subject
.
getPrivateCredentials
(
credClass
).
iterator
();
while
(
iterator
.
hasNext
())
{
T
t
=
iterator
.
next
();
String
name
=
((
KerberosKey
)
t
).
getPrincipal
().
getName
();
if
(
serverPrincipal
==
null
||
serverPrincipal
.
equals
(
name
))
{
if
(
DEBUG
)
{
if
(
DEBUG
)
{
System
.
out
.
println
(
"Found key for "
System
.
out
.
println
(
"Found "
+
+
key
.
getPrincipal
()
+
"("
+
credClass
.
getSimpleName
()
+
" for "
+
name
);
key
.
getKeyType
()
+
")"
);
}
}
if
(
oneOnly
)
{
if
(
oneOnly
)
{
return
key
;
return
t
;
}
else
{
}
else
{
if
(
serverPrincipal
==
null
)
{
if
(
serverPrincipal
==
null
)
{
// Record name so that keys returned will all
// Record name so that keys returned will all
// belong to the same principal
// belong to the same principal
serverPrincipal
=
serverPrincipal
=
name
;
key
.
getPrincipal
().
getName
();
}
}
answer
.
add
(
key
);
answer
.
add
(
t
);
}
}
}
}
}
}
...
@@ -167,7 +180,7 @@ class SubjectComber {
...
@@ -167,7 +180,7 @@ class SubjectComber {
serverPrincipal
=
serverPrincipal
=
ticket
.
getServer
().
getName
();
ticket
.
getServer
().
getName
();
}
}
answer
.
add
(
ticket
);
answer
.
add
(
(
T
)
ticket
);
}
}
}
}
}
}
...
...
src/share/classes/sun/security/krb5/Config.java
浏览文件 @
812a3eaf
...
@@ -110,7 +110,6 @@ public class Config {
...
@@ -110,7 +110,6 @@ public class Config {
public
static
synchronized
void
refresh
()
throws
KrbException
{
public
static
synchronized
void
refresh
()
throws
KrbException
{
singleton
=
new
Config
();
singleton
=
new
Config
();
KeyTab
.
refresh
();
KdcComm
.
initStatic
();
KdcComm
.
initStatic
();
}
}
...
...
src/share/classes/sun/security/krb5/EncryptionKey.java
浏览文件 @
812a3eaf
/*
/*
* Copyright (c) 2000, 201
0
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 201
1
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -138,8 +138,7 @@ public class EncryptionKey
...
@@ -138,8 +138,7 @@ public class EncryptionKey
* @returns an array of secret keys or null if none were found.
* @returns an array of secret keys or null if none were found.
*/
*/
public
static
EncryptionKey
[]
acquireSecretKeys
(
PrincipalName
princ
,
public
static
EncryptionKey
[]
acquireSecretKeys
(
PrincipalName
princ
,
String
keytab
)
String
keytab
)
{
throws
KrbException
,
IOException
{
if
(
princ
==
null
)
if
(
princ
==
null
)
throw
new
IllegalArgumentException
(
throw
new
IllegalArgumentException
(
...
@@ -148,11 +147,6 @@ public class EncryptionKey
...
@@ -148,11 +147,6 @@ public class EncryptionKey
// KeyTab getInstance(keytab) will call KeyTab.getInstance()
// KeyTab getInstance(keytab) will call KeyTab.getInstance()
// if keytab is null
// if keytab is null
KeyTab
ktab
=
KeyTab
.
getInstance
(
keytab
);
KeyTab
ktab
=
KeyTab
.
getInstance
(
keytab
);
if
(
ktab
==
null
)
{
return
null
;
}
return
ktab
.
readServiceKeys
(
princ
);
return
ktab
.
readServiceKeys
(
princ
);
}
}
...
...
src/share/classes/sun/security/krb5/KrbAsRep.java
浏览文件 @
812a3eaf
...
@@ -37,6 +37,8 @@ import sun.security.krb5.internal.crypto.EType;
...
@@ -37,6 +37,8 @@ import sun.security.krb5.internal.crypto.EType;
import
sun.security.util.*
;
import
sun.security.util.*
;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.util.Objects
;
import
java.util.Objects
;
import
javax.security.auth.kerberos.KeyTab
;
import
sun.security.jgss.krb5.Krb5Util
;
/**
/**
* This class encapsulates a AS-REP message that the KDC sends to the
* This class encapsulates a AS-REP message that the KDC sends to the
...
@@ -90,29 +92,32 @@ class KrbAsRep extends KrbKdcRep {
...
@@ -90,29 +92,32 @@ class KrbAsRep extends KrbKdcRep {
}
}
/**
/**
* Called by KrbAsReqBuilder to resolve a AS-REP message using
keys
.
* Called by KrbAsReqBuilder to resolve a AS-REP message using
a keytab
.
* @param k
eys user provided keys
, not null
* @param k
tab the keytab
, not null
* @param asReq the original AS-REQ sent, used to validate AS-REP
* @param asReq the original AS-REQ sent, used to validate AS-REP
* @param cname the user principal name, used to locate keys in ktab
*/
*/
void
decryptUsingKey
s
(
EncryptionKey
[]
keys
,
KrbAsReq
asReq
)
void
decryptUsingKey
Tab
(
KeyTab
ktab
,
KrbAsReq
asReq
,
PrincipalName
cname
)
throws
KrbException
,
Asn1Exception
,
IOException
{
throws
KrbException
,
Asn1Exception
,
IOException
{
EncryptionKey
dkey
=
null
;
EncryptionKey
dkey
=
null
;
int
encPartKeyType
=
rep
.
encPart
.
getEType
();
int
encPartKeyType
=
rep
.
encPart
.
getEType
();
Integer
encPartKvno
=
rep
.
encPart
.
kvno
;
Integer
encPartKvno
=
rep
.
encPart
.
kvno
;
try
{
try
{
dkey
=
EncryptionKey
.
findKey
(
encPartKeyType
,
encPartKvno
,
keys
);
dkey
=
EncryptionKey
.
findKey
(
encPartKeyType
,
encPartKvno
,
}
catch
(
KrbException
ke
)
{
Krb5Util
.
keysFromJavaxKeyTab
(
ktab
,
cname
));
if
(
ke
.
returnCode
()
==
Krb5
.
KRB_AP_ERR_BADKEYVER
)
{
}
catch
(
KrbException
ke
)
{
// Fallback to no kvno. In some cases, keytab is generated
if
(
ke
.
returnCode
()
==
Krb5
.
KRB_AP_ERR_BADKEYVER
)
{
// not by sysadmin but Java's ktab command
// Fallback to no kvno. In some cases, keytab is generated
dkey
=
EncryptionKey
.
findKey
(
encPartKeyType
,
keys
);
// not by sysadmin but Java's ktab command
dkey
=
EncryptionKey
.
findKey
(
encPartKeyType
,
Krb5Util
.
keysFromJavaxKeyTab
(
ktab
,
cname
));
}
}
if
(
dkey
==
null
)
{
throw
new
KrbException
(
Krb5
.
API_INVALID_ARG
,
"Cannot find key for type/kvno to decrypt AS REP - "
+
EType
.
toString
(
encPartKeyType
)
+
"/"
+
encPartKvno
);
}
}
}
if
(
dkey
==
null
)
{
throw
new
KrbException
(
Krb5
.
API_INVALID_ARG
,
"Cannot find key for type/kvno to decrypt AS REP - "
+
EType
.
toString
(
encPartKeyType
)
+
"/"
+
encPartKvno
);
}
decrypt
(
dkey
,
asReq
);
decrypt
(
dkey
,
asReq
);
}
}
...
...
src/share/classes/sun/security/krb5/KrbAsReqBuilder.java
浏览文件 @
812a3eaf
/*
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010,
2011,
Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -27,6 +27,8 @@ package sun.security.krb5;
...
@@ -27,6 +27,8 @@ package sun.security.krb5;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.util.Arrays
;
import
java.util.Arrays
;
import
javax.security.auth.kerberos.KeyTab
;
import
sun.security.jgss.krb5.Krb5Util
;
import
sun.security.krb5.internal.HostAddresses
;
import
sun.security.krb5.internal.HostAddresses
;
import
sun.security.krb5.internal.KDCOptions
;
import
sun.security.krb5.internal.KDCOptions
;
import
sun.security.krb5.internal.KRBError
;
import
sun.security.krb5.internal.KRBError
;
...
@@ -42,13 +44,16 @@ import sun.security.krb5.internal.crypto.EType;
...
@@ -42,13 +44,16 @@ import sun.security.krb5.internal.crypto.EType;
* 1. Gather information to create AS-REQ
* 1. Gather information to create AS-REQ
* 2. Create and send AS-REQ
* 2. Create and send AS-REQ
* 3. Receive AS-REP and KRB-ERROR (-KRB_ERR_RESPONSE_TOO_BIG) and parse them
* 3. Receive AS-REP and KRB-ERROR (-KRB_ERR_RESPONSE_TOO_BIG) and parse them
* 4. Emit credentials and secret keys (for JAAS storeKey=true)
* 4. Emit credentials and secret keys (for JAAS storeKey=true
with password
)
*
*
* This class does not:
* This class does not:
* 1. Deal with real communications (KdcComm does it, and TGS-REQ)
* 1. Deal with real communications (KdcComm does it, and TGS-REQ)
* a. Name of KDCs for a realm
* a. Name of KDCs for a realm
* b. Server availability, timeout, UDP or TCP
* b. Server availability, timeout, UDP or TCP
* d. KRB_ERR_RESPONSE_TOO_BIG
* d. KRB_ERR_RESPONSE_TOO_BIG
* 2. Stores its own copy of password, this means:
* a. Do not change/wipe it before Builder finish
* b. Builder will not wipe it for you
*
*
* With this class:
* With this class:
* 1. KrbAsReq has only one constructor
* 1. KrbAsReq has only one constructor
...
@@ -70,19 +75,17 @@ public final class KrbAsReqBuilder {
...
@@ -70,19 +75,17 @@ public final class KrbAsReqBuilder {
private
HostAddresses
addresses
;
private
HostAddresses
addresses
;
// Secret source: can't be changed once assigned, only one (of the two
// Secret source: can't be changed once assigned, only one (of the two
// sources) can be set
and should be
non-null
// sources) can be set
to
non-null
private
EncryptionKey
[]
keys
;
private
final
char
[]
password
;
private
char
[]
password
;
private
final
KeyTab
ktab
;
// Used to create a ENC-TIMESTAMP in the 2nd AS-REQ
// Used to create a ENC-TIMESTAMP in the 2nd AS-REQ
private
EncryptionKey
pakey
;
private
PAData
[]
paList
;
// PA-DATA from both KRB-ERROR and AS-REP.
private
PAData
[]
paList
;
// PA-DATA from both KRB-ERROR and AS-REP.
// Used by getKeys() only.
// Used by getKeys() only.
// Only AS-REP should be enough per RFC,
// Only AS-REP should be enough per RFC,
// combined in case etypes are different.
// combined in case etypes are different.
// The generated and received:
// The generated and received:
int
[]
eTypes
;
private
KrbAsReq
req
;
private
KrbAsReq
req
;
private
KrbAsRep
rep
;
private
KrbAsRep
rep
;
...
@@ -94,7 +97,7 @@ public final class KrbAsReqBuilder {
...
@@ -94,7 +97,7 @@ public final class KrbAsReqBuilder {
private
State
state
;
private
State
state
;
// Called by other constructors
// Called by other constructors
private
KrbAsReqBuilder
(
PrincipalName
cname
)
private
void
init
(
PrincipalName
cname
)
throws
KrbException
{
throws
KrbException
{
if
(
cname
.
getRealm
()
==
null
)
{
if
(
cname
.
getRealm
()
==
null
)
{
cname
.
setRealm
(
Config
.
getInstance
().
getDefaultRealm
());
cname
.
setRealm
(
Config
.
getInstance
().
getDefaultRealm
());
...
@@ -114,14 +117,11 @@ public final class KrbAsReqBuilder {
...
@@ -114,14 +117,11 @@ public final class KrbAsReqBuilder {
* This argument will neither be modified nor stored by the method.
* This argument will neither be modified nor stored by the method.
* @throws KrbException
* @throws KrbException
*/
*/
public
KrbAsReqBuilder
(
PrincipalName
cname
,
EncryptionKey
[]
keys
)
public
KrbAsReqBuilder
(
PrincipalName
cname
,
KeyTab
ktab
)
throws
KrbException
{
throws
KrbException
{
this
(
cname
);
init
(
cname
);
this
.
keys
=
new
EncryptionKey
[
keys
.
length
];
this
.
ktab
=
ktab
;
for
(
int
i
=
0
;
i
<
keys
.
length
;
i
++)
{
this
.
password
=
null
;
this
.
keys
[
i
]
=
(
EncryptionKey
)
keys
[
i
].
clone
();
}
eTypes
=
EType
.
getDefaults
(
"default_tkt_enctypes"
,
keys
);
}
}
/**
/**
...
@@ -137,30 +137,24 @@ public final class KrbAsReqBuilder {
...
@@ -137,30 +137,24 @@ public final class KrbAsReqBuilder {
*/
*/
public
KrbAsReqBuilder
(
PrincipalName
cname
,
char
[]
pass
)
public
KrbAsReqBuilder
(
PrincipalName
cname
,
char
[]
pass
)
throws
KrbException
{
throws
KrbException
{
this
(
cname
);
init
(
cname
);
this
.
password
=
pass
.
clone
();
this
.
password
=
pass
.
clone
();
eTypes
=
EType
.
getDefaults
(
"default_tkt_enctypes"
)
;
this
.
ktab
=
null
;
}
}
/**
/**
* Retrieves an array of secret keys for the client. This is use
ful if
* Retrieves an array of secret keys for the client. This is use
d when
* the client supplies password but need keys to act as an acceptor
* the client supplies password but need keys to act as an acceptor
* (in JAAS words, isInitiator=true and storeKey=true)
* (in JAAS words, isInitiator=true and storeKey=true)
* @return original keys if initiated with keys, or generated keys if
* @return generated keys from password. PA-DATA from server might be used.
* password. In latter case, PA-DATA from server might be used to
* All "default_tkt_enctypes" keys will be generated, Never null.
* generate keys. All "default_tkt_enctypes" keys will be generated,
* @throws IllegalStateException if not constructed from a password
* Never null.
* @throws KrbException
* @throws KrbException
*/
*/
public
EncryptionKey
[]
getKeys
()
throws
KrbException
{
public
EncryptionKey
[]
getKeys
()
throws
KrbException
{
checkState
(
State
.
REQ_OK
,
"Cannot get keys"
);
checkState
(
State
.
REQ_OK
,
"Cannot get keys"
);
if
(
keys
!=
null
)
{
if
(
password
!=
null
)
{
EncryptionKey
[]
result
=
new
EncryptionKey
[
keys
.
length
];
int
[]
eTypes
=
EType
.
getDefaults
(
"default_tkt_enctypes"
);
for
(
int
i
=
0
;
i
<
keys
.
length
;
i
++)
{
result
[
i
]
=
(
EncryptionKey
)
keys
[
i
].
clone
();
}
return
result
;
}
else
{
EncryptionKey
[]
result
=
new
EncryptionKey
[
eTypes
.
length
];
EncryptionKey
[]
result
=
new
EncryptionKey
[
eTypes
.
length
];
/*
/*
...
@@ -205,6 +199,8 @@ public final class KrbAsReqBuilder {
...
@@ -205,6 +199,8 @@ public final class KrbAsReqBuilder {
}
}
}
}
return
result
;
return
result
;
}
else
{
throw
new
IllegalStateException
(
"Required password not provided"
);
}
}
}
}
...
@@ -241,12 +237,22 @@ public final class KrbAsReqBuilder {
...
@@ -241,12 +237,22 @@ public final class KrbAsReqBuilder {
/**
/**
* Build a KrbAsReq object from all info fed above. Normally this method
* Build a KrbAsReq object from all info fed above. Normally this method
* will be called twice: initial AS-REQ and second with pakey
* will be called twice: initial AS-REQ and second with pakey
* @param key null (initial AS-REQ) or pakey (with preauth)
* @return the KrbAsReq object
* @return the KrbAsReq object
* @throws KrbException
* @throws KrbException
* @throws IOException
* @throws IOException
*/
*/
private
KrbAsReq
build
()
throws
KrbException
,
IOException
{
private
KrbAsReq
build
(
EncryptionKey
key
)
throws
KrbException
,
IOException
{
return
new
KrbAsReq
(
pakey
,
int
[]
eTypes
;
if
(
password
!=
null
)
{
eTypes
=
EType
.
getDefaults
(
"default_tkt_enctypes"
);
}
else
{
EncryptionKey
[]
ks
=
Krb5Util
.
keysFromJavaxKeyTab
(
ktab
,
cname
);
eTypes
=
EType
.
getDefaults
(
"default_tkt_enctypes"
,
ks
);
for
(
EncryptionKey
k:
ks
)
k
.
destroy
();
}
return
new
KrbAsReq
(
key
,
options
,
options
,
cname
,
cname
,
sname
,
sname
,
...
@@ -263,9 +269,10 @@ public final class KrbAsReqBuilder {
...
@@ -263,9 +269,10 @@ public final class KrbAsReqBuilder {
* @throws Asn1Exception
* @throws Asn1Exception
* @throws IOException
* @throws IOException
*/
*/
private
KrbAsReqBuilder
resolve
()
throws
KrbException
,
Asn1Exception
,
IOException
{
private
KrbAsReqBuilder
resolve
()
if
(
keys
!=
null
)
{
throws
KrbException
,
Asn1Exception
,
IOException
{
rep
.
decryptUsingKeys
(
keys
,
req
);
if
(
ktab
!=
null
)
{
rep
.
decryptUsingKeyTab
(
ktab
,
req
,
cname
);
}
else
{
}
else
{
rep
.
decryptUsingPassword
(
password
,
req
,
cname
);
rep
.
decryptUsingPassword
(
password
,
req
,
cname
);
}
}
...
@@ -292,9 +299,10 @@ public final class KrbAsReqBuilder {
...
@@ -292,9 +299,10 @@ public final class KrbAsReqBuilder {
private
KrbAsReqBuilder
send
()
throws
KrbException
,
IOException
{
private
KrbAsReqBuilder
send
()
throws
KrbException
,
IOException
{
boolean
preAuthFailedOnce
=
false
;
boolean
preAuthFailedOnce
=
false
;
KdcComm
comm
=
new
KdcComm
(
cname
.
getRealmAsString
());
KdcComm
comm
=
new
KdcComm
(
cname
.
getRealmAsString
());
EncryptionKey
pakey
=
null
;
while
(
true
)
{
while
(
true
)
{
try
{
try
{
req
=
build
();
req
=
build
(
pakey
);
rep
=
new
KrbAsRep
(
comm
.
send
(
req
.
encoding
()));
rep
=
new
KrbAsRep
(
comm
.
send
(
req
.
encoding
()));
return
this
;
return
this
;
}
catch
(
KrbException
ke
)
{
}
catch
(
KrbException
ke
)
{
...
@@ -308,7 +316,10 @@ public final class KrbAsReqBuilder {
...
@@ -308,7 +316,10 @@ public final class KrbAsReqBuilder {
preAuthFailedOnce
=
true
;
preAuthFailedOnce
=
true
;
KRBError
kerr
=
ke
.
getError
();
KRBError
kerr
=
ke
.
getError
();
if
(
password
==
null
)
{
if
(
password
==
null
)
{
pakey
=
EncryptionKey
.
findKey
(
kerr
.
getEType
(),
keys
);
EncryptionKey
[]
ks
=
Krb5Util
.
keysFromJavaxKeyTab
(
ktab
,
cname
);
pakey
=
EncryptionKey
.
findKey
(
kerr
.
getEType
(),
ks
);
if
(
pakey
!=
null
)
pakey
=
(
EncryptionKey
)
pakey
.
clone
();
for
(
EncryptionKey
k:
ks
)
k
.
destroy
();
}
else
{
}
else
{
PAData
.
SaltAndParams
snp
=
PAData
.
getSaltAndParams
(
PAData
.
SaltAndParams
snp
=
PAData
.
getSaltAndParams
(
kerr
.
getEType
(),
kerr
.
getPA
());
kerr
.
getEType
(),
kerr
.
getPA
());
...
@@ -317,7 +328,7 @@ public final class KrbAsReqBuilder {
...
@@ -317,7 +328,7 @@ public final class KrbAsReqBuilder {
// does not recommend this
// does not recommend this
pakey
=
EncryptionKey
.
acquireSecretKey
(
password
,
pakey
=
EncryptionKey
.
acquireSecretKey
(
password
,
snp
.
salt
==
null
?
cname
.
getSalt
()
:
snp
.
salt
,
snp
.
salt
==
null
?
cname
.
getSalt
()
:
snp
.
salt
,
eTypes
[
0
],
EType
.
getDefaults
(
"default_tkt_enctypes"
)
[
0
],
null
);
null
);
}
else
{
}
else
{
pakey
=
EncryptionKey
.
acquireSecretKey
(
password
,
pakey
=
EncryptionKey
.
acquireSecretKey
(
password
,
...
@@ -369,15 +380,8 @@ public final class KrbAsReqBuilder {
...
@@ -369,15 +380,8 @@ public final class KrbAsReqBuilder {
*/
*/
public
void
destroy
()
{
public
void
destroy
()
{
state
=
State
.
DESTROYED
;
state
=
State
.
DESTROYED
;
if
(
keys
!=
null
)
{
for
(
EncryptionKey
k:
keys
)
{
k
.
destroy
();
}
keys
=
null
;
}
if
(
password
!=
null
)
{
if
(
password
!=
null
)
{
Arrays
.
fill
(
password
,
(
char
)
0
);
Arrays
.
fill
(
password
,
(
char
)
0
);
password
=
null
;
}
}
}
}
...
...
src/share/classes/sun/security/krb5/internal/ktab/KeyTab.java
浏览文件 @
812a3eaf
...
@@ -40,6 +40,7 @@ import java.io.IOException;
...
@@ -40,6 +40,7 @@ import java.io.IOException;
import
java.io.FileInputStream
;
import
java.io.FileInputStream
;
import
java.io.FileOutputStream
;
import
java.io.FileOutputStream
;
import
java.io.File
;
import
java.io.File
;
import
java.io.FileNotFoundException
;
import
java.util.Comparator
;
import
java.util.Comparator
;
import
java.util.HashMap
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.Map
;
...
@@ -50,92 +51,138 @@ import java.util.Vector;
...
@@ -50,92 +51,138 @@ import java.util.Vector;
* This class represents key table. The key table functions deal with storing
* This class represents key table. The key table functions deal with storing
* and retrieving service keys for use in authentication exchanges.
* and retrieving service keys for use in authentication exchanges.
*
*
* A KeyTab object is always constructed, if the file specified does not
* exist, it's still valid but empty. If there is an I/O error or file format
* error, it's invalid.
*
* The class is immutable on the read side (the write side is only used by
* the ktab tool).
*
* @author Yanni Zhang
* @author Yanni Zhang
*/
*/
public
class
KeyTab
implements
KeyTabConstants
{
public
class
KeyTab
implements
KeyTabConstants
{
int
kt_vno
;
private
static
KeyTab
singleton
=
null
;
private
static
final
boolean
DEBUG
=
Krb5
.
DEBUG
;
private
static
final
boolean
DEBUG
=
Krb5
.
DEBUG
;
private
static
String
name
;
private
static
String
defaultTabName
=
null
;
// Attention: Currently there is no way to remove a keytab from this map,
// this might lead to a memory leak.
private
static
Map
<
String
,
KeyTab
>
map
=
new
HashMap
<>();
// KeyTab file does not exist. Note: a missing keytab is still valid
private
boolean
isMissing
=
false
;
// KeyTab file is invalid, possibly an I/O error or a file format error.
private
boolean
isValid
=
true
;
private
final
String
tabName
;
private
long
lastModified
;
private
int
kt_vno
;
private
Vector
<
KeyTabEntry
>
entries
=
new
Vector
<>();
private
Vector
<
KeyTabEntry
>
entries
=
new
Vector
<>();
private
KeyTab
(
String
filename
)
throws
IOException
,
RealmException
{
/**
init
(
filename
);
* Constructs a KeyTab object.
*
* If there is any I/O error or format errot during the loading, the
* isValid flag is set to false, and all half-read entries are dismissed.
* @param filename path name for the keytab file, must not be null
*/
private
KeyTab
(
String
filename
)
{
tabName
=
filename
;
try
{
lastModified
=
new
File
(
tabName
).
lastModified
();
KeyTabInputStream
kis
=
new
KeyTabInputStream
(
new
FileInputStream
(
filename
));
load
(
kis
);
kis
.
close
();
}
catch
(
FileNotFoundException
e
)
{
entries
.
clear
();
isMissing
=
true
;
}
catch
(
Exception
ioe
)
{
entries
.
clear
();
isValid
=
false
;
}
}
}
/**
* Read a keytab file. Returns a new object and save it into cache when
* new content (modified since last read) is available. If keytab file is
* invalid, the old object will be returned. This is a safeguard for
* partial-written keytab files or non-stable network. Please note that
* a missing keytab is valid, which is equivalent to an empty keytab.
*
* @param s file name of keytab, must not be null
* @return the keytab object, can be invalid, but never null.
*/
private
synchronized
static
KeyTab
getInstance0
(
String
s
)
{
long
lm
=
new
File
(
s
).
lastModified
();
KeyTab
old
=
map
.
get
(
s
);
if
(
old
!=
null
&&
old
.
isValid
()
&&
old
.
lastModified
==
lm
)
{
return
old
;
}
KeyTab
ktab
=
new
KeyTab
(
s
);
if
(
ktab
.
isValid
())
{
// A valid new keytab
map
.
put
(
s
,
ktab
);
return
ktab
;
}
else
if
(
old
!=
null
)
{
// An existing old one
return
old
;
}
else
{
return
ktab
;
// first read is invalid
}
}
/**
* Gets a KeyTab object.
* @param s the key tab file name.
* @return the KeyTab object, never null.
*/
public
static
KeyTab
getInstance
(
String
s
)
{
public
static
KeyTab
getInstance
(
String
s
)
{
name
=
parse
(
s
);
if
(
s
==
null
)
{
if
(
name
==
null
)
{
return
getInstance
();
return
getInstance
();
}
else
{
return
getInstance0
(
s
);
}
}
return
getInstance
(
new
File
(
name
));
}
}
/**
/**
* Gets
the single instance of KeyTab class
.
* Gets
a KeyTab object
.
* @param file the key tab file.
* @param file the key tab file.
* @return single instance of KeyTab;
* @return the KeyTab object, never null.
* return null if error occurs while reading data out of the file.
*/
*/
public
static
KeyTab
getInstance
(
File
file
)
{
public
static
KeyTab
getInstance
(
File
file
)
{
try
{
if
(
file
==
null
)
{
if
(!(
file
.
exists
()))
{
return
getInstance
();
singleton
=
null
;
}
else
{
}
else
{
return
getInstance0
(
file
.
getPath
());
String
fname
=
file
.
getAbsolutePath
();
// Since this class deals with file I/O operations,
// we want only one class instance existing.
if
(
singleton
!=
null
)
{
File
kfile
=
new
File
(
singleton
.
name
);
String
kname
=
kfile
.
getAbsolutePath
();
if
(
kname
.
equalsIgnoreCase
(
fname
))
{
if
(
DEBUG
)
{
System
.
out
.
println
(
"KeyTab instance already exists"
);
}
}
}
else
{
singleton
=
new
KeyTab
(
fname
);
}
}
}
catch
(
Exception
e
)
{
singleton
=
null
;
if
(
DEBUG
)
{
System
.
out
.
println
(
"Could not obtain an instance of KeyTab"
+
e
.
getMessage
());
}
}
}
return
singleton
;
}
}
/**
/**
* Gets the single instance of KeyTab class.
* Gets the default KeyTab object.
* @return single instance of KeyTab; return null if default keytab file
* @return the KeyTab object, never null.
* does not exist, or error occurs while reading data from the file.
*/
*/
public
static
KeyTab
getInstance
()
{
public
static
KeyTab
getInstance
()
{
try
{
return
getInstance
(
getDefaultTabName
());
name
=
getDefaultKeyTab
();
}
if
(
name
!=
null
)
{
singleton
=
getInstance
(
new
File
(
name
));
public
boolean
isMissing
()
{
}
return
isMissing
;
}
catch
(
Exception
e
)
{
}
singleton
=
null
;
if
(
DEBUG
)
{
public
boolean
isValid
()
{
System
.
out
.
println
(
"Could not obtain an instance of KeyTab"
+
return
isValid
;
e
.
getMessage
());
}
}
return
singleton
;
}
}
/**
/**
* The location of keytab file will be read from the configuration file
* The location of keytab file will be read from the configuration file
* If it is not specified, consider user.home as the keytab file's
* If it is not specified, consider user.home as the keytab file's
* default location.
* default location.
* @return never null
*/
*/
private
static
String
getDefault
KeyTab
()
{
private
static
String
getDefault
TabName
()
{
if
(
n
ame
!=
null
)
{
if
(
defaultTabN
ame
!=
null
)
{
return
n
ame
;
return
defaultTabN
ame
;
}
else
{
}
else
{
String
kname
=
null
;
String
kname
=
null
;
try
{
try
{
...
@@ -145,7 +192,7 @@ public class KeyTab implements KeyTabConstants {
...
@@ -145,7 +192,7 @@ public class KeyTab implements KeyTabConstants {
StringTokenizer
st
=
new
StringTokenizer
(
keytab_names
,
" "
);
StringTokenizer
st
=
new
StringTokenizer
(
keytab_names
,
" "
);
while
(
st
.
hasMoreTokens
())
{
while
(
st
.
hasMoreTokens
())
{
kname
=
parse
(
st
.
nextToken
());
kname
=
parse
(
st
.
nextToken
());
if
(
kname
!=
null
)
{
if
(
new
File
(
kname
).
exists
()
)
{
break
;
break
;
}
}
}
}
...
@@ -165,19 +212,20 @@ public class KeyTab implements KeyTabConstants {
...
@@ -165,19 +212,20 @@ public class KeyTab implements KeyTabConstants {
new
sun
.
security
.
action
.
GetPropertyAction
(
"user.dir"
));
new
sun
.
security
.
action
.
GetPropertyAction
(
"user.dir"
));
}
}
if
(
user_home
!=
null
)
{
kname
=
user_home
+
File
.
separator
+
"krb5.keytab"
;
kname
=
user_home
+
File
.
separator
+
"krb5.keytab"
;
}
}
}
defaultTabName
=
kname
;
return
kname
;
return
kname
;
}
}
}
}
/**
* Parses some common keytab name formats
* @param name never null
* @return never null
*/
private
static
String
parse
(
String
name
)
{
private
static
String
parse
(
String
name
)
{
String
kname
=
null
;
String
kname
;
if
(
name
==
null
)
{
return
null
;
}
if
((
name
.
length
()
>=
5
)
&&
if
((
name
.
length
()
>=
5
)
&&
(
name
.
substring
(
0
,
5
).
equalsIgnoreCase
(
"FILE:"
)))
{
(
name
.
substring
(
0
,
5
).
equalsIgnoreCase
(
"FILE:"
)))
{
kname
=
name
.
substring
(
5
);
kname
=
name
.
substring
(
5
);
...
@@ -194,18 +242,6 @@ public class KeyTab implements KeyTabConstants {
...
@@ -194,18 +242,6 @@ public class KeyTab implements KeyTabConstants {
return
kname
;
return
kname
;
}
}
private
synchronized
void
init
(
String
filename
)
throws
IOException
,
RealmException
{
if
(
filename
!=
null
)
{
KeyTabInputStream
kis
=
new
KeyTabInputStream
(
new
FileInputStream
(
filename
));
load
(
kis
);
kis
.
close
();
name
=
filename
;
}
}
private
void
load
(
KeyTabInputStream
kis
)
private
void
load
(
KeyTabInputStream
kis
)
throws
IOException
,
RealmException
{
throws
IOException
,
RealmException
{
...
@@ -234,14 +270,13 @@ public class KeyTab implements KeyTabConstants {
...
@@ -234,14 +270,13 @@ public class KeyTab implements KeyTabConstants {
* etypes that have been configured for use. If there are multiple
* etypes that have been configured for use. If there are multiple
* keys with same etype, the one with the highest kvno is returned.
* keys with same etype, the one with the highest kvno is returned.
* @param service the PrincipalName of the requested service
* @param service the PrincipalName of the requested service
* @return an array containing all the service keys
* @return an array containing all the service keys
, never null
*/
*/
public
EncryptionKey
[]
readServiceKeys
(
PrincipalName
service
)
{
public
EncryptionKey
[]
readServiceKeys
(
PrincipalName
service
)
{
KeyTabEntry
entry
;
KeyTabEntry
entry
;
EncryptionKey
key
;
EncryptionKey
key
;
int
size
=
entries
.
size
();
int
size
=
entries
.
size
();
ArrayList
<
EncryptionKey
>
keys
=
new
ArrayList
<>(
size
);
ArrayList
<
EncryptionKey
>
keys
=
new
ArrayList
<>(
size
);
for
(
int
i
=
size
-
1
;
i
>=
0
;
i
--)
{
for
(
int
i
=
size
-
1
;
i
>=
0
;
i
--)
{
entry
=
entries
.
elementAt
(
i
);
entry
=
entries
.
elementAt
(
i
);
if
(
entry
.
service
.
match
(
service
))
{
if
(
entry
.
service
.
match
(
service
))
{
...
@@ -260,10 +295,7 @@ public class KeyTab implements KeyTabConstants {
...
@@ -260,10 +295,7 @@ public class KeyTab implements KeyTabConstants {
}
}
}
}
}
}
size
=
keys
.
size
();
size
=
keys
.
size
();
if
(
size
==
0
)
return
null
;
EncryptionKey
[]
retVal
=
keys
.
toArray
(
new
EncryptionKey
[
size
]);
EncryptionKey
[]
retVal
=
keys
.
toArray
(
new
EncryptionKey
[
size
]);
// Sort keys according to default_tkt_enctypes
// Sort keys according to default_tkt_enctypes
...
@@ -328,10 +360,13 @@ public class KeyTab implements KeyTabConstants {
...
@@ -328,10 +360,13 @@ public class KeyTab implements KeyTabConstants {
return
false
;
return
false
;
}
}
public
static
String
tabName
()
{
public
String
tabName
()
{
return
n
ame
;
return
tabN
ame
;
}
}
/////////////////// THE WRITE SIDE ///////////////////////
/////////////// only used by ktab tool //////////////////
/**
/**
* Adds a new entry in the key table.
* Adds a new entry in the key table.
* @param service the service which will have a new entry in the key table.
* @param service the service which will have a new entry in the key table.
...
@@ -394,7 +429,7 @@ public class KeyTab implements KeyTabConstants {
...
@@ -394,7 +429,7 @@ public class KeyTab implements KeyTabConstants {
*/
*/
public
synchronized
static
KeyTab
create
()
public
synchronized
static
KeyTab
create
()
throws
IOException
,
RealmException
{
throws
IOException
,
RealmException
{
String
dname
=
getDefault
KeyTab
();
String
dname
=
getDefault
TabName
();
return
create
(
dname
);
return
create
(
dname
);
}
}
...
@@ -408,8 +443,7 @@ public class KeyTab implements KeyTabConstants {
...
@@ -408,8 +443,7 @@ public class KeyTab implements KeyTabConstants {
new
KeyTabOutputStream
(
new
FileOutputStream
(
name
));
new
KeyTabOutputStream
(
new
FileOutputStream
(
name
));
kos
.
writeVersion
(
KRB5_KT_VNO
);
kos
.
writeVersion
(
KRB5_KT_VNO
);
kos
.
close
();
kos
.
close
();
singleton
=
new
KeyTab
(
name
);
return
new
KeyTab
(
name
);
return
singleton
;
}
}
/**
/**
...
@@ -417,7 +451,7 @@ public class KeyTab implements KeyTabConstants {
...
@@ -417,7 +451,7 @@ public class KeyTab implements KeyTabConstants {
*/
*/
public
synchronized
void
save
()
throws
IOException
{
public
synchronized
void
save
()
throws
IOException
{
KeyTabOutputStream
kos
=
KeyTabOutputStream
kos
=
new
KeyTabOutputStream
(
new
FileOutputStream
(
n
ame
));
new
KeyTabOutputStream
(
new
FileOutputStream
(
tabN
ame
));
kos
.
writeVersion
(
kt_vno
);
kos
.
writeVersion
(
kt_vno
);
for
(
int
i
=
0
;
i
<
entries
.
size
();
i
++)
{
for
(
int
i
=
0
;
i
<
entries
.
size
();
i
++)
{
kos
.
writeEntry
(
entries
.
elementAt
(
i
));
kos
.
writeEntry
(
entries
.
elementAt
(
i
));
...
@@ -490,13 +524,4 @@ public class KeyTab implements KeyTabConstants {
...
@@ -490,13 +524,4 @@ public class KeyTab implements KeyTabConstants {
kos
.
write16
(
KRB5_KT_VNO
);
kos
.
write16
(
KRB5_KT_VNO
);
kos
.
close
();
kos
.
close
();
}
}
public
static
void
refresh
()
{
if
(
singleton
!=
null
)
{
if
(
DEBUG
)
{
System
.
out
.
println
(
"Refreshing Keytab"
);
}
singleton
=
null
;
}
}
}
}
src/share/classes/sun/security/ssl/ServerHandshaker.java
浏览文件 @
812a3eaf
/*
/*
* Copyright (c) 1996, 201
0
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 201
1
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -1285,11 +1285,12 @@ final class ServerHandshaker extends Handshaker {
...
@@ -1285,11 +1285,12 @@ final class ServerHandshaker extends Handshaker {
// check permission to access and use the secret key of the
// check permission to access and use the secret key of the
// Kerberized "host" service
// Kerberized "host" service
if
(
kerberosKeys
!=
null
)
{
if
(
kerberosKeys
!=
null
&&
kerberosKeys
.
length
>
0
)
{
if
(
debug
!=
null
&&
Debug
.
isOn
(
"handshake"
))
{
if
(
debug
!=
null
&&
Debug
.
isOn
(
"handshake"
))
{
System
.
out
.
println
(
"Using Kerberos key: "
+
for
(
SecretKey
k:
kerberosKeys
)
{
kerberosKeys
[
0
]);
System
.
out
.
println
(
"Using Kerberos key: "
+
k
);
}
}
}
String
serverPrincipal
=
String
serverPrincipal
=
...
...
src/share/classes/sun/security/ssl/krb5/Krb5ProxyImpl.java
浏览文件 @
812a3eaf
/*
/*
* Copyright (c) 2009, 201
0
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 201
1
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -40,7 +40,7 @@ import sun.security.krb5.PrincipalName;
...
@@ -40,7 +40,7 @@ import sun.security.krb5.PrincipalName;
import
sun.security.ssl.Krb5Proxy
;
import
sun.security.ssl.Krb5Proxy
;
/**
/**
* An implementatin of Krb5Proxy that simply delegates to the appropriate
* An implementati
o
n of Krb5Proxy that simply delegates to the appropriate
* Kerberos APIs.
* Kerberos APIs.
*/
*/
public
class
Krb5ProxyImpl
implements
Krb5Proxy
{
public
class
Krb5ProxyImpl
implements
Krb5Proxy
{
...
@@ -62,7 +62,7 @@ public class Krb5ProxyImpl implements Krb5Proxy {
...
@@ -62,7 +62,7 @@ public class Krb5ProxyImpl implements Krb5Proxy {
@Override
@Override
public
SecretKey
[]
getServerKeys
(
AccessControlContext
acc
)
public
SecretKey
[]
getServerKeys
(
AccessControlContext
acc
)
throws
LoginException
{
throws
LoginException
{
return
Krb5Util
.
get
Keys
(
GSSCaller
.
CALLER_SSL_SERVER
,
null
,
acc
);
return
Krb5Util
.
get
ServiceCreds
(
GSSCaller
.
CALLER_SSL_SERVER
,
null
,
acc
).
getKKeys
(
);
}
}
@Override
@Override
...
...
src/windows/classes/sun/security/krb5/internal/tools/Kinit.java
浏览文件 @
812a3eaf
/*
/*
* Copyright (c) 2000, 201
0
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 201
1
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -30,12 +30,15 @@
...
@@ -30,12 +30,15 @@
package
sun.security.krb5.internal.tools
;
package
sun.security.krb5.internal.tools
;
import
java.io.File
;
import
sun.security.krb5.*
;
import
sun.security.krb5.*
;
import
sun.security.krb5.internal.*
;
import
sun.security.krb5.internal.*
;
import
sun.security.krb5.internal.ccache.*
;
import
sun.security.krb5.internal.ccache.*
;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.util.Arrays
;
import
java.util.Arrays
;
import
javax.security.auth.kerberos.KerberosPrincipal
;
import
sun.security.util.Password
;
import
sun.security.util.Password
;
import
javax.security.auth.kerberos.KeyTab
;
/**
/**
* Kinit tool for obtaining Kerberos v5 tickets.
* Kinit tool for obtaining Kerberos v5 tickets.
...
@@ -153,7 +156,6 @@ public class Kinit {
...
@@ -153,7 +156,6 @@ public class Kinit {
System
.
out
.
println
(
"Principal is "
+
principal
);
System
.
out
.
println
(
"Principal is "
+
principal
);
}
}
char
[]
psswd
=
options
.
password
;
char
[]
psswd
=
options
.
password
;
EncryptionKey
[]
skeys
=
null
;
boolean
useKeytab
=
options
.
useKeytabFile
();
boolean
useKeytab
=
options
.
useKeytabFile
();
if
(!
useKeytab
)
{
if
(!
useKeytab
)
{
if
(
princName
==
null
)
{
if
(
princName
==
null
)
{
...
@@ -186,17 +188,9 @@ public class Kinit {
...
@@ -186,17 +188,9 @@ public class Kinit {
}
}
}
}
// assert princName and principal are nonnull
builder
=
new
KrbAsReqBuilder
(
principal
,
ktabName
==
null
skeys
=
EncryptionKey
.
acquireSecretKeys
(
principal
,
ktabName
);
?
KeyTab
.
getInstance
()
:
KeyTab
.
getInstance
(
new
File
(
ktabName
)));
if
(
skeys
==
null
||
skeys
.
length
==
0
)
{
String
msg
=
"No supported key found in keytab"
;
if
(
princName
!=
null
)
{
msg
+=
" for principal "
+
princName
;
}
throw
new
KrbException
(
msg
);
}
builder
=
new
KrbAsReqBuilder
(
principal
,
skeys
);
}
}
KDCOptions
opt
=
new
KDCOptions
();
KDCOptions
opt
=
new
KDCOptions
();
...
...
src/windows/classes/sun/security/krb5/internal/tools/Klist.java
浏览文件 @
812a3eaf
/*
/*
* Copyright (c) 2003, 20
09
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 20
11
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -95,16 +95,15 @@ public class Klist {
...
@@ -95,16 +95,15 @@ public class Klist {
}
}
break
;
break
;
case
'k'
:
case
'k'
:
if
(
klist
.
name
==
null
)
{
try
{
klist
.
target
=
KeyTab
.
getInstance
();
KeyTab
ktab
=
KeyTab
.
getInstance
(
klist
.
name
);
klist
.
name
=
KeyTab
.
tabName
();
klist
.
target
=
ktab
;
}
else
klist
.
target
=
KeyTab
.
getInstance
(
klist
.
name
);
klist
.
name
=
ktab
.
tabName
();
if
(
klist
.
target
!=
null
)
{
}
catch
(
Exception
e
)
{
klist
.
displayTab
();
}
else
{
klist
.
displayMessage
(
"KeyTab"
);
klist
.
displayMessage
(
"KeyTab"
);
System
.
exit
(-
1
);
System
.
exit
(-
1
);
}
}
klist
.
displayTab
();
break
;
break
;
default
:
default
:
if
(
klist
.
name
!=
null
)
{
if
(
klist
.
name
!=
null
)
{
...
@@ -295,9 +294,10 @@ public class Klist {
...
@@ -295,9 +294,10 @@ public class Klist {
void
displayMessage
(
String
target
)
{
void
displayMessage
(
String
target
)
{
if
(
name
==
null
)
{
if
(
name
==
null
)
{
name
=
""
;
System
.
out
.
println
(
"Default "
+
target
+
" not found."
);
}
else
{
System
.
out
.
println
(
target
+
" "
+
name
+
" not found."
);
}
}
System
.
out
.
println
(
target
+
" "
+
name
+
" not found."
);
}
}
/**
/**
* Reformats the date from the form -
* Reformats the date from the form -
...
...
src/windows/classes/sun/security/krb5/internal/tools/Ktab.java
浏览文件 @
812a3eaf
/*
/*
* Copyright (c) 2003, 201
0
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 201
1
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -321,7 +321,7 @@ public class Ktab {
...
@@ -321,7 +321,7 @@ public class Ktab {
* Lists key table name and entries in it.
* Lists key table name and entries in it.
*/
*/
void
listKt
()
{
void
listKt
()
{
System
.
out
.
println
(
"Keytab name: "
+
KeyTab
.
tabName
());
System
.
out
.
println
(
"Keytab name: "
+
table
.
tabName
());
KeyTabEntry
[]
entries
=
table
.
getEntries
();
KeyTabEntry
[]
entries
=
table
.
getEntries
();
if
((
entries
!=
null
)
&&
(
entries
.
length
>
0
))
{
if
((
entries
!=
null
)
&&
(
entries
.
length
>
0
))
{
String
[][]
output
=
new
String
[
entries
.
length
+
1
][
showTime
?
3
:
2
];
String
[][]
output
=
new
String
[
entries
.
length
+
1
][
showTime
?
3
:
2
];
...
...
test/sun/security/krb5/auto/Context.java
浏览文件 @
812a3eaf
...
@@ -44,6 +44,7 @@ import com.sun.security.jgss.InquireType;
...
@@ -44,6 +44,7 @@ import com.sun.security.jgss.InquireType;
import
com.sun.security.jgss.AuthorizationDataEntry
;
import
com.sun.security.jgss.AuthorizationDataEntry
;
import
java.io.ByteArrayInputStream
;
import
java.io.ByteArrayInputStream
;
import
java.io.ByteArrayOutputStream
;
import
java.io.ByteArrayOutputStream
;
import
javax.security.auth.kerberos.KeyTab
;
/**
/**
* Context of a JGSS subject, encapsulating Subject and GSSContext.
* Context of a JGSS subject, encapsulating Subject and GSSContext.
...
@@ -107,15 +108,19 @@ public class Context {
...
@@ -107,15 +108,19 @@ public class Context {
return
out
;
return
out
;
}
}
public
static
Context
fromUserPass
(
String
user
,
char
[]
pass
,
boolean
storeKey
)
throws
Exception
{
return
fromUserPass
(
null
,
user
,
pass
,
storeKey
);
}
/**
/**
* Logins with a username and a password, using Krb5LoginModule directly
* Logins with a username and a password, using Krb5LoginModule directly
* @param storeKey true if key should be saved, used on acceptor side
* @param storeKey true if key should be saved, used on acceptor side
*/
*/
public
static
Context
fromUserPass
(
S
tring
user
,
char
[]
pass
,
boolean
storeKey
)
public
static
Context
fromUserPass
(
S
ubject
s
,
throws
Exception
{
String
user
,
char
[]
pass
,
boolean
storeKey
)
throws
Exception
{
Context
out
=
new
Context
();
Context
out
=
new
Context
();
out
.
name
=
user
;
out
.
name
=
user
;
out
.
s
=
new
Subject
()
;
out
.
s
=
s
==
null
?
new
Subject
()
:
s
;
Krb5LoginModule
krb5
=
new
Krb5LoginModule
();
Krb5LoginModule
krb5
=
new
Krb5LoginModule
();
Map
<
String
,
String
>
map
=
new
HashMap
<>();
Map
<
String
,
String
>
map
=
new
HashMap
<>();
Map
<
String
,
Object
>
shared
=
new
HashMap
<>();
Map
<
String
,
Object
>
shared
=
new
HashMap
<>();
...
@@ -198,12 +203,25 @@ public class Context {
...
@@ -198,12 +203,25 @@ public class Context {
* @throws java.lang.Exception
* @throws java.lang.Exception
*/
*/
public
void
startAsServer
(
final
Oid
mech
)
throws
Exception
{
public
void
startAsServer
(
final
Oid
mech
)
throws
Exception
{
startAsServer
(
null
,
mech
);
}
/**
* Starts as a server with the specified service name
* @param name the service name
* @param mech GSS mech
* @throws java.lang.Exception
*/
public
void
startAsServer
(
final
String
name
,
final
Oid
mech
)
throws
Exception
{
doAs
(
new
Action
()
{
doAs
(
new
Action
()
{
@Override
@Override
public
byte
[]
run
(
Context
me
,
byte
[]
dummy
)
throws
Exception
{
public
byte
[]
run
(
Context
me
,
byte
[]
dummy
)
throws
Exception
{
GSSManager
m
=
GSSManager
.
getInstance
();
GSSManager
m
=
GSSManager
.
getInstance
();
me
.
x
=
(
ExtendedGSSContext
)
m
.
createContext
(
m
.
createCredential
(
me
.
x
=
(
ExtendedGSSContext
)
m
.
createContext
(
m
.
createCredential
(
null
,
name
==
null
?
null
:
(
name
.
indexOf
(
'@'
)
<
0
?
m
.
createName
(
name
,
null
)
:
m
.
createName
(
name
,
GSSName
.
NT_HOSTBASED_SERVICE
)),
GSSCredential
.
INDEFINITE_LIFETIME
,
GSSCredential
.
INDEFINITE_LIFETIME
,
mech
,
mech
,
GSSCredential
.
ACCEPT_ONLY
));
GSSCredential
.
ACCEPT_ONLY
));
...
@@ -229,6 +247,14 @@ public class Context {
...
@@ -229,6 +247,14 @@ public class Context {
return
x
;
return
x
;
}
}
/**
* Accesses the internal subject.
* @return the subject
*/
public
Subject
s
()
{
return
s
;
}
/**
/**
* Disposes the GSSContext within
* Disposes the GSSContext within
* @throws org.ietf.jgss.GSSException
* @throws org.ietf.jgss.GSSException
...
@@ -297,7 +323,7 @@ public class Context {
...
@@ -297,7 +323,7 @@ public class Context {
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
;
// Don't care
;
// Don't care
}
}
System
.
out
.
println
(
"======
=========================
======"
);
System
.
out
.
println
(
"======
Private Credentials Set
======"
);
for
(
Object
o
:
s
.
getPrivateCredentials
())
{
for
(
Object
o
:
s
.
getPrivateCredentials
())
{
System
.
out
.
println
(
" "
+
o
.
getClass
());
System
.
out
.
println
(
" "
+
o
.
getClass
());
if
(
o
instanceof
KerberosTicket
)
{
if
(
o
instanceof
KerberosTicket
)
{
...
@@ -315,6 +341,8 @@ public class Context {
...
@@ -315,6 +341,8 @@ public class Context {
for
(
Object
k
:
map
.
keySet
())
{
for
(
Object
k
:
map
.
keySet
())
{
System
.
out
.
println
(
" "
+
k
+
": "
+
map
.
get
(
k
));
System
.
out
.
println
(
" "
+
k
+
": "
+
map
.
get
(
k
));
}
}
}
else
{
System
.
out
.
println
(
" "
+
o
);
}
}
}
}
if
(
x
!=
null
&&
x
instanceof
ExtendedGSSContext
)
{
if
(
x
!=
null
&&
x
instanceof
ExtendedGSSContext
)
{
...
...
test/sun/security/krb5/auto/DynamicKeytab.java
0 → 100644
浏览文件 @
812a3eaf
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 6894072
* @run main/othervm DynamicKeytab
* @summary always refresh keytab
*/
import
java.io.File
;
import
java.io.FileOutputStream
;
import
org.ietf.jgss.GSSException
;
import
sun.security.jgss.GSSUtil
;
import
sun.security.krb5.KrbException
;
import
sun.security.krb5.internal.Krb5
;
public
class
DynamicKeytab
{
Context
c
,
s
;
public
static
void
main
(
String
[]
args
)
throws
Exception
{
new
DynamicKeytab
().
go
();
}
void
go
()
throws
Exception
{
OneKDC
k
=
new
OneKDC
(
null
);
k
.
writeJAASConf
();
new
File
(
OneKDC
.
KTAB
).
delete
();
// Starts with no keytab
c
=
Context
.
fromJAAS
(
"client"
);
s
=
Context
.
fromJAAS
(
"com.sun.security.jgss.krb5.accept"
);
// Test 1: read new key 1 from keytab
k
.
addPrincipal
(
OneKDC
.
SERVER
,
"pass1"
.
toCharArray
());
k
.
writeKtab
(
OneKDC
.
KTAB
);
connect
();
// Test 2: service key cached, find 1 in keytab (now contains 1 and 2)
k
.
addPrincipal
(
OneKDC
.
SERVER
,
"pass2"
.
toCharArray
());
k
.
appendKtab
(
OneKDC
.
KTAB
);
connect
();
// Test 3: re-login. Now find 2 in keytab
c
=
Context
.
fromJAAS
(
"client"
);
connect
();
// Test 4: re-login, KDC use 3 this time.
c
=
Context
.
fromJAAS
(
"client"
);
// Put 3 and 4 into keytab but keep the real key back to 3.
k
.
addPrincipal
(
OneKDC
.
SERVER
,
"pass3"
.
toCharArray
());
k
.
appendKtab
(
OneKDC
.
KTAB
);
k
.
addPrincipal
(
OneKDC
.
SERVER
,
"pass4"
.
toCharArray
());
k
.
appendKtab
(
OneKDC
.
KTAB
);
k
.
addPrincipal
(
OneKDC
.
SERVER
,
"pass3"
.
toCharArray
());
connect
();
// Test 5: invalid keytab file, should ignore
new
FileOutputStream
(
OneKDC
.
KTAB
).
write
(
"BADBADBAD"
.
getBytes
());
connect
();
// Test 6: delete keytab file, identical to revoke all
new
File
(
OneKDC
.
KTAB
).
delete
();
try
{
connect
();
throw
new
Exception
(
"Should not success"
);
}
catch
(
GSSException
gsse
)
{
System
.
out
.
println
(
gsse
);
KrbException
ke
=
(
KrbException
)
gsse
.
getCause
();
// KrbApReq.authenticate(*) if (dkey == null)...
// This should have been Krb5.KRB_AP_ERR_NOKEY
if
(
ke
.
returnCode
()
!=
Krb5
.
API_INVALID_ARG
)
{
throw
new
Exception
(
"Not expected failure code: "
+
ke
.
returnCode
());
}
}
// Test 7: 3 revoked, should fail (now contains only 5)
k
.
addPrincipal
(
OneKDC
.
SERVER
,
"pass5"
.
toCharArray
());
k
.
writeKtab
(
OneKDC
.
KTAB
);
// overwrite keytab, which means
// old key is revoked
try
{
connect
();
throw
new
Exception
(
"Should not success"
);
}
catch
(
GSSException
gsse
)
{
System
.
out
.
println
(
gsse
);
KrbException
ke
=
(
KrbException
)
gsse
.
getCause
();
if
(
ke
.
returnCode
()
!=
Krb5
.
KRB_AP_ERR_BADKEYVER
)
{
throw
new
Exception
(
"Not expected failure code: "
+
ke
.
returnCode
());
}
}
// Test 8: an empty KDC means revoke all
KDC
.
create
(
"EMPTY.REALM"
).
writeKtab
(
OneKDC
.
KTAB
);
try
{
connect
();
throw
new
Exception
(
"Should not success"
);
}
catch
(
GSSException
gsse
)
{
System
.
out
.
println
(
gsse
);
KrbException
ke
=
(
KrbException
)
gsse
.
getCause
();
// KrbApReq.authenticate(*) if (dkey == null)...
// This should have been Krb5.KRB_AP_ERR_NOKEY
if
(
ke
.
returnCode
()
!=
Krb5
.
API_INVALID_ARG
)
{
throw
new
Exception
(
"Not expected failure code: "
+
ke
.
returnCode
());
}
}
}
void
connect
()
throws
Exception
{
Thread
.
sleep
(
2000
);
// make sure ktab timestamp is different
c
.
startAsClient
(
OneKDC
.
SERVER
,
GSSUtil
.
GSS_KRB5_MECH_OID
);
s
.
startAsServer
(
GSSUtil
.
GSS_KRB5_MECH_OID
);
Context
.
handshake
(
c
,
s
);
}
}
test/sun/security/krb5/auto/KDC.java
浏览文件 @
812a3eaf
...
@@ -228,7 +228,33 @@ public class KDC {
...
@@ -228,7 +228,33 @@ public class KDC {
}
}
/**
/**
* Write all principals' keys from multiple KDCsinto one keytab file.
* Writes or appends KDC keys into a keytab. See doc for writeMultiKtab.
* @param append true if append, otherwise, overwrite.
*/
private
static
void
writeKtab0
(
String
tab
,
boolean
append
,
KDC
...
kdcs
)
throws
IOException
,
KrbException
{
KeyTab
ktab
=
append
?
KeyTab
.
getInstance
(
tab
)
:
KeyTab
.
create
(
tab
);
for
(
KDC
kdc:
kdcs
)
{
for
(
String
name
:
kdc
.
passwords
.
keySet
())
{
char
[]
pass
=
kdc
.
passwords
.
get
(
name
);
int
kvno
=
0
;
if
(
Character
.
isDigit
(
pass
[
pass
.
length
-
1
]))
{
kvno
=
pass
[
pass
.
length
-
1
]
-
'0'
;
}
ktab
.
addEntry
(
new
PrincipalName
(
name
,
name
.
indexOf
(
'/'
)
<
0
?
PrincipalName
.
KRB_NT_UNKNOWN
:
PrincipalName
.
KRB_NT_SRV_HST
),
pass
,
kvno
,
true
);
}
}
ktab
.
save
();
}
/**
* Writes all principals' keys from multiple KDCs into one keytab file.
* Note that the keys for the krbtgt principals will not be written.
* Note that the keys for the krbtgt principals will not be written.
* <p>
* <p>
* Attention: This method references krb5.conf settings. If you need to
* Attention: This method references krb5.conf settings. If you need to
...
@@ -252,17 +278,16 @@ public class KDC {
...
@@ -252,17 +278,16 @@ public class KDC {
*/
*/
public
static
void
writeMultiKtab
(
String
tab
,
KDC
...
kdcs
)
public
static
void
writeMultiKtab
(
String
tab
,
KDC
...
kdcs
)
throws
IOException
,
KrbException
{
throws
IOException
,
KrbException
{
KeyTab
ktab
=
KeyTab
.
create
(
tab
);
writeKtab0
(
tab
,
false
,
kdcs
);
for
(
KDC
kdc:
kdcs
)
{
}
for
(
String
name
:
kdc
.
passwords
.
keySet
())
{
ktab
.
addEntry
(
new
PrincipalName
(
name
,
/**
name
.
indexOf
(
'/'
)
<
0
?
* Appends all principals' keys from multiple KDCs to one keytab file.
PrincipalName
.
KRB_NT_UNKNOWN
:
* See writeMultiKtab for details.
PrincipalName
.
KRB_NT_SRV_HST
),
*/
kdc
.
passwords
.
get
(
name
),
-
1
,
true
);
public
static
void
appendMultiKtab
(
String
tab
,
KDC
...
kdcs
)
}
throws
IOException
,
KrbException
{
}
writeKtab0
(
tab
,
true
,
kdcs
);
ktab
.
save
();
}
}
/**
/**
...
@@ -272,6 +297,13 @@ public class KDC {
...
@@ -272,6 +297,13 @@ public class KDC {
KDC
.
writeMultiKtab
(
tab
,
this
);
KDC
.
writeMultiKtab
(
tab
,
this
);
}
}
/**
* Appends keys in this KDC to a ktab.
*/
public
void
appendKtab
(
String
tab
)
throws
IOException
,
KrbException
{
KDC
.
appendMultiKtab
(
tab
,
this
);
}
/**
/**
* Adds a new principal to this realm with a given password.
* Adds a new principal to this realm with a given password.
* @param user the principal's name. For a service principal, use the
* @param user the principal's name. For a service principal, use the
...
...
test/sun/security/krb5/auto/KeyTabCompat.java
0 → 100644
浏览文件 @
812a3eaf
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 6894072
* @compile -XDignore.symbol.file KeyTabCompat.java
* @run main/othervm KeyTabCompat
* @summary always refresh keytab
*/
import
javax.security.auth.kerberos.KerberosKey
;
import
sun.security.jgss.GSSUtil
;
/*
* There are 2 compat issues to check:
*
* 1. If there is only KerberosKeys in private credential set and no
* KerberosPrincipal. JAAS login should go on.
* 2. Even if KeyTab is used, user can still get KerberosKeys from
* private credentials set.
*/
public
class
KeyTabCompat
{
public
static
void
main
(
String
[]
args
)
throws
Exception
{
OneKDC
kdc
=
new
OneKDC
(
"aes128-cts"
);
kdc
.
writeJAASConf
();
kdc
.
addPrincipal
(
OneKDC
.
SERVER
,
"pass1"
.
toCharArray
());
kdc
.
writeKtab
(
OneKDC
.
KTAB
);
Context
c
,
s
;
// Part 1
c
=
Context
.
fromUserPass
(
OneKDC
.
USER
,
OneKDC
.
PASS
,
false
);
s
=
Context
.
fromUserPass
(
OneKDC
.
USER2
,
OneKDC
.
PASS2
,
true
);
s
.
s
().
getPrincipals
().
clear
();
c
.
startAsClient
(
OneKDC
.
USER2
,
GSSUtil
.
GSS_KRB5_MECH_OID
);
s
.
startAsServer
(
GSSUtil
.
GSS_KRB5_MECH_OID
);
Context
.
handshake
(
c
,
s
);
// Part 2
c
=
Context
.
fromJAAS
(
"client"
);
s
=
Context
.
fromJAAS
(
"server"
);
c
.
startAsClient
(
OneKDC
.
SERVER
,
GSSUtil
.
GSS_KRB5_MECH_OID
);
s
.
startAsServer
(
GSSUtil
.
GSS_KRB5_MECH_OID
);
s
.
status
();
if
(
s
.
s
().
getPrivateCredentials
(
KerberosKey
.
class
).
size
()
!=
1
)
{
throw
new
Exception
(
"There should be one KerberosKey"
);
}
Thread
.
sleep
(
2000
);
// make sure ktab timestamp is different
kdc
.
addPrincipal
(
OneKDC
.
SERVER
,
"pass2"
.
toCharArray
());
kdc
.
writeKtab
(
OneKDC
.
KTAB
);
Context
.
handshake
(
c
,
s
);
s
.
status
();
if
(
s
.
s
().
getPrivateCredentials
(
KerberosKey
.
class
).
size
()
!=
1
)
{
throw
new
Exception
(
"There should be only one KerberosKey"
);
}
}
}
test/sun/security/krb5/auto/LoginModuleOptions.java
浏览文件 @
812a3eaf
...
@@ -28,7 +28,6 @@
...
@@ -28,7 +28,6 @@
* @summary Krb5LoginModule a little too restrictive, and the doc is not clear.
* @summary Krb5LoginModule a little too restrictive, and the doc is not clear.
*/
*/
import
com.sun.security.auth.module.Krb5LoginModule
;
import
com.sun.security.auth.module.Krb5LoginModule
;
import
java.io.IOException
;
import
java.util.HashMap
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.Map
;
import
javax.security.auth.Subject
;
import
javax.security.auth.Subject
;
...
@@ -36,7 +35,6 @@ import javax.security.auth.callback.Callback;
...
@@ -36,7 +35,6 @@ import javax.security.auth.callback.Callback;
import
javax.security.auth.callback.CallbackHandler
;
import
javax.security.auth.callback.CallbackHandler
;
import
javax.security.auth.callback.NameCallback
;
import
javax.security.auth.callback.NameCallback
;
import
javax.security.auth.callback.PasswordCallback
;
import
javax.security.auth.callback.PasswordCallback
;
import
javax.security.auth.callback.UnsupportedCallbackException
;
public
class
LoginModuleOptions
{
public
class
LoginModuleOptions
{
...
@@ -61,10 +59,12 @@ public class LoginModuleOptions {
...
@@ -61,10 +59,12 @@ public class LoginModuleOptions {
// 1. ccache -> keytab
// 1. ccache -> keytab
login
(
null
,
"useTicketCache"
,
"true"
,
"ticketCache"
,
"krbcc_non_exists"
,
login
(
null
,
"useTicketCache"
,
"true"
,
"ticketCache"
,
"krbcc_non_exists"
,
"useKeyTab"
,
"true"
,
"principal"
,
"dummy"
);
"useKeyTab"
,
"true"
,
"principal"
,
"dummy"
);
// 2. keytab -> shared
// 2. keytab -> shared
login
(
null
,
"useKeyTab"
,
"true"
,
"principal"
,
"dummy"
,
login
(
null
,
"useKeyTab"
,
"true"
,
"principal"
,
"dummy"
,
"keyTab"
,
"ktab_non_exist"
,
"keyTab"
,
"ktab_non_exist"
,
"tryFirstPass"
,
"true"
,
NAME
,
OneKDC
.
USER
,
PWD
,
OneKDC
.
PASS
);
"tryFirstPass"
,
"true"
,
NAME
,
OneKDC
.
USER
,
PWD
,
OneKDC
.
PASS
);
// 3. shared -> callback
// 3. shared -> callback
// 3.1. useFirstPass, no callback
// 3.1. useFirstPass, no callback
boolean
failed
=
false
;
boolean
failed
=
false
;
...
...
test/sun/security/krb5/auto/SSL.java
浏览文件 @
812a3eaf
...
@@ -48,7 +48,7 @@ import sun.security.krb5.internal.ktab.KeyTab;
...
@@ -48,7 +48,7 @@ import sun.security.krb5.internal.ktab.KeyTab;
public
class
SSL
{
public
class
SSL
{
private
static
String
krb5Cipher
;
private
static
String
krb5Cipher
;
private
static
final
int
LOOP_LIMIT
=
1
;
private
static
final
int
LOOP_LIMIT
=
3
;
private
static
int
loopCount
=
0
;
private
static
int
loopCount
=
0
;
private
static
volatile
String
server
;
private
static
volatile
String
server
;
private
static
volatile
int
port
;
private
static
volatile
int
port
;
...
@@ -98,13 +98,13 @@ public class SSL {
...
@@ -98,13 +98,13 @@ public class SSL {
fos
.
close
();
fos
.
close
();
f
.
deleteOnExit
();
f
.
deleteOnExit
();
final
Context
c
=
Context
.
fromUserPass
(
OneKDC
.
USER
,
OneKDC
.
PASS
,
false
)
;
Context
c
;
final
Context
s
=
Context
.
fromJAAS
(
"ssl"
);
final
Context
s
=
Context
.
fromJAAS
(
"ssl"
);
c
.
startAsClient
(
"host/"
+
server
,
GSSUtil
.
GSS_KRB5_MECH_OID
);
// There's no keytab file when server starts.
s
.
startAsServer
(
GSSUtil
.
GSS_KRB5_MECH_OID
);
s
.
startAsServer
(
GSSUtil
.
GSS_KRB5_MECH_OID
);
new
Thread
(
new
Runnable
()
{
Thread
server
=
new
Thread
(
new
Runnable
()
{
public
void
run
()
{
public
void
run
()
{
try
{
try
{
s
.
doAs
(
new
JsseServerAction
(),
null
);
s
.
doAs
(
new
JsseServerAction
(),
null
);
...
@@ -112,12 +112,57 @@ public class SSL {
...
@@ -112,12 +112,57 @@ public class SSL {
e
.
printStackTrace
();
e
.
printStackTrace
();
}
}
}
}
}).
start
();
});
server
.
setDaemon
(
true
);
server
.
start
();
// Warm the server
// Warm the server
Thread
.
sleep
(
2000
);
Thread
.
sleep
(
2000
);
// Now create the keytab
/*
// Add 3 versions of keys into keytab
KeyTab ktab = KeyTab.create(OneKDC.KTAB);
PrincipalName service = new PrincipalName(
"host/" + server, PrincipalName.KRB_NT_SRV_HST);
ktab.addEntry(service, "pass1".toCharArray(), 1);
ktab.addEntry(service, "pass2".toCharArray(), 2);
ktab.addEntry(service, "pass3".toCharArray(), 3);
ktab.save();
// and use the middle one as the real key
kdc.addPrincipal("host/" + server, "pass2".toCharArray());
*/
c
=
Context
.
fromUserPass
(
OneKDC
.
USER
,
OneKDC
.
PASS
,
false
);
c
.
startAsClient
(
"host/"
+
server
,
GSSUtil
.
GSS_KRB5_MECH_OID
);
c
.
doAs
(
new
JsseClientAction
(),
null
);
c
.
doAs
(
new
JsseClientAction
(),
null
);
// Add another version of key, make sure it can be loaded
Thread
.
sleep
(
2000
);
ktab
=
KeyTab
.
getInstance
(
OneKDC
.
KTAB
);
ktab
.
addEntry
(
service
,
"pass4"
.
toCharArray
(),
4
,
true
);
ktab
.
save
();
kdc
.
addPrincipal
(
"host/"
+
server
,
"pass4"
.
toCharArray
());
c
=
Context
.
fromUserPass
(
OneKDC
.
USER
,
OneKDC
.
PASS
,
false
);
c
.
startAsClient
(
"host/"
+
server
,
GSSUtil
.
GSS_KRB5_MECH_OID
);
c
.
doAs
(
new
JsseClientAction
(),
null
);
// Revoke the old key
/*Thread.sleep(2000);
ktab = KeyTab.create(OneKDC.KTAB);
ktab.addEntry(service, "pass5".toCharArray(), 5, false);
ktab.save();
c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false);
c.startAsClient("host/" + server, GSSUtil.GSS_KRB5_MECH_OID);
try {
c.doAs(new JsseClientAction(), null);
throw new Exception("Should fail this time.");
} catch (SSLException e) {
// Correct behavior.
}*/
}
}
// Following codes copied from
// Following codes copied from
...
@@ -126,6 +171,7 @@ public class SSL {
...
@@ -126,6 +171,7 @@ public class SSL {
public
byte
[]
run
(
Context
s
,
byte
[]
input
)
throws
Exception
{
public
byte
[]
run
(
Context
s
,
byte
[]
input
)
throws
Exception
{
SSLSocketFactory
sslsf
=
SSLSocketFactory
sslsf
=
(
SSLSocketFactory
)
SSLSocketFactory
.
getDefault
();
(
SSLSocketFactory
)
SSLSocketFactory
.
getDefault
();
System
.
out
.
println
(
"Connecting "
+
server
+
":"
+
port
);
SSLSocket
sslSocket
=
(
SSLSocket
)
sslsf
.
createSocket
(
server
,
port
);
SSLSocket
sslSocket
=
(
SSLSocket
)
sslsf
.
createSocket
(
server
,
port
);
// Enable only a KRB5 cipher suite.
// Enable only a KRB5 cipher suite.
...
@@ -154,6 +200,9 @@ public class SSL {
...
@@ -154,6 +200,9 @@ public class SSL {
System
.
out
.
println
(
"Server is: "
+
peer
.
toString
());
System
.
out
.
println
(
"Server is: "
+
peer
.
toString
());
sslSocket
.
close
();
sslSocket
.
close
();
// This line should not be needed. It's the server's duty to
// forget the old key
//sslSocket.getSession().invalidate();
return
null
;
return
null
;
}
}
}
}
...
@@ -165,6 +214,7 @@ public class SSL {
...
@@ -165,6 +214,7 @@ public class SSL {
SSLServerSocket
sslServerSocket
=
SSLServerSocket
sslServerSocket
=
(
SSLServerSocket
)
sslssf
.
createServerSocket
(
0
);
// any port
(
SSLServerSocket
)
sslssf
.
createServerSocket
(
0
);
// any port
port
=
sslServerSocket
.
getLocalPort
();
port
=
sslServerSocket
.
getLocalPort
();
System
.
out
.
println
(
"Listening on "
+
port
);
// Enable only a KRB5 cipher suite.
// Enable only a KRB5 cipher suite.
String
enabledSuites
[]
=
{
krb5Cipher
};
String
enabledSuites
[]
=
{
krb5Cipher
};
...
...
test/sun/security/krb5/auto/TwoPrinces.java
0 → 100644
浏览文件 @
812a3eaf
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 6894072
* @compile -XDignore.symbol.file TwoPrinces.java
* @run main/othervm TwoPrinces
* @summary always refresh keytab
*/
import
java.io.File
;
import
java.io.FileOutputStream
;
import
sun.security.jgss.GSSUtil
;
import
sun.security.krb5.Config
;
public
class
TwoPrinces
{
public
static
void
main
(
String
[]
args
)
throws
Exception
{
KDC
k1
=
KDC
.
create
(
"R1"
);
k1
.
addPrincipal
(
"u1"
,
"hello"
.
toCharArray
());
k1
.
addPrincipalRandKey
(
"krbtgt/R1"
);
k1
.
addPrincipalRandKey
(
"host/same.host"
);
KDC
k2
=
KDC
.
create
(
"R2"
);
k2
.
addPrincipal
(
"u2"
,
"hello"
.
toCharArray
());
k2
.
addPrincipalRandKey
(
"krbtgt/R2"
);
k2
.
addPrincipalRandKey
(
"host/same.host"
);
System
.
setProperty
(
"java.security.krb5.conf"
,
"krb5.conf"
);
// R1 is the default realm now
KDC
.
saveConfig
(
"krb5.conf"
,
k1
,
k2
);
Config
.
refresh
();
k1
.
writeKtab
(
"ktab1"
);
k2
.
writeKtab
(
"ktab2"
);
// A JAAS config file with 2 Krb5LoginModules, after commit, the
// subject with have principals and keytabs from both sides
System
.
setProperty
(
"java.security.auth.login.config"
,
"jaas.conf"
);
File
f
=
new
File
(
"jaas.conf"
);
FileOutputStream
fos
=
new
FileOutputStream
(
f
);
fos
.
write
((
"me {\n"
+
" com.sun.security.auth.module.Krb5LoginModule required"
+
" isInitiator=true principal=\"host/same.host@R1\""
+
" useKeyTab=true keyTab=ktab1 storeKey=true;\n"
+
" com.sun.security.auth.module.Krb5LoginModule required"
+
" isInitiator=true principal=\"host/same.host@R2\""
+
" useKeyTab=true keyTab=ktab2 storeKey=true;\n"
+
"};\n"
).
getBytes
());
fos
.
close
();
/*
* This server side context will be able to act as services in both
* realms. Please note that we still don't support a single instance
* of server to accept connections from two realms at the same time.
* Therefore, we must call startAsServer in a given realm to start
* working there. The same Subject never changes anyway.
*/
Context
s
=
Context
.
fromJAAS
(
"me"
);
// Default realm still R1
s
.
startAsServer
(
"host@same.host"
,
GSSUtil
.
GSS_KRB5_MECH_OID
);
Context
c1
=
Context
.
fromUserPass
(
"u1"
,
"hello"
.
toCharArray
(),
false
);
c1
.
startAsClient
(
"host@same.host"
,
GSSUtil
.
GSS_KRB5_MECH_OID
);
Context
.
handshake
(
c1
,
s
);
KDC
.
saveConfig
(
"krb5.conf"
,
k2
,
k1
);
Config
.
refresh
();
// Default realm now R2
s
.
startAsServer
(
"host@same.host"
,
GSSUtil
.
GSS_KRB5_MECH_OID
);
Context
c2
=
Context
.
fromUserPass
(
"u2"
,
"hello"
.
toCharArray
(),
false
);
c2
.
startAsClient
(
"host@same.host"
,
GSSUtil
.
GSS_KRB5_MECH_OID
);
Context
.
handshake
(
c2
,
s
);
}
}
test/sun/security/krb5/ktab/KeyTabIndex.java
浏览文件 @
812a3eaf
/*
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010,
2011,
Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -44,7 +44,6 @@ public class KeyTabIndex {
...
@@ -44,7 +44,6 @@ public class KeyTabIndex {
KeyTab
.
getInstance
(
"ktab"
).
getClass
();
KeyTab
.
getInstance
(
"ktab"
).
getClass
();
}
}
};
};
KeyTab
.
refresh
();
for
(
int
i
=
0
;
i
<
10
;
i
++)
{
for
(
int
i
=
0
;
i
<
10
;
i
++)
{
new
Thread
(
t
).
start
();
new
Thread
(
t
).
start
();
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录