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;
37 char macAddr4[ADDRMAXLN]="?"; /* client MAC address (format for arp) */
38 char macAddr6[ADDRMAXLN]="?"; /* client MAC address (format for ndp) */
40 char userid[USERMAXLN];
41 char useridshort[USERMAXLN];/* userID before @ mark(cut off serverID) */
42 char serverid[USERMAXLN];
43 char userProperty[BUFFMAXLN];
44 time_t timeIn, timeOut;
46 void PutCloseMsg(time_t timeOut, time_t timeIn);
47 void ReFormatMacAddr(char* macAddr4, char* macAddr6);
48 void GetMacAddr(void);
49 void CheckIpVersions(void);
50 void closeExit(int signo);
52 /***************************************************/
53 /* main routine called as cgi from Web server */
54 /***************************************************/
55 int main(int argc, char **argv)
57 char password[PASSMAXLN];
61 int duration; /* requested usage duration */
63 /* prepare config file */
67 errToSyslog(atoi(GetConfValue("Syslog/Enable")));
68 openlog(argv[0], LOG_PID, atoi(GetConfValue("Syslog/Facility")));
71 if(CheckReferer()==FALSE){
76 if(GetPostData(userid, password, clientAddr4, &duration)==FALSE){
80 /* split user@server to user and server */
81 SplitId(userid, useridshort, serverid);
83 /* setup ID for config file */
84 SetupConfId(serverid);
86 /* get address of client from getenv. it might be IPv4 or IPv6. */
87 GetClientAddr(clientAddr6);
89 /* check enable IP versions */
92 /* get MAC address from arp and ndp */
95 /* authenticate the user with authentication server */
96 if(!AuthenticateUser(useridshort, password)){
97 /* if not authenticate, send deny */
98 PutClientDeny(clientAddr4);
99 err_msg("DENY: user %s from %s at %s", userid, clientAddr4, macAddr4);
104 bzero(password, PASSMAXLN);
106 /* get user property from user database (if you edit comm-userdb.c) */
107 if(!GetUserProperty(userid, userProperty)){
108 PutClientMsg("Error: You are denied.");
109 err_msg("DENY: user %s from %s at %s (ill-property)",
110 userid, clientAddr4, macAddr4);
114 /* usage duration is restricted to permitted range */
116 duration=atoi(GetConfValue("Duration/Default"));
118 int durmax=atoi(GetConfValue("Duration/Max"));
119 if(duration > durmax){
123 /* set terminate signal handler */
124 Signal(SIGTERM, closeExit);
126 /* open firewall for the client */
127 if(OpenClientGate()==FALSE) return 0;
130 /* set (ruleNumber,userid,clientAddr) in process title */
131 if(ipStatus==IPV46DUAL){
132 setproctitle("%s(useIPv6),[%s(%s)],[%s(%s)]", useridshort, clientAddr4, ruleNumber4, clientAddr6, ruleNumber6);
133 }else if(ipStatus==IPV4ONLY){
134 setproctitle("%s,[%s(%s)],",useridshort, clientAddr4, ruleNumber4);
135 }else if(ipStatus==IPV6ONLY){
136 setproctitle("%s(useIPv6),,[%s(%s)]",useridshort, clientAddr6, ruleNumber6);
139 /* get temporary port for server-listen */
140 port=GetListenPort();
142 err_msg("ERR in main: cannot get unused listen port");
143 PutClientMsg("Error: Please contact to the administrator");
148 /** parent process **/
150 PutJavaApplet(userid, port, pid, clientAddr4, clientAddr6, ipStatus);
152 /* detach from Web server */
155 /** child process **/
157 /* detach from Web server */
158 Close(0);Close(1); /* detach stdin and out pipe connected to Web */
159 Close(2); /* detach stderr */
160 Pipe(dummyfd); /* connect dummy pipe for stdin and out */
162 /* wait connection from the java applet */
163 /* if no connection, close gate when duration is passed */
164 /* or ipaddr for the macAddr4 is changed */
165 if(WaitAppletConnect(userid, clientAddr4, clientAddr6, duration, macAddr4, ipStatus, pClientAddr)==1){
167 /* wait until the user quit */
168 /* close gate when no reply to temporal hello or end of TCP connection */
169 /* macAddr6 is used for NDP to search addition ipaddr */
170 WaitClientClose(pClientAddr, userid, userProperty, macAddr6, ipStatus);
172 /* close firewall and exit */
180 /**************************************/
181 /* Open client gate for IPv4 and IPv6 */
182 /**************************************/
183 int openClientGate(void)
186 struct clientAddr *pLastClientAddr = NULL;
188 /**** if client have IPv6 & IPv4 addresses, do below */
189 if(ipStatus == IPV46DUAL){
191 /* open firewall for clientAddr4 */
192 //err_msg("START: user %s use IPv6 and IPv4 at %s", userid, macAddr4);
193 if((ret=OpenClientGate4(clientAddr4, userid, macAddr4, userProperty))<0){
195 /* overlapped rules or other */
196 PutClientMsg("Error: Please End Web and Retry");
200 /* system error raise */
201 PutClientMsg("Error: Please contact to the administrator");
205 /* open ipv4 success. write message */
206 err_msg("OPEN: user %s from %s at %s", userid, clientAddr4, macAddr4);
208 /* create new address list. head and tail pointer point the same item. */
209 pClientAddr = CreateAddrListItem(clientAddr4,ruleNumber4,IPV4);
210 pLastClientAddr = pClientAddr;
212 /* open firewall for clientAddr6 */
213 if((ret=OpenClientGate6(clientAddr6, userid, macAddr6, userProperty))<0){
215 /* overlapped rules or other */
216 PutClientMsg("Error: Please End Web and Retry");
218 /* remove registered ipv4 rule from list */
219 if(pClientAddr!=NULL){
220 if(pClientAddr->ipType==IPV4){
221 CloseClientGate4(pClientAddr,userid,macAddr4);
230 /* system error raise */
231 PutClientMsg("Error: Please contact to the administrator");
235 /* open ipv6 success, write message */
236 err_msg("OPEN: user %s from %s at %s", userid, clientAddr6, macAddr6);
238 /* add the address info to list */
239 pLastClientAddr->next = CreateAddrListItem(clientAddr6,ruleNumber6,IPV6);
242 /***** if client have IPv4 only, do below */
243 }else if(ipStatus==IPV4ONLY){
244 //err_msg("START: user %s use IPv4 at %s", userid, macAddr4);
246 if((ret=OpenClientGate4(clientAddr4, userid, macAddr4, userProperty))<0){
247 PutClientMsg("Error: Please End Web and Retry");
251 PutClientMsg("Error: Please contact to the administrator");
254 err_msg("OPEN: user %s from %s at %s", userid, clientAddr4, macAddr4);
256 /* create new address list. head and tail pointer point the same item. */
257 pClientAddr = CreateAddrListItem(clientAddr4,ruleNumber4,IPV4);
258 pLastClientAddr = pClientAddr;
260 /***** if client have IPv6 only, do below */
261 }else if(ipStatus==IPV6ONLY){
262 //err_msg("START: user %s use IPv6 at %s", userid, macAddr6);
264 if((ret=OpenClientGate6(clientAddr6, userid, macAddr6, userProperty))<0){
265 PutClientMsg("Error: Please End Web and Retry");
269 PutClientMsg("Error: Please contact to the administrator");
273 err_msg("OPEN: user %s from %s at %s", userid, clientAddr6, macAddr6);
275 /* create new address list. head and tail pointer point the same item. */
276 pClientAddr = CreateAddrListItem(clientAddr4,ruleNumber4,IPV4);
277 pLastClientAddr = pClientAddr;
282 /*******************************************/
283 /* calc connection duration and put it out */
284 /*******************************************/
285 void putCloseMsg(time_t timeOut, time_t timeIn)
290 time=difftime(timeOut,timeIn);
292 min=(time-hour*60*60)/60;
293 sec=(time-hour*60*60-min*60);
294 //err_msg("STOP: user %s at %s ( %02d:%02d:%02d )", userid, macAddr4, hour,min,sec);
298 /*****************************/
299 /* Check enable IP versions */
300 /*****************************/
302 void checkIpVersions(void){
304 if(strstr(clientAddr4,".")!=NULL){
305 if(strstr(clientAddr6,":")!=NULL){
306 ipStatus = IPV46DUAL;
311 if(strstr(clientAddr6,":")!=NULL){
314 err_msg("ERR in main: Can not get IP for user %s v4:%s v6:%s", userid,clientAddr4,clientAddr6);
315 PutClientMsg("Error: Please contact to the administrator");
321 /********************/
322 /* Get Mac Address */
323 /********************/
324 void getMacAddr(void)
327 if(ipStatus==IPV46DUAL){
328 GetMacAddrFromArp(clientAddr4, macAddr4);
329 GetMacAddrFromNdp(clientAddr6,macAddr6);
331 }else if(ipStatus==IPV4ONLY){
332 GetMacAddrFromArp(clientAddr4, macAddr4);
333 ReFormatMacAddr(macAddr4,macAddr6);
336 GetMacAddrFromNdp(clientAddr6, macAddr6);
342 /*********************************/
343 /* format macAddr for ndp or arp */
344 /*********************************/
345 void reFormatMacAddr(char* macAddr4, char* macAddr6)
349 char buf[ADDRMAXLN] = "";
350 char nullstr[ADDRMAXLN] = "";
352 strcpy(macAddr6,nullstr);
353 strcpy(buf,macAddr4);
354 strp=strtok(buf,delims);
356 if(strncmp(strp,"0",1)==0){
358 strcat(macAddr6,strp);
360 strcat(macAddr6,strp);
362 strp=strtok(NULL,delims);
364 strcat(macAddr6,delims);
365 if(strncmp(strp,"0",1)==0){
367 strcat(macAddr6,strp);
369 strcat(macAddr6,strp);
371 strp=strtok(NULL,delims);
375 /*****************************/
376 /* At termination, call this */
377 /*****************************/
378 void closeExit(int signo)
380 /* signal is disabled */
381 Signal(SIGTERM, SIG_DFL);
383 /* send quit message to client java */
386 /* close firewalls */
387 while(pClientAddr!=NULL){
388 if(pClientAddr->ipType==IPV4){
389 CloseClientGate4(pClientAddr,useridshort,macAddr4);
391 CloseClientGate6(pClientAddr,useridshort,macAddr6);
392 DeleteNdpEntry(pClientAddr->ipAddr);
394 pClientAddr = pClientAddr->next;
399 PutCloseMsg(timeOut,timeIn);
400 if(debug) err_msg("DEBUG:terminated");
402 /* release the conf file area */
408 /*****************************/
409 /*****************************/
410 int OpenClientGate(void)
413 if(debug) err_msg("DEBUG:=>openClientGate( )");
414 ret = openClientGate();
415 if(debug) err_msg("DEBUG:(%d)<=openClientGate()",ret);
419 void PutCloseMsg(time_t timeOut, time_t timeIn)
421 if(debug) err_msg("DEBUG:=>putCloseMsg( )");
422 putCloseMsg(timeOut,timeIn);
423 if(debug) err_msg("DEBUG:<=putCloseMsg( )");
426 void ReFormatMacAddr(char* macAddr4, char* macAddr6)
428 if(debug) err_msg("DEBUG:=>reFormatMacAddr(%s)", macAddr4);
429 reFormatMacAddr(macAddr4, macAddr6);
430 if(debug) err_msg("DEBUG:<=reFormatMacAddr(%s)", macAddr6);
433 void GetMacAddr(void)
435 if(debug) err_msg("DEBUG:=>getMacAddr( )");
437 if(debug) err_msg("DEBUG:<=getMacAddr( )");
440 void CheckIpVersions(void)
442 if(debug) err_msg("DEBUG:=>checkIpVersions( )");
444 if(debug) err_msg("DEBUG:<=checkIpversions( )");