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); }
/* 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; }