Esempio n. 1
0
File: zxidwsc.c Progetto: kiwiroy/zx
/* Called by:  zxid_call, zxid_callf_epr */
struct zx_str* zxid_call_epr(zxid_conf* cf, zxid_ses* ses, zxid_epr* epr, const char* az_cred, const char* enve)
{
  char* ret_enve;
  struct zx_str* ret;
  struct zx_e_Envelope_s* env;

  if (!cf || !ses || !enve) {
    ERR("Missing mandatory arguments ses=%p enve=%p (programmer error)", ses, enve);
    return 0;
  }

  D_INDENT("call: ");
  env = zxid_add_env_if_needed(cf, enve);
  if (!env) {
    D_DEDENT("call: ");
    return 0;
  }
  if (errmac_debug > 1) { ret = zx_easy_enc_elem_opt(cf, &env->gg);  D("sending(%.*s) enve(%s)", ret->len, ret->s, enve); }
  
  /* Call Rq-Out PDP */

  if (!zxid_query_ctlpt_pdp(cf, ses, az_cred, env, TAS3_PEP_RQ_OUT,"e:Client", cf->pepmap_rqout)) {
    D_DEDENT("call: ");
    return 0;
  }

  /* *** add usage directives */

  env = zxid_wsc_call(cf, ses, epr, env, &ret_enve);
  if (!env || env == (void*)ZXID_REDIR_OK || !env->Body) {
    ERR("Parsing return value failed %p", env);
    INFO("ret_enve(%s) len=%d", ret_enve, (int)strlen(ret_enve));
    D_DEDENT("call: ");
    if (cf->valid_opt & ZXID_VALID_OPT_SKIP_RESP_HDR) {
      ERR("WARNING! Important response security validations disabled by VALID_OPT=0x%x AND Fault occured or parsing return value failed. Pretending success anyway.", cf->valid_opt);
      return zx_dup_str(cf->ctx, ret_enve);
    }
    return 0;
  }
  if (zxid_wsc_valid_re_env(cf, ses, az_cred, env, ret_enve) != 1) {
    D_DEDENT("call: ");
    return 0;
  }

#if 1
  ret = zx_ref_str(cf->ctx, ret_enve);
#else  
  ret = zx_easy_enc_elem_opt(cf, &env->gg);
#endif
  D_DEDENT("call: ");
  return ret;
}
Esempio n. 2
0
/* Called by:  zxid_soap_call_hdr_body, zxid_wsc_call */
struct zx_root_s* zxid_soap_call_raw(zxid_conf* cf, struct zx_str* url, struct zx_e_Envelope_s* env, char** ret_enve)
{
#ifdef USE_CURL
  struct zx_root_s* r;
  struct zx_str* ret;
  struct zx_str* ss;
  char soap_action_buf[1024];
  char* soap_act;
  const char* env_start;

  ss = zx_easy_enc_elem_opt(cf, &env->gg);
  DD("ss(%.*s) len=%d", ss->len, ss->s, ss->len);

  if (cf->soap_action_hdr && strcmp(cf->soap_action_hdr,"#inhibit")) {
    if (!strcmp(cf->soap_action_hdr,"#same")) {
      if (env->Header && env->Header->Action && ZX_GET_CONTENT_S(env->Header->Action)) {
	snprintf(soap_action_buf,sizeof(soap_action_buf), "SOAPAction: \"%.*s\"", ZX_GET_CONTENT_LEN(env->Header->Action), ZX_GET_CONTENT_S(env->Header->Action));
	soap_action_buf[sizeof(soap_action_buf)-1] = 0;
	soap_act = soap_action_buf;
	D("SOAPaction(%s)", soap_action_buf);
      } else {
	ERR("e:Envelope/e:Headers/a:Action SOAP header is malformed %p", env->Header);
      }
    } else {
      snprintf(soap_action_buf,sizeof(soap_action_buf), "SOAPAction: \"%s\"", cf->soap_action_hdr);
      soap_action_buf[sizeof(soap_action_buf)-1] = 0;
      soap_act = soap_action_buf;
    }
  } else
    soap_act = 0;
  
  ret = zxid_http_cli(cf, url->len, url->s, ss->len, ss->s, cf->wsc_soap_content_type, soap_act, 0);
  zx_str_free(cf->ctx, ss);
  if (ret_enve)
    *ret_enve = ret?ret->s:0;
  if (!ret)
    return 0;
  
  env_start = zxid_locate_soap_Envelope(ret->s);
  if (!env_start) {
    ERR("SOAP response does not have Envelope element url(%.*s)", url->len, url->s);
    D_XML_BLOB(cf, "NO ENVELOPE SOAP RESPONSE", ret->len, ret->s);
    ZX_FREE(cf->ctx, ret);
    return 0;
  }

  cf->ctx->top1 = 1;  /* Stop parsing after first toplevel <e:Envelope> */
  r = zx_dec_zx_root(cf->ctx, ret->len - (env_start - ret->s), env_start, "soap_call");
  if (!r || !r->Envelope || !r->Envelope->Body) {
    ERR("Failed to parse SOAP response url(%.*s)", url->len, url->s);
    D_XML_BLOB(cf, "BAD SOAP RESPONSE", ret->len, ret->s);
    ZX_FREE(cf->ctx, ret);
    return 0;
  }
  return r;
#else
  ERR("This copy of zxid was compiled to NOT use libcurl. SOAP calls (such as Artifact profile and WSC) are not supported. Add -DUSE_CURL (make ENA_CURL=1) and recompile. %d", 0);
  return 0;
#endif
}
Esempio n. 3
0
File: zxidmk.c Progetto: kiwiroy/zx
/* Called by:  zxid_add_fed_tok2epr, zxid_imreq, zxid_mk_saml_resp */
struct zx_sa_EncryptedAssertion_s* zxid_mk_enc_a7n(zxid_conf* cf, struct zx_elem_s* father, zxid_a7n* a7n, zxid_entity* meta)
{
    struct zx_xenc_EncryptedData_s* ed;
    struct zx_str* ss;
    struct zx_sa_EncryptedAssertion_s* enc_a7n;
    if (!cf || !a7n) {
        ERR("NULL arguments (programmer error) %p", cf);
        return 0;
    }
    if (!meta || !meta->enc_cert) {
        ERR("Missing destination metadata or the metadata does not have encryption certificate. %p", meta);
        return 0;
    }
    ss = zx_easy_enc_elem_opt(cf, &a7n->gg);
    if (!ss) {
        ERR("Failed to XML serialize assertion %p", a7n);
        return 0;
    }
    enc_a7n = zx_NEW_sa_EncryptedAssertion(cf->ctx, father);
    if (cf->enckey_opt & 0x20) {
        /* Nested EncryptedKey approach (Shibboleth early 2010) */
        ed = zxenc_pubkey_enc(cf, ss, 0, meta->enc_cert, "40", 0);
    } else {
        /* RetrievalMethod approach */
        ed = zxenc_pubkey_enc(cf, ss, &enc_a7n->EncryptedKey, meta->enc_cert, "39", meta);
    }
    if (!ed) {
        ERR("Failed to encrypt assertion %p (this could be due to problems with encryption certificate of the destination or destination's metadata; you may be able to work around this problem by manipulating POST_A7N_ENC or DI_A7N_ENC config option, but consider the security implication)", a7n);
        return 0;
    }
    ZX_ADD_KID(enc_a7n, EncryptedData, ed);
    zx_str_free(cf->ctx, ss);
    return enc_a7n;
}
Esempio n. 4
0
File: zxcot.c Progetto: gitpan/zxid
/* Called by:  zxcot_main */
static int zxid_addmd(zxid_conf* cf, char* mdurl, int dry_run, const char* dcot)
{
  int got;
  fdtype fd;
  char* p;
  zxid_entity* ent;
  struct zx_str* ss;
  
  if (mdurl) {
    ent = zxid_get_meta(cf, mdurl);
  } else {
    read_all_fd(fdstdin, buf, sizeof(buf)-1, &got);
    buf[got] = 0;
    p = buf;
    ent = zxid_parse_meta(cf, &p, buf+got);
  }
  
  if (!ent) {
    ERR("***** Parsing metadata failed %d", 0);
    return 1;
  }

  for (; ent; ent = ent->n) {
    ss = zx_easy_enc_elem_opt(cf, &ent->ed->gg);
    if (!ss)
      return 2;
  
    if (dry_run) {
      write_all_fd(fdstdout, ss->s, ss->len);
      zx_str_free(cf->ctx, ss);
      if (verbose>1)
	printf("\n\nDry run ent(%s) to %s%s\n", ent->eid, dcot, ent->sha1_name);
      continue;
    }
    if (verbose)
      printf("Writing ent(%s) to %s%s\n", ent->eid, dcot, ent->sha1_name);
  
    fd = open_fd_from_path(O_CREAT | O_WRONLY | O_TRUNC, 0666, "zxcot -a", 1,
			   "%s%s", dcot, ent->sha1_name);
    if (fd == BADFD) {
      perror("open metadata for writing metadata to cache");
      ERR("Failed to open file for writing: sha1_name(%s) to metadata cache", ent->sha1_name);
      zx_str_free(cf->ctx, ss);
      return 1;
    }
    
    write_all_fd(fd, ss->s, ss->len);
    zx_str_free(cf->ctx, ss);
    close_file(fd, (const char*)__FUNCTION__);
  }
  return 0;
}
Esempio n. 5
0
/* Called by:  zxid_idp_soap_dispatch x2, zxid_sp_soap_dispatch x8 */
int zxid_soap_cgi_resp_body(zxid_conf* cf, zxid_ses* ses, struct zx_e_Body_s* body)
{
  struct zx_e_Envelope_s* env = zx_NEW_e_Envelope(cf->ctx,0);
  struct zx_str* ss;
  struct zx_str* logpath;
  env->Body = body;
  zx_add_kid(&env->gg, &body->gg);
  env->Header = zx_NEW_e_Header(cf->ctx, &env->gg);

  if (ses && ses->curflt) {
    D("Detected curflt, abandoning previous Body content. %d", 0);
    /* *** LEAK: Should free previous body content */
    env->Body = (struct zx_e_Body_s*)zx_replace_kid(&env->gg, (struct zx_elem_s*)zx_NEW_e_Body(cf->ctx, 0));
    ZX_ADD_KID(env->Body, Fault, ses->curflt);
  }
  
  zxid_wsf_decor(cf, ses, env, 1, 0);
  ss = zx_easy_enc_elem_opt(cf, &env->gg);

  if (cf->log_issue_msg) {
    logpath = zxlog_path(cf, ses->issuer, ss, ZXLOG_ISSUE_DIR, ZXLOG_WIR_KIND, 1);
    if (logpath) {
      if (zxlog_dup_check(cf, logpath, "cgi_resp")) {
	ERR("Duplicate wire msg(%.*s) (Simple Sign)", ss->len, ss->s);
#if 0
	if (cf->dup_msg_fatal) {
	  ERR("FATAL (by configuration): Duplicate wire msg(%.*s) (cgi_resp)", ss->len, ss->s);
	  zxlog_blob(cf, 1, logpath, ss, "cgi_resp dup");
	  zx_str_free(cf->ctx, logpath);
	  return 0;
	}
#endif
      }
      zxlog_blob(cf, 1, logpath, ss, "cgi_resp");
      zxlogwsp(cf, ses, "K", "CGIRESP", 0, "logpath(%.*s)", logpath->len, logpath->s);
      zx_str_free(cf->ctx, logpath);
    }
  }
  
  if (errmac_debug & ERRMAC_INOUT) INFO("SOAP_RESP(%.*s)", ss->len, ss->s);
  fprintf(stdout, "CONTENT-TYPE: text/xml" CRLF "CONTENT-LENGTH: %d" CRLF2 "%.*s", ss->len, ss->len, ss->s);
  fflush(stdout);
  D("^^^^^^^^^^^^^^ Done (%d chars returned) ^^^^^^^^^^^^^", ss->len);
  return ZXID_REDIR_OK;
}
Esempio n. 6
0
File: zxidwsc.c Progetto: kiwiroy/zx
/* Called by:  ws_validations, zxid_wsc_prepare_callf */
struct zx_str* zxid_wsc_prepare_call(zxid_conf* cf, zxid_ses* ses, zxid_epr* epr, const char* az_cred, const char* enve)
{
  struct zx_str* ret;
  struct zx_e_Envelope_s* env;

  if (!cf || !ses || !enve) {
    ERR("Missing mandatory arguments ses=%p (programmer error)", ses);
    return 0;
  }
  D_INDENT("prep: ");
  env = zxid_add_env_if_needed(cf, enve);
  if (!env) {
    D_DEDENT("prep: ");
    return 0;
  }
  
  /* Call Rq-Out PDP */
  
  if (!zxid_query_ctlpt_pdp(cf, ses, az_cred, env, TAS3_PEP_RQ_OUT,"e:Client", cf->pepmap_rqout)) {
    D_DEDENT("prep: ");
    return 0;
  }
  
  /* *** add usage directives */

  if (!zxid_wsc_prep(cf, ses, epr, env)) {
    D_DEDENT("prep: ");
    return 0;
  }
  if (!zxid_wsc_prep_secmech(cf, ses, epr, env)) {
    D_DEDENT("prep: ");
    return 0;
  }
  ses->wsc_msgid = zx_str_to_c(cf->ctx, ZX_GET_CONTENT(env->Header->MessageID));

  ret = zx_easy_enc_elem_opt(cf, &env->gg);
  D_DEDENT("prep: ");
  return ret;
}
Esempio n. 7
0
File: zxidmk.c Progetto: kiwiroy/zx
/* Called by:  a7n_test, zxid_sp_mni_redir, zxid_sp_mni_soap */
struct zx_sp_ManageNameIDRequest_s* zxid_mk_mni(zxid_conf* cf, zxid_nid* nid, struct zx_str* new_nym, zxid_entity* idp_meta)
{
    struct zx_str* ss;
    struct zx_xenc_EncryptedKey_s* ek;
    struct zx_elem_s* newid;
    struct zx_sp_ManageNameIDRequest_s* r = zx_NEW_sp_ManageNameIDRequest(cf->ctx,0);
    r->Issuer = zxid_my_issuer(cf, &r->gg);
    r->ID = zxid_mk_id_attr(cf, &r->gg, zx_ID_ATTR, "R", ZXID_ID_BITS);
    r->Version = zx_ref_attr(cf->ctx, &r->gg, zx_Version_ATTR, SAML2_VERSION);
    r->IssueInstant = zxid_date_time_attr(cf, &r->gg, zx_IssueInstant_ATTR, time(0));
    if (cf->nameid_enc && idp_meta) {
        r->EncryptedID = zxid_mk_enc_id(cf, &r->gg, nid, idp_meta);
        if (new_nym && new_nym->len) {
            newid = zx_new_str_elem(cf->ctx, 0, zx_sp_NewID_ELEM, new_nym);
            ss = zx_easy_enc_elem_opt(cf, newid);
            r->NewEncryptedID = zx_NEW_sp_NewEncryptedID(cf->ctx, &r->gg);
            if (cf->enckey_opt & 0x20) {
                /* Nested EncryptedKey approach (Shibboleth early 2010) */
                ZX_ADD_KID(r->NewEncryptedID, EncryptedData, zxenc_pubkey_enc(cf, ss, 0, idp_meta->enc_cert, "43",0));
            } else {
                /* RetrievalMethod approach */
                ZX_ADD_KID(r->NewEncryptedID, EncryptedData, zxenc_pubkey_enc(cf, ss, &ek, idp_meta->enc_cert, "39", idp_meta));
                ZX_ADD_KID(r->NewEncryptedID, EncryptedKey, ek);
                zx_reverse_elem_lists(&r->NewEncryptedID->gg);
            }
            zx_str_free(cf->ctx, ss);
            zx_free_elem(cf->ctx, newid, 0);
        } else
            r->Terminate = zx_new_str_elem(cf->ctx, &r->gg, zx_sp_Terminate_ELEM, 0);
    } else {
        r->NameID = nid;
        if (new_nym && new_nym->len)
            r->NewID = zx_new_str_elem(cf->ctx, &r->gg, zx_sp_NewID_ELEM, new_nym);
        else
            r->Terminate = zx_new_str_elem(cf->ctx, &r->gg, zx_sp_Terminate_ELEM, 0);
    }
    return r;
}
Esempio n. 8
0
File: zxcot.c Progetto: gitpan/zxid
/* Called by:  zxcot_main */
static int zxid_reg_svc(zxid_conf* cf, int bs_reg, int dry_run, const char* ddimd, const char* duid)
{
  char sha1_name[28];
  char path[ZXID_MAX_BUF];
  int got;
  fdtype fd;
  struct zx_root_s* r;
  zxid_epr* epr;
  struct zx_str* ss;
  struct zx_str* tt;
  
  read_all_fd(fdstdin, buf, sizeof(buf)-1, &got);  /* Read EPR */
  buf[got] = 0;
  
  r = zx_dec_zx_root(cf->ctx, got, buf, "cot reg_svc");
  if (!r || !r->EndpointReference) {
    ERR("Failed to parse <EndpointReference> buf(%.*s)", got, buf);
    return 1;
  }
  epr = r->EndpointReference;
  if (!ZX_SIMPLE_ELEM_CHK(epr->Address)) {
    ERR("<EndpointReference> MUST have <Address> element buf(%.*s)", got, buf);
    return 1;
  }
  if (!epr->Metadata) {
    ERR("<EndpointReference> MUST have <Metadata> element buf(%.*s)", got, buf);
    return 1;
  }
  if (!ZX_SIMPLE_ELEM_CHK(epr->Metadata->ProviderID)) {
    ERR("<EndpointReference> MUST have <Metadata> with <ProviderID> element buf(%.*s)", got, buf);
    return 1;
  }
  if (!epr->Metadata->ServiceType) {
    ERR("<EndpointReference> MUST have <ServiceType> element buf(%.*s)", got, buf);
    return 1;
  }

  /* *** possibly add something here and double check the required fields are available. */

  ss = zx_easy_enc_elem_opt(cf, &epr->gg);
  if (!ss)
    return 2;
  
#if 0
  // *** wrong
  tt = ZX_GET_CONTENT(epr->Metadata->ProviderID);
#else
  tt = ZX_GET_CONTENT(epr->Metadata->ServiceType);
#endif
  got = MIN(tt->len, sizeof(path)-1);
  memcpy(path, tt?tt->s:"", got);
  path[got] = 0;
  zxid_fold_svc(path, got);

  sha1_safe_base64(sha1_name, ss->len, ss->s);
  sha1_name[27] = 0;

  if (verbose)
    fprintf(stderr, "Registering metadata in %s%s,%s\n", ddimd, path, sha1_name);
  
  if (dry_run) {
    if (verbose)
      fprintf(stderr, "Register EPR dry run. Would have written to path(%s%s,%s). "
	      "You may also want to\n"
	      "  touch %s.all/.bs/%s,%s\n\n", ddimd, path, sha1_name, uiddir, path, sha1_name);
    fflush(stdin);
    write_all_fd(fdstdout, ss->s, ss->len);
    zx_str_free(cf->ctx, ss);
    return 0;
  }
  
  D("Register EPR path(%s%s,%s) in discovery metadata.", ddimd, path, sha1_name);
  fd = open_fd_from_path(O_CREAT | O_WRONLY | O_TRUNC, 0666, "zxcot -b", 1,
			 "%s%s,%s", ddimd, path, sha1_name);
  if (fd == BADFD) {
    perror("open epr for registering");
    ERR("Failed to open file for writing: sha1_name(%s,%s) to service registration", path, sha1_name);
    zx_str_free(cf->ctx, ss);
    return 1;
  }
  
  write_all_fd(fd, ss->s, ss->len);
  zx_str_free(cf->ctx, ss);
  close_file(fd, (const char*)__FUNCTION__);

  if (bs_reg) {
    if (verbose)
      fprintf(stderr, "Activating bootstrap %s.all/.bs/%s,%s", duid, path, sha1_name);

    if (!dryrun) {
      fd = open_fd_from_path(O_CREAT | O_WRONLY | O_TRUNC, 0666, "zxcot -bs", 1,
			     "%s.all/.bs/%s,%s", duid, path, sha1_name);
      if (fd == BADFD) {
	perror("open epr for bootstrap activation");
	ERR("Failed to open file for writing: sha1_name(%s,%s) to bootstrap activation", path, sha1_name);
	return 1;
      }
    
      write_all_fd(fd, "", 0);
      close_file(fd, (const char*)__FUNCTION__);
    }
  } else {
    D("You may also want to activate bootstrap by\n  touch %s.all/.bs/%s,%s", duid, path, sha1_name);
  }
  return 0;
}
Esempio n. 9
0
File: zxidwsc.c Progetto: kiwiroy/zx
/* Called by:  zxid_call_epr, zxid_wsc_prepare_call, zxid_wsc_valid_resp, zxid_wsp_decorate */
struct zx_e_Envelope_s* zxid_add_env_if_needed(zxid_conf* cf, const char* enve)
{
  struct zx_e_Envelope_s* env;
  struct zx_root_s* r;
  struct zx_str* ret;
  r = zx_dec_zx_root(cf->ctx, strlen(enve), enve, "add_env");
  if (!r) {
    ERR("Malformed XML enve(%s)", enve);
    return 0;
  }
  /* N.B. The lists are in reverse order after the parse. */
  env = r->Envelope;
  if (env) {
    /* N.B. Maintain the forward order, Header is 1st element of Envelope->kids. */
    if (!env->Header) {
      D("ENV EXISTS, no Header %p %p", env, env->Body);
      if (!env->Body)
	env->Body = zx_NEW_e_Body(cf->ctx, &env->gg);
      env->Header = zx_NEW_e_Header(cf->ctx, &env->gg);
    } else {
      D("ENV EXISTS w/Header %p %p", env, env->Body);
      if (!env->Body)
	env->Body = zx_NEW_e_Body(cf->ctx, &env->gg);
    }
  } else if (r->Body) {
    D("HERE2 BODY EXISTS %p %p", env, r->Header);
    env = zx_NEW_e_Envelope(cf->ctx,0);
    ZX_ADD_KID(env, Body, r->Body);
    if (r->Header)
      ZX_ADD_KID(env, Header, r->Header);
    else
      env->Header = zx_NEW_e_Header(cf->ctx, &env->gg);
    /* N.B. Maintain the Forward order: Header is now first element of Envelope->kids. */
  } else { /* Resort to stringwise attempt to add envelope. */
    ZX_FREE(cf->ctx, r);
    if (!memcmp(enve, "<?xml ", sizeof("<?xml ")-1)) {  /* Ignore common, but unnecessary decl. */
      for (enve += sizeof("<?xml "); *enve && !(enve[0] == '?' && enve[1] == '>'); ++enve) ;
      if (*enve)
	enve += 2;
    }
    /* Must be just payload */
    enve = zx_alloc_sprintf(cf->ctx, 0, "%s%s%s", zx_env_body_open, enve, zx_env_body_close);
    D("HERE3 ADD ENV(%s)", enve);
    r = zx_dec_zx_root(cf->ctx, strlen(enve), enve, "add_env2");
    if (!r) {
      ERR("Malformed XML enve(%s)", enve);
      return 0;
    }
    env = r->Envelope;
#if 0
    ret=zx_easy_enc_elem_opt(cf,&env->gg); INFO("ser(%.*s) enve(%s)",ret->len,ret->s,enve); // ***
    /* The lists are in reverse order after the parse. But since this is a text parse,
     * wireorder is maintained, thus giving forward order, afterall. */
    zx_reverse_elem_lists(&env->gg);
#endif
  }
  ZX_FREE(cf->ctx, r);
  if (env->gg.kids != &env->Header->gg) {
    D("ENV Fixing Header-Body ordering %p", env);
    env->gg.kids = &env->Header->gg;
    env->Header->gg.g.n = &env->Body->gg.g;
    env->Body->gg.g.n = 0;
  }
  ret = zx_easy_enc_elem_opt(cf,&env->gg); INFO("ser(%.*s) enve(%s)",ret->len,ret->s,enve); // ***
  if (!env)
    ERR("No <e:Envelope> found in input argument. enve(%s)", enve);
  /* DO NOT: zx_reverse_elem_lists(&env->gg);  * ensure forward order for external use */
  return env;
}