Applied Ere's global client-authentication patch.
authorAdam Dickmeiss <adam@indexdata.dk>
Wed, 28 Jun 2006 23:38:23 +0000 (23:38 +0000)
committerAdam Dickmeiss <adam@indexdata.dk>
Wed, 28 Jun 2006 23:38:23 +0000 (23:38 +0000)
include/yazproxy/proxy.h
src/mod_helsinki.cpp
src/proxyp.h
src/yaz-proxy-config.cpp
src/yaz-proxy.cpp

index dbed522..2f9c588 100644 (file)
@@ -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();
index 5558c87..9de9250 100644 (file)
@@ -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;
     }
 
index 06e46bd..6e84952 100644 (file)
@@ -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);
index 24fa1b0..e6642a5 100644 (file)
@@ -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);
index 194b973..3dfdb00 100644 (file)
@@ -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);