{"thread":{"id":"63878","subject":"[PATCH v2] send-email: add --get-smtp-server option to fetch SMTP settings","startedAt":"2025-07-30T15:12:41Z","lastAt":"2025-08-27T08:54:38Z","messageCount":10,"participants":["Aditya Garg","Julian Swagemakers","brian m. carlson"],"isPatch":true,"patchVersion":2,"patchTotal":null},"messages":[{"id":"523009","messageId":"20250730151227.12389-1-gargaditya08@live.com","threadId":"63878","inReplyTo":null,"subject":"[PATCH v2] send-email: add --get-smtp-server option to fetch SMTP settings","fromName":"Aditya Garg","fromEmail":"gargaditya08@live.com","sentAt":"2025-07-30T15:12:36Z","receivedAt":"2025-07-30T15:12:41Z","isPatch":true,"sender":{"key":"gargaditya08@live.com","avatar":"https://avatars.githubusercontent.com/u/85610623?v=4"},"body":"Autoconfiguring SMTP server settings is a common feature present in many\nemail clients. In order to get the correct SMTP server settings easily,\nthis commit adds a `--get-smtp-server` option to `git send-email`. This\noption attempts to fetch the SMTP server settings for a given email address\nvia the following steps:\n\n1. It first tries to fetch the settings from Mozilla's ISPDB at\n   `https://autoconfig.thunderbird.net/v1.1/[domain]`.\n\n2. If that fails, it attempts to fetch the autoconfig file from the email\n   provider's autoconfig URL, which is typically in the format\n   `https://autoconfig.[domain]/mail/config-v1.1.xml?emailaddress=[email]`.\n\n3. If that also fails, it falls back to checking the MX records of the\n   domain used in the email address to find the SMTP server. It can be\n   useful in case of emails with custom domains. It attempts to guess\n   the correct domain for the email from the MX records, and repeats the\n   first 2 steps with the guessed domain.\n\nThis feature is heavily inpired by the autoconfig feature in Mozilla\nThunderbird. A detailed documentation about how thunderbird fetches the\nautoconfig settings can be found at:\n\nhttps://www.bucksch.org/1/projects/thunderbird/autoconfiguration/\n---\n\nv2: - Improved checks for valid email address.\n\n Documentation/git-send-email.adoc |  55 ++++++++++-\n git-send-email.perl               | 157 +++++++++++++++++++++++++++++-\n 2 files changed, 209 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/git-send-email.adoc b/Documentation/git-send-email.adoc\nindex 5335502d68..d4fb761b4f 100644\n--- a/Documentation/git-send-email.adoc\n+++ b/Documentation/git-send-email.adoc\n@@ -13,6 +13,7 @@ SYNOPSIS\n 'git send-email' [<options>] <format-patch-options>\n 'git send-email' --dump-aliases\n 'git send-email' --translate-aliases\n+'git send-email' --get-smtp-server\n \n \n DESCRIPTION\n@@ -505,6 +506,15 @@ Information\n \taddress to standard output, one per line. See `sendemail.aliasFile`\n \tfor more information about aliases.\n \n+--get-smtp-server::\n+\tAttempt to get the correct SMTP server settings by entering an email\n+\taddress. Once an email address is entered, it will first try to get\n+\tthe correct settings from\n+\thttps://autoconfig.thunderbird.net/v1.1/[Mozilla's ISPDB], followed\n+\tby attempting to check for an autoconfig file hosted by the email\n+\tprovider, finally falling back to the MX records of the domain used\n+\tby the email address.\n+\n CONFIGURATION\n -------------\n \n@@ -512,6 +522,44 @@ include::includes/cmd-config-section-all.adoc[]\n \n include::config/sendemail.adoc[]\n \n+GETTING THE CORRECT SMTP SERVER SETTINGS\n+----------------------------------------\n+\n+You can attempt to get the correct SMTP server settings by using\n+the `--get-smtp-server` command line option with `git send-email`.\n+It will ask you for your email address, then attempt to get the\n+correct SMTP server settings for that email address. An email\n+address may have more than one configuration. In that case, any of\n+them can be used.\n+\n+For example, an output with email `someone@pobox.com` yields:\n+\n+----\n+Configuration 1:\n+  Server: smtp.pobox.com\n+  Port: 465\n+  Encryption: ssl\n+  Username: ssw@pobox.com\n+\n+Configuration 2:\n+  Server: smtp.pobox.com\n+  Port: 587\n+  Encryption: tls\n+  Username: ssw@pobox.com\n+----\n+\n+Here the value of:\n++\n+- `Server` corresponds to `sendmail.smtpServer`.\n+- `Port` corresponds to `sendmail.smtpServerPort`.\n+- `Encryption` corresponds to `sendmail.smtpEncryption`.\n+- `Username` corresponds to `sendmail.smtpUser`.\n++\n+\n+This method should work well for almost all large email providers in the\n+world. If it provides invalid settings or cannot retrieve them, contact\n+your email provider.\n+\n EXAMPLES OF SMTP SERVERS\n ------------------------\n Use Gmail as the SMTP Server\n@@ -624,8 +672,11 @@ https://metacpan.org/pod/Net::SMTP[Net::SMTP].\n \n These additional Perl modules are also required:\n \n-https://metacpan.org/pod/Authen::SASL[Authen::SASL] and\n-https://metacpan.org/pod/Mail::Address[Mail::Address].\n+https://metacpan.org/pod/Authen::SASL[Authen::SASL],\n+https://metacpan.org/pod/Mail::Address[Mail::Address],\n+https://metacpan.org/pod/Net::DNS[Net::DNS],\n+https://metacpan.org/pod/URI::Escape[URI::Escape] and\n+https://metacpan.org/dist/XML-LibXML[XML::LibXML].\n \n Exploiting the `sendmailCmd` option of `git send-email`\n ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex 437f8ac46a..580e272139 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -32,6 +32,7 @@ sub usage {\n git send-email [<options>] <format-patch options>\n git send-email --dump-aliases\n git send-email --translate-aliases\n+git send-email --get-smtp-server\n \n   Composing:\n     --from                  <str>  * Email From:\n@@ -108,6 +109,7 @@ sub usage {\n                                      input according to the configured email\n                                      alias file(s), outputting the result to\n                                      standard output.\n+    --get-smtp-server              * Print the SMTP server settings for a given email.\n \n EOT\n \texit(1);\n@@ -222,6 +224,7 @@ sub format_2822_time {\n my $force = 0;\n my $dump_aliases = 0;\n my $translate_aliases = 0;\n+my $get_smtp_server = 0;\n \n # Variables to prevent short format-patch options from being captured\n # as abbreviated send-email options\n@@ -501,6 +504,15 @@ sub config_regexp {\n     if !$help and ($dump_aliases or $translate_aliases) and @ARGV;\n die __(\"--dump-aliases and --translate-aliases are mutually exclusive\\n\")\n     if !$help and $dump_aliases and $translate_aliases;\n+\n+my %get_smtp_server_options = (\n+\t\"get-smtp-server\" => \\$get_smtp_server,\n+);\n+$rc = GetOptions(%get_smtp_server_options);\n+usage() unless $rc;\n+die __(\"--get-smtp-server incompatible with other options\\n\")\n+\tif !$help and $get_smtp_server and @ARGV;\n+\n my %options = (\n \t\t    \"sender|from=s\" => \\$sender,\n \t\t    \"in-reply-to=s\" => \\$initial_in_reply_to,\n@@ -565,7 +577,7 @@ sub config_regexp {\n my @initial_bcc = @getopt_bcc ? @getopt_bcc : ($no_bcc ? () : @config_bcc);\n \n usage() if $help;\n-my %all_options = (%options, %dump_aliases_options, %identity_options);\n+my %all_options = (%options, %dump_aliases_options, %identity_options, %get_smtp_server_options);\n completion_helper(\\%all_options) if $git_completion_helper;\n unless ($rc) {\n     usage();\n@@ -757,6 +769,149 @@ sub parse_sendmail_aliases {\n \texit(0);\n }\n \n+sub fetch_config_mozilla_ispdb {\n+\tmy ($domain) = @_;\n+\tmy $ispdb_url = \"https://autoconfig.thunderbird.net/v1.1/$domain\";\n+\tmy $xml = fetch_config($ispdb_url);\n+\treturn $xml if $xml;\n+}\n+\n+sub fetch_config_domain_autoconfig {\n+\tmy ($domain, $email_enc) = @_;\n+\tmy $autoconfig_url = \"https://autoconfig.$domain/mail/config-v1.1.xml?emailaddress=$email_enc\";\n+\tmy $xml = fetch_config($autoconfig_url);\n+\treturn $xml if $xml;\n+}\n+\n+sub fetch_config {\n+\trequire HTTP::Tiny;\n+\tmy ($url) = @_;\n+\tmy $http = HTTP::Tiny->new(timeout => 10);\n+\tmy $res = $http->get($url);\n+\n+\treturn unless $res->{success};\n+\treturn $res->{content};\n+}\n+\n+sub extract_base_domain {\n+\trequire IO::Socket::SSL::PublicSuffix;\n+\tmy ($host) = @_;\n+\tmy $ps = IO::Socket::SSL::PublicSuffix->default;\n+\n+\tmy $public_suffix = $ps->public_suffix($host);\n+\treturn $host unless defined $public_suffix;\n+\n+\tmy @host_parts = split(/\\./, lc($host));\n+\tmy @suffix_parts = split(/\\./, $public_suffix);\n+\n+\t# Find where the suffix starts in the host\n+\tfor (my $i = 0; $i <= $#host_parts - $#suffix_parts; $i++) {\n+\t\tif (join('.', @host_parts[$i .. $#host_parts]) eq $public_suffix) {\n+\t\t\t# Precursor + suffix = base domain\n+\t\t\treturn join('.', $host_parts[$i - 1], @host_parts[$i .. $#host_parts]) if $i > 0;\n+\t\t\treturn $public_suffix;\n+\t\t}\n+\t}\n+\n+\treturn $host;\n+}\n+\n+sub get_mx_base_domain {\n+\trequire Net::DNS;\n+\tmy ($domain) = @_;\n+\tmy $resolver = Net::DNS::Resolver->new;\n+\tmy $query = $resolver->query($domain, \"MX\");\n+\n+\tif ($query) {\n+\t\tmy @mx_hosts = sort { $a->preference <=> $b->preference } grep { $_->type eq \"MX\" } $query->answer;\n+\t\tif (@mx_hosts) {\n+\t\t\tmy $mx_host = $mx_hosts[0]->exchange;\n+\t\t\t$mx_host =~ s/\\.$//;  # Remove trailing dot\n+\t\t\treturn extract_base_domain($mx_host);\n+\t\t}\n+\t}\n+\treturn;\n+}\n+\n+sub parse_config {\n+\trequire XML::LibXML;\n+\tmy ($xml, $email) = @_;\n+\tmy $parser = XML::LibXML->new;\n+\tmy $doc = eval { $parser->load_xml(string => $xml) };\n+\tdie \"Failed to parse XML\\n\" unless $doc;\n+\tmy $config_num = 0;\n+\tmy $smtp_encryption_config;\n+\tmy $smtp_user_config;\n+\n+\tforeach my $outgoing ($doc->findnodes('//outgoingServer')) {\n+\t\t$config_num++;\n+\t\tif ($outgoing->findvalue('./socketType') eq 'SSL') {\n+\t\t\t$smtp_encryption_config = 'ssl';\n+\t\t} elsif ($outgoing->findvalue('./socketType') eq 'STARTTLS') {\n+\t\t\t$smtp_encryption_config = 'tls';\n+\t\t} else {\n+\t\t\t$smtp_encryption_config = 'plain';\n+\t\t}\n+\n+\t\tif ($outgoing->findvalue('./username') eq '%EMAILADDRESS%') {\n+\t\t\t$smtp_user_config = $email;\n+\t\t} elsif ($outgoing->findvalue('./username') eq '%EMAILLOCALPART%') {\n+\t\t\t$smtp_user_config = (split /@/, $email)[0];\n+\t\t} elsif ($outgoing->findvalue('./username') eq '%EMAILDOMAIN%') {\n+\t\t\t$smtp_user_config = (split /@/, $email)[1];\n+\t\t} else {\n+\t\t\t$smtp_user_config = $outgoing->findvalue('./username');\n+\t\t}\n+\n+\t\tprint \"\\nConfiguration $config_num:\\n\";\n+\t\tprint \"  Server: \", $outgoing->findvalue('./hostname'), \"\\n\";\n+\t\tprint \"  Port: \", $outgoing->findvalue('./port'), \"\\n\";\n+\t\tprint \"  Encryption: \", $smtp_encryption_config, \"\\n\";\n+\t\tprint \"  Username: \", $smtp_user_config, \"\\n\";\n+\t}\n+}\n+\n+if ($get_smtp_server) {\n+\trequire URI::Escape;\n+\tprint \"Enter your email address: \";\n+\tchomp(my $email = <STDIN>);\n+\t$email = extract_valid_address($email);\n+\tif (!$email) {\n+\t\tdie __(\"Invalid email format.\\n\");\n+\t}\n+\t$email =~ /@(.+)$/;\n+\tmy $domain = $1;\n+\tmy $email_enc = URI::Escape::uri_escape($email);\n+\n+\t# 1. Try Mozilla ISPDB\n+\tmy $xml = fetch_config_mozilla_ispdb($domain);\n+\n+\t# 2. Try domain autoconfig if ISPDB fails\n+\tif (!$xml) {\n+\t\t$xml = fetch_config_domain_autoconfig($domain, $email_enc);\n+\t}\n+\n+\t# 3. Try MX record lookup\n+\tif (!$xml) {\n+\t\tmy $base_domain = get_mx_base_domain($domain);\n+\t\tif ($base_domain && $base_domain ne $domain) {\n+\t\t\t$xml = fetch_config_mozilla_ispdb($base_domain);\n+\n+\t\t\tif (!$xml) {\n+\t\t\t\t$xml = fetch_config_domain_autoconfig($base_domain, $email_enc);\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\tif ($xml) {\n+\t\tprint \"\\nFound SMTP server settings for $email:\\n\";\n+\t\tparse_config($xml, $email);\n+\t} else {\n+\t\tprint \"\\nUnable to find SMTP server settings for $email\\n\";\n+\t}\n+\texit(0);\n+}\n+\n # is_format_patch_arg($f) returns 0 if $f names a patch, or 1 if\n # $f is a revision list specification to be passed to format-patch.\n sub is_format_patch_arg {\n\nRange-diff against v1:\n1:  5e32982219 ! 1:  0db913ba39 send-email: add --get-smtp-server option to fetch SMTP settings\n    @@ git-send-email.perl: sub parse_sendmail_aliases {\n     +\trequire URI::Escape;\n     +\tprint \"Enter your email address: \";\n     +\tchomp(my $email = <STDIN>);\n    -+\t$email =~ /@(.+)$/ or die \"Invalid email format.\\n\";\n    ++\t$email = extract_valid_address($email);\n    ++\tif (!$email) {\n    ++\t\tdie __(\"Invalid email format.\\n\");\n    ++\t}\n    ++\t$email =~ /@(.+)$/;\n     +\tmy $domain = $1;\n     +\tmy $email_enc = URI::Escape::uri_escape($email);\n     +\n-- \n2.50.1.320.g2ad311502d\n\n"},{"id":"523336","messageId":"DBSU01804YQB.2JA3KHG5FDV55@swagemakers.org","threadId":"63878","inReplyTo":"20250730151227.12389-1-gargaditya08@live.com","subject":"Re: [PATCH v2] send-email: add --get-smtp-server option to fetch SMTP settings","fromName":"Julian Swagemakers","fromEmail":"julian@swagemakers.org","sentAt":"2025-08-03T13:36:47Z","receivedAt":"2025-08-03T13:36:49Z","isPatch":true,"sender":{"key":"julian@swagemakers.org","avatar":"https://gravatar.com/avatar/61b8010bc77390da6713f1622e3276430152d11cd512c11c1c241716991a358b?d=mp&s=160"},"body":"Hi Aditya, really cool idea, here are some random thoughts:\n\nOn Wed Jul 30, 2025 at 5:12 PM CEST, Aditya Garg wrote:\n> Autoconfiguring SMTP server settings is a common feature present in many\n> email clients. In order to get the correct SMTP server settings easily,\n> this commit adds a `--get-smtp-server` option to `git send-email`. This\n> option attempts to fetch the SMTP server settings for a given email address\n> via the following steps:\n>\n> 1. It first tries to fetch the settings from Mozilla's ISPDB at\n>    `https://autoconfig.thunderbird.net/v1.1/[domain]`.\n\nWe should first check autoconfig and then move to the 3rd party\ndatabase, this is how thunderbird[0] and aerc[1] do it.\n\n>\n> 2. If that fails, it attempts to fetch the autoconfig file from the email\n>    provider's autoconfig URL, which is typically in the format\n>    `https://autoconfig.[domain]/mail/config-v1.1.xml?emailaddress=[email]`.\n\nThe documentation mentions using `DOMAIN/.well-known/autoconfig/mail/`\nas an alternative to the autoconfig subdomain, what do you think about\nsupporting that?\n\n>\n> 3. If that also fails, it falls back to checking the MX records of the\n>    domain used in the email address to find the SMTP server. It can be\n>    useful in case of emails with custom domains. It attempts to guess\n>    the correct domain for the email from the MX records, and repeats the\n>    first 2 steps with the guessed domain.\n>\n> This feature is heavily inpired by the autoconfig feature in Mozilla\n\ns/inpired/inspired\n\n\n> +sub parse_config {\n> +\trequire XML::LibXML;\n> +\tmy ($xml, $email) = @_;\n> +\tmy $parser = XML::LibXML->new;\n> +\tmy $doc = eval { $parser->load_xml(string => $xml) };\n> +\tdie \"Failed to parse XML\\n\" unless $doc;\n> +\tmy $config_num = 0;\n> +\tmy $smtp_encryption_config;\n> +\tmy $smtp_user_config;\n> +\n> +\tforeach my $outgoing ($doc->findnodes('//outgoingServer')) {\n> +\t\t$config_num++;\n> +\t\tif ($outgoing->findvalue('./socketType') eq 'SSL') {\n> +\t\t\t$smtp_encryption_config = 'ssl';\n> +\t\t} elsif ($outgoing->findvalue('./socketType') eq 'STARTTLS') {\n> +\t\t\t$smtp_encryption_config = 'tls';\n> +\t\t} else {\n> +\t\t\t$smtp_encryption_config = 'plain';\n\n'plain' is unencrypted, I think this should be accompanied by a big\nwarning.\n\n> +\t\t}\n> +\n> +\t\tif ($outgoing->findvalue('./username') eq '%EMAILADDRESS%') {\n> +\t\t\t$smtp_user_config = $email;\n> +\t\t} elsif ($outgoing->findvalue('./username') eq '%EMAILLOCALPART%') {\n> +\t\t\t$smtp_user_config = (split /@/, $email)[0];\n> +\t\t} elsif ($outgoing->findvalue('./username') eq '%EMAILDOMAIN%') {\n> +\t\t\t$smtp_user_config = (split /@/, $email)[1];\n> +\t\t} else {\n> +\t\t\t$smtp_user_config = $outgoing->findvalue('./username');\n> +\t\t}\n> +\n> +\t\tprint \"\\nConfiguration $config_num:\\n\";\n> +\t\tprint \"  Server: \", $outgoing->findvalue('./hostname'), \"\\n\";\n> +\t\tprint \"  Port: \", $outgoing->findvalue('./port'), \"\\n\";\n> +\t\tprint \"  Encryption: \", $smtp_encryption_config, \"\\n\";\n> +\t\tprint \"  Username: \", $smtp_user_config, \"\\n\";\n\nThe new option only gives you the needed SMTP configuration, as a\nuser you still need to apply them and to do that you will need to\nlook up how. We could help the user here and give them copy and\npaste commands similar to when trying to commit without having an\nidentity set.\n\nThe XML file also contains authentication details, what do you think\nabout processing those? That would also allow adding references to the\ndocumentation in case it is OAuth2.\n\n> +\t}\n> +}\n> +\n> +if ($get_smtp_server) {\n> +\trequire URI::Escape;\n> +\tprint \"Enter your email address: \";\n> +\tchomp(my $email = <STDIN>);\n\nSomeone sending out emails will most likely already have set up\n`user.email` in their gitconfig. We could just use that instead of\nprompting for user input, or at least suggest it as a default.\n\nIf you don't have an SMTP server configured then `git send-email`\nwill default to `localhost` and fail if you are not running a\nlocal SMTP server with: `Unable to initialize SMTP properly.\nCheck config and use --smtp-debug.`. I would suggest altering the\nmessage pointing the user to the new option.\n\nRegards Julian\n\n[0]: https://hg-edge.mozilla.org/comm-central/file/tip/mail/components/accountcreation/content/accountSetup.js#l57\n[1]: https://git.sr.ht/~rjarry/aerc/tree/d31995f1e20b1eff28f9cbe95c14efc90d991e9a/item/lib/autoconfig/get.go#L29\n"},{"id":"523337","messageId":"1ABB6EBC-7CA0-4108-94AC-F38E96BC7673@live.com","threadId":"63878","inReplyTo":"DBSU01804YQB.2JA3KHG5FDV55@swagemakers.org","subject":"Re: [PATCH v2] send-email: add --get-smtp-server option to fetch SMTP settings","fromName":"Aditya Garg","fromEmail":"gargaditya08@live.com","sentAt":"2025-08-03T13:59:14Z","receivedAt":"2025-08-03T13:59:19Z","isPatch":true,"sender":{"key":"gargaditya08@live.com","avatar":"https://avatars.githubusercontent.com/u/85610623?v=4"},"body":"\n\nOn 03/08/25 7:06 pm, Julian Swagemakers wrote:\n> Hi Aditya, really cool idea, here are some random thoughts:\n> \n> On Wed Jul 30, 2025 at 5:12 PM CEST, Aditya Garg wrote:\n>> Autoconfiguring SMTP server settings is a common feature present in many\n>> email clients. In order to get the correct SMTP server settings easily,\n>> this commit adds a `--get-smtp-server` option to `git send-email`. This\n>> option attempts to fetch the SMTP server settings for a given email address\n>> via the following steps:\n>> \n>> 1. It first tries to fetch the settings from Mozilla's ISPDB at\n>>   `https://autoconfig.thunderbird.net/v1.1/[domain]`.\n> \n> We should first check autoconfig and then move to the 3rd party\n> database, this is how thunderbird[0] and aerc[1] do it.\n\nAh, I thought Thunderbird did the opposite. Thanks for noticing that.\nIt does make more sense to use autoconfig first.\n\n> \n>> \n>> 2. If that fails, it attempts to fetch the autoconfig file from the email\n>>   provider's autoconfig URL, which is typically in the format\n>>   `https://autoconfig.[domain]/mail/config-v1.1.xml?emailaddress=[email]`.\n> \n> The documentation mentions using `DOMAIN/.well-known/autoconfig/mail/`\n> as an alternative to the autoconfig subdomain, what do you think about\n> supporting that?\n\nCan be supported, but I unfortunately didn't find any email provider having\nthat sort of server to test. Do you have any in mind? Nevertheless, and untested\nimplementation can be done.\n\n> \n>> \n>> 3. If that also fails, it falls back to checking the MX records of the\n>>   domain used in the email address to find the SMTP server. It can be\n>>   useful in case of emails with custom domains. It attempts to guess\n>>   the correct domain for the email from the MX records, and repeats the\n>>   first 2 steps with the guessed domain.\n>> \n>> This feature is heavily inpired by the autoconfig feature in Mozilla\n> \n> s/inpired/inspired\n\nThanks for noticing that :)\n\n> \n> \n>> +sub parse_config {\n>> +\trequire XML::LibXML;\n>> +\tmy ($xml, $email) = @_;\n>> +\tmy $parser = XML::LibXML->new;\n>> +\tmy $doc = eval { $parser->load_xml(string => $xml) };\n>> +\tdie \"Failed to parse XML\\n\" unless $doc;\n>> +\tmy $config_num = 0;\n>> +\tmy $smtp_encryption_config;\n>> +\tmy $smtp_user_config;\n>> +\n>> +\tforeach my $outgoing ($doc->findnodes('//outgoingServer')) {\n>> +\t\t$config_num++;\n>> +\t\tif ($outgoing->findvalue('./socketType') eq 'SSL') {\n>> +\t\t\t$smtp_encryption_config = 'ssl';\n>> +\t\t} elsif ($outgoing->findvalue('./socketType') eq 'STARTTLS') {\n>> +\t\t\t$smtp_encryption_config = 'tls';\n>> +\t\t} else {\n>> +\t\t\t$smtp_encryption_config = 'plain';\n> \n> 'plain' is unencrypted, I think this should be accompanied by a big\n> warning.\n\nAny ideas on how you want that to be displayed?\n\n> \n>> +\t\t}\n>> +\n>> +\t\tif ($outgoing->findvalue('./username') eq '%EMAILADDRESS%') {\n>> +\t\t\t$smtp_user_config = $email;\n>> +\t\t} elsif ($outgoing->findvalue('./username') eq '%EMAILLOCALPART%') {\n>> +\t\t\t$smtp_user_config = (split /@/, $email)[0];\n>> +\t\t} elsif ($outgoing->findvalue('./username') eq '%EMAILDOMAIN%') {\n>> +\t\t\t$smtp_user_config = (split /@/, $email)[1];\n>> +\t\t} else {\n>> +\t\t\t$smtp_user_config = $outgoing->findvalue('./username');\n>> +\t\t}\n>> +\n>> +\t\tprint \"\\nConfiguration $config_num:\\n\";\n>> +\t\tprint \"  Server: \", $outgoing->findvalue('./hostname'), \"\\n\";\n>> +\t\tprint \"  Port: \", $outgoing->findvalue('./port'), \"\\n\";\n>> +\t\tprint \"  Encryption: \", $smtp_encryption_config, \"\\n\";\n>> +\t\tprint \"  Username: \", $smtp_user_config, \"\\n\";\n> \n> The new option only gives you the needed SMTP configuration, as a\n> user you still need to apply them and to do that you will need to\n> look up how. We could help the user here and give them copy and\n> paste commands similar to when trying to commit without having an\n> identity set.\n\nGit allows you to set it as global config or repo specific config.\nI'm not sure how to give a copy/paste command for different needs.\n\n> \n> The XML file also contains authentication details, what do you think\n> about processing those? That would also allow adding references to the\n> documentation in case it is OAuth2.\n\nHonestly, app passwords remain as a preferred way to use git send-email.\nOutlook I guess is just an exception due to obvious reasons. Plus, OAuth2\ndoes not tell if the Auth is XOAUTH2 or OAUTHBEARER. Not sure if its worth\nadding here. I am open to ideas on use cases though, and may try to\nimplement.\n\n> \n>> +\t}\n>> +}\n>> +\n>> +if ($get_smtp_server) {\n>> +\trequire URI::Escape;\n>> +\tprint \"Enter your email address: \";\n>> +\tchomp(my $email = <STDIN>);\n> \n> Someone sending out emails will most likely already have set up\n> `user.email` in their gitconfig. We could just use that instead of\n> prompting for user input, or at least suggest it as a default.\n\nSuggesting as a default is better then not prompting. Although I think\nit won't be easy to read the config since all this exits before the config\nis parsed (I guess?).>\n> If you don't have an SMTP server configured then `git send-email`\n> will default to `localhost` and fail if you are not running a\n> local SMTP server with: `Unable to initialize SMTP properly.\n> Check config and use --smtp-debug.`. I would suggest altering the\n> message pointing the user to the new option.\n\n\"Unable to initialize SMTP properly. Check config and use --smtp-debug. Use --get-smtp-server to get the correct settings for you SMTP server if needed.\"\n\nWhat do you think about that?\n"},{"id":"523434","messageId":"DBTME8R0DCOH.2E8WOTO3STJ4L@swagemakers.org","threadId":"63878","inReplyTo":"1ABB6EBC-7CA0-4108-94AC-F38E96BC7673@live.com","subject":"Re: [PATCH v2] send-email: add --get-smtp-server option to fetch SMTP settings","fromName":"Julian Swagemakers","fromEmail":"julian@swagemakers.org","sentAt":"2025-08-04T11:51:52Z","receivedAt":"2025-08-04T11:51:54Z","isPatch":true,"sender":{"key":"julian@swagemakers.org","avatar":"https://gravatar.com/avatar/61b8010bc77390da6713f1622e3276430152d11cd512c11c1c241716991a358b?d=mp&s=160"},"body":"On Sun Aug 3, 2025 at 3:59 PM CEST, Aditya Garg wrote:\n> On 03/08/25 7:06 pm, Julian Swagemakers wrote:\n>> On Wed Jul 30, 2025 at 5:12 PM CEST, Aditya Garg wrote:\n>>> \n>>> 2. If that fails, it attempts to fetch the autoconfig file from the email\n>>>   provider's autoconfig URL, which is typically in the format\n>>>   `https://autoconfig.[domain]/mail/config-v1.1.xml?emailaddress=[email]`.\n>> \n>> The documentation mentions using `DOMAIN/.well-known/autoconfig/mail/`\n>> as an alternative to the autoconfig subdomain, what do you think about\n>> supporting that?\n>\n> Can be supported, but I unfortunately didn't find any email provider having\n> that sort of server to test. Do you have any in mind? Nevertheless, and untested\n> implementation can be done.\n>\n\nI also don't know any hosts supporting this.\n\n>>> +sub parse_config {\n>>> +\trequire XML::LibXML;\n>>> +\tmy ($xml, $email) = @_;\n>>> +\tmy $parser = XML::LibXML->new;\n>>> +\tmy $doc = eval { $parser->load_xml(string => $xml) };\n>>> +\tdie \"Failed to parse XML\\n\" unless $doc;\n>>> +\tmy $config_num = 0;\n>>> +\tmy $smtp_encryption_config;\n>>> +\tmy $smtp_user_config;\n>>> +\n>>> +\tforeach my $outgoing ($doc->findnodes('//outgoingServer')) {\n>>> +\t\t$config_num++;\n>>> +\t\tif ($outgoing->findvalue('./socketType') eq 'SSL') {\n>>> +\t\t\t$smtp_encryption_config = 'ssl';\n>>> +\t\t} elsif ($outgoing->findvalue('./socketType') eq 'STARTTLS') {\n>>> +\t\t\t$smtp_encryption_config = 'tls';\n>>> +\t\t} else {\n>>> +\t\t\t$smtp_encryption_config = 'plain';\n>> \n>> 'plain' is unencrypted, I think this should be accompanied by a big\n>> warning.\n>\n> Any ideas on how you want that to be displayed?\n\nHow about something like this:\n\n    Found SMTP server settings for example@tiscali.cz:\n\n    Configuration 1:\n      Server: smtp.mail.tiscali.cz\n      Port: 25\n      Encryption: plain\n      Username: example@tiscali.cz\n\n    Warning: Encryption plain is unencrypted!\n\n>>> +\t\t}\n>>> +\n>>> +\t\tif ($outgoing->findvalue('./username') eq '%EMAILADDRESS%') {\n>>> +\t\t\t$smtp_user_config = $email;\n>>> +\t\t} elsif ($outgoing->findvalue('./username') eq '%EMAILLOCALPART%') {\n>>> +\t\t\t$smtp_user_config = (split /@/, $email)[0];\n>>> +\t\t} elsif ($outgoing->findvalue('./username') eq '%EMAILDOMAIN%') {\n>>> +\t\t\t$smtp_user_config = (split /@/, $email)[1];\n>>> +\t\t} else {\n>>> +\t\t\t$smtp_user_config = $outgoing->findvalue('./username');\n>>> +\t\t}\n>>> +\n>>> +\t\tprint \"\\nConfiguration $config_num:\\n\";\n>>> +\t\tprint \"  Server: \", $outgoing->findvalue('./hostname'), \"\\n\";\n>>> +\t\tprint \"  Port: \", $outgoing->findvalue('./port'), \"\\n\";\n>>> +\t\tprint \"  Encryption: \", $smtp_encryption_config, \"\\n\";\n>>> +\t\tprint \"  Username: \", $smtp_user_config, \"\\n\";\n>> \n>> The new option only gives you the needed SMTP configuration, as a\n>> user you still need to apply them and to do that you will need to\n>> look up how. We could help the user here and give them copy and\n>> paste commands similar to when trying to commit without having an\n>> identity set.\n>\n> Git allows you to set it as global config or repo specific config.\n> I'm not sure how to give a copy/paste command for different needs.\n\nHow about something like this:\n\n    Found SMTP server settings for example@pobox.com:\n\n    Configuration 1:\n      Server: smtp.pobox.com\n      Port: 465\n      Encryption: ssl\n      Username: example@pobox.com\n\n    Configuration 2:\n      Server: smtp.pobox.com\n      Port: 587\n      Encryption: tls\n      Username: example@pobox.com\n\n    To apply the settings use:\n\n      git config --global sendmail.smtpServer VALUE\n      git config --global sendmail.smtpServerPort VALUE\n      git config --global sendmail.smtpEncryption VALUE\n      git config --global sendmail.smtpUser VALUE\n\n    Omit --global to set the configuration only in this repository.\n\n>> The XML file also contains authentication details, what do you think\n>> about processing those? That would also allow adding references to the\n>> documentation in case it is OAuth2.\n>\n> Honestly, app passwords remain as a preferred way to use git send-email.\n> Outlook I guess is just an exception due to obvious reasons. Plus, OAuth2\n> does not tell if the Auth is XOAUTH2 or OAUTHBEARER. Not sure if its worth\n> adding here. I am open to ideas on use cases though, and may try to\n> implement.\n>\n\nI was thinking of something as simple as rendering a message if oauth2\nis one of the options. Something like:\n\n    Found SMTP server settings for example@gmail.com:\n\n    Configuration 1:\n      Server: smtp.gmail.com\n      Port: 465\n      Encryption: ssl\n      Username: example@gmail.com\n\n    The SMTP server supports OAuth2 authentication. If you want to use OAuth2,\n    please review the git-send-email man pages for more details.\n\n>>> +\t}\n>>> +}\n>>> +\n>>> +if ($get_smtp_server) {\n>>> +\trequire URI::Escape;\n>>> +\tprint \"Enter your email address: \";\n>>> +\tchomp(my $email = <STDIN>);\n>> \n>> Someone sending out emails will most likely already have set up\n>> `user.email` in their gitconfig. We could just use that instead of\n>> prompting for user input, or at least suggest it as a default.\n>\n> Suggesting as a default is better then not prompting. Although I think\n> it won't be easy to read the config since all this exits before the config\n> is parsed (I guess?).>\n>> If you don't have an SMTP server configured then `git send-email`\n>> will default to `localhost` and fail if you are not running a\n>> local SMTP server with: `Unable to initialize SMTP properly.\n>> Check config and use --smtp-debug.`. I would suggest altering the\n>> message pointing the user to the new option.\n>\n> \"Unable to initialize SMTP properly. Check config and use\n> --smtp-debug. Use --get-smtp-server to get the correct settings for\n> you SMTP server if needed.\"\n>\n> What do you think about that?\n\nLooks good.\n\nRegards Julian\n"},{"id":"523478","messageId":"PN3PR01MB9597F827535A46AB78988642B823A@PN3PR01MB9597.INDPRD01.PROD.OUTLOOK.COM","threadId":"63878","inReplyTo":"DBTME8R0DCOH.2E8WOTO3STJ4L@swagemakers.org","subject":"Re: [PATCH v2] send-email: add --get-smtp-server option to fetch SMTP settings","fromName":"Aditya Garg","fromEmail":"gargaditya08@live.com","sentAt":"2025-08-04T19:45:37Z","receivedAt":"2025-08-04T19:45:46Z","isPatch":true,"sender":{"key":"gargaditya08@live.com","avatar":"https://avatars.githubusercontent.com/u/85610623?v=4"},"body":"\n\nOn 4 August 2025 5:21:52 pm IST, Julian Swagemakers <julian@swagemakers.org> wrote:\n>On Sun Aug 3, 2025 at 3:59 PM CEST, Aditya Garg wrote:\n>> On 03/08/25 7:06 pm, Julian Swagemakers wrote:\n>>> On Wed Jul 30, 2025 at 5:12 PM CEST, Aditya Garg wrote:\n>>>> \n>>>> 2. If that fails, it attempts to fetch the autoconfig file from the email\n>>>>   provider's autoconfig URL, which is typically in the format\n>>>>   `https://autoconfig.[domain]/mail/config-v1.1.xml?emailaddress=[email]`.\n>>> \n>>> The documentation mentions using `DOMAIN/.well-known/autoconfig/mail/`\n>>> as an alternative to the autoconfig subdomain, what do you think about\n>>> supporting that?\n>>\n>> Can be supported, but I unfortunately didn't find any email provider having\n>> that sort of server to test. Do you have any in mind? Nevertheless, and untested\n>> implementation can be done.\n>>\n>\n>I also don't know any hosts supporting this.\n>\n>>>> +sub parse_config {\n>>>> +\trequire XML::LibXML;\n>>>> +\tmy ($xml, $email) = @_;\n>>>> +\tmy $parser = XML::LibXML->new;\n>>>> +\tmy $doc = eval { $parser->load_xml(string => $xml) };\n>>>> +\tdie \"Failed to parse XML\\n\" unless $doc;\n>>>> +\tmy $config_num = 0;\n>>>> +\tmy $smtp_encryption_config;\n>>>> +\tmy $smtp_user_config;\n>>>> +\n>>>> +\tforeach my $outgoing ($doc->findnodes('//outgoingServer')) {\n>>>> +\t\t$config_num++;\n>>>> +\t\tif ($outgoing->findvalue('./socketType') eq 'SSL') {\n>>>> +\t\t\t$smtp_encryption_config = 'ssl';\n>>>> +\t\t} elsif ($outgoing->findvalue('./socketType') eq 'STARTTLS') {\n>>>> +\t\t\t$smtp_encryption_config = 'tls';\n>>>> +\t\t} else {\n>>>> +\t\t\t$smtp_encryption_config = 'plain';\n>>> \n>>> 'plain' is unencrypted, I think this should be accompanied by a big\n>>> warning.\n>>\n>> Any ideas on how you want that to be displayed?\n>\n>How about something like this:\n>\n>    Found SMTP server settings for example@tiscali.cz:\n>\n>    Configuration 1:\n>      Server: smtp.mail.tiscali.cz\n>      Port: 25\n>      Encryption: plain\n>      Username: example@tiscali.cz\n>\n>    Warning: Encryption plain is unencrypted!\n\nLooks good!\n\n>\n>>>> +\t\t}\n>>>> +\n>>>> +\t\tif ($outgoing->findvalue('./username') eq '%EMAILADDRESS%') {\n>>>> +\t\t\t$smtp_user_config = $email;\n>>>> +\t\t} elsif ($outgoing->findvalue('./username') eq '%EMAILLOCALPART%') {\n>>>> +\t\t\t$smtp_user_config = (split /@/, $email)[0];\n>>>> +\t\t} elsif ($outgoing->findvalue('./username') eq '%EMAILDOMAIN%') {\n>>>> +\t\t\t$smtp_user_config = (split /@/, $email)[1];\n>>>> +\t\t} else {\n>>>> +\t\t\t$smtp_user_config = $outgoing->findvalue('./username');\n>>>> +\t\t}\n>>>> +\n>>>> +\t\tprint \"\\nConfiguration $config_num:\\n\";\n>>>> +\t\tprint \"  Server: \", $outgoing->findvalue('./hostname'), \"\\n\";\n>>>> +\t\tprint \"  Port: \", $outgoing->findvalue('./port'), \"\\n\";\n>>>> +\t\tprint \"  Encryption: \", $smtp_encryption_config, \"\\n\";\n>>>> +\t\tprint \"  Username: \", $smtp_user_config, \"\\n\";\n>>> \n>>> The new option only gives you the needed SMTP configuration, as a\n>>> user you still need to apply them and to do that you will need to\n>>> look up how. We could help the user here and give them copy and\n>>> paste commands similar to when trying to commit without having an\n>>> identity set.\n>>\n>> Git allows you to set it as global config or repo specific config.\n>> I'm not sure how to give a copy/paste command for different needs.\n>\n>How about something like this:\n>\n>    Found SMTP server settings for example@pobox.com:\n>\n>    Configuration 1:\n>      Server: smtp.pobox.com\n>      Port: 465\n>      Encryption: ssl\n>      Username: example@pobox.com\n>\n>    Configuration 2:\n>      Server: smtp.pobox.com\n>      Port: 587\n>      Encryption: tls\n>      Username: example@pobox.com\n>\n>    To apply the settings use:\n>\n>      git config --global sendmail.smtpServer VALUE\n>      git config --global sendmail.smtpServerPort VALUE\n>      git config --global sendmail.smtpEncryption VALUE\n>      git config --global sendmail.smtpUser VALUE\n>\n>    Omit --global to set the configuration only in this repository.\n>\n\nI will implement this.\n\n>>> The XML file also contains authentication details, what do you think\n>>> about processing those? That would also allow adding references to the\n>>> documentation in case it is OAuth2.\n>>\n>> Honestly, app passwords remain as a preferred way to use git send-email.\n>> Outlook I guess is just an exception due to obvious reasons. Plus, OAuth2\n>> does not tell if the Auth is XOAUTH2 or OAUTHBEARER. Not sure if its worth\n>> adding here. I am open to ideas on use cases though, and may try to\n>> implement.\n>>\n>\n>I was thinking of something as simple as rendering a message if oauth2\n>is one of the options. Something like:\n>\n>    Found SMTP server settings for example@gmail.com:\n>\n>    Configuration 1:\n>      Server: smtp.gmail.com\n>      Port: 465\n>      Encryption: ssl\n>      Username: example@gmail.com\n>\n>    The SMTP server supports OAuth2 authentication. If you want to use OAuth2,\n>    please review the git-send-email man pages for more details.\n>\n\nI think this will become crowdy if there are more than 1 configurations.\n\n>>>> +\t}\n>>>> +}\n>>>> +\n>>>> +if ($get_smtp_server) {\n>>>> +\trequire URI::Escape;\n>>>> +\tprint \"Enter your email address: \";\n>>>> +\tchomp(my $email = <STDIN>);\n>>> \n>>> Someone sending out emails will most likely already have set up\n>>> `user.email` in their gitconfig. We could just use that instead of\n>>> prompting for user input, or at least suggest it as a default.\n>>\n>> Suggesting as a default is better then not prompting. Although I think\n>> it won't be easy to read the config since all this exits before the config\n>> is parsed (I guess?).>\n>>> If you don't have an SMTP server configured then `git send-email`\n>>> will default to `localhost` and fail if you are not running a\n>>> local SMTP server with: `Unable to initialize SMTP properly.\n>>> Check config and use --smtp-debug.`. I would suggest altering the\n>>> message pointing the user to the new option.\n>>\n>> \"Unable to initialize SMTP properly. Check config and use\n>> --smtp-debug. Use --get-smtp-server to get the correct settings for\n>> you SMTP server if needed.\"\n>>\n>> What do you think about that?\n>\n>Looks good.\n>\n>Regards Julian\n"},{"id":"524713","messageId":"20250822151039.36006-1-gargaditya08@live.com","threadId":"63878","inReplyTo":"20250730151227.12389-1-gargaditya08@live.com","subject":"[PATCH v3] send-email: add --get-smtp-server option to fetch SMTP settings","fromName":"Aditya Garg","fromEmail":"gargaditya08@live.com","sentAt":"2025-08-22T15:10:45Z","receivedAt":"2025-08-22T15:10:50Z","isPatch":true,"sender":{"key":"gargaditya08@live.com","avatar":"https://avatars.githubusercontent.com/u/85610623?v=4"},"body":"Autoconfiguring SMTP server settings is a common feature present in many\nemail clients. In order to get the correct SMTP server settings easily,\nthis commit adds a `--get-smtp-server` option to `git send-email`. This\noption attempts to fetch the SMTP server settings for a given email address\nvia the following steps:\n\n1. It first attempts to fetch the autoconfig file from the email\n   provider's autoconfig URL, which is typically in the format\n   `https://autoconfig.[domain]/mail/config-v1.1.xml?emailaddress=[email]`\n   or `https://[domain]/.well-known/autoconfig/mail/config-v1.1.xml`\n\n2. If that fails, it tries to fetch the settings from Mozilla's ISPDB at\n   `https://autoconfig.thunderbird.net/v1.1/[domain]`.\n\n3. If that also fails, it falls back to checking the MX records of the\n   domain used in the email address to find the SMTP server. It can be\n   useful in case of emails with custom domains. It attempts to guess\n   the correct domain for the email from the MX records, and repeats the\n   first 2 steps with the guessed domain.\n\nThis feature is heavily inspired by the autoconfig feature in Mozilla\nThunderbird. A detailed documentation about how thunderbird fetches the\nautoconfig settings can be found at:\n\nhttps://www.bucksch.org/1/projects/thunderbird/autoconfiguration/\n---\n\nv2: - Improved checks for valid email address.\n\nv3: - Try to get settings from email provider's autoconfig URL first,\n      followed by Mozilla ISPDB, then MX records.\n    - Add support for another variant of autoconfig URL:\n      `https://[domain]/.well-known/autoconfig/mail/config-v1.1.xml`\n    - Added support to list supported auth mechanisms.\n    - Added warning if encryption is plain (unencrypted).\n    - Suggest user to read the docs for OAuth2.\n    - Give instructions on how to apply the settings.\n\n Documentation/git-send-email.adoc |  51 ++++++-\n git-send-email.perl               | 219 +++++++++++++++++++++++++++++-\n 2 files changed, 266 insertions(+), 4 deletions(-)\n\ndiff --git a/Documentation/git-send-email.adoc b/Documentation/git-send-email.adoc\nindex 5335502d68..daddaae36d 100644\n--- a/Documentation/git-send-email.adoc\n+++ b/Documentation/git-send-email.adoc\n@@ -13,6 +13,7 @@ SYNOPSIS\n 'git send-email' [<options>] <format-patch-options>\n 'git send-email' --dump-aliases\n 'git send-email' --translate-aliases\n+'git send-email' --get-smtp-server\n \n \n DESCRIPTION\n@@ -505,6 +506,14 @@ Information\n \taddress to standard output, one per line. See `sendemail.aliasFile`\n \tfor more information about aliases.\n \n+--get-smtp-server::\n+\tAttempt to get the correct SMTP server settings by entering an email\n+\taddress. Once an email address is entered, it will first attempt to check\n+\tfor an autoconfig file hosted by the email provider, followed\n+\tby attempting to get the correct settings from\n+\thttps://autoconfig.thunderbird.net/v1.1/[Mozilla's ISPDB], finally falling\n+\tback to the MX records of the domain used by the email address.\n+\n CONFIGURATION\n -------------\n \n@@ -512,6 +521,41 @@ include::includes/cmd-config-section-all.adoc[]\n \n include::config/sendemail.adoc[]\n \n+GETTING THE CORRECT SMTP SERVER SETTINGS\n+----------------------------------------\n+\n+You can attempt to get the correct SMTP server settings by using\n+the `--get-smtp-server` command line option with `git send-email`.\n+It will ask you for your email address, then attempt to get the\n+correct SMTP server settings for that email address. An email\n+address may have more than one configuration. In that case, any of\n+them can be used.\n+\n+For example, an output with email `someone@gmail.com` yields:\n+\n+----\n+Configuration 1:\n+  Server: smtp.gmail.com\n+  Port: 465\n+  Encryption: ssl\n+  Username: jhk@gmail.com\n+  Authentication: Normal Password\n+  Authentication: OAuth2\n+----\n+\n+Here the value of:\n++\n+- `Server` corresponds to `sendmail.smtpServer`.\n+- `Port` corresponds to `sendmail.smtpServerPort`.\n+- `Encryption` corresponds to `sendmail.smtpEncryption`.\n+- `Username` corresponds to `sendmail.smtpUser`.\n+- `Authentication` indicates supported authentication methods.\n++\n+\n+This method should work well for almost all large email providers in the\n+world. If it provides invalid settings or cannot retrieve them, contact\n+your email provider.\n+\n EXAMPLES OF SMTP SERVERS\n ------------------------\n Use Gmail as the SMTP Server\n@@ -624,8 +668,11 @@ https://metacpan.org/pod/Net::SMTP[Net::SMTP].\n \n These additional Perl modules are also required:\n \n-https://metacpan.org/pod/Authen::SASL[Authen::SASL] and\n-https://metacpan.org/pod/Mail::Address[Mail::Address].\n+https://metacpan.org/pod/Authen::SASL[Authen::SASL],\n+https://metacpan.org/pod/Mail::Address[Mail::Address],\n+https://metacpan.org/pod/Net::DNS[Net::DNS],\n+https://metacpan.org/pod/URI::Escape[URI::Escape] and\n+https://metacpan.org/dist/XML-LibXML[XML::LibXML].\n \n Exploiting the `sendmailCmd` option of `git send-email`\n ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex 437f8ac46a..9f4b6faf08 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -32,6 +32,7 @@ sub usage {\n git send-email [<options>] <format-patch options>\n git send-email --dump-aliases\n git send-email --translate-aliases\n+git send-email --get-smtp-server\n \n   Composing:\n     --from                  <str>  * Email From:\n@@ -108,6 +109,7 @@ sub usage {\n                                      input according to the configured email\n                                      alias file(s), outputting the result to\n                                      standard output.\n+    --get-smtp-server              * Print the SMTP server settings for a given email.\n \n EOT\n \texit(1);\n@@ -222,6 +224,7 @@ sub format_2822_time {\n my $force = 0;\n my $dump_aliases = 0;\n my $translate_aliases = 0;\n+my $get_smtp_server = 0;\n \n # Variables to prevent short format-patch options from being captured\n # as abbreviated send-email options\n@@ -501,6 +504,15 @@ sub config_regexp {\n     if !$help and ($dump_aliases or $translate_aliases) and @ARGV;\n die __(\"--dump-aliases and --translate-aliases are mutually exclusive\\n\")\n     if !$help and $dump_aliases and $translate_aliases;\n+\n+my %get_smtp_server_options = (\n+\t\"get-smtp-server\" => \\$get_smtp_server,\n+);\n+$rc = GetOptions(%get_smtp_server_options);\n+usage() unless $rc;\n+die __(\"--get-smtp-server incompatible with other options\\n\")\n+\tif !$help and $get_smtp_server and @ARGV;\n+\n my %options = (\n \t\t    \"sender|from=s\" => \\$sender,\n \t\t    \"in-reply-to=s\" => \\$initial_in_reply_to,\n@@ -565,7 +577,7 @@ sub config_regexp {\n my @initial_bcc = @getopt_bcc ? @getopt_bcc : ($no_bcc ? () : @config_bcc);\n \n usage() if $help;\n-my %all_options = (%options, %dump_aliases_options, %identity_options);\n+my %all_options = (%options, %dump_aliases_options, %identity_options, %get_smtp_server_options);\n completion_helper(\\%all_options) if $git_completion_helper;\n unless ($rc) {\n     usage();\n@@ -757,6 +769,208 @@ sub parse_sendmail_aliases {\n \texit(0);\n }\n \n+our $doc;\n+\n+sub fetch_config_domain_autoconfig {\n+\trequire XML::LibXML;\n+\tmy ($domain, $email_enc) = @_;\n+\tmy $parser = XML::LibXML->new;\n+\tmy $autoconfig_url = \"https://autoconfig.$domain/mail/config-v1.1.xml?emailaddress=$email_enc\";\n+\tmy $xml = fetch_config($autoconfig_url);\n+\tif ($xml) {\n+\t\t$doc = eval { $parser->load_xml(string => $xml) };\n+\t\treturn $doc if $doc;\n+\t}\n+\tif (!$xml || !$doc) {\n+\t\t$autoconfig_url = \"http://$domain/.well-known/autoconfig/mail/config-v1.1.xml\";\n+\t\t$xml = fetch_config($autoconfig_url);\n+\t\tif ($xml) {\n+\t\t\t$doc = eval { $parser->load_xml(string => $xml) };\n+\t\t\treturn $doc if $doc;\n+\t\t}\n+\t}\n+}\n+\n+sub fetch_config_mozilla_ispdb {\n+\trequire XML::LibXML;\n+\tmy ($domain) = @_;\n+\tmy $parser = XML::LibXML->new;\n+\tmy $ispdb_url = \"https://autoconfig.thunderbird.net/v1.1/$domain\";\n+\tmy $xml = fetch_config($ispdb_url);\n+\tif ($xml) {\n+\t\t$doc = eval { $parser->load_xml(string => $xml) };\n+\t\treturn $doc if $doc;\n+\t}\n+}\n+\n+sub fetch_config {\n+\trequire HTTP::Tiny;\n+\tmy ($url) = @_;\n+\tmy $http = HTTP::Tiny->new(timeout => 10);\n+\tmy $res = $http->get($url);\n+\n+\treturn unless $res->{success};\n+\treturn $res->{content};\n+}\n+\n+sub extract_base_domain {\n+\trequire IO::Socket::SSL::PublicSuffix;\n+\tmy ($host) = @_;\n+\tmy $ps = IO::Socket::SSL::PublicSuffix->default;\n+\n+\tmy $public_suffix = $ps->public_suffix($host);\n+\treturn $host unless defined $public_suffix;\n+\n+\tmy @host_parts = split(/\\./, lc($host));\n+\tmy @suffix_parts = split(/\\./, $public_suffix);\n+\n+\t# Find where the suffix starts in the host\n+\tfor (my $i = 0; $i <= $#host_parts - $#suffix_parts; $i++) {\n+\t\tif (join('.', @host_parts[$i .. $#host_parts]) eq $public_suffix) {\n+\t\t\t# Precursor + suffix = base domain\n+\t\t\treturn join('.', $host_parts[$i - 1], @host_parts[$i .. $#host_parts]) if $i > 0;\n+\t\t\treturn $public_suffix;\n+\t\t}\n+\t}\n+\n+\treturn $host;\n+}\n+\n+sub get_mx_base_domain {\n+\trequire Net::DNS;\n+\tmy ($domain) = @_;\n+\tmy $resolver = Net::DNS::Resolver->new;\n+\tmy $query = $resolver->query($domain, \"MX\");\n+\n+\tif ($query) {\n+\t\tmy @mx_hosts = sort { $a->preference <=> $b->preference } grep { $_->type eq \"MX\" } $query->answer;\n+\t\tif (@mx_hosts) {\n+\t\t\tmy $mx_host = $mx_hosts[0]->exchange;\n+\t\t\t$mx_host =~ s/\\.$//;  # Remove trailing dot\n+\t\t\treturn extract_base_domain($mx_host);\n+\t\t}\n+\t}\n+\treturn;\n+}\n+\n+sub parse_config {\n+\tmy ($doc_parsed, $email) = @_;\n+\tmy $config_num = 0;\n+\tmy $smtp_encryption_config;\n+\tmy $smtp_user_config;\n+\tmy $supports_oauth2 = 0;\n+\n+\tforeach my $outgoing ($doc_parsed->findnodes('//outgoingServer')) {\n+\t\t$config_num++;\n+\t\tif ($outgoing->findvalue('./socketType') eq 'SSL') {\n+\t\t\t$smtp_encryption_config = 'ssl';\n+\t\t} elsif ($outgoing->findvalue('./socketType') eq 'STARTTLS') {\n+\t\t\t$smtp_encryption_config = 'tls';\n+\t\t} else {\n+\t\t\t$smtp_encryption_config = 'plain';\n+\t\t}\n+\n+\t\tif ($outgoing->findvalue('./username') eq '%EMAILADDRESS%') {\n+\t\t\t$smtp_user_config = $email;\n+\t\t} elsif ($outgoing->findvalue('./username') eq '%EMAILLOCALPART%') {\n+\t\t\t$smtp_user_config = (split /@/, $email)[0];\n+\t\t} elsif ($outgoing->findvalue('./username') eq '%EMAILDOMAIN%') {\n+\t\t\t$smtp_user_config = (split /@/, $email)[1];\n+\t\t} else {\n+\t\t\t$smtp_user_config = $outgoing->findvalue('./username');\n+\t\t}\n+\n+\t\tmy $auth_mechanisms = $outgoing->findvalue('./authentication');\n+\n+\t\tprint \"\\nConfiguration $config_num:\\n\";\n+\t\tprint \"  Server: \", $outgoing->findvalue('./hostname'), \"\\n\";\n+\t\tprint \"  Port: \", $outgoing->findvalue('./port'), \"\\n\";\n+\t\tprint \"  Encryption: \", $smtp_encryption_config, \"\\n\";\n+\t\tprint \"  Username: \", $smtp_user_config, \"\\n\";\n+\t\tif ($auth_mechanisms =~ /password-cleartext/i) {\n+\t\t\tprint \"  Authentication: Normal Password\\n\";\n+\t\t}\n+\t\tif ($auth_mechanisms =~ /password-encrypted/i) {\n+\t\t\tprint \"  Authentication: Encrypted Password\\n\";\n+\t\t}\n+\t\tif ($auth_mechanisms =~ /NTLM/i) {\n+\t\t\tprint \"  Authentication: NTLM\\n\";\n+\t\t}\n+\t\tif ($auth_mechanisms =~ /GSSAPI/i) {\n+\t\t\tprint \"  Authentication: Kerberos / GSSAPI\\n\";\n+\t\t}\n+\t\tif ($auth_mechanisms =~ /client-IP-address/i) {\n+\t\t\tprint \"  Authentication: Client IP Address\\n\";\n+\t\t}\n+\t\tif ($auth_mechanisms =~ /TLS-client-cert/i) {\n+\t\t\tprint \"  Authentication: TLS Certificate\\n\";\n+\t\t}\n+\t\tif ($auth_mechanisms =~ /OAuth2/i) {\n+\t\t\tprint \"  Authentication: OAuth2\\n\";\n+\t\t\t$supports_oauth2 = 1;\n+\t\t}\n+\t\tif ($auth_mechanisms =~ /none/i) {\n+\t\t\tprint \"  Authentication: No Authentication\\n\";\n+\t\t}\n+\t\tif ($smtp_encryption_config eq 'plain') {\n+\t\t\tprint \"\\nWarning: Encryption plain is unencrypted!\\n\";\n+\t\t}\n+\t}\n+\tif ($supports_oauth2) {\n+\t\tprint \"\\nThe SMTP server supports OAuth2 authentication. If you want to use OAuth2,\\n\";\n+\t\tprint \"please review the git-send-email man pages for more details.\\n\";\n+\t}\n+\tprint \"\\e[33m\"; # yellow\n+\tprint \"\\nTo apply the settings use:\\n\";\n+\tprint \"  git config --global sendmail.smtpServer VALUE\\n\";\n+\tprint \"  git config --global sendmail.smtpServerPort VALUE\\n\";\n+\tprint \"  git config --global sendmail.smtpEncryption VALUE\\n\";\n+\tprint \"  git config --global sendmail.smtpUser VALUE\\n\";\n+\tprint \"\\nOmit --global to set the configuration only in this repository.\\n\";\n+\tprint \"\\e[0m\"; # reset\n+}\n+\n+if ($get_smtp_server) {\n+\trequire URI::Escape;\n+\tprint \"Enter your email address: \";\n+\tchomp(my $email = <STDIN>);\n+\t$email = extract_valid_address($email);\n+\tif (!$email) {\n+\t\tdie __(\"Invalid email format.\\n\");\n+\t}\n+\t$email =~ /@(.+)$/;\n+\tmy $domain = $1;\n+\tmy $email_enc = URI::Escape::uri_escape($email);\n+\n+\t# 1. Try domain autoconfig if ISPDB fails\n+\t$doc = fetch_config_domain_autoconfig($domain, $email_enc);\n+\n+\t# 2. Try Mozilla ISPDB if domain autoconfig fails\n+\tif (!$doc) {\n+\t\t$doc = fetch_config_mozilla_ispdb($domain);\n+\t}\n+\n+\t# 3. Try MX record lookup\n+\tif (!$doc) {\n+\t\tmy $base_domain = get_mx_base_domain($domain);\n+\t\tif ($base_domain && $base_domain ne $domain) {\n+\t\t\t$doc = fetch_config_domain_autoconfig($base_domain, $email_enc);\n+\n+\t\t\tif (!$doc) {\n+\t\t\t\t$doc = fetch_config_mozilla_ispdb($base_domain);\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\tif ($doc) {\n+\t\tprint \"\\nFound SMTP server settings for $email:\\n\";\n+\t\tparse_config($doc, $email);\n+\t} else {\n+\t\tprint \"\\nUnable to find SMTP server settings for $email\\n\";\n+\t}\n+\texit(0);\n+}\n+\n # is_format_patch_arg($f) returns 0 if $f names a patch, or 1 if\n # $f is a revision list specification to be passed to format-patch.\n sub is_format_patch_arg {\n@@ -1760,7 +1974,8 @@ sub send_message {\n \t\t}\n \n \t\tif (!$smtp) {\n-\t\t\tdie __(\"Unable to initialize SMTP properly. Check config and use --smtp-debug.\"),\n+\t\t\tdie __(\"Unable to initialize SMTP properly. Check config and use --smtp-debug.\\n\"),\n+\t\t\t    __(\"Use --get-smtp-server to get correct settings for your SMTP server if needed.\\n\"),\n \t\t\t    \" VALUES: server=$smtp_server \",\n \t\t\t    \"encryption=$smtp_encryption \",\n \t\t\t    \"hello=$smtp_domain\",\n\nRange-diff against v2:\n1:  0db913ba39 ! 1:  63f9c628ac send-email: add --get-smtp-server option to fetch SMTP settings\n    @@ Commit message\n         option attempts to fetch the SMTP server settings for a given email address\n         via the following steps:\n     \n    -    1. It first tries to fetch the settings from Mozilla's ISPDB at\n    -       `https://autoconfig.thunderbird.net/v1.1/[domain]`.\n    -\n    -    2. If that fails, it attempts to fetch the autoconfig file from the email\n    +    1. It first attempts to fetch the autoconfig file from the email\n            provider's autoconfig URL, which is typically in the format\n    -       `https://autoconfig.[domain]/mail/config-v1.1.xml?emailaddress=[email]`.\n    +       `https://autoconfig.[domain]/mail/config-v1.1.xml?emailaddress=[email]`\n    +       or `https://[domain]/.well-known/autoconfig/mail/config-v1.1.xml`\n    +\n    +    2. If that fails, it tries to fetch the settings from Mozilla's ISPDB at\n    +       `https://autoconfig.thunderbird.net/v1.1/[domain]`.\n     \n         3. If that also fails, it falls back to checking the MX records of the\n            domain used in the email address to find the SMTP server. It can be\n    @@ Commit message\n            the correct domain for the email from the MX records, and repeats the\n            first 2 steps with the guessed domain.\n     \n    -    This feature is heavily inpired by the autoconfig feature in Mozilla\n    +    This feature is heavily inspired by the autoconfig feature in Mozilla\n         Thunderbird. A detailed documentation about how thunderbird fetches the\n         autoconfig settings can be found at:\n     \n    @@ Documentation/git-send-email.adoc: Information\n      \n     +--get-smtp-server::\n     +\tAttempt to get the correct SMTP server settings by entering an email\n    -+\taddress. Once an email address is entered, it will first try to get\n    -+\tthe correct settings from\n    -+\thttps://autoconfig.thunderbird.net/v1.1/[Mozilla's ISPDB], followed\n    -+\tby attempting to check for an autoconfig file hosted by the email\n    -+\tprovider, finally falling back to the MX records of the domain used\n    -+\tby the email address.\n    ++\taddress. Once an email address is entered, it will first attempt to check\n    ++\tfor an autoconfig file hosted by the email provider, followed\n    ++\tby attempting to get the correct settings from\n    ++\thttps://autoconfig.thunderbird.net/v1.1/[Mozilla's ISPDB], finally falling\n    ++\tback to the MX records of the domain used by the email address.\n     +\n      CONFIGURATION\n      -------------\n    @@ Documentation/git-send-email.adoc: include::includes/cmd-config-section-all.adoc\n     +address may have more than one configuration. In that case, any of\n     +them can be used.\n     +\n    -+For example, an output with email `someone@pobox.com` yields:\n    ++For example, an output with email `someone@gmail.com` yields:\n     +\n     +----\n     +Configuration 1:\n    -+  Server: smtp.pobox.com\n    ++  Server: smtp.gmail.com\n     +  Port: 465\n     +  Encryption: ssl\n    -+  Username: ssw@pobox.com\n    -+\n    -+Configuration 2:\n    -+  Server: smtp.pobox.com\n    -+  Port: 587\n    -+  Encryption: tls\n    -+  Username: ssw@pobox.com\n    ++  Username: jhk@gmail.com\n    ++  Authentication: Normal Password\n    ++  Authentication: OAuth2\n     +----\n     +\n     +Here the value of:\n    @@ Documentation/git-send-email.adoc: include::includes/cmd-config-section-all.adoc\n     +- `Port` corresponds to `sendmail.smtpServerPort`.\n     +- `Encryption` corresponds to `sendmail.smtpEncryption`.\n     +- `Username` corresponds to `sendmail.smtpUser`.\n    ++- `Authentication` indicates supported authentication methods.\n     ++\n     +\n     +This method should work well for almost all large email providers in the\n    @@ git-send-email.perl: sub parse_sendmail_aliases {\n      \texit(0);\n      }\n      \n    -+sub fetch_config_mozilla_ispdb {\n    -+\tmy ($domain) = @_;\n    -+\tmy $ispdb_url = \"https://autoconfig.thunderbird.net/v1.1/$domain\";\n    -+\tmy $xml = fetch_config($ispdb_url);\n    -+\treturn $xml if $xml;\n    -+}\n    ++our $doc;\n     +\n     +sub fetch_config_domain_autoconfig {\n    ++\trequire XML::LibXML;\n     +\tmy ($domain, $email_enc) = @_;\n    ++\tmy $parser = XML::LibXML->new;\n     +\tmy $autoconfig_url = \"https://autoconfig.$domain/mail/config-v1.1.xml?emailaddress=$email_enc\";\n     +\tmy $xml = fetch_config($autoconfig_url);\n    -+\treturn $xml if $xml;\n    ++\tif ($xml) {\n    ++\t\t$doc = eval { $parser->load_xml(string => $xml) };\n    ++\t\treturn $doc if $doc;\n    ++\t}\n    ++\tif (!$xml || !$doc) {\n    ++\t\t$autoconfig_url = \"http://$domain/.well-known/autoconfig/mail/config-v1.1.xml\";\n    ++\t\t$xml = fetch_config($autoconfig_url);\n    ++\t\tif ($xml) {\n    ++\t\t\t$doc = eval { $parser->load_xml(string => $xml) };\n    ++\t\t\treturn $doc if $doc;\n    ++\t\t}\n    ++\t}\n    ++}\n    ++\n    ++sub fetch_config_mozilla_ispdb {\n    ++\trequire XML::LibXML;\n    ++\tmy ($domain) = @_;\n    ++\tmy $parser = XML::LibXML->new;\n    ++\tmy $ispdb_url = \"https://autoconfig.thunderbird.net/v1.1/$domain\";\n    ++\tmy $xml = fetch_config($ispdb_url);\n    ++\tif ($xml) {\n    ++\t\t$doc = eval { $parser->load_xml(string => $xml) };\n    ++\t\treturn $doc if $doc;\n    ++\t}\n     +}\n     +\n     +sub fetch_config {\n    @@ git-send-email.perl: sub parse_sendmail_aliases {\n     +}\n     +\n     +sub parse_config {\n    -+\trequire XML::LibXML;\n    -+\tmy ($xml, $email) = @_;\n    -+\tmy $parser = XML::LibXML->new;\n    -+\tmy $doc = eval { $parser->load_xml(string => $xml) };\n    -+\tdie \"Failed to parse XML\\n\" unless $doc;\n    ++\tmy ($doc_parsed, $email) = @_;\n     +\tmy $config_num = 0;\n     +\tmy $smtp_encryption_config;\n     +\tmy $smtp_user_config;\n    ++\tmy $supports_oauth2 = 0;\n     +\n    -+\tforeach my $outgoing ($doc->findnodes('//outgoingServer')) {\n    ++\tforeach my $outgoing ($doc_parsed->findnodes('//outgoingServer')) {\n     +\t\t$config_num++;\n     +\t\tif ($outgoing->findvalue('./socketType') eq 'SSL') {\n     +\t\t\t$smtp_encryption_config = 'ssl';\n    @@ git-send-email.perl: sub parse_sendmail_aliases {\n     +\t\t\t$smtp_user_config = $outgoing->findvalue('./username');\n     +\t\t}\n     +\n    ++\t\tmy $auth_mechanisms = $outgoing->findvalue('./authentication');\n    ++\n     +\t\tprint \"\\nConfiguration $config_num:\\n\";\n     +\t\tprint \"  Server: \", $outgoing->findvalue('./hostname'), \"\\n\";\n     +\t\tprint \"  Port: \", $outgoing->findvalue('./port'), \"\\n\";\n     +\t\tprint \"  Encryption: \", $smtp_encryption_config, \"\\n\";\n     +\t\tprint \"  Username: \", $smtp_user_config, \"\\n\";\n    ++\t\tif ($auth_mechanisms =~ /password-cleartext/i) {\n    ++\t\t\tprint \"  Authentication: Normal Password\\n\";\n    ++\t\t}\n    ++\t\tif ($auth_mechanisms =~ /password-encrypted/i) {\n    ++\t\t\tprint \"  Authentication: Encrypted Password\\n\";\n    ++\t\t}\n    ++\t\tif ($auth_mechanisms =~ /NTLM/i) {\n    ++\t\t\tprint \"  Authentication: NTLM\\n\";\n    ++\t\t}\n    ++\t\tif ($auth_mechanisms =~ /GSSAPI/i) {\n    ++\t\t\tprint \"  Authentication: Kerberos / GSSAPI\\n\";\n    ++\t\t}\n    ++\t\tif ($auth_mechanisms =~ /client-IP-address/i) {\n    ++\t\t\tprint \"  Authentication: Client IP Address\\n\";\n    ++\t\t}\n    ++\t\tif ($auth_mechanisms =~ /TLS-client-cert/i) {\n    ++\t\t\tprint \"  Authentication: TLS Certificate\\n\";\n    ++\t\t}\n    ++\t\tif ($auth_mechanisms =~ /OAuth2/i) {\n    ++\t\t\tprint \"  Authentication: OAuth2\\n\";\n    ++\t\t\t$supports_oauth2 = 1;\n    ++\t\t}\n    ++\t\tif ($auth_mechanisms =~ /none/i) {\n    ++\t\t\tprint \"  Authentication: No Authentication\\n\";\n    ++\t\t}\n    ++\t\tif ($smtp_encryption_config eq 'plain') {\n    ++\t\t\tprint \"\\nWarning: Encryption plain is unencrypted!\\n\";\n    ++\t\t}\n    ++\t}\n    ++\tif ($supports_oauth2) {\n    ++\t\tprint \"\\nThe SMTP server supports OAuth2 authentication. If you want to use OAuth2,\\n\";\n    ++\t\tprint \"please review the git-send-email man pages for more details.\\n\";\n     +\t}\n    ++\tprint \"\\e[33m\"; # yellow\n    ++\tprint \"\\nTo apply the settings use:\\n\";\n    ++\tprint \"  git config --global sendmail.smtpServer VALUE\\n\";\n    ++\tprint \"  git config --global sendmail.smtpServerPort VALUE\\n\";\n    ++\tprint \"  git config --global sendmail.smtpEncryption VALUE\\n\";\n    ++\tprint \"  git config --global sendmail.smtpUser VALUE\\n\";\n    ++\tprint \"\\nOmit --global to set the configuration only in this repository.\\n\";\n    ++\tprint \"\\e[0m\"; # reset\n     +}\n     +\n     +if ($get_smtp_server) {\n    @@ git-send-email.perl: sub parse_sendmail_aliases {\n     +\tmy $domain = $1;\n     +\tmy $email_enc = URI::Escape::uri_escape($email);\n     +\n    -+\t# 1. Try Mozilla ISPDB\n    -+\tmy $xml = fetch_config_mozilla_ispdb($domain);\n    ++\t# 1. Try domain autoconfig if ISPDB fails\n    ++\t$doc = fetch_config_domain_autoconfig($domain, $email_enc);\n     +\n    -+\t# 2. Try domain autoconfig if ISPDB fails\n    -+\tif (!$xml) {\n    -+\t\t$xml = fetch_config_domain_autoconfig($domain, $email_enc);\n    ++\t# 2. Try Mozilla ISPDB if domain autoconfig fails\n    ++\tif (!$doc) {\n    ++\t\t$doc = fetch_config_mozilla_ispdb($domain);\n     +\t}\n     +\n     +\t# 3. Try MX record lookup\n    -+\tif (!$xml) {\n    ++\tif (!$doc) {\n     +\t\tmy $base_domain = get_mx_base_domain($domain);\n     +\t\tif ($base_domain && $base_domain ne $domain) {\n    -+\t\t\t$xml = fetch_config_mozilla_ispdb($base_domain);\n    ++\t\t\t$doc = fetch_config_domain_autoconfig($base_domain, $email_enc);\n     +\n    -+\t\t\tif (!$xml) {\n    -+\t\t\t\t$xml = fetch_config_domain_autoconfig($base_domain, $email_enc);\n    ++\t\t\tif (!$doc) {\n    ++\t\t\t\t$doc = fetch_config_mozilla_ispdb($base_domain);\n     +\t\t\t}\n     +\t\t}\n     +\t}\n     +\n    -+\tif ($xml) {\n    ++\tif ($doc) {\n     +\t\tprint \"\\nFound SMTP server settings for $email:\\n\";\n    -+\t\tparse_config($xml, $email);\n    ++\t\tparse_config($doc, $email);\n     +\t} else {\n     +\t\tprint \"\\nUnable to find SMTP server settings for $email\\n\";\n     +\t}\n    @@ git-send-email.perl: sub parse_sendmail_aliases {\n      # is_format_patch_arg($f) returns 0 if $f names a patch, or 1 if\n      # $f is a revision list specification to be passed to format-patch.\n      sub is_format_patch_arg {\n    +@@ git-send-email.perl: sub send_message {\n    + \t\t}\n    + \n    + \t\tif (!$smtp) {\n    +-\t\t\tdie __(\"Unable to initialize SMTP properly. Check config and use --smtp-debug.\"),\n    ++\t\t\tdie __(\"Unable to initialize SMTP properly. Check config and use --smtp-debug.\\n\"),\n    ++\t\t\t    __(\"Use --get-smtp-server to get correct settings for your SMTP server if needed.\\n\"),\n    + \t\t\t    \" VALUES: server=$smtp_server \",\n    + \t\t\t    \"encryption=$smtp_encryption \",\n    + \t\t\t    \"hello=$smtp_domain\",\n-- \n2.50.1.320.g2ad311502d\n\n"},{"id":"524714","messageId":"PN3PR01MB9597AA61D622066CD32568D1B83DA@PN3PR01MB9597.INDPRD01.PROD.OUTLOOK.COM","threadId":"63878","inReplyTo":"DBSU01804YQB.2JA3KHG5FDV55@swagemakers.org","subject":"Re: [PATCH v2] send-email: add --get-smtp-server option to fetch SMTP settings","fromName":"Aditya Garg","fromEmail":"gargaditya08@live.com","sentAt":"2025-08-22T15:14:14Z","receivedAt":"2025-08-22T15:14:21Z","isPatch":true,"sender":{"key":"gargaditya08@live.com","avatar":"https://avatars.githubusercontent.com/u/85610623?v=4"},"body":"Hi Julian\n\n>> Autoconfiguring SMTP server settings is a common feature present in many\n>> email clients. In order to get the correct SMTP server settings easily,\n>> this commit adds a `--get-smtp-server` option to `git send-email`. This\n>> option attempts to fetch the SMTP server settings for a given email address\n>> via the following steps:\n>>\n>> 1. It first tries to fetch the settings from Mozilla's ISPDB at\n>>    `https://autoconfig.thunderbird.net/v1.1/[domain]`.\n> \n> We should first check autoconfig and then move to the 3rd party\n> database, this is how thunderbird[0] and aerc[1] do it.\n> \n>>\n>> 2. If that fails, it attempts to fetch the autoconfig file from the email\n>>    provider's autoconfig URL, which is typically in the format\n>>    `https://autoconfig.[domain]/mail/config-v1.1.xml?emailaddress=[email]`.\n> \n> The documentation mentions using `DOMAIN/.well-known/autoconfig/mail/`\n> as an alternative to the autoconfig subdomain, what do you think about\n> supporting that?\n> \n>>\n>> 3. If that also fails, it falls back to checking the MX records of the\n>>    domain used in the email address to find the SMTP server. It can be\n>>    useful in case of emails with custom domains. It attempts to guess\n>>    the correct domain for the email from the MX records, and repeats the\n>>    first 2 steps with the guessed domain.\n>>\n>> This feature is heavily inpired by the autoconfig feature in Mozilla\n> \n> s/inpired/inspired\n> \n> \n>> +sub parse_config {\n>> +\trequire XML::LibXML;\n>> +\tmy ($xml, $email) = @_;\n>> +\tmy $parser = XML::LibXML->new;\n>> +\tmy $doc = eval { $parser->load_xml(string => $xml) };\n>> +\tdie \"Failed to parse XML\\n\" unless $doc;\n>> +\tmy $config_num = 0;\n>> +\tmy $smtp_encryption_config;\n>> +\tmy $smtp_user_config;\n>> +\n>> +\tforeach my $outgoing ($doc->findnodes('//outgoingServer')) {\n>> +\t\t$config_num++;\n>> +\t\tif ($outgoing->findvalue('./socketType') eq 'SSL') {\n>> +\t\t\t$smtp_encryption_config = 'ssl';\n>> +\t\t} elsif ($outgoing->findvalue('./socketType') eq 'STARTTLS') {\n>> +\t\t\t$smtp_encryption_config = 'tls';\n>> +\t\t} else {\n>> +\t\t\t$smtp_encryption_config = 'plain';\n> \n> 'plain' is unencrypted, I think this should be accompanied by a big\n> warning.\n> \n>> +\t\t}\n>> +\n>> +\t\tif ($outgoing->findvalue('./username') eq '%EMAILADDRESS%') {\n>> +\t\t\t$smtp_user_config = $email;\n>> +\t\t} elsif ($outgoing->findvalue('./username') eq '%EMAILLOCALPART%') {\n>> +\t\t\t$smtp_user_config = (split /@/, $email)[0];\n>> +\t\t} elsif ($outgoing->findvalue('./username') eq '%EMAILDOMAIN%') {\n>> +\t\t\t$smtp_user_config = (split /@/, $email)[1];\n>> +\t\t} else {\n>> +\t\t\t$smtp_user_config = $outgoing->findvalue('./username');\n>> +\t\t}\n>> +\n>> +\t\tprint \"\\nConfiguration $config_num:\\n\";\n>> +\t\tprint \"  Server: \", $outgoing->findvalue('./hostname'), \"\\n\";\n>> +\t\tprint \"  Port: \", $outgoing->findvalue('./port'), \"\\n\";\n>> +\t\tprint \"  Encryption: \", $smtp_encryption_config, \"\\n\";\n>> +\t\tprint \"  Username: \", $smtp_user_config, \"\\n\";\n> \n> The new option only gives you the needed SMTP configuration, as a\n> user you still need to apply them and to do that you will need to\n> look up how. We could help the user here and give them copy and\n> paste commands similar to when trying to commit without having an\n> identity set.\n> \n> The XML file also contains authentication details, what do you think\n> about processing those? That would also allow adding references to the\n> documentation in case it is OAuth2.\n> \n>> +\t}\n>> +}\n>> +\n>> +if ($get_smtp_server) {\n>> +\trequire URI::Escape;\n>> +\tprint \"Enter your email address: \";\n>> +\tchomp(my $email = <STDIN>);\n> \n> Someone sending out emails will most likely already have set up\n> `user.email` in their gitconfig. We could just use that instead of\n> prompting for user input, or at least suggest it as a default.\n> \n> If you don't have an SMTP server configured then `git send-email`\n> will default to `localhost` and fail if you are not running a\n> local SMTP server with: `Unable to initialize SMTP properly.\n> Check config and use --smtp-debug.`. I would suggest altering the\n> message pointing the user to the new option\n\nI've sent a v3 with hopefully your suggested changes addressed. Let me know if something is missing!\n"},{"id":"524952","messageId":"20250826133936.1569-1-gargaditya08@live.com","threadId":"63878","inReplyTo":"20250822151039.36006-1-gargaditya08@live.com","subject":"[PATCH v4] send-email: add --get-smtp-server option to fetch SMTP settings","fromName":"Aditya Garg","fromEmail":"gargaditya08@live.com","sentAt":"2025-08-26T13:39:38Z","receivedAt":"2025-08-26T13:39:43Z","isPatch":true,"sender":{"key":"gargaditya08@live.com","avatar":"https://avatars.githubusercontent.com/u/85610623?v=4"},"body":"Autoconfiguring SMTP server settings is a common feature present in many\nemail clients. In order to get the correct SMTP server settings easily,\nthis commit adds a `--get-smtp-server` option to `git send-email`. This\noption attempts to fetch the SMTP server settings for a given email address\nvia the following steps:\n\n1. It first attempts to fetch the autoconfig file from the email\n   provider's autoconfig URL, which is typically in the format\n   `https://autoconfig.[domain]/mail/config-v1.1.xml?emailaddress=[email]`\n   or `https://[domain]/.well-known/autoconfig/mail/config-v1.1.xml`\n\n2. If that fails, it tries to fetch the settings from Mozilla's ISPDB at\n   `https://autoconfig.thunderbird.net/v1.1/[domain]`.\n\n3. If that also fails, it falls back to checking the MX records of the\n   domain used in the email address to find the SMTP server. It can be\n   useful in case of emails with custom domains. It attempts to guess\n   the correct domain for the email from the MX records, and repeats the\n   first 2 steps with the guessed domain.\n\nThis feature is heavily inspired by the autoconfig feature in Mozilla\nThunderbird. A detailed documentation about how thunderbird fetches the\nautoconfig settings can be found at:\n\nhttps://www.bucksch.org/1/projects/thunderbird/autoconfiguration/\n---\n\nv2: - Improved checks for valid email address.\n\nv3: - Try to get settings from email provider's autoconfig URL first,\n      followed by Mozilla ISPDB, then MX records.\n    - Add support for another variant of autoconfig URL:\n      `https://[domain]/.well-known/autoconfig/mail/config-v1.1.xml`\n    - Added support to list supported auth mechanisms.\n    - Added warning if encryption is plain (unencrypted).\n    - Suggest user to read the docs for OAuth2.\n    - Give instructions on how to apply the settings.\n\nv4: - Fix typo in git config commands\n\n Documentation/git-send-email.adoc |  51 ++++++-\n git-send-email.perl               | 219 +++++++++++++++++++++++++++++-\n 2 files changed, 266 insertions(+), 4 deletions(-)\n\ndiff --git a/Documentation/git-send-email.adoc b/Documentation/git-send-email.adoc\nindex 5335502d68..daddaae36d 100644\n--- a/Documentation/git-send-email.adoc\n+++ b/Documentation/git-send-email.adoc\n@@ -13,6 +13,7 @@ SYNOPSIS\n 'git send-email' [<options>] <format-patch-options>\n 'git send-email' --dump-aliases\n 'git send-email' --translate-aliases\n+'git send-email' --get-smtp-server\n \n \n DESCRIPTION\n@@ -505,6 +506,14 @@ Information\n \taddress to standard output, one per line. See `sendemail.aliasFile`\n \tfor more information about aliases.\n \n+--get-smtp-server::\n+\tAttempt to get the correct SMTP server settings by entering an email\n+\taddress. Once an email address is entered, it will first attempt to check\n+\tfor an autoconfig file hosted by the email provider, followed\n+\tby attempting to get the correct settings from\n+\thttps://autoconfig.thunderbird.net/v1.1/[Mozilla's ISPDB], finally falling\n+\tback to the MX records of the domain used by the email address.\n+\n CONFIGURATION\n -------------\n \n@@ -512,6 +521,41 @@ include::includes/cmd-config-section-all.adoc[]\n \n include::config/sendemail.adoc[]\n \n+GETTING THE CORRECT SMTP SERVER SETTINGS\n+----------------------------------------\n+\n+You can attempt to get the correct SMTP server settings by using\n+the `--get-smtp-server` command line option with `git send-email`.\n+It will ask you for your email address, then attempt to get the\n+correct SMTP server settings for that email address. An email\n+address may have more than one configuration. In that case, any of\n+them can be used.\n+\n+For example, an output with email `someone@gmail.com` yields:\n+\n+----\n+Configuration 1:\n+  Server: smtp.gmail.com\n+  Port: 465\n+  Encryption: ssl\n+  Username: jhk@gmail.com\n+  Authentication: Normal Password\n+  Authentication: OAuth2\n+----\n+\n+Here the value of:\n++\n+- `Server` corresponds to `sendmail.smtpServer`.\n+- `Port` corresponds to `sendmail.smtpServerPort`.\n+- `Encryption` corresponds to `sendmail.smtpEncryption`.\n+- `Username` corresponds to `sendmail.smtpUser`.\n+- `Authentication` indicates supported authentication methods.\n++\n+\n+This method should work well for almost all large email providers in the\n+world. If it provides invalid settings or cannot retrieve them, contact\n+your email provider.\n+\n EXAMPLES OF SMTP SERVERS\n ------------------------\n Use Gmail as the SMTP Server\n@@ -624,8 +668,11 @@ https://metacpan.org/pod/Net::SMTP[Net::SMTP].\n \n These additional Perl modules are also required:\n \n-https://metacpan.org/pod/Authen::SASL[Authen::SASL] and\n-https://metacpan.org/pod/Mail::Address[Mail::Address].\n+https://metacpan.org/pod/Authen::SASL[Authen::SASL],\n+https://metacpan.org/pod/Mail::Address[Mail::Address],\n+https://metacpan.org/pod/Net::DNS[Net::DNS],\n+https://metacpan.org/pod/URI::Escape[URI::Escape] and\n+https://metacpan.org/dist/XML-LibXML[XML::LibXML].\n \n Exploiting the `sendmailCmd` option of `git send-email`\n ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex 437f8ac46a..7d7fb52d6a 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -32,6 +32,7 @@ sub usage {\n git send-email [<options>] <format-patch options>\n git send-email --dump-aliases\n git send-email --translate-aliases\n+git send-email --get-smtp-server\n \n   Composing:\n     --from                  <str>  * Email From:\n@@ -108,6 +109,7 @@ sub usage {\n                                      input according to the configured email\n                                      alias file(s), outputting the result to\n                                      standard output.\n+    --get-smtp-server              * Print the SMTP server settings for a given email.\n \n EOT\n \texit(1);\n@@ -222,6 +224,7 @@ sub format_2822_time {\n my $force = 0;\n my $dump_aliases = 0;\n my $translate_aliases = 0;\n+my $get_smtp_server = 0;\n \n # Variables to prevent short format-patch options from being captured\n # as abbreviated send-email options\n@@ -501,6 +504,15 @@ sub config_regexp {\n     if !$help and ($dump_aliases or $translate_aliases) and @ARGV;\n die __(\"--dump-aliases and --translate-aliases are mutually exclusive\\n\")\n     if !$help and $dump_aliases and $translate_aliases;\n+\n+my %get_smtp_server_options = (\n+\t\"get-smtp-server\" => \\$get_smtp_server,\n+);\n+$rc = GetOptions(%get_smtp_server_options);\n+usage() unless $rc;\n+die __(\"--get-smtp-server incompatible with other options\\n\")\n+\tif !$help and $get_smtp_server and @ARGV;\n+\n my %options = (\n \t\t    \"sender|from=s\" => \\$sender,\n \t\t    \"in-reply-to=s\" => \\$initial_in_reply_to,\n@@ -565,7 +577,7 @@ sub config_regexp {\n my @initial_bcc = @getopt_bcc ? @getopt_bcc : ($no_bcc ? () : @config_bcc);\n \n usage() if $help;\n-my %all_options = (%options, %dump_aliases_options, %identity_options);\n+my %all_options = (%options, %dump_aliases_options, %identity_options, %get_smtp_server_options);\n completion_helper(\\%all_options) if $git_completion_helper;\n unless ($rc) {\n     usage();\n@@ -757,6 +769,208 @@ sub parse_sendmail_aliases {\n \texit(0);\n }\n \n+our $doc;\n+\n+sub fetch_config_domain_autoconfig {\n+\trequire XML::LibXML;\n+\tmy ($domain, $email_enc) = @_;\n+\tmy $parser = XML::LibXML->new;\n+\tmy $autoconfig_url = \"https://autoconfig.$domain/mail/config-v1.1.xml?emailaddress=$email_enc\";\n+\tmy $xml = fetch_config($autoconfig_url);\n+\tif ($xml) {\n+\t\t$doc = eval { $parser->load_xml(string => $xml) };\n+\t\treturn $doc if $doc;\n+\t}\n+\tif (!$xml || !$doc) {\n+\t\t$autoconfig_url = \"http://$domain/.well-known/autoconfig/mail/config-v1.1.xml\";\n+\t\t$xml = fetch_config($autoconfig_url);\n+\t\tif ($xml) {\n+\t\t\t$doc = eval { $parser->load_xml(string => $xml) };\n+\t\t\treturn $doc if $doc;\n+\t\t}\n+\t}\n+}\n+\n+sub fetch_config_mozilla_ispdb {\n+\trequire XML::LibXML;\n+\tmy ($domain) = @_;\n+\tmy $parser = XML::LibXML->new;\n+\tmy $ispdb_url = \"https://autoconfig.thunderbird.net/v1.1/$domain\";\n+\tmy $xml = fetch_config($ispdb_url);\n+\tif ($xml) {\n+\t\t$doc = eval { $parser->load_xml(string => $xml) };\n+\t\treturn $doc if $doc;\n+\t}\n+}\n+\n+sub fetch_config {\n+\trequire HTTP::Tiny;\n+\tmy ($url) = @_;\n+\tmy $http = HTTP::Tiny->new(timeout => 10);\n+\tmy $res = $http->get($url);\n+\n+\treturn unless $res->{success};\n+\treturn $res->{content};\n+}\n+\n+sub extract_base_domain {\n+\trequire IO::Socket::SSL::PublicSuffix;\n+\tmy ($host) = @_;\n+\tmy $ps = IO::Socket::SSL::PublicSuffix->default;\n+\n+\tmy $public_suffix = $ps->public_suffix($host);\n+\treturn $host unless defined $public_suffix;\n+\n+\tmy @host_parts = split(/\\./, lc($host));\n+\tmy @suffix_parts = split(/\\./, $public_suffix);\n+\n+\t# Find where the suffix starts in the host\n+\tfor (my $i = 0; $i <= $#host_parts - $#suffix_parts; $i++) {\n+\t\tif (join('.', @host_parts[$i .. $#host_parts]) eq $public_suffix) {\n+\t\t\t# Precursor + suffix = base domain\n+\t\t\treturn join('.', $host_parts[$i - 1], @host_parts[$i .. $#host_parts]) if $i > 0;\n+\t\t\treturn $public_suffix;\n+\t\t}\n+\t}\n+\n+\treturn $host;\n+}\n+\n+sub get_mx_base_domain {\n+\trequire Net::DNS;\n+\tmy ($domain) = @_;\n+\tmy $resolver = Net::DNS::Resolver->new;\n+\tmy $query = $resolver->query($domain, \"MX\");\n+\n+\tif ($query) {\n+\t\tmy @mx_hosts = sort { $a->preference <=> $b->preference } grep { $_->type eq \"MX\" } $query->answer;\n+\t\tif (@mx_hosts) {\n+\t\t\tmy $mx_host = $mx_hosts[0]->exchange;\n+\t\t\t$mx_host =~ s/\\.$//;  # Remove trailing dot\n+\t\t\treturn extract_base_domain($mx_host);\n+\t\t}\n+\t}\n+\treturn;\n+}\n+\n+sub parse_config {\n+\tmy ($doc_parsed, $email) = @_;\n+\tmy $config_num = 0;\n+\tmy $smtp_encryption_config;\n+\tmy $smtp_user_config;\n+\tmy $supports_oauth2 = 0;\n+\n+\tforeach my $outgoing ($doc_parsed->findnodes('//outgoingServer')) {\n+\t\t$config_num++;\n+\t\tif ($outgoing->findvalue('./socketType') eq 'SSL') {\n+\t\t\t$smtp_encryption_config = 'ssl';\n+\t\t} elsif ($outgoing->findvalue('./socketType') eq 'STARTTLS') {\n+\t\t\t$smtp_encryption_config = 'tls';\n+\t\t} else {\n+\t\t\t$smtp_encryption_config = 'plain';\n+\t\t}\n+\n+\t\tif ($outgoing->findvalue('./username') eq '%EMAILADDRESS%') {\n+\t\t\t$smtp_user_config = $email;\n+\t\t} elsif ($outgoing->findvalue('./username') eq '%EMAILLOCALPART%') {\n+\t\t\t$smtp_user_config = (split /@/, $email)[0];\n+\t\t} elsif ($outgoing->findvalue('./username') eq '%EMAILDOMAIN%') {\n+\t\t\t$smtp_user_config = (split /@/, $email)[1];\n+\t\t} else {\n+\t\t\t$smtp_user_config = $outgoing->findvalue('./username');\n+\t\t}\n+\n+\t\tmy $auth_mechanisms = $outgoing->findvalue('./authentication');\n+\n+\t\tprint \"\\nConfiguration $config_num:\\n\";\n+\t\tprint \"  Server: \", $outgoing->findvalue('./hostname'), \"\\n\";\n+\t\tprint \"  Port: \", $outgoing->findvalue('./port'), \"\\n\";\n+\t\tprint \"  Encryption: \", $smtp_encryption_config, \"\\n\";\n+\t\tprint \"  Username: \", $smtp_user_config, \"\\n\";\n+\t\tif ($auth_mechanisms =~ /password-cleartext/i) {\n+\t\t\tprint \"  Authentication: Normal Password\\n\";\n+\t\t}\n+\t\tif ($auth_mechanisms =~ /password-encrypted/i) {\n+\t\t\tprint \"  Authentication: Encrypted Password\\n\";\n+\t\t}\n+\t\tif ($auth_mechanisms =~ /NTLM/i) {\n+\t\t\tprint \"  Authentication: NTLM\\n\";\n+\t\t}\n+\t\tif ($auth_mechanisms =~ /GSSAPI/i) {\n+\t\t\tprint \"  Authentication: Kerberos / GSSAPI\\n\";\n+\t\t}\n+\t\tif ($auth_mechanisms =~ /client-IP-address/i) {\n+\t\t\tprint \"  Authentication: Client IP Address\\n\";\n+\t\t}\n+\t\tif ($auth_mechanisms =~ /TLS-client-cert/i) {\n+\t\t\tprint \"  Authentication: TLS Certificate\\n\";\n+\t\t}\n+\t\tif ($auth_mechanisms =~ /OAuth2/i) {\n+\t\t\tprint \"  Authentication: OAuth2\\n\";\n+\t\t\t$supports_oauth2 = 1;\n+\t\t}\n+\t\tif ($auth_mechanisms =~ /none/i) {\n+\t\t\tprint \"  Authentication: No Authentication\\n\";\n+\t\t}\n+\t\tif ($smtp_encryption_config eq 'plain') {\n+\t\t\tprint \"\\nWarning: Encryption plain is unencrypted!\\n\";\n+\t\t}\n+\t}\n+\tif ($supports_oauth2) {\n+\t\tprint \"\\nThe SMTP server supports OAuth2 authentication. If you want to use OAuth2,\\n\";\n+\t\tprint \"please review the git-send-email man pages for more details.\\n\";\n+\t}\n+\tprint \"\\e[33m\"; # yellow\n+\tprint \"\\nTo apply the settings use:\\n\";\n+\tprint \"  git config --global sendemail.smtpServer VALUE\\n\";\n+\tprint \"  git config --global sendemail.smtpServerPort VALUE\\n\";\n+\tprint \"  git config --global sendemail.smtpEncryption VALUE\\n\";\n+\tprint \"  git config --global sendemail.smtpUser VALUE\\n\";\n+\tprint \"\\nOmit --global to set the configuration only in this repository.\\n\";\n+\tprint \"\\e[0m\"; # reset\n+}\n+\n+if ($get_smtp_server) {\n+\trequire URI::Escape;\n+\tprint \"Enter your email address: \";\n+\tchomp(my $email = <STDIN>);\n+\t$email = extract_valid_address($email);\n+\tif (!$email) {\n+\t\tdie __(\"Invalid email format.\\n\");\n+\t}\n+\t$email =~ /@(.+)$/;\n+\tmy $domain = $1;\n+\tmy $email_enc = URI::Escape::uri_escape($email);\n+\n+\t# 1. Try domain autoconfig if ISPDB fails\n+\t$doc = fetch_config_domain_autoconfig($domain, $email_enc);\n+\n+\t# 2. Try Mozilla ISPDB if domain autoconfig fails\n+\tif (!$doc) {\n+\t\t$doc = fetch_config_mozilla_ispdb($domain);\n+\t}\n+\n+\t# 3. Try MX record lookup\n+\tif (!$doc) {\n+\t\tmy $base_domain = get_mx_base_domain($domain);\n+\t\tif ($base_domain && $base_domain ne $domain) {\n+\t\t\t$doc = fetch_config_domain_autoconfig($base_domain, $email_enc);\n+\n+\t\t\tif (!$doc) {\n+\t\t\t\t$doc = fetch_config_mozilla_ispdb($base_domain);\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\tif ($doc) {\n+\t\tprint \"\\nFound SMTP server settings for $email:\\n\";\n+\t\tparse_config($doc, $email);\n+\t} else {\n+\t\tprint \"\\nUnable to find SMTP server settings for $email\\n\";\n+\t}\n+\texit(0);\n+}\n+\n # is_format_patch_arg($f) returns 0 if $f names a patch, or 1 if\n # $f is a revision list specification to be passed to format-patch.\n sub is_format_patch_arg {\n@@ -1760,7 +1974,8 @@ sub send_message {\n \t\t}\n \n \t\tif (!$smtp) {\n-\t\t\tdie __(\"Unable to initialize SMTP properly. Check config and use --smtp-debug.\"),\n+\t\t\tdie __(\"Unable to initialize SMTP properly. Check config and use --smtp-debug.\\n\"),\n+\t\t\t    __(\"Use --get-smtp-server to get correct settings for your SMTP server if needed.\\n\"),\n \t\t\t    \" VALUES: server=$smtp_server \",\n \t\t\t    \"encryption=$smtp_encryption \",\n \t\t\t    \"hello=$smtp_domain\",\n\nRange-diff against v3:\n1:  63f9c628ac ! 1:  7638f71514 send-email: add --get-smtp-server option to fetch SMTP settings\n    @@ git-send-email.perl: sub parse_sendmail_aliases {\n     +\t}\n     +\tprint \"\\e[33m\"; # yellow\n     +\tprint \"\\nTo apply the settings use:\\n\";\n    -+\tprint \"  git config --global sendmail.smtpServer VALUE\\n\";\n    -+\tprint \"  git config --global sendmail.smtpServerPort VALUE\\n\";\n    -+\tprint \"  git config --global sendmail.smtpEncryption VALUE\\n\";\n    -+\tprint \"  git config --global sendmail.smtpUser VALUE\\n\";\n    ++\tprint \"  git config --global sendemail.smtpServer VALUE\\n\";\n    ++\tprint \"  git config --global sendemail.smtpServerPort VALUE\\n\";\n    ++\tprint \"  git config --global sendemail.smtpEncryption VALUE\\n\";\n    ++\tprint \"  git config --global sendemail.smtpUser VALUE\\n\";\n     +\tprint \"\\nOmit --global to set the configuration only in this repository.\\n\";\n     +\tprint \"\\e[0m\"; # reset\n     +}\n-- \n2.51.0\n\n"},{"id":"525013","messageId":"aK5RInMzjC6vuLv_@fruit.crustytoothpaste.net","threadId":"63878","inReplyTo":"20250826133936.1569-1-gargaditya08@live.com","subject":"Re: [PATCH v4] send-email: add --get-smtp-server option to fetch SMTP settings","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2025-08-27T00:28:18Z","receivedAt":"2025-08-27T00:28:21Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On 2025-08-26 at 13:39:38, Aditya Garg wrote:\n> Autoconfiguring SMTP server settings is a common feature present in many\n> email clients. In order to get the correct SMTP server settings easily,\n> this commit adds a `--get-smtp-server` option to `git send-email`. This\n> option attempts to fetch the SMTP server settings for a given email address\n> via the following steps:\n> \n> 1. It first attempts to fetch the autoconfig file from the email\n>    provider's autoconfig URL, which is typically in the format\n>    `https://autoconfig.[domain]/mail/config-v1.1.xml?emailaddress=[email]`\n>    or `https://[domain]/.well-known/autoconfig/mail/config-v1.1.xml`\n> \n> 2. If that fails, it tries to fetch the settings from Mozilla's ISPDB at\n>    `https://autoconfig.thunderbird.net/v1.1/[domain]`.\n\nI'm sorry I didn't ask this sooner, but it just occurred to me.  Do we\nhave permission from Mozilla to embed this service into Git?\n\nThe reason I ask is that sometimes software vendors embed external\nservices in a way that causes excessive or unreasonable load.  For\ninstance, some router manufacturers hard-coded certain NTP servers into\ntheir firmware in a way that polled too frequently and then effectively\nDDoSed those servers, all without asking permission first.\n\nIf we embed this into Git, then it will be present on systems for a long\ntime.  Some Linux distros are going up to 12 or more years for software\nlifetimes, so we should assume anything we embed here is going to be\npresent on OSes for at least that long and will be used at least\nmillions of times a day in a highly automated way.  Even if this only\nlasts one release, it will likely be on a nontrivial number of machines\nfor at least 12, if not more, years.  (Not everyone actually upgrades\nwhen their OS goes EOL, unfortunately.)\n\nIs Mozilla comfortable with providing that service for that amount of\ntime and having every Git installation on the planet potentially use it\nat top speed[0]?  If we haven't verified that, then we should probably\nnot include this service in the code.\n\n> +sub fetch_config {\n> +\trequire HTTP::Tiny;\n> +\tmy ($url) = @_;\n> +\tmy $http = HTTP::Tiny->new(timeout => 10);\n\nThis needs to set `verify_SSL => 1` explicitly, or we'll have a security\nvulnerability due to not verifying the certificate.  Our minimum\nsupported Perl version is 5.26, which shipped with HTTP::Tiny 0.070.\nVersions before 0.083 defaulted to not verifying certificates, so we\nstill need to set it explicitly.\n\n[0] Even if we don't think users will use this that way, with the number\nof Git users, there will be a nontrivial amount of users who do.  Many\nof them will not realize they may be causing a problem, though.\n-- \nbrian m. carlson (they/them)\nToronto, Ontario, CA\n"},{"id":"525027","messageId":"PN3PR01MB959731225E912FDCA7308508B838A@PN3PR01MB9597.INDPRD01.PROD.OUTLOOK.COM","threadId":"63878","inReplyTo":"aK5RInMzjC6vuLv_@fruit.crustytoothpaste.net","subject":"Re: [PATCH v4] send-email: add --get-smtp-server option to fetch SMTP settings","fromName":"Aditya Garg","fromEmail":"gargaditya08@live.com","sentAt":"2025-08-27T08:54:31Z","receivedAt":"2025-08-27T08:54:38Z","isPatch":true,"sender":{"key":"gargaditya08@live.com","avatar":"https://avatars.githubusercontent.com/u/85610623?v=4"},"body":"\n\nOn 27 August 2025 5:58:18 am IST, \"brian m. carlson\" <sandals@crustytoothpaste.net> wrote:\n>On 2025-08-26 at 13:39:38, Aditya Garg wrote:\n>> Autoconfiguring SMTP server settings is a common feature present in many\n>> email clients. In order to get the correct SMTP server settings easily,\n>> this commit adds a `--get-smtp-server` option to `git send-email`. This\n>> option attempts to fetch the SMTP server settings for a given email address\n>> via the following steps:\n>> \n>> 1. It first attempts to fetch the autoconfig file from the email\n>>    provider's autoconfig URL, which is typically in the format\n>>    `https://autoconfig.[domain]/mail/config-v1.1.xml?emailaddress=[email]`\n>>    or `https://[domain]/.well-known/autoconfig/mail/config-v1.1.xml`\n>> \n>> 2. If that fails, it tries to fetch the settings from Mozilla's ISPDB at\n>>    `https://autoconfig.thunderbird.net/v1.1/[domain]`.\n>\n>I'm sorry I didn't ask this sooner, but it just occurred to me.  Do we\n>have permission from Mozilla to embed this service into Git?\n>\n>The reason I ask is that sometimes software vendors embed external\n>services in a way that causes excessive or unreasonable load.  For\n>instance, some router manufacturers hard-coded certain NTP servers into\n>their firmware in a way that polled too frequently and then effectively\n>DDoSed those servers, all without asking permission first.\n>\n>If we embed this into Git, then it will be present on systems for a long\n>time.  Some Linux distros are going up to 12 or more years for software\n>lifetimes, so we should assume anything we embed here is going to be\n>present on OSes for at least that long and will be used at least\n>millions of times a day in a highly automated way.  Even if this only\n>lasts one release, it will likely be on a nontrivial number of machines\n>for at least 12, if not more, years.  (Not everyone actually upgrades\n>when their OS goes EOL, unfortunately.)\n>\n>Is Mozilla comfortable with providing that service for that amount of\n>time and having every Git installation on the planet potentially use it\n>at top speed[0]?  If we haven't verified that, then we should probably\n>not include this service in the code.\n\nGood point. Ccing the maintainer of the autoconfig code with this reply:\n\nHi Brendan\n\nAditya here. I was proposing a patch to git send email which uses Mozilla's ISPDB to get configurations for various email providers, and makes things easier for users. The original patch has been sent here: <https://lore.kernel.org/git/20250826133936.1569-1-gargaditya08@live.com/>\n\nbrian believes that I should ask Mozilla whether they are fine with users using their ISPDB with git send email. I agree with them and thus, am sending this message to you for your views.\n\nHope to hear from you soon!\n\nThanks\nAditya\n\n>\n>> +sub fetch_config {\n>> +\trequire HTTP::Tiny;\n>> +\tmy ($url) = @_;\n>> +\tmy $http = HTTP::Tiny->new(timeout => 10);\n>\n>This needs to set `verify_SSL => 1` explicitly, or we'll have a security\n>vulnerability due to not verifying the certificate.  Our minimum\n>supported Perl version is 5.26, which shipped with HTTP::Tiny 0.070.\n>Versions before 0.083 defaulted to not verifying certificates, so we\n>still need to set it explicitly.\n\nWill do if Mozilla allows us to use their service.\n\n>\n>[0] Even if we don't think users will use this that way, with the number\n>of Git users, there will be a nontrivial amount of users who do.  Many\n>of them will not realize they may be causing a problem, though.\n"}]}