First CLI implementation.

This commit is contained in:
Blallo 2020-02-06 18:30:13 +01:00
commit 4d4454a14c
No known key found for this signature in database
GPG key ID: 0CBE577C9B72DC3F
2 changed files with 263 additions and 0 deletions

213
main.go Normal file
View file

@ -0,0 +1,213 @@
package main
import (
"flag"
"fmt"
"log"
"reflect"
"strings"
toml "github.com/pelletier/go-toml"
// mail "gopkg.in/gomail.v2"
)
type ServerConfig struct {
Address string `toml:address,omitempty`
Port int64 `toml:port,omitempty`
Encryption string `toml:encryption,omitempty`
User string `toml:user,omitempty`
Password string `toml:password,omitempty`
}
func (s ServerConfig) String() string {
return fmt.Sprintf(
"\tAddress: %s\n\tPort: %d\n\tEncryption: %s\n\tUser: %s\n\tPassword: %s\n",
s.Address,
s.Port,
s.Encryption,
s.User,
s.Password,
)
}
type Config struct {
Server *ServerConfig `toml:server,omitempty`
From string `toml:from,omitempty`
To []string `toml:to,omitempty`
Cc []string `toml:cc,omitempty`
Bcc []string `toml:bcc,omitempty`
Subject string `toml:subject,omitempty`
Text string `toml:text,omitempty`
}
func (c Config) String() string {
return fmt.Sprintf(
"From: %s\nTo: %s\nCc: %s\nBcc: %s\nSubject: %s\nText:\n%s\nServer:\n%s",
c.From,
c.To,
c.Cc,
c.Bcc,
c.Subject,
c.Text,
c.Server,
)
}
func NewConfig() *Config {
server := &ServerConfig{}
config := &Config{}
config.Server = server
return config
}
func debug(active bool, fmt string, msg ...interface{}) {
if active {
log.Printf(fmt, msg...)
}
}
func isPresent(slice []string, val string) bool {
for _, item := range slice {
if item == val {
return true
}
}
return false
}
func isEmpty(value interface{}) bool {
t := reflect.TypeOf(value)
v := reflect.ValueOf(value)
switch v.Kind() {
case reflect.Slice:
return v.Len() == 1
default:
return value == reflect.Zero(t).Interface()
}
}
func readConfig(configPath, section string) *Config {
config := NewConfig()
tree, err := toml.LoadFile(configPath)
if err != nil {
log.Panicln(err)
}
keys := tree.Keys()
if !isPresent(keys, section) {
return config
}
sub := tree.Get(section).(*toml.Tree)
err = sub.Unmarshal(config)
return config
}
func (c *Config) Validate() error {
return nil
}
func merge(key string, value, obj interface{}) {
if isEmpty(value) {
return
}
var elem reflect.Value
if reflect.TypeOf(obj) != reflect.TypeOf(reflect.Value{}) {
log.Println("Not Value")
elem = reflect.ValueOf(obj).Elem()
} else {
log.Println("Value")
elem = obj.(reflect.Value)
}
field := elem.FieldByName(key)
if field.CanSet() {
switch field.Kind() {
case reflect.Int64:
field.SetInt(value.(int64))
case reflect.Bool:
field.SetBool(value.(bool))
case reflect.String:
field.SetString(value.(string))
case reflect.Slice:
field.Set(reflect.ValueOf(value))
default:
merge(key, reflect.ValueOf(value), field)
//merge(key, value, field.Pointer())
}
}
}
func (s *ServerConfig) Merge(key string, value interface{}) {
merge(key, value, s)
}
func (c *Config) Merge(key string, value interface{}) {
merge(key, value, c)
}
func main() {
//var err error
var configPath, section, serverAddress, encryption, user, password, to, cc, bcc, from, subject string
var dbg bool
var serverPort_ int
var serverPort int64
flag.StringVar(&configPath, "conf", "/etc/sendmail.toml", "Path to a config file (defaults to /etc/sendmail.toml)")
flag.StringVar(&section, "section", "default", "Section of the conf to read (defaults to \"default\")")
flag.BoolVar(&dbg, "dbg", false, "Enable debugging output")
flag.StringVar(&serverAddress, "server-address", "", "The SMTP server address")
flag.IntVar(&serverPort_, "server-port", 0, "The SMTP server")
flag.StringVar(&encryption, "encryption", "", "The encryption type (no, starttls, tls)")
flag.StringVar(&user, "user", "", "The user to authenticate with to the server")
flag.StringVar(&password, "password", "", "The password to authenticate with to the server")
flag.StringVar(&to, "to", "", "Comma-separated list of recipient(s)")
flag.StringVar(&cc, "cc", "", "Comma-separated list of carbon-copy recipient(s)")
flag.StringVar(&bcc, "bcc", "", "Comma-separated list of blind carbon-copy recipient(s)")
flag.StringVar(&from, "from", "", "Sender of the mail (used as default account user to log in on the SMTP server)")
flag.StringVar(&subject, "sub", "", "Subject of the mail")
flag.Parse()
serverPort = int64(serverPort_)
debug(
dbg,
`parameters:
conf: %s
dbg: %t
address: %s
port: %d
encryption: %s
user: %s
password: %s
to: %s
from: %s
subject: %s`,
configPath,
dbg,
serverAddress,
serverPort,
encryption,
user,
password,
to,
from,
subject,
)
config := readConfig(configPath, section)
debug(dbg, "\n%s", *config)
// config.Server.Merge("Address", serverAddress)
// config.Server.Merge("Port", serverPort)
// config.Server.Merge("Encryption", encryption)
// config.Server.Merge("User", user)
// config.Server.Merge("Password", password)
config.Merge("Server", &ServerConfig{serverAddress, serverPort, encryption, user, password})
config.Merge("From", from)
config.Merge("To", strings.Split(to, ","))
config.Merge("Cc", strings.Split(cc, ","))
config.Merge("Bcc", strings.Split(bcc, ","))
config.Merge("Subject", subject)
// config.Merge("Text", text)
debug(dbg, "\n%s", config)
}

50
test_conf.toml Normal file
View file

@ -0,0 +1,50 @@
[default]
from = "me@domain.com"
to = ["test@dom.in","test@examle.com"]
cc = ["other@foo.com","name@bar.org"]
bcc = ["forever@alone.com"]
subject = "My favourite topic"
text = '''
Hello,
I am the crown prince of Nigeria.
I need to launder some money, would you help?
Greetings
'''
[default.server]
address = "1.3.1.2"
port = 587
encryption = "tls"
user = "faggiano@uccelli.net"
password = "yougetit"
[personal]
from = "notme@domain.com"
to = ["test@dom.in","test@examle.com"]
cc = ["other@foo.com","name@bar.org"]
bcc = ["forever@alone.com"]
subject = "My favourite topic"
text = '''
I am an h4X0r. I infected your computer.
You will follow this instructions or I will publish your
most personal pictures.
https://followthewhiterabbit.com
'''
[personal.server]
address = "10.13.12.10"
port = 25
encryption = "starttls"
user = "master@domain.local"
password = "yougetitagain"
[secret]
[secret.server]
address = "my.server.org"
port = 12345
encryption = "tls"
user = "me"