1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2020 by the Linux Foundation
#
__author__ = 'Konstantin Ryabitsev <konstantin@linuxfoundation.org>'
import argparse
import logging
import b4
logger = b4.logger
def cmd_mbox_common_opts(sp):
sp.add_argument('msgid', nargs='?',
help='Message ID to process, or pipe a raw message')
sp.add_argument('-o', '--outdir', default='.',
help='Output into this directory')
sp.add_argument('-p', '--use-project', dest='useproject', default=None,
help='Use a specific project instead of guessing (linux-mm, linux-hardening, etc)')
sp.add_argument('-c', '--check-newer-revisions', dest='checknewer', action='store_true', default=False,
help='Check if newer patch revisions exist')
sp.add_argument('-n', '--mbox-name', dest='wantname', default=None,
help='Filename to name the mbox file')
sp.add_argument('-m', '--use-local-mbox', dest='localmbox', default=None,
help='Instead of grabbing a thread from lore, process this mbox file')
def cmd_mbox(cmdargs):
import b4.mbox
b4.mbox.main(cmdargs)
def cmd_am(cmdargs):
import b4.mbox
b4.mbox.main(cmdargs)
def cmd_attest(cmdargs):
import b4.attest
b4.attest.create_attestation(cmdargs)
def cmd_verify(cmdargs):
import b4.attest
b4.attest.verify_attestation(cmdargs)
def cmd():
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter
)
parser.add_argument('-d', '--debug', action='store_true', default=False,
help='Add more debugging info to the output')
parser.add_argument('-q', '--quiet', action='store_true', default=False,
help='Output critical information only')
subparsers = parser.add_subparsers(help='sub-command help', dest='subcmd')
# b4 mbox
sp_mbox = subparsers.add_parser('mbox', help='Download a thread as an mbox file')
cmd_mbox_common_opts(sp_mbox)
sp_mbox.set_defaults(func=cmd_mbox)
# b4 am
sp_am = subparsers.add_parser('am', help='Create an mbox file that is ready to git-am')
cmd_mbox_common_opts(sp_am)
sp_am.add_argument('-v', '--use-version', dest='wantver', type=int, default=None,
help='Get a specific version of the patch/series')
sp_am.add_argument('-t', '--apply-cover-trailers', dest='covertrailers', action='store_true', default=False,
help='Apply trailers sent to the cover letter to all patches')
sp_am.add_argument('-T', '--no-add-trailers', dest='noaddtrailers', action='store_true', default=False,
help='Do not add or sort any trailers')
sp_am.add_argument('-s', '--add-my-sob', dest='addmysob', action='store_true', default=False,
help='Add your own signed-off-by to every patch')
sp_am.add_argument('-l', '--add-link', dest='addlink', action='store_true', default=False,
help='Add a lore.kernel.org/r/ link to every patch')
sp_am.add_argument('-Q', '--quilt-ready', dest='quiltready', action='store_true', default=False,
help='Save mbox patches in a quilt-ready folder')
sp_am.set_defaults(func=cmd_am)
# b4 attest
sp_att = subparsers.add_parser('attest', help='Submit cryptographic attestation for patches')
# GDPR-proofing: by default, we add as little PII-sensitive info as possible
sp_att.add_argument('-f', '--from', dest='sender', default='devnull@kernel.org',
help='Use a custom From field')
sp_att.add_argument('-n', '--no-submit', dest='nosubmit', action='store_true', default=False,
help='Do not submit attestation, just save the message ready to send')
sp_att.add_argument('-o', '--output', default='xxxx-attestation-letter.patch',
help='Save attestation message in this file if not submitting it')
sp_att.add_argument('patchfile', nargs='+', help='Patches to attest')
sp_att.set_defaults(func=cmd_attest)
# b4 verify
sp_ver = subparsers.add_parser('attverify', help='Verify cryptographic attestation of patches in an mbox')
sp_ver.add_argument('-i', '--attestation-file', dest='attfile',
help='Use this file for attestation data instead of querying lore.kernel.org')
sp_ver.add_argument('-t', '--tofu', action='store_true', default=False,
help='Force TOFU trust model (otherwise uses your global GnuPG setting)')
sp_ver.add_argument('-X', '--no-fast-exit', dest='nofast', action='store_true', default=False,
help='Do not exit after first failure')
sp_ver.add_argument('-F', '--ignore-from-mismatch', dest='ignorefrom', action='store_true',
default=False, help='Ignore mismatches between From: and PGP uid data')
sp_ver.add_argument('mbox', nargs=1, help='Mbox containing patches to attest')
sp_ver.set_defaults(func=cmd_verify)
cmdargs = parser.parse_args()
logger.setLevel(logging.DEBUG)
ch = logging.StreamHandler()
formatter = logging.Formatter('%(message)s')
ch.setFormatter(formatter)
if cmdargs.quiet:
ch.setLevel(logging.CRITICAL)
elif cmdargs.debug:
ch.setLevel(logging.DEBUG)
else:
ch.setLevel(logging.INFO)
logger.addHandler(ch)
cmdargs.func(cmdargs)
if __name__ == '__main__':
cmd()
|