| 734 | } |
| 735 | |
| 736 | sq_callback_result_t Webserver::BeginRequestCallback(struct sq_connection* connection, |
| 737 | struct sq_request_info* request_info) { |
| 738 | if (VLOG_IS_ON(4)) { |
| 739 | VLOG(4) << request_info->request_method << " " << request_info->uri << " " |
| 740 | << request_info->http_version; |
| 741 | for (int i = 0; i < request_info->num_headers; ++i) { |
| 742 | VLOG(4) << " " << request_info->http_headers[i].name << ": " |
| 743 | << request_info->http_headers[i].value; |
| 744 | } |
| 745 | } |
| 746 | |
| 747 | if (strncmp("OPTIONS", request_info->request_method, 7) == 0) { |
| 748 | // Let Squeasel deal with the request. OPTIONS requests should not require |
| 749 | // authentication, so do this before doing SPNEGO. |
| 750 | return SQ_CONTINUE_HANDLING; |
| 751 | } |
| 752 | |
| 753 | vector<string> response_headers; |
| 754 | bool authenticated = false; |
| 755 | // Random value from cookie that we'll also use as a csrf_token to implement the |
| 756 | // "Double Submit Cookie" and custom header (X-Requested-By) patterns for preventing |
| 757 | // cross-site request forgery (CSRF). |
| 758 | std::string cookie_rand_value; |
| 759 | // With JWTs we can skip CSRF protection because browsers won't send "Authorization: |
| 760 | // Bearer" headers automatically. |
| 761 | bool check_csrf_protection = true; |
| 762 | // Flags if we have a valid cookie to test for CSRF. |
| 763 | bool cookie_authenticated = false; |
| 764 | |
| 765 | // Try authenticating with JWT token first, if enabled. |
| 766 | if (use_jwt_ || use_oauth_) { |
| 767 | const char* auth_value = nullptr; |
| 768 | const char* value = sq_get_header(connection, "Authorization"); |
| 769 | if (value != nullptr) auth_value = StripLeadingWhiteSpace(value); |
| 770 | // Check Authorization header with the Bearer authentication scheme as: |
| 771 | // Authorization: Bearer <token> |
| 772 | // A well-formed JWT consists of three concatenated Base64url-encoded strings, |
| 773 | // separated by dots (.). |
| 774 | if (auth_value != nullptr && strncasecmp(auth_value, "Bearer ", 7) == 0 |
| 775 | && strchr(auth_value, '.') != nullptr) { |
| 776 | string bearer_token= string(auth_value + 7); |
| 777 | StripWhiteSpace(&bearer_token); |
| 778 | if (!bearer_token.empty()) { |
| 779 | if (use_jwt_) { |
| 780 | if (JWTTokenAuth(bearer_token, connection, request_info)) { |
| 781 | total_jwt_token_auth_success_->Increment(1); |
| 782 | authenticated = true; |
| 783 | check_csrf_protection = false; |
| 784 | // TODO: cookies are not added, but are not needed right now |
| 785 | } |
| 786 | } |
| 787 | if (!authenticated && use_oauth_) { |
| 788 | if (OAuthTokenAuth(bearer_token, connection, request_info)) { |
| 789 | total_oauth_token_auth_success_->Increment(1); |
| 790 | authenticated = true; |
| 791 | check_csrf_protection = false; |
| 792 | // TODO: cookies are not added, but are not needed right now |
| 793 | } |
no test coverage detected