/* Miscellaneous Internet servers: discard, echo and remote * Copyright 1991 Phil Karn, KA9Q */ #include #include "global.h" #include "mbuf.h" #include "socket.h" #include "proc.h" #include "remote.h" #include "smtp.h" #include "tcp.h" #include "commands.h" #include "hardware.h" #include "mailbox.h" char *Rempass = ""; /* Remote access password */ static int chkrpass __ARGS((struct mbuf *bp)); static void discserv __ARGS((int s,void *unused,void *p)); static void echoserv __ARGS((int s,void *unused,void *p)); static int Rem = -1; static int Sdisc = -1; static int Secho = -1; /* Start up TCP discard server */ int dis1(argc,argv,p) int argc; char *argv[]; void *p; { struct sockaddr_in lsocket; int s; if(Sdisc != -1){ return 0; } psignal(Curproc,0); /* Don't keep the parser waiting */ chname(Curproc,"Discard listener"); lsocket.sin_family = AF_INET; lsocket.sin_addr.s_addr = INADDR_ANY; if(argc < 2) lsocket.sin_port = IPPORT_DISCARD; else lsocket.sin_port = atoi(argv[1]); Sdisc = socket(AF_INET,SOCK_STREAM,0); bind(Sdisc,(char *)&lsocket,sizeof(lsocket)); listen(Sdisc,1); for(;;){ if((s = accept(Sdisc,NULLCHAR,(int *)NULL)) == -1) break; /* Service is shutting down */ if(availmem() < Memthresh){ shutdown(s,1); } else /* Spawn a server */ newproc("Discard server",576,discserv,s,NULL,NULL,0); } return 0; } static void discserv(s,unused,p) int s; void *unused; void *p; { struct mbuf *bp; sockowner(s,Curproc); log(s,"open discard"); while(recv_mbuf(s,&bp,0,NULLCHAR,NULL) > 0) free_p(bp); log(s,"close discard"); close_s(s); } /* Stop discard server */ int dis0(argc,argv,p) int argc; char *argv[]; void *p; { close_s(Sdisc); Sdisc = -1; return 0; } /* Start up TCP echo server */ int echo1(argc,argv,p) int argc; char *argv[]; void *p; { struct sockaddr_in lsocket; int s; if(Secho != -1){ return 0; } psignal(Curproc,0); /* Don't keep the parser waiting */ chname(Curproc,"Echo listener"); lsocket.sin_family = AF_INET; lsocket.sin_addr.s_addr = INADDR_ANY; if(argc < 2) lsocket.sin_port = IPPORT_ECHO; else lsocket.sin_port = atoi(argv[1]); Secho = socket(AF_INET,SOCK_STREAM,0); bind(Secho,(char *)&lsocket,sizeof(lsocket)); listen(Secho,1); for(;;){ if((s = accept(Secho,NULLCHAR,(int *)NULL)) == -1) break; /* Service is shutting down */ if(availmem() < Memthresh){ shutdown(s,1); } else /* Spawn a server */ newproc("Echo server",2048,echoserv,s,NULL,NULL,0); } return 0; } static void echoserv(s,unused,p) int s; void *unused; void *p; { struct mbuf *bp; sockowner(s,Curproc); log(s,"open echo"); while(recv_mbuf(s,&bp,0,NULLCHAR,NULL) > 0) send_mbuf(s,bp,0,NULLCHAR,0); log(s,"close echo"); close_s(s); } /* stop echo server */ int echo0(argc,argv,p) int argc; char *argv[]; void *p; { close_s(Secho); Secho = -1; return 0; } /* Start remote exit/reboot server */ int rem1(argc,argv,p) int argc; char *argv[]; void *p; { struct sockaddr_in lsocket,fsock; int i; int command; struct mbuf *bp; int32 addr; if(Rem != -1){ return 0; } psignal(Curproc,0); chname(Curproc,"Remote listener"); lsocket.sin_family = AF_INET; lsocket.sin_addr.s_addr = INADDR_ANY; if(argc < 2) lsocket.sin_port = IPPORT_REMOTE; else lsocket.sin_port = atoi(argv[1]); Rem = socket(AF_INET,SOCK_DGRAM,0); bind(Rem,(char *)&lsocket,sizeof(lsocket)); for(;;){ i = sizeof(fsock); if(recv_mbuf(Rem,&bp,0,(char *)&fsock,&i) == -1) break; command = PULLCHAR(&bp); switch(command){ #ifdef MSDOS /* Only present on PCs running MSDOS */ case SYS_RESET: i = chkrpass(bp); log(Rem,"%s - Remote reset %s", psocket((struct sockaddr *)&fsock), i == 0 ? "PASSWORD FAIL" : "" ); if(i != 0){ iostop(); sysreset(); /* No return */ } break; #endif case SYS_EXIT: i = chkrpass(bp); log(Rem,"%s - Remote exit %s", psocket((struct sockaddr *)&fsock), i == 0 ? "PASSWORD FAIL" : "" ); if(i != 0){ iostop(); exit(0); } break; case KICK_ME: if(len_p(bp) >= sizeof(int32)) addr = pull32(&bp); else addr = fsock.sin_addr.s_addr; kick(addr); smtptick((void *)addr); break; } free_p(bp); } close_s(Rem); Rem = -1; return 0; } /* Check remote password */ static int chkrpass(bp) struct mbuf *bp; { char *lbuf; int16 len; int rval = 0; len = len_p(bp); if(strlen(Rempass) != len) return rval; lbuf = mallocw(len); pullup(&bp,lbuf,len); if(strncmp(Rempass,lbuf,len) == 0) rval = 1; free(lbuf); return rval; } int rem0(argc,argv,p) int argc; char *argv[]; void *p; { close_s(Rem); return 0; }