/ SecurityTool / sharedTool / log_control.c
log_control.c
  1  /*
  2   * Copyright (c) 2003-2007,2009-2010,2013-2014 Apple Inc. All Rights Reserved.
  3   *
  4   * @APPLE_LICENSE_HEADER_START@
  5   *
  6   * This file contains Original Code and/or Modifications of Original Code
  7   * as defined in and that are subject to the Apple Public Source License
  8   * Version 2.0 (the 'License'). You may not use this file except in
  9   * compliance with the License. Please obtain a copy of the License at
 10   * http://www.opensource.apple.com/apsl/ and read it before using this
 11   * file.
 12   *
 13   * The Original Code and all software distributed under the License are
 14   * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 15   * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 16   * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 17   * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 18   * Please see the License for the specific language governing rights and
 19   * limitations under the License.
 20   *
 21   * @APPLE_LICENSE_HEADER_END@
 22   *
 23   * log_control.c
 24   */
 25  
 26  #include <string.h>
 27  #include <getopt.h>
 28  #include <stdlib.h>
 29  
 30  #include <Security/SecItem.h>
 31  #include <CoreFoundation/CoreFoundation.h>
 32  
 33  #include "SecurityTool/sharedTool/tool_errors.h"
 34  
 35  #include <Security/SecLogging.h>
 36  
 37  #include <utilities/debugging.h>
 38  
 39  #include <utilities/SecCFWrappers.h>
 40  
 41  #include "SecurityCommands.h"
 42  
 43  
 44  static void
 45  set_log_settings(const char * settings)
 46  {
 47      CFErrorRef error = NULL;
 48  
 49      CFStringRef scope = CFStringCreateWithCString(kCFAllocatorDefault, settings, kCFStringEncodingUTF8);
 50  
 51      if (!SecSetLoggingInfoForXPCScope((CFPropertyListRef) scope, &error)) {
 52          fprintf(stderr, "Failed: ");
 53          CFShow(error);
 54      }
 55  
 56      CFReleaseSafe(scope);
 57      CFReleaseSafe(error);
 58  }
 59  
 60  static void
 61  set_circle_settings(const char * settings)
 62  {
 63      CFErrorRef error = NULL;
 64      
 65      CFStringRef scope = CFStringCreateWithCString(kCFAllocatorDefault, settings, kCFStringEncodingUTF8);
 66      
 67      if (!SecSetLoggingInfoForCircleScope((CFPropertyListRef) scope, &error)) {
 68          fprintf(stderr, "Failed: ");
 69          CFShow(error);
 70      }
 71      
 72      CFReleaseSafe(scope);
 73      CFReleaseSafe(error);
 74  }
 75  
 76  static const char * getScopeIDName(int id)
 77  {
 78      switch (id) {
 79          case kScopeIDXPC:           return "XPC";
 80          case kScopeIDDefaults:      return "Defaults";
 81          case kScopeIDEnvironment:   return "Environment Variables";
 82          case kScopeIDConfig:        return "Config";
 83          case kScopeIDCircle:        return "Circle";
 84          default:                    return "Unknown";
 85      }
 86  };
 87  
 88  static const char * getPriorityName(CFNumberRef id_number)
 89  {
 90      int priority = -1;
 91  
 92      CFNumberGetValue(id_number, kCFNumberIntType, &priority);
 93  
 94      switch (priority) {
 95          case ASL_LEVEL_EMERG:   return ASL_STRING_EMERG;
 96          case ASL_LEVEL_ALERT:   return ASL_STRING_ALERT;
 97          case ASL_LEVEL_CRIT:    return ASL_STRING_CRIT;
 98          case ASL_LEVEL_ERR:     return ASL_STRING_ERR;
 99          case ASL_LEVEL_WARNING: return ASL_STRING_WARNING;
100          case ASL_LEVEL_NOTICE:  return ASL_STRING_NOTICE;
101          case ASL_LEVEL_INFO:    return ASL_STRING_INFO;
102          case ASL_LEVEL_DEBUG:   return ASL_STRING_DEBUG;
103          default: return "Unknown";
104  
105      }
106  };
107  
108  static void print_comma_separated(FILE* file, CFArrayRef array)
109  {
110      fprintf(file, "[");
111      __block const char *separator = "";
112      CFArrayForEach(array, ^(const void *value) {
113          cffprint(file, CFSTR("%s%@"), separator, value);
114          separator = ", ";
115      });
116      fprintf(file, "]");
117  
118  }
119  
120  static void
121  list_log_settings()
122  {
123      CFErrorRef error = NULL;
124  
125      CFArrayRef result = SecGetCurrentServerLoggingInfo(&error);
126      if (result) {
127          __block int index = 0;
128          CFArrayForEach(result, ^(const void *value) {
129              printf("%s: ", getScopeIDName(index));
130  
131              if (isArray(value)) {
132                  print_comma_separated(stdout, (CFArrayRef) value);
133                  printf("\n");
134              } else if (isDictionary(value)) {
135                  printf("\n");
136                  CFDictionaryForEach((CFDictionaryRef) value, ^(const void *level, const void *array) {
137                      printf("   %s: ", getPriorityName(level));
138                      if (isArray(array)) {
139                          print_comma_separated(stdout, (CFArrayRef) array);
140                      } else {
141                          cffprint(stdout, CFSTR("%@"), array);
142                      }
143                      printf("\n");
144                  });
145              } else {
146                  cffprint(stdout, CFSTR("%@\n"), value);
147              }
148  
149              ++index;
150          });
151      } else {
152          fprintf(stderr, "Failed: ");
153          CFShow(error);
154      }
155  
156      CFReleaseSafe(error);
157  }
158  
159  int log_control(int argc, char * const *argv)
160  {
161      int ch, result = 2; /* @@@ Return 2 triggers usage message. */
162  
163      bool list = false;
164      /*
165       "-l - list"
166       */
167      while ((ch = getopt(argc, argv, "ls:c:")) != -1)
168      {
169          switch  (ch)
170          {
171              case 'l':
172                  list = true;
173                  break;
174              case 's':
175                  set_log_settings(optarg);
176                  break;
177              case 'c':
178                  set_circle_settings(optarg);
179                  break;
180              case '?':
181              default:
182                  goto fail;
183          }
184      }
185  
186      argc -= optind;
187      argv += optind;
188  
189      if (argc > 1)
190          goto fail;
191  
192      if (argc == 1) {
193          set_log_settings(argv[0]);
194  
195          argc -= 1;
196          argv += 1;
197      }
198  
199      (void) argv;
200  
201      if (argc != 0)
202          goto fail;
203  
204      if (list)
205          list_log_settings();
206  
207      result = 0;
208  
209  fail:
210      return result;
211  }