(picture) |
|||
Line 22: | Line 22: | ||
automatically reload your SSL/TLS certificates when they are changed on the filesystem, no need for a cron job. | automatically reload your SSL/TLS certificates when they are changed on the filesystem, no need for a cron job. | ||
<syntaxhighlight lang="c" line> | |||
/* License: GPLv2 | |||
* Author: clrx | |||
*/ | |||
#include "unrealircd.h" | |||
ModuleHeader MOD_HEADER | |||
= { | |||
"third/certificate-refresh", /* name */ | |||
"1.0.0", /* version */ | |||
"Certificate Refresh: Automatically checks SSL/TLS certificates for changes, and reloads SSL/TLS if the certificate has been updated.", /* description */ | |||
"clarx", /* author */ | |||
"unrealircd-5", /* do not change this, it indicates module API version */ | |||
}; | |||
/*** <<<MODULE MANAGER START>>> | |||
module | |||
{ | |||
// Documentation, as displayed in './unrealircd module info nameofmodule', and possibly at other places: | |||
documentation "https://www.example.org/"; | |||
// This is displayed in './unrealircd module info ..' and also if compilation of the module fails: | |||
troubleshooting "In case of problems, check the FAQ at ... or e-mail me at ..."; | |||
min-unrealircd-version "5.*"; | |||
max-unrealircd-version "5.*"; | |||
post-install-text { | |||
"The module is installed. Now all you need to do is add a loadmodule line:"; | |||
"loadmodule \"third/certificate-refresh\";"; | |||
"And /REHASH the IRCd."; | |||
"The module does not need any other configuration."; | |||
} | |||
} | |||
*** <<<MODULE MANAGER END>>> | |||
*/ | |||
#define _MCRF_TIMEOUT 43200000 /* 12 hours, in milliseconds. */ | |||
typedef struct mCRF_Watch_File mCRF_Watch_File; | |||
struct mCRF_Watch_File { | |||
char *path; | |||
time_t last_modified; | |||
mCRF_Watch_File *next; | |||
}; | |||
/* Forward Declarations. */ | |||
EVENT(mCRF_timeout); | |||
EVENT(mCRF_setup_files); | |||
time_t mCRF_get_cert_time(const char *path); | |||
mCRF_Watch_File *mCRF_add_watch_file(const char *path); | |||
mCRF_Watch_File *mCRF_find_watch_file(const char *path); | |||
static mCRF_Watch_File *watched_files; | |||
EVENT(mCRF_timeout) | |||
{ | |||
TLSOptions *tls_options; | |||
int needReload = 0; | |||
mCRF_Watch_File *wptr; | |||
for (wptr = watched_files; wptr; wptr = wptr->next) | |||
{ | |||
time_t ts_curr = mCRF_get_cert_time(wptr->path); | |||
if (ts_curr != wptr->last_modified) | |||
{ | |||
needReload = 1; | |||
wptr->last_modified = ts_curr; | |||
} | |||
} | |||
if (needReload) | |||
{ | |||
sendto_snomask(SNO_SNOTICE, "*** [third/certificate-refresh]: Server TLS certificate(s) updated, reloading certificates."); | |||
reinit_ssl(NULL); | |||
} | |||
} | |||
EVENT(mCRF_setup_files) | |||
{ | |||
ConfigItem_listen *lptr; | |||
ConfigItem_sni *sptr; | |||
mCRF_Watch_File *wptr, *wptri; | |||
TLSOptions *tls_options = get_tls_options_for_client(&me); | |||
if (tls_options) | |||
mCRF_add_watch_file(tls_options->certificate_file); | |||
for (lptr = conf_listen; lptr; lptr = lptr->next) | |||
{ | |||
tls_options = lptr->tls_options; | |||
if (tls_options) | |||
mCRF_add_watch_file(tls_options->certificate_file); | |||
} | |||
for (sptr = conf_sni; sptr; sptr = sptr->next) | |||
{ | |||
mCRF_add_watch_file(sptr->tls_options->certificate_file); | |||
} | |||
} | |||
time_t mCRF_get_cert_time(const char *path) | |||
{ | |||
time_t r = 0; | |||
struct stat st; | |||
if (!stat(path, &st)) | |||
{ | |||
r = st.st_mtime; | |||
} | |||
return r; | |||
} | |||
mCRF_Watch_File *mCRF_add_watch_file(const char *path) | |||
{ | |||
mCRF_Watch_File *wptr; | |||
if (path == NULL) | |||
return NULL; | |||
wptr = mCRF_find_watch_file(path); | |||
if (wptr) | |||
return wptr; | return wptr; | ||
mCRF_Watch_File *mCRF_find_watch_file(const char *path) | wptr = safe_alloc(sizeof(mCRF_Watch_File)); | ||
memset(wptr, 0, sizeof(mCRF_Watch_File)); | |||
wptr->path = our_strdup(path); | |||
wptr->last_modified = mCRF_get_cert_time(wptr->path); | |||
if (watched_files == NULL) | |||
{ | |||
watched_files = wptr; | |||
} | |||
else | |||
{ | |||
mCRF_Watch_File *tmp, *prv; | |||
tmp = watched_files; | |||
while (tmp != NULL) | |||
{ | |||
prv = tmp; | |||
tmp = tmp->next; | |||
} | |||
prv->next = wptr; | |||
} | |||
return wptr; | |||
} | |||
mCRF_Watch_File *mCRF_find_watch_file(const char *path) | |||
{ | |||
mCRF_Watch_File *wptr; | |||
for (wptr = watched_files; wptr; wptr = wptr->next) | |||
{ | |||
if (smycmp(path, wptr->path) == 0) | |||
return wptr; | |||
} | |||
return NULL; | |||
} | |||
MOD_INIT() | |||
{ | |||
EventAdd(modinfo->handle, "mCRF_timeout", mCRF_timeout, NULL, _MCRF_TIMEOUT, 0); | |||
EventAdd(modinfo->handle, "mCRF_setup_files", mCRF_setup_files, NULL, 5 * 1000, 1); | |||
return MOD_SUCCESS; | |||
} | |||
MOD_UNLOAD() | |||
{ | { | ||
mCRF_Watch_File *wptr, *wptri; | |||
} | |||
for (wptr = watched_files; wptr; wptr = wptri) | |||
{ | |||
wptri = wptr->next; | |||
safe_free(wptr->path); | |||
safe_free(wptr); | |||
} | |||
return MOD_SUCCESS; | |||
} | |||
MOD_TEST() | |||
{ | |||
return MOD_SUCCESS; | |||
} | |||
MOD_LOAD() | |||
{ | |||
return MOD_SUCCESS; | |||
} | |||
</syntaxhighlight> |
Revision as of 02:52, 7 July 2021
"US Leaf" is not in the list (Hub, Leaf, Chaos Node, Art, Pseudoserver, Provisional, Banned) of allowed values for the "Node Type" property.{| class="infobox" |- |colspan="2" class="infobox-title"| dunes.p.mojavenet.xyz |- ! Name | dunes.p.mojavenet.xyz |- ! Location | San Jose, CA |- ! Hosting Provider | Oracle |- ! Owner | clrx |- ! SID | 8SL |- ! Type | US Leaf"US Leaf" is not in the list (Hub, Leaf, Chaos Node, Art, Pseudoserver, Provisional, Banned) of allowed values for the "Node Type" property. |- ! Status | Active |- !
|
|}
ports: 6667, 6697 (SSL) IPv4 & IPv6!
Cool features:
Create a new #channel, get a free +q!
Modules
/src/modules/third/certificate-refresh.c
automatically reload your SSL/TLS certificates when they are changed on the filesystem, no need for a cron job.
/* License: GPLv2
* Author: clrx
*/
#include "unrealircd.h"
ModuleHeader MOD_HEADER
= {
"third/certificate-refresh", /* name */
"1.0.0", /* version */
"Certificate Refresh: Automatically checks SSL/TLS certificates for changes, and reloads SSL/TLS if the certificate has been updated.", /* description */
"clarx", /* author */
"unrealircd-5", /* do not change this, it indicates module API version */
};
/*** <<<MODULE MANAGER START>>>
module
{
// Documentation, as displayed in './unrealircd module info nameofmodule', and possibly at other places:
documentation "https://www.example.org/";
// This is displayed in './unrealircd module info ..' and also if compilation of the module fails:
troubleshooting "In case of problems, check the FAQ at ... or e-mail me at ...";
min-unrealircd-version "5.*";
max-unrealircd-version "5.*";
post-install-text {
"The module is installed. Now all you need to do is add a loadmodule line:";
"loadmodule \"third/certificate-refresh\";";
"And /REHASH the IRCd.";
"The module does not need any other configuration.";
}
}
*** <<<MODULE MANAGER END>>>
*/
#define _MCRF_TIMEOUT 43200000 /* 12 hours, in milliseconds. */
typedef struct mCRF_Watch_File mCRF_Watch_File;
struct mCRF_Watch_File {
char *path;
time_t last_modified;
mCRF_Watch_File *next;
};
/* Forward Declarations. */
EVENT(mCRF_timeout);
EVENT(mCRF_setup_files);
time_t mCRF_get_cert_time(const char *path);
mCRF_Watch_File *mCRF_add_watch_file(const char *path);
mCRF_Watch_File *mCRF_find_watch_file(const char *path);
static mCRF_Watch_File *watched_files;
EVENT(mCRF_timeout)
{
TLSOptions *tls_options;
int needReload = 0;
mCRF_Watch_File *wptr;
for (wptr = watched_files; wptr; wptr = wptr->next)
{
time_t ts_curr = mCRF_get_cert_time(wptr->path);
if (ts_curr != wptr->last_modified)
{
needReload = 1;
wptr->last_modified = ts_curr;
}
}
if (needReload)
{
sendto_snomask(SNO_SNOTICE, "*** [third/certificate-refresh]: Server TLS certificate(s) updated, reloading certificates.");
reinit_ssl(NULL);
}
}
EVENT(mCRF_setup_files)
{
ConfigItem_listen *lptr;
ConfigItem_sni *sptr;
mCRF_Watch_File *wptr, *wptri;
TLSOptions *tls_options = get_tls_options_for_client(&me);
if (tls_options)
mCRF_add_watch_file(tls_options->certificate_file);
for (lptr = conf_listen; lptr; lptr = lptr->next)
{
tls_options = lptr->tls_options;
if (tls_options)
mCRF_add_watch_file(tls_options->certificate_file);
}
for (sptr = conf_sni; sptr; sptr = sptr->next)
{
mCRF_add_watch_file(sptr->tls_options->certificate_file);
}
}
time_t mCRF_get_cert_time(const char *path)
{
time_t r = 0;
struct stat st;
if (!stat(path, &st))
{
r = st.st_mtime;
}
return r;
}
mCRF_Watch_File *mCRF_add_watch_file(const char *path)
{
mCRF_Watch_File *wptr;
if (path == NULL)
return NULL;
wptr = mCRF_find_watch_file(path);
if (wptr)
return wptr;
wptr = safe_alloc(sizeof(mCRF_Watch_File));
memset(wptr, 0, sizeof(mCRF_Watch_File));
wptr->path = our_strdup(path);
wptr->last_modified = mCRF_get_cert_time(wptr->path);
if (watched_files == NULL)
{
watched_files = wptr;
}
else
{
mCRF_Watch_File *tmp, *prv;
tmp = watched_files;
while (tmp != NULL)
{
prv = tmp;
tmp = tmp->next;
}
prv->next = wptr;
}
return wptr;
}
mCRF_Watch_File *mCRF_find_watch_file(const char *path)
{
mCRF_Watch_File *wptr;
for (wptr = watched_files; wptr; wptr = wptr->next)
{
if (smycmp(path, wptr->path) == 0)
return wptr;
}
return NULL;
}
MOD_INIT()
{
EventAdd(modinfo->handle, "mCRF_timeout", mCRF_timeout, NULL, _MCRF_TIMEOUT, 0);
EventAdd(modinfo->handle, "mCRF_setup_files", mCRF_setup_files, NULL, 5 * 1000, 1);
return MOD_SUCCESS;
}
MOD_UNLOAD()
{
mCRF_Watch_File *wptr, *wptri;
for (wptr = watched_files; wptr; wptr = wptri)
{
wptri = wptr->next;
safe_free(wptr->path);
safe_free(wptr);
}
return MOD_SUCCESS;
}
MOD_TEST()
{
return MOD_SUCCESS;
}
MOD_LOAD()
{
return MOD_SUCCESS;
}