validate_token_exp, private
This commit is contained in:
parent
af936cb46e
commit
4720b6f233
90
src/http.c
90
src/http.c
@ -115,13 +115,19 @@ http_process_headers(struct http_transaction *ta)
|
||||
if (!strcasecmp(field_name, "Content-Length")) {
|
||||
ta->req_content_len = atoi(field_value);
|
||||
}
|
||||
|
||||
|
||||
ta->valid_token = false; // special case?
|
||||
/* Handle other headers here. Both field_value and field_name
|
||||
* are zero-terminated strings.
|
||||
*/
|
||||
if (!strcasecmp(field_name, "Cookie")) {
|
||||
if (!strcasecmp(field_name, "Cookie")) {
|
||||
if (field_value == NULL)
|
||||
return false;
|
||||
ta->token = field_value + 11; // + 11 gets rid of "auth_token=" heading.
|
||||
|
||||
ta->valid_token = validate_token_exp(ta, ta->token);
|
||||
|
||||
ta->cookie = bufio_ptr2offset(ta->client->bufio, field_name);
|
||||
ta->token = field_value; // fix this! needs to be just auth_token part
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -294,22 +300,31 @@ guess_mime_type(char *filename)
|
||||
}
|
||||
|
||||
/* Check a token is not expired. */
|
||||
static bool validate_token_exp(struct http_transaction *ta, char* grants) {
|
||||
|
||||
char *gs = calloc(strlen(grants) + 1, sizeof(char));
|
||||
memcpy(gs, grants, strlen(grants) + 1);
|
||||
char *end;
|
||||
char *expire = strtok_r(gs, "{\":, }", &end);
|
||||
while (expire != NULL) {
|
||||
if (!strcasecmp(expire, "exp")) {
|
||||
int exp = atoi(strtok_r(NULL, "{\":, }", &end));
|
||||
if (time(NULL) >= exp) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
bool validate_token_exp(struct http_transaction *ta, char* token) {
|
||||
jwt_t* cookie;
|
||||
|
||||
// Decode token.
|
||||
int rc = jwt_decode(&cookie, ta->token, (unsigned char *)NEVER_EMBED_A_SECRET_IN_CODE, strlen(NEVER_EMBED_A_SECRET_IN_CODE));
|
||||
if (rc)
|
||||
return send_error(ta, HTTP_OK, "{}");
|
||||
|
||||
// Get claim (formatted grants).
|
||||
char* grants = jwt_get_grants_json(cookie, NULL);
|
||||
if (grants == NULL)
|
||||
return send_error(ta, HTTP_OK, "{}");
|
||||
|
||||
// Get expiration time.
|
||||
json_error_t error;
|
||||
json_t *jgrants = json_loadb(grants, strlen(grants), 0, &error);
|
||||
json_int_t exp, iat;
|
||||
const char *sub;
|
||||
json_unpack(jgrants, "{s:I, s:I, s:s}", "exp", &exp, "iat", &iat, "sub", &sub);
|
||||
|
||||
// Check expiration time.
|
||||
if (time(NULL) >= exp)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Handle HTTP transaction for static files. */
|
||||
@ -322,7 +337,7 @@ handle_static_asset(struct http_transaction *ta, char *basedir)
|
||||
// The code below is vulnerable to an attack. Can you see
|
||||
// which? Fix it to avoid indirect object reference (IDOR) attacks.
|
||||
snprintf(fname, sizeof fname, "%s%s", basedir, req_path);
|
||||
|
||||
|
||||
char *endptr;
|
||||
char *p = calloc(strlen(fname) + 1, sizeof(char));
|
||||
memcpy(p, fname, strlen(fname) + 1);
|
||||
@ -340,6 +355,7 @@ handle_static_asset(struct http_transaction *ta, char *basedir)
|
||||
snprintf(fname, sizeof fname, "%s%s", server_root, "/index.html");
|
||||
}
|
||||
|
||||
|
||||
if (access(fname, R_OK)) {
|
||||
if (errno == EACCES)
|
||||
return send_error(ta, HTTP_PERMISSION_DENIED, "Permission denied.");
|
||||
@ -436,10 +452,12 @@ post_handle_login(struct http_transaction *ta)
|
||||
// Add Set-Cookie header.
|
||||
http_add_header(&ta->resp_headers, "Set-Cookie", "auth_token=%s; Path=%s; Max-Age=%d; HttpOnly", token, "/", max_age);
|
||||
|
||||
//
|
||||
// Get claim (formatted grants).
|
||||
char *grants = jwt_get_grants_json(cookie, NULL);
|
||||
buffer_appends(&ta->resp_body, grants);
|
||||
buffer_appends(&ta->resp_body, CRLF);
|
||||
|
||||
// Send claim.
|
||||
ta->resp_status = HTTP_OK;
|
||||
return send_response(ta);
|
||||
}
|
||||
@ -451,29 +469,14 @@ post_handle_login(struct http_transaction *ta)
|
||||
static bool get_handle_login(struct http_transaction *ta) {
|
||||
http_add_header(&ta->resp_headers, "Content-Type", "application/json");
|
||||
|
||||
if (ta->token == NULL) {
|
||||
return send_error(ta, HTTP_OK, "{}");
|
||||
}
|
||||
|
||||
jwt_t *cookie;
|
||||
int rc = jwt_decode(&cookie, ta->token, (unsigned char *) "key", 3);
|
||||
if (rc) {
|
||||
return send_error(ta, HTTP_OK, "{}\n");
|
||||
}
|
||||
/* Send claims */
|
||||
char *grants = jwt_get_grants_json(cookie, NULL);
|
||||
if (grants == NULL) {
|
||||
return send_error(ta, HTTP_OK, "{}\n");
|
||||
}
|
||||
|
||||
if (!validate_token_exp(ta, grants)) {
|
||||
if (!ta->valid_token) {
|
||||
return send_error(ta, HTTP_PERMISSION_DENIED,"Forbidden.\n");
|
||||
}
|
||||
|
||||
char *json = buffer_ensure_capacity(&ta->resp_body, MAX_HEADER_LEN);
|
||||
int len = snprintf(json, strlen(grants) + 2, "%s\n", grants);
|
||||
int length = len > MAX_HEADER_LEN ? MAX_HEADER_LEN - 1 : len;
|
||||
ta->resp_body.len += length;
|
||||
//~ char *json = buffer_ensure_capacity(&ta->resp_body, MAX_HEADER_LEN);
|
||||
//~ int len = snprintf(json, strlen(grants) + 2, "%s\n", grants);
|
||||
//~ int length = len > MAX_HEADER_LEN ? MAX_HEADER_LEN - 1 : len;
|
||||
//~ ta->resp_body.len += length;
|
||||
|
||||
return send_response(ta);
|
||||
}
|
||||
@ -595,7 +598,10 @@ http_setup_client(struct http_client *self, struct bufio *bufio)
|
||||
static bool
|
||||
handle_private(struct http_transaction *ta)
|
||||
{
|
||||
return false;
|
||||
if (ta->valid_token) {
|
||||
return handle_static_asset(ta, server_root);
|
||||
}
|
||||
return send_error(ta, HTTP_PERMISSION_DENIED,"Forbidden.\n");
|
||||
}
|
||||
|
||||
/* Handle a single HTTP transaction. Returns true on success. */
|
||||
|
@ -42,6 +42,7 @@ struct http_transaction {
|
||||
|
||||
size_t cookie; // offset to cookie header
|
||||
char *token; // authentication token
|
||||
bool valid_token;
|
||||
|
||||
/* response related fields */
|
||||
enum http_response_status resp_status;
|
||||
@ -58,5 +59,6 @@ struct http_client {
|
||||
void http_setup_client(struct http_client *, struct bufio *bufio);
|
||||
bool http_handle_transaction(struct http_client *);
|
||||
void http_add_header(buffer_t * resp, char* key, char* fmt, ...);
|
||||
bool validate_token_exp(struct http_transaction *ta, char* token);
|
||||
|
||||
#endif /* _HTTP_H */
|
||||
|
Loading…
x
Reference in New Issue
Block a user