Skip to content

Commit

Permalink
Merge pull request #11 from jaredhendrickson13/v111
Browse files Browse the repository at this point in the history
v1.1.1 Fixes & Features
  • Loading branch information
jaredhendrickson13 authored Jan 2, 2022
2 parents de4e660 + 17a4307 commit 27f9350
Show file tree
Hide file tree
Showing 19 changed files with 579 additions and 141 deletions.
36 changes: 36 additions & 0 deletions .github/ISSUE_TEMPLATE/bug-report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
name: Bug Report
about: Report a bug or problem
title: ''
labels: ''
assignees: ''

---

**Describe the bug**
A clear and concise description of what the bug is. Please note, IdP implementation and/or incompatibility should **not** be classified as a bug report.

**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**Expected behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**pfSense Version & Package Version:**
- pfSense Version: [e.g. pfSense 2.5.1]
- Package Version [e.g. v1.1.0]

**Identity Provider Information:**
- IdP Name: [e.g. Okta, OneLogin, Google]
- IdP Type: [e.g. internal, cloud, SaaS]
- IdP Website: [e.g. www.okta.com]

**Additional context**
Add any other context about the problem here.
19 changes: 19 additions & 0 deletions docs/SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Security Policy

## Supported Versions

Below are versions that are currently supported and will receive security updates when available.

| Version | Supported |
| ------- | ------------------ |
| 1.1.x | :white_check_mark: |
| 1.0.x | :x: |

## Reporting a Vulnerability

Should you discover a vulnerability in the pfSense SAML2 authentication code, please report the issue in one of the following ways:
1) A pull request with code that fixes the discovered vulnerability
2) A private email to either the project owner or the respective code owner
3) As a last resort, you may open a public issue on the repository

Please note this is an independent and open-source project and no bug bounty or reward can be granted.
4 changes: 2 additions & 2 deletions pfSense-pkg-saml2-auth/files/etc/inc/priv/saml2_auth.priv.inc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?php
// Copyright 2021 Jared Hendrickson
// Copyright 2022 Jared Hendrickson
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -19,4 +19,4 @@ $priv_list['page-system-saml2-auth'] = array();
$priv_list['page-system-saml2-auth']['name'] = "WebCfg - System: SAML2 authentication package";
$priv_list['page-system-saml2-auth']['descr'] = "Allow access to SAML2 authentication package UI";
$priv_list['page-system-saml2-auth']['match'] = array();
$priv_list['page-system-saml2-auth']['match'][] = "saml2_auth*";
$priv_list['page-system-saml2-auth']['match'][] = "saml2_auth*";
203 changes: 194 additions & 9 deletions pfSense-pkg-saml2-auth/files/etc/inc/saml2_auth/SAML2Auth.inc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?php
// Copyright 2021 Jared Hendrickson
// Copyright 2022 Jared Hendrickson
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -18,20 +18,25 @@ require_once("config.inc");

class SAML2Auth {
public $auth;
public $file_path;
private $config;

# Constructs the saml2_auth object by loading SAML2 settings and creating the OneLogin_Saml2_Auth object
public function __construct() {
public function __construct($no_auth=false) {
session_start();
global $config;
$this->config = $config;
$this->file_path = "/usr/local/share/pfSense-pkg-saml2-auth";

# Try to start SAML2 authentication, handle errors accordingly
try {
$this->auth = new OneLogin\Saml2\Auth($this::get_saml_settings());
} catch (OneLogin\Saml2\Error $error) {
echo $error->getMessage().PHP_EOL;
exit();
# Only try to start authentication if the object wasn't requested without authentication
if (!$no_auth) {
# Try to start SAML2 authentication, handle errors accordingly
try {
$this->auth = new OneLogin\Saml2\Auth($this::get_saml_settings());
} catch (OneLogin\Saml2\Error $error) {
echo $error->getMessage().PHP_EOL;
exit();
}
}
}

Expand Down Expand Up @@ -101,6 +106,14 @@ class SAML2Auth {
}
}

# Writes log data
private function __log($msg, $console=false) {
# Print our log message to the console if requested
if ($console) {
echo $msg;
}
}

public function get_saml2_errors() {
# Print SAML errors if they exist
if (!empty($this->auth->getErrors())) {
Expand Down Expand Up @@ -159,5 +172,177 @@ class SAML2Auth {
return $php_saml_config;
}

# Fetches the current version of pfSense
public static function get_pfsense_version($full=false) {
# Only display the full release name if requested, Otherwise only provide the major and minor.
return ($full) ? str_replace(PHP_EOL, "", file_get_contents("/etc/version")) : substr(file_get_contents("/etc/version"), 0, 3);
}

public static function get_pkg_version() {
# Pull the raw pkg info for the SAML2 auth package into an array for each line
$pkg_info = explode(PHP_EOL, shell_exec("pkg info pfSense-pkg-saml2-auth"));

# Loop through each line and check the version
foreach ($pkg_info as $pkg_line) {
if (substr($pkg_line, 0, 7 ) === "Version") {
# Locate the version and format it to a standard semantic version format (x.x.x)
$version = str_replace(" ", "", $pkg_line);
$version = explode(":", $version)[1];
$version = (strlen($version) === 3) ? $version.".0" : $version;
$version = str_replace("_", ".", $version);
return $version;
}
}
}

public static function get_latest_pkg_version() {
# Fetch our latest version and format it semantically (x.x.x)
$latest_version = array_key_first(self::get_all_pkg_versions());
$latest_version = str_replace("v", "", $latest_version);
return $latest_version;
}

public static function get_latest_pkg_release_date() {
# Loop through each release and locate the latest available releases creation date
foreach (self::get_pkg_releases()["releases"] as $release) {
# Check if this releases is latest available for our platform
if ($release["tag_name"] === "v".self::get_latest_pkg_version()) {
return $release["created_at"];
}
}
}

public static function is_update_available() {
# Check if the current version is less than the latest version
$curr_ver_num = intval(str_replace(".", "", self::get_pkg_version()));
$latest_ver_num = intval(str_replace(".", "", self::get_latest_pkg_version()));
return $curr_ver_num < $latest_ver_num;
}

public static function is_pkg_supported() {
# Local variables
$overrides_dir = "/etc/inc/saml2_auth/overrides/";
$overrides = glob($overrides_dir."*" , GLOB_ONLYDIR);
$pf_version = self::get_pfsense_version(true);

# Check if this version of pfSense has a supported file override
if (in_array($overrides_dir.$pf_version, $overrides)) {
return true;
} else {
return false;
}
}

public static function get_pkg_releases() {
# Variables
$releases_file = "/usr/local/share/pfSense-pkg-saml2-auth/releases.json";
$releases = json_decode(file_get_contents($releases_file), true);
$fetch_releases_cmd = "curl -s https://api.github.com/repos/jaredhendrickson13/pfsense-saml2-auth/releases -m 10";

# Check if our previous releases data is older than 120 seconds
if ($releases["last_updated"] + 120 < time()) {
# Pull the releases data from Github and rewrite the releases file
$api_resp = shell_exec($fetch_releases_cmd);
$api_resp = json_decode($api_resp, true);
$releases = ["last_updated" => time(), "releases" => $api_resp];
file_put_contents($releases_file, json_encode($releases));
}
return $releases;
}

public static function get_all_pkg_versions() {
# Variables
$pf_version = substr(self::get_pfsense_version(), 0, 3);
$versions = [];
$count = 0;
$releases = self::get_pkg_releases()["releases"];

# Loop through each version and populate our version data
foreach ($releases as $release) {
# Loop through the assets of each release and check if our version of pfSense is supported
foreach ($release["assets"] as $asset) {
if ($asset["name"] === "pfSense-".$pf_version."-pkg-saml2-auth.txz") {
# The first item of our list is the latest release, mark it as such.
if ($count === 0) {
$versions[$release["tag_name"]] = $release["name"]." - Latest";
$count++;
} else {
$versions[$release["tag_name"]] = $release["name"];
}
}
}
}
return $versions;
}

# Pulls our current pfSense SAML2 configuration and saves to a non-volatile location.
public function backup_config($console=false) {
# Local variables
$path = $this->file_path."/backup.json";
$config_data = $this->get_package_config()[1];

# Print status message
$this->__log("Backing up configuration...", $console);

# Save a JSON file containing the data
file_put_contents($path, json_encode($config_data));
$this->__log("done." . PHP_EOL, $console);
return true;
}

# Restores the pfSense SAML2 configuration from a specified backup file
public function restore_config($console=false) {
# Local variables
global $config;
$path = $this->file_path."/backup.json";
$config_id = $this->get_package_config()[0];
$config_json = file_get_contents($path);
$config_data = json_decode($config_json, true);

# Print status message
$this->__log("Restoring configuration...", $console);

# Save the backup configuration to the pfSense master configuration if found
if (file_exists($path)) {
$config["installedpackages"]["package"][$config_id]["conf"] = $config_data;
write_config("Restoring SAML2 configuration");
$this->__log("done." . PHP_EOL, $console);
return true;
}
else {
$this->__log("no backup found.".PHP_EOL, $console);
return false;
}
}

# Update to the latest version of the package
public function update_pkg($version="latest", $console=false) {
# Local variables
$base_url = "https://github.com/jaredhendrickson13/pfsense-saml2-auth/releases";

# Format the package URL based on the requested version
if ($version === "latest") {
$url = $base_url."/latest/download/pfSense-".$this->get_pfsense_version()."-pkg-saml2-auth.txz";
} else {
$url = $base_url."/download/".$version."/pfSense-".$this->get_pfsense_version()."-pkg-saml2-auth.txz";
}

# Backup the package configuration before updating
$this->backup_config();

# Remove the existing package and add the new one, then og the results
exec("pkg delete -y pfSense-pkg-saml2-auth", $del_cmd_out, $del_cmd_rc);
exec("pkg add ".$url, $add_cmd_out, $add_cmd_rc);
$this->__log(implode("\n", $del_cmd_out), $console);
$this->__log(implode("\n", $add_cmd_out), $console);

# Check if the update was successful
if ($del_cmd_rc === 0 and $add_cmd_rc === 0) {
return true;
} else {
return false;
}
}


}
}
3 changes: 2 additions & 1 deletion pfSense-pkg-saml2-auth/files/pkg-deinstall.in
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/bin/sh
if [ "${2}" != "POST-DEINSTALL" ]; then

if [ "${2}" != "DEINSTALL" ]; then
exit 0
fi

Expand Down
4 changes: 2 additions & 2 deletions pfSense-pkg-saml2-auth/files/usr/local/pkg/saml2_auth.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* SAML2_AUTH
* - A SAML2 authentication extension for the pfSense UI
*
* Copyright 2021 Jared Hendrickson
* Copyright 2022 Jared Hendrickson
*/
]]>
</copyright>
Expand All @@ -23,4 +23,4 @@
</menu>
<tabs>
</tabs>
</packagegui>
</packagegui>
Loading

0 comments on commit 27f9350

Please sign in to comment.