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