Example #1
0
        internal override async Task <IntPtr> BindSimpleAsync(SafeHandle ld, string who, string password)
        {
            LdapConnect(ld);
            return(await Task.Factory.StartNew(() =>
            {
                var berval = new Native.berval
                {
                    bv_len = password.Length,
                    bv_val = Marshal.StringToHGlobalAnsi(password)
                };
                var ptr = Marshal.AllocHGlobal(Marshal.SizeOf(berval));
                Marshal.StructureToPtr(berval, ptr, false);
                var result = IntPtr.Zero;
                var msgidp = NativeMethodsWindows.ldap_simple_bind(ld, who, password);

                if (msgidp == -1)
                {
                    throw new LdapException($"{nameof(BindSimpleAsync)} failed. {nameof(NativeMethodsWindows.ldap_simple_bind)} returns wrong or empty result", nameof(NativeMethodsWindows.ldap_simple_bind), 1);
                }

                var rc = ldap_result(ld, msgidp, 0, IntPtr.Zero, ref result);

                if (rc == Native.LdapResultType.LDAP_ERROR || rc == Native.LdapResultType.LDAP_TIMEOUT)
                {
                    ThrowIfError((int)rc, nameof(NativeMethodsWindows.ldap_simple_bind));
                }

                return result;
            }).ConfigureAwait(false));
        }
Example #2
0
        private static int DecodingBerValOstringHelper(BerSafeHandle berElement, char fmt, out byte[] byteArray)
        {
            var result      = Marshal.AllocHGlobal(IntPtr.Size);
            var binaryValue = new Native.Native.berval();

            byteArray = null;

            var error = LdapNative.Instance.ber_scanf_ostring(berElement, new string(fmt, 1), result);

            try
            {
                if (error != -1 && result != IntPtr.Zero)
                {
                    Marshal.PtrToStructure(result, binaryValue);

                    byteArray = new byte[binaryValue.bv_len];
                    Marshal.Copy(binaryValue.bv_val, byteArray, 0, binaryValue.bv_len);
                }
            }
            finally
            {
                if (result != IntPtr.Zero)
                {
                    LdapNative.Instance.ber_memfree(result);
                }
            }

            return(error);
        }
Example #3
0
        private static int DecodingBerValByteArrayHelper(BerSafeHandle berElement, char fmt, out byte[] byteArray)
        {
            var result      = IntPtr.Zero;
            var binaryValue = new Native.Native.berval();

            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.
            var rc = LdapNative.Instance.ber_scanf_ptr(berElement, new string(fmt, 1), ref result);

            try
            {
                if (rc != -1 && result != IntPtr.Zero)
                {
                    Marshal.PtrToStructure(result, binaryValue);

                    byteArray = new byte[binaryValue.bv_len];
                    if (binaryValue.bv_val != IntPtr.Zero)
                    {
                        Marshal.Copy(binaryValue.bv_val, byteArray, 0, binaryValue.bv_len);
                    }
                }
            }
            finally
            {
                if (result != IntPtr.Zero)
                {
                    LdapNative.Instance.ber_bvfree(result);
                }
            }

            return(rc);
        }
Example #4
0
        internal override async Task <IntPtr> BindSimpleAsync(SafeHandle ld, string userDn, string password, LDAP_TIMEVAL timeout)
        {
            return(await Task.Factory.StartNew(() =>
            {
                var berval = new Native.berval
                {
                    bv_len = password.Length,
                    bv_val = Encoder.Instance.StringToPtr(password)
                };
                var ptr = Marshal.AllocHGlobal(Marshal.SizeOf(berval));
                Marshal.StructureToPtr(berval, ptr, false);
                var msgidp = 0;
                var result = IntPtr.Zero;
                NativeMethodsOsx.ldap_sasl_bind(ld, userDn, null, ptr, IntPtr.Zero, IntPtr.Zero, ref msgidp);
                Marshal.FreeHGlobal(ptr);
                if (msgidp == -1)
                {
                    throw new LdapException(
                        new LdapExceptionData($"{nameof(BindSimpleAsync)} failed. {nameof(NativeMethodsOsx.ldap_sasl_bind)} returns wrong or empty result",
                                              nameof(NativeMethodsOsx.ldap_sasl_bind), 1));
                }

                var rc = NativeMethodsOsx.ldap_result(ld, msgidp, 0, timeout, ref result);

                if (rc == Native.LdapResultType.LDAP_ERROR || rc == Native.LdapResultType.LDAP_TIMEOUT)
                {
                    ThrowIfError((int)rc, nameof(NativeMethodsOsx.ldap_sasl_bind));
                }

                return result;
            }).ConfigureAwait(false));
        }
Example #5
0
 private static IntPtr StringToBerVal(string value)
 {
     var berval = new Native.berval
     {
         bv_len = value.Length,
         bv_val = Encoder.Instance.StringToPtr(value)
     };
     var bervalPtr = Marshal.AllocHGlobal(Marshal.SizeOf(berval));
     Marshal.StructureToPtr(berval, bervalPtr, true);
     return bervalPtr;
 }
Example #6
0
        internal BerSafeHandle(Native.Native.berval value) : base(true)
        {
            var ptr = Marshal.AllocHGlobal(Marshal.SizeOf <Native.Native.berval>());

            try
            {
                Marshal.StructureToPtr(value, ptr, false);
                SetHandle(LdapNative.Instance.ber_init(ptr));
                if (handle == IntPtr.Zero)
                {
                    throw new LdapException("Could not initialized ber value");
                }
            }
            finally
            {
                Marshal.FreeHGlobal(ptr);
            }
        }
Example #7
0
        internal static object[] TryDecode(string format, byte[] value, out bool decodeSucceeded)
        {
            if (format == null)
            {
                throw new ArgumentNullException(nameof(format));
            }

            Debug.WriteLine("Begin decoding");

            if (!format.All(LdapNative.Instance.BerScanfSupports))
            {
                throw new ArgumentException($"{nameof(format)} has unsupported format characters");
            }

            var           berValue   = new Native.Native.berval();
            var           resultList = new ArrayList();
            BerSafeHandle berElement;

            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 BerSafeHandle(berValue);
            }
            finally
            {
                if (berValue.bv_val != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(berValue.bv_val);
                }
            }

            foreach (var fmt in format)
            {
                if (!DecodeActions.TryGetValue(fmt, out var decodeAction))
                {
                    throw new ArgumentException($"Format string contains unrecognized format character {fmt}");
                }

                var decodeFormat = decodeAction.UseFormat == char.MinValue ? fmt : decodeAction.UseFormat;

                if (decodeAction.Action(berElement, decodeFormat, out var result) == -1)
                {
                    Debug.WriteLine($"ber_scanf for {fmt} failed");

                    return(resultList.ToArray());
                }

                if (!decodeAction.Empty)
                {
                    resultList.Add(result);
                }
            }

            decodeSucceeded = true;
            return(resultList.ToArray());
        }
Example #8
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.
            byte[] encodingResult;
            // 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");

            // allocate the berelement
            var berElement = new BerSafeHandle();

            var valueCount = 0;

            for (var i = 0; i < format.Length; i++)
            {
                var fmt = format[i];
                if (!EncodeActions.TryGetValue(fmt, out var encodeAction))
                {
                    throw new ArgumentException("Format string contains undefined character: " + new string(fmt, 1));
                }

                fmt = encodeAction.UseFormat == char.MinValue ? fmt : encodeAction.UseFormat;
                if (encodeAction.Action(berElement, fmt, value, valueCount) == -1)
                {
                    Debug.WriteLine("ber_printf failed\n");
                    throw new LdapBerConversionException(new LdapExceptionData($"ber_printf failed. Format: {format}. Current char: {fmt} with index {i}"));
                }

                if (encodeAction.Next)
                {
                    valueCount++;
                }
            }

            // get the binary value back
            var berVal     = new Native.Native.berval();
            var 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.
                var rc = LdapNative.Instance.ber_flatten(berElement, ref flattenPtr);

                if (rc == -1)
                {
                    throw new LdapBerConversionException(new LdapExceptionData("ber_flatten failed"));
                }

                if (flattenPtr != IntPtr.Zero)
                {
                    Marshal.PtrToStructure(flattenPtr, berVal);
                }

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

                    Marshal.Copy(berVal.bv_val, encodingResult, 0, berVal.bv_len);
                }
            }
            finally
            {
                if (flattenPtr != IntPtr.Zero)
                {
                    LdapNative.Instance.ber_bvfree(flattenPtr);
                }
            }

            return(encodingResult);
        }