Commit 234912c5 authored by venaas's avatar venaas Committed by venaas
Browse files

added code for reading main config and restructured tls init code

git-svn-id: https://svn.testnett.uninett.no/radsecproxy/trunk@39 e88ac4ed-0b26-0410-9574-a7f39faa03bf
parent 10b6ffd2
......@@ -58,6 +58,7 @@
#include <openssl/hmac.h>
#include "radsecproxy.h"
static struct options options;
static struct client clients[MAX_PEERS];
static struct server servers[MAX_PEERS];
......@@ -66,10 +67,9 @@ static int server_count = 0;
static struct replyq udp_server_replyq;
static int udp_server_sock = -1;
static char *udp_server_port = DEFAULT_UDP_PORT;
static pthread_mutex_t *ssl_locks;
static long *ssl_lock_count;
static SSL_CTX *ssl_ctx_cl;
static SSL_CTX *ssl_ctx = NULL;
extern int optind;
extern char *optarg;
......@@ -86,8 +86,14 @@ void ssl_locking_callback(int mode, int type, const char *file, int line) {
pthread_mutex_unlock(&ssl_locks[type]);
}
void ssl_locks_setup() {
void ssl_init() {
int i;
unsigned long error;
if (!options.tlscertificatefile || !options.tlscertificatekeyfile) {
printf("TLSCertificateFile and TLSCertificateKeyFile must be specified for TLS\n");
exit(1);
}
ssl_locks = malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
ssl_lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
......@@ -95,10 +101,36 @@ void ssl_locks_setup() {
ssl_lock_count[i] = 0;
pthread_mutex_init(&ssl_locks[i], NULL);
}
CRYPTO_set_id_callback(ssl_thread_id);
CRYPTO_set_locking_callback(ssl_locking_callback);
}
SSL_load_error_strings();
SSL_library_init();
while (!RAND_status()) {
time_t t = time(NULL);
pid_t pid = getpid();
RAND_seed((unsigned char *)&t, sizeof(time_t));
RAND_seed((unsigned char *)&pid, sizeof(pid));
}
ssl_ctx = SSL_CTX_new(TLSv1_method());
if (!ssl_ctx) {
printf("failed to initialise ssl");
exit(1);
}
if (!SSL_CTX_use_certificate_file(ssl_ctx, options.tlscertificatefile, SSL_FILETYPE_PEM)) {
while ((error = ERR_get_error()))
err("SSL: %s", ERR_error_string(error, NULL));
errx("Failed to load certificate");
}
if (!SSL_CTX_use_PrivateKey_file(ssl_ctx, options.tlscertificatekeyfile, SSL_FILETYPE_PEM)) {
while ((error = ERR_get_error()))
err("SSL: %s", ERR_error_string(error, NULL));
errx("Failed to load private key");
}
}
void printauth(char *s, unsigned char *t) {
int i;
......@@ -299,7 +331,7 @@ void tlsconnect(struct server *server, struct timeval *when, char *text) {
if ((server->sock = connecttoserver(server->peer.addrinfo)) < 0)
continue;
SSL_free(server->peer.ssl);
server->peer.ssl = SSL_new(ssl_ctx_cl);
server->peer.ssl = SSL_new(ssl_ctx);
SSL_set_fd(server->peer.ssl, server->sock);
if (SSL_connect(server->peer.ssl) > 0)
break;
......@@ -1217,11 +1249,11 @@ void *udpserverrd(void *arg) {
struct client *fr;
pthread_t udpserverwrth;
if ((udp_server_sock = bindport(SOCK_DGRAM, udp_server_port)) < 0) {
if ((udp_server_sock = bindport(SOCK_DGRAM, options.udpserverport)) < 0) {
printf("udpserverrd: socket/bind failed\n");
exit(1);
}
printf("udpserverrd: listening on UDP port %s\n", udp_server_port);
printf("udpserverrd: listening on UDP port %s\n", options.udpserverport);
if (pthread_create(&udpserverwrth, NULL, udpserverwr, NULL))
errx("pthread_create failed");
......@@ -1328,7 +1360,7 @@ void *tlsserverrd(void *arg) {
pthread_exit(NULL);
}
int tlslistener(SSL_CTX *ssl_ctx) {
int tlslistener() {
pthread_t tlsserverth;
int s, snew;
struct sockaddr_storage from;
......@@ -1395,11 +1427,7 @@ char *parsehostport(char *s, struct peer *peer) {
printf("missing host/address\n");
exit(1);
}
peer->host = malloc(p - field + 1);
if (!peer->host)
errx("malloc failed");
memcpy(peer->host, field, p - field);
peer->host[p - field] = '\0';
peer->host = stringcopy(field, p - field);
if (ipv6) {
p++;
if (*p && *p != ':' && *p != ' ' && *p != '\t' && *p != '\n') {
......@@ -1415,13 +1443,9 @@ char *parsehostport(char *s, struct peer *peer) {
printf("syntax error, : but no following port\n");
exit(1);
}
peer->port = malloc(p - field + 1);
if (!peer->port)
errx("malloc failed");
memcpy(peer->port, field, p - field);
peer->port[p - field] = '\0';
peer->port = stringcopy(field, p - field);
} else
peer->port = NULL;
peer->port = stringcopy(peer->type == 'U' ? DEFAULT_UDP_PORT : DEFAULT_TLS_PORT, 0);
return p;
}
......@@ -1435,14 +1459,10 @@ char *parserealmlist(char *s, struct server *server) {
n++;
l = p - s;
if (!l) {
server->realms = NULL;
return p;
printf("realm list must be specified\n");
exit(1);
}
server->realmdata = malloc(l + 1);
if (!server->realmdata)
errx("malloc failed");
memcpy(server->realmdata, s, l);
server->realmdata[l] = '\0';
server->realmdata = stringcopy(s, l);
server->realms = malloc((1+n) * sizeof(char *));
if (!server->realms)
errx("malloc failed");
......@@ -1508,15 +1528,9 @@ void getconfig(const char *serverfile, const char *clientfile) {
peer->type = *p;
for (p++; *p == ' ' || *p == '\t'; p++);
p = parsehostport(p, peer);
if (!peer->port)
peer->port = (peer->type == 'U' ? DEFAULT_UDP_PORT : DEFAULT_TLS_PORT);
for (; *p == ' ' || *p == '\t'; p++);
if (serverfile) {
p = parserealmlist(p, server);
if (!server->realms) {
printf("realm list must be specified\n");
exit(1);
}
for (; *p == ' ' || *p == '\t'; p++);
}
field = p;
......@@ -1527,13 +1541,9 @@ void getconfig(const char *serverfile, const char *clientfile) {
printf("secret must be specified for UDP\n");
exit(1);
}
peer->secret = DEFAULT_TLS_SECRET;
peer->secret = stringcopy(DEFAULT_TLS_SECRET, 0);
} else {
peer->secret = malloc(p - field + 1);
if (!peer->secret)
errx("malloc failed");
memcpy(peer->secret, field, p - field);
peer->secret[p - field] = '\0';
peer->secret = stringcopy(field, p - field);
/* check that rest of line only white space */
for (; *p == ' ' || *p == '\t'; p++);
if (*p && *p != '\n') {
......@@ -1586,6 +1596,62 @@ void getconfig(const char *serverfile, const char *clientfile) {
fclose(f);
}
void getmainconfig(const char *configfile) {
FILE *f;
char line[1024];
char *p, *opt, *endopt, *val, *endval;
printf("opening file %s for reading\n", configfile);
f = fopen(configfile, "r");
if (!f)
errx("getmainconfig failed to open %s for reading", configfile);
memset(&options, 0, sizeof(options));
while (fgets(line, 1024, f)) {
for (p = line; *p == ' ' || *p == '\t'; p++);
if (!*p || *p == '#' || *p == '\n')
continue;
opt = p++;
for (; *p && *p != ' ' && *p != '\t' && *p != '\n'; p++);
endopt = p - 1;
for (; *p == ' ' || *p == '\t'; p++);
if (!*p || *p == '\n') {
endopt[1] = '\0';
printf("error in %s, option %s has no value\n", configfile, opt);
exit(1);
}
val = p;
for (; *p && *p != '\n'; p++)
if (*p != ' ' && *p != '\t')
endval = p;
endopt[1] = '\0';
endval[1] = '\0';
printf("getmainconfig: %s = %s\n", opt, val);
if (!strcasecmp(opt, "TLSCertificateFile")) {
options.tlscertificatefile = stringcopy(val, 0);
continue;
}
if (!strcasecmp(opt, "TLSCertificateKeyFile")) {
options.tlscertificatekeyfile = stringcopy(val, 0);
continue;
}
if (!strcasecmp(opt, "UDPServerPort")) {
options.udpserverport = stringcopy(val, 0);
continue;
}
printf("error in %s, unknown option %s\n", configfile, opt);
exit(1);
}
fclose(f);
if (!options.udpserverport)
options.udpserverport = stringcopy(DEFAULT_UDP_PORT, 0);
}
#if 0
void parseargs(int argc, char **argv) {
int c;
......@@ -1605,20 +1671,18 @@ void parseargs(int argc, char **argv) {
printf("radsecproxy [ -p UDP-port ]\n");
exit(1);
}
#endif
int main(int argc, char **argv) {
SSL_CTX *ssl_ctx_srv;
unsigned long error;
pthread_t udpserverth;
// pthread_attr_t joinable;
int i;
parseargs(argc, argv);
// parseargs(argc, argv);
getmainconfig("radsecproxy.conf");
getconfig("servers.conf", NULL);
getconfig(NULL, "clients.conf");
ssl_locks_setup();
// pthread_attr_init(&joinable);
// pthread_attr_setdetachstate(&joinable, PTHREAD_CREATE_JOINABLE);
......@@ -1630,53 +1694,27 @@ int main(int argc, char **argv) {
errx("pthread_create failed");
break;
}
/* SSL setup */
SSL_load_error_strings();
SSL_library_init();
while (!RAND_status()) {
time_t t = time(NULL);
pid_t pid = getpid();
RAND_seed((unsigned char *)&t, sizeof(time_t));
RAND_seed((unsigned char *)&pid, sizeof(pid));
}
/* initialise client part and start clients */
ssl_ctx_cl = SSL_CTX_new(TLSv1_client_method());
if (!ssl_ctx_cl)
errx("no ssl ctx");
for (i = 0; i < server_count; i++) {
/* only initialise ssl here if at least one TLS server defined */
for (i = 0; i < server_count; i++)
if (servers[i].peer.type == 'T') {
ssl_init();
break;
}
for (i = 0; i < server_count; i++)
if (pthread_create(&servers[i].clientth, NULL, clientwr, (void *)&servers[i]))
errx("pthread_create failed");
}
/* start listener if at least one TLS client defined */
for (i = 0; i < client_count; i++)
if (clients[i].peer.type == 'T')
break;
if (i == client_count) {
printf("No TLS clients defined, not starting TLS listener\n");
/* just hang around doing nothing, anything to do here? */
for (;;)
sleep(1000);
}
/* setting up server/daemon part */
ssl_ctx_srv = SSL_CTX_new(TLSv1_server_method());
if (!ssl_ctx_srv)
errx("no ssl ctx");
if (!SSL_CTX_use_certificate_file(ssl_ctx_srv, "/tmp/server.pem", SSL_FILETYPE_PEM)) {
while ((error = ERR_get_error()))
err("SSL: %s", ERR_error_string(error, NULL));
errx("Failed to load certificate");
}
if (!SSL_CTX_use_PrivateKey_file(ssl_ctx_srv, "/tmp/server.key", SSL_FILETYPE_PEM)) {
while ((error = ERR_get_error()))
err("SSL: %s", ERR_error_string(error, NULL));
errx("Failed to load private key");
}
if (clients[i].peer.type == 'T') {
if (!ssl_ctx)
ssl_init();
return tlslistener();
}
return tlslistener(ssl_ctx_srv);
/* just hang around doing nothing, anything to do here? */
for (;;)
sleep(1000);
}
......@@ -42,6 +42,12 @@
#define RAD_Attr_Length 1
#define RAD_Attr_Value 2
struct options {
char *tlscertificatefile;
char *tlscertificatekeyfile;
char *udpserverport;
};
/* requests that a client will send */
struct request {
unsigned char *buf;
......@@ -101,6 +107,7 @@ struct server {
void errx(char *format, ...);
void err(char *format, ...);
char *stringcopy(char *s, int len);
char *addr2string(struct sockaddr *addr, socklen_t len);
int bindport(int type, char *port);
int connectport(int type, char *host, char *port);
......@@ -45,6 +45,18 @@ void err(char *format, ...) {
fprintf(stderr, "\n");
}
char *stringcopy(char *s, int len) {
char *r;
if (!len)
len = strlen(s);
r = malloc(len + 1);
if (!r)
errx("stringcopy: malloc failed");
memcpy(r, s, len);
r[len] = '\0';
return r;
}
char *addr2string(struct sockaddr *addr, socklen_t len) {
struct sockaddr_in6 *sa6;
struct sockaddr_in sa4;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment