我正在尝试编写一个简单的脚本来通过我的 gmail 帐户发送邮件。但我是初学者,所以没那么简单。我尝试了谷歌,但除了hackage,根本没有帮助或示例。
问题是我没有找到使用 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
另一件事是我使用监听功能来了解发生了什么。但我不知道如何将它与 write 一起使用。也就是说,我希望能够在发送一些数据时看到服务器端发生了什么。
我发现了两个可以解决我的问题的功能:
connectionClient :: CryptoRandomGen g => String -> String -> TLSParams -> g -> IO (TLSCtx Handle)
forkIO :: IO () -> IO ThreadId
第一个用于 tls,第二个用于同时发送和接收。但似乎无法让它们工作。
我希望我不会在这里弄乱,任何帮助将不胜感激。
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 或developpez.com。
无论如何,一些关于谷歌和 tls 的指针将受到欢迎。我查看了 msmtp 客户端代码,但坦率地说,我没有所需的级别。