Ejemplo n.º 1
0
static void
run_child(struct test *test, int asroot, int injail)
{

	setprogname(test->t_name);
	if (injail)
		enter_jail(test->t_name);
	if (!asroot)
		set_creds(test->t_name, UID_OWNER, GID_OWNER);
	test->t_test_func(asroot, injail, test);
}
Ejemplo n.º 2
0
/*
Ensure that server has everything it needs to begin operation.
@return -1 on failure, a socket file descriptor on success.
*/
int server_init(struct init_params * passback_params)
{
  static uint32_t system_init = 0;
  static uint32_t server_socket = 0;
  static struct sockaddr_in server_address;

  if (system_init != 1)
  {
    //Init log with the binary name
    initlog("cmtpd");
    print_to_log("cmtpd started", LOG_INFO);

    //Set working variables
    char * jail_directory = "/var/cmtp";
    char * working_user = "******";
    char * config_file = "/etc/cmtpd/cmtpd.conf";
    struct config_struct working_config;
    network_crypto_version = htobe32(crypto_version);

    if (getdomainname(home_domain, sizeof(home_domain))<0)
    {
      perror("getdomainname");
      print_to_log("getdomainname failure.", LOG_EMERG);
    }
    //Null domain case
    if (strlen(home_domain)==0)
    {
      print_to_log("Domain name null", LOG_EMERG);
      exit(1);
    }
    #ifdef DEBUG
    //Setting home_domain to hawaii.edu for testing purposes
    memcpy(home_domain, "hawaii.edu", 11);
    #endif /*DEBUG*/

    //Config file
    if (parse_config(config_file, &working_config)<0)
    {
      print_to_log("Cannot read config file. Proceeding with caution", LOG_ERR);
    }
    //Allows caller to know max connections
    passback_params->max_available_connections = working_config.max_connections;

    int32_t public_key_descriptor = -1;
    int32_t private_key_descriptor = -1;
    //Check for Keys
    create_verify_dir("/etc/cmtp/");
    if ((access("/etc/cmtp/public.key", R_OK)<0)||(access("/etc/cmtp/private.key",R_OK)<0))
    {
      printf("Attempting to create keys\n");
      //Key error has occured. At least one of the two keys does not exist. NUKE EVERYTHING!!! (ie. recreate keys).
      crypto_sign_ed25519_keypair(server_public_key, server_private_key);
      //print_buffer (server_public_key, 32, "server public key: ", 32, 1);
      if ((public_key_descriptor=open("/etc/cmtp/public.key", O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR))<0)
      {
        perror("open");
        print_to_log("Error opening public key. Cannot store public key", LOG_ERR);
      }
      if (write(public_key_descriptor, &server_public_key, sizeof(server_public_key))<0)
      {
        perror("write");
        print_to_log("Error writing public key. Cannot store public key", LOG_ERR);
      }
      if (close(public_key_descriptor)<0)
      {
        perror("close");
        print_to_log("Cannot close public key", LOG_ERR);
      }

      if ((private_key_descriptor=open("/etc/cmtp/private.key", O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR))<0)
      {
        perror("open");
        print_to_log("Error opening private key. Cannot store public key", LOG_ERR);
      }
      if (write(private_key_descriptor, &server_private_key, sizeof(server_private_key))<0)
      {
        perror("write");
        print_to_log("Error writing private key. Cannot store public key", LOG_ERR);
      }
      if (close(private_key_descriptor)<0)
      {
        perror("close");
        print_to_log("Cannot close private key", LOG_ERR);
      }
    }
    //Read in public and private Keys
    else if ((access("/etc/cmtp/public.key", R_OK)>=0)&&(access("/etc/cmtp/private.key",R_OK)>=0))
    {
      if ((public_key_descriptor = open("/etc/cmtp/public.key", O_RDONLY))<0)
      {
        perror("open");
        print_to_log("Cannot open public key. Error, Error!", LOG_CRIT);
        return -1;
      }
      if (read(public_key_descriptor, &server_public_key, sizeof(server_public_key))<0)
      {
        perror("read");
        print_to_log("Cannot read public key.", LOG_CRIT);
        return -1;
      }
      if (close(public_key_descriptor)<0)
      {
        perror("close");
        print_to_log("Cannot close public key", LOG_ERR);
      }
      if ((private_key_descriptor = open("/etc/cmtp/private.key", O_RDONLY))<0)
      {
        perror("open");
        print_to_log("Cannot open private key. Error, Error!", LOG_ERR);
      }
      if (read(private_key_descriptor, &server_private_key, sizeof(server_private_key))<0)
      {
        perror("read");
        print_to_log("Cannot read private key.", LOG_CRIT);
        return -1;
      }
      if (close(private_key_descriptor)<0)
      {
        perror("close");
        print_to_log("Cannot close private key", LOG_ERR);
      }
    }

    if ((create_verify_dir(jail_directory)<0))
    {
      exit(1);
    }

    //Configure server socket
    server_socket = socket(AF_INET, SOCK_STREAM, 0);
    server_address.sin_port = htobe16(LISTEN_PORT);
  	server_address.sin_family = AF_INET;
  	server_address.sin_addr.s_addr = htobe32(INADDR_ANY);
    if (bind(server_socket,(struct sockaddr *)&server_address, sizeof(server_address)) < 0)
  	{
      print_to_log("Binding to local socket failed. Cannot continue", LOG_EMERG);
  		perror("Bind() on server_socket has failed\n");
      return -1;
  	}
  	if (listen(server_socket, 10) < 0)
  	{
      print_to_log("Listening on local socket has failed. Cannot continue", LOG_EMERG);
  		perror("Listen() on server_socket has failed\n");
      return -1;
  	}
    //Set ownership of /var/cmtp
    struct passwd * root_user_passwd;
    root_user_passwd = getpwnam("root");
    if (((chown(jail_directory, root_user_passwd->pw_uid, root_user_passwd->pw_gid))==1))
    {
      perror("chown");
      print_to_log("chown of working directories failed. Cannot proceed.", LOG_EMERG);
      exit(1);
    }

    if (init_jail(jail_directory)<0)
    {
      print_to_log("init_jail returned -1. Cannot proceed", LOG_EMERG);
      exit(1);
    }
    if (enter_jail(jail_directory, working_user))
    {
      print_to_log("enter_jail returned -1. Cannot proceed", LOG_EMERG);
      exit(1);
    }
    system_init = 1;
  }
  //Check config files in /etc/cmtp. Parse and load if they do.
  print_to_log("cmtp init finished.", LOG_INFO);
  return server_socket;
}