]> git.saurik.com Git - apple/libsecurity_codesigning.git/blob - lib/diskrep.cpp
0a284907473f64c6beea5a27a4bc9ac0f12d7ff2
[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 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