Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 619988 | Differences between
and this patch

Collapse All | Expand All

(-)a/portage-utils-0.62/qtegrity.c (-4 / +130 lines)
Lines 9-35 Link Here
9
9
10
#ifdef APPLET_qtegrity
10
#ifdef APPLET_qtegrity
11
11
12
#define QTEGRITY_FLAGS "i" COMMON_FLAGS
12
#define QTEGRITY_FLAGS "ia:" COMMON_FLAGS
13
static struct option const qtegrity_long_opts[] = {
13
static struct option const qtegrity_long_opts[] = {
14
	{"no-ima-check",	no_argument, NULL, 'i'},
14
	{"no-ima-check",	no_argument, NULL, 'i'},
15
	{"add",			a_argument, NULL, 'a'},
15
	COMMON_LONG_OPTS
16
	COMMON_LONG_OPTS
16
};
17
};
17
static const char * const qtegrity_opts_help[] = {
18
static const char * const qtegrity_opts_help[] = {
18
	"Don't perform integrity check against IMA file", //@TODO, also add functionality to add a single file+digest to the vardb-QTEGRITY file
19
	"Don't perform integrity check against IMA file",
20
	"Add file to QTEGRITY",
19
	COMMON_OPTS_HELP
21
	COMMON_OPTS_HELP
20
};
22
};
21
#define qtegrity_usage(ret) usage(ret, QTEGRITY_FLAGS, qtegrity_long_opts, qtegrity_opts_help, lookup_applet_idx("qtegrity"))
23
#define qtegrity_usage(ret) usage(ret, QTEGRITY_FLAGS, qtegrity_long_opts, qtegrity_opts_help, lookup_applet_idx("qtegrity"))
22
24
23
struct qtegrity_opt_state {
25
struct qtegrity_opt_state {
24
	bool ima;
26
	bool ima;
27
	bool add;
28
	char* add_file;
25
};
29
};
26
30
31
#define FILE_SUCCESS 1
32
#define FILE_EMPTY 2
33
#define FILE_RELATIVE 3
34
27
#define SHA1_DIGEST_LENGTH 40
35
#define SHA1_DIGEST_LENGTH 40
28
#define SHA256_PREFIX_LENGTH 8
36
#define SHA256_PREFIX_LENGTH 8
29
#define SHA256_DIGEST_LENGTH 64
37
#define SHA256_DIGEST_LENGTH 64
30
#define SHA256_LENGTH (SHA256_PREFIX_LENGTH + SHA256_DIGEST_LENGTH)
38
#define SHA256_LENGTH (SHA256_PREFIX_LENGTH + SHA256_DIGEST_LENGTH)
31
#define SHA512_DIGEST_LENGTH 128
39
#define SHA512_DIGEST_LENGTH 128
32
40
41
void external_check_sha(char * ret_digest, char * filepath, char * algo) {
42
	FILE *fp;
43
	char digest[130];
44
	size_t size_digest = 1;
45
46
	if (strcmp(algo, "sha256") == 0) {
47
		size_digest = 66;
48
	} else if (strcmp(algo, "sha512") == 0) {
49
		size_digest = 130;
50
	}
51
52
	if ((strcmp(algo, "sha256") != 0) && (strcmp(algo, "sha512") != 0)) {
53
		return;
54
	}
55
56
	char text[29+strlen(filepath)+1];
57
	snprintf(text, 29+strlen(filepath)+1, "/usr/bin/%ssum \"%s\" 2>&1", algo, filepath);
58
59
	/* Open the command for reading. */
60
	fp = popen(text, "r");
61
	if (fp == NULL) {
62
		printf("Failed to run command '%s'\n", text);
63
		exit(1);
64
	}
65
66
	/* Read the output a line at a time - output it. */
67
	if (fgets(digest, size_digest, fp) == NULL)
68
		return;
69
70
	char *pfound;
71
	size_t dposfound;
72
	pfound = strchr(digest, ' '); //pointer to first char in string
73
	dposfound = pfound - digest + 1; //get relative position by subtracting pointers
74
	if (dposfound == 65) {
75
		memcpy(ret_digest, digest, dposfound - 1);
76
		ret_digest[dposfound - 1] = '\0';
77
	} else {
78
		printf("%zu\n", dposfound);
79
	}
80
81
	/* close */
82
	pclose(fp);
83
84
	return;
85
}
86
33
void get_file_from_ima(char * line, char **ret, int digest_size)
87
void get_file_from_ima(char * line, char **ret, int digest_size)
34
{
88
{
35
	//skip first 123 chars to get to file
89
	//skip first 123 chars to get to file
Lines 181-198 Link Here
181
	}
235
	}
182
}
236
}
183
237
238
int check_file(char * filename)
239
{
240
	if (strlen(filename) > 255)
241
		err("Filename too long");
242
	if (filename == NULL) {
243
		return FILE_EMPTY;
244
	} else if (filename[0] != '/') {
245
		return FILE_RELATIVE;
246
	}
247
248
	return FILE_SUCCESS;
249
}
250
184
int qtegrity_main(int argc, char **argv)
251
int qtegrity_main(int argc, char **argv)
185
{
252
{
186
	int i;
253
	int i;
187
254
188
	struct qtegrity_opt_state state = {
255
	struct qtegrity_opt_state state = {
189
		.ima = true,
256
		.ima = true,
257
		.add = false,
190
	};
258
	};
191
259
192
	while ((i = GETOPT_LONG(QTEGRITY, qtegrity, "")) != -1) {
260
	while ((i = GETOPT_LONG(QTEGRITY, qtegrity, "")) != -1) {
193
		switch (i) {
261
		switch (i) {
194
			COMMON_GETOPTS_CASES(qtegrity)
262
			COMMON_GETOPTS_CASES(qtegrity)
195
			case 'i': state.ima = false; break;
263
			case 'i': state.ima = false; break;
264
			case 'a':
265
				state.ima = false;
266
				state.add = true;
267
				if (check_file(optarg) == FILE_SUCCESS) {
268
					state.add_file = xstrdup(optarg);
269
				} else {
270
					err("Expected absolute file as argument, got '%s'", optarg);
271
				}
272
				break;
196
		}
273
		}
197
	}
274
	}
198
275
Lines 201-206 Link Here
201
		int fd_ima;
278
		int fd_ima;
202
		FILE *fp_ima;
279
		FILE *fp_ima;
203
		struct stat st;
280
		struct stat st;
281
		int file_state;
204
282
205
		fd_ima = open(fn_ima, O_RDONLY|O_CLOEXEC, 0);
283
		fd_ima = open(fn_ima, O_RDONLY|O_CLOEXEC, 0);
206
		if (fd_ima == -1) {
284
		if (fd_ima == -1) {
Lines 221-226 Link Here
221
		while (getline(&line, &linelen, fp_ima) != -1) {
299
		while (getline(&line, &linelen, fp_ima) != -1) {
222
			free(buffer);
300
			free(buffer);
223
			buffer = xstrdup(line);
301
			buffer = xstrdup(line);
302
			file_state = 0;
224
303
225
			if (buffer[0] != '1' || buffer[1] != '0')
304
			if (buffer[0] != '1' || buffer[1] != '0')
226
				continue;
305
				continue;
Lines 230-239 Link Here
230
			get_file_from_ima(buffer, &targetfname, digest_size);
309
			get_file_from_ima(buffer, &targetfname, digest_size);
231
			get_digest_from_ima(buffer, &targetdigest, digest_size);
310
			get_digest_from_ima(buffer, &targetdigest, digest_size);
232
311
233
			if (targetfname == NULL) {
312
			file_state = check_file(targetfname);
313
			if (file_state == FILE_EMPTY) {
234
				printf("Target empty: %s\n", line);
314
				printf("Target empty: %s\n", line);
235
				continue;
315
				continue;
236
			} else if (targetfname[0] != '/') {
316
			} else if (file_state == FILE_RELATIVE) {
237
				printf("Seems like a kernel process: %s\n", targetfname);
317
				printf("Seems like a kernel process: %s\n", targetfname);
238
				continue;
318
				continue;
239
			} else if (targetdigest == NULL) {
319
			} else if (targetdigest == NULL) {
Lines 266-273 Link Here
266
346
267
		close(fd_ima);
347
		close(fd_ima);
268
		fclose(fp_ima);
348
		fclose(fp_ima);
349
	} else if (state.add) {
350
		//Add a single executable file+digest to the vardb-QTEGRITY file
351
		char *fn_qtegrity_custom = "/var/db/QTEGRITY_custom";
352
		int fd_qtegrity_custom;
353
		FILE *fp_qtegrity_custom;
354
		struct stat st;
355
		int flush_status;
356
357
		fd_qtegrity_custom = open(fn_qtegrity_custom, O_RDWR|O_CREAT|O_APPEND|O_CLOEXEC, 0);
358
		if (fd_qtegrity_custom == -1) {
359
			warnp("Unable to open(%s)", fn_qtegrity_custom);
360
			exit(0);
361
		}
362
		if ((fp_qtegrity_custom = fdopen(fd_qtegrity_custom, "a+")) == NULL) {
363
			warnp("Unable to fopen(%s, r)", fn_qtegrity_custom);
364
			close(fd_qtegrity_custom);
365
			exit(0);
366
		}
367
368
		printf("Adding %s to %s\n", state.add_file, fn_qtegrity_custom);
369
370
		if (stat(state.add_file, &st) < 0)
371
			err("Couldn't access file '%s'\n", state.add_file);
372
373
		if (!(st.st_mode & S_IXUSR || st.st_mode & S_IXGRP || st.st_mode & S_IXOTH))
374
			err("File '%s' is not executable\n", state.add_file);
375
376
		//add digest
377
		char *hash_algo = "sha256";
378
		char *file_digest;
379
		file_digest = xmalloc(SHA256_DIGEST_LENGTH+1);
380
		external_check_sha(file_digest, state.add_file, hash_algo);
381
382
		fputs(hash_algo, fp_qtegrity_custom);
383
		fputs(":", fp_qtegrity_custom);
384
		fputs(file_digest, fp_qtegrity_custom);
385
		fputs(" file:", fp_qtegrity_custom);
386
		fputs(state.add_file, fp_qtegrity_custom);
387
		fputs("\n", fp_qtegrity_custom);
388
389
		flush_status = fflush(fp_qtegrity_custom);
390
		if (flush_status != 0)
391
		        puts("Error flushing stream!");
269
	}
392
	}
270
393
394
	if (state.add)
395
		free(state.add_file);
396
271
	return EXIT_SUCCESS;
397
	return EXIT_SUCCESS;
272
}
398
}

Return to bug 619988