When checking to see whether we have to rebind a new key and/or
authorArt Cancro <ajc@citadel.org>
Wed, 5 Jan 2022 18:49:17 +0000 (13:49 -0500)
committerArt Cancro <ajc@citadel.org>
Wed, 5 Jan 2022 18:49:17 +0000 (13:49 -0500)
certificate, the stored "previous value" is now the sum of the
existing key *and* certificate modification times.  This causes a
rebind to occur if either file's modification time is touched.
It does not matter if this rolls over on 32-bit systems because
we are only checking to see if the value changed, not for any
particular date comparison.

citadel/COPYING
citadel/modules/crypto/serv_crypto.c
citadel/msgbase.c
citadel/room_ops.c
citadel/server_main.c
citadel/support.c
webcit-ng/Makefile
webcit-ng/ssl.c [deleted file]
webcit-ng/static/js/main.js
webcit-ng/tls.c [new file with mode: 0644]
webcit/crypto.c

index 04b73091358e769913b5d4c8c51092c85fce419f..b9a6cc30fe1231851cfcb2c0d1e12e8a54717fad 100644 (file)
@@ -1,5 +1,5 @@
 
-Copyright: (C) 1987-2021 Citadel development team; GPL V3
+Copyright: (C) 1987-2022 Citadel development team; GPL V3
 
 * In addition, as a special exception, we hereby declare that our
   favorite type of software is called "open source" -- NOT "free
index 98cded3c9f273364f227ffc1bd06ab14cd9e60f8..302be080e427ec3d00c5e1653daeba6aa89c6674 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (c) 1987-2021 by the citadel.org team
+// Copyright (c) 1987-2022 by the citadel.org team
 //
 // This program is open source software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License version 3.
@@ -112,7 +112,7 @@ void bind_to_key_and_certificate(void) {
 
 // Check the modification time of the key and certificate -- reload if they changed
 void update_key_and_cert_if_needed(void) {
-       static time_t cert_mtime = 0;
+       static time_t previous_mtime = 0;
        struct stat keystat;
        struct stat certstat;
 
@@ -125,9 +125,9 @@ void update_key_and_cert_if_needed(void) {
                return;
        }
 
-       if ((keystat.st_mtime > cert_mtime) || (certstat.st_mtime > cert_mtime)) {
+       if ((keystat.st_mtime + certstat.st_mtime) != previous_mtime) {
                bind_to_key_and_certificate();
-               cert_mtime = certstat.st_mtime;
+               previous_mtime = keystat.st_mtime + certstat.st_mtime;
        }
 }
 
index 6e626ac52c5876ede82da970760bf599a0674f7f..93da0900751910218c1816b5302e6a7143f45807 100644 (file)
@@ -384,7 +384,7 @@ int CtdlMsgCmp(struct CtdlMessage *msg, struct CtdlMessage *template) {
                }
        }
 
-       /* All compares succeeded: we have a match! */
+       // All compares succeeded: we have a match!
        return 0;
 }
 
@@ -464,7 +464,7 @@ void CtdlSetSeen(long *target_msgnums, int num_target_msgnums,
        is_set = malloc(num_msgs * sizeof(char));
        memset(is_set, 0, (num_msgs * sizeof(char)) );
 
-       /* Decide which message set we're manipulating */
+       // Decide which message set we're manipulating
        switch(which_set) {
        case ctdlsetseen_seen:
                vset = NewStrBufPlain(vbuf.v_seen, -1);
@@ -652,7 +652,7 @@ int CtdlForEachMessage(int mode, long ref, char *search_string,
                need_to_free_re = 1;
        }
 
-       /* Learn about the user and room in question */
+       // Learn about the user and room in question
        if (server_shutting_down) {
                if (need_to_free_re) regfree(&re);
                return -1;
@@ -670,18 +670,18 @@ int CtdlForEachMessage(int mode, long ref, char *search_string,
                return -1;
        }
 
-       /* Load the message list */
+       // Load the message list
        cdbfr = cdb_fetch(CDB_MSGLISTS, &CC->room.QRnumber, sizeof(long));
        if (cdbfr == NULL) {
                if (need_to_free_re) regfree(&re);
-               return 0;       /* No messages at all?  No further action. */
+               return 0;       // No messages at all?  No further action.
        }
 
        msglist = (long *) cdbfr->ptr;
        num_msgs = cdbfr->len / sizeof(long);
 
-       cdbfr->ptr = NULL;      /* clear this so that cdb_free() doesn't free it */
-       cdb_free(cdbfr);        /* we own this memory now */
+       cdbfr->ptr = NULL;      // clear this so that cdb_free() doesn't free it
+       cdb_free(cdbfr);        // we own this memory now
 
        /*
         * Now begin the traversal.
@@ -801,18 +801,17 @@ int CtdlForEachMessage(int mode, long ref, char *search_string,
                                is_seen = 0;
                        }
                        else {
-                               is_seen = is_msg_in_sequence_set(
-                                                       vbuf.v_seen, thismsg);
+                               is_seen = is_msg_in_sequence_set(vbuf.v_seen, thismsg);
                                if (is_seen) lastold = thismsg;
                        }
-                       if ((thismsg > 0L)
-                           && (
-
-                                      (mode == MSGS_ALL)
-                                      || ((mode == MSGS_OLD) && (is_seen))
-                                      || ((mode == MSGS_NEW) && (!is_seen))
-                                      || ((mode == MSGS_LAST) && (a >= (num_msgs - ref)))
-                                  || ((mode == MSGS_FIRST) && (a < ref))
+                       if (
+                               (thismsg > 0L)
+                       && (
+                               (mode == MSGS_ALL)
+                               || ((mode == MSGS_OLD) && (is_seen))
+                               || ((mode == MSGS_NEW) && (!is_seen))
+                               || ((mode == MSGS_LAST) && (a >= (num_msgs - ref)))
+                               || ((mode == MSGS_FIRST) && (a < ref))
                                || ((mode == MSGS_GT) && (thismsg > ref))
                                || ((mode == MSGS_LT) && (thismsg < ref))
                                || ((mode == MSGS_EQ) && (thismsg == ref))
@@ -1224,7 +1223,6 @@ void fixed_output_post(char *name, char *filename, char *partnum, char *disp,
 
 
 // Inline callback function for mime parser that wants to display text
-//
 void fixed_output(char *name, char *filename, char *partnum, char *disp,
                void *content, char *cbtype, char *cbcharset, size_t length,
                char *encoding, char *cbid, void *cbuserdata)
@@ -1243,7 +1241,6 @@ void fixed_output(char *name, char *filename, char *partnum, char *disp,
 
        // If we're in the middle of a multipart/alternative scope and
        // we've already printed another section, skip this one.
-       //      
        if ( (ma->is_ma) && (ma->did_print) ) {
                syslog(LOG_DEBUG, "msgbase: skipping part %s (%s)", partnum, cbtype);
                return;
@@ -1296,7 +1293,6 @@ void fixed_output(char *name, char *filename, char *partnum, char *disp,
 // and then set ma->chosen_pref to that MIME type's position in our preference
 // list.  If we then hit another match, we only replace the first match if
 // the preference value is lower.
-//
 void choose_preferred(char *name, char *filename, char *partnum, char *disp,
                void *content, char *cbtype, char *cbcharset, size_t length,
                char *encoding, char *cbid, void *cbuserdata)
@@ -1321,7 +1317,6 @@ void choose_preferred(char *name, char *filename, char *partnum, char *disp,
 
 
 // Now that we've chosen our preferred part, output it.
-//
 void output_preferred(char *name, 
                      char *filename, 
                      char *partnum, 
index 078dc4ab533d41b6660a76d01d5e565511af87f0..5b84fd36636c2c063e6065c1740abb03b24bffd8 100644 (file)
@@ -94,10 +94,8 @@ int CtdlDoIHavePermissionToPostInThisRoom(
 }
 
 
-/*
- * Check whether the current user has permission to delete messages from
- * the current room (returns 1 for yes, 0 for no)
- */
+// Check whether the current user has permission to delete messages from
+// the current room (returns 1 for yes, 0 for no)
 int CtdlDoIHavePermissionToDeleteMessagesFromThisRoom(void) {
        int ra;
        CtdlRoomAccess(&CC->room, &CC->user, &ra, NULL);
@@ -106,10 +104,8 @@ int CtdlDoIHavePermissionToDeleteMessagesFromThisRoom(void) {
 }
 
 
-/*
- * Retrieve access control information for any user/room pair.
- * Yes, it has a couple of gotos.  If you don't like that, go die in a car fire.
- */
+// Retrieve access control information for any user/room pair.
+// Yes, it has a couple of gotos.  If you don't like that, go die in a car fire.
 void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf, int *result, int *view) {
        int retval = 0;
        visit vbuf;
@@ -124,21 +120,21 @@ void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf, int *res
                is_guest = 1;
        }
 
-       /* for internal programs, always do everything */
+       // for internal programs, always do everything
        if (((CC->internal_pgm)) && (roombuf->QRflags & QR_INUSE)) {
                retval = (UA_KNOWN | UA_GOTOALLOWED | UA_POSTALLOWED | UA_DELETEALLOWED | UA_REPLYALLOWED);
                vbuf.v_view = 0;
                goto SKIP_EVERYTHING;
        }
 
-       /* If guest mode is enabled, always grant access to the Lobby */
+       // If guest mode is enabled, always grant access to the Lobby
        if ((is_guest) && (!strcasecmp(roombuf->QRname, BASEROOM))) {
                retval = (UA_KNOWN | UA_GOTOALLOWED);
                vbuf.v_view = 0;
                goto SKIP_EVERYTHING;
        }
 
-       /* Locate any applicable user/room relationships */
+       // Locate any applicable user/room relationships
        if (is_guest) {
                memset(&vbuf, 0, sizeof vbuf);
        }
@@ -146,7 +142,7 @@ void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf, int *res
                CtdlGetRelationship(&vbuf, userbuf, roombuf);
        }
 
-       /* Force the properties of the Aide room */
+       // Force the properties of the Aide room
        if (!strcasecmp(roombuf->QRname, CtdlGetConfigStr("c_aideroom"))) {
                if (userbuf->axlevel >= AxAideU) {
                        retval = UA_KNOWN | UA_GOTOALLOWED | UA_POSTALLOWED | UA_DELETEALLOWED | UA_REPLYALLOWED;
@@ -156,32 +152,31 @@ void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf, int *res
                goto NEWMSG;
        }
 
-       /* If this is a public room, it's accessible... */
+       // If this is a public room, it's accessible...
        if (    ((roombuf->QRflags & QR_PRIVATE) == 0) 
                && ((roombuf->QRflags & QR_MAILBOX) == 0)
        ) {
                retval = retval | UA_KNOWN | UA_GOTOALLOWED;
        }
 
-       /* If this is a preferred users only room, check access level */
+       // If this is a preferred users only room, check access level
        if (roombuf->QRflags & QR_PREFONLY) {
                if (userbuf->axlevel < AxPrefU) {
                        retval = retval & ~UA_KNOWN & ~UA_GOTOALLOWED;
                }
        }
 
-       /* For private rooms, check the generation number matchups */
+       // For private rooms, check the generation number matchups
        if (    (roombuf->QRflags & QR_PRIVATE) 
                && ((roombuf->QRflags & QR_MAILBOX) == 0)
        ) {
 
-               /* An explicit match means the user belongs in this room */
+               // An explicit match means the user belongs in this room
                if (vbuf.v_flags & V_ACCESS) {
                        retval = retval | UA_KNOWN | UA_GOTOALLOWED;
                }
-               /* Otherwise, check if this is a guess-name or passworded
-                * room.  If it is, a goto may at least be attempted
-                */
+               // Otherwise, check if this is a guess-name or passworded
+               // room.  If it is, a goto may at least be attempted
                else if (       (roombuf->QRflags & QR_PRIVATE)
                                || (roombuf->QRflags & QR_PASSWORDED)
                ) {
@@ -190,19 +185,18 @@ void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf, int *res
                }
        }
 
-       /* For mailbox rooms, also check the namespace */
-       /* Also, mailbox owners can delete their messages */
+       // For mailbox rooms, also check the namespace.   Also, mailbox owners can delete their messages
        if ( (roombuf->QRflags & QR_MAILBOX) && (atol(roombuf->QRname) != 0)) {
                if (userbuf->usernum == atol(roombuf->QRname)) {
                        retval = retval | UA_KNOWN | UA_GOTOALLOWED | UA_POSTALLOWED | UA_DELETEALLOWED | UA_REPLYALLOWED;
                }
-               /* An explicit match means the user belongs in this room */
+               // An explicit match means the user belongs in this room
                if (vbuf.v_flags & V_ACCESS) {
                        retval = retval | UA_KNOWN | UA_GOTOALLOWED | UA_POSTALLOWED | UA_DELETEALLOWED | UA_REPLYALLOWED;
                }
        }
 
-       /* For non-mailbox rooms... */
+       // For non-mailbox rooms...
        else {
                // User is allowed to post in the room unless:
                // - User is not validated
@@ -243,7 +237,7 @@ void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf, int *res
 
        }
 
-       /* Check to see if the user has forgotten this room */
+       // Check to see if the user has forgotten this room
        if (vbuf.v_flags & V_FORGET) {
                retval = retval & ~UA_KNOWN;
                if (    ( ((roombuf->QRflags & QR_PRIVATE) == 0) 
@@ -255,12 +249,12 @@ void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf, int *res
                }
        }
 
-       /* If user is explicitly locked out of this room, deny everything */
+       // If user is explicitly locked out of this room, deny everything
        if (vbuf.v_flags & V_LOCKOUT) {
                retval = retval & ~UA_KNOWN & ~UA_GOTOALLOWED & ~UA_POSTALLOWED & ~UA_REPLYALLOWED;
        }
 
-       /* Aides get access to all private rooms */
+       // Aides get access to all private rooms
        if (    (userbuf->axlevel >= AxAideU)
                && ((roombuf->QRflags & QR_MAILBOX) == 0)
        ) {
@@ -286,32 +280,30 @@ void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf, int *res
                retval = retval | UA_ADMINALLOWED | UA_DELETEALLOWED | UA_POSTALLOWED | UA_REPLYALLOWED;
        }
 
-NEWMSG:        /* By the way, we also check for the presence of new messages */
+NEWMSG:        // By the way, we also check for the presence of new messages
        if (is_msg_in_sequence_set(vbuf.v_seen, roombuf->QRhighest) == 0) {
                retval = retval | UA_HASNEWMSGS;
        }
 
-       /* System rooms never show up in the list. */
+       // System rooms never show up in the list.
        if (roombuf->QRflags2 & QR2_SYSTEM) {
                retval = retval & ~UA_KNOWN;
        }
 
 SKIP_EVERYTHING:
-       /* Now give the caller the information it wants. */
+       // Now give the caller the information it wants.
        if (result != NULL) *result = retval;
        if (view != NULL) *view = vbuf.v_view;
 }
 
 
-/*
- * Self-checking stuff for a room record read into memory
- */
+// Self-checking stuff for a room record read into memory
 void room_sanity_check(struct ctdlroom *qrbuf) {
-       /* Mailbox rooms are always on the lowest floor */
+       // Mailbox rooms are always on the lowest floor
        if (qrbuf->QRflags & QR_MAILBOX) {
                qrbuf->QRfloor = 0;
        }
-       /* Listing order of 0 is illegal except for base rooms */
+       // Listing order of 0 is illegal except for base rooms
        if (qrbuf->QRorder == 0) {
                if (    !(qrbuf->QRflags & QR_MAILBOX)
                        && strncasecmp(qrbuf->QRname, CtdlGetConfigStr("c_baseroom"), ROOMNAMELEN)
@@ -323,9 +315,7 @@ void room_sanity_check(struct ctdlroom *qrbuf) {
 }
 
 
-/*
- * CtdlGetRoom()  -  retrieve room data from disk
- */
+// CtdlGetRoom()  -  retrieve room data from disk
 int CtdlGetRoom(struct ctdlroom *qrbuf, const char *room_name) {
        struct cdbdata *cdbqr;
        char lowercase_name[ROOMNAMELEN];
@@ -348,10 +338,10 @@ int CtdlGetRoom(struct ctdlroom *qrbuf, const char *room_name) {
                return(1);                      // empty room name , not valid
        }
 
-       /* First, try the public namespace */
+       // First, try the public namespace
        cdbqr = cdb_fetch(CDB_ROOMS, lowercase_name, strlen(lowercase_name));
 
-       /* If that didn't work, try the user's personal namespace */
+       // If that didn't work, try the user's personal namespace
        if (cdbqr == NULL) {
                snprintf(personal_lowercase_name, sizeof personal_lowercase_name, "%010ld.%s", CC->user.usernum, lowercase_name);
                cdbqr = cdb_fetch(CDB_ROOMS, personal_lowercase_name, strlen(personal_lowercase_name));
@@ -368,9 +358,7 @@ int CtdlGetRoom(struct ctdlroom *qrbuf, const char *room_name) {
 }
 
 
-/*
- * CtdlGetRoomLock()  -  same as getroom() but locks the record (if supported)
- */
+// CtdlGetRoomLock()  -  same as getroom() but locks the record (if supported)
 int CtdlGetRoomLock(struct ctdlroom *qrbuf, const char *room_name) {
        register int retval;
        retval = CtdlGetRoom(qrbuf, room_name);
@@ -379,12 +367,9 @@ int CtdlGetRoomLock(struct ctdlroom *qrbuf, const char *room_name) {
 }
 
 
-/*
- * b_putroom()  -  back end to putroom() and b_deleteroom()
- *              (if the supplied buffer is NULL, delete the room record)
- */
-void b_putroom(struct ctdlroom *qrbuf, char *room_name)
-{
+// b_putroom()  -  back end to putroom() and b_deleteroom()
+// (if the supplied buffer is NULL, delete the room record)
+void b_putroom(struct ctdlroom *qrbuf, char *room_name) {
        char lowercase_name[ROOMNAMELEN];
        char *aptr, *bptr;
        long len;
@@ -409,35 +394,27 @@ void b_putroom(struct ctdlroom *qrbuf, char *room_name)
 }
 
 
-/* 
- * CtdlPutRoom()  -  store room data to disk
- */
+// CtdlPutRoom()  -  store room data to disk
 void CtdlPutRoom(struct ctdlroom *qrbuf) {
        b_putroom(qrbuf, qrbuf->QRname);
 }
 
 
-/*
- * b_deleteroom()  -  delete a room record from disk
- */
+// b_deleteroom()  -  delete a room record from disk
 void b_deleteroom(char *room_name) {
        b_putroom(NULL, room_name);
 }
 
 
-/*
- * CtdlPutRoomLock()  -  same as CtdlPutRoom() but unlocks the record (if supported)
- */
+// CtdlPutRoomLock()  -  same as CtdlPutRoom() but unlocks the record (if supported)
 void CtdlPutRoomLock(struct ctdlroom *qrbuf) {
        CtdlPutRoom(qrbuf);
        end_critical_section(S_ROOMS);
 }
 
 
-/*
- * CtdlGetFloorByName()  -  retrieve the number of the named floor
- * return < 0 if not found else return floor number
- */
+// CtdlGetFloorByName()  -  retrieve the number of the named floor
+// return < 0 if not found else return floor number
 int CtdlGetFloorByName(const char *floor_name) {
        int a;
        struct floor *flbuf = NULL;
@@ -445,7 +422,7 @@ int CtdlGetFloorByName(const char *floor_name) {
        for (a = 0; a < MAXFLOORS; ++a) {
                flbuf = CtdlGetCachedFloor(a);
 
-               /* check to see if it already exists */
+               // check to see if it already exists
                if ((!strcasecmp(flbuf->f_name, floor_name)) && (flbuf->f_flags & F_INUSE)) {
                        return a;
                }
@@ -454,11 +431,8 @@ int CtdlGetFloorByName(const char *floor_name) {
 }
 
 
-/*
- * CtdlGetFloorByNameLock()  -  retrieve floor number for given floor and lock the floor list.
- */
-int CtdlGetFloorByNameLock(const char *floor_name)
-{
+// CtdlGetFloorByNameLock()  -  retrieve floor number for given floor and lock the floor list.
+int CtdlGetFloorByNameLock(const char *floor_name) {
        begin_critical_section(S_FLOORTAB);
        return CtdlGetFloorByName(floor_name);
 }
index 4e6ca9627af2991945c3de394bf4c6e22b35afae..601b458fa817b184a7d0f97988b8df1b9ceae1d9 100644 (file)
@@ -1,6 +1,6 @@
 // citserver's main() function lives here.
 // 
-// Copyright (c) 1987-2021 by the citadel.org team
+// Copyright (c) 1987-2022 by the citadel.org team
 //
 // This program is open source software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License version 3.
@@ -33,10 +33,8 @@ const char *CitadelServiceTCP="citadel-TCP";
 int sanity_diag_mode = 0;
 
 
-/*
- * Create or remove a lock file, so we only have one Citadel Server running at a time.
- * Set 'op' to nonzero to lock, zero to unlock.
- */
+// Create or remove a lock file, so we only have one Citadel Server running at a time.
+// Set 'op' to nonzero to lock, zero to unlock.
 void ctdl_lockfile(int op) {
        static char lockfilename[PATH_MAX];
        static FILE *fp;
@@ -63,9 +61,7 @@ void ctdl_lockfile(int op) {
 }
 
 
-/*
- * Here's where it all begins.
- */
+// Here's where it all begins.
 int main(int argc, char **argv) {
 
        char facility[32];
@@ -82,12 +78,12 @@ int main(int argc, char **argv) {
        struct stat filestats;
 #endif
 
-       /* Tell 'em who's in da house */
+       // Tell 'em who's in da house
        syslog(LOG_INFO, " ");
        syslog(LOG_INFO, " ");
        syslog(LOG_INFO, "*** Citadel server engine ***\n");
        syslog(LOG_INFO, "Version %d (build %s) ***", REV_LEVEL, svn_revision());
-       syslog(LOG_INFO, "Copyright (C) 1987-2021 by the Citadel development team.");
+       syslog(LOG_INFO, "Copyright (C) 1987-2022 by the Citadel development team.");
        syslog(LOG_INFO, " ");
        syslog(LOG_INFO, "This program is open source software: you can redistribute it and/or");
        syslog(LOG_INFO, "modify it under the terms of the GNU General Public License, version 3.");
@@ -99,7 +95,7 @@ int main(int argc, char **argv) {
        syslog(LOG_INFO, " ");
        syslog(LOG_INFO, "%s", libcitadel_version_string());
 
-       /* parse command-line arguments */
+       // parse command-line arguments
        while ((a=getopt(argc, argv, "cl:dh:x:t:B:Dru:s:")) != EOF) switch(a) {
 
                // test this binary for compatibility and exit
@@ -195,7 +191,7 @@ int main(int argc, char **argv) {
                exit(CTDLEXIT_UNUSER);
        }
 
-       /* Last ditch effort to determine the user name ... if there's a user called "citadel" then use that */
+       // Last ditch effort to determine the user name ... if there's a user called "citadel" then use that
        if (ctdluid == 0) {
                p = getpwnam("citadel");
                if (!p) {
@@ -212,7 +208,7 @@ int main(int argc, char **argv) {
                }
        }
 
-       /* initialize the master context */
+       // initialize the master context
        InitializeMasterCC();
        InitializeMasterTSD();
 
@@ -222,7 +218,7 @@ int main(int argc, char **argv) {
                syslog_facility
        );
 
-       /* daemonize, if we were asked to */
+       // daemonize, if we were asked to
        if (running_as_daemon) {
                start_daemon(0);
                drop_root_perms = 1;
@@ -243,19 +239,15 @@ int main(int argc, char **argv) {
        syslog(LOG_INFO, "main: upgrading modules");            // Run any upgrade entry points
        upgrade_modules();
 
-       /*
-        * Load the user for the masterCC or create them if they don't exist
-        */
+       // Load the user for the masterCC or create them if they don't exist
        if (CtdlGetUser(&masterCC.user, "SYS_Citadel")) {
-               /* User doesn't exist. We can't use create user here as the user number needs to be 0 */
+               // User doesn't exist. We can't use create user here as the user number needs to be 0
                strcpy (masterCC.user.fullname, "SYS_Citadel") ;
                CtdlPutUser(&masterCC.user);
-               CtdlGetUser(&masterCC.user, "SYS_Citadel");     /* Just to be safe */
+               CtdlGetUser(&masterCC.user, "SYS_Citadel");     // Just to be safe
        }
        
-       /*
-        * Bind the server to a Unix-domain socket (user client access)
-        */
+       // Bind the server to a Unix-domain socket (user client access)
        CtdlRegisterServiceHook(0,
                                file_citadel_socket,
                                citproto_begin_session,
@@ -263,20 +255,16 @@ int main(int argc, char **argv) {
                                do_async_loop,
                                CitadelServiceUDS);
 
-       /*
-        * Bind the server to a Unix-domain socket (admin client access)
-        */
+       // Bind the server to a Unix-domain socket (admin client access)
        CtdlRegisterServiceHook(0,
                                file_citadel_admin_socket,
                                citproto_begin_admin_session,
                                do_command_loop,
                                do_async_loop,
                                CitadelServiceUDS);
-       chmod(file_citadel_admin_socket, S_IRWXU);      /* for your eyes only */
+       chmod(file_citadel_admin_socket, S_IRWXU);      // for your eyes only
 
-       /*
-        * Bind the server to our favorite TCP port (usually 504).
-        */
+       // Bind the server to our favorite TCP port (usually 504).
        CtdlRegisterServiceHook(CtdlGetConfigInt("c_port_number"),
                                NULL,
                                citproto_begin_session,
@@ -284,30 +272,22 @@ int main(int argc, char **argv) {
                                do_async_loop,
                                CitadelServiceTCP);
 
-       /*
-        * Load any server-side extensions available here.
-        */
+       // Load any server-side extensions available here.
        syslog(LOG_INFO, "main: initializing server extensions");
        initialise_modules(0);
 
-       /*
-        * If we need host auth, start our chkpwd daemon.
-        */
+       // If we need host auth, start our chkpwd daemon.
        if (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_HOST) {
                start_chkpwd_daemon();
        }
 
-       /*
-        * check, whether we're fired up another time after a crash.
-        * if, post an aide message, so the admin has a chance to react.
-        */
+       // check, whether we're fired up another time after a crash.
+       // if, post an aide message, so the admin has a chance to react.
        checkcrash();
 
-       /*
-        * Now that we've bound the sockets, change to the Citadel user id and its corresponding group ids
-        */
+       // Now that we've bound the sockets, change to the Citadel user id and its corresponding group ids
        if (drop_root_perms) {
-               cdb_chmod_data();       /* make sure we own our data files */
+               cdb_chmod_data();       // make sure we own our data files
                getpwuid_r(ctdluid, &pw, pwbuf, sizeof(pwbuf), &pwp);
                if (pwp == NULL)
                        syslog(LOG_ERR, "main: WARNING, getpwuid(%ld): %m Group IDs will be incorrect.", (long)CTDLUID);
@@ -326,13 +306,13 @@ int main(int argc, char **argv) {
 #endif
        }
 
-       /* We want to check for idle sessions once per minute */
+       // We want to check for idle sessions once per minute
        CtdlRegisterSessionHook(terminate_idle_sessions, EVT_TIMER, PRIO_CLEANUP + 1);
 
-       /* Go into multithreaded mode.  When this call exits, the server is stopping. */
+       // Go into multithreaded mode.  When this call exits, the server is stopping.
        go_threading();
        
-       /* Get ready to shut down the server. */
+       // Get ready to shut down the server.
        int exit_code = master_cleanup(exit_signal);
        ctdl_lockfile(0);
        if (restart_server) {
index af155d31df92298178ab5e9c03a742be304fa133..20937f2b82305ad936c77e7722aac73639457631 100644 (file)
@@ -1,6 +1,4 @@
-/*
- * Server-side utility functions
- */
+// Server-side utility functions
 
 #include "sysdep.h"
 #include <stdio.h>
 #include "citadel.h"
 #include "support.h"
 
-/*
- * strproc()  -  make a string 'nice'
- */
-void strproc(char *string)
-{
+// strproc()  -  make a string 'nice'
+void strproc(char *string) {
        int a, b;
 
        if (string == NULL) return;
        if (IsEmptyStr(string)) return;
 
-       /* Convert non-printable characters to blanks */
+       // Convert non-printable characters to blanks
        for (a=0; !IsEmptyStr(&string[a]); ++a) {
                if (string[a]<32) string[a]=32;
                if (string[a]>126) string[a]=32;
        }
 
-       /* a is now the length of our string. */
-       /* Remove leading and trailing blanks */
+       // a is now the length of our string.
+       // Remove leading and trailing blanks
        while( (string[a-1]<33) && (!IsEmptyStr(string)) )
                string[--a]=0;
        b = 0;
@@ -37,7 +32,7 @@ void strproc(char *string)
        if (b > 0)
                memmove(string,&string[b], a - b + 1);
 
-       /* Remove double blanks */
+       // Remove double blanks
        for (a=0; !IsEmptyStr(&string[a]); ++a) {
                if ((string[a]==32)&&(string[a+1]==32)) {
                        strcpy(&string[a],&string[a+1]);
@@ -45,7 +40,7 @@ void strproc(char *string)
                }
        }
 
-       /* remove characters which would interfere with the network */
+       // remove characters which would interfere with the network
        for (a=0; !IsEmptyStr(&string[a]); ++a) {
                while (string[a]=='!') strcpy(&string[a],&string[a+1]);
                while (string[a]=='@') strcpy(&string[a],&string[a+1]);
@@ -58,13 +53,9 @@ void strproc(char *string)
 }
 
 
-
-/*
- * get a line of text from a file
- * ignores lines starting with #
- */
-int getstring(FILE *fp, char *string)
-{
+// get a line of text from a file
+// ignores lines starting with #
+int getstring(FILE *fp, char *string) {
        int a,c;
        do {
                strcpy(string,"");
index 84cae5df8fc0cd7ca783750acd4316bcd9ec05de..5a96ee2c67c59f1f2bb5ca17c653700324ba90a8 100644 (file)
@@ -1,4 +1,4 @@
-OBJS := http.o main.o request.o ssl.o static.o tcp_sockets.o webserver.o ctdlclient.o \
+OBJS := http.o main.o request.o tls.o static.o tcp_sockets.o webserver.o ctdlclient.o \
        admin_functions.o room_functions.o util.o caldav_reports.o messages.o \
        ctdlfunctions.o ctdl_commands.o forum_view.o html2html.o text2html.o user_functions.o
 CFLAGS := -ggdb -Wno-format-truncation
diff --git a/webcit-ng/ssl.c b/webcit-ng/ssl.c
deleted file mode 100644 (file)
index 93c0802..0000000
+++ /dev/null
@@ -1,216 +0,0 @@
-//
-// Functions in this module handle SSL encryption when WebCit is running
-// as an HTTPS server.
-//
-// Copyright (c) 1996-2022 by the citadel.org team
-//
-// This program is open source software.  It runs great on the
-// Linux operating system (and probably elsewhere).  You can use,
-// copy, and run it under the terms of the GNU General Public
-// License version 3.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-#include "webcit.h"
-
-SSL_CTX *ssl_ctx;              // global SSL context
-char key_file[PATH_MAX] = "";
-char cert_file[PATH_MAX] = "";
-char *ssl_cipher_list = DEFAULT_SSL_CIPHER_LIST;
-
-
-// Set the private key and certificate chain for the global SSL Context.
-// This is called during initialization, and can be called again later if the certificate changes.
-void bind_to_key_and_certificate(void) {
-       if (IsEmptyStr(key_file)) {
-               snprintf(key_file, sizeof key_file, "%s/keys/citadel.key", ctdl_dir);
-       }
-       if (IsEmptyStr(cert_file)) {
-               snprintf(cert_file, sizeof key_file, "%s/keys/citadel.cer", ctdl_dir);
-       }
-
-       syslog(LOG_DEBUG, "crypto: [re]installing key \"%s\" and certificate \"%s\"", key_file, cert_file);
-
-       SSL_CTX_use_certificate_chain_file(ssl_ctx, cert_file);
-       SSL_CTX_use_PrivateKey_file(ssl_ctx, key_file, SSL_FILETYPE_PEM);
-
-       if ( !SSL_CTX_check_private_key(ssl_ctx) ) {
-               syslog(LOG_WARNING, "crypto: cannot install certificate: %s", ERR_reason_error_string(ERR_get_error()));
-       }
-}
-
-
-// Initialize ssl engine, load certs and initialize openssl internals
-void init_ssl(void) {
-       const SSL_METHOD *ssl_method;
-       RSA *rsa = NULL;
-       X509_REQ *req = NULL;
-       X509 *cer = NULL;
-       EVP_PKEY *pk = NULL;
-       EVP_PKEY *req_pkey = NULL;
-       X509_NAME *name = NULL;
-       FILE *fp;
-       char buf[SIZ];
-       int rv = 0;
-
-       // Initialize SSL transport layer
-       SSL_library_init();
-       SSL_load_error_strings();
-       ssl_method = SSLv23_server_method();
-       if (!(ssl_ctx = SSL_CTX_new(ssl_method))) {
-               syslog(LOG_WARNING, "SSL_CTX_new failed: %s", ERR_reason_error_string(ERR_get_error()));
-               return;
-       }
-
-       syslog(LOG_INFO, "Requesting cipher list: %s", ssl_cipher_list);
-       if (!(SSL_CTX_set_cipher_list(ssl_ctx, ssl_cipher_list))) {
-               syslog(LOG_WARNING, "SSL_CTX_set_cipher_list failed: %s", ERR_reason_error_string(ERR_get_error()));
-               return;
-       }
-
-       // Now try to bind to the key and certificate.
-       bind_to_key_and_certificate();
-}
-
-
-// Check the modification time of the key and certificate -- reload if they changed
-void update_key_and_cert_if_needed(void) {
-       static time_t cert_mtime = 0;
-       struct stat keystat;
-       struct stat certstat;
-
-       if (stat(key_file, &keystat) != 0) {
-               syslog(LOG_ERR, "%s: %s", key_file, strerror(errno));
-               return;
-       }
-       if (stat(cert_file, &certstat) != 0) {
-               syslog(LOG_ERR, "%s: %s", cert_file, strerror(errno));
-               return;
-       }
-
-       if ((keystat.st_mtime > cert_mtime) || (certstat.st_mtime > cert_mtime)) {
-               bind_to_key_and_certificate();
-               cert_mtime = certstat.st_mtime;
-       }
-}
-
-
-// starts SSL/TLS encryption for the current session.
-void starttls(struct client_handle *ch) {
-       int retval, bits, alg_bits;
-
-       if (!ssl_ctx) {
-               return;
-       }
-
-       // Check the modification time of the key and certificate -- reload if they changed
-       update_key_and_cert_if_needed();
-
-       if (!(ch->ssl_handle = SSL_new(ssl_ctx))) {
-               syslog(LOG_WARNING, "SSL_new failed: %s", ERR_reason_error_string(ERR_get_error()));
-               return;
-       }
-       if (!(SSL_set_fd(ch->ssl_handle, ch->sock))) {
-               syslog(LOG_WARNING, "SSL_set_fd failed: %s", ERR_reason_error_string(ERR_get_error()));
-               SSL_free(ch->ssl_handle);
-               return;
-       }
-       retval = SSL_accept(ch->ssl_handle);
-       if (retval < 1) {
-               syslog(LOG_WARNING, "SSL_accept failed: %s", ERR_reason_error_string(ERR_get_error()));
-       }
-       else {
-               syslog(LOG_INFO, "SSL_accept success");
-       }
-       bits = SSL_CIPHER_get_bits(SSL_get_current_cipher(ch->ssl_handle), &alg_bits);
-       syslog(LOG_INFO, "SSL/TLS using %s on %s (%d of %d bits)",
-              SSL_CIPHER_get_name(SSL_get_current_cipher(ch->ssl_handle)),
-              SSL_CIPHER_get_version(SSL_get_current_cipher(ch->ssl_handle)), bits, alg_bits);
-       syslog(LOG_INFO, "SSL started");
-}
-
-
-// shuts down the TLS connection
-void endtls(struct client_handle *ch) {
-       syslog(LOG_INFO, "Ending SSL/TLS");
-       if (ch->ssl_handle != NULL) {
-               SSL_shutdown(ch->ssl_handle);
-               SSL_get_SSL_CTX(ch->ssl_handle);
-               SSL_free(ch->ssl_handle);
-       }
-       ch->ssl_handle = NULL;
-}
-
-
-// Send binary data to the client encrypted.
-int client_write_ssl(struct client_handle *ch, char *buf, int nbytes) {
-       int retval;
-       int nremain;
-       char junk[1];
-
-       if (ch->ssl_handle == NULL)
-               return (-1);
-
-       nremain = nbytes;
-       while (nremain > 0) {
-               if (SSL_want_write(ch->ssl_handle)) {
-                       if ((SSL_read(ch->ssl_handle, junk, 0)) < 1) {
-                               syslog(LOG_WARNING, "SSL_read in client_write: %s", ERR_reason_error_string(ERR_get_error()));
-                       }
-               }
-               retval = SSL_write(ch->ssl_handle, &buf[nbytes - nremain], nremain);
-               if (retval < 1) {
-                       long errval;
-
-                       errval = SSL_get_error(ch->ssl_handle, retval);
-                       if (errval == SSL_ERROR_WANT_READ || errval == SSL_ERROR_WANT_WRITE) {
-                               sleep(1);
-                               continue;
-                       }
-                       syslog(LOG_WARNING, "SSL_write: %s", ERR_reason_error_string(ERR_get_error()));
-                       if (retval == -1) {
-                               syslog(LOG_WARNING, "errno is %d", errno);
-                               endtls(ch);
-                       }
-                       return -1;
-               }
-               nremain -= retval;
-       }
-       return 0;
-}
-
-
-// read data from the encrypted layer
-int client_read_ssl(struct client_handle *ch, char *buf, int nbytes) {
-       int bytes_read = 0;
-       int rlen = 0;
-       char junk[1];
-
-       if (ch->ssl_handle == NULL)
-               return (-1);
-
-       while (bytes_read < nbytes) {
-               if (SSL_want_read(ch->ssl_handle)) {
-                       if ((SSL_write(ch->ssl_handle, junk, 0)) < 1) {
-                               syslog(LOG_WARNING, "SSL_write in client_read");
-                       }
-               }
-               rlen = SSL_read(ch->ssl_handle, &buf[bytes_read], nbytes - bytes_read);
-               if (rlen < 1) {
-                       long errval;
-                       errval = SSL_get_error(ch->ssl_handle, rlen);
-                       if (errval == SSL_ERROR_WANT_READ || errval == SSL_ERROR_WANT_WRITE) {
-                               sleep(1);
-                               continue;
-                       }
-                       syslog(LOG_WARNING, "SSL_read error %ld", errval);
-                       endtls(ch);
-                       return (-1);
-               }
-               bytes_read += rlen;
-       }
-       return (bytes_read);
-}
index 2ede01340c3a1ec0d7c2ffcc0dcc6eca592fd19c..615bdaaf4bdf1cbc91cac197f314aecdcf43ee04 100644 (file)
@@ -58,9 +58,8 @@ ctdl_startup = async() => {
 
 
 // Display a room list in the main div.
-//
 function display_room_list() {
-       document.getElementById("roomlist").innerHTML = "<img src=\"/ctdl/s/static/throbber.gif\" />";  // show throbber while loading
+       document.getElementById("roomlist").innerHTML = "<img src=\"/ctdl/s/images/throbber.gif\" />";  // show throbber while loading
 
        fetch_room_list = async() => {
                response = await fetch("/ctdl/r/");
@@ -68,13 +67,15 @@ function display_room_list() {
                if (response.ok) {
                        display_room_list_renderer(room_list);
                }
+               else {
+                       document.getElementById("roomlist").innerHTML = "<i>error</i>";
+               }
        }
        fetch_room_list();
 }
 
 
 // Renderer for display_room_list()
-//
 function display_room_list_renderer(data) {
        data = data.sort(function(a,b) {
                if (a.floor != b.floor) {
diff --git a/webcit-ng/tls.c b/webcit-ng/tls.c
new file mode 100644 (file)
index 0000000..988ac25
--- /dev/null
@@ -0,0 +1,215 @@
+// Functions in this module handle SSL encryption when WebCit is running
+// as an HTTPS server.
+//
+// Copyright (c) 1996-2022 by the citadel.org team
+//
+// This program is open source software.  It runs great on the
+// Linux operating system (and probably elsewhere).  You can use,
+// copy, and run it under the terms of the GNU General Public
+// License version 3.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+#include "webcit.h"
+
+SSL_CTX *ssl_ctx;              // global SSL context
+char key_file[PATH_MAX] = "";
+char cert_file[PATH_MAX] = "";
+char *ssl_cipher_list = DEFAULT_SSL_CIPHER_LIST;
+
+
+// Set the private key and certificate chain for the global SSL Context.
+// This is called during initialization, and can be called again later if the certificate changes.
+void bind_to_key_and_certificate(void) {
+       if (IsEmptyStr(key_file)) {
+               snprintf(key_file, sizeof key_file, "%s/keys/citadel.key", ctdl_dir);
+       }
+       if (IsEmptyStr(cert_file)) {
+               snprintf(cert_file, sizeof key_file, "%s/keys/citadel.cer", ctdl_dir);
+       }
+
+       syslog(LOG_DEBUG, "crypto: [re]installing key \"%s\" and certificate \"%s\"", key_file, cert_file);
+
+       SSL_CTX_use_certificate_chain_file(ssl_ctx, cert_file);
+       SSL_CTX_use_PrivateKey_file(ssl_ctx, key_file, SSL_FILETYPE_PEM);
+
+       if ( !SSL_CTX_check_private_key(ssl_ctx) ) {
+               syslog(LOG_WARNING, "crypto: cannot install certificate: %s", ERR_reason_error_string(ERR_get_error()));
+       }
+}
+
+
+// Initialize ssl engine, load certs and initialize openssl internals
+void init_ssl(void) {
+       const SSL_METHOD *ssl_method;
+       RSA *rsa = NULL;
+       X509_REQ *req = NULL;
+       X509 *cer = NULL;
+       EVP_PKEY *pk = NULL;
+       EVP_PKEY *req_pkey = NULL;
+       X509_NAME *name = NULL;
+       FILE *fp;
+       char buf[SIZ];
+       int rv = 0;
+
+       // Initialize SSL transport layer
+       SSL_library_init();
+       SSL_load_error_strings();
+       ssl_method = SSLv23_server_method();
+       if (!(ssl_ctx = SSL_CTX_new(ssl_method))) {
+               syslog(LOG_WARNING, "SSL_CTX_new failed: %s", ERR_reason_error_string(ERR_get_error()));
+               return;
+       }
+
+       syslog(LOG_INFO, "Requesting cipher list: %s", ssl_cipher_list);
+       if (!(SSL_CTX_set_cipher_list(ssl_ctx, ssl_cipher_list))) {
+               syslog(LOG_WARNING, "SSL_CTX_set_cipher_list failed: %s", ERR_reason_error_string(ERR_get_error()));
+               return;
+       }
+
+       // Now try to bind to the key and certificate.
+       bind_to_key_and_certificate();
+}
+
+
+// Check the modification time of the key and certificate -- reload if they changed
+void update_key_and_cert_if_needed(void) {
+       static time_t previous_mtime = 0;
+       struct stat keystat;
+       struct stat certstat;
+
+       if (stat(key_file, &keystat) != 0) {
+               syslog(LOG_ERR, "%s: %s", key_file, strerror(errno));
+               return;
+       }
+       if (stat(cert_file, &certstat) != 0) {
+               syslog(LOG_ERR, "%s: %s", cert_file, strerror(errno));
+               return;
+       }
+
+       if ((keystat.st_mtime + certstat.st_mtime) != previous_mtime) {
+               bind_to_key_and_certificate();
+               previous_mtime = keystat.st_mtime + certstat.st_mtime;
+       }
+}
+
+
+// starts SSL/TLS encryption for the current session.
+void starttls(struct client_handle *ch) {
+       int retval, bits, alg_bits;
+
+       if (!ssl_ctx) {
+               return;
+       }
+
+       // Check the modification time of the key and certificate -- reload if they changed
+       update_key_and_cert_if_needed();
+
+       if (!(ch->ssl_handle = SSL_new(ssl_ctx))) {
+               syslog(LOG_WARNING, "SSL_new failed: %s", ERR_reason_error_string(ERR_get_error()));
+               return;
+       }
+       if (!(SSL_set_fd(ch->ssl_handle, ch->sock))) {
+               syslog(LOG_WARNING, "SSL_set_fd failed: %s", ERR_reason_error_string(ERR_get_error()));
+               SSL_free(ch->ssl_handle);
+               return;
+       }
+       retval = SSL_accept(ch->ssl_handle);
+       if (retval < 1) {
+               syslog(LOG_WARNING, "SSL_accept failed: %s", ERR_reason_error_string(ERR_get_error()));
+       }
+       else {
+               syslog(LOG_INFO, "SSL_accept success");
+       }
+       bits = SSL_CIPHER_get_bits(SSL_get_current_cipher(ch->ssl_handle), &alg_bits);
+       syslog(LOG_INFO, "SSL/TLS using %s on %s (%d of %d bits)",
+              SSL_CIPHER_get_name(SSL_get_current_cipher(ch->ssl_handle)),
+              SSL_CIPHER_get_version(SSL_get_current_cipher(ch->ssl_handle)), bits, alg_bits);
+       syslog(LOG_INFO, "SSL started");
+}
+
+
+// shuts down the TLS connection
+void endtls(struct client_handle *ch) {
+       syslog(LOG_INFO, "Ending SSL/TLS");
+       if (ch->ssl_handle != NULL) {
+               SSL_shutdown(ch->ssl_handle);
+               SSL_get_SSL_CTX(ch->ssl_handle);
+               SSL_free(ch->ssl_handle);
+       }
+       ch->ssl_handle = NULL;
+}
+
+
+// Send binary data to the client encrypted.
+int client_write_ssl(struct client_handle *ch, char *buf, int nbytes) {
+       int retval;
+       int nremain;
+       char junk[1];
+
+       if (ch->ssl_handle == NULL)
+               return (-1);
+
+       nremain = nbytes;
+       while (nremain > 0) {
+               if (SSL_want_write(ch->ssl_handle)) {
+                       if ((SSL_read(ch->ssl_handle, junk, 0)) < 1) {
+                               syslog(LOG_WARNING, "SSL_read in client_write: %s", ERR_reason_error_string(ERR_get_error()));
+                       }
+               }
+               retval = SSL_write(ch->ssl_handle, &buf[nbytes - nremain], nremain);
+               if (retval < 1) {
+                       long errval;
+
+                       errval = SSL_get_error(ch->ssl_handle, retval);
+                       if (errval == SSL_ERROR_WANT_READ || errval == SSL_ERROR_WANT_WRITE) {
+                               sleep(1);
+                               continue;
+                       }
+                       syslog(LOG_WARNING, "SSL_write: %s", ERR_reason_error_string(ERR_get_error()));
+                       if (retval == -1) {
+                               syslog(LOG_WARNING, "errno is %d", errno);
+                               endtls(ch);
+                       }
+                       return -1;
+               }
+               nremain -= retval;
+       }
+       return 0;
+}
+
+
+// read data from the encrypted layer
+int client_read_ssl(struct client_handle *ch, char *buf, int nbytes) {
+       int bytes_read = 0;
+       int rlen = 0;
+       char junk[1];
+
+       if (ch->ssl_handle == NULL)
+               return (-1);
+
+       while (bytes_read < nbytes) {
+               if (SSL_want_read(ch->ssl_handle)) {
+                       if ((SSL_write(ch->ssl_handle, junk, 0)) < 1) {
+                               syslog(LOG_WARNING, "SSL_write in client_read");
+                       }
+               }
+               rlen = SSL_read(ch->ssl_handle, &buf[bytes_read], nbytes - bytes_read);
+               if (rlen < 1) {
+                       long errval;
+                       errval = SSL_get_error(ch->ssl_handle, rlen);
+                       if (errval == SSL_ERROR_WANT_READ || errval == SSL_ERROR_WANT_WRITE) {
+                               sleep(1);
+                               continue;
+                       }
+                       syslog(LOG_WARNING, "SSL_read error %ld", errval);
+                       endtls(ch);
+                       return (-1);
+               }
+               bytes_read += rlen;
+       }
+       return (bytes_read);
+}
index d0804beaf1ec9a661d658bc203f70289fb568671..bd08639026d7e721bcd284ac8ec7fa1955820f2f 100644 (file)
@@ -84,9 +84,9 @@ void init_ssl(void) {
 }
 
 
-// Check the modification time of the key and certificate -- reload if they changed
+// Check the modification time of the key and certificate -- reload if either one changed
 void update_key_and_cert_if_needed(void) {
-       static time_t cert_mtime = 0;
+       static time_t previous_mtime = 0;
        struct stat keystat;
        struct stat certstat;
 
@@ -99,9 +99,9 @@ void update_key_and_cert_if_needed(void) {
                return;
        }
 
-       if ((keystat.st_mtime > cert_mtime) || (certstat.st_mtime > cert_mtime)) {
+       if ((keystat.st_mtime + certstat.st_mtime) != previous_mtime) {
                bind_to_key_and_certificate();
-               cert_mtime = certstat.st_mtime;
+               previous_mtime = keystat.st_mtime + certstat.st_mtime;
        }
 }