Skip to content
Snippets Groups Projects
Commit 3e70d479 authored by Robert Craig's avatar Robert Craig
Browse files

Introduce post_process_mac_perms script.


usage: post_process_mac_perms [-h] -s SEINFO -d DIR -f POLICY

Tool to help modify an existing mac_permissions.xml with additional app certs
not already found in that policy. This becomes useful when a directory
containing apps is searched and the certs from those apps are added to the
policy not already explicitly listed.

optional arguments:
  -h, --help            show this help message and exit
  -s SEINFO, --seinfo SEINFO
                        seinfo tag for each generated stanza
  -d DIR, --dir DIR     Directory to search for apks
  -f POLICY, --file POLICY
                        mac_permissions.xml policy file

Change-Id: Ifbaca3b3120874a567d3f22eb487de1aa8bda796
Signed-off-by: default avatarrpcraig <rpcraig@tycho.ncsc.mil>
parent f8479e02
No related branches found
No related tags found
No related merge requests found
#!/usr/bin/env python
#
# Copyright (C) 2013 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Tool to help modify an existing mac_permissions.xml with additional app
certs not already found in that policy. This becomes useful when a directory
containing apps is searched and the certs from those apps are added to the
policy not already explicitly listed.
"""
import sys
import os
import argparse
from base64 import b16encode, b64decode
import fileinput
import re
import subprocess
import zipfile
PEM_CERT_RE = """-----BEGIN CERTIFICATE-----
(.+?)
-----END CERTIFICATE-----
"""
def collect_certs_for_app(filename):
app_certs = set()
with zipfile.ZipFile(filename, 'r') as apkzip:
for info in apkzip.infolist():
name = info.filename
if name.startswith('META-INF/') and name.endswith(('.DSA', '.RSA')):
cmd = ['openssl', 'pkcs7', '-inform', 'DER',
'-outform', 'PEM', '-print_certs']
p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
pem_string, err = p.communicate(apkzip.read(name))
if err and err.strip():
raise RuntimeError('Problem running openssl on %s (%s)' % (filename, e))
# turn multiline base64 to single line base16
transform = lambda x: b16encode(b64decode(x.replace('\n', ''))).lower()
results = re.findall(PEM_CERT_RE, pem_string, re.DOTALL)
certs = [transform(i) for i in results]
app_certs.update(certs)
return app_certs
def add_leftover_certs(args):
all_app_certs = set()
for dirpath, _, files in os.walk(args.dir):
transform = lambda x: os.path.join(dirpath, x)
condition = lambda x: x.endswith('.apk')
apps = [transform(i) for i in files if condition(i)]
# Collect certs for each app found
for app in apps:
app_certs = collect_certs_for_app(app)
all_app_certs.update(app_certs)
if all_app_certs:
policy_certs = set()
with open(args.policy, 'r') as f:
cert_pattern = 'signature="([a-fA-F0-9]+)"'
policy_certs = re.findall(cert_pattern, f.read())
cert_diff = all_app_certs.difference(policy_certs)
# Build xml stanzas
inner_tag = '<seinfo value="%s"/>' % args.seinfo
stanza = '<signer signature="%s">%s</signer>'
new_stanzas = [stanza % (cert, inner_tag) for cert in cert_diff]
mac_perms_string = ''.join(new_stanzas)
mac_perms_string += '</policy>'
# Inline replace with new policy stanzas
for line in fileinput.input(args.policy, inplace=True):
print line.replace('</policy>', mac_perms_string)
def main(argv):
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('-s', '--seinfo', dest='seinfo', required=True,
help='seinfo tag for each generated stanza')
parser.add_argument('-d', '--dir', dest='dir', required=True,
help='Directory to search for apks')
parser.add_argument('-f', '--file', dest='policy', required=True,
help='mac_permissions.xml policy file')
parser.set_defaults(func=add_leftover_certs)
args = parser.parse_args()
args.func(args)
if __name__ == '__main__':
main(sys.argv)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment