Exemple #1
0
void profile_read(const char *fname) {
	EUID_ASSERT();

	// exit program if maximum include level was reached
	if (include_level > MAX_INCLUDE_LEVEL) {
		fprintf(stderr, "Error: maximum profile include level was reached\n");
		exit(1);
	}

	// check file
	invalid_filename(fname);
	if (strlen(fname) == 0 || is_dir(fname)) {
		fprintf(stderr, "Error: invalid profile file\n");
		exit(1);
	}
	if (access(fname, R_OK)) {
		// if the file ends in ".local", do not exit
		const char *base = gnu_basename(fname);
		char *ptr = strstr(base, ".local");
		if (ptr && strlen(ptr) == 6)
			return;

		fprintf(stderr, "Error: cannot access profile file\n");
		exit(1);
	}

	// allow debuggers
	if (arg_allow_debuggers) {
		char *tmp = strrchr(fname, '/');
		if (tmp && *(tmp + 1) != '\0') {
			tmp++;
			if (strcmp(tmp, "disable-devel.inc") == 0)
				return;
		}
	}

	// open profile file:
	FILE *fp = fopen(fname, "r");
	if (fp == NULL) {
		fprintf(stderr, "Error: cannot open profile file %s\n", fname);
		exit(1);
	}

	int msg_printed = 0;

	// read the file line by line
	char buf[MAX_READ + 1];
	int lineno = 0;
	while (fgets(buf, MAX_READ, fp)) {
		++lineno;
		// remove empty space - ptr in allocated memory
		char *ptr = line_remove_spaces(buf);
		if (ptr == NULL)
			continue;

		// comments
		if (*ptr == '#' || *ptr == '\0') {
			free(ptr);
			continue;
		}

		// process quiet
		if (strcmp(ptr, "quiet") == 0) {
			arg_quiet = 1;
			free(ptr);
			continue;
		}
		if (!msg_printed) {
			if (!arg_quiet)
				fprintf(stderr, "Reading profile %s\n", fname);
			msg_printed = 1;
		}

		// process include
		if (strncmp(ptr, "include ", 8) == 0) {
			include_level++;

			// extract profile filename and new skip params
			char *newprofile = ptr + 8; // profile name

			// expand ${HOME}/ in front of the new profile file
			char *newprofile2 = expand_home(newprofile, cfg.homedir);

			// recursivity
			profile_read((newprofile2)? newprofile2:newprofile);
			include_level--;
			if (newprofile2)
				free(newprofile2);
			free(ptr);
			continue;
		}

		// verify syntax, exit in case of error
		if (profile_check_line(ptr, lineno, fname))
			profile_add(ptr);
// we cannot free ptr here, data is extracted from ptr and linked as a pointer in cfg structure
//		else {
//			free(ptr);
//		}
#ifdef HAVE_GCOV
		__gcov_flush();
#endif
	}
	fclose(fp);
}
Exemple #2
0
void profile_read(const char *fname) {
	EUID_ASSERT();
	
	// exit program if maximum include level was reached
	if (include_level > MAX_INCLUDE_LEVEL) {
		fprintf(stderr, "Error: maximum profile include level was reached\n");
		exit(1);	
	}

	if (strlen(fname) == 0) {
		fprintf(stderr, "Error: invalid profile file\n");
		exit(1);
	}

	// open profile file:
	FILE *fp = fopen(fname, "r");
	if (fp == NULL) {
		fprintf(stderr, "Error: cannot open profile file %s\n", fname);
		exit(1);
	}

	if (!arg_quiet)
		fprintf(stderr, "Reading profile %s\n", fname);

	// read the file line by line
	char buf[MAX_READ + 1];
	int lineno = 0;
	while (fgets(buf, MAX_READ, fp)) {
		++lineno;
		// remove empty space - ptr in allocated memory
		char *ptr = line_remove_spaces(buf);
		if (ptr == NULL)
			continue;
		
		// comments
		if (*ptr == '#' || *ptr == '\0') {
			free(ptr);
			continue;
		}
		
		// process include
		if (strncmp(ptr, "include ", 8) == 0) {
			include_level++;
			
			// extract profile filename and new skip params
			char *newprofile = ptr + 8; // profile name
			
			// expand ${HOME}/ in front of the new profile file
			char *newprofile2 = expand_home(newprofile, cfg.homedir);
			
			// recursivity
			profile_read((newprofile2)? newprofile2:newprofile);
			include_level--;
			if (newprofile2)
				free(newprofile2);
			free(ptr);
			continue;
		}
		
		// verify syntax, exit in case of error
		if (profile_check_line(ptr, lineno, fname))
			profile_add(ptr);
// we cannot free ptr here, data is extracted from ptr and linked as a pointer in cfg structure
//		else {
//			free(ptr);
//		}
	}
	fclose(fp);
}
Exemple #3
0
int checkcfg(int val) {
	EUID_ASSERT();
	assert(val < CFG_MAX);
	int line = 0;

	if (!initialized) {
		// initialize defaults
		int i;
		for (i = 0; i < CFG_MAX; i++)
			cfg_val[i] = 1; // most of them are enabled by default

		cfg_val[CFG_RESTRICTED_NETWORK] = 0; // disabled by default
		cfg_val[CFG_FORCE_NONEWPRIVS] = 0; // disabled by default
		
		// open configuration file
		char *fname;
		if (asprintf(&fname, "%s/firejail.config", SYSCONFDIR) == -1)
			errExit("asprintf");

		FILE *fp = fopen(fname, "r");
		if (!fp) {
#ifdef HAVE_GLOBALCFG			
			fprintf(stderr, "Warning: Firejail configuration file %s not found\n", fname);
			exit(1);
#else
			initialized = 1;
			return	cfg_val[val];
#endif	
		}
		
		// if the file exists, it should be owned by root
		struct stat s;
		if (stat(fname, &s) == -1)
			errExit("stat");
		if (s.st_uid != 0 || s.st_gid != 0) {
			fprintf(stderr, "Error: configuration file should be owned by root\n");
			exit(1);
		}

		// read configuration file
		char buf[MAX_READ];
		while (fgets(buf,MAX_READ, fp)) {
			line++;
			if (*buf == '#' || *buf == '\n') 
				continue;

			// parse line				
			char *ptr = line_remove_spaces(buf);
			if (!ptr)
				continue;
			
			// file transfer	
			if (strncmp(ptr, "file-transfer ", 14) == 0) {
				if (strcmp(ptr + 14, "yes") == 0)
					cfg_val[CFG_FILE_TRANSFER] = 1;
				else if (strcmp(ptr + 14, "no") == 0)
					cfg_val[CFG_FILE_TRANSFER] = 0;
				else
					goto errout;
			}
			// x11
			else if (strncmp(ptr, "x11 ", 4) == 0) {
				if (strcmp(ptr + 4, "yes") == 0)
					cfg_val[CFG_X11] = 1;
				else if (strcmp(ptr + 4, "no") == 0)
					cfg_val[CFG_X11] = 0;
				else
					goto errout;
			}
			// bind
			else if (strncmp(ptr, "bind ", 5) == 0) {
				if (strcmp(ptr + 5, "yes") == 0)
					cfg_val[CFG_BIND] = 1;
				else if (strcmp(ptr + 5, "no") == 0)
					cfg_val[CFG_BIND] = 0;
				else
					goto errout;
			}
			// user namespace
			else if (strncmp(ptr, "userns ", 7) == 0) {
				if (strcmp(ptr + 7, "yes") == 0)
					cfg_val[CFG_USERNS] = 1;
				else if (strcmp(ptr + 7, "no") == 0)
					cfg_val[CFG_USERNS] = 0;
				else
					goto errout;
			}
			// chroot
			else if (strncmp(ptr, "chroot ", 7) == 0) {
				if (strcmp(ptr + 7, "yes") == 0)
					cfg_val[CFG_CHROOT] = 1;
				else if (strcmp(ptr + 7, "no") == 0)
					cfg_val[CFG_CHROOT] = 0;
				else
					goto errout;
			}
			// nonewprivs
			else if (strncmp(ptr, "force-nonewprivs ", 17) == 0) {
				if (strcmp(ptr + 17, "yes") == 0)
					cfg_val[CFG_SECCOMP] = 1;
				else if (strcmp(ptr + 17, "no") == 0)
					cfg_val[CFG_SECCOMP] = 0;
				else
					goto errout;
			}
			// seccomp
			else if (strncmp(ptr, "seccomp ", 8) == 0) {
				if (strcmp(ptr + 8, "yes") == 0)
					cfg_val[CFG_SECCOMP] = 1;
				else if (strcmp(ptr + 8, "no") == 0)
					cfg_val[CFG_SECCOMP] = 0;
				else
					goto errout;
			}
			// whitelist
			else if (strncmp(ptr, "whitelist ", 10) == 0) {
				if (strcmp(ptr + 10, "yes") == 0)
					cfg_val[CFG_WHITELIST] = 1;
				else if (strcmp(ptr + 10, "no") == 0)
					cfg_val[CFG_WHITELIST] = 0;
				else
					goto errout;
			}
			// network
			else if (strncmp(ptr, "network ", 8) == 0) {
				if (strcmp(ptr + 8, "yes") == 0)
					cfg_val[CFG_NETWORK] = 1;
				else if (strcmp(ptr + 8, "no") == 0)
					cfg_val[CFG_NETWORK] = 0;
				else
					goto errout;
			}
			// network
			else if (strncmp(ptr, "restricted-network ", 19) == 0) {
				if (strcmp(ptr + 19, "yes") == 0)
					cfg_val[CFG_RESTRICTED_NETWORK] = 1;
				else if (strcmp(ptr + 19, "no") == 0)
					cfg_val[CFG_RESTRICTED_NETWORK] = 0;
				else
					goto errout;
			}
			// netfilter
			else if (strncmp(ptr, "netfilter-default ", 18) == 0) {
				char *fname = ptr + 18;
				while (*fname == ' ' || *fname == '\t')
					ptr++;
				char *end = strchr(fname, ' ');
				if (end)
					*end = '\0';
				
				// is the file present?
				struct stat s;
				if (stat(fname, &s) == -1) {
					fprintf(stderr, "Error: netfilter-default file %s not available\n", fname);
					exit(1);
				}
				
				netfilter_default = strdup(fname);
				if (!netfilter_default)
					errExit("strdup");
				if (arg_debug)
					printf("netfilter default file %s\n", fname);
			}
			
			// Xephyr screen size
			else if (strncmp(ptr, "xephyr-screen ", 14) == 0) {
				// expecting two numbers and an x between them
				int n1;
				int n2;
				int rv = sscanf(ptr + 14, "%dx%d", &n1, &n2);
				if (rv != 2)
					goto errout;
				if (asprintf(&xephyr_screen, "%dx%d", n1, n2) == -1)
					errExit("asprintf");
			}
	
			// xephyr window title
			else if (strncmp(ptr, "xephyr-window-title ", 20) == 0) {
				if (strcmp(ptr + 20, "yes") == 0)
					cfg_val[CFG_XEPHYR_WINDOW_TITLE] = 1;
				else if (strcmp(ptr + 20, "no") == 0)
					cfg_val[CFG_XEPHYR_WINDOW_TITLE] = 0;
				else
					goto errout;
			}
				
			// Xephyr command extra parameters
			else if (strncmp(ptr, "xephyr-extra-params ", 19) == 0) {
				xephyr_extra_params = strdup(ptr + 19);
				if (!xephyr_extra_params)
					errExit("strdup");
			}

			else
				goto errout;

			free(ptr);
		}

		fclose(fp);
		free(fname);
		initialized = 1;
	}
	
	return cfg_val[val];
	
errout:
	fprintf(stderr, "Error: invalid line %d in firejail configuration file\n", line );
	exit(1);
}
Exemple #4
0
// skip1, skip2 - if the string is found in the line, the line is not interpreted
void profile_read(const char *fname, const char *skip1, const char *skip2) {
	// exit program if maximum include level was reached
	if (include_level > MAX_INCLUDE_LEVEL) {
		fprintf(stderr, "Error: maximum profile include level was reached\n");
		exit(1);	
	}

	if (strlen(fname) == 0) {
		fprintf(stderr, "Error: invalid profile file\n");
		exit(1);
	}

	// open profile file:
	FILE *fp = fopen(fname, "r");
	if (fp == NULL) {
		fprintf(stderr, "Error: cannot open profile file\n");
		exit(1);
	}

	if (!arg_quiet)
		fprintf(stderr, "Reading profile %s\n", fname);

	// read the file line by line
	char buf[MAX_READ + 1];
	int lineno = 0;
	while (fgets(buf, MAX_READ, fp)) {
		++lineno;
		// remove empty space - ptr in allocated memory
		char *ptr = line_remove_spaces(buf);
		if (ptr == NULL)
			continue;
		
		// comments
		if (*ptr == '#' || *ptr == '\0') {
			free(ptr);
			continue;
		}
		
		// process include
		if (strncmp(ptr, "include ", 8) == 0) {
			include_level++;
			
			// extract profile filename and new skip params
			char *newprofile = ptr + 8; // profile name
			char *newskip1 = NULL; // new skip1
			char *newskip2 = NULL; // new skip2
			char *p = newprofile;
			while (*p != '\0') {
				if (*p == ' ') {
					*p = '\0';
					if (newskip1 == NULL)
						newskip1 = p + 1;
					else if (newskip2 == NULL)
						newskip2 = p + 1;
				}
				p++;
			}
			
			// expand ${HOME}/ in front of the new profile file
			char *newprofile2 = expand_home(newprofile, cfg.homedir);
			
			// recursivity
			profile_read((newprofile2)? newprofile2:newprofile, newskip1, newskip2);
			include_level--;
			if (newprofile2)
				free(newprofile2);
			free(ptr);
			continue;
		}
		
		// skip
		if (skip1) {
			if (strstr(ptr, skip1)) {
				free(ptr);
				continue;
			}
		}
		if (skip2) {
			if (strstr(ptr, skip2)) {
				free(ptr);
				continue;
			}
		}
		
		// verify syntax, exit in case of error
		if (profile_check_line(ptr, lineno))
			profile_add(ptr);
	}
	fclose(fp);
}
Exemple #5
0
void profile_read(const char *fname) {
	// exit program if maximum include level was reached
	if (include_level > MAX_INCLUDE_LEVEL) {
		fprintf(stderr, "Error: maximum profile include level was reached\n");
		exit(1);	
	}

	if (strlen(fname) == 0) {
		fprintf(stderr, "Error: invalid profile file\n");
		exit(1);
	}

	// open profile file:
	FILE *fp = fopen(fname, "r");
	if (fp == NULL) {
		fprintf(stderr, "Error: cannot open profile file\n");
		exit(1);
	}

	printf("Reading %s\n", fname);

	// linked list of lines
	struct mylist {
		char *line;
		struct mylist *next;
	}
	m = {
		NULL, NULL
	};
	struct mylist *mptr = &m;
	int mylist_cnt = 1;

	// read the file line by line
	char buf[MAX_READ + 1];
	int lineno = 0;
	while (fgets(buf, MAX_READ, fp)) {
		++lineno;
		// remove empty space
		char *ptr = line_remove_spaces(buf);
		if (ptr == NULL || *ptr == '\0')
			continue;
		
		// comments
		if (*ptr == '#')
			continue;
		
		// process include
		if (strncmp(ptr, "include ", 8) == 0) {
			include_level++;
			// recursivity
			profile_read(ptr + 8);
			include_level--;
			continue;
		}
		
		// verify syntax, exit in case of error
		if (profile_check_line(ptr, lineno))
			profile_add(ptr);
	}
	fclose(fp);
}