#include #include #include #include #include #include #include #ifdef HAVE_SSL #include #include #include #include #include #include #endif #include "sbuf.h" #include "struct.h" #include "send.h" unsigned int req = 0; extern void *pmalloc(size_t size); #define CONFCMD(x) int x(confetti * jr, int pargc, char **pargv) CONFCMD(conf_listen); CONFCMD(conf_listenex); #ifdef HAVE_SSL CONFCMD(conf_publickey); CONFCMD(conf_privatekey); #endif CONFCMD(gen_c); CONFCMD(gen_d); CONFCMD(gen_p); CONFCMD(gen_s); CONFCMD(gen_v); CONFCMD(gen_x); CONFCMD(gen_l); CONFCMD(gen_m); CONFCMD(gen_w); CONFCMD(gen_a); CONFCMD(gen_b); CONFCMD(gen_i); CONFCMD(conf_password); CONFCMD(conf_allow); struct confcmd { char *name; CONFCMD((*func)); }; struct confcmd confcmdlist[] = { {"C",gen_c}, {"D",gen_d}, {"P",gen_p}, {"S",gen_s}, {"V",gen_v}, {"X",gen_x}, {"L",gen_l}, {"M",gen_m}, {"W",gen_w}, {"A",gen_a}, {"B",gen_b}, {"I",gen_i}, {"LISTEN", conf_listen}, {"LISTENEX", conf_listenex}, #ifdef HAVE_SSL { "PUBLICKEY", conf_publickey}, { "PRIVATEKEY", conf_privatekey}, #endif {"PASSWORD",conf_password}, {"ADMINPASS",gen_s}, {"ALLOW",conf_allow}, {"VHOST",gen_v}, {"DEFAULTVHOST",gen_x}, {"PIDFILE",gen_p}, {"MOTDFILE",gen_m}, {"USEIDENTWD",gen_w}, {"LOGFILE",gen_l}, {NULL,NULL} }; int mytoi(char *buf) { int acum; int p; acum=0; for(p=0;buf[p];p++) { if( isdigit( buf[p] )) { acum*=10; acum+= ( buf[p] - '0' ); } } return acum; } void add_access (confetti * jr, accesslist * a) { if (!jr->has_alist) { jr->alist = jr->alist_end = a; jr->has_alist++; } else { jr->alist_end->next = a; jr->alist_end = a; } } CONFCMD(conf_password) { if(pargc < 2) { return -1; } strncpy (jr->dpass, pargv[1], PASSLEN); jr->dpass[PASSLEN]='\0'; jr->dpassf = 1; return 0; } CONFCMD(conf_listenex) { int idx; char *opt; unsigned int flags; int f_argc; char *f_argv[1]; char *localhost; char *maxusers; char *port; char *strend; unsigned long ulport; localhost = NULL; maxusers = NULL; flags = 0; f_argc = 0; idx = 1; while(idx < pargc) { opt = pargv[idx++]; if(*opt == '-') { ++opt; if(*opt == '-') { ++opt; // long options if( strcasecmp(opt, "localhost") == 0) { if(idx >= pargc) { fprintf(stderr, "--localhost requires argument\n"); return -1; } localhost = pargv[idx++]; } else if( strcasecmp(opt, "limit") == 0) { if(idx >= pargc) { fprintf(stderr, "--limit requires argument\n"); return -1; } maxusers = pargv[idx++]; } else if( strcasecmp(opt, "ipv6") == 0) { flags |= USE_IPV6; } #ifdef HAVE_SSL else if(strcasecmp(opt, "ssl") == 0) { flags |= USE_SSL; } #endif else { fprintf(stderr, "Unknown long options --%s\n", opt); return -1; } } else { // short options } } else { if(f_argc >= 1) break; f_argv[f_argc++] = opt; } } if(f_argc < 1) return -1; port = f_argv[0]; if(localhost) { strncpy(jr->dhost, localhost, HOSTLEN); jr->dhost[HOSTLEN] = 0; } if(maxusers) { unsigned long t; t = strtoul(maxusers, &strend, 0); if(t > UINT_MAX || strend == maxusers) { fprintf(stderr, "Invalid maxusers argument\n"); return -1; } jr->maxusers = t; } ulport = strtoul(port, &strend, 0); if(ulport > USHRT_MAX || strend == port) { fprintf(stderr, "Invalid port %lu\n", ulport); return -1; } jr->dport = ulport; jr->optflags |= flags; req |= 1; return 0; } CONFCMD(conf_listen) { char *src; char *dest; char *eod; char *port; #if 0 int p; for(p = 0; p < pargc; p++) { printf("(%i) %s\n", p, pargv[p]); } #endif if(pargc < 2) { return -1; } port = pargv[1]; for(src = pargv[1]; *src; src++) { if(*src == '[') { for(src++; *src; src++) { if(*src == ']') { src++; break; } } } if(*src == ':') { int flag; port = src + 1; dest = jr->dhost; eod = dest + HOSTLEN; flag = 0; for(src = pargv[1]; *src; src++) { if( *src == '[' && (flag & 1) == 0) { flag |= 1; continue; } if( *src == ']' && (flag & 1) == 1) { flag &= ~1; continue; } if( *src == ':' && (flag & 1) == 0) break; if(dest >= eod) break; *dest++ = *src; } *eod = '\0'; break; } } jr->dport = (mytoi(port) % 65535); jr->maxusers=0; req|=1; if(pargc < 3) { return 0; } jr->maxusers=mytoi(pargv[2]); return 0; } #ifdef HAVE_SSL CONFCMD(conf_publickey) { if (pargc < 2) { return 0; } strncpy (jr->public_cert_file, pargv[1], FILELEN); jr->public_cert_file[FILELEN]='\0'; return 0; } CONFCMD(conf_privatekey) { if (pargc < 2) { return 0; } strncpy (jr->private_cert_file, pargv[1], FILELEN); jr->private_cert_file[FILELEN]='\0'; return 0; } #endif CONFCMD(conf_allow) { accesslist *na; int p; if (pargc < 2) { return 0; } for(p=1;ptype = 1; strncpy (na->addr, pargv[p], HOSTLEN); na->addr[HOSTLEN]='\0'; na->next = NULL; add_access (jr, na); } return 0; } CONFCMD(gen_c) { if(pargc < 2) { return 0; } jr->cport = mytoi(pargv[1]); if(jr->cport < 0) { jr->cport=0; } if(jr->cport > 65535) { jr->cport = 65535; } return 0; } CONFCMD(gen_d) { if (pargc < 3) { return 0; } req |= 1; jr->dport = mytoi (pargv[1]); jr->maxusers = mytoi (pargv[2]); if (pargc > 3) { strncpy (jr->dpass, pargv[3], PASSLEN); jr->dpass[PASSLEN]='\0'; jr->dpassf = 1; } return 0; } CONFCMD(gen_p) { if (pargc < 2) { return 0; } strncpy (jr->pidfile, pargv[1], FILELEN); jr->pidfile[FILELEN]='\0'; return 0; } CONFCMD(gen_s) { if (pargc < 2) { return 0; } strncpy (jr->spass, pargv[1], PASSLEN); jr->spass[PASSLEN]='\0'; req |= 2; return 0; } CONFCMD(gen_v) { struct vhostentry *vhost_ptr; if (pargc < 2) { return 0; } vhost_ptr = (struct vhostentry *) pmalloc (sizeof (struct vhostentry)); if (vhost_ptr == NULL) { return 0; } vhost_ptr->next=jr->vhostlist; jr->vhostlist=vhost_ptr; strncpy (vhost_ptr->vhost, pargv[1], HOSTLEN); vhost_ptr->vhost[HOSTLEN]='\0'; return 0; } CONFCMD(gen_x) { if (pargc < 2) { return 0; } strncpy (jr->vhostdefault, pargv[1], HOSTLEN); jr->vhostdefault[HOSTLEN]='\0'; return 0; } CONFCMD(gen_l) { if (pargc < 2) { return 0; } if ((jr->logfile = fopen (pargv[1], "ab")) != NULL) { jr->logf = 1; } return 0; } CONFCMD(gen_m) { if (pargc < 2) { return 0; } strncpy (jr->motdf, pargv[1], 256); jr->motdf[256]='\0'; jr->usemotd = 1; return 0; } CONFCMD(gen_w) { if (pargc < 2) { jr->identwd = 1; return 0; } jr->identwd = mytoi (pargv[1]); return 0; } CONFCMD(gen_a) { accesslist *na; if (pargc < 3) { return 0; } if (mytoi (pargv[1]) > 2) { return 0; } na = pmalloc (sizeof (accesslist)); na->type = mytoi (pargv[1]); strncpy (na->addr, pargv[2], HOSTLEN); na->addr[HOSTLEN]='\0'; na->next = NULL; add_access (jr, na); return 0; } CONFCMD(gen_b) { if(pargc < 2) { return 0; } jr->mtype=mytoi(pargv[1]); if(jr->mtype > 1) { jr->mtype=1; } printf("mtype is %i\n",jr->mtype); return 0; } CONFCMD(gen_i) { if (pargc < 2) { jr->logfile = fopen (".ident", "ab"); } else { jr->logfile = fopen (pargv[1], "ab"); } return 0; } /****************************** printf ("--Option line in error:(%i)\n", pargc); for (p = 0; p < pargc; p++) { printf (" %i:%s\n", p, pargv[p]); } *******************************/ int confoption(confetti * jr, int pargc, char **pargv) { int p; for(p=0;confcmdlist[p].name;p++) { if(!strcasecmp(confcmdlist[p].name,pargv[0])) { return confcmdlist[p].func(jr,pargc,pargv); } } printf ("Skipping unknown Field in conf file: (%s)\n", pargv[0]); return -1; } int loadconf (char *fname, confetti * jr) { FILE *src; unsigned char linbuff[1024]; char *pargv[100]; char *tmp; int p; int err; int line; // set some defaults jr->maxusers = 0; jr->optflags = 0; req = 0; if ((src = fopen (fname, "rb")) == NULL) { return CONFNOTFOUND; } line=0; while (!feof (src)) { if ((fgets (linbuff, 1024, src)) == NULL) { break; } line++; p = 0; if(strlen(linbuff) < 2) continue; if(linbuff[1] == ':') { /* old style */ printf("old style\n"); tmp = strtok (linbuff, ":\n\r"); if (tmp != NULL) { if(tmp[0] == '#') { continue; } pargv[p++] = tmp; while ((tmp = strtok (NULL, ": \n\r")) != NULL) { pargv[p++] = tmp; if (p > 100) { break; } } err = confoption (jr, p, pargv); if(err == -1) { printf ("--Option line in error:(%i)\n", line); } } } else { tmp = strtok (linbuff, " \n\r,"); if (tmp != NULL) { if(tmp[0] == '#') { continue; } pargv[p++] = tmp; while ((tmp = strtok (NULL, " \n\r,")) != NULL) { pargv[p++] = tmp; if (p > 100) { break; } } err = confoption (jr, p, pargv); if(err == -1) { printf ("--Option line in error:(%i)\n", line); } } } } fclose (src); if (req != 3) { return CONFREQNOTHAPPY; } return 0; } unsigned char tolowertab[] = { 0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, ' ', '!', '"', '#', '$', '%', '&', 0x27, '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff }; unsigned char touppertab[] = { 0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, ' ', '!', '"', '#', '$', '%', '&', 0x27, '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', 0x5f, '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff };