Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kirzner <borisk@mono-cvs.ximian.com>2005-08-14 19:56:10 +0400
committerBoris Kirzner <borisk@mono-cvs.ximian.com>2005-08-14 19:56:10 +0400
commitaa6f208f1f237d9181b9bb9b778b0b4a76a26bcd (patch)
treee5f9932741fb53ea55c174eb0831d3ac410987ba /mcs/class/Novell.Directory.Ldap
parent0f84ad9c484d1c247a9fa4f0914d79b4d4bdd611 (diff)
Fixes for TARGET_JVM secure binding.
svn path=/trunk/mcs/; revision=48365
Diffstat (limited to 'mcs/class/Novell.Directory.Ldap')
-rw-r--r--mcs/class/Novell.Directory.Ldap/ChangeLog6
-rw-r--r--mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Security.jvm/ChangeLog6
-rw-r--r--mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Security.jvm/Krb5Helper.cs73
-rw-r--r--mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Security.jvm/SecureStream.cs4
-rw-r--r--mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap/LdapConnection.cs56
5 files changed, 120 insertions, 25 deletions
diff --git a/mcs/class/Novell.Directory.Ldap/ChangeLog b/mcs/class/Novell.Directory.Ldap/ChangeLog
index a144e2f4114..64d36848e9f 100644
--- a/mcs/class/Novell.Directory.Ldap/ChangeLog
+++ b/mcs/class/Novell.Directory.Ldap/ChangeLog
@@ -1,3 +1,9 @@
+2005-14-08 Boris Kirzner <borisk@mainsoft.com>
+ * LdapConnection.cs:
+ - Values from app settings are not stored anymore in app domain.
+ - Exchange tokens until negotiatin is complete.
+ - Added new property for authentication mech, stored in app settings.
+
2005-28-07 Boris Kirzner <borisk@mainsoft.com>
* Novell.Directory.Ldap.Security.jvm: added new directory containing
TARGET_JVM specific classes for kerberos authentication.
diff --git a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Security.jvm/ChangeLog b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Security.jvm/ChangeLog
index df96b0968cb..7cba50782e6 100644
--- a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Security.jvm/ChangeLog
+++ b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Security.jvm/ChangeLog
@@ -1,3 +1,9 @@
+2005-14-08 Boris Kirzner <borisk@mainsoft.com>
+ * Krb5Helper.cs: ExchangeTokens does proper final handshaking. Wrap/Unwrap
+ perform no action if no integrity and encryption accured.
+ * SecureStream.cs: Private convertion methods became internal, used by
+ Krb5Helper.
+
2005-28-07 Boris Kirzner <borisk@mainsoft.com>
* Novell.Directory.Ldap.Security.jvm/ExchangeTokenPrivilegedAction.cs,
Novell.Directory.Ldap.Security.jvm/CreateContextPrivilegedAction.cs,
diff --git a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Security.jvm/Krb5Helper.cs b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Security.jvm/Krb5Helper.cs
index 86f7f18ebcd..a83d2afe917 100644
--- a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Security.jvm/Krb5Helper.cs
+++ b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Security.jvm/Krb5Helper.cs
@@ -41,6 +41,12 @@ namespace Novell.Directory.Ldap.Security
{
internal class Krb5Helper
{
+ enum QOP {
+ NO_PROTECTION = 1,
+ INTEGRITY_ONLY_PROTECTION = 2,
+ PRIVACY_PROTECTION = 4
+ }
+
#region Fields
internal static readonly sbyte [] EmptyToken = new sbyte [0];
@@ -92,8 +98,39 @@ namespace Novell.Directory.Ldap.Security
public sbyte [] ExchangeTokens(sbyte [] clientToken)
{
- if (Context.isEstablished ())
- return Krb5Helper.EmptyToken;
+ if (Context.isEstablished ()) {
+ if (clientToken == null || clientToken.Length == 0)
+ return Krb5Helper.EmptyToken;
+
+ MessageProp messageProp = new MessageProp (0, false);
+
+ //final handshake
+ byte [] challengeData = (byte []) TypeUtils.ToByteArray (clientToken);
+ byte [] gssOutToken = Unwrap (challengeData, 0, challengeData.Length, messageProp);
+
+ QOP myCop = QOP.NO_PROTECTION;
+
+ if (_encryption)
+ myCop = QOP.PRIVACY_PROTECTION;
+ else if (_signing || (((QOP)gssOutToken [0] & QOP.INTEGRITY_ONLY_PROTECTION) != 0))
+ myCop = QOP.INTEGRITY_ONLY_PROTECTION;
+
+ if ((myCop & (QOP)gssOutToken [0]) == 0)
+ throw new LdapException ("Server does not support the requested security level", 80, "");
+
+ int srvMaxBufSize = SecureStream.NetworkByteOrderToInt (gssOutToken, 1, 3);
+
+ //int rawSendSize = Context.getWrapSizeLimit(0, _encryption, srvMaxBufSize);
+
+ byte [] gssInToken = new byte [4];
+ gssInToken [0] = (byte) myCop;
+
+ SecureStream.IntToNetworkByteOrder (srvMaxBufSize, gssInToken, 1, 3);
+
+ gssOutToken = Wrap (gssInToken, 0, gssInToken.Length, messageProp);
+
+ return TypeUtils.ToSByteArray (gssOutToken);
+ }
sbyte [] token;
try {
@@ -121,13 +158,25 @@ namespace Novell.Directory.Ldap.Security
return token;
}
- public byte [] Wrap(byte [] outgoing, int start, int len)
+ public byte [] Wrap(byte [] outgoing, int start, int len)
+ {
+ return Wrap (outgoing, start, len, _messageProperties);
+ }
+
+ public byte [] Wrap(byte [] outgoing, int start, int len, MessageProp messageProp)
{
if (!Context.isEstablished ())
throw new LdapException ("GSSAPI authentication not completed",LdapException.OTHER,"");
+ if (!(Context.getConfState () || Context.getIntegState ())) {
+ // in the case no encryption and no integrity required - return the original data
+ byte [] buff = new byte [len];
+ Array.Copy (outgoing, start, buff, 0, len);
+ return buff;
+ }
+
try {
- WrapPrivilegedAction action = new WrapPrivilegedAction (Context, outgoing, start, len, _messageProperties);
+ WrapPrivilegedAction action = new WrapPrivilegedAction (Context, outgoing, start, len, messageProp);
return (byte []) Subject.doAs (_subject, action);
}
catch (PrivilegedActionException e) {
@@ -135,13 +184,25 @@ namespace Novell.Directory.Ldap.Security
}
}
- public byte [] Unwrap(byte [] incoming, int start, int len)
+ public byte [] Unwrap(byte [] incoming, int start, int len)
+ {
+ return Unwrap (incoming, start, len, _messageProperties);
+ }
+
+ public byte [] Unwrap(byte [] incoming, int start, int len, MessageProp messageProp)
{
if (!Context.isEstablished ())
throw new LdapException ("GSSAPI authentication not completed",LdapException.OTHER,"");
+ if (!(Context.getConfState () || Context.getIntegState ())) {
+ // in the case no encryption and no integrity required - return the original data
+ byte [] buff = new byte [len];
+ Array.Copy (incoming, start, buff, 0, len);
+ return buff;
+ }
+
try {
- UnwrapPrivilegedAction action = new UnwrapPrivilegedAction (Context, incoming, start, len, _messageProperties);
+ UnwrapPrivilegedAction action = new UnwrapPrivilegedAction (Context, incoming, start, len, messageProp);
return (byte []) Subject.doAs (_subject, action);
}
catch (PrivilegedActionException e) {
diff --git a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Security.jvm/SecureStream.cs b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Security.jvm/SecureStream.cs
index f37ef8517ff..43508c33313 100644
--- a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Security.jvm/SecureStream.cs
+++ b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Security.jvm/SecureStream.cs
@@ -180,7 +180,7 @@ namespace Novell.Directory.Ldap.Security
_stream.Write (wrappedToken, 0, wrappedToken.Length);
}
- private static int NetworkByteOrderToInt(byte [] buf, int start, int count)
+ internal static int NetworkByteOrderToInt(byte [] buf, int start, int count)
{
int answer = 0;
for (int i = 0; i < count; i++) {
@@ -190,7 +190,7 @@ namespace Novell.Directory.Ldap.Security
return answer;
}
- private static void IntToNetworkByteOrder(int num, byte [] buf, int start, int count)
+ internal static void IntToNetworkByteOrder(int num, byte [] buf, int start, int count)
{
for (int i = count-1; i >= 0; i--) {
buf [start + i] = (byte)(num & 0xff);
diff --git a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap/LdapConnection.cs b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap/LdapConnection.cs
index a8bfd4aa834..374b3f61b5c 100644
--- a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap/LdapConnection.cs
+++ b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap/LdapConnection.cs
@@ -480,9 +480,6 @@ namespace Novell.Directory.Ldap
private static System.Object nameLock; // protect agentNum
private static int lConnNum = 0; // Debug, LdapConnection number
private System.String name; // String name for debug
-
- private const string LDAP_SECURITY_MECH = "System.DirectoryServices.SecurityMech";
- private const string LDAP_SECURITY_APP_NAME = "System.DirectoryServices.SecurityAppName";
/// <summary> Used with search to specify that the scope of entrys to search is to
/// search only the base obect.
@@ -1559,7 +1556,17 @@ namespace Novell.Directory.Ldap
#if TARGET_JVM
// stopping reader to enable stream replace after secure binding is complete, see Connection.ReplaceStreams()
if (mech != null)
+ {
+ if (conn.BindSemIdClear) {
+ // need to acquire a semaphore only if bindSemId is clear
+ // because if we receive SASL_BIND_IN_PROGRESS the semaphore is not
+ // released when the response is queued
+ conn.acquireWriteSemaphore(msgId);
+ conn.BindSemId = msgId;
+ }
conn.stopReaderOnReply(msgId);
+ }
+ else
#endif
// The semaphore is released when the bind response is queued.
conn.acquireWriteSemaphore(msgId);
@@ -1586,11 +1593,19 @@ namespace Novell.Directory.Ldap
Krb5Helper krb5Helper = new Krb5Helper ("ldap@" + conn.Host, subject, authenticationTypes, SecurityMech);
sbyte [] token = krb5Helper.ExchangeTokens (Krb5Helper.EmptyToken);
- LdapResponseQueue queue = Bind(LdapConnection.Ldap_V3, username, token, null, null, "GSS-SPNEGO");
- LdapResponse res = (LdapResponse) queue.getResponse ();
- token = ((RfcBindResponse)res.Asn1Object.Response).ServerSaslCreds.byteValue ();
+ for (;;) {
+ LdapResponseQueue queue = Bind(LdapConnection.Ldap_V3, username, token, null, null, AuthenticationMech);
+ LdapResponse res = (LdapResponse) queue.getResponse ();
+ Asn1OctetString serverSaslCreds = ((RfcBindResponse)res.Asn1Object.Response).ServerSaslCreds;
+ token = serverSaslCreds != null ? serverSaslCreds.byteValue () : null;
- token = krb5Helper.ExchangeTokens(token == null ? Krb5Helper.EmptyToken : token);
+ token = krb5Helper.ExchangeTokens(token == null ? Krb5Helper.EmptyToken : token);
+
+ if (res.ResultCode != LdapException.SASL_BIND_IN_PROGRESS)
+ break;
+
+ conn.ReplaceStreams (conn.InputStream,conn.OutputStream);
+ }
System.IO.Stream inStream = conn.InputStream;
System.IO.Stream newIn = new SecureStream (inStream, krb5Helper);
@@ -1603,9 +1618,7 @@ namespace Novell.Directory.Ldap
private string SecurityMech
{
get {
- string securityMech = (string) AppDomain.CurrentDomain.GetData (LDAP_SECURITY_MECH);
-
- if (securityMech == null) {
+ string securityMech = null;
NameValueCollection config = (NameValueCollection) ConfigurationSettings.GetConfig ("System.DirectoryServices/Settings");
if (config != null)
securityMech = config ["securitymech"];
@@ -1613,8 +1626,6 @@ namespace Novell.Directory.Ldap
if (securityMech == null)
throw new ArgumentException("Security mechanism id not found in application settings");
- AppDomain.CurrentDomain.SetData (LDAP_SECURITY_MECH,securityMech);
- }
return securityMech;
}
}
@@ -1622,9 +1633,7 @@ namespace Novell.Directory.Ldap
private string SecurityAppName
{
get {
- string securityAppName = (string) AppDomain.CurrentDomain.GetData (LDAP_SECURITY_APP_NAME);
-
- if (securityAppName == null) {
+ string securityAppName = null;
NameValueCollection config = (NameValueCollection) ConfigurationSettings.GetConfig ("System.DirectoryServices/Settings");
if (config != null)
securityAppName = config ["securityappname"];
@@ -1632,11 +1641,24 @@ namespace Novell.Directory.Ldap
if (securityAppName == null)
throw new ArgumentException("Application section name not found in application settings");
- AppDomain.CurrentDomain.SetData (LDAP_SECURITY_APP_NAME,securityAppName);
- }
return securityAppName;
}
}
+
+ private string AuthenticationMech
+ {
+ get {
+ string authenticationMech = null;
+ NameValueCollection config = (NameValueCollection) ConfigurationSettings.GetConfig ("System.DirectoryServices/Settings");
+ if (config != null)
+ authenticationMech = config ["authenticationmech"];
+
+ if (authenticationMech == null)
+ throw new ArgumentException("Authentication mechanism not found in application settings");
+
+ return authenticationMech;
+ }
+ }
#endif
//*************************************************************************