Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

flt_registerednames.c

Go to the documentation of this file.
00001 
00008 /* {{{ Initial comments */
00009 /*
00010  * $LastChangedDate: 2004-02-12 06:53:33 +0100 (Thu, 12 Feb 2004) $
00011  * $LastChangedRevision: 43 $
00012  * $LastChangedBy: ckruse $
00013  *
00014  */
00015 /* }}} */
00016 
00017 /* {{{ Includes */
00018 #include "config.h"
00019 #include "defines.h"
00020 
00021 #include <db.h>
00022 
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 #include <string.h>
00026 #include <ctype.h>
00027 #include <time.h>
00028 
00029 #include <sys/stat.h>
00030 #include <sys/types.h>
00031 
00032 #include <pthread.h>
00033 
00034 #include "cf_pthread.h"
00035 
00036 #include "readline.h"
00037 #include "hashlib.h"
00038 #include "utils.h"
00039 #include "configparser.h"
00040 #include "readline.h"
00041 #include "fo_server.h"
00042 #include "serverlib.h"
00043 /* }}} */
00044 
00045 static DB *NamesDB = NULL;
00046 static u_char *AuthNames = NULL;
00047 
00048 u_char *transform(const u_char *val) {
00049   register u_char *ptr = (u_char *)val;
00050   register int ws = 0;
00051   t_string str;
00052 
00053   if(!ptr) return NULL;
00054 
00055   str_init(&str);
00056 
00057   for(;*ptr;ptr++) {
00058     if(isspace(*ptr)) {
00059       if(ws == 0) str_char_append(&str,*ptr);
00060       ws = 1;
00061     }
00062     else {
00063       ws = 0;
00064       str_char_append(&str,tolower(*ptr));
00065     }
00066   }
00067 
00068   /* delete trailing whitespaces */
00069   while(isspace(str.content[str.len-1])) str.len--;
00070   str.content[str.len] = '\0';
00071 
00072   ptr = str.content;
00073   while(isspace(*ptr)) ptr++;
00074 
00075   return ptr;
00076 }
00077 
00078 int check_auth(u_char *name,u_char *pass) {
00079   DBT key,data;
00080   int ret;
00081 
00082   memset(&key,0,sizeof(key));
00083   memset(&data,0,sizeof(data));
00084 
00085   key.data = name;
00086   key.size = strlen(name);
00087 
00088   if((ret = NamesDB->get(NamesDB,NULL,&key,&data,0)) != 0) {
00089     if(ret != DB_NOTFOUND) cf_log(LOG_ERR,__FILE__,__LINE__,"db->get: %s\n",db_strerror(ret));
00090     return ret == DB_NOTFOUND ? 0 : -1;
00091   }
00092 
00093   if(!pass) return 1;
00094   if(cf_strcmp(data.data,pass) == 0) return 0;
00095 
00096   return 1;
00097 }
00098 
00099 unsigned long long hashval(DB *db,u_char *key,size_t length) {
00100   return lookup(key,length,0);
00101 }
00102 
00103 int flt_registerednames_handler(int connfd,const u_char **tokens,int tnum,rline_t *tsd) {
00104   u_char *ln = NULL,*tmp,*names[2],*pass;
00105   long llen;
00106   t_cf_hash *infos;
00107   DBT key,data;
00108   int ret;
00109 
00110   memset(&key,0,sizeof(key));
00111   memset(&data,0,sizeof(data));
00112 
00113   if(cf_strcmp(tokens[0],"AUTH") == 0) {
00114     infos = cf_hash_new(NULL);
00115 
00116     do {
00117       ln  = readline(connfd,tsd);
00118       if(ln) {
00119         llen = tsd->rl_len;
00120         while(ln[llen] != '\n') ln[llen--] = '\0'; /* delete the \n */
00121         ln[llen--] = '\0';
00122 
00123         tmp = strstr(ln,":");
00124 
00125         if(tmp) {
00126           cf_hash_set(infos,ln,tmp-ln,tmp+2,llen-(int)(tmp-ln));
00127         }
00128         else {
00129           if(*ln == '\0') break;
00130 
00131           free(ln);
00132           ln = NULL;
00133           writen(connfd,"503 Bad request\n",16);
00134           break;
00135         }
00136 
00137         free(ln);
00138       }
00139     } while(ln);
00140 
00141     if(ln) {
00142       if(tnum == 2 || tnum == 3) {
00143         if(cf_strncmp(tokens[1],"CHECK",5) == 0) {
00144           names[0] = transform(cf_hash_get(infos,"Name",4));
00145           pass     = cf_hash_get(infos,"Pass",4);
00146 
00147           if(!names[0]) {
00148             writen(connfd,"503 Bad request\n",16);
00149           }
00150           else {
00151             if(check_auth(names[0],pass) == 0) writen(connfd,"200 Ok\n",7);
00152             else writen(connfd,"504 Auth required\n",18);
00153           }
00154         }
00155         else if(cf_strncmp(tokens[1],"DELETE",6) == 0) {
00156           names[0] = transform(cf_hash_get(infos,"Name",4));
00157           pass     = cf_hash_get(infos,"Pass",4);
00158 
00159           if(!names[0] || (!pass && tnum != 3)) {
00160             writen(connfd,"504 Auth required\n",18);
00161           }
00162           else {
00163             if(tnum != 3 && check_auth(names[0],pass) != 0) {
00164               writen(connfd,"504 Auth required\n",18);
00165             }
00166             else {
00167               key.data = names[0];
00168               key.size = strlen(names[0]);
00169               if((ret = NamesDB->del(NamesDB,NULL,&key,0)) != 0) {
00170                 if(ret != DB_NOTFOUND) cf_log(LOG_ERR,__FILE__,__LINE__,"DB->del: %s\n",db_strerror(ret));
00171                 writen(connfd,"504 Auth required\n",18);
00172               }
00173               else {
00174                 writen(connfd,"200 Ok\n",7);
00175               }
00176             }
00177           }
00178         }
00179         else if(cf_strncmp(tokens[1],"SET",3) == 0) {
00180           names[0] = transform(cf_hash_get(infos,"Name",4));
00181           names[1] = transform(cf_hash_get(infos,"New-Name",8));
00182           pass     = cf_hash_get(infos,"Pass",4);
00183 
00184           if(!names[1] || !pass) {
00185             writen(connfd,"504 Auth required\n",18);
00186           }
00187           else {
00188             if(names[0]) {
00189               if(check_auth(names[0],pass) == 0) {
00190                 /* check if registered and set auth */
00191                 key.data = names[1];
00192                 key.size = strlen(names[1]);
00193 
00194                 if((ret = NamesDB->get(NamesDB,NULL,&key,&data,0)) == 0) {
00195                   writen(connfd,"504 Auth required\n",18);
00196                 }
00197                 else {
00198                   if(ret == DB_NOTFOUND) {
00199                     data.data = pass;
00200                     data.size = strlen(pass)+1; // don't forget the terminating \0
00201                     if((ret = NamesDB->put(NamesDB,NULL,&key,&data,0)) != 0) {
00202                       cf_log(LOG_ERR,__FILE__,__LINE__,"DB->put: %s\n",db_strerror(ret));
00203                       writen(connfd,"504 Auth required\n",18);
00204                     }
00205                     else {
00206                       writen(connfd,"200 Ok\n",7);
00207 
00208                       key.data = names[0];
00209                       key.size = strlen(names[0]);
00210 
00211                       if((ret = NamesDB->del(NamesDB,NULL,&key,0)) != 0) {
00212                         if(ret != DB_NOTFOUND) cf_log(LOG_ERR,__FILE__,__LINE__,"ALERT! DB->del failed: %s\n",db_strerror(ret));
00213                       }
00214                     }
00215                   }
00216                   else {
00217                     cf_log(LOG_ERR,__FILE__,__LINE__,"DB->get: %s\n",db_strerror(ret));
00218                     writen(connfd,"504 Auth required\n",18);
00219                   }
00220                 }
00221               }
00222               else {
00223                 writen(connfd,"504 Auth required\n",18);
00224               }
00225             }
00226             else {
00227               /* check if registered and set auth */
00228               key.data = names[1];
00229               key.size = strlen(names[1]);
00230 
00231               if((ret = NamesDB->get(NamesDB,NULL,&key,&data,0)) == 0) {
00232                 writen(connfd,"504 Auth required\n",18);
00233               }
00234               else {
00235                 if(ret == DB_NOTFOUND) {
00236                   data.data = pass;
00237                   data.size = strlen(pass)+1;
00238                   if((ret = NamesDB->put(NamesDB,NULL,&key,&data,0)) != 0) {
00239                     cf_log(LOG_ERR,__FILE__,__LINE__,"DB->put: %s\n",db_strerror(ret));
00240                     writen(connfd,"504 Auth required\n",18);
00241                   }
00242                   else {
00243                     writen(connfd,"200 Ok\n",7);
00244                   }
00245                 }
00246                 else {
00247                   cf_log(LOG_ERR,__FILE__,__LINE__,"DB->get: %s\n",db_strerror(ret));
00248                   writen(connfd,"504 Auth required\n",18);
00249                 }
00250               }
00251             }
00252           }
00253 
00254         }
00255         else {
00256           writen(connfd,"503 Sorry, I do not understand\n",31);
00257         }
00258       }
00259       else {
00260         writen(connfd,"503 Sorry, I do not understand\n",31);
00261       }
00262 
00263       free(ln);
00264     }
00265 
00266     if(infos) cf_hash_destroy(infos);
00267 
00268     return FLT_OK;
00269   }
00270 
00271   return FLT_DECLINE;
00272 }
00273 
00274 int flt_registerednames_init_module(int sock) {
00275   int ret;
00276 
00277   if(!AuthNames) {
00278     cf_log(LOG_ERR,__FILE__,__LINE__,"I need a database to save the names in!\n");
00279     return FLT_EXIT;
00280   }
00281 
00282   if((ret = db_create(&NamesDB,NULL,0)) != 0) {
00283     cf_log(LOG_ERR,__FILE__,__LINE__,"db_create: %s\n",db_strerror(ret));
00284     return FLT_EXIT;
00285   }
00286 
00287   if((ret = NamesDB->open(NamesDB,AuthNames,NULL,DB_HASH,DB_CREATE,0644)) != 0) {
00288     cf_log(LOG_ERR,__FILE__,__LINE__,"DB->open: %s\n",db_strerror(ret));
00289     return FLT_EXIT;
00290   }
00291 
00292   cf_register_protocol_handler("AUTH",flt_registerednames_handler);
00293 
00294   return FLT_OK;
00295 }
00296 
00297 int flt_registerednames_handle_command(t_configfile *cf,t_conf_opt *opt,u_char **args,int argnum) {
00298   if(argnum == 1) {
00299     if(AuthNames) free(AuthNames);
00300     AuthNames = strdup(args[0]);
00301   }
00302   else {
00303     cf_log(LOG_ERR,__FILE__,__LINE__,"flt_registerednames: expecting one argument for directive AuthNames!\n");
00304   }
00305 
00306   return 0;
00307 }
00308 
00309 void flt_registerednames_cleanup(void) {
00310   if(AuthNames) free(AuthNames);
00311   if(NamesDB)   NamesDB->close(NamesDB,0);
00312 }
00313 
00314 t_conf_opt flt_registerednames_config[] = {
00315   { "AuthNames", flt_registerednames_handle_command, NULL },
00316   { NULL, NULL, NULL }
00317 };
00318 
00319 t_handler_config flt_registerednames_handlers[] = {
00320   { INIT_HANDLER,            flt_registerednames_init_module   },
00321   { 0, NULL }
00322 };
00323 
00324 t_module_config flt_registerednames = {
00325   flt_registerednames_config,
00326   flt_registerednames_handlers,
00327   NULL,
00328   NULL,
00329   NULL,
00330   flt_registerednames_cleanup
00331 };
00332 
00333 /* eof */

Generated on Sun Apr 25 16:37:39 2004 for Classic Forum by doxygen 1.3.5