Prosody IM/how to/SSL/prosody-cert-fix.php

from HTYP, the free directory anyone can edit if they can prove to me that they're not a spambot
Jump to navigation Jump to search

Notes

  • It may be necessary to have this script execute service prosody restart whenever changes are made. To be tested.
  • If the SSL certificate used is from Let's Encrypt, clients such as Pidgin may still not recognize it as valid (but the error message will indicate that the signing authority is not valid, rather than some other issue like expiration date).

Code

<?php
/*
  PURPOSE: cron script for updating cert access when certs are renewed
    Cert renewal resets the cert access mode to user-only, no access for anyone else.
    We need to share some certs across multiple applications with different users, however.
  ACTION:
    * Checks the current group-owner and chmod for each cert in a list
    * If needed, resets the mode to give access to the group designated for SSL cert access.
  USAGE: run this script after running certbot, or regularly at some time-of-day not long
    after certbot runs.
  HISTORY:
    2018-06-24 started
*/

// ++ DEBUGGING ++ //

$fErrLevel = 0
    | E_ALL
    | E_STRICT
    ;
error_reporting($fErrLevel);
if (!ini_get('display_errors')) {
    ini_set('display_errors', 1);
}

// ++ SETTINGS ++ //

$sGroupDo = 'ssl-cert';	// group we're using for general cert access
$arCertFiles = array(		// list of cert files to check
  '/home/hypertwins/ssl.cert',
  '/home/hypertwins/ssl.key'
  );
$fsLog = __DIR__.'/shared-certs.log';
echo "Logging to [$fsLog]...\n";

// Why aren't there already constants for these?
define('KI_FMODE_OWNER_READ',0400);
define('KI_FMODE_OWNER_WRITE',0200);
define('KI_FMODE_OWNER_EXEC',0100);
define('KI_FMODE_GROUP_READ',0040);
define('KI_FMODE_GROUP_WRITE',0020);
define('KI_FMODE_GROUP_EXEC',0010);
define('KI_FMODE_GLOBAL_READ',0004);
define('KI_FMODE_GLOBAL_WRITE',0002);
define('KI_FMODE_GLOBAL_EXEC',0001);

// -- SETTINGS -- //
// ++ CALCULATIONS ++ //

$arGroupDo = posix_getgrnam($sGroupDo);
$idGroupDo = $arGroupDo['gid'];

// -- CALCULATIONS -- //
// ++ LOGGER CLASS ++ //

class cLogger {
    private $fs,$rf;

    public function __construct($fs) {
	$this->fs = $fs;
    }
    protected function OpenFile() {
	$this->rf = fopen($this->fs,'a');	// open log file for appending
    }
    protected function ShutFile() {
	fclose($this->rf);
    }
    protected function getTimeStamp() {
	return date('Y.m.d H:i:s');
    }
    public function WriteLine($s) {
	$this->OpenFile();
	$s = $this->getTimeStamp() . "\t" . $s . "\n";
	fwrite($this->rf,$s);
	echo "LOGGING: $s\n";
	$this->ShutFile();
    }
}

// -- LOGGER CLASS -- //
// ++ MAIN ++ //

$oLog = new cLogger($fsLog);

foreach ($arCertFiles as $fs) {
    $arStatIs = stat($fs);	// get information about file
    
    // check mode
    $nModeIs = $arStatIs['mode'];	// get file's permissions
    $sStatus = sprintf('[%s] is mode %o',$fs,$nModeIs);
    if (($nModeIs & KI_FMODE_GROUP_READ) == 0) {
	$nModeDo = $nModeIs | KI_FMODE_GROUP_READ;
	$sLine = $sStatus.sprintf(', changing to mode %o',$nModeDo);
	$oLog->WriteLine($sLine);
	chmod($fs,$nModeDo);
    } else {
	$sStatus .= ', no change needed.';
	echo $sStatus."\n";
    }
    
    // check owner-group
    $idGroupIs = $arStatIs['gid'];	// get file's group ID
    $arGroupIs = posix_getgrgid($idGroupIs);
    $sGroupIs = $arGroupIs['name'];
    $sStatus = "[$fs] is group #$idGroupIs ($sGroupIs)";
    if ($idGroupIs == $idGroupDo) {
	$sLine = $sStatus.', no change needed.';
	echo $sStatus."\n";
    } else {
	$sLine = $sStatus.", changing to #$idGroupDo ($sGroupDo)";
	$oLog->WriteLine($sLine);
	chgrp($fs,$idGroupDo);
    }
}

// -- MAIN -- //