public bool DoWork(Util.UpdateStatusDelegate SetStatus, Util.ShouldCancelDelegate ShouldCancel) { SetStatus("Connecting to SSH...", 0); using (VyattaShell Shell = new VyattaShell(Data.Address, Data.Username, Data.Password)) { SetStatus("Killing DNSCrypt if running...", 10); RouterEnableDNSCrypt.KillDNSCrypt(Shell); SetStatus("Killing DNSCrypt if running...", 30); Shell.RunCommand("configure"); Shell.RunCommand("delete service dns forwarding options"); SetStatus("Committing changes...", 60); Shell.RunCommand("commit"); Shell.RunCommand("save"); Shell.RunCommand("exit"); SetStatus("Restarting dnsmasq...", 80); Shell.RunCommand("sudo /etc/init.d/dnsmasq restart"); } SetStatus("Completed.", 100); return(true); }
static public void KillDNSCrypt(VyattaShell Shell) { string RunningDNSCrypt = Shell.RunCommand("sudo ps ax | grep '[d]nscrypt-proxy'"); var MatchDNSCryptProcess = new Regex(@"\W+(\d+)\W+\w+\W+\d+:\d+\W+dnscrypt-proxy.*"); var MatchDNSCryptProcessResult = MatchDNSCryptProcess.Match(RunningDNSCrypt); if (MatchDNSCryptProcessResult.Success) { //DNSCrypt is currently running Shell.RunCommand(string.Format("sudo kill {0}", MatchDNSCryptProcessResult.Groups[1].Value)); } }
public bool FreeUpPreviousImage(VyattaShell Shell, string CommandResult) { if (CommandResult.Contains("No space left on device") || CommandResult.Contains("Not found") || CommandResult.Contains("not found") || CommandResult.Contains("Some index files failed to download")) { if (MessageBox.Show("You've run out of disk space on your device,\ndo you want to free up some space by\ndeleting the previous system image?", "Out of disk space!", MessageBoxButtons.YesNoCancel) == DialogResult.Yes) { Shell.RunCommand("sudo delete system image"); Shell.RunCommand("sudo rm -rf /root.dev/w.*"); Shell.RunCommand("sudo apt-get autoclean"); return(true); } } return(false); }
public bool DoWork(Util.UpdateStatusDelegate SetStatus, Util.ShouldCancelDelegate ShouldCancel) { if (ShouldCancel()) { return(false); } SetStatus("Connecting to SSH...", 0); using (VyattaShell Shell = new VyattaShell(Data.Address, Data.Username, Data.Password)) { if (ShouldCancel()) { return(false); } //Verify that we can identify the device SetStatus("Identifying device...", 5); var Version = Shell.RunCommand("cat /proc/version"); if (!Version.Contains("edgeos")) { throw new Exception("The device is not running EdgeOS and is not supported. Device "); } if (ShouldCancel()) { return(false); } //Enter configure mode SetStatus("Processing routing interfaces...", 8); Dictionary <string, string> Gateways = IPRoute.GetDefaultGateways(Shell); SetStatus("Processing interface list...", 16); string ShowInterfaces = Shell.RunCommand("show interfaces"); Regex ParseInterfaces = new Regex(@"([\w\.]+)\s+([0-9.\-]+(:?\/[0-9]+)?)\s+(\w\/\w)\s+(\w+)?"); Data.Interfaces = new ObservableCollection <InterfaceMapping>(); string[] InterfaceLines = ShowInterfaces.Split(new char[] { '\n' }); foreach (string Line in InterfaceLines) { Match Match = ParseInterfaces.Match(Line); if (Match.Success) { InterfaceMapping Mapping = new InterfaceMapping(); Mapping.Interface = Match.Groups[1].Value; Mapping.IPAddress = Match.Groups[2].Value == "-" ? "" : Match.Groups[2].Value; Mapping.Codes = Match.Groups[4].Value; Mapping.Description = Match.Groups[5].Value; string Gateway; if (Gateways.TryGetValue(Mapping.Interface, out Gateway)) { Mapping.Gateway = Gateway; } Data.Interfaces.Add(Mapping); } } } SetStatus("Connecting over SCP...", 60); if (ShouldCancel()) { return(false); } using (ScpClient Client = new ScpClient(Data.Address, Data.Username, Data.Password)) { Client.Connect(); if (ShouldCancel()) { return(false); } SetStatus("Downloading config...", 80); using (Stream tempFile = new FileStream(TempPath, FileMode.CreateNew)) { Client.Download("/config/config.boot", tempFile); } SetStatus("Parsing existing config...", 85); string Errors = ""; Data.OldConfigLines = File.ReadAllLines(TempPath); Data.ConfigRoot = VyattaConfigUtil.ReadFromFile(TempPath, ref Errors); if (Errors.Length > 0) { throw new Exception(Errors); } SetStatus("Downloading current template...", 90); try { using (Stream tempTemplateFile = new FileStream(TempTemplatePath, FileMode.CreateNew)) { Client.Download("/config/vcu/current.vcu", tempTemplateFile); } SetStatus("Parsing current template...", 95); Errors = ""; Data.TemplateRoot = VyattaConfigUtil.ReadFromFile(TempTemplatePath, ref Errors); if (Errors.Length > 0) { throw new Exception(Errors); } } catch (SshException e) { if (!e.Message.Contains("No such file or directory")) { throw e; } //It's quite okay to fail here, it means the user hasn't uploaded //a config with the tool yet. Data.TemplateRoot = new VyattaConfigObject(null); } if (ShouldCancel()) { return(false); } SetStatus("Disconnecting...", 98); Client.Disconnect(); } SetStatus("Completed.", 100); return(true); }
public bool DoWork(Util.UpdateStatusDelegate SetStatus, Util.ShouldCancelDelegate ShouldCancel) { SetStatus("Flushing local DNS cache...", 0); try { string IPConfigPath = Environment.ExpandEnvironmentVariables(@"%SystemRoot%\System32\ipconfig.exe"); var IPConfig = Process.Start(IPConfigPath, "/flushdns"); if (IPConfig == null) { throw new Exception("Unable to flush local DNS cache. Could not run ipconfig."); } IPConfig.WaitForExit(); } catch (Exception) { throw new Exception("Unable to flush local DNS cache. Could not run ipconfig."); } SetStatus("Connecting to SSH and SCP...", 5); using (VyattaShell Shell = new VyattaShell(Data.Address, Data.Username, Data.Password)) { using (ScpClient Client = new ScpClient(Data.Address, Data.Username, Data.Password)) { Client.Connect(); SetStatus("Grabbing dnsmasq config...", 10); string DNSMasqConfigPath = Path.ChangeExtension(Path.GetTempFileName(), Guid.NewGuid().ToString()); string NewDNSMasqConfigPath = Path.ChangeExtension(Path.GetTempFileName(), Guid.NewGuid().ToString()); using (Stream tempFile = new FileStream(DNSMasqConfigPath, FileMode.CreateNew)) { Client.Download("/etc/dnsmasq.conf", tempFile); } SetStatus("Backing up dnsmasq config...", 15); Shell.RunCommand("sudo cp /etc/dnsmasq.conf /etc/dnsmasq.conf.bak"); SetStatus("Processing config file...", 20); string[] ConfigFile = File.ReadAllLines(DNSMasqConfigPath); for (int LineIndex = 0; LineIndex < ConfigFile.Length; LineIndex++) { //Comment out log related lines if (ConfigFile[LineIndex].StartsWith("log-") || ConfigFile[LineIndex].StartsWith("cache-size=")) { ConfigFile[LineIndex] = "#" + ConfigFile[LineIndex]; } } string[] ConfigFileFooter = new string[] { "log-queries", //"log-async=25", // This just confuses the log and makes it more difficult to parse. "log-facility=/tmp/dnslog.txt", "cache-size=0" }; string[] ConfigFileFinal = new string[ConfigFile.Length + ConfigFileFooter.Length]; ConfigFile.CopyTo(ConfigFileFinal, 0); ConfigFileFooter.CopyTo(ConfigFileFinal, ConfigFile.Length); using (TextWriter FileOut = new StreamWriter(NewDNSMasqConfigPath)) { FileOut.NewLine = "\n"; foreach (var Line in ConfigFileFinal) { FileOut.WriteLine(Line); } } SetStatus("Uploading new temporary config file...", 30); using (Stream uploadFile = new FileStream(NewDNSMasqConfigPath, FileMode.Open)) { Client.Upload(uploadFile, "/tmp/NewConfigFile"); } SetStatus("Preparing config file...", 40); Shell.RunCommand("sudo cp /tmp/NewConfigFile /etc/dnsmasq.conf"); Shell.RunCommand("rm /tmp/NewConfigFile"); Shell.RunCommand("sudo chmod 0644 /etc/dnsmasq.conf"); SetStatus("Restarting dnsmasq...", 60); //Do stop/start separately so we can delete the file in case //something went wrong previously. Shell.RunCommand("sudo /etc/init.d/dnsmasq stop"); Shell.RunCommand("sudo rm /tmp/dnslog.txt"); Shell.RunCommand("sudo /etc/init.d/dnsmasq start"); SetStatus("Collecting data, press Cancel to stop...", 100); while (!ShouldCancel()) { System.Threading.Thread.Sleep(100); } SetStatus("Restarting dnsmasq as normal...", 0); //Restore backup Shell.RunCommand("sudo cp /etc/dnsmasq.conf.bak /etc/dnsmasq.conf"); //Restart dnsmasq with the old config again Shell.RunCommand("sudo /etc/init.d/dnsmasq restart"); SetStatus("Downloading collected data...", 50); LogPath = Path.ChangeExtension(Path.GetTempFileName(), Guid.NewGuid().ToString()); Shell.RunCommand("sudo chmod 777 /tmp/dnslog.txt"); using (Stream tempFile = new FileStream(LogPath, FileMode.CreateNew)) { Client.Download("/tmp/dnslog.txt", tempFile); } //Delete the log file now we've got it. Shell.RunCommand("sudo rm /tmp/dnslog.txt"); SetStatus("Disconnecting.", 95); Client.Disconnect(); } } SetStatus("Completed.", 100); return(true); }
public bool DoWork(Util.UpdateStatusDelegate SetStatus, Util.ShouldCancelDelegate ShouldCancel) { SetStatus("Connecting to SSH...", 0); using (VyattaShell Shell = new VyattaShell(Data.Address, Data.Username, Data.Password)) { SetStatus("Checking for wget...", 5); string DoesWgetExist = Shell.RunCommand("wget"); if (DoesWgetExist.Contains("command not found")) { SetStatus("Adding main debian sources...", 10); Shell.RunCommand("configure"); Shell.RunCommand("set system package repository wheezy components 'main contrib non-free'"); Shell.RunCommand("set system package repository wheezy distribution wheezy"); Shell.RunCommand("set system package repository wheezy url http://http.us.debian.org/debian"); SetStatus("Committing changes...", 10); Shell.RunCommand("commit"); Shell.RunCommand("save"); Shell.RunCommand("exit"); var WgetResult = Shell.RunCommand("sudo apt-get install wget"); if (WgetResult.Contains("Package 'wget' has no installation candidate") || WgetResult.Contains("Unable to locate package wget")) { Prev: SetStatus("Updating package lists...", 15); var UpdateResult = Shell.RunCommand("sudo apt-get update"); if (FreeUpPreviousImage(Shell, UpdateResult)) { goto Prev; } if (UpdateResult.Contains("Not Found") || UpdateResult.Contains("not Found")) { string[] Lines = UpdateResult.Split(new [] { '\n' }, StringSplitOptions.RemoveEmptyEntries); int Max5Lines = Lines.Length - 5; string LastUpdateBlock = string.Join("\n", Lines, Max5Lines, Lines.Length - Math.Max(Max5Lines, 0)); throw new Exception("One or more packages was not found:\n" + LastUpdateBlock); } Prev2: SetStatus("Installing wget...", 20); WgetResult = Shell.RunCommand("sudo apt-get install wget"); if (WgetResult.Contains("Package 'wget' has no installation candidate") || WgetResult.Contains("Unable to locate package wget")) { string[] Lines = UpdateResult.Split(new [] { '\n' }, StringSplitOptions.RemoveEmptyEntries); int Max5Lines = Lines.Length - 5; string LastUpdateBlock = string.Join("\n", Lines, Max5Lines, Lines.Length - Math.Max(Max5Lines, 0)); throw new Exception("Unable to install wget:\n" + LastUpdateBlock + WgetResult); } if (FreeUpPreviousImage(Shell, UpdateResult)) { goto Prev2; } SetStatus("Checking wget...", 25); string RecheckWget = Shell.RunCommand("wget"); if (!RecheckWget.Contains("wget: missing URL")) { throw new Exception("wget not found after installation."); } } } else if (!DoesWgetExist.Contains("wget: missing URL")) { throw new Exception("Unknown state - could not determine if wget exists."); } if (ShouldCancel()) { return(false); } SetStatus("Checking for Entware...", 30); string DoesOpkgExist = Shell.RunCommand("/opt/bin/opkg"); if (DoesOpkgExist.Contains("No such file or directory")) { SetStatus("Installing Entware...", 32); string GetInstaller = Shell.RunCommand("wget -O - https://pkg.entware.net/binaries/mipsel/installer/installer.sh | sudo sh"); if (GetInstaller.Contains("Connection refused")) { if (MessageBox.Show("The connection to the Entware package server was refused over https.\nDo you want to try again over http? This might indicate a problem on their server or an attempt to interfere with your installation.", "Try again over an insecure connection?", MessageBoxButtons.YesNoCancel) == DialogResult.Yes) { Shell.RunCommand("wget -O - http://pkg.entware.net/binaries/mipsel/installer/installer.sh | sudo sh"); } else { return(false); } } SetStatus("Checking for Entware...", 60); DoesOpkgExist = Shell.RunCommand("/opt/bin/opkg"); if (!DoesOpkgExist.Contains("usage: opkg")) { throw new Exception("Unknown state - could not determine if opkg exists."); } } else if (!DoesOpkgExist.Contains("usage: opkg")) { throw new Exception("Unknown state - could not determine if opkg exists."); } if (ShouldCancel()) { return(false); } SetStatus("Checking for newer packages...", 61); Shell.RunCommand("sudo /opt/bin/opkg update"); SetStatus("Checking for DNSCrypt...", 63); bool WasInstalled = false; string DoesDNSCryptExist = Shell.RunCommand("/opt/sbin/dnscrypt-proxy --help"); if (DoesDNSCryptExist.Contains("No such file or directory")) { SetStatus("Installing DNSCrypt...", 66); Shell.RunCommand("sudo /opt/bin/opkg install dnscrypt-proxy", new Regex("Choose server from list or hit Enter to continue"), ChooseResolver); DoesDNSCryptExist = Shell.RunCommand("/opt/sbin/dnscrypt-proxy --help"); if (!DoesDNSCryptExist.Contains("dnscrypt-proxy ")) { throw new Exception("Unknown state - could not determine if DNSCrypt exists."); } WasInstalled = true; } else if (!DoesDNSCryptExist.Contains("dnscrypt-proxy ")) { throw new Exception("Unknown state - could not determine if DNSCrypt exists."); } if (ShouldCancel()) { return(false); } if (!WasInstalled) { //It's entirely possible that we've changed something and we previously had DNSCrypt running //So we should find it and kill it. SetStatus("Killing DNSCrypt if running...", 68); KillDNSCrypt(Shell); Shell.RunCommand("sudo /opt/bin/opkg upgrade dnscrypt-proxy", new Regex("Choose server from list or hit Enter to continue"), ChooseResolver); } if (ShouldCancel()) { return(false); } SetStatus("Connecting via SCP...", 80); string DNSCryptProxyPort = "65053"; using (ScpClient Client = new ScpClient(Data.Address, Data.Username, Data.Password)) { Client.Connect(); if (ShouldCancel()) { return(false); } SetStatus("Downloading daemon profile...", 85); string OriginalDaemonPath = Path.ChangeExtension(Path.GetTempFileName(), Guid.NewGuid().ToString()); string NewDaemonPath = Path.ChangeExtension(Path.GetTempFileName(), Guid.NewGuid().ToString()); string DNSCryptResolvers = Path.ChangeExtension(Path.GetTempFileName(), Guid.NewGuid().ToString()); string StartupScriptPath = Path.ChangeExtension(Path.GetTempFileName(), Guid.NewGuid().ToString()); using (Stream tempFile = new FileStream(OriginalDaemonPath, FileMode.CreateNew)) { Client.Download("/opt/etc/init.d/S09dnscrypt-proxy", tempFile); } SetStatus("Downloading resolver list...", 87); using (Stream tempFile = new FileStream(DNSCryptResolvers, FileMode.CreateNew)) { Client.Download("/opt/share/dnscrypt-proxy/dnscrypt-resolvers.csv", tempFile); } SetStatus("Processing daemon file...", 88); string[] DaemonFile = File.ReadAllLines(OriginalDaemonPath); string LocalAddress = "--local-address=127.0.0.1:"; string Resolver = "-R "; //First match group is the port it starts on, the second is the current var DaemonArgsRegex = new Regex(@".*" + LocalAddress + @"(\d+).*" + Resolver + @"([\w.-]+).*"); for (int LineIndex = 0; LineIndex < DaemonFile.Length; LineIndex++) { if (DaemonFile[LineIndex].StartsWith("ARGS=")) { var Match = DaemonArgsRegex.Match(DaemonFile[LineIndex]); if (!Match.Success) { throw new Exception("Unable to parse dnscrypt-proxy arg line: " + DaemonFile[LineIndex]); } DNSCryptProxyPort = Match.Groups[1].Value; var OldResolverName = Match.Groups[2].Value; var ResolverName = Match.Groups[2].Value; bool Aborted = false; Parent.Invoke(new Action(() => { var PickDNS = new DNSCryptResolverPicker(DNSCryptResolvers); if (PickDNS.ShowDialog() != DialogResult.OK) { Aborted = true; } ResolverName = PickDNS.GetPickedResolver(); })); if (Aborted) { return(false); } DaemonFile[LineIndex] = DaemonFile[LineIndex].Replace(Resolver + OldResolverName, Resolver + ResolverName); } } SetStatus("Uploading new daemon file...", 88); using (TextWriter FileOut = new StreamWriter(NewDaemonPath)) { FileOut.NewLine = "\n"; foreach (var Line in DaemonFile) { FileOut.WriteLine(Line); } } using (Stream uploadFile = new FileStream(NewDaemonPath, FileMode.Open)) { Client.Upload(uploadFile, "/tmp/NewDaemonProfile"); } Shell.RunCommand("sudo cp /tmp/NewDaemonProfile /opt/etc/init.d/S09dnscrypt-proxy"); Shell.RunCommand("rm /tmp/NewDaemonProfile"); Shell.RunCommand("sudo chmod 0755 /opt/etc/init.d/S09dnscrypt-proxy"); SetStatus("Uploading new startup script...", 90); string[] StartupScript = new string[] { "#!/bin/bash", "sudo /opt/etc/init.d/S09dnscrypt-proxy start", "exit" }; using (TextWriter FileOut = new StreamWriter(StartupScriptPath)) { FileOut.NewLine = "\n"; foreach (var Line in StartupScript) { FileOut.WriteLine(Line); } } using (Stream uploadFile = new FileStream(StartupScriptPath, FileMode.Open)) { Client.Upload(uploadFile, "/tmp/NewStartupScript"); } Client.Disconnect(); } Shell.RunCommand("sudo cp /tmp/NewStartupScript /config/scripts/post-config.d/start_dnscrypt.sh"); Shell.RunCommand("rm /tmp/NewStartupScript"); Shell.RunCommand("sudo chmod 0755 /config/scripts/post-config.d/start_dnscrypt.sh"); SetStatus("Starting DNSCrypt...", 92); Shell.RunCommand("sudo /config/scripts/post-config.d/start_dnscrypt.sh"); SetStatus("Configuring dnsmasq to use DNSCrypt...", 94); Shell.RunCommand("configure"); Shell.RunCommand(string.Format("set service dns forwarding options \"server=127.0.0.1#{0}\"", DNSCryptProxyPort)); Shell.RunCommand("set service dns forwarding options proxy-dnssec"); //WARNING: This line disables all other forms of DNS. If DNSCrypt is not working you'll lose DNS completely. Shell.RunCommand("set service dns forwarding options no-resolv"); SetStatus("Committing changes...", 96); Shell.RunCommand("commit"); Shell.RunCommand("save"); Shell.RunCommand("exit"); SetStatus("Restarting dnsmasq...", 98); Shell.RunCommand("sudo /etc/init.d/dnsmasq restart"); } //^(\d+\))\W+([a-zA-Z0-9\-.]+)\W+\((.*)\)$ SetStatus("Completed.", 100); return(true); }
public bool DoWork(Util.UpdateStatusDelegate SetStatus, Util.ShouldCancelDelegate ShouldCancel) { SetStatus("Connecting to SSH...", 0); using (VyattaShell Shell = new VyattaShell(Data.Address, Data.Username, Data.Password)) { SetStatus("Creating backup...", 5); Shell.RunCommand("mkdir /config/vcu"); Shell.RunCommand("cp /config/config.boot /config/vcu/previous.boot"); Shell.RunCommand("cp /config/current.vcu /config/vcu/previous.vcu"); Shell.RunCommand(string.Format("cp /config/config.boot /config/vcu/history_{0}.boot", DateTime.Now.ToString(VyattaConfigUtil.SortableDateFormat))); Shell.RunCommand(string.Format("cp /config/current.vcu /config/vcu/history_{0}.vcu", DateTime.Now.ToString(VyattaConfigUtil.SortableDateFormat))); SetStatus("Entering configure mode...", 10); Shell.RunCommand("configure"); if (!ShouldCancel()) { using (ScpClient ScpClient = new ScpClient(Data.Address, Data.Username, Data.Password)) { string TempConfigPath = Path.ChangeExtension(Path.GetTempFileName(), Guid.NewGuid().ToString()); Data.NewConfigLines = VyattaConfigUtil.WriteToStringLines(Data.ConfigRoot); VyattaConfigUtil.WriteToFile(Data.ConfigRoot, TempConfigPath); string TempTemplatePath = Path.ChangeExtension(Path.GetTempFileName(), Guid.NewGuid().ToString()); VyattaConfigUtil.WriteToFile(Data.TemplateRoot, TempTemplatePath); ScpClient.Connect(); SetStatus("Uploading new config...", 15); if (!ShouldCancel()) { using (Stream configFile = new FileStream(TempConfigPath, FileMode.Open)) { ScpClient.Upload(configFile, "/config/config.boot"); } } //Probably shouldn't cancel after this point it might leave things in a weird state... using (Stream templateFile = new FileStream(TempTemplatePath, FileMode.Open)) { ScpClient.Upload(templateFile, "/config/current.vcu"); } SetStatus("Disconnecting SCP...", 20); ScpClient.Disconnect(); } } SetStatus("Loading new config...", 25); Shell.RunCommand("load"); SetStatus("Comparing config...", 35); Shell.RunCommand("compare"); SetStatus("Committing new config (this will take a while)...", 45); string CommitResult = Shell.RunCommand("commit"); if (CommitResult.Contains("Commit failed")) { //Restore the backup Shell.RunCommand("cp /config/vcu/previous.boot /config/config.boot"); Shell.RunCommand("load"); Shell.RunCommand("commit"); Shell.RunCommand("exit"); throw new Exception(CommitResult); } SetStatus("Committing new config (this will take a while)...", 95); Shell.RunCommand("exit"); SetStatus("Disconnecting from SSH...", 98); } SetStatus("Completed.", 100); return(true); }