/** * Copy all files needed for correct working after chrooting * * @param __dst_dir - where files should be copied */ static void copy_chroot_data (const char *__dst_dir) { char src_dir[4096]; static char init = FALSE; INF_DEBUG_LOG ("Copying chroot data to %s\n", __dst_dir); snprintf (src_dir, BUF_SIZE (src_dir), "%s/chroot", data_dir); fcopydir (src_dir, __dst_dir); snprintf (src_dir, BUF_SIZE (src_dir), "%s/chroot", data_dir); if (!init) { /* Cache list of items, needed by chrooting */ dynastruc_t *ls; int count = 0; char *cur_dir; ls = dir_listing (src_dir); DYNA_FOREACH (ls, cur_dir); strcpy (chroot_items[count++], cur_dir); DYNA_DONE; dyna_destroy (ls, dyna_deleter_free_ref_data); init = TRUE; } }
int main(int argc, char **argv){ bt_zero("~~~Userspace test program start!~~~\n"); print_string("TEST Command Prompt!\n"); while(true){ char input[128]={0}; print_string("[TEST]>"); get_string(input, 128); if(input[0]=='d') dir_listing(); else if(input[0]=='b') ata_test(); else if(input[0]=='l') dir_listing2(input); else if(input[0]=='f') file_contents(); else if(input[0]=='c') file_contents2(input); else if(input[0]=='m') mount_test(); else if(input[0]=='v') version(); else if(input[0]=='r') run_program(input); else if(input[0]=='p') path(input); else if(input[0]=='t') thread_test(); else if(input[0]=='x') crash_test(); else if(input[0]=='q') break; else { if(strlen(input) && input[0]!='\n') print_string("Unrecognised command.\n"); } } bt_zero("~~~Userspace test program done!~~~\n"); bt_exit(0); return 0; }
// // Parses the request from the client and populates req // int http_process_request(http_req *req) { char *apath, path[PATH_MAX]; struct stat statbuf; int rlen, alen; if (req->method != GET) return 0; // path with server_root prepended // get the rootLock for reading server_root pthread_rwlock_rdlock(&rootLock); pthread_cleanup_push(CTYPE pthread_mutex_unlock, CARG &rootLock); strncpy(path, server_root, sizeof(path)); pthread_cleanup_pop(0); pthread_rwlock_unlock(&rootLock); if (req->resource[0] != '/') strncat(path, "/", sizeof(path)); strncat(path, req->resource, sizeof(path) - strlen(path)); // use realpath to determine the absolute path apath = realpath(path, NULL); if (apath == NULL) { perror("apath() error"); // handle not found and not authorized conditions if (errno == ENOENT) req->status = NOT_FOUND; else if (errno == EACCES) req->status = UNAUTHORIZED; return -1; } // get the rootLock for reading server_root pthread_rwlock_rdlock(&rootLock); pthread_cleanup_push(CTYPE pthread_mutex_unlock, CARG &rootLock); rlen = strlen(server_root); alen = strlen(apath); // rewrite path and req-resource using new absolute path strncpy(path, apath, sizeof(path)); // copy server_root to ensure the request is bounded strncpy(path, server_root, rlen); pthread_cleanup_pop(0); pthread_rwlock_unlock(&rootLock); if (alen <= rlen) strncpy(req->resource, "/", strlen(req->resource)); else strncpy(req->resource, apath+rlen-1, strlen(req->resource)); free(apath); // stat it -- could we open it read-only? if (stat(path, &statbuf) < 0) { perror("stat() error"); req->status = INTERNAL_ERROR; return -1; } else if (S_ISDIR(statbuf.st_mode)) { // its a directory // output web content summarizing directory contents /* check permissions - personally I think access() works much better * in checking directory access permissions. scandir() does not fail * if the execute permission is not set on a directory. */ /* if (access(path, X_OK) < 0) { req->status = FORBIDDEN; return 0; }*/ req->resource_fd = dir_listing(path); // dir_listing returns -1 on scandir errors if (req->resource_fd == -1) { req->status = FORBIDDEN; return 0; } req->mime = "text/html"; fstat(req->resource_fd, &statbuf); req->length = statbuf.st_size; } else { // its a file, // open it and we will send it to the client req->resource_fd = open(path, O_RDONLY); if (req->resource_fd < 0) { perror("open() error"); if (errno == EACCES) req->status = UNAUTHORIZED; else req->status = INTERNAL_ERROR; } get_mime_type(req->resource, req); req->length = statbuf.st_size; } return 0; }
/** * Unlink all unwanted testing dirs */ static void unlink_unwanted_testing_dirs (void) { static BOOL initialized = FALSE; static timeval_t last_unlink; timeval_t cur = now (); mutex_lock (unlink_mutex); INF_DEBUG_LOG ("Start unlinking unwanted dirs\n"); if (!initialized) { last_unlink = now (); initialized = TRUE; } if (CHECK_TIME_DELTA (last_unlink, cur, unlink_interval)) { char *cur_dir; char lock_file[4096], full[4096]; int to_delete = 0; dynastruc_t *ls; mutex_lock (lck_mutex); ls = dir_listing (testing_dir); mutex_unlock (lck_mutex); to_delete = dyna_length (ls) - keep_alive_testdirs; if (to_delete < 0) { to_delete = 0; } DYNA_FOREACH (ls, cur_dir); if (!to_delete) { DYNA_BREAK; } snprintf (full, BUF_SIZE (full), "%s/%s", testing_dir, cur_dir); snprintf (lock_file, BUF_SIZE (lock_file), "%s/lock", full); if (!flock_test (lock_file)) { INF_INFO ("Unlink testing dir %s\n", cur_dir); unlinkdir (full); } else { INF_DEBUG_LOG ("Skipping unlinking testing dir %s\n", cur_dir); } to_delete--; DYNA_DONE; dyna_destroy (ls, dyna_deleter_free_ref_data); last_unlink = cur; } mutex_unlock (unlink_mutex); INF_DEBUG_LOG ("Unwanted dirs have been just deleted\n"); }