diff --git a/MainForm.Designer.cs b/MainForm.Designer.cs index c1fd978..22b2c76 100644 --- a/MainForm.Designer.cs +++ b/MainForm.Designer.cs @@ -72,6 +72,7 @@ this.devicesTabControl = new System.Windows.Forms.TabControl(); this.devicesTabPage = new System.Windows.Forms.TabPage(); this.devicesPanel = new System.Windows.Forms.Panel(); + this.noSearchResultsLabel = new System.Windows.Forms.Label(); this.noDevicesLabel = new System.Windows.Forms.Label(); this.portMapTabPage = new System.Windows.Forms.TabPage(); this.mapPanel = new System.Windows.Forms.Panel(); @@ -92,7 +93,8 @@ this.openToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator(); this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.noSearchResultsLabel = new System.Windows.Forms.Label(); + this.emailTokenButton = new System.Windows.Forms.Button(); + this.tokenEmailSentLabel = new System.Windows.Forms.Label(); this.panel5.SuspendLayout(); this.mainPanel.SuspendLayout(); this.mainTabControl.SuspendLayout(); @@ -352,6 +354,8 @@ // // panel2 // + this.panel2.Controls.Add(this.tokenEmailSentLabel); + this.panel2.Controls.Add(this.emailTokenButton); this.panel2.Controls.Add(this.label3); this.panel2.Controls.Add(this.tokenTextBox); this.panel2.Controls.Add(this.pictureBox6); @@ -382,7 +386,9 @@ this.tokenTextBox.Name = "tokenTextBox"; this.tokenTextBox.Size = new System.Drawing.Size(213, 20); this.tokenTextBox.TabIndex = 18; + this.tokenTextBox.TextChanged += new System.EventHandler(this.tokenTextBox_TextChanged); this.tokenTextBox.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.tokenTextBox_KeyPress); + this.tokenTextBox.KeyUp += new System.Windows.Forms.KeyEventHandler(this.tokenTextBox_KeyUp); // // pictureBox6 // @@ -624,6 +630,19 @@ this.devicesPanel.Size = new System.Drawing.Size(470, 244); this.devicesPanel.TabIndex = 50; // + // noSearchResultsLabel + // + this.noSearchResultsLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.noSearchResultsLabel.Font = new System.Drawing.Font("Arial", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.noSearchResultsLabel.Location = new System.Drawing.Point(91, 96); + this.noSearchResultsLabel.Name = "noSearchResultsLabel"; + this.noSearchResultsLabel.Size = new System.Drawing.Size(283, 17); + this.noSearchResultsLabel.TabIndex = 5; + this.noSearchResultsLabel.Text = "No Search Results"; + this.noSearchResultsLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + this.noSearchResultsLabel.Visible = false; + // // noDevicesLabel // this.noDevicesLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) @@ -826,18 +845,26 @@ this.exitToolStripMenuItem.Text = "E&xit"; this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click_1); // - // noSearchResultsLabel + // emailTokenButton // - this.noSearchResultsLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.noSearchResultsLabel.Font = new System.Drawing.Font("Arial", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.noSearchResultsLabel.Location = new System.Drawing.Point(91, 96); - this.noSearchResultsLabel.Name = "noSearchResultsLabel"; - this.noSearchResultsLabel.Size = new System.Drawing.Size(283, 17); - this.noSearchResultsLabel.TabIndex = 5; - this.noSearchResultsLabel.Text = "No Search Results"; - this.noSearchResultsLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; - this.noSearchResultsLabel.Visible = false; + this.emailTokenButton.Location = new System.Drawing.Point(241, 177); + this.emailTokenButton.Name = "emailTokenButton"; + this.emailTokenButton.Size = new System.Drawing.Size(75, 23); + this.emailTokenButton.TabIndex = 20; + this.emailTokenButton.Text = "Email"; + this.emailTokenButton.UseVisualStyleBackColor = true; + this.emailTokenButton.Visible = false; + this.emailTokenButton.Click += new System.EventHandler(this.emailTokenButton_Click); + // + // tokenEmailSentLabel + // + this.tokenEmailSentLabel.AutoSize = true; + this.tokenEmailSentLabel.Location = new System.Drawing.Point(238, 182); + this.tokenEmailSentLabel.Name = "tokenEmailSentLabel"; + this.tokenEmailSentLabel.Size = new System.Drawing.Size(55, 13); + this.tokenEmailSentLabel.TabIndex = 21; + this.tokenEmailSentLabel.Text = "Email sent"; + this.tokenEmailSentLabel.Visible = false; // // MainForm // @@ -951,6 +978,8 @@ private System.Windows.Forms.Label noDevicesLabel; private System.Windows.Forms.TextBox searchTextBox; private System.Windows.Forms.Label noSearchResultsLabel; + private System.Windows.Forms.Button emailTokenButton; + private System.Windows.Forms.Label tokenEmailSentLabel; } } diff --git a/MainForm.cs b/MainForm.cs index 180db9e..e2f2496 100644 --- a/MainForm.cs +++ b/MainForm.cs @@ -38,6 +38,7 @@ namespace MeshCentralRouter public bool ignoreCert = false; public bool inaddrany = false; public bool forceExit = false; + public bool sendEmailToken = false; public class DeviceComparer : IComparer { @@ -102,6 +103,9 @@ namespace MeshCentralRouter panel3.Visible = (newPanel == 3); panel4.Visible = (newPanel == 4); currentPanel = newPanel; + + // Setup stuff + nextButton2.Enabled = (tokenTextBox.Text.Replace(" ", "") != ""); } private void MainForm_Load(object sender, EventArgs e) @@ -315,7 +319,13 @@ namespace MeshCentralRouter if (this.InvokeRequired) { this.Invoke(new MeshCentralServer.onStateChangedHandler(Meshcentral_onStateChanged), state); return; } if (state == 0) { - if (meshcentral.disconnectMsg == "tokenrequired") { tokenTextBox.Text = ""; setPanel(2); tokenTextBox.Focus(); } else { setPanel(1); } + if (meshcentral.disconnectMsg == "tokenrequired") { + emailTokenButton.Visible = (meshcentral.disconnectEmail2FA == true) && (meshcentral.disconnectEmail2FASent == false); + tokenEmailSentLabel.Visible = (meshcentral.disconnectEmail2FASent == true); + tokenTextBox.Text = ""; + setPanel(2); + tokenTextBox.Focus(); + } else { setPanel(1); } if ((meshcentral.disconnectMsg != null) && meshcentral.disconnectMsg.StartsWith("noauth")) { stateLabel.Text = "Invalid username or password"; stateLabel.Visible = true; stateClearTimer.Enabled = true; serverNameComboBox.Focus(); } else if (meshcentral.disconnectMsg == "cert") { lastBadConnectCert = meshcentral.disconnectCert; @@ -562,6 +572,8 @@ namespace MeshCentralRouter private void nextButton2_Click(object sender, EventArgs e) { + if ((tokenTextBox.Text.Replace(" ", "") == "") && (sendEmailToken == false)) return; + // Attempt to login with token addButton.Enabled = false; addRelayButton.Enabled = false; @@ -573,7 +585,15 @@ namespace MeshCentralRouter meshcentral.onStateChanged += Meshcentral_onStateChanged; meshcentral.onNodesChanged += Meshcentral_onNodesChanged; meshcentral.onLoginTokenChanged += Meshcentral_onLoginTokenChanged; - meshcentral.connect(serverurl, userNameTextBox.Text, passwordTextBox.Text, tokenTextBox.Text.Replace(" ", "")); + if (sendEmailToken == true) + { + sendEmailToken = false; + meshcentral.connect(serverurl, userNameTextBox.Text, passwordTextBox.Text, "**email**"); + } + else + { + meshcentral.connect(serverurl, userNameTextBox.Text, passwordTextBox.Text, tokenTextBox.Text.Replace(" ", "")); + } } private void tokenTextBox_KeyPress(object sender, KeyPressEventArgs e) @@ -773,6 +793,25 @@ namespace MeshCentralRouter map.appButton_Click(this, null); } + private void emailTokenButton_Click(object sender, EventArgs e) + { + if (MessageBox.Show(this, "Send token to registered email address?", "Two-factor Authentication", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK) + { + sendEmailToken = true; + nextButton2_Click(this, null); + } + } + + private void tokenTextBox_KeyUp(object sender, KeyEventArgs e) + { + nextButton2.Enabled = (tokenTextBox.Text.Replace(" ","") != ""); + } + + private void tokenTextBox_TextChanged(object sender, EventArgs e) + { + nextButton2.Enabled = (tokenTextBox.Text.Replace(" ", "") != ""); + } + /* private delegate void displayMessageHandler(string msg, int buttons, string extra, int progress); private void displayMessage(string msg, int buttons = 0, string extra = "", int progress = 0) diff --git a/MainForm.resx b/MainForm.resx index eff130e..fa5c6f6 100644 --- a/MainForm.resx +++ b/MainForm.resx @@ -117,6 +117,9 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + This server presented a un-trusted certificate. This may indicate that this is not the correct server or that the server does not have a valid certificate. It is not recommanded, but you can press the ignore button to continue connection to this server. + @@ -151,9 +154,6 @@ RncTzRV6H30abpmOBnUzakAfGPsPoCH77EfzJ24AAAAASUVORK5CYII= - - This server presented a un-trusted certificate. This may indicate that this is not the correct server or that the server does not have a valid certificate. It is not recommanded, but you can press the ignore button to continue connection to this server. - 17, 17 diff --git a/MeshCentralServer.cs b/MeshCentralServer.cs index 836a9bc..ef40ef6 100644 --- a/MeshCentralServer.cs +++ b/MeshCentralServer.cs @@ -46,6 +46,8 @@ namespace MeshCentralRouter public Dictionary meshes = null; public string disconnectCause = null; public string disconnectMsg = null; + public bool disconnectEmail2FA = false; + public bool disconnectEmail2FASent = false; public X509Certificate2 disconnectCert; public string authCookie = null; public string loginCookie = null; @@ -182,6 +184,8 @@ namespace MeshCentralRouter { disconnectCause = jsonAction["cause"].ToString(); disconnectMsg = jsonAction["msg"].ToString(); + if (jsonAction.ContainsKey("email2fa")) { disconnectEmail2FA = (bool)jsonAction["email2fa"]; } else { disconnectEmail2FA = false; } + if (jsonAction.ContainsKey("email2fasent")) { disconnectEmail2FASent = (bool)jsonAction["email2fasent"]; } else { disconnectEmail2FASent = false; } break; } case "serverinfo":