commit
cbe5c55f6d
48 ha cambiato i file con 10679 aggiunte e 0 eliminazioni
@ -0,0 +1,8 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
return [ |
||||||
|
'host' => 'localhost', |
||||||
|
'database' => 'database', |
||||||
|
'username' => 'username', |
||||||
|
'password' => 'password', |
||||||
|
]; |
||||||
@ -0,0 +1,5 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
return [ |
||||||
|
'key' => 'CHANGE_ME', |
||||||
|
]; |
||||||
@ -0,0 +1,141 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace MwgAuth\Controllers; |
||||||
|
|
||||||
|
use MwgAuth\Core\Controller; |
||||||
|
use MwgAuth\Models\User; |
||||||
|
|
||||||
|
class ControllerV1 extends Controller |
||||||
|
{ |
||||||
|
public static function login(): string |
||||||
|
{ |
||||||
|
self::requireMethod('POST'); |
||||||
|
$input = self::getPost(); |
||||||
|
if (null === $input) { |
||||||
|
return self::error(self::ERROR_INVALID_INPUT); |
||||||
|
} |
||||||
|
$userName = $input[self::PARAMETER_USERNAME] ?? null; |
||||||
|
if (null === $userName) { |
||||||
|
return self::error(self::ERROR_MISSING_PARAMETER, self::PARAMETER_USERNAME); |
||||||
|
} |
||||||
|
$password = $input[self::PARAMETER_PASSWORD] ?? null; |
||||||
|
if (null === $password) { |
||||||
|
return self::error(self::ERROR_MISSING_PARAMETER, self::PARAMETER_PASSWORD); |
||||||
|
} |
||||||
|
$user = User::load($userName, $password, $_SERVER['REMOTE_ADDR']); |
||||||
|
if (null === $user) { |
||||||
|
return self::error(self::ERROR_INVALID_PASSWORD); |
||||||
|
} |
||||||
|
return self::response([self::PARAMETER_AUTH => $user->getAuth()]); |
||||||
|
} |
||||||
|
|
||||||
|
public static function getToken(): string |
||||||
|
{ |
||||||
|
self::requireMethod('POST'); |
||||||
|
$input = self::getPost(); |
||||||
|
if (null === $input) { |
||||||
|
return self::error(self::ERROR_INVALID_INPUT); |
||||||
|
} |
||||||
|
$auth = $input[self::PARAMETER_AUTH] ?? null; |
||||||
|
if (null === $auth) { |
||||||
|
return self::error(self::ERROR_MISSING_PARAMETER, self::PARAMETER_AUTH); |
||||||
|
} |
||||||
|
$callback = $input[self::PARAMETER_CALLBACK_URL] ?? null; |
||||||
|
if (null === $callback) { |
||||||
|
return self::error(self::ERROR_MISSING_PARAMETER, self::PARAMETER_CALLBACK_URL); |
||||||
|
} |
||||||
|
$user = User::verifyAuth($auth); |
||||||
|
if (null === $user) { |
||||||
|
return self::error(self::ERROR_INVALID_AUTH); |
||||||
|
} |
||||||
|
$token = $user->getToken($callback); |
||||||
|
return self::response([self::PARAMETER_TOKEN => $token]); |
||||||
|
} |
||||||
|
|
||||||
|
public static function getUser(): string |
||||||
|
{ |
||||||
|
self::requireMethod('POST'); |
||||||
|
$input = self::getPost(); |
||||||
|
if (null === $input) { |
||||||
|
return self::error(self::ERROR_INVALID_INPUT); |
||||||
|
} |
||||||
|
$auth = $input[self::PARAMETER_AUTH] ?? null; |
||||||
|
if (null === $auth) { |
||||||
|
return self::error(self::ERROR_MISSING_PARAMETER, self::PARAMETER_AUTH); |
||||||
|
} |
||||||
|
$user = User::verifyAuth($auth); |
||||||
|
if (null === $user) { |
||||||
|
return self::error(self::ERROR_INVALID_AUTH); |
||||||
|
} |
||||||
|
$token = $input[self::PARAMETER_TOKEN] ?? null; |
||||||
|
if (null === $token) { |
||||||
|
return self::error(self::ERROR_MISSING_PARAMETER, self::PARAMETER_TOKEN); |
||||||
|
} |
||||||
|
if (!$user->verifyToken($token)) { |
||||||
|
return self::error(self::ERROR_INVALID_TOKEN); |
||||||
|
} |
||||||
|
$userData = $user->getLoginData($token); |
||||||
|
if (null === $userData) { |
||||||
|
return self::error(self::ERROR_INVALID_LOGIN); |
||||||
|
} |
||||||
|
return self::response($userData); |
||||||
|
} |
||||||
|
|
||||||
|
private static function json(array $values): string |
||||||
|
{ |
||||||
|
return json_encode($values, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); |
||||||
|
} |
||||||
|
|
||||||
|
private static function response(array $values): string |
||||||
|
{ |
||||||
|
$response = [ |
||||||
|
self::LABEL_ERROR_CODE => self::ERROR_OK, |
||||||
|
self::LABEL_STATUS => self::STATUS_OK, |
||||||
|
self::LABEL_DESCRIPTION => self::ERROR_DESCRIPTIONS[self::ERROR_OK], |
||||||
|
]; |
||||||
|
$response += $values; |
||||||
|
return self::json($response); |
||||||
|
} |
||||||
|
|
||||||
|
private static function error(int $errorCode, ...$parameters): string |
||||||
|
{ |
||||||
|
$status = $errorCode == self::ERROR_OK ? self::STATUS_OK : self::STATUS_ERROR; |
||||||
|
return self::json([ |
||||||
|
self::LABEL_ERROR_CODE => $errorCode, |
||||||
|
self::LABEL_STATUS => $status, |
||||||
|
self::LABEL_DESCRIPTION => vsprintf(self::ERROR_DESCRIPTIONS[$errorCode], $parameters), |
||||||
|
]); |
||||||
|
} |
||||||
|
|
||||||
|
protected const LABEL_ERROR_CODE = 'code'; |
||||||
|
protected const LABEL_DESCRIPTION = 'description'; |
||||||
|
protected const LABEL_STATUS = 'status'; |
||||||
|
|
||||||
|
protected const ERROR_OK = 0; |
||||||
|
protected const ERROR_INVALID_AUTH = 1; |
||||||
|
protected const ERROR_INVALID_LOGIN = 2; |
||||||
|
protected const ERROR_INVALID_TOKEN = 3; |
||||||
|
protected const ERROR_INVALID_INPUT = 4; |
||||||
|
protected const ERROR_MISSING_PARAMETER = 5; |
||||||
|
protected const ERROR_INVALID_PASSWORD = 6; |
||||||
|
|
||||||
|
protected const STATUS_OK = 'success'; |
||||||
|
protected const STATUS_ERROR = 'error'; |
||||||
|
|
||||||
|
protected const ERROR_DESCRIPTIONS = [ |
||||||
|
self::ERROR_OK => 'success', |
||||||
|
self::ERROR_INVALID_AUTH => 'invalid or expired authorization', |
||||||
|
self::ERROR_INVALID_LOGIN => 'no login associated with this token', |
||||||
|
self::ERROR_INVALID_TOKEN => 'invalid or expired token', |
||||||
|
self::ERROR_INVALID_INPUT => 'invalid input', |
||||||
|
self::ERROR_MISSING_PARAMETER => "parameter '%s' is missing", |
||||||
|
self::ERROR_INVALID_PASSWORD => 'invalid username or password', |
||||||
|
]; |
||||||
|
|
||||||
|
protected const PARAMETER_AUTH = 'auth'; |
||||||
|
protected const PARAMETER_CALLBACK_URL = 'callback'; |
||||||
|
protected const PARAMETER_REDIRECT = 'redirect'; |
||||||
|
protected const PARAMETER_TOKEN = 'token'; |
||||||
|
protected const PARAMETER_USERNAME = 'username'; |
||||||
|
protected const PARAMETER_PASSWORD = 'password'; |
||||||
|
} |
||||||
@ -0,0 +1,29 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace MwgAuth\Core; |
||||||
|
|
||||||
|
class AutoLoader |
||||||
|
{ |
||||||
|
private static $patterns = []; |
||||||
|
private static $replacements = []; |
||||||
|
|
||||||
|
public static function register() |
||||||
|
{ |
||||||
|
if (empty(self::$patterns)) { |
||||||
|
self::$patterns = [ |
||||||
|
'/^' . explode('\\', self::class)[0] . '/', |
||||||
|
'/\\\\/', |
||||||
|
]; |
||||||
|
} |
||||||
|
if (empty(self::$replacements)) { |
||||||
|
self::$replacements = ['', '/']; |
||||||
|
} |
||||||
|
spl_autoload_register(self::class . '::autoLoader'); |
||||||
|
} |
||||||
|
|
||||||
|
public static function autoLoader(string $class) |
||||||
|
{ |
||||||
|
$class = preg_replace(self::$patterns, self::$replacements, $class); |
||||||
|
require_once(dirname(__DIR__) . $class . '.php'); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,30 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace MwgAuth\Core; |
||||||
|
|
||||||
|
class Config |
||||||
|
{ |
||||||
|
private static $config = []; |
||||||
|
|
||||||
|
private static function load(): void |
||||||
|
{ |
||||||
|
if (empty(self::$config)) { |
||||||
|
foreach (glob(dirname(__DIR__) . '/Config/*.php') as $config) { |
||||||
|
$section = pathinfo($config, PATHINFO_FILENAME); |
||||||
|
self::$config[$section] = include($config); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static function getSection(string $section): array |
||||||
|
{ |
||||||
|
self::load(); |
||||||
|
return self::$config[$section] ?? []; |
||||||
|
} |
||||||
|
|
||||||
|
public static function getValue(string $section, string $name): ?string |
||||||
|
{ |
||||||
|
self::load(); |
||||||
|
return self::$config[$section][$name] ?? null; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,109 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace MwgAuth\Core; |
||||||
|
|
||||||
|
class Controller |
||||||
|
{ |
||||||
|
|
||||||
|
private static $charset = 'UTF-8'; |
||||||
|
private static $contentType = 'application/json'; |
||||||
|
private static $responseCode = 200; |
||||||
|
|
||||||
|
public static function run(string $function): void |
||||||
|
{ |
||||||
|
if ($function === '') { |
||||||
|
$function = 'index'; |
||||||
|
} else { |
||||||
|
$function = self::camelize($function); |
||||||
|
} |
||||||
|
if (method_exists(static::class, $function)) { |
||||||
|
$html = static::$function(); |
||||||
|
$header = 'Content-Type: ' . self::$contentType; |
||||||
|
if (null !== self::$charset) { |
||||||
|
$header .= "; charset=" . self::$charset; |
||||||
|
} |
||||||
|
header($header, true, self::$responseCode); |
||||||
|
echo $html; |
||||||
|
} else { |
||||||
|
self::page404(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected static function camelize(string $input): string |
||||||
|
{ |
||||||
|
$ret = []; |
||||||
|
foreach (explode('_', $input) as $part) { |
||||||
|
$ret[] = ucfirst($part); |
||||||
|
} |
||||||
|
return implode('', $ret); |
||||||
|
} |
||||||
|
|
||||||
|
protected static function getPost(): ?array |
||||||
|
{ |
||||||
|
$input = file_get_contents('php://input'); |
||||||
|
return json_decode($input, true); |
||||||
|
} |
||||||
|
|
||||||
|
protected static function requireMethod(string $method): void |
||||||
|
{ |
||||||
|
if ($method !== $_SERVER['REQUEST_METHOD']) { |
||||||
|
header($_SERVER['SERVER_PROTOCOL'] . ' 405 Method Not Allowed', true, 405); |
||||||
|
die("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n" . |
||||||
|
"<html><head>\n" . |
||||||
|
"<title>405 Method Not Allowed</title>\n" . |
||||||
|
"</head><body>\n" . |
||||||
|
"<h1>Method Not Allowed</h1>\n" . |
||||||
|
"<p>The requested method " . $_SERVER['REQUEST_METHOD'] . " is not allowed for this resource.</p>\n" . |
||||||
|
self::serverSignature()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected static function page404(): string |
||||||
|
{ |
||||||
|
header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found', true, 404); |
||||||
|
die("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n" . |
||||||
|
"<html><head>\n" . |
||||||
|
"<title>404 Not Found</title>\n" . |
||||||
|
"</head><body>\n" . |
||||||
|
"<h1>Not Found</h1>\n" . |
||||||
|
"<p>The requested URL was not found on this server.</p>\n" . |
||||||
|
self::serverSignature()); |
||||||
|
} |
||||||
|
|
||||||
|
public static function redirect(string $location) |
||||||
|
{ |
||||||
|
header($_SERVER['SERVER_PROTOCOL'] . ' 302 Found', true, 302); |
||||||
|
header('Location: ' . $location, true); |
||||||
|
die("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n" . |
||||||
|
"<html><head>\n" . |
||||||
|
"<title>302 Found</title>\n" . |
||||||
|
"</head><body>\n" . |
||||||
|
"<h1>Found</h1>\n" . |
||||||
|
"<p>The document has moved <a href=\"" . $location . "\">here</a>.</p>\n" . |
||||||
|
self::serverSignature()); |
||||||
|
} |
||||||
|
|
||||||
|
private static function serverSignature(): string |
||||||
|
{ |
||||||
|
return |
||||||
|
"<hr>\n" . |
||||||
|
"<address>" . $_SERVER['SERVER_SOFTWARE'] . " Server at " . $_SERVER['SERVER_NAME'] . " Port " . |
||||||
|
$_SERVER['SERVER_PORT'] . "</address>\n" . |
||||||
|
"</body></html>\n"; |
||||||
|
} |
||||||
|
|
||||||
|
protected static function setCharset(string $charset): void |
||||||
|
{ |
||||||
|
self::$charset = $charset; |
||||||
|
} |
||||||
|
|
||||||
|
protected static function setContentType(string $contentType): void |
||||||
|
{ |
||||||
|
self::$contentType = $contentType; |
||||||
|
} |
||||||
|
|
||||||
|
protected static function setResponseCode(string $responseCode): void |
||||||
|
{ |
||||||
|
self::$responseCode = $responseCode; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,160 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace MwgAuth\Core; |
||||||
|
|
||||||
|
use PDO; |
||||||
|
use PDOStatement; |
||||||
|
|
||||||
|
class Model |
||||||
|
{ |
||||||
|
private static $database = null; |
||||||
|
private static $lastErrorMessage = ''; |
||||||
|
|
||||||
|
private static function connect(): void |
||||||
|
{ |
||||||
|
if (null === self::$database) { |
||||||
|
$config = Config::getSection('database'); |
||||||
|
self::$database = new PDO( |
||||||
|
'mysql:host=' . $config['host'] . ';dbname=' . $config['database'], |
||||||
|
$config['username'], |
||||||
|
$config['password'], |
||||||
|
); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected static function delete(string $table, array $conditions): bool |
||||||
|
{ |
||||||
|
$where = $parameters = []; |
||||||
|
foreach ($conditions as $condition) { |
||||||
|
switch (count($condition)) { |
||||||
|
case 1: |
||||||
|
$where[] = '`' . $condition[0] . '`'; |
||||||
|
break; |
||||||
|
case 2: |
||||||
|
$where[] = '`' . $condition[0] . '`=:' . $condition[0]; |
||||||
|
$parameters[':' . $condition[0]] = $condition[1]; |
||||||
|
break; |
||||||
|
case 3: |
||||||
|
$where[] = '`' . $condition[0] . '`' . $condition[1] . ':' . $condition[0]; |
||||||
|
$parameters[':' . $condition[0]] = $condition[2]; |
||||||
|
break; |
||||||
|
default: |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
$sql = "DELETE FROM `$table` WHERE (" . implode(") AND (", $where) . ")"; |
||||||
|
$statement = self::prepare($sql, $parameters); |
||||||
|
return self::execute($statement); |
||||||
|
} |
||||||
|
|
||||||
|
private static function execute(PDOStatement $statement): bool |
||||||
|
{ |
||||||
|
if ($ret = $statement->execute()) { |
||||||
|
self::$lastErrorMessage = ''; |
||||||
|
} else { |
||||||
|
$errorInfo = $statement->errorInfo(); |
||||||
|
self::$lastErrorMessage = $errorInfo[0] . ': ' . $errorInfo[2]; |
||||||
|
} |
||||||
|
return $ret; |
||||||
|
} |
||||||
|
|
||||||
|
protected static function getLastErrorMessage(): string |
||||||
|
{ |
||||||
|
return self::$lastErrorMessage; |
||||||
|
} |
||||||
|
|
||||||
|
private static function getParameters(array $conditions): array |
||||||
|
{ |
||||||
|
$parameters = []; |
||||||
|
foreach ($conditions as $field => $value) { |
||||||
|
$parameters[":$field"] = $value; |
||||||
|
} |
||||||
|
return $parameters; |
||||||
|
} |
||||||
|
|
||||||
|
private static function getSelectQuery(string $table, array $fields, array $conditions): string |
||||||
|
{ |
||||||
|
$where = []; |
||||||
|
foreach ($conditions as $field => $value) { |
||||||
|
$where[] = "(`$field`=:$field)"; |
||||||
|
} |
||||||
|
return "SELECT `" . implode('`,`', $fields) . "` FROM `$table` WHERE " . implode(' AND ', $where); |
||||||
|
} |
||||||
|
|
||||||
|
protected static function insert(string $table, array $fields): bool |
||||||
|
{ |
||||||
|
$fields['created_at'] = $fields['modified_at'] = date('Y-m-d H:i:s'); |
||||||
|
$parameters = self::getParameters($fields); |
||||||
|
$sql = "INSERT INTO `$table`(`" . implode('`,`', array_keys($fields)) . "`) VALUES (" . |
||||||
|
implode(',', array_keys($parameters)) . ')'; |
||||||
|
$statement = self::prepare($sql, $parameters); |
||||||
|
return self::execute($statement); |
||||||
|
} |
||||||
|
|
||||||
|
private static function prepare(string $sql, array $parameters): PDOStatement |
||||||
|
{ |
||||||
|
self::connect(); |
||||||
|
$statement = self::$database->prepare($sql); |
||||||
|
foreach ($parameters as $name => $value) { |
||||||
|
if (is_bool($value)) { |
||||||
|
$type = PDO::PARAM_BOOL; |
||||||
|
} elseif (is_int($value)) { |
||||||
|
$type = PDO::PARAM_INT; |
||||||
|
} else { |
||||||
|
$type = PDO::PARAM_STR; |
||||||
|
} |
||||||
|
$statement->bindValue($name, $value, $type); |
||||||
|
} |
||||||
|
return $statement; |
||||||
|
} |
||||||
|
|
||||||
|
protected static function select(string $table, array $fields, array $conditions): ?array |
||||||
|
{ |
||||||
|
$parameters = self::getParameters($conditions); |
||||||
|
$sql = self::getSelectQuery($table, $fields, $conditions); |
||||||
|
$statement = self::prepare($sql, $parameters); |
||||||
|
self::execute($statement); |
||||||
|
$ret = $statement->fetchAll(PDO::FETCH_ASSOC); |
||||||
|
$statement->closeCursor(); |
||||||
|
return false === $ret ? null : $ret; |
||||||
|
} |
||||||
|
|
||||||
|
protected static function selectOne(string $table, array $fields, array $conditions): ?array |
||||||
|
{ |
||||||
|
$parameters = self::getParameters($conditions); |
||||||
|
$sql = self::getSelectQuery($table, $fields, $conditions) . ' LIMIT 1'; |
||||||
|
$statement = self::prepare($sql, $parameters); |
||||||
|
self::execute($statement); |
||||||
|
$ret = $statement->fetch(PDO::FETCH_ASSOC); |
||||||
|
$statement->closeCursor(); |
||||||
|
return false === $ret ? null : $ret; |
||||||
|
} |
||||||
|
|
||||||
|
protected static function selectSingleValue(string $table, string $field, array $conditions) |
||||||
|
{ |
||||||
|
$parameters = self::getParameters($conditions); |
||||||
|
$sql = self::getSelectQuery($table, [$field], $conditions) . ' LIMIT 1'; |
||||||
|
$statement = self::prepare($sql, $parameters); |
||||||
|
self::execute($statement); |
||||||
|
$ret = $statement->fetchColumn(); |
||||||
|
$statement->closeCursor(); |
||||||
|
return false === $ret ? null : $ret; |
||||||
|
} |
||||||
|
|
||||||
|
protected static function update(string $table, array $fields, array $conditions): bool |
||||||
|
{ |
||||||
|
$fields['modified_at'] = date('Y-m-d H:i:s'); |
||||||
|
$where = $parameters = $set = []; |
||||||
|
foreach ($fields as $field => $value) { |
||||||
|
$set[] = "`$field`=:p$field"; |
||||||
|
$parameters[":p$field"] = $value; |
||||||
|
} |
||||||
|
foreach ($conditions as $field => $value) { |
||||||
|
$where[] = "(`$field`=:w$field)"; |
||||||
|
$parameters[":w$field"] = $value; |
||||||
|
} |
||||||
|
$sql = "UPDATE `$table` SET " . implode(',', $set) . " WHERE " . implode(',', $where); |
||||||
|
$statement = self::prepare($sql, $parameters); |
||||||
|
return self::execute($statement); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,96 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace MwgAuth\Models; |
||||||
|
|
||||||
|
use MwgAuth\Core\Model; |
||||||
|
|
||||||
|
class Cns extends Model |
||||||
|
{ |
||||||
|
private static $policyValide = [ |
||||||
|
'1.3.76.16.2.1', // CNS |
||||||
|
'1.3.76.47.4', // CIE |
||||||
|
'1.3.6.1.4.1.29741.1.1.10', // CNS-Like |
||||||
|
'1.3.159.1.10.1', // Actalis |
||||||
|
'1.3.76.36.1.1.3', // CNS-Like Infocert |
||||||
|
]; |
||||||
|
private $certificato; |
||||||
|
private $codiceFiscale; |
||||||
|
|
||||||
|
public function __construct(string $certificato) |
||||||
|
{ |
||||||
|
if (null !== $certificato) { |
||||||
|
$this->certificato = openssl_x509_parse($certificato, false); |
||||||
|
$this->verificaCertificato(); |
||||||
|
// https://www.agid.gov.it/sites/default/files/repository_files/documentazione_trasparenza/strutturacertificatoautenticazionecns_v1.1_.pdf |
||||||
|
if (isset($this->certificato['subject']['serialNumber'])) { |
||||||
|
$this->codiceFiscale = preg_replace('/^[A-Za-z]{2}:/', '', $this->certificato['subject']['serialNumber']); |
||||||
|
} else { |
||||||
|
$this->codiceFiscale = explode('/', $this->certificato['subject']['commonName'])[0]; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public function getCertificato(): array |
||||||
|
{ |
||||||
|
return $this->certificato; |
||||||
|
} |
||||||
|
|
||||||
|
public function getCodiceFiscale(): ?string |
||||||
|
{ |
||||||
|
return $this->codiceFiscale; |
||||||
|
} |
||||||
|
|
||||||
|
public function getCognome(): ?string |
||||||
|
{ |
||||||
|
if (isset($this->certificato['subject']['surname'])) { |
||||||
|
$ret = $this->certificato['subject']['surname']; |
||||||
|
} elseif (isset($this->certificato['subject']['organizationalUnitName'])) { |
||||||
|
$ret = $this->certificato['subject']['organizationalUnitName']; |
||||||
|
if (is_array($ret)) { |
||||||
|
$ret = implode('/', $ret); |
||||||
|
} |
||||||
|
} else { |
||||||
|
$ret = $this->codiceFiscale; |
||||||
|
} |
||||||
|
return $ret; |
||||||
|
} |
||||||
|
|
||||||
|
public function getNome(): ?string |
||||||
|
{ |
||||||
|
return $this->certificato['subject']['givenName'] ?? $this->codiceFiscale; |
||||||
|
} |
||||||
|
|
||||||
|
public function verificaPolicyCertificato(): bool |
||||||
|
{ |
||||||
|
preg_match_all( |
||||||
|
'/Policy: ([0-9\.]+)/', |
||||||
|
$this->certificato['extensions']['certificatePolicies'], |
||||||
|
$policies |
||||||
|
); |
||||||
|
foreach ($policies[1] as $policy) { |
||||||
|
if (in_array($policy, self::$policyValide)) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
$this->salvaCertificato(); |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
private function verificaCertificato() |
||||||
|
{ |
||||||
|
// if (!isset($this->certificato['subject']['commonName']) || |
||||||
|
// !isset($this->certificato['subject']['surname']) || |
||||||
|
// !isset($this->certificato['subject']['givenName']) || |
||||||
|
// isset($this->certificato['subject']['serialNumber']) || |
||||||
|
// !isset($this->certificato['extensions']['certificatePolicies'])) { |
||||||
|
$this->salvaCertificato(); |
||||||
|
// } |
||||||
|
} |
||||||
|
|
||||||
|
private function salvaCertificato() |
||||||
|
{ |
||||||
|
$file = '/var/www/html/cns/policy/cert-' . sha1($this->certificato['subject']['commonName']); |
||||||
|
@file_put_contents($file . '.txt', print_r($this->certificato, true)); |
||||||
|
@file_put_contents($file . '.cer', $_SERVER['SSL_CLIENT_CERT']); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,18 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace MwgAuth\Models; |
||||||
|
|
||||||
|
use MwgAuth\Core\Model; |
||||||
|
|
||||||
|
class SiteConfig extends Model |
||||||
|
{ |
||||||
|
private static $config = []; |
||||||
|
|
||||||
|
public static function getSetting(string $key): string |
||||||
|
{ |
||||||
|
if (!isset(self::$config[$key])) { |
||||||
|
self::$config[$key] = self::selectSingleValue('config', 'value', ['key' >= $key]); |
||||||
|
} |
||||||
|
return self::$config[$key]; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,31 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace MwgAuth\Models; |
||||||
|
|
||||||
|
use MwgAuth\Core\Model; |
||||||
|
|
||||||
|
class Storage extends Model |
||||||
|
{ |
||||||
|
public static function fileGetContents(string $fileName): ?string |
||||||
|
{ |
||||||
|
$fullName = self::getFullName($fileName); |
||||||
|
if (file_exists($fullName)) { |
||||||
|
return file_get_contents($fullName); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
public static function filePutContents(string $fileName, string $data, int $flags = 0) |
||||||
|
{ |
||||||
|
$fullName = self::getFullName($fileName); |
||||||
|
$umask = umask(0); |
||||||
|
mkdir(dirname($fullName), 0777, true); |
||||||
|
file_put_contents($fullName, $data, $flags); |
||||||
|
umask($umask); |
||||||
|
} |
||||||
|
|
||||||
|
private static function getFullName(string $fileName): string |
||||||
|
{ |
||||||
|
return $_SERVER['DOCUMENT_ROOT'] . '/storage/' . $fileName; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,137 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace MwgAuth\Models; |
||||||
|
|
||||||
|
use MwgAuth\Core\Config; |
||||||
|
use MwgAuth\Core\Model; |
||||||
|
|
||||||
|
class User extends Model |
||||||
|
{ |
||||||
|
private $id; |
||||||
|
private $auth; |
||||||
|
private $userName; |
||||||
|
|
||||||
|
public static function load(string $userName, string $password, string $remoteAddress): ?User |
||||||
|
{ |
||||||
|
$password = self::hashPassword($password); |
||||||
|
#file_put_contents('/var/www/storage/password.txt', "$userName\n$password\n$remoteAddress\n"); |
||||||
|
$rows = self::select('users', ['id', 'username', 'remote'], ['username' => $userName, 'password' => $password]); |
||||||
|
foreach ($rows as $row) { |
||||||
|
if (fnmatch($row['remote'], $remoteAddress)) { |
||||||
|
return new User($row['id'], $row['username']); |
||||||
|
} |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
public function __construct(int $id, string $userName, ?string $auth = null) |
||||||
|
{ |
||||||
|
$this->id = $id; |
||||||
|
$this->userName = $userName; |
||||||
|
if (null === $auth) { |
||||||
|
do { |
||||||
|
$this->auth = sha1(random_int(PHP_INT_MIN, PHP_INT_MAX)); // /dev/urandom |
||||||
|
$result = $this->insert('sessions', [ |
||||||
|
'auth' => $this->auth, |
||||||
|
'user_id' => $this->id, |
||||||
|
'username' => $this->userName, |
||||||
|
]); |
||||||
|
} while (!$result); |
||||||
|
} else { |
||||||
|
$this->auth = $auth; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public static function cleanUp(): void |
||||||
|
{ |
||||||
|
$timestamp = date('Y-m-d H:i:s', time() - 900); |
||||||
|
self::delete('tokens', [['modified_at', '<', $timestamp]]); |
||||||
|
self::delete('sessions', [['modified_at', '<', $timestamp]]); |
||||||
|
} |
||||||
|
|
||||||
|
public function getAuth(): string |
||||||
|
{ |
||||||
|
return $this->auth; |
||||||
|
} |
||||||
|
|
||||||
|
public static function getCallback(string $token): ?string |
||||||
|
{ |
||||||
|
return self::selectSingleValue('tokens', 'callback', ['token' => $token]); |
||||||
|
} |
||||||
|
|
||||||
|
public function getLoginData(string $token): ?array |
||||||
|
{ |
||||||
|
$ret = $this->select('logins', ['codice_fiscale', 'nome', 'cognome'], ['token' => $token]); |
||||||
|
return empty($ret) ? null : $ret[0]; |
||||||
|
} |
||||||
|
|
||||||
|
public function getId(): int |
||||||
|
{ |
||||||
|
return $this->id; |
||||||
|
} |
||||||
|
|
||||||
|
public function getToken(string $callback): string |
||||||
|
{ |
||||||
|
do { |
||||||
|
$token = sha1(random_int(PHP_INT_MIN, PHP_INT_MAX)); // /dev/urandom |
||||||
|
$result = $this->insert('tokens', [ |
||||||
|
'token' => $token, |
||||||
|
'auth' => $this->auth, |
||||||
|
'callback' => $callback, |
||||||
|
]); |
||||||
|
} while (!$result); |
||||||
|
$this->touchAuth($this->auth); |
||||||
|
return $token; |
||||||
|
} |
||||||
|
|
||||||
|
public function getUserName(): string |
||||||
|
{ |
||||||
|
return $this->userName; |
||||||
|
} |
||||||
|
|
||||||
|
public static function setLoginData(string $token, string $codiceFiscale, string $nome, string $cognome): bool |
||||||
|
{ |
||||||
|
return self::insert('logins', [ |
||||||
|
'token' => $token, |
||||||
|
'codice_fiscale' => $codiceFiscale, |
||||||
|
'nome' => $nome, |
||||||
|
'cognome' => $cognome, |
||||||
|
]); |
||||||
|
} |
||||||
|
|
||||||
|
public static function verifyAuth(string $auth): ?User |
||||||
|
{ |
||||||
|
$row = self::selectOne('sessions', ['user_id', 'username', 'auth'], ['auth' => $auth]); |
||||||
|
if (null === $row) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
self::touchAuth($row['auth']); |
||||||
|
return new User($row['user_id'], $row['username'], $row['auth']); |
||||||
|
} |
||||||
|
|
||||||
|
public function verifyToken(string $token): bool |
||||||
|
{ |
||||||
|
$row = $this->select('tokens', ['token'], ['auth' => $this->auth, 'token' => $token]); |
||||||
|
return count($row) > 0; |
||||||
|
} |
||||||
|
|
||||||
|
private static function getSiteKey(): string |
||||||
|
{ |
||||||
|
return Config::getValue('site', 'key'); |
||||||
|
} |
||||||
|
|
||||||
|
private static function hashPassword(string $password): string |
||||||
|
{ |
||||||
|
$siteKey = self::getSiteKey(); |
||||||
|
return hash('sha256', $siteKey . $password); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Ha il solo effetto di aggiornare il campo "modified_at" della sessione |
||||||
|
*/ |
||||||
|
private static function touchAuth(string $auth): bool |
||||||
|
{ |
||||||
|
return self::update('sessions', [], ['auth' => $auth]); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,6 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace MwgAuth\Core; |
||||||
|
|
||||||
|
require_once(__DIR__.'/Core/AutoLoader.php'); |
||||||
|
AutoLoader::register(); |
||||||
@ -0,0 +1,8 @@ |
|||||||
|
#!/usr/bin/env php |
||||||
|
<?php |
||||||
|
|
||||||
|
use MwgAuth\Models\User; |
||||||
|
|
||||||
|
require('bootstrap.php'); |
||||||
|
|
||||||
|
User::cleanUp(); |
||||||
@ -0,0 +1,5 @@ |
|||||||
|
#!/bin/bash |
||||||
|
for a in $(seq 0 $(($(ls html/cns/policy/*.txt | wc -l) - 1))); do |
||||||
|
echo $a |
||||||
|
php int.php $a | grep 'Codice fiscale:' |
||||||
|
done |
||||||
@ -0,0 +1,6 @@ |
|||||||
|
<IfModule mod_rewrite.c> |
||||||
|
RewriteEngine On |
||||||
|
RewriteCond %{REQUEST_FILENAME} !-f |
||||||
|
RewriteCond %{REQUEST_FILENAME} !-d |
||||||
|
RewriteRule . index.php [L] |
||||||
|
</IfModule> |
||||||
@ -0,0 +1,8 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
use MwgAuth\Controllers\ControllerV1; |
||||||
|
|
||||||
|
require(dirname($_SERVER['DOCUMENT_ROOT']) . '/App/bootstrap.php'); |
||||||
|
preg_match('@/([_0-9A-Za-z]+)\.cgi$@', $_SERVER['REQUEST_URI'], $matches); |
||||||
|
$function = $matches[1] ?? ''; |
||||||
|
ControllerV1::run($function); |
||||||
@ -0,0 +1,21 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
use MwgAuth\Core\Controller; |
||||||
|
use MwgAuth\Models\Cns; |
||||||
|
use MwgAuth\Models\User; |
||||||
|
|
||||||
|
require_once(dirname($_SERVER['DOCUMENT_ROOT']) . '/App/bootstrap.php'); |
||||||
|
$cns = new Cns($_SERVER['SSL_CLIENT_CERT']); |
||||||
|
if (!$cns->verificaPolicyCertificato()) { |
||||||
|
Controller::redirect('/cns/policy-error.html'); |
||||||
|
} |
||||||
|
$token = $_GET['t'] ?? null; |
||||||
|
if (null === $token) { |
||||||
|
include($_SERVER['DOCUMENT_ROOT'] . '/errors/generic.php'); |
||||||
|
} else { |
||||||
|
if (null !== $cns->getCodiceFiscale()) { |
||||||
|
User::setLoginData($token, $cns->getCodiceFiscale(), $cns->getNome(), $cns->getCognome()); |
||||||
|
} |
||||||
|
$callback = User::getCallback($token); |
||||||
|
Controller::redirect($callback); |
||||||
|
} |
||||||
@ -0,0 +1,13 @@ |
|||||||
|
<!DOCTYPE html> |
||||||
|
<html> |
||||||
|
<head> |
||||||
|
<meta http-equiv="content-type" content="text/html; charset=UTF-8"> |
||||||
|
<title>Policy Error</title> |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
<h1>Errore Certificate Policies (Object ID: 2.5.29.32)<br></h1> |
||||||
|
<h2>Non è stato possibile autenticarti.</h2> |
||||||
|
<p>Il certificato presentato è valido ma non rispetta le <strong>Certificate Policies (Object ID: |
||||||
|
2.5.29.32)</strong> previste per la CIE e TS-CNS.</p> |
||||||
|
</body> |
||||||
|
</html> |
||||||
@ -0,0 +1,39 @@ |
|||||||
|
* { |
||||||
|
font-family: 'Titillium Web', sans-serif; |
||||||
|
} |
||||||
|
|
||||||
|
.btn-label, #spid-button .spid-button-icon { |
||||||
|
position: relative; |
||||||
|
left: -12px; |
||||||
|
display: inline-block; |
||||||
|
padding: 6px 12px; |
||||||
|
background: rgba(0,0,0,0.15); |
||||||
|
border-radius: 3px 0 0 3px; |
||||||
|
} |
||||||
|
.btn-labeled { |
||||||
|
padding-top: 0; |
||||||
|
padding-bottom: 0; |
||||||
|
} |
||||||
|
.btn { |
||||||
|
margin-bottom:10px; |
||||||
|
border-radius: 0; |
||||||
|
font-size: 16px; |
||||||
|
} |
||||||
|
hr.solid { |
||||||
|
border-top: 1px solid #ccc; |
||||||
|
width: 40%; |
||||||
|
margin-left: 0; |
||||||
|
} |
||||||
|
|
||||||
|
#spid-button .spid-button { |
||||||
|
margin: 0; |
||||||
|
border-radius: 0; |
||||||
|
padding: 0 0.75rem; |
||||||
|
height: auto; |
||||||
|
font-size: 16px; |
||||||
|
} |
||||||
|
|
||||||
|
.spid-button-text{ |
||||||
|
vertical-align: initial !important; |
||||||
|
font-weight: normal; |
||||||
|
} |
||||||
@ -0,0 +1,38 @@ |
|||||||
|
<?php require_once('init.php'); ?><!doctype html>
|
||||||
|
<html lang="it"> |
||||||
|
<head> |
||||||
|
<meta charset="utf-8"> |
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> |
||||||
|
<title>Autenticazione Regione Siciliana</title> |
||||||
|
<link rel="stylesheet" |
||||||
|
href="https://fonts.googleapis.com/css2?family=Titillium+Web:ital,wght@0,200;0,300;0,400;0,600;0,700;0,900;1,200;1,300;1,400;1,600;1,700&display=swap"> |
||||||
|
<link href="/css/bootstrap.css" rel="stylesheet"> |
||||||
|
<link href="/css/custom.css" rel="stylesheet"> |
||||||
|
</head> |
||||||
|
<body class="bg-light"> |
||||||
|
<div class="container"> |
||||||
|
<div class="row mt-3"> |
||||||
|
<div class="col-xs-12 col-sm-12 pb-4"> |
||||||
|
<img src="/images/logo-regione.png"> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="row"> |
||||||
|
<div class="col-xs-12 col-sm-12"> |
||||||
|
<h2>Errore di autenticazione</h2> |
||||||
|
<p>Si è verificato un errore inatteso durante l'autenticazione. Si prega di riprovare più tardi.</p> |
||||||
|
<?php if (null !== $callback) { ?> |
||||||
|
<div class="text-center d-block"> |
||||||
|
<a class="btn btn-primary btn-lg mt-4 text-center " href="<?= $callback ?>">Torna al portale</a>
|
||||||
|
</div> |
||||||
|
<?php } ?> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="row mt-3"> |
||||||
|
<div class="col-xs-12 col-sm-12 pb-4 text-center"> |
||||||
|
<p>Regione Siciliana - D.R.T.</p> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
</div> |
||||||
|
</body> |
||||||
|
</html> |
||||||
@ -0,0 +1,22 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
use MwgAuth\Models\User; |
||||||
|
|
||||||
|
require_once(dirname($_SERVER['DOCUMENT_ROOT']) . '/App/bootstrap.php'); |
||||||
|
|
||||||
|
$callback = null; |
||||||
|
parse_str($_SERVER['REDIRECT_QUERY_STRING'], $get); |
||||||
|
$token = $get['t'] ?? null; |
||||||
|
if (null !== $token) { |
||||||
|
$callback = User::getCallback($token); |
||||||
|
$parsed = parse_url($callback); |
||||||
|
if (isset($parsed['scheme']) && isset($parsed['host'])) { |
||||||
|
$callback = $parsed['scheme'] . '://' . $parsed['host']; |
||||||
|
if (($parsed['scheme'] === 'http' && $parsed['port'] != 80) |
||||||
|
|| ($parsed['scheme'] === 'https' && $parsed['port'] != 443) |
||||||
|
) { |
||||||
|
$callback .= ':' . $parsed['port']; |
||||||
|
} |
||||||
|
$callback .= '/'; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,39 @@ |
|||||||
|
<?php require_once('init.php'); ?><!doctype html>
|
||||||
|
<html lang="it"> |
||||||
|
<head> |
||||||
|
<meta charset="utf-8"> |
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> |
||||||
|
<title>Autenticazione Regione Siciliana</title> |
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Titillium+Web:ital,wght@0,200;0,300;0,400;0,600;0,700;0,900;1,200;1,300;1,400;1,600;1,700&display=swap" rel="stylesheet"> |
||||||
|
<link href="/css/bootstrap.css" rel="stylesheet"> |
||||||
|
<link href="/css/custom.css" rel="stylesheet"> |
||||||
|
</head> |
||||||
|
<body class="bg-light"> |
||||||
|
<div class="container"> |
||||||
|
<div class="row mt-3"> |
||||||
|
<div class="col-xs-12 col-sm-12 pb-4"> |
||||||
|
<img src="/images/logo-regione.png"> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="row"> |
||||||
|
<div class="col-xs-12 col-sm-12"> |
||||||
|
<h2>Errore autenticazione con CNS</h2> |
||||||
|
<p>Non è stato possibile autenticarti. Verifica che il lettore sia correttamente collegato e |
||||||
|
funzionante, e che la carta CIE o TS-CNS sia correttamente inserita o appoggiata sul lettore nel |
||||||
|
momento in cui procedi con l'accesso.</p> |
||||||
|
<?php if (null !== $callback) { ?> |
||||||
|
<div class="text-center d-block"> |
||||||
|
<a class="btn btn-primary btn-lg mt-4 text-center " href="<?= $callback ?>">Torna al portale</a>
|
||||||
|
</div> |
||||||
|
<?php } ?> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="row mt-3"> |
||||||
|
<div class="col-xs-12 col-sm-12 pb-4 text-center"> |
||||||
|
<p>Regione Siciliana - D.R.T.</p> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
</div> |
||||||
|
</body> |
||||||
|
</html> |
||||||
|
Dopo Larghezza: | Altezza: | Dimensione: 24 KiB |
|
Dopo Larghezza: | Altezza: | Dimensione: 20 KiB |
|
Dopo Larghezza: | Altezza: | Dimensione: 2.4 KiB |
@ -0,0 +1,63 @@ |
|||||||
|
<!doctype html> |
||||||
|
<html lang="it"> |
||||||
|
<head> |
||||||
|
<meta charset="utf-8"> |
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> |
||||||
|
<title>Autenticazione Regione Siciliana</title> |
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Titillium+Web:ital,wght@0,200;0,300;0,400;0,600;0,700;0,900;1,200;1,300;1,400;1,600;1,700&display=swap" rel="stylesheet"> |
||||||
|
<link href="/css/bootstrap.css" rel="stylesheet"> |
||||||
|
<link href="/css/custom.css" rel="stylesheet"> |
||||||
|
</head> |
||||||
|
<body class="bg-light"> |
||||||
|
<div class="container"> |
||||||
|
<div class="row mt-3"> |
||||||
|
<div class="col-12 pb-4"> |
||||||
|
<img src="/images/logo-regione.png"> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="row"> |
||||||
|
<div class="col-md-6 col-xs-12"> |
||||||
|
<h2>Accedi con CNS</h2> |
||||||
|
<hr class="solid"> |
||||||
|
<p> |
||||||
|
La Carta Nazionale dei Servizi o CNS è una smart card o una chiavetta USB che contiene un |
||||||
|
"certificato digitale" di autenticazione personale, utile per accedere ai servizi online della |
||||||
|
Regione Siciliana. |
||||||
|
</p> |
||||||
|
<form action="/cns/" method="GET"> |
||||||
|
<input type="hidden" name="t" value="<?= @$_GET['t'] ?>">
|
||||||
|
<button type="submit" class="btn btn-labeled btn-primary"> |
||||||
|
<span class="btn-label"> |
||||||
|
<img width="30" src="images/cns-icon.png"> |
||||||
|
</span> Entra con CNS |
||||||
|
</button> |
||||||
|
</form> |
||||||
|
</div> |
||||||
|
<div class="col-md-6 col-xs-12"> |
||||||
|
<h2>Accedi con SPID o CieID</h2> |
||||||
|
<hr class="solid"> |
||||||
|
<p> |
||||||
|
SPID è il sistema di accesso che consente di utilizzare, con un'identità digitale unica, i servizi |
||||||
|
online della Pubblica Amministrazione e dei privati accreditati. Se sei già in possesso di |
||||||
|
un'identità digitale, accedi con le credenziali del tuo gestore. Se non hai ancora un'identità |
||||||
|
digitale, richiedila ad uno dei gestori. |
||||||
|
</p> |
||||||
|
<form action="/spid/" method="GET"> |
||||||
|
<input type="hidden" name="t" value="<?= @$_GET['t'] ?>">
|
||||||
|
<button type="submit" class="btn btn-labeled btn-primary"> |
||||||
|
<span class="btn-label"> |
||||||
|
<img width="30" src="images/spid-icon.png"> |
||||||
|
</span> Entra con SPID o CieID |
||||||
|
</button> |
||||||
|
</form> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="row mt-3"> |
||||||
|
<div class="col-xs-12 col-sm-12 pb-4 text-center"> |
||||||
|
<p>Regione Siciliana - D.R.T.</p> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<script src="/js/jquery.min.js"></script> |
||||||
|
</body> |
||||||
|
</html> |
||||||
File diff suppressed because one or more lines are too long
@ -0,0 +1,12 @@ |
|||||||
|
{ |
||||||
|
"keys": [ |
||||||
|
{ |
||||||
|
"kty": "RSA", |
||||||
|
"alg": "RS256", |
||||||
|
"use": "sig", |
||||||
|
"kid": "auth", |
||||||
|
"n": "0guv1uiJLOulgTJN7O4m+Hrf9N80ByPnncssc7ule+3XtSdgSbUEG4ztZq+TsBoAmAwsE44LxY4FvYxy39n1cZrw9EeuGY62bMulh9qdScHyHoUQwPGz6xLDQGJ0orr5THcFfLISGJdXutND9bNsxlPwC328Nbvym2SEp6NL8g77tGlg1dDGNybs6lAeUTUWS1qXbWEMl3VhJZa711BUstCujZsL2WyEsupVr80tWYobeCxuys/XBnbWbuPLiFMXCaGUnEzaoc1N4bF9AO6LrGphMG9JLAcPbNyF/DIFYn2Mlvy7eaXkyFIom7GJejpZexABhtKDMSLBHnDHaneLrkwmy0WogJpVSuTYL0nJdfPT1bT8ONx8YGikWQS/b8gtk/u/QQRBGtsBTA5a4Begyo8LmqLzeXBilqopviyIHpJ3kOU2iZo4Fj5qSjnAMT2IGuKKDhrjCGjito40GtYQEqkxbZf+Zz8QSuf4EWQt4oXLVYqD1WiSUk1MQ93ZT2MwCyh+jDG7m67dkcikDJa7yQYi7knDEGKmhBCBu3u/q2042vlSUe/OJIeBpqB16pZUZxPAKr1LUjURCKeHA2R7f3N3oC4jjVYrdgCvrOV/ZcJpsXR4EpyChgRtK0owXFCs+981xbnlBLSBazJwUxB+LbRJoHRiUc+TuqFM38CQJ9M=", |
||||||
|
"e": "AQAB" |
||||||
|
} |
||||||
|
] |
||||||
|
} |
||||||
@ -0,0 +1,27 @@ |
|||||||
|
{ |
||||||
|
"client_id": "https://auth.mwg.it", |
||||||
|
"client_name": "Autenticazione Lavori Pubblici Sicilia", |
||||||
|
"grant_types": [ |
||||||
|
"authorization_code", |
||||||
|
"refresh_token" |
||||||
|
], |
||||||
|
"jwks_uri": "https://auth.mwg.it/openidc/jwks.json", |
||||||
|
"jwks": { |
||||||
|
"keys": [ |
||||||
|
{ |
||||||
|
"kty": "RSA", |
||||||
|
"alg": "RS256", |
||||||
|
"use": "sig", |
||||||
|
"kid": "auth", |
||||||
|
"n": "0guv1uiJLOulgTJN7O4m+Hrf9N80ByPnncssc7ule+3XtSdgSbUEG4ztZq+TsBoAmAwsE44LxY4FvYxy39n1cZrw9EeuGY62bMulh9qdScHyHoUQwPGz6xLDQGJ0orr5THcFfLISGJdXutND9bNsxlPwC328Nbvym2SEp6NL8g77tGlg1dDGNybs6lAeUTUWS1qXbWEMl3VhJZa711BUstCujZsL2WyEsupVr80tWYobeCxuys/XBnbWbuPLiFMXCaGUnEzaoc1N4bF9AO6LrGphMG9JLAcPbNyF/DIFYn2Mlvy7eaXkyFIom7GJejpZexABhtKDMSLBHnDHaneLrkwmy0WogJpVSuTYL0nJdfPT1bT8ONx8YGikWQS/b8gtk/u/QQRBGtsBTA5a4Begyo8LmqLzeXBilqopviyIHpJ3kOU2iZo4Fj5qSjnAMT2IGuKKDhrjCGjito40GtYQEqkxbZf+Zz8QSuf4EWQt4oXLVYqD1WiSUk1MQ93ZT2MwCyh+jDG7m67dkcikDJa7yQYi7knDEGKmhBCBu3u/q2042vlSUe/OJIeBpqB16pZUZxPAKr1LUjURCKeHA2R7f3N3oC4jjVYrdgCvrOV/ZcJpsXR4EpyChgRtK0owXFCs+981xbnlBLSBazJwUxB+LbRJoHRiUc+TuqFM38CQJ9M=", |
||||||
|
"e": "AQAB" |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
"redirect_uris": [ |
||||||
|
"https://auth.mwg.it/spid/callback/" |
||||||
|
], |
||||||
|
"response_types": [ |
||||||
|
"code" |
||||||
|
] |
||||||
|
} |
||||||
@ -0,0 +1,23 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
use MwgAuth\Core\Controller; |
||||||
|
use MwgAuth\Models\User; |
||||||
|
|
||||||
|
require_once(dirname($_SERVER['DOCUMENT_ROOT']) . '/App/bootstrap.php'); |
||||||
|
$token = $_GET['t'] ?? null; |
||||||
|
if ('' === ($token ?? '')) { |
||||||
|
include($_SERVER['DOCUMENT_ROOT'] . '/errors/generic.php'); |
||||||
|
} else { |
||||||
|
User::setLoginData( |
||||||
|
$token, |
||||||
|
$_SERVER['SPID_claim_fiscalNumber'], |
||||||
|
$_SERVER['SPID_claim_given_name'], |
||||||
|
$_SERVER['SPID_claim_family_name'] |
||||||
|
); |
||||||
|
$callback = User::getCallback($token); |
||||||
|
if (null === $callback) { |
||||||
|
include($_SERVER['DOCUMENT_ROOT'] . '/errors/generic.php'); |
||||||
|
} else { |
||||||
|
Controller::redirect($callback); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,18 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
if (php_sapi_name() != 'cli') { |
||||||
|
die(); |
||||||
|
} |
||||||
|
require_once('App/Core/Model.php'); |
||||||
|
require_once('App/Models/Cns.php'); |
||||||
|
|
||||||
|
$files = glob('html/cns/policy/*.cer'); |
||||||
|
if (count($files)) { |
||||||
|
$idx = $argc > 1 ? intval($argv[1]) : 0; |
||||||
|
$crt = file_get_contents($files[$idx]); |
||||||
|
$cns = new \MwgAuth\Models\Cns($crt); |
||||||
|
echo 'Codice fiscale: ' . $cns->getCodiceFiscale() . "\n"; |
||||||
|
echo 'Cognome: ' . $cns->getCognome() . "\n"; |
||||||
|
echo 'Nome: ' . $cns->getNome() . "\n"; |
||||||
|
echo 'Valido: ' . ($cns->verificaPolicyCertificato() ? 'true' : 'false') . "\n"; |
||||||
|
} |
||||||
@ -0,0 +1 @@ |
|||||||
|
25 3 * * * root /usr/local/bin/auto-update-gov-certificates |
||||||
@ -0,0 +1,20 @@ |
|||||||
|
<VirtualHost *:80> |
||||||
|
ServerAdmin ${APACHE_SERVER_ADMIN} |
||||||
|
ServerName ${SERVER_NAME} |
||||||
|
|
||||||
|
DocumentRoot /var/www/certbot |
||||||
|
|
||||||
|
RewriteEngine On |
||||||
|
|
||||||
|
RewriteRule ^/$ https://%{HTTP_HOST}/ [L,R=301] |
||||||
|
|
||||||
|
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f |
||||||
|
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d |
||||||
|
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] |
||||||
|
|
||||||
|
<Directory "/var/www/certbot"> |
||||||
|
Require all granted |
||||||
|
AllowOverride All |
||||||
|
Options -Indexes |
||||||
|
</Directory> |
||||||
|
</VirtualHost> |
||||||
@ -0,0 +1,70 @@ |
|||||||
|
SSLStrictSNIVHostCheck off |
||||||
|
|
||||||
|
<VirtualHost *:${APACHE_SSL_PORT}> |
||||||
|
ServerAdmin ${APACHE_SERVER_ADMIN} |
||||||
|
ServerName ${SERVER_NAME} |
||||||
|
|
||||||
|
DocumentRoot /var/www/html |
||||||
|
|
||||||
|
LogLevel ${APACHE_LOG_LEVEL} ssl:${APACHE_SSL_LOG_LEVEL} |
||||||
|
|
||||||
|
ErrorLog ${APACHE_LOG_DIR}/${SERVER_NAME}_error.log |
||||||
|
CustomLog ${APACHE_LOG_DIR}/${SERVER_NAME}_access.log "%h %{SSL_PROTOCOL}x %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" |
||||||
|
|
||||||
|
SSLEngine on |
||||||
|
|
||||||
|
SSLCertificateFile /etc/letsencrypt/live/${SERVER_NAME}/${APACHE_SSL_CERTS} |
||||||
|
SSLCertificateKeyFile /etc/letsencrypt/live/${SERVER_NAME}/${APACHE_SSL_PRIVATE} |
||||||
|
|
||||||
|
SSLCACertificatePath /etc/ssl/itaca/ |
||||||
|
SSLInsecureRenegotiation on |
||||||
|
|
||||||
|
OIDCProviderMetadataURL https://is-test.regione.sicilia.it:443/oauth2/token/.well-known/openid-configuration |
||||||
|
OIDCClientID sJs9yMsWWz8K2Vkvys1F37zmtwwa |
||||||
|
OIDCRedirectURI https://${SERVER_NAME}/spid/callback/ |
||||||
|
OIDCClientName SISMICA |
||||||
|
OIDCClientContact admin@mwg.it |
||||||
|
OIDCCryptoPassphrase zyNVgGtYvDh5d7RqsSvnz8EYR2a8 |
||||||
|
OIDCClaimPrefix SPID_claim_ |
||||||
|
OIDCPassClaimsAs environment |
||||||
|
OIDCPublicKeyFiles "auth#/etc/apache2/keys/public.pem" |
||||||
|
OIDCPrivateKeyFiles "auth#/etc/apache2/keys/private.pem" |
||||||
|
|
||||||
|
<Directory "/var/www/html"> |
||||||
|
Require all granted |
||||||
|
AllowOverride All |
||||||
|
Options -MultiViews +SymLinksIfOwnerMatch |
||||||
|
SSLOptions +StdEnvVars |
||||||
|
|
||||||
|
#Order Allow,Deny |
||||||
|
#Allow from 79.8.172.13 |
||||||
|
#Allow from 80.17.206.46 |
||||||
|
</Directory> |
||||||
|
|
||||||
|
<Directory "/var/www/html/cns"> |
||||||
|
AllowOverride None |
||||||
|
|
||||||
|
SSLVerifyClient ${APACHE_SSL_VERIFY_CLIENT} |
||||||
|
SSLRenegBufferSize 16777216 |
||||||
|
SSLVerifyDepth 10 |
||||||
|
SSLOptions +ExportCertData +StdEnvVars +OptRenegotiate |
||||||
|
|
||||||
|
SSLUserName SSL_CLIENT_S_DN_CN |
||||||
|
|
||||||
|
<If "env('APACHE_SSL_VERIFY_CLIENT') =~ /optional|optional_no_ca/"> |
||||||
|
RewriteEngine on |
||||||
|
RewriteCond %{SSL:SSL_CLIENT_VERIFY} !^SUCCESS$ |
||||||
|
RewriteRule .? - [F] |
||||||
|
ErrorDocument 403 ${CLIENT_VERIFY_LANDING_PAGE} |
||||||
|
</If> |
||||||
|
</Directory> |
||||||
|
|
||||||
|
<Directory "/var/www/html/spid"> |
||||||
|
Options -Indexes |
||||||
|
</Directory> |
||||||
|
|
||||||
|
<Location "/spid"> |
||||||
|
AuthType openid-connect |
||||||
|
Require valid-user |
||||||
|
</Location> |
||||||
|
</VirtualHost> |
||||||
@ -0,0 +1,63 @@ |
|||||||
|
/*!40101 SET NAMES utf8 */; |
||||||
|
|
||||||
|
/*!40101 SET SQL_MODE=''*/; |
||||||
|
|
||||||
|
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; |
||||||
|
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; |
||||||
|
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; |
||||||
|
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; |
||||||
|
CREATE DATABASE /*!32312 IF NOT EXISTS*/`autenticazione` /*!40100 DEFAULT CHARACTER SET utf8 */; |
||||||
|
USE `autenticazione`; |
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `logins`; |
||||||
|
CREATE TABLE `logins` ( |
||||||
|
`token` char(40) NOT NULL, |
||||||
|
`codice_fiscale` varchar(255) DEFAULT NULL, |
||||||
|
`nome` varchar(255) DEFAULT NULL, |
||||||
|
`cognome` varchar(255) DEFAULT NULL, |
||||||
|
`created_at` timestamp NULL DEFAULT NULL, |
||||||
|
`modified_at` timestamp NULL DEFAULT NULL, |
||||||
|
PRIMARY KEY (`token`) |
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `sessions`; |
||||||
|
CREATE TABLE `sessions` ( |
||||||
|
`auth` char(40) NOT NULL, |
||||||
|
`user_id` int(10) unsigned NOT NULL, |
||||||
|
`username` varchar(255) NOT NULL, |
||||||
|
`created_at` timestamp NULL DEFAULT NULL, |
||||||
|
`modified_at` timestamp NULL DEFAULT NULL, |
||||||
|
PRIMARY KEY (`auth`) |
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `tokens`; |
||||||
|
CREATE TABLE `tokens` ( |
||||||
|
`token` char(40) NOT NULL, |
||||||
|
`auth` char(40) NOT NULL, |
||||||
|
`callback` TEXT DEFAULT NULL, |
||||||
|
`created_at` timestamp NULL DEFAULT NULL, |
||||||
|
`modified_at` timestamp NULL DEFAULT NULL, |
||||||
|
PRIMARY KEY (`token`) |
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `users`; |
||||||
|
CREATE TABLE `users` ( |
||||||
|
`id` int(10) unsigned NOT NULL AUTO_INCREMENT, |
||||||
|
`username` varchar(255) NOT NULL, |
||||||
|
`password` char(64) NOT NULL, |
||||||
|
`remote` varchar(45) DEFAULT NULL, |
||||||
|
`created_at` timestamp NULL DEFAULT NULL, |
||||||
|
`updated_at` timestamp NULL DEFAULT NULL, |
||||||
|
`deleted_at` timestamp NULL DEFAULT NULL, |
||||||
|
PRIMARY KEY (`id`), |
||||||
|
UNIQUE KEY `users_username_remote_unique` (`username`,`remote`) |
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8; |
||||||
|
|
||||||
|
INSERT INTO `users`(`id`,`username`,`password`,`remote`,`created_at`,`updated_at`,`deleted_at`) VALUES |
||||||
|
(1,'sismica','268633d46fdf00502dba60facce2ba5eec6a5d86c843c19f3f3b1ef8c0342ada','192.168.15.*',CURRENT_TIMESTAMP,CURRENT_TIMESTAMP,NULL), |
||||||
|
(2,'sismica','268633d46fdf00502dba60facce2ba5eec6a5d86c843c19f3f3b1ef8c0342ada','79.8.172.13',CURRENT_TIMESTAMP,CURRENT_TIMESTAMP,NULL); |
||||||
|
|
||||||
|
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; |
||||||
|
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; |
||||||
|
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; |
||||||
|
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; |
||||||
@ -0,0 +1,22 @@ |
|||||||
|
SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH |
||||||
|
SSLProtocol All -SSLv2 -SSLv3 -TLSv1 -TLSv1.3 |
||||||
|
SSLHonorCipherOrder On |
||||||
|
|
||||||
|
# Disable preloading HSTS for now. You can use the commented out header line that includes |
||||||
|
# the "preload" directive if you understand the implications. |
||||||
|
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" |
||||||
|
Header always set X-Frame-Options DENY |
||||||
|
Header always set X-Content-Type-Options nosniff |
||||||
|
|
||||||
|
# Requires Apache >= 2.4 |
||||||
|
SSLCompression off |
||||||
|
SSLUseStapling on |
||||||
|
SSLStaplingCache "shmcb:logs/stapling-cache(150000)" |
||||||
|
|
||||||
|
# Prevent browsers from failing if an OCSP server is temporarily broken. |
||||||
|
SSLStaplingReturnResponderErrors off |
||||||
|
SSLStaplingErrorCacheTimeout 60 |
||||||
|
SSLStaplingStandardCacheTimeout 36000 |
||||||
|
|
||||||
|
# Requires Apache >= 2.4.11 |
||||||
|
SSLSessionTickets Off |
||||||
@ -0,0 +1,67 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
//define('SERVER_NAME', 'autenticazione.lavoripubblici.sicilia.it'); |
||||||
|
define('SERVER_NAME', 'auth.mwg.it'); |
||||||
|
define('CLIENT_ID', 'https://' . SERVER_NAME); |
||||||
|
define('CLIENT_NAME', 'Autenticazione Lavori Pubblici Sicilia'); |
||||||
|
define('REDIRECT_URIS', ['https://' . SERVER_NAME . '/spid/callback/']); |
||||||
|
define('JWKS_URI', 'https://' . SERVER_NAME . '/openidc/jwks.json'); |
||||||
|
|
||||||
|
$distinguished_names = [ |
||||||
|
'countryName' => 'IT', |
||||||
|
'stateOrProvinceName' => 'Sicilia', |
||||||
|
"organizationName" => 'Regione Siciliana', |
||||||
|
"organizationalUnitName" => 'Assessorato Infrastrutture, Trasporti e Mobilità', |
||||||
|
"commonName" => SERVER_NAME, |
||||||
|
"emailAddress" => 'info@lavoripubblici.sicilia.it', |
||||||
|
]; |
||||||
|
|
||||||
|
define('OPENIDC_PATH', '/var/www/html/openidc'); |
||||||
|
define('PRIVATE_KEY', 'private.pem'); |
||||||
|
define('PUBLIC_KEY', 'public.pem'); |
||||||
|
|
||||||
|
if (file_exists(PRIVATE_KEY)) { |
||||||
|
$private = openssl_pkey_get_private(file_get_contents(PRIVATE_KEY)); |
||||||
|
} else { |
||||||
|
$private = openssl_pkey_new([ |
||||||
|
'private_key_bits' => 4096, |
||||||
|
'private_key_type' => OPENSSL_KEYTYPE_RSA, |
||||||
|
]); |
||||||
|
openssl_pkey_export_to_file($private, 'private.pem'); |
||||||
|
} |
||||||
|
$details = openssl_pkey_get_details($private); |
||||||
|
file_put_contents(PUBLIC_KEY, $details['key']); |
||||||
|
// $csr = openssl_csr_new($distinguished_names, $private); |
||||||
|
// $x509 = openssl_csr_sign($csr, null, $private, 3650, ['digest_alg' => 'sha512']); |
||||||
|
// openssl_pkcs12_export_to_file($x509, 'privatekeys.pfx', $private, 'm4n1f'); |
||||||
|
$jwks = [ |
||||||
|
'keys' => [ |
||||||
|
[ |
||||||
|
'kty' => 'RSA', |
||||||
|
'alg' => 'RS256', |
||||||
|
'use' => 'sig', |
||||||
|
'kid' => 'auth', |
||||||
|
'n' => base64_encode($details['rsa']['n']), |
||||||
|
'e' => base64_encode($details['rsa']['e']), |
||||||
|
], |
||||||
|
], |
||||||
|
]; |
||||||
|
if (!is_dir(OPENIDC_PATH)) { |
||||||
|
mkdir(OPENIDC_PATH, 0777, true); |
||||||
|
} |
||||||
|
file_put_contents(OPENIDC_PATH . '/jwks.json', json_encode($jwks, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)); |
||||||
|
$metadata = json_encode([ |
||||||
|
'client_id' => CLIENT_ID, |
||||||
|
'client_name' => CLIENT_NAME, |
||||||
|
'grant_types' => [ |
||||||
|
'authorization_code', |
||||||
|
'refresh_token', |
||||||
|
], |
||||||
|
'jwks_uri' => JWKS_URI, |
||||||
|
'jwks' => $jwks, |
||||||
|
'redirect_uris' => REDIRECT_URIS, |
||||||
|
'response_types' => [ |
||||||
|
'code', |
||||||
|
], |
||||||
|
], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); |
||||||
|
file_put_contents(OPENIDC_PATH . '/metadata.json', $metadata); |
||||||
@ -0,0 +1,52 @@ |
|||||||
|
-----BEGIN PRIVATE KEY----- |
||||||
|
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 |
||||||
|
VUCvqPCuPs2rHHJ8y/0686d72gU3+gg= |
||||||
|
-----END PRIVATE KEY----- |
||||||
File binario non mostrato.
@ -0,0 +1,14 @@ |
|||||||
|
-----BEGIN PUBLIC KEY----- |
||||||
|
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0guv1uiJLOulgTJN7O4m |
||||||
|
+Hrf9N80ByPnncssc7ule+3XtSdgSbUEG4ztZq+TsBoAmAwsE44LxY4FvYxy39n1 |
||||||
|
cZrw9EeuGY62bMulh9qdScHyHoUQwPGz6xLDQGJ0orr5THcFfLISGJdXutND9bNs |
||||||
|
xlPwC328Nbvym2SEp6NL8g77tGlg1dDGNybs6lAeUTUWS1qXbWEMl3VhJZa711BU |
||||||
|
stCujZsL2WyEsupVr80tWYobeCxuys/XBnbWbuPLiFMXCaGUnEzaoc1N4bF9AO6L |
||||||
|
rGphMG9JLAcPbNyF/DIFYn2Mlvy7eaXkyFIom7GJejpZexABhtKDMSLBHnDHaneL |
||||||
|
rkwmy0WogJpVSuTYL0nJdfPT1bT8ONx8YGikWQS/b8gtk/u/QQRBGtsBTA5a4Beg |
||||||
|
yo8LmqLzeXBilqopviyIHpJ3kOU2iZo4Fj5qSjnAMT2IGuKKDhrjCGjito40GtYQ |
||||||
|
EqkxbZf+Zz8QSuf4EWQt4oXLVYqD1WiSUk1MQ93ZT2MwCyh+jDG7m67dkcikDJa7 |
||||||
|
yQYi7knDEGKmhBCBu3u/q2042vlSUe/OJIeBpqB16pZUZxPAKr1LUjURCKeHA2R7 |
||||||
|
f3N3oC4jjVYrdgCvrOV/ZcJpsXR4EpyChgRtK0owXFCs+981xbnlBLSBazJwUxB+ |
||||||
|
LbRJoHRiUc+TuqFM38CQJ9MCAwEAAQ== |
||||||
|
-----END PUBLIC KEY----- |
||||||
@ -0,0 +1,77 @@ |
|||||||
|
#!/bin/sh -e |
||||||
|
set -x |
||||||
|
SERVER_NAME='autenticazione.lavoripubblici.sicilia.it' |
||||||
|
CERTBOT_EMAIL='admin@mwg.it' |
||||||
|
DOCUMENT_ROOT='/var/www/html' |
||||||
|
|
||||||
|
MARIADB_USERNAME='mwg' |
||||||
|
MARIADB_PASSWORD='Aw42#1e_w.as' |
||||||
|
MARIADB_DATABASE='autenticazione' |
||||||
|
|
||||||
|
FOLDER="$(dirname $(realpath $0))" |
||||||
|
|
||||||
|
apt update |
||||||
|
apt -y dist-upgrade |
||||||
|
apt install -y apache2 certbot cron libapache2-mod-auth-openidc mariadb-server php php-mysql python |
||||||
|
|
||||||
|
# OpenSSL |
||||||
|
sed -i -e 's/^CipherString = .*/CipherString = DEFAULT@SECLEVEL=1/' /etc/ssl/openssl.cnf |
||||||
|
|
||||||
|
# MariaDB |
||||||
|
# mysql -e "DROP DATABASE IF EXISTS \`$MARIADB_DATABASE\`;" |
||||||
|
if [ "0" = "$(mysql -B -N -e "SHOW DATABASES LIKE '$MARIADB_DATABASE';" | wc -l)" ]; then |
||||||
|
mysql < $FOLDER/file/autenticazione.sql |
||||||
|
fi |
||||||
|
if [ "0" = "$(mysql -B -N -e \ |
||||||
|
"SELECT \`User\` FROM \`mysql\`.\`user\` WHERE \`User\`='$MARIADB_USERNAME' AND \`Host\`='localhost';" | \ |
||||||
|
wc -l)" ]; then |
||||||
|
mysql -e "GRANT ALL PRIVILEGES ON \`$MARIADB_DATABASE\`.* TO '$MARIADB_USERNAME'@'localhost' IDENTIFIED BY \ |
||||||
|
'$MARIADB_PASSWORD'" |
||||||
|
fi |
||||||
|
sed -i -e "s/\\(\\s*'password'\\s*=>\\s*\\).*/\\1'$MARIADB_PASSWORD',/" /var/www/App/Config/database.php |
||||||
|
|
||||||
|
# Sshd |
||||||
|
mkdir -p /etc/ssh/sshd_config.d |
||||||
|
echo 'PasswordAuthentication no' > /etc/ssh/sshd_config.d/mwg.conf |
||||||
|
|
||||||
|
# Autenticazione |
||||||
|
cp $FOLDER/usr-local-bin/* /usr/local/bin |
||||||
|
. /usr/local/bin/project_env.sh |
||||||
|
echo "export SERVER_NAME=$SERVER_NAME" >> /usr/local/bin/project_env.sh |
||||||
|
echo "export APPLICATION_URL=https://$SERVER_NAME:443" >> /usr/local/bin/project_env.sh |
||||||
|
|
||||||
|
# Apache |
||||||
|
cp $FOLDER/file/ssl-params.conf /etc/apache2/conf-available/ |
||||||
|
if [ "$(grep /usr/local/bin/project_env.sh /etc/apache2/envvars | wc -l)" = "0" ]; then |
||||||
|
echo '. /usr/local/bin/project_env.sh' >> /etc/apache2/envvars |
||||||
|
fi |
||||||
|
a2enconf ssl-params |
||||||
|
a2enmod headers |
||||||
|
a2enmod rewrite |
||||||
|
a2enmod ssl |
||||||
|
cd /etc/apache2/sites-enabled |
||||||
|
find /etc/apache2/sites-enabled -type l -exec sh -c 'a2dissite $(basename {})' \; |
||||||
|
cp $FOLDER/file/0certbot.conf /etc/apache2/sites-available |
||||||
|
a2ensite 0certbot |
||||||
|
systemctl restart apache2 |
||||||
|
|
||||||
|
certbot certonly -d $SERVER_NAME --webroot --webroot-path /var/www/certbot -m $CERTBOT_EMAIL --agree-tos \ |
||||||
|
--non-interactive --no-eff-email --expand |
||||||
|
|
||||||
|
mkdir -p /etc/apache2/keys |
||||||
|
cp $FOLDER/metadata/private.pem $FOLDER/metadata/public.pem /etc/apache2/keys |
||||||
|
cp $FOLDER/file/1autenticazione.conf /etc/apache2/sites-available |
||||||
|
a2ensite 1autenticazione |
||||||
|
|
||||||
|
/usr/local/bin/auto-update-gov-certificates |
||||||
|
|
||||||
|
# Cronjob |
||||||
|
cp $FOLDER/cron/* /etc/cron.d |
||||||
|
|
||||||
|
echo Installazione terminata |
||||||
|
|
||||||
|
# apt purge --auto-remove apache2 certbot cron libapache2-mod-auth-openidc mariadb-server php php-mysql python;rmdir /var/lib/apache2/;rm -Rf /etc/ssl/itaca/ |
||||||
|
|
||||||
|
# openssl req -key private.pem -new -x509 -days 3650 -subj /C=IT/ST=Sicilia/O=Regione Siciliana/OU=Autenticazione Lavori Pubblici/CN=Autenticazione Lavori Pubblici -out cert.pem |
||||||
|
# openssl pkcs12 -export -inkey private.pem -in cert.pem -out keys.pfx -name autenticazione |
||||||
|
# keytool -v -list -keystore keys.pfx |
||||||
@ -0,0 +1,39 @@ |
|||||||
|
#!/bin/sh -e |
||||||
|
|
||||||
|
LOG_FILE="/var/log/auto-update-gov-certificates.log" |
||||||
|
echo "$(date "+%FT%T") Start auto upgrade Gov Certificates..." >> "$LOG_FILE" |
||||||
|
|
||||||
|
. /usr/local/bin/project_env.sh |
||||||
|
|
||||||
|
SIM_DIR="/etc/ssl/itaca" |
||||||
|
touch "$LOG_FILE" |
||||||
|
TMP_CERT_PATH=`mktemp -d` |
||||||
|
|
||||||
|
echo "$(date "+%FT%T") Remove temporary certificates file from $TMP_CERT_PATH" >> "$LOG_FILE" |
||||||
|
rm -Rf "$TMP_CERT_PATH"/* >> "$LOG_FILE" 2>&1 |
||||||
|
|
||||||
|
echo "$(date "+%FT%T") Downloading Gov Certificates in tmp path $TMP_CERT_PATH..." >> "$LOG_FILE" |
||||||
|
/usr/local/bin/parse-gov-certs.py --output-folder "$TMP_CERT_PATH" --service-type-identifier "$GOV_TRUST_CERTS_SERVICE_TYPE_IDENTIFIER" >> "$LOG_FILE" 2>&1 |
||||||
|
echo "$(date "+%FT%T") Downloading Gov Certificates...[END]" >> "$LOG_FILE" |
||||||
|
|
||||||
|
echo "$(date "+%FT%T") Save Gov Certificates into $GOV_TRUST_CERTS_OUTPUT_PATH" >> "$LOG_FILE" |
||||||
|
mkdir -p "$GOV_TRUST_CERTS_OUTPUT_PATH" >> "$LOG_FILE" 2>&1 |
||||||
|
rm -Rf "$GOV_TRUST_CERTS_OUTPUT_PATH"/* >> "$LOG_FILE" 2>&1 |
||||||
|
mv "$TMP_CERT_PATH"/* "$GOV_TRUST_CERTS_OUTPUT_PATH" >> "$LOG_FILE" 2>&1 |
||||||
|
rm -Rf "$TMP_CERT_PATH" >> "$LOG_FILE" 2>&1 |
||||||
|
|
||||||
|
echo "$(date "+%FT%T") Removing simlinks from $SIM_DIR ..." >> "$LOG_FILE" |
||||||
|
mkdir -p "$SIM_DIR" >> "$LOG_FILE" 2>&1 |
||||||
|
rm -Rf "$SIM_DIR"/* >> "$LOG_FILE" 2>&1 |
||||||
|
|
||||||
|
echo "$(date "+%FT%T") Creating simlinks into $SIM_DIR/" >> "$LOG_FILE" |
||||||
|
find "$GOV_TRUST_CERTS_OUTPUT_PATH" -type f | xargs -I{} basename "{}" | xargs -I{} ln -s "$GOV_TRUST_CERTS_OUTPUT_PATH/{}" "$SIM_DIR/{}" >> "$LOG_FILE" 2>&1 |
||||||
|
|
||||||
|
echo "$(date "+%FT%T") Re-Hashing $SIM_DIR/..." >> "$LOG_FILE" |
||||||
|
c_rehash "$SIM_DIR/" >> "$LOG_FILE" 2>&1 |
||||||
|
|
||||||
|
echo "$(date "+%FT%T") Start auto upgrade Gov Certificates...[END]" >> "$LOG_FILE" |
||||||
|
|
||||||
|
echo "$(date "+%FT%T") Restart Apache HTTP Service..." >> "$LOG_FILE" |
||||||
|
systemctl restart apache2 >> "$LOG_FILE" 2>&1 |
||||||
|
echo "$(date "+%FT%T") End auto upgrade Gov Certificates..." >> "$LOG_FILE" |
||||||
@ -0,0 +1,146 @@ |
|||||||
|
#!/usr/bin/env python |
||||||
|
# -*- coding: utf-8 -*- |
||||||
|
# Copyright (C) Marco Trevisan |
||||||
|
# |
||||||
|
# Authors: |
||||||
|
# Marco Trevisan <marco@trevisan.xyz> |
||||||
|
# |
||||||
|
# Revision for new URL: |
||||||
|
# Andrea Costantino <costan@amg.it> |
||||||
|
# |
||||||
|
# Revision for new XPath Query (add a filter by service type identifier) |
||||||
|
# Antonio Musarra <antonio.musarra@gmail.com> |
||||||
|
# |
||||||
|
# This program is free software; you can redistribute it and/or modify it under |
||||||
|
# the terms of the GNU General Public License as published by the Free Software |
||||||
|
# Foundation; version 3. |
||||||
|
# |
||||||
|
# This program is distributed in the hope that it will be useful, but WITHOUTa |
||||||
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
||||||
|
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
||||||
|
# details. |
||||||
|
# |
||||||
|
# You should have received a copy of the GNU General Public License along with |
||||||
|
# this program; if not, write to the Free Software Foundation, Inc., |
||||||
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||||
|
# |
||||||
|
# Get Italian government Certification Authority certificates from used by |
||||||
|
# by various National Service SmartCards (Carta Nazionale dei Servizi- CNS) |
||||||
|
# |
||||||
|
# Original URI: |
||||||
|
# - http://www.agid.gov.it/agenda-digitale/infrastrutture-architetture/firme-elettroniche/certificati |
||||||
|
# |
||||||
|
# Current XML file: |
||||||
|
# - https://eidas.agid.gov.it/TL/TSL-IT.xml |
||||||
|
|
||||||
|
import argparse |
||||||
|
import re |
||||||
|
import sys |
||||||
|
import xml.etree.ElementTree as ET |
||||||
|
import textwrap |
||||||
|
import os |
||||||
|
|
||||||
|
DEFAULT_XML_URI = "https://eidas.agid.gov.it/TL/TSL-IT.xml" |
||||||
|
EXTENSION = ".pem" |
||||||
|
|
||||||
|
def get_certs_xml(): |
||||||
|
if sys.version_info[0] == 2: |
||||||
|
import urllib2 |
||||||
|
request = urllib2 |
||||||
|
else: |
||||||
|
import urllib.request |
||||||
|
request = urllib.request |
||||||
|
|
||||||
|
return request.urlopen(DEFAULT_XML_URI) |
||||||
|
|
||||||
|
def write_certificate(f, x509_cert): |
||||||
|
f.write('-----BEGIN CERTIFICATE-----\n') |
||||||
|
for line in textwrap.wrap(x509_cert, 65): |
||||||
|
f.write(line+'\n') |
||||||
|
f.write('-----END CERTIFICATE-----\n') |
||||||
|
|
||||||
|
def get_service_info(service): |
||||||
|
name = service.find("*/"+ns+"Name").text |
||||||
|
x509_cert = service.find("*//"+ns+"X509Certificate").text |
||||||
|
return {'name': name, 'x509_cert': x509_cert} |
||||||
|
|
||||||
|
parser = argparse.ArgumentParser() |
||||||
|
action = parser.add_mutually_exclusive_group(required=True) |
||||||
|
action.add_argument("--output-folder", help="Where to save the certs files") |
||||||
|
action.add_argument("--output-file", help="File saving certificates") |
||||||
|
parser.add_argument("--cert-file", help="Input Xml file, instead of %s" % DEFAULT_XML_URI) |
||||||
|
parser.add_argument("--service-type-identifier", help="Save certs by Service Type Identifier, instead of all") |
||||||
|
args = parser.parse_args() |
||||||
|
|
||||||
|
if args.output_folder: |
||||||
|
if os.path.exists(args.output_folder): |
||||||
|
if not os.path.isdir(args.output_folder): |
||||||
|
print("Impossible to save certificates in `%s': file exists and is not a folder." % args.output_folder) |
||||||
|
sys.exit(1) |
||||||
|
else: |
||||||
|
os.makedirs(args.output_folder) |
||||||
|
elif args.output_file: |
||||||
|
if os.path.exists(args.output_file): |
||||||
|
if not os.path.isfile(args.output_file): |
||||||
|
print("Impossible to write on `%s', it's not a file." % args.output_file) |
||||||
|
sys.exit(1) |
||||||
|
|
||||||
|
print("File `%s' will be overwritten..." % args.output_file) |
||||||
|
|
||||||
|
|
||||||
|
if args.cert_file: |
||||||
|
tree = ET.parse(args.cert_file) |
||||||
|
root = tree.getroot() |
||||||
|
else: |
||||||
|
root = ET.fromstring(get_certs_xml().read()) |
||||||
|
|
||||||
|
try: |
||||||
|
[ns] = re.findall("({[^}]*}).*", root.tag) |
||||||
|
except: |
||||||
|
ns = "" |
||||||
|
|
||||||
|
print("Namespace: `%s`", ns) |
||||||
|
|
||||||
|
if args.service_type_identifier: |
||||||
|
services = root.findall(ns+"TrustServiceProviderList//"+ns+"TSPService/"+ns+"ServiceInformation["+ns+"ServiceTypeIdentifier='"+args.service_type_identifier+"']") |
||||||
|
else: |
||||||
|
services = root.findall(ns+"TrustServiceProviderList//"+ns+"TSPService/"+ns+"ServiceInformation") |
||||||
|
|
||||||
|
if args.output_folder: |
||||||
|
for service in services: |
||||||
|
try: |
||||||
|
info = get_service_info(service) |
||||||
|
name = re.sub('[A-z]{1,2}=', '_', re.sub('[/\,\' "]', '_', info['name'])).replace('__', '_').strip('_- ') |
||||||
|
filename = args.output_folder+os.path.sep+name |
||||||
|
|
||||||
|
idx = 1 |
||||||
|
tmpname = filename |
||||||
|
while os.path.exists(tmpname+EXTENSION): |
||||||
|
tmpname = filename+str(idx) |
||||||
|
idx += 1 |
||||||
|
filename = tmpname+EXTENSION |
||||||
|
|
||||||
|
f = open(filename, 'w') |
||||||
|
write_certificate(f, info['x509_cert']) |
||||||
|
f.close() |
||||||
|
print("Added certificate: %s" % filename) |
||||||
|
|
||||||
|
except Exception as e: |
||||||
|
print("Impossible to add file: %s" % e) |
||||||
|
pass |
||||||
|
|
||||||
|
else: |
||||||
|
f = open(args.output_file, 'w') |
||||||
|
|
||||||
|
for service in services: |
||||||
|
try: |
||||||
|
info = get_service_info(service) |
||||||
|
write_certificate(f, info['x509_cert']) |
||||||
|
|
||||||
|
print("Added certificate %s" % info['name']) |
||||||
|
|
||||||
|
except Exception as e: |
||||||
|
print("Impossible to add certificate to file: %s" % e) |
||||||
|
pass |
||||||
|
|
||||||
|
f.close() |
||||||
@ -0,0 +1,12 @@ |
|||||||
|
export APACHE_SSL_VERIFY_CLIENT=optional |
||||||
|
export APACHE_LOG_LEVEL=info |
||||||
|
export GOV_TRUST_CERTS_OUTPUT_PATH=/usr/share/ca-certificates/it-gov |
||||||
|
export APACHE_SSL_LOG_LEVEL=debug |
||||||
|
export APACHE_SSL_PORT=443 |
||||||
|
export APACHE_SSL_PRIVATE=privkey.pem |
||||||
|
export GOV_TRUST_CERTS_SERVICE_TYPE_IDENTIFIER=http://uri.etsi.org/TrstSvc/Svctype/IdV |
||||||
|
export APACHE_SSL_CERTS=fullchain.pem |
||||||
|
export CLIENT_VERIFY_LANDING_PAGE=/errors/no-cns.php |
||||||
|
export APACHE_SERVER_ADMIN=info@lavoripubblici.sicilia.it |
||||||
|
export APACHE_RUN_USER=mwg |
||||||
|
export APACHE_RUN_GROUP=mwg |
||||||
Caricamento…
Reference in new issue