オープンソース・ソフトウェアの開発とダウンロード

Subversion リポジトリの参照

Annotation of /trunk/1.5.x/ccs-tools/ccstools/ccstools.src/ccstools.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 585 - (hide annotations) (download) (as text)
Wed Oct 17 08:39:32 2007 UTC (16 years, 7 months ago) by kumaneko
File MIME type: text/x-csrc
File size: 18284 byte(s)
Don't try to open /proc/self/fd/0
1 kumaneko 213 /*
2     * ccstools.c
3     *
4     * TOMOYO Linux's utilities.
5     *
6     * Copyright (C) 2005-2007 NTT DATA CORPORATION
7     *
8 kumaneko 585 * Version: 1.5.1-pre 2007/10/17
9 kumaneko 213 *
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 kumaneko 344 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 kumaneko 213 unsigned int hash;
345 kumaneko 344 struct free_memory_block_list *fmb = &fmb_list;
346 kumaneko 213 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 kumaneko 344 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 kumaneko 213 memset(cp, 0, PAGE_SIZE);
377     fmb = fmb->next;
378     fmb->ptr = cp;
379     fmb->len = PAGE_SIZE;
380     }
381     }
382 kumaneko 344 if ((ptr = (struct savename_entry *) alloc_element(sizeof(struct savename_entry))) == NULL) OutOfMemory();
383     memset(ptr, 0, sizeof(struct savename_entry));
384 kumaneko 213 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 kumaneko 344 struct free_memory_block_list *ptr = &fmb_list;
392 kumaneko 213 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 kumaneko 348 const char *proc_policy_dir = "/proc/ccs/",
437     *disk_policy_dir = "/etc/ccs/",
438     *proc_policy_domain_policy = "/proc/ccs/domain_policy",
439 kumaneko 361 *disk_policy_domain_policy = "/etc/ccs/domain_policy.conf",
440 kumaneko 348 *proc_policy_exception_policy = "/proc/ccs/exception_policy",
441 kumaneko 361 *disk_policy_exception_policy = "/etc/ccs/exception_policy.conf",
442 kumaneko 348 *proc_policy_system_policy = "/proc/ccs/system_policy",
443 kumaneko 361 *disk_policy_system_policy = "/etc/ccs/system_policy.conf",
444 takedakn 392 *proc_policy_profile = "/proc/ccs/profile",
445 kumaneko 361 *disk_policy_profile = "/etc/ccs/profile.conf",
446 kumaneko 348 *proc_policy_manager = "/proc/ccs/manager",
447 kumaneko 361 *disk_policy_manager = "/etc/ccs/manager.conf",
448 kumaneko 348 *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 kumaneko 213 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 kumaneko 473 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 kumaneko 348 proc_policy_dir = "/proc/tomoyo/";
480     disk_policy_dir = "/etc/tomoyo/";
481 takedakn 356 proc_policy_domain_policy = "/proc/tomoyo/domain_policy";
482 kumaneko 361 disk_policy_domain_policy = "/etc/tomoyo/domain_policy.conf";
483 kumaneko 348 proc_policy_exception_policy = "/proc/tomoyo/exception_policy";
484 kumaneko 361 disk_policy_exception_policy = "/etc/tomoyo/exception_policy.conf";
485 kumaneko 348 proc_policy_system_policy = "/proc/tomoyo/system_policy";
486 kumaneko 361 disk_policy_system_policy = "/etc/tomoyo/system_policy.conf";
487 takedakn 392 proc_policy_profile = "/proc/tomoyo/profile";
488 kumaneko 361 disk_policy_profile = "/etc/tomoyo/profile.conf";
489 kumaneko 348 proc_policy_manager = "/proc/tomoyo/manager";
490 kumaneko 361 disk_policy_manager = "/etc/tomoyo/manager.conf";
491 kumaneko 348 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 kumaneko 213 if (strrchr(argv0, '/')) argv0 = strrchr(argv0, '/') + 1;
498 kumaneko 383 retry:
499 kumaneko 213 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 kumaneko 383 if (strncmp(argv0, "ccs-", 4) == 0) {
514     argv0 += 4;
515     goto retry;
516     }
517 kumaneko 213 /*
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 kumaneko 502 printf("ccstools version 1.5.0 build 2007/09/20\n");
523 kumaneko 213 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