Created
May 5, 2022 13:54
-
-
Save azumakuniyuki/f0590b7eab4a182d5764c863622176a0 to your computer and use it in GitHub Desktop.
Make a string for SMTP "AUTH PLAIN" from an username and a password
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// _ _ _ _ | |
// ___ _ __ ___ | |_ _ __ __ _ _ _| |_| |__ _ __ __ _ ___ _____ _____ _ __ __| | | |
// / __| '_ ` _ \| __| '_ \ / _` | | | | __| '_ \ _____| '_ \ / _` / __/ __\ \ /\ / / _ \| '__/ _` | | |
// \__ \ | | | | | |_| |_) | (_| | |_| | |_| | | |_____| |_) | (_| \__ \__ \\ V V / (_) | | | (_| | | |
// |___/_| |_| |_|\__| .__/ \__,_|\__,_|\__|_| |_| | .__/ \__,_|___/___/ \_/\_/ \___/|_| \__,_| | |
// |_| |_| | |
package main | |
// Usage: | |
// $ go run ./smtpauth-password username@example.jp password-string-for-smtp-authentication | |
// $ go run ./smtpauth-password --aws ap-northeast-1 --smtp-password AccessKeyID AccessSecret | |
import "os" | |
import "flag" | |
import "fmt" | |
import "crypto/hmac" | |
import "crypto/sha256" | |
import b64 "encoding/base64" | |
var Version = "0.0.1" | |
var Default = map[string]string{ | |
"region": "us-east-1", | |
} | |
var Setting = map[string]string{ | |
"region": "", | |
} | |
var Options = map[string]uint8{ | |
"exec": (1 << 0), | |
"test": (1 << 1), | |
"neko": (1 << 2), | |
"aws": (1 << 3), | |
"smtp-password": (1 << 4), | |
} | |
func e(mesg string, cont bool) { | |
if len(mesg) > 0 { | |
fmt.Fprintf(os.Stderr, " * error0: %s\n", mesg) | |
if !cont { | |
os.Exit(1) | |
} | |
} | |
} | |
func main() { | |
o := parseoptions() | |
a := flag.Args() | |
if o&Options["exec"] > 0 { | |
username := a[0] | |
password := a[1] | |
authtext := "" | |
if o&Options["aws"] > 0 { | |
// --aws option specified | |
if len(username) == 0 { | |
e("Access Key ID is empty", false) | |
} | |
if len(password) == 0 { | |
e("Secret Access Key is empty", false) | |
} | |
parameters := map[string]string{ | |
"date": "11111111", | |
"service": "ses", | |
"message": "SendRawEmail", | |
"terminal": "aws4_request", | |
"version": "\x04", | |
} | |
regionlist := []string{ | |
"us-east-2", // US East (Ohio) | |
"us-east-1", // US East (N. Virginia) | |
"us-west-2", // US West (Oregon) | |
"ap-south-1", // # Asia Pacific (Mumbai) | |
"ap-northeast-2", // Asia Pacific (Seoul) | |
"ap-southeast-1", // Asia Pacific (Singapore) | |
"ap-southeast-2", // Asia Pacific (Sydney) | |
"ap-northeast-1", // Asia Pacific (Tokyo) | |
"ca-central-1", // Canada (Central) | |
"eu-central-1", // Europe (Frankfurt) | |
"eu-west-1", // Europe (Ireland) | |
"eu-west-2", // Europe (London) | |
"sa-east-1", // South America (Sao Paulo) | |
"us-gov-west-1", // AWS GovCloud (US) | |
} | |
regionok := false | |
for _, e := range regionlist { | |
// The regsion specified with --region option does not have an SMTP endpoint | |
if Setting["region"] == e { | |
regionok = true | |
break | |
} | |
} | |
if !regionok { | |
e(fmt.Sprintf("The %s region does not have an SMTP endpoint", Setting["region"]), false) | |
} | |
digesthash := "" | |
smtppasswd := "" | |
makedigest := func(key, msg string) string { | |
if len(key) == 0 { | |
return "" | |
} | |
if len(msg) == 0 { | |
return "" | |
} | |
mac := hmac.New(sha256.New, []byte(key)) | |
mac.Write([]byte(msg)) | |
return string(mac.Sum(nil)) | |
} | |
digesthash = makedigest("AWS4"+password, parameters["date"]) | |
digesthash = makedigest(digesthash, Setting["region"]) | |
digesthash = makedigest(digesthash, parameters["service"]) | |
digesthash = makedigest(digesthash, parameters["terminal"]) | |
digesthash = makedigest(digesthash, parameters["message"]) | |
smtppasswd = b64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s%s", parameters["version"], digesthash))) | |
if o&Options["smtp-password"] > 0 { | |
// Print an SMTP password and exit when --smtp-password option was specified | |
fmt.Printf("%s\n", smtppasswd) | |
} else { | |
// Print an authentication text for "AUTH PLAIN" SMTP command | |
authtext = fmt.Sprintf("%s\x00%s\x00%s", username, username, smtppasswd) | |
fmt.Printf("%s\n", b64.StdEncoding.EncodeToString([]byte(authtext))) | |
} | |
} else { | |
// Make an credentials for general SMTP Authentication | |
if len(username) == 0 { | |
e("Username is empty", false) | |
} | |
if len(password) == 0 { | |
e("Passowrd is empty", false) | |
} | |
authtext = fmt.Sprintf("%s\x00%s\x00%s", username, username, password) | |
fmt.Printf("%s\n", b64.StdEncoding.EncodeToString([]byte(authtext))) | |
} | |
} | |
} | |
func parseoptions() uint8 { | |
// Parse arguments given from a command line | |
var o uint8 = 0 | |
var f_is_amazonses = flag.String("aws", "", "Make SMTP Credentials for Amazon SES") | |
var f_smtppassword = flag.Bool("smtp-password", false, "Output SMTP Password for Amazon SES") | |
flag.Parse() | |
o |= Options["exec"] | |
if len(*f_is_amazonses) > 0 { | |
// --aws option specified | |
o |= Options["aws"] | |
Setting["region"] = *f_is_amazonses | |
} | |
if *f_smtppassword { | |
// --smtp-password option specified | |
o |= Options["smtp-password"] | |
} | |
return o | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment