1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
<?php
class WebInterface
{
public const PROP_TYPE = 'webinterface.https-type';
public const PROP_HSTS = 'webinterface.https-hsts';
public const PROP_REDIRECT = 'webinterface.https-redirect';
public const PROP_CURRENT_CERT_DOMAINS = 'webinterface.https-domains';
public const PROP_REDIRECT_DOMAIN = 'webinterface.redirect-domain';
/**
* Read data all handled domains from current certificate.
* SAN takes precedence, if empty, we fall back to CN.
* @param string[] $certDomains
* @return bool success reading?
*/
public static function extractCurrentCertData(array &$certDomains, int &$expireTimestamp, string &$issuer): bool
{
if (!is_readable('/etc/lighttpd/pub-cert.pem'))
return false;
$cert = openssl_x509_parse(file_get_contents('/etc/lighttpd/pub-cert.pem'));
if ($cert === false)
return false;
// Domains
$certDomains = [];
if (isset($cert['extensions']['subjectAltName'])) {
$doms = preg_split('/[,\s]+/', $cert['extensions']['subjectAltName'], -1, PREG_SPLIT_NO_EMPTY);
foreach ($doms as $d) {
if (substr_compare($d, 'DNS:', 0, 4, true) !== 0)
continue;
$d = substr($d, 4);
if (preg_match('/^([a-z0-9_-]|\*\.)[a-z0-9_.-]+$/', $d) && !in_array($d, $certDomains)) {
$certDomains[] = $d;
}
}
}
if (empty($certDomains) && isset($cert['subject']['CN'])
&& preg_match('/^([a-z0-9_-]|\*\.)[a-z0-9_.-]+$/', $cert['subject']['CN'])) {
$certDomains[] = $cert['subject']['CN'];
}
foreach ($certDomains as &$d) {
if ($d[-1] === '.') {
$d = substr($d, 0, -1);
}
}
Property::set(self::PROP_CURRENT_CERT_DOMAINS, implode(' ', $certDomains));
// Expire time
$expireTimestamp = $cert['validTo_time_t'] ?? 0;
// Issuer
$issuer = $cert['issuer']['CN'] ?? 'Unknown';
return true;
}
public static function setDomainRedirect(bool $enable): void
{
Property::set(self::PROP_REDIRECT_DOMAIN, $enable ? '1' : false);
}
public static function getDomainRedirect(): bool
{
return !empty(Property::get(self::PROP_REDIRECT_DOMAIN, false));
}
}
|