/ SecurityTool / macOS / translocate.c
translocate.c
  1  /*
  2   * Copyright (c) 2016 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  
 24  #include <stdio.h>
 25  #include <dirent.h>
 26  
 27  #include <CoreFoundation/CoreFoundation.h>
 28  
 29  #include <Security/SecTranslocate.h>
 30  
 31  #include "security_tool.h"
 32  #include "translocate.h"
 33  
 34  static CFURLRef CFURLfromPath(const char * path, Boolean isDir)
 35  {
 36      return CFURLCreateFromFileSystemRepresentation(NULL, (UInt8*)path, strlen(path), isDir);
 37  }
 38  
 39  static char * PathFromCFURL(CFURLRef url)
 40  {
 41      char* path = malloc(PATH_MAX);
 42  
 43      if (!path)
 44      {
 45          goto done;
 46      }
 47  
 48      if (!CFURLGetFileSystemRepresentation(url, true, (UInt8*)path, PATH_MAX))
 49      {
 50          free(path);
 51          path = NULL;
 52      }
 53  
 54  done:
 55      return path;
 56  }
 57  
 58  static Boolean PathIsDir(const char * path)
 59  {
 60      Boolean result = false;
 61  
 62      if(!path)
 63      {
 64          goto done;
 65      }
 66  
 67      DIR* d = opendir(path);
 68  
 69      if(d)
 70      {
 71          result = true;
 72          closedir(d);
 73      }
 74  
 75  done:
 76      return result;
 77  }
 78  
 79  static void SafeCFRelease(CFTypeRef ref)
 80  {
 81      if (ref)
 82      {
 83          CFRelease(ref);
 84      }
 85  }
 86  
 87  /* return 2 = bad args, anything else is ignored */
 88  
 89  int translocate_create(int argc, char * const *argv)
 90  {
 91      int result = -1;
 92  
 93      if (argc != 2)
 94      {
 95          return SHOW_USAGE_MESSAGE;
 96      }
 97  
 98      CFURLRef inUrl = CFURLfromPath(argv[1], PathIsDir(argv[1]));
 99      CFURLRef outUrl = NULL;
100      CFErrorRef error = NULL;
101      char* outPath = NULL;
102  
103      if(!inUrl)
104      {
105          printf("Error: failed to create url for: %s\n", argv[1]);
106          goto done;
107      }
108  
109      outUrl = SecTranslocateCreateSecureDirectoryForURL(inUrl, NULL, &error);
110  
111      if (!outUrl)
112      {
113          int err = (int)CFErrorGetCode(error);
114          printf("Error: failed while trying to translocate %s (errno: %d, %s)\n", argv[1], err, strerror(err));
115          goto done;
116      }
117  
118      outPath = PathFromCFURL(outUrl);
119  
120      if( !outPath )
121      {
122          printf("Error: failed to convert out url to string for %s\n", argv[1]);
123          goto done;
124      }
125  
126      printf("Translocation point: (note if this is what you passed in then that path should not be translocated)\n\t%s\n",outPath);
127  
128      free(outPath);
129      result = 0;
130  
131  done:
132      SafeCFRelease(inUrl);
133      SafeCFRelease(outUrl);
134      SafeCFRelease(error);
135  
136      return result;
137  }
138  
139  int translocate_policy(int argc, char * const *argv)
140  {
141      int result = -1;
142  
143      if (argc != 2)
144      {
145          return SHOW_USAGE_MESSAGE;
146      }
147  
148      CFURLRef inUrl = CFURLfromPath(argv[1], PathIsDir(argv[1]));
149      bool should = false;
150      CFErrorRef error = NULL;
151  
152      if(!inUrl)
153      {
154          printf("Error: failed to create url for: %s\n", argv[1]);
155          goto done;
156      }
157  
158      if (!SecTranslocateURLShouldRunTranslocated(inUrl, &should, &error))
159      {
160          int err = (int)CFErrorGetCode(error);
161          printf("Error: failed while trying to check policy for %s (errno: %d, %s)\n", argv[1], err, strerror(err));
162          goto done;
163      }
164  
165      printf("\t%s\n", should ? "Would translocate": "Would not translocate");
166  
167      result = 0;
168  
169  done:
170      SafeCFRelease(inUrl);
171      SafeCFRelease(error);
172  
173      return result;
174  }
175  
176  int translocate_check(int argc, char * const *argv)
177  {
178      int result = -1;
179  
180      if (argc != 2)
181      {
182          return SHOW_USAGE_MESSAGE;
183      }
184  
185      CFURLRef inUrl = CFURLfromPath(argv[1], PathIsDir(argv[1]));
186      bool is = false;
187      CFErrorRef error = NULL;
188  
189      if(!inUrl)
190      {
191          printf("Error: failed to create url for: %s\n", argv[1]);
192          goto done;
193      }
194  
195      if (!SecTranslocateIsTranslocatedURL(inUrl, &is, &error))
196      {
197          int err = (int)CFErrorGetCode(error);
198          printf("Error: failed while trying to check status for %s (errno: %d, %s)\n", argv[1], err, strerror(err));
199          goto done;
200      }
201  
202      printf("\t%s\n", is ? "TRANSLOCATED": "NOT TRANSLOCATED");
203  
204      result = 0;
205  
206  done:
207      SafeCFRelease(inUrl);
208      SafeCFRelease(error);
209  
210      return result;
211  }
212  
213  int translocate_original_path(int argc, char * const * argv)
214  {
215      int result = -1;
216  
217      if (argc != 2)
218      {
219          return SHOW_USAGE_MESSAGE;
220      }
221  
222      CFURLRef inUrl = CFURLfromPath(argv[1], PathIsDir(argv[1]));
223      CFURLRef outUrl = NULL;
224      CFErrorRef error = NULL;
225      char* outPath = NULL;
226  
227      if(!inUrl)
228      {
229          printf("Error: failed to create url for: %s\n", argv[1]);
230          goto done;
231      }
232  
233      outUrl = SecTranslocateCreateOriginalPathForURL(inUrl, &error);
234  
235      if (!outUrl)
236      {
237          int err = (int)CFErrorGetCode(error);
238          printf("Error: failed while trying to find original path for %s (errno: %d, %s)\n", argv[1], err, strerror(err));
239          goto done;
240      }
241  
242      outPath = PathFromCFURL(outUrl);
243  
244      if( !outPath )
245      {
246          printf("Error: failed to convert out url to string for %s\n", argv[1]);
247          goto done;
248      }
249  
250      printf("Original Path: (note if this is what you passed in then that path is not translocated)\n\t%s\n",outPath);
251  
252      free(outPath);
253      result = 0;
254  
255  done:
256      SafeCFRelease(inUrl);
257      SafeCFRelease(outUrl);
258      SafeCFRelease(error);
259  
260      return result;
261  }
262