int SocketAccept(uv_stream_t *const sstream, struct tls *const ssecure, SocketRef *const out) { SocketRef socket = calloc(1, sizeof(struct Socket)); if(!socket) return UV_ENOMEM; int rc = uv_tcp_init(async_loop, socket->stream); if(rc < 0) goto cleanup; rc = uv_accept(sstream, (uv_stream_t *)socket->stream); if(rc < 0) goto cleanup; if(ssecure) { uv_os_fd_t fd; rc = uv_fileno((uv_handle_t *)socket->stream, &fd); if(rc < 0) goto cleanup; for(;;) { int event = tls_accept_socket(ssecure, &socket->secure, fd); if(0 == event) break; rc = tls_poll((uv_stream_t *)socket->stream, event); if(rc < 0) goto cleanup; } } socket->rdmem = NULL; *socket->rd = uv_buf_init(NULL, 0); *socket->wr = uv_buf_init(NULL, 0); *out = socket; socket = NULL; cleanup: SocketFree(&socket); return rc; }
static bool connection_tls_handshake(Client *client) { uv_os_fd_t fd; struct tls *context = NULL; int ret = TLS_READ_AGAIN; if(uv_fileno((uv_handle_t *)client->handle, &fd) != 0) { return false; } while((ret = tls_accept_socket(CurrentConnectionState.ServerContext, &context, fd)) != 0) { if(ret == -1) { return false; } } client->TlsContext = context; tls_get_cert_fingerprint(client->TlsContext, client->CertificateFp, sizeof(client->CertificateFp)); return true; }
static const char *start_worker(struct Worker *w, int fd) { int err; w->socket = fd; if (w->is_server) { err = tls_accept_socket(w->base, &w->ctx, fd); } else { err = tls_connect_socket(w->ctx, fd, w->hostname); } if (err != 0) { return tls_error(w->ctx ? w->ctx : w->base); } return do_handshake(w, fd); }
static const char *do_handshake(struct Worker *w, int fd) { int err; const char *msg; if (w->is_server) { err = tls_accept_socket(w->base, &w->ctx, fd); } else { err = tls_connect_socket(w->ctx, fd, w->hostname); } if (err == TLS_READ_AGAIN) { return wait_for_event(w, EV_READ); } else if (err == TLS_WRITE_AGAIN) { return wait_for_event(w, EV_WRITE); } else if (err == 0) { w->wstate = CONNECTED; return done_handshake(w); } msg = tls_error(w->ctx ? w->ctx : w->base); return msg ? msg : "handshake failure"; }
void worker(int connfd, struct tls* ctx) { // Process HEADER //-------------- struct tls* cctx = NULL; tls_accept_socket(ctx, &cctx, connfd); json_t *header = recvOverTLS(cctx); const char* clientName = json_string_value(json_object_get(header, "from")); for (size_t i = 0; i < sizeof(clientName); i++) { if (clientName[i] == '/' || clientName[i] == '\\') { syslog(LOG_ERR, "ERROR in clientName!, aborting"); return; } } const char* clientAuth = json_string_value(json_object_get(header, "auth")); if (strcmp(clientAuth, getClientAuth()) != 0) { syslog(LOG_ERR, "Authentication failed"); return; } connType type = json_integer_value(json_object_get(header, "type")); int size = json_integer_value(json_object_get(header, "size")); // Process Payload //---------------- // new Values for graphs if (type == NEWDATA) { for (int i = 0; i < size; i++) { json_t* payload = recvOverTLS(cctx); pasteJSON(payload, clientName); } } // create .json or update displaysettings if (type == CREATE || type == UPDATE) { for (int i = 0; i < size; i++) { json_t* payload = recvOverTLS(cctx); const char * name = json_string_value(json_object_get(payload, "name")); if (name == NULL) { syslog(LOG_ERR, "Error in Message from Client"); return; } json_t *root = json_object_get(payload, "payload"); char* file = composeFileName(clientName, name, "json"); if (type == CREATE) { dumpJSON(root, file); } else { mergeJSON(root,file); } } } // Look, which files are not available if (type == HELLO) { json_t *relist = json_array(); json_t *list = recvOverTLS(cctx); for (int i = 0; i < size; i++) { const char * name = json_string_value(json_array_get(list, i)); if (name == NULL) { syslog(LOG_ERR, "Error in Message from Client"); return; } char* file = composeFileName(clientName, name, "json"); if (access( file, F_OK ) == -1) { json_array_append_new(relist, json_string(name)); } } char * relistStr = json_dumps(relist, JSON_COMPACT); sendOverTLS(cctx, relistStr); free(relistStr); } // Delete all files from this client if (type == DELETE) { json_t *list = recvOverTLS(cctx); for (int i = 0; i < size; i++) { const char * name = json_string_value(json_array_get(list, i)); delete(clientName, name); } } tls_close(cctx); tls_free(cctx); }
int main(int argc, char **argv) { struct tls_config *config = NULL; struct tls *tls = NULL; unsigned int protocols = 0; struct sockaddr_in server, client; int sock = socket(AF_INET, SOCK_STREAM, 0); int opt = 1; int b; struct tls *tls2 = NULL; ssize_t outlen = 0; char bufs[1000], bufc[1000]; int sc; char *msg = "HELLO TLS CLIENT\n"; char *ciphers = "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384"; struct pollfd pfd[2]; if(tls_init() < 0) { printf("tls_init error\n"); exit(1); } config = tls_config_new(); if(config == NULL) { printf("tls_config_new error\n"); exit(1); } tls = tls_server(); if(tls == NULL) { printf("tls_server error\n"); exit(1); } if(tls_config_parse_protocols(&protocols, "secure") < 0) { printf("tls_config_parse_protocols error\n"); exit(1); } tls_config_set_protocols(config, protocols); if(tls_config_set_ciphers(config, ciphers) < 0) { printf("tls_config_set_ciphers error\n"); exit(1); } if(tls_config_set_key_file(config, "private.pem") < 0) { printf("tls_config_set_key_file error\n"); exit(1); } if(tls_config_set_cert_file(config, "server.crt") < 0) { printf("tls_config_set_cert_file error\n"); exit(1); } if(tls_configure(tls, config) < 0) { printf("tls_configure error: %s\n", tls_error(tls)); exit(1); } bzero(&server, sizeof(server)); server.sin_addr.s_addr = inet_addr("127.0.0.1"); server.sin_port = htons(9000); server.sin_family = AF_INET; setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, 4); b = bind(sock, (struct sockaddr *) &server, sizeof(server)); if(b < 0) { printf("erro bind\n"); exit(1); } listen(sock, 10); socklen_t client_size = sizeof(client); sc = accept(sock, (struct sockaddr *) &client, &client_size); if(tls_accept_socket(tls, &tls2, sc) < 0) { printf("tls_accept_socket error\n"); exit(1); } tls_write(tls2, msg, strlen(msg)); pfd[0].fd = 0; pfd[0].events = POLLIN; pfd[1].fd = sc; pfd[1].events = POLLIN; while(bufc[0] != ':' && bufc[1] != 'q') { poll(pfd, 2, -1); bzero(bufs, 1000); bzero(bufc, 1000); if(pfd[0].revents & POLLIN) { int q = read(0, bufc, 1000); tls_write(tls2, bufc, q); } if(pfd[1].revents & POLLIN) { if((outlen = tls_read(tls2, bufs, 1000)) <= 0) break; printf("Mensagem (%lu): %s\n", outlen, bufs); } } tls_close(tls); tls_free(tls); tls_config_free(config); return 0; }