private void addCredentialButton_Click(object sender, RoutedEventArgs e)
        {
            try {
                ListView listView = this.credentialListView;

                // create a new CredentialSettings
                CredentialSettings newItem = new CredentialSettings();
                // set its default persistence to Process (i.e. not persistent)
                // The default value reverted because it was confusing.
//				newItem.Persistence = CredentialPersistence.Process;

                // prepare a validator
                CredentialSettings[] items = listView.Items.Cast <CredentialSettings>().ToArray();
                Func <CredentialSettings, string> validator = (s) => {
                    // check whether there is no credential which is for the same end point
                    CredentialSettings conflicting = items.Where(item => s.HasSameEndPoint(item)).FirstOrDefault();
                    return((conflicting == null) ? null : string.Format(Properties.Resources.SettingsWindow_Message_ConflictingCredential, s.EndPoint));
                };

                // edit the CredentialSettings
                CredentialDialog dialog = new CredentialDialog(newItem, validator, endPointEditable: true);
                dialog.Owner = this;
                if (dialog.ShowDialog() ?? false)
                {
                    // add the CredentialSettings
                    AddListItem(listView, dialog.CredentialSettings);
                }
            } catch (Exception exception) {
                ShowErrorDialog(exception.Message);
            }

            return;
        }
Example #2
0
            /// <summary>
            /// </summary>
            /// <remarks>
            /// GetCredential() call may cause user interaction such as showing a Credential Dialog.
            /// So its call should be synchronized by locking this.getCredentialLocker
            /// not to show multiple user interactions at a time.
            /// </remarks>
            CredentialSettings IProxyRunner.GetCredential(string endPoint, string realm, bool needUpdate)
            {
                // argument checks
                if (endPoint == null)
                {
                    throw new ArgumentNullException(nameof(endPoint));
                }
                if (realm == null)
                {
                    realm = string.Empty;
                }

                CredentialSettings credential = null;

                lock (this.getCredentialLocker) {
                    // state checks
                    IDictionary <string, CredentialSettings> dictionary;
                    lock (this.credentialsLocker) {
                        dictionary = this.dictionary;
                        if (dictionary == null)
                        {
                            throw new ObjectDisposedException(nameof(RunningProxyState));
                        }

                        if (needUpdate == false)
                        {
                            // try to find the credential for the end point
                            if (dictionary.TryGetValue(endPoint, out credential) == false)
                            {
                                // try to find the credential for the "wildcard"
                                if (dictionary.TryGetValue(string.Empty, out credential) == false)
                                {
                                    needUpdate = true;
                                }
                            }
                        }
                    }

                    // update the credential if necessary
                    if (needUpdate)
                    {
                        credential = this.Owner.UpdateCredential(endPoint, realm, credential);
                        if (credential != null)
                        {
                            SetCredential(credential);
                        }
                    }
                    else
                    {
                        Debug.Assert(credential != null);
                    }
                }

                // return the clone of the credential not to be changed
                return(CloneSettings(credential));
            }
Example #3
0
        protected override CredentialSettings UpdateCredential(string endPoint, string realm, CredentialSettings oldCredential)
        {
            // argument checks
            Debug.Assert(endPoint != null);
            Debug.Assert(realm != null);                // may be empty
            // oldCredential can be null

            // state checks
            Debug.Assert(this.app != null);

            // clone the CredentialSettings
            CredentialSettings credentialSettings;

            if (oldCredential != null)
            {
                credentialSettings = CredentialSettings.Clone(oldCredential);
            }
            else
            {
                credentialSettings = new CredentialSettings();
                // set default Persistence value to Session (i.e. volatile)
                // The default value reverted because it was confusing.
//				credentialSettings.Persistence = CredentialPersistence.Session;
            }
            credentialSettings.EndPoint = endPoint;

            // ask user's credential
            Func <CredentialSettings> callback = () => {
                // get the MainWindow
                // Note that the MainWindow can be accessed only from the GUI thread
                // (that is, it must be gotten inside this callback)
                Window mainWindow = this.app.MainWindow;

                // prepare CredentialDialog
                CredentialDialog dialog = new CredentialDialog(credentialSettings);
                dialog.Title = realm;
                if (mainWindow != null)
                {
                    dialog.Owner = mainWindow;
                }

                // show the credential dialog and get user input
                this.credentialDialog = dialog;
                try {
                    return((dialog.ShowDialog() ?? false) ? dialog.CredentialSettings : null);
                } finally {
                    this.credentialDialog = null;
                }
            };

            return(this.app.Dispatcher.Invoke <CredentialSettings>(callback));
        }
Example #4
0
            private void SetCredential(CredentialSettings credential)
            {
                // argument checks
                Debug.Assert(credential != null);

                lock (this.credentialsLocker) {
                    // state checks
                    IDictionary <string, CredentialSettings> dictionary = this.dictionary;
                    Debug.Assert(dictionary != null);

                    // register the credential to the credential list
                    string             endPoint = credential.EndPoint;
                    bool               changed  = false;
                    CredentialSettings oldCredential;
                    if (dictionary.TryGetValue(endPoint, out oldCredential))
                    {
                        // the credential for the endpoint exists
                        changed = !credential.Equals(oldCredential);
                    }
                    else
                    {
                        // newly added
                        changed = true;
                    }

                    if (changed)
                    {
                        // register the credential
                        this.isCredentialsDirty = true;
                        if (credential.Persistence == CredentialPersistence.Session)
                        {
                            // do not keep in the process state
                            dictionary.Remove(endPoint);
                        }
                        else
                        {
                            dictionary[endPoint] = credential;
                        }
                    }
                }

                return;
            }
        private void editCredentialButton_Click(object sender, RoutedEventArgs e)
        {
            try {
                ListView listView = this.credentialListView;

                // get the selected CredentialSettings
                CredentialSettings originalItem = listView.SelectedItem as CredentialSettings;
                if (originalItem == null)
                {
                    // this item is not editable
                    return;
                }

                // create a clone of the selected CredentialSettings
                CredentialSettings newItem = CredentialSettings.Clone(originalItem);

                // prepare a validator
                CredentialSettings[] items = listView.Items.Cast <CredentialSettings>().ToArray();
                Func <CredentialSettings, string> validator = (s) => {
                    // check there is no credential which is for the same end point
                    CredentialSettings conflicting = items.Where(item => (item != originalItem && s.HasSameEndPoint(item))).FirstOrDefault();
                    return((conflicting == null) ? null : string.Format(Properties.Resources.SettingsWindow_Message_ConflictingCredential, s.EndPoint));
                };

                // edit the clone
                CredentialDialog dialog = new CredentialDialog(newItem, validator, endPointEditable: true);
                dialog.Owner = this;
                if (dialog.ShowDialog() ?? false)
                {
                    ReplaceSelectedListItemWith(listView, dialog.CredentialSettings);
                }
            } catch (Exception exception) {
                ShowErrorDialog(exception.Message);
            }

            return;
        }
Example #6
0
        protected override CredentialSettings UpdateCredential(string endPoint, string realm, CredentialSettings oldCredential)
        {
            // argument checks
            Debug.Assert(endPoint != null);
            Debug.Assert(realm != null);                // may be empty

            return(AskCredentialInfo(endPoint, realm, canSave: this.HasSettingsFile));
        }
Example #7
0
        /// <remarks>
        /// Note that Dispose() may be called during running this method.
        /// That is, system shutdown or suspend may cause Dispose() call
        /// while it executes runner.GetCredential(), which may be opening a CredentialDialog.
        /// In this case, runner.GetCredential() will return in the next turn
        /// on the GUI thread cycle after Dispose() is called.
        /// </remarks>
        public BasicCredential GetServerBasicCredentials(string endPoint, string realm, bool firstRequest, BasicCredential oldBasicCredentials)
        {
            // argument checks
            if (endPoint == null)
            {
                throw new ArgumentNullException(nameof(endPoint));
            }
            // realm can be null
            // oldBasicCredentials can be null

            BasicCredential basicCredential;
            IDictionary <string, BasicCredential> basicCredentialCache;
            IProxyRunner runner;

            // the value of the this.serverBasicCredentialCache field is synchronized by locking this
            lock (this) {
                // state checks
                basicCredentialCache = this.serverBasicCredentialCache;
                if (basicCredentialCache == null)
                {
                    throw new ObjectDisposedException(this.ComponentName);
                }
                runner = this.Runner;
            }

            // the contents of the this.serverBasicCredentialCache are synchronized by locking this.credentialCacheLocker
            lock (this.credentialCacheLocker) {
                // get value from the cache
                basicCredentialCache.TryGetValue(endPoint, out basicCredential);

                // need a new credential?
                bool needGetCredential;
                if (basicCredential == null)
                {
                    needGetCredential = !firstRequest;
                }
                else
                {
                    // try the current credential if the current revision is newer than the caller's.
                    needGetCredential = ((oldBasicCredentials != null) && (basicCredential.Revision <= oldBasicCredentials.Revision));
                }

                // get the credential from the runner
                if (needGetCredential)
                {
                    // figure out the next revision number
                    int revision = 1;
                    if (basicCredential != null)
                    {
                        revision = basicCredential.Revision;
                        if (int.MaxValue <= revision)
                        {
                            throw new Exception("An internal counter was overflowed.");
                        }
                        ++revision;
                    }

                    // get the credential from the runner
                    CredentialSettings credential = null;
                    if (runner != null)
                    {
                        credential = runner.GetCredential(endPoint, realm, needUpdate: (basicCredential != null));
                    }
                    if (credential == null)
                    {
                        // maybe user cancel entering a credential
                        basicCredential = null;
                    }
                    else
                    {
                        basicCredential = new BasicCredential(revision, credential.EnableAssumptionMode, CreateBasicProxyAuthorizationBytes(credential.GetNetworkCredential()));
                    }

                    // update the cache
                    if (basicCredential == null || credential.Persistence == CredentialPersistence.Session)
                    {
                        basicCredentialCache.Remove(endPoint);
                    }
                    else
                    {
                        basicCredentialCache[endPoint] = basicCredential;
                    }
                }
            }

            // adjust for first time
            if (firstRequest && basicCredential != null && basicCredential.EnableAssumptionMode == false)
            {
                // In the first request, the basic credential is returned only if the AssumptionMode is enabled
                basicCredential = null;
            }

            return(basicCredential);
        }
Example #8
0
 protected virtual CredentialSettings UpdateCredential(string endPoint, string realm, CredentialSettings oldCredential)
 {
     return(null);               // no credential by default
 }
Example #9
0
        public CredentialDialog(CredentialSettings credentialSettings, Func <CredentialSettings, string> validator = null, bool endPointEditable = false)
        {
            // argument checks
            if (credentialSettings == null)
            {
                throw new ArgumentNullException(nameof(credentialSettings));
            }
            // validator can be null
            if (endPointEditable && credentialSettings.Persistence == CredentialPersistence.Session)
            {
                // session mode is useless when endPoint is editable
                throw new ArgumentException($"Its 'Persistence' property cannot be 'Session' if '{nameof(endPointEditable)}' is true.", nameof(credentialSettings));
            }

            // initialize members
            this.CredentialSettings = credentialSettings;
            this.validator          = validator;

            // initialize components
            InitializeComponent();
            this.DataContext = credentialSettings;

            // EndPoint
            if (endPointEditable)
            {
                // show TextBox to edit EndPoint
                this.endPointLabel.Visibility        = Visibility.Visible;
                this.endPointTextBox.Visibility      = Visibility.Visible;
                this.endPointTextBox.IsEnabled       = true;
                this.descriptionTextBlock.Visibility = Visibility.Hidden;
                this.sessionRadioButton.IsEnabled    = false;                   // useless in this mode

                // this.endPointTextBox.Text is bound to credentialSettings.EndPoint
            }
            else
            {
                // show EndPoint which asks your credential
                string endPoint = credentialSettings.EndPoint;
                if (endPoint == null)
                {
                    endPoint = "(unidentified proxy)";
                }
                else if (endPoint.Length == 0)
                {
                    endPoint = "(all proxies)";
                }
                this.descriptionTextBlock.Text = string.Format(Properties.Resources.CredentialDialog_descriptionTextBlock_Text, endPoint);

                this.endPointLabel.Visibility        = Visibility.Hidden;
                this.endPointTextBox.Visibility      = Visibility.Hidden;
                this.endPointTextBox.IsEnabled       = false;
                this.descriptionTextBlock.Visibility = Visibility.Visible;
            }

            // UserName
            // this.userNameTextBox.Text is bound to credentialSettings.UserName

            // Password
            this.passwordBox.Password = credentialSettings.Password;

            // Persistence
            // update persistence radio buttons
            RadioButton radioButton = null;

            switch (credentialSettings.Persistence)
            {
            case CredentialPersistence.Session:
                radioButton = this.sessionRadioButton;
                break;

            case CredentialPersistence.Persistent:
                radioButton = this.persistentRadioButton;
                break;

            default:
                // CredentialPersistence.Process is default
                radioButton = this.processRadioButton;
                break;
            }
            radioButton.IsChecked = true;

            // EnableAssumptionMode
            // this.enableAssumptionModeCheckBox.IsChecked is bound to credentialSettings.EnableAssumptionMode

            // set initial focus
            Control control;

            if (endPointEditable)
            {
                control = this.endPointTextBox;
            }
            else
            {
                if (string.IsNullOrEmpty(credentialSettings.UserName))
                {
                    control = this.userNameTextBox;
                }
                else
                {
                    control = this.passwordBox;
                }
            }
            control.Focus();

            return;
        }