csm_service_list * csm_services_init(void) { csm_service_list *services = h_calloc(1, sizeof(csm_service_list)); CHECK_MEM(services); co_obj_t *csm_services = co_list16_create(); CHECK_MEM(csm_services); services->services = csm_services; hattach(services->services, services); co_obj_t *service_fields = co_list16_create(); CHECK_MEM(service_fields); services->service_fields = service_fields; hattach(services->service_fields, services); co_obj_t *update_handlers = co_list16_create(); CHECK_MEM(update_handlers); services->update_handlers = update_handlers; hattach(services->update_handlers, services); return services; error: return NULL; }
static inline _treenode_t * _co_tree_insert_r(_treenode_t *root, _treenode_t *current, const char *orig_key, const size_t orig_klen, const char *key, const size_t klen, co_obj_t *value) { if (current == NULL) { current = (_treenode_t *) h_calloc(1, sizeof(_treenode_t)); if(root == NULL) { root = current; } else { hattach(current, root); } current->splitchar = *key; } if (*key < current->splitchar) { current->low = _co_tree_insert_r(root, current->low, orig_key, orig_klen, key, klen, value); } else if (*key == current->splitchar) { if (klen > 1) { // not done yet, keep going but one less current->equal = _co_tree_insert_r(root, current->equal, orig_key, orig_klen, key+1, klen - 1, value); } else { if(current->value != NULL) { co_obj_free(current->value); } if(current->key != NULL) { co_obj_free(current->key); } current->value = value; current->key = co_str8_create(orig_key, orig_klen, 0); hattach(current->key, current); hattach(current->value, current); current->key->_ref++; current->value->_ref++; } } else { current->high = _co_tree_insert_r(root, current->high, orig_key, orig_klen, key, klen, value); } return current; }
void co_free(co_obj_t *object) { hattach(object, NULL); co_obj_free(object); return; }
int connection_http_to_proxy(Connection *conn) { Proxy *proxy = Request_get_action(conn->req, proxy); check(proxy != NULL, "Should have a proxy backend."); int proxy_fd = netdial(1, bdata(proxy->server), proxy->port); check(proxy_fd != -1, "Failed to connect to proxy backend %s:%d", bdata(proxy->server), proxy->port); if(!conn->proxy_iob) { conn->proxy_iob = IOBuf_create(BUFFER_SIZE, proxy_fd, IOBUF_SOCKET); check_mem(conn->proxy_iob); } if(!conn->client) { conn->client = h_calloc(sizeof(httpclient_parser), 1); check_mem(conn->client); hattach(conn->client, conn); } return CONNECT; error: return FAILED; }
int csm_add_service(csm_service_list *services, csm_service *s, csm_ctx *ctx) { // validate service fields against schema CHECK(csm_validate_fields(ctx, s), "Service doesn't validate"); // attach service to service list s->parent = services; // co_obj_t *service_obj = co_service_create(s); // CHECK_MEM(service_obj); co_service_t *service_obj = container_of(s, co_service_t, service); CHECK(co_list_append(services->services, (co_obj_t *)service_obj), "Failed to add service to service list"); co_obj_t *fields = s->fields; // detach s->fields from s before adding s->fields to services->service_fields hattach(fields, NULL); // add service fields to service list CHECK(co_list_append(services->service_fields, fields), "Failed to add service fields to service list"); CHECK(csm_update_service(services, s, ctx, 0), "Failed to finalize service"); return 1; error: csm_remove_service(services, s); // csm_service_destroy(s); return 0; }
IOBuf *IOBuf_create(size_t len, int fd, IOBufType type) { IOBuf *buf = h_calloc(sizeof(IOBuf), 1); check_mem(buf); buf->fd = fd; buf->len = len; buf->buf = h_malloc(len + 1); check_mem(buf->buf); hattach(buf->buf, buf); buf->type = type; if(type == IOBUF_SSL) { buf->use_ssl = 1; buf->handshake_performed = 0; ssl_init(&buf->ssl); ssl_set_endpoint(&buf->ssl, SSL_IS_SERVER); ssl_set_authmode(&buf->ssl, SSL_VERIFY_NONE); havege_init(&buf->hs); ssl_set_rng(&buf->ssl, havege_rand, &buf->hs); ssl_set_dbg(&buf->ssl, ssl_debug, NULL); ssl_set_bio(&buf->ssl, ssl_fdrecv_wrapper, buf, ssl_fdsend_wrapper, buf); ssl_set_session(&buf->ssl, 1, 0, &buf->ssn); memset(&buf->ssn, 0, sizeof(buf->ssn)); buf->send = ssl_send; buf->recv = ssl_recv; buf->stream_file = ssl_stream_file; } else if(type == IOBUF_NULL) { buf->send = null_send; buf->recv = null_recv; buf->stream_file = null_stream_file; } else if(type == IOBUF_FILE) { buf->send = file_send; buf->recv = file_recv; buf->stream_file = plain_stream_file; } else if(type == IOBUF_SOCKET) { buf->send = plaintext_send; buf->recv = plaintext_recv; buf->stream_file = plain_stream_file; } else { sentinel("Invalid IOBufType given: %d", type); } return buf; error: if(buf) h_free(buf); return NULL; }
int co_init(void) { CHECK(_pool == NULL, "Commotion API already initialized."); _pool = h_calloc(1, sizeof(_pool)); _sockets = co_list16_create(); hattach(_sockets, _pool); DEBUG("Commotion API initialized."); return 1; error: return 0; }
int co_call(co_obj_t *connection, co_obj_t **response, const char *method, const size_t mlen, co_obj_t *request) { CHECK(method != NULL && mlen > 0 && mlen < UINT8_MAX, "Invalid method name."); CHECK(connection != NULL && IS_SOCK(connection), "Invalid connection."); co_obj_t *params = NULL, *rlist = NULL, *rtree = NULL; int retval = 0; size_t reqlen = 0, resplen = 0; char req[REQUEST_MAX]; char resp[RESPONSE_MAX]; if(request != NULL) { CHECK(IS_LIST(request), "Not a valid request."); params = request; } else { params = co_list16_create(); } co_obj_t *m = co_str8_create(method, mlen, 0); reqlen = co_request_alloc(req, sizeof(req), m, params); CHECK(((co_socket_t*)connection)->send((co_obj_t*)((co_socket_t*)connection)->fd, req, reqlen) != -1, "Send error!"); if((resplen = ((co_socket_t*)connection)->receive(connection, (co_obj_t*)((co_socket_t*)connection)->fd, resp, sizeof(resp))) > 0) { CHECK(co_list_import(&rlist, resp, resplen) > 0, "Failed to parse response."); rtree = co_list_element(rlist, 3); if(!IS_NIL(rtree)) { retval = 1; } else { rtree = co_list_element(rlist, 2); retval = 0; } if(rtree != NULL && IS_TREE(rtree)) { *response = rtree; hattach(*response, _pool); } else SENTINEL("Invalid response."); } else SENTINEL("Failed to receive data."); co_obj_free(m); if(params != request) co_obj_free(params); return retval; error: co_obj_free(m); if(params != request) co_obj_free(params); return retval; }
co_obj_t * co_connect(const char *uri, const size_t ulen) { CHECK_MEM(_sockets); CHECK(uri != NULL && ulen > 0, "Invalid URI."); co_obj_t *socket = NEW(co_socket, unix_socket); hattach(socket, _pool); CHECK((((co_socket_t*)socket)->connect(socket, uri)), "Failed to connect to commotiond at %s\n", uri); co_list_append(_sockets, socket); return socket; error: co_obj_free(socket); return NULL; }
HandlerParser *HandlerParser_create(size_t max_targets) { HandlerParser *parser = h_calloc(sizeof(HandlerParser), 1); check_mem(parser); parser->target_max = max_targets; parser->targets = h_calloc(sizeof(unsigned long), max_targets); check_mem(parser->targets); hattach(parser->targets, parser); return parser; error: return NULL; }
Heap *Heap_create(size_t capacity) { Heap *h = (Heap *)h_calloc(sizeof(Heap), 1); check_mem(h); h->capacity = capacity; h->keys = h_calloc(sizeof(int), capacity); check_mem(h->keys); hattach(h, h->keys); return h; error: Heap_destroy(h); return NULL; }
Route *Route_alloc(Route *parent, const char *name) { Route *r = h_calloc(1, sizeof(Route)); assert_mem(r); r->name = bfromcstr(name); assert_mem(r->name); r->members = Heap_create(NULL); r->children = Heap_create(Route_children_compare); // add it to the children mapping if(parent) { hattach(r, parent); Heap_add(parent->children, r); } return r; }
darray_t *darray_create(size_t element_size, size_t initial_max) { darray_t *array = h_malloc(sizeof(darray_t)); check_mem(array); array->contents = h_calloc(sizeof(void *), initial_max); check_mem(array->contents); hattach(array->contents, array); array->max = initial_max; array->end = 0; array->element_size = element_size; array->expand_rate = DEFAULT_EXPAND_RATE; return array; error: if(array) h_free(array); return NULL; }
static inline _treenode_t * _co_tree_delete_r(_treenode_t *root, _treenode_t *current, const char *key, const size_t klen, co_obj_t **value) { DEBUG("Tree current: %s", key); if (*key < current->splitchar) { current->low = _co_tree_delete_r(root, current->low, key, klen, value); } else if (*key == current->splitchar) { if (klen > 1) { // not done yet, keep going but one less current->equal = _co_tree_delete_r(root, current->equal, key+1, klen - 1, value); } else { if(current->value != NULL) { DEBUG("Found current value."); hattach(current->value, NULL); current->value->_ref--; *value = current->value; current->value = NULL; } } } else { current->high = _co_tree_delete_r(root, current->high, key, klen, value); } if(current->low == NULL && current->high == NULL && current->equal == NULL && current->value == NULL) { h_free(current); return NULL; } else return current; }
int serval_open_keyring(svl_crypto_ctx *ctx) { CHECK_ERR(ctx,"Invalid ctx"); if (ctx->keyring_len == 0) { // if no keyring specified, use default keyring CHECK(serval_path,"Default Serval path not initialized"); char keyring_path_str[PATH_MAX] = {0}; strcpy(keyring_path_str, serval_path); if (serval_path[strlen(serval_path) - 1] != '/') strcat(keyring_path_str, "/"); strcat(keyring_path_str, "serval.keyring"); // Fetching SAS keys requires setting the SERVALINSTANCE_PATH environment variable CHECK_ERR(setenv("SERVALINSTANCE_PATH", serval_path, 1) == 0, "Failed to set SERVALINSTANCE_PATH env variable"); ctx->keyring_len = strlen(keyring_path_str); ctx->keyring_path = h_malloc(ctx->keyring_len + 1); strcpy(ctx->keyring_path,keyring_path_str); hattach(ctx->keyring_path,ctx); } else { // otherwise, use specified keyring (NOTE: if keyring does not exist, it will be created) CHECK(ctx->keyring_len < PATH_MAX, "Keyring length too long"); } ctx->keyring_file = keyring_open(ctx->keyring_path); CHECK_ERR(ctx->keyring_file, "Failed to open specified keyring file"); if (keyring_enter_pin(ctx->keyring_file, KEYRING_PIN) <= 0) { // put initial identity in if we don't have any visible CHECK_ERR(keyring_seed(ctx->keyring_file) == 0, "Failed to seed keyring"); } return 1; error: return 0; }
static int Server_load_ciphers(Server *srv, bstring ssl_ciphers_val) { const struct tagbstring bstr_underscore = bsStatic("_"); const struct tagbstring bstr_dash = bsStatic("-"); struct bstrList *ssl_cipher_list = bsplit(ssl_ciphers_val, ' '); int i = 0, n = 0; int *ciphers = NULL; check(ssl_cipher_list != NULL && ssl_cipher_list->qty > 0, "Invalid cipher list, it must be separated by space ' ' characters " "and you need at least one. Or, just leave it out for defaults."); ciphers = h_calloc(ssl_cipher_list->qty + 1, sizeof(int)); check_mem(ciphers); for(i = 0; i < ssl_cipher_list->qty; i++) { bstring cipher = ssl_cipher_list->entry[i]; int id = -1; // Replace underscores (used in old ciphers) with dashes bfindreplace(cipher, &bstr_underscore, &bstr_dash, 0); // Search legacy cipher list for(n = 0; legacy_cipher_table[n].name != NULL; ++n) { if(biseqcstr(cipher, legacy_cipher_table[n].name)) { id = legacy_cipher_table[n].id; break; } } if(id != -1 && mbedtls_ssl_ciphersuite_from_id(id) != NULL) { ciphers[i] = id; } else { // Search polarssl cipher list const mbedtls_ssl_ciphersuite_t * suite = mbedtls_ssl_ciphersuite_from_string(bdata(cipher)); if (suite != NULL) ciphers[i] = suite->id; else sentinel("Unrecognized cipher: %s", bdata(cipher)); } } bstrListDestroy(ssl_cipher_list); ciphers[i] = 0; srv->ciphers = ciphers; hattach(ciphers, srv); return 0; error: if(ssl_cipher_list) bstrListDestroy(ssl_cipher_list); if(ciphers != NULL) h_free(ciphers); return -1; }
void Server_queue_push(Server *srv) { Server_queue_cleanup(); darray_push(SERVER_QUEUE, srv); hattach(srv, SERVER_QUEUE); }
int csm_update_service(csm_service_list *services, csm_service *s, csm_ctx *ctx, int validate) { if (validate) CHECK(csm_validate_fields(ctx, s), "Service doesn't validate"); // assert(s->lifetime); long lifetime = s->lifetime; // check if service is attached to service_list CHECK(co_list_contains(services->services, (co_obj_t*)container_of(s, co_service_t, service)), "Cannot update service not in service list"); // detach s->fields from s and attach to services->service_fields if (!co_list_contains(services->service_fields, s->fields)) { co_obj_t *fields = s->fields; hattach(fields, NULL); CHECK(co_list_append(services->service_fields, fields), "Failed to add service fields to service list"); } /* Create or verify signature */ if (s->signature) CHECK(csm_verify_signature(s),"Invalid signature"); else CHECK(csm_create_signature(s),"Failed to create signature"); /* Set expiration timer on the service */ #ifdef USE_UCI long def_lifetime = default_lifetime(); if (lifetime == 0 || (def_lifetime < lifetime && def_lifetime > 0)) lifetime = def_lifetime; #endif if (lifetime > 0) { struct timeval tv; avahi_elapse_time(&tv, 1000*lifetime, 0); time_t current_time = time(NULL); // create expiration event for service s->timeout = avahi_simple_poll_get(simple_poll)->timeout_new(avahi_simple_poll_get(simple_poll), &tv, _csm_expire_service, s); /* Convert lifetime period into timestamp */ if (current_time != ((time_t)-1)) { struct tm *timestr = localtime(¤t_time); timestr->tm_sec += lifetime; current_time = mktime(timestr); char *c_time_string = ctime(¤t_time); if (c_time_string) { c_time_string[strlen(c_time_string)-1] = '\0'; /* ctime adds \n to end of time string; remove it */ s->expiration = h_strdup(c_time_string); CHECK_MEM(s->expiration); service_attach(s->expiration, s); } } } // finalize service by running update handlers csm_services_commit(services); return 1; error: return 0; }