OSDN Git Service

Ver.1.3.5: Modify documents. Add time info in addr encoding. Add retry info page.
[opengate/opengate.git] / opengate / opengatesrv / main.c
1 /**************************************************
2 opengate server main
3
4 Copyright (C) 1999 Opengate Project Team
5 Written by Yoshiaki Watanabe
6 Modified Katsuhiko Eguchi, 2005 
7
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.
12
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.
17
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.
21
22 Email: watanaby@is.saga-u.ac.jp
23 **************************************************/
24
25 #include        "opengatesrv.h"
26
27 int ipStatus;              /* flag for IPv4 or IPv6 */
28
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];
32
33 char clientAddr4[ADDRMAXLN]="";  /* client addr (nnn.nnn.nnn.nnn) */
34 char clientAddr6[ADDRMAXLN]="";  /* client addr (nnnn:nnnn:xxxx::xxxx) 128bit */
35
36 struct clientAddr *pClientAddr = NULL;
37
38 char macAddr4[ADDRMAXLN]="?";    /* client MAC address (format for arp) */
39 char macAddr6[ADDRMAXLN]="?";    /* client MAC address (format for ndp) */
40
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;
46
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);
52
53 /***************************************************/
54 /*  main routine called as cgi from Web server     */
55 /***************************************************/
56 int  main(int argc, char **argv)
57 {
58   char password[PASSMAXLN];
59   int port;
60   int dummyfd[2];
61   int pid;
62   int duration;     /* requested usage duration */
63
64   /* start log */
65   errToSyslog(ERRORTOSYSLOG);     /* output of err_xxx() to syslogd */
66   openlog(argv[0], LOG_PID, FACILITY);
67
68   /* prepare config file */
69   OpenConfFile();
70  
71   /* get default language at the top of lang list */
72   sscanf(GetConfValue("HtmlLangs"), "%s", language);
73
74  /* check referer */
75   if(CheckReferer()==FALSE){
76     PutClientRetry(language);
77     CloseConfFile();
78     return 0;
79   }
80
81   /* get POST data */
82   if(GetPostData(userid, password, clientAddr4, &duration)==FALSE){
83     PutClientRetry(language);
84     CloseConfFile();
85     return 0;
86   }
87
88   /* split user@server to user and server */
89   SplitId(userid, useridshort, extraId);
90
91   /* setup ID for config file */
92   SetupConfId(extraId);
93
94   /* get address of client from getenv. it might be IPv4 or IPv6. */
95   GetClientAddr(clientAddr6);
96
97   /* check enable IP versions */
98   CheckIpVersions();
99
100   /* get MAC address from arp and ndp */
101   GetMacAddr();
102
103   /* authenticate the user with authentication server */
104   if(!AuthenticateUser(useridshort, password)){
105     /* if not authenticate, send deny */
106     PutClientDeny();
107     err_msg("DENY: user %s from %s at %s", userid, clientAddr4, macAddr4);
108     return 0;
109   }
110
111   /* clear password */
112   bzero(password, PASSMAXLN);
113
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);
119     return 0;
120   }
121
122   /* usage duration is restricted to permitted range */
123   if(duration <= 0){
124     duration=atoi(GetConfValue("Duration/Default"));
125   }else{
126     int durmax=atoi(GetConfValue("Duration/Max"));
127     if(duration > durmax){
128       duration=durmax;
129     }
130   }
131   /* set terminate signal handler */
132   Signal(SIGTERM, closeExit);
133
134   /* open firewall for the client */
135   if(OpenClientGate()==FALSE) return 0;
136   timeIn=time(NULL);
137
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);
145   }
146   
147   /* get temporary port for server-listen */
148   port=GetListenPort();
149   if(port<0){
150     err_msg("ERR in main: cannot get unused listen port");
151     PutClientMsg("Error: Please contact to the administrator");
152     closeExit(1);
153   }
154
155   if((pid=Fork())!=0){
156     /** parent process **/
157     /* send java */
158     PutJavaApplet(userid, port, pid, clientAddr4, clientAddr6, ipStatus);
159
160     /* detach from Web server */
161     return 0;
162   }
163   /** child process **/
164
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 */
169
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){
174
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);
179   }
180   /* close firewall and exit */
181   closeExit(1);
182
183   return 0;
184 }
185
186
187
188 /**************************************/
189 /* Open client gate for IPv4 and IPv6 */
190 /**************************************/
191 int openClientGate(void)
192 {
193   int ret;
194   struct clientAddr *pLastClientAddr = NULL;
195
196   /**** if client have IPv6 & IPv4 addresses, do below */
197   if(ipStatus == IPV46DUAL){
198
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){
202
203       /* overlapped rules or other */
204       PutClientMsg("Error: Please End Web and Retry");
205       return FALSE;
206
207     }else if(ret>0){
208       /* system error raise */
209       PutClientMsg("Error: Please contact to the administrator");
210       return FALSE;
211     }
212
213     /* open ipv4 success. write message */
214     err_msg("OPEN: user %s from %s at %s", userid, clientAddr4, macAddr4);
215
216     /* create new address list. head and tail pointer point the same item. */
217     pClientAddr = CreateAddrListItem(clientAddr4,ruleNumber4,IPV4);
218     pLastClientAddr = pClientAddr;
219
220     /* open firewall for clientAddr6 */
221     if((ret=OpenClientGate6(clientAddr6, userid, macAddr6, userProperty))<0){
222
223       /* overlapped rules or other */
224       PutClientMsg("Error: Please End Web and Retry");
225
226       /* remove registered ipv4 rule from list */ 
227       if(pClientAddr!=NULL){
228         if(pClientAddr->ipType==IPV4){
229           CloseClientGate4(pClientAddr,userid,macAddr4);
230           free(pClientAddr);
231           pClientAddr=NULL;
232         }
233       }
234       return FALSE;
235
236     }else if(ret>0){
237
238       /* system error raise */
239       PutClientMsg("Error: Please contact to the administrator");
240       return FALSE;
241     }
242
243     /* open ipv6 success, write message */
244     err_msg("OPEN: user %s from %s at %s", userid, clientAddr6, macAddr6);
245
246     /* add the address info to list */
247     pLastClientAddr->next = CreateAddrListItem(clientAddr6,ruleNumber6,IPV6);
248     
249
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);
253
254     if((ret=OpenClientGate4(clientAddr4, userid, macAddr4, userProperty))<0){
255       PutClientMsg("Error: Please End Web and Retry");
256       return FALSE;
257
258     }else if(ret>0){
259       PutClientMsg("Error: Please contact to the administrator");
260       return FALSE;
261     }
262     err_msg("OPEN: user %s from %s at %s", userid, clientAddr4, macAddr4);
263
264     /* create new address list. head and tail pointer point the same item. */
265     pClientAddr = CreateAddrListItem(clientAddr4,ruleNumber4,IPV4);
266     pLastClientAddr = pClientAddr;
267   
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);
271
272     if((ret=OpenClientGate6(clientAddr6, userid, macAddr6, userProperty))<0){
273       PutClientMsg("Error: Please End Web and Retry");
274       return FALSE;
275
276     }else if(ret>0){
277       PutClientMsg("Error: Please contact to the administrator");
278       return FALSE;
279     }
280
281     err_msg("OPEN: user %s from %s at %s", userid, clientAddr6, macAddr6);
282
283     /* create new address list. head and tail pointer point the same item. */
284     pClientAddr = CreateAddrListItem(clientAddr4,ruleNumber4,IPV4);
285     pLastClientAddr = pClientAddr;
286   }
287   return TRUE;
288 }
289
290 /*******************************************/
291 /* calc connection duration and put it out */
292 /*******************************************/
293 void putCloseMsg(time_t timeOut, time_t timeIn)
294 {
295   double time;
296   int hour,min,sec;
297
298   time=difftime(timeOut,timeIn);
299   hour=time/60/60;
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);
303   return;
304 }
305
306 /*****************************/
307 /* Check enable IP versions  */
308 /*****************************/
309
310 void checkIpVersions(void){
311
312   if(strstr(clientAddr4,".")!=NULL){
313     if(strstr(clientAddr6,":")!=NULL){
314       ipStatus = IPV46DUAL;
315     }else{
316       ipStatus = IPV4ONLY;
317     }
318   }else{
319     if(strstr(clientAddr6,":")!=NULL){
320       ipStatus = IPV6ONLY;
321     }else{
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");
324       exit(1);
325     }
326   }
327 }
328
329 /********************/
330 /* Get Mac Address  */
331 /********************/
332 void getMacAddr(void)
333 {
334
335   if(ipStatus==IPV46DUAL){
336     GetMacAddrFromArp(clientAddr4, macAddr4);
337     GetMacAddrFromNdp(clientAddr6,macAddr6);
338     
339   }else if(ipStatus==IPV4ONLY){
340     GetMacAddrFromArp(clientAddr4, macAddr4);
341     ReFormatMacAddr(macAddr4,macAddr6);
342     
343   }else{
344     GetMacAddrFromNdp(clientAddr6, macAddr6);
345   }
346   
347   return;
348 }
349
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)
357 {
358   char *strp = NULL;
359   char delims[] = ":";
360   char buf[ADDRMAXLN] = "";
361
362   strcpy(macAddr6,"");
363   strcpy(buf,macAddr4);
364   strp=strtok(buf,delims);
365   
366   if(strncmp(strp,"0",1)==0){
367     strp++;
368     strcat(macAddr6,strp);
369   }else{
370     strcat(macAddr6,strp);
371   }
372
373   strp=strtok(NULL,delims);
374   while(strp!=NULL){
375     strcat(macAddr6,delims);
376     if(strncmp(strp,"0",1)==0){
377       strp++;
378       strcat(macAddr6,strp);
379     }else{
380       strcat(macAddr6,strp);
381     }
382     strp=strtok(NULL,delims);
383   }
384 }
385
386 /*****************************/
387 /* At termination, call this */
388 /*****************************/
389 void closeExit(int signo)
390 {
391   /* signal is disabled */
392   Signal(SIGTERM, SIG_DFL);
393
394   /* send quit message to client java */
395   SendQuitClient();
396
397   /* close firewalls */
398   while(pClientAddr!=NULL){
399     if(pClientAddr->ipType==IPV4){
400       CloseClientGate4(pClientAddr,useridshort,macAddr4);
401     }else{
402       CloseClientGate6(pClientAddr,useridshort,macAddr6);
403       DeleteNdpEntry(pClientAddr->ipAddr);
404     }
405     pClientAddr = pClientAddr->next;
406   }
407
408   /* put out time */
409   timeOut=time(NULL);
410   PutCloseMsg(timeOut,timeIn);
411   if(debug) err_msg("DEBUG:terminated");
412
413   /* release the conf file area */
414   CloseConfFile();
415
416   exit(1);
417 }
418
419 /*****************************/
420 /*****************************/
421 int OpenClientGate(void)
422 {
423   int ret;
424   if(debug) err_msg("DEBUG:=>openClientGate( )");
425   ret = openClientGate();
426   if(debug) err_msg("DEBUG:(%d)<=openClientGate()",ret);
427   return ret;
428 }
429
430 void PutCloseMsg(time_t timeOut, time_t timeIn)
431 {
432   if(debug) err_msg("DEBUG:=>putCloseMsg( )");
433   putCloseMsg(timeOut,timeIn);
434   if(debug) err_msg("DEBUG:<=putCloseMsg( )");
435 }
436
437 void ReFormatMacAddr(char* macAddr4, char* macAddr6)
438 {
439   if(debug) err_msg("DEBUG:=>reFormatMacAddr(%s)", macAddr4);
440   reFormatMacAddr(macAddr4, macAddr6);
441   if(debug) err_msg("DEBUG:<=reFormatMacAddr(%s)", macAddr6);
442 }
443
444 void GetMacAddr(void)
445 {
446   if(debug) err_msg("DEBUG:=>getMacAddr( )");
447   getMacAddr();
448   if(debug) err_msg("DEBUG:<=getMacAddr( )");
449 }
450
451 void CheckIpVersions(void)
452 {
453   if(debug) err_msg("DEBUG:=>checkIpVersions( )");
454   checkIpVersions();
455   if(debug) err_msg("DEBUG:<=checkIpversions( )");
456 }
457