/// <summary> /// Calls the authentication callback handler. /// </summary> /// - /// <param name="e">An instance of <see cref="T:BluetoothAuthenticationEventArgs"/> /// containing the details of the authentication callback. /// </param> protected virtual void OnAuthentication(BluetoothAuthenticationEventArgs e) { EventHandler <BluetoothAuthenticationEventArgs> callback = m_userCallback; if (callback != null) { m_userCallback(this, e); } }
private int BluetoothSendAuthenticationResponseExOob(ref BLUETOOTH_DEVICE_INFO bdi, bool?confirm, BluetoothAuthenticationEventArgs e) { if (!confirm.HasValue) { return(NativeErrorSuccess); } int ret; BLUETOOTH_AUTHENTICATE_RESPONSE__OOB_DATA_INFO rsp = new BLUETOOTH_AUTHENTICATE_RESPONSE__OOB_DATA_INFO { negativeResponse = 1, // Default to NEGATIVE, really set below. authMethod = e.AuthenticationMethod }; if (!(e.AuthenticationMethod == BluetoothAuthenticationMethod.OutOfBand)) { Debug.Fail("Bad call!!! method is: " + e.AuthenticationMethod); return(NativeErrorNotAuthenticated); } rsp.bthAddressRemote = bdi.Address; switch (confirm) { case true: rsp.negativeResponse = 0; // Set the oob values // (Testing shows that P/Invoke disallowed only incorrect // lengthinline arrays, null arrays are ok). if (e.OobC != null) { rsp.oobInfo.C = e.OobC; } if (e.OobR != null) { rsp.oobInfo.R = e.OobR; } break; case false: case null: Debug.Assert(confirm != null, "Should have exited above when non-response."); rsp.negativeResponse = 1; break; } ret = NativeMethods.BluetoothSendAuthenticationResponseEx( m_radioHandle, ref rsp); return(ret); }
private int BluetoothSendAuthenticationResponseExNumCompPasskey(ref BLUETOOTH_DEVICE_INFO bdi, bool?confirm, BluetoothAuthenticationEventArgs e) { if (!confirm.HasValue) { return(NativeErrorSuccess); } int ret; BLUETOOTH_AUTHENTICATE_RESPONSE__NUMERIC_COMPARISON_PASSKEY_INFO rsp = new BLUETOOTH_AUTHENTICATE_RESPONSE__NUMERIC_COMPARISON_PASSKEY_INFO { negativeResponse = 1, // Default to NEGATIVE, really set below. authMethod = e.AuthenticationMethod }; if (!(e.AuthenticationMethod == BluetoothAuthenticationMethod.NumericComparison || e.AuthenticationMethod == BluetoothAuthenticationMethod.Passkey || e.AuthenticationMethod == BluetoothAuthenticationMethod.PasskeyNotification)) { Debug.Fail("Bad call!!! method is: " + e.AuthenticationMethod); return(NativeErrorNotAuthenticated); } rsp.bthAddressRemote = bdi.Address; switch (confirm) { case true: rsp.negativeResponse = 0; // Set the response number/passcode value if (e.ResponseNumberOrPasskey.HasValue) { rsp.numericComp_passkey = checked ((uint)e.ResponseNumberOrPasskey.Value); } break; case false: case null: Debug.Assert(confirm != null, "Should have exited above when non-response."); rsp.negativeResponse = 1; break; } ret = NativeMethods.BluetoothSendAuthenticationResponseEx( m_radioHandle, ref rsp); return(ret); }
private bool NativeCallback(BluetoothAuthenticationMethod method, IntPtr param, ref BLUETOOTH_DEVICE_INFO bdi, bool versionEx, ref BLUETOOTH_AUTHENTICATION_CALLBACK_PARAMS?pAuthCallbackParams) { System.Diagnostics.Debug.Assert(m_pin == null ^ m_userCallback == null); // System.Diagnostics.Debug.WriteLine(string.Format( System.Globalization.CultureInfo.InvariantCulture, "AuthenticateResponder callback (for {0}): 0x{1:X} 0x{2:X}", m_remoteAddress, param, bdi.Address)); // string pin; int ret; if (m_pin != null) { // Pre-specified case. System.Diagnostics.Debug.Assert(bdi.Address == m_remoteAddress, "Should only get callback for the single device."); //TODO if (bdi.Address != m_remoteAddress.ToInt64()) { // return false; //} pin = m_pin; if (versionEx) { // TODO Want to send a positive response here to NumericComparison?? ret = BluetoothSendAuthenticationResponseExPin(ref bdi, pin); } else { ret = NativeMethods.BluetoothSendAuthenticationResponse( m_radioHandle, ref bdi, pin); } } else if (method == BluetoothAuthenticationMethod.Legacy) { // Callback case. System.Diagnostics.Debug.Assert(m_userCallback != null); BluetoothAuthenticationEventArgs e = new BluetoothAuthenticationEventArgs(bdi); while (true) { // Callback the user code OnAuthentication(e); // Don't proceed if no (null) passcode given, or // if the last attempt was successful, or // the decvice has disppeared. if (e.Pin == null) { ret = NativeErrorSuccess; break; } if (e.PreviousNativeErrorCode == NativeErrorSuccess && e.AttemptNumber != 0) { Debug.Assert(e.CallbackWithResult, "NOT CbWR but here (A#)!!"); ret = NativeErrorSuccess; break; } if (e.PreviousNativeErrorCode == NativeErrorDeviceNotConnected) { Debug.Assert(e.CallbackWithResult, "NOT CbWR but here (DNC)!!"); // When I try this (against Win2k+Belkin and iPaq hx2190, // both apparently with Broadcom) I see: //[[ //Authenticate one device -- with wrong passcode here the first two times. //Passcode respectively: 'BAD-x', 'BAD-y', '9876' //Making PC discoverable //Hit Return to complete //Authenticating 0017E464CF1E wm_alan1 // Attempt# 0, Last error code 0 //Using '0.23672947484847' //Authenticating 0017E464CF1E wm_alan1 // Attempt# 1, Last error code 1244 //Using '0.54782851764365' //Authenticating 0017E464CF1E wm_alan1 // Attempt# 2, Last error code 1167 //Using '9876' //Authenticating 0017E464CF1E wm_alan1 // Attempt# 3, Last error code 1167 //etc //]] // That is we see the error code of 1244=ErrorNotAuthenticated // once, and then the peer device disappears (1167=ErrorDeviceNotConnected). // I suppose that's a security feature -- its stops an attacker // from trying again and again with different passcodes. // // Anyway the result of that is that is it NOT worth repeating // the callback after the device disappears. ret = NativeErrorSuccess; break; } pin = e.Pin; System.Diagnostics.Debug.WriteLine(string.Format(System.Globalization.CultureInfo.InvariantCulture, "BW32Auth SendAuthRsp pin {0}", pin)); if (versionEx) { ret = BluetoothSendAuthenticationResponseExPin(ref bdi, pin); } else { ret = NativeMethods.BluetoothSendAuthenticationResponse( m_radioHandle, ref bdi, pin); } if (ret != NativeErrorSuccess) { System.Diagnostics.Trace.WriteLine(string.Format( System.Globalization.CultureInfo.InvariantCulture, " BluetoothSendAuthenticationResponse failed: {0}=0x{0:X}", ret)); } // Have to callback the user code after the attempt? BluetoothAuthenticationEventArgs lastEa = e; if (!lastEa.CallbackWithResult) { break; } e = new BluetoothAuthenticationEventArgs(ret, lastEa); } } else if (method == BluetoothAuthenticationMethod.NumericComparison || method == BluetoothAuthenticationMethod.Passkey || method == BluetoothAuthenticationMethod.PasskeyNotification || method == BluetoothAuthenticationMethod.OutOfBand ) { // Callback case. System.Diagnostics.Debug.Assert(m_userCallback != null); BluetoothAuthenticationEventArgs e = new BluetoothAuthenticationEventArgs(bdi, ref pAuthCallbackParams); while (true) { // Callback the user code OnAuthentication(e); // Check if after e.CallbackWithResult... if (e.PreviousNativeErrorCode == NativeErrorSuccess && e.AttemptNumber != 0) { Debug.Assert(e.CallbackWithResult, "NOT CbWR but here (A#)!!"); ret = NativeErrorSuccess; break; } if (e.PreviousNativeErrorCode == NativeErrorDeviceNotConnected) { Debug.Assert(e.CallbackWithResult, "NOT CbWR but here (DNC)!!"); ret = NativeErrorSuccess; break; } bool?confirm = e.Confirm; System.Diagnostics.Debug.WriteLine(string.Format(System.Globalization.CultureInfo.InvariantCulture, "BW32Auth SendAuthRspEx-NumComparison {0}", confirm)); if (confirm == null) { ret = NativeErrorSuccess; break; } if (method != BluetoothAuthenticationMethod.OutOfBand) { ret = BluetoothSendAuthenticationResponseExNumCompPasskey(ref bdi, confirm, e); } else { ret = BluetoothSendAuthenticationResponseExOob(ref bdi, confirm, e); } if (ret != NativeErrorSuccess) { System.Diagnostics.Trace.WriteLine(string.Format( System.Globalization.CultureInfo.InvariantCulture, " BluetoothSendAuthenticationResponseEx failed: {0}=0x{0:X}", ret)); } // Have to callback the user code after the attempt? BluetoothAuthenticationEventArgs lastEa = e; if (!lastEa.CallbackWithResult) { break; } e = new BluetoothAuthenticationEventArgs(ret, lastEa); } } else { Debug.Fail("Unsupported auth method: " + method); ret = NativeErrorSuccess; } // if (ret != NativeErrorSuccess) { Trace.WriteLine(string.Format( System.Globalization.CultureInfo.InvariantCulture, "BluetoothSendAuthenticationResponse failed: {0}=0x{0:X}", ret)); } return(true); // "The return value from this function is ignored by the system." }