cint_t cherokee_buffer_cmp (cherokee_buffer_t *buf, char *txt, cuint_t txt_len) { cherokee_buffer_t tmp; cherokee_buffer_fake (&tmp, txt, txt_len); return cherokee_buffer_cmp_buf (buf, &tmp); }
ret_t cherokee_validator_digest_check (cherokee_validator_t *validator, cherokee_buffer_t *passwd, cherokee_connection_t *conn) { ret_t ret; int re = -1; cherokee_buffer_t a1 = CHEROKEE_BUF_INIT; cherokee_buffer_t buf = CHEROKEE_BUF_INIT; /* Sanity check */ if (cherokee_buffer_is_empty (&validator->user) || cherokee_buffer_is_empty (&validator->realm)) return ret_deny; /* Build A1 */ cherokee_buffer_ensure_size (&a1, validator->user.len + 1 + validator->realm.len + 1 + passwd->len); cherokee_buffer_add_buffer (&a1, &validator->user); cherokee_buffer_add_str (&a1, ":"); cherokee_buffer_add_buffer (&a1, &validator->realm); cherokee_buffer_add_str (&a1, ":"); cherokee_buffer_add_buffer (&a1, passwd); cherokee_buffer_encode_md5_digest (&a1); /* Build a possible response */ ret = cherokee_validator_digest_response (validator, a1.buf, &buf, conn); if (unlikely(ret != ret_ok)) goto go_out; /* Compare and return */ re = cherokee_buffer_cmp_buf (&conn->validator->response, &buf); go_out: cherokee_buffer_mrproper (&a1); cherokee_buffer_mrproper (&buf); return (re == 0) ? ret_ok : ret_deny; }
static ret_t validate_digest (cherokee_validator_htdigest_t *htdigest, cherokee_connection_t *conn, cherokee_buffer_t *file) { int re; ret_t ret; char *user = NULL; char *realm = NULL; char *passwd = NULL; cherokee_buffer_t buf = CHEROKEE_BUF_INIT; /* Sanity check */ if (cherokee_buffer_is_empty (&conn->validator->response)) return ret_error; /* Extact the right entry information */ ret = extract_user_entry (file, conn->validator->user.buf, &user, &realm, &passwd); if (unlikely(ret != ret_ok)) return ret; /* Build the hash: * In this case passwd is the HA1 hash: md5(user:realm:passwd) */ ret = cherokee_validator_digest_response (VALIDATOR(htdigest), passwd, &buf, conn); if (unlikely(ret != ret_ok)) goto go_out; /* Compare and return */ re = cherokee_buffer_cmp_buf (&conn->validator->response, &buf); go_out: cherokee_buffer_mrproper (&buf); return (re == 0) ? ret_ok : ret_deny; }
static ret_t match (cherokee_rule_directory_t *rule, cherokee_connection_t *conn, cherokee_config_entry_t *ret_conf) { UNUSED(ret_conf); /* Not the same lenght */ if (conn->request.len < rule->directory.len) { TRACE(ENTRIES, "Match directory: rule=%s req=%s: (shorter) ret_not_found\n", rule->directory.buf, conn->request.buf); return ret_not_found; } /* Does not match */ if (strncmp (rule->directory.buf, conn->request.buf, rule->directory.len) != 0) { TRACE(ENTRIES, "Match directory: rule=%s req=%s: (str) ret_not_found\n", rule->directory.buf, conn->request.buf); return ret_not_found; } /* Does not match: same begining, but a longer name */ if ((conn->request.len > rule->directory.len) && (conn->request.buf[rule->directory.len] != '/')) { TRACE(ENTRIES, "Match directory: rule=%s req=%s: (str) ret_not_found\n", rule->directory.buf, conn->request.buf); return ret_not_found; } /* If the request is exactly the directory entry, and it * doesn't end with a slash, it must be redirected. Eg: * * web_directory = "/blog" * request = "/blog" * * It must be redirected to "/blog/" */ if ((conn->request.len > 1) && (cherokee_buffer_end_char (&conn->request) != '/') && (cherokee_buffer_cmp_buf (&conn->request, &rule->directory) == 0)) { cherokee_buffer_add_str (&conn->request, "/"); cherokee_connection_set_redirect (conn, &conn->request); cherokee_buffer_drop_ending (&conn->request, 1); TRACE(ENTRIES, "Had to redirect to: %s\n", conn->redirect.buf); conn->error_code = http_moved_permanently; return ret_error; } /* Copy the web directory property */ if ((RULE(rule)->config.handler_new_func != NULL) || (RULE(rule)->config.document_root != NULL)) { cherokee_buffer_clean (&conn->web_directory); cherokee_buffer_add_buffer (&conn->web_directory, &rule->directory); } TRACE(ENTRIES, "Match! rule=%s req=%s web_directory=%s: ret_ok\n", rule->directory.buf, conn->request.buf, conn->web_directory.buf); return ret_ok; }
ret_t cherokee_validator_plain_check (cherokee_validator_plain_t *plain, cherokee_connection_t *conn) { int re; ret_t ret; const char *p; const char *end; cherokee_buffer_t *fpass; cherokee_buffer_t file = CHEROKEE_BUF_INIT; cherokee_buffer_t buser = CHEROKEE_BUF_INIT; cherokee_buffer_t bpass = CHEROKEE_BUF_INIT; /* Sanity check */ if (unlikely ((conn->validator == NULL) || cherokee_buffer_is_empty(&conn->validator->user))) { return ret_error; } /* Get the full path to the file */ ret = cherokee_validator_file_get_full_path (VFILE(plain), conn, &fpass, &CONN_THREAD(conn)->tmp_buf1); if (ret != ret_ok) { ret = ret_error; goto out; } /* Read its contents */ ret = cherokee_buffer_read_file (&file, fpass->buf); if (ret != ret_ok) { ret = ret_error; goto out; } if (! cherokee_buffer_is_ending(&file, '\n')) cherokee_buffer_add_str (&file, "\n"); p = file.buf; end = file.buf + file.len; while (p < end) { char *eol; char *colon; /* Look for the EOL */ eol = strchr (p, '\n'); if (eol == NULL) { ret = ret_ok; goto out; } *eol = '\0'; /* Skip comments */ if (p[0] == '#') goto next; colon = strchr (p, ':'); if (colon == NULL) { goto next; } /* Is it the right user? */ cherokee_buffer_clean (&buser); cherokee_buffer_add (&buser, p, colon - p); re = cherokee_buffer_cmp_buf (&buser, &conn->validator->user); if (re != 0) goto next; /* Check the password */ cherokee_buffer_clean (&bpass); cherokee_buffer_add (&bpass, colon+1, eol - (colon+1)); switch (conn->req_auth_type) { case http_auth_basic: /* Empty password */ if (cherokee_buffer_is_empty (&bpass) && cherokee_buffer_is_empty (&conn->validator->passwd)) { ret = ret_ok; goto out; } /* Check the passwd */ re = cherokee_buffer_cmp_buf (&bpass, &conn->validator->passwd); if (re != 0) ret = ret_deny; goto out; case http_auth_digest: ret = cherokee_validator_digest_check (VALIDATOR(plain), &bpass, conn); goto out; default: SHOULDNT_HAPPEN; } /* A user entry has been tested and failed */ ret = ret_deny; goto out; next: p = eol + 1; /* Reached the end without success */ if (p >= end) { ret = ret_deny; goto out; } } out: cherokee_buffer_mrproper (&file); cherokee_buffer_mrproper (&buser); cherokee_buffer_mrproper (&bpass); return ret; }