void* fable_accept_shmem_pipe(void* handle, int direction) { if(direction == FABLE_DIRECTION_DUPLEX) { fprintf(stderr, "shmem_pipe transport can't do duplex yet\n"); return 0; } struct shmem_pipe_handle* listen_handle = (struct shmem_pipe_handle*)handle; void* new_unix_handle = fable_accept_unixdomain(&listen_handle->fd, FABLE_DIRECTION_DUPLEX); if(!new_unix_handle) return 0; int conn_fd = *((int*)new_unix_handle); free(new_unix_handle); // TODO: these are blocking operations, even if the Fable handle is nonblocking. int shmem_fd = unix_recv_fd(conn_fd); if(shmem_fd == -1) { int save_errno = errno; close(conn_fd); errno = save_errno; return 0; } int seg_pages; read_all_fd(conn_fd, (char*)&seg_pages, sizeof(int)); void* ring_addr = mmap(NULL, PAGE_SIZE * seg_pages, PROT_READ|PROT_WRITE, MAP_SHARED, shmem_fd, 0); if(ring_addr == MAP_FAILED) { int save_errno = errno; close(shmem_fd); close(conn_fd); errno = save_errno; return 0; } struct shmem_pipe_handle_conn* new_handle = (struct shmem_pipe_handle_conn*)malloc(sizeof(struct shmem_pipe_handle_conn)); if(!new_handle) { close(shmem_fd); close(conn_fd); errno = ENOMEM; return 0; } memset(new_handle, 0, sizeof(struct shmem_pipe_handle_conn)); new_handle->base.fd = conn_fd; new_handle->base.type = SHMEMPIPE_HANDLE_CONN; new_handle->ring = ring_addr; new_handle->ring_pages = seg_pages; new_handle->direction = direction; if(direction == FABLE_DIRECTION_SEND) shmem_pipe_init_send(new_handle); // Otherwise memset-0 is enough return new_handle; }
/* 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; }
/* 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; }
/* Called by: */ int zxumacall_main(int argc, char** argv, char** env) { int siz, got, n; char* p; struct zx_str* ss; zxid_ses* ses; zxid_entity* idp_meta; zxid_epr* epr; strncpy(errmac_instance, CC_CYNY("\tzxuma"), sizeof(errmac_instance)); cf = zxid_new_conf_to_cf(0); opt(&argc, &argv, &env); if (dynclireg) { zxumacall_dynclireg_client(cf); return 0; } if (rsrc_name) { if (!client_secret) zxumacall_dynclireg_client(cf); zxumacall_rsrcreg_client(cf); return 0; } if (sid) { D("Existing session sesid(%s)", sid); ses = zxid_fetch_ses(cf, sid); if (!ses) { ERR("Session not found or error in session sesid(%s)", sid); return 1; } } else { D("Obtain session from authentication service(%s)", idp); idp_meta = zxid_get_ent(cf, idp); if (!idp_meta) { ERR("IdP metadata not found and could not be fetched. idp(%s)", idp); return 1; } for (p = user; !ONE_OF_2(*p, ':', 0); ++p) ; if (*p) *p++ = 0; ses = zxid_as_call(cf, idp_meta, user, p); if (!ses) { ERR("Login using Authentication Service failed idp(%s)", idp); return 1; } INFO("Logged in. NameID(%s) Session in %s" ZXID_SES_DIR "%s", ses->nid, cf->cpath, ses->sid); } if (listses) return zxid_print_session(cf, ses); if (im_to) { D("ID-WSF Map to identity at eid(%s)", im_to); zxid_map_identity_token(cf, ses, im_to, 0); //printf("%.*s\n", ZX_GET_CONTENT_LEN(nameid), ZX_GET_CONTENT_S(nameid)); return 0; } if (nidmap_to) { D("SAML Map to identity at eid(%s)", nidmap_to); zxid_nidmap_identity_token(cf, ses, nidmap_to, 0); //printf("%.*s\n", ZX_GET_CONTENT_LEN(nameid), ZX_GET_CONTENT_S(nameid)); return 0; } if (di_only) { D("Discover only. svctype(%s), dindex=%d", STRNULLCHK(svc), din); epr = zxid_get_epr(cf, ses, svc, url, di, 0 /*action*/, din); if (!epr) { ERR("Discovery failed to find any epr of service type(%s)", STRNULLCHK(svc)); return 3; } for (din = 1; ;++din) { epr = zxid_get_epr(cf, ses, svc, url, di, 0 /*action*/, din); if (!epr) break; printf("%d. Found epr for service type(%s)\n", din, STRNULLCHK(svc)); ss = zxid_get_epr_desc(cf, epr); printf(" Description: %.*s\n", ss?ss->len:0, ss?ss->s:""); ss = zxid_get_epr_address(cf, epr); printf(" EPURL: %.*s\n", ss?ss->len:0, ss?ss->s:""); ss = zxid_get_epr_entid(cf, epr); printf(" EntityID: %.*s\n", ss?ss->len:0, ss?ss->s:""); } return 0; } if (svc) { D("Call service svctype(%s)", svc); if (!bdy) { if (verbose) fprintf(stderr, "Reading SOAP request body from stdin...\n"); siz = 4096; p = bdy = ZX_ALLOC(cf->ctx, siz); while (1) { n = read_all_fd(fdstdin, p, siz+bdy-p-1, &got); if (n == -1) { perror("reading SOAP req from stdin"); break; } p += got; if (got < siz+bdy-p-1) break; siz += 60*1024; REALLOCN(bdy, siz); } *p = 0; } if (dryrun) { if (verbose) fprintf(stderr, "Dryrun. Call aborted.\n"); return 0; } if (verbose) fprintf(stderr, "Calling...\n"); ss = zxid_call(cf, ses, svc, url, di, az, bdy); if (!ss || !ss->s) { ERR("Call failed %p", ss); return 2; } if (verbose) fprintf(stderr, "Done. Call returned %d bytes.\n", ss->len); if (out_fmt) { p = zxid_extract_body(cf, ss->s); printf("%s", p); } else printf("%.*s", ss->len, ss->s); } else if (az) { D("Call Az(%s)", az); if (dryrun) { if (verbose) fprintf(stderr, "Dryrun. zxid_az() aborted.\n"); return 0; } if (zxid_az_cf_ses(cf, az, ses)) { if (verbose) fprintf(stderr, "Permit.\n"); return 0; } else { if (verbose) fprintf(stderr, "Deny.\n"); return 1; } } else { D("Neither service type (-t) nor -az supplied. Performed only authentication. %d",0); if (verbose) fprintf(stderr, "Authentication only.\n"); } return 0; }