2014-03-01 29 views
2

我正在移植一些現有Python代碼去。一位負責通過Exchange服務器發送電子郵件(SMTP + STARTTLS)。現有(簡化)代碼如下所示:如何使用starttls從Go中的交換服務器連接和發送電子郵件?

import smtplib 
client = smtplib.SMTP("exchangeserver.com") 
client.starttls() 
client.login('user', 'password') 
client.sendmail('[email protected]', 
    ['[email protected]', '[email protected]'], 
    '..message..') 

我想用Go來做同樣的事情,非常感謝 - 謝謝。

回答

4

編輯:

這裏是一個使用tls連接設置的例子。我沒有一個測試反對,所以失敗對我的端部連接,但我懷疑這是你需要使它工作

package main 

import (
    "crypto/tls" 
    "fmt" 
    "log" 
    "net/smtp" 
) 

func main() { 
    var (
    host  = "smtp.google.com" 
    port  = 587 
    from  = "[email protected]" 
    password = "baz" 
    to  = []string{"[email protected]"} 
    msg  = []byte("This is my message") 
    auth  = smtp.PlainAuth("", from, password, "smtp.gmail.com") 
) 
    serverAddr := fmt.Sprintf("%s:%d", host, port) 

    conn, err := tls.Dial("tcp", serverAddr, nil) 
    if err != nil { 
    log.Printf("Error Dialing %s\n", err) 
    return 
    } 

    client, err := smtp.NewClient(conn, host) 
    if err != nil { 
    log.Printf("Error SMTP connection: %s\n", err) 
    return 
    } 

    if ok, _ := client.Extension("AUTH"); ok { 
    if err := client.Auth(auth); err != nil { 
     log.Printf("Error during AUTH %s\n", err) 
     return 
    } 
    } 

    if err := client.Mail(from); err != nil { 
    log.Printf("Error: %s\n", err) 
    return 
    } 

    for _, addr := range to { 
    if err := client.Rcpt(addr); err != nil { 
     log.Printf("Error: %s\n", err) 
     return 
    } 
    } 

    w, err := client.Data() 
    if err != nil { 
    log.Printf("Error: %s\n", err) 
    return 
    } 

    _, err = w.Write(msg) 
    if err != nil { 
    log.Printf("Error: %s\n", err) 
    return 

    } 

    err = w.Close() 
    if err != nil { 
    log.Printf("Error: %s\n", err) 
    return 

    } 

    client.Quit() 
} 

我覺得這樣的事情可能會奏效的。您必須對服務器,用戶/密碼等進行適當的更改。讓我知道您是否需要更多幫助。

package main 

import (
    "fmt" 
    "log" 
    "net/smtp" 
) 

func main() { 
    to := "[email protected]" 
    from := "[email protected]" 
    password := "myPassword" 
    subject := "subject line of email" 
    msg := "a one-line email message" 

    emailTemplate := `To: %s 
Subject: %s 

%s 
` 
    body := fmt.Sprintf(emailTemplate, to, subject, msg) 
    auth := smtp.PlainAuth("", from, password, "smtp.gmail.com") 
    err := smtp.SendMail(
    "smtp.gmail.com:587", 
    auth, 
    from, 
    []string{to}, 
    []byte(body), 
) 
    if err != nil { 
    log.Fatal(err) 
    } 
} 
+0

謝謝。您的示例適用於Gmail,但我試圖連接到Microsoft Exchange服務器(2013)並通過它發送電子郵件。因此,它可能需要創建一個SMTP客戶端[並在其上調用啓動TLS()](https://groups.google.com/forum/#!searchin/golang-nuts/starttls/golang-nuts/W95PXq99uns/n6pcKAFhT6kJ)。仍在試圖弄清楚,部分:) – sa125

+0

一個類似的例子:https://gist.github.com/chrisgillis/10888032 –

3

要擴大Cory LaNou's的回答,您可以在正常net.Conn使用STARTTLS。您需要定義一個tls.Config,然後使用它來升級連接以使用TLS。

下面的例子是基於科裏的答案,還搶斷從crypto/tls test files一些代碼用於創建RSA證書和私鑰。在生產中,你顯然會用真正的證書和密鑰來取代它們。

它可能需要變量的一些定製,以及一些改動tls.Config到適合您的環境。

package main 

import (
    "crypto/rsa" 
    "crypto/tls" 
    "encoding/hex" 
    "fmt" 
    "log" 
    "math/big" 
    "net" 
    "net/smtp" 
) 

func main() { 

    var (
     host  = "smtp.myexchange.com" 
     port  = 587 
     from  = "[email protected]" 
     password = "password" 
     to  = []string{"[email protected]"} 
     msg  = []byte("This is my message") 
     auth  = smtp.PlainAuth("", from, password, "smtp.myexchange.com") 
    ) 

    conf := new(tls.Config) 
    conf.Certificates = make([]tls.Certificate, 1) 
    conf.Certificates[0].Certificate = [][]byte{testRSACertificate} 
    conf.Certificates[0].PrivateKey = testRSAPrivateKey 
    conf.CipherSuites = []uint16{tls.TLS_RSA_WITH_RC4_128_SHA} 
    conf.InsecureSkipVerify = true 
    conf.MinVersion = tls.VersionSSL30 
    conf.MaxVersion = tls.VersionTLS10 
    serverAddr := fmt.Sprintf("%s:%d", host, port) 

    conn, err := net.Dial("tcp", serverAddr) 
    if err != nil { 
     log.Printf("Error Dialing %s\n", err) 
     return 
    } 

    client, err := smtp.NewClient(conn, host) 
    if err != nil { 
     log.Printf("Error SMTP connection: %s\n", err) 
     return 
    } 

    if err = client.StartTLS(conf); err != nil { 
     log.Printf("Error performing StartTLS: %s\n", err) 
     return 
    } 

    if ok, _ := client.Extension("AUTH"); ok { 
     if err := client.Auth(auth); err != nil { 
      log.Printf("Error during AUTH %s\n", err) 
      return 
     } 
    } 

    if err := client.Mail(from); err != nil { 
     log.Printf("Error: %s\n", err) 
     return 
    } 

    for _, addr := range to { 
     if err := client.Rcpt(addr); err != nil { 
      log.Printf("Error: %s\n", err) 
      return 
     } 
    } 

    w, err := client.Data() 
    if err != nil { 
     log.Printf("Error: %s\n", err) 
     return 
    } 

    _, err = w.Write(msg) 
    if err != nil { 
     log.Printf("Error: %s\n", err) 
     return 

    } 

    err = w.Close() 
    if err != nil { 
     log.Printf("Error: %s\n", err) 
     return 

    } 

    client.Quit() 
} 

// Code below from http://golang.org/src/pkg/crypto/tls/handshake_server_test.go 

func bigFromString(s string) *big.Int { 
    ret := new(big.Int) 
    ret.SetString(s, 10) 
    return ret 
} 

func fromHex(s string) []byte { 
    b, _ := hex.DecodeString(s) 
    return b 
} 

var testRSACertificate = fromHex("308202b030820219a00302010202090085b0bba48a7fb8ca300d06092a864886f70d01010505003045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c7464301e170d3130303432343039303933385a170d3131303432343039303933385a3045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c746430819f300d06092a864886f70d010101050003818d0030818902818100bb79d6f517b5e5bf4610d0dc69bee62b07435ad0032d8a7a4385b71452e7a5654c2c78b8238cb5b482e5de1f953b7e62a52ca533d6fe125c7a56fcf506bffa587b263fb5cd04d3d0c921964ac7f4549f5abfef427100fe1899077f7e887d7df10439c4a22edb51c97ce3c04c3b326601cfafb11db8719a1ddbdb896baeda2d790203010001a381a73081a4301d0603551d0e04160414b1ade2855acfcb28db69ce2369ded3268e18883930750603551d23046e306c8014b1ade2855acfcb28db69ce2369ded3268e188839a149a4473045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c746482090085b0bba48a7fb8ca300c0603551d13040530030101ff300d06092a864886f70d010105050003818100086c4524c76bb159ab0c52ccf2b014d7879d7a6475b55a9566e4c52b8eae12661feb4f38b36e60d392fdf74108b52513b1187a24fb301dbaed98b917ece7d73159db95d31d78ea50565cd5825a2d5a5f33c4b6d8c97590968c0f5298b5cd981f89205ff2a01ca31b9694dda9fd57e970e8266d71999b266e3850296c90a7bdd9") 

var testRSAPrivateKey = &rsa.PrivateKey{ 
    PublicKey: rsa.PublicKey{ 
     N: bigFromString("131650079503776001033793877885499001334664249354723305978524647182322416328664556247316495448366990052837680518067798333412266673813370895702118944398081598789828837447552603077848001020611640547221687072142537202428102790818451901395596882588063427854225330436740647715202971973145151161964464812406232198521"), 
     E: 65537, 
    }, 
    D: bigFromString("29354450337804273969007277378287027274721892607543397931919078829901848876371746653677097639302788129485893852488285045793268732234230875671682624082413996177431586734171663258657462237320300610850244186316880055243099640544518318093544057213190320837094958164973959123058337475052510833916491060913053867729"), 
    Primes: []*big.Int{ 
     bigFromString("11969277782311800166562047708379380720136961987713178380670422671426759650127150688426177829077494755200794297055316163155755835813760102405344560929062149"), 
     bigFromString("10998999429884441391899182616418192492905073053684657075974935218461686523870125521822756579792315215543092255516093840728890783887287417039645833477273829"), 
    }, 
} 

Playground

相關問題