From 5e6db1beccac423a6394858a26606b200cd5e646 Mon Sep 17 00:00:00 2001 From: "Tobias Dussa (TGD)" <dussa@dfn-cert.de> Date: Tue, 10 Sep 2024 12:51:54 +0200 Subject: [PATCH] Added the option to pass args to the GPG init call. --- reaction-mailcreate/README.md | 9 +++++ reaction-mailcreate/createMails.py | 65 +++++++++++++++--------------- 2 files changed, 42 insertions(+), 32 deletions(-) diff --git a/reaction-mailcreate/README.md b/reaction-mailcreate/README.md index 5f140cd..c08b515 100644 --- a/reaction-mailcreate/README.md +++ b/reaction-mailcreate/README.md @@ -134,6 +134,9 @@ DFN-CERT,Tobias,Dussa,dussa@dfn-cert.de be empty (`""`) or `gpg`. Defaults to none. - `--sign-arg`: Specifies additional arguments to be passed to the function call that signs the mail. Defaults to none. + - `--sign-init-arg`: Specifies additional arguments to be passed to the + function call that initializes the mail-signing mechanism. Defaults to + none. - `-s`/`--subject`: Specifies the mail subject to be used. Defaults to `Security Challenge Message -- {campaign}{infix}`. - `-T`/`--to`: Specifies the recipient mail address to be used. Defaults @@ -269,6 +272,12 @@ the signing command: ./createMails.py --sign gpg --sign-arg "keyid=0x1234567890ABCDEF" ``` +You can also specify a different directory to be used as GnuPG home by +passing call options to the signing command: +``` +./createMails.py --sign gpg --sign-init-arg "gnupghome=/some/dir" +``` + By default, mails are sent to localhost on port 25 using plain SMTP. To use a different mail server, you need to specify the server to be used: ``` diff --git a/reaction-mailcreate/createMails.py b/reaction-mailcreate/createMails.py index 374c190..cef0959 100755 --- a/reaction-mailcreate/createMails.py +++ b/reaction-mailcreate/createMails.py @@ -53,36 +53,37 @@ class KeyValueAction(argparse.Action): parser.register('action', 'keyvalue', KeyValueAction) # Parse args -parser.add_argument('-a', '--attach', dest='attach', default=[], nargs=1, action='extend', help='add attachment(s) to mail (default: None)') -parser.add_argument('-b', '--basedir', dest='basedir', default='Mails', help='base directory for all output (default: "Mails")') -parser.add_argument('-B', '--bcc', dest='bcc', default=[], nargs=1, action='extend', help='additional mail recipient(s) to bcc (default: None)') -parser.add_argument('-c', '--campaign', dest='campaign', default='Test', help='campaign name (default: "Test")') -parser.add_argument('-C', '--cc', dest='cc', default=[], nargs=1, action='extend', help='additional mail recipient(s) to cc (default: None)') -parser.add_argument('-d', '--dry-run', dest='dryrun', default=False, action='store_true', help='dry run -- do not actually send mails or create targets (default: False)') -parser.add_argument('-f', '--from', dest='sender', default='Nobody <nobody@example.com>', help='sender mail address (default: "Nobody <nobody@example.com>"; implies dry-run if not set)') -parser.add_argument('-F', '--force', dest='force', default=False, action='store_true', help='force insecure login without TLS/SSL (default: False)') -parser.add_argument('-H', '--hashstring', dest='hashstring', default='{salt}{campaign}{infix}-{site}', help='string to be hashed for the URL (default: "{salt}{campaign}{infix}-{site}" where "{salt}" is a random string)') -parser.add_argument('-i', '--input', dest='input', default='{basedir}/{campaign}/Input{infix}.lst', help='input file (default: "{basedir}/{campaign}/Input{infix}.lst")') -parser.add_argument('-I', '--message-id', dest='messageid', default=False, action='store_true', help='create a message ID (default: False)') -parser.add_argument('-o', '--output', dest='output', default='{basedir}/{campaign}/{site}/{timestamp}{infix}.eml', help='output file name template (default: "{basedir}/{campaign}/{site}/{timestamp}{infix}.eml")') -parser.add_argument('-R', '--reply-to', dest='replyto', default=None, help='reply-to mail address (default: None)') -parser.add_argument( '--salt', dest='salt', default=None, help='salt to use for hashing (default: random 8-byte hex string)') -parser.add_argument( '--sign', dest='sign', default='', type=str.lower, choices=['', 'gpg', 'gpgsm'], help='signature method (default: ""); one of "", "gpg"') -parser.add_argument( '--sign-arg', dest='signarg', default={}, nargs=1, action='keyvalue', help='additional arguments to be passed to the signature call (default: None)') -parser.add_argument('-s', '--subject', dest='subject', default='Security Challenge for {site} -- {campaign}{infix}', help='mail subject (default: "Security Challenge Message -- {campaign}{infix}")') -parser.add_argument('-S', '--smtpserver', dest='smtpserver', default='localhost', help='SMTP server to use (default: "localhost"); port can be specified with "<host>:<port>" notation and takes precedence over implied ports and port specification') -parser.add_argument( '--smtpport', dest='smtpport', default=0, type=int, help='SMTP port to use (default: 25); takes precedence over implied ports') -parser.add_argument( '--smtpuser', dest='smtpuser', default=None, help='SMTP user to login with (default: none); implies TLS (port 465) unless STARTTLS is set as well') -parser.add_argument( '--smtppass', dest='smtppass', default=None, help='SMTP password to login with (default: none); implies TLS (port 465) unless STARTTLS is set as well; will be queried interactively if set to "-"') -parser.add_argument( '--starttls', dest='starttls', default=False, action='store_true', help='login using STARTTLS (default: False); implies port 587') -parser.add_argument('-t', '--template', dest='template', default='{basedir}/{campaign}/Mail.template', help='mail template file (default: "{basedir}/{campaign}/Mail.template")') -parser.add_argument( '--timestamp', dest='timestamp', default='%Y-%m-%dT%H:%M:%SZ', help='timestamp format used for {timestamp} keyword (default: "%%Y-%%m-%%dT%%H:%%M:%%SZ")') -parser.add_argument('-T', '--to', dest='to', default='{firstname} {lastname} <{email}>', help='recipient mail address (default: "{firstname} {lastname} <{email}>")') -parser.add_argument('-u', '--url', dest='url', default='{webserver}/{campaign}{infix}-{hash}', help='URL template to use (default: "{webserver}/{campaign}{infix}-{hash}"') -parser.add_argument('-U', '--createurl', dest='createurl', default='{webserver}/{campaign}{infix}-{hash}/create', help='URL template to use for creation URL (default: "{webserver}/{campaign}{infix}-{hash}/create"') -parser.add_argument('-v', '--verbose', dest='verbose', default=False, action='store_true', help='increase verbosity') -parser.add_argument('-w', '--webserver', dest='webserver', default='https://challenge.example.com', help='web server to use (default: "https://challenge.example.com"; implies dry-run if not set; to suppress web-hook calling, set to empty string ""') -parser.add_argument('infix', default='', nargs='?', help='infix for ID purposes, default empty') +parser.add_argument('-a', '--attach', dest='attach', default=[], nargs=1, action='extend', help='add attachment(s) to mail (default: None)') +parser.add_argument('-b', '--basedir', dest='basedir', default='Mails', help='base directory for all output (default: "Mails")') +parser.add_argument('-B', '--bcc', dest='bcc', default=[], nargs=1, action='extend', help='additional mail recipient(s) to bcc (default: None)') +parser.add_argument('-c', '--campaign', dest='campaign', default='Test', help='campaign name (default: "Test")') +parser.add_argument('-C', '--cc', dest='cc', default=[], nargs=1, action='extend', help='additional mail recipient(s) to cc (default: None)') +parser.add_argument('-d', '--dry-run', dest='dryrun', default=False, action='store_true', help='dry run -- do not actually send mails or create targets (default: False)') +parser.add_argument('-f', '--from', dest='sender', default='Nobody <nobody@example.com>', help='sender mail address (default: "Nobody <nobody@example.com>"; implies dry-run if not set)') +parser.add_argument('-F', '--force', dest='force', default=False, action='store_true', help='force insecure login without TLS/SSL (default: False)') +parser.add_argument('-H', '--hashstring', dest='hashstring', default='{salt}{campaign}{infix}-{site}', help='string to be hashed for the URL (default: "{salt}{campaign}{infix}-{site}" where "{salt}" is a random string)') +parser.add_argument('-i', '--input', dest='input', default='{basedir}/{campaign}/Input{infix}.lst', help='input file (default: "{basedir}/{campaign}/Input{infix}.lst")') +parser.add_argument('-I', '--message-id', dest='messageid', default=False, action='store_true', help='create a message ID (default: False)') +parser.add_argument('-o', '--output', dest='output', default='{basedir}/{campaign}/{site}/{timestamp}{infix}.eml', help='output file name template (default: "{basedir}/{campaign}/{site}/{timestamp}{infix}.eml")') +parser.add_argument('-R', '--reply-to', dest='replyto', default=None, help='reply-to mail address (default: None)') +parser.add_argument( '--salt', dest='salt', default=None, help='salt to use for hashing (default: random 8-byte hex string)') +parser.add_argument( '--sign', dest='sign', default='', type=str.lower, choices=['', 'gpg', 'gpgsm'], help='signature method (default: ""); one of "", "gpg"') +parser.add_argument( '--sign-arg', dest='signarg', default={}, nargs=1, action='keyvalue', help='additional arguments to be passed to the signature call (default: None)') +parser.add_argument( '--sign-init-arg', dest='signinitarg', default={}, nargs=1, action='keyvalue', help='additional arguments to be passed to the signature-mechanism init call (default: None)') +parser.add_argument('-s', '--subject', dest='subject', default='Security Challenge for {site} -- {campaign}{infix}', help='mail subject (default: "Security Challenge Message -- {campaign}{infix}")') +parser.add_argument('-S', '--smtpserver', dest='smtpserver', default='localhost', help='SMTP server to use (default: "localhost"); port can be specified with "<host>:<port>" notation and takes precedence over implied ports and port specification') +parser.add_argument( '--smtpport', dest='smtpport', default=0, type=int, help='SMTP port to use (default: 25); takes precedence over implied ports') +parser.add_argument( '--smtpuser', dest='smtpuser', default=None, help='SMTP user to login with (default: none); implies TLS (port 465) unless STARTTLS is set as well') +parser.add_argument( '--smtppass', dest='smtppass', default=None, help='SMTP password to login with (default: none); implies TLS (port 465) unless STARTTLS is set as well; will be queried interactively if set to "-"') +parser.add_argument( '--starttls', dest='starttls', default=False, action='store_true', help='login using STARTTLS (default: False); implies port 587') +parser.add_argument('-t', '--template', dest='template', default='{basedir}/{campaign}/Mail.template', help='mail template file (default: "{basedir}/{campaign}/Mail.template")') +parser.add_argument( '--timestamp', dest='timestamp', default='%Y-%m-%dT%H:%M:%SZ', help='timestamp format used for {timestamp} keyword (default: "%%Y-%%m-%%dT%%H:%%M:%%SZ")') +parser.add_argument('-T', '--to', dest='to', default='{firstname} {lastname} <{email}>', help='recipient mail address (default: "{firstname} {lastname} <{email}>")') +parser.add_argument('-u', '--url', dest='url', default='{webserver}/{campaign}{infix}-{hash}', help='URL template to use (default: "{webserver}/{campaign}{infix}-{hash}"') +parser.add_argument('-U', '--createurl', dest='createurl', default='{webserver}/{campaign}{infix}-{hash}/create', help='URL template to use for creation URL (default: "{webserver}/{campaign}{infix}-{hash}/create"') +parser.add_argument('-v', '--verbose', dest='verbose', default=False, action='store_true', help='increase verbosity') +parser.add_argument('-w', '--webserver', dest='webserver', default='https://challenge.example.com', help='web server to use (default: "https://challenge.example.com"; implies dry-run if not set; to suppress web-hook calling, set to empty string ""') +parser.add_argument('infix', default='', nargs='?', help='infix for ID purposes, default empty') args = parser.parse_args() class SafeDict(dict): @@ -221,9 +222,9 @@ def toHex(serial): def signMailGPG(message): # Set up GPG context if args.sign == 'gpg': - gpg = gnupg.GPG() + gpg = gnupg.GPG(**args.signinitarg) else: - gpg = gnupg.GPG(gpgbinary='gpgsm') + gpg = gnupg.GPG(gpgbinary='gpgsm', **args.signinitarg) # Sign mail try: -- GitLab