#include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef NO_CRYPT_DOT_H #include #endif #include "globals.h" #include "functions.h" #include "language.h" unsigned char help_message[sizeof(HELP)+sizeof(CHAN_HELP)+2]; void safestrncpy(char *dest, char *source, int n) { int r; for (r=0; rBANS_BUFFER_SIZE) { return 1; } strcpy(banptr,addr); bancount++; return 0; } void read_config() { FILE *fp; int r=0,w=0,t; unsigned char name[100]; unsigned char *badwordptr; unsigned char *allowptr; allowcount=0; allowptr=allows; bancount=0; badwordcount=0; badwordptr=badword; welcomelen=0; fp=fopen(configdir,"r"); if (fp==0) { printf("Couldn't open %s. Trying /usr/local/etc/nakenchat.conf\n",configdir); strcpy(configdir,"/usr/local/etc/nakenchat.conf"); fp=fopen(configdir,"r"); if (fp==0) { printf("Couldn't open %s. Trying ./nakenchat\n",configdir); strcpy(configdir,"./nakenchat.conf"); fp=fopen(configdir,"r"); if (fp==0) { printf("No config file found. Going with defaults.\n"); } } } if (fp!=0) { printf("Config File: %s\n",configdir); while(fgets(name,100,fp)!=NULL) { t=0; while((name[t]!=' ' && name[t]!='\t') && (name[t]!='\n' && name[t]!='\r')) { if (t==100) break; t++; } if (name[0]==0 || (name[0]=='\n' || name[0]=='\r')) name[0]='#'; name[t++]=0; if (name[0]!='#') { w=0; if (strcasecmp(name,"SYSOP_PASSWORD")==0) w=1; else if (strcasecmp(name,"BAD_WORD")==0) w=2; else if (strcasecmp(name,"ALLOW")==0) w=3; else if (strcasecmp(name,"BAN")==0) w=4; else if (strcasecmp(name,"INTERNATIONAL")==0) w=5; else if (strcasecmp(name,"PORT")==0) w=6; else if (strcasecmp(name,"HOSTLOOKUPS")==0) w=7; else if (strcasecmp(name,"SHOWIPS")==0) w=8; else if (strcasecmp(name,"WELCOME")==0) addtowelcome(&name[t]); else if (strcasecmp(name,"NODUPIPS")==0) w=9; else if (strcasecmp(name,"LOGFILE")==0) w=10; else if (strcasecmp(name,"MAXCONN")==0) w=11; else if (strcasecmp(name,"MINCONN")==0) w=12; else if (strcasecmp(name,"MAX_IDLE_TIME")==0) w=13; else if (strcasecmp(name,"PASSWD")==0) w=14; else if (strcasecmp(name,"CENSOR")==0) w=15; else if (strcasecmp(name,"CHANNEL_DISABLE")==0) w=16; else if (strcasecmp(name,"LOGGING")==0) w=17; else if (strcasecmp(name,"FORCE_PASSWD")==0) w=18; else if (strcasecmp(name,"FORCE_NAME")==0) w=19; else if (strcasecmp(name,"NODUP_NAMES")==0) w=20; if (w!=0) { while(name[t]==' ' || name[t]=='\t') { if (name[t]==0 || (name[t]=='\r' || name[t]=='\n')) break; t++; } r=t; while((name[t]!=' ' && name[t]!='\t') && ((name[t]!='\n' && name[t]!='\r') && name[t]!=0)) { t++; } if (r!=t) { name[t]=0; if (w==1) safestrncpy(sysoppw,&name[r],15); else if (w==2) { if (strlen(&name[r])+badwordptr+1>=badword+BAD_WORD_BUFFER_SIZE) { printf("Exceeded %d bytes for bad words. Cannot add word %s\n",BAD_WORD_BUFFER_SIZE,&name[r]); } else { strcpy(badwordptr,&name[r]); badwordptr=badwordptr+strlen(&name[r])+1; badwordcount++; } } else if (w==3) { if (strlen(&name[r])+allowptr+1>=allows+ALLOWS_BUFFER_SIZE) { printf("Exceeded %d bytes for allows. Cannot add site %s\n",ALLOWS_BUFFER_SIZE,&name[r]); } else { strcpy(allowptr,&name[r]); allowptr=allowptr+strlen(&name[r])+1; allowcount++; } } else if (w==4) { if (ban_address(&name[r])==1) { printf("Exceeded %d bytes for bans. Cannot add site %s\n",BANS_BUFFER_SIZE,&name[r]); } } else if (w==5) { if (atoi(&name[r])==1) international=1; } else if (w==6) port=atoi(&name[r]); else if (w==7) { if (atoi(&name[r])==1) serverflags=serverflags|2; } else if (w==8) { if (atoi(&name[r])==1) serverflags=serverflags|4; } else if (w==9) { if (atoi(&name[r])==1) serverflags=serverflags|8; } else if (w==10) { strcpy(logfile,&name[r]); } else if (w==11) maxconn=atoi(&name[r]); else if (w==12) minconn=atoi(&name[r]); else if (w==13) max_idle_time=atoi(&name[r])*60; else if (w==14) { strcpy(passwd,&name[r]); } else if (w==15) censor=atoi(&name[r]); else if (w==16) { if (atoi(&name[r])==1) serverflags=serverflags|1; } else if (w==17) { if (atoi(&name[r])==1) logfile_on(-1); } else if (w==18) { if (atoi(&name[r])==1) serverflags=serverflags|32; } else if (w==19) { if (atoi(&name[r])==1) serverflags=serverflags|64; } else if (w==20) { if (atoi(&name[r])==1) serverflags=serverflags|128; } } } } } fclose(fp); } if (welcomelen==0) { strcpy(welcome,">> Naken Chat - Copyright 1997-2003 Michael Kohn\n\r\n\r"); welcomelen=strlen(welcome); return; } sprintf(help_message,HELP,EMOTE_CHAR); if ((serverflags&1)==0) { strcat(help_message,CHAN_HELP); } /* { strcpy(&help_message[sizeof(HELP)-1],CHAN_HELP); } */ strcat(help_message,"\n\r"); } void message(int ID, char *daMessage, int att) { unsigned char newMessage[2048]; unsigned char tempMessage[2048]; int t; if (users[ID]->inuse!=1 && users[ID]->inuse!=100) return; if (att==1) { if ((users[ID]->uflags&1)!=0) { sprintf(newMessage,"%c%s",(char)7,daMessage); } else { strcpy(newMessage,daMessage); } if ((users[ID]->uflags&2)!=0) { sprintf(tempMessage,"%c[1m%s%c[0m",(char)27,newMessage,(char)27); strcpy(newMessage,tempMessage); } if ((users[ID]->uflags&32)!=0 && time(NULL)-users[ID]->stamptime>600) { t=time(NULL); sprintf(tempMessage,">> %s\r",ctime((time_t*)&t)); strcat(newMessage,tempMessage); users[ID]->stamptime=time(NULL); } #ifdef LEET if ((serverflags&16)==16) { leet(newMessage); } #endif if (write(users[ID]->socketid,newMessage,strlen(newMessage))<=0) { users[ID]->inuse=4; close(users[ID]->socketid); kill_user(ID); } } else { if ((users[ID]->uflags&32)!=0 && time(NULL)-users[ID]->stamptime>600) { t=time(NULL); sprintf(newMessage,"%s>> %s\r",daMessage,ctime((time_t*)&t)); #ifdef LEET if ((serverflags&16)==16) { leet(newMessage); } #endif users[ID]->stamptime=time(NULL); if (write(users[ID]->socketid,newMessage,strlen(newMessage))<=0) { users[ID]->inuse=4; close(users[ID]->socketid); kill_user(ID); } } else { #ifdef LEET strcpy(newMessage,daMessage); if ((serverflags&16)==16) { leet(newMessage); } if (write(users[ID]->socketid,newMessage,strlen(newMessage))<=0) { users[ID]->inuse=4; close(users[ID]->socketid); kill_user(ID); } #else if (write(users[ID]->socketid,daMessage,strlen(daMessage))<=0) { users[ID]->inuse=4; close(users[ID]->socketid); kill_user(ID); } #endif } } } int getNum(char *myString,int ID) { int r,len,out=0; r=0; len=strlen(myString); while (r='0' && myString[r]<='9')) { if (r<8) out=out*10+(myString[r]-48); r++; } if (r==0) { if (ID!=-1) { message(ID,UNDERSTAND_MESSAGE,0); } return -1; } if (ID!=-1) { if (out>maxconn || users[out]->inuse!=1) { message(ID,NOT_HERE,0); return -1; } } return out; } int strip(char *myString) { int r=0; while(myString[r]>='0' && myString[r]<='9') { /* if (myString[r]==0) return r; */ r++; } while(myString[r]==' ') { /* if (myString[r]==0) return r; */ r++; } return r; } void timediff(int time1,int time2, char *thisString) { int temp; unsigned char tempString[70]; thisString[0]=0; if (time1channel])==0) return -2; for (r=1; ruser_level<10) return -1; oflag=-1; for (r=0; r<=MAXCHAN; r++) { if (channels[r][0]==0) oflag=-2; if (strcasecmp(Name,channels[r])==0) { oflag=r; break; } } curr=users[ID]->channel; if (curr!=0 && oflag!=-1) { for (r=0; rinuse==1) if (users[r]->channel==curr && r!=ID) r=MAXCONN+6; if (r=0) return oflag; else if (oflag==-1) return -3; for (r=1; r<=MAXCHAN; r++) { if (channels[r][0]==0) { strcpy(channels[r],Name); if ((serverflags&1)==0) { channelop[r]=ID; } else { channelop[r]=-1; } return r; } } return users[ID]->channel; } int ConvNum(char *myString) { int r=0; unsigned char tempString[40]; safestrncpy(tempString,myString,39); while(r<39) { if (tempString[r]<'0' || tempString[r]>'9') break; r++; } tempString[r]=0; if (r==0) return -1; return atoi(tempString); } void channelinfo(int ID) { unsigned char myString[WHO_BUFFER_SIZE]; unsigned char tempString[100]; unsigned char cops[128]; int r,buffer_ptr; #ifdef HIDDEN_CAVES int t; #endif buffer_ptr=0; strcpy(myString,CHANNEL_HEADER1); buffer_ptr=sizeof(CHANNEL_HEADER1)-1; strcpy(&myString[buffer_ptr],"------------------------------------------\n\r"); buffer_ptr+=sizeof("------------------------------------------\n\r")-1; strcpy(&myString[buffer_ptr],CHANNEL_HEADER2); buffer_ptr+=sizeof(CHANNEL_HEADER2)-1; for(r=1; r<=MAXCHAN; r++) { if (channels[r][0]!=0) { #ifdef HIDDEN_CAVES if ((t=ConvNum(channels[r]))<1000 || t>=2000) #endif { if (users[ID]->user_level<10 && channelop[r]>=0) { if (users[channelop[r]]->user_level==10 && (users[channelop[r]]->uflags&128)!=0) { continue; } } if (channelop[r]>=0) { sprintf(cops,"[%d]%s",channelop[r],users[channelop[r]]->username); } else { strcpy(cops,NOONE); } if ((cflags[r]&1)==1) { sprintf(tempString,"%-15s %-20s "YES"\n\r",channels[r],cops); } else { sprintf(tempString,"%-15s %-20s "NO"\n\r",channels[r],cops); } strcpy(&myString[buffer_ptr],tempString); buffer_ptr=buffer_ptr+strlen(tempString); if (buffer_ptr>WHO_BUFFER_SIZE-150) { message(ID,myString,0); buffer_ptr=0; myString[0]=0; } } } } strcpy(&myString[buffer_ptr],"\n\r"); message(ID,myString,0); } void viewbans(int ID) { unsigned char myString[BANS_BUFFER_SIZE+1024]; unsigned char tempString[1024]; unsigned char *banptr; int r,c; strcpy(myString,CURRENTBAN); banptr=bans; c=0; for (r=0; r> %d: %s\n\r",r,banptr); strcat(myString,tempString); banptr=banptr+(strlen(banptr))+1; c=c+strlen(tempString); if (c>BANS_BUFFER_SIZE) { message(ID,myString,0); tempString[0]=0; c=0; } } sprintf(tempString,BANCOUNT,bancount); strcat(myString,tempString); message(ID,myString,0); } int is_number(char *myString) { int r=0; while((myString[r]!=' ' && myString[r]!='\t') && ((myString[r]!='\n' && myString[r]!='\r') && myString[r]!=0)) { if (myString[r]<'0' || myString[r]>'9') return 0; r++; } if (r==0) return 0; return 1; } void update_list(int ID, int add) { unsigned char tempString[128]; int r; if (add==1) { sprintf(tempString,"+[%d]%s\n\r",ID,users[ID]->username); } else { sprintf(tempString,"-[%d]%s\n\r",ID,users[ID]->username); } for (r=0; rinuse==1 && ((users[r]->uflags&256)!=0 && users[r]->channel==users[ID]->channel)) #else if (users[r]->inuse==1 && (users[r]->uflags&256)!=0) #endif { message(r,tempString,0); } } } void clientshow(int ID) { unsigned char myString[maxconn*20]; unsigned char temp[80]; int r; /* strcpy(myString,""); */ strcpy(myString,"@\n\r"); for (r=0; ruser_level<10 && (users[r]->user_level==10 && (users[r]->uflags&128)!=0)) { continue; } #ifdef USER_LIST_CHAN if (users[r]->inuse==1 && users[r]->channel==users[ID]->channel) #else if (users[r]->inuse==1) #endif { sprintf(temp,"+[%d]%s\n\r",r,users[r]->username); strcat(myString,temp); } } message(ID,myString,0); } void show_levels(int ID) { unsigned char myString[maxconn*80+500]; unsigned char tempString[1024]; int r; strcpy(myString,"----------------------------------\n\r"); for (r=0; rinuse==1) { sprintf(tempString,"[%d]%-20s %d\n\r",r,users[r]->username,users[r]->user_level); strcat(myString,tempString); } } strcat(myString,"----------------------------------\n\r"); message(ID,myString,0); } void who(int ID,char *grep) { int c,r,num=-2,trim=0,buffer_ptr; unsigned char myString[WHO_BUFFER_SIZE]; unsigned char tempString[1024]; unsigned char flags[6]; unsigned char channelString[20]; unsigned char location[21]; unsigned char idleString[40]; unsigned char tempf[40]; time_t myTime; #ifdef HIDDEN_CAVES int n; #endif sprintf(tempf,"%%-%ds %%-14s %%s ",MAX_USER_NAME_LENGTH+9); sprintf(myString,tempf,WHO_NAME,WHO_CHANNEL,WHO_IDLE); if ((serverflags&4)!=0 || users[ID]->user_level==10) { strcat(myString,WHO_LOCATION); } strcat(myString,"\n\r"); sprintf(tempf,"[%%d]%%-%ds %%-5s %%-14s %%4s %%s\n\r",MAX_USER_NAME_LENGTH); strcpy(location,""); myTime=time(NULL); while (grep[trim]==' ') trim++; if (is_number(&grep[trim])==1) { num=getNum(&grep[trim],-1); grep[trim]=0; } else { r=trim; while((grep[r]!='\n' && grep[r]!='\r') && ((grep[r]!=' ' && grep[r]!='\t') && grep[r]!=0)) r++; grep[r]=0; } c=0; buffer_ptr=strlen(myString); for(r=0; ruser_level<10 && (users[r]->user_level==10 && (users[r]->uflags&128)!=0)) { continue; } if ((serverflags&1)==1 && (users[ID]->channel!=users[r]->channel && users[ID]->user_level<8)) continue; if (num!=-2 && num!=r) continue; strcpy(flags,"-----"); if (users[r]->inuse==1) { if ((users[r]->uflags&8)==8) flags[0]='H'; if ((users[r]->gags[ID/8]&(1<<(ID%8)))!=0) flags[0]='G'; if ((users[r]->uflags&1)==1) flags[1]='B'; if ((users[ID]->gags[r/8]&(1<<(r%8)))!=0) flags[1]='g'; if ((channelop[users[r]->channel]==r) && users[r]->channel!=0) flags[2]='O'; if ((cflags[users[r]->channel]&1)==1) flags[3]='L'; if ((users[r]->uflags&4)==4) flags[4]='S'; #ifdef HIDDEN_CAVES if ((n=ConvNum(channels[users[r]->channel]))>=1000 && n<=1999) { strcpy(channelString,"Hidden Cave"); } else #endif { strcpy(channelString,channels[users[r]->channel]); } shorttimediff(myTime,users[r]->idletime,idleString); if ((serverflags&4)!=0 || users[ID]->user_level==10) { safestrncpy(location,users[r]->location,20); } sprintf(tempString,tempf,r,users[r]->username,flags,channelString, idleString,location); if (grep[trim]==0) { strcpy(&myString[buffer_ptr],tempString); buffer_ptr=buffer_ptr+strlen(tempString); c++; } else { if (strstr(tempString,&grep[trim])!=NULL) { strcpy(&myString[buffer_ptr],tempString); buffer_ptr=buffer_ptr+strlen(tempString); c++; } } if (buffer_ptr>WHO_BUFFER_SIZE-150) { message(ID,myString,0); buffer_ptr=0; myString[0]=0; } } } strcpy(&myString[buffer_ptr],"--------------------------------------------------------"); buffer_ptr=buffer_ptr+sizeof("--------------------------------------------------------")-1; sprintf(tempString,WHO_TOTAL,c); strcpy(&myString[buffer_ptr],tempString); message(ID,myString,0); } void who_short(int ID) { unsigned char myString[WHO_BUFFER_SIZE]; unsigned char tempString[1024]; int c,r,buffer_ptr; buffer_ptr=0; strcpy(myString,"--------------------------------------------------------\n\r"); buffer_ptr=sizeof("--------------------------------------------------------\n\r")-1; c=0; for (r=0; rinuse==1) { if (users[ID]->user_level<10 && (users[r]->user_level==10 && (users[r]->uflags&128)!=0)) { continue; } if ((serverflags&1)==1 && (users[ID]->channel!=users[r]->channel && users[ID]->user_level<8)) continue; c++; sprintf(tempString,"[%d]%-18s",r,users[r]->username); strcpy(&myString[buffer_ptr],tempString); buffer_ptr=buffer_ptr+strlen(tempString); if (c%3==0) { strcat(&myString[buffer_ptr],"\n\r"); buffer_ptr=buffer_ptr+2; } } if (buffer_ptr>WHO_BUFFER_SIZE-150) { message(ID,myString,0); buffer_ptr=0; myString[0]=0; } } if (c%3!=0) { strcpy(&myString[buffer_ptr],"\n\r"); buffer_ptr=buffer_ptr+2; } strcpy(&myString[buffer_ptr],"--------------------------------------------------------\n\r"); message(ID,myString,0); } void sendpriv(int ID,int OID,char *daMessage) { unsigned char tempString[9000]; #ifdef DEBUG if (debug==1) printf("TO: %d FROM: %d MESSAGE: %s\n",ID,OID,daMessage); #endif if (logging==1) { fprintf(logfp,"TO: %d %s FROM: %d %s MESSAGE: %s",ID,users[ID]->username, OID,users[OID]->username,daMessage); fflush(logfp); } if (IDinuse==1) { message(ID,daMessage,1); if ((users[OID]->uflags&16)==0) { sprintf(tempString,PRIVATE,ID,users[ID]->username); } else { sprintf(tempString,PRIVATE_ECHO,ID,users[ID]->username,daMessage); } message(OID,tempString,0); } else { message(OID,NOT_HERE,0); } } else { message(OID,NOT_HERE,0); } } void sendchan(int ID, int channel, char *daMessage) { int r; if (logging==1) { fprintf(logfp,"[%s]",channels[channel]); fprintf(logfp,"%s",daMessage); fflush(logfp); } for (r=0; rinuse==1 && users[r]->channel==channel) { if (ID==-1) message(r,daMessage,0); else if ((users[r]->gags[ID/8]&(1<<(ID%8)))==0) { if (users[r]->user_level<10 && (users[ID]->user_level==10 && (users[ID]->uflags&128)!=0)) { continue; } message(r,daMessage,0); } } } } void yell(int ID,char *daMessage) { int r; if (logging==1) { fprintf(logfp,"%s",daMessage); fflush(logfp); } for(r=0; rinuse==1) { if ((users[r]->gags[ID/8]&(1<<(ID%8)))==0) if ((users[r]->uflags&8)==0) message(r,daMessage,0); } } } void sendchanbut(int ID, int channel, char *daMessage) { int r; if (logging==1) { fprintf(logfp,"[%s]",channels[channel]); fprintf(logfp,"%s",daMessage); fflush(logfp); } for (r=0; rinuse==1 && users[r]->channel==channel) && (r!=ID && (users[r]->uflags&64)==0)) { if (users[r]->user_level<10 && (users[ID]->user_level==10 && (users[ID]->uflags&128)!=0)) { continue; } message(r,daMessage,0); } } } void sendall(int ID, char *daMessage) { int r; if (logging==1) { fprintf(logfp,"%s",daMessage); fflush(logfp); } for (r=0; rinuse==1) { if (ID==-1) message(r,daMessage,0); else if ((users[r]->gags[ID/8]&(1<<(ID%8)))==0 && (users[r]->uflags&64)==0) { if (users[r]->user_level<10 && (users[ID]->user_level==10 && (users[ID]->uflags&128)!=0)) { continue; } message(r,daMessage,0); } } } } void sendallbut(int ID, char *daMessage) { int r; if (logging==1) { fprintf(logfp,"%s",daMessage); fflush(logfp); } for (r=0; rinuse==1 && r!=ID) { if (ID==-1) message(r,daMessage,0); else if ((users[r]->gags[ID/8]&(1<<(ID%8)))==0 && (users[r]->uflags&64)==0) { if (users[r]->user_level<10 && (users[ID]->user_level==10 && (users[ID]->uflags&128)!=0)) { continue; } message(r,daMessage,0); } } } } void help(int ID) { message(ID,help_message,0); } void setup(int argc, char *argv[]) { unsigned char *allowptr; unsigned char *banptr; int r; port=DEFAULT_PORT; configdir[0]=0; for (r=1; rinuse!=0) { if (strncasecmp(users[t]->username,name,MAX_USER_NAME_LENGTH)==0) { return 1; } } } return 0; } int read_param(FILE *fp, char *s) { int ch; int r; r=0; s[0]=0; while(1) { ch=getc(fp); if (ch==EOF && r==0) return -1; if ((ch=='\n' || ch=='\r') && r==0) continue; if (ch=='\\') { s[r++]=getc(fp); continue; } if (ch==':' || ch=='\n' || ch=='\r' || ch==EOF) break; s[r++]=ch; } s[r]=0; if (ch==':') return 1; return 0; } int checkname_reg(unsigned char *name, int ID) { FILE *in; unsigned char *p; unsigned char param[1024]; char seed[3]; char crypted[20]; unsigned int l,t; int i; in=fopen(passwd,"rb"); if (in==0) { #ifdef DEBUG if (debug==1) printf("Couldn't open password file.\n"); #endif passwd[0]=0; return 1; } l=strlen(name); t=l; while (name[l]!='=' && l>0) l--; if (l==0) { p=&name[t]; } else { name[l]=0; p=&name[l+1]; } while(1) { i=read_param(in,param); if (strcasecmp(param,name)==0) { if (ID==-1) return 1; read_param(in,param); seed[0]=param[0]; seed[1]=param[1]; seed[2]=0; strcpy(crypted,crypt(p,seed)); if (strcmp(crypted,param)!=0) { fclose(in); return 1; } read_param(in,param); users[ID]->user_level=atoi(param); read_param(in,param); users[ID]->emote_char=param[0]; read_param(in,param); t=atoi(param); l=0xffffffff^(1|2|16); users[ID]->uflags=users[ID]->uflags&l; users[ID]->uflags=users[ID]->uflags|t; read_param(in,param); i=channel(ID,param); if (i>=0) { users[ID]->channel=i; users[ID]->uflags=users[ID]->uflags&65531; } fclose(in); return 0; } if (i==1) { while(read_param(in,param)); } else { break; } } fclose(in); return 2; }