9

gmail アカウントを介してメールを送信するための簡単なスクリプトを作成しようとしています。でも初心者なのでそんなに簡単ではありません。私はグーグルを試しましたが、ハックを除いて、ヘルプや例はまったくありません.

問題は、tls-extra(または tls) を使用して STARTTLS 交換を開始する方法が見つからなかったことです。

わかりました、ここにコードがあります:

import Network
import Network.TLS.Extra
import System.IO
import Text.Printf

server = "smtp.gmail.com"
port   = 25 --that has to chage, I think

forever a = a >> forever a

main = test1

write :: Handle -> String -> IO ()
write h s  = do
    hPrintf h "%s\r\n" s
    printf    "> %s\n" s

listen :: Handle -> IO () 
listen h = forever $ hGetLine h >>= putStrLn

test1 = do h <- connectTo server (PortNumber (fromIntegral port))
           hSetBuffering h NoBuffering
           write h "EHLO"
           write h "STARTTLS"
           listen h

もう 1 つのことは、何が起こっているかを知るために listen 関数を使用することです。しかし、書き込みと一緒に使用する方法がわかりません。つまり、データを送信しているときにサーバー側で何が起こっているかを確認できるようにしたいと考えています。

問題を解決する可能性のある 2 つの関数を見つけました。

connectionClient :: CryptoRandomGen g => String -> String -> TLSParams -> g -> IO (TLSCtx Handle)
forkIO :: IO () -> IO ThreadId

1 つ目は tls 用で、2 つ目は同時に送受信するためのものです。しかし、それらを機能させることはできないようです。

ここで混乱しないことを願っています。助けていただければ幸いです。

PS: 英語は私の母国語ではありません。

編集:だから、私はいくつかの進歩を遂げました。

import Network
import Network.TLS
import Network.TLS.Extra
import System.IO
import Text.Printf
import Control.Monad (forever)
import Control.Concurrent (threadDelay)
import qualified Data.ByteString.Char8 as B
import Crypto.Random

serv :: String
serv = "smtp.gmail.com"
port :: Int
port   = 25 --that has to chage, I think

main :: IO ()
main = test1

write :: Handle -> String -> IO ()
write h s  = do
    hPrintf h "%s\r\n" s
    printf    "> %s\n" s

listen :: Handle -> IO ()
listen h = forever $ hGetLine h >>= putStrLn

printSock :: Handle -> String -> IO ()
printSock h s = do write h s
                   hGetLine h >>= putStrLn
                   threadDelay 25

params :: TLSParams
params=defaultParams {pConnectVersion=TLS12
                     ,pAllowedVersions=[TLS10, TLS11, TLS12]
                     ,pCiphers=ciphersuite_all}

test1 = do h <- connectTo serv (PortNumber (fromIntegral port))
           hSetBuffering h NoBuffering
           printSock h "EHLO"
           printSock h "STARTTLS"
           --google waits for tls handshake
           --the problem is from here
           g <- newGenIO :: IO SystemRandom
           tlsH <- client params g h
           handshake tlsH --the handshake is failling

それでも、その TLS ハンドシェイクをネゴシエートする方法がわかりません。

私は言わなければなりません、私は答えがないことに非常に驚いています。他にも数回問題がありましたが、コミュニティはすぐに助けてくれました。しかし、これは興味をそそるようには見えません (単なるコンスタテーションです)。ここ SO または #haskell または developmentpez.com でも。

とにかく、Google と tls に関するいくつかの指針を歓迎します。msmtp クライアント コードを確認しましたが、率直に言って、必要なレベルがありません。

4

2 に答える 2

1

何が問題を引き起こしているのか正確にはわかりませんが (私の SMTP は少し錆びています)、問題の一部は間違ったポートに接続していることだと思います。これらは、Google で SMTP を使用するための正しいパラメーターだと思います。

Gmail SMTP server address: smtp.gmail.com
Gmail SMTP user name: Your full Gmail address (e.g. example@gmail.com)
Gmail SMTP password: Your Gmail password
Gmail SMTP port: 465
Gmail SMTP TLS/SSL required: yes 

編集: Hackage を簡単に検索して、TLS/SSL を使用してユーザー名とパスワードでログインできる SMTP パッケージがあるかどうかを確認しましたが、何も表示されませんでした。(ただし、何かを見落としていた可能性があります!) 最も近いものは simplesmtpclient でした。SSL をサポートしているとは思いませんが、それを拡張したり、独自のものを作成するためのガイドとして使用したりできます。

于 2012-10-17T15:05:12.627 に答える