Esempio n. 1
0
/*
 * process an assertion using the hosted verifier.
 *
 * TODO: local verification
 */
VerifyResult processAssertion(request_rec *r, const char *assertion)
{
  VerifyResult res = apr_pcalloc(r->pool, sizeof(struct _VerifyResult));
  yajl_val parsed_result = NULL;

  char *assertionResult = verifyAssertionRemote(r, (char*) assertion);

  if (assertionResult) {
    char errorBuffer[256];
    parsed_result = yajl_tree_parse(assertionResult, errorBuffer, 255);
    if (!parsed_result) {
      res->errorResponse = apr_psprintf(r->pool, jsonErrorResponse,
                                       "malformed payload", errorBuffer);
      return res;
    }
  } else {
    // XXX: verifyAssertionRemote should return specific error message.
    res->errorResponse = apr_psprintf(r->pool, jsonErrorResponse,
                                     "communication error", "can't contact verification server");
    return res;
  }

  char *parsePath[2];
  parsePath[0] = "email";
  parsePath[1] = NULL;
  yajl_val foundEmail = yajl_tree_get(parsed_result, (const char**)parsePath, yajl_t_string);

  if (!foundEmail) {
    res->errorResponse = apr_pstrdup(r->pool, assertionResult);
    return res;
  }

  parsePath[0] = "issuer";
  parsePath[1] = NULL;
  yajl_val identityIssuer = yajl_tree_get(parsed_result, (const char**)parsePath, yajl_t_string);

  if (!identityIssuer) {
    res->errorResponse = apr_pstrdup(r->pool, assertionResult);
    return res;
  }

  res->verifiedEmail = apr_pstrdup(r->pool, foundEmail->u.string);
  res->identityIssuer = apr_pstrdup(r->pool, identityIssuer->u.string);

  return res;
}
Esempio n. 2
0
/*
 * process an assertion using the hosted verifier.
 *
 * TODO: local verification
 */
VerifyResult processAssertion(request_rec *r, const char *verifier_url,
                              const char *assertion)
{
  VerifyResult res = apr_pcalloc(r->pool, sizeof(struct _VerifyResult));
  json_tokener *tok = json_tokener_new();
  json_object *jobj = NULL;
  enum json_tokener_error jerr;

  char *assertionResult =
    verifyAssertionRemote(r, verifier_url, (char *) assertion);

  if (assertionResult) {
    jobj =
      json_tokener_parse_ex(tok, assertionResult, strlen(assertionResult));
    jerr = json_tokener_get_error(tok);

    if (json_tokener_success != jerr) {

      res->errorResponse = apr_psprintf(r->pool, jsonErrorResponse,
                                        "malformed payload",
                                        json_tokener_error_desc(jerr));
      json_tokener_free(tok);
      return res;
    }

    ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,
                  ERRTAG
                  "Assertion (parsed) recieved is : %s",
                  json_object_to_json_string(jobj));
  }
  else {
    // XXX: verifyAssertionRemote should return specific error message.
    res->errorResponse = apr_psprintf(r->pool, jsonErrorResponse,
                                      "communication error",
                                      "can't contact verification server");
    return res;
  }

  struct json_object_iterator it = json_object_iter_begin(jobj);
  struct json_object_iterator itEnd = json_object_iter_end(jobj);
  const char *reason = NULL;
  const char *status = "unknown";
  int success = 0;

  while (!json_object_iter_equal(&it, &itEnd)) {
    const char *key = json_object_iter_peek_name(&it);
    json_object *val = json_object_iter_peek_value(&it);

    if (strncmp("email", key, 6) == 0) {
      res->verifiedEmail = apr_pstrdup(r->pool, json_object_get_string(val));
    }
    else if (strncmp("issuer", key, 7) == 0) {
      res->identityIssuer = apr_pstrdup(r->pool, json_object_get_string(val));
    }
    else if (strncmp("audience", key, 9) == 0) {
      res->audience = apr_pstrdup(r->pool, json_object_get_string(val));
    }
    else if (strncmp("expires", key, 8) == 0) {
      apr_time_ansi_put(&res->expires, json_object_get_int64(val) / 1000);
    }
    else if (strncmp("reason", key, 7) == 0) {
      reason = json_object_get_string(val);
    }
    else if (strncmp("status", key, 7) == 0) {
      status = json_object_get_string(val);
      if (strncmp("okay", status, 5) == 0) {
        success = 1;
      }
    }
    json_object_iter_next(&it);
  }

  json_tokener_free(tok);

  // XXX: This is bad, doesn't catch multiple missing bits
  if (!res->verifiedEmail) {
    res->errorResponse = apr_pstrdup(r->pool, "Missing e-mail in assertion");
  }
  if (!res->identityIssuer) {
    res->errorResponse = apr_pstrdup(r->pool, "Missing issuer in assertion");
  }
  if (res->audience
      && strncmp(res->audience, r->server->server_hostname,
                 strlen(r->server->server_hostname)) != 0) {
    res->errorResponse =
      apr_psprintf(r->pool, "Audience %s doesn't match %s", res->audience,
                   r->server->server_hostname);
  }

  apr_time_t now = apr_time_now();
  if (res->expires && res->expires <= now) {
    char exp_time[APR_RFC822_DATE_LEN];
    apr_rfc822_date(exp_time, res->expires);
    res->errorResponse =
      apr_psprintf(r->pool, "Assertion expired on %s", exp_time);
  }

  if (!success) {
    if (reason) {
      res->errorResponse = apr_pstrdup(r->pool, reason);
    }
    else {
      res->errorResponse =
        apr_psprintf(r->pool, "Assertion failed with status '%s'", status);
    }
  }

  return res;
}