diff ARClient/frmEditResource.cs @ 0:90ea68d4f92f

First release
author Ivo Smits <Ivo@UCIS.nl>
date Sat, 08 Nov 2014 22:43:51 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ARClient/frmEditResource.cs	Sat Nov 08 22:43:51 2014 +0100
@@ -0,0 +1,371 @@
+using System;
+using System.Collections;
+using System.Net;
+using System.Text;
+using System.Windows.Forms;
+
+namespace ARClient {
+	partial class frmEditResource : Form {
+		public Form1 MainForm { get; set; }
+		public Byte[] Label = null;
+		public IDictionary Value = new Hashtable();
+		public UInt32 UpdateSerial = 0;
+
+		public frmEditResource() {
+			InitializeComponent();
+			radTypeDomain.Checked = true;
+		}
+
+		private void frmEditResource_Load(object sender, EventArgs e) {
+			tabControl1_SelectedIndexChanged(null, null);
+		}
+		public void ImportData() {
+			tabControl1.SelectedIndex = 1;
+		}
+
+		private void radType_CheckedChanged(object sender, EventArgs e) {
+			if (radTypeDomain.Checked) {
+				lblLabelHint.Text = "Enter the domain name including the top level component. For an Anonet domain, your domain name must end in '.ano'.";
+				if (Label != null && Label.Length > 1 && Label[0] == 4) txtLabelValue.Text = Encoding.UTF8.GetString(Label, 1, Label.Length - 1);
+				else txtLabelValue_TextChanged(sender, e);
+			} else if (radTypeIPv4.Checked) {
+				lblLabelHint.Text = "Enter the IPv4 network in CIDR notation, e.g. '1.2.3.0/24'.";
+				if (Label != null && Label.Length == 6 && Label[0] == 1) txtLabelValue.Text = Label[1].ToString() + "." + Label[2].ToString() + "." + Label[3].ToString() + "." + Label[4].ToString() + "/" + Label[5].ToString();
+				else txtLabelValue_TextChanged(sender, e);
+			} else if (radTypeIPv6.Checked) {
+				lblLabelHint.Text = "Enter the IPv6 network in CIDR notation, e.g. 'fd63:1e39:6f73:001b::/64'.";
+				if (Label != null && Label.Length == 18 && Label[0] == 2) {
+					Byte[] address = new Byte[16];
+					Buffer.BlockCopy(Label, 2, address, 0, 16);
+					txtLabelValue.Text = (new IPAddress(address)).ToString() + "/" + Label[17].ToString();
+				} else txtLabelValue_TextChanged(sender, e);
+			} else if (radTypeASNumber.Checked) {
+				lblLabelHint.Text = "Enter the AS number.";
+				if (Label != null && Label.Length == 5 && Label[0] == 3) txtLabelValue.Text = Functions.DecodeInt32BigEndian(Label, 1).ToString();
+				else txtLabelValue_TextChanged(sender, e);
+			} else if (radTypeOtherHex.Checked) {
+				lblLabelHint.Text = "Expert usage! Enter the raw label value in hexadecimal notation.";
+				if (Label != null) txtLabelValue.Text = Functions.bin2hex(Label);
+				else txtLabelValue_TextChanged(sender, e);
+			} else {
+				lblLabelHint.Text = "Select a resource type.";
+			}
+		}
+
+		private Boolean TryParseLabel() {
+			Label = null;
+			if (radTypeDomain.Checked) {
+				if (txtLabelValue.Text.Length < 1) return false;
+				Byte[] bytes = Encoding.UTF8.GetBytes(txtLabelValue.Text.ToLowerInvariant());
+				Label = new Byte[bytes.Length + 1];
+				Label[0] = 4;
+				bytes.CopyTo(Label, 1);
+				return true;
+			} else if (radTypeIPv4.Checked) {
+				String[] parts1 = txtLabelValue.Text.Split('/');
+				if (parts1.Length != 2) return false;
+				String[] parts2 = parts1[0].Split('.');
+				if (parts2.Length != 4) return false;
+				Byte[] bytes = new Byte[6];
+				bytes[0] = 1;
+				for (int i = 0; i < 4; i++) if (!Byte.TryParse(parts2[i], out bytes[i + 1])) return false;
+				if (!Byte.TryParse(parts1[1], out bytes[5])) return false;
+				if (bytes[5] > 32) return false;
+				Label = bytes;
+				return true;
+			} else if (radTypeIPv6.Checked) {
+				String[] parts1 = txtLabelValue.Text.Split('/');
+				if (parts1.Length != 2) return false;
+				IPAddress addr;
+				if (!IPAddress.TryParse(parts1[0], out addr)) return false;
+				if (addr.AddressFamily != System.Net.Sockets.AddressFamily.InterNetworkV6) return false;
+				Byte len;
+				if (!Byte.TryParse(parts1[1], out len)) return false;
+				if (len > 128) return false;
+				Label = new Byte[18];
+				Label[0] = 2;
+				addr.GetAddressBytes().CopyTo(Label, 1);
+				Label[17] = len;
+				return true;
+			} else if (radTypeASNumber.Checked) {
+				UInt32 asn;
+				if (!UInt32.TryParse(txtLabelValue.Text, out asn)) return false;
+				Label = new Byte[5];
+				Label[0] = 3;
+				Functions.EncodeInt32BigEndian(asn).CopyTo(Label, 1);
+				return true;
+			} else if (radTypeOtherHex.Checked) {
+				Label = Functions.hex2bin(txtLabelValue.Text);
+				return Label != null;
+			} else {
+				return false;
+			}
+		}
+
+		private void txtLabelValue_TextChanged(object sender, EventArgs e) {
+			Boolean valid = TryParseLabel();
+			lblLabelValid.Visible = !valid;
+			btnLabelNext.Visible = valid;
+		}
+
+		private void btnLabelNext_Click(object sender, EventArgs e) {
+			tabControl1.SelectedIndex++;
+		}
+
+		private void UpdateValueTree() {
+			lvwData.SuspendLayout();
+			lvwData.Nodes.Clear();
+
+			if (Value is IDictionary) {
+				foreach (DictionaryEntry child in (IDictionary)Value) lvwData.Nodes.Add(AddResourceValueInTree(child.Key.ToString() + ": ", child.Value));
+			} else if (Value is ICollection) {
+				foreach (Object child in (ICollection)Value) lvwData.Nodes.Add(AddResourceValueInTree(String.Empty, child));
+			} else if (Value == null) {
+				lvwData.Nodes.Add("Null").Tag = null;
+			} else {
+				lvwData.Nodes.Add(Value.ToString()).Tag = Value;
+			}
+
+			lvwData.ResumeLayout();
+		}
+		private TreeNode AddResourceValueInTree(String prefix, Object value) {
+			TreeNode node = new TreeNode();
+			if (value is IDictionary) {
+				node.Text = prefix + "Dictionary";
+				foreach (DictionaryEntry child in (IDictionary)value) node.Nodes.Add(AddResourceValueInTree(child.Key.ToString() + ": ", child.Value));
+			} else if (value is ICollection) {
+				node.Text = prefix + "Collection";
+				foreach (Object child in (ICollection)value) node.Nodes.Add(AddResourceValueInTree(String.Empty, child));
+			} else if (value == null) {
+				node.Text = prefix + "Null";
+			} else {
+				node.Text = prefix + value.ToString();
+			}
+			node.Tag = value;
+			node.Expand();
+			return node;
+		}
+
+		private void btnDataSetOwner_Click(object sender, EventArgs e) {
+			frmTextInput form = new frmTextInput();
+			form.Text = "MARC - Resource data";
+			form.Description = "Enter the owner name:";
+			if (!(Value is IDictionary)) Value = new Hashtable();
+			if (Value.Contains("owner")) form.Value = Value["owner"].ToString();
+			if (form.ShowDialog(this) != DialogResult.OK) return;
+			Value["owner"] = form.Value;
+			UpdateValueTree();
+		}
+		private void btnDataSetDescription_Click(object sender, EventArgs e) {
+			frmTextInput form = new frmTextInput();
+			form.Text = "MARC - Resource data";
+			form.Description = "Enter the resource description:";
+			if (!(Value is IDictionary)) Value = new Hashtable();
+			if (Value.Contains("descr")) form.Value = Value["descr"].ToString();
+			if (form.ShowDialog(this) != DialogResult.OK) return;
+			Value["descr"] = form.Value;
+			UpdateValueTree();
+		}
+		private void btnDataAddDNS_Click(object sender, EventArgs e) {
+			frmTextInput form = new frmTextInput();
+			form.Text = "MARC - Resource data";
+			form.Description = "Enter the nameserver name in the current zone, or add a dot ad the end to use a nameserver in another zone:";
+			form.Value = "ns1";
+			if (form.ShowDialog(this) != DialogResult.OK) return;
+			String nsname = form.Value;
+			String nsip4 = null, nsip6 = null;
+			if (!nsname.EndsWith(".")) {
+				form.Description = "Enter the nameserver IPv4 address, if any:";
+				form.Value = "";
+				if (form.ShowDialog(this) == DialogResult.OK) nsip4 = form.Value;
+				form.Description = "Enter the nameserver IPv6 address, if any:";
+				form.Value = "";
+				if (form.ShowDialog(this) == DialogResult.OK) nsip6 = form.Value;
+			}
+			if (!(Value is IDictionary)) Value = new Hashtable();
+			if (Value["ns"] == null || !(Value["ns"] is IDictionary)) Value["ns"] = new Hashtable();
+			IDictionary dns = (IDictionary)Value["ns"];
+			IList ns = new ArrayList();
+			dns[nsname] = ns;
+			if (nsip4 != null && nsip4.Length > 0) ns.Add(nsip4);
+			if (nsip6 != null && nsip6.Length > 0) ns.Add(nsip6);
+			UpdateValueTree();
+		}
+
+		private void btnDataEditString_Click(object sender, EventArgs e) {
+			if (lvwData.SelectedNode == null || lvwData.SelectedNode.Tag == null) return;
+			frmTextInput form = new frmTextInput();
+			form.Text = "MARC - Resource data";
+			form.Description = "Enter the new value:";
+			form.Value = lvwData.SelectedNode.Tag.ToString();
+			if (form.ShowDialog(this) != DialogResult.OK) return;
+			Object parent = lvwData.SelectedNode.Parent == null ? Value : lvwData.SelectedNode.Parent.Tag;
+			if (parent == null) return;
+			if (parent is IDictionary) {
+				foreach (DictionaryEntry entry in ((IDictionary)parent)) {
+					if (lvwData.SelectedNode.Tag == entry.Value) {
+						((IDictionary)parent)[entry.Key] = form.Value;
+						break;
+					}
+				}
+			} else if (parent is IList) {
+				for (int i = 0; i < ((IList)parent).Count; i++) {
+					if (((IList)parent)[i] == lvwData.SelectedNode.Tag) ((IList)parent)[i] = form.Value;
+				}
+			}
+			UpdateValueTree();
+		}
+
+		private void btnDataAddSring_Click(object sender, EventArgs e) {
+			Object parent = lvwData.SelectedNode == null ? Value : lvwData.SelectedNode.Tag;
+			if (!(parent is IDictionary || parent is IList)) return;
+			frmTextInput form = new frmTextInput();
+			form.Text = "MARC - Resource data";
+			String dkey = null;
+			if (parent is IDictionary) {
+				form.Description = "Enter the dictionary key:";
+				if (form.ShowDialog(this) != DialogResult.OK) return;
+				dkey = form.Value;
+			}
+			form.Value = String.Empty;
+			form.Description = "Enter the value:";
+			if (form.ShowDialog(this) != DialogResult.OK) return;
+			if (parent is IDictionary) {
+				((IDictionary)parent)[dkey]= form.Value;
+			} else if (parent is IList) {
+				((IList)parent).Add(form.Value);
+			}
+			UpdateValueTree();
+		}
+
+		private void btnDataAddCollection_Click(object sender, EventArgs e) {
+			Object parent = lvwData.SelectedNode == null ? Value : lvwData.SelectedNode.Tag;
+			if (parent is IDictionary) {
+				frmTextInput form = new frmTextInput();
+				form.Text = "MARC - Resource data";
+				form.Description = "Enter the dictionary key:";
+				if (form.ShowDialog(this) != DialogResult.OK) return;
+				((IDictionary)parent)[form.Value] = new ArrayList();
+			} else if (parent is IList) {
+				((IList)parent).Add(new ArrayList());
+			}
+			UpdateValueTree();
+		}
+
+		private void btnDataAddDictionary_Click(object sender, EventArgs e) {
+			Object parent = lvwData.SelectedNode == null ? Value : lvwData.SelectedNode.Tag;
+			if (parent is IDictionary) {
+				frmTextInput form = new frmTextInput();
+				form.Text = "MARC - Resource data";
+				form.Description = "Enter the dictionary key:";
+				if (form.ShowDialog(this) != DialogResult.OK) return;
+				((IDictionary)parent)[form.Value] = new Hashtable();
+			} else if (parent is IList) {
+				((IList)parent).Add(new Hashtable());
+			}
+			UpdateValueTree();
+		}
+
+		private void btnDataDelete_Click(object sender, EventArgs e) {
+			if (lvwData.SelectedNode == null || lvwData.SelectedNode.Tag == null) return;
+			Object parent = lvwData.SelectedNode.Parent == null ? Value : lvwData.SelectedNode.Parent.Tag;
+			if (parent == null) return;
+			if (parent is IDictionary) {
+				foreach (DictionaryEntry entry in ((IDictionary)parent)) {
+					if (lvwData.SelectedNode.Tag == entry.Value) {
+						((IDictionary)parent).Remove(entry.Key);
+						break;
+					}
+				}
+			} else if (parent is IList) {
+				((IList)parent).Remove(lvwData.SelectedNode.Tag);
+			}
+			UpdateValueTree();
+		}
+
+		private void btnDataDeleteAll_Click(object sender, EventArgs e) {
+			Value = null;
+			UpdateValueTree();
+		}
+
+		private void UpdateResourceStatus() {
+			MARCUpdate resource;
+			grpUpdateConflict.Visible = false;
+			grpUpdateExport.Visible = true;
+			txtUpdateLabel.Text = Functions.GetNameForLabel(Label);
+			UpdateSerial = checked((UInt32)MARCUpdate.DateTimeToUnix(DateTime.Now));
+			if (MainForm.Resources.TryGetValue(new MARCLabel(Label), out resource)) {
+				txtUpdateCurrentOwner.Text = Functions.bin2hex(resource.Key.Bytes);
+				txtUpdateCurrentTransfer.Text = resource.Transfer == null ? "None" : Functions.bin2hex(resource.Transfer.Value.Bytes);
+				txtUpdateCurrentSerial.Text = resource.Serial.ToString() + " (" + resource.UpdateTimestamp.ToShortDateString() + ")";
+				txtUpdateCurrentExpiration.Text = resource.Expiration == null ? "None" : resource.Expiration.Value.ToString() + " (" + resource.ExpirationTimestamp.ToShortDateString() + ")";
+				if (!resource.CanUpdate(MainForm.PublicKey)) {
+					txtUpdateCurrentStatus.Text = "Not available";
+					grpUpdateConflict.Visible = true;
+					grpUpdateExport.Visible = false;
+					return;
+				}
+				txtUpdateCurrentStatus.Text = "Registered";
+				if (UpdateSerial <= resource.Serial) UpdateSerial = resource.Serial + 1;
+				txtUpdateCurrentSize.Text = resource.UpdateMessage.Length.ToString();
+			} else {
+				txtUpdateCurrentOwner.Text = "None";
+				txtUpdateCurrentTransfer.Text = "None";
+				txtUpdateCurrentSerial.Text = String.Empty;
+				txtUpdateCurrentStatus.Text = "Free";
+				txtUpdateCurrentSize.Text = "N/A";
+			}
+			txtUpdateOwner.Text = MainForm.PublicKey.ToString();
+			dtpUpdateExpiration.Value = DateTime.Now.AddYears(1);
+			dtpUpdateExpiration.Checked = false;
+			chkUpdateTransferEnabled.Checked = false;
+		}
+
+		private void tabControl1_SelectedIndexChanged(object sender, EventArgs e) {
+			if (tabControl1.SelectedIndex == 0) {
+				if (Label != null && Label.Length > 0) {
+					switch (Label[0]) {
+						case 1: radTypeIPv4.Checked = true; break;
+						case 2: radTypeIPv6.Checked = true; break;
+						case 3: radTypeASNumber.Checked = true; break;
+						case 4: radTypeDomain.Checked = true; break;
+						default: radTypeOtherHex.Checked = true; break;
+					}
+				}
+				radType_CheckedChanged(sender, e);
+				txtLabelValue_TextChanged(sender, e);
+			} else if (Label == null || Label.Length == 0) {
+				MessageBox.Show("The selected label is not valid. Please correct the label and try again.", "MARC - Invalid label", MessageBoxButtons.OK, MessageBoxIcon.Error);
+				tabControl1.SelectedIndex = 0;
+			} else if (tabControl1.SelectedIndex == 1) {
+				UpdateValueTree();
+			} else if (tabControl1.SelectedIndex == 2) {
+				UpdateResourceStatus();
+			}
+		}
+
+		private void btnUpdateDelete_Click(object sender, EventArgs e) {
+			MARCLabel l = new MARCLabel(Label);
+			MainForm.ResourceHasChanged(null, MainForm.Resources[l]);
+			MainForm.Resources.Remove(l);
+			UpdateResourceStatus();
+		}
+
+		private void btnUpdateNow_Click(object sender, EventArgs e) {
+			UInt32? Expiration = null;
+			Byte[] Transfer = null;
+			if (dtpUpdateExpiration.Checked) {
+				DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
+				Expiration = checked((UInt32)(dtpUpdateExpiration.Value.ToUniversalTime() - epoch).TotalSeconds);
+			}
+			if (chkUpdateTransferEnabled.Checked) {
+				Transfer = Functions.hex2bin(txtUpdateTransfer.Text);
+			}
+			MARCUpdate update = MARCUpdate.Create(MainForm.SecretKey, UpdateSerial, Label, Value, Expiration, Transfer);
+			txtUpdateCurrentSize.Text = update.UpdateMessage.Length.ToString() + " bytes";
+			MainForm.ReplaceOrAddResource(update);
+			MainForm.DatabaseSaved = false;
+			UpdateResourceStatus();
+		}
+	}
+}
\ No newline at end of file