Compare commits

...

30 Commits

Author SHA1 Message Date
Sarah Vaupel
1d346b07fb 0.3.4.1 -> 0.4.0.2 2025-06-12 14:49:44 +02:00
Leza Morais Lutonda
6fe62d91af
Merge pull request #23 from limick/master
Bump dependency on 'network' package so it compiles with LTS-13
2019-01-17 12:31:55 +01:00
limick
4b2ea920e9 Bump dependency on 'network' package so it compiles with Stackage LTS-13. 2019-01-06 12:02:17 +02:00
Leza Lutonda
9bb3c2299f Bump version number to 0.3.4.0. Solves fpco/stackage#2693 2017-08-01 15:42:04 +01:00
Leza Lutonda
94266dd970 Update dependencies. See fpco/stackage#2693 2017-08-01 14:59:33 +01:00
Leza Lutonda (Lemol-C)
631a0bcbbb Fix a bun in the smtp example. 2016-07-29 14:30:00 +01:00
Leza Morais Lutonda (Lemol-C)
00602e297b Bump version number to 0.3.3.0 2016-04-25 00:04:14 +01:00
Leza Morais Lutonda
48a2c8c1c3 Merge pull request #17 from k0ral/master
Derive Eq, Ord and Show instances for Settings data type
2016-04-24 23:44:17 +01:00
koral
7432711d62 Derive Eq, Ord and Show instances for Settings data type 2016-04-23 11:27:42 +02:00
Leza Morais Lutonda (Lemol-C)
702d54f76d Set lemol as a maintainer 2015-11-09 03:37:28 -05:00
Daniel P. Wright
3bbb4a6e05 Merge pull request #15 from lemol/master
Bump HaskellNet version to <0.6
2015-11-09 07:35:17 +09:00
Leza Morais Lutonda (Lemol-C)
61969afabf Bump HaskellNet version to <0.6
(see fpco/stackage#960)
2015-11-06 03:07:03 -05:00
Daniel P. Wright
a777a369d4 Bump version number to 0.3.1.0 2015-10-29 11:50:10 +09:00
Daniel P. Wright
f7e895fb06 Merge pull request #13 from da-x/bump-tls-version
Bump tls version dep, after having verified it worked with tls-1.3.*
2015-09-28 16:21:15 +09:00
Dan Aloni
35c03e8f84 Bump tls version dep, after having verified it worked with tls-1.3.* 2015-09-25 20:03:49 +03:00
Daniel P. Wright
ec5c163e7a Bump version number to 0.3.0.0
Commit bc814b6345 renames one of the
functions, making this a backwards-incompatible change, so I'm upping
the version number to 0.3.0.0 even though the other changes are
relatively minor.
2015-04-20 08:26:00 +09:00
Daniel P. Wright
de90b9b120 Merge pull request #12 from lemol/master
Update gmail example
2015-04-09 15:09:15 +09:00
Leza Morais Lutonda (Lemol-C)
717f8e202a Update gmail example 2015-04-08 23:58:44 -04:00
Daniel P. Wright
9357f7e609 Merge pull request #11 from lemol/master
Re-export Network.HaskellNet.* modules
2015-04-09 09:38:31 +09:00
Leza Morais Lutonda (Lemol-C)
bd46b74785 Make HaskellNet.X.SSL re-exports HaskellNet.X and SSL.Settings
see dpwright#10
2015-04-08 13:26:10 -04:00
Leza Morais Lutonda (Lemol-C)
e61f8db1bc Update gitignore 2015-04-08 12:57:59 -04:00
Daniel P. Wright
c9c0127b6d Merge pull request #9 from lemol/master
Rename sslDisableCertficateValidation to sslDisableCertificateValidation
2015-01-05 09:45:35 +09:00
Leza Morais Lutonda (Lemol-C)
bc814b6345 Rename sslDisableCertficateValidation to sslDisableCertificateValidation 2015-01-04 02:09:27 -05:00
Daniel P. Wright
2dc5878f29 Merge pull request #8 from lemol/master
Allow connection with disabled certificate validation
2014-12-09 12:35:11 +09:00
Leza Morais Lutonda (Lemol-C)
4fd67bbf72 Allow connection with disabled certificate validation 2014-12-08 21:14:38 -05:00
Daniel P. Wright
3ded1c8aef Bump version number 2014-10-23 10:24:35 +09:00
Daniel P. Wright
28ec9b955b Allow NoUpperBounds build to fail
Also set fast_finish to true
2014-10-23 10:23:47 +09:00
Daniel P. Wright
8930d7c983 Manually specify Travis build matrix
Build the normal build with GHC versions 7.4, 7.6 and 7.8, and the
NoUpperBounds build with GHC version 7.8 only.
2014-10-23 10:11:49 +09:00
Daniel P. Wright
9a1f4856db Add NoUpperBounds flag for testing latest packages 2014-10-23 10:09:32 +09:00
Daniel P. Wright
9751145745 Update network dependency to include versions < 2.7 2014-10-23 10:01:05 +09:00
13 changed files with 232 additions and 47 deletions

31
.gitignore vendored
View File

@ -1 +1,32 @@
# Linux
*~
.directory
# Vim
[._]*.s[a-w][a-z]
[._]s[a-w][a-z]
*.un~
Session.vim
.netrwhist
*~
tags
# Haskell
dist
cabal-dev
*.o
*.hi
*.chi
*.chs.h
*.dyn_o
*.dyn_hi
.virtualenv
.hpc
.hsenv
.cabal-sandbox/
cabal.sandbox.config
cabal.config
*.prof
*.aux
*.hp
.stack-work/

View File

@ -1,5 +1,6 @@
language: haskell
ghc:
- 7.8
- 7.6
- 7.4
matrix:
fast_finish: true
include:
- ghc: 7.10
- ghc: 7.8

16
CHANGELOG.md Normal file
View File

@ -0,0 +1,16 @@
# Revision history for HaskellNet-SSL
## 0.4.0.0 -- 2025-01-07
- drop support for connection in favour of crypton-connection
- compatibility with GHCs up to ghc 9.8 (bump base and bytestring)
- fix example
- add tested-with stanza
## 0.4.0.1 -- 2025-01-17
- Ignore 502 error on helo - fixes communication with some servers
## 0.4.0.1 -- 2025-02-15
- bump data-default and network

View File

@ -1,19 +1,24 @@
name: HaskellNet-SSL
synopsis: Helpers to connect to SSL/TLS mail servers with HaskellNet
version: 0.2.5.1
version: 0.4.0.2
description: This package ties together the HaskellNet and connection
packages to make it easy to open IMAP and SMTP connections
over SSL.
homepage: https://github.com/dpwright/HaskellNet-SSL
tested-with: GHC ==9.4.8 || ==9.6.5 || ==9.8.2
license: BSD3
license-file: LICENSE
author: Daniel P. Wright
maintainer: dani@dpwright.com
maintainer: Leza M. Lutonda <lemol-c@outlook.com>, dani@dpwright.com, contact@mangoiv.com
copyright: (c) 2013 Daniel P. Wright
category: Network
build-type: Simple
cabal-version: >=1.8
data-files: README.md
cabal-version: 1.18
extra-doc-files: README.md, CHANGELOG.md
flag network-bsd
description: Get Network.BSD from the network-bsd package
default: True
source-repository head
type: git
@ -22,15 +27,30 @@ source-repository head
library
hs-source-dirs: src
ghc-options: -Wall
default-language: Haskell2010
exposed-modules: Network.HaskellNet.IMAP.SSL
Network.HaskellNet.POP3.SSL
Network.HaskellNet.SMTP.SSL
Network.HaskellNet.SSL
other-modules: Network.HaskellNet.SSL.Internal
build-depends: base >= 4 && < 5,
HaskellNet >= 0.3 && < 0.5,
tls == 1.2.*,
connection == 0.2.*,
network >= 2.4 && < 2.6,
bytestring,
data-default
HaskellNet >= 0.3 && < 0.7,
crypton-connection >= 0.3.1 && < 0.5,
bytestring >= 0.9 && < 0.13,
data-default >= 0.2 && < 0.9
if flag(network-bsd)
build-depends: network >= 3.0 && < 3.3,
network-bsd >= 2.7 && < 2.9
else
build-depends: network >= 2.4 && < 3.3
executable HaskellNet-SSL-example
hs-source-dirs: examples
main-is: gmail.hs
other-modules:
build-depends: base,
HaskellNet-SSL,
HaskellNet,
bytestring
default-language: Haskell2010

View File

@ -1,13 +1,12 @@
HaskellNet-SSL
--------------
# HaskellNet-SSL
[![Build Status](https://travis-ci.org/dpwright/HaskellNet-SSL.svg?branch=master)](https://travis-ci.org/dpwright/HaskellNet-SSL)
[![haskell ci](https://github.com/dpwright/HaskellNet-SSL/actions/workflows/haskell.yml/badge.svg)](https://github.com/dpwright/HaskellNet-SSL/actions/workflows/haskell.yml)
This package ties together the excellent [HaskellNet][HaskellNet] and
[connection][connection] packages to make it easy to open IMAP and SMTP
[crypton-connection][crypton-connection] packages to make it easy to open IMAP and SMTP
connections over SSL. This is a simple "glue" library; all credit for a)
connecting to IMAP/SMTP servers and b) making an SSL connection goes to the
aforementioned libraries.
[HaskellNet]: https://github.com/jtdaugherty/HaskellNet
[connection]: https://github.com/vincenthz/hs-connection
[crypton-connection]: https://github.com/kazu-yamamoto/crypton-connection

6
cabal.project Normal file
View File

@ -0,0 +1,6 @@
packages: .
allow-newer:
, HaskellNet:base
, HaskellNet:network
, HaskellNet:data-default

View File

@ -1,42 +1,54 @@
{-# LANGUAGE OverloadedStrings #-}
import Network.HaskellNet.IMAP
import Network.HaskellNet.IMAP.SSL
import Network.HaskellNet.IMAP.SSL
import Network.HaskellNet.SMTP.SSL as SMTP
import Network.HaskellNet.SMTP
import Network.HaskellNet.SMTP.SSL
import Network.HaskellNet.SSL
import Network.HaskellNet.Auth (AuthType(LOGIN))
import Network.HaskellNet.Auth (AuthType(LOGIN), Password)
import Network.Mail.Mime
import qualified Data.ByteString.Char8 as B
import Data.String
username :: IsString s => s
username = "username@gmail.com"
password :: Password
password = "password"
recipient :: Address
recipient = "someone@somewhere.com"
imapTest :: IO ()
imapTest = do
c <- connectIMAPSSLWithSettings "imap.gmail.com" cfg
login c username password
mboxes <- list c
mapM_ print mboxes
select c "INBOX"
msgs <- search c [ALLs]
let firstMsg = head msgs
msgs@(firstMsg : _) <- search c [ALLs]
msgContent <- fetch c firstMsg
B.putStrLn msgContent
logout c
where cfg = defaultSettingsIMAPSSL { sslMaxLineLength = 100000 }
smtpTest :: IO ()
smtpTest = doSMTPSTARTTLS "smtp.gmail.com" $ \c -> do
r@(rsp, _) <- sendCommand c $ AUTH LOGIN username password
if rsp /= 235
then print r
else sendMail username [recipient] mailContent c
where mailContent = subject `B.append` body
subject = "Subject: Test message\r\n\r\n"
body = "This is a test message"
authSucceed <- SMTP.authenticate LOGIN username password c
if authSucceed
then do
mail <- simpleMail
recipient
username
subject
body
mempty
mempty
sendMail mail c -- recipient username subject body
else print "Authentication error."
where subject = "Test message"
body = "This is a test message"
main :: IO ()
main = smtpTest >> imapTest >> return ()
main = do
smtpTest
imapTest

View File

@ -1,9 +1,13 @@
-- | IMAP SSL Connections
module Network.HaskellNet.IMAP.SSL
( -- * Establishing connection
connectIMAPSSL
, connectIMAPSSLWithSettings
-- * Settings
, Settings(..)
, defaultSettingsIMAPSSL
-- * Network.HaskellNet.IMAP re-exports
, module Network.HaskellNet.IMAP
) where
import Network.HaskellNet.IMAP.Connection
@ -12,11 +16,14 @@ import Network.HaskellNet.SSL
import Network.HaskellNet.SSL.Internal
-- | Create IMAP connection with default settings
connectIMAPSSL :: String -> IO IMAPConnection
connectIMAPSSL hostname = connectIMAPSSLWithSettings hostname defaultSettingsIMAPSSL
-- | Create IMAP connection with given settings
connectIMAPSSLWithSettings :: String -> Settings -> IO IMAPConnection
connectIMAPSSLWithSettings hostname cfg = connectSSL hostname cfg >>= connectStream
-- | Default IMAP SSL settings, port 993
defaultSettingsIMAPSSL :: Settings
defaultSettingsIMAPSSL = defaultSettingsWithPort 993

View File

@ -3,7 +3,10 @@ module Network.HaskellNet.POP3.SSL
connectPop3SSL
, connectPop3SSLWithSettings
-- * Settings
, Settings(..)
, defaultSettingsPop3SSL
-- * Network.HaskellNet.POP3 re-exports
, module Network.HaskellNet.POP3
) where
import Network.HaskellNet.POP3.Connection

View File

@ -10,8 +10,11 @@ module Network.HaskellNet.SMTP.SSL
, doSMTPSTARTTLS
, doSMTPSTARTTLSWithSettings
-- * Settings
, Settings(..)
, defaultSettingsSMTPSSL
, defaultSettingsSMTPSTARTTLS
-- * Network.HaskellNet.SMTP re-exports
, module Network.HaskellNet.SMTP
) where
import Network.HaskellNet.SMTP
@ -45,10 +48,12 @@ connectSTARTTLS hostname cfg = do
(bs, startTLS) <- connectPlain hostname cfg
greeting <- bsGetLine bs
failIfNot bs 220 $ parseResponse greeting
failIfNot bs 220 $ parse $ B.unpack greeting
hn <- getHostName
bsPut bs $ B.pack ("HELO " ++ hn ++ "\r\n")
getResponse bs >>= failIfNotEx bs (`elem` [250, 502])
bsPut bs $ B.pack ("EHLO " ++ hn ++ "\r\n")
getResponse bs >>= failIfNot bs 250
bsPut bs $ B.pack "STARTTLS\r\n"
getResponse bs >>= failIfNot bs 220
@ -57,15 +62,22 @@ connectSTARTTLS hostname cfg = do
prefixRef <- newIORef [greeting]
return $ bs {bsGetLine = prefixedGetLine prefixRef (bsGetLine bs)}
where parseResponse = parse . B.unpack
parse s = (getCode s, s)
where getFinalResponse bs = do
line <- fmap B.unpack $ bsGetLine bs
if (line !! 3) == '-' then getFinalResponse bs else return line
parse s = (getCode s, s)
getCode = read . head . words
getResponse bs = liftM parseResponse $ bsGetLine bs
getResponse bs = liftM parse $ getFinalResponse bs
failIfNot :: BSStream -> Integer -> (Integer, String) -> IO ()
failIfNot bs code (rc, rs) = when (code /= rc) closeAndFail
where closeAndFail = bsClose bs >> fail ("cannot connect to server: " ++ rs)
-- | Extended version of fail if, can support multiple statuses
failIfNotEx :: BSStream -> (Integer -> Bool) -> (Integer, String) -> IO ()
failIfNotEx bs f (rc, rs) = unless (f rc) closeAndFail
where closeAndFail = bsClose bs >> fail ("cannot connect to server: " ++ rs)
-- This is a bit of a nasty hack. Network.HaskellNet.SMTP.connectStream
-- expects to receive a status 220 from the server as soon as it connects,
-- but we've intercepted it in order to establish a STARTTLS connection.

View File

@ -1,19 +1,28 @@
{-# LANGUAGE CPP #-}
module Network.HaskellNet.SSL
( Settings (..)
, defaultSettingsWithPort
) where
#if MIN_VERSION_network(3,0,0)
import Network.Socket (PortNumber)
#else
import Network.Socket.Internal (PortNumber)
#endif
-- | Settings for configuring HaskellNet connections
data Settings = Settings
{ sslPort :: PortNumber
, sslMaxLineLength :: Int
, sslLogToConsole :: Bool
}
{ sslPort :: PortNumber -- ^ Port number to connect to
, sslMaxLineLength :: Int -- ^ Max line lengths
, sslLogToConsole :: Bool -- ^ Log info to console
, sslDisableCertificateValidation :: Bool -- ^ Disable certificate validation
} deriving(Eq, Ord, Show)
-- | Construct default settings for a port
defaultSettingsWithPort :: PortNumber -> Settings
defaultSettingsWithPort p = Settings
{ sslPort = p
, sslMaxLineLength = 10000
, sslLogToConsole = False
, sslDisableCertificateValidation = False
}

View File

@ -28,6 +28,7 @@ connectionToStream c cfg = BSStream
, bsClose = connectionClose c
, bsIsOpen = return True
, bsGetLine = connectionGetLine maxl c >>= withLog "RECV"
, bsWaitForInput = connectionWaitForInput c
} where maxl = sslMaxLineLength cfg
withLog = if sslLogToConsole cfg then logToConsole
else flip (const . return)
@ -41,13 +42,15 @@ connectSSL :: String -> Settings -> IO BSStream
connectSSL hostname cfg = do
c <- initConnectionContext >>= flip connectTo params
return $ connectionToStream c cfg
where params = ConnectionParams hostname port (Just def) Nothing
where params = ConnectionParams hostname port (Just tlsCfg) Nothing
port = sslPort cfg
tlsCfg = def { settingDisableCertificateValidation = sslDisableCertificateValidation cfg }
connectPlain :: String -> Settings -> IO (BSStream, STARTTLS)
connectPlain hostname cfg = do
ctx <- initConnectionContext
c <- connectTo ctx params
return (connectionToStream c cfg, connectionSetSecure ctx c def)
return (connectionToStream c cfg, connectionSetSecure ctx c tlsCfg)
where params = ConnectionParams hostname port Nothing Nothing
port = sslPort cfg
tlsCfg = def { settingDisableCertificateValidation = sslDisableCertificateValidation cfg }

66
stack.yaml Normal file
View File

@ -0,0 +1,66 @@
# This file was automatically generated by 'stack init'
#
# Some commonly used options have been documented as comments in this file.
# For advanced use and comprehensive documentation of the format, please see:
# http://docs.haskellstack.org/en/stable/yaml_configuration/
# Resolver to choose a 'specific' stackage snapshot or a compiler version.
# A snapshot resolver dictates the compiler version and the set of packages
# to be used for project dependencies. For example:
#
# resolver: lts-3.5
# resolver: nightly-2015-09-21
# resolver: ghc-7.10.2
# resolver: ghcjs-0.1.0_ghc-7.10.2
# resolver:
# name: custom-snapshot
# location: "./custom-snapshot.yaml"
resolver: lts-7.19
# User packages to be built.
# Various formats can be used as shown in the example below.
#
# packages:
# - some-directory
# - https://example.com/foo/bar/baz-0.0.2.tar.gz
# - location:
# git: https://github.com/commercialhaskell/stack.git
# commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a
# - location: https://github.com/commercialhaskell/stack/commit/e7b331f14bcffb8367cd58fbfc8b40ec7642100a
# extra-dep: true
# subdirs:
# - auto-update
# - wai
#
# A package marked 'extra-dep: true' will only be built if demanded by a
# non-dependency (i.e. a user package), and its test suites and benchmarks
# will not be run. This is useful for tweaking upstream packages.
packages:
- '.'
# Dependency packages to be pulled from upstream that are not in the resolver
# (e.g., acme-missiles-0.3)
extra-deps: []
# Override default flag values for local packages and extra-deps
flags: {}
# Extra package databases containing global packages
extra-package-dbs: []
# Control whether we use the GHC we find on the path
# system-ghc: true
#
# Require a specific version of stack, using version ranges
# require-stack-version: -any # Default
# require-stack-version: ">=1.1"
#
# Override the architecture used by stack, especially useful on Windows
# arch: i386
# arch: x86_64
#
# Extra directories used by stack for building
# extra-include-dirs: [/path/to/dir]
# extra-lib-dirs: [/path/to/dir]
#
# Allow a newer minor version of GHC than the snapshot specifies
# compiler-check: newer-minor