}
!
$CC $CFLAGS $CPPFLAGS $tempcc -o $tempfile $LDFLAGS -lssl -lcrypto && $tempfile >/dev/null 2>&1 && {
- CFLAGS=${CFLAGS}' -DHAVE_OPENSSL'
LDFLAGS=${LDFLAGS}' -lssl -lcrypto -lz'
} || {
echo Citadel Server requires OpenSSL which is not present.
me->MigrateBuf = NULL;
me->sMigrateBuf = NULL;
me->redirect_buffer = NULL;
-#ifdef HAVE_OPENSSL
me->ssl = NULL;
-#endif
-
me->download_fp = NULL;
me->upload_fp = NULL;
me->ma = NULL;
// Redirect this session's output to a memory buffer?
StrBuf *redirect_buffer; // the buffer
StrBuf *StatusMessage;
-#ifdef HAVE_OPENSSL
SSL *ssl;
int redirect_ssl;
-#endif
char curr_user[USERNAME_SIZE]; // name of current user
int logged_in; // logged in?
#include <sys/types.h>
#include "../../sysdep.h"
-#ifdef HAVE_OPENSSL
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/rand.h>
-#endif
#include <time.h>
#include "../../config.h"
#include "../../ctdl_module.h"
-#ifdef HAVE_OPENSSL
-
SSL_CTX *ssl_ctx = NULL; // This SSL context is used for all sessions.
char *ssl_cipher_list = CIT_CIPHERS;
CC->ssl = NULL;
CC->redirect_ssl = 0;
}
-
-#endif // HAVE_OPENSSL
// Which ciphers will be offered; see https://www.openssl.org/docs/manmaster/man1/ciphers.html
#define CIT_CIPHERS "ALL:RC4+RSA:+SSLv2:+TLSv1:!MD5:@STRENGTH"
-#ifdef HAVE_OPENSSL
#define OPENSSL_NO_KRB5 /* work around redhat b0rken ssl headers */
void init_ssl(void);
void client_write_ssl (const char *buf, int nbytes);
void endtls(void);
void CtdlStartTLS(char *ok_response, char *nosup_response, char *error_response);
extern SSL_CTX *ssl_ctx;
-
-#endif
-/*
- * Citadel protocol main dispatcher
- *
- * Copyright (c) 1987-2017 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.
- *
- * 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.
- */
+// Citadel protocol main dispatcher
+// Copyright (c) 1987-2024 by the citadel.org team
+// This program is open source software. Use, duplication, or disclosure are subject to the GNU General Public License v3.
#include <stdio.h>
#include <libcitadel.h>
-
#include "../../citserver.h"
#include "../../ctdl_module.h"
#include "../../config.h"
-/*
- * This loop recognizes all server commands.
- */
+
+// This loop recognizes all server commands.
void do_command_loop(void) {
- struct CitContext *CCC = CC;
char cmdbuf[SIZ];
- time(&CCC->lastcmd);
- memset(cmdbuf, 0, sizeof cmdbuf); /* Clear it, just in case */
+ time(&CC->lastcmd);
+ memset(cmdbuf, 0, sizeof cmdbuf); // Clear it, just in case
if (client_getln(cmdbuf, sizeof cmdbuf) < 1) {
syslog(LOG_INFO, "Citadel client disconnected: ending session.");
- CCC->kill_me = KILLME_CLIENT_DISCONNECTED;
+ CC->kill_me = KILLME_CLIENT_DISCONNECTED;
return;
}
- /* Log the server command, but don't show passwords... */
- if ( (strncasecmp(cmdbuf, "PASS", 4)) && (strncasecmp(cmdbuf, "SETP", 4)) ) {
- syslog(LOG_DEBUG, "[%s(%ld)] %s",
- CCC->curr_user, CCC->user.usernum, cmdbuf
- );
+ // Log the server command, but don't show passwords...
+ if ( (strncasecmp(cmdbuf, "PASS", 4))
+ && (strncasecmp(cmdbuf, "SETP", 4))
+ ) {
+ syslog(LOG_DEBUG, "[%s(%ld)] %s", CC->curr_user, CC->user.usernum, cmdbuf);
}
else {
- syslog(LOG_DEBUG, "[%s(%ld)] <password command hidden from log>",
- CCC->curr_user, CCC->user.usernum
- );
+ syslog(LOG_DEBUG, "[%s(%ld)] <password command hidden from log>", CC->curr_user, CC->user.usernum);
}
buffer_output();
- /*
- * Let other clients see the last command we executed, and
- * update the idle time, but not NOOP, QNOP, PEXP, GEXP, RWHO, or TIME.
- */
- if ( (strncasecmp(cmdbuf, "NOOP", 4))
- && (strncasecmp(cmdbuf, "QNOP", 4))
- && (strncasecmp(cmdbuf, "PEXP", 4))
- && (strncasecmp(cmdbuf, "GEXP", 4))
- && (strncasecmp(cmdbuf, "RWHO", 4))
- && (strncasecmp(cmdbuf, "TIME", 4)) ) {
- strcpy(CCC->lastcmdname, " ");
- safestrncpy(CCC->lastcmdname, cmdbuf, sizeof(CCC->lastcmdname));
- time(&CCC->lastidle);
+ // Let other clients see the last command we executed, and
+ // update the idle time, but not NOOP, QNOP, PEXP, GEXP, RWHO, or TIME.
+ if ( (strncasecmp(cmdbuf, "NOOP", 4))
+ && (strncasecmp(cmdbuf, "QNOP", 4))
+ && (strncasecmp(cmdbuf, "PEXP", 4))
+ && (strncasecmp(cmdbuf, "GEXP", 4))
+ && (strncasecmp(cmdbuf, "RWHO", 4))
+ && (strncasecmp(cmdbuf, "TIME", 4))
+ ) {
+ strcpy(CC->lastcmdname, " ");
+ safestrncpy(CC->lastcmdname, cmdbuf, sizeof(CC->lastcmdname));
+ time(&CC->lastidle);
}
- if ((strncasecmp(cmdbuf, "ENT0", 4))
- && (strncasecmp(cmdbuf, "MESG", 4))
- && (strncasecmp(cmdbuf, "MSGS", 4)))
- {
- CCC->cs_flags &= ~CS_POSTING;
+ if ( (strncasecmp(cmdbuf, "ENT0", 4))
+ && (strncasecmp(cmdbuf, "MESG", 4))
+ && (strncasecmp(cmdbuf, "MSGS", 4))
+ ) {
+ CC->cs_flags &= ~CS_POSTING;
}
if (!DLoader_Exec_Cmd(cmdbuf)) {
unbuffer_output();
- /* Run any after-each-command routines registered by modules */
+ // Run any after-each-command routines registered by modules
PerformSessionHooks(EVT_CMD);
}
void imap_output_capability_string(void) {
IAPuts("CAPABILITY IMAP4REV1 NAMESPACE ID AUTH=PLAIN AUTH=LOGIN UIDPLUS");
-#ifdef HAVE_OPENSSL
if (!CC->redirect_ssl) IAPuts(" STARTTLS");
-#endif
#ifndef DISABLE_IMAP_ACL
IAPuts(" ACL");
*/
void imaps_greeting(void) {
CtdlModuleStartCryptoMsgs(NULL, NULL, NULL);
-#ifdef HAVE_OPENSSL
if (!CC->redirect_ssl) CC->kill_me = KILLME_NO_CRYPTO; /* kill session if no crypto */
-#endif
imap_greeting();
}
RegisterImapCMD("LOGIN", "", imap_login, I_FLAG_NONE);
RegisterImapCMD("AUTHENTICATE", "", imap_authenticate, I_FLAG_NONE);
RegisterImapCMD("CAPABILITY", "", imap_capability, I_FLAG_NONE);
-#ifdef HAVE_OPENSSL
RegisterImapCMD("STARTTLS", "", imap_starttls, I_FLAG_NONE);
-#endif
/* The commans below require a logged-in state */
RegisterImapCMD("SELECT", "", imap_select, I_FLAG_LOGGED_IN);
if (!threading) {
CtdlRegisterServiceHook(CtdlGetConfigInt("c_imap_port"), NULL, imap_greeting, imap_command_loop, NULL, CitadelServiceIMAP);
-#ifdef HAVE_OPENSSL
CtdlRegisterServiceHook(CtdlGetConfigInt("c_imaps_port"), NULL, imaps_greeting, imap_command_loop, NULL, CitadelServiceIMAPS);
-#endif
CtdlRegisterSessionHook(imap_cleanup_function, EVT_STOP, PRIO_STOP + 30);
}
// NNTPS is just like NNTP, except it goes crypto right away.
void nntps_greeting(void) {
CtdlModuleStartCryptoMsgs(NULL, NULL, NULL);
-#ifdef HAVE_OPENSSL
if (!CC->redirect_ssl) CC->kill_me = KILLME_NO_CRYPTO; // kill session if no crypto
-#endif
nntp_greeting();
}
cprintf("MODE-READER\r\n");
cprintf("LIST ACTIVE NEWSGROUPS\r\n");
cprintf("OVER\r\n");
-#ifdef HAVE_OPENSSL
cprintf("STARTTLS\r\n");
-#endif
if (!CC->logged_in) {
cprintf("AUTHINFO USER\r\n");
}
NULL,
CitadelServiceNNTP);
-#ifdef HAVE_OPENSSL
CtdlRegisterServiceHook(CtdlGetConfigInt("c_nntps_port"),
NULL,
nntps_greeting,
nntp_command_loop,
NULL,
CitadelServiceNNTPS);
-#endif
CtdlRegisterSessionHook(nntp_cleanup_function, EVT_STOP, PRIO_STOP + 250);
}
#include "../../ctdl_module.h"
-// This cleanup function blows away the temporary memory and files used by
-// the POP3 server.
+// This cleanup function blows away the temporary memory and files used by the POP3 server.
void pop3_cleanup_function(void) {
- /* Don't do this stuff if this is not a POP3 session! */
+ // Don't do this stuff if this is not a POP3 session!
if (CC->h_command_function != pop3_command_loop) return;
struct citpop3 *pop3 = ((struct citpop3 *)CC->session_specific_data);
void pop3s_greeting(void) {
CtdlModuleStartCryptoMsgs(NULL, NULL, NULL);
-/* kill session if no crypto */
-#ifdef HAVE_OPENSSL
- if (!CC->redirect_ssl) CC->kill_me = KILLME_NO_CRYPTO;
-#else
- CC->kill_me = KILLME_NO_CRYPTO;
-#endif
-
+ // kill the session if TLS is not running by now
+ if (!CC->redirect_ssl) {
+ CC->kill_me = KILLME_NO_CRYPTO;
+ }
pop3_greeting();
}
if (CtdlGetRoom(&CC->room, MAILROOM) != 0) return(-1);
- /* Load up the messages */
+ // Load up the messages
CtdlForEachMessage(MSGS_ALL, 0L, NULL, NULL, NULL, pop3_add_message, NULL);
- /* Figure out which are old and which are new */
+ // Figure out which are old and which are new
CtdlGetRelationship(&vbuf, &CC->user, &CC->room);
POP3->lastseen = (-1);
if (POP3->num_msgs) for (i=0; i<POP3->num_msgs; ++i) {
pop3_pass(&cmdbuf[5]);
}
-#ifdef HAVE_OPENSSL
else if (!strncasecmp(cmdbuf, "STLS", 4)) {
pop3_stls();
}
-#endif
else if (!CC->logged_in) {
cprintf("-ERR Not logged in.\r\n");
pop3_command_loop,
NULL,
CitadelServicePop3);
-#ifdef HAVE_OPENSSL
CtdlRegisterServiceHook(CtdlGetConfigInt("c_pop3s_port"),
NULL,
pop3s_greeting,
pop3_command_loop,
NULL,
CitadelServicePop3S);
-#endif
CtdlRegisterSessionHook(pop3_cleanup_function, EVT_STOP, PRIO_STOP + 30);
}
- /* return our module name for the log */
+ // return our module name for the log
return "pop3";
}
// SMTPS is just like SMTP, except it goes crypto right away.
void smtps_greeting(void) {
CtdlModuleStartCryptoMsgs(NULL, NULL, NULL);
-#ifdef HAVE_OPENSSL
- if (!CC->redirect_ssl) CC->kill_me = KILLME_NO_CRYPTO; // kill session if no crypto
-#endif
+ if (!CC->redirect_ssl) {
+ CC->kill_me = KILLME_NO_CRYPTO; // kill session if no crypto
+ }
smtp_greeting(0);
}
cprintf("250-HELP\r\n");
cprintf("250-SIZE %ld\r\n", CtdlGetConfigLong("c_maxmsglen"));
-#ifdef HAVE_OPENSSL
// Offer the STARTTLS option...
if ( (!CC->redirect_ssl) // not if we're already TLS
&& ( (SMTP->is_msa) // Always on port 587
) {
cprintf("250-STARTTLS\r\n");
}
-#endif
cprintf("250-AUTH LOGIN PLAIN\r\n"
"250-AUTH=LOGIN PLAIN\r\n"
smtp_rcpt();
return;
}
-#ifdef HAVE_OPENSSL
if (!strncasecmp(ChrPtr(SMTP->Cmd), "STARTTLS", 8)) {
smtp_starttls();
return;
}
-#endif
cprintf("502 I'm afraid I can't do that.\r\n");
}
NULL,
CitadelServiceSMTP_MTA);
-#ifdef HAVE_OPENSSL
CtdlRegisterServiceHook(CtdlGetConfigInt("c_smtps_port"), // SMTPS MTA
NULL,
smtps_greeting,
smtp_command_loop,
NULL,
CitadelServiceSMTPS_MTA);
-#endif
CtdlRegisterServiceHook(CtdlGetConfigInt("c_msa_port"), // SMTP MSA
NULL,
/*
* TLS encryption (but only if it isn't already active)
*/
-#ifdef HAVE_OPENSSL
if (!CC->redirect_ssl) {
cprintf("<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'></starttls>");
}
-#endif
if (!CC->logged_in) {
/* If we're not logged in yet, offer SASL as our feature set */
}
else if (!strcasecmp(el, "starttls")) {
-#ifdef HAVE_OPENSSL
cprintf("<proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
CtdlModuleStartCryptoMsgs(NULL, NULL, NULL);
if (!CC->redirect_ssl) CC->kill_me = KILLME_NO_CRYPTO;
-#else
- cprintf("<failure xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
- CC->kill_me = KILLME_NO_CRYPTO;
-#endif
}
else if (!strcasecmp(el, "ping")) {
-/*
- * XMPP event queue
- *
- * Copyright (c) 2007-2021 by Art Cancro
- *
- * 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.
- *
- * 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.
- */
+// XMPP event queue
+// Copyright (c) 2007-2024 by Art Cancro
+// This program is open source software. Use, duplication, or disclosure is subject to the GNU General Public License v3.
#include "../../sysdep.h"
#include <stdlib.h>
syslog(LOG_DEBUG, "xmpp: xmpp_queue_event(%d, %s)", event_type, email_addr);
- /* Purge events more than a minute old */
+ // Purge events more than a minute old
begin_critical_section(S_XMPP_QUEUE);
do {
purged_something = 0;
} while(purged_something);
end_critical_section(S_XMPP_QUEUE);
- /* Create a new event */
+ // Create a new event
new_event = (struct xmpp_event *) malloc(sizeof(struct xmpp_event));
new_event->next = NULL;
new_event->event_time = time(NULL);
new_event->session_which_generated_this_event = CC->cs_pid;
safestrncpy(new_event->event_jid, email_addr, sizeof new_event->event_jid);
- /* Add it to the list */
+ // Add it to the list
begin_critical_section(S_XMPP_QUEUE);
if (xmpp_queue == NULL) {
xmpp_queue = new_event;
}
end_critical_section(S_XMPP_QUEUE);
- /* Tell the sessions that something is happening */
+ // Tell the sessions that something is happening
begin_critical_section(S_SESSION_TABLE);
for (cptr = ContextList; cptr != NULL; cptr = cptr->next) {
if ((cptr->logged_in) && (cptr->h_async_function == xmpp_async_loop)) {
}
-/*
- * Are we interested in anything from the queue? (Called in async loop)
- */
+// Are we interested in anything from the queue? (Called in async loop)
void xmpp_process_events(void) {
struct xmpp_event *xptr = NULL;
int highest_event = 0;
for (xptr=xmpp_queue; xptr!=NULL; xptr=xptr->next) {
- if (xptr->event_seq > XMPP->last_event_processed) { // we are getting crashes on this line?
+ if (xptr->event_seq > XMPP->last_event_processed) {
switch(xptr->event_type) {
// "Start TLS" function that is (hopefully) adaptable for any protocol
void CtdlModuleStartCryptoMsgs(char *ok_response, char *nosup_response, char *error_response) {
-#ifdef HAVE_OPENSSL
CtdlStartTLS (ok_response, nosup_response, error_response);
-#endif
}
#endif
#include "citadel_defs.h"
-#ifdef HAVE_OPENSSL
#define OPENSSL_NO_KRB5 // work around redhat b0rken ssl headers
#include <openssl/ssl.h>
-#endif
// New format for a message in memory
#endif
// If we've got OpenSSL, we're going to use it.
-#ifdef HAVE_OPENSSL
init_ssl();
-#endif
if (pthread_key_create(&MyConKey, NULL) != 0) { // TSD for sessions
syslog(LOG_CRIT, "sysdep: can't create TSD key: %m");
void buffer_output(void) {
#ifdef HAVE_TCP_BUFFERING
-#ifdef HAVE_OPENSSL
- if (!CC->redirect_ssl)
-#endif
+ if (!CC->redirect_ssl) {
setsockopt(CC->client_socket, IPPROTO_TCP, TCP_CORK, &on, 4);
+ }
#endif
}
void unbuffer_output(void) {
#ifdef HAVE_TCP_BUFFERING
-#ifdef HAVE_OPENSSL
- if (!CC->redirect_ssl)
-#endif
+ if (!CC->redirect_ssl) {
setsockopt(CC->client_socket, IPPROTO_TCP, TCP_CORK, &off, 4);
+ }
#endif
}
return 0;
}
-#ifdef HAVE_OPENSSL
if (Ctx->redirect_ssl) {
client_write_ssl(buf, nbytes);
return 0;
}
-#endif
if (Ctx->client_socket == -1) return -1;
fdflags = fcntl(Ctx->client_socket, F_GETFL);
const char *Error;
int retval = 0;
-#ifdef HAVE_OPENSSL
if (CC->redirect_ssl) {
retval = client_read_sslblob(Target, bytes, timeout);
if (retval < 0) {
syslog(LOG_ERR, "sysdep: client_read_blob() failed");
}
}
- else
-#endif
- {
+ else {
retval = StrBufReadBLOBBuffered(Target,
CC->RecvBuf.Buf,
&CC->RecvBuf.ReadWritePointer,
int rc;
FlushStrBuf(Target);
-#ifdef HAVE_OPENSSL
if (CC->redirect_ssl) {
rc = client_readline_sslbuffer(Target, CC->RecvBuf.Buf, &CC->RecvBuf.ReadWritePointer, 1);
return rc;
}
- else
-#endif
- {
+ else {
rc = StrBufTCP_read_buffered_line_fast(Target,
CC->RecvBuf.Buf,
&CC->RecvBuf.ReadWritePointer,