{"thread":{"id":"65025","subject":"Re: [RFC PATCH] Introduce filesystem type tracking","startedAt":"2026-02-20T05:44:01Z","lastAt":"2026-02-20T07:53:13Z","messageCount":2,"participants":["David Timber"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"536459","messageId":"a676fa73-bb73-485b-9ace-36a841be2b15@dev.snart.me","threadId":"65025","inReplyTo":"20260219-kavaliersdelikt-ansatz-9bdd1aa77326@brauner","subject":"Re: [RFC PATCH] Introduce filesystem type tracking","fromName":"David Timber","fromEmail":"dxdt@dev.snart.me","sentAt":"2026-02-20T05:43:58Z","receivedAt":"2026-02-20T05:44:01Z","isPatch":true,"sender":{"key":"dxdt@dev.snart.me","avatar":"https://avatars.githubusercontent.com/u/10917528?v=4"},"body":"> All these mails have a broken header and set In-Reply-To: to <>:\n>\n>   In-Reply-To: <>\n>\n> So all of these messages share a single bogus parent with the empty\n> message ID <> and then Neomutt groups them together which makes it look\n> like a really old thread got new replies...\nSorry for off-topic\n\nI run my own Postfix+Dovecot stack and for an added layer of security, I\nenabled client cert verification for all MUA ports(submission and imap)\nso that bots don't even have a chance at establishing a TLS session.\n\nThe downside of this would be lack of client support. I'd love to use\nbut unfortunately git-send-email cannot be configured to present a\nclient cert to the server. I just learned that git-send-email is only a\nsingle 2k-line perl script, so I could submit the patch if anyone's\ninterested. Just a few lines for the script to pass the PEM paths to the\nopenssl lib.\n"},{"id":"536464","messageId":"20260220075304.536514-1-dxdt@dev.snart.me","threadId":"65025","inReplyTo":"20260219-kavaliersdelikt-ansatz-9bdd1aa77326@brauner","subject":"[PATCH] send-mail: add client certificate options","fromName":"David Timber","fromEmail":"dxdt@dev.snart.me","sentAt":"2026-02-20T07:52:53Z","receivedAt":"2026-02-20T07:53:13Z","isPatch":true,"sender":{"key":"dxdt@dev.snart.me","avatar":"https://avatars.githubusercontent.com/u/10917528?v=4"},"body":"For SMTP servers that do \"mutual certificate verification\", the mail\nclient is required to present its own TLS certificate as well. This\npatch adds --smtp-ssl-client-cert and --smtp-ssl-client-key for such\nservers.\n\nSigned-off-by: David Timber <dxdt@dev.snart.me>\n---\n Documentation/git-send-email.adoc | 13 +++++++++\n git-send-email.perl               | 48 ++++++++++++++++++++++++-------\n 2 files changed, 50 insertions(+), 11 deletions(-)\n\ndiff --git a/Documentation/git-send-email.adoc b/Documentation/git-send-email.adoc\nindex ebe8853e9f..9c782a4d9a 100644\n--- a/Documentation/git-send-email.adoc\n+++ b/Documentation/git-send-email.adoc\n@@ -290,6 +290,19 @@ must be used for each option.\n \tvariable, if set, or the backing SSL library's compiled-in default\n \totherwise (which should be the best choice on most platforms).\n \n+--smtp-ssl-client-cert <path>::\n+\tPath to a client certificate file to present to the SMTP server. This option\n+\tcan be used when the server verifies the certificate from the client. The\n+\tformat could be in either PKCS12 or PEM. In the latter case, the private key\n+\tcan be specified using `--smtp-ssl-client-key` option. More more\n+\tdetail, see\n+\thttps://metacpan.org/pod/IO::Socket::SSL#SSL_cert_file-|-SSL_cert-|-SSL_key_file-|-SSL_key\n+\n+--smtp-ssl-client-key <path>::\n+\tOptional path to the private key file. If this is not given and a PKCS12\n+\tcertificate file is used, the private key from the PKCS12 certificate will\n+\tbe used(see `--smtp-ssl-client-cert`).\n+\n --smtp-user=<user>::\n \tUsername for SMTP-AUTH. Default is the value of `sendemail.smtpUser`;\n \tif a username is not specified (with `--smtp-user` or `sendemail.smtpUser`),\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex cd4b316ddc..49601a91d8 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -66,6 +66,9 @@ sub usage {\n     --smtp-ssl-cert-path    <str>  * Path to ca-certificates (either directory or file).\n                                      Pass an empty string to disable certificate\n                                      verification.\n+    --smtp-ssl-client-cert  <str>  * Path to client certificate file to present to SMTP server\n+    --smtp-ssl-client-key   <str>  * Path to the private key file for the client certificate\n+                                     (optional if a PKCS12 client certificate is used)\n     --smtp-domain           <str>  * The domain name sent to HELO/EHLO handshake\n     --smtp-auth             <str>  * Space-separated list of allowed AUTH mechanisms, or\n                                      \"none\" to disable authentication.\n@@ -279,6 +282,7 @@ sub do_edit {\n my ($to_cmd, $cc_cmd, $header_cmd);\n my ($smtp_server, $smtp_server_port, @smtp_server_options);\n my ($smtp_authuser, $smtp_encryption, $smtp_ssl_cert_path);\n+my ($smtp_ssl_client_cert, $smtp_ssl_client_key);\n my ($batch_size, $relogin_delay);\n my ($identity, $aliasfiletype, @alias_files, $smtp_domain, $smtp_auth);\n my ($imap_sent_folder);\n@@ -350,6 +354,8 @@ sub do_edit {\n my %config_path_settings = (\n     \"aliasesfile\" => \\@alias_files,\n     \"smtpsslcertpath\" => \\$smtp_ssl_cert_path,\n+    \"smtpsslclientcert\" => \\$smtp_ssl_client_cert,\n+    \"smtpsslclientkey\" => \\$smtp_ssl_client_key,\n     \"mailmap.file\" => \\$mailmap_file,\n     \"mailmap.blob\" => \\$mailmap_blob,\n );\n@@ -531,6 +537,8 @@ sub config_regexp {\n \t\t    \"smtp-ssl\" => sub { $smtp_encryption = 'ssl' },\n \t\t    \"smtp-encryption=s\" => \\$smtp_encryption,\n \t\t    \"smtp-ssl-cert-path=s\" => \\$smtp_ssl_cert_path,\n+\t\t    \"smtp-ssl-client-cert=s\" => \\$smtp_ssl_client_cert,\n+\t\t    \"smtp-ssl-client-key=s\" => \\$smtp_ssl_client_key,\n \t\t    \"smtp-debug:i\" => \\$debug_net_smtp,\n \t\t    \"smtp-domain:s\" => \\$smtp_domain,\n \t\t    \"smtp-auth=s\" => \\$smtp_auth,\n@@ -1520,6 +1528,8 @@ sub handle_smtp_error {\n }\n \n sub ssl_verify_params {\n+\tmy %ret = ();\n+\n \teval {\n \t\trequire IO::Socket::SSL;\n \t\tIO::Socket::SSL->import(qw/SSL_VERIFY_PEER SSL_VERIFY_NONE/);\n@@ -1531,20 +1541,36 @@ sub ssl_verify_params {\n \n \tif (!defined $smtp_ssl_cert_path) {\n \t\t# use the OpenSSL defaults\n-\t\treturn (SSL_verify_mode => SSL_VERIFY_PEER());\n+\t\t$ret{SSL_verify_mode} = SSL_VERIFY_PEER();\n+\t}\n+\telse {\n+\t\tif ($smtp_ssl_cert_path eq \"\") {\n+\t\t\t$ret{SSL_verify_mode} = SSL_VERIFY_NONE();\n+\t\t} elsif (-d $smtp_ssl_cert_path) {\n+\t\t\t$ret{SSL_verify_mode} = SSL_VERIFY_PEER();\n+\t\t\t$ret{SSL_ca_path} = $smtp_ssl_cert_path;\n+\t\t} elsif (-f $smtp_ssl_cert_path) {\n+\t\t\t$ret{SSL_verify_mode} = SSL_VERIFY_PEER();\n+\t\t\t$ret{SSL_ca_file} = $smtp_ssl_cert_path;\n+\t\t} else {\n+\t\t\tdie sprintf(__(\"CA path \\\"%s\\\" does not exist\"), $smtp_ssl_cert_path);\n+\t\t}\n \t}\n \n-\tif ($smtp_ssl_cert_path eq \"\") {\n-\t\treturn (SSL_verify_mode => SSL_VERIFY_NONE());\n-\t} elsif (-d $smtp_ssl_cert_path) {\n-\t\treturn (SSL_verify_mode => SSL_VERIFY_PEER(),\n-\t\t\tSSL_ca_path => $smtp_ssl_cert_path);\n-\t} elsif (-f $smtp_ssl_cert_path) {\n-\t\treturn (SSL_verify_mode => SSL_VERIFY_PEER(),\n-\t\t\tSSL_ca_file => $smtp_ssl_cert_path);\n-\t} else {\n-\t\tdie sprintf(__(\"CA path \\\"%s\\\" does not exist\"), $smtp_ssl_cert_path);\n+\tif (defined $smtp_ssl_client_cert) {\n+\t\t# The cert could be in PKCS12 format, which can store both cert and key\n+\t\t$ret{SSL_cert_file} = $smtp_ssl_client_cert;\n+\t\t$ret{SSL_use_cert} = 1;\n \t}\n+\tif (defined $smtp_ssl_client_key) {\n+\t\tif (!defined $smtp_ssl_client_cert) {\n+\t\t\t# doesn't make sense to use a client key only\n+\t\t\tdie sprintf(__(\"Only client key \\\"%s\\\" specified\"), $smtp_ssl_client_key);\n+\t\t}\n+\t\t$ret{SSL_key_file} = $smtp_ssl_client_key;\n+\t}\n+\n+\treturn %ret;\n }\n \n sub file_name_is_absolute {\n-- \n2.53.0\n\n"}]}