Esempio n. 1
0
async def build_task_dependencies(chain, task, name, my_task_id):
    """Recursively build the task dependencies of a task.

    Args:
        chain (ChainOfTrust): the chain of trust to add to.
        task (dict): the task definition to operate on.
        name (str): the name of the task to operate on.
        my_task_id (str): the taskId of the task to operate on.

    Raises:
        CoTError: on failure.
    """
    log.info("build_task_dependencies {} {}".format(name, my_task_id))
    if name.count(':') > 5:
        raise CoTError("Too deep recursion!\n{}".format(name))
    sorted_dependencies = find_sorted_task_dependencies(task, name, my_task_id)

    for task_name, task_id in sorted_dependencies:
        if task_id not in chain.dependent_task_ids():
            link = LinkOfTrust(chain.context, task_name, task_id)
            json_path = link.get_artifact_full_path('task.json')
            try:
                task_defn = await chain.context.queue.task(task_id)
                link.task = task_defn
                chain.links.append(link)
                # write task json to disk
                makedirs(os.path.dirname(json_path))
                with open(json_path, 'w') as fh:
                    fh.write(format_json(task_defn))
                await build_task_dependencies(chain, task_defn, task_name,
                                              task_id)
            except TaskclusterFailure as exc:
                raise CoTError(str(exc))
Esempio n. 2
0
def generate_cot(context, path=None):
    """Format and sign the cot body, and write to disk

    Args:
        context (scriptworker.context.Context): the scriptworker context.
        path (str, optional): The path to write the chain of trust artifact to.
            If None, this is artifact_dir/public/chainOfTrust.json.asc.
            Defaults to None.

    Returns:
        str: the contents of the chain of trust artifact.

    Raises:
        ScriptWorkerException: on schema error.
    """
    body = generate_cot_body(context)
    try:
        with open(context.config['cot_schema_path'], "r") as fh:
            schema = json.load(fh)
    except (IOError, ValueError) as e:
        raise ScriptWorkerException("Can't read schema file {}: {}".format(
            context.config['cot_schema_path'], str(e)))
    validate_json_schema(body, schema, name="chain of trust")
    body = format_json(body)
    path = path or os.path.join(context.config['artifact_dir'], "public",
                                "chainOfTrust.json.asc")
    if context.config['sign_chain_of_trust']:
        body = sign(GPG(context), body)
    with open(path, "w") as fh:
        print(body, file=fh, end="")
    return body
Esempio n. 3
0
def generate_cot(context, parent_path=None):
    """Format and sign the cot body, and write to disk.

    Args:
        context (scriptworker.context.Context): the scriptworker context.
        parent_path (str, optional): The directory to write the chain of trust
            artifacts to.  If None, this is ``artifact_dir/public/``.
            Defaults to None.

    Returns:
        str: the contents of the chain of trust artifact.

    Raises:
        ScriptWorkerException: on schema error.

    """
    body = generate_cot_body(context)
    schema = load_json_or_yaml(
        context.config['cot_schema_path'], is_path=True,
        exception=ScriptWorkerException,
        message="Can't read schema file {}: %(exc)s".format(context.config['cot_schema_path'])
    )
    validate_json_schema(body, schema, name="chain of trust")
    body = format_json(body)
    parent_path = parent_path or os.path.join(context.config['artifact_dir'], 'public')
    unsigned_path = os.path.join(parent_path, 'chain-of-trust.json')
    write_to_file(unsigned_path, body)
    if context.config['sign_chain_of_trust']:
        ed25519_signature_path = '{}.sig'.format(unsigned_path)
        ed25519_private_key = ed25519_private_key_from_file(context.config['ed25519_private_key_path'])
        ed25519_signature = ed25519_private_key.sign(body.encode('utf-8'))
        write_to_file(ed25519_signature_path, ed25519_signature, file_type='binary')
    return body
Esempio n. 4
0
def test_format_json():
    expected = "\n".join([
        "{", '  "a": 1,', '  "b": [', "    4,", "    3,", "    2", "  ],",
        '  "c": {', '    "d": 5', "  }", "}"
    ])
    assert utils.format_json({
        "c": {
            "d": 5
        },
        "a": 1,
        "b": [4, 3, 2]
    }) == expected
Esempio n. 5
0
def test_format_json():
    expected = '\n'.join([
        '{', '  "a": 1,', '  "b": [', '    4,', '    3,', '    2', '  ],',
        '  "c": {', '    "d": 5', '  }', '}'
    ])
    assert utils.format_json({
        'c': {
            'd': 5
        },
        'a': 1,
        'b': [4, 3, 2]
    }) == expected
Esempio n. 6
0
def test_format_json():
    expected = '\n'.join([
        '{',
        '  "a": 1,',
        '  "b": [',
        '    4,',
        '    3,',
        '    2',
        '  ],',
        '  "c": {',
        '    "d": 5',
        '  }',
        '}'
    ])
    assert utils.format_json({'c': {'d': 5}, 'a': 1, 'b': [4, 3, 2]}) == expected
Esempio n. 7
0
def verify_cot_signatures(chain):
    """Verify the signatures of the chain of trust artifacts populated in ``download_cot``.

    Populate each link.cot with the chain of trust json body.

    Args:
        chain (ChainOfTrust): the chain of trust to add to.

    Raises:
        CoTError: on failure.
    """
    for link in chain.links:
        path = link.get_artifact_full_path('public/chainOfTrust.json.asc')
        gpg_home = os.path.join(chain.context.config['base_gpg_home_dir'],
                                link.worker_impl)
        gpg = GPG(chain.context, gpg_home=gpg_home)
        log.debug(
            "Verifying the {} {} chain of trust signature against {}".format(
                link.name, link.task_id, gpg_home))
        try:
            with open(path, "r") as fh:
                contents = fh.read()
        except OSError as exc:
            raise CoTError("Can't read {}: {}!".format(path, str(exc)))
        try:
            # TODO remove verify_sig pref and kwarg when git repo pubkey
            # verification works reliably!
            body = get_body(
                gpg,
                contents,
                verify_sig=chain.context.config['verify_cot_signature'])
        except ScriptWorkerGPGException as exc:
            raise CoTError(
                "GPG Error verifying chain of trust for {}: {}!".format(
                    path, str(exc)))
        link.cot = load_json(
            body,
            exception=CoTError,
            message="{} {}: Invalid cot json body! %(exc)s".format(
                link.name, link.task_id))
        unsigned_path = link.get_artifact_full_path('chainOfTrust.json')
        log.debug("Good.  Writing json contents to {}".format(unsigned_path))
        with open(unsigned_path, "w") as fh:
            fh.write(format_json(link.cot))
Esempio n. 8
0
def generate_cot(context, parent_path=None):
    """Format and sign the cot body, and write to disk.

    Args:
        context (scriptworker.context.Context): the scriptworker context.
        parent_path (str, optional): The directory to write the chain of trust
            artifacts to.  If None, this is ``artifact_dir/public/``.
            Defaults to None.

    Returns:
        str: the contents of the chain of trust artifact.

    Raises:
        ScriptWorkerException: on schema error.

    """
    body = generate_cot_body(context)
    schema = load_json_or_yaml(
        context.config['cot_schema_path'],
        is_path=True,
        exception=ScriptWorkerException,
        message="Can't read schema file {}: %(exc)s".format(
            context.config['cot_schema_path']))
    validate_json_schema(body, schema, name="chain of trust")
    body = format_json(body)
    parent_path = parent_path or os.path.join(context.config['artifact_dir'],
                                              'public')
    asc_path = os.path.join(parent_path, "chainOfTrust.json.asc")
    unsigned_path = os.path.join(parent_path, 'chain-of-trust.json')
    write_to_file(unsigned_path, body)
    if context.config['sign_chain_of_trust']:
        ed25519_signature_path = '{}.sig'.format(unsigned_path)
        ed25519_private_key = ed25519_private_key_from_file(
            context.config['ed25519_private_key_path'])
        ed25519_signature = ed25519_private_key.sign(body.encode('utf-8'))
        write_to_file(ed25519_signature_path,
                      ed25519_signature,
                      file_type='binary')
        body = sign(GPG(context), body)
    write_to_file(asc_path, body)
    return body