1 /**************************************************
3 module for Communication through CGI
5 Copyright (C) 1999 Opengate Project Team
6 Written by Yoshiaki Watanabe
7 Modified Katsuhiko Eguchi, 2005
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version 2
12 of the License, or (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 Email: watanaby@is.saga-u.ac.jp
25 Programmed by Yoshiaki WATANABE
26 Modified by Shin-ichi TADAKI
27 Modified by Katsuhiko Eguchi
28 **************************************************/
30 #include "opengatesrv.h"
32 /* convert two-char-hex "aa" to one-number 0Xaa */
33 #define hex2num(x) ((x)>='A' ? ((x) & 0XDF) - 'A' +10 : ((x) - '0'))
35 int isHttpWatchEnableClient(void);
36 int isJavaWatchEnableClient(void);
37 void split(char content[], char *name[], char *value[], char *next[]);
38 void decode(char *string);
40 char language[WORDMAXLN]; /* message language in java applet */
42 /*******************************/
43 /* get the client addr */
44 /*******************************/
45 void getClientAddr(char *clientAddr)
47 strncpy(clientAddr, getenv("REMOTE_ADDR"), ADDRMAXLN);
50 /********************************************/
51 /* get Post data from the client */
52 /********************************************/
53 int getPostData(char *userid, char *password, char *clientAddr4, int *durationPtr, char *watchMode)
56 char content[BUFFMAXLN];
61 char durationStr[WORDMAXLN];
62 char langList[BUFFMAXLN];
63 char encodeAddr4[ADDRMAXLN];
64 char accessAddr[ADDRMAXLN];
66 /* get content sent from web input */
67 if(getenv("CONTENT_LENGTH")==NULL){
68 err_msg("ERR at %s#%d: CONTENT_LENGTH is not defined",__FILE__,__LINE__);
72 contentLen=atoi(getenv("CONTENT_LENGTH"));
74 err_msg("ERR at %s#%d: CONTENT_LENGTH is zero",__FILE__,__LINE__);
78 contentLen++; /* for terminate ch */
79 if(contentLen > BUFFMAXLN) contentLen=BUFFMAXLN;
80 if(fgets(content, contentLen, stdin) == NULL){
84 /* get items from string */
94 split(ptr, name, value, next);
96 if(strstr(name[0], "userid")!=NULL){
97 strncpy(userid, value[0], USERMAXLN);
98 }else if(strstr(name[0], "password")!=NULL){
99 strncpy(password, value[0], PASSMAXLN);
100 }else if(strstr(name[0],"remote_addr")!=NULL){
101 strncpy(encodeAddr4,value[0],ADDRMAXLN);
102 }else if(strstr(name[0], "language")!=NULL){
103 strncpy(language, value[0], WORDMAXLN);
104 }else if(strstr(name[0], "duration")!=NULL){
105 strncpy(durationStr, value[0], WORDMAXLN);
106 }else if(strstr(name[0], "watchmode")!=NULL){
107 strncpy(watchMode, value[0], WORDMAXLN);
112 /* decode the HTTP encoding */
120 /* if not available language, use first lang */
121 strncpy(langList, GetConfValue("HtmlLangs"), BUFFMAXLN); /* list of available languages */
122 if(strstr(langList,language)==NULL){
123 sscanf(langList,"%s",language);
126 /* convert duration string to interger and minutes to seconds */
127 *durationPtr = atoi(durationStr)*60;
129 /* usage duration is restricted to permitted range */
130 if(*durationPtr <= 0){
131 *durationPtr=atoi(GetConfValue("Duration/Default"));
133 int durmax=atoi(GetConfValue("Duration/Max"));
134 if(*durationPtr > durmax) *durationPtr=durmax;
137 /* encoded address starting as "0-0-0" means no addr info */
138 /* it indicates needless to get dual stack addresses */
139 /* and only use getenv("REMOTE_ADDR") address */
140 if(strnstr(encodeAddr4, "0-0-0", ADDRMAXLN)==encodeAddr4){
144 /* decode client address to dot separated form */
145 else if(AddrDecode(clientAddr4, encodeAddr4)==1){
146 /* if can't decode, retry */
147 err_msg("ERR at %s#%d: Cannot decode client address",__FILE__,__LINE__);
151 /* if the decoded IPv4 addr is not same as access IPv4 addr, use later */
152 strncpy(accessAddr, getenv("REMOTE_ADDR"), ADDRMAXLN);
153 if((strnstr(accessAddr, ".", ADDRMAXLN)!=NULL) /* access is IPv4 */
154 && strncmp(accessAddr, clientAddr4, ADDRMAXLN)!=0){ /* and not same */
155 strncpy(clientAddr4, accessAddr, ADDRMAXLN);
161 /*********************************************/
162 /* deny message to the client */
163 /*********************************************/
164 void putClientDeny(char *clientAddr4)
166 char denydoc[BUFFMAXLN];
167 char authCgiUrl[BUFFMAXLN];
168 char encodeAddr[ADDRMAXLN];
171 /* the left key is replaced by the right value */
172 struct html_key keys[]=
174 {"%%AUTHCGIURL%%", authCgiUrl},
175 {"%%ADDR4%%", encodeAddr},
176 {"",""} /* DON'T REMOVE THIS LINE */
179 /* create authcgi URL string */
180 snprintf(authCgiUrl, BUFFMAXLN, "%s%s%s/%s",
181 GetConfValue("OpengateServerName"),
182 GetConfValue("CgiDir"),
183 GetConfValue("OpengateDir"),
184 GetConfValue("AuthCgi"));
186 /* create encoded addr4 */
187 if(AddrEncode(encodeAddr, clientAddr4)==1){
191 /* make path to the denydoc for ssl or non-ssl */
192 if(strcmp(getenv("SERVER_PORT"),GetServicePortStr("https"))==0){
193 snprintf(denydoc, BUFFMAXLN, "%s%s/%s/%s",GetConfValue("DocumentRoot"),
194 GetConfValue("OpengateDir"),language,GetConfValue("DenyDocSsl"));
196 snprintf(denydoc, BUFFMAXLN, "%s%s/%s/%s",GetConfValue("DocumentRoot"),
197 GetConfValue("OpengateDir"),language,GetConfValue("DenyDoc"));
200 /* replace keyword and send out the file */
201 printf("Content-type: text/html\r\n\r\n\r\n");
202 HtmlTemplate(denydoc, keys);
206 /*********************************************/
207 /* deny message to the client */
208 /*********************************************/
209 void putClientRetry(char *lang)
211 char retrydoc[BUFFMAXLN];
212 char externalUrl[BUFFMAXLN];
213 char authCgiUrl[BUFFMAXLN];
216 /* the left key is replaced by the right value */
217 struct html_key keys[]=
219 {"%%EXTERNALURL%%", externalUrl},
220 {"%%AUTHCGIURL%%", authCgiUrl},
221 {"",""} /* DON'T REMOVE THIS LINE */
224 /* create external URL string */
225 strncpy(externalUrl, GetConfValue("ExternalUrl"), BUFFMAXLN);
227 /* create authcgi URL string */
228 snprintf(authCgiUrl, BUFFMAXLN, "%s%s%s/%s",
229 GetConfValue("OpengateServerName"),
230 GetConfValue("CgiDir"),
231 GetConfValue("OpengateDir"),
232 GetConfValue("AuthCgi"));
234 /* make read in path to the retry document */
235 snprintf(retrydoc, BUFFMAXLN, "%s%s/%s/%s",GetConfValue("DocumentRoot"),
236 GetConfValue("OpengateDir"),lang,GetConfValue("RetryDoc"));
238 /* replace keyword and send out the file */
239 printf("Content-type: text/html\r\n\r\n\r\n");
240 HtmlTemplate(retrydoc, keys);
245 /*********************************************/
246 /* put some message to the client */
247 /*********************************************/
248 void putClientMsg(char *message)
250 printf("Content-type: text/html\r\n\r\n\r\n");
251 printf("<HTML><HEAD><TITLE>OpengateMsg</TITLE></HEAD> \r\n");
252 printf("<BODY> \r\n");
253 printf("%s\r\n", message);
254 printf("</BODY></HTML> \r\n\r\n");
258 /*********************************************/
259 /* put accept message and java to the client */
260 /*********************************************/
261 void putClientAccept(char *userid, char *sessionId, int port, int pid, char *clientAddr4, char *clientAddr6, int ipStatus, int duration, char *watchMode)
264 char buff[BUFFMAXLN];
265 char acceptdoc[BUFFMAXLN];
266 char acceptdoc2url[BUFFMAXLN];
267 char terminateurl[BUFFMAXLN];
268 char httpkeepUrl[BUFFMAXLN];
269 char portStr[WORDMAXLN];
270 char durationStr[WORDMAXLN];
273 char *startPageUrl=GetConfValue("StartPage/Url");
274 int startPageType=atoi(GetConfValue("StartPage/Type"));
275 char *opengateDir=GetConfValue("OpengateDir");
277 /* select proper accept doc */
278 switch(watchMode[0]){
280 /* HTTP watch mode */
282 if(isHttpWatchEnableClient()){
283 acceptDoc=GetConfValue("AcceptDocHttp");
284 }else if(isJavaWatchEnableClient()){
285 acceptDoc=GetConfValue("AcceptDocJava");
287 acceptDoc=GetConfValue("AcceptDocTime");
291 /* JAVA watch mode */
293 if(isJavaWatchEnableClient()){
294 acceptDoc=GetConfValue("AcceptDocJava");
295 }else if(isHttpWatchEnableClient()){
296 acceptDoc=GetConfValue("AcceptDocHttp");
298 acceptDoc=GetConfValue("AcceptDocTime");
302 /* TIMEOUT watch mode */
304 acceptDoc=GetConfValue("AcceptDocTime");
308 err_msg("ERR at %s#%d: Unknown watch mode [%s]",__FILE__,__LINE__,watchMode);
309 acceptDoc=GetConfValue("AcceptDocJava");
312 /* create path to acceptdoc */
313 snprintf(acceptdoc, BUFFMAXLN, "%s%s/%s/%s",GetConfValue("DocumentRoot"),
314 GetConfValue("OpengateDir"),language,acceptDoc);
317 snprintf(acceptdoc2url, BUFFMAXLN,
318 "http://%s%s/%s/%s",GetConfValue("OpengateServerName"),
319 GetConfValue("OpengateDir"),language,GetConfValue("AcceptDoc2"));
321 /* create terminate url [http://<servaddr>:<port>/terminate-<pid>] */
322 snprintf(terminateurl, BUFFMAXLN, "http://%s:%d/terminate-%d",
323 GetConfValue("OpengateServerName"), port, getpid());
325 /* create httpkeep page url
326 ['http://<servaddr>:<port>/httpkeep-<userid>'] */
327 snprintf(httpkeepUrl, BUFFMAXLN,
328 "'http://%s:%d/httpkeep-%s-%s'",
329 GetConfValue("OpengateServerName"), port, userid,sessionId);
331 /* create port string */
332 snprintf(portStr, WORDMAXLN, "%d", port);
334 /* create duration string (duration=sec, display value=min) */
335 snprintf(durationStr, WORDMAXLN, "%d", duration/60);
338 if((fp=fopen(acceptdoc, "r"))==NULL){
339 err_msg("ERR at %s#%d: cannot open %s",__FILE__,__LINE__,acceptdoc);
340 PutClientMsg("Cannot find html document");
344 /* read html document from file and send to web */
345 printf("Content-type: text/html\r\n\r\n\r\n");
346 while(fgets(buff, BUFFMAXLN, fp)!=NULL){
349 if(strlen(buff)>=BUFFMAXLN-1){
350 err_msg("ERR at %s#%d: too long line in %s",__FILE__,__LINE__,acceptdoc);
354 htmlReplace(buff, "%%OPENGATEDIR%%", opengateDir);
355 htmlReplace(buff, "%%OPENGATEPORT%%", portStr);
356 htmlReplace(buff, "%%DURATION%%", durationStr);
357 htmlReplace(buff, "%%USERID%%", userid);
358 htmlReplace(buff, "%%SESSIONID%%", sessionId);
359 htmlReplace(buff, "%%LANGUAGE%%", language);
361 htmlReplace(buff, "%%TERMINATEURL%%", terminateurl);
362 htmlReplace(buff, "%%HTTPKEEPURL%%", httpkeepUrl);
364 /* replace information url mark */
365 if( startPageType==1 ){
366 htmlReplace(buff, "%%STARTURL%%", startPageUrl);
368 htmlReplace(buff, "%%STARTURL%%", acceptdoc2url);
375 fputs("\r\n\r\n",stdout);
381 /*****************************************************/
382 /* is the client enable to keep long http connection */
383 /*****************************************************/
384 int isHttpWatchEnableClient(void)
386 /* HTTP Keep-Alive is not standard in http/1.0 */
387 if(strcmp(getenv("SERVER_PROTOCOL"),"HTTP/1.0")==0) return FALSE;
389 /* some user agent does not support long HTTP Keep-Alive */
390 if(RegExMatch(getenv("HTTP_USER_AGENT"),
391 GetConfValue("HttpWatch/SkipAgentPattern"))) return FALSE;
396 /********************************************/
397 /* is the client enable to load Java Applet */
398 /********************************************/
399 int isJavaWatchEnableClient(void)
401 /* some user agent does not support Java Applet */
402 if(RegExMatch(getenv("HTTP_USER_AGENT"),
403 GetConfValue("JavaWatch/SkipAgentPattern"))) return FALSE;
408 /************************************/
409 /* split value for indicated name */
410 /* in content "name=value&..." */
411 /************************************/
412 void split(char content[], char *name[], char *value[], char *next[])
418 value[0]=content+strlen(content);
422 if((pstr=strchr(name[0],(int)'='))==NULL){
428 /* set value start */
433 if((pstr=strchr(value[0],'&'))==NULL){
446 /**********************************/
447 /* decode text coding in web post */
448 /**********************************/
449 void decode(char *string)
451 char *pcheck, *pinsert;
453 pcheck=pinsert=string;
454 while(*pcheck != '\0'){
457 }else if(*pcheck == '%'){
458 *pinsert=(char)(hex2num(*(pcheck+1))*16 + hex2num(*(pcheck+2)));
469 /***************************************/
470 /* get HTTP_REFERER and check true url */
471 /***************************************/
472 int checkReferer(void)
474 char url[BUFFMAXLN]="";
475 if(getenv("HTTP_REFERER")!=NULL){
476 strncpy(url,getenv("HTTP_REFERER"),BUFFMAXLN);
477 if(strstr(url,GetConfValue("OpengateServerName"))==NULL){
484 /*******************************/
485 /*******************************/
486 void GetClientAddr(char *clientAddr)
488 if(debug>1) err_msg("DEBUG:=>getClientAddr( )");
489 getClientAddr(clientAddr);
490 if(debug>1) err_msg("DEBUG:<=getClientAddr(%s)",clientAddr);
494 int GetPostData(char *userid, char *password, char *clientAddr4, int *durationPtr, char *watchMode)
498 if(debug>1) err_msg("DEBUG:=>getPostData( )");
499 ret=getPostData(userid,password,clientAddr4,durationPtr, watchMode);
500 if(debug>1) err_msg("DEBUG:%d<=getPostData(%s,passwd,%s,%d,%s)",ret,userid,clientAddr4,*durationPtr,watchMode);
504 void PutClientAccept(char *userid, char *sessionId, int port, int pid, char *clientAddr4, char *clientAddr6, int ipStatus, int duration, char *watchMode)
506 if(debug>1) err_msg("DEBUG:=>putClientAccept(%s,%s,%d,%d,%s,%s,%d,%d,%s)",userid,sessionId,port,pid,clientAddr4,clientAddr6,ipStatus, duration, watchMode);
507 putClientAccept(userid,sessionId,port,pid,clientAddr4,clientAddr6,ipStatus,duration,watchMode);
508 if(debug>1) err_msg("DEBUG:<=putClientAccept( )");
511 void PutClientDeny(char *clientAddr4)
513 if(debug>1) err_msg("DEBUG:=>putClientDeny(&s)",clientAddr4);
514 putClientDeny(clientAddr4);
515 if(debug>1) err_msg("DEBUG:<=putClientDeny( )");
518 void PutClientRetry(char *lang)
520 if(debug>1) err_msg("DEBUG:=>putClientRetry(%s)",lang);
521 putClientRetry(lang);
522 if(debug>1) err_msg("DEBUG:<=putClientRetry( )");
525 void PutClientMsg(char *message)
527 if(debug>1) err_msg("DEBUG:=>putClientMsg( %s )",message);
528 putClientMsg(message);
529 if(debug>1) err_msg("DEBUG:<=putClientMsg( )");
532 int CheckReferer(void)
535 if(debug>1) err_msg("DEBUG:=>checkReferer( )");
536 ret = checkReferer();
537 if(debug>1) err_msg("DEBUG:(%d)<=checkReferer( )",ret);