bugfixes, moved to TLS v1.2 as a more secure way to deal with;

v0.5.xx
Alexander Vdolainen 10 years ago
parent 50b337dfb7
commit 647d7bb7b8

@ -166,10 +166,16 @@ static int __ar_multiply(void *data, sexp_t *sx)
/* define a little bit */ /* define a little bit */
#define DEFAULT_PORT 13133 #define DEFAULT_PORT 13133
static void sigpipe_handler(int a)
{
//fprintf(stderr, "\n\n\n\n\nBroken pipe\n\n\n\n");
return;
}
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
// set detailed signal handler // set detailed signal handler
struct sigaction sigact; struct sigaction sigact, sigpipe;
sigact.sa_flags = SA_SIGINFO; sigact.sa_flags = SA_SIGINFO;
sigact.sa_sigaction = signal_error; sigact.sa_sigaction = signal_error;
sigemptyset(&sigact.sa_mask); sigemptyset(&sigact.sa_mask);
@ -177,6 +183,10 @@ int main(int argc, char **argv)
sigaction(SIGILL, &sigact, 0); sigaction(SIGILL, &sigact, 0);
sigaction(SIGSEGV, &sigact, 0); sigaction(SIGSEGV, &sigact, 0);
sigaction(SIGBUS, &sigact, 0); sigaction(SIGBUS, &sigact, 0);
memset(&sigpipe, 0, sizeof(struct sigaction));
sigpipe.sa_handler = sigpipe_handler;
sigaction(SIGPIPE, &sigpipe, NULL);
char *rootca = NULL, *cert = NULL; char *rootca = NULL, *cert = NULL;
int port = DEFAULT_PORT; int port = DEFAULT_PORT;
@ -272,7 +282,9 @@ int main(int argc, char **argv)
int client = accept(srv, (struct sockaddr*)&addr, &len); /* accept connection as usual */ int client = accept(srv, (struct sockaddr*)&addr, &len); /* accept connection as usual */
opt = connection_create(co, client); /* create connection, that's all */ opt = connection_create(co, client); /* create connection, that's all */
if(opt) return opt; if(opt) {
fprintf(stderr, "Cannot create connetion (%d)\n", opt);
}
} }
return 0; return 0;

@ -68,6 +68,7 @@ typedef struct __perm_context_type {
#define CXCONN_MASTER (1 << 1) #define CXCONN_MASTER (1 << 1)
#define CXCONN_SLAVE (1 << 2) #define CXCONN_SLAVE (1 << 2)
#define CXCONN_ESTABL (1 << 3) #define CXCONN_ESTABL (1 << 3)
#define CXCONN_BROKEN (1 << 4)
/* /*
* älä jätä kommentteja omalla kielellä! yksinkertaisia englanti sijaan! * älä jätä kommentteja omalla kielellä! yksinkertaisia englanti sijaan!
@ -133,6 +134,7 @@ typedef struct __sexp_payload_t {
#define ESXMSG_NOWAIT (1 << 7) #define ESXMSG_NOWAIT (1 << 7)
#define ESXMSG_ISREPLY (1 << 8) #define ESXMSG_ISREPLY (1 << 8)
#define ESXMSG_CLOSURE (1 << 9) #define ESXMSG_CLOSURE (1 << 9)
#define ESXMSG_RMONRETR (1 << 10)
/** /**
* \brief Message used in sntl message passing * \brief Message used in sntl message passing

@ -43,6 +43,23 @@ static long __cmp_ulong(const void *a, const void *b);
static sxmsg_t *__allocate_msg(int *res); static sxmsg_t *__allocate_msg(int *res);
static void __destroy_msg(sxmsg_t *msg); static void __destroy_msg(sxmsg_t *msg);
/* examination */
static inline int __exam_connection(conn_t *co)
{
int r = 0;
pthread_mutex_lock(&co->oplock);
if(co->flags | CXCONN_BROKEN) {
/* wake up all */
/* destroy thread poll */
/* free all memory and sync primitives */
r = 1;
}
pthread_mutex_unlock(&co->oplock);
return r;
}
static int __rpc_callback(void *data) static int __rpc_callback(void *data)
{ {
struct __rpc_job *job = (struct __rpc_job *)data; struct __rpc_job *job = (struct __rpc_job *)data;
@ -242,35 +259,47 @@ static int __insert_rpc_function(usrtc_t *tree, const char *name, int (*rpcf)(vo
return 0; return 0;
} }
/* wake up all waiters on messages with given opcode */
static void __wake_up_waiters(conn_t *co, int opcode) static void __wake_up_waiters(conn_t *co, int opcode)
{ {
usrtc_node_t *node = NULL, *last_node = NULL; usrtc_node_t *node = NULL, *last_node = NULL;
usrtc_node_t *msg_node = NULL, *last_msg_node = NULL; usrtc_node_t *msg_node = NULL, *last_msg_node = NULL;
chnl_t *ch; chnl_t *ch;
sxmsg_t *smsg = NULL; sxmsg_t *smsg = NULL;
pthread_rwlock_wrlock(&(co->chnl_lock)); pthread_rwlock_wrlock(&(co->chnl_lock));
node = usrtc_first(co->chnl_tree); node = usrtc_first(co->chnl_tree);
last_node = usrtc_last(co->chnl_tree); last_node = usrtc_last(co->chnl_tree);
/* going through channels tree */
while(!usrtc_isempty(co->chnl_tree)) { while(!usrtc_isempty(co->chnl_tree)) {
ch = (chnl_t *)usrtc_node_getdata(node); ch = (chnl_t *)usrtc_node_getdata(node);
pthread_rwlock_rdlock(&(ch->msglock)); pthread_rwlock_rdlock(&(ch->msglock));
msg_node = usrtc_first(ch->msgs_tree); msg_node = usrtc_first(ch->msgs_tree);
last_msg_node = usrtc_last(ch->msgs_tree); last_msg_node = usrtc_last(ch->msgs_tree);
while(!usrtc_isempty(ch->msgs_tree)) {
while(!usrtc_isempty(ch->msgs_tree)) { /* messages bypassing */
smsg = (sxmsg_t *)usrtc_node_getdata(msg_node); smsg = (sxmsg_t *)usrtc_node_getdata(msg_node);
smsg->opcode = opcode; smsg->opcode = opcode;
/* wake up waiting thread */
pthread_mutex_unlock(&(smsg->wait)); pthread_mutex_unlock(&(smsg->wait));
if(msg_node == last_msg_node) break; if(msg_node == last_msg_node) break;
msg_node = usrtc_next(ch->msgs_tree, msg_node); msg_node = usrtc_next(ch->msgs_tree, msg_node);
} }
pthread_rwlock_unlock(&(ch->msglock)); pthread_rwlock_unlock(&(ch->msglock));
if(node == last_node) break; if(node == last_node) break;
node = usrtc_next(co->chnl_tree, node); node = usrtc_next(co->chnl_tree, node);
} }
pthread_rwlock_unlock(&(co->chnl_lock)); pthread_rwlock_unlock(&(co->chnl_lock));
return;
} }
static int __default_auth_set_context(void *cctx, sexp_t *sx) static int __default_auth_set_context(void *cctx, sexp_t *sx)
@ -339,6 +368,7 @@ __reply:
/* we will send it */ /* we will send it */
if(__conn_write(co, tbuf, strlen(tbuf)) < 0) { if(__conn_write(co, tbuf, strlen(tbuf)) < 0) {
co->flags &= ~CXCONN_ESTABL; co->flags &= ~CXCONN_ESTABL;
co->flags |= CXCONN_BROKEN;
__wake_up_waiters(co, ESXNOCONNECT); __wake_up_waiters(co, ESXNOCONNECT);
} }
destroy_sexp(sx); destroy_sexp(sx);
@ -449,6 +479,7 @@ static int __default_ch_get_types(void *cctx, sexp_t *sx)
/* reply to this rpc */ /* reply to this rpc */
if(__conn_write(co, tbuf, strlen(tbuf)) < 0) { if(__conn_write(co, tbuf, strlen(tbuf)) < 0) {
co->flags &= ~CXCONN_ESTABL; co->flags &= ~CXCONN_ESTABL;
co->flags |= CXCONN_BROKEN;
__wake_up_waiters(co, ESXNOCONNECT); __wake_up_waiters(co, ESXNOCONNECT);
} }
free(tbuf); free(tbuf);
@ -512,6 +543,7 @@ __send_reply:
snprintf(buf, 1024, "(ch-gl-error (%d))", r); snprintf(buf, 1024, "(ch-gl-error (%d))", r);
if(__conn_write(co, buf, strlen(buf)) < 0) { if(__conn_write(co, buf, strlen(buf)) < 0) {
co->flags &= ~CXCONN_ESTABL; co->flags &= ~CXCONN_ESTABL;
co->flags |= CXCONN_BROKEN;
__wake_up_waiters(co, ESXNOCONNECT); __wake_up_waiters(co, ESXNOCONNECT);
} }
destroy_sexp(sx); destroy_sexp(sx);
@ -640,6 +672,7 @@ static int __default_ch_open(void *cctx, sexp_t *sx)
uuid, cid); uuid, cid);
if(__conn_write(co, buf, strlen(buf)) < 0) { if(__conn_write(co, buf, strlen(buf)) < 0) {
co->flags &= ~CXCONN_ESTABL; co->flags &= ~CXCONN_ESTABL;
co->flags |= CXCONN_BROKEN;
__wake_up_waiters(co, ESXNOCONNECT); __wake_up_waiters(co, ESXNOCONNECT);
} }
destroy_sexp(sx); destroy_sexp(sx);
@ -823,6 +856,7 @@ __send_repl:
destroy_sexp(sx); destroy_sexp(sx);
if(__conn_write(co, buf, strlen(buf)) < 0) { if(__conn_write(co, buf, strlen(buf)) < 0) {
co->flags &= ~CXCONN_ESTABL; co->flags &= ~CXCONN_ESTABL;
co->flags |= CXCONN_BROKEN;
__wake_up_waiters(co, ESXNOCONNECT); __wake_up_waiters(co, ESXNOCONNECT);
} }
free(buf); free(buf);
@ -1241,12 +1275,13 @@ static int __default_msg_return(void *cctx, sexp_t *sx)
smsg->flags |= ESXMSG_CLOSURE; smsg->flags |= ESXMSG_CLOSURE;
/* Q: can we remove the message from the tree there??? */ /* Q: can we remove the message from the tree there??? */
/* A: yep */ /* A: actually no */
/* first remove the message from tree */ /* first remove the message from tree */
pthread_rwlock_wrlock(&(chan->msglock)); if(smsg->flags & ESXMSG_RMONRETR) {
usrtc_delete(chan->msgs_tree, &(smsg->pendingq_node)); pthread_rwlock_wrlock(&(chan->msglock));
pthread_rwlock_unlock(&(chan->msglock)); usrtc_delete(chan->msgs_tree, &(smsg->pendingq_node));
pthread_rwlock_unlock(&(chan->msglock));
}
pthread_mutex_unlock(&(smsg->wait)); pthread_mutex_unlock(&(smsg->wait));
} }
@ -1403,10 +1438,10 @@ static void *__cxslave_thread_listener(void *wctx)
while((r = __conn_read(co, buf, 4096)) != -1) { while((r = __conn_read(co, buf, 4096)) != -1) {
buf[r] = '\0'; buf[r] = '\0';
//if(r) printf("Got the message %s (%d bytes)\n", buf, r);
r = __eval_cstr(buf, conn_sys->system_rpc, co); r = __eval_cstr(buf, conn_sys->system_rpc, co);
} }
co->flags &= ~CXCONN_ESTABL; co->flags &= ~CXCONN_ESTABL;
co->flags |= CXCONN_BROKEN;
__wake_up_waiters(co, ESXNOCONNECT); __wake_up_waiters(co, ESXNOCONNECT);
free(buf); free(buf);
@ -1426,6 +1461,7 @@ static void *__cxmaster_thread_listener(void *wctx)
r = __eval_cstr(buf, conn_sys->system_rpc, co); r = __eval_cstr(buf, conn_sys->system_rpc, co);
} }
co->flags &= ~CXCONN_ESTABL; co->flags &= ~CXCONN_ESTABL;
co->flags |= CXCONN_BROKEN;
__wake_up_waiters(co, ESXNOCONNECT); __wake_up_waiters(co, ESXNOCONNECT);
free(buf); free(buf);
@ -1598,6 +1634,7 @@ static void *__msg_queue_thread(void *ctx)
/* write it */ /* write it */
if(__conn_write(co, (void *)buf, strlen(buf) + sizeof(char)) < 0) { if(__conn_write(co, (void *)buf, strlen(buf) + sizeof(char)) < 0) {
co->flags &= ~CXCONN_ESTABL; co->flags &= ~CXCONN_ESTABL;
co->flags |= CXCONN_BROKEN;
__wake_up_waiters(co, ESXNOCONNECT); __wake_up_waiters(co, ESXNOCONNECT);
} }
@ -1671,6 +1708,8 @@ static int __verify_certcall(int preverify_ok, X509_STORE_CTX *ctx)
X509_STORE_CTX_set_error(ctx, err); X509_STORE_CTX_set_error(ctx, err);
} }
if(!preverify_ok) return 0;
/* ok, now we're on top of SSL (depth == 0) certs chain, /* ok, now we're on top of SSL (depth == 0) certs chain,
* and we can validate client certificate */ * and we can validate client certificate */
if(!depth) { if(!depth) {
@ -1688,6 +1727,12 @@ static int __verify_certcall(int preverify_ok, X509_STORE_CTX *ctx)
return preverify_ok; return preverify_ok;
} }
/* dummy just to check the server side */
static int __verify_certcall_dummy(int preverify_ok, X509_STORE_CTX *ctx)
{
return preverify_ok;
}
/* subsystem: here u can told me about how it's ugly to use global pointers, /* subsystem: here u can told me about how it's ugly to use global pointers,
* yep, it's a business of fucking morons, btw it works (heh, openssl uses this * yep, it's a business of fucking morons, btw it works (heh, openssl uses this
* ancient shit method too, many many and many others too, trust me ...). * ancient shit method too, many many and many others too, trust me ...).
@ -1731,6 +1776,7 @@ void *__system_queue_listener(void *data)
/* write the buf */ /* write the buf */
if(__conn_write(co, (void *)payload->cstr, strlen(payload->cstr) + 1) < 0) { if(__conn_write(co, (void *)payload->cstr, strlen(payload->cstr) + 1) < 0) {
co->flags &= ~CXCONN_ESTABL; co->flags &= ~CXCONN_ESTABL;
co->flags |= CXCONN_BROKEN;
__wake_up_waiters(co, ESXNOCONNECT); __wake_up_waiters(co, ESXNOCONNECT);
} }
} }
@ -1919,10 +1965,14 @@ int connection_initiate(conn_t *co, const char *host, int port,
co->mqueue = mqueue; co->mqueue = mqueue;
/* init SSL certificates and context */ /* init SSL certificates and context */
co->ctx = SSL_CTX_new(SSLv3_client_method()); co->ctx = SSL_CTX_new(TLSv1_2_client_method());
if(!co->ctx) { ERR_print_errors_fp(stderr); if(!co->ctx) { ERR_print_errors_fp(stderr);
r = EINVAL; goto __fail_3; } r = EINVAL; goto __fail_3; }
else SSL_CTX_set_verify_depth(co->ctx, 1); /* FIXME: use configuration */ else {
SSL_CTX_set_verify(co->ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
__verify_certcall_dummy);
SSL_CTX_set_verify_depth(co->ctx, 1); /* FIXME: use configuration */
}
/* load certificates */ /* load certificates */
SSL_CTX_load_verify_locations(co->ctx, conn_sys->rootca, NULL); SSL_CTX_load_verify_locations(co->ctx, conn_sys->rootca, NULL);
@ -1996,7 +2046,8 @@ int connection_initiate(conn_t *co, const char *host, int port,
// we've lost the connection // we've lost the connection
co->flags &= ~CXCONN_ESTABL; co->flags &= ~CXCONN_ESTABL;
r = ESXNOCONNECT; r = ESXNOCONNECT;
__wake_up_waiters(co, ESXNOCONNECT); co->flags |= CXCONN_BROKEN;
//__wake_up_waiters(co, ESXNOCONNECT);
free(buf); free(buf);
/* shutdown connection */ /* shutdown connection */
goto __fail_3; goto __fail_3;
@ -2012,8 +2063,9 @@ int connection_initiate(conn_t *co, const char *host, int port,
if(bytes == -1) { if(bytes == -1) {
// we've lost the connection // we've lost the connection
co->flags &= ~CXCONN_ESTABL; co->flags &= ~CXCONN_ESTABL;
co->flags |= CXCONN_BROKEN;
r = ESXNOCONNECT; r = ESXNOCONNECT;
__wake_up_waiters(co, ESXNOCONNECT); //__wake_up_waiters(co, ESXNOCONNECT);
free(buf); free(buf);
/* shutdown connection */ /* shutdown connection */
goto __fail_3; goto __fail_3;
@ -2104,7 +2156,7 @@ int connection_create(conn_t *co, int sck)
co->mqueue = mqueue; co->mqueue = mqueue;
/* init SSL certificates and context */ /* init SSL certificates and context */
co->ctx = SSL_CTX_new(SSLv3_server_method()); co->ctx = SSL_CTX_new(TLSv1_2_server_method());
if(!co->ctx) { r = EINVAL; printf("%s:%d\n", __FUNCTION__, __LINE__);goto __fail_3; } if(!co->ctx) { r = EINVAL; printf("%s:%d\n", __FUNCTION__, __LINE__);goto __fail_3; }
else { else {
/* set verify context */ /* set verify context */
@ -2174,7 +2226,8 @@ int connection_create(conn_t *co, int sck)
if(bytes < 0) { if(bytes < 0) {
printf("Terminate SSL connection, the other end is lost.\n"); printf("Terminate SSL connection, the other end is lost.\n");
co->flags &= ~CXCONN_ESTABL; co->flags &= ~CXCONN_ESTABL;
__wake_up_waiters(co, ESXNOCONNECT); co->flags |= CXCONN_BROKEN;
//__wake_up_waiters(co, ESXNOCONNECT);
r = ESXNOCONNECT; r = ESXNOCONNECT;
goto __fail_3; goto __fail_3;
} }
@ -2539,7 +2592,7 @@ static int __message_send(chnl_t *ch, sexp_t *sx, sxmsg_t **msg, struct timespec
int r = 0; int r = 0;
sxmsg_t *m = NULL; sxmsg_t *m = NULL;
conn_t *co = ch->connection; conn_t *co = ch->connection;
if(!(co->flags & CXCONN_ESTABL)) { if(!(co->flags & CXCONN_ESTABL)) {
destroy_sexp(sx); destroy_sexp(sx);
return ESXNOCONNECT; return ESXNOCONNECT;
@ -2605,7 +2658,7 @@ static int __msg_reply(sxmsg_t *msg, sexp_t *sx, struct timespec *tio, int opcod
int r = 0; int r = 0;
chnl_t *ch = msg->pch; chnl_t *ch = msg->pch;
conn_t *co = ch->connection; conn_t *co = ch->connection;
if(!(co->flags & CXCONN_ESTABL)) { if(!(co->flags & CXCONN_ESTABL)) {
destroy_sexp(sx); destroy_sexp(sx);
return ESXNOCONNECT; return ESXNOCONNECT;
@ -2620,6 +2673,7 @@ static int __msg_reply(sxmsg_t *msg, sexp_t *sx, struct timespec *tio, int opcod
msg->flags |= ESXMSG_ISREPLY; /* this is a reply */ msg->flags |= ESXMSG_ISREPLY; /* this is a reply */
if(!sx) msg->flags &= ~ESXMSG_PENDING; if(!sx) msg->flags &= ~ESXMSG_PENDING;
else msg->flags |= ESXMSG_RMONRETR;
/* put the message to the queue */ /* put the message to the queue */
r = pth_queue_add(co->mqueue, (void *)msg, USR_MSG); r = pth_queue_add(co->mqueue, (void *)msg, USR_MSG);
@ -2641,7 +2695,6 @@ static int __msg_reply(sxmsg_t *msg, sexp_t *sx, struct timespec *tio, int opcod
destroy_sexp(msg->initial_sx); destroy_sexp(msg->initial_sx);
__destroy_msg(msg); __destroy_msg(msg);
} }
return r; return r;
} }

Loading…
Cancel
Save