]>
Commit | Line | Data |
---|---|---|
7d31e928 A |
1 | /* |
2 | * Copyright (c) 2006-2007 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 | // | |
25 | // diskrep - disk representations of code | |
26 | // | |
27 | #include "diskrep.h" | |
28 | #include <sys/stat.h> | |
29 | #include <CoreFoundation/CFBundlePriv.h> | |
30 | ||
31 | // specific disk representations created by the bestGuess() function | |
32 | #include "filediskrep.h" | |
33 | #include "bundlediskrep.h" | |
34 | #include "cfmdiskrep.h" | |
35 | #include "foreigndiskrep.h" | |
36 | ||
37 | ||
38 | namespace Security { | |
39 | namespace CodeSigning { | |
40 | ||
41 | using namespace UnixPlusPlus; | |
42 | ||
43 | ||
44 | // | |
45 | // Abstract features | |
46 | // | |
47 | DiskRep::DiskRep() | |
48 | { | |
49 | } | |
50 | ||
51 | DiskRep::~DiskRep() | |
52 | { /* virtual */ } | |
53 | ||
54 | ||
55 | // | |
56 | // Normal DiskReps are their own base. | |
57 | // | |
58 | DiskRep *DiskRep::base() | |
59 | { | |
60 | return this; | |
61 | } | |
62 | ||
63 | ||
64 | // | |
65 | // By default, DiskReps are read-only. | |
66 | // | |
67 | DiskRep::Writer *DiskRep::writer() | |
68 | { | |
69 | MacOSError::throwMe(errSecCSBadObjectFormat); | |
70 | } | |
71 | ||
72 | ||
73 | // | |
74 | // Given a file system path, come up with the most likely correct | |
75 | // disk representation for what's there. | |
76 | // This is, strictly speaking, a heuristic that could be fooled - there's | |
77 | // no fool-proof rule for figuring this out. But we'd expect this to work | |
78 | // fine in ordinary use. If you happen to know what you're looking at | |
79 | // (say, a bundle), then just create the suitable subclass of DiskRep directly. | |
80 | // That's quite legal. | |
81 | // | |
82 | DiskRep *DiskRep::bestGuess(const char *path) | |
83 | { | |
84 | struct stat st; | |
85 | if (::stat(path, &st)) | |
86 | UnixError::throwMe(); | |
87 | ||
88 | // if it's a directory, assume it's a bundle | |
89 | if ((st.st_mode & S_IFMT) == S_IFDIR) // directory - assume bundle | |
90 | return new BundleDiskRep(path); | |
91 | ||
92 | // see if it's the main executable of a recognized bundle | |
93 | if (CFRef<CFURLRef> pathURL = makeCFURL(path)) | |
94 | if (CFRef<CFBundleRef> bundle = _CFBundleCreateWithExecutableURLIfLooksLikeBundle(NULL, pathURL)) | |
95 | return new BundleDiskRep(bundle); | |
96 | ||
97 | // follow the file choosing rules | |
98 | return bestFileGuess(path); | |
99 | } | |
100 | ||
101 | ||
102 | DiskRep *DiskRep::bestFileGuess(const char *path) | |
103 | { | |
104 | AutoFileDesc fd(path, O_RDONLY); | |
105 | if (MachORep::candidiate(fd)) | |
106 | return new MachORep(path); | |
107 | if (CFMDiskRep::candidiate(fd)) | |
108 | return new CFMDiskRep(path); | |
109 | if (ForeignDiskRep::candidate(fd)) | |
110 | return new ForeignDiskRep(path); | |
111 | ||
112 | return new FileDiskRep(path); | |
113 | } | |
114 | ||
115 | ||
116 | // | |
117 | // Default behaviors of DiskRep | |
118 | // | |
119 | string DiskRep::resourcesRootPath() | |
120 | { | |
121 | return ""; // has no resources directory | |
122 | } | |
123 | ||
124 | CFDictionaryRef DiskRep::defaultResourceRules() | |
125 | { | |
126 | return NULL; // none | |
127 | } | |
128 | ||
129 | const Requirements *DiskRep::defaultRequirements(const Architecture *) | |
130 | { | |
131 | return NULL; // none | |
132 | } | |
133 | ||
134 | Universal *DiskRep::mainExecutableImage() | |
135 | { | |
136 | return NULL; // no Mach-O executable | |
137 | } | |
138 | ||
139 | size_t DiskRep::pageSize() | |
140 | { | |
141 | return monolithicPageSize; // unpaged (monolithic) | |
142 | } | |
143 | ||
144 | size_t DiskRep::signingBase() | |
145 | { | |
146 | return 0; // whole file (start at beginning) | |
147 | } | |
148 | ||
149 | CFArrayRef DiskRep::modifiedFiles() | |
150 | { | |
151 | // by default, claim (just) the main executable modified | |
152 | CFRef<CFURLRef> mainURL = makeCFURL(mainExecutablePath()); | |
153 | return makeCFArray(1, mainURL.get()); | |
154 | } | |
155 | ||
156 | void DiskRep::flush() | |
157 | { | |
158 | // nothing cached | |
159 | } | |
160 | ||
161 | ||
162 | // | |
163 | // Writers | |
164 | // | |
165 | DiskRep::Writer::Writer(uint32_t attrs) | |
166 | : mArch(CPU_TYPE_ANY), mAttributes(attrs) | |
167 | { | |
168 | } | |
169 | ||
170 | DiskRep::Writer::~Writer() | |
171 | { /* virtual */ } | |
172 | ||
173 | uint32_t DiskRep::Writer::attributes() const | |
174 | { return mAttributes; } | |
175 | ||
176 | void DiskRep::Writer::flush() | |
177 | { /* do nothing */ } | |
178 | ||
179 | ||
180 | } // end namespace CodeSigning | |
181 | } // end namespace Security |