/* Called by: */ int zxbus_login_subj_hash(struct hi_thr* hit, struct hi_io* io, unsigned long subj_hash) { struct hi_ent* ent; char* p; char* eid; char buf[1024]; if (!read_all(sizeof(buf), buf, "ClientTLS login", 1, "%s" ZXID_UID_DIR "/%lu/.bs/.at", zxbus_path, subj_hash)) { ERR("Login by ClienTLS failed subj_hash(%lu). No such uid.", subj_hash); return 0; } if (!(eid = strstr(buf, "eid: "))) { ERR("Login by ClienTLS failed subj_hash(%lu). .bs/.at file does not specify eid", subj_hash); return 0; } eid += sizeof("eid: ")-1; if (p = strchr(eid, '\n')) *p = 0; LOCK(hit->shf->ent_mut, "subj_hash"); D("LOCK ent_mut->thr=%x (%s:%d)", hit->shf->ent_mut.thr, hit->shf->ent_mut.func, hit->shf->ent_mut.line); if (!(ent = zxbus_load_ent(hit->shf, -1, eid))) { if (hit->shf->anonlogin) { ent = zxbus_new_ent(hit->shf, -1, eid); INFO("Anon login eid(%s)", ent->eid); /* *** consider persisting the newly created account */ } else { D("UNLOCK ent_mut->thr=%x (%s:%d)", hit->shf->ent_mut.thr, hit->shf->ent_mut.func, hit->shf->ent_mut.line); UNLOCK(hit->shf->ent_mut, "subj_hash-fail"); ERR("Login account(%s) does not exist and no anon login", eid); return 0; } } if (ent->io) { if (ent->io == io) { NEVER("Entity has io already set to current io_%p", io); } else { NEVER("Entity has io already set to different io_%p", ent->io); } } ent->io = io; LOCK(io->qel.mut, "subj_hash"); D("LOCK io(%x)->qel.mut->thr=%x (%s:%d)", io->qel.mut.thr, io->qel.mut.func, io->qel.mut.line); if (io->ent) { if (io->ent == ent) { NEVER("io has ent already set to current ent_%p", ent); } else { NEVER("io has ent already set to different ent_%p", ent); } } io->ent = ent; D("UNLOCK io(%x)->qel.mut->thr=%x (%s:%d)", io->qel.mut.thr, io->qel.mut.func, io->qel.mut.line); UNLOCK(io->qel.mut, "subj_hash"); D("UNLOCK ent_mut->thr=%x (%s:%d)", hit->shf->ent_mut.thr, hit->shf->ent_mut.func, hit->shf->ent_mut.line); UNLOCK(hit->shf->ent_mut, "subj_hash"); return 1; }
/* Called by: zxbus_load_subs */ static int zxbus_load_ch_subs(struct hiios* shf, struct hi_ch* ch) { int ch_num = ch - shf->chs; char* buf; char* p; char* nl; struct hi_ent* ent; D("Loading subs for ch(%s) ch_num=%d", ch->dest, ch_num); buf = p = read_all_malloc("load_ch_subs",1,0, "%s" ZXBUS_CH_DIR "%s/.subs", zxbus_path, ch->dest); if (!p) return 0; while (nl = strchr(p, '\n')) { *nl = 0; if (ent = zxbus_load_ent(shf, -1, p)) { ent->chs[ch_num] = HI_SUBS; } else { ERR("entity(%s) does not exist, in %s/.subs", p, ch->dest); } p = nl+1; } FREE(buf); return 1; }
/* Called by: stomp_got_login */ int zxbus_login_ent(struct hi_thr* hit, struct hi_io* io, struct hi_pdu* req) { char* p; char* login = req->ad.stomp.login; struct hi_ent* ent; int eidlen; eidlen = strchr(login, '\n') - login; login[eidlen] = 0; /* nul term */ DD("login_ent(%s) eidlen=%d", login, eidlen); for (p = login; *p; ++p) /* Undo STOMP 1.1 forbidden ':' escaping */ if (*p == '|') *p = ':'; D("login_ent(%s) eidlen=%d - deescaped", login, eidlen); D("WILL LOCK ent_mut->thr=%lx (%s:%d)", (long)hit->shf->ent_mut.thr, hit->shf->ent_mut.func, hit->shf->ent_mut.line); LOCK(hit->shf->ent_mut, "login"); D("LOCK ent_mut->thr=%lx (%s:%d)", (long)hit->shf->ent_mut.thr, hit->shf->ent_mut.func, hit->shf->ent_mut.line); if (!(ent = zxbus_load_ent(hit->shf, eidlen, login))) { if (hit->shf->anonlogin) { ent = zxbus_new_ent(hit->shf, eidlen, login); INFO("Anon login eid(%s)", ent->eid); /* *** consider persisting the newly created account */ } else { D("UNLOCK ent_mut->thr=%lx (%s:%d)", (long)hit->shf->ent_mut.thr, hit->shf->ent_mut.func, hit->shf->ent_mut.line); UNLOCK(hit->shf->ent_mut, "login-fail"); ERR("Login account(%s) does not exist and no anon login", login); return 0; } } if (req->ad.stomp.pw) { if (!zxbus_pw_authn_ent(login, req->ad.stomp.pw, io->fd)) { D("UNLOCK ent_mut->thr=%lx (%s:%d)", (long)hit->shf->ent_mut.thr, hit->shf->ent_mut.func, hit->shf->ent_mut.line); UNLOCK(hit->shf->ent_mut, "login-fail3"); return 0; } } else { /* This could be ClientTLS */ if (!hi_vfy_peer_ssl_cred(hit, io, login)) { D("UNLOCK ent_mut->thr=%lx (%s:%d)", (long)hit->shf->ent_mut.thr, hit->shf->ent_mut.func, hit->shf->ent_mut.line); UNLOCK(hit->shf->ent_mut, "login-fail5"); ERR("Login account(%s): no password supplied and no ClientTLS match", ent->eid); return 0; } } if (ent->io) { if (ent->io == io) { NEVER("Entity has io already set to current io_%p", io); } else { NEVER("Entity has io already set to different io_%p", ent->io); } } ent->io = io; LOCK(io->qel.mut, "login"); D("LOCK io(%p)->qel.mut->thr=%lx (%s:%d)", io, (long)io->qel.mut.thr, io->qel.mut.func, io->qel.mut.line); if (io->ent) { if (io->ent == ent) { NEVER("io has ent already set to current ent_%p", ent); } else { NEVER("io has ent already set to different ent_%p", ent); } } io->ent = ent; D("Logged in ent_%p eid(%s) io_%p (%x)", ent, ent->eid, io, io->fd); loginok: D("UNLOCK io(%p)->qel.mut->thr=%lx (%s:%d)", io, (long)io->qel.mut.thr, io->qel.mut.func, io->qel.mut.line); UNLOCK(io->qel.mut, "login"); D("UNLOCK ent_mut->thr=%lx (%s:%d)", (long)hit->shf->ent_mut.thr, hit->shf->ent_mut.func, hit->shf->ent_mut.line); UNLOCK(hit->shf->ent_mut, "login"); return 1; }