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 /* usage is same as fprintf */
34 /*************************************************/
35 void Writefmt(int fd, const char *fmt, ...){
41 vsnprintf(buff, BUFFMAXLN, fmt, ap);
45 nwrt=write(fd, buff, nchar);
50 /***********************************************/
51 /* SSL version of WriteFmt */
52 /***********************************************/
53 void WritefmtSSL(SSL *fd, const char *fmt, ...){
59 vsnprintf(buff, BUFFMAXLN, fmt, ap);
63 nwrt=SSL_write(fd, buff, nchar);
69 /******************************************************/
71 /* fd: file descriptor */
72 /* vptr: input buffer pointer */
73 /* maxlen: buffer length */
75 /* read the string terminated with EOL or EOF */
76 /* # this function assumes two EOL chars [CR LF] */
77 /* CRLF is not stored into buffer and is skipped */
78 /* [abcdCRLFefghCRLF] => store[abcd],remain[efghCRLF] */
81 /* plus value means the count of read-in chars */
82 /* value 0 means NULL line (no-chars & CRLF) */
83 /* value -1 means error (errno is set) */
84 /* value -2 means EOF (no-chars & EOF) */
85 /******************************************************/
86 ssize_t readln(int fd, void *vptr, size_t maxlen){
94 if(rc==0) return(-2); /* EOF */
95 if(rc<0) return(-1); /* ERR */
100 if ( rc == 1) { /* get some char */
101 if (iscntrl(c)){ /* get control char (means EOL) */
102 rc = read(fd, &c, 1); /* skip second EOL char */
107 }else if (rc == 0) { /* EOF (but some chars are read already) */
112 rc = read(fd, &c, 1);
114 /* null terminate string */
119 /***********************************************/
120 /* SSL version of readIn */
121 /***********************************************/
122 ssize_t readlnSSL(SSL *fd, void *vptr, size_t maxlen){
129 rc = SSL_read(fd, &c, 1);
130 if(rc==0) return(-2); /* EOF */
131 if(rc<0) return(-1); /* ERR */
135 while(n < maxlen-1) {
136 if ( rc == 1) { /* get some char */
137 if (iscntrl(c)){ /* get control char (means EOL) */
138 rc = SSL_read(fd, &c, 1); /* skip second EOL char */
143 }else if (rc == 0) { /* EOF (but some char are read already */
148 rc = SSL_read(fd, &c, 1);
150 /* null terminate string */
155 /******************************/
156 /* lock function using fcntl */
157 /******************************/
162 lck.l_whence=SEEK_SET;
165 return fcntl(fd, F_SETLKW, &lck);
168 /********************************/
169 /* unlock function using fcntl */
170 /********************************/
175 lck.l_whence=SEEK_SET;
178 return fcntl(fd, F_SETLK, &lck);
181 /**********************************************/
182 /* return true, if the pointer value is NULL */
183 /* or pointer points to null(length=0) string */
184 /**********************************************/
185 int isNull(const char *pStr){
186 if(pStr==NULL) return TRUE;
187 if(*pStr=='\0') return TRUE;
191 /**************************************************/
192 /* popen with argument list */
193 /* rootPriv: if 1, run command as root user */
194 /* type : open type "r" or "w" */
195 /* path : path of command executing fork/exec */
196 /* ... : command arguments. last must be (char*)0 */
197 /* If you use [user entered string] in arguments */
198 /* sanitize the string to prevent hacking. */
199 /**************************************************/
200 FILE *Popenl(int rootPriv, const char *type, const char *path, ...){
201 char commandLine[BUFFMAXLN];
206 /* insert command path */
207 strlcpy(commandLine, path, BUFFMAXLN);
209 /* insert command arguments */
212 while((pStr=va_arg(ap, char *))!=(char *)0){
213 strcat(commandLine, " ");
214 strlcat(commandLine, pStr, BUFFMAXLN);
219 /* if desired, add root privilege */
222 err_msg("ERR at %s#%d: cannot add root privilege ",
227 /* open the pipe to the program */
228 if(debug>1) err_msg("DEBUG:=>popen(%s, %s)", commandLine, type);
229 file=popen(commandLine, type);
230 if(debug>1) err_msg("DEBUG:(%x)<=popen( )",file);
232 /* remove root privilege */
239 /**************************************************/
240 /* system with argument list */
241 /* rootPriv: if 1, run command as root user */
242 /* path : command path to fork/exec */
243 /* ... : command arguments. last must be (char*)0 */
244 /* If you use [user entered string] in arguments */
245 /* sanitize the string to prevent hacking. */
246 /**************************************************/
247 int Systeml(int rootPriv, const char *path, ...){
248 char commandLine[BUFFMAXLN];
253 /* insert command path */
254 strlcpy(commandLine, path, BUFFMAXLN);
256 /* insert command arguments */
259 while((pStr=va_arg(ap, char *))!=(char *)0){
260 strcat(commandLine, " ");
261 strlcat(commandLine, pStr, BUFFMAXLN);
266 /* if desired, add root privilege */
269 err_msg("ERR at %s#%d: cannot add root privilege ",
275 if(debug>1) err_msg("DEBUG:=>system(%s)", commandLine);
276 ret=system(commandLine);
277 if(debug>1) err_msg("DEBUG:<=system()");
279 /* remove root privilege */
284 /*************************************************/
285 /* calc MD5 and return in hex form */
286 /* str: (input)plain text to convert */
287 /* hexdigest: (output) converted hex string */
288 /* prepare buff more or equal to 33chars */
289 /* len: (input) length of hexdigest buffer */
290 /*************************************************/
291 char *md5hex(char *hexdigest, int len, char *str){
292 char unsigned digest[16];
293 char hexcode[16]="0123456789abcdef";
296 /* if not enough buffer, exit */
302 /* calc MD5 digest */
303 MD5((unsigned char*)str, strlen(str), digest);
305 /* convert to HEX string */
307 hexdigest[2*i]=hexcode[digest[i]/16];
308 hexdigest[2*i+1]=hexcode[digest[i]%16];
310 hexdigest[2*16]='\0';
315 /*******************************************/
316 /* create random session cookie */
317 /* as md5hex(processId.TimeNow) */
318 /*******************************************/
319 void createCookie(char *cookie)
323 /* make Http-cookie from pid&time */
324 snprintf(str, BUFFMAXLN, "%d%ld", getpid(),time(NULL));
325 md5hex(cookie, SIDMAXLN, str);
328 /********************************************/
329 /* get port number defined in /etc/services */
330 /* return as string form */
331 /********************************************/
332 char *getServicePortStr(char *servName){
333 struct servent *pServEnt;
334 static char portStr[WORDMAXLN];
336 /* get service info from service name */
337 pServEnt = getservbyname(servName, NULL);
340 err_msg("ERR at %s#%d: cannot find /etc/services entry for %s",
341 __FILE__,__LINE__,servName);
345 /* convert service port number to string form */
346 snprintf(portStr, sizeof(portStr),"%d",ntohs(pServEnt->s_port));
351 /**************************************************************/
352 /* get env value from string including multiple env-var */
354 /* if string(env) = "ab cd-ef-gh ijk" */
355 /* repert the search of env-var having non-null value */
356 /* getenv("ab"),getenv("cd_ef_gh"),getenv("ijk") */
357 /* if pre=TRUE convert '-' to '_' in env-var before search */
358 /* if post=TRUE convert ' '|'@' to '_' in get-str after search*/
359 /**************************************************************/
360 char* getenvEx(char* env, int pre, int post){
361 char work[BUFFMAXLN];
368 /* copy string to work area */
369 strlcpy(work, env, BUFFMAXLN);
371 /* repeat from the head to the tail of the work area */
372 thisVar=nextVar=work;
373 while(!isNull(thisVar)){
375 /* skip preceeding spaces in string, and points the head of vairable */
376 for(p=thisVar; *p==' '; p++);
379 /* search space (=the end of this variable) */
380 for(p=thisVar; (*p!=' ' && *p!='\0'); p++);
382 /* points the next variable */
383 if(*p=='\0') nextVar=p; /* end of string */
384 else{ /* some string follows */
385 *p='\0'; /* set termination char of this variable */
386 nextVar=p+1; /* set the next search point */
389 /* if PRE is true, replace '-' in string with '_' */
391 for(p=thisVar; *p!='\0'; p++){
396 /* exeute getenv. if success, exit loop */
397 envValue = getenv(thisVar);
398 if(!isNull(envValue)){
403 /* try next variable */
407 /* getting no data */
408 if(!found) return NULL;
410 /* if POST is true, convert ' ' and '@' to '_' */
412 for(p=envValue; *p!='\0'; p++){
421 /*********************************************************/
422 /* TCP Connection routine */
423 /* from UNIX NETWORK PROGRAMMING,Vol.1,Second Edition, */
424 /* By W. Richard Stevens, Published By Prentice Hall */
425 /* ftp://ftp.kohala.com/pub/rstevens/unpv12e.tar.gz */
426 /**********************************************************/
427 int tcp_connect(const char *host, const char *serv){
429 struct addrinfo hints, *res, *ressave;
431 bzero(&hints, sizeof(struct addrinfo));
432 hints.ai_family = AF_UNSPEC;
433 hints.ai_socktype = SOCK_STREAM;
435 if ( (n = getaddrinfo(host, serv, &hints, &res)) != 0){
436 err_msg("tcp_connect error for %s, %s: %s",
437 host, serv, gai_strerror(n));
443 sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
445 continue; /* ignore this one */
447 if (connect(sockfd, res->ai_addr, res->ai_addrlen) == 0)
450 Close(sockfd); /* ignore this one */
451 } while ( (res = res->ai_next) != NULL);
453 if (res == NULL){ /* errno set from final connect() */
454 err_msg("tcp_connect error for %s, %s", host, serv);
458 freeaddrinfo(ressave);
463 /****************************************/
464 /****************************************/
465 void CreateCookie(char *cookie){
466 if(debug>1) err_msg("DEBUG:=>createCookie( )");
467 createCookie(cookie);
468 if(debug>1) err_msg("DEBUG:<=createCookie(%s)", cookie);
471 char *GetServicePortStr(char *servName){
473 if(debug>1) err_msg("DEBUG:=>getServicePortStr(%s)", servName);
474 ret = getServicePortStr(servName);
475 if(debug>1) err_msg("DEBUG:(%s)<=getServicePortStr( )", ret);
479 int Pclose(FILE *stream){
482 if(debug>1) err_msg("DEBUG:=>pclose( )");
483 ret = pclose(stream);
484 if(debug>1) err_msg("DEBUG:<=pclose( )");
492 if(debug>1) err_msg("DEBUG:=>lock( )");
494 if(debug>1) err_msg("DEBUG:(%d)<=lock( )",ret);
502 if(debug>1) err_msg("DEBUG:=>unlock( )");
504 if(debug>1) err_msg("DEBUG:(%d)<=unlock( )",ret);
509 int Open(const char *pathname, int oflag, mode_t mode){
512 if ( (fd = open(pathname, oflag, mode)) == -1)
513 err_msg("open error for %s", pathname);
520 /*if( (ret=close(fd)) == -1)
521 * err_msg("close error");
532 if ( (pid = fork()) == -1)
533 err_msg("fork error");
539 if ((ret=pipe(fds)) < 0)
540 err_msg("pipe error");
545 void *Malloc(size_t size){
548 if ( (ptr = malloc(size)) == NULL)
549 err_msg("malloc error");
553 int Tcp_connect(const char *host, const char *serv){
554 return(tcp_connect(host, serv));