Open-Source-Software-Entwicklung und Downloads

Browse Subversion Repository

Contents of /trunk/1.6.x/ccs-tools/ccstools/ccstools.src/ccstools.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1278 - (show annotations) (download) (as text)
Tue Jun 10 00:59:43 2008 UTC (15 years, 11 months ago) by kumaneko
File MIME type: text/x-csrc
File size: 18012 byte(s)


1 /*
2 * ccstools.c
3 *
4 * TOMOYO Linux's utilities.
5 *
6 * Copyright (C) 2005-2008 NTT DATA CORPORATION
7 *
8 * Version: 1.6.2-pre 2008/06/10
9 *
10 */
11 #include "ccstools.h"
12
13 /***** UTILITY FUNCTIONS START *****/
14
15 void OutOfMemory(void) {
16 fprintf(stderr, "Out of memory. Aborted.\n");
17 exit(1);
18 }
19
20 void NormalizeLine(unsigned char *line) {
21 unsigned char *sp = line, *dp = line;
22 int first = 1;
23 while (*sp && (*sp <= 32 || 127 <= *sp)) sp++;
24 while (*sp) {
25 if (!first) *dp++ = ' ';
26 first = 0;
27 while (32 < *sp && *sp < 127) *dp++ = *sp++;
28 while (*sp && (*sp <= 32 || 127 <= *sp)) sp++;
29 }
30 *dp = '\0';
31 }
32
33 /* Copied from kernel source. */
34 static inline unsigned long partial_name_hash(unsigned long c, unsigned long prevhash) {
35 return (prevhash + (c << 4) + (c >> 4)) * 11;
36 }
37
38 /* Copied from kernel source. */
39 static inline unsigned int full_name_hash(const unsigned char *name, unsigned int len) {
40 unsigned long hash = 0;
41 while (len--) hash = partial_name_hash(*name++, hash);
42 return (unsigned int) hash;
43 }
44
45 static char *alloc_element(const unsigned int size) {
46 static char *buf = NULL;
47 static unsigned int buf_used_len = PAGE_SIZE;
48 char *ptr = NULL;
49 if (size > PAGE_SIZE) return NULL;
50 if (buf_used_len + size > PAGE_SIZE) {
51 if ((ptr = malloc(PAGE_SIZE)) == NULL) OutOfMemory();
52 buf = ptr;
53 memset(buf, 0, PAGE_SIZE);
54 buf_used_len = size;
55 ptr = buf;
56 } else if (size) {
57 int i;
58 ptr = buf + buf_used_len;
59 buf_used_len += size;
60 for (i = 0; i < size; i++) if (ptr[i]) OutOfMemory();
61 }
62 return ptr;
63 }
64
65 static int PathDepth(const char *pathname) {
66 int i = 0;
67 if (pathname) {
68 char *ep = strchr(pathname, '\0');
69 if (pathname < ep--) {
70 if (*ep != '/') i++;
71 while (pathname <= ep) if (*ep-- == '/') i += 2;
72 }
73 }
74 return i;
75 }
76
77 static int const_part_length(const char *filename) {
78 int len = 0;
79 if (filename) {
80 char c;
81 while ((c = *filename++) != '\0') {
82 if (c != '\\') { len++; continue; }
83 switch (c = *filename++) {
84 case '\\': /* "\\" */
85 len += 2; continue;
86 case '0': /* "\ooo" */
87 case '1':
88 case '2':
89 case '3':
90 if ((c = *filename++) >= '0' && c <= '7' && (c = *filename++) >= '0' && c <= '7') { len += 4; continue; }
91 }
92 break;
93 }
94 }
95 return len;
96 }
97
98 int IsDomainDef(const unsigned char *domainname) {
99 return strncmp(domainname, ROOT_NAME, ROOT_NAME_LEN) == 0 && (domainname[ROOT_NAME_LEN] == '\0' || domainname[ROOT_NAME_LEN] == ' ');
100 }
101
102 int IsCorrectDomain(const unsigned char *domainname) {
103 unsigned char c, d, e;
104 if (!domainname || strncmp(domainname, ROOT_NAME, ROOT_NAME_LEN)) goto out;
105 domainname += ROOT_NAME_LEN;
106 if (!*domainname) return 1;
107 do {
108 if (*domainname++ != ' ') goto out;
109 if (*domainname++ != '/') goto out;
110 while ((c = *domainname) != '\0' && c != ' ') {
111 domainname++;
112 if (c == '\\') {
113 switch ((c = *domainname++)) {
114 case '\\': /* "\\" */
115 continue;
116 case '0': /* "\ooo" */
117 case '1':
118 case '2':
119 case '3':
120 if ((d = *domainname++) >= '0' && d <= '7' && (e = *domainname++) >= '0' && e <= '7') {
121 const unsigned char f =
122 (((unsigned char) (c - '0')) << 6) +
123 (((unsigned char) (d - '0')) << 3) +
124 (((unsigned char) (e - '0')));
125 if (f && (f <= ' ' || f >= 127)) continue; /* pattern is not \000 */
126 }
127 }
128 goto out;
129 } else if (c < ' ' || c >= 127) {
130 goto out;
131 }
132 }
133 } while (*domainname);
134 return 1;
135 out:
136 return 0;
137 }
138
139 void fprintf_encoded(FILE *fp, const char *pathname) {
140 unsigned char c;
141 while ((c = * (const unsigned char *) pathname++) != 0) {
142 if (c == '\\') {
143 fputc('\\', fp);
144 fputc('\\', fp);
145 } else if (c > 32 && c < 127) {
146 fputc(c, fp);
147 } else {
148 fprintf(fp, "\\%c%c%c", (c >> 6) + '0', ((c >> 3) & 7) + '0', (c & 7) + '0');
149 }
150 }
151 }
152
153 void RemoveHeader(char *line, const int len) {
154 memmove(line, line + len, strlen(line + len) + 1);
155 }
156
157 int IsCorrectPath(const char *filename, const int start_type, const int pattern_type, const int end_type) {
158 int contains_pattern = 0;
159 char c, d, e;
160 if (!filename) goto out;
161 c = *filename;
162 if (start_type == 1) { /* Must start with '/' */
163 if (c != '/') goto out;
164 } else if (start_type == -1) { /* Must not start with '/' */
165 if (c == '/') goto out;
166 }
167 if (c) c = * (strchr(filename, '\0') - 1);
168 if (end_type == 1) { /* Must end with '/' */
169 if (c != '/') goto out;
170 } else if (end_type == -1) { /* Must not end with '/' */
171 if (c == '/') goto out;
172 }
173 while ((c = *filename++) != '\0') {
174 if (c == '\\') {
175 switch ((c = *filename++)) {
176 case '\\': /* "\\" */
177 continue;
178 case '$': /* "\$" */
179 case '+': /* "\+" */
180 case '?': /* "\?" */
181 case '*': /* "\*" */
182 case '@': /* "\@" */
183 case 'x': /* "\x" */
184 case 'X': /* "\X" */
185 case 'a': /* "\a" */
186 case 'A': /* "\A" */
187 case '-': /* "\-" */
188 if (pattern_type == -1) break; /* Must not contain pattern */
189 contains_pattern = 1;
190 continue;
191 case '0': /* "\ooo" */
192 case '1':
193 case '2':
194 case '3':
195 if ((d = *filename++) >= '0' && d <= '7' && (e = *filename++) >= '0' && e <= '7') {
196 const unsigned char f =
197 (((unsigned char) (c - '0')) << 6) +
198 (((unsigned char) (d - '0')) << 3) +
199 (((unsigned char) (e - '0')));
200 if (f && (f <= ' ' || f >= 127)) continue; /* pattern is not \000 */
201 }
202 }
203 goto out;
204 } else if (c <= ' ' || c >= 127) {
205 goto out;
206 }
207 }
208 if (pattern_type == 1) { /* Must contain pattern */
209 if (!contains_pattern) goto out;
210 }
211 return 1;
212 out:
213 return 0;
214 }
215
216 static int FileMatchesToPattern2(const char *filename, const char *filename_end, const char *pattern, const char *pattern_end) {
217 while (filename < filename_end && pattern < pattern_end) {
218 if (*pattern != '\\') {
219 if (*filename++ != *pattern++) return 0;
220 } else {
221 char c = *filename;
222 pattern++;
223 switch (*pattern) {
224 case '?':
225 if (c == '/') {
226 return 0;
227 } else if (c == '\\') {
228 if ((c = filename[1]) == '\\') {
229 filename++; /* safe because filename is \\ */
230 } else if (c >= '0' && c <= '3' && (c = filename[2]) >= '0' && c <= '7' && (c = filename[3]) >= '0' && c <= '7') {
231 filename += 3; /* safe because filename is \ooo */
232 } else {
233 return 0;
234 }
235 }
236 break;
237 case '\\':
238 if (c != '\\') return 0;
239 if (*++filename != '\\') return 0; /* safe because *filename != '\0' */
240 break;
241 case '+':
242 if (c < '0' || c > '9') return 0;
243 break;
244 case 'x':
245 if (!((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'))) return 0;
246 break;
247 case 'a':
248 if (!((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))) return 0;
249 break;
250 case '0':
251 case '1':
252 case '2':
253 case '3':
254 if (c == '\\' && (c = filename[1]) >= '0' && c <= '3' && c == *pattern
255 && (c = filename[2]) >= '0' && c <= '7' && c == pattern[1]
256 && (c = filename[3]) >= '0' && c <= '7' && c == pattern[2]) {
257 filename += 3; /* safe because filename is \ooo */
258 pattern += 2; /* safe because pattern is \ooo */
259 break;
260 }
261 return 0; /* Not matched. */
262 case '*':
263 case '@':
264 {
265 int i;
266 for (i = 0; i <= filename_end - filename; i++) {
267 if (FileMatchesToPattern2(filename + i, filename_end, pattern + 1, pattern_end)) return 1;
268 if ((c = filename[i]) == '.' && *pattern == '@') break;
269 if (c == '\\') {
270 if ((c = filename[i + 1]) == '\\') {
271 i++; /* safe because filename is \\ */
272 } else if (c >= '0' && c <= '3' && (c = filename[i + 2]) >= '0' && c <= '7' && (c = filename[i + 3]) >= '0' && c <= '7') {
273 i += 3; /* safe because filename is \ooo */
274 } else {
275 break; /* Bad pattern. */
276 }
277 }
278 }
279 return 0; /* Not matched. */
280 }
281 default:
282 {
283 int i, j = 0;
284 if ((c = *pattern) == '$') {
285 while ((c = filename[j]) >= '0' && c <= '9') j++;
286 } else if (c == 'X') {
287 while (((c = filename[j]) >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f')) j++;
288 } else if (c == 'A') {
289 while (((c = filename[j]) >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) j++;
290 }
291 for (i = 1; i <= j; i++) {
292 if (FileMatchesToPattern2(filename + i, filename_end, pattern + 1, pattern_end)) return 1;
293 }
294 }
295 return 0; /* Not matched or bad pattern. */
296 }
297 filename++; /* safe because *filename != '\0' */
298 pattern++; /* safe because *pattern != '\0' */
299 }
300 }
301 while (*pattern == '\\' && (*(pattern + 1) == '*' || *(pattern + 1) == '@')) pattern += 2;
302 return (filename == filename_end && pattern == pattern_end);
303 }
304
305 int FileMatchesToPattern(const char *filename, const char *filename_end, const char *pattern, const char *pattern_end) {
306 const char *pattern_start = pattern;
307 int first = 1;
308 int result;
309 while (pattern < pattern_end - 1) {
310 if (*pattern++ != '\\' || *pattern++ != '-') continue;
311 result = FileMatchesToPattern2(filename, filename_end, pattern_start, pattern - 2);
312 if (first) result = !result;
313 if (result) return 0;
314 first = 0;
315 pattern_start = pattern;
316 }
317 result = FileMatchesToPattern2(filename, filename_end, pattern_start, pattern_end);
318 return first ? result : !result;
319 }
320
321 int string_compare(const void *a, const void *b) {
322 return strcmp(* (char **) a, * (char **) b);
323 }
324
325 int pathcmp(const struct path_info *a, const struct path_info *b) {
326 return a->hash != b->hash || strcmp(a->name, b->name);
327 }
328
329 void fill_path_info(struct path_info *ptr) {
330 const char *name = ptr->name;
331 const int len = strlen(name);
332 ptr->total_len = len;
333 ptr->const_len = const_part_length(name);
334 ptr->is_dir = len && (name[len - 1] == '/');
335 ptr->is_patterned = (ptr->const_len < len);
336 ptr->hash = full_name_hash(name, len);
337 ptr->depth = PathDepth(name);
338 }
339
340 const struct path_info *SaveName(const char *name) {
341 static struct free_memory_block_list fmb_list = { NULL, NULL, 0 };
342 static struct savename_entry name_list[SAVENAME_MAX_HASH]; /* The list of names. */
343 struct savename_entry *ptr, *prev = NULL;
344 unsigned int hash;
345 struct free_memory_block_list *fmb = &fmb_list;
346 int len;
347 static int first_call = 1;
348 if (!name) return NULL;
349 len = strlen(name) + 1;
350 if (len > CCS_MAX_PATHNAME_LEN) {
351 fprintf(stderr, "ERROR: Name too long for SaveName().\n");
352 return NULL;
353 }
354 hash = full_name_hash((const unsigned char *) name, len - 1);
355 if (first_call) {
356 int i;
357 first_call = 0;
358 memset(&name_list, 0, sizeof(name_list));
359 for (i = 0; i < SAVENAME_MAX_HASH; i++) {
360 name_list[i].entry.name = "/";
361 fill_path_info(&name_list[i].entry);
362 }
363 if (CCS_MAX_PATHNAME_LEN > PAGE_SIZE) abort();
364 }
365 ptr = &name_list[hash % SAVENAME_MAX_HASH];
366 while (ptr) {
367 if (hash == ptr->entry.hash && strcmp(name, ptr->entry.name) == 0) goto out;
368 prev = ptr; ptr = ptr->next;
369 }
370 while (len > fmb->len) {
371 if (fmb->next) {
372 fmb = fmb->next;
373 } else {
374 char *cp;
375 if ((cp = (char *) malloc(PAGE_SIZE)) == NULL || (fmb->next = (struct free_memory_block_list *) alloc_element(sizeof(struct free_memory_block_list))) == NULL) OutOfMemory();
376 memset(cp, 0, PAGE_SIZE);
377 fmb = fmb->next;
378 fmb->ptr = cp;
379 fmb->len = PAGE_SIZE;
380 }
381 }
382 if ((ptr = (struct savename_entry *) alloc_element(sizeof(struct savename_entry))) == NULL) OutOfMemory();
383 memset(ptr, 0, sizeof(struct savename_entry));
384 ptr->entry.name = fmb->ptr;
385 memmove(fmb->ptr, name, len);
386 fill_path_info(&ptr->entry);
387 fmb->ptr += len;
388 fmb->len -= len;
389 prev->next = ptr; /* prev != NULL because name_list is not empty. */
390 if (fmb->len == 0) {
391 struct free_memory_block_list *ptr = &fmb_list;
392 while (ptr->next != fmb) ptr = ptr->next; ptr->next = fmb->next;
393 }
394 out:
395 return ptr ? &ptr->entry : NULL;
396 }
397
398 char *shared_buffer = NULL;
399 static int buffer_lock = 0;
400 void get(void) {
401 if (buffer_lock) OutOfMemory();
402 if (!shared_buffer && (shared_buffer = malloc(shared_buffer_len)) == NULL) OutOfMemory();
403 buffer_lock++;
404 }
405 void put(void) {
406 if (buffer_lock != 1) OutOfMemory();
407 buffer_lock--;
408 }
409 int freadline(FILE *fp) {
410 char *cp;
411 memset(shared_buffer, 0, shared_buffer_len);
412 if (fgets(shared_buffer, shared_buffer_len - 1, fp) == NULL ||
413 (cp = strchr(shared_buffer, '\n')) == NULL) return 0;
414 *cp = '\0';
415 NormalizeLine(shared_buffer);
416 return 1;
417 }
418
419 /***** UTILITY FUNCTIONS END *****/
420
421 extern int sortpolicy_main(int argc, char *argv[]);
422 extern int setprofile_main(int argc, char *argv[]);
423 extern int setlevel_main(int argc, char *argv[]);
424 extern int savepolicy_main(int argc, char *argv[]);
425 extern int pathmatch_main(int argc, char *argv[]);
426 extern int loadpolicy_main(int argc, char *argv[]);
427 extern int ldwatch_main(int argc, char *argv[]);
428 extern int findtemp_main(int argc, char *argv[]);
429 extern int editpolicy_main(int argc, char *argv[]);
430 extern int checkpolicy_main(int argc, char *argv[]);
431 extern int ccstree_main(int argc, char *argv[]);
432 extern int ccsqueryd_main(int argc, char *argv[]);
433 extern int ccsauditd_main(int argc, char *argv[]);
434 extern int patternize_main(int argc, char *argv[]);
435
436 const char *proc_policy_dir = "/proc/ccs/",
437 *disk_policy_dir = "/etc/ccs/",
438 *proc_policy_domain_policy = "/proc/ccs/domain_policy",
439 *disk_policy_domain_policy = "/etc/ccs/domain_policy.conf",
440 *proc_policy_exception_policy = "/proc/ccs/exception_policy",
441 *disk_policy_exception_policy = "/etc/ccs/exception_policy.conf",
442 *proc_policy_system_policy = "/proc/ccs/system_policy",
443 *disk_policy_system_policy = "/etc/ccs/system_policy.conf",
444 *proc_policy_profile = "/proc/ccs/profile",
445 *disk_policy_profile = "/etc/ccs/profile.conf",
446 *proc_policy_manager = "/proc/ccs/manager",
447 *disk_policy_manager = "/etc/ccs/manager.conf",
448 *proc_policy_query = "/proc/ccs/query",
449 *proc_policy_grant_log = "/proc/ccs/grant_log",
450 *proc_policy_reject_log = "/proc/ccs/reject_log",
451 *proc_policy_domain_status = "/proc/ccs/.domain_status",
452 *proc_policy_process_status = "/proc/ccs/.process_status";
453
454 int main(int argc, char *argv[]) {
455 const char *argv0 = argv[0];
456 if (!argv0) {
457 fprintf(stderr, "Function not specified.\n");
458 return 1;
459 }
460 if (access("/sys/kernel/security/tomoyo/", F_OK) == 0) {
461 proc_policy_dir = "/sys/kernel/security/tomoyo/";
462 disk_policy_dir = "/etc/tomoyo/";
463 proc_policy_domain_policy = "/sys/kernel/security/tomoyo/domain_policy";
464 disk_policy_domain_policy = "/etc/tomoyo/domain_policy.conf";
465 proc_policy_exception_policy = "/sys/kernel/security/tomoyo/exception_policy";
466 disk_policy_exception_policy = "/etc/tomoyo/exception_policy.conf";
467 proc_policy_system_policy = "/sys/kernel/security/tomoyo/system_policy";
468 disk_policy_system_policy = "/etc/tomoyo/system_policy.conf";
469 proc_policy_profile = "/sys/kernel/security/tomoyo/profile";
470 disk_policy_profile = "/etc/tomoyo/profile.conf";
471 proc_policy_manager = "/sys/kernel/security/tomoyo/manager";
472 disk_policy_manager = "/etc/tomoyo/manager.conf";
473 proc_policy_query = "/sys/kernel/security/tomoyo/query";
474 proc_policy_grant_log = "/sys/kernel/security/tomoyo/grant_log";
475 proc_policy_reject_log = "/sys/kernel/security/tomoyo/reject_log";
476 proc_policy_domain_status = "/sys/kernel/security/tomoyo/.domain_status";
477 proc_policy_process_status = "/sys/kernel/security/tomoyo/.process_status";
478 } else if (access("/proc/tomoyo/", F_OK) == 0) {
479 proc_policy_dir = "/proc/tomoyo/";
480 disk_policy_dir = "/etc/tomoyo/";
481 proc_policy_domain_policy = "/proc/tomoyo/domain_policy";
482 disk_policy_domain_policy = "/etc/tomoyo/domain_policy.conf";
483 proc_policy_exception_policy = "/proc/tomoyo/exception_policy";
484 disk_policy_exception_policy = "/etc/tomoyo/exception_policy.conf";
485 proc_policy_system_policy = "/proc/tomoyo/system_policy";
486 disk_policy_system_policy = "/etc/tomoyo/system_policy.conf";
487 proc_policy_profile = "/proc/tomoyo/profile";
488 disk_policy_profile = "/etc/tomoyo/profile.conf";
489 proc_policy_manager = "/proc/tomoyo/manager";
490 disk_policy_manager = "/etc/tomoyo/manager.conf";
491 proc_policy_query = "/proc/tomoyo/query";
492 proc_policy_grant_log = "/proc/tomoyo/grant_log";
493 proc_policy_reject_log = "/proc/tomoyo/reject_log";
494 proc_policy_domain_status = "/proc/tomoyo/.domain_status";
495 proc_policy_process_status = "/proc/tomoyo/.process_status";
496 }
497 if (strrchr(argv0, '/')) argv0 = strrchr(argv0, '/') + 1;
498 retry:
499 if (strcmp(argv0, "sortpolicy") == 0) return sortpolicy_main(argc, argv);
500 if (strcmp(argv0, "setprofile") == 0) return setprofile_main(argc, argv);
501 if (strcmp(argv0, "setlevel") == 0) return setlevel_main(argc, argv);
502 if (strcmp(argv0, "savepolicy") == 0) return savepolicy_main(argc, argv);
503 if (strcmp(argv0, "pathmatch") == 0) return pathmatch_main(argc, argv);
504 if (strcmp(argv0, "loadpolicy") == 0) return loadpolicy_main(argc, argv);
505 if (strcmp(argv0, "ld-watch") == 0) return ldwatch_main(argc, argv);
506 if (strcmp(argv0, "findtemp") == 0) return findtemp_main(argc, argv);
507 if (strcmp(argv0, "editpolicy") == 0 || strcmp(argv0, "editpolicy_offline") == 0) return editpolicy_main(argc, argv);
508 if (strcmp(argv0, "checkpolicy") == 0) return checkpolicy_main(argc, argv);
509 if (strcmp(argv0, "ccstree") == 0) return ccstree_main(argc, argv);
510 if (strcmp(argv0, "ccs-queryd") == 0) return ccsqueryd_main(argc, argv);
511 if (strcmp(argv0, "ccs-auditd") == 0) return ccsauditd_main(argc, argv);
512 if (strcmp(argv0, "patternize") == 0) return patternize_main(argc, argv);
513 if (strncmp(argv0, "ccs-", 4) == 0) {
514 argv0 += 4;
515 goto retry;
516 }
517 /*
518 * Unlike busybox, I don't use argv[1] if argv[0] is the name of this program
519 * because it is dangerous to allow updating policies via unchecked argv[1].
520 * You should use either "symbolic links with 'alias' directive" or "hard links".
521 */
522 printf("ccstools version 1.6.2-pre build 2008/06/10\n");
523 fprintf(stderr, "Function %s not implemented.\n", argv0);
524 return 1;
525 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26