*/
/*@{*/
+#include "sysdep.h"
#ifdef HAVE_OPENSSL
#include "webcit.h"
#include "webserver.h"
/** \todo dirify */
/** where to find the keys */
-#define CTDL_CRYPTO_DIR "./keys"
-#define CTDL_KEY_PATH CTDL_CRYPTO_DIR "/citadel.key" /**< the key */
-#define CTDL_CSR_PATH CTDL_CRYPTO_DIR "/citadel.csr" /**< the csr file */
-#define CTDL_CER_PATH CTDL_CRYPTO_DIR "/citadel.cer" /**< the cer file */
+#define CTDL_CRYPTO_DIR ctdl_key_dir
+#define CTDL_KEY_PATH file_crpt_file_key /**< the key */
+#define CTDL_CSR_PATH file_crpt_file_csr /**< the csr file */
+#define CTDL_CER_PATH file_crpt_file_cer /**< the cer file */
#define SIGN_DAYS 365 /**< how long our certificate should live */
SSL_CTX *ssl_ctx; /**< SSL context */
return (unsigned long) pthread_self();
}
+void shutdown_ssl(void)
+{
+ ERR_free_strings();
+
+ /* Openssl requires these while shutdown.
+ * Didn't find a way to get out of this clean.
+ * int i, n = CRYPTO_num_locks();
+ * for (i = 0; i < n; i++)
+ * free(SSLCritters[i]);
+ * free(SSLCritters);
+ */
+}
+
/**
* \brief initialize ssl engine
* load certs and initialize openssl internals
if (!SSLCritters) {
lprintf(1, "citserver: can't allocate memory!!\n");
/* Nothing's been initialized, just die */
- exit(1);
+ ShutDownWebcit();
+ exit(WC_EXIT_SSL);
} else {
int a;
lprintf(1,
"citserver: can't allocate memory!!\n");
/** Nothing's been initialized, just die */
- exit(1);
+ ShutDownWebcit();
+ exit(WC_EXIT_SSL);
}
pthread_mutex_init(SSLCritters[a], NULL);
}
}
fclose(fp);
}
+ else {
+ lprintf(3, "Cannot write key: %s\n", CTDL_KEY_PATH);
+ ShutDownWebcit();
+ exit(0);
+ }
RSA_free(rsa);
}
}
- /**
- * Generate a CSR if we don't have one.
+ /*
+ * If there is no certificate file on disk, we will be generating a self-signed certificate
+ * in the next step. Therefore, if we have neither a CSR nor a certificate, generate
+ * the CSR in this step so that the next step may commence.
*/
- if (access(CTDL_CSR_PATH, R_OK) != 0) {
+ if ( (access(CTDL_CER_PATH, R_OK) != 0) && (access(CTDL_CSR_PATH, R_OK) != 0) ) {
lprintf(5, "Generating a certificate signing request.\n");
/**
MBSTRING_ASC, "Mount Kisco", -1, -1, 0);
*/
- X509_NAME_add_entry_by_txt(name, "O",
- MBSTRING_ASC, "FIXME.FIXME.org", -1, -1, 0);
-
- X509_NAME_add_entry_by_txt(name, "OU",
- MBSTRING_ASC, "Citadel server", -1, -1, 0);
-
- X509_NAME_add_entry_by_txt(name, "CN",
- MBSTRING_ASC, "FIXME.FIXME.org", -1, -1, 0);
+ X509_NAME_add_entry_by_txt(
+ name, "O",
+ MBSTRING_ASC,
+ (unsigned char*)"Organization name",
+ -1, -1, 0);
+
+ X509_NAME_add_entry_by_txt(
+ name, "OU",
+ MBSTRING_ASC,
+ (unsigned char*)"Citadel server1",
+ -1, -1, 0);
+
+ X509_NAME_add_entry_by_txt(
+ name, "CN",
+ MBSTRING_ASC,
+ (unsigned char*)"*", -1, -1, 0);
X509_REQ_set_subject_name(req, name);
PEM_write_X509_REQ(fp, req);
fclose(fp);
}
+ else {
+ lprintf(3, "Cannot write key: %s\n", CTDL_CSR_PATH);
+ ShutDownWebcit();
+ exit(0);
+ }
}
X509_REQ_free(req);
PEM_write_X509(fp, cer);
fclose(fp);
}
+ else {
+ lprintf(3, "Cannot write key: %s\n", CTDL_CER_PATH);
+ ShutDownWebcit();
+ exit(0);
+ }
}
X509_free(cer);
}
/**
* \brief starts SSL/TLS encryption for the current session.
* \param sock the socket connection
- * \return foo????
+ * \return Zero if the SSL/TLS handshake succeeded, non-zero otherwise.
*/
int starttls(int sock) {
int retval, bits, alg_bits;
* revert to unencrypted communications.
*/
long errval;
+ const char *ssl_error_reason = NULL;
errval = SSL_get_error(newssl, retval);
- lprintf(3, "SSL_accept failed: %s\n",
- ERR_reason_error_string(ERR_get_error()));
+ ssl_error_reason = ERR_reason_error_string(ERR_get_error());
+ if (ssl_error_reason == NULL)
+ lprintf(3, "SSL_accept failed: errval=%i, retval=%i\n", errval, retval);
+ else
+ lprintf(3, "SSL_accept failed: %s\n", ssl_error_reason);
+ sleep(1);
+ retval = SSL_accept(newssl);
+ }
+ if (retval < 1) {
+ long errval;
+ const char *ssl_error_reason = NULL;
+
+ errval = SSL_get_error(newssl, retval);
+ ssl_error_reason = ERR_reason_error_string(ERR_get_error());
+ if (ssl_error_reason == NULL)
+ lprintf(3, "SSL_accept failed: errval=%i, retval=%i\n", errval, retval);
+ else
+ lprintf(3, "SSL_accept failed: %s\n", ssl_error_reason);
SSL_free(newssl);
newssl = NULL;
return(4);
- }
+ } else lprintf(15, "SSL_accept success\n");
BIO_set_close(newssl->rbio, BIO_NOCLOSE);
- bits =
- SSL_CIPHER_get_bits(SSL_get_current_cipher(newssl),
- &alg_bits);
- lprintf(5, "SSL/TLS using %s on %s (%d of %d bits)\n",
+ bits = SSL_CIPHER_get_bits(SSL_get_current_cipher(newssl), &alg_bits);
+ lprintf(15, "SSL/TLS using %s on %s (%d of %d bits)\n",
SSL_CIPHER_get_name(SSL_get_current_cipher(newssl)),
SSL_CIPHER_get_version(SSL_get_current_cipher(newssl)),
bits, alg_bits);
pthread_setspecific(ThreadSSL, newssl);
+ lprintf(15, "SSL started\n");
return(0);
}
*/
void endtls(void)
{
+ SSL_CTX *ctx = NULL;
+
if (THREADSSL == NULL) return;
- lprintf(5, "Ending SSL/TLS\n");
+ lprintf(15, "Ending SSL/TLS\n");
SSL_shutdown(THREADSSL);
+ ctx = SSL_get_SSL_CTX(THREADSSL);
+
+ /** I don't think this is needed, and it crashes the server anyway
+ *
+ * if (ctx != NULL) {
+ * lprintf(9, "Freeing CTX at %x\n", (int)ctx );
+ * SSL_CTX_free(ctx);
+ * }
+ */
+
SSL_free(THREADSSL);
pthread_setspecific(ThreadSSL, NULL);
}
* \param buf chars to send to the client
* \param nbytes how many chars
*/
-void client_write_ssl(char *buf, int nbytes)
+void client_write_ssl(const StrBuf *Buf)
{
+ const char *buf;
int retval;
int nremain;
+ long nbytes;
char junk[1];
if (THREADSSL == NULL) return;
- nremain = nbytes;
+ nbytes = nremain = StrLength(Buf);
+ buf = ChrPtr(Buf);
while (nremain > 0) {
if (SSL_want_write(THREADSSL)) {
* \param timeout how long should we wait?
* \returns what???
*/
-int client_read_ssl(char *buf, int bytes, int timeout)
+int client_read_sslbuffer(StrBuf *buf, int timeout)
{
#if 0
fd_set rfds;
int retval;
int s;
#endif
- int len, rlen;
+ char sbuf[16384]; /**< Openssl communicates in 16k blocks, so lets speak its native tongue. */
+ int rlen;
char junk[1];
if (THREADSSL == NULL) return(0);
- len = 0;
- while (len < bytes) {
+ while (1) {
#if 0
/**
* This code is disabled because we don't need it when
#endif
if (SSL_want_read(THREADSSL)) {
if ((SSL_write(THREADSSL, junk, 0)) < 1) {
- lprintf(9, "SSL_write in client_read: %s\n", ERR_reason_error_string(ERR_get_error()));
+ lprintf(9, "SSL_write in client_read\n");
}
}
- rlen = SSL_read(THREADSSL, &buf[len], bytes - len);
+ rlen = SSL_read(THREADSSL, sbuf, sizeof(sbuf));
if (rlen < 1) {
long errval;
endtls();
return (0);
}
- len += rlen;
+ StrBufAppendBufPlain(buf, sbuf, rlen, 0);
+ return(1);
}
return (1);
}