1 /**************************************************
4 Copyright (C) 1999 Opengate Project Team
5 Written by Yoshiaki Watanabe
6 Modified Katsuhiko Eguchi, 2005
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 Email: watanaby@is.saga-u.ac.jp
23 **************************************************/
25 #include "opengatesrv.h"
27 int ipStatus; /* flag for IPv4 or IPv6 */
29 extern char ruleNumber4[WORDMAXLN]; /* ipfw rule number in string form */
30 extern char ruleNumber6[WORDMAXLN]; /* ip6fw rule number in string form */
31 extern char language[WORDMAXLN];
33 char clientAddr4[ADDRMAXLN]=""; /* client addr (nnn.nnn.nnn.nnn) */
34 char clientAddr6[ADDRMAXLN]=""; /* client addr (nnnn:nnnn:xxxx::xxxx) 128bit */
36 struct clientAddr *pClientAddr = NULL;
38 char macAddr4[ADDRMAXLN]="?"; /* client MAC address (format for arp) */
39 char macAddr6[ADDRMAXLN]="?"; /* client MAC address (format for ndp) */
41 char userid[USERMAXLN];
42 char useridshort[USERMAXLN];/* userID before @ mark(cut off extraID) */
43 char extraId[USERMAXLN];
44 char userProperty[BUFFMAXLN];
45 time_t timeIn, timeOut;
47 void PutCloseMsg(time_t timeOut, time_t timeIn);
48 void ReFormatMacAddr(char* macAddr4, char* macAddr6);
49 void GetMacAddr(void);
50 void CheckIpVersions(void);
51 void closeExit(int signo);
53 /***************************************************/
54 /* main routine called as cgi from Web server */
55 /***************************************************/
56 int main(int argc, char **argv)
58 char password[PASSMAXLN];
62 int duration; /* requested usage duration */
65 errToSyslog(ERRORTOSYSLOG); /* output of err_xxx() to syslogd */
66 openlog(argv[0], LOG_PID, FACILITY);
68 /* prepare config file */
71 /* get default language at the top of lang list */
72 sscanf(GetConfValue("HtmlLangs"), "%s", language);
75 if(CheckReferer()==FALSE){
76 PutClientRetry(language);
82 if(GetPostData(userid, password, clientAddr4, &duration)==FALSE){
83 PutClientRetry(language);
88 /* split user@server to user and server */
89 SplitId(userid, useridshort, extraId);
91 /* setup ID for config file */
94 /* get address of client from getenv. it might be IPv4 or IPv6. */
95 GetClientAddr(clientAddr6);
97 /* check enable IP versions */
100 /* get MAC address from arp and ndp */
103 /* authenticate the user with authentication server */
104 if(!AuthenticateUser(useridshort, password)){
105 /* if not authenticate, send deny */
107 err_msg("DENY: user %s from %s at %s", userid, clientAddr4, macAddr4);
112 bzero(password, PASSMAXLN);
114 /* get user property from user database (if you edit comm-userdb.c) */
115 if(!GetUserProperty(userid, userProperty)){
116 PutClientMsg("Error: You are denied.");
117 err_msg("DENY: user %s from %s at %s (ill-property)",
118 userid, clientAddr4, macAddr4);
122 /* usage duration is restricted to permitted range */
124 duration=atoi(GetConfValue("Duration/Default"));
126 int durmax=atoi(GetConfValue("Duration/Max"));
127 if(duration > durmax){
131 /* set terminate signal handler */
132 Signal(SIGTERM, closeExit);
134 /* open firewall for the client */
135 if(OpenClientGate()==FALSE) return 0;
138 /* set (ruleNumber,userid,clientAddr) in process title */
139 if(ipStatus==IPV46DUAL){
140 setproctitle("%s(useIPv6),[%s(%s)],[%s(%s)]", useridshort, clientAddr4, ruleNumber4, clientAddr6, ruleNumber6);
141 }else if(ipStatus==IPV4ONLY){
142 setproctitle("%s,[%s(%s)],",useridshort, clientAddr4, ruleNumber4);
143 }else if(ipStatus==IPV6ONLY){
144 setproctitle("%s(useIPv6),,[%s(%s)]",useridshort, clientAddr6, ruleNumber6);
147 /* get temporary port for server-listen */
148 port=GetListenPort();
150 err_msg("ERR in main: cannot get unused listen port");
151 PutClientMsg("Error: Please contact to the administrator");
156 /** parent process **/
158 PutJavaApplet(userid, port, pid, clientAddr4, clientAddr6, ipStatus);
160 /* detach from Web server */
163 /** child process **/
165 /* detach from Web server */
166 Close(0);Close(1); /* detach stdin and out pipe connected to Web */
167 Close(2); /* detach stderr */
168 Pipe(dummyfd); /* connect dummy pipe for stdin and out */
170 /* wait connection from the java applet */
171 /* if no connection, close gate when duration is passed */
172 /* or ipaddr for the macAddr4 is changed */
173 if(WaitAppletConnect(userid, clientAddr4, clientAddr6, duration, macAddr4, ipStatus, pClientAddr)==1){
175 /* wait until the user quit */
176 /* close gate when no reply to temporal hello or end of TCP connection */
177 /* macAddr6 is used for NDP to search addition ipaddr */
178 WaitClientClose(pClientAddr, userid, userProperty, macAddr6, ipStatus);
180 /* close firewall and exit */
188 /**************************************/
189 /* Open client gate for IPv4 and IPv6 */
190 /**************************************/
191 int openClientGate(void)
194 struct clientAddr *pLastClientAddr = NULL;
196 /**** if client have IPv6 & IPv4 addresses, do below */
197 if(ipStatus == IPV46DUAL){
199 /* open firewall for clientAddr4 */
200 //err_msg("START: user %s use IPv6 and IPv4 at %s", userid, macAddr4);
201 if((ret=OpenClientGate4(clientAddr4, userid, macAddr4, userProperty))<0){
203 /* overlapped rules or other */
204 PutClientMsg("Error: Please End Web and Retry");
208 /* system error raise */
209 PutClientMsg("Error: Please contact to the administrator");
213 /* open ipv4 success. write message */
214 err_msg("OPEN: user %s from %s at %s", userid, clientAddr4, macAddr4);
216 /* create new address list. head and tail pointer point the same item. */
217 pClientAddr = CreateAddrListItem(clientAddr4,ruleNumber4,IPV4);
218 pLastClientAddr = pClientAddr;
220 /* open firewall for clientAddr6 */
221 if((ret=OpenClientGate6(clientAddr6, userid, macAddr6, userProperty))<0){
223 /* overlapped rules or other */
224 PutClientMsg("Error: Please End Web and Retry");
226 /* remove registered ipv4 rule from list */
227 if(pClientAddr!=NULL){
228 if(pClientAddr->ipType==IPV4){
229 CloseClientGate4(pClientAddr,userid,macAddr4);
238 /* system error raise */
239 PutClientMsg("Error: Please contact to the administrator");
243 /* open ipv6 success, write message */
244 err_msg("OPEN: user %s from %s at %s", userid, clientAddr6, macAddr6);
246 /* add the address info to list */
247 pLastClientAddr->next = CreateAddrListItem(clientAddr6,ruleNumber6,IPV6);
250 /***** if client have IPv4 only, do below */
251 }else if(ipStatus==IPV4ONLY){
252 //err_msg("START: user %s use IPv4 at %s", userid, macAddr4);
254 if((ret=OpenClientGate4(clientAddr4, userid, macAddr4, userProperty))<0){
255 PutClientMsg("Error: Please End Web and Retry");
259 PutClientMsg("Error: Please contact to the administrator");
262 err_msg("OPEN: user %s from %s at %s", userid, clientAddr4, macAddr4);
264 /* create new address list. head and tail pointer point the same item. */
265 pClientAddr = CreateAddrListItem(clientAddr4,ruleNumber4,IPV4);
266 pLastClientAddr = pClientAddr;
268 /***** if client have IPv6 only, do below */
269 }else if(ipStatus==IPV6ONLY){
270 //err_msg("START: user %s use IPv6 at %s", userid, macAddr6);
272 if((ret=OpenClientGate6(clientAddr6, userid, macAddr6, userProperty))<0){
273 PutClientMsg("Error: Please End Web and Retry");
277 PutClientMsg("Error: Please contact to the administrator");
281 err_msg("OPEN: user %s from %s at %s", userid, clientAddr6, macAddr6);
283 /* create new address list. head and tail pointer point the same item. */
284 pClientAddr = CreateAddrListItem(clientAddr4,ruleNumber4,IPV4);
285 pLastClientAddr = pClientAddr;
290 /*******************************************/
291 /* calc connection duration and put it out */
292 /*******************************************/
293 void putCloseMsg(time_t timeOut, time_t timeIn)
298 time=difftime(timeOut,timeIn);
300 min=(time-hour*60*60)/60;
301 sec=(time-hour*60*60-min*60);
302 //err_msg("STOP: user %s at %s ( %02d:%02d:%02d )", userid, macAddr4, hour,min,sec);
306 /*****************************/
307 /* Check enable IP versions */
308 /*****************************/
310 void checkIpVersions(void){
312 if(strstr(clientAddr4,".")!=NULL){
313 if(strstr(clientAddr6,":")!=NULL){
314 ipStatus = IPV46DUAL;
319 if(strstr(clientAddr6,":")!=NULL){
322 err_msg("ERR in main: Can not get IP for user %s v4:%s v6:%s", userid,clientAddr4,clientAddr6);
323 PutClientMsg("Error: Please contact to the administrator");
329 /********************/
330 /* Get Mac Address */
331 /********************/
332 void getMacAddr(void)
335 if(ipStatus==IPV46DUAL){
336 GetMacAddrFromArp(clientAddr4, macAddr4);
337 GetMacAddrFromNdp(clientAddr6,macAddr6);
339 }else if(ipStatus==IPV4ONLY){
340 GetMacAddrFromArp(clientAddr4, macAddr4);
341 ReFormatMacAddr(macAddr4,macAddr6);
344 GetMacAddrFromNdp(clientAddr6, macAddr6);
350 /**********************************/
351 /* format macAddr for ndp or arp */
352 /* match the form of two program */
353 /* mac addr by arp 00:01:12:0b:.. */
354 /* mac addr by ndp 0:1:12:b:.. */
355 /**********************************/
356 void reFormatMacAddr(char* macAddr4, char* macAddr6)
360 char buf[ADDRMAXLN] = "";
363 strcpy(buf,macAddr4);
364 strp=strtok(buf,delims);
366 if(strncmp(strp,"0",1)==0){
368 strcat(macAddr6,strp);
370 strcat(macAddr6,strp);
373 strp=strtok(NULL,delims);
375 strcat(macAddr6,delims);
376 if(strncmp(strp,"0",1)==0){
378 strcat(macAddr6,strp);
380 strcat(macAddr6,strp);
382 strp=strtok(NULL,delims);
386 /*****************************/
387 /* At termination, call this */
388 /*****************************/
389 void closeExit(int signo)
391 /* signal is disabled */
392 Signal(SIGTERM, SIG_DFL);
394 /* send quit message to client java */
397 /* close firewalls */
398 while(pClientAddr!=NULL){
399 if(pClientAddr->ipType==IPV4){
400 CloseClientGate4(pClientAddr,useridshort,macAddr4);
402 CloseClientGate6(pClientAddr,useridshort,macAddr6);
403 DeleteNdpEntry(pClientAddr->ipAddr);
405 pClientAddr = pClientAddr->next;
410 PutCloseMsg(timeOut,timeIn);
411 if(debug) err_msg("DEBUG:terminated");
413 /* release the conf file area */
419 /*****************************/
420 /*****************************/
421 int OpenClientGate(void)
424 if(debug) err_msg("DEBUG:=>openClientGate( )");
425 ret = openClientGate();
426 if(debug) err_msg("DEBUG:(%d)<=openClientGate()",ret);
430 void PutCloseMsg(time_t timeOut, time_t timeIn)
432 if(debug) err_msg("DEBUG:=>putCloseMsg( )");
433 putCloseMsg(timeOut,timeIn);
434 if(debug) err_msg("DEBUG:<=putCloseMsg( )");
437 void ReFormatMacAddr(char* macAddr4, char* macAddr6)
439 if(debug) err_msg("DEBUG:=>reFormatMacAddr(%s)", macAddr4);
440 reFormatMacAddr(macAddr4, macAddr6);
441 if(debug) err_msg("DEBUG:<=reFormatMacAddr(%s)", macAddr6);
444 void GetMacAddr(void)
446 if(debug) err_msg("DEBUG:=>getMacAddr( )");
448 if(debug) err_msg("DEBUG:<=getMacAddr( )");
451 void CheckIpVersions(void)
453 if(debug) err_msg("DEBUG:=>checkIpVersions( )");
455 if(debug) err_msg("DEBUG:<=checkIpversions( )");