From c990b5f85d736a35132c6902ba8b2966d5146360 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Wed, 28 Jun 2006 23:38:23 +0000 Subject: [PATCH] Applied Ere's global client-authentication patch. --- include/yazproxy/proxy.h | 3 ++- src/mod_helsinki.cpp | 10 ++++---- src/proxyp.h | 5 +++- src/yaz-proxy-config.cpp | 43 +++++++++++++++++++++++++++++++- src/yaz-proxy.cpp | 61 +++++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 113 insertions(+), 9 deletions(-) diff --git a/include/yazproxy/proxy.h b/include/yazproxy/proxy.h index dbed522..2f9c588 100644 --- a/include/yazproxy/proxy.h +++ b/include/yazproxy/proxy.h @@ -1,4 +1,4 @@ -/* $Id: proxy.h,v 1.36 2006-06-09 09:35:13 adam Exp $ +/* $Id: proxy.h,v 1.37 2006-06-28 23:38:23 adam Exp $ Copyright (c) 1998-2006, Index Data. This file is part of the yazproxy. @@ -217,6 +217,7 @@ class YAZ_EXPORT Yaz_Proxy : public yazpp_1::Z_Assoc { bool dec_ref(); int handle_authentication(Z_APDU *apdu); + int handle_global_authentication(Z_APDU *apdu); void result_authentication(Z_APDU *apdu, int ret); void handle_init(Z_APDU *apdu); void inc_request_no(); diff --git a/src/mod_helsinki.cpp b/src/mod_helsinki.cpp index 5558c87..9de9250 100644 --- a/src/mod_helsinki.cpp +++ b/src/mod_helsinki.cpp @@ -1,4 +1,4 @@ -/* $Id: mod_helsinki.cpp,v 1.1 2006-03-25 10:56:28 adam Exp $ +/* $Id: mod_helsinki.cpp,v 1.2 2006-06-28 23:38:23 adam Exp $ Copyright (c) 1998-2005, Index Data. This file is part of the yaz-proxy. @@ -138,7 +138,7 @@ int my_authenticate(void *user_handle, #endif // args holds args (or NULL if none are provided) - yaz_log(YLOG_LOG, "Authentication: authenticating user %s, address %s", user ? user : "-", peer_IP ? peer_IP : "-"); + yaz_log(YLOG_LOG, "Authentication: authenticating user %s, address %s", user ? user : "(none)", peer_IP ? peer_IP : "-"); // authentication handler char user_file[255], ip_file[255]; @@ -146,7 +146,7 @@ int my_authenticate(void *user_handle, *ip_file = '\0'; sscanf(args, "%254[^:]:%254s", user_file, ip_file); - yaz_log(YLOG_LOG, "Authentication: user file: %s, ip file: %s", user_file, ip_file); + yaz_log(YLOG_DEBUG, "Authentication: user file: %s, ip file: %s", user_file, ip_file); // Check if the IP address is listed in the file of allowed address ranges. // The format of the file: @@ -156,7 +156,7 @@ int my_authenticate(void *user_handle, int status = YAZPROXY_RET_PERM; if (ip_file && peer_IP) { - yaz_log(YLOG_LOG, "Authentication: checking ip address"); + yaz_log(YLOG_DEBUG, "Authentication: checking ip address"); const char *pIP = peer_IP; if (strncmp(pIP, "tcp:", 4) == 0) @@ -202,7 +202,7 @@ int my_authenticate(void *user_handle, if (!user || !password || !*user_file) { - yaz_log(YLOG_WARN, "Authentication: no user name, password or user file specified"); + yaz_log(YLOG_LOG, "Authentication: anonymous authentication failed"); return YAZPROXY_RET_PERM; } diff --git a/src/proxyp.h b/src/proxyp.h index 06e46bd..6e84952 100644 --- a/src/proxyp.h +++ b/src/proxyp.h @@ -1,4 +1,4 @@ -/* $Id: proxyp.h,v 1.17 2006-06-09 09:35:13 adam Exp $ +/* $Id: proxyp.h,v 1.18 2006-06-28 23:38:23 adam Exp $ Copyright (c) 1998-2006, Index Data. This file is part of the yazproxy. @@ -140,6 +140,9 @@ public: const char *user, const char *group, const char *password, const char *peer_IP); + int global_client_authentication(const char *user, const char *group, + const char *password, + const char *peer_IP); char *get_explain_doc(ODR odr, const char *name, const char *db, int *len); const char *get_explain_name(const char *db, const char **backend_db); diff --git a/src/yaz-proxy-config.cpp b/src/yaz-proxy-config.cpp index 24fa1b0..e6642a5 100644 --- a/src/yaz-proxy-config.cpp +++ b/src/yaz-proxy-config.cpp @@ -1,4 +1,4 @@ -/* $Id: yaz-proxy-config.cpp,v 1.32 2006-06-09 09:35:14 adam Exp $ +/* $Id: yaz-proxy-config.cpp,v 1.33 2006-06-28 23:38:23 adam Exp $ Copyright (c) 1998-2006, Index Data. This file is part of the yazproxy. @@ -676,6 +676,44 @@ int Yaz_ProxyConfig::client_authentication(const char *name, return 1; } +int Yaz_ProxyConfig::global_client_authentication(const char *user, + const char *group, + const char *password, + const char *peer_IP) +{ + int ret = YAZPROXY_RET_NOT_ME; +#if HAVE_XSLT + if (!m_cp->m_proxyPtr) + return 1; + xmlNodePtr ptr; + for (ptr = m_cp->m_proxyPtr->children; ptr; ptr = ptr->next) + { + if (ptr->type == XML_ELEMENT_NODE && + !strcmp((const char *) ptr->name, "client-authentication")) + { + struct _xmlAttr *attr; + const char *module_name = 0; + for (attr = ptr->properties; attr; attr = attr->next) + { + if (!strcmp((const char *) attr->name, "module") && + attr->children && attr->children->type == XML_TEXT_NODE) + module_name = (const char *) attr->children->content; + } + ret = m_cp->m_modules.authenticate(module_name, + NULL, ptr, + user, group, password, + peer_IP + ); + if (ret != YAZPROXY_RET_NOT_ME) + break; + } + } +#endif + if (ret == YAZPROXY_RET_PERM) + return 0; + return 1; +} + int Yaz_ProxyConfig::check_syntax(ODR odr, const char *name, Odr_oid *syntax, Z_RecordComposition *comp, char **addinfo, @@ -1110,6 +1148,9 @@ void Yaz_ProxyConfig::get_generic_info(int *log_mask, !strcmp((const char *) ptr->name, "module")) ; else if (ptr->type == XML_ELEMENT_NODE && + !strcmp((const char *) ptr->name, "client-authentication")) + ; + else if (ptr->type == XML_ELEMENT_NODE && !strcmp((const char *) ptr->name, "threads")) { const char *t = m_cp->get_text(ptr); diff --git a/src/yaz-proxy.cpp b/src/yaz-proxy.cpp index 194b973..3dfdb00 100644 --- a/src/yaz-proxy.cpp +++ b/src/yaz-proxy.cpp @@ -1,4 +1,4 @@ -/* $Id: yaz-proxy.cpp,v 1.68 2006-06-09 09:35:14 adam Exp $ +/* $Id: yaz-proxy.cpp,v 1.69 2006-06-28 23:38:23 adam Exp $ Copyright (c) 1998-2006, Index Data. This file is part of the yazproxy. @@ -1144,6 +1144,10 @@ int Yaz_Proxy::send_http_response(int code) z_HTTP_header_add(o, &hres->headers, "Connection", "Keep-Alive"); else timeout(0); + if (code == 401) + z_HTTP_header_add(o, &hres->headers, "WWW-Authenticate", + "Basic realm=\"YAZ Proxy\""); + if (m_log_mask & PROXY_LOG_REQ_CLIENT) { @@ -2417,6 +2421,44 @@ int Yaz_Proxy::handle_authentication(Z_APDU *apdu) return ret; } +int Yaz_Proxy::handle_global_authentication(Z_APDU *apdu) +{ + if (apdu->which != Z_APDU_initRequest) + return 1; // pass if no init request + Z_InitRequest *req = apdu->u.initRequest; + + Yaz_ProxyConfig *cfg = check_reconfigure(); + if (!cfg) + return 1; // pass if no config + + int ret; + if (req->idAuthentication == 0) + { + ret = cfg->global_client_authentication(0, 0, 0, + m_peername); + } + else if (req->idAuthentication->which == Z_IdAuthentication_idPass) + { + ret = cfg->global_client_authentication( + req->idAuthentication->u.idPass->userId, + req->idAuthentication->u.idPass->groupId, + req->idAuthentication->u.idPass->password, + m_peername); + } + else if (req->idAuthentication->which == Z_IdAuthentication_open) + { + char user[64], pass[64]; + *user = '\0'; + *pass = '\0'; + sscanf(req->idAuthentication->u.open, "%63[^/]/%63s", user, pass); + ret = cfg->global_client_authentication(user, 0, pass, + m_peername); + } + else + ret = cfg->global_client_authentication(0, 0, 0, m_peername); + return ret; +} + Z_APDU *Yaz_Proxy::handle_syntax_validation(Z_APDU *apdu) { m_marcxml_mode = none; @@ -3192,6 +3234,23 @@ void Yaz_Proxy::handle_incoming_Z_PDU(Z_APDU *apdu) if (apdu->which == Z_APDU_searchRequest) m_search_stat.add_bytes(1); + // Handle global authentication + if (!handle_global_authentication(apdu)) + { + if (m_http_version) + { // HTTP. Send unauthorized + send_http_response(401); + return; + } + else + { + // Z39.50 just shutdown + timeout(0); + return; + } + return; + } + // Determine our client. Z_OtherInformation **oi; get_otherInfoAPDU(apdu, &oi); -- 1.7.10.4