Use YAZ_HAVE_XSLT because yaz-config 2.1.23 or later defines it
[yazproxy-moved-to-github.git] / src / yaz-proxy.cpp
index 194b973..b1d18c0 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.70 2006-07-06 11:50:26 adam Exp $
    Copyright (c) 1998-2006, Index Data.
 
 This file is part of the yazproxy.
@@ -314,7 +314,7 @@ Yaz_Proxy::~Yaz_Proxy()
     delete m_charset_converter;
     xfree(m_optimize);
 
-#if HAVE_XSLT
+#if YAZ_HAVE_XSLT
     if (m_stylesheet_xsp)
         xsltFreeStylesheet((xsltStylesheetPtr) m_stylesheet_xsp);
 #endif
@@ -877,7 +877,7 @@ int Yaz_Proxy::convert_xsl(Z_NamePlusRecordList *p, Z_APDU *apdu)
 
 void Yaz_Proxy::convert_xsl_delay()
 {
-#if HAVE_XSLT
+#if YAZ_HAVE_XSLT
     Z_NamePlusRecord *npr = m_stylesheet_nprl->records[m_stylesheet_offset];
     if (npr->which == Z_NamePlusRecord_databaseRecord)
     {
@@ -920,7 +920,7 @@ void Yaz_Proxy::convert_xsl_delay()
     {
         m_timeout_mode = timeout_normal;
         m_stylesheet_nprl = 0;
-#if HAVE_XSLT
+#if YAZ_HAVE_XSLT
         if (m_stylesheet_xsp)
             xsltFreeStylesheet((xsltStylesheetPtr) m_stylesheet_xsp);
 #endif
@@ -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)
     {
@@ -1178,7 +1182,7 @@ int Yaz_Proxy::send_srw_response(Z_SRW_PDU *srw_pdu, int http_code /* = 200 */)
         z_HTTP_header_add(o, &hres->headers, "WWW-Authenticate", "Basic realm=\"YAZ Proxy\"");
 
     static Z_SOAP_Handler soap_handlers[2] = {
-#if HAVE_XSLT
+#if YAZ_HAVE_XSLT
         {"http://www.loc.gov/zing/srw/", 0,
          (Z_SOAP_fun) yaz_srw_codec},
 #endif
@@ -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;
@@ -2457,7 +2499,7 @@ Z_APDU *Yaz_Proxy::handle_syntax_validation(Z_APDU *apdu)
         {
             m_parent->low_socket_close();
 
-#if HAVE_XSLT
+#if YAZ_HAVE_XSLT
             if (m_stylesheet_xsp)
                 xsltFreeStylesheet((xsltStylesheetPtr) m_stylesheet_xsp);
             m_stylesheet_xsp = xsltParseStylesheetFile((const xmlChar*)
@@ -2534,7 +2576,7 @@ Z_APDU *Yaz_Proxy::handle_syntax_validation(Z_APDU *apdu)
         {
             m_parent->low_socket_close();
 
-#if HAVE_XSLT
+#if YAZ_HAVE_XSLT
             if (m_stylesheet_xsp)
                 xsltFreeStylesheet((xsltStylesheetPtr) m_stylesheet_xsp);
             m_stylesheet_xsp = xsltParseStylesheetFile((const xmlChar*)
@@ -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);