diff options
author | Sunil Kumar <sunilk@mono-cvs.ximian.com> | 2003-11-24 06:59:43 +0300 |
---|---|---|
committer | Sunil Kumar <sunilk@mono-cvs.ximian.com> | 2003-11-24 06:59:43 +0300 |
commit | 97eb9c81ca39d0f8c500dec1bf0a06008b014bc8 (patch) | |
tree | ee4cfc1bf1ff33d71f5050f4567254f0dc4dd83b /mcs/class/Novell.Directory.Ldap | |
parent | b54c016e597cd7410abdd5f529a1e1d1c341d5e2 (diff) |
Class files Implementing various utility classes used by LDAP C# Libraray
svn path=/trunk/mcs/; revision=20367
Diffstat (limited to 'mcs/class/Novell.Directory.Ldap')
13 files changed, 2919 insertions, 0 deletions
diff --git a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/ArrayEnumeration.cs b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/ArrayEnumeration.cs new file mode 100755 index 00000000000..95fee05560c --- /dev/null +++ b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/ArrayEnumeration.cs @@ -0,0 +1,89 @@ +/****************************************************************************** +* The MIT License +* Copyright (c) 2003 Novell Inc. www.novell.com +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the Software), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +*******************************************************************************/ +// +// Novell.Directory.Ldap.Utilclass.ArrayEnumeration.cs +// +// Author: +// Sunil Kumar (Sunilk@novell.com) +// +// (C) 2003 Novell, Inc (http://www.novell.com) +// + +using System; + +namespace Novell.Directory.Ldap.Utilclass +{ + + public class ArrayEnumeration : System.Collections.IEnumerator + { + private System.Object tempAuxObj; + public virtual bool MoveNext() + { + bool result = hasMoreElements(); + if (result) + { + tempAuxObj = nextElement(); + } + return result; + } + public virtual void Reset() + { + tempAuxObj = null; + } + public virtual System.Object Current + { + get + { + return tempAuxObj; + } + + } + private System.Object[] eArray; + private int index = 0; + /// <summary> Constructor to create the Enumeration + /// + /// </summary> + /// <param name="eArray">the array to use for the Enumeration + /// </param> + public ArrayEnumeration(System.Object[] eArray) + { + this.eArray = eArray; + } + + public bool hasMoreElements() + { + if (eArray == null) + return false; + return (index < eArray.Length); + } + + public System.Object nextElement() + { + if ((eArray == null) || (index >= eArray.Length)) + { + throw new System.ArgumentOutOfRangeException(); + } + return eArray[index++]; + } + } +} diff --git a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/AttributeQualifier.cs b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/AttributeQualifier.cs new file mode 100755 index 00000000000..d111009e88d --- /dev/null +++ b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/AttributeQualifier.cs @@ -0,0 +1,93 @@ +/****************************************************************************** +* The MIT License +* Copyright (c) 2003 Novell Inc. www.novell.com +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the Software), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +*******************************************************************************/ +// +// Novell.Directory.Ldap.Utilclass.AttributeQualifier.cs +// +// Author: +// Sunil Kumar (Sunilk@novell.com) +// +// (C) 2003 Novell, Inc (http://www.novell.com) +// + +using System; + +namespace Novell.Directory.Ldap.Utilclass +{ + + /// <summary> Encapsulates a qualifier in a Schema definition. Definitions that are not + /// in rfc2252. Begins with 'X-' + /// </summary> + public class AttributeQualifier + { + virtual public System.String Name + { + /* + public void addValue( String value ) + { + values.add( value ); + return; + } + */ + + get + { + return name; + } + + } + virtual public System.String[] Values + { + get + { + System.String[] strValues = null; + if (values.Count > 0) + { + strValues = new System.String[values.Count]; + for (int i = 0; i < values.Count; i++) + { + strValues[i] = ((System.String) values[i]); + } + } + return strValues; + } + + } + internal System.String name; + internal System.Collections.ArrayList values; + + public AttributeQualifier(System.String name, System.String[] value_Renamed) + { + if ((System.Object) name == null || value_Renamed == null) + { + throw new System.ArgumentException("A null name or value " + "was passed in for a schema definition qualifier"); + } + this.name = name; + values = new System.Collections.ArrayList(5); + for (int i = 0; i < value_Renamed.Length; i++) + { + values.Add(value_Renamed[i]); + } + return ; + } + } +} diff --git a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/Base64.cs b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/Base64.cs new file mode 100755 index 00000000000..0d648fb88b9 --- /dev/null +++ b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/Base64.cs @@ -0,0 +1,722 @@ +/****************************************************************************** +* The MIT License +* Copyright (c) 2003 Novell Inc. www.novell.com +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the Software), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +*******************************************************************************/ +// +// Novell.Directory.Ldap.Utilclass.Base64.cs +// +// Author: +// Sunil Kumar (Sunilk@novell.com) +// +// (C) 2003 Novell, Inc (http://www.novell.com) +// + +using System; + +namespace Novell.Directory.Ldap.Utilclass +{ + + /// <summary> The Base64 utility class performs base64 encoding and decoding. + /// + /// The Base64 Content-Transfer-Encoding is designed to represent + /// arbitrary sequences of octets in a form that need not be humanly + /// readable. The encoding and decoding algorithms are simple, but the + /// encoded data are consistently only about 33 percent larger than the + /// unencoded data. The base64 encoding algorithm is defined by + /// RFC 2045. + /// </summary> + public class Base64 + { + /// <summary>Conversion table for encoding to base64. + /// + /// emap is a six-bit value to base64 (8-bit) converstion table. + /// For example, the value of the 6-bit value 15 + /// is mapped to 0x50 which is the ASCII letter 'P', i.e. the letter P + /// is the base64 encoded character that represents the 6-bit value 15. + /// </summary> + /* + * 8-bit base64 encoded character base64 6-bit + * encoded original + * character binary value + */ + private static readonly char[] emap = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; // 4-9, + /; 56-63 + + /// <summary>conversion table for decoding from base64. + /// + /// dmap is a base64 (8-bit) to six-bit value converstion table. + /// For example the ASCII character 'P' has a value of 80. + /// The value in the 80th position of the table is 0x0f or 15. + /// 15 is the original 6-bit value that the letter 'P' represents. + /// </summary> + /* + * 6-bit decoded value base64 base64 + * encoded character + * value + * + * Note: about half of the values in the table are only place holders + */ + private static readonly sbyte[] dmap = new sbyte[]{(sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x3e), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x3f), (sbyte) (0x34), (sbyte) (0x35), (sbyte) (0x36), (sbyte) (0x37), (sbyte) (0x38), (sbyte) (0x39), (sbyte) (0x3a), (sbyte) (0x3b), (sbyte) (0x3c), (sbyte) (0x3d), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x01), (sbyte) (0x02), (sbyte) (0x03), (sbyte) (0x04), (sbyte) (0x05), (sbyte) (0x06), (sbyte) (0x07), (sbyte) (0x08), (sbyte) (0x09), (sbyte) (0x0a), (sbyte) (0x0b), (sbyte) (0x0c), (sbyte) (0x0d), (sbyte) (0x0e), (sbyte) (0x0f), (sbyte) (0x10), (sbyte) (0x11), (sbyte) (0x12), (sbyte) (0x13), (sbyte) (0x14), (sbyte) (0x15), (sbyte) (0x16), (sbyte) (0x17), (sbyte) (0x18), (sbyte) (0x19), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x1a), (sbyte) (0x1b), (sbyte) (0x1c), (sbyte) (0x1d), (sbyte) (0x1e), (sbyte) (0x1f), (sbyte) (0x20), (sbyte) (0x21), (sbyte) (0x22), (sbyte) (0x23), (sbyte) (0x24), (sbyte) (0x25), (sbyte) (0x26), (sbyte) (0x27), (sbyte) (0x28), (sbyte) (0x29), (sbyte) (0x2a), (sbyte) (0x2b), (sbyte) (0x2c), (sbyte) (0x2d), (sbyte) (0x2e), (sbyte) (0x2f), (sbyte) (0x30), (sbyte) (0x31), (sbyte) (0x32), (sbyte) (0x33), (sbyte) (0x00), ( + sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00)}; // 120-127 'xyz ' + + /// <summary> Default constructor, don't allow instances of the + /// utility class to be created. + /// </summary> + private Base64() + { + return ; + } + + + /// <summary> Encodes the specified String into a base64 encoded String object. + /// + /// </summary> + /// <param name="inputString"> The String object to be encoded. + /// + /// </param> + /// <returns> a String containing the encoded value of the input. + /// </returns> + public static System.String encode(System.String inputString) + { + try + { + System.Text.Encoding encoder = System.Text.Encoding.GetEncoding("utf-8"); + byte[] ibytes = encoder.GetBytes(inputString); + sbyte[] sbytes=SupportClass.ToSByteArray(ibytes); + return encode(sbytes); + } + catch (System.IO.IOException ue) + { + throw new System.SystemException("US-ASCII String encoding not supported by JVM"); + } + } + + /// <summary> Encodes the specified bytes into a base64 array of bytes. + /// Each byte in the return array represents a base64 character. + /// + /// </summary> + /// <param name="inputBytes"> the byte array to be encoded. + /// + /// </param> + /// <returns> a String containing the base64 encoded data + /// </returns> + [CLSCompliantAttribute(false)] + public static System.String encode(sbyte[] inputBytes) + { + int i, j, k; + int t, t1, t2; + int ntb; // number of three-bytes in inputBytes + bool onePadding = false, twoPaddings = false; + char[] encodedChars; // base64 encoded chars + int len = inputBytes.Length; + + if (len == 0) + { + // No data, return no data. + return new System.Text.StringBuilder("").ToString(); + } + + // every three bytes will be encoded into four bytes + if (len % 3 == 0) + { + ntb = len / 3; + } + // the last one or two bytes will be encoded into + // four bytes with one or two paddings + else + { + ntb = len / 3 + 1; + } + + // need two paddings + if ((len % 3) == 1) + { + twoPaddings = true; + } + // need one padding + else if ((len % 3) == 2) + { + onePadding = true; + } + + encodedChars = new char[ntb * 4]; + + // map of decoded and encoded bits + // bits in 3 decoded bytes: 765432 107654 321076 543210 + // bits in 4 encoded bytes: 76543210765432107654321076543210 + // plain "AAA": 010000 010100 000101 000001 + // base64 encoded "QUFB": 00010000000101000000010100000001 + // one padding: + // bits in 2 decoded bytes: 765432 10 7654 3210 + // bits in 4 encoded bytes: 765432107654 321076543210 '=' + // plain "AA": 010000 010100 0001 + // base64 encoded "QUE=": 00010000000101000000010000111101 + // two paddings: + // bits in 1 decoded bytes: 765432 10 + // bits in 4 encoded bytes: 7654321076543210 '=' '=' + // plain "A": 010000 01 + // base64 encoded "QQ==": 00010000000100000011110100111101 + // + // note: the encoded bits which have no corresponding decoded bits + // are filled with zeros; '=' = 00111101. + for (i = 0, j = 0, k = 1; i < len; i += 3, j += 4, k++) + { + + // build encodedChars[j] + t = 0x00ff & inputBytes[i]; + encodedChars[j] = emap[t >> 2]; + + // build encodedChars[j+1] + if ((k == ntb) && twoPaddings) + { + encodedChars[j + 1] = emap[(t & 0x03) << 4]; + encodedChars[j + 2] = '='; + encodedChars[j + 3] = '='; + break; + } + else + { + t1 = 0x00ff & inputBytes[i + 1]; + encodedChars[j + 1] = emap[((t & 0x03) << 4) + ((t1 & 0xf0) >> 4)]; + } + + // build encodedChars[j+2] + if ((k == ntb) && onePadding) + { + encodedChars[j + 2] = emap[(t1 & 0x0f) << 2]; + encodedChars[j + 3] = '='; + break; + } + else + { + t2 = 0x00ff & inputBytes[i + 2]; + encodedChars[j + 2] = (emap[(t1 & 0x0f) << 2 | (t2 & 0xc0) >> 6]); + } + + // build encodedChars[j+3] + encodedChars[j + 3] = (emap[(t2 & 0x3f)]); + } + return new System.String(encodedChars); + } + + + /// <summary> Decodes the input base64 encoded String. + /// The resulting binary data is returned as an array of bytes. + /// + /// </summary> + /// <param name="encodedString">The base64 encoded String object. + /// + /// </param> + /// <returns> The decoded byte array. + /// </returns> + [CLSCompliantAttribute(false)] + public static sbyte[] decode(System.String encodedString) + { + char[] c = new char[encodedString.Length]; + SupportClass.GetCharsFromString(encodedString, 0, encodedString.Length, ref c, 0); + return decode(c); + } + + /// <summary> Decodes the input base64 encoded array of characters. + /// The resulting binary data is returned as an array of bytes. + /// + /// </summary> + /// <param name="encodedChars">The character array containing the base64 encoded data. + /// + /// </param> + /// <returns> A byte array object containing decoded bytes. + /// </returns> + [CLSCompliantAttribute(false)] + public static sbyte[] decode(char[] encodedChars) + { + int i, j, k; + int ecLen = encodedChars.Length; // length of encodedChars + int gn = ecLen / 4; // number of four-byte groups in encodedChars + int dByteLen; // length of decoded bytes, default is '0' + bool onePad = false, twoPads = false; + sbyte[] decodedBytes; // decoded bytes + + if (encodedChars.Length == 0) + { + return new sbyte[0]; + } + // the number of encoded bytes should be multiple of 4 + if ((ecLen % 4) != 0) + { + throw new System.SystemException("com.novell.ldap.ldif_dsml." + "Base64Decoder: decode: mal-formatted encode value"); + } + + // every four-bytes in encodedString, except the last one if it in the + // form of '**==' or '***=' ( can't be '*===' or '===='), will be + // decoded into three bytes. + if ((encodedChars[ecLen - 1] == (int) '=') && (encodedChars[ecLen - 2] == (int) '=')) + { + // the last four bytes of encodedChars is in the form of '**==' + twoPads = true; + // the first two bytes of the last four-bytes of encodedChars will + // be decoded into one byte. + dByteLen = gn * 3 - 2; + decodedBytes = new sbyte[dByteLen]; + } + else if (encodedChars[ecLen - 1] == '=') + { + // the last four bytes of encodedChars is in the form of '***=' + onePad = true; + // the first two bytes of the last four-bytes of encodedChars will + // be decoded into two bytes. + dByteLen = gn * 3 - 1; + decodedBytes = new sbyte[dByteLen]; + } + else + { + // the last four bytes of encodedChars is in the form of '****', + // e.g. no pad. + dByteLen = gn * 3; + decodedBytes = new sbyte[dByteLen]; + } + + // map of encoded and decoded bits + // no padding: + // bits in 4 encoded bytes: 76543210 76543210 76543210 76543210 + // bits in 3 decoded bytes: 765432 107654 321076 543210 + // base64 string "QUFB":00010000 00010100 000001010 0000001 + // plain string "AAA": 010000 010100 000101 000001 + // one padding: + // bits in 4 encoded bytes: 76543210 76543210 76543210 76543210 + // bits in 2 decoded bytes: 765432 107654 3210 + // base64 string "QUE=": 00010000 000101000 0000100 00111101 + // plain string "AA": 010000 010100 0001 + // two paddings: + // bits in 4 encoded bytes: 76543210 76543210 76543210 76543210 + // bits in 1 decoded bytes: 765432 10 + // base64 string "QQ==": 00010000 00010000 00111101 00111101 + // plain string "A": 010000 01 + for (i = 0, j = 0, k = 1; i < ecLen; i += 4, j += 3, k++) + { + // build decodedBytes[j]. + decodedBytes[j] = (sbyte) (dmap[encodedChars[i]] << 2 | (dmap[encodedChars[i + 1]] & 0x30) >> 4); + + // build decodedBytes[j+1] + if ((k == gn) && twoPads) + { + break; + } + else + { + decodedBytes[j + 1] = (sbyte) ((dmap[encodedChars[i + 1]] & 0x0f) << 4 | (dmap[encodedChars[i + 2]] & 0x3c) >> 2); + } + + // build decodedBytes[j+2] + if ((k == gn) && onePad) + { + break; + } + else + { + decodedBytes[j + 2] = (sbyte) ((dmap[encodedChars[i + 2]] & 0x03) << 6 | dmap[encodedChars[i + 3]] & 0x3f); + } + } + return decodedBytes; + } + + /// <summary> Decodes a base64 encoded StringBuffer. + /// Decodes all or part of the input base64 encoded StringBuffer, each + /// Character value representing a base64 character. The resulting + /// binary data is returned as an array of bytes. + /// + /// </summary> + /// <param name="encodedSBuf">The StringBuffer object that contains base64 + /// encoded data. + /// </param> + /// <param name="start"> The start index of the base64 encoded data. + /// </param> + /// <param name="end"> The end index + 1 of the base64 encoded data. + /// + /// </param> + /// <returns> The decoded byte array + /// </returns> + [CLSCompliantAttribute(false)] + public static sbyte[] decode(System.Text.StringBuilder encodedSBuf, int start, int end) + { + int i, j, k; + int esbLen = end - start; // length of the encoded part + int gn = esbLen / 4; // number of four-bytes group in ebs + int dByteLen; // length of dbs, default is '0' + bool onePad = false, twoPads = false; + sbyte[] decodedBytes; // decoded bytes + + if (encodedSBuf.Length == 0) + { + return new sbyte[0]; + } + // the number of encoded bytes should be multiple of number 4 + if ((esbLen % 4) != 0) + { + throw new System.SystemException("com.novell.ldap.ldif_dsml." + "Base64Decoder: decode error: mal-formatted encode value"); + } + + // every four-bytes in ebs, except the last one if it in the form of + // '**==' or '***=' ( can't be '*===' or '===='), will be decoded into + // three bytes. + if ((encodedSBuf[end - 1] == (int) '=') && (encodedSBuf[end - 2] == (int) '=')) + { + // the last four bytes of ebs is in the form of '**==' + twoPads = true; + // the first two bytes of the last four-bytes of ebs will be + // decoded into one byte. + dByteLen = gn * 3 - 2; + decodedBytes = new sbyte[dByteLen]; + } + else if (encodedSBuf[end - 1] == (int) '=') + { + // the last four bytes of ebs is in the form of '***=' + onePad = true; + // the first two bytes of the last four-bytes of ebs will be + // decoded into two bytes. + dByteLen = gn * 3 - 1; + decodedBytes = new sbyte[dByteLen]; + } + else + { + // the last four bytes of ebs is in the form of '****', eg. no pad. + dByteLen = gn * 3; + decodedBytes = new sbyte[dByteLen]; + } + + // map of encoded and decoded bits + // no padding: + // bits in 4 encoded bytes: 76543210 76543210 76543210 76543210 + // bits in 3 decoded bytes: 765432 107654 321076 543210 + // base64 string "QUFB":00010000 00010100 000001010 0000001 + // plain string "AAA": 010000 010100 000101 000001 + // one padding: + // bits in 4 encoded bytes: 76543210 76543210 76543210 76543210 + // bits in 2 decoded bytes: 765432 107654 3210 + // base64 string "QUE=": 00010000 000101000 0000100 00111101 + // plain string "AA": 010000 010100 0001 + // two paddings: + // bits in 4 encoded bytes: 76543210 76543210 76543210 76543210 + // bits in 1 decoded bytes: 765432 10 + // base64 string "QQ==": 00010000 00010000 00111101 00111101 + // plain string "A": 010000 01 + for (i = 0, j = 0, k = 1; i < esbLen; i += 4, j += 3, k++) + { + // build decodedBytes[j]. + decodedBytes[j] = (sbyte) (dmap[encodedSBuf[start + i]] << 2 | (dmap[encodedSBuf[start + i + 1]] & 0x30) >> 4); + + // build decodedBytes[j+1] + if ((k == gn) && twoPads) + { + break; + } + else + { + decodedBytes[j + 1] = (sbyte) ((dmap[encodedSBuf[start + i + 1]] & 0x0f) << 4 | (dmap[encodedSBuf[start + i + 2]] & 0x3c) >> 2); + } + + // build decodedBytes[j+2] + if ((k == gn) && onePad) + { + break; + } + else + { + decodedBytes[j + 2] = (sbyte) ((dmap[encodedSBuf[start + i + 2]] & 0x03) << 6 | dmap[encodedSBuf[start + i + 3]] & 0x3f); + } + } + return decodedBytes; + } + + /// <summary> Checks if the input byte array contains only safe values, that is, + /// the data does not need to be encoded for use with LDIF. + /// The rules for checking safety are based on the rules for LDIF + /// (Ldap Data Interchange Format) per RFC 2849. The data does + /// not need to be encoded if all the following are true: + /// <br> + /// <p>The data cannot start with the following byte values:</p> + /// <pre> + /// 00 (NUL) + /// 10 (LF) + /// 13 (CR) + /// 32 (SPACE) + /// 58 (:) + /// 60 (<) + /// Any character with value greater than 127 + /// (Negative for a byte value) + /// </pre> + /// <p>The data cannot contain any of the following byte values:</p> + /// <pre> + /// 00 (NUL) + /// 10 (LF) + /// 13 (CR) + /// Any character with value greater than 127 + /// (Negative for a byte value) + /// </pre> + /// <p>The data cannot end with a space.</p> + /// + /// </summary> + /// <param name="bytes">the bytes to be checked. + /// + /// </param> + /// <returns> true if encoding not required for LDIF + /// </returns> + [CLSCompliantAttribute(false)] + public static bool isLDIFSafe(sbyte[] bytes) + { + int len = bytes.Length; + if (len > 0) + { + int testChar = bytes[0]; + // unsafe if first character is a NON-SAFE-INIT-CHAR + if ((testChar == 0x00) || (testChar == 0x0A) || (testChar == 0x0D) || (testChar == 0x20) || (testChar == 0x3A) || (testChar == 0x3C) || (testChar < 0)) + { + // non ascii (>127 is negative) + return false; + } + // unsafe if last character is a space + if (bytes[len - 1] == ' ') + { + return false; + } + // unsafe if contains any non safe character + if (len > 1) + { + for (int i = 1; i < bytes.Length; i++) + { + testChar = bytes[i]; + if ((testChar == 0x00) || (testChar == 0x0A) || (testChar == 0x0D) || (testChar < 0)) + { + // non ascii (>127 is negative) + return false; + } + } + } + } + return true; + } + /// <summary> Checks if the input String contains only safe values, that is, + /// the data does not need to be encoded for use with LDIF. + /// The rules for checking safety are based on the rules for LDIF + /// (Ldap Data Interchange Format) per RFC 2849. The data does + /// not need to be encoded if all the following are true: + /// <br> + /// <p>The data cannot start with the following char values:</p> + /// <pre> + /// 00 (NUL) + /// 10 (LF) + /// 13 (CR) + /// 32 (SPACE) + /// 58 (:) + /// 60 (<) + /// Any character with value greater than 127 + /// </pre> + /// <p>The data cannot contain any of the following char values:</p> + /// <pre> + /// 00 (NUL) + /// 10 (LF) + /// 13 (CR) + /// Any character with value greater than 127 + /// </pre> + /// <p>The data cannot end with a space.</p> + /// + /// </summary> + /// <param name="str">the String to be checked. + /// + /// </param> + /// <returns> true if encoding not required for LDIF + /// </returns> + public static bool isLDIFSafe(System.String str) + { + try + { + System.Text.Encoding encoder = System.Text.Encoding.GetEncoding("utf-8"); + byte[] ibytes = encoder.GetBytes(str); + sbyte[] sbytes=SupportClass.ToSByteArray(ibytes); return (isLDIFSafe(sbytes)); + } + catch (System.IO.IOException ue) + { + throw new System.SystemException("UTF-8 String encoding not supported by JVM"); + } + } + + /* **************UTF-8 Validation methods and members******************* + * The following text is taken from draft-yergeau-rfc2279bis-02 and explains + * UTF-8 encoding: + * + *<p>In UTF-8, characters are encoded using sequences of 1 to 6 octets. + * If the range of character numbers is restricted to U+0000..U+10FFFF + * (the UTF-16 accessible range), then only sequences of one to four + * octets will occur. The only octet of a "sequence" of one has the + * higher-order bit set to 0, the remaining 7 bits being used to encode + * the character number. In a sequence of n octets, n>1, the initial + * octet has the n higher-order bits set to 1, followed by a bit set to + * 0. The remaining bit(s) of that octet contain bits from the number + * of the character to be encoded. The following octet(s) all have the + * higher-order bit set to 1 and the following bit set to 0, leaving 6 + * bits in each to contain bits from the character to be encoded.</p> + * + * <p>The table below summarizes the format of these different octet types. + * The letter x indicates bits available for encoding bits of the + * character number.</p> + * + * <pre> + * Char. number range | UTF-8 octet sequence + * (hexadecimal) | (binary) + * --------------------+--------------------------------------------- + * 0000 0000-0000 007F | 0xxxxxxx + * 0000 0080-0000 07FF | 110xxxxx 10xxxxxx + * 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx + * 0001 0000-001F FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0020 0000-03FF FFFF | 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0400 0000-7FFF FFFF | 1111110x 10xxxxxx ... 10xxxxxx + * </pre> + */ + + /// <summary> Given the first byte in a sequence, getByteCount returns the number of + /// additional bytes in a UTF-8 character sequence (not including the first + /// byte). + /// + /// </summary> + /// <param name="b"> The first byte in a UTF-8 character sequence. + /// + /// </param> + /// <returns> the number of additional bytes in a UTF-8 character sequence. + /// </returns> + private static int getByteCount(sbyte b) + { + if (b > 0) + return 0; + if ((b & 0xE0) == 0xC0) + { + return 1; //one additional byte (2 bytes total) + } + if ((b & 0xF0) == 0xE0) + { + return 2; //two additional bytes (3 bytes total) + } + if ((b & 0xF8) == 0xF0) + { + return 3; //three additional bytes (4 bytes total) + } + if ((b & 0xFC) == 0xF8) + { + return 4; //four additional bytes (5 bytes total) + } + if ((b & 0xFF) == 0xFC) + { + return 5; //five additional bytes (6 bytes total) + } + return - 1; + } + + /// <summary> Bit masks used to determine if a the value of UTF-8 byte sequence + /// is less than the minimum value. + /// + /// <p>If the value of a byte sequence is less than the minimum value then + /// the number should be encoded in fewer bytes and is invalid. For example + /// If the first byte indicates that a sequence has three bytes in a + /// sequence. Then the top five bits cannot be zero. Notice the index into + /// the array is one less than the number of bytes in a sequence. + /// A validity test for this could be: + /// <pre> + /// if ((lowerBoundMask[1][0] & byte[0] != 0) || + /// (lowerBoundMask[1][1] & byte[1] != 0)) { + /// then the value is above the minimum and is valid. + /// } + /// </pre> + /// </summary> + private static readonly sbyte[][] lowerBoundMask = {new sbyte[]{0, 0}, new sbyte[]{(sbyte) (0x1E), (sbyte) (0x00)}, new sbyte[]{(sbyte) (0x0F), (sbyte) (0x20)}, new sbyte[]{(sbyte) (0x07), (sbyte) (0x30)}, new sbyte[]{(sbyte) (0x02), (sbyte) (0x38)}, new sbyte[]{(sbyte) (0x01), (sbyte) (0x3C)}}; + + /// <summary>mask to AND with a continuation byte: should equal continuationResult </summary> + private static sbyte continuationMask = (sbyte) SupportClass.Identity(0xC0); + + /// <summary>expected result of ANDing a continuation byte with continuationMask </summary> + private static sbyte continuationResult = (sbyte) SupportClass.Identity(0x80); + + /// <summary> Determines if an array of bytes contains only valid UTF-8 characters. + /// <p> + /// UTF-8 is the standard encoding for Ldap strings. If a value contains + /// data that is not valid UTF-8 then data is lost converting the + /// value to a Java String. + /// </p> + /// + /// <p>In addition, Java Strings currently use UCS2 (Unicode Code Standard + /// 2-byte characters). UTF-8 can be encoded as USC2 and UCS4 (4-byte + /// characters). Some valid UTF-8 characters cannot be represented as UCS2 + /// characters. To determine if all UTF-8 sequences can be encoded into + /// UCS2 characters (a Java String), specify the <code>isUCS2Only</code> + /// parameter as <code>true</code>.<p> + /// + /// </summary> + /// <param name="array"> An array of bytes that are to be tested for valid UTF-8 + /// encoding. + /// <br><br> + /// </param> + /// <param name="isUCS2Only">true if the UTF-8 values must be restricted to fit + /// within UCS2 encoding (2 bytes) + /// </param> + /// <returns> true if all values in the byte array are valid UTF-8 + /// sequences. If <code>isUCS2Only</code> is + /// <code>true</code>, the method returns false if a UTF-8 + /// sequence generates any character that cannot be + /// represented as a UCS2 character (Java String) + /// </returns> + [CLSCompliantAttribute(false)] + public static bool isValidUTF8(sbyte[] array, bool isUCS2Only) + { + int index = 0; + while (index < array.Length) + { + int count = getByteCount(array[index]); + if (count == 0) + { + //anything that qualifies as count=0 is valid UTF-8 + index++; + continue; + } + + if (count == - 1 || index + count >= array.Length || (isUCS2Only && count >= 3)) + { + /* Any count that puts us out of bounds for the index is + * invalid. Valid UCS2 characters can only have 2 additional + * bytes. (three total) */ + return false; + } + + /* Tests if the first and second byte are below the minimum bound */ + if ((lowerBoundMask[count][0] & array[index]) == 0 && (lowerBoundMask[count][1] & array[index + 1]) == 0) + { + return false; + } + + /* testing continuation on the second and following bytes */ + for (int i = 1; i <= count; i++) + { + if ((array[index + i] & continuationMask) != continuationResult) + { + return false; + } + } + index += count + 1; + } + return true; + } + } +} diff --git a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/BindProperties.cs b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/BindProperties.cs new file mode 100755 index 00000000000..3d255532c09 --- /dev/null +++ b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/BindProperties.cs @@ -0,0 +1,134 @@ +/****************************************************************************** +* The MIT License +* Copyright (c) 2003 Novell Inc. www.novell.com +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the Software), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +*******************************************************************************/ +// +// Novell.Directory.Ldap.Utilclass.BindProperties.cs +// +// Author: +// Sunil Kumar (Sunilk@novell.com) +// +// (C) 2003 Novell, Inc (http://www.novell.com) +// + +using System; + +namespace Novell.Directory.Ldap.Utilclass +{ + + /// <summary> Encapsulates an Ldap Bind properties</summary> + public class BindProperties + { + /// <summary> gets the protocol version</summary> + virtual public int ProtocolVersion + { + get + { + return version; + } + + } + /// <summary> Gets the authentication dn + /// + /// </summary> + /// <returns> the authentication dn for this connection + /// </returns> + virtual public System.String AuthenticationDN + { + get + { + return dn; + } + + } + /// <summary> Gets the authentication method + /// + /// </summary> + /// <returns> the authentication method for this connection + /// </returns> + virtual public System.String AuthenticationMethod + { + get + { + return method; + } + + } + /// <summary> Gets the SASL Bind properties + /// + /// </summary> + /// <returns> the sasl bind properties for this connection + /// </returns> + virtual public System.Collections.Hashtable SaslBindProperties + { + get + { + return bindProperties; + } + + } + + /// <summary> Gets the SASL callback handler + /// + /// </summary> + /// <returns> the sasl callback handler for this connection + /// </returns> + virtual public System.Object SaslCallbackHandler + { + get + { + return bindCallbackHandler; + } + + } + + /// <summary> Indicates whether or not the bind properties specify an anonymous bind + /// + /// </summary> + /// <returns> true if the bind properties specify an anonymous bind + /// </returns> + virtual public bool Anonymous + { + get + { + return anonymous; + } + + } + + private int version = 3; + private System.String dn = null; + private System.String method = null; + private bool anonymous; + private System.Collections.Hashtable bindProperties = null; + private System.Object bindCallbackHandler = null; + + public BindProperties(int version, System.String dn, System.String method, bool anonymous, System.Collections.Hashtable bindProperties, System.Object bindCallbackHandler) + { + this.version = version; + this.dn = dn; + this.method = method; + this.anonymous = anonymous; + this.bindProperties = bindProperties; + this.bindCallbackHandler = bindCallbackHandler; + } + } +} diff --git a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/DN.cs b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/DN.cs new file mode 100755 index 00000000000..6db86f7033f --- /dev/null +++ b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/DN.cs @@ -0,0 +1,743 @@ +/****************************************************************************** +* The MIT License +* Copyright (c) 2003 Novell Inc. www.novell.com +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the Software), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +*******************************************************************************/ +// +// Novell.Directory.Ldap.Utilclass.DN.cs +// +// Author: +// Sunil Kumar (Sunilk@novell.com) +// +// (C) 2003 Novell, Inc (http://www.novell.com) +// + +using System; + +namespace Novell.Directory.Ldap.Utilclass +{ + + /// <summary> <P>A DN encapsulates a Distinguished Name (an ldap name with context). A DN + /// does not need to be fully distinguished, or extend to the Root of a + /// directory. It provides methods to get information about the DN and to + /// manipulate the DN. </P> + /// + /// <P> The following are examples of valid DN: + /// <ul> + /// <li>cn=admin,ou=marketing,o=corporation</li> + /// <li>cn=admin,ou=marketing</li> + /// <li>2.5.4.3=admin,ou=marketing</li> + /// <li>oid.2.5.4.3=admin,ou=marketing</li> + /// </ul> + /// + /// <P>Note: Multivalued attributes are all considered to be one + /// component and are represented in one RDN (see RDN) + /// </P> + /// + /// </summary> + /// <seealso cref="RDN"> + /// </seealso> + + public class DN : System.Object + { + private void InitBlock() + { + rdnList = new System.Collections.ArrayList(); + } + /// <summary> Retrieves a list of RDN Objects, or individual names of the DN</summary> + /// <returns> list of RDNs + /// </returns> + virtual public System.Collections.ArrayList RDNs + { + get + { + int size = rdnList.Count; + System.Collections.ArrayList v = new System.Collections.ArrayList(size); + for (int i = 0; i < size; i++) + { + v.Add(rdnList[i]); + } + return v; + } + + } + /// <summary> Returns the Parent of this DN</summary> + /// <returns> Parent DN + /// </returns> + virtual public DN Parent + { + get + { + DN parent = new DN(); + parent.rdnList = (System.Collections.ArrayList) this.rdnList.Clone(); + if (parent.rdnList.Count >= 1) + parent.rdnList.Remove(rdnList[0]); //remove first object + return parent; + } + + } + + //parser state identifiers. + private const int LOOK_FOR_RDN_ATTR_TYPE = 1; + private const int ALPHA_ATTR_TYPE = 2; + private const int OID_ATTR_TYPE = 3; + private const int LOOK_FOR_RDN_VALUE = 4; + private const int QUOTED_RDN_VALUE = 5; + private const int HEX_RDN_VALUE = 6; + private const int UNQUOTED_RDN_VALUE = 7; + + /* State transition table: Parsing starts in state 1. + + State COMMA DIGIT "Oid." ALPHA EQUAL QUOTE SHARP HEX + -------------------------------------------------------------------- + 1 Err 3 3 2 Err Err Err Err + 2 Err Err Err 2 4 Err Err Err + 3 Err 3 Err Err 4 Err Err Err + 4 Err 7 Err 7 Err 5 6 7 + 5 1 5 Err 5 Err 1 Err 7 + 6 1 6 Err Err Err Err Err 6 + 7 1 7 Err 7 Err Err Err 7 + + */ + + + private System.Collections.ArrayList rdnList; + + public DN() + { + InitBlock(); + return ; + } + /// <summary> Constructs a new DN based on the specified string representation of a + /// distinguished name. The syntax of the DN must conform to that specified + /// in RFC 2253. + /// + /// </summary> + /// <param name="dnString">a string representation of the distinguished name + /// </param> + /// <exception cref=""> IllegalArgumentException if the the value of the dnString + /// parameter does not adhere to the syntax described in + /// RFC 2253 + /// </exception> + public DN(System.String dnString) + { + InitBlock(); + /* the empty string is a valid DN */ + if (dnString.Length == 0) + return ; + + char currChar; + char nextChar; + int currIndex; + char[] tokenBuf = new char[dnString.Length]; + int tokenIndex; + int lastIndex; + int valueStart; + int state; + int trailingSpaceCount = 0; + System.String attrType = ""; + System.String attrValue = ""; + System.String rawValue = ""; + int hexDigitCount = 0; + RDN currRDN = new RDN(); + + //indicates whether an OID number has a first digit of ZERO + bool firstDigitZero = false; + + tokenIndex = 0; + currIndex = 0; + valueStart = 0; + state = LOOK_FOR_RDN_ATTR_TYPE; + lastIndex = dnString.Length - 1; + while (currIndex <= lastIndex) + { + currChar = dnString[currIndex]; + switch (state) + { + + case LOOK_FOR_RDN_ATTR_TYPE: + while (currChar == ' ' && (currIndex < lastIndex)) + currChar = dnString[++currIndex]; + if (isAlpha(currChar)) + { + if (dnString.Substring(currIndex).StartsWith("oid.") || dnString.Substring(currIndex).StartsWith("OID.")) + { + //form is "oid.###.##.###... or OID.###.##.###... + currIndex += 4; //skip oid. prefix and get to actual oid + if (currIndex > lastIndex) + throw new System.ArgumentException(dnString); + currChar = dnString[currIndex]; + if (isDigit(currChar)) + { + tokenBuf[tokenIndex++] = currChar; + state = OID_ATTR_TYPE; + } + else + throw new System.ArgumentException(dnString); + } + else + { + tokenBuf[tokenIndex++] = currChar; + state = ALPHA_ATTR_TYPE; + } + } + else if (isDigit(currChar)) + { + --currIndex; + state = OID_ATTR_TYPE; + } + else if (!(System.Char.GetUnicodeCategory(currChar) == System.Globalization.UnicodeCategory.SpaceSeparator)) + throw new System.ArgumentException(dnString); + break; + + + case ALPHA_ATTR_TYPE: + if (isAlpha(currChar) || isDigit(currChar) || (currChar == '-')) + tokenBuf[tokenIndex++] = currChar; + else + { + //skip any spaces + while ((currChar == ' ') && (currIndex < lastIndex)) + currChar = dnString[++currIndex]; + if (currChar == '=') + { + attrType = new System.String(tokenBuf, 0, tokenIndex); + tokenIndex = 0; + state = LOOK_FOR_RDN_VALUE; + } + else + throw new System.ArgumentException(dnString); + } + break; + + + case OID_ATTR_TYPE: + if (!isDigit(currChar)) + throw new System.ArgumentException(dnString); + firstDigitZero = (currChar == '0')?true:false; + tokenBuf[tokenIndex++] = currChar; + currChar = dnString[++currIndex]; + + if ((isDigit(currChar) && firstDigitZero) || (currChar == '.' && firstDigitZero)) + { + throw new System.ArgumentException(dnString); + } + + //consume all numbers. + while (isDigit(currChar) && (currIndex < lastIndex)) + { + tokenBuf[tokenIndex++] = currChar; + currChar = dnString[++currIndex]; + } + if (currChar == '.') + { + tokenBuf[tokenIndex++] = currChar; + //The state remains at OID_ATTR_TYPE + } + else + { + //skip any spaces + while (currChar == ' ' && (currIndex < lastIndex)) + currChar = dnString[++currIndex]; + if (currChar == '=') + { + attrType = new System.String(tokenBuf, 0, tokenIndex); + tokenIndex = 0; + state = LOOK_FOR_RDN_VALUE; + } + else + throw new System.ArgumentException(dnString); + } + break; + + + case LOOK_FOR_RDN_VALUE: + while (currChar == ' ') + { + if (currIndex < lastIndex) + currChar = dnString[++currIndex]; + else + throw new System.ArgumentException(dnString); + } + if (currChar == '"') + { + state = QUOTED_RDN_VALUE; + valueStart = currIndex; + } + else if (currChar == '#') + { + hexDigitCount = 0; + tokenBuf[tokenIndex++] = currChar; + valueStart = currIndex; + state = HEX_RDN_VALUE; + } + else + { + valueStart = currIndex; + //check this character again in the UNQUOTED_RDN_VALUE state + currIndex--; + state = UNQUOTED_RDN_VALUE; + } + break; + + + case UNQUOTED_RDN_VALUE: + if (currChar == '\\') + { + if (!(currIndex < lastIndex)) + throw new System.ArgumentException(dnString); + currChar = dnString[++currIndex]; + if (isHexDigit(currChar)) + { + if (!(currIndex < lastIndex)) + throw new System.ArgumentException(dnString); + nextChar = dnString[++currIndex]; + if (isHexDigit(nextChar)) + { + tokenBuf[tokenIndex++] = hexToChar(currChar, nextChar); + trailingSpaceCount = 0; + } + else + throw new System.ArgumentException(dnString); + } + else if (needsEscape(currChar) || currChar == '#' || currChar == '=' || currChar == ' ') + { + tokenBuf[tokenIndex++] = currChar; + trailingSpaceCount = 0; + } + else + throw new System.ArgumentException(dnString); + } + else if (currChar == ' ') + { + trailingSpaceCount++; + tokenBuf[tokenIndex++] = currChar; + } + else if ((currChar == ',') || (currChar == ';') || (currChar == '+')) + { + attrValue = new System.String(tokenBuf, 0, tokenIndex - trailingSpaceCount); + rawValue = dnString.Substring(valueStart, (currIndex - trailingSpaceCount) - (valueStart)); + + currRDN.add(attrType, attrValue, rawValue); + if (currChar != '+') + { + rdnList.Add(currRDN); + currRDN = new RDN(); + } + + trailingSpaceCount = 0; + tokenIndex = 0; + state = LOOK_FOR_RDN_ATTR_TYPE; + } + else if (needsEscape(currChar)) + { + throw new System.ArgumentException(dnString); + } + else + { + trailingSpaceCount = 0; + tokenBuf[tokenIndex++] = currChar; + } + break; //end UNQUOTED RDN VALUE + + + case QUOTED_RDN_VALUE: + if (currChar == '"') + { + rawValue = dnString.Substring(valueStart, (currIndex + 1) - (valueStart)); + if (currIndex < lastIndex) + currChar = dnString[++currIndex]; + //skip any spaces + while ((currChar == ' ') && (currIndex < lastIndex)) + currChar = dnString[++currIndex]; + if ((currChar == ',') || (currChar == ';') || (currChar == '+') || (currIndex == lastIndex)) + { + attrValue = new System.String(tokenBuf, 0, tokenIndex); + + currRDN.add(attrType, attrValue, rawValue); + if (currChar != '+') + { + rdnList.Add(currRDN); + currRDN = new RDN(); + } + trailingSpaceCount = 0; + tokenIndex = 0; + state = LOOK_FOR_RDN_ATTR_TYPE; + } + else + throw new System.ArgumentException(dnString); + } + else if (currChar == '\\') + { + currChar = dnString[++currIndex]; + if (isHexDigit(currChar)) + { + nextChar = dnString[++currIndex]; + if (isHexDigit(nextChar)) + { + tokenBuf[tokenIndex++] = hexToChar(currChar, nextChar); + trailingSpaceCount = 0; + } + else + throw new System.ArgumentException(dnString); + } + else if (needsEscape(currChar) || currChar == '#' || currChar == '=' || currChar == ' ') + { + tokenBuf[tokenIndex++] = currChar; + trailingSpaceCount = 0; + } + else + throw new System.ArgumentException(dnString); + } + else + tokenBuf[tokenIndex++] = currChar; + break; //end QUOTED RDN VALUE + + + case HEX_RDN_VALUE: + if ((!isHexDigit(currChar)) || (currIndex > lastIndex)) + { + //check for odd number of hex digits + if ((hexDigitCount % 2) != 0 || hexDigitCount == 0) + throw new System.ArgumentException(dnString); + else + { + rawValue = dnString.Substring(valueStart, (currIndex) - (valueStart)); + //skip any spaces + while ((currChar == ' ') && (currIndex < lastIndex)) + currChar = dnString[++currIndex]; + if ((currChar == ',') || (currChar == ';') || (currChar == '+') || (currIndex == lastIndex)) + { + attrValue = new System.String(tokenBuf, 0, tokenIndex); + + //added by cameron + currRDN.add(attrType, attrValue, rawValue); + if (currChar != '+') + { + rdnList.Add(currRDN); + currRDN = new RDN(); + } + tokenIndex = 0; + state = LOOK_FOR_RDN_ATTR_TYPE; + } + else + { + throw new System.ArgumentException(dnString); + } + } + } + else + { + tokenBuf[tokenIndex++] = currChar; + hexDigitCount++; + } + break; //end HEX RDN VALUE + } //end switch + currIndex++; + } //end while + + //check ending state + if (state == UNQUOTED_RDN_VALUE || (state == HEX_RDN_VALUE && (hexDigitCount % 2) == 0) && hexDigitCount != 0) + { + attrValue = new System.String(tokenBuf, 0, tokenIndex - trailingSpaceCount); + rawValue = dnString.Substring(valueStart, (currIndex - trailingSpaceCount) - (valueStart)); + currRDN.add(attrType, attrValue, rawValue); + rdnList.Add(currRDN); + } + else if (state == LOOK_FOR_RDN_VALUE) + { + //empty value is valid + attrValue = ""; + rawValue = dnString.Substring(valueStart); + currRDN.add(attrType, attrValue, rawValue); + rdnList.Add(currRDN); + } + else + { + throw new System.ArgumentException(dnString); + } + } //end DN constructor (string dn) + + + /// <summary> Checks a character to see if it is an ascii alphabetic character in + /// ranges 65-90 or 97-122. + /// + /// </summary> + /// <param name="ch">the character to be tested. + /// </param> + /// <returns> <code>true</code> if the character is an ascii alphabetic + /// character + /// </returns> + private bool isAlpha(char ch) + { + if (((ch < 91) && (ch > 64)) || ((ch < 123) && (ch > 96))) + //ASCII A-Z + return true; + else + return false; + } + + + /// <summary> Checks a character to see if it is an ascii digit (0-9) character in + /// the ascii value range 48-57. + /// + /// </summary> + /// <param name="ch">the character to be tested. + /// </param> + /// <returns> <code>true</code> if the character is an ascii alphabetic + /// character + /// </returns> + private bool isDigit(char ch) + { + if ((ch < 58) && (ch > 47)) + //ASCII 0-9 + return true; + else + return false; + } + + /// <summary> Checks a character to see if it is valid hex digit 0-9, a-f, or + /// A-F (ASCII value ranges 48-47, 65-70, 97-102). + /// + /// </summary> + /// <param name="ch">the character to be tested. + /// </param> + /// <returns> <code>true</code> if the character is a valid hex digit + /// </returns> + + private static bool isHexDigit(char ch) + { + if (((ch < 58) && (ch > 47)) || ((ch < 71) && (ch > 64)) || ((ch < 103) && (ch > 96))) + //ASCII A-F + return true; + else + return false; + } + + /// <summary> Checks a character to see if it must always be escaped in the + /// string representation of a DN. We must tests for space, sharp, and + /// equals individually. + /// + /// </summary> + /// <param name="ch">the character to be tested. + /// </param> + /// <returns> <code>true</code> if the character needs to be escaped in at + /// least some instances. + /// </returns> + private bool needsEscape(char ch) + { + if ((ch == ',') || (ch == '+') || (ch == '\"') || (ch == ';') || (ch == '<') || (ch == '>') || (ch == '\\')) + return true; + else + return false; + } + + /// <summary> Converts two valid hex digit characters that form the string + /// representation of an ascii character value to the actual ascii + /// character. + /// + /// </summary> + /// <param name="hex1">the hex digit for the high order byte. + /// </param> + /// <param name="hex0">the hex digit for the low order byte. + /// </param> + /// <returns> the character whose value is represented by the parameters. + /// </returns> + + private static char hexToChar(char hex1, char hex0) + { + int result; + + if ((hex1 < 58) && (hex1 > 47)) + //ASCII 0-9 + result = (hex1 - 48) * 16; + else if ((hex1 < 71) && (hex1 > 64)) + //ASCII a-f + result = (hex1 - 55) * 16; + else if ((hex1 < 103) && (hex1 > 96)) + //ASCII A-F + result = (hex1 - 87) * 16; + else + throw new System.ArgumentException("Not hex digit"); + + if ((hex0 < 58) && (hex0 > 47)) + //ASCII 0-9 + result += (hex0 - 48); + else if ((hex0 < 71) && (hex0 > 64)) + //ASCII a-f + result += (hex0 - 55); + else if ((hex0 < 103) && (hex0 > 96)) + //ASCII A-F + result += (hex0 - 87); + else + throw new System.ArgumentException("Not hex digit"); + + return (char) result; + } + + /// <summary> Creates and returns a string that represents this DN. The string + /// follows RFC 2253, which describes String representation of DN's and + /// RDN's + /// + /// </summary> + /// <returns> A DN string. + /// </returns> + public override System.String ToString() + { + int length = rdnList.Count; + System.String dn = ""; + if (length < 1) + return null; + dn = rdnList[0].ToString(); + for (int i = 1; i < length; i++) + { + dn += ("," + rdnList[i].ToString()); + } + return dn; + } + + + /// <summary> Compares this DN to the specified DN to determine if they are equal. + /// + /// </summary> + /// <param name="toDN">the DN to compare to + /// </param> + /// <returns> <code>true</code> if the DNs are equal; otherwise + /// <code>false</code> + /// </returns> + + public System.Collections.ArrayList getrdnList() + { + return this.rdnList; + } + public override bool Equals(System.Object toDN) + { + return Equals((DN) toDN); + } + public bool Equals(DN toDN) + { + System.Collections.ArrayList aList=toDN.getrdnList(); + int length = aList.Count; + + if (this.rdnList.Count != length) + return false; + + for (int i = 0; i < length; i++) + { + if (!((RDN) rdnList[i]).equals((RDN) toDN.getrdnList()[i])) + return false; + } + return true; + } + + /// <summary> return a string array of the individual RDNs contained in the DN + /// + /// </summary> + /// <param name="noTypes"> If true, returns only the values of the + /// components, and not the names, e.g. "Babs + /// Jensen", "Accounting", "Acme", "us" - instead of + /// "cn=Babs Jensen", "ou=Accounting", "o=Acme", and + /// "c=us". + /// </param> + /// <returns> <code>String[]</code> containing the rdns in the DN with + /// the leftmost rdn in the first element of the array + /// + /// </returns> + public virtual System.String[] explodeDN(bool noTypes) + { + int length = rdnList.Count; + System.String[] rdns = new System.String[length]; + for (int i = 0; i < length; i++) + rdns[i] = ((RDN) rdnList[i]).toString(noTypes); + return rdns; + } + + /// <summary> Retrieves the count of RDNs, or individule names, in the Distinguished name</summary> + /// <returns> the count of RDN + /// </returns> + public virtual int countRDNs() + { + return rdnList.Count; + } + + /// <summary>Determines if this DN is <I>contained</I> by the DN passed in. For + /// example: "cn=admin, ou=marketing, o=corporation" is contained by + /// "o=corporation", "ou=marketing, o=corporation", and "ou=marketing" + /// but <B>not</B> by "cn=admin" or "cn=admin,ou=marketing,o=corporation" + /// Note: For users of Netscape's SDK this method is comparable to contains + /// + /// </summary> + /// <param name="containerDN">of a container + /// </param> + /// <returns> true if containerDN contains this DN + /// </returns> + public virtual bool isDescendantOf(DN containerDN) + { + int i = containerDN.rdnList.Count - 1; //index to an RDN of the ContainerDN + int j = this.rdnList.Count - 1; //index to an RDN of the ContainedDN + //Search from the end of the DN for an RDN that matches the end RDN of + //containerDN. + while (!((RDN) this.rdnList[j--]).equals((RDN) containerDN.rdnList[i])) + { + if (j <= 0) + return false; + //if the end RDN of containerDN does not have any equal + //RDN in rdnList, then containerDN does not contain this DN + } + i--; //avoid a redundant compare + j--; + //step backwards to verify that all RDNs in containerDN exist in this DN + for (; i >= 0 && j >= 0; i--, j--) + { + if (!((RDN) this.rdnList[j]).equals((RDN) containerDN.rdnList[i])) + return false; + } + if (j == 0 && i == 0) + //the DNs are identical and thus not contained + return false; + + return true; + } + + /// <summary> Adds the RDN to the beginning of the current DN.</summary> + /// <param name="rdn">an RDN to be added + /// </param> + public virtual void addRDN(RDN rdn) + { + rdnList.Insert(0, rdn); + } + + /// <summary> Adds the RDN to the beginning of the current DN.</summary> + /// <param name="rdn">an RDN to be added + /// </param> + public virtual void addRDNToFront(RDN rdn) + { + rdnList.Insert(0, rdn); + } + + /// <summary> Adds the RDN to the end of the current DN</summary> + /// <param name="rdn">an RDN to be added + /// </param> + public virtual void addRDNToBack(RDN rdn) + { + rdnList.Add(rdn); + } + } //end class DN +} diff --git a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/EnumeratedIterator.cs b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/EnumeratedIterator.cs new file mode 100755 index 00000000000..beecaf4f58c --- /dev/null +++ b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/EnumeratedIterator.cs @@ -0,0 +1,91 @@ +/****************************************************************************** +* The MIT License +* Copyright (c) 2003 Novell Inc. www.novell.com +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the Software), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +*******************************************************************************/ +// +// Novell.Directory.Ldap.Utilclass.EnumeratedIterator.cs +// +// Author: +// Sunil Kumar (Sunilk@novell.com) +// +// (C) 2003 Novell, Inc (http://www.novell.com) +// + +using System; + +namespace Novell.Directory.Ldap.Utilclass +{ + /// <summary> wrappers a class of type Iterator and makes it act as an Enumerator. This + /// is used when the API requires enumerations be used but we may be using + /// JDK1.2 collections, which return iterators instead of enumerators. Used by + /// LdapSchema and LdapSchemaElement + /// + /// </summary> + /// <seealso cref="com.novell.ldap.LdapSchema#getAttributeSchemas"> + /// </seealso> + /// <seealso cref="com.novell.ldap.LdapSchemaElement#getQualifierNames"> + /// </seealso> + + public class EnumeratedIterator : System.Collections.IEnumerator + { + private System.Object tempAuxObj; + public virtual bool MoveNext() + { + bool result = hasMoreElements(); + if (result) + { + tempAuxObj = nextElement(); + } + return result; + } + public virtual void Reset() + { + tempAuxObj = null; + } + public virtual System.Object Current + { + get + { + return tempAuxObj; + } + + } + private System.Collections.IEnumerator i; + + public EnumeratedIterator(System.Collections.IEnumerator iterator) + { + i = iterator; + return ; + } + + /// <summary> Enumeration method that maps to Iterator.hasNext()</summary> + public bool hasMoreElements() + { + return i.MoveNext(); + } + + /// <summary> Enumeration method that maps to Iterator.next()</summary> + public System.Object nextElement() + { + return i.Current; + } + } +} diff --git a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/ExceptionMessages.cs b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/ExceptionMessages.cs new file mode 100755 index 00000000000..ace778e240d --- /dev/null +++ b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/ExceptionMessages.cs @@ -0,0 +1,120 @@ +/****************************************************************************** +* The MIT License +* Copyright (c) 2003 Novell Inc. www.novell.com +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the Software), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +*******************************************************************************/ +// +// Novell.Directory.Ldap.Utilclass.ExceptionMessages.cs +// +// Author: +// Sunil Kumar (Sunilk@novell.com) +// +// (C) 2003 Novell, Inc (http://www.novell.com) +// + +using System; + +namespace Novell.Directory.Ldap.Utilclass +{ + + /// <summary> This class contains strings that may be associated with Exceptions generated + /// by the Ldap API libraries. + /// Two entries are made for each message, a String identifier, and the + /// actual error string. Parameters are identified as {0}, {1}, etc. + /// </summary> + public class ExceptionMessages:System.Resources.ResourceManager + { + public System.Object[][] getContents() + { + return contents; + } + //static strings to aide lookup and guarantee accuracy: + //DO NOT include these strings in other Locales + [CLSCompliantAttribute(false)] + public const System.String TOSTRING = "TOSTRING"; + public const System.String SERVER_MSG = "SERVER_MSG"; + public const System.String MATCHED_DN = "MATCHED_DN"; + public const System.String FAILED_REFERRAL = "FAILED_REFERRAL"; + public const System.String REFERRAL_ITEM = "REFERRAL_ITEM"; + public const System.String CONNECTION_ERROR = "CONNECTION_ERROR"; + public const System.String CONNECTION_IMPOSSIBLE = "CONNECTION_IMPOSSIBLE"; + public const System.String CONNECTION_WAIT = "CONNECTION_WAIT"; + public const System.String CONNECTION_FINALIZED = "CONNECTION_FINALIZED"; + public const System.String CONNECTION_CLOSED = "CONNECTION_CLOSED"; + public const System.String CONNECTION_READER = "CONNECTION_READER"; + public const System.String DUP_ERROR = "DUP_ERROR"; + public const System.String REFERRAL_ERROR = "REFERRAL_ERROR"; + public const System.String REFERRAL_LOCAL = "REFERRAL_LOCAL"; + public const System.String REFERENCE_ERROR = "REFERENCE_ERROR"; + public const System.String REFERRAL_SEND = "REFERRAL_SEND"; + public const System.String REFERENCE_NOFOLLOW = "REFERENCE_NOFOLLOW"; + public const System.String REFERRAL_BIND = "REFERRAL_BIND"; + public const System.String REFERRAL_BIND_MATCH = "REFERRAL_BIND_MATCH"; + public const System.String NO_DUP_REQUEST = "NO_DUP_REQUEST"; + public const System.String SERVER_CONNECT_ERROR = "SERVER_CONNECT_ERROR"; + public const System.String NO_SUP_PROPERTY = "NO_SUP_PROPERTY"; + public const System.String ENTRY_PARAM_ERROR = "ENTRY_PARAM_ERROR"; + public const System.String DN_PARAM_ERROR = "DN_PARAM_ERROR"; + public const System.String RDN_PARAM_ERROR = "RDN_PARAM_ERROR"; + public const System.String OP_PARAM_ERROR = "OP_PARAM_ERROR"; + public const System.String PARAM_ERROR = "PARAM_ERROR"; + public const System.String DECODING_ERROR = "DECODING_ERROR"; + public const System.String ENCODING_ERROR = "ENCODING_ERROR"; + public const System.String IO_EXCEPTION = "IO_EXCEPTION"; + public const System.String INVALID_ESCAPE = "INVALID_ESCAPE"; + public const System.String SHORT_ESCAPE = "SHORT_ESCAPE"; + public const System.String INVALID_CHAR_IN_FILTER = "INVALID_CHAR_IN_FILTER"; + public const System.String INVALID_CHAR_IN_DESCR = "INVALID_CHAR_IN_DESCR"; + public const System.String INVALID_ESC_IN_DESCR = "INVALID_ESC_IN_DESCR"; + public const System.String UNEXPECTED_END = "UNEXPECTED_END"; + public const System.String MISSING_LEFT_PAREN = "MISSING_LEFT_PAREN"; + public const System.String MISSING_RIGHT_PAREN = "MISSING_RIGHT_PAREN"; + public const System.String EXPECTING_RIGHT_PAREN = "EXPECTING_RIGHT_PAREN"; + public const System.String EXPECTING_LEFT_PAREN = "EXPECTING_LEFT_PAREN"; + public const System.String NO_OPTION = "NO_OPTION"; + public const System.String INVALID_FILTER_COMPARISON = "INVALID_FILTER_COMPARISON"; + public const System.String NO_MATCHING_RULE = "NO_MATCHING_RULE"; + public const System.String NO_ATTRIBUTE_NAME = "NO_ATTRIBUTE_NAME"; + public const System.String NO_DN_NOR_MATCHING_RULE = "NO_DN_NOR_MATCHING_RULE"; + public const System.String NOT_AN_ATTRIBUTE = "NOT_AN_ATTRIBUTE"; + public const System.String UNEQUAL_LENGTHS = "UNEQUAL_LENGTHS"; + public const System.String IMPROPER_REFERRAL = "IMPROPER_REFERRAL"; + public const System.String NOT_IMPLEMENTED = "NOT_IMPLEMENTED"; + public const System.String NO_MEMORY = "NO_MEMORY"; + public const System.String SERVER_SHUTDOWN_REQ = "SERVER_SHUTDOWN_REQ"; + public const System.String INVALID_ADDRESS = "INVALID_ADDRESS"; + public const System.String UNKNOWN_RESULT = "UNKNOWN_RESULT"; + public const System.String OUTSTANDING_OPERATIONS = "OUTSTANDING_OPERATIONS"; + public const System.String WRONG_FACTORY = "WRONG_FACTORY"; + public const System.String NO_TLS_FACTORY = "NO_TLS_FACTORY"; + public const System.String NO_STARTTLS = "NO_STARTTLS"; + public const System.String STOPTLS_ERROR = "STOPTLS_ERROR"; + public const System.String MULTIPLE_SCHEMA = "MULTIPLE_SCHEMA"; + public const System.String NO_SCHEMA = "NO_SCHEMA"; + public const System.String READ_MULTIPLE = "READ_MULTIPLE"; + public const System.String CANNOT_BIND = "CANNOT_BIND"; + + //End constants + + internal static readonly System.Object[][] contents = {new System.Object[]{"TOSTRING", "{0}: {1} ({2}) {3}"}, new System.Object[]{"SERVER_MSG", "{0}: Server Message: {1}"}, new System.Object[]{"MATCHED_DN", "{0}: Matched DN: {1}"}, new System.Object[]{"FAILED_REFERRAL", "{0}: Failed Referral: {1}"}, new System.Object[]{"REFERRAL_ITEM", "{0}: Referral: {1}"}, new System.Object[]{"CONNECTION_ERROR", "Unable to connect to server {0}:{1}"}, new System.Object[]{"CONNECTION_IMPOSSIBLE", "Unable to reconnect to server, application has never called connect()"}, new System.Object[]{"CONNECTION_WAIT", "Connection lost waiting for results from {0}:{1}"}, new System.Object[]{"CONNECTION_FINALIZED", "Connection closed by the application finalizing the object"}, new System.Object[]{"CONNECTION_CLOSED", "Connection closed by the application disconnecting"}, new System.Object[]{"CONNECTION_READER", "Reader thread terminated"}, new System.Object[]{"DUP_ERROR", "RfcLdapMessage: Cannot duplicate message built from the input stream"}, new System.Object[]{"REFERENCE_ERROR", "Error attempting to follow a search continuation reference"}, new System.Object[]{"REFERRAL_ERROR", "Error attempting to follow a referral"}, new System.Object[]{"REFERRAL_LOCAL", "LdapSearchResults.{0}(): No entry found & request is not complete"}, new System.Object[]{"REFERRAL_SEND", "Error sending request to referred server"}, new System.Object[]{"REFERENCE_NOFOLLOW", "Search result reference received, and referral following is off"}, new System.Object[]{"REFERRAL_BIND", "LdapBind.bind() function returned null"}, new System.Object[]{"REFERRAL_BIND_MATCH", "Could not match LdapBind.bind() connection with Server Referral URL list"}, new System.Object[]{"NO_DUP_REQUEST", "Cannot duplicate message to follow referral for {0} request, not allowed"}, new System.Object[]{"SERVER_CONNECT_ERROR", "Error connecting to server {0} while attempting to follow a referral"}, new System.Object[]{"NO_SUP_PROPERTY", "Requested property is not supported."}, new + System.Object[]{"ENTRY_PARAM_ERROR", "Invalid Entry parameter"}, new System.Object[]{"DN_PARAM_ERROR", "Invalid DN parameter"}, new System.Object[]{"RDN_PARAM_ERROR", "Invalid DN or RDN parameter"}, new System.Object[]{"OP_PARAM_ERROR", "Invalid extended operation parameter, no OID specified"}, new System.Object[]{"PARAM_ERROR", "Invalid parameter"}, new System.Object[]{"DECODING_ERROR", "Error Decoding responseValue"}, new System.Object[]{"ENCODING_ERROR", "Encoding Error"}, new System.Object[]{"IO_EXCEPTION", "I/O Exception on host {0}, port {1}"}, new System.Object[]{"INVALID_ESCAPE", "Invalid value in escape sequence \"{0}\""}, new System.Object[]{"SHORT_ESCAPE", "Incomplete escape sequence"}, new System.Object[]{"UNEXPECTED_END", "Unexpected end of filter"}, new System.Object[]{"MISSING_LEFT_PAREN", "Unmatched parentheses, left parenthesis missing"}, new System.Object[]{"NO_OPTION", "Semicolon present, but no option specified"}, new System.Object[]{"MISSING_RIGHT_PAREN", "Unmatched parentheses, right parenthesis missing"}, new System.Object[]{"EXPECTING_RIGHT_PAREN", "Expecting right parenthesis, found \"{0}\""}, new System.Object[]{"EXPECTING_LEFT_PAREN", "Expecting left parenthesis, found \"{0}\""}, new System.Object[]{"NO_ATTRIBUTE_NAME", "Missing attribute description"}, new System.Object[]{"NO_DN_NOR_MATCHING_RULE", "DN and matching rule not specified"}, new System.Object[]{"NO_MATCHING_RULE", "Missing matching rule"}, new System.Object[]{"INVALID_FILTER_COMPARISON", "Invalid comparison operator"}, new System.Object[]{"INVALID_CHAR_IN_FILTER", "The invalid character \"{0}\" needs to be escaped as \"{1}\""}, new System.Object[]{"INVALID_ESC_IN_DESCR", "Escape sequence not allowed in attribute description"}, new System.Object[]{"INVALID_CHAR_IN_DESCR", "Invalid character \"{0}\" in attribute description"}, new System.Object[]{"NOT_AN_ATTRIBUTE", "Schema element is not an LdapAttributeSchema object"}, new System.Object[]{"UNEQUAL_LENGTHS", + "Length of attribute Name array does not equal length of Flags array"}, new System.Object[]{"IMPROPER_REFERRAL", "Referral not supported for command {0}"}, new System.Object[]{"NOT_IMPLEMENTED", "Method LdapConnection.startTLS not implemented"}, new System.Object[]{"NO_MEMORY", "All results could not be stored in memory, sort failed"}, new System.Object[]{"SERVER_SHUTDOWN_REQ", "Received unsolicited notification from server {0}:{1} to shutdown"}, new System.Object[]{"INVALID_ADDRESS", "Invalid syntax for address with port; {0}"}, new System.Object[]{"UNKNOWN_RESULT", "Unknown Ldap result code {0}"}, new System.Object[]{"OUTSTANDING_OPERATIONS", "Cannot start or stop TLS because outstanding Ldap operations exist on this connection"}, new System.Object[]{"WRONG_FACTORY", "StartTLS cannot use the set socket factory because it does not implement LdapTLSSocketFactory"}, new System.Object[]{"NO_TLS_FACTORY", "StartTLS failed because no LdapTLSSocketFactory has been set for this Connection"}, new System.Object[]{"NO_STARTTLS", "An attempt to stopTLS on a connection where startTLS had not been called"}, new System.Object[]{"STOPTLS_ERROR", "Error stopping TLS: Error getting input & output streams from the original socket"}, new System.Object[]{"MULTIPLE_SCHEMA", "Multiple schema found when reading the subschemaSubentry for {0}"}, new System.Object[]{"NO_SCHEMA", "No schema found when reading the subschemaSubentry for {0}"}, new System.Object[]{"READ_MULTIPLE", "Read response is ambiguous, multiple entries returned"}, new System.Object[]{"CANNOT_BIND", "Cannot bind. Use PoolManager.getBoundConnection()"}}; + } //End ExceptionMessages +} diff --git a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/ExtResponseFactory.cs b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/ExtResponseFactory.cs new file mode 100755 index 00000000000..dfd668d6e91 --- /dev/null +++ b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/ExtResponseFactory.cs @@ -0,0 +1,117 @@ +/****************************************************************************** +* The MIT License +* Copyright (c) 2003 Novell Inc. www.novell.com +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the Software), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +*******************************************************************************/ +// +// Novell.Directory.Ldap.Utilclass.ExtResponseFactory.cs +// +// Author: +// Sunil Kumar (Sunilk@novell.com) +// +// (C) 2003 Novell, Inc (http://www.novell.com) +// + +using System; +using Novell.Directory.Ldap; +using Novell.Directory.Ldap.Extensions; +using Novell.Directory.Ldap.Rfc2251; + +namespace Novell.Directory.Ldap.Utilclass +{ + /// <summary> + /// Takes an LdapExtendedResponse and returns an object + /// (that implements the base class ParsedExtendedResponse) + /// based on the OID. + /// + /// <p>You can then call methods defined in the child + /// class to parse the contents of the response. The methods available + /// depend on the child class. All child classes inherit from the + /// ParsedExtendedResponse. + /// + /// </summary> + public class ExtResponseFactory + { + + /// <summary> Used to Convert an RfcLdapMessage object to the appropriate + /// LdapExtendedResponse object depending on the operation being performed. + /// + /// </summary> + /// <param name="inResponse"> The LdapExtendedReponse object as returned by the + /// extendedOperation method in the LdapConnection object. + /// <br><br> + /// </param> + /// <returns> An object of base class LdapExtendedResponse. The actual child + /// class of this returned object depends on the operation being + /// performed. + /// + /// </returns> + /// <exception cref=""> LdapException A general exception which includes an error message + /// and an Ldap error code. + /// </exception> + + static public LdapExtendedResponse convertToExtendedResponse(RfcLdapMessage inResponse) + { + + LdapExtendedResponse tempResponse = new LdapExtendedResponse(inResponse); + + // Get the oid stored in the Extended response + System.String inOID = tempResponse.ID; + + if ((System.Object) inOID == null) + return tempResponse; + // Is this an OID we support, if yes then build the + // detailed LdapExtendedResponse object + try + { + if (inOID.Equals(ReplicationConstants.NAMING_CONTEXT_COUNT_RES)) + { + return new PartitionEntryCountResponse(inResponse); + } + if (inOID.Equals(ReplicationConstants.GET_IDENTITY_NAME_RES)) + { + return new GetBindDNResponse(inResponse); + } + if (inOID.Equals(ReplicationConstants.GET_EFFECTIVE_PRIVILEGES_RES)) + { + return new GetEffectivePrivilegesResponse(inResponse); + } + if (inOID.Equals(ReplicationConstants.GET_REPLICA_INFO_RES)) + { + return new GetReplicaInfoResponse(inResponse); + } + if (inOID.Equals(ReplicationConstants.LIST_REPLICAS_RES)) + { + return new ListReplicasResponse(inResponse); + } + if (inOID.Equals(ReplicationConstants.GET_REPLICATION_FILTER_RES)) + { + return new GetReplicationFilterResponse(inResponse); + } + else + return tempResponse; + } + catch (System.IO.IOException ioe) + { + throw new LdapException(ExceptionMessages.DECODING_ERROR, LdapException.DECODING_ERROR, (System.String) null); + } + } + } +} diff --git a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/RDN.cs b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/RDN.cs new file mode 100755 index 00000000000..b3e780f9422 --- /dev/null +++ b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/RDN.cs @@ -0,0 +1,315 @@ +/****************************************************************************** +* The MIT License +* Copyright (c) 2003 Novell Inc. www.novell.com +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the Software), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +*******************************************************************************/ +// +// Novell.Directory.Ldap.Utilclass.RDN.cs +// +// Author: +// Sunil Kumar (Sunilk@novell.com) +// +// (C) 2003 Novell, Inc (http://www.novell.com) +// + +using System; + +namespace Novell.Directory.Ldap.Utilclass +{ + + /// <summary> <P>A RDN encapsulates a single object's name of a Distinguished Name(DN). + /// The object name represented by this class contains no context. Thus a + /// Relative Distinguished Name (RDN) could be relative to anywhere in the + /// Directories tree.</P> + /// + /// <P>For example, of following DN, 'cn=admin, ou=marketing, o=corporation', all + /// possible RDNs are 'cn=admin', 'ou=marketing', and 'o=corporation'.</P> + /// + /// <P>Multivalued attributes are encapsulated in this class. For example the + /// following could be represented by an RDN: 'cn=john + l=US', or + /// 'cn=juan + l=ES' </P> + /// + /// </summary> + /// <seealso cref="DN"> + /// </seealso> + + + public class RDN:System.Object + { + /// <summary> Returns the actually Raw String before Normalization + /// + /// </summary> + /// <returns> The raw string + /// </returns> + virtual protected internal System.String RawValue + { + get + { + return rawValue; + } + + } + /// <summary> Returns the type of this RDN. This method assumes that only one value + /// is used, If multivalues attributes are used only the first Type is + /// returned. Use GetTypes. + /// </summary> + /// <returns> Type of attribute + /// </returns> + virtual public System.String Type + { + get + { + return (System.String) types[0]; + } + + } + /// <summary> Returns all the types for this RDN.</summary> + /// <returns> list of types + /// </returns> + virtual public System.String[] Types + { + get + { + System.String[] toReturn = new System.String[types.Count]; + for (int i = 0; i < types.Count; i++) + toReturn[i] = ((System.String) types[i]); + return toReturn; + } + + } + /// <summary> Returns the values of this RDN. If multivalues attributes are used only + /// the first Type is returned. Use GetTypes. + /// + /// </summary> + /// <returns> Type of attribute + /// </returns> + virtual public System.String Value + { + get + { + return (System.String) values[0]; + } + + } + /// <summary> Returns all the types for this RDN.</summary> + /// <returns> list of types + /// </returns> + virtual public System.String[] Values + { + get + { + System.String[] toReturn = new System.String[values.Count]; + for (int i = 0; i < values.Count; i++) + toReturn[i] = ((System.String) values[i]); + return toReturn; + } + + } + /// <summary> Determines if this RDN is multivalued or not</summary> + /// <returns> true if this RDN is multivalued + /// </returns> + virtual public bool Multivalued + { + get + { + return (values.Count > 1)?true:false; + } + + } + private System.Collections.ArrayList types; //list of Type strings + private System.Collections.ArrayList values; //list of Value strings + private System.String rawValue; //the unnormalized value + + /// <summary> Creates an RDN object from the DN component specified in the string RDN + /// + /// </summary> + /// <param name="rdn">the DN component + /// </param> + public RDN(System.String rdn) + { + rawValue = rdn; + DN dn = new DN(rdn); + System.Collections.ArrayList rdns = dn.RDNs; + //there should only be one rdn + if (rdns.Count != 1) + throw new System.ArgumentException("Invalid RDN: see API " + "documentation"); + RDN thisRDN = (RDN) (rdns[0]); + this.types = thisRDN.types; + this.values = thisRDN.values; + this.rawValue = thisRDN.rawValue; + return ; + } + + public RDN() + { + types = new System.Collections.ArrayList(); + values = new System.Collections.ArrayList(); + rawValue = ""; + return ; + } + + /// <summary> Compares the RDN to the rdn passed. Note: If an there exist any + /// mulivalues in one RDN they must all be present in the other. + /// + /// </summary> + /// <param name="rdn">the RDN to compare to + /// + /// @throws IllegalArgumentException if the application compares a name + /// with an OID. + /// </param> + [CLSCompliantAttribute(false)] + public virtual bool equals(RDN rdn) + { + if (this.values.Count != rdn.values.Count) + { + return false; + } + int j, i; + for (i = 0; i < this.values.Count; i++) + { + //verify that the current value and type exists in the other list + j = 0; + //May need a more intellegent compare + while (j < values.Count && (!((System.String) this.values[i]).ToUpper().Equals(((System.String) rdn.values[j]).ToUpper()) || !equalAttrType((System.String) this.types[i], (System.String) rdn.types[j]))) + { + j++; + } + if (j >= rdn.values.Count) + //couldn't find first value + return false; + } + return true; + } + + /// <summary> Internal function used by equal to compare Attribute types. Because + /// attribute types could either be an OID or a name. There needs to be a + /// Translation mechanism. This function will absract this functionality. + /// + /// Currently if types differ (Oid and number) then UnsupportedOperation is + /// thrown, either one or the other must used. In the future an OID to name + /// translation can be used. + /// + /// + /// </summary> + private bool equalAttrType(System.String attr1, System.String attr2) + { + if (System.Char.IsDigit(attr1[0]) ^ System.Char.IsDigit(attr2[0])) + //isDigit tests if it is an OID + throw new System.ArgumentException("OID numbers are not " + "currently compared to attribute names"); + + return attr1.ToUpper().Equals(attr2.ToUpper()); + } + + /// <summary> Adds another value to the RDN. Only one attribute type is allowed for + /// the RDN. + /// </summary> + /// <param name="attrType">Attribute type, could be an OID or String + /// </param> + /// <param name="attrValue">Attribute Value, must be normalized and escaped + /// </param> + /// <param name="rawValue">or text before normalization, can be Null + /// </param> + public virtual void add(System.String attrType, System.String attrValue, System.String rawValue) + { + types.Add(attrType); + values.Add(attrValue); + this.rawValue += rawValue; + } + + /// <summary> Creates a string that represents this RDN, according to RFC 2253 + /// + /// </summary> + /// <returns> An RDN string + /// </returns> + public override System.String ToString() + { + return toString(false); + } + + /// <summary> Creates a string that represents this RDN. + /// + /// If noTypes is true then Atribute types will be ommited. + /// + /// </summary> + /// <param name="noTypes">true if attribute types will be omitted. + /// + /// </param> + /// <returns> An RDN string + /// </returns> + [CLSCompliantAttribute(false)] + public virtual System.String toString(bool noTypes) + { + int length = types.Count; + System.String toReturn = ""; + if (length < 1) + return null; + if (!noTypes) + { + toReturn = types[0] + "="; + } + toReturn += values[0]; + + for (int i = 1; i < length; i++) + { + toReturn += "+"; + if (!noTypes) + { + toReturn += (types[i] + "="); + } + toReturn += values[i]; + } + return toReturn; + } + + /// <summary> Returns each multivalued name in the current RDN as an array of Strings. + /// + /// </summary> + /// <param name="noTypes">Specifies whether Attribute types are included. The attribute + /// type names will be ommitted if the parameter noTypes is true. + /// + /// </param> + /// <returns> List of multivalued Attributes + /// </returns> + public virtual System.String[] explodeRDN(bool noTypes) + { + int length = types.Count; + if (length < 1) + return null; + System.String[] toReturn = new System.String[types.Count]; + + if (!noTypes) + { + toReturn[0] = types[0] + "="; + } + toReturn[0] += values[0]; + + for (int i = 1; i < length; i++) + { + if (!noTypes) + { + toReturn[i] += (types[i] + "="); + } + toReturn[i] += values[i]; + } + + return toReturn; + } + } //end class RDN +} diff --git a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/ReferralInfo.cs b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/ReferralInfo.cs new file mode 100755 index 00000000000..4cf83a69e46 --- /dev/null +++ b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/ReferralInfo.cs @@ -0,0 +1,104 @@ +/****************************************************************************** +* The MIT License +* Copyright (c) 2003 Novell Inc. www.novell.com +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the Software), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +*******************************************************************************/ +// +// Novell.Directory.Ldap.Utilclass.ReferralInfo.cs +// +// Author: +// Sunil Kumar (Sunilk@novell.com) +// +// (C) 2003 Novell, Inc (http://www.novell.com) +// + +using System; +using Novell.Directory.Ldap; +using LdapUrl = Novell.Directory.Ldap.LdapUrl; + +namespace Novell.Directory.Ldap.Utilclass +{ + + /// <summary> This class encapsulates the combination of LdapReferral URL and + /// the connection opened to service this URL + /// </summary> + public class ReferralInfo + { + /// <summary>Returns the referral URL + /// + /// </summary> + /// <returns> the Referral URL + /// </returns> + virtual public LdapUrl ReferralUrl + { + get + { + return referralUrl; + } + + } + /// <summary>Returns the referral Connection + /// + /// </summary> + /// <returns> the Referral Connection + /// </returns> + virtual public LdapConnection ReferralConnection + { + get + { + return conn; + } + + } + /// <summary>Returns the referral list + /// + /// </summary> + /// <returns> the Referral list + /// </returns> + virtual public System.String[] ReferralList + { + get + { + return referralList; + } + + } +// private DirectoryEntry conn; + private LdapConnection conn; + private LdapUrl referralUrl; + private System.String[] referralList; + + /// <summary> Construct the ReferralInfo class + /// + /// </summary> + /// <param name="lc">The DirectoryEntry opened to process this referral + /// + /// </param> + /// <param name="refUrl">The URL string associated with this connection + /// </param> + public ReferralInfo(LdapConnection lc, System.String[] refList, LdapUrl refUrl) + { + conn = lc; + referralUrl = refUrl; + referralList = refList; + return ; + } + } +} diff --git a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/ResourcesHandler.cs b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/ResourcesHandler.cs new file mode 100755 index 00000000000..b552576f51f --- /dev/null +++ b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/ResourcesHandler.cs @@ -0,0 +1,217 @@ +/****************************************************************************** +* The MIT License +* Copyright (c) 2003 Novell Inc. www.novell.com +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the Software), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +*******************************************************************************/ +// +// Novell.Directory.Ldap.Utilclass.ResourcesHandler.cs +// +// Author: +// Sunil Kumar (Sunilk@novell.com) +// +// (C) 2003 Novell, Inc (http://www.novell.com) +// + +using System; + +namespace Novell.Directory.Ldap.Utilclass +{ + + /// <summary> A utility class to get strings from the ExceptionMessages and + /// ResultCodeMessages resources. + /// </summary> + public class ResourcesHandler + { + // Cannot create an instance of this class + private ResourcesHandler() + { + return ; + } + + /* + * Initialized when the first result string is requested + */ + private static System.Resources.ResourceManager defaultResultCodes = null; + + /// <summary> Initialized when the first Exception message string is requested</summary> + private static System.Resources.ResourceManager defaultMessages = null; + + + /// <summary> Package where resources are found</summary> + private static System.String pkg = "Novell.Directory.Ldap.Utilclass."; + + /// <summary> The default Locale</summary> + private static System.Globalization.CultureInfo defaultLocale; + + /// <summary> Returns a string using the MessageOrKey as a key into + /// ExceptionMessages or, if the Key does not exist, returns the + /// string messageOrKey. In addition it formats the arguments into the message + /// according to MessageFormat. + /// + /// </summary> + /// <param name="messageOrKey"> Key string for the resource. + /// <br><br> + /// </param> + /// <param name="">arguments + /// + /// </param> + /// <returns> the text for the message specified by the MessageKey or the Key + /// if it there is no message for that key. + /// </returns> + public static System.String getMessage(System.String messageOrKey, System.Object[] arguments) + { + return getMessage(messageOrKey, arguments, null); + } + + /// <summary> Returns the message stored in the ExceptionMessages resource for the + /// specified locale using messageOrKey and argments passed into the + /// constructor. If no string exists in the resource then this returns + /// the string stored in message. (This method is identical to + /// getLdapErrorMessage(Locale locale).) + /// + /// </summary> + /// <param name="messageOrKey"> Key string for the resource. + /// <br><br> + /// </param> + /// <param name="">arguments + /// <br><br> + /// </param> + /// <param name="locale"> The Locale that should be used to pull message + /// strings out of ExceptionMessages. + /// + /// </param> + /// <returns> the text for the message specified by the MessageKey or the Key + /// if it there is no message for that key. + /// </returns> + public static System.String getMessage(System.String messageOrKey, System.Object[] arguments, System.Globalization.CultureInfo locale) + { + System.String pattern; + System.Resources.ResourceManager messages = null; + + if ((System.Object) messageOrKey == null) + { + messageOrKey = ""; + } + + try + { + if ((locale == null) || defaultLocale.Equals(locale)) + { + locale = defaultLocale; + // Default Locale + if (defaultMessages == null) + { + System.Threading.Thread.CurrentThread.CurrentUICulture = defaultLocale; + defaultMessages = System.Resources.ResourceManager.CreateFileBasedResourceManager(pkg + "ExceptionMessages", "", null); + } + messages = defaultMessages; + } + else + { + System.Threading.Thread.CurrentThread.CurrentUICulture = locale; + messages = System.Resources.ResourceManager.CreateFileBasedResourceManager(pkg + "ExceptionMessages", "", null); + } + pattern = messages.GetString(messageOrKey); + } + catch (System.Resources.MissingManifestResourceException mre) + { + pattern = messageOrKey; + } + + // Format the message if arguments were passed + if (arguments != null) + { +// MessageFormat mf = new MessageFormat(pattern); + pattern=System.String.Format(locale,pattern,arguments); +// mf.setLocale(locale); + //this needs to be reset with the new local - i18n defect in java +// mf.applyPattern(pattern); +// pattern = mf.format(arguments); + } + return pattern; + } + + /// <summary> Returns a string representing the Ldap result code from the + /// default ResultCodeMessages resource. + /// + /// </summary> + /// <param name="code"> the result code + /// <br><br> + /// </param> + /// <returns> the String representing the result code. + /// </returns> + public static System.String getResultString(int code) + { + return getResultString(code, null); + } + + /// <summary> Returns a string representing the Ldap result code. The message + /// is obtained from the locale specific ResultCodeMessage resource. + /// + /// </summary> + /// <param name="code"> the result code + /// <br><br> + /// </param> + /// <param name="locale"> The Locale that should be used to pull message + /// strings out of ResultMessages. + /// + /// </param> + /// <returns> the String representing the result code. + /// </returns> + public static System.String getResultString(int code, System.Globalization.CultureInfo locale) + { + System.Resources.ResourceManager messages; + System.String result; + try + { + if ((locale == null) || defaultLocale.Equals(locale)) + { + locale = defaultLocale; + // Default Locale + if (defaultResultCodes == null) + { + System.Threading.Thread.CurrentThread.CurrentUICulture = defaultLocale; + defaultResultCodes = System.Resources.ResourceManager.CreateFileBasedResourceManager(pkg + "ResultCodeMessages", "", null); + } + messages = defaultResultCodes; +// Console.WriteLine("Test Message.." + pkg + "ResultCodeMessages" ); + } + else + { + System.Threading.Thread.CurrentThread.CurrentUICulture = locale; + messages = System.Resources.ResourceManager.CreateFileBasedResourceManager(pkg + "ResultCodeMessages", "", null); + } +// result = messages.GetString(System.Convert.ToString(code)); + result = Convert.ToString(code); + } + catch (System.Resources.MissingManifestResourceException mre) + { + result = getMessage(ExceptionMessages.UNKNOWN_RESULT, new System.Object[]{code}, locale); + } + return result; + } + static ResourcesHandler() + { +// defaultLocale = System.Globalization.CultureInfo.CurrentCulture; + defaultLocale=new System.Globalization.CultureInfo("en-US"); + + } + } //end class ResourcesHandler +} diff --git a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/RespControlVector.cs b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/RespControlVector.cs new file mode 100755 index 00000000000..1732bd46d38 --- /dev/null +++ b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/RespControlVector.cs @@ -0,0 +1,124 @@ +/****************************************************************************** +* The MIT License +* Copyright (c) 2003 Novell Inc. www.novell.com +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the Software), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +*******************************************************************************/ +// +// Novell.Directory.Ldap.Utilclass.RespControlVector.cs +// +// Author: +// Sunil Kumar (Sunilk@novell.com) +// +// (C) 2003 Novell, Inc (http://www.novell.com) +// + +using System; + +namespace Novell.Directory.Ldap.Utilclass +{ + + /// <summary> The <code>MessageVector</code> class implements extends the + /// existing Vector class so that it can be used to maintain a + /// list of currently registered control responses. + /// </summary> + public class RespControlVector:System.Collections.ArrayList + { + public RespControlVector(int cap, int incr):base(cap) + { + return ; + } + + /// <summary>Inner class defined to create a temporary object to encapsulate + /// all registration information about a response control. This class + /// cannot be used outside this class + /// </summary> + private class RegisteredControl + { + private void InitBlock(RespControlVector enclosingInstance) + { + this.enclosingInstance = enclosingInstance; + } + private RespControlVector enclosingInstance; + public RespControlVector Enclosing_Instance + { + get + { + return enclosingInstance; + } + + } + public System.String myOID; + public System.Type myClass; + + public RegisteredControl(RespControlVector enclosingInstance, System.String oid, System.Type controlClass) + { + InitBlock(enclosingInstance); + myOID = oid; + myClass = controlClass; + } + } + + /* Adds a control to the current list of registered response controls. + * + */ + public void registerResponseControl(System.String oid, System.Type controlClass) + { + lock (this) + { + + Add(new RegisteredControl(this, oid, controlClass)); + } + } + + /* Searches the list of registered controls for a mathcing control. We + * search using the OID string. If a match is found we return the + * Class name that was provided to us on registration. + */ + public System.Type findResponseControl(System.String searchOID) + { + lock (this) + { + RegisteredControl ctl = null; + + /* loop through the contents of the vector */ + for (int i = 0; i < Count; i++) + { + + /* Get next registered control */ + if ((ctl = (RegisteredControl) ToArray()[i]) == null) + { + throw new System.FieldAccessException(); + } + + /* Does the stored OID match with whate we are looking for */ + if (ctl.myOID.CompareTo(searchOID) == 0) + { + + + /* Return the class name if we have match */ + return ctl.myClass; + } + } + /* The requested control does not have a registered response class */ + return null; + } + } + } +} diff --git a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/ResultCodeMessages.cs b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/ResultCodeMessages.cs new file mode 100755 index 00000000000..0db59a4a24a --- /dev/null +++ b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Utilclass/ResultCodeMessages.cs @@ -0,0 +1,50 @@ +/****************************************************************************** +* The MIT License +* Copyright (c) 2003 Novell Inc. www.novell.com +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the Software), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +*******************************************************************************/ +// +// Novell.Directory.Ldap.Utilclass.ResultCodeMessages.cs +// +// Author: +// Sunil Kumar (Sunilk@novell.com) +// +// (C) 2003 Novell, Inc (http://www.novell.com) +// + +using System; + +namespace Novell.Directory.Ldap.Utilclass +{ + + /// <summary> This class contains strings corresponding to Ldap Result Codes. + /// The resources are accessed by the String representation of the result code. + /// </summary> + + public class ResultCodeMessages:System.Resources.ResourceManager + { + public System.Object[][] getContents() + { + return contents; + } + internal static readonly System.Object[][] contents = {new System.Object[]{"0", "Success"}, new System.Object[]{"1", "Operations Error"}, new System.Object[]{"2", "Protocol Error"}, new System.Object[]{"3", "Timelimit Exceeded"}, new System.Object[]{"4", "Sizelimit Exceeded"}, new System.Object[]{"5", "Compare False"}, new System.Object[]{"6", "Compare True"}, new System.Object[]{"7", "Authentication Method Not Supported"}, new System.Object[]{"8", "Strong Authentication Required"}, new System.Object[]{"9", "Partial Results"}, new System.Object[]{"10", "Referral"}, new System.Object[]{"11", "Administrative Limit Exceeded"}, new System.Object[]{"12", "Unavailable Critical Extension"}, new System.Object[]{"13", "Confidentiality Required"}, new System.Object[]{"14", "SASL Bind In Progress"}, new System.Object[]{"16", "No Such Attribute"}, new System.Object[]{"17", "Undefined Attribute Type"}, new System.Object[]{"18", "Inappropriate Matching"}, new System.Object[]{"19", "Constraint Violation"}, new System.Object[]{"20", "Attribute Or Value Exists"}, new System.Object[]{"21", "Invalid Attribute Syntax"}, new System.Object[]{"32", "No Such Object"}, new System.Object[]{"33", "Alias Problem"}, new System.Object[]{"34", "Invalid DN Syntax"}, new System.Object[]{"35", "Is Leaf"}, new System.Object[]{"36", "Alias Dereferencing Problem"}, new System.Object[]{"48", "Inappropriate Authentication"}, new System.Object[]{"49", "Invalid Credentials"}, new System.Object[]{"50", "Insufficient Access Rights"}, new System.Object[]{"51", "Busy"}, new System.Object[]{"52", "Unavailable"}, new System.Object[]{"53", "Unwilling To Perform"}, new System.Object[]{"54", "Loop Detect"}, new System.Object[]{"64", "Naming Violation"}, new System.Object[]{"65", "Object Class Violation"}, new System.Object[]{"66", "Not Allowed On Non-leaf"}, new System.Object[]{"67", "Not Allowed On RDN"}, new System.Object[]{"68", "Entry Already Exists"}, new System.Object[]{"69", "Object Class Modifications Prohibited"}, new System.Object[]{"71", + "Affects Multiple DSAs"}, new System.Object[]{"80", "Other"}, new System.Object[]{"81", "Server Down"}, new System.Object[]{"82", "Local Error"}, new System.Object[]{"83", "Encoding Error"}, new System.Object[]{"84", "Decoding Error"}, new System.Object[]{"85", "Ldap Timeout"}, new System.Object[]{"86", "Authentication Unknown"}, new System.Object[]{"87", "Filter Error"}, new System.Object[]{"88", "User Cancelled"}, new System.Object[]{"89", "Parameter Error"}, new System.Object[]{"90", "No Memory"}, new System.Object[]{"91", "Connect Error"}, new System.Object[]{"92", "Ldap Not Supported"}, new System.Object[]{"93", "Control Not Found"}, new System.Object[]{"94", "No Results Returned"}, new System.Object[]{"95", "More Results To Return"}, new System.Object[]{"96", "Client Loop"}, new System.Object[]{"97", "Referral Limit Exceeded"}, new System.Object[]{"112", "TLS not supported"}}; + } //End ResultCodeMessages +} |