From 66663d272496cedff1da574891413f90ce716b85 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Mon, 30 May 2005 20:09:20 +0000 Subject: [PATCH] Added support for threaded authentication modules. See etc/config-modules.xml + mod_sample.cpp for an example. --- NEWS | 4 + etc/config-modules.xml | 5 +- include/yazproxy/module.h | 20 ++- include/yazproxy/proxy.h | 15 ++- src/Makefile.am | 5 +- src/modules.cpp | 178 ++++++++++++++++++++++++++ src/yaz-proxy-config.cpp | 146 ++-------------------- src/yaz-proxy-main.cpp | 4 +- src/yaz-proxy.cpp | 304 +++++++++++++++++++++++++++------------------ 9 files changed, 412 insertions(+), 269 deletions(-) create mode 100644 src/modules.cpp diff --git a/NEWS b/NEWS index 140c67b..821fb59 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ + +Added support for threaded authentication modules. See +etc/config-modules.xml + mod_sample.cpp for an example. + Added support for Z39.50 character set negotiation. This allows the proxy to act as a Z39.50 server supporting character set negotiation for backends not supporting it. New config element target-charset diff --git a/etc/config-modules.xml b/etc/config-modules.xml index fc10e04..9804cd5 100644 --- a/etc/config-modules.xml +++ b/etc/config-modules.xml @@ -1,5 +1,5 @@ - + @@ -32,10 +32,7 @@ 0 pqf.properties - my/bad - iso-8859-1 - US 50 client-requests server-requests diff --git a/include/yazproxy/module.h b/include/yazproxy/module.h index 7afbff5..d701209 100644 --- a/include/yazproxy/module.h +++ b/include/yazproxy/module.h @@ -1,4 +1,4 @@ -/* $Id: module.h,v 1.2 2005-02-21 14:27:31 adam Exp $ +/* $Id: module.h,v 1.3 2005-05-30 20:09:20 adam Exp $ Copyright (c) 1998-2005, Index Data. This file is part of the yaz-proxy. @@ -50,4 +50,22 @@ struct Yaz_ProxyModule_int0 { ); }; +class Yaz_ProxyModule; + +class Yaz_ProxyModules { + friend class Proxy_Msg; + public: + Yaz_ProxyModules(); + ~Yaz_ProxyModules(); + int authenticate(const char *module_name, + const char *target_name, void *element_ptr, + const char *user, + const char *group, + const char *password); + int add_module(const char *fname); + void unload_modules(); + private: + Yaz_ProxyModule *m_list; +}; + #endif diff --git a/include/yazproxy/proxy.h b/include/yazproxy/proxy.h index 854191c..7482f52 100644 --- a/include/yazproxy/proxy.h +++ b/include/yazproxy/proxy.h @@ -1,4 +1,4 @@ -/* $Id: proxy.h,v 1.16 2005-05-18 20:15:22 adam Exp $ +/* $Id: proxy.h,v 1.17 2005-05-30 20:09:20 adam Exp $ Copyright (c) 1998-2005, Index Data. This file is part of the yaz-proxy. @@ -22,6 +22,7 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA #ifndef YAZ_PROXY_H_INCLUDED #define YAZ_PROXY_H_INCLUDED +#include #include #include #include @@ -48,8 +49,11 @@ enum YAZ_Proxy_MARCXML_mode { marcxml, }; +class Msg_Thread; + /// Information Retrieval Proxy Server. class YAZ_EXPORT Yaz_Proxy : public Yaz_Z_Assoc { + friend class Proxy_Msg; private: char *get_cookie(Z_OtherInformation **otherInfo); char *get_proxy(Z_OtherInformation **otherInfo); @@ -63,6 +67,7 @@ class YAZ_EXPORT Yaz_Proxy : public Yaz_Z_Assoc { void releaseClient(); Yaz_ProxyClient *m_client; IYaz_PDU_Observable *m_PDU_Observable; + IYazSocketObservable *m_socket_observable; Yaz_ProxyClient *m_clientPool; Yaz_Proxy *m_parent; int m_seqno; @@ -92,7 +97,6 @@ class YAZ_EXPORT Yaz_Proxy : public Yaz_Z_Assoc { Z_GDU *m_bw_hold_PDU; int m_max_record_retrieve; void handle_max_record_retrieve(Z_APDU *apdu); - int handle_authentication(Z_APDU *apdu); void display_diagrecs(Z_DiagRec **pp, int num); Z_Records *create_nonSurrogateDiagnostics(ODR o, int error, const char *addinfo); @@ -165,6 +169,7 @@ class YAZ_EXPORT Yaz_Proxy : public Yaz_Z_Assoc { Z_ElementSetNames *mk_esn_from_schema(ODR o, const char *schema); Z_ReferenceId *m_referenceId; NMEM m_referenceId_mem; + #define NO_SPARE_SOLARIS_FD 10 int m_lo_fd[NO_SPARE_SOLARIS_FD]; void low_socket_open(); @@ -175,12 +180,17 @@ class YAZ_EXPORT Yaz_Proxy : public Yaz_Z_Assoc { Yaz_CharsetConverter *m_charset_converter; public: Yaz_Proxy(IYaz_PDU_Observable *the_PDU_Observable, + IYazSocketObservable *the_socket_observable, Yaz_Proxy *parent = 0); ~Yaz_Proxy(); + int handle_authentication(Z_APDU *apdu); + void result_authentication(Z_APDU *apdu, int ret); + void handle_init(Z_APDU *apdu); void inc_request_no(); void recv_GDU(Z_GDU *apdu, int len); void handle_incoming_HTTP(Z_HTTP_Request *req); void handle_incoming_Z_PDU(Z_APDU *apdu); + void handle_incoming_Z_PDU_2(Z_APDU *apdu); IYaz_PDU_Observer* sessionNotify (IYaz_PDU_Observable *the_PDU_Observable, int fd); void failNotify(); @@ -205,6 +215,7 @@ class YAZ_EXPORT Yaz_Proxy : public Yaz_Z_Assoc { int get_log_mask() { return m_log_mask; }; int handle_init_response_for_invalid_session(Z_APDU *apdu); void set_debug_mode(int mode); + Msg_Thread *m_my_thread; }; #endif diff --git a/src/Makefile.am b/src/Makefile.am index 1b8a5ca..95c84ca 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,4 +1,4 @@ -## $Id: Makefile.am,v 1.7 2005-05-19 21:29:58 adam Exp $ +## $Id: Makefile.am,v 1.8 2005-05-30 20:09:21 adam Exp $ AM_CXXFLAGS = $(YAZPPINC) -I$(srcdir)/../include $(XSLT_CFLAGS) $(USEMARCONINC) @@ -6,7 +6,8 @@ lib_LTLIBRARIES = libyazproxy.la libyazproxy_la_LDFLAGS=-version-info 1:0:0 libyazproxy_la_SOURCES= yaz-proxy.cpp yaz-proxy-config.cpp yaz-bw.cpp \ - proxyp.h yaz-usemarcon.cpp charset-converter.cpp + proxyp.h yaz-usemarcon.cpp charset-converter.cpp msg-thread.cpp msg-thread.h \ + modules.cpp bin_PROGRAMS = yazproxy check_PROGRAMS = cdetails diff --git a/src/modules.cpp b/src/modules.cpp new file mode 100644 index 0000000..4e7f473 --- /dev/null +++ b/src/modules.cpp @@ -0,0 +1,178 @@ +/* $Id: modules.cpp,v 1.1 2005-05-30 20:09:21 adam Exp $ + Copyright (c) 1998-2005, Index Data. + +This file is part of the yaz-proxy. + +YAZ proxy is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2, or (at your option) any later +version. + +YAZ proxy is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with YAZ proxy; see the file LICENSE. If not, write to the +Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. + */ + +#include +#if HAVE_DLFCN_H +#include +#endif + +#include +#include + +class Yaz_ProxyModule { + friend class Proxy_Msg; +private: + void *m_dl_handle; /* dlopen/close handle */ + Yaz_ProxyModule_entry *m_entry; + Yaz_ProxyModule *m_next; + void *m_user_handle; /* user handle */ +public: + Yaz_ProxyModule(void *dl_handle, Yaz_ProxyModule_entry *ent, + Yaz_ProxyModule *next); + ~Yaz_ProxyModule(); + + Yaz_ProxyModule *get_next() { return m_next; }; + int is_module(const char *name); + int authenticate(const char *target_name, void *element_ptr, + const char *user, const char *group, const char *password); +}; + +int Yaz_ProxyModule::is_module(const char *name) +{ + if (!name || !strcmp(m_entry->module_name, name)) + return 1; + return 0; +} + +Yaz_ProxyModule::Yaz_ProxyModule(void *dl_handle, Yaz_ProxyModule_entry *ent, + Yaz_ProxyModule *next) +{ + m_dl_handle = dl_handle; + m_entry = ent; + m_next = next; + m_user_handle = 0; + if (m_entry->int_version == 0) + { + struct Yaz_ProxyModule_int0 *int0 = + reinterpret_cast(m_entry->fl); + if (int0->init) + m_user_handle = (*int0->init)(); + } +} + +Yaz_ProxyModule::~Yaz_ProxyModule() +{ + if (m_entry->int_version == 0) + { + struct Yaz_ProxyModule_int0 *int0 = + reinterpret_cast(m_entry->fl); + if (int0->destroy) + (*int0->destroy)(m_user_handle); + } +#if HAVE_DLFCN_H + dlclose(m_dl_handle); +#endif +} + +int Yaz_ProxyModule::authenticate(const char *name, + void *element_ptr, + const char *user, const char *group, + const char *password) +{ + if (m_entry->int_version == 0) + { + struct Yaz_ProxyModule_int0 *int0 = + reinterpret_cast(m_entry->fl); + + if (!int0->authenticate) + return YAZPROXY_RET_NOT_ME; + return (*int0->authenticate)(m_user_handle, name, element_ptr, + user, group, password); + } + return YAZPROXY_RET_NOT_ME; +} + +Yaz_ProxyModules::Yaz_ProxyModules() +{ + m_list = 0; +} + + +Yaz_ProxyModules::~Yaz_ProxyModules() +{ + unload_modules(); +} + +void Yaz_ProxyModules::unload_modules() +{ + Yaz_ProxyModule *m = m_list; + while (m) + { + Yaz_ProxyModule *m_next = m->get_next(); + delete m; + m = m_next; + } + m_list = 0; +} + + +int Yaz_ProxyModules::authenticate(const char *module_name, + const char *target_name, void *element_ptr, + const char *user, + const char *group, + const char *password) +{ + int ret = YAZPROXY_RET_NOT_ME; + Yaz_ProxyModule *m = m_list; + for (; m; m = m->get_next()) + { + if (m->is_module(module_name)) + { + ret = m->authenticate(target_name, element_ptr, + user, group, password); + if (ret != YAZPROXY_RET_NOT_ME) + break; + } + } + return ret; +} + +int Yaz_ProxyModules::add_module(const char *fname) +{ +#if HAVE_DLFCN_H + void *dl_handle = dlopen(fname, RTLD_NOW|RTLD_GLOBAL); + if (dl_handle) + { + Yaz_ProxyModule_entry *fl_ptr = 0; + fl_ptr = reinterpret_cast + (dlsym(dl_handle, "yazproxy_module")); + if (fl_ptr) + { + Yaz_ProxyModule *m = new Yaz_ProxyModule(dl_handle, + fl_ptr, + m_list); + m_list = m; + + return 0; + } + else + { + return -1; + dlclose(dl_handle); + } + } + else + return -1; +#else + return -1; +#endif +} + diff --git a/src/yaz-proxy-config.cpp b/src/yaz-proxy-config.cpp index 76259cf..6a5b313 100644 --- a/src/yaz-proxy-config.cpp +++ b/src/yaz-proxy-config.cpp @@ -1,4 +1,4 @@ -/* $Id: yaz-proxy-config.cpp,v 1.19 2005-05-18 20:15:22 adam Exp $ +/* $Id: yaz-proxy-config.cpp,v 1.20 2005-05-30 20:09:21 adam Exp $ Copyright (c) 1998-2005, Index Data. This file is part of the yaz-proxy. @@ -21,97 +21,18 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include -#if HAVE_DLFCN_H -#include -#endif - #include #include "proxyp.h" - -class Yaz_ProxyModule { -private: - void *m_dl_handle; /* dlopen/close handle */ - Yaz_ProxyModule_entry *m_entry; - Yaz_ProxyModule *m_next; - void *m_user_handle; /* user handle */ -public: - Yaz_ProxyModule(void *dl_handle, Yaz_ProxyModule_entry *ent, - Yaz_ProxyModule *next); - ~Yaz_ProxyModule(); - - Yaz_ProxyModule *get_next() { return m_next; }; - int is_module(const char *name); - int authenticate(const char *target_name, void *element_ptr, - const char *user, const char *group, const char *password); -}; - -int Yaz_ProxyModule::is_module(const char *type) -{ - if (!type || !strcmp(m_entry->module_name, type)) - return 1; - return 0; -} - -Yaz_ProxyModule::Yaz_ProxyModule(void *dl_handle, Yaz_ProxyModule_entry *ent, - Yaz_ProxyModule *next) -{ - m_dl_handle = dl_handle; - m_entry = ent; - m_next = next; - m_user_handle = 0; - if (m_entry->int_version == 0) - { - struct Yaz_ProxyModule_int0 *int0 = - reinterpret_cast(m_entry->fl); - if (int0->init) - m_user_handle = (*int0->init)(); - } -} - -Yaz_ProxyModule::~Yaz_ProxyModule() -{ - if (m_entry->int_version == 0) - { - struct Yaz_ProxyModule_int0 *int0 = - reinterpret_cast(m_entry->fl); - if (int0->destroy) - (*int0->destroy)(m_user_handle); - } -#if HAVE_DLFCN_H - dlclose(m_dl_handle); -#endif -} - -int Yaz_ProxyModule::authenticate(const char *name, - void *element_ptr, - const char *user, const char *group, - const char *password) -{ - if (m_entry->int_version == 0) - { - struct Yaz_ProxyModule_int0 *int0 = - reinterpret_cast(m_entry->fl); - - if (!int0->authenticate) - return YAZPROXY_RET_NOT_ME; - return (*int0->authenticate)(m_user_handle, name, element_ptr, - user, group, password); - } - return YAZPROXY_RET_NOT_ME; -} - class Yaz_ProxyConfigP { friend class Yaz_ProxyConfig; - Yaz_ProxyModule *m_modules; - + Yaz_ProxyModules m_modules; int mycmp(const char *hay, const char *item, size_t len); int match_list(int v, const char *m); int atoi_l(const char **cp); #if HAVE_XSLT void load_modules(void); - void unload_modules(void); int check_schema(xmlNodePtr ptr, Z_RecordComposition *comp, const char *schema_identifier); xmlDocPtr m_docPtr; @@ -143,13 +64,12 @@ class Yaz_ProxyConfigP { ~Yaz_ProxyConfigP(); }; -Yaz_ProxyConfigP::Yaz_ProxyConfigP() +Yaz_ProxyConfigP::Yaz_ProxyConfigP() : m_modules() { #if HAVE_XSLT m_docPtr = 0; m_proxyPtr = 0; #endif - m_modules = 0; } Yaz_ProxyConfigP::~Yaz_ProxyConfigP() @@ -162,7 +82,7 @@ Yaz_ProxyConfigP::~Yaz_ProxyConfigP() Yaz_ProxyConfig::Yaz_ProxyConfig() { - m_cp = new Yaz_ProxyConfigP; + m_cp = new Yaz_ProxyConfigP(); } Yaz_ProxyConfig::~Yaz_ProxyConfig() @@ -171,20 +91,6 @@ Yaz_ProxyConfig::~Yaz_ProxyConfig() } #if HAVE_XSLT -void Yaz_ProxyConfigP::unload_modules() -{ - Yaz_ProxyModule *m = m_modules; - while (m) - { - Yaz_ProxyModule *m_next = m->get_next(); - delete m; - m = m_next; - } - m_modules = 0; -} -#endif - -#if HAVE_XSLT void Yaz_ProxyConfigP::load_modules() { if (!m_proxyPtr) @@ -197,32 +103,7 @@ void Yaz_ProxyConfigP::load_modules() && !strcmp((const char *) ptr->name, "module") && (fname = get_text(ptr))) { -#if HAVE_DLFCN_H - void *dl_handle = dlopen(fname, RTLD_NOW|RTLD_GLOBAL); - if (dl_handle) - { - Yaz_ProxyModule_entry *fl_ptr = 0; - fl_ptr = reinterpret_cast - (dlsym(dl_handle, "yazproxy_module")); - if (fl_ptr) - { - Yaz_ProxyModule *m = new Yaz_ProxyModule(dl_handle, - fl_ptr, - m_modules); - m_modules = m; - yaz_log(YLOG_LOG, "Loading %s OK", fname); - } - else - { - yaz_log(YLOG_WARN, "Loading %s FAIL: missing yazproxy_module symbol", fname); - dlclose(dl_handle); - } - } - else - yaz_log(YLOG_WARN, "Loading %s FAIL: dlopen failed", fname); -#else - yaz_log(YLOG_WARN, "Loading &s FAIL: dl unsupported", fname); -#endif + m_modules.add_module(fname); } } } @@ -257,7 +138,7 @@ int Yaz_ProxyConfig::read_xml(const char *fname) xmlFreeDoc(m_cp->m_docPtr); m_cp->m_docPtr = ndoc; - m_cp->unload_modules(); + m_cp->m_modules.unload_modules(); m_cp->load_modules(); return 0; #else @@ -742,16 +623,11 @@ int Yaz_ProxyConfig::client_authentication(const char *name, attr->children && attr->children->type == XML_TEXT_NODE) module_name = (const char *) attr->children->content; } - Yaz_ProxyModule *m = m_cp->m_modules; - for (; m; m = m->get_next()) - { - if (m->is_module(module_name)) - { - ret = m->authenticate(name, ptr, user, group, password); - if (ret != YAZPROXY_RET_NOT_ME) - break; - } - } + ret = m_cp->m_modules.authenticate(module_name, + name, ptr, + user, group, password); + if (ret != YAZPROXY_RET_NOT_ME) + break; } #endif if (ret == YAZPROXY_RET_PERM) diff --git a/src/yaz-proxy-main.cpp b/src/yaz-proxy-main.cpp index f40c64a..4257c79 100644 --- a/src/yaz-proxy-main.cpp +++ b/src/yaz-proxy-main.cpp @@ -1,4 +1,4 @@ -/* $Id: yaz-proxy-main.cpp,v 1.12 2005-02-21 14:27:32 adam Exp $ +/* $Id: yaz-proxy-main.cpp,v 1.13 2005-05-30 20:09:21 adam Exp $ Copyright (c) 1998-2005, Index Data. This file is part of the yaz-proxy. @@ -283,7 +283,7 @@ int main(int argc, char **argv) int cont = 1; int run = 1; Yaz_SocketManager mySocketManager; - Yaz_Proxy proxy(new Yaz_PDU_Assoc(&mySocketManager)); + Yaz_Proxy proxy(new Yaz_PDU_Assoc(&mySocketManager), &mySocketManager); static_yaz_proxy = &proxy; diff --git a/src/yaz-proxy.cpp b/src/yaz-proxy.cpp index e59613e..6aae564 100644 --- a/src/yaz-proxy.cpp +++ b/src/yaz-proxy.cpp @@ -1,4 +1,4 @@ -/* $Id: yaz-proxy.cpp,v 1.27 2005-05-27 18:07:49 adam Exp $ +/* $Id: yaz-proxy.cpp,v 1.28 2005-05-30 20:09:21 adam Exp $ Copyright (c) 1998-2005, Index Data. This file is part of the yaz-proxy. @@ -51,7 +51,45 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include #include #include +#include "msg-thread.h" +class Auth_Msg : public IMsg_Thread { +public: + int m_ret; + void destroy(); + IMsg_Thread *handle(); + void result(); + Yaz_Proxy *m_proxy; + Z_APDU *m_apdu; +}; + +IMsg_Thread *Auth_Msg::handle() +{ + yaz_log(YLOG_LOG, "Auth_Msg:handle begin"); + m_ret = m_proxy->handle_authentication(m_apdu); + yaz_log(YLOG_LOG, "Auth_Msg:handle end"); + return this; +} + +void Yaz_Proxy::result_authentication(Z_APDU *apdu, int ret) +{ + if (ret == 0) + { + Z_APDU *apdu_reject = zget_APDU(odr_encode(), Z_APDU_initResponse); + *apdu_reject->u.initResponse->result = 0; + send_to_client(apdu_reject); + shutdown(); + } + else + handle_incoming_Z_PDU_2(apdu); +} + +void Auth_Msg::result() +{ + yaz_log(YLOG_LOG, "Auth_Msg:result"); + m_proxy->result_authentication(m_apdu, m_ret); + delete this; +} static const char *apdu_name(Z_APDU *apdu) { @@ -104,11 +142,15 @@ static const char *gdu_name(Z_GDU *gdu) } return "Unknown request/response"; } + Yaz_Proxy::Yaz_Proxy(IYaz_PDU_Observable *the_PDU_Observable, - Yaz_Proxy *parent) : + IYazSocketObservable *the_socket_observable, + Yaz_Proxy *parent) + : Yaz_Z_Assoc(the_PDU_Observable), m_bw_stat(60), m_pdu_stat(60) { m_PDU_Observable = the_PDU_Observable; + m_socket_observable = the_socket_observable; m_client = 0; m_parent = parent; m_clientPool = 0; @@ -127,7 +169,7 @@ Yaz_Proxy::Yaz_Proxy(IYaz_PDU_Observable *the_PDU_Observable, m_target_idletime = 600; m_optimize = xstrdup ("1"); strcpy(m_session_str, "0 "); - m_session_no=0; + m_session_no = 0; m_bytes_sent = 0; m_bytes_recv = 0; m_bw_hold_PDU = 0; @@ -185,6 +227,7 @@ Yaz_Proxy::Yaz_Proxy(IYaz_PDU_Observable *the_PDU_Observable, m_usemarcon = new Yaz_usemarcon(); if (!m_parent) low_socket_open(); + m_my_thread = 0; } Yaz_Proxy::~Yaz_Proxy() @@ -220,6 +263,8 @@ Yaz_Proxy::~Yaz_Proxy() odr_destroy(m_s2z_odr_search); if (!m_parent) low_socket_close(); + if (!m_parent) + delete m_my_thread; delete m_config; } @@ -295,7 +340,8 @@ IYaz_PDU_Observer *Yaz_Proxy::sessionNotify(IYaz_PDU_Observable *the_PDU_Observable, int fd) { check_reconfigure(); - Yaz_Proxy *new_proxy = new Yaz_Proxy(the_PDU_Observable, this); + Yaz_Proxy *new_proxy = new Yaz_Proxy(the_PDU_Observable, + m_socket_observable, this); new_proxy->m_config = 0; new_proxy->m_config_fname = 0; new_proxy->timeout(m_client_idletime); @@ -314,6 +360,10 @@ IYaz_PDU_Observer *Yaz_Proxy::sessionNotify(IYaz_PDU_Observable the_PDU_Observable->getpeername()); new_proxy->set_proxy_negotiation(m_proxy_negotiation_charset, m_proxy_negotiation_lang); + // create thread object the first time we get an incoming connection + if (!m_my_thread) + m_my_thread = new Msg_Thread(m_socket_observable); + new_proxy->m_my_thread = m_my_thread; return new_proxy; } @@ -658,6 +708,7 @@ Yaz_ProxyClient *Yaz_Proxy::get_client(Z_APDU *apdu, const char *cookie, yaz_log (YLOG_DEBUG, "get_client 3 %p %p", this, c); return c; } + void Yaz_Proxy::display_diagrecs(Z_DiagRec **pp, int num) { int i; @@ -2601,6 +2652,123 @@ void Yaz_Proxy::handle_incoming_HTTP(Z_HTTP_Request *hreq) send_http_response(400); } +void Yaz_Proxy::handle_init(Z_APDU *apdu) +{ + Z_OtherInformation **oi; + get_otherInfoAPDU(apdu, &oi); + + if (apdu->u.initRequest->implementationId) + yaz_log(YLOG_LOG, "%simplementationId: %s", + m_session_str, apdu->u.initRequest->implementationId); + if (apdu->u.initRequest->implementationName) + yaz_log(YLOG_LOG, "%simplementationName: %s", + m_session_str, apdu->u.initRequest->implementationName); + if (apdu->u.initRequest->implementationVersion) + yaz_log(YLOG_LOG, "%simplementationVersion: %s", + m_session_str, apdu->u.initRequest->implementationVersion); + if (m_initRequest_apdu == 0) + { + if (m_initRequest_mem) + nmem_destroy(m_initRequest_mem); + + m_initRequest_apdu = apdu; + m_initRequest_mem = odr_extract_mem(odr_decode()); + + m_initRequest_preferredMessageSize = *apdu->u.initRequest-> + preferredMessageSize; + *apdu->u.initRequest->preferredMessageSize = 1024*1024; + m_initRequest_maximumRecordSize = *apdu->u.initRequest-> + maximumRecordSize; + *apdu->u.initRequest->maximumRecordSize = 1024*1024; + + // Save proposal charsets and langs. + if (ODR_MASK_GET(apdu->u.initRequest->options, + Z_Options_negotiationModel)) + { + Z_CharSetandLanguageNegotiation *charSetandLangRecord = + yaz_get_charneg_record(*oi); + + yaz_get_proposal_charneg(m_referenceId_mem, + charSetandLangRecord, + &m_initRequest_oi_negotiation_charsets, + &m_initRequest_oi_negotiation_num_charsets, + &m_initRequest_oi_negotiation_langs, + &m_initRequest_oi_negotiation_num_langs, + &m_initRequest_oi_negotiation_selected); + + for (int i = 0; iu.initRequest->options; + + apdu->u.initRequest->options = + (Odr_bitmask *)nmem_malloc(m_initRequest_mem, + sizeof(Odr_bitmask)); + ODR_MASK_ZERO(apdu->u.initRequest->options); + int i; + for (i = 0; i<= 24; i++) + ODR_MASK_SET(apdu->u.initRequest->options, i); + // check negotiation option + if (!ODR_MASK_GET(m_initRequest_options, + Z_Options_negotiationModel)) + { + ODR_MASK_CLEAR(apdu->u.initRequest->options, + Z_Options_negotiationModel); + } + ODR_MASK_CLEAR(apdu->u.initRequest->options, + Z_Options_concurrentOperations); + // make new version + m_initRequest_version = apdu->u.initRequest->protocolVersion; + apdu->u.initRequest->protocolVersion = + (Odr_bitmask *)nmem_malloc(m_initRequest_mem, + sizeof(Odr_bitmask)); + ODR_MASK_ZERO(apdu->u.initRequest->protocolVersion); + + for (i = 0; i<= 8; i++) + ODR_MASK_SET(apdu->u.initRequest->protocolVersion, i); + } + if (m_client->m_init_flag) + { + if (handle_init_response_for_invalid_session(apdu)) + return; + if (m_client->m_initResponse) + { + Z_APDU *apdu2 = m_client->m_initResponse; + apdu2->u.initResponse->otherInfo = 0; + if (m_client->m_cookie && *m_client->m_cookie) + set_otherInformationString(apdu2, VAL_COOKIE, 1, + m_client->m_cookie); + apdu2->u.initResponse->referenceId = + apdu->u.initRequest->referenceId; + apdu2->u.initResponse->options = m_client->m_initResponse_options; + apdu2->u.initResponse->protocolVersion = + m_client->m_initResponse_version; + + send_to_client(apdu2); + return; + } + } + m_client->m_init_flag = 1; + + Auth_Msg *m = new Auth_Msg; + m->m_apdu = apdu; + m->m_proxy = this; + m_my_thread->put(m); +} + void Yaz_Proxy::handle_incoming_Z_PDU(Z_APDU *apdu) { Z_ReferenceId **refid = get_referenceIdP(apdu); @@ -2645,126 +2813,15 @@ void Yaz_Proxy::handle_incoming_Z_PDU(Z_APDU *apdu) m_client->m_server = this; if (apdu->which == Z_APDU_initRequest) - { - if (apdu->u.initRequest->implementationId) - yaz_log(YLOG_LOG, "%simplementationId: %s", - m_session_str, apdu->u.initRequest->implementationId); - if (apdu->u.initRequest->implementationName) - yaz_log(YLOG_LOG, "%simplementationName: %s", - m_session_str, apdu->u.initRequest->implementationName); - if (apdu->u.initRequest->implementationVersion) - yaz_log(YLOG_LOG, "%simplementationVersion: %s", - m_session_str, apdu->u.initRequest->implementationVersion); - if (m_initRequest_apdu == 0) - { - if (m_initRequest_mem) - nmem_destroy(m_initRequest_mem); - - m_initRequest_apdu = apdu; - m_initRequest_mem = odr_extract_mem(odr_decode()); - - m_initRequest_preferredMessageSize = *apdu->u.initRequest-> - preferredMessageSize; - *apdu->u.initRequest->preferredMessageSize = 1024*1024; - m_initRequest_maximumRecordSize = *apdu->u.initRequest-> - maximumRecordSize; - *apdu->u.initRequest->maximumRecordSize = 1024*1024; - - // Save proposal charsets and langs. - if (ODR_MASK_GET(apdu->u.initRequest->options, - Z_Options_negotiationModel)) - { - Z_CharSetandLanguageNegotiation *charSetandLangRecord = - yaz_get_charneg_record(*oi); - - yaz_get_proposal_charneg(m_referenceId_mem, - charSetandLangRecord, - &m_initRequest_oi_negotiation_charsets, - &m_initRequest_oi_negotiation_num_charsets, - &m_initRequest_oi_negotiation_langs, - &m_initRequest_oi_negotiation_num_langs, - &m_initRequest_oi_negotiation_selected); - - for (int i=0; iu.initRequest->options; - - apdu->u.initRequest->options = - (Odr_bitmask *)nmem_malloc(m_initRequest_mem, - sizeof(Odr_bitmask)); - ODR_MASK_ZERO(apdu->u.initRequest->options); - int i; - for (i = 0; i<= 24; i++) - ODR_MASK_SET(apdu->u.initRequest->options, i); - // check negotiation option - if (!ODR_MASK_GET(m_initRequest_options, - Z_Options_negotiationModel)) - { - ODR_MASK_CLEAR(apdu->u.initRequest->options, - Z_Options_negotiationModel); - } - ODR_MASK_CLEAR(apdu->u.initRequest->options, - Z_Options_concurrentOperations); - // make new version - m_initRequest_version = apdu->u.initRequest->protocolVersion; - apdu->u.initRequest->protocolVersion = - (Odr_bitmask *)nmem_malloc(m_initRequest_mem, - sizeof(Odr_bitmask)); - ODR_MASK_ZERO(apdu->u.initRequest->protocolVersion); - - for (i = 0; i<= 8; i++) - ODR_MASK_SET(apdu->u.initRequest->protocolVersion, i); - } - if (m_client->m_init_flag) - { - if (handle_init_response_for_invalid_session(apdu)) - return; - if (m_client->m_initResponse) - { - Z_APDU *apdu2 = m_client->m_initResponse; - apdu2->u.initResponse->otherInfo = 0; - if (m_client->m_cookie && *m_client->m_cookie) - set_otherInformationString(apdu2, VAL_COOKIE, 1, - m_client->m_cookie); - apdu2->u.initResponse->referenceId = - apdu->u.initRequest->referenceId; - apdu2->u.initResponse->options = m_client->m_initResponse_options; - apdu2->u.initResponse->protocolVersion = - m_client->m_initResponse_version; - - send_to_client(apdu2); - return; - } - } - m_client->m_init_flag = 1; - } - - if (!handle_authentication(apdu)) - { - Z_APDU *apdu_reject = zget_APDU(odr_encode(), Z_APDU_initResponse); - *apdu_reject->u.initResponse->result = 0; - send_to_client(apdu_reject); - - shutdown(); - return; - } + handle_init(apdu); + else + handle_incoming_Z_PDU_2(apdu); +} +void Yaz_Proxy::handle_incoming_Z_PDU_2(Z_APDU *apdu) +{ handle_max_record_retrieve(apdu); - + if (apdu) apdu = handle_syntax_validation(apdu); @@ -2787,11 +2844,12 @@ void Yaz_Proxy::handle_incoming_Z_PDU(Z_APDU *apdu) return; } // Add otherInformation entry in APDU if - // negotiatoin in use. + // negotiation is in use. if (apdu) handle_charset_lang_negotiation(apdu); // delete other info construct completely if 0 elements + Z_OtherInformation **oi; get_otherInfoAPDU(apdu, &oi); if (oi && *oi && (*oi)->num_elements == 0) *oi = 0; -- 1.7.10.4