int session_new (http_t *h) { char *id_str; int rc; session_t *session; session = http_malloc(h, sizeof(*session)); if (!session) { return (-1); } uuid_generate(session->id); id_str = http_malloc(h, b64urlencsize(sizeof(session->id))); if (!id_str) { return (-1); } b64urlenc(&session->id, id_str, sizeof(session->id)); rc = http_set_cookie(h, COOKIES_SESSION, id_str); if (rc == -1) { return (rc); } rc = sess_db_put(h, session); if (rc == -1) { return (rc); } session_update_data(session); h->session = session; return (0); }
char * http_uri_decode_query_component(const char *str, size_t sz) { const char *iptr; char *component, *optr; size_t str_length, ilen; str_length = strlen(str); component = http_malloc(str_length + 1); iptr = str; ilen = sz; optr = component; while (ilen > 0) { if (*iptr == '%') { int d1, d2; if (ilen < 3) { http_set_error("truncated escape sequence"); goto error; } if (http_read_hex_digit((unsigned char)iptr[1], &d1) == -1 || http_read_hex_digit((unsigned char)iptr[2], &d2) == -1) { http_set_error("invalid escape sequence"); goto error; } *optr++ = (d1 << 4) | d2; iptr += 3; ilen -= 3; } else if (*iptr == '+') { *optr++ = ' '; iptr++; ilen--; } else { *optr++ = *iptr++; ilen--; } } *optr = '\0'; return component; error: http_free(component); return NULL; }
void http_uri_encode_query_component(const char *str, struct bf_buffer *buf) { static const char *hex_digits = "0123456789abcdef"; const char *iptr; char *optr; char *tmp; size_t len; /* Compute the size of the encoded string */ len = 0; iptr = str; while (*iptr != '\0') { if (http_uri_is_query_component_char((unsigned char)*iptr)) { len++; } else { len += 3; /* '%xx' */ } iptr++; } /* Encode the string */ tmp = http_malloc(len); iptr = str; optr = tmp; while (*iptr != '\0') { if (http_uri_is_query_component_char((unsigned char)*iptr)) { *optr++ = *iptr; } else if (*iptr == ' ') { *optr++ = '+'; } else { unsigned char c; c = (unsigned char)*iptr; *optr++ = '%'; *optr++ = hex_digits[c >> 4]; *optr++ = hex_digits[c & 0xf]; } iptr++; } bf_buffer_add(buf, tmp, len); http_free(tmp); }
void http_route_base_add_route(struct http_route_base *base, struct http_route *route) { assert(*route->path == '/'); if (base->nb_routes == 0) { base->routes_sz = 1; base->routes = http_malloc(sizeof(struct http_route *)); } else { size_t nsz; base->routes_sz *= 2; nsz = base->routes_sz * sizeof(struct http_route *); base->routes = http_realloc(base->routes, nsz); } base->routes[base->nb_routes++] = route; base->sorted = false; }
void http_uri_add_query_parameter(struct http_uri *uri, const char *name, const char *value) { struct http_query_parameter *parameters, *parameter; if (uri->nb_query_parameters == 0) { parameters = http_malloc(sizeof(struct http_query_parameter)); } else { size_t nsz; nsz = (uri->nb_query_parameters + 1) * sizeof(struct http_query_parameter); parameters = http_realloc(uri->query_parameters, nsz); } parameter = parameters + uri->nb_query_parameters; parameter->name = http_strdup(name); parameter->value = http_strdup(value); uri->query_parameters = parameters; uri->nb_query_parameters++; }
int session_get (http_t *h) { const ssr_t *id_str; int rc; session_t *session; id_str = http_get_cookie(h, COOKIES_SESSION); if ((!id_str) || (b64urldecsize_ssr(id_str) != sizeof(session->id))) { return (-1); } session = http_malloc(h, sizeof(*session)); b64urldec_ssr(id_str, &session->id); rc = sess_db_get(h, session); if (rc != 0) { return (-1); } session_update_data(session); h->session = session; return (0); }
int http_route_components_parse(const char *path, struct http_route_component **pcomponents, size_t *p_nb_components) { struct http_route_component *components; size_t nb_components; size_t components_sz; const char *ptr, *start; size_t toklen; components = NULL; nb_components = 0; components_sz = 0; ptr = path; if (*ptr != '/') { http_set_error("path is not absolute"); goto error; } ptr++; /* skip '/' */ start = ptr; if (*ptr == '\0') { /* Root path */ *pcomponents = NULL; *p_nb_components = 0; return 0; } for (;;) { if (*ptr == '/' || *ptr == '\0') { struct http_route_component component; toklen = (size_t)(ptr - start); if (toklen == 0) { http_set_error("empty component in path"); goto error; } if (memcmp(start, "*", toklen) == 0) { component.type = HTTP_ROUTE_COMPONENT_WILDCARD; } else if (*start == ':') { component.type = HTTP_ROUTE_COMPONENT_NAMED; start++; toklen--; if (toklen == 0) { http_set_error("empty named variable in path"); goto error; } } else { component.type = HTTP_ROUTE_COMPONENT_STRING; } if (component.type == HTTP_ROUTE_COMPONENT_WILDCARD) { component.value = NULL; } else { component.value = http_strndup(start, toklen); if (!component.value) goto error; } if (nb_components == 0) { components_sz = 1; components = http_malloc(sizeof(struct http_route_component)); } else if (nb_components + 1 > components_sz) { size_t nsz; components_sz *= 2; nsz = components_sz * sizeof(struct http_route_component); components = http_realloc(components, nsz); } components[nb_components++] = component; if (*ptr == '\0') break; ptr++; start = ptr; } else { ptr++; } } *pcomponents = components; *p_nb_components = nb_components; return 0; error: http_route_components_free(components, nb_components); return -1; }
static int dir_server_verify_signature (http_t *h, dir_server_t *server, const ssr_t **reason) { RSA *pkey; SHA512_CTX sh; char *der; size_t der_size; unsigned char hash[SHA512_DIGEST_LENGTH]; unsigned char *signature; size_t sig_size; const unsigned char *p; int rc; char time_str[128]; int time_str_len; der_size = b64urldecsize_ssr(&server->public_key); if (!der_size) { DEBUG("b64urldecsize_ssr(&server->public_key);"); *reason = http_400; return (-1); } der = http_malloc(h, der_size); if (!der) { WARN("http_malloc(): %zu", der_size); return (-1); } rc = b64urldec_ssr(&server->public_key, der); if (rc == -1) { DEBUG("b64urldec_ssr(&server->public_key, der);"); *reason = http_400; return (-1); } p = (unsigned char *)der; pkey = d2i_RSA_PUBKEY(NULL, &p, der_size); if (pkey == NULL) { WARN("d2i_RSA_PUBKEY(): %.*s", (int)server->public_key.size, server->public_key.data); *reason = http_403; return (-1); } snprintf(time_str, sizeof(time_str), "%"PRIu64, server->time); time_str_len = strlen(time_str); SHA512_Init(&sh); SHA512_Update(&sh, server->public_key.data, server->public_key.size); SHA512_Update(&sh, server->address.data, server->address.size); SHA512_Update(&sh, time_str, time_str_len); SHA512_Final(hash, &sh); sig_size = b64urldecsize_ssr(&server->signature); signature = http_malloc(h, sig_size); b64urldec_ssr(&server->signature, signature); if (RSA_verify(NID_sha512, hash, SHA512_DIGEST_LENGTH, signature, sig_size, pkey) != 1) { WARN("RSA_verify(): " "PublicKey='%.*s', " "Address='%.*s', " "Signature='%.*s', " "Time='%"PRIu64"'", (int)server->public_key.size, server->public_key.data, (int)server->address.size, server->address.data, (int)server->signature.size, server->signature.data, server->time); RSA_free(pkey); return (-1); } RSA_free(pkey); return (0); }