| #!/usr/bin/env python |
| |
| # Copyright (c) 2022 Project CHIP Authors |
| # |
| # 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. |
| |
| import argparse |
| import logging |
| import os |
| import subprocess |
| import sys |
| |
| # Absolute path to Tizen Studio CLI tool. |
| tizen_sdk_root = os.environ["TIZEN_SDK_ROOT"] |
| tizen_cli = os.path.join(tizen_sdk_root, "tools", "ide", "bin", "tizen") |
| |
| # Setup basic logging capabilities. |
| logging.basicConfig(level=logging.DEBUG) |
| |
| |
| def create_author_certificate(alias: str, password: str, |
| name: str = "", email: str = ""): |
| cmd = [tizen_cli, "certificate", "--alias", alias, "--password", password] |
| if name: |
| cmd.extend(["--name", name]) |
| if email: |
| cmd.extend(["--email", email]) |
| logging.debug("Execute: %s", " ".join(cmd)) |
| with subprocess.Popen(cmd, stdout=subprocess.PIPE) as proc: |
| for line in proc.stdout.readlines(): |
| line = line.decode().rstrip() |
| if line.startswith("Working path:"): |
| wd = line[len("Working path:"):].strip() |
| print(line) |
| return os.path.join(wd, "author.p12") |
| |
| |
| def check_security_profile(profile): |
| |
| # XXX: If Tizen Studio SDK data directory was removed but the config file |
| # was not, Tizen Studio CLI does not create profiles XML file. This |
| # is a workaround to create a dummy XML profiles file so later Tizen |
| # will regenerate it with the correct content. |
| |
| tizen_sdk_data_dir = None |
| with open(os.environ["TIZEN_SDK_ROOT"] + "/sdk.info") as f: |
| for line in f.readlines(): |
| if line.startswith("TIZEN_SDK_DATA_PATH"): |
| tizen_sdk_data_dir = line.split("=")[1].strip() |
| break |
| if not tizen_sdk_data_dir: |
| logging.error("Cannot find Tizen SDK data directory") |
| return False |
| |
| profiles_xml = os.path.join(tizen_sdk_data_dir, "profile", "profiles.xml") |
| if not os.path.exists(profiles_xml): |
| os.makedirs(os.path.dirname(profiles_xml), exist_ok=True) |
| with open(profiles_xml, "w") as f: |
| f.write('<profiles/>') |
| |
| cmd = [tizen_cli, "security-profiles", "list", "--name", profile] |
| logging.debug("Execute: %s", " ".join(cmd)) |
| with subprocess.Popen(cmd, stdout=subprocess.PIPE) as proc: |
| for line in proc.stdout.readlines(): |
| line = line.decode().rstrip() |
| print(line) |
| return proc.wait() == 0 |
| |
| |
| def add_security_profile(profile: str, certificate: str, password: str): |
| cmd = [tizen_cli, "security-profiles", "add", "--active", |
| "--name", profile, "--author", certificate, "--password", password] |
| logging.debug("Execute: %s", " ".join(cmd)) |
| with subprocess.Popen(cmd, stdout=subprocess.PIPE) as proc: |
| for line in proc.stdout.readlines(): |
| line = line.decode().rstrip() |
| print(line) |
| return proc.wait() == 0 |
| |
| |
| def update_stamp_file(path: str, message: str): |
| if path: |
| with open(path, "w") as f: |
| f.write(message + "\n") |
| |
| |
| parser = argparse.ArgumentParser( |
| description="Setup Tizen Studio development security profile.") |
| parser.add_argument( |
| '--author-certificate-name', metavar='NAME', |
| help="Set author certificate 'name' field.") |
| parser.add_argument( |
| '--author-certificate-email', metavar='EMAIL', |
| help="Set author certificate 'email' field.") |
| parser.add_argument( |
| '--author-certificate-password', metavar='PASSWORD', required=True, |
| help="Password for author certificate.") |
| parser.add_argument( |
| '--sign-security-profile', metavar='NAME', required=True, |
| help="Name of the security profile to add.") |
| parser.add_argument( |
| '--stamp-file', metavar='FILE', |
| help="Update the stamp file upon success.") |
| |
| args = parser.parse_args() |
| |
| rv = check_security_profile(args.sign_security_profile) |
| if rv: |
| update_stamp_file(args.stamp_file, "Using existing security profile.") |
| logging.info("Security profile already exists") |
| sys.exit() |
| |
| # Create author certificate if it does not exist. If the certificate already |
| # exists, it will be used. However, if the password is different, it will not |
| # be possible to use the certificate when updating the security profile. |
| cert = create_author_certificate("CHIP", |
| args.author_certificate_password, |
| args.author_certificate_name, |
| args.author_certificate_email) |
| if not cert: |
| logging.error("Failed to create author certificate") |
| sys.exit(1) |
| |
| rv = add_security_profile(args.sign_security_profile, cert, |
| args.author_certificate_password) |
| if not rv: |
| logging.error("Failed to add security profile") |
| sys.exit(1) |
| |
| update_stamp_file(args.stamp_file, "New security profile created.") |
| sys.exit() |