示例#1
0
        /// <summary>
        ///     Verify and create the authenticator if needed
        /// </summary>
        /// <returns>true is successful</returns>
        private bool verifyAuthenticator(string privatekey)
        {
            if (string.IsNullOrEmpty(privatekey))
            {
                return(false);
            }

            Authenticator.Name = nameField.Text;

            var authtype = "totp";

            // if this is a URL, pull it down
            Uri   uri;
            Match match;

            if (Regex.IsMatch(privatekey, "https?://.*") && Uri.TryCreate(privatekey, UriKind.Absolute, out uri))
            {
                try
                {
                    var request = (HttpWebRequest)WebRequest.Create(uri);
                    request.AllowAutoRedirect = true;
                    request.Timeout           = 20000;
                    request.UserAgent         = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)";
                    using (var response = (HttpWebResponse)request.GetResponse())
                    {
                        if (response.StatusCode == HttpStatusCode.OK &&
                            response.ContentType.StartsWith("image/", StringComparison.OrdinalIgnoreCase))
                        {
                            using (var bitmap = (Bitmap)Image.FromStream(response.GetResponseStream()))
                            {
                                IBarcodeReader reader = new BarcodeReader();
                                var            result = reader.Decode(bitmap);
                                if (result != null)
                                {
                                    privatekey = HttpUtility.UrlDecode(result.Text);
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    WinAuthForm.ErrorDialog(Owner, "Cannot load QR code image from " + privatekey, ex);
                    return(false);
                }
            }
            else if ((match = Regex.Match(privatekey, @"data:image/([^;]+);base64,(.*)", RegexOptions.IgnoreCase))
                     .Success)
            {
                var imagedata = Convert.FromBase64String(match.Groups[2].Value);
                using (var ms = new MemoryStream(imagedata))
                {
                    using (var bitmap = (Bitmap)Image.FromStream(ms))
                    {
                        IBarcodeReader reader = new BarcodeReader();
                        var            result = reader.Decode(bitmap);
                        if (result != null)
                        {
                            privatekey = HttpUtility.UrlDecode(result.Text);
                        }
                    }
                }
            }
            else if (IsValidFile(privatekey))
            {
                // assume this is the image file
                using (var bitmap = (Bitmap)Image.FromFile(privatekey))
                {
                    IBarcodeReader reader = new BarcodeReader();
                    var            result = reader.Decode(bitmap);
                    if (result != null)
                    {
                        privatekey = result.Text;
                    }
                }
            }

            // check for otpauth://, e.g. "otpauth://totp/[email protected]?secret=IHZJDKAEEC774BMUK3GX6SA"
            match = Regex.Match(privatekey, @"otpauth://([^/]+)/([^?]+)\?(.*)", RegexOptions.IgnoreCase);
            if (match.Success)
            {
                authtype = match.Groups[1].Value; // @todo we only handle totp (not hotp)
                if (string.Compare(authtype, "totp", true) != 0)
                {
                    WinAuthForm.ErrorDialog(Owner,
                                            "Only time-based (TOTP) authenticators are supported when adding a Google Authenticator. Use the general \"Add Authenticator\" for counter-based (HOTP) authenticators.");
                    return(false);
                }

                var label = match.Groups[2].Value;
                if (string.IsNullOrEmpty(label) == false)
                {
                    Authenticator.Name = nameField.Text = label;
                }

                var qs = WinAuthHelper.ParseQueryString(match.Groups[3].Value);
                privatekey = qs["secret"] ?? privatekey;
            }

            // just get the hex chars
            privatekey = Regex.Replace(privatekey, @"[^0-9a-z]", "", RegexOptions.IgnoreCase);
            if (privatekey.Length == 0)
            {
                WinAuthForm.ErrorDialog(Owner, "The secret code is not valid");
                return(false);
            }

            try
            {
                var auth = new GoogleAuthenticator();
                auth.Enroll(privatekey);
                Authenticator.AuthenticatorData = auth;

                codeProgress.Visible = true;

                var key = Base32.getInstance().Encode(Authenticator.AuthenticatorData.SecretKey);
                secretCodeField.Text = Regex.Replace(key, ".{3}", "$0 ").Trim();
                codeField.Text       = auth.CurrentCode;

                if (auth.ServerTimeDiff == 0L && SyncErrorWarned == false)
                {
                    SyncErrorWarned = true;
                    MessageBox.Show(this, string.Format(strings.AuthenticatorSyncError, "Google"),
                                    WinAuthMain.APPLICATION_TITLE, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
            }
            catch (Exception irre)
            {
                WinAuthForm.ErrorDialog(Owner,
                                        "Unable to create the authenticator. The secret code is probably invalid.", irre);
                return(false);
            }

            return(true);
        }
		/// <summary>
		/// Verify and create the authenticator if needed
		/// </summary>
		/// <returns>true is successful</returns>
		private bool verifyAuthenticator(string privatekey)
		{
			if (string.IsNullOrEmpty(privatekey) == true)
			{
				return false;
			}

			this.Authenticator.Name = nameField.Text;

			string authtype = "totp";

			// if this is a URL, pull it down
			Uri uri;
			Match match;
			if (Regex.IsMatch(privatekey, "https?://.*") == true && Uri.TryCreate(privatekey, UriKind.Absolute, out uri) == true)
			{
				try
				{
					var request = (HttpWebRequest)WebRequest.Create(uri);
					request.AllowAutoRedirect = true;
					request.Timeout = 20000;
					request.UserAgent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)";
					using (var response = (HttpWebResponse)request.GetResponse())
					{
						if (response.StatusCode == HttpStatusCode.OK && response.ContentType.StartsWith("image/", StringComparison.OrdinalIgnoreCase) == true)
						{
							using (Bitmap bitmap = (Bitmap)Bitmap.FromStream(response.GetResponseStream()))
							{
								IBarcodeReader reader = new BarcodeReader();
								var result = reader.Decode(bitmap);
								if (result != null)
								{
									privatekey = HttpUtility.UrlDecode(result.Text);
								}
							}
						}
					}
				}
				catch (Exception ex)
				{
					WinAuthForm.ErrorDialog(this.Owner, "Cannot load QR code image from " + privatekey, ex);
					return false;
				}
			}
			else if ((match = Regex.Match(privatekey, @"data:image/([^;]+);base64,(.*)", RegexOptions.IgnoreCase)).Success == true)
			{
				byte[] imagedata = Convert.FromBase64String(match.Groups[2].Value);
				using (MemoryStream ms = new MemoryStream(imagedata))
				{
					using (Bitmap bitmap = (Bitmap)Bitmap.FromStream(ms))
					{
						IBarcodeReader reader = new BarcodeReader();
						var result = reader.Decode(bitmap);
						if (result != null)
						{
							privatekey = HttpUtility.UrlDecode(result.Text);
						}
					}
				}
			}
			else if (IsValidFile(privatekey) == true)
			{
				// assume this is the image file
				using (Bitmap bitmap = (Bitmap)Bitmap.FromFile(privatekey))
				{
					IBarcodeReader reader = new BarcodeReader();
					var result = reader.Decode(bitmap);
					if (result != null)
					{
						privatekey = result.Text;
					}
				}
			}

			// check for otpauth://, e.g. "otpauth://totp/[email protected]?secret=IHZJDKAEEC774BMUK3GX6SA"
			match = Regex.Match(privatekey, @"otpauth://([^/]+)/([^?]+)\?(.*)", RegexOptions.IgnoreCase);
			if (match.Success == true)
			{
				authtype = match.Groups[1].Value; // @todo we only handle totp (not hotp)
				if (string.Compare(authtype, "totp", true) != 0)
				{
					WinAuthForm.ErrorDialog(this.Owner, "Only time-based (TOTP) authenticators are supported when adding a Google Authenticator. Use the general \"Add Authenticator\" for counter-based (HOTP) authenticators.");
					return false;
				}

				string label = match.Groups[2].Value;
				if (string.IsNullOrEmpty(label) == false)
				{
					this.Authenticator.Name = this.nameField.Text = label;
				}

				NameValueCollection qs = WinAuthHelper.ParseQueryString(match.Groups[3].Value);
				privatekey = qs["secret"] ?? privatekey;
			}

			// just get the hex chars
			privatekey = Regex.Replace(privatekey, @"[^0-9a-z]", "", RegexOptions.IgnoreCase);
			if (privatekey.Length == 0)
			{
				WinAuthForm.ErrorDialog(this.Owner, "The secret code is not valid");
				return false;
			}

			try
			{
				GoogleAuthenticator auth = new GoogleAuthenticator();
				auth.Enroll(privatekey);
				this.Authenticator.AuthenticatorData = auth;

				codeProgress.Visible = true;

				string key = Base32.getInstance().Encode(this.Authenticator.AuthenticatorData.SecretKey);
				this.secretCodeField.Text = Regex.Replace(key, ".{3}", "$0 ").Trim();
				this.codeField.Text = auth.CurrentCode;

				if (auth.ServerTimeDiff == 0L && SyncErrorWarned == false)
				{
					SyncErrorWarned = true;
					MessageBox.Show(this, string.Format(strings.AuthenticatorSyncError, "Google"), WinAuthMain.APPLICATION_TITLE, MessageBoxButtons.OK, MessageBoxIcon.Warning);
				}
			}
			catch (Exception irre)
			{
				WinAuthForm.ErrorDialog(this.Owner, "Unable to create the authenticator. The secret code is probably invalid.", irre);
				return false;
			}

			return true;
		}