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

            // Create a session on the pfSense webserver
            HttpUtility.HttpCreateSession(pfSenseServer.ServerBaseUrl, cookieJar);

            Program.WriteOutput("Authenticating");

            // Authenticate the session
            var authenticationResult = HttpUtility.AuthenticateViaUrlEncodedFormMethod(string.Concat(pfSenseServer.ServerBaseUrl, "index.php"),
                                                                                       new Dictionary <string, string>(),
                                                                                       new Dictionary <string, string>
            {
                { "usernamefld", System.Web.HttpUtility.UrlEncode(pfSenseServer.Username) },
                { "passwordfld", System.Web.HttpUtility.UrlEncode(pfSenseServer.Password) },
                { "login", "Login" }
            },
                                                                                       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("Retrieving backup file");

            var downloadArgs = new Dictionary <string, string>
            {
                { "donotbackuprrd", pfSenseServer.BackupStatisticsData ? "" : "on" },
                { "nopackages", pfSenseServer.BackupPackageInfo ? "" : "on" },
                { "Submit", "Download configuration" }
            };

            string filename;
            var    pfSenseBackupFile = new PfSenseBackupFile
            {
                FileContents = HttpUtility.DownloadBackupFile(string.Concat(pfSenseServer.ServerBaseUrl, "diag_backup.php"),
                                                              new Dictionary <string, string>(),
                                                              downloadArgs,
                                                              cookieJar,
                                                              out filename,
                                                              timeout),
                FileName = filename
            };

            return(pfSenseBackupFile);
        }
示例#2
0
        /// <summary>
        /// Connects with the specified pfSense server using the v1.2 protocol implementation and returns the backup file contents
        /// </summary>
        /// <param name="pfSenseServer">pfSense server details which identifies which pfSense server to connect to</param>
        /// <param name="cookieJar">Cookie container to use through the communication with pfSense</param>
        /// <param name="timeout">Timeout in milliseconds on how long requests to pfSense may take. Default = 60000 = 60 seconds.</param>
        /// <returns>PfSenseBackupFile instance containing the retrieved backup content from pfSense</returns>
        public PfSenseBackupFile Execute(PfSenseServerDetails pfSenseServer, CookieContainer cookieJar, int timeout = 60000)
        {
            Program.WriteOutput("Retrieving backup file");

            var downloadArgs = new Dictionary <string, string>
            {
                { "nopackages", pfSenseServer.BackupPackageInfo ? "" : "on" },
                { "Submit", "Download configuration" }
            };

            string filename;
            var    pfSenseBackupFile = new PfSenseBackupFile
            {
                FileContents = HttpUtility.DownloadBackupFile(string.Concat(pfSenseServer.ServerBaseUrl, "diag_backup.php"),
                                                              downloadArgs,
                                                              cookieJar,
                                                              out filename,
                                                              timeout),
                FileName = filename
            };

            return(pfSenseBackupFile);
        }
示例#3
0
        /// <summary>
        /// Retrieves the backup file from pfSense
        /// </summary>
        private static void RetrieveBackupFile()
        {
            if (PfSenseServerDetails.UseHttps)
            {
                // Ignore all certificate related errors
                ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;

                // Also allow TLS 1.1 and TLS 1.2 to be used by the pfSense server. TLS 1.0 and SSLv3 are already allowed by default.
                ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
            }

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

            // Define the protocol implementation to use to communicate with pfSense
            Protocols.IPfSenseProtocol pfSenseProtocol = null;
            switch (PfSenseServerDetails.Version)
            {
            case "1.2":
                pfSenseProtocol = new Protocols.PfSenseVersion12();
                break;

            case "2.0":
                pfSenseProtocol = new Protocols.PfSenseVersion20();
                break;

            case "2.1":
            case "2.2":
                pfSenseProtocol = new Protocols.PfSenseVersion21();
                break;

            case "2.3":
                pfSenseProtocol = new Protocols.PfSenseVersion23();
                break;

            case "2.3.3":
                pfSenseProtocol = new Protocols.PfSenseVersion233();
                break;

            case "opn1907":
                pfSenseProtocol = new Protocols.OPNSenseVersion197();
                break;

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

            // Execute the communication with pfSense through the protocol implementation
            Protocols.PfSenseBackupFile pfSenseBackupFile = null;
            try
            {
                pfSenseBackupFile = pfSenseProtocol.Execute(PfSenseServerDetails, cookieJar, PfSenseServerDetails.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 (pfSenseBackupFile == null || string.IsNullOrEmpty(pfSenseBackupFile.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 pfSense, unless otherwise specified using the -o parameter.
            string outputPath;

            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 pfSense
                outputPath = Path.Combine(new FileInfo(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName).DirectoryName, pfSenseBackupFile.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 pfSense to store it in the by -o provided path
                    outputPath = Path.Combine(OutputFileName, pfSenseBackupFile.FileName);
                }
                else
                {
                    // Complete path including filename has been provided with the -o flag, use that to store the backup
                    outputPath = OutputFileName;
                }
            }

            WriteOutput($"Saving backup file to {outputPath}");

            // Store the backup contents in the file
            WriteBackupToFile(outputPath, pfSenseBackupFile.FileContents);

            // Check if we should look to remove old backups
            if (PfSenseServerDetails.BackupDaysToKeep.HasValue)
            {
                DeleteOldBackups(Directory.GetParent(outputPath).FullName, PfSenseServerDetails.BackupDaysToKeep.Value);
            }

            WriteOutput();
            WriteOutput("DONE");
        }
示例#4
0
        /// <summary>
        /// Connects with the specified pfSense server using the v2.1 and v2.2 implementation and returns the backup file contents
        /// </summary>
        /// <param name="pfSenseServer">pfSense server details which identifies which pfSense server to connect to</param>
        /// <param name="cookieJar">Cookie container to use through the communication with pfSense</param>
        /// <param name="timeout">Timeout in milliseconds on how long requests to pfSense may take. Default = 60000 = 60 seconds.</param>
        /// <returns>PfSenseBackupFile instance containing the retrieved backup content from pfSense</returns>
        public PfSenseBackupFile Execute(PfSenseServerDetails pfSenseServer, CookieContainer cookieJar, int timeout = 60000)
        {
            Program.WriteOutput("Connecting using protocol version {0}", new object[] { pfSenseServer.Version });

            // Create a session on the pfSense webserver
            var loginPageContents = HttpUtility.HttpGetLoginPageContents(pfSenseServer.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['\"].+?name=['\"]_+?csrf_magic['\"] value=['\"](?<xsstoken>.*?)['\"].+?/>", RegexOptions.IgnoreCase);

            // Verify that the anti XSS token was found
            if (!xssToken.Success)
            {
                xssToken = Regex.Match(loginPageContents, "var.*?csrfMagicToken.*?=.*?\"(?<xsstoken>.*?)\"");
            }

            // Authenticate the session
            var authenticationResult = HttpUtility.AuthenticateViaUrlEncodedFormMethod(string.Concat(pfSenseServer.ServerBaseUrl, "index.php"),
                                                                                       new Dictionary <string, string>
            {
                { "__csrf_magic", xssToken.Groups["xsstoken"].Value },
                { "usernamefld", System.Web.HttpUtility.UrlEncode(pfSenseServer.Username) },
                { "passwordfld", System.Web.HttpUtility.UrlEncode(pfSenseServer.Password) },
                { "login", "Login" }
            },
                                                                                       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("Retrieving backup file");

            var downloadArgs = new Dictionary <string, string>
            {
                { "donotbackuprrd", pfSenseServer.BackupStatisticsData ? "" : "on" },
                { "nopackages", pfSenseServer.BackupPackageInfo ? "" : "on" },
                { "encrypt", pfSenseServer.EncryptBackup ? "on" : "" },
                { "encrypt_password", pfSenseServer.EncryptionPassword },
                { "encrypt_passconf", pfSenseServer.EncryptionPassword },
                { "Submit", "Download configuration" }
            };

            string filename;
            var    pfSenseBackupFile = new PfSenseBackupFile
            {
                FileContents = HttpUtility.DownloadBackupFile(string.Concat(pfSenseServer.ServerBaseUrl, "diag_backup.php"),
                                                              downloadArgs,
                                                              cookieJar,
                                                              out filename,
                                                              timeout),
                FileName = filename
            };

            return(pfSenseBackupFile);
        }
        /// <summary>
        /// Connects with the specified OPNSense server using the 19.07 protocol implementation and returns the backup file contents
        /// </summary>
        /// <param name="pfSenseServer">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 PfSenseBackupFile Execute(PfSenseServerDetails pfSenseServer, CookieContainer cookieJar, int timeout = 60000)
        {
            Program.WriteOutput("Connecting using protocol version {0}", new object[] { pfSenseServer.Version });

            // Create a session on the OPNSense webserver
            var loginPageContents = HttpUtility.HttpGetLoginPageContents(pfSenseServer.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, @"xhr.setRequestHeader\(""X-CSRFToken"", ""(.*)"" \);", RegexOptions.IgnoreCase);

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

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

            Program.WriteOutput("Requesting backup file");

            // Get the backup page contents for the xsrf token
            var backupPageUrl = string.Concat(pfSenseServer.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, @"xhr.setRequestHeader\(""X-CSRFToken"", ""(.*)"" \);", RegexOptions.IgnoreCase);

            Program.WriteOutput("Retrieving backup file");

            var downloadArgs = new Dictionary <string, string>();

            downloadArgs.Add("download", "Download configuration");
            if (!pfSenseServer.BackupStatisticsData)
            {
                downloadArgs.Add("donotbackuprrd", "on");
            }
            if (pfSenseServer.EncryptBackup)
            {
                downloadArgs.Add("encrypt", "on");
                downloadArgs.Add("encrypt_password", pfSenseServer.EncryptionPassword);
                downloadArgs.Add("encrypt_passconf", pfSenseServer.EncryptionPassword);
            }

            string filename;
            var    pfSenseBackupFile = new PfSenseBackupFile
            {
                FileContents = HttpUtility.DownloadBackupFile(backupPageUrl,
                                                              new Dictionary <string, string>
                {
                    { "X-CSRFToken", xssToken.Groups[1].Value }
                },
                                                              downloadArgs,
                                                              cookieJar,
                                                              out filename,
                                                              timeout,
                                                              backupPageUrl),
                FileName = filename
            };

            return(pfSenseBackupFile);
        }