create GSSCredential only once, cleanup
authorKonstantin Triger <kostat@mono-cvs.ximian.com>
Sun, 6 Nov 2005 17:20:34 +0000 (17:20 -0000)
committerKonstantin Triger <kostat@mono-cvs.ximian.com>
Sun, 6 Nov 2005 17:20:34 +0000 (17:20 -0000)
svn path=/trunk/mcs/; revision=52628

mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Security.jvm/ChangeLog
mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Security.jvm/CreateContextPrivilegedAction.cs
mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Security.jvm/Krb5Helper.cs
mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Security.jvm/SecureStream.cs
mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap/ChangeLog
mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap/LdapConnection.cs

index 972675275484a982f1d52f9c86397977f80616d8..cc77f724ea80e1c81f59663af3de18aec5eac674 100644 (file)
@@ -1,3 +1,8 @@
+2005-11-06  Konstantin Triger <kostat@mainsoft.com>
+
+       * SecureStream.cs, CreateContextPrivilegedAction.cs, Krb5Helper.cs:
+               create GSSCredential only once, cleanup
+
 2005-11-03  Konstantin Triger <kostat@mainsoft.com>
 
        * CreateContextPrivilegedAction.cs: always require mutual auth;
index e98fb9d40532016637c9ab746b1d647b7d4dd11f..73b280f55813cf6e89cd2552b4cd0e142a92dde3 100644 (file)
@@ -44,15 +44,17 @@ namespace Novell.Directory.Ldap.Security
                private readonly bool _signing;\r
                private readonly bool _delegation;\r
                private readonly string _name;\r
+               private readonly string _clientName;\r
                private readonly string _mech;\r
 \r
                #endregion //Fields\r
 \r
                #region Constructors\r
 \r
-               public CreateContextPrivilegedAction(string name, string mech, bool encryption, bool signing, bool delegation)\r
+               public CreateContextPrivilegedAction(string name, string clientName, string mech, bool encryption, bool signing, bool delegation)\r
                {\r
                        _name = name;\r
+                       _clientName = clientName;\r
                        _mech = mech;\r
                        _encryption = encryption;\r
                        _signing = signing;\r
@@ -68,16 +70,30 @@ namespace Novell.Directory.Ldap.Security
                        try {                           \r
                                Oid krb5Oid = new Oid (_mech);\r
                                GSSManager manager = GSSManager.getInstance ();\r
-                               GSSName serverName = manager.createName (_name, GSSName__Finals.NT_HOSTBASED_SERVICE, krb5Oid);\r
-                               GSSContext context = manager.createContext (serverName, krb5Oid, null, GSSContext__Finals.INDEFINITE_LIFETIME);\r
+                               GSSName clientName = \r
+                                       manager.createName(_clientName, GSSName__Finals.NT_USER_NAME);\r
+                               GSSCredential clientCreds =\r
+                                       manager.createCredential(clientName,\r
+                                       GSSContext__Finals.INDEFINITE_LIFETIME,\r
+                                       krb5Oid,\r
+                                       GSSCredential__Finals.INITIATE_ONLY);\r
 \r
-                               context.requestMutualAuth(true);  \r
-                               context.requestConf (_encryption);\r
-                               if (!_encryption || _signing)\r
-                                       context.requestInteg (!_encryption || _signing); \r
-                               context.requestCredDeleg (_delegation);\r
+//                             try {\r
+                                       GSSName serverName = manager.createName (_name, GSSName__Finals.NT_HOSTBASED_SERVICE, krb5Oid);\r
+                                       GSSContext context = manager.createContext (serverName, krb5Oid, clientCreds, GSSContext__Finals.INDEFINITE_LIFETIME);\r
 \r
-                               return context;\r
+                                       context.requestMutualAuth(true);  \r
+                                       context.requestConf (_encryption);\r
+                                       if (!_encryption || _signing)\r
+                                               context.requestInteg (!_encryption || _signing); \r
+                                       context.requestCredDeleg (_delegation);\r
+\r
+                                       return context;\r
+//                             }\r
+//                             finally {\r
+//                                     // Calling this throws GSSException: Operation unavailable...\r
+//                                     clientCreds.dispose();\r
+//                             }\r
                        }\r
                        catch (GSSException e) {\r
                                throw new PrivilegedActionException (e);\r
index 41889337d15b3aaaf7753a2dffd8777409e40676..65c037f6d7bd2edfc6e8913e0c80b226f5fc74f3 100644 (file)
@@ -39,7 +39,7 @@ using org.ietf.jgss;
 \r
 namespace Novell.Directory.Ldap.Security\r
 {\r
-       internal class Krb5Helper\r
+       internal class Krb5Helper : IDisposable\r
        {\r
                enum QOP {\r
                        NO_PROTECTION = 1,
@@ -57,26 +57,23 @@ namespace Novell.Directory.Ldap.Security
 \r
                private readonly GSSContext _context;\r
 \r
-               private readonly string _name;\r
-               private readonly Subject _subject;\r
-               private readonly string _mech;\r
-\r
                #endregion // Fields\r
 \r
                #region Constructors\r
 \r
-               public Krb5Helper(string name, Subject subject, AuthenticationTypes authenticationTypes, string mech)\r
+               public Krb5Helper(string name, string clientName, Subject subject, AuthenticationTypes authenticationTypes, string mech)\r
                {\r
-                       _name = name;\r
-                       _subject = subject;\r
-                       _mech = mech;\r
-\r
                        _encryption = (authenticationTypes & AuthenticationTypes.Sealing) != 0;\r
                        _signing = (authenticationTypes & AuthenticationTypes.Signing) != 0;\r
                        _delegation = (authenticationTypes & AuthenticationTypes.Delegation) != 0;\r
 \r
-                       CreateContextPrivilegedAction action = new CreateContextPrivilegedAction (_name,_mech,_encryption,_signing,_delegation);\r
-                       _context = (GSSContext) Subject.doAs (_subject,action);\r
+                       CreateContextPrivilegedAction action = new CreateContextPrivilegedAction (name, clientName, mech,_encryption,_signing,_delegation);\r
+                       try {\r
+                               _context = (GSSContext) Subject.doAs (subject,action);\r
+                       }\r
+                       catch (PrivilegedActionException e) {\r
+                               throw new LdapException ("Problem performing token exchange with the server",LdapException.OTHER,"",e.getCause()); \r
+                       }\r
                }\r
 \r
                #endregion // Constructors\r
@@ -126,14 +123,7 @@ namespace Novell.Directory.Ldap.Security
                                return TypeUtils.ToSByteArray (gssOutToken);\r
                        }\r
 \r
-                       sbyte [] token;\r
-                       try {\r
-                               ExchangeTokenPrivilegedAction action = new ExchangeTokenPrivilegedAction (Context, clientToken);
-                               token = (sbyte []) Subject.doAs (_subject, action);\r
-                       } \r
-                       catch (PrivilegedActionException e) {\r
-                               throw new LdapException ("Problem performing token exchange with the server",LdapException.OTHER,"",e); \r
-                       }\r
+                       sbyte [] token = Context.initSecContext (clientToken, 0, clientToken.Length);\r
 \r
                        if (Context.isEstablished ()) {\r
                                \r
@@ -169,13 +159,8 @@ namespace Novell.Directory.Ldap.Security
                                return buff;\r
                        }\r
 \r
-                       try {\r
-                               WrapPrivilegedAction action = new WrapPrivilegedAction (Context, outgoing, start, len, messageProp);\r
-                               return (byte []) Subject.doAs (_subject, action);                               \r
-                       } \r
-                       catch (PrivilegedActionException e) {\r
-                               throw new LdapException ("Problem performing GSS wrap",LdapException.OTHER,"",e); \r
-                       }\r
+                       sbyte [] result = Context.wrap (TypeUtils.ToSByteArray (outgoing), start, len, messageProp);\r
+                       return (byte []) TypeUtils.ToByteArray (result);\r
                }\r
 \r
                public byte [] Unwrap(byte [] incoming, int start, int len) \r
@@ -195,15 +180,18 @@ namespace Novell.Directory.Ldap.Security
                                return buff;\r
                        }\r
 \r
-                       try {\r
-                               UnwrapPrivilegedAction action = new UnwrapPrivilegedAction (Context, incoming, start, len, messageProp);\r
-                               return (byte []) Subject.doAs (_subject, action);\r
-                       } \r
-                       catch (PrivilegedActionException e) {\r
-                               throw new LdapException("Problems unwrapping SASL buffer",LdapException.OTHER,"",e);\r
-                       }\r
+                       sbyte [] result = Context.unwrap (TypeUtils.ToSByteArray (incoming), start, len, messageProp);\r
+                       return (byte []) TypeUtils.ToByteArray (result);\r
                }\r
 \r
                #endregion // Methods\r
+\r
+               #region IDisposable Members\r
+\r
+               public void Dispose() {\r
+                       Context.dispose();\r
+               }\r
+\r
+               #endregion\r
        }\r
 }\r
index 43508c33313d89e7cd223124cf319e2d2866068e..f9aa4e43aecdef9b61ba797d1951f0fbf1722ef5 100644 (file)
@@ -118,6 +118,11 @@ namespace Novell.Directory.Ldap.Security
                        }               \r
                }\r
 \r
+               public override void Close() {\r
+                       _stream.Close();\r
+                       _helper.Dispose();\r
+               }\r
+\r
                private int Fill()\r
                {\r
                        int actual = ReadAll (_lenBuf, 4);\r
index 19c7e8dcf639fb0ac38157154e37b9b1ebb388ce..ab0f2a0ecdaa496a1baa6fdead9ef67847317756 100644 (file)
@@ -1,3 +1,7 @@
+2005-11-06 Konstantin Triger <kostat@mainsoft.com>
+
+        * LdapConnection.cs: TARGET_JVM: create GSSCredential only once, cleanup
+
 2005-11-03 Konstantin Triger <kostat@mainsoft.com>
 
        * LdapConnection.cs: TARGET_JVM: throw an exception if failed during
index 87b3e5c819b6e8e880fb03bab579b480cf3616f8..60964d721ddce0b04c5f381ea66cd4bd50117a88 100644 (file)
@@ -1601,21 +1601,27 @@ namespace Novell.Directory.Ldap
 
                                        loginContext.login ();
                                }
-                               catch (LoginException e) {
+                               catch (Exception e) {
                                        throw new LdapException ("Failed to create login security context", 80, "", e);
                                }
 
-                               Subject subject = loginContext.getSubject ();
-
-                               Krb5Helper krb5Helper = new Krb5Helper ("ldap@" + conn.Host, subject, authenticationTypes, SecurityMech);
+                               Krb5Helper krb5Helper = null;
+                               try {
+                                       krb5Helper = new Krb5Helper ("ldap@" + conn.Host, username, loginContext.getSubject (), authenticationTypes, SecurityMech);
+                               }
+                               finally {
+                                       loginContext.logout();
+                               }
                                sbyte [] token = krb5Helper.ExchangeTokens (Krb5Helper.EmptyToken);
 
                                for (;;) {
                                        LdapResponseQueue queue = Bind(LdapConnection.Ldap_V3, username, token, null, null, AuthenticationMech);
                                        LdapResponse res = (LdapResponse) queue.getResponse ();
                                        if (res.ResultCode != LdapException.SASL_BIND_IN_PROGRESS &&
-                                               res.ResultCode != LdapException.SUCCESS)
+                                               res.ResultCode != LdapException.SUCCESS) {
+                                               krb5Helper.Dispose();
                                                throw new LdapException(ExceptionMessages.CONNECTION_ERROR, res.ResultCode, res.ErrorMessage);
+                                       }
                                        Asn1OctetString serverSaslCreds = ((RfcBindResponse)res.Asn1Object.Response).ServerSaslCreds;
                                        token = serverSaslCreds != null ? serverSaslCreds.byteValue () : null;
 
@@ -1635,7 +1641,7 @@ namespace Novell.Directory.Ldap
                        }               
                }
 
-               private string SecurityMech
+               static string SecurityMech
                {
                        get {
                                string securityMech = null;
@@ -1650,7 +1656,7 @@ namespace Novell.Directory.Ldap
                        }
                }
 
-               private string SecurityAppName
+               static string SecurityAppName
                {
                        get {
                                string securityAppName = null; 
@@ -1665,7 +1671,7 @@ namespace Novell.Directory.Ldap
                        }
                }
 
-               private string AuthenticationMech
+               static string AuthenticationMech
                {
                        get {
                                string authenticationMech = null;