2 // Novell.Directory.Ldap.Security.Krb5Helper.cs
5 // Boris Kirzner <borsk@mainsoft.com>
6 // Konstantin Triger <kostat@mainsoft.com>
8 // (C) 2005 Mainsoft Corporation (http://www.mainsoft.com)
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 using java.security;
\r
36 using javax.security.auth;
\r
37 using org.ietf.jgss;
\r
40 namespace Novell.Directory.Ldap.Security
\r
42 internal class Krb5Helper
\r
46 INTEGRITY_ONLY_PROTECTION = 2,
47 PRIVACY_PROTECTION = 4
\r
52 internal static readonly sbyte [] EmptyToken = new sbyte [0];
\r
54 private readonly bool _encryption;
\r
55 private readonly bool _signing;
\r
56 private readonly bool _delegation;
\r
58 private readonly GSSContext _context;
\r
60 private readonly string _name;
\r
61 private readonly Subject _subject;
\r
62 private readonly string _mech;
\r
64 #endregion // Fields
\r
66 #region Constructors
\r
68 public Krb5Helper(string name, Subject subject, AuthenticationTypes authenticationTypes, string mech)
\r
74 _encryption = (authenticationTypes & AuthenticationTypes.Sealing) != 0;
\r
75 _signing = (authenticationTypes & AuthenticationTypes.Signing) != 0;
\r
76 _delegation = (authenticationTypes & AuthenticationTypes.Delegation) != 0;
\r
78 CreateContextPrivilegedAction action = new CreateContextPrivilegedAction (_name,_mech,_encryption,_signing,_delegation);
\r
79 _context = (GSSContext) Subject.doAs (_subject,action);
\r
82 #endregion // Constructors
\r
86 internal GSSContext Context
\r
88 get { return _context; }
\r
91 #endregion // Properties
\r
95 public sbyte [] ExchangeTokens(sbyte [] clientToken)
\r
97 if (Context.isEstablished ()) {
\r
98 if (clientToken == null || clientToken.Length == 0)
\r
99 return Krb5Helper.EmptyToken;
\r
102 byte [] challengeData = (byte []) TypeUtils.ToByteArray (clientToken);
\r
103 byte [] gssOutToken = Unwrap (challengeData, 0, challengeData.Length, new MessageProp (false));
\r
105 QOP myCop = QOP.NO_PROTECTION;
\r
108 myCop = QOP.PRIVACY_PROTECTION;
\r
109 else if (_signing || (((QOP)gssOutToken [0] & QOP.INTEGRITY_ONLY_PROTECTION) != 0))
\r
110 myCop = QOP.INTEGRITY_ONLY_PROTECTION;
\r
112 if ((myCop & (QOP)gssOutToken [0]) == 0)
\r
113 throw new LdapException ("Server does not support the requested security level", 80, "");
\r
115 int srvMaxBufSize = SecureStream.NetworkByteOrderToInt (gssOutToken, 1, 3);
\r
117 //int rawSendSize = Context.getWrapSizeLimit(0, _encryption, srvMaxBufSize);
\r
119 byte [] gssInToken = new byte [4];
120 gssInToken [0] = (byte) myCop;
\r
122 SecureStream.IntToNetworkByteOrder (srvMaxBufSize, gssInToken, 1, 3);
\r
124 gssOutToken = Wrap (gssInToken, 0, gssInToken.Length, new MessageProp (true));
\r
126 return TypeUtils.ToSByteArray (gssOutToken);
\r
131 ExchangeTokenPrivilegedAction action = new ExchangeTokenPrivilegedAction (Context, clientToken);
132 token = (sbyte []) Subject.doAs (_subject, action);
\r
134 catch (PrivilegedActionException e) {
\r
135 throw new LdapException ("Problem performing token exchange with the server",LdapException.OTHER,"",e);
\r
138 if (Context.isEstablished ()) {
\r
140 if (Context.getConfState () != _encryption)
\r
141 throw new LdapException ("Encryption protocol was not established layer between client and server", 80, "");
\r
143 if (Context.getCredDelegState () != _delegation)
\r
144 throw new LdapException ("Credential delegation was not established layer between client and server", 80, "");
\r
146 if (_signing && (Context.getIntegState () != _signing))
\r
147 throw new LdapException ("Signing protocol was not established layer between client and server", 80, "");
\r
149 if (token == null)
\r
155 public byte [] Wrap(byte [] outgoing, int start, int len)
\r
157 return Wrap (outgoing, start, len, new MessageProp(true));
\r
160 public byte [] Wrap(byte [] outgoing, int start, int len, MessageProp messageProp)
\r
162 if (!Context.isEstablished ())
\r
163 throw new LdapException ("GSSAPI authentication not completed",LdapException.OTHER,"");
\r
165 if (!(Context.getConfState () || Context.getIntegState ())) {
\r
166 // in the case no encryption and no integrity required - return the original data
\r
167 byte [] buff = new byte [len];
\r
168 Array.Copy (outgoing, start, buff, 0, len);
\r
173 WrapPrivilegedAction action = new WrapPrivilegedAction (Context, outgoing, start, len, messageProp);
\r
174 return (byte []) Subject.doAs (_subject, action);
\r
176 catch (PrivilegedActionException e) {
\r
177 throw new LdapException ("Problem performing GSS wrap",LdapException.OTHER,"",e);
\r
181 public byte [] Unwrap(byte [] incoming, int start, int len)
\r
183 return Unwrap (incoming, start, len, new MessageProp(true));
\r
186 public byte [] Unwrap(byte [] incoming, int start, int len, MessageProp messageProp)
\r
188 if (!Context.isEstablished ())
\r
189 throw new LdapException ("GSSAPI authentication not completed",LdapException.OTHER,"");
\r
191 if (!(Context.getConfState () || Context.getIntegState ())) {
\r
192 // in the case no encryption and no integrity required - return the original data
\r
193 byte [] buff = new byte [len];
\r
194 Array.Copy (incoming, start, buff, 0, len);
\r
199 UnwrapPrivilegedAction action = new UnwrapPrivilegedAction (Context, incoming, start, len, messageProp);
\r
200 return (byte []) Subject.doAs (_subject, action);
\r
202 catch (PrivilegedActionException e) {
\r
203 throw new LdapException("Problems unwrapping SASL buffer",LdapException.OTHER,"",e);
\r
207 #endregion // Methods
\r