Skip to content

Commit

Permalink
Add -q and -Q to dump and sign "requirement data".
Browse files Browse the repository at this point in the history
  • Loading branch information
saurik committed Aug 26, 2016
1 parent b2e6a29 commit 9914b1b
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 14 deletions.
57 changes: 45 additions & 12 deletions ldid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1444,7 +1444,7 @@ static void Commit(const std::string &path, const std::string &temp) {

namespace ldid {

void Sign(const void *idata, size_t isize, std::streambuf &output, const std::string &identifier, const std::string &entitlements, const std::string &key, const Slots &slots) {
void Sign(const void *idata, size_t isize, std::streambuf &output, const std::string &identifier, const std::string &entitlements, const std::string &requirement, const std::string &key, const Slots &slots) {
std::string team;

#ifndef LDID_NOSMIME
Expand All @@ -1471,7 +1471,10 @@ void Sign(const void *idata, size_t isize, std::streambuf &output, const std::st

special = std::max(special, CSSLOT_REQUIREMENTS);
alloc += sizeof(struct BlobIndex);
alloc += 0xc;
if (!requirement.empty())
alloc += 0xc;
else
alloc += requirement.size();

if (!entitlements.empty()) {
special = std::max(special, CSSLOT_ENTITLEMENTS);
Expand Down Expand Up @@ -1513,8 +1516,12 @@ void Sign(const void *idata, size_t isize, std::streambuf &output, const std::st
if (true) {
std::stringbuf data;

Blobs requirements;
put(data, CSMAGIC_REQUIREMENTS, requirements);
if (requirement.empty()) {
Blobs requirements;
put(data, CSMAGIC_REQUIREMENTS, requirements);
} else {
put(data, requirement.data(), requirement.size());
}

insert(blobs, CSSLOT_REQUIREMENTS, data);
}
Expand Down Expand Up @@ -1921,18 +1928,18 @@ struct RuleCode {
};

#ifndef LDID_NOPLIST
static void Sign(const uint8_t *prefix, size_t size, std::streambuf &buffer, std::vector<char> &hash, std::streambuf &save, const std::string &identifier, const std::string &entitlements, const std::string &key, const Slots &slots) {
static void Sign(const uint8_t *prefix, size_t size, std::streambuf &buffer, std::vector<char> &hash, std::streambuf &save, const std::string &identifier, const std::string &entitlements, const std::string &requirement, const std::string &key, const Slots &slots) {
// XXX: this is a miserable fail
std::stringbuf temp;
put(temp, prefix, size);
copy(buffer, temp);
auto data(temp.str());

HashProxy proxy(hash, save);
Sign(data.data(), data.size(), proxy, identifier, entitlements, key, slots);
Sign(data.data(), data.size(), proxy, identifier, entitlements, requirement, key, slots);
}

std::string Bundle(const std::string &root, Folder &folder, const std::string &key, std::map<std::string, std::vector<char>> &remote, const std::string &entitlements) {
std::string Bundle(const std::string &root, Folder &folder, const std::string &key, std::map<std::string, std::vector<char>> &remote, const std::string &entitlements, const std::string &requirement) {
std::string executable;
std::string identifier;

Expand Down Expand Up @@ -1994,7 +2001,7 @@ std::string Bundle(const std::string &root, Folder &folder, const std::string &k
return;
auto bundle(root + Split(name).dir);
SubFolder subfolder(folder, bundle);
Bundle(bundle, subfolder, key, local, "");
Bundle(bundle, subfolder, key, local, "", "");
}));

folder.Find("", fun([&](const std::string &name, const Functor<void (const Functor<void (std::streambuf &, std::streambuf &)> &)> &code) {
Expand Down Expand Up @@ -2027,7 +2034,7 @@ std::string Bundle(const std::string &root, Folder &folder, const std::string &k
case MH_MAGIC: case MH_MAGIC_64:
case MH_CIGAM: case MH_CIGAM_64:
Slots slots;
Sign(header.bytes, size, data, hash, save, identifier, "", key, slots);
Sign(header.bytes, size, data, hash, save, identifier, "", "", key, slots);
return;
}

Expand Down Expand Up @@ -2118,7 +2125,7 @@ std::string Bundle(const std::string &root, Folder &folder, const std::string &k
Slots slots;
slots[1] = local.at(info);
slots[3] = local.at(signature);
Sign(NULL, 0, buffer, local[executable], save, identifier, entitlements, key, slots);
Sign(NULL, 0, buffer, local[executable], save, identifier, entitlements, requirement, key, slots);
}));
}));

Expand Down Expand Up @@ -2147,6 +2154,7 @@ int main(int argc, char *argv[]) {

bool flag_r(false);
bool flag_e(false);
bool flag_q(false);

#ifndef LDID_NOFLAGT
bool flag_T(false);
Expand All @@ -2173,6 +2181,7 @@ int main(int argc, char *argv[]) {
#endif

Map entitlements;
Map requirement;
Map key;
ldid::Slots slots;

Expand Down Expand Up @@ -2209,6 +2218,13 @@ int main(int argc, char *argv[]) {
sha1(slots[number], file.data(), file.size());
} break;

case 'q': flag_q = true; break;

case 'Q': {
const char *xml = argv[argi] + 2;
requirement.open(xml, O_RDONLY, PROT_READ, MAP_PRIVATE);
} break;

case 'D': flag_D = true; break;

case 'a': flag_a = true; break;
Expand Down Expand Up @@ -2294,7 +2310,7 @@ int main(int argc, char *argv[]) {
_assert(!flag_r);
ldid::DiskFolder folder(path);
std::map<std::string, std::vector<char>> hashes;
path += "/" + Bundle("", folder, key, hashes, entitlements);
path += "/" + Bundle("", folder, key, hashes, entitlements, requirement);
#else
_assert(false);
#endif
Expand All @@ -2309,7 +2325,7 @@ int main(int argc, char *argv[]) {
ldid::Unsign(input.data(), input.size(), output);
else {
std::string identifier(flag_I ?: split.base.c_str());
ldid::Sign(input.data(), input.size(), output, identifier, entitlements, key, slots);
ldid::Sign(input.data(), input.size(), output, identifier, entitlements, requirement, key, slots);
}

Commit(path, temp);
Expand Down Expand Up @@ -2402,6 +2418,23 @@ int main(int argc, char *argv[]) {
}
}

if (flag_q) {
_assert(signature != NULL);

uint32_t data = mach_header.Swap(signature->dataoff);

uint8_t *top = reinterpret_cast<uint8_t *>(mach_header.GetBase());
uint8_t *blob = top + data;
struct SuperBlob *super = reinterpret_cast<struct SuperBlob *>(blob);

for (size_t index(0); index != Swap(super->count); ++index)
if (Swap(super->index[index].type) == CSSLOT_REQUIREMENTS) {
uint32_t begin = Swap(super->index[index].offset);
struct Blob *requirement = reinterpret_cast<struct Blob *>(blob + begin);
fwrite(requirement, 1, Swap(requirement->length), stdout);
}
}

if (flag_s) {
_assert(signature != NULL);

Expand Down
4 changes: 2 additions & 2 deletions ldid.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,11 +139,11 @@ class UnionFolder :
}
};

std::string Bundle(const std::string &root, Folder &folder, const std::string &key, std::map<std::string, std::vector<char>> &remote, const std::string &entitlements);
std::string Bundle(const std::string &root, Folder &folder, const std::string &key, std::map<std::string, std::vector<char>> &remote, const std::string &entitlements, const std::string &requirement);

typedef std::map<uint32_t, std::vector<char>> Slots;

void Sign(const void *idata, size_t isize, std::streambuf &output, const std::string &identifier, const std::string &entitlements, const std::string &key, const Slots &slots);
void Sign(const void *idata, size_t isize, std::streambuf &output, const std::string &identifier, const std::string &entitlements, const std::string &requirement, const std::string &key, const Slots &slots);

}

Expand Down

0 comments on commit 9914b1b

Please sign in to comment.