reqparser.cpp
1 /* 2 * Copyright (c) 2006-2007,2011 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 // reqparser - interface to Requirement language parser/compiler 26 // 27 #include "reqparser.h" 28 #include "antlrplugin.h" 29 #include "cserror.h" 30 #include "codesigning_dtrace.h" 31 #include <CoreFoundation/CoreFoundation.h> 32 #include <security_utilities/osxcode.h> 33 #include <security_utilities/logging.h> 34 35 namespace Security { 36 namespace CodeSigning { 37 38 39 struct PluginHost { 40 PluginHost(); 41 RefPointer<LoadableBundle> plugin; 42 AntlrPlugin *antlr; 43 }; 44 45 ModuleNexus<PluginHost> plugin; 46 47 48 // 49 // The PluginHost constructor runs under the protection of ModuleNexus's constructor, 50 // so it doesn't have to worry about thread safety and such. 51 // 52 PluginHost::PluginHost() 53 { 54 if (CFBundleRef securityFramework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.security"))) 55 if (CFRef<CFURLRef> plugins = CFBundleCopyBuiltInPlugInsURL(securityFramework)) 56 if (CFRef<CFURLRef> pluginURL = makeCFURL("csparser.bundle", true, plugins)) { 57 plugin = new LoadableBundle(cfString(pluginURL).c_str()); 58 plugin->load(); 59 CODESIGN_LOAD_ANTLR(); 60 antlr = reinterpret_cast<FindAntlrPlugin *>(plugin->lookupSymbol(FINDANTLRPLUGIN))(); 61 return; 62 } 63 64 // can't load plugin - fail 65 Syslog::warning("code signing problem: unable to load csparser plug-in"); 66 MacOSError::throwMe(errSecCSInternalError); 67 } 68 69 70 // 71 // Drive a parsing function through the plugin harness and translate any errors 72 // into a CFError exception. 73 // 74 template <class Result, class Source> 75 const Result *parse(Source source, const Result *(*AntlrPlugin::*func)(Source, string &)) 76 { 77 string errors; 78 if (const Result *result = (plugin().antlr->*func)(source, errors)) 79 return result; 80 else 81 CSError::throwMe(errSecCSReqInvalid, kSecCFErrorRequirementSyntax, CFTempString(errors)); 82 } 83 84 85 // 86 // Implement the template instances by passing them through the plugin's eye-of-the-needle. 87 // Any other combination of input and output types will cause linker errors. 88 // 89 template <> 90 const Requirement *RequirementParser<Requirement>::operator () (std::FILE *source) 91 { 92 return parse(source, &AntlrPlugin::fileRequirement); 93 } 94 95 template <> 96 const Requirement *RequirementParser<Requirement>::operator () (const std::string &source) 97 { 98 return parse(source, &AntlrPlugin::stringRequirement); 99 } 100 101 template <> 102 const Requirements *RequirementParser<Requirements>::operator () (std::FILE *source) 103 { 104 return parse(source, &AntlrPlugin::fileRequirements); 105 } 106 107 template <> 108 const Requirements *RequirementParser<Requirements>::operator () (const std::string &source) 109 { 110 return parse(source, &AntlrPlugin::stringRequirements); 111 } 112 113 template <> 114 const BlobCore *RequirementParser<BlobCore>::operator () (std::FILE *source) 115 { 116 return parse(source, &AntlrPlugin::fileGeneric); 117 } 118 119 template <> 120 const BlobCore *RequirementParser<BlobCore>::operator () (const std::string &source) 121 { 122 return parse(source, &AntlrPlugin::stringGeneric); 123 } 124 125 126 } // CodeSigning 127 } // Security