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 */
32 char clientAddr4[ADDRMAXLN]=""; /* client addr (nnn.nnn.nnn.nnn) */
33 char clientAddr6[ADDRMAXLN]=""; /* client addr (nnnn:nnnn:xxxx::xxxx) 128bit */
35 struct clientAddr *pClientAddr = NULL;
36 struct clientAddr *pLastClientAddr = 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 serverID) */
43 char serverid[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);
69 if(CheckReferer()==FALSE){
74 if(GetPostData(userid, password, clientAddr4, &duration)==FALSE){
78 /* split user@server to user and server */
79 SplitId(userid, useridshort, serverid);
81 /* read config file and setup parameters buffer */
82 CreateDbBuffer(serverid);
84 /* get address of client from getenv. it might be IPv4 or IPv6. */
85 GetClientAddr(clientAddr6);
87 /* check enable IP versions */
90 /* get MAC address from arp and ndp */
93 /* authenticate the user with authentication server */
94 if(!AuthenticateUser(useridshort, password)){
95 /* if not authenticate, send deny */
96 PutClientDeny(clientAddr4);
97 err_msg("DENY: user %s from %s at %s", userid, clientAddr4, macAddr4);
102 bzero(password, PASSMAXLN);
104 /* get user property from user database (if you edit comm-userdb.c) */
105 if(!GetUserProperty(userid, userProperty)){
106 PutClientMsg("Error: You are denied.");
107 err_msg("DENY: user %s from %s at %s (ill-property)",
108 userid, clientAddr4, macAddr4);
112 /* usage duration is restricted to permitted range */
114 duration=GetDurationDefault();
115 }else if(duration > GetDurationMax()){
116 duration=GetDurationMax();
119 /* set terminate signal handler */
120 Signal(SIGTERM, closeExit);
122 /* open firewall for the client */
123 if(OpenClientGate()==FALSE) return 0;
126 /* set (ruleNumber,userid,clientAddr) in process title */
127 if(ipStatus==IPV46DUAL){
128 setproctitle("%s(useIPv6),[%s(%s)],[%s(%s)]", useridshort, clientAddr4, ruleNumber4, clientAddr6, ruleNumber6);
129 }else if(ipStatus==IPV4ONLY){
130 setproctitle("%s,[%s(%s)]",useridshort, clientAddr4, ruleNumber4);
131 }else if(ipStatus==IPV6ONLY){
132 setproctitle("%s(useIPv6),[%s(%s)]",useridshort, clientAddr6, ruleNumber6);
135 /* get temporary port for server-listen */
136 port=GetListenPort();
138 err_msg("ERR in main: cannot get unused listen port");
139 PutClientMsg("Error: Please contact to the administrator");
144 /** parent process **/
146 PutJavaApplet(userid, port, pid, clientAddr4, clientAddr6, ipStatus);
148 /* detach from Web server */
151 /** child process **/
153 /* detach from Web server */
154 Close(0);Close(1); /* detach stdin and out pipe connected to Web */
155 Close(2); /* detach stderr */
156 Pipe(dummyfd); /* connect dummy pipe for stdin and out */
158 /* wait connection from the java applet */
159 /* if no connection, close gate when duration is passed */
160 /* or ipaddr for the macAddr4 is changed */
161 if(WaitAppletConnect(userid, clientAddr4, clientAddr6, duration, macAddr4, ipStatus, pClientAddr)==1){
163 /* wait until the user quit */
164 /* close gate when no reply to temporal hello or end of TCP connection */
165 /* macAddr6 is used for NDP to search addition ipaddr */
166 WaitClientClose(pClientAddr, userid, userProperty, macAddr6, ipStatus);
168 /* close firewall and exit */
176 /**************************************/
177 /* Open client gate for IPv4 and IPv6 */
178 /**************************************/
179 int openClientGate(void)
183 /**** if client have IPv6 & IPv4 addresses, do below */
184 if(ipStatus == IPV46DUAL){
186 /* open firewall for clientAddr4 */
187 //err_msg("START: user %s use IPv6 and IPv4 at %s", userid, macAddr4);
188 if((ret=OpenClientGate4(clientAddr4, userid, macAddr4, userProperty))<0){
190 /* overlapped rules or other */
191 PutClientMsg("Error: Please End Web and Retry");
195 /* system error raise */
196 PutClientMsg("Error: Please contact to the administrator");
200 /* open ipv4 success. write message */
201 err_msg("OPEN: user %s from %s at %s", userid, clientAddr4, macAddr4);
203 /* create new address list. head and tail pointer point the same item. */
204 pClientAddr = CreateAddrListItem(clientAddr4,ruleNumber4,IPV4);
205 pLastClientAddr = pClientAddr;
207 /* open firewall for clientAddr6 */
208 if((ret=OpenClientGate6(clientAddr6, userid, macAddr6, userProperty))<0){
210 /* overlapped rules or other */
211 PutClientMsg("Error: Please End Web and Retry");
213 /* remove registered ipv4 rule from list */
214 if(pClientAddr!=NULL){
215 if(pClientAddr->ipType==IPV4){
216 CloseClientGate4(pClientAddr,userid,macAddr4);
225 /* system error raise */
226 PutClientMsg("Error: Please contact to the administrator");
230 /* open ipv6 success, write message */
231 err_msg("OPEN: user %s from %s at %s", userid, clientAddr6, macAddr6);
233 /* add the address info to list */
234 pLastClientAddr->next = CreateAddrListItem(clientAddr6,ruleNumber6,IPV6);
237 /***** if client have IPv4 only, do below */
238 }else if(ipStatus==IPV4ONLY){
239 //err_msg("START: user %s use IPv4(IPv6) at %s", userid, macAddr4);
241 if((ret=OpenClientGate4(clientAddr4, userid, macAddr4, userProperty))<0){
242 PutClientMsg("Error: Please End Web and Retry");
246 PutClientMsg("Error: Please contact to the administrator");
249 err_msg("OPEN: user %s from %s at %s", userid, clientAddr4, macAddr4);
251 /* create new address list. head and tail pointer point the same item. */
252 pClientAddr = CreateAddrListItem(clientAddr4,ruleNumber4,IPV4);
253 pLastClientAddr = pClientAddr;
255 /***** if client have IPv6 only, do below */
256 }else if(ipStatus==IPV6ONLY){
257 //err_msg("START: user %s use IPv6 at %s", userid, macAddr6);
259 if((ret=OpenClientGate6(clientAddr6, userid, macAddr6, userProperty))<0){
260 PutClientMsg("Error: Please End Web and Retry");
264 PutClientMsg("Error: Please contact to the administrator");
268 err_msg("OPEN: user %s from %s at %s", userid, clientAddr6, macAddr6);
270 /* create new address list. head and tail pointer point the same item. */
271 pClientAddr = CreateAddrListItem(clientAddr4,ruleNumber4,IPV4);
272 pLastClientAddr = pClientAddr;
277 /*******************************************/
278 /* calc connection duration and put it out */
279 /*******************************************/
280 void putCloseMsg(time_t timeOut, time_t timeIn)
285 time=difftime(timeOut,timeIn);
287 min=(time-hour*60*60)/60;
288 sec=(time-hour*60*60-min*60);
289 //err_msg("STOP: user %s at %s ( %02d:%02d:%02d )", userid, macAddr4, hour,min,sec);
293 /*****************************/
294 /* Check enable IP versions */
295 /*****************************/
297 void checkIpVersions(void){
299 if(strstr(clientAddr4,".")!=NULL){
300 if(strstr(clientAddr6,":")!=NULL){
301 ipStatus = IPV46DUAL;
306 if(strstr(clientAddr6,":")!=NULL){
309 err_msg("ERR in main: Can not get IP for user %s v4:%s v6:%s", userid,clientAddr4,clientAddr6);
310 PutClientMsg("Error: Please contact to the administrator");
316 /********************/
317 /* Get Mac Address */
318 /********************/
319 void getMacAddr(void)
321 if(GetEnableMacAddr()==1){
323 if(ipStatus==IPV46DUAL){
324 GetMacAddrFromArp(clientAddr4, macAddr4);
325 GetMacAddrFromNdp(clientAddr6,macAddr6);
327 }else if(ipStatus==IPV4ONLY){
328 GetMacAddrFromArp(clientAddr4, macAddr4);
329 ReFormatMacAddr(macAddr4,macAddr6);
332 GetMacAddrFromNdp(clientAddr6, macAddr6);
338 /*********************************/
339 /* format macAddr for ndp or arp */
340 /*********************************/
341 void reFormatMacAddr(char* macAddr4, char* macAddr6)
345 char buf[ADDRMAXLN] = "";
346 char nullstr[ADDRMAXLN] = "";
348 strcpy(macAddr6,nullstr);
349 strcpy(buf,macAddr4);
350 strp=strtok(buf,delims);
352 if(strncmp(strp,"0",1)==0){
354 strcat(macAddr6,strp);
356 strcat(macAddr6,strp);
358 strp=strtok(NULL,delims);
360 strcat(macAddr6,delims);
361 if(strncmp(strp,"0",1)==0){
363 strcat(macAddr6,strp);
365 strcat(macAddr6,strp);
367 strp=strtok(NULL,delims);
371 /*****************************/
372 /* At termination, call this */
373 /*****************************/
374 void closeExit(int signo)
376 /* signal is disabled */
377 Signal(SIGTERM, SIG_DFL);
379 /* send quit message to client java */
382 /* close firewalls */
383 while(pClientAddr!=NULL){
384 if(pClientAddr->ipType==IPV4){
385 CloseClientGate4(pClientAddr,useridshort,macAddr4);
387 CloseClientGate6(pClientAddr,useridshort,macAddr6);
388 DeleteNdpEntry(pClientAddr->ipAddr);
390 pClientAddr = pClientAddr->next;
395 PutCloseMsg(timeOut,timeIn);
396 if(DEBUG) err_msg("DEBUG:terminated");
400 /*****************************/
401 /*****************************/
402 int OpenClientGate(void)
405 if(DEBUG) err_msg("DEBUG:=>openClientGate( )");
406 ret = openClientGate();
407 if(DEBUG) err_msg("DEBUG:(%d)<=openClientGate()",ret);
411 void PutCloseMsg(time_t timeOut, time_t timeIn)
413 if(DEBUG) err_msg("DEBUG:=>putCloseMsg( )");
414 putCloseMsg(timeOut,timeIn);
415 if(DEBUG) err_msg("DEBUG:<=putCloseMsg( )");
418 void ReFormatMacAddr(char* macAddr4, char* macAddr6)
420 if(DEBUG) err_msg("DEBUG:=>reFormatMacAddr(%s)", macAddr4);
421 reFormatMacAddr(macAddr4, macAddr6);
422 if(DEBUG) err_msg("DEBUG:<=reFormatMacAddr(%s)", macAddr6);
425 void GetMacAddr(void)
427 if(DEBUG) err_msg("DEBUG:=>getMacAddr( )");
429 if(DEBUG) err_msg("DEBUG:<=getMacAddr( )");
432 void CheckIpVersions(void)
434 if(DEBUG) err_msg("DEBUG:=>checkIpVersions( )");
436 if(DEBUG) err_msg("DEBUG:<=checkIpversions( )");