bekkalokk: init idp-simplesamlphp

add-simple-saml-theme
Oystein Kristoffer Tveit 2024-03-29 01:59:46 +01:00
parent 4c1966365b
commit 49a0b1a5f7
8 changed files with 1695 additions and 3 deletions

View File

@ -83,6 +83,7 @@
autoreconfHook = final.buildPackages.autoreconfHook269;
};
mediawiki-extensions = final.callPackage ./packages/mediawiki-extensions { };
simplesamlphp = final.callPackage ./packages/simplesamlphp { };
})
];
};

View File

@ -15,6 +15,7 @@
./services/kerberos
./services/webmail
# ./services/mediawiki.nix
./services/idp-simplesamlphp
];
sops.defaultSopsFile = ../../secrets/bekkalokk/bekkalokk.yaml;

View File

@ -0,0 +1,135 @@
<?php
/**
* Authenticate using HTTP login.
*
* @author Yorn de Jong
* @author Oystein Kristoffer Tveit
* @package simpleSAMLphp
*/
namespace SimpleSAML\Module\authpwauth\Auth\Source;
class PwAuth extends \SimpleSAML\Module\core\Auth\UserPassBase
{
protected $pwauth_bin_path;
protected $mail_domain;
public function __construct(array $info, array &$config) {
assert('is_array($info)');
assert('is_array($config)');
/* Call the parent constructor first, as required by the interface. */
parent::__construct($info, $config);
$this->pwauth_bin_path = $config['pwauth_bin_path'];
if (array_key_exists('mail_domain', $config)) {
$this->mail_domain = '@' . ltrim($config['mail_domain'], '@');
}
}
public function login(string $username, string $password): array {
$username = strtolower( $username );
if (!file_exists($this->pwauth_bin_path)) {
die("Could not find pwauth binary");
return false;
}
if (!is_executable($this->pwauth_bin_path)) {
die("pwauth binary is not executable");
return false;
}
$handle = popen($this->pwauth_bin_path, 'w');
if ($handle === FALSE) {
die("Error opening pipe to pwauth");
return false;
}
$data = "$username\n$password\n";
if (fwrite($handle, $data) !== strlen($data)) {
die("Error writing to pwauth pipe");
return false;
}
# Is the password valid?
$result = pclose( $handle );
if ($result !== 0) {
if (!in_array($result, [1, 2, 3, 4, 5, 6, 7], true)) {
die("pwauth returned $result for username $username");
}
throw new \SimpleSAML\Error\Error('WRONGUSERPASS');
}
/*
$ldap = ldap_connect('129.241.210.159', 389);
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_start_tls($ldap);
ldap_bind($ldap, 'passordendrer@pvv.ntnu.no', 'Oi7aekoh');
$search = ldap_search($ldap, 'DC=pvv,DC=ntnu,DC=no', '(sAMAccountName='.ldap_escape($username, '', LDAP_ESCAPE_FILTER).')');
$entry = ldap_first_entry($ldap, $search);
$dn = ldap_get_dn($ldap, $entry);
$newpassword = mb_convert_encoding("\"$password\"", 'UTF-16LE', 'UTF-8');
ldap_modify_batch($ldap, $dn, [
#[
# 'modtype' => LDAP_MODIFY_BATCH_REMOVE,
# 'attrib' => 'unicodePwd',
# 'values' => [$password],
#],
[
#'modtype' => LDAP_MODIFY_BATCH_ADD,
'modtype' => LDAP_MODIFY_BATCH_REPLACE,
'attrib' => 'unicodePwd',
'values' => [$newpassword],
],
]);
*/
#0 - Login OK.
#1 - Nonexistant login or (for some configurations) incorrect password.
#2 - Incorrect password (for some configurations).
#3 - Uid number is below MIN_UNIX_UID value configured in config.h.
#4 - Login ID has expired.
#5 - Login's password has expired.
#6 - Logins to system have been turned off (usually by /etc/nologin file).
#7 - Limit on number of bad logins exceeded.
#50 - pwauth was not run with real uid SERVER_UID. If you get this
# this error code, you probably have SERVER_UID set incorrectly
# in pwauth's config.h file.
#51 - pwauth was not given a login & password to check. The means
# the passing of data from mod_auth_external to pwauth is messed
# up. Most likely one is trying to pass data via environment
# variables, while the other is trying to pass data via a pipe.
#52 - one of several possible internal errors occured.
$uid = $username;
# TODO: Reinstate this code once passwd is working...
/*
$cn = trim(shell_exec('getent passwd '.escapeshellarg($uid).' | cut -d: -f5 | cut -d, -f1'));
$groups = preg_split('_\\s_', shell_exec('groups '.escapeshellarg($uid)));
array_shift($groups);
array_shift($groups);
array_pop($groups);
$info = posix_getpwnam($uid);
$group = $info['gid'];
if (!in_array($group, $groups)) {
$groups[] = $group;
}
*/
$cn = "Unknown McUnknown";
$groups = array();
$result = array(
'uid' => array($uid),
'cn' => array($cn),
'group' => $groups,
);
if (isset($this->mail_domain)) {
$result['mail'] = array($uid.$this->mail_domain);
}
return $result;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,202 @@
{ config, pkgs, lib, ... }:
let
pwAuthScript = pkgs.writeShellApplication {
name = "pwauth";
runtimeInputs = with pkgs; [ coreutils heimdal ];
text = ''
read -r user1
user2="$(echo -n "$user1" | tr -c -d '0123456789abcdefghijklmnopqrstuvwxyz')"
if test "$user1" != "$user2"
then
read -r _
exit 2
fi
kinit --password-file=STDIN "''${user1}@PVV.NTNU.NO"
'';
};
package = pkgs.simplesamlphp.override {
extra_files = {
# NOTE: Using self signed certificate created 30. march 2024, with command:
# openssl req -newkey rsa:4096 -new -x509 -days 365 -nodes -out idp.crt -keyout idp.pem
"metadata/saml20-idp-hosted.php" = pkgs.writeText "saml20-idp-remote.php" ''
<?php
$metadata['https://idp2.pvv.ntnu.no/'] = array(
'host' => '__DEFAULT__',
'privatekey' => '${config.sops.secrets."idp/privatekey".path}',
'certificate' => '${./idp.crt}',
'auth' => 'pwauth',
);
?>
'';
"metadata/saml20-sp-remote.php" = pkgs.writeText "saml20-sp-remote.php" ''
<?php
${ lib.pipe config.services.idp.sp-remote-metadata [
(map (url: ''
$metadata['${url}'] = [
'SingleLogoutService' => [
[
'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect',
'Location' => '${url}module.php/saml/sp/saml2-logout.php/default-sp',
],
[
'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:SOAP',
'Location' => '${url}module.php/saml/sp/saml2-logout.php/default-sp',
],
],
'AssertionConsumerService' => [
[
'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST',
'Location' => '${url}module.php/saml/sp/saml2-acs.php/default-sp',
'index' => 0,
],
[
'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact',
'Location' => '${url}module.php/saml/sp/saml2-acs.php/default-sp',
'index' => 1,
],
],
];
''))
(lib.concatStringsSep "\n")
]}
?>
'';
"config/authsources.php" = pkgs.writeText "idp-authsources.php" ''
<?php
$config = array(
'admin' => array(
'core:AdminPassword'
),
'pwauth' => array(
'authpwauth:PwAuth',
'pwauth_bin_path' => '${lib.getExe pwAuthScript}',
'mail_domain' => '@pvv.ntnu.no',
),
);
?>
'';
"config/config.php" = pkgs.runCommandLocal "simplesamlphp-config.php" { } ''
cp ${./config.php} "$out"
substituteInPlace "$out" \
--replace '$SAML_COOKIE_SECURE' 'true' \
--replace '$SAML_COOKIE_SALT' 'file_get_contents("${config.sops.secrets."idp/cookie_salt".path}")' \
--replace '$SAML_ADMIN_NAME' '"Drift"' \
--replace '$SAML_ADMIN_EMAIL' '"drift@pvv.ntnu.no"' \
--replace '$SAML_ADMIN_PASSWORD' 'file_get_contents("${config.sops.secrets."idp/admin_password".path}")' \
--replace '$SAML_TRUSTED_DOMAINS' 'array( "idp2.pvv.ntnu.no" )' \
--replace '$SAML_DATABASE_DSN' '"pgsql:host=postgres.pvv.ntnu.no;port=5432;dbname=idp"' \
--replace '$SAML_DATABASE_USERNAME' '"idp"' \
--replace '$SAML_DATABASE_PASSWORD' 'file_get_contents("${config.sops.secrets."idp/postgres_password".path}")' \
--replace '$CACHE_DIRECTORY' '/var/cache/idp'
'';
"modules/authpwauth/src/Auth/Source/PwAuth.php" = ./authpwauth.php;
};
};
in
{
options.services.idp.sp-remote-metadata = lib.mkOption {
type = with lib.types; listOf str;
default = [ ];
description = ''
List of urls point to (simplesamlphp) service profiders, which the idp should trust.
:::{.note}
Make sure the url ends with a `/`
:::
'';
};
config = {
sops.secrets = {
"idp/privatekey" = {
owner = "idp";
group = "idp";
mode = "0770";
};
"idp/admin_password" = {
owner = "idp";
group = "idp";
};
"idp/postgres_password" = {
owner = "idp";
group = "idp";
};
"idp/cookie_salt" = {
owner = "idp";
group = "idp";
};
};
users.groups."idp" = { };
users.users."idp" = {
description = "PVV Identity Provider Service User";
group = "idp";
createHome = false;
isSystemUser = true;
};
systemd.tmpfiles.settings."10-idp" = {
"/var/cache/idp".d = {
user = "idp";
group = "idp";
mode = "0770";
};
"/var/lib/idp".d = {
user = "idp";
group = "idp";
mode = "0770";
};
};
services.phpfpm.pools.idp = {
user = "idp";
group = "idp";
settings = let
listenUser = config.services.nginx.user;
listenGroup = config.services.nginx.group;
in {
"pm" = "dynamic";
"pm.max_children" = 32;
"pm.max_requests" = 500;
"pm.start_servers" = 2;
"pm.min_spare_servers" = 2;
"pm.max_spare_servers" = 4;
"listen.owner" = listenUser;
"listen.group" = listenGroup;
"catch_workers_output" = true;
"php_admin_flag[log_errors]" = true;
# "php_admin_value[error_log]" = "stderr";
};
};
services.nginx.virtualHosts."idp2.pvv.ntnu.no" = {
forceSSL = true;
enableACME = true;
root = "${package}/share/php/simplesamlphp/public";
locations = {
# based on https://simplesamlphp.org/docs/stable/simplesamlphp-install.html#configuring-nginx
"/" = {
alias = "${package}/share/php/simplesamlphp/public/";
index = "index.php";
extraConfig = ''
location ~ ^/(?<phpfile>.+?\.php)(?<pathinfo>/.*)?$ {
include ${pkgs.nginx}/conf/fastcgi_params;
fastcgi_pass unix:${config.services.phpfpm.pools.idp.socket};
fastcgi_param SCRIPT_FILENAME ${package}/share/php/simplesamlphp/public/$phpfile;
fastcgi_param SCRIPT_NAME /$phpfile;
fastcgi_param PATH_INFO $pathinfo if_not_empty;
}
'';
};
};
};
};
}

View File

@ -0,0 +1,33 @@
-----BEGIN CERTIFICATE-----
MIIFqTCCA5GgAwIBAgIUL2+PMM9rE9wI5W2yNnJ2CmfGxh0wDQYJKoZIhvcNAQEL
BQAwZDELMAkGA1UEBhMCTk8xEzARBgNVBAgMClNvbWUtU3RhdGUxHjAcBgNVBAoM
FVByb2dyYW12YXJldmVya3N0ZWRldDEgMB4GCSqGSIb3DQEJARYRZHJpZnRAcHZ2
Lm50bnUubm8wHhcNMjQwMzMwMDAyNjQ0WhcNMjUwMzMwMDAyNjQ0WjBkMQswCQYD
VQQGEwJOTzETMBEGA1UECAwKU29tZS1TdGF0ZTEeMBwGA1UECgwVUHJvZ3JhbXZh
cmV2ZXJrc3RlZGV0MSAwHgYJKoZIhvcNAQkBFhFkcmlmdEBwdnYubnRudS5ubzCC
AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL/0l0jdV+PoVxdd21F+2NLm
JN6sZmSJexOSk/sFjhhF4WMtjOfDAQYjt3hlLPyYl//jCe9WteavvtdCx1tHJitd
xjOUJ/leVjHzBttCVZR+iTlQtpsZ2TbRMJ5Fcfl82njlPecV4umJvnnFXawE4Qee
dE2OM8ODjjrK1cNaHR74tyZCwmdOxNHXZ7RN22p9kZjLD18LQyNr5igaDBeaZkyk
Gxbg4tbP51x9JFRLF7kUlyAc83geFnw6v/wBahr49m/X4y7xE0rdPb2L0moUjmOO
Zyl3hvxMI3+g/0FVMM5eKmfIIP2rIVEAa6MWMx0vPjC6h2fIyxkUqg5C8aFlpqav
+8f2rUc+JfdiFsIZNrylBXsleGzS+/wY1uB/pAy5Vg9WCp+eC75EtWMt0k2f442G
rhKa3lAZ6GIYrtEiQiNGM1aT1Cs1nqTtslfnHiuAKBefLjCXgq9uvL2yRodwe9/m
oZiqYnLHy/v1xfnF5rKTcRmOleU3tc+nlN6tZSGC1nZgMpqpoqdcbJXAkvaJ2Km4
sl0YS28VQnztgzuVPNdnv8lcS6HmkaGaNWbepKgWeaH5oT7O6u99wZIv88m+tf5m
Eu197YVpcclnojQCYKauWcQFsXS20egsVP87Qk0e2SHmGTUQp6YEYX6RLjkg7/vS
BelDBbCldraNVEiC0jmpAgMBAAGjUzBRMB0GA1UdDgQWBBSL0yofG5NEmzFIRuqC
xmyiuZW6DTAfBgNVHSMEGDAWgBSL0yofG5NEmzFIRuqCxmyiuZW6DTAPBgNVHRMB
Af8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQAZZVs7BLk/NLq3f4Ik8qH3IoDN
2m4XXRZS+xxw5RwctgSnik7AffgAfv8QQm2co8UYkHbB0whaG1PDz+L7wB1hVkWn
DVUaJcKQnn0x+sNU5LoTbjI0PlaST7PO5D0OMFab8FSNxpzzpbUcgZUhelc99Ri/
2Gh8mf4b3Y3Uzq6YKFsuFM65OuJhH8f1w6onai9x28t6tERHUSUfJ2keXzU4ytCV
EitWXwhe759VLqmdP4BATwlCOCuwa5aDeGcWRIqFpYIn0SOAmVV3o4V71JdZc1jE
fuOo/PbiHZ+R9ZGbh98aMidb0moL1ZDhmir9KbedezNyki6JJ72mVclhLqUajFxr
T39FXd5e2+QBMHPPhVFznQoHWnHEbZigTt61b0cg/TsxaxOkF4Ilmr/2DmSWysWK
TF5eq8hp6/53qVbXXSzrCjxd3wzGnRabsEVPX/L2hYDx81hluovJQCtskqTq1joI
W2R7AO5Sdyc6NfOR85kl0HXzHa+0Slsf8ZDs5nCz/mOOPoAGl7IxF7xQ6kPO7V+U
HdGE2tkblM/TrAObJH0HXySeJGI7Vfya+D1Y8IqGtyZtWyx1DmlA/OezGGf5D3rG
88LywHQQ2mQ+8aosBTE4+HQ+apLKZBprqQKuiDjT1RSUbfUHQkYuL+D1oIVmklAc
UxTpf01QJnZkMqf5NQ==
-----END CERTIFICATE-----

View File

@ -0,0 +1,22 @@
''
<?php
$metadata['https://idp2.pvv.ntnu.no/'] = [
'metadata-set' => 'saml20-idp-hosted',
'entityid' => 'https://idp2.pvv.ntnu.no/',
'SingleSignOnService' => [
[
'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect',
'Location' => 'https://idp2.pvv.ntnu.no/module.php/saml/idp/singleSignOnService',
],
],
'SingleLogoutService' => [
[
'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect',
'Location' => 'https://idp2.pvv.ntnu.no/module.php/saml/idp/singleLogout',
],
],
'NameIDFormat' => [ 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient' ],
'certificate' => '${./idp.crt}',
];
?>
''

View File

@ -13,6 +13,11 @@ mediawiki:
database: ENC[AES256_GCM,data:EvVK3Mo6cZiIZS+gTxixU4r9SXN41VqwaWOtortZRNH+WPJ4xcYvzYMJNg==,iv:JtFTRLn3fzKIfgAPRqRgQjct7EdkEHtiyQKPy8/sZ2Q=,tag:nqzseG6BC0X5UNI/3kZZ3A==,type:str]
keycloak:
database: ENC[AES256_GCM,data:76+AZnNR5EiturTP7BdOCKE90bFFkfGlRtviSP5NHxPbb3RfFPJEMlwtzA==,iv:nS7VTossHdlrHjPeethhX+Ysp9ukrb5JD7kjG28OFpY=,tag:OMpiEv9nQA7v6lWJfNxEEw==,type:str]
idp:
cookie_salt: ENC[AES256_GCM,data:vwHF7graEq0QmELkfuoZtrlvKVoFtc9JJAYcHZKR87y4y6J5XUpnDt5OebjYGOGTNs9CWCIQQFNZWqwVN8neXw==,iv:9lTSmCBv5gTGPoRFBMhkvcRCQozDqIsf87ZQrmV2j/M=,tag:atqB4SMZ9oLilChh7BkheQ==,type:str]
admin_password: ENC[AES256_GCM,data:g8yWKsplviBxm2za20RyP/dJYOY70Lop,iv:LFoU7VvYjSu1pQPFtRsfJp/CWFk5Lf9EQHZmUVhKkFY=,tag:JMJYpkU0rbqttNTnLcrOiw==,type:str]
postgres_password: ENC[AES256_GCM,data:ilrtmEcfs3b2eQ1NhV33i49MT7G+oAxu,iv:tkT17fmyEcSWHI29JZusHItqT+wa6oKlfCPIX75Mlhk=,tag:YwZqRTFFWPpVle53fSqR+g==,type:str]
privatekey: ENC[AES256_GCM,data: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,iv:iKBBowiGSpzsI2rL8Ek1ONteMji5P9ai2yaaR6eAVTw=,tag:wzO3qrMintbzKyIgLLwgFA==,type:str]
sops:
kms: []
gcp_kms: []
@ -46,8 +51,8 @@ sops:
akVjeTNTeGorZjJQOVlMeCtPRUVYL3MK+VMvGxrbzGz4Q3sdaDDWjal+OiK+JYKX
GHiMXVHQJZu/RrlxMjHKN6V3iaqxZpuvLAEJ2Lzy5EOHPtuiiRyeHQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2023-09-17T02:02:24Z"
mac: ENC[AES256_GCM,data:Lkvj9UOdE/WZtFReMs6n8ucFuJNPb76ZhPHFpYAEqYEe8d9FdMPMzq05DBAJe9IqpFS0jc9SWxJUPHfGgoMR8nPciZuR/mpJ+4s/cRkPbApwBPcLlvatE/qkbcxzoLlb1vN0gth5G/U7UEfk5Pp9gIz6Yo4sEIS3Za42tId1MpI=,iv:s3VELgU/RJ98/lbQV3vPtOLXtwFzB3KlY7bMKbAzp/g=,tag:D8s0XyGnd8UhbCseB/TyFg==,type:str]
lastmodified: "2024-03-30T22:09:16Z"
mac: ENC[AES256_GCM,data:1YyPauVMocYQoedanK/wfcfWCqeW6rXz/ItjPbnJGIYp4EdQ3XDiga7fzv06XmuF6kthY4j/T+qyF8mrJQqrb9bXLRvctEySyWOa5dhw2QhPKIbsPa7GeI9nlBQCEGN5I8z2fsMDLb5sOrY1Qw0PA/eb/6yponqeIeIs6Sgo0Ss=,iv:qjnEvEAX7dZYeNHdFWdO7zzpysMncRmcwFz6fWTn1kc=,tag:ghMtRMkPDTfg/e2Y48gPxw==,type:str]
pgp:
- created_at: "2023-05-21T00:28:40Z"
enc: |
@ -70,4 +75,4 @@ sops:
-----END PGP MESSAGE-----
fp: F7D37890228A907440E1FD4846B9228E814A2AAC
unencrypted_suffix: _unencrypted
version: 3.7.3
version: 3.8.1