Ejemplo n.º 1
0
        /// <summary>
        /// Connects with the specified opnSense server using the v17.1 protocol implementation and returns the backup file contents
        /// </summary>
        /// <param name="opnSenseServer">opnSense server details which identifies which opnSense server to connect to</param>
        /// <param name="cookieJar">Cookie container to use through the communication with opnSense</param>
        /// <param name="timeout">Timeout in milliseconds on how long requests to opnSense may take. Default = 60000 = 60 seconds.</param>
        /// <returns>OpnSenseBackupFile instance containing the retrieved backup content from opnSense</returns>
        public OpnSenseBackupFile Execute(OpnSenseServerDetails opnSenseServer, CookieContainer cookieJar, int timeout = 60000)
        {
            Program.WriteOutput("Connecting using protocol version {0}", new object[] { opnSenseServer.Version });

            // Create a session on the opnSense webserver
            var loginPageContents = HttpUtility.HttpGetLoginPageContents(opnSenseServer.ServerBaseUrl, cookieJar, timeout);

            // Check if a response was returned from the login page request
            if (string.IsNullOrEmpty(loginPageContents))
            {
                throw new ApplicationException("Unable to retrieve login page contents");
            }

            Program.WriteOutput("Authenticating");

            // Use a regular expression to fetch the anti cross site scriping token from the HTML
            var xssToken = Regex.Match(loginPageContents, "<input.+?type=['\"]hidden['\"].+?id=['\"]_+?opnsense_csrf['\"].+?name=['\"](?<xsstokenname>.*?)['\"].+?value=['\"](?<xsstokenvalue>.*?)['\"].+?/>", RegexOptions.IgnoreCase);

            // Verify that the anti XSS token was found
            if (!xssToken.Success)
            {
                throw new ApplicationException("Unable to retrieve Cross Site Request Forgery token from login page");
            }

            // Authenticate the session
            var authenticationResult = HttpUtility.AuthenticateViaUrlEncodedFormMethod(string.Concat(opnSenseServer.ServerBaseUrl, "index.php"),
                                                                                       new Dictionary <string, string>
            {
                { xssToken.Groups["xsstokenname"].Value, xssToken.Groups["xsstokenvalue"].Value },
                { "usernamefld", System.Web.HttpUtility.UrlEncode(opnSenseServer.Username) },
                { "passwordfld", System.Web.HttpUtility.UrlEncode(opnSenseServer.Password) },
                { "login", "1" }
            },
                                                                                       cookieJar,
                                                                                       timeout);

            // Verify if the username/password combination was valid by examining the server response
            if (authenticationResult.Contains("Username or Password incorrect"))
            {
                throw new ApplicationException("ERROR: Credentials incorrect");
            }

            Program.WriteOutput("Requesting backup file");

            // Get the backup page contents for the xsrf token
            var backupPageUrl = string.Concat(opnSenseServer.ServerBaseUrl, "diag_backup.php");

            var backupPageContents = HttpUtility.HttpGetLoginPageContents(backupPageUrl, cookieJar, timeout);

            // Check if a response was returned from the login page request
            if (string.IsNullOrEmpty(backupPageContents))
            {
                throw new ApplicationException("Unable to retrieve backup page contents");
            }

            // Use a regular expression to fetch the anti cross site scriping token from the HTML
            xssToken = Regex.Match(backupPageContents, "<input.+?type=['\"]hidden['\"].+?id=['\"]_+?opnsense_csrf['\"].+?name=['\"](?<xsstokenname>.*?)['\"].+?value=['\"](?<xsstokenvalue>.*?)['\"].+?/>", RegexOptions.IgnoreCase);

            // Verify that the anti XSS token was found
            if (!xssToken.Success)
            {
                throw new ApplicationException("Unable to retrieve Cross Site Request Forgery token from backup page");
            }

            Program.WriteOutput("Retrieving backup file");

            var downloadArgs = new Dictionary <string, string>
            {
                { xssToken.Groups["xsstokenname"].Value, xssToken.Groups["xsstokenvalue"].Value },
                { "donotbackuprrd", opnSenseServer.BackupStatisticsData ? "" : "on" },
                { "encrypt", opnSenseServer.EncryptBackup ? "on" : "" },
                { "encrypt_password", opnSenseServer.EncryptionPassword },
                { "encrypt_passconf", opnSenseServer.EncryptionPassword },
                { "download", "Download configuration" },
                { "restorearea", "" },
                { "rebootafterrestore", "on" },
                { "decrypt_password", "" },
                { "decrypt_passconf", "" }
            };

            string filename;
            var    opnSenseBackupFile = new OpnSenseBackupFile
            {
                FileContents = HttpUtility.DownloadBackupFile(backupPageUrl,
                                                              downloadArgs,
                                                              cookieJar,
                                                              out filename,
                                                              timeout,
                                                              backupPageUrl),
                FileName = filename
            };

            return(opnSenseBackupFile);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Retrieves the backup file from opnSense
        /// </summary>
        private static void RetrieveBackupFile()
        {
            if (OpnSenseServerDetails.UseHttps)
            {
                // Ignore all certificate related errors
                ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
            }

            // Create a cookie container to hold the session cookies
            var cookieJar = new CookieContainer();

            // Define the protocol implementation to use to communicate with opnSense
            Protocols.IOpnSenseProtocol opnSenseProtocol = null;
            switch (OpnSenseServerDetails.Version)
            {
            case "17.1":
                opnSenseProtocol = new Protocols.OpnSenseVersion171();
                break;

            default:
                WriteOutput("Unsupported opnSense version provided ({0})", new object[] { OpnSenseServerDetails.Version });
                Environment.Exit(1);
                break;
            }

            // Execute the communication with opnSense through the protocol implementation
            Protocols.OpnSenseBackupFile opnSenseBackupFile = null;
            try
            {
                opnSenseBackupFile = opnSenseProtocol.Execute(OpnSenseServerDetails, cookieJar, OpnSenseServerDetails.RequestTimeOut.GetValueOrDefault(60000));
            }
            catch (Exception e)
            {
                WriteOutput("Error: {0}", new object[] { e.Message });
                Environment.Exit(1);
            }

            // Verify that the backup file returned contains content
            if (opnSenseBackupFile == null || string.IsNullOrEmpty(opnSenseBackupFile.FileContents))
            {
                WriteOutput("No valid backup contents returned");
                Environment.Exit(1);
            }

            // Define the full path to the file to store the backup in. By default this will be in the same directory as this application runs from using the filename provided by opnSense, unless otherwise specified using the -o parameter.
            string outputDirectory;

            if (string.IsNullOrEmpty(OutputFileName))
            {
                // -o flag has not been provided, store the file in the same directory as this tool runs using the same filename as provided by opnSense
                outputDirectory = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), opnSenseBackupFile.FileName);
            }
            else
            {
                // -o flag has been provided, check if just a path was provided or a path including filename
                if (Directory.Exists(OutputFileName))
                {
                    // Path was provided, use the filename as provided by opnSense to store it in the by -o provided path
                    outputDirectory = Path.Combine(OutputFileName, opnSenseBackupFile.FileName);
                }
                else
                {
                    // Complete path including filename has been provided with the -o flag, use that to store the backup
                    outputDirectory = OutputFileName;
                }
            }

            WriteOutput(string.Concat("Saving backup file to ", outputDirectory));

            // Store the backup contents in the file
            WriteBackupToFile(outputDirectory, opnSenseBackupFile.FileContents);

            WriteOutput();
            WriteOutput("DONE");
        }