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)); }
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); }
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); }
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)); }
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; }
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); } }
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()); }
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); }