summaryrefslogtreecommitdiff
path: root/java/ssl/jdk1.4/IceSSL
diff options
context:
space:
mode:
authorMatthew Newhook <matthew@zeroc.com>2006-06-05 15:11:48 +0000
committerMatthew Newhook <matthew@zeroc.com>2006-06-05 15:11:48 +0000
commitc7830493b1a04964c872095e7b924d86c08b2b52 (patch)
tree106dd9f15a637962b24dd870e023f7b3dd236f61 /java/ssl/jdk1.4/IceSSL
parentAdd addressFilter to build (diff)
downloadice-c7830493b1a04964c872095e7b924d86c08b2b52.tar.bz2
ice-c7830493b1a04964c872095e7b924d86c08b2b52.tar.xz
ice-c7830493b1a04964c872095e7b924d86c08b2b52.zip
added support for TrustOnly.
Diffstat (limited to 'java/ssl/jdk1.4/IceSSL')
-rw-r--r--java/ssl/jdk1.4/IceSSL/AcceptorI.java8
-rw-r--r--java/ssl/jdk1.4/IceSSL/ConnectionInfo.java12
-rw-r--r--java/ssl/jdk1.4/IceSSL/ConnectorI.java2
-rw-r--r--java/ssl/jdk1.4/IceSSL/EndpointI.java4
-rw-r--r--java/ssl/jdk1.4/IceSSL/Instance.java34
-rw-r--r--java/ssl/jdk1.4/IceSSL/RFC2253.java416
-rw-r--r--java/ssl/jdk1.4/IceSSL/TrustManager.java252
-rw-r--r--java/ssl/jdk1.4/IceSSL/Util.java4
8 files changed, 714 insertions, 18 deletions
diff --git a/java/ssl/jdk1.4/IceSSL/AcceptorI.java b/java/ssl/jdk1.4/IceSSL/AcceptorI.java
index 48f9ae4b57c..d781bcd6a29 100644
--- a/java/ssl/jdk1.4/IceSSL/AcceptorI.java
+++ b/java/ssl/jdk1.4/IceSSL/AcceptorI.java
@@ -131,8 +131,8 @@ class AcceptorI implements IceInternal.Acceptor
}
}
- connInfo = Util.populateConnectionInfo(fd);
- _instance.verifyPeer(connInfo, fd, "", true);
+ connInfo = Util.populateConnectionInfo(fd, _adapterName, true);
+ _instance.verifyPeer(connInfo, fd, _adapterName, true);
}
catch(java.net.SocketTimeoutException ex)
{
@@ -271,9 +271,10 @@ class AcceptorI implements IceInternal.Acceptor
return _addr.getPort();
}
- AcceptorI(Instance instance, String host, int port)
+ AcceptorI(Instance instance, String adapterName, String host, int port)
{
_instance = instance;
+ _adapterName = adapterName;
_logger = instance.communicator().getLogger();
_backlog = 0;
@@ -447,6 +448,7 @@ class AcceptorI implements IceInternal.Acceptor
}
private Instance _instance;
+ private String _adapterName;
private Ice.Logger _logger;
private javax.net.ssl.SSLServerSocket _fd;
private int _backlog;
diff --git a/java/ssl/jdk1.4/IceSSL/ConnectionInfo.java b/java/ssl/jdk1.4/IceSSL/ConnectionInfo.java
index 8e58d7edbaf..c087c838896 100644
--- a/java/ssl/jdk1.4/IceSSL/ConnectionInfo.java
+++ b/java/ssl/jdk1.4/IceSSL/ConnectionInfo.java
@@ -37,4 +37,16 @@ public class ConnectionInfo
// The remote TCP/IP host & port.
//
public java.net.InetSocketAddress remoteAddr;
+
+ //
+ // If the connection is incoming this bool is true, false
+ // otherwise.
+ //
+ boolean incoming;
+
+ //
+ // The name of the object adapter that hosts this endpoint, if
+ // any.
+ //
+ String adapterName;
}
diff --git a/java/ssl/jdk1.4/IceSSL/ConnectorI.java b/java/ssl/jdk1.4/IceSSL/ConnectorI.java
index b42cb6ce519..9e0b8dcefc1 100644
--- a/java/ssl/jdk1.4/IceSSL/ConnectorI.java
+++ b/java/ssl/jdk1.4/IceSSL/ConnectorI.java
@@ -131,7 +131,7 @@ final class ConnectorI implements IceInternal.Connector
}
}
- connInfo = Util.populateConnectionInfo(fd);
+ connInfo = Util.populateConnectionInfo(fd, "", false);
_instance.verifyPeer(connInfo, fd, _host, false);
}
catch(java.net.ConnectException ex)
diff --git a/java/ssl/jdk1.4/IceSSL/EndpointI.java b/java/ssl/jdk1.4/IceSSL/EndpointI.java
index debeb4482ff..9b09790bc81 100644
--- a/java/ssl/jdk1.4/IceSSL/EndpointI.java
+++ b/java/ssl/jdk1.4/IceSSL/EndpointI.java
@@ -353,9 +353,9 @@ final class EndpointI extends IceInternal.EndpointI
// assigned.
//
public IceInternal.Acceptor
- acceptor(IceInternal.EndpointIHolder endpoint)
+ acceptor(IceInternal.EndpointIHolder endpoint, String adapterName)
{
- AcceptorI p = new AcceptorI(_instance, _host, _port);
+ AcceptorI p = new AcceptorI(_instance, adapterName, _host, _port);
endpoint.value = new EndpointI(_instance, _host, p.effectivePort(), _timeout, _connectionId, _compress,
_publish);
return p;
diff --git a/java/ssl/jdk1.4/IceSSL/Instance.java b/java/ssl/jdk1.4/IceSSL/Instance.java
index 0aaf8c22b31..b1794c64765 100644
--- a/java/ssl/jdk1.4/IceSSL/Instance.java
+++ b/java/ssl/jdk1.4/IceSSL/Instance.java
@@ -18,6 +18,7 @@ class Instance
_securityTraceLevel = communicator.getProperties().getPropertyAsIntWithDefault("IceSSL.Trace.Security", 0);
_securityTraceCategory = "Security";
_initialized = false;
+ _trustManager = new TrustManager(communicator);
//
// Register the endpoint factory. We have to do this now, rather than
@@ -581,22 +582,32 @@ class Instance
}
}
- if(_verifier != null)
+ if(!_trustManager.verify(info))
{
- if(!_verifier.verify(info))
+ String msg = (incoming ? "incoming" : "outgoing") + " connection rejected by trust manager\n" +
+ IceInternal.Network.fdToString(fd);
+ if(_securityTraceLevel >= 1)
{
- String msg = (incoming ? "incoming" : "outgoing") + " connection rejected by certificate verifier\n" +
- IceInternal.Network.fdToString(fd);
+ _logger.trace(_securityTraceCategory, msg);
+ }
+ Ice.SecurityException ex = new Ice.SecurityException();
+ ex.reason = msg;
+ throw ex;
+ }
- if(_securityTraceLevel > 0)
- {
- _logger.trace(_securityTraceCategory, msg);
- }
+ if(_verifier != null && !_verifier.verify(info))
+ {
+ String msg = (incoming ? "incoming" : "outgoing") + " connection rejected by certificate verifier\n" +
+ IceInternal.Network.fdToString(fd);
- Ice.SecurityException ex = new Ice.SecurityException();
- ex.reason = msg;
- throw ex;
+ if(_securityTraceLevel > 0)
+ {
+ _logger.trace(_securityTraceCategory, msg);
}
+
+ Ice.SecurityException ex = new Ice.SecurityException();
+ ex.reason = msg;
+ throw ex;
}
}
@@ -728,4 +739,5 @@ class Instance
private String[] _protocols;
private boolean _checkCertName;
private CertificateVerifier _verifier;
+ private TrustManager _trustManager;
}
diff --git a/java/ssl/jdk1.4/IceSSL/RFC2253.java b/java/ssl/jdk1.4/IceSSL/RFC2253.java
new file mode 100644
index 00000000000..0b66a93aaa3
--- /dev/null
+++ b/java/ssl/jdk1.4/IceSSL/RFC2253.java
@@ -0,0 +1,416 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2006 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+package IceSSL;
+
+//
+// See RFC 2253 and RFC 1779.
+//
+class RFC2253
+{
+ static class ParseException extends Ice.LocalException
+ {
+ public ParseException()
+ {
+ }
+
+ public ParseException(String reason)
+ {
+ this.reason = reason;
+ }
+
+ public String
+ ice_name()
+ {
+ return "RFC2253::ParseException";
+ }
+
+ public String reason;
+ }
+
+ static class RDNPair
+ {
+ String key;
+ String value;
+ };
+
+ static private class ParseState
+ {
+ String data;
+ int pos;
+ };
+
+ public static java.util.List
+ parse(String data)
+ throws ParseException
+ {
+ java.util.List results = new java.util.LinkedList();
+ java.util.List current = new java.util.LinkedList();
+ ParseState state = new ParseState();
+ state.data = data;
+ state.pos = 0;
+ while(state.pos < state.data.length())
+ {
+ current.add(parseNameComponent(state));
+ eatWhite(state);
+ if(state.pos < state.data.length() && state.data.charAt(state.pos) == ',')
+ {
+ ++state.pos;
+ }
+ else if(state.pos < state.data.length() && state.data.charAt(state.pos) == ';')
+ {
+ ++state.pos;
+ results.add(current);
+ current = new java.util.LinkedList();
+ }
+ else if(state.pos < state.data.length())
+ {
+ throw new ParseException("expected ',' or ';' at `" + state.data.substring(state.pos) + "'");
+ }
+ }
+ if(!current.isEmpty())
+ {
+ results.add(current);
+ }
+
+ return results;
+ }
+
+ public static java.util.List
+ parseStrict(String data)
+ throws ParseException
+ {
+ java.util.List results = new java.util.LinkedList();
+ ParseState state = new ParseState();
+ state.data = data;
+ state.pos = 0;
+ while(state.pos < state.data.length())
+ {
+ results.add(parseNameComponent(state));
+ eatWhite(state);
+ if(state.pos < state.data.length() &&
+ (state.data.charAt(state.pos) == ',' || state.data.charAt(state.pos) == ';'))
+ {
+ ++state.pos;
+ }
+ else if(state.pos < state.data.length())
+ {
+ throw new ParseException("expected ',' or ';' at `" + state.data.substring(state.pos) + "'");
+ }
+ }
+ return results;
+ }
+
+ private static RDNPair
+ parseNameComponent(ParseState state)
+ throws ParseException
+ {
+ RDNPair result = parseAttributeTypeAndValue(state);
+ while(state.pos < state.data.length())
+ {
+ eatWhite(state);
+ if(state.pos < state.data.length() && state.data.charAt(state.pos) == '+')
+ {
+ ++state.pos;
+ }
+ else
+ {
+ break;
+ }
+ RDNPair p = parseAttributeTypeAndValue(state);
+ result.value += "+";
+ result.value += p.key;
+ result.value += '=';
+ result.value += p.value;
+ }
+ return result;
+ }
+
+ private static RDNPair
+ parseAttributeTypeAndValue(ParseState state)
+ throws ParseException
+ {
+ RDNPair p = new RDNPair();
+ p.key = parseAttributeType(state);
+ eatWhite(state);
+ if(state.pos >= state.data.length())
+ {
+ throw new ParseException("invalid attribute type/value pair (unexpected end of state.data)");
+ }
+ if(state.data.charAt(state.pos) != '=')
+ {
+ throw new ParseException("invalid attribute type/value pair (missing =)");
+ }
+ ++state.pos;
+ p.value = parseAttributeValue(state);
+ return p;
+ }
+
+ private static String
+ parseAttributeType(ParseState state)
+ throws ParseException
+ {
+ eatWhite(state);
+ if(state.pos >= state.data.length())
+ {
+ throw new ParseException("invalid attribute type (expected end of state.data)");
+ }
+
+ String result = new String();
+
+ //
+ // RFC 1779.
+ // <key> ::= 1*( <keychar> ) | "OID." <oid> | "oid." <oid>
+ // <oid> ::= <digitString> | <digitstring> "." <oid>
+ // RFC 2253:
+ // attributeType = (ALPHA 1*keychar) | oid
+ // keychar = ALPHA | DIGIT | "-"
+ // oid = 1*DIGIT *("." 1*DIGIT)
+ //
+ // In section 4 of RFC 2253 the document says:
+ // Implementations MUST allow an oid in the attribute type to be
+ // prefixed by one of the character Strings "oid." or "OID.".
+ //
+ // Here we must also check for "oid." and "OID." before parsing
+ // according to the ALPHA KEYCHAR* rule.
+ //
+ // First the OID case.
+ //
+ if(Character.isDigit(state.data.charAt(state.pos)) ||
+ (state.data.length() - state.pos >= 4 && (state.data.substring(state.pos, state.pos + 4) == "oid." ||
+ state.data.substring(state.pos, state.pos + 4) == "OID.")))
+ {
+ if(!Character.isDigit(state.data.charAt(state.pos)))
+ {
+ result += state.data.substring(state.pos, state.pos + 4);
+ state.pos += 4;
+ }
+
+ while(true)
+ {
+ // 1*DIGIT
+ while(state.pos < state.data.length() && Character.isDigit(state.data.charAt(state.pos)))
+ {
+ result += state.data.charAt(state.pos);
+ ++state.pos;
+ }
+ // "." 1*DIGIT
+ if(state.pos < state.data.length() && state.data.charAt(state.pos) == '.')
+ {
+ result += state.data.charAt(state.pos);
+ ++state.pos;
+ // 1*DIGIT must follow "."
+ if(state.pos < state.data.length() && !Character.isDigit(state.data.charAt(state.pos)))
+ {
+ throw new ParseException("invalid attribute type (expected end of state.data)");
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ else if(Character.isUpperCase(state.data.charAt(state.pos)) || Character.isLowerCase(state.data.charAt(state.pos)))
+ {
+ //
+ // The grammar is wrong in this case. It should be ALPHA
+ // KEYCHAR* otherwise it will not accept "O" as a valid
+ // attribute type.
+ //
+ result += state.data.charAt(state.pos);
+ ++state.pos;
+ // 1* KEYCHAR
+ while(state.pos < state.data.length() &&
+ (Character.isDigit(state.data.charAt(state.pos)) ||
+ Character.isUpperCase(state.data.charAt(state.pos)) ||
+ Character.isLowerCase(state.data.charAt(state.pos)) ||
+ state.data.charAt(state.pos) == '-'))
+ {
+ result += state.data.charAt(state.pos);
+ ++state.pos;
+ }
+ }
+ else
+ {
+ throw new ParseException("invalid attribute type");
+ }
+ return result;
+ }
+
+ private static String
+ parseAttributeValue(ParseState state)
+ throws ParseException
+ {
+ eatWhite(state);
+ String result = new String();
+ if(state.pos >= state.data.length())
+ {
+ return result;
+ }
+
+ //
+ // RFC 2253
+ // # hexString
+ //
+ if(state.data.charAt(state.pos) == '#')
+ {
+ result += state.data.charAt(state.pos);
+ ++state.pos;
+ while(true)
+ {
+ String h = parseHexPair(state, true);
+ if(h.length() == 0)
+ {
+ break;
+ }
+ result += h;
+ }
+ }
+ //
+ // RFC 2253
+ // QUOTATION *( quotechar | pair ) QUOTATION ; only from v2
+ // quotechar = <any character except "\" or QUOTATION >
+ //
+ else if(state.data.charAt(state.pos) == '"')
+ {
+ result += state.data.charAt(state.pos);
+ ++state.pos;
+ while(true)
+ {
+ if(state.pos >= state.data.length())
+ {
+ throw new ParseException("invalid attribute value (unexpected end of state.data)");
+ }
+ // final terminating "
+ if(state.data.charAt(state.pos) == '"')
+ {
+ result += state.data.charAt(state.pos);
+ ++state.pos;
+ break;
+ }
+ // any character except '\'
+ else if(state.data.charAt(state.pos) != '\\')
+ {
+ result += state.data.charAt(state.pos);
+ ++state.pos;
+ }
+ // pair '\'
+ else
+ {
+ result += parsePair(state);
+ }
+ }
+ }
+ //
+ // RFC 2253
+ // * (Stringchar | pair)
+ // Stringchar = <any character except one of special, "\" or QUOTATION >
+ //
+ else
+ {
+ while(state.pos < state.data.length())
+ {
+ if(state.data.charAt(state.pos) == '\\')
+ {
+ result += parsePair(state);
+ }
+ else if(special.indexOf(state.data.charAt(state.pos)) == -1 && state.data.charAt(state.pos) != '"')
+ {
+ result += state.data.charAt(state.pos);
+ ++state.pos;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ return result;
+ }
+
+ //
+ // RFC2253:
+ // pair = "\" ( special | "\" | QUOTATION | hexpair )
+ //
+ private static String
+ parsePair(ParseState state)
+ throws ParseException
+ {
+ String result = new String();
+
+ assert(state.data.charAt(state.pos) == '\\');
+ result += state.data.charAt(state.pos);
+ ++state.pos;
+
+ if(state.pos >= state.data.length())
+ {
+ throw new ParseException("invalid escape format (unexpected end of state.data)");
+ }
+
+ if(special.indexOf(state.data.charAt(state.pos)) != -1 || state.data.charAt(state.pos) != '\\' ||
+ state.data.charAt(state.pos) != '"')
+ {
+ result += state.data.charAt(state.pos);
+ ++state.pos;
+ return result;
+ }
+ return parseHexPair(state, false);
+ }
+
+ //
+ // RFC 2253
+ // hexpair = hexchar hexchar
+ //
+ private static String
+ parseHexPair(ParseState state, boolean allowEmpty)
+ throws ParseException
+ {
+ String result = new String();
+ if(state.pos < state.data.length() && hexvalid.indexOf(state.data.charAt(state.pos)) != -1)
+ {
+ result += state.data.charAt(state.pos);
+ ++state.pos;
+ }
+ if(state.pos < state.data.length() && hexvalid.indexOf(state.data.charAt(state.pos)) != -1)
+ {
+ result += state.data.charAt(state.pos);
+ ++state.pos;
+ }
+ if(result.length() != 2)
+ {
+ if(allowEmpty && result.length() == 0)
+ {
+ return result;
+ }
+ throw new ParseException("invalid hex format");
+ }
+ return result;
+ }
+
+ //
+ // RFC 2253:
+ //
+ // Implementations MUST allow for space (' ' ASCII 32) characters to be
+ // present between name-component and ',', between attributeTypeAndValue
+ // and '+', between attributeType and '=', and between '=' and
+ // attributeValue. These space characters are ignored when parsing.
+ //
+ private static void
+ eatWhite(ParseState state)
+ {
+ while(state.pos < state.data.length() && state.data.charAt(state.pos) == ' ')
+ {
+ ++state.pos;
+ }
+ }
+
+ private final static String special = ",=+<>#;";
+ private final static String hexvalid = "0123456789abcdefABCDEF";
+}
diff --git a/java/ssl/jdk1.4/IceSSL/TrustManager.java b/java/ssl/jdk1.4/IceSSL/TrustManager.java
new file mode 100644
index 00000000000..5f601354112
--- /dev/null
+++ b/java/ssl/jdk1.4/IceSSL/TrustManager.java
@@ -0,0 +1,252 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2006 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+package IceSSL;
+
+class TrustManager
+{
+ TrustManager(Ice.Communicator communicator)
+ {
+ assert communicator != null;
+ _communicator = communicator;
+ Ice.Properties properties = communicator.getProperties();
+ _traceLevel = properties.getPropertyAsInt("IceSSL.Trace.Security");
+ String key = null;
+ try
+ {
+ key = "IceSSL.TrustOnly";
+ _all = parse(properties.getProperty(key));
+ key = "IceSSL.TrustOnly.Client";
+ _client = parse(properties.getProperty(key));
+ key = "IceSSL.TrustOnly.Server";
+ _allServer = parse(properties.getProperty(key));
+ java.util.Map dict = properties.getPropertiesForPrefix("IceSSL.TrustOnly.Server.");
+ java.util.Iterator p = dict.entrySet().iterator();
+ while(p.hasNext())
+ {
+ java.util.Map.Entry entry = (java.util.Map.Entry)p.next();
+ key = (String)entry.getKey();
+ String name = key.substring("IceSSL.TrustOnly.Server.".length());
+ _server.put(name, parse((String)entry.getValue()));
+ }
+ }
+ catch(RFC2253.ParseException e)
+ {
+ Ice.PluginInitializationException ex = new Ice.PluginInitializationException();
+ ex.reason = "IceSSL: invalid property " + key + ":\n" + e.reason;
+ throw ex;
+ }
+ }
+
+ boolean
+ verify(ConnectionInfo info)
+ {
+ java.util.List trustset = new java.util.LinkedList();
+ if(!_all.isEmpty())
+ {
+ trustset.add(_all);
+ }
+
+ if(info.incoming)
+ {
+ if(!_allServer.isEmpty())
+ {
+ trustset.add(_allServer);
+ }
+ if(info.adapterName.length() > 0)
+ {
+ java.util.List p = (java.util.List)_server.get(info.adapterName);
+ if(p != null)
+ {
+ trustset.add(p);
+ }
+ }
+ }
+ else
+ {
+ if(!_client.isEmpty())
+ {
+ trustset.add(_client);
+ }
+ }
+
+ //
+ // If there is nothing to match against, then we accept the cert.
+ //
+ if(trustset.isEmpty())
+ {
+ return true;
+ }
+
+ //
+ // If there is no certificate then we match false.
+ //
+ if(info.certs.length != 0)
+ {
+ javax.security.auth.x500.X500Principal subjectDN = (javax.security.auth.x500.X500Principal)
+ ((java.security.cert.X509Certificate)info.certs[0]).getSubjectX500Principal();
+ String subjectName = subjectDN.getName(javax.security.auth.x500.X500Principal.RFC2253);
+ assert subjectName != null;
+ try
+ {
+ //
+ // Decompose the subject DN into the RDNs.
+ //
+ if(_traceLevel > 0)
+ {
+ _communicator.getLogger().trace("Security", "trust manager evaluating peer DN:\n" + subjectName);
+ }
+ java.util.List dn = RFC2253.parseStrict(subjectName);
+
+ //
+ // Try matching against everything in the trust set.
+ //
+ java.util.Iterator p = trustset.iterator();
+ while(p.hasNext())
+ {
+ if(match((java.util.List)p.next(), dn))
+ {
+ return true;
+ }
+ }
+ }
+ catch(RFC2253.ParseException e)
+ {
+ _communicator.getLogger().warning(
+ "IceSSL: unable to parse certificate DN `" + subjectName + "'\nreason: " + e.reason);
+ }
+ }
+
+ return false;
+ }
+
+ private boolean
+ match(java.util.List matchSet, java.util.List subject)
+ {
+ java.util.Iterator r = matchSet.iterator();
+ while(r.hasNext())
+ {
+ if(matchRDNs((java.util.List)r.next(), subject))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean
+ matchRDNs(java.util.List match, java.util.List subject)
+ {
+ java.util.Iterator p = match.iterator();
+ while(p.hasNext())
+ {
+ RFC2253.RDNPair matchRDN = (RFC2253.RDNPair)p.next();
+ boolean found = false;
+ java.util.Iterator q = subject.iterator();
+ while(q.hasNext())
+ {
+ RFC2253.RDNPair subjectRDN = (RFC2253.RDNPair)q.next();
+ if(matchRDN.key.equals(subjectRDN.key))
+ {
+ found = true;
+ if(!matchRDN.value.equals(subjectRDN.value))
+ {
+ return false;
+ }
+ }
+ }
+ if(!found)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ java.util.List
+ parse(String value)
+ throws RFC2253.ParseException
+ {
+ //
+ // Java X500Principal.getName says:
+ //
+ // If "RFC2253" is specified as the format, this method emits
+ // the attribute type keywords defined in RFC 2253 (CN, L, ST,
+ // O, OU, C, STREET, DC, UID). Any other attribute type is
+ // emitted as an OID. Under a strict reading, RFC 2253 only
+ // specifies a UTF-8 string representation. The String
+ // returned by this method is the Unicode string achieved by
+ // decoding this UTF-8 representation.
+ //
+ // This means that things like emailAddress and such will be turned into
+ // something like:
+ //
+ // 1.2.840.113549.1.9.1=#160e696e666f407a65726f632e636f6d
+ //
+ // The left hand side is the OID (see
+ // http://www.columbia.edu/~ariel/ssleay/asn1-oids.html) for a
+ // list. The right hand side is a BER encoding of the value.
+ //
+ // This means that the user input, unless it uses the
+ // unfriendly OID format, will not directly match the
+ // principal.
+ //
+ // Two possible solutions:
+ //
+ // Have the RFC2253 parser convert anything that is not CN, L,
+ // ST, O, OU, C, STREET, DC, UID into OID format, and have it
+ // convert the values into a BER encoding.
+ //
+ // Send the user data through X500Principal to string form and
+ // then through the RFC2253 encoder. This uses the
+ // X500Principal to do the encoding for us.
+ //
+ // The latter is much simpler, however, it means we need to
+ // send the data through the parser twice because we split the
+ // DNs on ';' which cannot be blindly split because of quotes,
+ // \ and such.
+ //
+ java.util.List result = new java.util.LinkedList();
+ java.util.List l = RFC2253.parse(value);
+ java.util.Iterator p = l.iterator();
+ while(p.hasNext())
+ {
+ java.util.List dn = (java.util.List)p.next();
+ String v = new String();
+ boolean first = true;
+ java.util.Iterator q = dn.iterator();
+ while(q.hasNext())
+ {
+ if(!first)
+ {
+ v += ",";
+ }
+ first = false;
+ RFC2253.RDNPair pair = (RFC2253.RDNPair)q.next();
+ v += pair.key;
+ v += "=";
+ v += pair.value;
+ }
+ javax.security.auth.x500.X500Principal princ = new javax.security.auth.x500.X500Principal(v);
+ String subjectName = princ.getName(javax.security.auth.x500.X500Principal.RFC2253);
+ java.util.List l2 = RFC2253.parse(subjectName);
+ assert l2.size() == 1;
+ result.add((java.util.List)l2.get(0));
+ }
+ return result;
+ }
+
+ private Ice.Communicator _communicator;
+ private int _traceLevel;
+
+ private java.util.List _all;
+ private java.util.List _client;
+ private java.util.List _allServer;
+ private java.util.Map _server = new java.util.HashMap();
+}
diff --git a/java/ssl/jdk1.4/IceSSL/Util.java b/java/ssl/jdk1.4/IceSSL/Util.java
index 38031ef4f24..6f0ed5e3f44 100644
--- a/java/ssl/jdk1.4/IceSSL/Util.java
+++ b/java/ssl/jdk1.4/IceSSL/Util.java
@@ -95,7 +95,7 @@ public final class Util
}
static ConnectionInfo
- populateConnectionInfo(javax.net.ssl.SSLSocket fd)
+ populateConnectionInfo(javax.net.ssl.SSLSocket fd, String adapterName, boolean incoming)
{
ConnectionInfo info = new ConnectionInfo();
javax.net.ssl.SSLSession session = fd.getSession();
@@ -110,6 +110,8 @@ public final class Util
info.cipher = session.getCipherSuite();
info.localAddr = (java.net.InetSocketAddress)fd.getLocalSocketAddress();
info.remoteAddr = (java.net.InetSocketAddress)fd.getRemoteSocketAddress();
+ info.adapterName = adapterName;
+ info.incoming = incoming;
return info;
}
}