1 /**************************************************
2 OpengateM - MAC address authentication system
3 module for misc routines
5 Copyright (C) 2011 Opengate Project Team
6 Written by Yoshiaki Watanabe
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 "opengatemmng.h"
28 /*************************************************/
30 /* fd : file descriptor */
31 /* fmt : format to write */
32 /* ... : terms to write */
33 /*************************************************/
34 void Writefmt(int fd, const char *fmt, ...)
41 vsnprintf(buff, BUFFMAXLN, fmt, ap);
45 nwrt=write(fd, buff, nchar);
51 void WritefmtSSL(SSL *fd, const char *fmt, ...)
58 vsnprintf(buff, BUFFMAXLN, fmt, ap);
62 nwrt=SSL_write(fd, buff, nchar);
68 /******************************************************/
70 /* fd: file descriptor */
71 /* vptr: input buffer pointer */
72 /* maxlen: buffer length */
74 /* the chars terminated with EOL or EOF is read in */
75 /* ## this function assumes two EOL chars [CR LF] */
76 /* CRLF is not read in and skipped */
77 /* [abcdCRLFefghCRLF] => read[abcd],left[efghCRLF] */
80 /* plus value means the count of chars to read */
81 /* value 0 means NULL line (no-chars & CRLF) */
82 /* value -1 means error (errno is set) */
83 /* value -2 means EOF (no-chars & EOF) */
84 /******************************************************/
86 readln(int fd, void *vptr, size_t maxlen)
95 if(rc==0) return(-2); /* EOF */
96 if(rc<0) return(-1); /* ERR */
100 while(n < maxlen-1) {
101 if ( rc == 1) { /* get some char */
102 if (iscntrl(c)){ /* get control char (means EOL) */
103 rc = read(fd, &c, 1); /* skip second EOL char */
108 }else if (rc == 0) { /* EOF (but some chars are read already) */
113 rc = read(fd, &c, 1);
115 /* null terminate string */
122 readlnSSL(SSL *fd, void *vptr, size_t maxlen)
130 rc = SSL_read(fd, &c, 1);
131 if(rc==0) return(-2); /* EOF */
132 if(rc<0) return(-1); /* ERR */
136 while(n < maxlen-1) {
137 if ( rc == 1) { /* get some char */
138 if (iscntrl(c)){ /* get control char (means EOL) */
139 rc = SSL_read(fd, &c, 1); /* skip second EOL char */
144 }else if (rc == 0) { /* EOF (but some char are read already */
149 rc = SSL_read(fd, &c, 1);
151 /* null terminate string */
156 /******************************/
157 /* lock functions using fcntl */
158 /******************************/
163 lck.l_whence=SEEK_SET;
166 return fcntl(fd, F_SETLKW, &lck);
169 /********************************/
170 /* unlock functions using fcntl */
171 /********************************/
177 lck.l_whence=SEEK_SET;
180 return fcntl(fd, F_SETLK, &lck);
183 /**************************************/
184 /* check NULL or point to null string */
185 /**************************************/
186 int isNull(const char *pStr)
188 if(pStr==NULL) return TRUE;
189 if(*pStr=='\0') return TRUE;
195 /**************************************************/
196 /* popen with argument list */
197 /* rootPriv: if 1, run command as root user */
198 /* type : open type "r" or "w" */
199 /* path : command path to fork/exec */
200 /* ... : command arguments. last must be (char*)0 */
201 /* DO NOT SET [user entered string] in args */
202 /* to prevent hacking */
203 /**************************************************/
204 FILE *Popenl(int rootPriv, const char *type, const char *path, ...)
206 char commandLine[BUFFMAXLN];
211 /* insert command path */
212 strlcpy(commandLine, path, BUFFMAXLN);
214 /* insert command arguments */
217 while((pStr=va_arg(ap, char *))!=(char *)0){
218 strcat(commandLine, " ");
219 strncat(commandLine, pStr, BUFFMAXLN);
224 /* if desired, add root privilege */
227 err_msg("ERR at %s#%d: cannot add root privilege ",
232 /* open the pipe to the program */
233 if(debug>1) err_msg("DEBUG:=>popen(%s, %s)", commandLine, type);
234 file=popen(commandLine, type);
235 if(debug>1) err_msg("DEBUG:(%x)<=popen( )",file);
237 /* remove root privilege */
244 /**************************************************/
245 /* system with argument list */
246 /* rootPriv: if 1, run command as root user */
247 /* path : command path to fork/exec */
248 /* ... : command arguments. last must be (char*)0 */
249 /* DO NOT SET [user entered string] in args */
250 /* to prevent hacking */
251 /**************************************************/
252 int Systeml(int rootPriv, const char *path, ...)
254 char commandLine[BUFFMAXLN];
259 /* insert command path */
260 strlcpy(commandLine, path, BUFFMAXLN);
262 /* insert command arguments */
265 while((pStr=va_arg(ap, char *))!=(char *)0){
266 strcat(commandLine, " ");
267 strncat(commandLine, pStr, BUFFMAXLN);
272 /* if desired, add root privilege */
275 err_msg("ERR at %s#%d: cannot add root privilege ",
281 if(debug>1) err_msg("DEBUG:=>system(%s)", commandLine);
282 ret=system(commandLine);
283 if(debug>1) err_msg("DEBUG:<=system()");
285 /* remove root privilege */
290 /*************************************************/
291 /* calc MD5 in hex form */
292 /* str: plain text to convert */
293 /* hexdigest: converted hex string */
294 /* prepare buff more or equal to 33chars */
295 /* len: length of hexdigest buffer */
296 /*************************************************/
297 char *md5hex(char *hexdigest, int len, char *str)
299 char unsigned digest[16];
300 char hexcode[16]="0123456789abcdef";
303 /* if not enough buffer, exit */
309 /* calc MD5 digest */
310 MD5((unsigned char*)str, strlen(str), digest);
312 /* convert to HEX string */
314 hexdigest[2*i]=hexcode[digest[i]/16];
315 hexdigest[2*i+1]=hexcode[digest[i]%16];
317 hexdigest[2*16]='\0';
322 /*******************************************/
323 /* create random session cookie */
324 /*******************************************/
325 void createCookie(char *cookie)
329 /* make Http-cookie from pid&time */
330 snprintf(str, BUFFMAXLN, "%d%d", getpid(),time(NULL));
331 md5hex(cookie, SIDMAXLN, str);
334 /*******************************************/
335 /* get port number string in /etc/services */
336 /*******************************************/
337 char *getServicePortStr(char *servName)
339 struct servent *pServEnt;
340 static char portStr[WORDMAXLN];
342 /* get service info from service name */
343 pServEnt = getservbyname(servName, NULL);
346 err_msg("ERR at %s#%d: cannot find /etc/services entry for %s",
347 __FILE__,__LINE__,servName);
351 /* convert service port number to string form */
352 snprintf(portStr, sizeof(portStr),"%d",ntohs(pServEnt->s_port));
357 /****************************************************/
358 /* getenv for multiple variables */
359 /* after replacing '-' with '_' */
361 /* if env = "ab cd-ef-gh ijk" */
362 /* repeat getenv until getting non-null value */
363 /* getnev("ab"),getenv("cd_ef_gh"),getenv("ijk") */
364 /* if pre=TRUE convert '-' to '_' in env-var name */
365 /* if post=TRUE convert ' '|'@' to '_' in get-str */
366 /****************************************************/
367 char* getenvEx(char* env, int pre, int post){
368 char work[BUFFMAXLN];
375 /* copy string not to destroy it */
376 strlcpy(work, env, BUFFMAXLN);
378 /* repeat for variables */
379 thisVar=nextVar=work;
381 while(!isNull(thisVar)){
383 /* skip preceeding space in string */
384 for(p=thisVar; *p==' '; p++);
387 /* search space (end of this variable) */
388 for(p=thisVar; (*p!=' ' && *p!='\0'); p++);
390 /* prepare next variable */
391 if(*p=='\0') nextVar=p; /* end of env string */
392 else{ /* some variales follows */
393 *p='\0'; /* set end of this variable */
394 nextVar=p+1; /* and start of next variable */
397 /* replace '-' in string with '_' */
399 for(p=thisVar; *p!='\0'; p++){
404 /* exeute getenv. if success, exit loop */
405 envValue = getenv(thisVar);
406 if(!isNull(envValue)){
411 /* try next variable */
415 /* getting no data */
416 if(!found) return NULL;
418 /* convert ' ' and '@' to '_' */
420 for(p=envValue; *p!='\0'; p++){
429 /*********************************************************/
430 /* TCP Connection routine */
431 /* from UNIX NETWORK PROGRAMMING,Vol.1,Second Edition, */
432 /* By W. Richard Stevens, Published By Prentice Hall */
433 /* ftp://ftp.kohala.com/pub/rstevens/unpv12e.tar.gz */
434 /**********************************************************/
436 tcp_connect(const char *host, const char *serv)
439 struct addrinfo hints, *res, *ressave;
441 bzero(&hints, sizeof(struct addrinfo));
442 hints.ai_family = AF_UNSPEC;
443 hints.ai_socktype = SOCK_STREAM;
445 if ( (n = getaddrinfo(host, serv, &hints, &res)) != 0){
446 err_msg("tcp_connect error for %s, %s: %s",
447 host, serv, gai_strerror(n));
453 sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
455 continue; /* ignore this one */
457 if (connect(sockfd, res->ai_addr, res->ai_addrlen) == 0)
460 Close(sockfd); /* ignore this one */
461 } while ( (res = res->ai_next) != NULL);
463 if (res == NULL){ /* errno set from final connect() */
464 err_msg("tcp_connect error for %s, %s", host, serv);
468 freeaddrinfo(ressave);
472 /* end tcp_connect */
475 * We place the wrapper function here, not in wraplib.c, because some
476 * XTI programs need to include wraplib.c, and it also defines
477 * a Tcp_connect() function.
481 /****************************************/
482 /****************************************/
483 void CreateCookie(char *cookie){
484 if(debug>1) err_msg("DEBUG:=>createCookie( )");
485 createCookie(cookie);
486 if(debug>1) err_msg("DEBUG:<=createCookie(%s)", cookie);
489 char *GetServicePortStr(char *servName)
492 if(debug>1) err_msg("DEBUG:=>getServicePortStr(%s)", servName);
493 ret = getServicePortStr(servName);
494 if(debug>1) err_msg("DEBUG:(%s)<=getServicePortStr( )", ret);
498 int Pclose(FILE *stream)
502 if(debug>1) err_msg("DEBUG:=>pclose( )");
503 ret = pclose(stream);
504 if(debug>1) err_msg("DEBUG:<=pclose( )");
514 if(debug>1) err_msg("DEBUG:=>lock( )");
516 if(debug>1) err_msg("DEBUG:(%d)<=lock( )",ret);
526 if(debug>1) err_msg("DEBUG:=>unlock( )");
528 if(debug>1) err_msg("DEBUG:(%d)<=unlock( )",ret);
535 Open(const char *pathname, int oflag, mode_t mode)
539 if ( (fd = open(pathname, oflag, mode)) == -1)
540 err_msg("open error for %s", pathname);
549 /*if( (ret=close(fd)) == -1)
550 * err_msg("close error");
563 if ( (pid = fork()) == -1)
564 err_msg("fork error");
572 if ((ret=pipe(fds)) < 0)
573 err_msg("pipe error");
583 if ( (ptr = malloc(size)) == NULL)
584 err_msg("malloc error");
589 Tcp_connect(const char *host, const char *serv)
591 return(tcp_connect(host, serv));