+std::string escape_cql_term(std::string inp)
+{
+ std::string res;
+ size_t l = inp.length();
+ size_t i;
+ for (i = 0; i < l; i++)
+ {
+ if (strchr("*?^\"", inp[i]))
+ res += "\\";
+ res += inp[i];
+ }
+ return res;
+}
+
+void yf::Zoom::Frontend::auth(mp::Package &package, Z_InitRequest *req,
+ int *error, char **addinfo, ODR odr)
+{
+ if (m_p->torus_auth_url.length() == 0)
+ return;
+
+ std::string user;
+ std::string password;
+ if (req->idAuthentication)
+ {
+ Z_IdAuthentication *auth = req->idAuthentication;
+ switch (auth->which)
+ {
+ case Z_IdAuthentication_open:
+ if (auth->u.open)
+ {
+ const char *cp = strchr(auth->u.open, '/');
+ if (cp)
+ {
+ user.assign(auth->u.open, cp - auth->u.open);
+ password.assign(cp + 1);
+ }
+ }
+ break;
+ case Z_IdAuthentication_idPass:
+ if (auth->u.idPass->userId)
+ user.assign(auth->u.idPass->userId);
+ if (auth->u.idPass->password)
+ password.assign(auth->u.idPass->password);
+ break;
+ }
+ }
+
+ Z_OtherInformation **oi = &req->otherInfo;
+ const char *ip =
+ yaz_oi_get_string_oid(oi, yaz_oid_userinfo_client_ip, 1, 0);
+ if (!ip)
+ ip = package.origin().get_address().c_str();
+
+ yaz_log(YLOG_LOG, "IP=%s", ip);
+
+ std::string torus_query;
+ int failure_code;
+
+ if (user.length() && password.length())
+ {
+ torus_query = "userName==\"" + escape_cql_term(user) +
+ "\" and password==\"" + escape_cql_term(password) + "\"";
+ failure_code = YAZ_BIB1_INIT_AC_BAD_USERID_AND_OR_PASSWORD;
+ }
+ else
+ {
+ torus_query = "ipRanges encloses/net.ipaddress \"";
+ torus_query += escape_cql_term(std::string(ip));
+ torus_query += "\"";
+
+ if (m_p->torus_auth_hostname.length())
+ {
+ torus_query += " AND hostName == \"";
+ torus_query += escape_cql_term(m_p->torus_auth_hostname);
+ torus_query += "\"";
+ }
+ failure_code = YAZ_BIB1_INIT_AC_BLOCKED_NETWORK_ADDRESS;
+ }
+
+ std::string dummy_db;
+ std::string dummy_realm;
+ std::string torus_addinfo;
+ xmlDoc *doc = mp::get_searchable(package, m_p->torus_auth_url, dummy_db,
+ torus_query, dummy_realm, m_p->proxy,
+ torus_addinfo);
+ if (!doc)
+ {
+ // something fundamental broken in lookup.
+ *error = YAZ_BIB1_TEMPORARY_SYSTEM_ERROR;
+ if (torus_addinfo.length())
+ *addinfo = odr_strdup(odr, torus_addinfo.c_str());
+ return;
+ }
+ const xmlNode *ptr = xmlDocGetRootElement(doc);
+ if (ptr && ptr->type == XML_ELEMENT_NODE)
+ {
+ if (strcmp((const char *) ptr->name, "records") == 0)
+ {
+ ptr = ptr->children;
+ while (ptr && ptr->type != XML_ELEMENT_NODE)
+ ptr = ptr->next;
+ }
+ if (ptr && strcmp((const char *) ptr->name, "record") == 0)
+ {
+ ptr = ptr->children;
+ while (ptr && ptr->type != XML_ELEMENT_NODE)
+ ptr = ptr->next;
+ }
+ if (ptr && strcmp((const char *) ptr->name, "layer") == 0)
+ {
+ ptr = ptr->children;
+ while (ptr && ptr->type != XML_ELEMENT_NODE)
+ ptr = ptr->next;
+ }
+ while (ptr)
+ {
+ if (ptr && ptr->type == XML_ELEMENT_NODE &&
+ !strcmp((const char *) ptr->name, "identityId"))
+ break;
+ ptr = ptr->next;
+ }
+ }
+ if (!ptr)
+ {
+ *error = failure_code;
+ return;
+ }
+ session_realm = mp::xml::get_text(ptr);
+}
+