]> git.saurik.com Git - apple/libsecurity_codesigning.git/blob - lib/diskrep.cpp
5db86a395ffe0c2e7c7e99b576cf93d177be13a2
[apple/libsecurity_codesigning.git] / lib / diskrep.cpp
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 try {
85 struct stat st;
86 if (::stat(path, &st))
87 UnixError::throwMe();
88
89 // if it's a directory, assume it's a bundle
90 if ((st.st_mode & S_IFMT) == S_IFDIR) // directory - assume bundle
91 return new BundleDiskRep(path);
92
93 // see if it's the main executable of a recognized bundle
94 if (CFRef<CFURLRef> pathURL = makeCFURL(path))
95 if (CFRef<CFBundleRef> bundle = _CFBundleCreateWithExecutableURLIfMightBeBundle(NULL, pathURL))
96 return new BundleDiskRep(bundle);
97
98 // follow the file choosing rules
99 return bestFileGuess(path);
100 } catch (const CommonError &error) {
101 switch (error.unixError()) {
102 case ENOENT:
103 MacOSError::throwMe(errSecCSStaticCodeNotFound);
104 default:
105 throw;
106 }
107 }
108 }
109
110
111 DiskRep *DiskRep::bestFileGuess(const char *path)
112 {
113 AutoFileDesc fd(path, O_RDONLY);
114 if (MachORep::candidiate(fd))
115 return new MachORep(path);
116 if (CFMDiskRep::candidiate(fd))
117 return new CFMDiskRep(path);
118 if (ForeignDiskRep::candidate(fd))
119 return new ForeignDiskRep(path);
120
121 return new FileDiskRep(path);
122 }
123
124
125 //
126 // Default behaviors of DiskRep
127 //
128 string DiskRep::resourcesRootPath()
129 {
130 return ""; // has no resources directory
131 }
132
133 CFDictionaryRef DiskRep::defaultResourceRules()
134 {
135 return NULL; // none
136 }
137
138 void DiskRep::adjustResources(ResourceBuilder &builder)
139 {
140 // do nothing
141 }
142
143 const Requirements *DiskRep::defaultRequirements(const Architecture *)
144 {
145 return NULL; // none
146 }
147
148 Universal *DiskRep::mainExecutableImage()
149 {
150 return NULL; // no Mach-O executable
151 }
152
153 size_t DiskRep::pageSize()
154 {
155 return monolithicPageSize; // unpaged (monolithic)
156 }
157
158 size_t DiskRep::signingBase()
159 {
160 return 0; // whole file (start at beginning)
161 }
162
163 CFArrayRef DiskRep::modifiedFiles()
164 {
165 // by default, claim (just) the main executable modified
166 CFRef<CFURLRef> mainURL = makeCFURL(mainExecutablePath());
167 return makeCFArray(1, mainURL.get());
168 }
169
170 void DiskRep::flush()
171 {
172 // nothing cached
173 }
174
175
176 //
177 // Writers
178 //
179 DiskRep::Writer::Writer(uint32_t attrs)
180 : mArch(CPU_TYPE_ANY), mAttributes(attrs)
181 {
182 }
183
184 DiskRep::Writer::~Writer()
185 { /* virtual */ }
186
187 uint32_t DiskRep::Writer::attributes() const
188 { return mAttributes; }
189
190 void DiskRep::Writer::flush()
191 { /* do nothing */ }
192
193
194 } // end namespace CodeSigning
195 } // end namespace Security