Beispiel #1
0
static int tr_msg_decode_one_server(json_t *jsrvr, TID_SRVR_BLK *srvr) 
{
  json_t *jsrvr_addr = NULL;
  json_t *jsrvr_kn = NULL;
  json_t *jsrvr_dh = NULL;
  json_t *jsrvr_expire = NULL;

  if (jsrvr == NULL)
    return -1;


  if ((NULL == (jsrvr_addr = json_object_get(jsrvr, "server_addr"))) ||
      (NULL == (jsrvr_kn = json_object_get(jsrvr, "key_name"))) ||
      (NULL == (jsrvr_dh = json_object_get(jsrvr, "server_dh")))) {
    tr_notice("tr_msg_decode_one_server(): Error parsing required fields.");
    return -1;
  }
  
  /* TBD -- handle IPv6 Addresses */
  inet_aton(json_string_value(jsrvr_addr), &(srvr->aaa_server_addr));
  srvr->key_name = tr_new_name((char *)json_string_value(jsrvr_kn));
  srvr->aaa_server_dh = tr_msg_decode_dh(jsrvr_dh);
  srvr->path = json_object_get(jsrvr, "path");
  jsrvr_expire = json_object_get(jsrvr, "key_expiration");
  if (jsrvr_expire && json_is_string(jsrvr_expire)) {
    if (!g_time_val_from_iso8601(json_string_value(jsrvr_expire),
				 &srvr->key_expiration))
      tr_notice("Key expiration %s cannot be parsed", json_string_value(jsrvr_expire));
  }
  
  return 0;
}
Beispiel #2
0
static int tids_handle_request(TIDS_INSTANCE *tids, TID_REQ *req, TID_RESP *resp)
{
  int rc=-1;

  /* Check that this is a valid TID Request.  If not, send an error return. */
  if ((!req) ||
      (!(req->rp_realm)) ||
      (!(req->realm)) ||
      (!(req->comm))) {
    tr_notice("tids_handle_request(): Not a valid TID Request.");
    tid_resp_set_result(resp, TID_ERROR);
    tid_resp_set_err_msg(resp, tr_new_name("Bad request format"));
    return -1;
  }

  tr_debug("tids_handle_request: adding self to req path.");
  tid_req_add_path(req, tids->hostname, tids->tids_port);

  /* Call the caller's request handler */
  /* TBD -- Handle different error returns/msgs */
  if (0 > (rc = (*tids->req_handler)(tids, req, resp, tids->cookie))) {
    /* set-up an error response */
    tr_debug("tids_handle_request: req_handler returned error.");
    tid_resp_set_result(resp, TID_ERROR);
    if (!tid_resp_get_err_msg(resp))	/* Use msg set by handler, if any */
      tid_resp_set_err_msg(resp, tr_new_name("Internal processing error"));
  } else {
    /* set-up a success response */
    tr_debug("tids_handle_request: req_handler returned success.");
    tid_resp_set_result(resp, TID_SUCCESS);
    resp->err_msg = NULL;	/* No error msg on successful return */
  }

  return rc;
}
Beispiel #3
0
/**
 * Encode/send a response
 *
 * Part of the public interface
 *
 * @param tids not actually used, but kept for ABI compatibility
 * @param req
 * @param resp
 * @return
 */
int tids_send_response (TIDS_INSTANCE *tids, TID_REQ *req, TID_RESP *resp)
{
  int err;
  char *resp_buf;

  if ((!tids) || (!req) || (!resp)) {
    tr_debug("tids_send_response: Invalid parameters.");
    return -1;
  }

  /* Never send a second response if we already sent one. */
  if (req->resp_sent)
    return 0;

  resp_buf = tids_encode_response(NULL, NULL);
  if (resp_buf == NULL) {
    tr_err("tids_send_response: Error encoding json response.");
    tr_audit_req(req);
    return -1;
  }

  tr_debug("tids_send_response: Encoded response: %s", resp_buf);

  /* If external logging is enabled, fire off a message */
  /* TODO Can be moved to end once segfault in gsscon_write_encrypted_token fixed */
  tr_audit_resp(resp);

  /* Send the response over the connection */
  err = gsscon_write_encrypted_token (req->conn, req->gssctx, resp_buf,
                                            strlen(resp_buf) + 1);
  if (err) {
    tr_notice("tids_send_response: Error sending response over connection.");
    tr_audit_req(req);
    return -1;
  }

  /* indicate that a response has been sent for this request */
  req->resp_sent = 1;

  free(resp_buf);

  return 0;
}
Beispiel #4
0
/**
 * Handle a request/response connection
 *
 * Authorizes/authenticates the connection, then reads a response, passes that to a
 * callback to get a response, sends that, then returns.
 *
 * @param conn connection file descriptor
 * @param acceptor_service acceptor name to present
 * @param acceptor_hostname acceptor hostname to present
 * @param auth_cb callback for authorization
 * @param auth_cookie cookie for the auth_cb
 * @param req_cb callback to handle the request and produce the response
 * @param req_cookie cookie for the req_cb
 */
TR_GSS_RC tr_gss_handle_connection(int conn,
                                   const char *acceptor_service,
                                   const char *acceptor_hostname,
                                   TR_GSS_AUTH_FN auth_cb,
                                   void *auth_cookie,
                                   TR_GSS_HANDLE_REQ_FN req_cb,
                                   void *req_cookie)
{
  TALLOC_CTX *tmp_ctx = talloc_new(NULL);
  gss_ctx_id_t gssctx = GSS_C_NO_CONTEXT;
  char *req_str = NULL;
  size_t req_len = 0;
  TR_MSG *req_msg = NULL;
  TR_MSG *resp_msg = NULL;
  char *resp_str = NULL;
  TR_GSS_RC rc = TR_GSS_ERROR;

  tr_debug("tr_gss_handle_connection: Attempting to accept %s connection on fd %d.",
           acceptor_service, conn);

  if (tr_gss_auth_connection(conn,
                             acceptor_service,
                             acceptor_hostname,
                             &gssctx,
                             auth_cb,
                             auth_cookie)) {
    tr_notice("tr_gss_handle_connection: Error authorizing connection.");
    goto cleanup;
  }

  tr_debug("tr_gss_handle_connection: Connection authorized");

  // TODO: should there be a timeout on this?
  do {
    /* continue until an error breaks us out */
    // try to read a request
    req_str = tr_gss_read_req(tmp_ctx, conn, gssctx);

    if (req_str == NULL) {
      // an error occurred, give up
      tr_notice("tr_gss_handle_connection: Error reading request");
      goto cleanup;
    }

    req_len = strlen(req_str);

    /* If we got no characters, we will loop again. Free the empty response for the next loop. */
    if (req_len == 0)
      talloc_free(req_str);

  } while (req_len == 0);

  /* Decode the request */
  req_msg = tr_msg_decode(tmp_ctx, req_str, req_len);
  if (req_msg == NULL) {
    tr_notice("tr_gss_handle_connection: Error decoding response");
    goto cleanup;
  }

  /* Hand off the request for processing and get the response */
  rc = req_cb(tmp_ctx, req_msg, &resp_msg, req_cookie);

  if (resp_msg == NULL) {
    // no response, clean up
    goto cleanup;
  }

  /* Encode the response */
  resp_str = tr_msg_encode(tmp_ctx, resp_msg);
  if (resp_str == NULL) {
    /* We apparently can't encode a response, so just return */
    tr_err("tr_gss_handle_connection: Error encoding response");
    goto cleanup;
  }

  // send the response
  if (tr_gss_write_resp(conn, gssctx, resp_str)) {
    tr_err("tr_gss_handle_connection: Error writing response");
    goto cleanup;
  }

  /* we successfully sent a response */
  rc = TR_GSS_SUCCESS;

cleanup:
  talloc_free(tmp_ctx);
  return rc;
}
Beispiel #5
0
static TID_REQ *tr_msg_decode_tidreq(json_t *jreq)
{
  TID_REQ *treq = NULL;
  json_t *jrp_realm = NULL;
  json_t *jrealm = NULL;
  json_t *jcomm = NULL;
  json_t *jorig_coi = NULL;
  json_t *jdh = NULL;
  json_t *jpath = NULL;
  json_t *jexpire_interval = NULL;

  if (!(treq =tid_req_new())) {
    tr_crit("tr_msg_decode_tidreq(): Error allocating TID_REQ structure.");
    return NULL;
  }
 
  /* store required fields from request */
  if ((NULL == (jrp_realm = json_object_get(jreq, "rp_realm"))) ||
      (NULL == (jrealm = json_object_get(jreq, "target_realm"))) ||
      (NULL == (jcomm = json_object_get(jreq, "community")))) {
    tr_notice("tr_msg_decode(): Error parsing required fields.");
    tid_req_free(treq);
    return NULL;
  }

  jpath = json_object_get(jreq, "path");
  jexpire_interval = json_object_get(jreq, "expiration_interval");

  treq->rp_realm = tr_new_name((char *)json_string_value(jrp_realm));
  treq->realm = tr_new_name((char *)json_string_value(jrealm));
  treq->comm = tr_new_name((char *)json_string_value(jcomm));

  /* Get DH Info from the request */
  if (NULL == (jdh = json_object_get(jreq, "dh_info"))) {
    tr_debug("tr_msg_decode(): Error parsing dh_info.");
    tid_req_free(treq);
    return NULL;
  }
  treq->tidc_dh = tr_msg_decode_dh(jdh);

  /* store optional "orig_coi" field */
  if (NULL != (jorig_coi = json_object_get(jreq, "orig_coi"))) {
    treq->orig_coi = tr_new_name((char *)json_string_value(jorig_coi));
  }

  treq->cons = (TR_CONSTRAINT_SET *) json_object_get(jreq, "constraints");
  if (treq->cons) {
    if (!tr_constraint_set_validate(treq->cons)) {
      tr_debug("Constraint set validation failed");
    tid_req_free(treq);
    return NULL;
    }
    json_incref((json_t *) treq->cons);
    tid_req_cleanup_json(treq, (json_t *) treq->cons);
  }
  if (jpath) {
    json_incref(jpath);
    treq->path = jpath;
    tid_req_cleanup_json(treq, jpath);
  }
  if (jexpire_interval)
    treq->expiration_interval = json_integer_value(jexpire_interval);
  
  return treq;
}