Estoy tratando de escribir un script simple para enviar un correo a través de mi cuenta de gmail. Pero soy un principiante, así que no es tan simple. Probé google pero no hice hackage, no hay ayuda ni ejemplos.Uso de tls-extra para smtp simple
El problema es que no encontré la manera de usar tls-extra (o tls) para iniciar el intercambio STARTTLS.
Ok, aquí está el código:
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
Otra cosa es que yo uso la función de escucha para saber lo que está pasando. Pero no puedo entender cómo usarlo junto con escribir. Es decir, me gustaría poder ver qué está sucediendo en el servidor mientras envío algunos datos.
me encontré con dos funciones que pueden resolver mis problemas:
connectionClient :: CryptoRandomGen g => String -> String -> TLSParams -> g -> IO (TLSCtx Handle)
forkIO :: IO() -> IO ThreadId
La primera para TLS y el segundo para enviar y recibir al mismo tiempo. Pero parece que no puede hacer que funcionen.
Espero no estar sucio aquí, cualquier ayuda sería apreciada.
PD: Inglés no es mi nativo.
EDITAR: Por lo tanto, he hecho algunos progresos.
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
Aún así, no puedo encontrar la manera de negociar ese tls handshake.
Tengo que decir que estoy bastante sorprendido por la falta de respuesta. Las otras pocas veces tuve un problema, la comunidad fue bastante rápida para ayudar. Pero esto no parece interesarse (solo una constatación). Aquí en SO o incluso en #haskell o developpez.com.
De todos modos algunos consejos sobre google y tls serían bienvenidos. He echado un vistazo al código del cliente msmtp pero francamente no tengo el nivel requerido.
Tengo exactamente el mismo problema. ¿Logramos averiguarlo? – Salil
No es realmente relevante para su pregunta, pero permítame señalar que 'forever' se define en las bibliotecas base. Ver [Hackage] (http://hackage.haskell.org/packages/archive/base/latest/doc/html/Control-Monad.html#v:forever). –