diff options
| -rw-r--r-- | config.go | 129 | ||||
| -rw-r--r-- | crypt.go | 92 | ||||
| -rw-r--r-- | main.go | 113 | ||||
| -rw-r--r-- | utils.go | 59 |
4 files changed, 393 insertions, 0 deletions
diff --git a/config.go b/config.go new file mode 100644 index 0000000..d371bc9 --- /dev/null +++ b/config.go @@ -0,0 +1,129 @@ +package main + +import ( + "bytes" + "fmt" + "os" + "io/ioutil" + "strconv" + "github.com/BurntSushi/toml" +) + +type Config struct { + Mailacc MailAccount `toml:"MailAccount"` + Massmail MassMail `toml:"MassMail"` +} +type MailAccount struct { + Address string //`toml:"address"` + Name string //`toml:"name"` + Smtpurl string //`toml:"smtpurl"` + Port int //`toml:"port"` + Accountname string //`toml:"accountname"` + Accountpwd string //`toml:"accountpwd"` +} +type MassMail struct { + Listfile string //`toml:"listfile"` + Mailfile string //`toml:"mailfile"` + Bannerfile string //`toml:"bannerfile"` + Anrede []string //`toml:"anrede"` + Subject string //`toml:"subject"` +} + +var config Config + +func initConf() { + goodconf := false + for !goodconf { + if _, err := toml.DecodeFile("myconfig.toml", &config); err != nil { + fmt.Println(err) + makeNewTOML(false) + }else{ + showConfig() + //fmt.Println("Loaded Config:\n",config) + if isSure("Is this Configuration Correct?") { + goodconf = true + }else{ + if isSure("Enter new Configuration?"){ + makeNewTOML(true) + }else{ + fmt.Println("I Really Dont think I can Help You then...! Goodbye.") + os.Exit(0) + } + } + + } + } +} + +func makeNewTOML(gibts bool) { + if gibts { + fmt.Println("Editing Configuration File\nPress [Enter] to keep the Current setting") + }else{ + fmt.Println("Making new Configuration File") + + arr := []string{"", "", ""} + ma0 := MailAccount{"","","",0,"",""} + mm0 := MassMail{"","","",arr,""} + config = Config{ma0,mm0} + } + fmt.Println("Enter properties of the Send-account\n") + email := getNewInput("Email Account to send from: ",config.Mailacc.Address) + mailname := getNewInput("Name for this Account: ",config.Mailacc.Name) + smtpurl := getNewInput("URL of the SMTP server: ",config.Mailacc.Smtpurl) + port := 0 + var err error + if gibts { + fmt.Println("Current:",config.Mailacc.Port) + } + for{ + strport := getInput("Port of the SMTP Server: ") + port,err = strconv.Atoi(strport) + if err != nil { + fmt.Println(" Please insert a valid Port number!!!") + }else {break} + } + logname := getNewInput("Login name of the Account: ",config.Mailacc.Accountname) + logpwd := Encrypt(getInput("Password of the Account: ")) + + ma := MailAccount{email,mailname,smtpurl,port,logname,logpwd} + + fmt.Println("\nEnter properties of the Mass Mail\n") + listfile := getNewInput("Which .csv file should be used?: ",config.Massmail.Listfile) + mailfile := getNewInput("What .html template to use?: ",config.Massmail.Mailfile) + bannerfile := getNewInput("Name of the banner image: ",config.Massmail.Bannerfile) + subject := getNewInput("Subject of the Mass Mail: ",config.Massmail.Subject) + if gibts { + fmt.Println("Current Salutations:",config.Massmail.Anrede) + } + anredemale := getInput("Salutation for a Male recipient: ") + anredeneut := getInput("Salutation for a unknown recipient: ") + anredefemale := getInput("Salutation for a Female recipient: ") + + strarr := []string{anredemale, anredeneut, anredefemale} + mm := MassMail{listfile, mailfile, bannerfile, strarr, subject} + conf := Config{ma,mm} + + buf := new(bytes.Buffer) + err = toml.NewEncoder(buf).Encode(conf) + if err != nil { + panic(err) + }else{ + //fmt.Println("Conffile:\n",buf.String()) + fmt.Println("Writing Configuration File") + err = ioutil.WriteFile("myconfig.toml", buf.Bytes(), 0644) + checkErr(err) + } + +} + +func showConfig() { + buf := new(bytes.Buffer) + err := toml.NewEncoder(buf).Encode(config) + if err != nil { + panic(err) + }else{ + fmt.Println("Configuration:\n",buf.String()) + } +} + + diff --git a/crypt.go b/crypt.go new file mode 100644 index 0000000..662184c --- /dev/null +++ b/crypt.go @@ -0,0 +1,92 @@ +package main + +import ( + "encoding/base64" + "crypto/aes" + "crypto/cipher" + "crypto/rand" + "fmt" + "io" + "os" + //"strconv" +) + +func cryptexample() { + fmt.Println("Testing Cryptics") + //key := "123456789012345678901234" // Needs to be 32 bytes long + //key := "Have some of the beautiful ideas" + plaintext1 := "Hello! You Fool! I Love You" + plaintext2 := "Somefancy Password" + foo := Encrypt(plaintext1) + fook := Decrypt(foo) + fmt.Printf("%s -> %s\n",plaintext1,foo) + fmt.Printf("%s -> %s\n\n",foo,fook) + bar := Encrypt(plaintext2) + barn := Decrypt(bar) + fmt.Printf("%s -> %s\n",plaintext2,bar) + fmt.Printf("%s -> %s\n\n",bar,barn) + os.Exit(0) +} + + //key := "123456789012345678901234" // Needs to be 32 bytes long +var keystr string = "Have some of the beautiful ideas" + +func encodeBase64(inp string) string { + b := []byte(inp) + return base64.StdEncoding.EncodeToString(b) +} + +func decodeBase64(s string) string { + data, err := base64.StdEncoding.DecodeString(s) + if err != nil { panic(err) } + return string(data) +} + +func Encrypt(textstr string) string { + text := []byte(textstr) + key := []byte(keystr) + + //fmt.Println(text) + block, err := aes.NewCipher([]byte(key)) + checkErr(err) + + b := base64.StdEncoding.EncodeToString(text) + ciphertext := make([]byte, aes.BlockSize+len(b)) + iv := ciphertext[:aes.BlockSize] + _, err = io.ReadFull(rand.Reader, iv) + checkErr(err) + cfb := cipher.NewCFBEncrypter(block, iv) + cfb.XORKeyStream(ciphertext[aes.BlockSize:], []byte(b)) + return encodeBase64(string(ciphertext)) + +} + +func Decrypt(textstr string) string { + + text := []byte(decodeBase64(textstr)) + key := []byte(keystr) + //checkErr(err) + + block, err := aes.NewCipher(key) + checkErr(err) + if len(text) < aes.BlockSize { + return "GEEEH SCHIESSEN! ZU Kurz?" + //return nil, errors.New("ciphertext too short") + } + iv := text[:aes.BlockSize] + text = text[aes.BlockSize:] + cfb := cipher.NewCFBDecrypter(block, iv) + cfb.XORKeyStream(text, text) + //data, err := base64.StdEncoding.DecodeString(string(text[aes.BlockSize:])) + data, err := base64.StdEncoding.DecodeString(string(text)) + checkErr(err) + return string(data) + //if err != nil { panic(err) } + //ciphertext := decodeBase64(text) + //cfb := cipher.NewCFBEncrypter(block, iv) + //plaintext := make([]byte, len(ciphertext)) + //cfb.XORKeyStream(plaintext, ciphertext) + //return string(plaintext) +} + + @@ -0,0 +1,113 @@ +package main + +import ( + "bytes" + "fmt" + "html/template" + "io" + "os" + "encoding/csv" + "strconv" + + "gopkg.in/gomail.v2" +) + +type Customer struct { + Name string + email string + Anrede string + gender int +} +type MailList struct { + customers []Customer +} + +var list []Customer +var filename string = "testlist.csv" + +func init() { + //cryptexample() + fmt.Println(" Starting MassMailer\n ##################################\n") + initConf() + + file, err := os.Open(config.Massmail.Listfile) + if err != nil { + panic(err) + }else{ + fmt.Println("\n",config.Massmail.Listfile, "opened Successfully!") + } + defer file.Close() + + reader := csv.NewReader(file) + reader.Comma = ';' + lineCount := 0 + + + + for { + line , erro := reader.Read() + if erro == io.EOF { + break + }else if erro != nil { + panic(erro) + } + gen, err := strconv.Atoi(line[2]) + if err != nil { + panic(err) + } + anrede := config.Massmail.Anrede[(gen+1)] + cn := Customer{Name: line[0], email: line[1], Anrede: anrede, gender: gen} + list = append(list, cn) + fmt.Println(cn) + lineCount += 1 + } + fmt.Println("\n All Customers:",lineCount) +} + +func main() { + if isSure("Send the Mail to all Customers?"){ + for _ , c := range list{ + err := SendMail(c) + if err==nil{ + fmt.Println("Sending Mail to",c.Anrede,c.Name,"Done Successful") + }else{ + panic(err) + } + } + }else{ + fmt.Println(" ok... bye then!") + } +} + +func SendMail(cust Customer) error { + t, err := template.ParseFiles(config.Massmail.Mailfile) + if err != nil { + return err + } + buf := new(bytes.Buffer) + err = t.Execute(buf, cust) + if err != nil { + return err + } + pass := Decrypt(config.Mailacc.Accountpwd) + + m := gomail.NewMessage() + m.SetHeader("From", m.FormatAddress(config.Mailacc.Address , config.Mailacc.Name)) + m.SetHeader("To", cust.email) + //m.SetAddressHeader("Cc", "test@mail.com", "Dan") + m.SetHeader("Subject", config.Massmail.Subject) + m.SetBody("text/html", buf.String()) + //m.Attach("someimage.jpg", gomail.Rename("logo.jpg")) + m.Embed(config.Massmail.Bannerfile) + + d := gomail.NewDialer(config.Mailacc.Smtpurl, config.Mailacc.Port, config.Mailacc.Accountname, pass) + + // Send the email to Bob, Cora and Dan. + if err := d.DialAndSend(m); err != nil { + fmt.Println("Connecting to Email Server Failed! Check your Accountname and Password\nError:") + panic(err) + } + return nil +} + + diff --git a/utils.go b/utils.go new file mode 100644 index 0000000..4daa4fc --- /dev/null +++ b/utils.go @@ -0,0 +1,59 @@ +package main + +import ( + "fmt" + "bufio" + "os" + "strings" +) + +func isSure(quest string) bool { + fmt.Printf("%s (type 'y/Y/yes' to confirm) : ",quest) + in := bufio.NewReader(os.Stdin) + line, err := in.ReadString('\n') + line = strings.TrimSuffix(line, "\n") + //line = strings.TrimSuffix(line, "\r\n") //for Windows + checkErr(err) + + if ( line == "yes" || line == "y" || line == "Y") { + return true + } else { + return false + } +} + +func checkErr(err error) { + if err != nil { + panic(err) + } +} + +func getInput(quest string) string { + fmt.Print(quest) + in := bufio.NewReader(os.Stdin) + line, err := in.ReadString('\n') + line = strings.TrimSuffix(line, "\n") + //line = strings.TrimSuffix(line, "\r\n")//for windows + checkErr(err) + return line +} + +func getNewInput(quest,old string) string { + if old != "" { + fmt.Println("Current:",old) + } + fmt.Print(quest) + in := bufio.NewReader(os.Stdin) + line, err := in.ReadString('\n') + line = strings.TrimSuffix(line, "\n") + //line = strings.TrimSuffix(line, "\r\n")//for windows + checkErr(err) + if line == "" { + return old + }else{ + return line + } +} + + + |
