haskell的Gmail TLS hanshake故障

haskell的Gmail TLS hanshake故障,haskell,gmail,ssl,handshake,Haskell,Gmail,Ssl,Handshake,我正试图写一个小脚本,通过gmail发送电子邮件。 我可以连接到gmail,但当我尝试hanshake时,它失败了。 有什么能让握手成功的建议吗 代码如下: import Network.Socket import Network import Network.TLS import Network.TLS.Extra import Crypto.Random import Data.CertificateStore -- to remove import System.Certificate.

我正试图写一个小脚本,通过gmail发送电子邮件。
我可以连接到gmail,但当我尝试hanshake时,它失败了。
有什么能让握手成功的建议吗

代码如下:

import Network.Socket
import Network
import Network.TLS
import Network.TLS.Extra

import Crypto.Random
import Data.CertificateStore -- to remove
import System.Certificate.X509 --to use I think

import System.IO
import Text.Printf

import Control.Monad (forever)
import qualified Data.ByteString.Char8 as B


main :: IO ()
main = emailGmail2

tListen :: Context -> IO ()
tListen ctx =
    forever $ recvData ctx >>= B.putStrLn

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

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

emailGmail2 = do
    let
        host = "smtp.gmail.com"
        port = 587
        params = defaultParamsClient
    g <- newGenIO :: IO SystemRandom
    h <- connectTo host (PortNumber (fromIntegral port))
    hSetBuffering h LineBuffering
    cWrite h "EHLO"
    cWrite h "STARTTLS"
    --cListen h
    con <- contextNewOnHandle h params g
    handshake con
    tListen con
导入网络套接字
导入网络
导入网络.TLS
导入Network.TLS.Extra
导入加密。随机
导入Data.CertificateStore--删除
导入System.Certificate.X509--我认为
导入系统.IO
导入文本.Printf
进口管制.单子(永远)
将限定数据.ByteString.Char8作为B导入
main::IO()
main=emailGmail2
tListen::Context->IO()
tListen ctx=
永久$recvData ctx>>=B.putStrLn
cWrite::Handle->String->IO()
cWrite h s=do
hPrintf h“%s\r\n”s
printf“>%s\n”s
cListen::Handle->IO()
克莱斯滕h=
永久$hGetLine h>>=putStrLn
emailGmail2=do
允许
host=“smtp.gmail.com”
端口=587
params=defaultParamsClient

g此错误部分与处理SMTP协议有关。查看通过TLS的安全SMTP的RFC,有一个示例客户机-服务器对话

S: <waits for connection on TCP port 25>
C: <opens connection>
S: 220 mail.imc.org SMTP service ready
C: EHLO mail.ietf.org
S: 250-mail.imc.org offers a warm hug of welcome
S: 250 STARTTLS
C: STARTTLS
S: 220 Go ahead
C: <starts TLS negotiation>
C & S: <negotiate a TLS session>
C & S: <check result of negotiation>
C: <continues by sending an SMTP command>
. . .
S:
C:
S:220 mail.imc.org SMTP服务就绪
C:EHLO mail.ietf.org
S:250-mail.imc.org热烈欢迎您的到来
S:250标准
C:开始
S:220请讲
C:
C&S:
C&S:
C:
. . .
在您的代码中,您正在发送EHLO和STARTTLS,然后立即开始握手协商。我相信现在发生的事情是,服务器仍在发送上述250和220个代码中的一些代码,而TLS库正试图将这些代码解释为导致问题的TLS消息

事实上,如果我打开另一个终端,用netcat监听端口587,并将程序更改为连接到本地主机,如果我用“250 STARTTLS”回复,我会收到相同的错误

改变这一点让程序对我起作用:

import Network.Socket
import Network
import Network.TLS
import Network.TLS.Extra

import Crypto.Random
import qualified Crypto.Random.AESCtr as RNG
import System.IO
import Text.Printf

import Control.Monad (when)
import Data.List (isPrefixOf)

ciphers :: [Cipher]
ciphers =
        [ cipher_AES128_SHA1
        , cipher_AES256_SHA1
        , cipher_RC4_128_MD5
        , cipher_RC4_128_SHA1
        ]

main :: IO ()
main = emailGmail2

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

cWaitFor :: Handle -> String -> IO ()
cWaitFor h str = do
    ln <- hGetLine h
    putStrLn ln
    when (not $ str `isPrefixOf` ln) (cWaitFor h str)

emailGmail2 = do
    let
        host = "smtp.gmail.com"
        port = 587
        params = defaultParamsClient{pCiphers = ciphers}
    g <- RNG.makeSystem
    h <- connectTo host (PortNumber (fromIntegral port))
    hSetBuffering h LineBuffering
    cWrite h "EHLO"
    cWaitFor h "250-STARTTLS"
    cWrite h "STARTTLS"
    cWaitFor h "220"
    con <- contextNewOnHandle h params g
    handshake con
    bye con
导入网络套接字
导入网络
导入网络.TLS
导入Network.TLS.Extra
导入加密。随机
将合格的Crypto.Random.AESCtr作为RNG导入
导入系统.IO
导入文本.Printf
导入控制.Monad(何时)
导入数据列表(isPrefixOf)
密码::[密码]
密码=
[密码\u AES128\u SHA1
,密码_AES256_SHA1
,cipher_RC4_128_MD5
,cipher_RC4_128_SHA1
]
main::IO()
main=emailGmail2
cWrite::Handle->String->IO()
cWrite h s=do
hPrintf h“%s\r\n”s
printf“>%s\n”s
cWaitFor::句柄->字符串->IO()
cwaith str=do

哇!欢迎来到SO,很好的开始。谢谢,我查看了射频,但没有发现错误。我会试着把它变成一个lib(我有技能吗?),因为它是默认情况下应该出现的东西(我的意见)。