Пример #1
0
        private void ManagementSession_StateReported(object sender, StateReportedEventArgs e)
        {
            var    state = SessionStatusType.Error;
            string msg   = null;

            switch (e.State)
            {
            case OpenVPNStateType.Connecting:
                state = SessionStatusType.Connecting;
                msg   = Resources.Strings.OpenVPNStateTypeConnecting;
                break;

            case OpenVPNStateType.Resolving:
                state = SessionStatusType.Connecting;
                msg   = Resources.Strings.OpenVPNStateTypeResolving;
                break;

            case OpenVPNStateType.TcpConnecting:
                state = SessionStatusType.Connecting;
                msg   = Resources.Strings.OpenVPNStateTypeTcpConnecting;
                break;

            case OpenVPNStateType.Waiting:
                state = SessionStatusType.Connecting;
                msg   = Resources.Strings.OpenVPNStateTypeWaiting;
                break;

            case OpenVPNStateType.Authenticating:
                state = SessionStatusType.Connecting;
                msg   = Resources.Strings.OpenVPNStateTypeAuthenticating;
                break;

            case OpenVPNStateType.GettingConfiguration:
                state = SessionStatusType.Connecting;
                msg   = Resources.Strings.OpenVPNStateTypeGettingConfiguration;
                break;

            case OpenVPNStateType.AssigningIP:
                state = SessionStatusType.Connecting;
                msg   = Resources.Strings.OpenVPNStateTypeAssigningIP;
                break;

            case OpenVPNStateType.AddingRoutes:
                state = SessionStatusType.Connecting;
                msg   = Resources.Strings.OpenVPNStateTypeAddingRoutes;
                break;

            case OpenVPNStateType.Connected:
                state = SessionStatusType.Connected;
                msg   = Resources.Strings.OpenVPNStateTypeConnected;
                break;

            case OpenVPNStateType.Reconnecting:
                state = SessionStatusType.Connecting;
                msg   = Resources.Strings.OpenVPNStateTypeReconnecting;
                break;

            case OpenVPNStateType.Exiting:
                state = SessionStatusType.Disconnecting;
                msg   = Resources.Strings.OpenVPNStateTypeExiting;
                break;
            }
            if (!string.IsNullOrEmpty(e.Message))
            {
                if (msg != null)
                {
                    msg += "\r\n" + e.Message;
                }
                else
                {
                    msg = e.Message;
                }
            }
            else if (msg == null)
            {
                msg = "";
            }
            Wizard.TryInvoke((Action)(() =>
            {
                StateDescription = msg;
                TunnelAddress = e.Tunnel;
                IPv6TunnelAddress = e.IPv6Tunnel;
                ConnectedAt = e.State == OpenVPNStateType.Connected ? (DateTimeOffset?)e.TimeStamp : null;

                // Set State property last, as the whole world is listening on this property to monitor connectivity changes.
                // It is important that we have IP addresses and other info already set before rising PropertyChanged event for State.
                State = state;
            }));

            if (e.State == OpenVPNStateType.Reconnecting)
            {
                switch (e.Message)
                {
                case "connection-reset":     // Connection was reset.
                    if (ValidTo <= DateTimeOffset.Now)
                    {
                        // Client certificate expired. Try with a new client certificate then.
                        goto case "tls-error";
                    }
                    goto default;

                case "auth-failure":  // Client certificate was deleted/revoked on the server side, or the user is disabled.
                case "tls-error":     // Client certificate is not compliant with this eduVPN server. Was eduVPN server reinstalled?
                                      // Refresh configuration.
                    var config = ConnectingProfile.Connect(
                        Wizard.GetAuthenticatingServer(ConnectingProfile.Server),
                        true,
                        ProfileConfig.ContentType,
                        Window.Abort.Token);
                    Wizard.TryInvoke((Action)(() => ProfileConfig = config));
                    IgnoreHoldHint = true;
                    break;

                default:
                    IgnoreHoldHint = false;
                    break;
                }

                ManagementSession.QueueReleaseHold(Window.Abort.Token);
            }
        }
Пример #2
0
        /// <inheritdoc/>
        protected override void Run()
        {
            Wizard.TryInvoke((Action)(() => Wizard.TaskCount++));
            try
            {
                var propertyUpdater = new DispatcherTimer(
                    new TimeSpan(0, 0, 0, 1),
                    DispatcherPriority.Normal,
                    (object sender, EventArgs e) => _ShowLog?.RaiseCanExecuteChanged(),
                    Wizard.Dispatcher);
                propertyUpdater.Start();
                try
                {
retry:
                    // Connect to WireGuard Tunnel Manager Service to activate the tunnel.
                    using (var managerSession = new eduWireGuard.ManagerService.Session())
                    {
                        Wizard.TryInvoke((Action)(() => State = SessionStatusType.Connecting));
                        try
                        {
                            managerSession.Activate(
                                "eduWGManager" + Properties.Settings.Default.WireGuardTunnelManagerServiceInstance,
                                TunnelName,
                                ProfileConfig.Value,
                                3000,
                                Window.Abort.Token);
                        }
                        catch (OperationCanceledException) { throw; }
                        catch (Exception ex) { throw new AggregateException(Resources.Strings.ErrorWireGuardTunnelManagerService, ex); }

                        IPAddress tunnelAddress = null, ipv6TunnelAddress = null;
                        using (var reader = new StringReader(ProfileConfig.Value))
                        {
                            var iface = new eduWireGuard.Interface(reader);
                            foreach (var a in iface.Addresses)
                            {
                                switch (a.Address.AddressFamily)
                                {
                                case AddressFamily.InterNetwork:
                                    tunnelAddress = a.Address;
                                    break;

                                case AddressFamily.InterNetworkV6:
                                    ipv6TunnelAddress = a.Address;
                                    break;
                                }
                            }
                        }

                        RenewInProgress = new CancellationTokenSource();
                        Wizard.TryInvoke((Action)(() =>
                        {
                            _Renew?.RaiseCanExecuteChanged();
                            _Disconnect?.RaiseCanExecuteChanged();
                            Wizard.TaskCount--;
                            TunnelAddress = tunnelAddress;
                            IPv6TunnelAddress = ipv6TunnelAddress;
                            State = SessionStatusType.Connected;
                        }));

                        // Wait for a change and update stats.
                        var ct = CancellationTokenSource.CreateLinkedTokenSource(new CancellationToken[] {
                            DeactivateInProgress.Token,
                            RenewInProgress.Token,
                            Window.Abort.Token
                        });
                        do
                        {
                            try
                            {
                                var            cfg = managerSession.GetTunnelConfig(ct.Token);
                                ulong          rxBytes = 0, txBytes = 0;
                                DateTimeOffset lastHandshake = DateTimeOffset.MinValue;
                                foreach (var peer in cfg.Peers)
                                {
                                    rxBytes += peer.RxBytes;
                                    txBytes += peer.TxBytes;
                                    if (lastHandshake < peer.LastHandshake)
                                    {
                                        lastHandshake = peer.LastHandshake;
                                    }
                                }
                                Wizard.TryInvoke((Action)(() =>
                                {
                                    if (ConnectedAt == null && lastHandshake != DateTimeOffset.MinValue)
                                    {
                                        ConnectedAt = lastHandshake;
                                    }
                                    BytesIn = rxBytes;
                                    BytesOut = txBytes;
                                }));
                            }
                            catch
                            {
                                Wizard.TryInvoke((Action)(() => ConnectedAt = null));
                            }
                        } while (!ct.Token.WaitHandle.WaitOne(5 * 1000));
                        Wizard.TryInvoke((Action)(() =>
                        {
                            Wizard.TaskCount++;
                            State = SessionStatusType.Disconnecting;
                        }));
                        managerSession.Deactivate();
                        if (DeactivateInProgress.IsCancellationRequested || Window.Abort.IsCancellationRequested)
                        {
                            return;
                        }
                    }

                    // Reapply for a profile config.
                    ConnectingProfile.Server.ResetKeypair();
                    var config = ConnectingProfile.Connect(
                        Wizard.GetAuthenticatingServer(ConnectingProfile.Server),
                        true,
                        ProfileConfig.ContentType,
                        Window.Abort.Token);
                    Wizard.TryInvoke((Action)(() => ProfileConfig = config));
                    goto retry;
                }
                finally
                {
                    Wizard.TryInvoke((Action)(() =>
                    {
                        // Cleanup status properties.
                        TunnelAddress = null;
                        IPv6TunnelAddress = null;
                        ConnectedAt = null;
                        BytesIn = null;
                        BytesOut = null;
                    }));

                    propertyUpdater.Stop();
                }
            }
            finally { Wizard.TryInvoke((Action)(() => Wizard.TaskCount--)); }
        }