Esempio n. 1
0
 internal SafeBerHandle(BerVal value) : base(true)
 {
     SetHandle(Interop.Ldap.ber_init(value));
     if (handle == IntPtr.Zero)
     {
         throw new BerConversionException();
     }
 }
Esempio n. 2
0
        private static byte[][] DecodingMultiByteArrayHelper(SafeBerHandle berElement, char fmt, ref int error)
        {
            error = 0;
            // several BerVal
            IntPtr    ptrResult  = IntPtr.Zero;
            int       i          = 0;
            ArrayList binaryList = new ArrayList();
            IntPtr    tempPtr    = IntPtr.Zero;

            byte[][] result = null;

            try
            {
                error = BerPal.ScanNextPtr(berElement, new string(fmt, 1), ref ptrResult);

                if (!BerPal.IsBerDecodeError(error))
                {
                    if (ptrResult != IntPtr.Zero)
                    {
                        tempPtr = Marshal.ReadIntPtr(ptrResult);
                        while (tempPtr != IntPtr.Zero)
                        {
                            BerVal ber = new BerVal();
                            Marshal.PtrToStructure(tempPtr, ber);

                            byte[] berArray = new byte[ber.bv_len];
                            Marshal.Copy(ber.bv_val, berArray, 0, ber.bv_len);

                            binaryList.Add(berArray);

                            i++;
                            tempPtr = Marshal.ReadIntPtr(ptrResult, i * IntPtr.Size);
                        }

                        result = new byte[binaryList.Count][];
                        for (int j = 0; j < binaryList.Count; j++)
                        {
                            result[j] = (byte[])binaryList[j];
                        }
                    }
                }
                else
                {
                    Debug.WriteLine("ber_scanf for format character 'V' failed");
                }
            }
            finally
            {
                if (ptrResult != IntPtr.Zero)
                {
                    BerPal.FreeBervalArray(ptrResult);
                }
            }

            return(result);
        }
Esempio n. 3
0
 internal SafeBerHandle(BerVal value) : base(true)
 {
     // In Linux if bv_val is null ber_init will segFault instead of returning IntPtr.Zero.
     // In Linux if bv_len is 0 ber_init returns a valid pointer which will then fail when trying to use it,
     // so we fail early by throwing exception if this is the case.
     if (value.bv_val == IntPtr.Zero || value.bv_len == 0)
     {
         throw new BerConversionException();
     }
     SetHandle(Interop.Ldap.ber_init(value));
     if (handle == IntPtr.Zero)
     {
         throw new BerConversionException();
     }
 }
Esempio n. 4
0
        internal static int BindToDirectory(ConnectionHandle ld, string who, string passwd)
        {
            IntPtr passwordPtr = IntPtr.Zero;

            try
            {
                passwordPtr = LdapPal.StringToPtr(passwd);
                BerVal passwordBerval = new BerVal
                {
                    bv_len = passwd?.Length ?? 0,
                    bv_val = passwordPtr,
                };

                return(Interop.Ldap.ldap_sasl_bind(ld, who, Interop.LDAP_SASL_SIMPLE, passwordBerval, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero));
            }
            finally
            {
                Marshal.FreeHGlobal(passwordPtr);
            }
        }
Esempio n. 5
0
        private static byte[] DecodingByteArrayHelper(SafeBerHandle berElement, char fmt, ref int error)
        {
            error = 0;
            IntPtr result      = IntPtr.Zero;
            BerVal binaryValue = new BerVal();

            byte[] byteArray = null;

            // can't use SafeBerval here as CLR creates a SafeBerval which points to a different memory location, but when doing memory
            // deallocation, wldap has special check. So have to use IntPtr directly here.
            error = BerPal.ScanNextPtr(berElement, new string(fmt, 1), ref result);

            try
            {
                if (!BerPal.IsBerDecodeError(error))
                {
                    if (result != IntPtr.Zero)
                    {
                        Marshal.PtrToStructure(result, binaryValue);

                        byteArray = new byte[binaryValue.bv_len];
                        Marshal.Copy(binaryValue.bv_val, byteArray, 0, binaryValue.bv_len);
                    }
                }
                else
                {
                    Debug.WriteLine("ber_scanf for format character 'O' failed");
                }
            }
            finally
            {
                if (result != IntPtr.Zero)
                {
                    BerPal.FreeBerval(result);
                }
            }

            return(byteArray);
        }
Esempio n. 6
0
 public PinningMarshaller(BerVal managed)
 {
     _managed = managed;
 }
Esempio n. 7
0
 internal static int ExtendedDirectoryOperation(ConnectionHandle ldapHandle, string oid, BerVal data, IntPtr servercontrol, IntPtr clientcontrol, ref int messageNumber) =>
 Interop.Ldap.ldap_extended_operation(ldapHandle, oid, data, servercontrol, clientcontrol, ref messageNumber);
Esempio n. 8
0
 internal static int CompareDirectoryEntries(ConnectionHandle ldapHandle, string dn, string attributeName, string strValue, BerVal binaryValue, IntPtr servercontrol, IntPtr clientcontrol, ref int messageNumber) =>
 Interop.Ldap.ldap_compare(ldapHandle, dn, attributeName, binaryValue, servercontrol, clientcontrol, ref messageNumber);
Esempio n. 9
0
 // All usages in our currently supported scenarios will always go through GetPinnableReference
 public static int *ConvertToUnmanaged(BerVal managed) => throw new UnreachableException();
Esempio n. 10
0
 public static ref int GetPinnableReference(BerVal managed) => ref (managed is null ? ref Unsafe.NullRef <int>() : ref managed.bv_len);
Esempio n. 11
0
        private static int EncodingMultiByteArrayHelper(SafeBerHandle berElement, byte[][] tempValue, char fmt, nuint tag)
        {
            IntPtr berValArray = IntPtr.Zero;
            IntPtr tempPtr;

            BerVal[] managedBervalArray = null;
            int      error = 0;

            try
            {
                if (tempValue != null)
                {
                    int i = 0;
                    berValArray = Utility.AllocHGlobalIntPtrArray(tempValue.Length + 1);
                    int structSize = Marshal.SizeOf(typeof(BerVal));
                    managedBervalArray = new BerVal[tempValue.Length];

                    for (i = 0; i < tempValue.Length; i++)
                    {
                        byte[] byteArray = tempValue[i];

                        // construct the managed BerVal
                        managedBervalArray[i] = new BerVal();

                        if (byteArray != null)
                        {
                            managedBervalArray[i].bv_len = byteArray.Length;
                            managedBervalArray[i].bv_val = Marshal.AllocHGlobal(byteArray.Length);
                            Marshal.Copy(byteArray, 0, managedBervalArray[i].bv_val, byteArray.Length);
                        }

                        // allocate memory for the unmanaged structure
                        IntPtr valPtr = Marshal.AllocHGlobal(structSize);
                        Marshal.StructureToPtr(managedBervalArray[i], valPtr, false);

                        tempPtr = (IntPtr)((long)berValArray + IntPtr.Size * i);
                        Marshal.WriteIntPtr(tempPtr, valPtr);
                    }

                    tempPtr = (IntPtr)((long)berValArray + IntPtr.Size * i);
                    Marshal.WriteIntPtr(tempPtr, IntPtr.Zero);
                }

                error = BerPal.PrintBerArray(berElement, new string(fmt, 1), berValArray, tag);
            }
            finally
            {
                if (berValArray != IntPtr.Zero)
                {
                    for (int i = 0; i < tempValue.Length; i++)
                    {
                        IntPtr ptr = Marshal.ReadIntPtr(berValArray, IntPtr.Size * i);
                        if (ptr != IntPtr.Zero)
                        {
                            Marshal.FreeHGlobal(ptr);
                        }
                    }
                    Marshal.FreeHGlobal(berValArray);
                }
                if (managedBervalArray != null)
                {
                    foreach (BerVal managedBerval in managedBervalArray)
                    {
                        if (managedBerval.bv_val != IntPtr.Zero)
                        {
                            Marshal.FreeHGlobal(managedBerval.bv_val);
                        }
                    }
                }
            }

            return(error);
        }
Esempio n. 12
0
        internal static object[] TryDecode(string format, byte[] value, out bool decodeSucceeded)
        {
            if (format == null)
            {
                throw new ArgumentNullException(nameof(format));
            }

            Debug.WriteLine("Begin decoding");

            UTF8Encoding  utf8Encoder = new UTF8Encoding(false, true);
            BerVal        berValue    = new BerVal();
            ArrayList     resultList  = new ArrayList();
            SafeBerHandle berElement  = null;

            object[] decodeResult = null;
            decodeSucceeded = false;

            if (value == null)
            {
                berValue.bv_len = 0;
                berValue.bv_val = IntPtr.Zero;
            }
            else
            {
                berValue.bv_len = value.Length;
                berValue.bv_val = Marshal.AllocHGlobal(value.Length);
                Marshal.Copy(value, 0, berValue.bv_val, value.Length);
            }

            try
            {
                berElement = new SafeBerHandle(berValue);
            }
            finally
            {
                if (berValue.bv_val != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(berValue.bv_val);
                }
            }

            int error;

            for (int formatCount = 0; formatCount < format.Length; formatCount++)
            {
                char fmt = format[formatCount];
                if (fmt == '{' || fmt == '}' || fmt == '[' || fmt == ']' || fmt == 'n' || fmt == 'x')
                {
                    error = BerPal.ScanNext(berElement, new string(fmt, 1));

                    if (BerPal.IsBerDecodeError(error))
                    {
                        Debug.WriteLine("ber_scanf for {, }, [, ], n or x failed");
                    }
                }
                else if (fmt == 'i' || fmt == 'e' || fmt == 'b')
                {
                    int result = 0;
                    error = BerPal.ScanNextInt(berElement, new string(fmt, 1), ref result);

                    if (!BerPal.IsBerDecodeError(error))
                    {
                        if (fmt == 'b')
                        {
                            // should return a bool
                            bool boolResult;
                            if (result == 0)
                            {
                                boolResult = false;
                            }
                            else
                            {
                                boolResult = true;
                            }
                            resultList.Add(boolResult);
                        }
                        else
                        {
                            resultList.Add(result);
                        }
                    }
                    else
                    {
                        Debug.WriteLine("ber_scanf for format character 'i', 'e' or 'b' failed");
                    }
                }
                else if (fmt == 'a')
                {
                    // return a string
                    byte[] byteArray = DecodingByteArrayHelper(berElement, 'O', out error);
                    if (!BerPal.IsBerDecodeError(error))
                    {
                        string s = null;
                        if (byteArray != null)
                        {
                            s = utf8Encoder.GetString(byteArray);
                        }

                        resultList.Add(s);
                    }
                }
                else if (fmt == 'O')
                {
                    // return BerVal
                    byte[] byteArray = DecodingByteArrayHelper(berElement, fmt, out error);
                    if (!BerPal.IsBerDecodeError(error))
                    {
                        // add result to the list
                        resultList.Add(byteArray);
                    }
                }
                else if (fmt == 'B')
                {
                    error = DecodeBitStringHelper(resultList, berElement);
                }
                else if (fmt == 'v')
                {
                    //null terminate strings
                    byte[][] byteArrayresult;
                    string[] stringArray = null;

                    byteArrayresult = DecodingMultiByteArrayHelper(berElement, 'V', out error);
                    if (!BerPal.IsBerDecodeError(error))
                    {
                        if (byteArrayresult != null)
                        {
                            stringArray = new string[byteArrayresult.Length];
                            for (int i = 0; i < byteArrayresult.Length; i++)
                            {
                                if (byteArrayresult[i] == null)
                                {
                                    stringArray[i] = null;
                                }
                                else
                                {
                                    stringArray[i] = utf8Encoder.GetString(byteArrayresult[i]);
                                }
                            }
                        }

                        resultList.Add(stringArray);
                    }
                }
                else if (fmt == 'V')
                {
                    byte[][] result;

                    result = DecodingMultiByteArrayHelper(berElement, fmt, out error);
                    if (!BerPal.IsBerDecodeError(error))
                    {
                        resultList.Add(result);
                    }
                }
                else
                {
                    Debug.WriteLine("Format string contains undefined character\n");
                    throw new ArgumentException(SR.BerConverterUndefineChar);
                }

                if (BerPal.IsBerDecodeError(error))
                {
                    // decode failed, just return
                    return(decodeResult);
                }
            }

            decodeResult = new object[resultList.Count];
            for (int count = 0; count < resultList.Count; count++)
            {
                decodeResult[count] = resultList[count];
            }

            decodeSucceeded = true;
            return(decodeResult);
        }
Esempio n. 13
0
        public static byte[] Encode(string format, params object[] value)
        {
            if (format == null)
            {
                throw new ArgumentNullException(nameof(format));
            }

            // no need to turn on invalid encoding detection as we just do string->byte[] conversion.
            UTF8Encoding utf8Encoder = new UTF8Encoding();

            byte[] encodingResult = null;
            // value is allowed to be null in certain scenario, so if it is null, just set it to empty array.
            if (value == null)
            {
                value = Array.Empty <object>();
            }

            Debug.WriteLine("Begin encoding\n");

            // allocate the berelement
            SafeBerHandle berElement = new SafeBerHandle();

            int valueCount = 0;
            int error      = 0;

            // We can't use vararg on Unix and can't do ber_printf(tag), so we use ber_put_int(val, tag)
            // and this local keeps tag value for the next element.
            nuint tag      = 0;
            bool  tagIsSet = false;

            for (int formatCount = 0; formatCount < format.Length; formatCount++)
            {
                if (tagIsSet)
                {
                    tagIsSet = false;
                }
                else
                {
                    int   lberTagDefaultInt   = -1;
                    nuint lberTagDefaultNuint = (nuint)lberTagDefaultInt;
                    tag = lberTagDefaultNuint;
                }
                char fmt = format[formatCount];
                if (fmt == '{' || fmt == '}' || fmt == '[' || fmt == ']' || fmt == 'n')
                {
                    // no argument needed
                    error = BerPal.PrintEmptyArgument(berElement, new string(fmt, 1), tag);
                }
                else if (fmt == 'i' || fmt == 'e')
                {
                    if (valueCount >= value.Length)
                    {
                        // we don't have enough argument for the format string
                        Debug.WriteLine("value argument is not valid, valueCount >= value.Length\n");
                        throw new ArgumentException(SR.BerConverterNotMatch);
                    }

                    if (!(value[valueCount] is int))
                    {
                        // argument is wrong
                        Debug.WriteLine("type should be int\n");
                        throw new ArgumentException(SR.BerConverterNotMatch);
                    }

                    // one int argument
                    error = BerPal.PrintInt(berElement, new string(fmt, 1), (int)value[valueCount], tag);

                    // increase the value count
                    valueCount++;
                }
                else if (fmt == 'b')
                {
                    if (valueCount >= value.Length)
                    {
                        // we don't have enough argument for the format string
                        Debug.WriteLine("value argument is not valid, valueCount >= value.Length\n");
                        throw new ArgumentException(SR.BerConverterNotMatch);
                    }

                    if (!(value[valueCount] is bool))
                    {
                        // argument is wrong
                        Debug.WriteLine("type should be boolean\n");
                        throw new ArgumentException(SR.BerConverterNotMatch);
                    }

                    // one int argument
                    error = BerPal.PrintInt(berElement, new string(fmt, 1), (bool)value[valueCount] ? 1 : 0, tag);

                    // increase the value count
                    valueCount++;
                }
                else if (fmt == 's')
                {
                    if (valueCount >= value.Length)
                    {
                        // we don't have enough argument for the format string
                        Debug.WriteLine("value argument is not valid, valueCount >= value.Length\n");
                        throw new ArgumentException(SR.BerConverterNotMatch);
                    }

                    if (value[valueCount] != null && !(value[valueCount] is string))
                    {
                        // argument is wrong
                        Debug.WriteLine("type should be string, but receiving value has type of ");
                        Debug.WriteLine(value[valueCount].GetType());
                        throw new ArgumentException(SR.BerConverterNotMatch);
                    }

                    // one string argument
                    byte[] tempValue = null;
                    if (value[valueCount] != null)
                    {
                        tempValue = utf8Encoder.GetBytes((string)value[valueCount]);
                    }
                    error = EncodingByteArrayHelper(berElement, tempValue, 'o', tag);

                    // increase the value count
                    valueCount++;
                }
                else if (fmt == 'o' || fmt == 'X')
                {
                    // we need to have one arguments
                    if (valueCount >= value.Length)
                    {
                        // we don't have enough argument for the format string
                        Debug.WriteLine("value argument is not valid, valueCount >= value.Length\n");
                        throw new ArgumentException(SR.BerConverterNotMatch);
                    }

                    if (value[valueCount] != null && !(value[valueCount] is byte[]))
                    {
                        // argument is wrong
                        Debug.WriteLine("type should be byte[], but receiving value has type of ");
                        Debug.WriteLine(value[valueCount].GetType());
                        throw new ArgumentException(SR.BerConverterNotMatch);
                    }

                    byte[] tempValue = (byte[])value[valueCount];
                    error = EncodingByteArrayHelper(berElement, tempValue, fmt, tag);

                    valueCount++;
                }
                else if (fmt == 'v')
                {
                    // we need to have one arguments
                    if (valueCount >= value.Length)
                    {
                        // we don't have enough argument for the format string
                        Debug.WriteLine("value argument is not valid, valueCount >= value.Length\n");
                        throw new ArgumentException(SR.BerConverterNotMatch);
                    }

                    if (value[valueCount] != null && !(value[valueCount] is string[]))
                    {
                        // argument is wrong
                        Debug.WriteLine("type should be string[], but receiving value has type of ");
                        Debug.WriteLine(value[valueCount].GetType());
                        throw new ArgumentException(SR.BerConverterNotMatch);
                    }

                    string[] stringValues = (string[])value[valueCount];
                    byte[][] tempValues;
                    if (stringValues != null)
                    {
                        tempValues = new byte[stringValues.Length][];
                        for (int i = 0; i < stringValues.Length; i++)
                        {
                            string s = stringValues[i];
                            if (s == null)
                            {
                                tempValues[i] = null;
                            }
                            else
                            {
                                tempValues[i] = utf8Encoder.GetBytes(s);
                            }
                            error = EncodingByteArrayHelper(berElement, tempValues[i], 'o', tag);
                            if (error == -1)
                            {
                                break;
                            }
                        }
                    }
                    valueCount++;
                }
                else if (fmt == 'V')
                {
                    // we need to have one arguments
                    if (valueCount >= value.Length)
                    {
                        // we don't have enough argument for the format string
                        Debug.WriteLine("value argument is not valid, valueCount >= value.Length\n");
                        throw new ArgumentException(SR.BerConverterNotMatch);
                    }

                    if (value[valueCount] != null && !(value[valueCount] is byte[][]))
                    {
                        // argument is wrong
                        Debug.WriteLine("type should be byte[][], but receiving value has type of ");
                        Debug.WriteLine(value[valueCount].GetType());
                        throw new ArgumentException(SR.BerConverterNotMatch);
                    }

                    byte[][] tempValue = (byte[][])value[valueCount];

                    error = EncodingMultiByteArrayHelper(berElement, tempValue, fmt, tag);

                    valueCount++;
                }
                else if (fmt == 't')
                {
                    if (valueCount >= value.Length)
                    {
                        // we don't have enough argument for the format string
                        Debug.WriteLine("value argument is not valid, valueCount >= value.Length\n");
                        throw new ArgumentException(SR.BerConverterNotMatch);
                    }

                    if (!(value[valueCount] is int))
                    {
                        // argument is wrong
                        Debug.WriteLine("type should be int\n");
                        throw new ArgumentException(SR.BerConverterNotMatch);
                    }
                    tag      = (uint)(int)value[valueCount];
                    tagIsSet = true;
                    // It will set the tag on Windows and only check the tag on Unix.
                    error = BerPal.PrintTag(berElement, new string(fmt, 1), tag);

                    // increase the value count
                    valueCount++;
                }
                else
                {
                    Debug.WriteLine("Format string contains undefined character: ");
                    Debug.WriteLine(new string(fmt, 1));
                    throw new ArgumentException(SR.BerConverterUndefineChar);
                }

                // process the return value
                if (error == -1)
                {
                    Debug.WriteLine("ber_printf failed\n");
                    throw new BerConversionException();
                }
            }

            // get the binary value back
            BerVal binaryValue = new BerVal();
            IntPtr flattenptr  = IntPtr.Zero;

            try
            {
                // can't use SafeBerval here as CLR creates a SafeBerval which points to a different memory location, but when doing memory
                // deallocation, wldap has special check. So have to use IntPtr directly here.
                error = BerPal.FlattenBerElement(berElement, ref flattenptr);

                if (error == -1)
                {
                    Debug.WriteLine("ber_flatten failed\n");
                    throw new BerConversionException();
                }

                if (flattenptr != IntPtr.Zero)
                {
                    Marshal.PtrToStructure(flattenptr, binaryValue);
                }

                if (binaryValue == null || binaryValue.bv_len == 0)
                {
                    encodingResult = Array.Empty <byte>();
                }
                else
                {
                    encodingResult = new byte[binaryValue.bv_len];

                    Marshal.Copy(binaryValue.bv_val, encodingResult, 0, binaryValue.bv_len);
                }
            }
            finally
            {
                if (flattenptr != IntPtr.Zero)
                {
                    BerPal.FreeBerval(flattenptr);
                }
            }

            return(encodingResult);
        }