Index: trunk/Common/log.c
===================================================================
--- trunk/Common/log.c	(revision 11)
+++ trunk/Common/log.c	(revision 12)
@@ -38,5 +38,6 @@
 			if(log[i] == 's') {
 				char* tmp = result;
-				result = cm_strcat(tmp, va_arg(args, char*));
+				char* c = va_arg(args, char*);
+				result = cm_strcat(tmp, c == NULL ? "(null)" : c);
 				free(tmp);
 			} else if(log[i] == 'd') {
Index: trunk/Server/config.c
===================================================================
--- trunk/Server/config.c	(revision 11)
+++ trunk/Server/config.c	(revision 12)
@@ -7,4 +7,5 @@
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 
 #include <cm_string.h>
@@ -13,4 +14,14 @@
 struct tw_config config;
 
+struct tw_config_entry* tw_vhost_match(const char* name, int port) {
+	int i;
+	for(i = 0; i < config.vhost_count; i++) {
+		if(strcmp(config.vhosts[i].name, name) == 0 && config.vhosts[i].port == port) {
+			return &config.vhosts[i];
+		}
+	}
+	return &config.root;
+}
+
 void tw_config_init(void) {
 	int i;
@@ -18,4 +29,12 @@
 		config.ports[i] = -1;
 	}
+	for(i = 0; i < MAX_VHOSTS; i++) {
+		config.vhosts[i].sslkey = NULL;
+		config.vhosts[i].sslcert = NULL;
+	}
+	config.root.sslkey = NULL;
+	config.root.sslcert = NULL;
+	config.vhost_count = 0;
+	gethostname(config.hostname, 1024);
 }
 
@@ -30,4 +49,5 @@
 		line[0] = 0;
 		int stop = 0;
+		struct tw_config_entry* current = &config.root;
 		char* vhost = NULL;
 		while(stop == 0) {
@@ -48,21 +68,33 @@
 					} else if(cm_strcaseequ(r[0], "BeginVirtualHost")) {
 						if(vhost != NULL) {
-							cm_log("Config", "Already in virtual host section");
+							cm_log("Config", "Already in virtual host section at line %d", ln);
 							stop = 1;
 						} else {
 							if(r[1] == NULL) {
-								cm_log("Config", "Missing virtual host");
+								cm_log("Config", "Missing virtual host at line %d", ln);
 								stop = 1;
 							} else {
 								vhost = cm_strdup(r[1]);
+								current = &config.vhosts[config.vhost_count++];
+								int i;
+								current->name = cm_strdup(vhost);
+								current->port = 80;
+								for(i = 0; vhost[i] != 0; i++) {
+									if(vhost[i] == ':') {
+										current->name[i] = 0;
+										current->port = atoi(current->name + i + 1);
+										break;
+									}
+								}
 							}
 						}
 					} else if(cm_strcaseequ(r[0], "EndVirtualHost")) {
 						if(vhost == NULL) {
-							cm_log("Config", "Not in virtual host section");
+							cm_log("Config", "Not in virtual host section at line %d", ln);
 							stop = 1;
 						} else {
 							free(vhost);
 							vhost = NULL;
+							current = &config.root;
 						}
 					} else if(cm_strcaseequ(r[0], "Listen") || cm_strcaseequ(r[0], "ListenSSL")) {
@@ -75,4 +107,20 @@
 								;
 							config.ports[j] = port;
+						}
+					} else if(cm_strcaseequ(r[0], "SSLKey")) {
+						if(r[1] == NULL) {
+							cm_log("Config", "Missing path at line %d", ln);
+							stop = 1;
+						} else {
+							if(current->sslkey != NULL) free(current->sslkey);
+							current->sslkey = cm_strdup(r[1]);
+						}
+					} else if(cm_strcaseequ(r[0], "SSLCertificate")) {
+						if(r[1] == NULL) {
+							cm_log("Config", "Missing path at line %d", ln);
+							stop = 1;
+						} else {
+							if(current->sslcert != NULL) free(current->sslcert);
+							current->sslcert = cm_strdup(r[1]);
 						}
 					} else {
Index: trunk/Server/server.c
===================================================================
--- trunk/Server/server.c	(revision 11)
+++ trunk/Server/server.c	(revision 12)
@@ -3,4 +3,5 @@
 #include "tw_server.h"
 
+#include "tw_ssl.h"
 #include "tw_config.h"
 
@@ -115,4 +116,5 @@
 struct pass_entry {
 	int sock;
+	int port;
 	bool ssl;
 };
@@ -121,7 +123,18 @@
 	int sock = ((struct pass_entry*)ptr)->sock;
 	bool ssl = ((struct pass_entry*)ptr)->ssl;
+	int port = ((struct pass_entry*)ptR)->port;
+	free(ptr);
 #else
-void tw_server_pass(int sock, bool ssl) {
+void tw_server_pass(int sock, bool ssl, int port) {
 #endif
+	SSL_CTX* ctx = NULL;
+	SSL* s = NULL;
+	if(ssl) {
+		ctx = tw_create_ssl_ctx(port);
+		s = SSL_new(ctx);
+		SSL_set_fd(s, sock);
+		if(SSL_accept(s) <= 0) goto cleanup;
+	}
+cleanup:
 	close_socket(sock);
 #ifdef __MINGW32__
@@ -151,4 +164,5 @@
 					int clen = sizeof(claddr);
 					int sock = accept(sockets[i], (struct sockaddr*)&claddr, &clen);
+					cm_log("Server", "New connection accepted");
 #ifdef __MINGW32__
 					HANDLE thread;
@@ -156,9 +170,10 @@
 					e->sock = sock;
 					e->ssl = config.ports[i] & (1ULL << 32);
+					e->port = config.ports[i];
 					thread = (HANDLE)_beginthreadex(NULL, 0, tw_server_pass, e, 0, NULL);
 #else
 					pid_t pid = fork();
 					if(pid == 0) {
-						tw_server_pass(sock, config.ports[i] & (1ULL << 32));
+						tw_server_pass(sock, config.ports[i] & (1ULL << 32), config.ports[i]);
 						_exit(0);
 					} else {
Index: trunk/Server/ssl.c
===================================================================
--- trunk/Server/ssl.c	(revision 11)
+++ trunk/Server/ssl.c	(revision 12)
@@ -2,2 +2,34 @@
 
 #include "tw_ssl.h"
+
+#include "tw_config.h"
+
+#include <stdio.h>
+
+#include <cm_log.h>
+
+extern struct tw_config config;
+
+int tw_ssl_cert_cb(SSL* ssl, void* arg) {
+	const char* s = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
+	if(s != NULL) {
+		cm_log("SSL", "Certificate request for %s", s);
+	} else {
+		s = config.hostname;
+		cm_log("SSL", "Could not get the servername, defaulting to the hostname: %s", s);
+	}
+	struct tw_config_entry* e = tw_vhost_match(s, (uint64_t)arg);
+	if(e != NULL && e->sslkey != NULL && e->sslcert != NULL) {
+		SSL_use_PrivateKey_file(ssl, e->sslkey, SSL_FILETYPE_PEM);
+		SSL_use_certificate_file(ssl, e->sslcert, SSL_FILETYPE_PEM);
+		return 1;
+	} else {
+		return 0;
+	}
+}
+
+SSL_CTX* tw_create_ssl_ctx(uint64_t port) {
+	SSL_CTX* ctx = SSL_CTX_new(TLS_server_method());
+	SSL_CTX_set_cert_cb(ctx, tw_ssl_cert_cb, (void*)port);
+	return ctx;
+}
Index: trunk/Server/tw_config.h
===================================================================
--- trunk/Server/tw_config.h	(revision 11)
+++ trunk/Server/tw_config.h	(revision 12)
@@ -6,16 +6,26 @@
 #include <stdint.h>
 
-/* I don't think you would listen to 1024 ports */
 #define MAX_PORTS 1024
 
-struct tw_config_entry {};
+#define MAX_VHOSTS 1024
+
+struct tw_config_entry {
+	char* name;
+	int port;
+	char* sslkey;
+	char* sslcert;
+};
 
 struct tw_config {
 	uint64_t ports[MAX_PORTS + 1]; /* If port & (1 << 32) is non-zero, it is SSL */
+	char hostname[1025];
 	struct tw_config_entry root;
+	struct tw_config_entry vhosts[MAX_VHOSTS];
+	int vhost_count;
 };
 
 void tw_config_init(void);
 int tw_config_read(const char* path);
+struct tw_config_entry* tw_vhost_match(const char* name, int port);
 
 #endif
Index: trunk/Server/tw_ssl.h
===================================================================
--- trunk/Server/tw_ssl.h	(revision 11)
+++ trunk/Server/tw_ssl.h	(revision 12)
@@ -4,3 +4,7 @@
 #define __TW_SSL_H__
 
+#include <openssl/ssl.h>
+
+SSL_CTX* tw_create_ssl_ctx(uint64_t port);
+
 #endif
Index: trunk/example.conf
===================================================================
--- trunk/example.conf	(revision 12)
+++ trunk/example.conf	(revision 12)
@@ -0,0 +1,11 @@
+# $Id$
+# This is an example config
+
+Listen 8000 8001 8002 8003 8004
+ListenSSL 8443 8444 8445 8446 8447
+
+SSLKey key.pem
+SSLCertificate cert.pem
+
+BeginVirtualHost nishinbsd-ssd:8443
+EndVirtualHost
