Add support for ini file for server properties via --config
This commit is contained in:
parent
19ff2d52a0
commit
d8cb106997
14
bin/makecert
14
bin/makecert
|
@ -20,18 +20,14 @@ if [ -z "$HOSTNAME" ]; then
|
|||
fi
|
||||
|
||||
echo "Making cert and key for host '$HOSTNAME'"
|
||||
mkdir -vp certs
|
||||
|
||||
# This one will generate a cert with SANs suitable for local dev
|
||||
openssl req -x509 -newkey rsa:4096 -nodes\
|
||||
-days 365 -subj "/CN=$HOSTNAME"\
|
||||
-keyout "$HOSTNAME.key.pem"\
|
||||
-out "$HOSTNAME.cert.pem"
|
||||
|
||||
# Use this one below with the -addext to include multiple domains (e.g. subdomains)
|
||||
#openssl req -x509 -newkey rsa:4096 -nodes\
|
||||
# -days 365 -subj "/CN=$HOSTNAME"\
|
||||
# -keyout "$HOSTNAME.key.pem"\
|
||||
# -out "$HOSTNAME.cert.pem"
|
||||
# -addext "subjectAltName=DNS:example.com,DNS:www.example.net,IP:10.0.0.1"
|
||||
-keyout "certs/$HOSTNAME.key.pem"\
|
||||
-out "certs/$HOSTNAME.cert.pem"\
|
||||
-addext "subjectAltName=DNS:$HOSTNAME,IP:127.0.0.1,IP:0.0.0.0"
|
||||
|
||||
# To inspect a cert use the following command
|
||||
#openssl x509 -in <path/to/cert/file> -text -noout
|
||||
|
|
|
@ -31,13 +31,15 @@ $autoload = require_once ORBIT_COMPOSER_AUTOLOAD;
|
|||
$args = new \Qi_Console_ArgV(
|
||||
$argv,
|
||||
[
|
||||
'config|c:' => 'Use specified config file (.ini) for configuration',
|
||||
'host:' => 'Set host/ip address to listen on (default 0.0.0.0)',
|
||||
'port|p:' => 'Set port to listen on (default 1965)',
|
||||
'hostname:' => 'Set hostname of server',
|
||||
'hostname:' => 'Set hostname of server (default localhost)',
|
||||
'tls-cert:' => 'Set cert PEM file to use (default null)',
|
||||
'tls-key:' => 'Set private key PEM file to use (default null)',
|
||||
'root-dir:' => 'Set the file root directory',
|
||||
'log:' => 'Set log filename (default orbit.log)',
|
||||
'dev' => 'Allow developer server functions (default false)',
|
||||
'help|h' => 'Show help',
|
||||
'verbose|v' => 'Include more verbose output',
|
||||
'quiet|q' => 'Print less messages',
|
||||
|
@ -46,7 +48,7 @@ $args = new \Qi_Console_ArgV(
|
|||
]
|
||||
);
|
||||
$terminal = new \Qi_Console_Terminal();
|
||||
$error_handler = new \Qi_Console_ExceptionHandler($terminal, true);
|
||||
$error_handler = new \Qi_Console_ExceptionHandler($terminal, true, true);
|
||||
$console = new \Orbit\Console($args, $terminal);
|
||||
|
||||
$value = $console->execute();
|
||||
|
|
44
config/example.ini
Normal file
44
config/example.ini
Normal file
|
@ -0,0 +1,44 @@
|
|||
; Example Orbit config file
|
||||
|
||||
; Host : The IP address designation that orbit should listen on
|
||||
host = "0.0.0.0"
|
||||
|
||||
; Port : the port that orbit should listen on
|
||||
port = 1965
|
||||
|
||||
; Hostname : the expected domain that orbit is serving
|
||||
hostname = "example.com"
|
||||
|
||||
; TLS cert file : The location to the cert file
|
||||
tls_certfile = "/etc/orbit/example.com.cert.pem"
|
||||
|
||||
; TLS key file : The location to the private key for the server
|
||||
tls_keyfile = "/etc/orbit/example.com.key.pem"
|
||||
|
||||
; Key passphrase : optional passphrase for server key
|
||||
key_passphrase = ""
|
||||
|
||||
; Log file : where orbit should log information
|
||||
log_file = "/var/log/orbit/orbit.log"
|
||||
|
||||
; Log level : Only log messages that are at or above this level
|
||||
; Possible values (from low to high):
|
||||
; - debug
|
||||
; - info
|
||||
; - notice
|
||||
; - warning
|
||||
; - error
|
||||
; - critical
|
||||
; - alert
|
||||
; - emergency
|
||||
log_level = "info"
|
||||
|
||||
; Root dir : Root directory of the server files
|
||||
root_dir = "/var/gemini"
|
||||
|
||||
; Index file : Name of the index file (when a directory is accessed)
|
||||
index_file = "index.gmi"
|
||||
|
||||
; Enable directory index : Whether orbit should serve up a directory listing
|
||||
; for directories accessed that have no index file present
|
||||
enable_directory_index = true
|
44
config/localhost.ini
Normal file
44
config/localhost.ini
Normal file
|
@ -0,0 +1,44 @@
|
|||
; Example Orbit config file for localhost
|
||||
|
||||
; Host : The IP address designation that orbit should listen on
|
||||
host = "0.0.0.0"
|
||||
|
||||
; Port : the port that orbit should listen on
|
||||
port = 1965
|
||||
|
||||
; Hostname : the expected domain that orbit is serving
|
||||
hostname = "localhost"
|
||||
|
||||
; TLS cert file : The location to the cert file
|
||||
tls_certfile = "certs/localhost.cert.pem"
|
||||
|
||||
; TLS key file : The location to the private key for the server
|
||||
tls_keyfile = "certs/localhost.key.pem"
|
||||
|
||||
; Key passphrase : optional passphrase for server key
|
||||
key_passphrase = ""
|
||||
|
||||
; Log file : where orbit should log information
|
||||
log_file = "log/orbit.log"
|
||||
|
||||
; Log level : Only log messages that are at or above this level
|
||||
; Possible values (from low to high):
|
||||
; - debug
|
||||
; - info
|
||||
; - notice
|
||||
; - warning
|
||||
; - error
|
||||
; - critical
|
||||
; - alert
|
||||
; - emergency
|
||||
log_level = "info"
|
||||
|
||||
; Root dir : Root directory of the server files
|
||||
root_dir = "."
|
||||
|
||||
; Index file : Name of the index file (when a directory is accessed)
|
||||
index_file = "index.gmi"
|
||||
|
||||
; Enable directory index : Whether orbit should serve up a directory listing
|
||||
; for directories accessed that have no index file present
|
||||
enable_directory_index = true
|
199
src/Orbit/Cert.php
Normal file
199
src/Orbit/Cert.php
Normal file
|
@ -0,0 +1,199 @@
|
|||
<?php
|
||||
|
||||
namespace Orbit;
|
||||
|
||||
use Monolog\Logger;
|
||||
|
||||
class Cert
|
||||
{
|
||||
public $hostname = '';
|
||||
public $tls_certfile = '';
|
||||
public $tls_keyfile = '';
|
||||
public $key_passphrase = '';
|
||||
|
||||
public function __construct(Config $config, Logger $logger)
|
||||
{
|
||||
$this->hostname = $config->hostname;
|
||||
$this->tls_certfile = $config->tls_certfile;
|
||||
$this->tls_keyfile = $config->tls_keyfile;
|
||||
$this->key_passphrase = $config->key_passphrase;
|
||||
|
||||
$this->logger = $logger;
|
||||
|
||||
if ($config->getIsDevelopmentServer()) {
|
||||
$this->initDevelopment();
|
||||
} else {
|
||||
$this->initProduction();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize for development mode
|
||||
*
|
||||
* If the cert files do not exist, generate a new self-signed cert
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function initDevelopment()
|
||||
{
|
||||
$this->logger->debug("Initialize cert for development mode.");
|
||||
|
||||
if ($this->tls_certfile == '') {
|
||||
$this->tls_certfile = sprintf("certs/%s.cert.pem", $this->hostname);
|
||||
}
|
||||
|
||||
if ($this->tls_keyfile == '') {
|
||||
$this->tls_keyfile = sprintf("certs/%s.key.pem", $this->hostname);
|
||||
}
|
||||
|
||||
if (file_exists($this->tls_certfile) && file_exists($this->tls_keyfile)) {
|
||||
$this->logger->info(sprintf("Using existing cert file '%s'", $this->tls_certfile));
|
||||
$this->logger->info(sprintf("Using existing key file '%s'", $this->tls_keyfile));
|
||||
} else {
|
||||
$this->logger->info(sprintf("Generating new cert file '%s'", $this->tls_certfile));
|
||||
$this->logger->info(sprintf("Generating new key file '%s'", $this->tls_keyfile));
|
||||
if (file_exists($this->tls_certfile)) {
|
||||
$this->logger->warning(sprintf("Warning! May overwrite existing cert file '%s'", $this->tls_certfile));
|
||||
}
|
||||
if (file_exists($this->tls_keyfile)) {
|
||||
$this->logger->warning(sprintf("Warning! May overwrite existing key file '%s'", $this->tls_keyfile));
|
||||
}
|
||||
$this->generateCert();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize for production mode
|
||||
*
|
||||
* Cert/key files must be provided. If fails, generates exception
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function initProduction()
|
||||
{
|
||||
$this->logger->debug("Initialize cert for production mode.");
|
||||
|
||||
$errors = [];
|
||||
if ($this->tls_certfile == '') {
|
||||
$errors[] = "Missing required cert file: use --tls-cert to specify;";
|
||||
}
|
||||
|
||||
if ($this->tls_keyfile == '') {
|
||||
$errors[] = "Missing required key file: use --tls-key to specify;";
|
||||
}
|
||||
|
||||
if ($this->tls_certfile && !file_exists($this->tls_certfile)) {
|
||||
$errors[] = sprintf("Cert file '%s' does not exist or is not readable!", $this->tls_certfile);
|
||||
}
|
||||
if ($this->tls_keyfile && !file_exists($this->tls_keyfile)) {
|
||||
$errors[] = sprintf("Key file '%s' does not exist or is not readable!", $this->tls_keyfile);
|
||||
}
|
||||
|
||||
if (count($errors)) {
|
||||
$errors[] = "\nTry running with --dev to generate a self-signed cert automatically.";
|
||||
$this->logger->alert(implode("\n", $errors));
|
||||
throw new \Exception("\n" . implode("\n", $errors));
|
||||
}
|
||||
|
||||
$this->logger->debug(sprintf("Using cert file '%s'", $this->tls_certfile));
|
||||
$this->logger->debug(sprintf("Using key file '%s'", $this->tls_keyfile));
|
||||
return true;
|
||||
}
|
||||
|
||||
private function generateCert()
|
||||
{
|
||||
// Certificate data
|
||||
$dn = [
|
||||
"countryName" => "UK",
|
||||
"stateOrProvinceName" => "X",
|
||||
"localityName" => "X",
|
||||
"organizationName" => "X",
|
||||
"organizationalUnitName" => "X",
|
||||
"commonName" => $this->hostname,
|
||||
"emailAddress" => "X",
|
||||
];
|
||||
|
||||
$days_valid = 365;
|
||||
$san_domains = ["DNS:" . $this->hostname, "IP:127.0.0.1", "IP:0.0.0.0"];
|
||||
$ssl_config = $this->createOpenSslConf($san_domains);
|
||||
|
||||
$csr_config = ['digest_alg' => 'sha256', 'req_extensions' => 'v3_req', 'config' => $ssl_config];
|
||||
$cert_config = ['digest_alg' => 'sha256', 'x509_extensions' => 'usr_cert', 'config' => $ssl_config];
|
||||
|
||||
// Generate certificate
|
||||
$private_key = openssl_pkey_new([
|
||||
'private_key_type' => OPENSSL_KEYTYPE_RSA,
|
||||
'private_key_bits' => 2048
|
||||
]);
|
||||
$cert = openssl_csr_new($dn, $private_key, $csr_config);
|
||||
$cert = openssl_csr_sign($cert, null, $private_key, $days_valid, $cert_config);
|
||||
|
||||
// Generate PEM files
|
||||
$pem = [];
|
||||
openssl_x509_export($cert, $pem[0]);
|
||||
openssl_pkey_export($private_key, $pem[1], $this->key_passphrase);
|
||||
|
||||
// Ensure dir exists for cert files
|
||||
$this->ensureDirExists($this->tls_certfile);
|
||||
$this->ensureDirExists($this->tls_keyfile);
|
||||
|
||||
// Save PEM files
|
||||
file_put_contents($this->tls_certfile, $pem[0]);
|
||||
file_put_contents($this->tls_keyfile, $pem[1]);
|
||||
|
||||
// Remove temp sslconf file
|
||||
unlink($ssl_config);
|
||||
}
|
||||
|
||||
/**
|
||||
* createOpenSslConf
|
||||
*
|
||||
* Creating this temp file to be used in the CSR and the cert signing is
|
||||
* required to add csr request and x509 extensions into the cert in order
|
||||
* to include the subject alternative names
|
||||
*
|
||||
* @param array $san_domains
|
||||
* @return string Filename
|
||||
*/
|
||||
private function createOpenSslConf($san_domains = [])
|
||||
{
|
||||
$san_domains_string = implode(",", $san_domains);
|
||||
|
||||
$str = <<<EOS
|
||||
[ req ]
|
||||
distinguished_name = req_distinguished_name
|
||||
req_extensions = v3_req
|
||||
|
||||
[ req_distinguished_name ]
|
||||
|
||||
[ v3_req ]
|
||||
basicConstraints = CA:FALSE
|
||||
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
|
||||
subjectAltName = $san_domains_string
|
||||
|
||||
[ usr_cert ]
|
||||
basicConstraints=CA:FALSE
|
||||
nsComment = "Generated Certificate by php unicorn"
|
||||
subjectKeyIdentifier=hash
|
||||
authorityKeyIdentifier=keyid,issuer
|
||||
subjectAltName = $san_domains_string
|
||||
EOS;
|
||||
|
||||
$temp_filename = tempnam("/tmp", "orbit-sslconf-");
|
||||
file_put_contents($temp_filename, $str);
|
||||
|
||||
return $temp_filename;
|
||||
}
|
||||
|
||||
private function ensureDirExists($filename)
|
||||
{
|
||||
$dir = dirname($filename);
|
||||
|
||||
if (!is_dir($dir)) {
|
||||
// Recursively make directory if necessary
|
||||
mkdir($dir, 0777, true);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,16 +7,56 @@ class Config
|
|||
public $host = "0.0.0.0";
|
||||
public $port = 1965;
|
||||
public $hostname = "localhost";
|
||||
public $log_file = "./orbit.log";
|
||||
|
||||
public $tls_certfile = "./server.cert.pem";
|
||||
public $tls_keyfile = "./server.key.pem";
|
||||
public $tls_certfile = "";
|
||||
public $tls_keyfile = "";
|
||||
public $key_passphrase = "";
|
||||
|
||||
public $quiet = false;
|
||||
public $verbose = false;
|
||||
public $log_file = ".log/orbit.log";
|
||||
public $log_level = "info";
|
||||
|
||||
public $root_dir = ".";
|
||||
public $index_file = "index.gmi";
|
||||
public $enable_directory_index = true;
|
||||
|
||||
private $is_development_server = false;
|
||||
|
||||
public function __construct($is_development = false)
|
||||
{
|
||||
$this->setIsDevelopmentServer($is_development);
|
||||
}
|
||||
|
||||
public function setIsDevelopmentServer($is_development_server)
|
||||
{
|
||||
$this->is_development_server = (bool) $is_development_server;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getIsDevelopmentServer()
|
||||
{
|
||||
return $this->is_development_server;
|
||||
}
|
||||
|
||||
public function readFromIniFile($filename)
|
||||
{
|
||||
if (!file_exists($filename) || !is_readable($filename)) {
|
||||
throw new \Exception("Cannot read config file '$filename'");
|
||||
}
|
||||
|
||||
$ini = parse_ini_file($filename);
|
||||
|
||||
$valid_keys = [
|
||||
'host', 'port', 'hostname', 'tls_certfile',
|
||||
'tls_keyfile', 'keypassphrase', 'log_file', 'log_level',
|
||||
'root_dir', 'index_file', 'enable_directory_index'
|
||||
];
|
||||
|
||||
foreach ($ini as $key => $value) {
|
||||
if (!in_array($key, $valid_keys)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->{$key} = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,19 +25,25 @@ class Console extends \Qi_Console_Client
|
|||
}
|
||||
|
||||
$config = $this->makeConfig();
|
||||
$logger = $this->makeLogger($config, $this->_args->quiet);
|
||||
|
||||
if (!$config->quiet) {
|
||||
if (!$this->_args->quiet) {
|
||||
print "Orbit // Gemini server software\n";
|
||||
print ":: Using cert file " . $config->tls_certfile . "\n";
|
||||
print ":: Using key file " . $config->tls_keyfile . "\n";
|
||||
}
|
||||
$server = new Server($config, $this->makeLogger($config));
|
||||
|
||||
$cert = new Cert($config, $logger);
|
||||
|
||||
$server = new Server($config, $cert, $logger);
|
||||
$server->listen();
|
||||
}
|
||||
|
||||
public function makeConfig()
|
||||
{
|
||||
$config = new Config();
|
||||
$config = new Config($this->_args->dev);
|
||||
|
||||
if ($this->_args->config) {
|
||||
$config->readFromIniFile($this->_args->config);
|
||||
}
|
||||
|
||||
if ($this->_args->host) {
|
||||
$config->host = $this->_args->host;
|
||||
|
@ -55,12 +61,8 @@ class Console extends \Qi_Console_Client
|
|||
$config->log_file = $this->_args->log;
|
||||
}
|
||||
|
||||
if ($this->_args->quiet) {
|
||||
$config->quiet = $this->_args->quiet;
|
||||
}
|
||||
|
||||
if ($this->_args->verbose) {
|
||||
$config->verbose = $this->_args->verbose;
|
||||
$config->log_level = Logger::DEBUG;
|
||||
}
|
||||
|
||||
if ($this->_args->get("root-dir")) {
|
||||
|
@ -69,33 +71,29 @@ class Console extends \Qi_Console_Client
|
|||
|
||||
if ($this->_args->get("tls-cert")) {
|
||||
$config->tls_certfile = $this->_args->get("tls-cert");
|
||||
} else {
|
||||
$config->tls_certfile = sprintf("%s.cert.pem", $config->hostname);
|
||||
}
|
||||
|
||||
if ($this->_args->get("tls-key")) {
|
||||
$config->tls_keyfile = $this->_args->get("tls-key");
|
||||
} else {
|
||||
$config->tls_keyfile = sprintf("%s.key.pem", $config->hostname);
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
public function makeLogger($config)
|
||||
public function makeLogger($config, $is_quiet = false)
|
||||
{
|
||||
$logger = new Logger('orbit');
|
||||
|
||||
$level = Logger::INFO;
|
||||
if ($config->verbose) {
|
||||
$level = Logger::DEBUG;
|
||||
if ($config->log_level) {
|
||||
$level = $config->log_level;
|
||||
}
|
||||
|
||||
$log_stream = new StreamHandler($config->log_file, $level);
|
||||
$log_stream->setFormatter($this->makeLogFormatter());
|
||||
$logger->pushHandler($log_stream);
|
||||
|
||||
if (!$config->quiet) {
|
||||
if (!$is_quiet) {
|
||||
$std_stream = new StreamHandler('php://stdout', $level);
|
||||
$std_stream->setFormatter($this->makeLogFormatter(true));
|
||||
$logger->pushHandler($std_stream);
|
||||
|
|
|
@ -10,15 +10,13 @@ class Server
|
|||
public static $version = "0.2";
|
||||
|
||||
public $config;
|
||||
public $tls_certfile = "./server.cert.pem";
|
||||
public $tls_keyfile = "./server.key.pem";
|
||||
public $key_passphrase = "";
|
||||
public $cert;
|
||||
public $timeout = 60;
|
||||
|
||||
private $ssl_context;
|
||||
private $logger;
|
||||
|
||||
public function __construct(Config $config = null, Logger $logger = null)
|
||||
public function __construct(Config $config = null, Cert $cert = null, Logger $logger = null)
|
||||
{
|
||||
if ($config == null) {
|
||||
$this->config = new Config();
|
||||
|
@ -28,22 +26,18 @@ class Server
|
|||
|
||||
if ($logger !== null) {
|
||||
$this->setLogger($logger);
|
||||
} else {
|
||||
$this->getLogger();
|
||||
}
|
||||
|
||||
if ($cert == null) {
|
||||
$this->cert = new Cert($config, $this->getLogger());
|
||||
} else {
|
||||
$this->cert = $cert;
|
||||
}
|
||||
|
||||
$this->timeout = ini_get("default_socket_timeout");
|
||||
|
||||
if (file_exists($this->config->tls_certfile) && file_exists($this->config->tls_keyfile)) {
|
||||
$this->log(Logger::DEBUG, "Using existing cert + key.");
|
||||
} else {
|
||||
$this->log(Logger::DEBUG, "Generating new cert.");
|
||||
if (file_exists($this->config->tls_certfile)) {
|
||||
$this->log(Logger::WARNING, "Warning! May overwrite existing cert file '" . $this->config->tls_certfile . "'\n");
|
||||
}
|
||||
if (file_exists($this->config->tls_keyfile)) {
|
||||
$this->log(Logger::WARNING, "Warning! May overwrite existing key file '" . $this->config->tls_keyfile . "'\n");
|
||||
}
|
||||
$this->generateCert();
|
||||
}
|
||||
$this->ssl_context = $this->createSslContext();
|
||||
}
|
||||
|
||||
|
@ -62,15 +56,19 @@ class Server
|
|||
return $this->logger;
|
||||
}
|
||||
|
||||
public function listen($root_dir = ".")
|
||||
public function listen($root_dir = null)
|
||||
{
|
||||
$path = realpath($root_dir);
|
||||
|
||||
if (!is_dir($path)) {
|
||||
throw new \Exception("Error: Root directory '$path' not a directory");
|
||||
if (null == $root_dir) {
|
||||
$root_dir = $this->config->root_dir;
|
||||
}
|
||||
|
||||
$this->log(Logger::DEBUG, "Root directory '$path'");
|
||||
if (!is_dir($root_dir)) {
|
||||
throw new \Exception("Error: Root directory '$root_dir' not a directory");
|
||||
}
|
||||
|
||||
$path = realpath($root_dir);
|
||||
|
||||
$this->logger->debug("Root directory '$path'");
|
||||
|
||||
$server = stream_socket_server(
|
||||
$this->getListenAddress(),
|
||||
|
@ -85,7 +83,7 @@ class Server
|
|||
|
||||
$protocol = "gemini";
|
||||
$name = stream_socket_get_name($server, false);
|
||||
$this->log(Logger::INFO, "Listening on $protocol://$name ...");
|
||||
$this->logger->info("Listening on $protocol://$name ...");
|
||||
|
||||
while (true) {
|
||||
# This is to swallow up the `timeout` warning
|
||||
|
@ -96,23 +94,22 @@ class Server
|
|||
if ($client) {
|
||||
$time = ['start' => microtime(true)];
|
||||
|
||||
$this->log(Logger::DEBUG, "$client_name Accepted");
|
||||
$this->logger->debug("$client_name Accepted");
|
||||
$request_buffer = stream_get_line($client, 1024, "\r\n");
|
||||
$this->log(Logger::INFO, "REQ: $request_buffer", ["client" => $client_name]);
|
||||
$this->logger->info("REQ: $request_buffer", ["client" => $client_name]);
|
||||
$request = new Request($request_buffer);
|
||||
|
||||
// Respond to client
|
||||
$response = $this->handleResponse($request, $path);
|
||||
$size = $response->send($client);
|
||||
$time['end'] = microtime(true);
|
||||
$this->log(
|
||||
Logger::DEBUG,
|
||||
$this->logger->debug(
|
||||
"RSP: " . trim($response->getHeader()),
|
||||
['size' => $size, 'time' => $time['end'] - $time['start']]
|
||||
);
|
||||
|
||||
fclose($client);
|
||||
$this->log(Logger::DEBUG, "$client_name Closed");
|
||||
$this->logger->debug("$client_name Closed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -186,10 +183,10 @@ class Server
|
|||
// Do nothing
|
||||
return;
|
||||
}
|
||||
$error = sprintf("Error %s: %s", $id, $message);
|
||||
$this->log(Logger::ERROR, "Connection Closed");
|
||||
|
||||
// Something else happened.
|
||||
$error = sprintf("Error %s: %s", $id, $message);
|
||||
$this->logger->error($error);
|
||||
throw new \Exception($error);
|
||||
}
|
||||
|
||||
|
@ -229,42 +226,14 @@ class Server
|
|||
return $body;
|
||||
}
|
||||
|
||||
private function generateCert()
|
||||
{
|
||||
// Certificate data
|
||||
$dn = [
|
||||
"countryName" => "UK",
|
||||
"stateOrProvinceName" => "X",
|
||||
"localityName" => "X",
|
||||
"organizationName" => "X",
|
||||
"organizationalUnitName" => "X",
|
||||
"commonName" => $this->config->hostname,
|
||||
"emailAddress" => "X"
|
||||
];
|
||||
|
||||
// Generate certificate
|
||||
$privkey = openssl_pkey_new();
|
||||
$cert = openssl_csr_new($dn, $privkey);
|
||||
$cert = openssl_csr_sign($cert, null, $privkey, 365);
|
||||
|
||||
// Generate PEM files
|
||||
$pem = [];
|
||||
openssl_x509_export($cert, $pem[0]);
|
||||
openssl_pkey_export($privkey, $pem[1], $this->config->key_passphrase);
|
||||
|
||||
// Save PEM files
|
||||
file_put_contents($this->config->tls_certfile, $pem[0]);
|
||||
file_put_contents($this->config->tls_keyfile, $pem[1]);
|
||||
}
|
||||
|
||||
public function createSslContext()
|
||||
{
|
||||
$context = stream_context_create();
|
||||
|
||||
// local_cert must be in PEM format
|
||||
stream_context_set_option($context, 'ssl', 'local_cert', $this->config->tls_certfile);
|
||||
stream_context_set_option($context, 'ssl', 'local_pk', $this->config->tls_keyfile);
|
||||
stream_context_set_option($context, 'ssl', 'passphrase', $this->config->key_passphrase);
|
||||
stream_context_set_option($context, 'ssl', 'local_cert', $this->cert->tls_certfile);
|
||||
stream_context_set_option($context, 'ssl', 'local_pk', $this->cert->tls_keyfile);
|
||||
stream_context_set_option($context, 'ssl', 'passphrase', $this->cert->key_passphrase);
|
||||
|
||||
stream_context_set_option($context, 'ssl', 'allow_self_signed', true);
|
||||
stream_context_set_option($context, 'ssl', 'verify_peer', false);
|
||||
|
|
Loading…
Reference in a new issue