-/* $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.
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();
-/* $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.
#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];
*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:
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)
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;
}
-/* $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.
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);
-/* $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.
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,
!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);
-/* $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.
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)
{
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;
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);