예제 #1
0
static int do_redirect(request_rec *request, am_status_t status,
		       const am_map_t advice_map, const char *original_url)
{
    boolean_t allocated;
    char *redirect_url;
    int apache_status;

    redirect_url = am_web_get_redirect_url(status, advice_map, original_url,
                                          &allocated);
    if (redirect_url != NULL) {
	apache_status = HTTP_MOVED_TEMPORARILY;
	am_web_log_debug("do_redirect() policy status = %s, redirection URL "
			"is %s", am_status_to_string(status), redirect_url);

	ap_custom_response(request, apache_status, redirect_url);
	if (B_TRUE==allocated) {
	    am_web_free_memory(redirect_url);
	}
    } else {
	apache_status = HTTP_FORBIDDEN;
	am_web_log_debug("do_redirect() policy status = %s, returning %d",
			am_status_to_string(status), apache_status);
    }

    return apache_status;
}
예제 #2
0
static int psx_auth_fail(request_rec *r, qEnvApache *renv)
{
// this is kinda wrong.... but for now we keep it....
	
	if (!r->header_only) {
		CStr resp = renv->GetCtx()->Eval("http-noauth");
		if (!resp.IsEmpty()) {
			qStrBuf bufin(resp);
			qStrBuf bufout;
			renv->GetCtx()->ParseTry(&bufin, &bufout);
			ap_custom_response(r, HTTP_UNAUTHORIZED, bufout.GetBuffer());
		}
	}

	if (!ap_auth_type(r)) {
		ap_table_setn(r->err_headers_out,
			  r->proxyreq ? "Proxy-Authenticate" : "WWW-Authenticate",
			  ap_pstrcat(r->pool, "Basic realm=\"", ap_auth_name(r), "\"",
				  NULL));
	} else {
		ap_note_basic_auth_failure(r);
	}
	renv->Free();

	ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, AP2STATUS r, "returning unauthorized: %d, status : %d", HTTP_UNAUTHORIZED, r->status);
	return HTTP_UNAUTHORIZED;
}
예제 #3
0
파일: agent.c 프로젝트: JonathanFu/OpenAM-1
static am_status_t set_custom_response(am_request_t *rq, const char *text, const char *cont_type) {
    request_rec *r = (request_rec *) (rq != NULL ? rq->ctx : NULL);
    if (r == NULL || !ISVALID(text)) return AM_EINVAL;
    if (rq->status == AM_INTERNAL_REDIRECT) {
        ap_internal_redirect(text, r);
        rq->status = AM_DONE;
    } else if (rq->status == AM_REDIRECT) {
        apr_table_add(r->headers_out, "Location", text);
        ap_custom_response(r, HTTP_MOVED_TEMPORARILY, text);
    } else {
        if (rq->status == AM_PDP_DONE) {
            request_rec *sr = ap_sub_req_method_uri(am_method_num_to_str(rq->method),
                    rq->post_data_url, r, NULL);

            sr->headers_in = r->headers_in;
            sr->notes = r->notes;

            am_log_debug(rq->instance_id, "set_custom_response(): issuing sub-request %s to %s",
                    sr->method, rq->post_data_url);

            ap_run_sub_req(sr);
            ap_destroy_sub_req(sr);
            rq->status = AM_DONE;

        } else {
            size_t tl = strlen(text);
            if (ISVALID(cont_type)) {
                ap_set_content_type(r, cont_type);
            }
            ap_set_content_length(r, tl);
            ap_rwrite(text, (int) tl, r);
            ap_custom_response(r,
                    am_status_value(rq->status == AM_SUCCESS ||
                    rq->status == AM_DONE ? AM_SUCCESS : rq->status), text);
            ap_rflush(r);
        }
    }
    am_log_info(rq->instance_id, "set_custom_response(): status: %s", am_strerror(rq->status));
    return AM_SUCCESS;
}
//
// Main functions.
//
static int check_auth_handler(request_rec *rec)
{
  auth_conf*  conf = (auth_conf*)ap_get_module_config(rec->per_dir_config, &auth_httprequest_module);
  context     ctx;
  CURLcode    ret;
  const char* secret, *url;
  int threaded_mpm;
  int code=0;

  AP_LOG_DEBUG(rec, "Incomming %s URI=%s", __FUNCTION__, conf->url);

  // Check requires.
  if(!is_auth_httprequest_required(rec))  return DECLINED;  // Not required.
  if(!conf->url[0]) return OK;  // URL is empty.

  AP_LOG_DEBUG(rec, "  %s %s", rec->method, rec->uri);

  // Enable to dump authorize result.
  if(conf->dump==ENABLED) {
    ap_add_output_filter(DUMP_AUTH_RESULT, apr_pmemdup(rec->pool, &ctx, sizeof(ctx)), rec, rec->connection);
  }

  // Skip nested request.
  secret = apr_table_get(rec->headers_in, SECRET);
  if(secret) {
    AP_LOG_DEBUG(rec, "  %s: %s", SECRET, secret);
    if(strstr(secret, conf->secret)) {
      AP_LOG_DEBUG(rec, "Check config. Nested request.");
      rec->user = apr_pstrdup(rec->pool, conf->url);  
      return OK;
    }
  }

  // Initialize callback-context.
  ctx.curl = curl_easy_init();
  ctx.rec  = rec;
  ctx.headers = NULL;
  ctx.status = 0;

  // Initialize libcurl for MPM.
  ap_mpm_query(AP_MPMQ_IS_THREADED, &threaded_mpm);
  curl_easy_setopt(ctx.curl, CURLOPT_NOSIGNAL, threaded_mpm);

  // Bypass request headers, set 'X-Auth-HttpRequest-URI'.
  apr_table_do(each_headers_proc, &ctx, rec->headers_in, NULL);
  each_headers_proc(&ctx, X_AUTH_HTTPREQUEST_URL, rec->uri);
  each_headers_proc(&ctx, X_AUTH_HTTPREQUEST_METHOD, rec->method);
  if(conf->secret[0]) each_headers_proc(&ctx, SECRET, conf->secret);

  // Setup URL to bypass response headers and body.
  curl_easy_setopt(ctx.curl, CURLOPT_URL, url = apr_psprintf(rec->pool, conf->url, rec->uri));
  curl_easy_setopt(ctx.curl, CURLOPT_CUSTOMREQUEST, "HEAD");
  curl_easy_setopt(ctx.curl, CURLOPT_HTTPHEADER, ctx.headers);
  curl_easy_setopt(ctx.curl, CURLOPT_USERAGENT, apr_psprintf(rec->pool, "%s %s", VERSION, curl_version()));
  curl_easy_setopt(ctx.curl, CURLOPT_WRITEHEADER, &ctx);
  curl_easy_setopt(ctx.curl, CURLOPT_HEADERFUNCTION, curl_header_proc);

  // Request.
  ret = curl_easy_perform(ctx.curl);
  curl_easy_getinfo(ctx.curl, CURLINFO_RESPONSE_CODE, &code);
  AP_LOG_DEBUG(rec, "curl result(%d) %d", ret, code);

  // Cleanup.
  curl_slist_free_all(ctx.headers);
  curl_easy_cleanup(ctx.curl);

  // Result.
  if(ret==0) {
    if(is_break_status(code)) {
      // Break request, set custom response.
      if(conf->errdoc) {
        char* msg = apr_psprintf(rec->pool, conf->errdoc, code);
        AP_LOG_DEBUG(rec, "Custom response: %s", msg);
        ap_custom_response(rec, code, msg);
      }
      return code;
    }

    if(is_authorized_status(code)) {
      // Set 'REMOTE_USER' and 'AUTH_TYPE'.
      rec->user = apr_pstrdup(rec->pool, conf->url); // => ENV['REMOTE_USER']
      AP_LOG_DEBUG(rec, "== AUTHORIZED(%s, %s)", rec->ap_auth_type, rec->user);
    } else {
      AP_LOG_DEBUG(rec, "== PATH THRU");
    }
  } else {
    static const char* const ce[8] = {
      "", "E_PROTOCOL", "E_INIT", "E_MALFORMAT",
      "E_MALFORMAT_USER", "E_PROXY", "E_HOST", "E_CONNECT",
    };
    AP_LOG_WARN(rec, "Check config. http resuest failed [%s] %s(CURLcode = %d)", url, ((ret<8)? ce[ret]: ce[0]), ret);
    
  }

  return OK;
}
예제 #5
0
/**************************************************
 * Authentication phase
 *
 * - If AuthType != Persona, do nothing
 * - Handle POSTed assertions ("null" -> logout)
 * - If we have a cookie, set up user context
 **************************************************/
static int Auth_persona_check_cookie(request_rec *r)
{
  char *szCookieValue=NULL;
  char *szRemoteIP=NULL;
  const char *assertion=NULL;

  if (!persona_authn_active(r)) {
    return DECLINED;
  }
  ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, r, ERRTAG "Auth_persona_check_cookie");

  // We'll trade you a valid assertion for a session cookie!
  // this is a programmatic XHR request.

  persona_config_t *conf = ap_get_module_config(r->server->module_config, &authnz_persona_module);
  assertion = apr_table_get(r->headers_in, PERSONA_ASSERTION_HEADER);
  if (assertion) {

    if (strcmp(r->method, "POST")) {
      r->status = HTTP_METHOD_NOT_ALLOWED;
      ap_set_content_type(r, "application/json");
      const char *error = "{\"status\": \"failure\", \"reason\":"
                          "\"login must be performed with POST\"}";
      ap_rwrite(error, strlen(error), r);
      return DONE;
    }

    if (!strcmp(assertion, "null")) {
      sendResetCookie(r);
      r->status = HTTP_OK;
      const char *status = "{\"status\": \"okay\"}";
      ap_set_content_type(r, "application/json");
      ap_rwrite(status, strlen(status), r);
      return DONE;
    }

    VerifyResult res = processAssertion(r, assertion);
    ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO, 0,r,ERRTAG
                  "Assertion received '%s'", assertion);

    if (res->verifiedEmail) {
      ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, ERRTAG
                    "email '%s' verified, vouched for by issuer '%s'",
                    res->verifiedEmail, res->identityIssuer);
      Cookie cookie = apr_pcalloc(r->pool, sizeof(struct _Cookie));
      cookie->verifiedEmail = res->verifiedEmail;
      cookie->identityIssuer = res->identityIssuer;
      cookie->created = apr_time_sec(r->request_time);
      sendSignedCookie(r, conf->secret, cookie);
      return DONE;
    } else {
      assert(res->errorResponse != NULL);

      r->status = HTTP_INTERNAL_SERVER_ERROR;
      ap_set_content_type(r, "application/json");
      ap_rwrite(res->errorResponse, strlen(res->errorResponse), r);

      // upon assertion verification failure we return JSON explaining why
      return DONE;
    }
  }

  // handle logout via LogoutPath hit before letting valid cookies through
  if (conf->logout_path->len && !strncmp(r->uri, conf->logout_path->data, conf->logout_path->len)) {
    return process_logout(r);
  }

  // if there's a valid cookie, allow the user through
  szCookieValue = extractCookie(r, conf->secret, PERSONA_COOKIE_NAME);

  Cookie cookie = NULL;
  if (szCookieValue &&
      (cookie = validateCookie(r, conf->secret, szCookieValue))) {
    r->user = (char *) cookie->verifiedEmail;
    apr_table_setn(r->notes, PERSONA_ISSUER_NOTE, cookie->identityIssuer);
    apr_table_setn(r->subprocess_env, "REMOTE_USER", cookie->verifiedEmail);
    ap_log_rerror(APLOG_MARK, APLOG_INFO|APLOG_NOERRNO, 0, r, ERRTAG "Valid auth cookie found, passthrough");
    ap_custom_response(r, 401, (const char*) build_error_html);
    ap_custom_response(r, 403, (const char*) build_error_html);
    return OK;
  }

  ap_log_rerror(APLOG_MARK, APLOG_INFO|APLOG_NOERRNO, 0, r, ERRTAG "Persona cookie not found; not authorized! RemoteIP:%s",szRemoteIP);
  r->status = HTTP_UNAUTHORIZED;
  ap_set_content_type(r, "text/html");
  ap_rwrite(src_signin_html, sizeof(src_signin_html), r);
  ap_rprintf(r, "var loggedInUser = undefined;\n");
  ap_rwrite(PERSONA_END_PAGE, sizeof(PERSONA_END_PAGE), r);
  return DONE;
}