Hi Szabolcs
On 03/29/2011 09:18 PM, Szabolcs Pota wrote:
Hi Max,
The client was Java in all cases. I've tried with the following
combinations:
* Open JDK b133 with JGSS
* Open JDK b133 with MIT native Kerberos
I guess this means using the native GSS provider with
-Dsun.security.jgss.native=true.
* JDK 6u23 with JGSS
* JDK 6u23with MIT native Kerberos
The result is always the same:
This is a little strange. I do think the service ticket on the client
should not have the caddr field. If your client is using JAAS, can you
print out the KerberosTicket in its private credentials set after the
first initSecContext() is called?
Anyway, I've made some code changes to my own OpenJDK code repository
and is now supporting this field in a service ticket. However, since
JGSS is token-based, it has no way to get the IP address of the client
from a socket object. In order to support no-addresses=false, both the
client and server have to turn on channel bindings, and then the server
will be able to get the client's IP address from it.
Do you build OpenJDK? If so, you can try out my attached patch.
Thanks
Max
Caused by: sun.security.krb5.internal.KrbApErrException: Incorrect net
address (38)
at sun.security.krb5.KrbApReq.authenticate(KrbApReq.java:329)
~[na:na]
at sun.security.krb5.KrbApReq.<init>(KrbApReq.java:146) ~[na:na]
at
sun.security.jgss.krb5.InitSecContextToken.<init>(InitSecContextToken.java:108)
~[na:na]
at
sun.security.jgss.krb5.Krb5Context.acceptSecContext(Krb5Context.java:761)
~[na:na]
Regards,
Szabolcs
On Mon, Mar 28, 2011 at 2:21 PM, Weijun Wang <[email protected]
<mailto:[email protected]>> wrote:
Sorry for the late reply.
I suppose your client side program is not in Java? Because in JDK a
service ticker's addresses field is always null.
Thanks
Max
On 03/25/2011 07:53 PM, Szabolcs Pota wrote:
[+ adding back security-dev]
Hi Henry,
Thank you for your reply. My answers are below.
On Fri, Mar 25, 2011 at 1:26 AM, Henry B. Hotz
<[email protected] <mailto:[email protected]>
<mailto:[email protected] <mailto:[email protected]>>>
wrote:
No-list reply since I'm subscribed with an alias which my
ISP won't
let me send with.
On Mar 23, 2011, at 5:16 AM, Szabolcs Pota wrote:
> Our global krb5.conf files have 'noaddresses=false' for both
client
> and server hence we get this exception. Please correct me if
someone
> thinks that setting this flag to false on the server side
would be
> incorrect.
There are two issues here. The one you're not looking at is
that
that config option is different for every one of the major C
implementations of Kerberos.
[appdefaults]
no-addresses = true # Heimdal
no_addresses = true # Sun
[lidefaults]
noaddresses = true # MIT
I have no idea which of these is understood by Java, though
I would
guess the Sun one, and hope that all of them are. Also the
default
value varies with the version. AFAIK all now default to disable
address checking.
As I've seen in sun.security.krb5.Config#useAddresses() it reads
either
the 'noaddresses' or the 'no-addresses' flag and indeed the
default is
no-addresses=true. We are using 'noaddresses' that is parsed without
problems by the current code.
------
As for what you are actually asking about: almost all of us
have
stopped worrying about addresses because the address check
does not
work in the real world with ubiquitous NAT and multiple
private IP
spaces. (Are you sure you're not running into one of those?) I
personally would not care if Java simply stopped supporting
address
checking.
That may not be an appropriate thing for the universal JGSS
implementation to do though.
What's *supposed* to happen (without reading the RFC) is the
endpoint gets the IP from the socket for the other end, and
compares
it with the appropriate field in the ticket. If they don't
match,
then the ticket *may* have been copied and is being injected
from
someplace it shouldn't be.
Since (almost) nobody is using the feature anymore I would
actually
be surprised if it works on IPv6 networks. As I said it is
guaranteed to fail if there is a NAT involved.
-----
To answer the specific question in the above paragraph, I
would say
checking addresses on a server is actually wrong if *any* of the
clients are connecting via VPN, or through your typical home
router
box. It can only be guaranteed correct if all clients are
on the
same corporate network as the server.
I agree with you that checking the client address is error prone and
even the RFC says so. It could be done only on a best effort
basis. At
the moment I think that the server should do one of the followings:
1. If EncTicketPart.caddr is set then try to get the client
IP and
check if it is in the list. If it is not then it *may*
throw and
exception.
2. Skip the whole no-addresses processing because of the
unreliable
client IP check.
My problem is that the current logic in KrbApReq java does non
of these
but throws an Exception. This prevents us using OpenJDK with
'noaddresses=false' in Kerberos configuration.
Regards,
Szabolcs
------------------------------------------------------
The opinions expressed in this message are mine,
not those of Caltech, JPL, NASA, or the US Government.
[email protected] <mailto:[email protected]>
<mailto:[email protected]
<mailto:[email protected]>>, or
[email protected] <mailto:[email protected]> <mailto:[email protected]
<mailto:[email protected]>>
--
Szabolcs Pota
Morgan Stanley | MSJava, EAI (MSSM)
Lechner Odon fasor 8 | Floor 07
Budapest, 1095
Phone: +36 1 881-3979
[email protected]
<mailto:[email protected]>
<mailto:[email protected]
<mailto:[email protected]>>
--
Szabolcs Pota
Morgan Stanley | MSJava, EAI (MSSM)
Lechner Odon fasor 8 | Floor 07
Budapest, 1095
Phone: +36 1 881-3979
[email protected] <mailto:[email protected]>
# HG changeset patch
# Parent 79cd9368b5551372a034d9212d1bef7487834c9b
9999999: cAddr in service ticket
Reviewed-by: nobody
diff --git a/src/share/classes/sun/security/krb5/Credentials.java
b/src/share/classes/sun/security/krb5/Credentials.java
--- a/src/share/classes/sun/security/krb5/Credentials.java
+++ b/src/share/classes/sun/security/krb5/Credentials.java
@@ -55,7 +55,7 @@
KerberosTime startTime;
KerberosTime endTime;
KerberosTime renewTill;
- HostAddresses cAddr;
+ public HostAddresses cAddr;
EncryptionKey serviceKey;
AuthorizationData authzData;
private static boolean DEBUG = Krb5.DEBUG;
@@ -122,7 +122,7 @@
(startTime == null? null: new KerberosTime(startTime)),
(endTime == null? null: new KerberosTime(endTime)),
(renewTill == null? null: new KerberosTime(renewTill)),
- null); // caddrs are in the encoding at this point
+ new HostAddresses(cAddrs)); // caddrs are in the encoding at this
point
}
/**
diff --git a/src/share/classes/sun/security/krb5/KrbTgsReq.java
b/src/share/classes/sun/security/krb5/KrbTgsReq.java
--- a/src/share/classes/sun/security/krb5/KrbTgsReq.java
+++ b/src/share/classes/sun/security/krb5/KrbTgsReq.java
@@ -73,7 +73,7 @@
}
// Called by Credentials, KrbCred
- KrbTgsReq(
+ public KrbTgsReq(
KDCOptions options,
Credentials asCreds,
PrincipalName sname,
diff --git a/src/share/classes/sun/security/krb5/internal/CredentialsUtil.java
b/src/share/classes/sun/security/krb5/internal/CredentialsUtil.java
--- a/src/share/classes/sun/security/krb5/internal/CredentialsUtil.java
+++ b/src/share/classes/sun/security/krb5/internal/CredentialsUtil.java
@@ -308,6 +308,7 @@
private static Credentials serviceCreds(
ServiceName service, Credentials ccreds)
throws KrbException, IOException {
- return new KrbTgsReq(ccreds, service).sendAndGetCreds();
+ return new KrbTgsReq(new KDCOptions(), ccreds, service, null, null,
null, null,
+ ccreds.cAddr, null, null, null).sendAndGetCreds();
}
}
diff --git a/test/sun/security/krb5/auto/NoAddresses.java
b/test/sun/security/krb5/auto/NoAddresses.java
new file mode 100644
--- /dev/null
+++ b/test/sun/security/krb5/auto/NoAddresses.java
@@ -0,0 +1,63 @@
+/*
+ * 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 6851973
+ * @run main/othervm NoAddresses
+ * @summary ignore incoming channel binding if acceptor does not set one
+ */
+
+import java.net.InetAddress;
+import org.ietf.jgss.ChannelBinding;
+import sun.security.jgss.GSSUtil;
+import sun.security.krb5.Config;
+
+public class NoAddresses {
+
+ public static void main(String[] args)
+ throws Exception {
+
+ OneKDC kdc = new OneKDC(null);
+ kdc.writeJAASConf();
+ KDC.saveConfig(OneKDC.KRB5_CONF, kdc,
+ "noaddresses = false",
+ "default_keytab_name = " + OneKDC.KTAB);
+ Config.refresh();
+
+ Context c = Context.fromJAAS("client");
+ Context s = Context.fromJAAS("server");
+
+ c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID);
+ s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID);
+ c.x().setChannelBinding(new ChannelBinding(
+ InetAddress.getByName("localhost"),
+ InetAddress.getByName("host." + OneKDC.REALM),
+ null));
+ s.x().setChannelBinding(new ChannelBinding(
+ InetAddress.getByName("localhost"),
+ InetAddress.getByName("host." + OneKDC.REALM),
+ null));
+ Context.handshake(c, s);
+ }
+}