コード例 #1
0
        private void InitializeComponent()
        {
            TrayIcon = new NotifyIcon();

            // If this is the first run, generate a random port
            if (Registry.Has("Port") == false)
            {
                StaticHelpers.RandomizePort();
            }

            // If this is the first run, make sure key field is available
            if (Registry.Has("PortLifetime") == false)
            {
                Registry.Set("PortLifetime", 30.ToString());
            }

            // If this is the first run, set default connection interval
            if (Registry.Has("Interval") == false)
            {
                Registry.Set("Interval", 20.ToString());
            }

            // If this is the first run, prompt user with authentication settings page
            if (Registry.Has("ApiKey") == false || Registry.Has("Key") == false)
            {
                SettingsMenuItem_Click(null, null);
            }

            // If user aborted before entering either key, we need to exit here.
            if (Registry.Has("ApiKey") == false || Registry.Has("Key") == false)
            {
                MessageBox.Show("Drawbridge will now exit.");

                Environment.Exit(1);
            }

            // Start the main timer loop
            this.loopTimer           = new System.Timers.Timer();
            this.loopTimer.Interval  = Int32.Parse(Registry.Get("Interval")) * 1000;
            this.loopTimer.Elapsed  += timerTickAsync;
            this.loopTimer.AutoReset = true;
            this.loopTimer.Enabled   = true;
            this.loopTimer.Start();
            timerTickAsync(null, null);

            // Check if this is the first run by seeing if there is a saved API and Protocol key
            // If keys are not present, then prompt user to enter them

            //The icon is added to the project resources.
            //Here I assume that the name of the file is 'TrayIcon.ico'
            TrayIcon.Icon = Properties.Resources.BlackRook;

            //Optional - Add a context menu to the TrayIcon:
            TrayIconContextMenu = new ContextMenuStrip();

            TrayIconContextMenu.SuspendLayout();

            this.TitleMenuItem.Text = String.Format("Drawbridge [{0}]", StaticHelpers.GetVersion());
            this.TrayIconContextMenu.Items.Add(this.TitleMenuItem);
            this.TitleMenuItem.Image = Properties.Resources.bullet_grey;

            // Add some HRs
            this.TrayIconContextMenu.Items.Add("-");
            this.TrayIconContextMenu.Items.Add("-");

            ToolStripMenuItem SettingsMenuItem = new ToolStripMenuItem();

            SettingsMenuItem.Text = "Settings";
            this.TrayIconContextMenu.Items.Add(SettingsMenuItem);

            ToolStripMenuItem Authentication = new ToolStripMenuItem();

            Authentication.Text   = "Authentication";
            Authentication.Click += new EventHandler(this.SettingsMenuItem_Click);
            SettingsMenuItem.DropDownItems.Add(Authentication);

            this.IntervalPicker.Text = "Ping Interval";
            SettingsMenuItem.DropDownItems.Add(this.IntervalPicker);

            foreach (KeyValuePair <int, string> Ping in this.PingsIntervals)
            {
                ToolStripMenuItem x = new ToolStripMenuItem();
                x.Text = Ping.Value;
                x.Tag  = Ping.Key;
                if (Ping.Key == Int32.Parse(Registry.Get("Interval")))
                {
                    x.Checked = true;
                }
                x.Click += delegate(Object sender, EventArgs e)
                {
                    ToolStripMenuItem s = sender as ToolStripMenuItem;
                    this.SelectIntervalSetting(Int32.Parse(s.Tag.ToString()));
                    Registry.Set("Interval", Ping.Key.ToString());
                };
                this.IntervalPicker.DropDownItems.Add(x);
            }

            foreach (KeyValuePair <int, string> Lifetime in this.Lifetimes)
            {
                ToolStripMenuItem x = new ToolStripMenuItem();
                x.Text = Lifetime.Value;
                x.Tag  = Lifetime.Key;
                if (Lifetime.Key == Int32.Parse(Registry.Get("PortLifetime")))
                {
                    x.Checked = true;
                }
                x.Click += delegate(Object sender, EventArgs e)
                {
                    // Uncheck existing option...
                    foreach (ToolStripMenuItem a in this.LifetimePickerMenuItem.DropDownItems)
                    {
                        a.Checked = false;
                    }
                    ToolStripMenuItem s = sender as ToolStripMenuItem;
                    Registry.Set("PortLifetime", Lifetime.Key.ToString());
                    s.Checked = true;
                };
                this.LifetimePickerMenuItem.DropDownItems.Add(x);
            }

            ToolStripMenuItem PortSettingsMenuItem = new ToolStripMenuItem();

            PortSettingsMenuItem.Text = "Mapped Port";
            SettingsMenuItem.DropDownItems.Add(PortSettingsMenuItem);

            this.PortDisplayLabelItem.Text = "Port: " + Registry.Get("Port");
            PortSettingsMenuItem.DropDownItems.Add(this.PortDisplayLabelItem);

            PortSettingsMenuItem.DropDownItems.Add("-");

            ToolStripMenuItem PortRandomizeMenuItem = new ToolStripMenuItem();

            PortRandomizeMenuItem.Text   = "Randomize";
            PortRandomizeMenuItem.Click += delegate(Object sender, EventArgs e)
            {
                int port = StaticHelpers.RandomizePort();
                this.PortDisplayLabelItem.Text = "Port: " + port;
                timerTickAsync(null, null);
            };
            PortSettingsMenuItem.DropDownItems.Add(PortRandomizeMenuItem);

            ToolStripMenuItem PortSetManualMenuItem = new ToolStripMenuItem();

            PortSetManualMenuItem.Text   = "Specify";
            PortSetManualMenuItem.Click += delegate(Object sender, EventArgs e)
            {
                int port = PortNumberInput(Int32.Parse(Registry.Get("Port")));
                Registry.Set("Port", port.ToString());
                this.PortDisplayLabelItem.Text = "Port: " + port;
                timerTickAsync(null, null);
            };
            PortSettingsMenuItem.DropDownItems.Add(PortSetManualMenuItem);

            this.LifetimePickerMenuItem.Text = "Time To Live";
            PortSettingsMenuItem.DropDownItems.Add(this.LifetimePickerMenuItem);

            WindowsServiceMenuItem.Text = "Windows Service";
            SettingsMenuItem.DropDownItems.Add(WindowsServiceMenuItem);

            this.RefreshWindowsServiceMenu();

            this.UpdateAvailableMenuItem.Visible = false;
            this.UpdateAvailableMenuItem.Text    = "Update Available!";
            this.UpdateAvailableMenuItem.Click  += new EventHandler(UpdateAvailableMenuItem_Click);
            this.TrayIconContextMenu.Items.Add(this.UpdateAvailableMenuItem);

            ToolStripMenuItem RefreshMenuItem = new ToolStripMenuItem();

            RefreshMenuItem.Text   = "Refresh";
            RefreshMenuItem.Click += new EventHandler(RefreshMenuItem_Click);
            this.TrayIconContextMenu.Items.Add(RefreshMenuItem);


            ToolStripMenuItem CloseMenuItem = new ToolStripMenuItem();

            CloseMenuItem.Text   = "Close";
            CloseMenuItem.Click += new EventHandler(CloseMenuItem_Click);
            this.TrayIconContextMenu.Items.Add(CloseMenuItem);

            TrayIconContextMenu.ResumeLayout(false);
            TrayIcon.ContextMenuStrip = TrayIconContextMenu;
        }
コード例 #2
0
        public async System.Threading.Tasks.Task <dynamic> SendAsync(INatDevice Router, string ApiKey, string Key)
        {
            try
            {
                this.ExternalIP = Router.GetExternalIP().ToString();
            }
            catch (Exception exc)
            {
                Debug.WriteLine(exc.Message);
                this.ExternalIP = "";
            }

            string Hostname = Dns.GetHostName();

            this.IsPortMapped = StaticHelpers.isPortMappedOnRouter(Router);

            ManagementObject os     = new ManagementObject("Win32_OperatingSystem=@");
            string           serial = (string)os["SerialNumber"];

            var values = new Dictionary <string, string>
            {
                { "status", IsPortMapped ? "open" : "closed" },
                { "rdpopen", StaticHelpers.isRDPAvailable() ? "1" : "0" },
                { "wanip", this.ExternalIP != null ? this.ExternalIP : "" },
                { "lanip", StaticHelpers.GetInternalIP() },
                { "port", Registry.Get("Port") },
                { "host", Hostname },
                { "interval", Registry.Get("Interval") },
                { "lifetime", Registry.Get("PortLifetime") },
                { "version", StaticHelpers.GetVersion() },
                { "guid", serial },
                { "serviceinstalled", StaticHelpers.IsServiceInstalled().ToString() },
                { "servicerunning", StaticHelpers.IsServiceRunning().ToString() }
            };

            var serializer = new JavaScriptSerializer();

            var content = new FormUrlEncodedContent(new Dictionary <string, string>
            {
                { "hostid", StaticHelpers.GetHostHash(Hostname) },
                { "apikey", ApiKey },
                { "payload", Harpocrates.Engine.Encrypt(serializer.Serialize(values), Key) }
            });

            // HttpWebRequest request = WebRequest.Create(Endpoint) as HttpWebRequest;
            // request.Proxy = new WebProxy(MyProxyHostString, MyProxyPort);

            // Send the API call
            HttpClient client   = new HttpClient();
            dynamic    response = await client.PostAsync(Endpoint, content);

            // Parse out the account TTL header
            IEnumerable <string> ttls;

            if (response.Headers.TryGetValues("ttl", out ttls))
            {
                foreach (string ttl in ttls)
                {
                    this.LifeTime = Int32.Parse(ttl);
                }
            }

            // Parse out version header
            IEnumerable <string> versions;

            if (response.Headers.TryGetValues("version", out versions))
            {
                foreach (string version in versions)
                {
                    this.Version = version;
                }
            }

            this.CommandWasProcessed = ProcessCommandHeader(Router, response, Key);

            // Create the machines List
            string responseString = await response.Content.ReadAsStringAsync();

            List <Dictionary <string, string> > RemoteMachinesRaw = new JavaScriptSerializer().Deserialize <List <Dictionary <string, string> > >(responseString);

            // If there was some error parsing the json, just quit here...
            if (RemoteMachinesRaw == null)
            {
                return(response);
            }

            foreach (var a in RemoteMachinesRaw)
            {
                RemoteMachineImportJson parsed;

                // First try to decrypt one return parameter for this machine
                // If decryption fails then other machine probably has different key
                try
                {
                    string payloadDecrypted = Harpocrates.Engine.Decrypt(a["payload"], Key);
                    parsed = serializer.Deserialize <RemoteMachineImportJson>(payloadDecrypted);
                }
                catch
                {
                    continue;
                }

                RemoteMachine x = new RemoteMachine();

                x.wanip            = parsed.wanip;
                x.lanip            = parsed.lanip;
                x.host             = parsed.host;
                x.port             = Int32.Parse(parsed.port);
                x.pending          = Convert.ToBoolean(Convert.ToInt32(a["pending"]));
                x.rdpopen          = Convert.ToBoolean(Convert.ToInt32(parsed.rdpopen));
                x.status           = parsed.status;
                x.version          = parsed.version;
                x.interval         = Int32.Parse(parsed.interval);
                x.lifetime         = Int32.Parse(parsed.lifetime);
                x.guid             = parsed.guid;
                x.servicerunning   = Boolean.Parse(parsed.servicerunning);
                x.serviceinstalled = Boolean.Parse(parsed.serviceinstalled);

                RemoteMachines.Add(x.host, x);
            }

            return(response);
        }
コード例 #3
0
        public async void timerTickAsync(object sender, EventArgs e)
        {
            Console.WriteLine("The timer ticked at {0:HH:mm:ss.fff}", DateTime.UtcNow);

            // Get some basic settings items out of the registry
            // which are required to make an API ping call
            string Key      = Registry.Get("Key");
            string ApiKey   = Registry.Get("ApiKey");
            string Interval = Registry.Get("Interval");

            // Protect application from crashing when important
            // settings values can not be found.
            if (ApiKey == "" || Interval == "" || Key == "")
            {
                return;
            }

            string host = Dns.GetHostName();

            // Reset timer interval incase it was changed in the settings
            this.loopTimer.Interval = Int32.Parse(Interval) * 1000;

            // If the router object is still being found, skip this ping
            if (Router == null)
            {
                this.TitleMenuItem.Image = Properties.Resources.bullet_yellow;

                this.TitleMenuItem.ToolTipText = "Your router does not seem to support all required features.";
            }
            else
            {
                this.TitleMenuItem.ToolTipText = "";
            }

            // Do something if the failed number of ping attempts is to high
            if (this.FailedPings > 3)
            {
                this.TitleMenuItem.Image = Properties.Resources.bullet_red;
            }
            else
            {
                this.TitleMenuItem.Image = Properties.Resources.bullet_green;
            }

            dynamic response;

            Ping = new PingRequest();

            try
            {
                response = await Ping.SendAsync(Router, ApiKey, Key);
            }
            catch (Exception exc)
            {
                Console.WriteLine(exc.Message);

                this.FailedPings++;

                return;
            }

            // Check with router to see if port is open
            // This allows the system to detect if port is still forwarded from a previous
            try
            {
                Mapping RoutedPort = this.Router.GetSpecificMapping(Protocol.Tcp, Int32.Parse(Registry.Get("Port")));
            }
            catch (Exception exc)
            {
            }
            this.isPortOpen = Ping.IsPortMapped;

            // If account is good, make menu header icon green
            if (Ping.LifeTime > 0)
            {
                this.TitleMenuItem.Image       = Properties.Resources.bullet_green;
                this.TitleMenuItem.ToolTipText = String.Format("Your API key is valid for {0} more days", Ping.LifeTime / (60 * 60 * 24));
            }

            // Display the update available menu item if update is available
            try
            {
                this.UpdateAvailableMenuItem.Visible = Ping.Version != null && Ping.Version != StaticHelpers.GetVersion();
            }
            catch (Exception exc)
            {
                Console.WriteLine(exc.Message);
            }

            // Keep running list of discovered machines, so that expired ones can be removed after
            List <string> machineList = new List <string>();

            if (Ping.RemoteMachines != null)
            {
                foreach (KeyValuePair <string, RemoteMachine> b in Ping.RemoteMachines)
                {
                    RemoteMachine x = b.Value;

                    string menukey = "menu___" + x.host;

                    machineList.Add(menukey);

                    // Remove any existing machine from the tray icon in a thread-safe way
                    if (TrayIconContextMenu.InvokeRequired)
                    {
                        TrayIconContextMenu.Invoke(new MethodInvoker(delegate
                        {
                            TrayIconContextMenu.Items.RemoveByKey(menukey);
                        }));
                    }
                    else
                    {
                        TrayIconContextMenu.Items.RemoveByKey(menukey);
                    }

                    ToolStripMenuItem HostMenuItem = this.CreateHostMenuItem(menukey, x);

                    // Add the menu item thread-safely
                    if (TrayIconContextMenu.InvokeRequired)
                    {
                        TrayIconContextMenu.Invoke(new MethodInvoker(delegate
                        {
                            this.TrayIconContextMenu.Items.Insert(2, HostMenuItem);
                        }));
                    }
                    else
                    {
                        this.TrayIconContextMenu.Items.Insert(2, HostMenuItem);
                    }
                }
            }

            List <string> removedMenuNames = new List <string>();

            // Remove expired entries
            foreach (var b in this.TrayIconContextMenu.Items)
            {
                ToolStripMenuItem test = b as ToolStripMenuItem;
                if (test != null && test.Name.Contains("menu___") && !machineList.Contains(test.Name))
                {
                    removedMenuNames.Add(test.Name);
                }
            }

            foreach (string removedMenuName in removedMenuNames)
            {
                this.TrayIconContextMenu.Items.RemoveByKey(removedMenuName);
            }

            // If this ping request resulted in commands which were processed, then a
            // new thread should run another ping request to send any updated status
            // back to the central server
            if (Ping.CommandWasProcessed == true)
            {
                new Thread(() =>
                {
                    Thread.CurrentThread.IsBackground = true;
                    timerTickAsync(null, null);
                }).Start();
            }

            // Refresh the interval value just incase it was changed
            this.SelectIntervalSetting(Int32.Parse(Registry.Get("Interval")));

            // Once a ping sequence has been fully completed, reset the fails counter
            this.FailedPings = 0;
        }