Impl *m_p;
bool m_is_virtual;
bool m_in_use;
+ std::string session_realm;
yazpp_1::GDU m_init_gdu;
BackendPtr m_backend;
void handle_package(mp::Package &package);
void handle_search(mp::Package &package);
+ void auth(mp::Package &package, Z_InitRequest *req,
+ int *error, char **addinfo, ODR odr);
+
BackendPtr explain_search(mp::Package &package,
std::string &database,
int *error,
char **addinfo,
mp::odr &odr,
+ std::string torus_url,
std::string &torus_db,
std::string &realm);
void handle_present(mp::Package &package);
boost::condition m_cond_session_ready;
std::string torus_searchable_url;
std::string torus_content_url;
+ std::string torus_auth_url;
std::string default_realm;
std::map<std::string,std::string> fieldmap;
std::string xsldir;
enable_cproxy = true;
enable_explain = false;
explain_doc = 0;
+ cqlt = 0;
}
yf::Zoom::Backend::~Backend()
torus_searchable_url = mp::xml::get_text(attr->children);
else if (!strcmp((const char *) attr->name, "content_url"))
torus_content_url = mp::xml::get_text(attr->children);
+ else if (!strcmp((const char *) attr->name, "auth_url"))
+ torus_auth_url = mp::xml::get_text(attr->children);
else if (!strcmp((const char *) attr->name, "realm"))
default_realm = mp::xml::get_text(attr->children);
else if (!strcmp((const char *) attr->name, "xsldir"))
std::string authentication;
std::string content_authentication;
std::string content_proxy;
- std::string realm = m_p->default_realm;
+ std::string realm = session_realm;
+ if (realm.length() == 0)
+ realm = m_p->default_realm;
const char *param_user = 0;
const char *param_password = 0;
out_values[no_out_args++] = value;
torus_url = m_p->torus_content_url;
}
- else if (!strcmp(name, "realm"))
+ else if (!strcmp(name, "realm") && session_realm.length() == 0)
realm = value;
+ else if (!strcmp(name, "torus_url") && session_realm.length() == 0)
+ torus_url = value;
else if (name[0] == 'x' && name[1] == '-')
{
out_names[no_out_args] = name;
}
if (torus_db.compare("IR-Explain---1") == 0)
- return explain_search(package, database, error, addinfo, odr, torus_db,
- realm);
+ return explain_search(package, database, error, addinfo, odr, torus_url,
+ torus_db, realm);
SearchablePtr sptr;
return b;
}
const xmlNode *ptr = xmlDocGetRootElement(doc);
- if (ptr)
- { // presumably ptr is a records element node
- // parse first record in document
- for (ptr = ptr->children; ptr; ptr = ptr->next)
+ if (ptr && ptr->type == XML_ELEMENT_NODE)
+ {
+ if (!strcmp((const char *) ptr->name, "record"))
+ {
+ sptr = m_p->parse_torus_record(ptr);
+ }
+ else if (!strcmp((const char *) ptr->name, "records"))
{
- if (ptr->type == XML_ELEMENT_NODE
- && !strcmp((const char *) ptr->name, "record"))
+ for (ptr = ptr->children; ptr; ptr = ptr->next)
{
- if (sptr)
+ if (ptr->type == XML_ELEMENT_NODE
+ && !strcmp((const char *) ptr->name, "record"))
{
- *error = YAZ_BIB1_UNSPECIFIED_ERROR;
- *addinfo = (char*) odr_malloc(odr, 40 + database.length()),
- sprintf(*addinfo, "multiple records for udb=%s",
- database.c_str());
- xmlFreeDoc(doc);
- BackendPtr b;
- return b;
+ if (sptr)
+ {
+ *error = YAZ_BIB1_UNSPECIFIED_ERROR;
+ *addinfo = (char*)
+ odr_malloc(odr, 40 + torus_db.length());
+ sprintf(*addinfo, "multiple records for udb=%s",
+ database.c_str());
+ xmlFreeDoc(doc);
+ BackendPtr b;
+ return b;
+ }
+ sptr = m_p->parse_torus_record(ptr);
}
- sptr = m_p->parse_torus_record(ptr);
}
}
+ else
+ {
+ *error = YAZ_BIB1_UNSPECIFIED_ERROR;
+ *addinfo = (char*) odr_malloc(
+ odr, 40 + strlen((const char *) ptr->name));
+ sprintf(*addinfo, "bad root element for torus: %s", ptr->name);
+ xmlFreeDoc(doc);
+ BackendPtr b;
+ return b;
+ }
}
xmlFreeDoc(doc);
}
}
}
- cql_transform_t cqlt;
+ cql_transform_t cqlt = 0;
if (sptr->rpn2cql_fname.length())
- cqlt = cql_transform_open_fname(sptr->rpn2cql_fname.c_str());
+ {
+ char fullpath[1024];
+ char *cp = yaz_filepath_resolve(sptr->rpn2cql_fname.c_str(),
+ m_p->file_path.c_str(), 0, fullpath);
+ if (cp)
+ cqlt = cql_transform_open_fname(fullpath);
+ }
else
cqlt = cql_transform_create();
int *error,
char **addinfo,
mp::odr &odr,
+ std::string torus_url,
std::string &torus_db,
std::string &realm)
{
else if (query->which == Z_Query_type_104 &&
query->u.type_104->which == Z_External_CQL)
{
- std::string torus_url = m_p->torus_searchable_url;
std::string torus_query(query->u.type_104->u.cql);
xmlDoc *doc = mp::get_searchable(package, torus_url, "",
torus_query,
}
}
+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;
+ }
+ }
+
+ std::string ip = package.origin().get_address();
+ yaz_log(YLOG_LOG, "IP=%s", ip.c_str());
+
+ 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
+ {
+ const char *ip_cstr = ip.c_str();
+ const char *cp = strchr(ip_cstr, ':');
+ if (cp)
+ ip_cstr = cp + 1;
+
+ torus_query = "ip encloses/net.ipaddress \"";
+ torus_query += escape_cql_term(std::string(ip_cstr));
+ torus_query += "\"";
+ failure_code = YAZ_BIB1_INIT_AC_BLOCKED_NETWORK_ADDRESS;
+ }
+
+ std::string dummy_db;
+ std::string dummy_realm;
+ xmlDoc *doc = mp::get_searchable(package, m_p->torus_auth_url, dummy_db,
+ torus_query, dummy_realm, m_p->proxy);
+ if (!doc)
+ {
+ // something fundamental broken in lookup.
+ *error = YAZ_BIB1_TEMPORARY_SYSTEM_ERROR;
+ *addinfo = odr_strdup(odr, "Torus server unavailable or "
+ "incorrectly configured");
+ 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);
+}
+
void yf::Zoom::Impl::process(mp::Package &package)
{
FrontendPtr f = get_frontend(package);
*resp->preferredMessageSize = *req->preferredMessageSize;
*resp->maximumRecordSize = *req->maximumRecordSize;
-
+
+ int error = 0;
+ char *addinfo = 0;
+ f->auth(package, req, &error, &addinfo, odr);
+ if (error)
+ {
+ resp->userInformationField =
+ zget_init_diagnostics(odr, error, addinfo);
+ *resp->result = 0;
+ package.session().close();
+ }
+ else
+ f->m_is_virtual = true;
package.response() = apdu;
- f->m_is_virtual = true;
}
else
package.move();