#ifndef _H_DISKREP
#define _H_DISKREP
#include "cs.h"
#include "codedirectory.h"
#include "cdbuilder.h"
#include "requirement.h"
#include "resources.h"
#include <security_utilities/macho++.h> // for class Architecture
#include <security_utilities/refcount.h>
#include <security_utilities/superblob.h>
#include <CoreFoundation/CFData.h>
namespace Security {
namespace CodeSigning {
class ResourceBuilder;
class DiskRep : public RefCount {
public:
class SigningContext;
public:
DiskRep();
virtual ~DiskRep();
virtual DiskRep *base();
virtual CFDataRef component(CodeDirectory::SpecialSlot slot) = 0; virtual CFDataRef identification() = 0; virtual std::string mainExecutablePath() = 0; virtual CFURLRef canonicalPath() = 0; virtual std::string resourcesRootPath(); virtual void adjustResources(ResourceBuilder &builder); virtual Universal *mainExecutableImage(); virtual size_t signingBase(); virtual size_t signingLimit() = 0; virtual std::string format() = 0; virtual CFArrayRef modifiedFiles(); virtual UnixPlusPlus::FileDesc &fd() = 0; virtual void flush();
virtual std::string recommendedIdentifier(const SigningContext &ctx) = 0; virtual CFDictionaryRef defaultResourceRules(const SigningContext &ctx); virtual const Requirements *defaultRequirements(const Architecture *arch,
const SigningContext &ctx); virtual size_t pageSize(const SigningContext &ctx);
bool mainExecutableIsMachO() { return mainExecutableImage() != NULL; }
CFDataRef codeDirectory() { return component(cdCodeDirectorySlot); }
CFDataRef signature() { return component(cdSignatureSlot); }
public:
class Writer;
virtual Writer *writer();
public:
struct Context {
Context() : arch(Architecture::none), version(NULL), offset(0), fileOnly(false), inMemory(NULL) { }
Architecture arch; const char *version; off_t offset; bool fileOnly; const void *inMemory; };
static DiskRep *bestGuess(const char *path, const Context *ctx = NULL); static DiskRep *bestFileGuess(const char *path, const Context *ctx = NULL); static DiskRep *bestGuess(const char *path, size_t archOffset);
static DiskRep *bestGuess(const std::string &path, const Context *ctx = NULL)
{ return bestGuess(path.c_str(), ctx); }
static DiskRep *bestGuess(const std::string &path, size_t archOffset) { return bestGuess(path.c_str(), archOffset); }
static DiskRep *bestFileGuess(const std::string &path, const Context *ctx = NULL) { return bestFileGuess(path.c_str(), ctx); }
public:
class SigningContext {
protected:
SigningContext() { }
public:
virtual std::string sdkPath(const std::string &path) const = 0;
virtual bool isAdhoc() const = 0;
virtual SecCSFlags signingFlags() const = 0;
};
protected:
static std::string canonicalIdentifier(const std::string &name);
public:
static const size_t segmentedPageSize = 4096; static const size_t monolithicPageSize = 0; };
class DiskRep::Writer : public RefCount {
public:
Writer(uint32_t attrs = 0);
virtual ~Writer();
virtual void component(CodeDirectory::SpecialSlot slot, CFDataRef data) = 0;
virtual uint32_t attributes() const;
virtual void addDiscretionary(CodeDirectory::Builder &builder);
virtual void remove();
virtual void flush();
bool attribute(uint32_t attr) const { return mAttributes & attr; }
void signature(CFDataRef data) { component(cdSignatureSlot, data); }
void codeDirectory(const CodeDirectory *cd)
{ component(cdCodeDirectorySlot, CFTempData(cd->data(), cd->length())); }
private:
Architecture mArch;
uint32_t mAttributes;
};
enum {
writerLastResort = 0x0001, writerNoGlobal = 0x0002, };
class FilterRep : public DiskRep {
public:
FilterRep(DiskRep *orig) : mOriginal(orig) { }
DiskRep *base() { return mOriginal; }
CFDataRef component(CodeDirectory::SpecialSlot slot) = 0;
CFDataRef identification() { return mOriginal->identification(); }
std::string mainExecutablePath() { return mOriginal->mainExecutablePath(); }
CFURLRef canonicalPath() { return mOriginal->canonicalPath(); }
std::string resourcesRootPath() { return mOriginal->resourcesRootPath(); }
void adjustResources(ResourceBuilder &builder) { return mOriginal->adjustResources(builder); }
Universal *mainExecutableImage() { return mOriginal->mainExecutableImage(); }
size_t signingBase() { return mOriginal->signingBase(); }
size_t signingLimit() { return mOriginal->signingLimit(); }
std::string format() { return mOriginal->format(); }
CFArrayRef modifiedFiles() { return mOriginal->modifiedFiles(); }
UnixPlusPlus::FileDesc &fd() { return mOriginal->fd(); }
void flush() { return mOriginal->flush(); }
std::string recommendedIdentifier(const SigningContext &ctx)
{ return mOriginal->recommendedIdentifier(ctx); }
CFDictionaryRef defaultResourceRules(const SigningContext &ctx)
{ return mOriginal->defaultResourceRules(ctx); }
private:
RefPointer<DiskRep> mOriginal; };
} }
#endif // !_H_DISKREP