예제 #1
0
        private async Task DiscoverDevice()
        {
            var authStageInfo = await SecondaryAuthenticationFactorAuthentication.GetAuthenticationStageInfoAsync();

            if (authStageInfo.Stage != SecondaryAuthenticationFactorAuthenticationStage.CollectingCredential)
            {
                return;                                                                                               // Bad status!
            }
            findAuth = true;
            var deviceList = await SecondaryAuthenticationFactorRegistration.FindAllRegisteredDeviceInfoAsync(SecondaryAuthenticationFactorDeviceFindScope.User);

            var db          = new DatabaseContext();
            var devicesInDb = db.Devices.ToList();

            db.Dispose();
            IPDiscover.DiscoverIP();

            foreach (var device in deviceList)
            {
                var deviceInDb = devicesInDb.Find(d => d.DeviceId.ToString() == device.DeviceId);
                if (deviceInDb == null)
                {
                    continue;
                }
                var session = new DeviceAuthSession
                {
                    LastIP     = deviceInDb.LastConnectedHost,
                    MACAddress = deviceInDb.DeviceMacAddress,
                    DeviceID   = device.DeviceId,
                    DeviceInDb = deviceInDb
                };
                deviceSessions.Add(session);
            }
            while (findAuth)
            {
                foreach (var session in deviceSessions)
                {
                    switch (session.Status)
                    {
                    case DeviceStatus.NotConnected:
                        var payload = Convert.ToBase64String(Encoding.UTF8.GetBytes(session.DeviceID));
                        var data    = Encoding.UTF8.GetBytes(DeviceDiscoverPrefix + payload);
                        if (!string.IsNullOrWhiteSpace(session.LastIP))
                        {
                            try
                            {
                                UDPListener.Send(session.LastIP, data);
                            }
                            catch (Exception)
                            {
                                // ignored
                            }
                        }

                        var ips = session.FindIPs()?.ToList();
                        if ((ips == null || !ips.Any()) && string.IsNullOrWhiteSpace(session.MACAddress) && IPDiscover.IsDiscoveryCompleted)
                        {
                            session.Status = DeviceStatus.Unreachable;
                            continue;
                        }

                        if (ips != null)
                        {
                            foreach (var ip in ips)
                            {
                                try
                                {
                                    UDPListener.Send(ip, data);
                                }
                                catch (Exception)
                                {
                                    // ignored
                                }
                            }
                        }
                        await UDPListener.Send(UDPListener.DeviceMulticastGroupAddress, data);

                        break;

                    case DeviceStatus.Unreachable:
                        deviceSessions.Remove(session);
                        break;

                    case DeviceStatus.Established:
                        findAuth = false;
                        break;
                    }
                }
                Thread.Sleep(1000);
            }

            Auth(deviceSessions.FirstOrDefault(s => s.Status == DeviceStatus.Established));
            CurrentSession = null;
        }
예제 #2
0
        private async void Auth(DeviceAuthSession session)
        {
            if (session == null)
            {
                await SecondaryAuthenticationFactorAuthentication.ShowNotificationMessageAsync("",
                                                                                               SecondaryAuthenticationFactorAuthenticationMessage.Invalid);

                return;
            }

            var deviceInDb = session.DeviceInDb;
            await SecondaryAuthenticationFactorAuthentication.ShowNotificationMessageAsync(deviceInDb.DeviceFriendlyName,
                                                                                           SecondaryAuthenticationFactorAuthenticationMessage.ReadyToSignIn);

            IBuffer svcAuthNonce = CryptographicBuffer.GenerateRandom(256 / 8);

            SecondaryAuthenticationFactorAuthenticationResult authResult = await
                                                                           SecondaryAuthenticationFactorAuthentication.StartAuthenticationAsync(
                session.DeviceID,
                svcAuthNonce);

            if (authResult.Status != SecondaryAuthenticationFactorAuthenticationStatus.Started)
            {
                var message = SecondaryAuthenticationFactorAuthenticationMessage.Invalid;
                switch (authResult.Status)
                {
                case SecondaryAuthenticationFactorAuthenticationStatus.DisabledByPolicy:
                    message = SecondaryAuthenticationFactorAuthenticationMessage.DisabledByPolicy;
                    break;

                case SecondaryAuthenticationFactorAuthenticationStatus.InvalidAuthenticationStage:
                    break;

                default:
                    return;
                }
                await SecondaryAuthenticationFactorAuthentication.ShowNotificationMessageAsync(null, message);

                return;
            }

            var auth = authResult.Authentication;

            CurrentSession = session;
            for (int retries = 0; retries < 3; retries++)
            {
                var svcAuthHmac  = auth.ServiceAuthenticationHmac;
                var deviceNonce  = auth.DeviceNonce;
                var sessionNonce = auth.SessionNonce;
                var arr          = new byte[3 + svcAuthHmac.Length + deviceNonce.Length + sessionNonce.Length];
                arr[0] = (byte)svcAuthHmac.Length;
                arr[1] = (byte)deviceNonce.Length;
                arr[2] = (byte)sessionNonce.Length;
                Array.Copy(svcAuthHmac.ToArray(), 0, arr, 3, svcAuthHmac.Length);
                Array.Copy(deviceNonce.ToArray(), 0, arr, 3 + svcAuthHmac.Length, deviceNonce.Length);
                Array.Copy(sessionNonce.ToArray(), 0, arr, 3 + svcAuthHmac.Length + deviceNonce.Length, sessionNonce.Length);
                var payload = Convert.ToBase64String(arr);
                UDPListener.Send(session.LastIP, Encoding.UTF8.GetBytes(DeviceDiscoverPrefix + payload));

                AuthResultReceivedEvent = new ManualResetEvent(false);
                try
                {
                    AuthResultReceivedEvent.WaitOne(20000);
                }
                catch (Exception)
                {
                    // ignored
                }

                var result = session.ResultBytes;
                if (result == null || result.Length <= 2 || result.Length != 2 + result[0] + result[1])
                {
                    return;

                    /*await SecondaryAuthenticationFactorAuthentication.ShowNotificationMessageAsync("",
                     *  SecondaryAuthenticationFactorAuthenticationMessage.TryAgain);
                     * await auth.AbortAuthenticationAsync("No data got.");
                     * continue;*/
                }

                var deviceHmac  = new Buffer(result[0]);
                var sessionHmac = new Buffer(result[1]);
                result.CopyTo(2, deviceHmac, 0, result[0]);
                result.CopyTo(2 + result[0], sessionHmac, 0, result[1]);
                var status = await auth.FinishAuthenticationAsync(deviceHmac, sessionHmac);

                switch (status)
                {
                case SecondaryAuthenticationFactorFinishAuthenticationStatus.Completed:
                    // The credential data is collected and ready for unlock
                    CurrentSession = null;
                    return;

                default:
                    await SecondaryAuthenticationFactorAuthentication.ShowNotificationMessageAsync("",
                                                                                                   SecondaryAuthenticationFactorAuthenticationMessage.TryAgain);

                    break;
                }
            }
            await SecondaryAuthenticationFactorAuthentication.ShowNotificationMessageAsync(deviceInDb.DeviceFriendlyName,
                                                                                           SecondaryAuthenticationFactorAuthenticationMessage.UnauthorizedUser);

            CurrentSession = null;
        }