1 /* $Id: mod_helsinki.cpp,v 1.1 2006-03-25 10:56:28 adam Exp $
2 Copyright (c) 1998-2005, Index Data.
4 This file is part of the yaz-proxy.
6 YAZ proxy is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 2, or (at your option) any later
11 YAZ proxy is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with YAZ proxy; see the file LICENSE. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
26 #include <yazproxy/module.h>
33 #include <libxml/parser.h>
34 #include <libxml/tree.h>
35 #include <libxml/xinclude.h>
36 #include <libxslt/xsltutils.h>
37 #include <libxslt/transform.h>
42 unsigned int a1, a2, a3, a4;
47 return 0; // no private data for handler
50 void my_destroy(void *p)
52 // private data destroy
55 void zero_address(IP_ADDRESS *addr)
57 addr->a1 = addr->a2 = addr->a3 = addr->a4 = 0;
60 int str_to_address(const char *str, IP_ADDRESS *addr)
63 return sscanf(str, "%3u.%3u.%3u.%3u", &addr->a1, &addr->a2, &addr->a3, &addr->a4);
66 void str_to_address_range(const char *str,
73 int num = sscanf(str, "%15[^-]-%15s", lo, hi);
77 // Create a range from a single address or a part of it (e.g. 192.168)
78 num = str_to_address(lo, range_lo);
81 range_hi->a1 = range_lo->a1;
82 range_hi->a2 = range_hi->a3 = range_hi->a4 = 255;
86 range_hi->a1 = range_lo->a1;
87 range_hi->a2 = range_lo->a2;
88 range_hi->a3 = range_hi->a4 = 255;
92 range_hi->a1 = range_lo->a1;
93 range_hi->a2 = range_lo->a2;
94 range_hi->a3 = range_lo->a3;
99 range_hi->a1 = range_lo->a1;
100 range_hi->a2 = range_lo->a2;
101 range_hi->a3 = range_lo->a3;
102 range_hi->a4 = range_lo->a4;
107 // If a range is specified, both ends need to be full addresses
108 if (str_to_address(lo, range_lo) != 4 || str_to_address(hi, range_hi) != 4)
110 zero_address(range_lo);
111 zero_address(range_hi);
115 unsigned int address_to_int(IP_ADDRESS addr)
117 return addr.a1 << 24 | addr.a2 << 16 | addr.a3 << 8 | addr.a4;
120 int my_authenticate(void *user_handle,
121 const char *target_name,
123 const char *user, const char *group, const char *password,
126 // see if we have an "args" attribute
127 const char *args = 0;
129 xmlNodePtr ptr = (xmlNodePtr) element_ptr;
130 struct _xmlAttr *attr;
132 for (attr = ptr->properties; attr; attr = attr->next)
134 if (!strcmp((const char *) attr->name, "args") &&
135 attr->children && attr->children->type == XML_TEXT_NODE)
136 args = (const char *) attr->children->content;
139 // args holds args (or NULL if none are provided)
141 yaz_log(YLOG_LOG, "Authentication: authenticating user %s, address %s", user ? user : "-", peer_IP ? peer_IP : "-");
143 // authentication handler
144 char user_file[255], ip_file[255];
147 sscanf(args, "%254[^:]:%254s", user_file, ip_file);
149 yaz_log(YLOG_LOG, "Authentication: user file: %s, ip file: %s", user_file, ip_file);
151 // Check if the IP address is listed in the file of allowed address ranges.
152 // The format of the file:
155 // 192.168.0.1-192.168.0.200
156 int status = YAZPROXY_RET_PERM;
157 if (ip_file && peer_IP)
159 yaz_log(YLOG_LOG, "Authentication: checking ip address");
161 const char *pIP = peer_IP;
162 if (strncmp(pIP, "tcp:", 4) == 0)
164 IP_ADDRESS peer_address;
165 if (str_to_address(pIP, &peer_address) != 4)
166 yaz_log(YLOG_WARN, "Authentication: could not decode peer IP address %s properly", pIP);
167 unsigned int peer_address_int = address_to_int(peer_address);
169 FILE *f = fopen(ip_file, "r");
172 yaz_log(YLOG_WARN, "Authentication: could not open ip authentication file %s", ip_file);
173 return YAZPROXY_RET_PERM;
183 char *comment_pos = strchr(line, '#');
187 IP_ADDRESS range_lo, range_hi;
188 str_to_address_range(line, &range_lo, &range_hi);
189 if (address_to_int(range_lo) <= peer_address_int && peer_address_int <= address_to_int(range_hi))
191 status = YAZPROXY_RET_OK;
196 if (status == YAZPROXY_RET_OK)
198 yaz_log(YLOG_LOG, "Authentication: IP address %s allowed", pIP);
199 return YAZPROXY_RET_OK;
203 if (!user || !password || !*user_file)
205 yaz_log(YLOG_WARN, "Authentication: no user name, password or user file specified");
206 return YAZPROXY_RET_PERM;
211 struct tm *local_time = localtime(¤t_time);
212 char current_date[10];
213 sprintf(current_date, "%04d%02d%02d", local_time->tm_year + 1900, local_time->tm_mon + 1, local_time->tm_mday);
215 FILE *f = fopen(user_file, "r");
218 yaz_log(YLOG_WARN, "Authentication: could not open user authentication file %s", user_file);
219 return YAZPROXY_RET_PERM;
227 char *p = strchr(line, '\n');
230 char f_user[255], f_password[255], f_expiry[255];
234 sscanf(line, "%254[^:]:%254[^:]:%254s", f_user, f_password, f_expiry);
236 if (strcmp(user, f_user) == 0 && strcmp(password, f_password) == 0 && (!*f_expiry || strcmp(current_date, f_expiry) <= 0))
238 status = YAZPROXY_RET_OK;
243 yaz_log(YLOG_LOG, "Authentication: %s for user %s", status == YAZPROXY_RET_OK ? "successful" : "failed", user);
247 Yaz_ProxyModule_int0 interface0 = {
253 Yaz_ProxyModule_entry yazproxy_module = {
254 0, // interface version
256 "Helsinki Module for YAZ Proxy",// description
263 * indent-tabs-mode: nil
265 * vim: shiftwidth=4 tabstop=8 expandtab