vhost works

git-svn-id: file:///raid/svn-personal/tewi/trunk@12 8739d7e6-ffea-ec47-b151-bdff447c6205
This commit is contained in:
Nishi 2024-09-13 13:36:03 +00:00
parent f110e3e190
commit 448281ee99
7 changed files with 129 additions and 8 deletions

View File

@ -37,7 +37,8 @@ void cm_log(const char* name, const char* log, ...) {
i++;
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') {
int a = va_arg(args, int);

View File

@ -6,17 +6,36 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <cm_string.h>
#include <cm_log.h>
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;
for(i = 0; i < MAX_PORTS + 1; i++) {
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);
}
int tw_config_read(const char* path) {
@ -29,6 +48,7 @@ int tw_config_read(const char* path) {
char* line = malloc(1);
line[0] = 0;
int stop = 0;
struct tw_config_entry* current = &config.root;
char* vhost = NULL;
while(stop == 0) {
int c = fread(cbuf, 1, 1, f);
@ -47,23 +67,35 @@ int tw_config_read(const char* path) {
}
} 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")) {
for(i = 1; r[i] != NULL; i++) {
@ -75,6 +107,22 @@ int tw_config_read(const char* path) {
;
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 {
if(r[0] != NULL) {
cm_log("Config", "Unknown directive `%s' at line %d", r[0], ln);

View File

@ -2,6 +2,7 @@
#include "tw_server.h"
#include "tw_ssl.h"
#include "tw_config.h"
#include <unistd.h>
@ -114,15 +115,27 @@ int tw_server_init(void) {
#ifdef __MINGW32__
struct pass_entry {
int sock;
int port;
bool ssl;
};
unsigned int WINAPI tw_server_pass(void* ptr) {
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__
_endthreadex(0);
@ -150,16 +163,18 @@ void tw_server_loop(void) {
SOCKADDR claddr;
int clen = sizeof(claddr);
int sock = accept(sockets[i], (struct sockaddr*)&claddr, &clen);
cm_log("Server", "New connection accepted");
#ifdef __MINGW32__
HANDLE thread;
struct pass_entry* e = malloc(sizeof(*e));
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 {
close_socket(sock);

View File

@ -1,3 +1,35 @@
/* $Id$ */
#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;
}

View File

@ -5,17 +5,27 @@
#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

View File

@ -3,4 +3,8 @@
#ifndef __TW_SSL_H__
#define __TW_SSL_H__
#include <openssl/ssl.h>
SSL_CTX* tw_create_ssl_ctx(uint64_t port);
#endif

11
example.conf Normal file
View File

@ -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