view 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 source

???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();
		}
	}
}