/*****************************************************************************/ /* overseer.c The overseer is the certificate management activity executing in the detached process. It schedules the once-per-day certificate expiry management activity. The overseer.c module is considered the main module of wCME as an autonomous certificate management agent. Acme-client-portable has its own main.c module. VERSION HISTORY --------------- 28-MAR-2018 MGD WCME_AGREEMENT logical name 15-OCT-2017 MGD wcme_socketpair() for building on earlier than VMS V8.2 23-JUL-2017 MGD http-01 standalone challenge server 09-JUL-2017 MGD initial release 23-APR-2017 MGD initial development */ /*****************************************************************************/ #define SOFTWAREVN "1.3.0" #define SOFTWARENM "WCME" #ifdef __ALPHA # define SOFTWAREID SOFTWARENM " AXP-" SOFTWAREVN #endif #ifdef __ia64 # define SOFTWAREID SOFTWARENM " IA64-" SOFTWAREVN #endif #ifdef __VAX # define SOFTWAREID SOFTWARENM " VAX-" SOFTWAREVN #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "certman.h" #include "overseer.h" #include "util.h" #include "acmeport/config.h" #define FI_LI "OVERSEER", __LINE__ char *WcmeLogFileName; char SoftwareId [] = SOFTWAREID; /* from [.acme-client-portable..]main.c */ extern char *AcmePortDomainPtr, *AcmePortEsPtr; char* doasprintf (char*, ...); /*****************************************************************************/ /* Called from [.acme-client-portable..]main.c when a detached process. Oversees the periodic certificate check and any required update. */ void OverseerProcess (int argc, char* argv[]) { static short PrevDay; int secs, status, PerHour, PollSecs; ulong BinTime [2]; ushort NumTime [7]; char *cptr; /*********/ /* begin */ /*********/ UtilSetPrn (AcmePortEsPtr = "overseer"); /* in case there's a detached process log being generated */ sys$gettim (&BinTime); sys$numtim (&NumTime, &BinTime); fprintf (stdout, "%%WCME-I-STARTUP, %04.04u-%02.02u-%02.02u-%02.02u:%02.02u:%02.02u\n\ %%WCME-I-VERSION, %s\n\ %%WCME-I-IMAGE, %s\n", NumTime[0], NumTime[1], NumTime[2], NumTime[3], NumTime[4], NumTime[5], SoftwareId, UtilImageName()); /* only for development purposes */ if (cptr = UtilTrnLnm ("WCME_OVERSEER_POLL", "LNM$SYSTEM", 0)) { PollSecs = atoi(cptr); if (PollSecs <= 0 || PollSecs > 3600) PollSecs = 60; } else PollSecs = 0; /* only for development purposes */ if (UtilTrnLnm ("WCME_HOURLY", "LNM$SYSTEM", 0)) PerHour = 1; else PerHour = 0; for (;;) { sys$gettim (&BinTime); sys$numtim (&NumTime, &BinTime); /* open the log */ OverseerLog (NumTime[0], NumTime[1]); if (!PrevDay) vmsdbg ("starting %s", SoftwareId); if ((PrevDay && PrevDay != NumTime[2]) || PerHour) { /* day has changed so perform certificate management */ vmsdbg ("certificate management"); CertManBegin (); /* reload the time in case of extended certificate activities */ sys$gettim (&BinTime); sys$numtim (&NumTime, &BinTime); } PrevDay = NumTime[2]; /* polls at twenty minutes after each hour */ secs = (3600 - (NumTime[4] * 60)) + (60 - NumTime[5]) + (19 * 60); /* close the log */ OverseerLog (0, 0); if (PollSecs) { PrevDay = -1; sleep (PollSecs); } else sleep (secs); } } /*****************************************************************************/ /* The log is maintained on a per-month basis. */ void OverseerLog ( int year, int month ) { int status; char *cptr, *lfname; FILE *fp; struct stat stat_buf; /*********/ /* begin */ /*********/ if (WcmeLogFileName) free (WcmeLogFileName); WcmeLogFileName = NULL; if (!year) { stderr = freopen ("/nl", "w", stderr); if (!stderr) exit (vaxc$errno); return; } lfname = doasprintf ("/wcme_root/log/overseer_%04.04d%02.02d.log", year, month); WcmeLogFileName = strdup(lfname); UtilSysPrv(); status = stat (lfname, &stat_buf); stderr = freopen (lfname, "a", stderr, "ctx=rec", "rfm=var", "rat=cr", "rop=rlk", "shr=get", "shr=put"); UtilMereMortal(); if (!stderr) exit (vaxc$errno); /* only note the log file name the once with a newly created file */ if (status) vmsdbg ("%s", (char*)UtilVmsName(lfname,-1)); free (lfname); } /*****************************************************************************/ /* Ensure acme-client-portable warn/error output is captured. Called by the lib$spawn()ed and furk()ed [.acme-client-portable..]main.c Each subprocess needs an indepedent C-RTL std-I/O buffer to prevent mingling of the data (stderr) being written. Let the underlying RMS sort out the records. */ void OverseerSubprocessLog (char *lfname) { /*********/ /* begin */ /*********/ UtilSysPrv(); stderr = freopen (lfname, "a", stderr, "ctx=rec", "rfm=var", "rat=cr", "rop=rlk", "shr=get", "shr=put"); UtilMereMortal(); if (!stderr) exit (vaxc$errno); fprintf (stdout, "%s [main] %s\n", tstamp(NULL), SoftwareId); } /*****************************************************************************/