Exemple #1
0
        /// <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);
            }
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        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);
        }
Exemple #4
0
        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."
        }