Added TLS/SSL support.
This commit is contained in:
parent
e7ca1d2465
commit
7d2d25da3e
@ -2,6 +2,10 @@
|
||||
VERSION 0.7.2cvs
|
||||
================
|
||||
|
||||
2005-10-03 Vincent Richard <vincent@vincent-richard.net>
|
||||
|
||||
* Added TLS/SSL support, using GNU TLS library.
|
||||
|
||||
2005-09-17 Vincent Richard <vincent@vincent-richard.net>
|
||||
|
||||
* Added SASL support, based on GNU SASL library. Slightly modified
|
||||
|
143
SConstruct
143
SConstruct
@ -26,33 +26,26 @@ import string
|
||||
# Version #
|
||||
#############
|
||||
|
||||
# How to increment version number when building a public release?
|
||||
# ===============================================================
|
||||
#
|
||||
# Changing package version number:
|
||||
#
|
||||
# * Increment major number if major changes have been made to the library,
|
||||
# that is, program depending on this library will need to be changed to
|
||||
# work with the new major release.
|
||||
#
|
||||
# * Increment minor number when the changes are upward-compatible: some
|
||||
# interfaces have been added, but compatibility is maintained for
|
||||
# existing interfaces.
|
||||
#
|
||||
# * Increment micro number when the changes do not add any new interface.
|
||||
# The changes only apply to the implementation (bug or security fix,
|
||||
# performance improvement, etc.).
|
||||
#
|
||||
|
||||
# Package version number
|
||||
packageVersionMajor = 0
|
||||
packageVersionMinor = 7
|
||||
packageVersionMicro = 2
|
||||
|
||||
# Shared library version number (computed from package version number)
|
||||
packageAPICurrent = packageVersionMajor + packageVersionMinor
|
||||
packageAPIRevision = packageVersionMicro
|
||||
packageAPIAge = packageVersionMinor
|
||||
# API version number (libtool)
|
||||
#
|
||||
# Increment this number only immediately before a public release.
|
||||
# This is independant from package version number.
|
||||
#
|
||||
# See: http://www.gnu.org/software/libtool/manual.html#Libtool-versioning
|
||||
#
|
||||
# . Implementation changed (eg. bug/security fix): REVISION++
|
||||
# . Interfaces added/removed/changed: CURRENT++, REVISION=0
|
||||
# . Interfaces added (upward-compatible changes): AGE++
|
||||
# . Interfaces removed: AGE=0
|
||||
#
|
||||
packageAPICurrent = 0
|
||||
packageAPIRevision = 0
|
||||
packageAPIAge = 0
|
||||
|
||||
# Package information
|
||||
packageName = 'libvmime'
|
||||
@ -204,7 +197,6 @@ libvmime_examples_sources = [
|
||||
]
|
||||
|
||||
libvmime_messaging_sources = [
|
||||
'net/authHelper.cpp', 'net/authHelper.hpp',
|
||||
'net/builtinServices.inl',
|
||||
'net/events.cpp', 'net/events.hpp',
|
||||
'net/folder.cpp', 'net/folder.hpp',
|
||||
@ -219,11 +211,23 @@ libvmime_messaging_sources = [
|
||||
'net/transport.cpp', 'net/transport.hpp'
|
||||
]
|
||||
|
||||
libvmime_net_tls_sources = [
|
||||
'net/tls/TLSSession.cpp', 'net/tls/TLSSession.hpp',
|
||||
'net/tls/TLSSocket.cpp', 'net/tls/TLSSocket.hpp',
|
||||
'net/tls/certificateChain.cpp', 'net/tls/certificateChain.hpp',
|
||||
'net/tls/certificateVerifier.hpp',
|
||||
'net/tls/defaultCertificateVerifier.cpp', 'net/tls/defaultCertificateVerifier.hpp',
|
||||
'net/tls/certificate.hpp',
|
||||
'net/tls/X509Certificate.cpp', 'net/tls/X509Certificate.hpp'
|
||||
]
|
||||
|
||||
libvmime_messaging_proto_sources = [
|
||||
[
|
||||
'pop3',
|
||||
[
|
||||
'net/pop3/POP3ServiceInfos.cpp', 'net/pop3/POP3ServiceInfos.hpp',
|
||||
'net/pop3/POP3Store.cpp', 'net/pop3/POP3Store.hpp',
|
||||
'net/pop3/POP3SStore.cpp', 'net/pop3/POP3SStore.hpp',
|
||||
'net/pop3/POP3Folder.cpp', 'net/pop3/POP3Folder.hpp',
|
||||
'net/pop3/POP3Message.cpp', 'net/pop3/POP3Message.hpp'
|
||||
]
|
||||
@ -231,24 +235,29 @@ libvmime_messaging_proto_sources = [
|
||||
[
|
||||
'smtp',
|
||||
[
|
||||
'net/smtp/SMTPTransport.cpp', 'net/smtp/SMTPTransport.hpp'
|
||||
'net/smtp/SMTPServiceInfos.cpp', 'net/smtp/SMTPServiceInfos.hpp',
|
||||
'net/smtp/SMTPTransport.cpp', 'net/smtp/SMTPTransport.hpp',
|
||||
'net/smtp/SMTPSTransport.cpp', 'net/smtp/SMTPSTransport.hpp'
|
||||
]
|
||||
],
|
||||
[
|
||||
'imap',
|
||||
[
|
||||
'net/imap/IMAPServiceInfos.cpp', 'net/imap/IMAPServiceInfos.hpp',
|
||||
'net/imap/IMAPConnection.cpp', 'net/imap/IMAPConnection.hpp',
|
||||
'net/imap/IMAPStore.cpp', 'net/imap/IMAPStore.hpp',
|
||||
'net/imap/IMAPSStore.cpp', 'net/imap/IMAPSStore.hpp',
|
||||
'net/imap/IMAPFolder.cpp', 'net/imap/IMAPFolder.hpp',
|
||||
'net/imap/IMAPMessage.cpp', 'net/imap/IMAPMessage.hpp',
|
||||
'net/imap/IMAPTag.cpp', 'net/imap/IMAPTag.hpp',
|
||||
'net/imap/IMAPUtils.cpp', 'net/imap/IMAPUtils.hpp',
|
||||
'net/imap/IMAPParser.hpp'
|
||||
'net/imap/IMAPParser.hpp',
|
||||
]
|
||||
],
|
||||
[
|
||||
'maildir',
|
||||
[
|
||||
'net/maildir/maildirServiceInfos.cpp', 'net/maildir/maildirServiceInfos.hpp',
|
||||
'net/maildir/maildirStore.cpp', 'net/maildir/maildirStore.hpp',
|
||||
'net/maildir/maildirFolder.cpp', 'net/maildir/maildirFolder.hpp',
|
||||
'net/maildir/maildirMessage.cpp', 'net/maildir/maildirMessage.hpp',
|
||||
@ -258,6 +267,7 @@ libvmime_messaging_proto_sources = [
|
||||
[
|
||||
'sendmail',
|
||||
[
|
||||
'net/sendmail/sendmailServiceInfos.cpp', 'net/sendmail/sendmailServiceInfos.hpp',
|
||||
'net/sendmail/sendmailTransport.cpp', 'net/sendmail/sendmailTransport.hpp'
|
||||
]
|
||||
]
|
||||
@ -348,6 +358,7 @@ libvmime_autotools = [
|
||||
'm4/lib-ld.m4',
|
||||
'm4/lib-link.m4',
|
||||
'm4/lib-prefix.m4',
|
||||
'm4/libgnutls.m4',
|
||||
'autotools/install-sh',
|
||||
# 'autotools/mkinstalldirs',
|
||||
'autotools/missing',
|
||||
@ -367,7 +378,7 @@ libvmime_autotools = [
|
||||
'vmime/Makefile.in'
|
||||
]
|
||||
|
||||
libvmime_all_sources = [] + libvmime_sources + libvmime_messaging_sources + libvmime_security_sasl_sources
|
||||
libvmime_all_sources = [] + libvmime_sources + libvmime_messaging_sources + libvmime_security_sasl_sources + libvmime_net_tls_sources
|
||||
|
||||
for i in range(len(libvmime_all_sources)):
|
||||
f = libvmime_all_sources[i]
|
||||
@ -481,6 +492,14 @@ opts.AddOptions(
|
||||
map = { },
|
||||
ignorecase = 1
|
||||
),
|
||||
EnumOption(
|
||||
'with_tls',
|
||||
'Enable TLS support (requires GNU TLS library)',
|
||||
'yes',
|
||||
allowed_values = ('yes', 'no'),
|
||||
map = { },
|
||||
ignorecase = 1
|
||||
),
|
||||
(
|
||||
'sendmail_path',
|
||||
'Specifies the path to sendmail.',
|
||||
@ -559,6 +578,8 @@ env.Append(CXXFLAGS = ['-pedantic'])
|
||||
env.Append(CXXFLAGS = ['-Wpointer-arith'])
|
||||
env.Append(CXXFLAGS = ['-Wold-style-cast'])
|
||||
env.Append(CXXFLAGS = ['-Wconversion'])
|
||||
env.Append(CXXFLAGS = ['-Wcast-align'])
|
||||
#env.Append(CXXFLAGS = ['-Wshadow'])
|
||||
|
||||
env.Append(TARFLAGS = ['-c'])
|
||||
env.Append(TARFLAGS = ['--bzip2'])
|
||||
@ -572,7 +593,11 @@ else:
|
||||
|
||||
#env.Append(LIBS = ['additional-lib-here'])
|
||||
|
||||
env.ParseConfig('pkg-config --cflags --libs libgsasl')
|
||||
if env['with_sasl'] == 'yes':
|
||||
env.ParseConfig('pkg-config --cflags --libs libgsasl')
|
||||
|
||||
if env['with_tls'] == 'yes':
|
||||
env.ParseConfig('pkg-config --cflags --libs libgnutls')
|
||||
|
||||
# Generate help text for command line options
|
||||
Help(opts.GenerateHelpText(env))
|
||||
@ -663,6 +688,7 @@ if env['with_messaging'] == 'yes':
|
||||
print "File-system support : " + env['with_filesystem']
|
||||
print "Platform handlers : " + env['with_platforms']
|
||||
print "SASL support : " + env['with_sasl']
|
||||
print "TLS/SSL support : " + env['with_tls']
|
||||
|
||||
if IsProtocolSupported(messaging_protocols, 'sendmail'):
|
||||
print "Sendmail path : " + env['sendmail_path']
|
||||
@ -754,6 +780,12 @@ if env['with_sasl'] == 'yes':
|
||||
else:
|
||||
config_hpp.write('#define VMIME_HAVE_SASL_SUPPORT 0\n')
|
||||
|
||||
config_hpp.write('// -- TLS/SSL support\n')
|
||||
if env['with_tls'] == 'yes':
|
||||
config_hpp.write('#define VMIME_HAVE_TLS_SUPPORT 1\n')
|
||||
else:
|
||||
config_hpp.write('#define VMIME_HAVE_TLS_SUPPORT 0\n')
|
||||
|
||||
config_hpp.write('// -- Messaging support\n')
|
||||
if env['with_messaging'] == 'yes':
|
||||
config_hpp.write('#define VMIME_HAVE_MESSAGING_FEATURES 1\n')
|
||||
@ -832,6 +864,11 @@ if env['with_sasl'] == 'yes':
|
||||
for file in libvmime_security_sasl_sources:
|
||||
libvmime_sel_sources.append(file)
|
||||
|
||||
# -- TLS support
|
||||
if env['with_tls'] == 'yes':
|
||||
for file in libvmime_net_tls_sources:
|
||||
libvmime_sel_sources.append(file)
|
||||
|
||||
# -- platform handlers
|
||||
for platform in platforms:
|
||||
files = libvmime_platforms_sources[platform]
|
||||
@ -1010,9 +1047,9 @@ def generateAutotools(target, source, env):
|
||||
vmime_pc_in.write("Description: " + packageDescription + "\n")
|
||||
vmime_pc_in.write("Version: @VERSION@\n")
|
||||
vmime_pc_in.write("Requires: @GSASL_REQUIRED@\n")
|
||||
vmime_pc_in.write("Libs: -L${libdir} -l@GENERIC_VERSIONED_LIBRARY_NAME@ @GSASL_LIBS@\n")
|
||||
vmime_pc_in.write("Libs: -L${libdir} -l@GENERIC_VERSIONED_LIBRARY_NAME@ @GSASL_LIBS@ @LIBGNUTLS_LIBS@\n")
|
||||
#vmime_pc_in.write("Cflags: -I${includedir}/@GENERIC_VERSIONED_LIBRARY_NAME@\n")
|
||||
vmime_pc_in.write("Cflags: -I${includedir}/\n")
|
||||
vmime_pc_in.write("Cflags: -I${includedir}/ @LIBGNUTLS_CFLAGS@\n")
|
||||
vmime_pc_in.close()
|
||||
|
||||
# Generate 'Makefile.am'
|
||||
@ -1123,6 +1160,15 @@ INCLUDES = -I$(top_srcdir) -I$(srcdir) @PKGCONFIG_CFLAGS@ @EXTRA_CFLAGS@
|
||||
Makefile_am.write(packageVersionedName + "_la_SOURCES += " + buildMakefileFileList(x, 1) + "\n")
|
||||
Makefile_am.write("endif\n")
|
||||
|
||||
# -- TLS support
|
||||
x = selectFilesFromSuffixNot(libvmime_net_tls_sources, '.hpp')
|
||||
sourceFiles += x
|
||||
|
||||
Makefile_am.write("\n")
|
||||
Makefile_am.write("if VMIME_HAVE_TLS_SUPPORT\n")
|
||||
Makefile_am.write(packageVersionedName + "_la_SOURCES += " + buildMakefileFileList(x, 1) + "\n")
|
||||
Makefile_am.write("endif\n")
|
||||
|
||||
# -- platform handlers
|
||||
for platform in libvmime_platforms_sources:
|
||||
Makefile_am.write("\n")
|
||||
@ -1256,6 +1302,9 @@ AC_CHECK_HEADER(gsasl.h,
|
||||
have_gsasl=no),
|
||||
have_gsasl=no)
|
||||
|
||||
# -- GNU TLS Library (http://www.gnu.org/software/gnutls/)
|
||||
AM_PATH_LIBGNUTLS(1.2.0, have_gnutls=yes, have_gnutls=no)
|
||||
|
||||
# -- global constructors (stolen from 'configure.in' in libsigc++)
|
||||
AC_MSG_CHECKING([if linker supports global constructors])
|
||||
cat > mylib.$ac_ext <<EOF
|
||||
@ -1299,7 +1348,7 @@ if test -x mytest; then
|
||||
AC_ERROR([
|
||||
===================================================================
|
||||
ERROR: This platform lacks support of construction of global
|
||||
objects in shared librarys.
|
||||
objects in shared libraries.
|
||||
|
||||
See ftp://rtfm.mit.edu/pub/usenet/news.answers/g++-FAQ/plain
|
||||
for details about this problem. Also for possible solutions
|
||||
@ -1514,6 +1563,29 @@ fi
|
||||
AC_SUBST(GSASL_REQUIRED)
|
||||
AC_SUBST(GSASL_LIBS)
|
||||
|
||||
# ** TLS
|
||||
|
||||
AC_ARG_ENABLE(tls,
|
||||
AC_HELP_STRING([--enable-tls], [Enable TLS/SSL support with GNU TLS, default: enabled]),
|
||||
[case "${enableval}" in
|
||||
yes) conf_tls=yes ;;
|
||||
no) conf_tls=no ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-tls) ;;
|
||||
esac],
|
||||
[conf_tls=yes])
|
||||
|
||||
if test "x$conf_tls" = "xyes"; then
|
||||
if test "x$have_gnutls" = "xyes"; then
|
||||
AM_CONDITIONAL(VMIME_HAVE_TLS_SUPPORT, true)
|
||||
VMIME_HAVE_TLS_SUPPORT=1
|
||||
else
|
||||
AC_MSG_ERROR(can't find an usable version of GNU TLS library)
|
||||
fi
|
||||
else
|
||||
AM_CONDITIONAL(VMIME_HAVE_TLS_SUPPORT, false)
|
||||
VMIME_HAVE_TLS_SUPPORT=0
|
||||
fi
|
||||
|
||||
# ** platform handlers
|
||||
|
||||
VMIME_BUILTIN_PLATFORMS=''
|
||||
@ -1637,8 +1709,8 @@ PKGCONFIG_LIBS=""
|
||||
AC_SUBST(PKGCONFIG_CFLAGS)
|
||||
AC_SUBST(PKGCONFIG_LIBS)
|
||||
|
||||
EXTRA_CFLAGS="$EXTRA_CFLAGS -D_REENTRANT=1"
|
||||
EXTRA_LIBS="$GSASL_LIBS"
|
||||
EXTRA_CFLAGS="$EXTRA_CFLAGS -D_REENTRANT=1 -D_THREAD_SAFE=1 $LIBGNUTLS_CFLAGS"
|
||||
EXTRA_LIBS="$GSASL_LIBS $LIBGNUTLS_LIBS"
|
||||
|
||||
CFLAGS=""
|
||||
CXXFLAGS=""
|
||||
@ -1755,6 +1827,8 @@ typedef unsigned ${VMIME_TYPE_INT32} vmime_uint32;
|
||||
#define VMIME_HAVE_FILESYSTEM_FEATURES 1
|
||||
// -- SASL support
|
||||
#define VMIME_HAVE_SASL_SUPPORT ${VMIME_HAVE_SASL_SUPPORT}
|
||||
// -- TLS support
|
||||
#define VMIME_HAVE_TLS_SUPPORT ${VMIME_HAVE_TLS_SUPPORT}
|
||||
// -- Messaging support
|
||||
#define VMIME_HAVE_MESSAGING_FEATURES ${VMIME_HAVE_MESSAGING_FEATURES}
|
||||
""")
|
||||
@ -1809,6 +1883,7 @@ Messaging support : $conf_messaging
|
||||
File-system support : yes
|
||||
Platform handlers :$VMIME_BUILTIN_PLATFORMS
|
||||
SASL support : $conf_sasl
|
||||
TLS/SSL support : $conf_tls
|
||||
|
||||
Please check 'vmime/config.hpp' to ensure the configuration is correct.
|
||||
])
|
||||
@ -2081,6 +2156,10 @@ typedef unsigned int vmime_uint32;
|
||||
#define VMIME_NO_MULTIPLE_INHERITANCE 1
|
||||
// -- File-system support
|
||||
#define VMIME_HAVE_FILESYSTEM_FEATURES 1
|
||||
// -- SASL support
|
||||
#define VMIME_HAVE_SASL_SUPPORT 1
|
||||
// -- TLS/SSL support
|
||||
#define VMIME_HAVE_TLS_SUPPORT 1
|
||||
// -- Messaging support
|
||||
#define VMIME_HAVE_MESSAGING_FEATURES 1
|
||||
// -- Built-in messaging protocols
|
||||
|
@ -1,9 +1,12 @@
|
||||
=========================================
|
||||
Instructions for compiling VMime examples
|
||||
=========================================
|
||||
|
||||
1) Configure, compile and install vmime library
|
||||
|
||||
2) Compile the sample programs with:
|
||||
$ g++ -o exampleX exampleX.cpp ../libvmime.a ../libvmime-posix.a
|
||||
$ g++ -o exampleX exampleX.cpp `pkg-config libvmime`
|
||||
|
||||
3) For a more complete documentation, please visit:
|
||||
http://vmime.sourceforge.net/documentation/
|
||||
http://www.vmime.org/documentation/
|
||||
|
||||
|
@ -59,7 +59,7 @@ class interactiveAuthenticator : public vmime::security::sasl::defaultSASLAuthen
|
||||
|
||||
void setSASLMechanism(vmime::ref <vmime::security::sasl::SASLMechanism> mech)
|
||||
{
|
||||
std::cout << "Trying " << mech->getName() << std::endl;
|
||||
std::cout << "Trying '" << mech->getName() << "' authentication mechanism" << std::endl;
|
||||
|
||||
defaultSASLAuthenticator::setSASLMechanism(mech);
|
||||
}
|
||||
@ -98,6 +98,94 @@ private:
|
||||
};
|
||||
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
// Certificate verifier (TLS/SSL)
|
||||
class interactiveCertificateVerifier : public vmime::net::tls::defaultCertificateVerifier
|
||||
{
|
||||
public:
|
||||
|
||||
void verify(vmime::ref <vmime::net::tls::certificateChain> chain)
|
||||
{
|
||||
try
|
||||
{
|
||||
setX509TrustedCerts(m_trustedCerts);
|
||||
|
||||
defaultCertificateVerifier::verify(chain);
|
||||
}
|
||||
catch (vmime::exceptions::certificate_verification_exception&)
|
||||
{
|
||||
// Obtain subject's certificate
|
||||
vmime::ref <vmime::net::tls::certificate> cert = chain->getAt(0);
|
||||
|
||||
std::cout << std::endl;
|
||||
std::cout << "Server sent a '" << cert->getType() << "'" << " certificate." << std::endl;
|
||||
std::cout << "Do you want to accept this certificate? (Y/n) ";
|
||||
std::cout.flush();
|
||||
|
||||
std::string answer;
|
||||
std::getline(std::cin, answer);
|
||||
|
||||
if (answer.length() != 0 &&
|
||||
(answer[0] == 'Y' || answer[0] == 'y'))
|
||||
{
|
||||
// Accept it, and remember user's choice for later
|
||||
if (cert->getType() == "X.509")
|
||||
{
|
||||
m_trustedCerts.push_back(cert.dynamicCast
|
||||
<vmime::net::tls::X509Certificate>());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
throw vmime::exceptions::certificate_verification_exception
|
||||
("User did not accept the certificate.");
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
static std::vector <vmime::ref <vmime::net::tls::X509Certificate> > m_trustedCerts;
|
||||
};
|
||||
|
||||
|
||||
std::vector <vmime::ref <vmime::net::tls::X509Certificate> >
|
||||
interactiveCertificateVerifier::m_trustedCerts;
|
||||
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
|
||||
/** Returns the messaging protocols supported by VMime.
|
||||
*
|
||||
* @param type service type (vmime::net::service::TYPE_STORE or
|
||||
* vmime::net::service::TYPE_TRANSPORT)
|
||||
*/
|
||||
static const std::string findAvailableProtocols(const vmime::net::service::Type type)
|
||||
{
|
||||
vmime::net::serviceFactory* sf = vmime::net::serviceFactory::getInstance();
|
||||
|
||||
std::ostringstream res;
|
||||
int count = 0;
|
||||
|
||||
for (int i = 0 ; i < sf->getServiceCount() ; ++i)
|
||||
{
|
||||
const vmime::net::serviceFactory::registeredService& serv = *sf->getServiceAt(i);
|
||||
|
||||
if (serv.getType() == type)
|
||||
{
|
||||
if (count != 0)
|
||||
res << ", ";
|
||||
|
||||
res << serv.getName();
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
return res.str();
|
||||
}
|
||||
|
||||
|
||||
// Exception helper
|
||||
static std::ostream& operator<<(std::ostream& os, const vmime::exception& e)
|
||||
{
|
||||
@ -244,6 +332,7 @@ static void sendMessage()
|
||||
{
|
||||
// Request user to enter an URL
|
||||
std::cout << "Enter an URL to connect to transport service." << std::endl;
|
||||
std::cout << "Available protocols: " << findAvailableProtocols(vmime::net::service::TYPE_TRANSPORT) << std::endl;
|
||||
std::cout << "(eg. smtp://myserver.com, sendmail://localhost)" << std::endl;
|
||||
std::cout << "> ";
|
||||
std::cout.flush();
|
||||
@ -256,9 +345,21 @@ static void sendMessage()
|
||||
vmime::ref <vmime::net::transport> tr =
|
||||
g_session->getTransport(url, vmime::create <interactiveAuthenticator>());
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
// Enable TLS support if available
|
||||
tr->setProperty("connection.tls", true);
|
||||
|
||||
// Set the object responsible for verifying certificates, in the
|
||||
// case a secured connection is used (TLS/SSL)
|
||||
tr->setCertificateVerifier
|
||||
(vmime::create <interactiveCertificateVerifier>());
|
||||
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
// You can also set some properties (see example7 to know the properties
|
||||
// available for each service). For example, for SMTP:
|
||||
tr->setProperty("options.need-authentication", true);
|
||||
// tr->setProperty("options.need-authentication", true);
|
||||
|
||||
// Information about the mail
|
||||
std::cout << "Enter email of the expeditor (eg. me@somewhere.com): ";
|
||||
@ -338,6 +439,7 @@ static void connectStore()
|
||||
{
|
||||
// Request user to enter an URL
|
||||
std::cout << "Enter an URL to connect to store service." << std::endl;
|
||||
std::cout << "Available protocols: " << findAvailableProtocols(vmime::net::service::TYPE_STORE) << std::endl;
|
||||
std::cout << "(eg. pop3://user:pass@myserver.com, imap://myserver.com:123)" << std::endl;
|
||||
std::cout << "> ";
|
||||
std::cout.flush();
|
||||
@ -357,6 +459,18 @@ static void connectStore()
|
||||
else
|
||||
st = g_session->getStore(url);
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
// Enable TLS support if available
|
||||
st->setProperty("connection.tls", true);
|
||||
|
||||
// Set the object responsible for verifying certificates, in the
|
||||
// case a secured connection is used (TLS/SSL)
|
||||
st->setCertificateVerifier
|
||||
(vmime::create <interactiveCertificateVerifier>());
|
||||
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
// Connect to the mail store
|
||||
st->connect();
|
||||
|
||||
|
160
m4/libgnutls.m4
Normal file
160
m4/libgnutls.m4
Normal file
@ -0,0 +1,160 @@
|
||||
dnl Autoconf macros for libgnutls
|
||||
dnl $id$
|
||||
|
||||
# Modified for LIBGNUTLS -- nmav
|
||||
# Configure paths for LIBGCRYPT
|
||||
# Shamelessly stolen from the one of XDELTA by Owen Taylor
|
||||
# Werner Koch 99-12-09
|
||||
|
||||
dnl AM_PATH_LIBGNUTLS([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]])
|
||||
dnl Test for libgnutls, and define LIBGNUTLS_CFLAGS and LIBGNUTLS_LIBS
|
||||
dnl
|
||||
AC_DEFUN([AM_PATH_LIBGNUTLS],
|
||||
[dnl
|
||||
dnl Get the cflags and libraries from the libgnutls-config script
|
||||
dnl
|
||||
AC_ARG_WITH(libgnutls-prefix,
|
||||
[ --with-libgnutls-prefix=PFX Prefix where libgnutls is installed (optional)],
|
||||
libgnutls_config_prefix="$withval", libgnutls_config_prefix="")
|
||||
|
||||
if test x$libgnutls_config_prefix != x ; then
|
||||
if test x${LIBGNUTLS_CONFIG+set} != xset ; then
|
||||
LIBGNUTLS_CONFIG=$libgnutls_config_prefix/bin/libgnutls-config
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_PATH_PROG(LIBGNUTLS_CONFIG, libgnutls-config, no)
|
||||
min_libgnutls_version=ifelse([$1], ,0.1.0,$1)
|
||||
AC_MSG_CHECKING(for libgnutls - version >= $min_libgnutls_version)
|
||||
no_libgnutls=""
|
||||
if test "$LIBGNUTLS_CONFIG" = "no" ; then
|
||||
no_libgnutls=yes
|
||||
else
|
||||
LIBGNUTLS_CFLAGS=`$LIBGNUTLS_CONFIG $libgnutls_config_args --cflags`
|
||||
LIBGNUTLS_LIBS=`$LIBGNUTLS_CONFIG $libgnutls_config_args --libs`
|
||||
libgnutls_config_version=`$LIBGNUTLS_CONFIG $libgnutls_config_args --version`
|
||||
|
||||
|
||||
ac_save_CFLAGS="$CFLAGS"
|
||||
ac_save_LIBS="$LIBS"
|
||||
CFLAGS="$CFLAGS $LIBGNUTLS_CFLAGS"
|
||||
LIBS="$LIBS $LIBGNUTLS_LIBS"
|
||||
dnl
|
||||
dnl Now check if the installed libgnutls is sufficiently new. Also sanity
|
||||
dnl checks the results of libgnutls-config to some extent
|
||||
dnl
|
||||
rm -f conf.libgnutlstest
|
||||
AC_TRY_RUN([
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <gnutls/gnutls.h>
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
system ("touch conf.libgnutlstest");
|
||||
|
||||
if( strcmp( gnutls_check_version(NULL), "$libgnutls_config_version" ) )
|
||||
{
|
||||
printf("\n*** 'libgnutls-config --version' returned %s, but LIBGNUTLS (%s)\n",
|
||||
"$libgnutls_config_version", gnutls_check_version(NULL) );
|
||||
printf("*** was found! If libgnutls-config was correct, then it is best\n");
|
||||
printf("*** to remove the old version of LIBGNUTLS. You may also be able to fix the error\n");
|
||||
printf("*** by modifying your LD_LIBRARY_PATH enviroment variable, or by editing\n");
|
||||
printf("*** /etc/ld.so.conf. Make sure you have run ldconfig if that is\n");
|
||||
printf("*** required on your system.\n");
|
||||
printf("*** If libgnutls-config was wrong, set the environment variable LIBGNUTLS_CONFIG\n");
|
||||
printf("*** to point to the correct copy of libgnutls-config, and remove the file config.cache\n");
|
||||
printf("*** before re-running configure\n");
|
||||
}
|
||||
else if ( strcmp(gnutls_check_version(NULL), LIBGNUTLS_VERSION ) )
|
||||
{
|
||||
printf("\n*** LIBGNUTLS header file (version %s) does not match\n", LIBGNUTLS_VERSION);
|
||||
printf("*** library (version %s)\n", gnutls_check_version(NULL) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( gnutls_check_version( "$min_libgnutls_version" ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("no\n*** An old version of LIBGNUTLS (%s) was found.\n",
|
||||
gnutls_check_version(NULL) );
|
||||
printf("*** You need a version of LIBGNUTLS newer than %s. The latest version of\n",
|
||||
"$min_libgnutls_version" );
|
||||
printf("*** LIBGNUTLS is always available from ftp://gnutls.hellug.gr/pub/gnutls.\n");
|
||||
printf("*** \n");
|
||||
printf("*** If you have already installed a sufficiently new version, this error\n");
|
||||
printf("*** probably means that the wrong copy of the libgnutls-config shell script is\n");
|
||||
printf("*** being found. The easiest way to fix this is to remove the old version\n");
|
||||
printf("*** of LIBGNUTLS, but you can also set the LIBGNUTLS_CONFIG environment to point to the\n");
|
||||
printf("*** correct copy of libgnutls-config. (In this case, you will have to\n");
|
||||
printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n");
|
||||
printf("*** so that the correct libraries are found at run-time))\n");
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
],, no_libgnutls=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
|
||||
if test "x$no_libgnutls" = x ; then
|
||||
AC_MSG_RESULT(yes)
|
||||
ifelse([$2], , :, [$2])
|
||||
else
|
||||
if test -f conf.libgnutlstest ; then
|
||||
:
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
if test "$LIBGNUTLS_CONFIG" = "no" ; then
|
||||
echo "*** The libgnutls-config script installed by LIBGNUTLS could not be found"
|
||||
echo "*** If LIBGNUTLS was installed in PREFIX, make sure PREFIX/bin is in"
|
||||
echo "*** your path, or set the LIBGNUTLS_CONFIG environment variable to the"
|
||||
echo "*** full path to libgnutls-config."
|
||||
else
|
||||
if test -f conf.libgnutlstest ; then
|
||||
:
|
||||
else
|
||||
echo "*** Could not run libgnutls test program, checking why..."
|
||||
CFLAGS="$CFLAGS $LIBGNUTLS_CFLAGS"
|
||||
LIBS="$LIBS $LIBGNUTLS_LIBS"
|
||||
AC_TRY_LINK([
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <gnutls/gnutls.h>
|
||||
], [ return !!gnutls_check_version(NULL); ],
|
||||
[ echo "*** The test program compiled, but did not run. This usually means"
|
||||
echo "*** that the run-time linker is not finding LIBGNUTLS or finding the wrong"
|
||||
echo "*** version of LIBGNUTLS. If it is not finding LIBGNUTLS, you'll need to set your"
|
||||
echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
|
||||
echo "*** to the installed location Also, make sure you have run ldconfig if that"
|
||||
echo "*** is required on your system"
|
||||
echo "***"
|
||||
echo "*** If you have an old version installed, it is best to remove it, although"
|
||||
echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"
|
||||
echo "***" ],
|
||||
[ echo "*** The test program failed to compile or link. See the file config.log for the"
|
||||
echo "*** exact error that occured. This usually means LIBGNUTLS was incorrectly installed"
|
||||
echo "*** or that you have moved LIBGNUTLS since it was installed. In the latter case, you"
|
||||
echo "*** may want to edit the libgnutls-config script: $LIBGNUTLS_CONFIG" ])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
fi
|
||||
LIBGNUTLS_CFLAGS=""
|
||||
LIBGNUTLS_LIBS=""
|
||||
ifelse([$3], , :, [$3])
|
||||
fi
|
||||
rm -f conf.libgnutlstest
|
||||
AC_SUBST(LIBGNUTLS_CFLAGS)
|
||||
AC_SUBST(LIBGNUTLS_LIBS)
|
||||
])
|
||||
|
||||
dnl *-*wedit:notab*-* Please keep this as the last line.
|
@ -719,6 +719,60 @@ const char* no_auth_information::name() const throw() { return "no_auth_informat
|
||||
#endif // VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
|
||||
//
|
||||
// tls_exception
|
||||
//
|
||||
|
||||
tls_exception::~tls_exception() throw() {}
|
||||
tls_exception::tls_exception(const string& what, const exception& other)
|
||||
: exception(what, other) {}
|
||||
|
||||
exception* tls_exception::clone() const { return new tls_exception(*this); }
|
||||
const char* tls_exception::name() const throw() { return "tls_exception"; }
|
||||
|
||||
|
||||
//
|
||||
// certificate_exception
|
||||
//
|
||||
|
||||
certificate_exception::~certificate_exception() throw() {}
|
||||
certificate_exception::certificate_exception(const string& what, const exception& other)
|
||||
: tls_exception(what, other) {}
|
||||
|
||||
exception* certificate_exception::clone() const { return new certificate_exception(*this); }
|
||||
const char* certificate_exception::name() const throw() { return "certificate_exception"; }
|
||||
|
||||
|
||||
//
|
||||
// certificate_verification_exception
|
||||
//
|
||||
|
||||
certificate_verification_exception::~certificate_verification_exception() throw() {}
|
||||
certificate_verification_exception::certificate_verification_exception(const string& what, const exception& other)
|
||||
: certificate_exception(what, other) {}
|
||||
|
||||
exception* certificate_verification_exception::clone() const { return new certificate_verification_exception(*this); }
|
||||
const char* certificate_verification_exception::name() const throw() { return "certificate_verification_exception"; }
|
||||
|
||||
|
||||
//
|
||||
// unsupported_certificate_type
|
||||
//
|
||||
|
||||
unsupported_certificate_type::~unsupported_certificate_type() throw() {}
|
||||
unsupported_certificate_type::unsupported_certificate_type(const string& type, const exception& other)
|
||||
: certificate_exception("Unsupported certificate type: '" + type + "'", other) {}
|
||||
|
||||
exception* unsupported_certificate_type::clone() const { return new unsupported_certificate_type(*this); }
|
||||
const char* unsupported_certificate_type::name() const throw() { return "unsupported_certificate_type"; }
|
||||
|
||||
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
|
||||
} // exceptions
|
||||
|
||||
|
||||
|
@ -1,111 +0,0 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc., Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA..
|
||||
//
|
||||
|
||||
#include "vmime/net/authHelper.hpp"
|
||||
|
||||
#include "vmime/config.hpp"
|
||||
#include "vmime/security/digest/messageDigestFactory.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
|
||||
|
||||
//
|
||||
// This code is based on the Sample Code published in the Appendix of
|
||||
// the RFC-2104: "HMAC: Keyed-Hashing for Message Authentication".
|
||||
//
|
||||
|
||||
void hmac_md5(const string& text, const string& key, string& hexDigest)
|
||||
{
|
||||
vmime_uint8 digest[16];
|
||||
|
||||
unsigned char ipad[65]; // inner padding - key XORd with ipad
|
||||
unsigned char opad[65]; // outer padding - key XORd with opad
|
||||
|
||||
unsigned char tkey[16];
|
||||
int tkeyLen;
|
||||
|
||||
ref <security::digest::messageDigest> md5 =
|
||||
security::digest::messageDigestFactory::getInstance()->create("md5");
|
||||
|
||||
// If key is longer than 64 bytes reset it to key = MD5(key)
|
||||
if (key.length() > 64)
|
||||
{
|
||||
md5->reset();
|
||||
md5->update(reinterpret_cast <const vmime_uint8*>(key.data()), key.length());
|
||||
md5->finalize();
|
||||
|
||||
std::copy(md5->getDigest(), md5->getDigest() + 16, tkey);
|
||||
tkeyLen = 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::copy(key.begin(), key.end(), tkey);
|
||||
tkeyLen = key.length();
|
||||
}
|
||||
|
||||
//
|
||||
// the HMAC_MD5 transform looks like:
|
||||
//
|
||||
// MD5(K XOR opad, MD5(K XOR ipad, text))
|
||||
//
|
||||
// where K is an n byte key
|
||||
// ipad is the byte 0x36 repeated 64 times
|
||||
//
|
||||
// opad is the byte 0x5c repeated 64 times
|
||||
// and text is the data being protected
|
||||
//
|
||||
|
||||
// Start out by storing key in pads
|
||||
std::fill(ipad, ipad + sizeof(ipad), 0);
|
||||
std::fill(opad, opad + sizeof(opad), 0);
|
||||
|
||||
std::copy(tkey, tkey + tkeyLen, ipad);
|
||||
std::copy(tkey, tkey + tkeyLen, opad);
|
||||
|
||||
// XOR key with ipad and opad values
|
||||
for (int i = 0 ; i < 64 ; ++i)
|
||||
{
|
||||
ipad[i] ^= 0x36;
|
||||
opad[i] ^= 0x5c;
|
||||
}
|
||||
|
||||
// Perform inner MD5
|
||||
md5->reset();
|
||||
md5->update(ipad, 64);
|
||||
md5->update(text);
|
||||
md5->finalize();
|
||||
|
||||
std::copy(md5->getDigest(), md5->getDigest() + 16, digest);
|
||||
|
||||
// Perform outer MD5
|
||||
md5->reset();
|
||||
md5->update(opad, 64);
|
||||
md5->update(digest, 16);
|
||||
md5->finalize();
|
||||
|
||||
//std::copy(outerMD5.hash(), outerMD5.hash() + 16, digest);
|
||||
|
||||
hexDigest = md5->getHexDigest();
|
||||
}
|
||||
|
||||
|
||||
} // net
|
||||
} // vmime
|
@ -24,36 +24,52 @@
|
||||
#ifndef VMIME_BUILDING_DOC
|
||||
|
||||
|
||||
#define REGISTER_SERVICE(p_class, p_name) \
|
||||
vmime::net::service::initializer <vmime::net::p_class> p_name(#p_name)
|
||||
#define REGISTER_SERVICE(p_class, p_name, p_type) \
|
||||
vmime::net::service::initializer <vmime::net::p_class> \
|
||||
p_name(#p_name, vmime::net::service::p_type)
|
||||
|
||||
|
||||
#if VMIME_BUILTIN_MESSAGING_PROTO_POP3
|
||||
#include "vmime/net/pop3/POP3Store.hpp"
|
||||
REGISTER_SERVICE(pop3::POP3Store, pop3);
|
||||
REGISTER_SERVICE(pop3::POP3Store, pop3, TYPE_STORE);
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
#include "vmime/net/pop3/POP3SStore.hpp"
|
||||
REGISTER_SERVICE(pop3::POP3SStore, pop3s, TYPE_STORE);
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
#endif
|
||||
|
||||
|
||||
#if VMIME_BUILTIN_MESSAGING_PROTO_SMTP
|
||||
#include "vmime/net/smtp/SMTPTransport.hpp"
|
||||
REGISTER_SERVICE(smtp::SMTPTransport, smtp);
|
||||
REGISTER_SERVICE(smtp::SMTPTransport, smtp, TYPE_TRANSPORT);
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
#include "vmime/net/smtp/SMTPSTransport.hpp"
|
||||
REGISTER_SERVICE(smtp::SMTPSTransport, smtps, TYPE_TRANSPORT);
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
#endif
|
||||
|
||||
|
||||
#if VMIME_BUILTIN_MESSAGING_PROTO_IMAP
|
||||
#include "vmime/net/imap/IMAPStore.hpp"
|
||||
REGISTER_SERVICE(imap::IMAPStore, imap);
|
||||
REGISTER_SERVICE(imap::IMAPStore, imap, TYPE_STORE);
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
#include "vmime/net/imap/IMAPSStore.hpp"
|
||||
REGISTER_SERVICE(imap::IMAPSStore, imaps, TYPE_STORE);
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
#endif
|
||||
|
||||
|
||||
#if VMIME_BUILTIN_MESSAGING_PROTO_MAILDIR
|
||||
#include "vmime/net/maildir/maildirStore.hpp"
|
||||
REGISTER_SERVICE(maildir::maildirStore, maildir);
|
||||
REGISTER_SERVICE(maildir::maildirStore, maildir, TYPE_STORE);
|
||||
#endif
|
||||
|
||||
#if VMIME_BUILTIN_MESSAGING_PROTO_SENDMAIL
|
||||
#include "vmime/net/sendmail/sendmailTransport.hpp"
|
||||
REGISTER_SERVICE(sendmail::sendmailTransport, sendmail);
|
||||
REGISTER_SERVICE(sendmail::sendmailTransport, sendmail, TYPE_TRANSPORT);
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -29,16 +29,20 @@
|
||||
#include "vmime/security/sasl/SASLContext.hpp"
|
||||
#endif // VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
#include "vmime/net/tls/TLSSession.hpp"
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
#include <sstream>
|
||||
|
||||
|
||||
// Helpers for service properties
|
||||
#define GET_PROPERTY(type, prop) \
|
||||
(m_store->getInfos().getPropertyValue <type>(getSession(), \
|
||||
dynamic_cast <const IMAPStore::_infos&>(m_store->getInfos()).getProperties().prop))
|
||||
dynamic_cast <const IMAPServiceInfos&>(m_store->getInfos()).getProperties().prop))
|
||||
#define HAS_PROPERTY(prop) \
|
||||
(m_store->getInfos().hasProperty(getSession(), \
|
||||
dynamic_cast <const IMAPStore::_infos&>(m_store->getInfos()).getProperties().prop))
|
||||
dynamic_cast <const IMAPServiceInfos&>(m_store->getInfos()).getProperties().prop))
|
||||
|
||||
|
||||
namespace vmime {
|
||||
@ -94,6 +98,20 @@ void IMAPConnection::connect()
|
||||
getSocketFactory(GET_PROPERTY(string, PROPERTY_SERVER_SOCKETFACTORY));
|
||||
|
||||
m_socket = sf->create();
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
if (m_store->isSecuredConnection()) // dedicated port/IMAPS
|
||||
{
|
||||
ref <tls::TLSSession> tlsSession =
|
||||
vmime::create <tls::TLSSession>(m_store->getCertificateVerifier());
|
||||
|
||||
ref <tls::TLSSocket> tlsSocket =
|
||||
tlsSession->getSocket(m_socket);
|
||||
|
||||
m_socket = tlsSocket;
|
||||
}
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
m_socket->connect(address, port);
|
||||
|
||||
|
||||
@ -110,6 +128,7 @@ void IMAPConnection::connect()
|
||||
// --- S: * OK mydomain.org IMAP4rev1 v12.256 server ready
|
||||
|
||||
utility::auto_ptr <IMAPParser::greeting> greet(m_parser->readGreeting());
|
||||
bool needAuth = false;
|
||||
|
||||
if (greet->resp_cond_bye())
|
||||
{
|
||||
@ -117,6 +136,47 @@ void IMAPConnection::connect()
|
||||
throw exceptions::connection_greeting_error(m_parser->lastLine());
|
||||
}
|
||||
else if (greet->resp_cond_auth()->condition() != IMAPParser::resp_cond_auth::PREAUTH)
|
||||
{
|
||||
needAuth = true;
|
||||
}
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
// Setup secured connection, if requested
|
||||
const bool tls = HAS_PROPERTY(PROPERTY_CONNECTION_TLS)
|
||||
&& GET_PROPERTY(bool, PROPERTY_CONNECTION_TLS);
|
||||
const bool tlsRequired = HAS_PROPERTY(PROPERTY_CONNECTION_TLS_REQUIRED)
|
||||
&& GET_PROPERTY(bool, PROPERTY_CONNECTION_TLS_REQUIRED);
|
||||
|
||||
if (!m_store->isSecuredConnection() && tls) // only if not IMAPS
|
||||
{
|
||||
try
|
||||
{
|
||||
startTLS();
|
||||
}
|
||||
// Non-fatal error
|
||||
catch (exceptions::command_error&)
|
||||
{
|
||||
if (tlsRequired)
|
||||
{
|
||||
m_state = STATE_NONE;
|
||||
throw;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TLS is not required, so don't bother
|
||||
}
|
||||
}
|
||||
// Fatal error
|
||||
catch (...)
|
||||
{
|
||||
m_state = STATE_NONE;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
// Authentication
|
||||
if (needAuth)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -287,17 +347,19 @@ void IMAPConnection::authenticateSASL()
|
||||
respDataList = resp->continue_req_or_response_data();
|
||||
|
||||
string response;
|
||||
bool hasResponse = false;
|
||||
|
||||
for (unsigned int i = 0 ; i < respDataList.size() ; ++i)
|
||||
{
|
||||
if (respDataList[i]->continue_req())
|
||||
{
|
||||
response = respDataList[i]->continue_req()->resp_text()->text();
|
||||
hasResponse = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (response.empty())
|
||||
if (!hasResponse)
|
||||
{
|
||||
cont = false;
|
||||
continue;
|
||||
@ -365,6 +427,50 @@ void IMAPConnection::authenticateSASL()
|
||||
#endif // VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
void IMAPConnection::startTLS()
|
||||
{
|
||||
try
|
||||
{
|
||||
send(true, "STARTTLS", true);
|
||||
|
||||
utility::auto_ptr <IMAPParser::response> resp(m_parser->readResponse());
|
||||
|
||||
if (resp->isBad() || resp->response_done()->response_tagged()->
|
||||
resp_cond_state()->status() != IMAPParser::resp_cond_state::OK)
|
||||
{
|
||||
throw exceptions::command_error
|
||||
("STARTTLS", m_parser->lastLine(), "bad response");
|
||||
}
|
||||
|
||||
ref <tls::TLSSession> tlsSession =
|
||||
vmime::create <tls::TLSSession>(m_store->getCertificateVerifier());
|
||||
|
||||
ref <tls::TLSSocket> tlsSocket =
|
||||
tlsSession->getSocket(m_socket);
|
||||
|
||||
tlsSocket->handshake(m_timeoutHandler);
|
||||
|
||||
m_socket = tlsSocket;
|
||||
m_parser->setSocket(m_socket);
|
||||
}
|
||||
catch (exceptions::command_error&)
|
||||
{
|
||||
// Non-fatal error
|
||||
throw;
|
||||
}
|
||||
catch (exception&)
|
||||
{
|
||||
// Fatal error
|
||||
internalDisconnect();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
|
||||
const std::vector <string> IMAPConnection::getCapabilities()
|
||||
{
|
||||
send(true, "CAPABILITY", true);
|
||||
|
65
src/net/imap/IMAPSStore.cpp
Normal file
65
src/net/imap/IMAPSStore.cpp
Normal file
@ -0,0 +1,65 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc., Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA..
|
||||
//
|
||||
|
||||
#include "vmime/net/imap/IMAPSStore.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace imap {
|
||||
|
||||
|
||||
IMAPSStore::IMAPSStore(ref <session> sess, ref <security::authenticator> auth)
|
||||
: IMAPStore(sess, auth, true)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
IMAPSStore::~IMAPSStore()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const string IMAPSStore::getProtocolName() const
|
||||
{
|
||||
return "imaps";
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Service infos
|
||||
|
||||
IMAPServiceInfos IMAPSStore::sm_infos(true);
|
||||
|
||||
|
||||
const serviceInfos& IMAPSStore::getInfosInstance()
|
||||
{
|
||||
return sm_infos;
|
||||
}
|
||||
|
||||
|
||||
const serviceInfos& IMAPSStore::getInfos() const
|
||||
{
|
||||
return sm_infos;
|
||||
}
|
||||
|
||||
|
||||
} // imap
|
||||
} // net
|
||||
} // vmime
|
133
src/net/imap/IMAPServiceInfos.cpp
Normal file
133
src/net/imap/IMAPServiceInfos.cpp
Normal file
@ -0,0 +1,133 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc., Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA..
|
||||
//
|
||||
|
||||
#include "vmime/net/imap/IMAPServiceInfos.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace imap {
|
||||
|
||||
|
||||
IMAPServiceInfos::IMAPServiceInfos(const bool imaps)
|
||||
: m_imaps(imaps)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const string IMAPServiceInfos::getPropertyPrefix() const
|
||||
{
|
||||
if (m_imaps)
|
||||
return "store.imaps.";
|
||||
else
|
||||
return "store.imap.";
|
||||
}
|
||||
|
||||
|
||||
const IMAPServiceInfos::props& IMAPServiceInfos::getProperties() const
|
||||
{
|
||||
static props imapProps =
|
||||
{
|
||||
// IMAP-specific options
|
||||
#if VMIME_HAVE_SASL_SUPPORT
|
||||
property("options.sasl", serviceInfos::property::TYPE_BOOL, "true"),
|
||||
property("options.sasl.fallback", serviceInfos::property::TYPE_BOOL, "true"),
|
||||
#endif // VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
// Common properties
|
||||
property(serviceInfos::property::AUTH_USERNAME, serviceInfos::property::FLAG_REQUIRED),
|
||||
property(serviceInfos::property::AUTH_PASSWORD, serviceInfos::property::FLAG_REQUIRED),
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
property(serviceInfos::property::CONNECTION_TLS),
|
||||
property(serviceInfos::property::CONNECTION_TLS_REQUIRED),
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
property(serviceInfos::property::SERVER_ADDRESS, serviceInfos::property::FLAG_REQUIRED),
|
||||
property(serviceInfos::property::SERVER_PORT, "143"),
|
||||
property(serviceInfos::property::SERVER_SOCKETFACTORY),
|
||||
|
||||
property(serviceInfos::property::TIMEOUT_FACTORY)
|
||||
};
|
||||
|
||||
static props imapsProps =
|
||||
{
|
||||
// IMAP-specific options
|
||||
#if VMIME_HAVE_SASL_SUPPORT
|
||||
property("options.sasl", serviceInfos::property::TYPE_BOOL, "true"),
|
||||
property("options.sasl.fallback", serviceInfos::property::TYPE_BOOL, "true"),
|
||||
#endif // VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
// Common properties
|
||||
property(serviceInfos::property::AUTH_USERNAME, serviceInfos::property::FLAG_REQUIRED),
|
||||
property(serviceInfos::property::AUTH_PASSWORD, serviceInfos::property::FLAG_REQUIRED),
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
property(serviceInfos::property::CONNECTION_TLS),
|
||||
property(serviceInfos::property::CONNECTION_TLS_REQUIRED),
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
property(serviceInfos::property::SERVER_ADDRESS, serviceInfos::property::FLAG_REQUIRED),
|
||||
property(serviceInfos::property::SERVER_PORT, "993"),
|
||||
property(serviceInfos::property::SERVER_SOCKETFACTORY),
|
||||
|
||||
property(serviceInfos::property::TIMEOUT_FACTORY)
|
||||
};
|
||||
|
||||
return m_imaps ? imapsProps : imapProps;
|
||||
}
|
||||
|
||||
|
||||
const std::vector <serviceInfos::property> IMAPServiceInfos::getAvailableProperties() const
|
||||
{
|
||||
std::vector <property> list;
|
||||
const props& p = getProperties();
|
||||
|
||||
// IMAP-specific options
|
||||
#if VMIME_HAVE_SASL_SUPPORT
|
||||
list.push_back(p.PROPERTY_OPTIONS_SASL);
|
||||
list.push_back(p.PROPERTY_OPTIONS_SASL_FALLBACK);
|
||||
#endif // VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
// Common properties
|
||||
list.push_back(p.PROPERTY_AUTH_USERNAME);
|
||||
list.push_back(p.PROPERTY_AUTH_PASSWORD);
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
if (!m_imaps)
|
||||
{
|
||||
list.push_back(p.PROPERTY_CONNECTION_TLS);
|
||||
list.push_back(p.PROPERTY_CONNECTION_TLS_REQUIRED);
|
||||
}
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
list.push_back(p.PROPERTY_SERVER_ADDRESS);
|
||||
list.push_back(p.PROPERTY_SERVER_PORT);
|
||||
list.push_back(p.PROPERTY_SERVER_SOCKETFACTORY);
|
||||
|
||||
list.push_back(p.PROPERTY_TIMEOUT_FACTORY);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
} // imap
|
||||
} // net
|
||||
} // vmime
|
||||
|
@ -32,8 +32,8 @@ namespace net {
|
||||
namespace imap {
|
||||
|
||||
|
||||
IMAPStore::IMAPStore(ref <session> sess, ref <security::authenticator> auth)
|
||||
: store(sess, getInfosInstance(), auth), m_connection(NULL)
|
||||
IMAPStore::IMAPStore(ref <session> sess, ref <security::authenticator> auth, const bool secured)
|
||||
: store(sess, getInfosInstance(), auth), m_connection(NULL), m_secured(secured)
|
||||
{
|
||||
}
|
||||
|
||||
@ -91,6 +91,12 @@ const bool IMAPStore::isValidFolderName(const folder::path::component& /* name *
|
||||
}
|
||||
|
||||
|
||||
const bool IMAPStore::isSecuredConnection() const
|
||||
{
|
||||
return m_secured;
|
||||
}
|
||||
|
||||
|
||||
void IMAPStore::connect()
|
||||
{
|
||||
if (isConnected())
|
||||
@ -189,78 +195,21 @@ const int IMAPStore::getCapabilities() const
|
||||
|
||||
// Service infos
|
||||
|
||||
IMAPStore::_infos IMAPStore::sm_infos;
|
||||
IMAPServiceInfos IMAPStore::sm_infos(false);
|
||||
|
||||
|
||||
const serviceInfos& IMAPStore::getInfosInstance()
|
||||
{
|
||||
return (sm_infos);
|
||||
return sm_infos;
|
||||
}
|
||||
|
||||
|
||||
const serviceInfos& IMAPStore::getInfos() const
|
||||
{
|
||||
return (sm_infos);
|
||||
return sm_infos;
|
||||
}
|
||||
|
||||
|
||||
const string IMAPStore::_infos::getPropertyPrefix() const
|
||||
{
|
||||
return "store.imap.";
|
||||
}
|
||||
|
||||
|
||||
const IMAPStore::_infos::props& IMAPStore::_infos::getProperties() const
|
||||
{
|
||||
static props p =
|
||||
{
|
||||
// IMAP-specific options
|
||||
#if VMIME_HAVE_SASL_SUPPORT
|
||||
property("options.sasl", serviceInfos::property::TYPE_BOOL, "true"),
|
||||
property("options.sasl.fallback", serviceInfos::property::TYPE_BOOL, "true"),
|
||||
#endif // VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
// Common properties
|
||||
property(serviceInfos::property::AUTH_USERNAME, serviceInfos::property::FLAG_REQUIRED),
|
||||
property(serviceInfos::property::AUTH_PASSWORD, serviceInfos::property::FLAG_REQUIRED),
|
||||
|
||||
property(serviceInfos::property::SERVER_ADDRESS, serviceInfos::property::FLAG_REQUIRED),
|
||||
property(serviceInfos::property::SERVER_PORT, "143"),
|
||||
property(serviceInfos::property::SERVER_SOCKETFACTORY),
|
||||
|
||||
property(serviceInfos::property::TIMEOUT_FACTORY)
|
||||
};
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
const std::vector <serviceInfos::property> IMAPStore::_infos::getAvailableProperties() const
|
||||
{
|
||||
std::vector <property> list;
|
||||
const props& p = getProperties();
|
||||
|
||||
// IMAP-specific options
|
||||
#if VMIME_HAVE_SASL_SUPPORT
|
||||
list.push_back(p.PROPERTY_OPTIONS_SASL);
|
||||
list.push_back(p.PROPERTY_OPTIONS_SASL_FALLBACK);
|
||||
#endif // VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
// Common properties
|
||||
list.push_back(p.PROPERTY_AUTH_USERNAME);
|
||||
list.push_back(p.PROPERTY_AUTH_PASSWORD);
|
||||
|
||||
list.push_back(p.PROPERTY_SERVER_ADDRESS);
|
||||
list.push_back(p.PROPERTY_SERVER_PORT);
|
||||
list.push_back(p.PROPERTY_SERVER_SOCKETFACTORY);
|
||||
|
||||
list.push_back(p.PROPERTY_TIMEOUT_FACTORY);
|
||||
|
||||
return (list);
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // imap
|
||||
} // net
|
||||
} // vmime
|
||||
|
64
src/net/maildir/maildirServiceInfos.cpp
Normal file
64
src/net/maildir/maildirServiceInfos.cpp
Normal file
@ -0,0 +1,64 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc., Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA..
|
||||
//
|
||||
|
||||
#include "vmime/net/maildir/maildirServiceInfos.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace maildir {
|
||||
|
||||
|
||||
maildirServiceInfos::maildirServiceInfos()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const string maildirServiceInfos::getPropertyPrefix() const
|
||||
{
|
||||
return "store.maildir.";
|
||||
}
|
||||
|
||||
|
||||
const maildirServiceInfos::props& maildirServiceInfos::getProperties() const
|
||||
{
|
||||
static props maildirProps =
|
||||
{
|
||||
property(serviceInfos::property::SERVER_ROOTPATH, serviceInfos::property::FLAG_REQUIRED)
|
||||
};
|
||||
|
||||
return maildirProps;
|
||||
}
|
||||
|
||||
|
||||
const std::vector <serviceInfos::property> maildirServiceInfos::getAvailableProperties() const
|
||||
{
|
||||
std::vector <property> list;
|
||||
const props& p = getProperties();
|
||||
|
||||
list.push_back(p.PROPERTY_SERVER_ROOTPATH);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
} // maildir
|
||||
} // net
|
||||
} // vmime
|
||||
|
@ -29,9 +29,11 @@
|
||||
|
||||
// Helpers for service properties
|
||||
#define GET_PROPERTY(type, prop) \
|
||||
(sm_infos.getPropertyValue <type>(getSession(), sm_infos.getProperties().prop))
|
||||
(getInfos().getPropertyValue <type>(getSession(), \
|
||||
dynamic_cast <const maildirServiceInfos&>(getInfos()).getProperties().prop))
|
||||
#define HAS_PROPERTY(prop) \
|
||||
(sm_infos.hasProperty(getSession(), sm_infos.getProperties().prop))
|
||||
(getInfos().hasProperty(getSession(), \
|
||||
dynamic_cast <const maildirServiceInfos&>(getInfos()).getProperties().prop))
|
||||
|
||||
|
||||
namespace vmime {
|
||||
@ -205,50 +207,20 @@ const int maildirStore::getCapabilities() const
|
||||
|
||||
|
||||
|
||||
|
||||
// Service infos
|
||||
|
||||
maildirStore::_infos maildirStore::sm_infos;
|
||||
maildirServiceInfos maildirStore::sm_infos;
|
||||
|
||||
|
||||
const serviceInfos& maildirStore::getInfosInstance()
|
||||
{
|
||||
return (sm_infos);
|
||||
return sm_infos;
|
||||
}
|
||||
|
||||
|
||||
const serviceInfos& maildirStore::getInfos() const
|
||||
{
|
||||
return (sm_infos);
|
||||
}
|
||||
|
||||
|
||||
const string maildirStore::_infos::getPropertyPrefix() const
|
||||
{
|
||||
return "store.maildir.";
|
||||
}
|
||||
|
||||
|
||||
const maildirStore::_infos::props& maildirStore::_infos::getProperties() const
|
||||
{
|
||||
static props p =
|
||||
{
|
||||
property(serviceInfos::property::SERVER_ROOTPATH, serviceInfos::property::FLAG_REQUIRED)
|
||||
};
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
const std::vector <serviceInfos::property> maildirStore::_infos::getAvailableProperties() const
|
||||
{
|
||||
std::vector <property> list;
|
||||
const props& p = getProperties();
|
||||
|
||||
// Maildir-specific properties
|
||||
list.push_back(p.PROPERTY_SERVER_ROOTPATH);
|
||||
|
||||
return (list);
|
||||
return sm_infos;
|
||||
}
|
||||
|
||||
|
||||
|
66
src/net/pop3/POP3SStore.cpp
Normal file
66
src/net/pop3/POP3SStore.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc., Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA..
|
||||
//
|
||||
|
||||
#include "vmime/net/pop3/POP3SStore.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace pop3 {
|
||||
|
||||
|
||||
POP3SStore::POP3SStore(ref <session> sess, ref <security::authenticator> auth)
|
||||
: POP3Store(sess, auth, true)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
POP3SStore::~POP3SStore()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const string POP3SStore::getProtocolName() const
|
||||
{
|
||||
return "pop3s";
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Service infos
|
||||
|
||||
POP3ServiceInfos POP3SStore::sm_infos(true);
|
||||
|
||||
|
||||
const serviceInfos& POP3SStore::getInfosInstance()
|
||||
{
|
||||
return sm_infos;
|
||||
}
|
||||
|
||||
|
||||
const serviceInfos& POP3SStore::getInfos() const
|
||||
{
|
||||
return sm_infos;
|
||||
}
|
||||
|
||||
|
||||
} // pop3
|
||||
} // net
|
||||
} // vmime
|
||||
|
139
src/net/pop3/POP3ServiceInfos.cpp
Normal file
139
src/net/pop3/POP3ServiceInfos.cpp
Normal file
@ -0,0 +1,139 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc., Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA..
|
||||
//
|
||||
|
||||
#include "vmime/net/pop3/POP3ServiceInfos.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace pop3 {
|
||||
|
||||
|
||||
POP3ServiceInfos::POP3ServiceInfos(const bool pop3s)
|
||||
: m_pop3s(pop3s)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const string POP3ServiceInfos::getPropertyPrefix() const
|
||||
{
|
||||
if (m_pop3s)
|
||||
return "store.pop3s.";
|
||||
else
|
||||
return "store.pop3.";
|
||||
}
|
||||
|
||||
|
||||
const POP3ServiceInfos::props& POP3ServiceInfos::getProperties() const
|
||||
{
|
||||
static props pop3Props =
|
||||
{
|
||||
// POP3-specific options
|
||||
property("options.apop", serviceInfos::property::TYPE_BOOL, "true"),
|
||||
property("options.apop.fallback", serviceInfos::property::TYPE_BOOL, "true"),
|
||||
#if VMIME_HAVE_SASL_SUPPORT
|
||||
property("options.sasl", serviceInfos::property::TYPE_BOOL, "true"),
|
||||
property("options.sasl.fallback", serviceInfos::property::TYPE_BOOL, "true"),
|
||||
#endif // VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
// Common properties
|
||||
property(serviceInfos::property::AUTH_USERNAME, serviceInfos::property::FLAG_REQUIRED),
|
||||
property(serviceInfos::property::AUTH_PASSWORD, serviceInfos::property::FLAG_REQUIRED),
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
property(serviceInfos::property::CONNECTION_TLS),
|
||||
property(serviceInfos::property::CONNECTION_TLS_REQUIRED),
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
property(serviceInfos::property::SERVER_ADDRESS, serviceInfos::property::FLAG_REQUIRED),
|
||||
property(serviceInfos::property::SERVER_PORT, "110"),
|
||||
property(serviceInfos::property::SERVER_SOCKETFACTORY),
|
||||
|
||||
property(serviceInfos::property::TIMEOUT_FACTORY)
|
||||
};
|
||||
|
||||
static props pop3sProps =
|
||||
{
|
||||
// POP3-specific options
|
||||
property("options.apop", serviceInfos::property::TYPE_BOOL, "true"),
|
||||
property("options.apop.fallback", serviceInfos::property::TYPE_BOOL, "true"),
|
||||
#if VMIME_HAVE_SASL_SUPPORT
|
||||
property("options.sasl", serviceInfos::property::TYPE_BOOL, "true"),
|
||||
property("options.sasl.fallback", serviceInfos::property::TYPE_BOOL, "true"),
|
||||
#endif // VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
// Common properties
|
||||
property(serviceInfos::property::AUTH_USERNAME, serviceInfos::property::FLAG_REQUIRED),
|
||||
property(serviceInfos::property::AUTH_PASSWORD, serviceInfos::property::FLAG_REQUIRED),
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
property(serviceInfos::property::CONNECTION_TLS),
|
||||
property(serviceInfos::property::CONNECTION_TLS_REQUIRED),
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
property(serviceInfos::property::SERVER_ADDRESS, serviceInfos::property::FLAG_REQUIRED),
|
||||
property(serviceInfos::property::SERVER_PORT, "995"),
|
||||
property(serviceInfos::property::SERVER_SOCKETFACTORY),
|
||||
|
||||
property(serviceInfos::property::TIMEOUT_FACTORY)
|
||||
};
|
||||
|
||||
return m_pop3s ? pop3sProps : pop3Props;
|
||||
}
|
||||
|
||||
|
||||
const std::vector <serviceInfos::property> POP3ServiceInfos::getAvailableProperties() const
|
||||
{
|
||||
std::vector <property> list;
|
||||
const props& p = getProperties();
|
||||
|
||||
// POP3-specific options
|
||||
list.push_back(p.PROPERTY_OPTIONS_APOP);
|
||||
list.push_back(p.PROPERTY_OPTIONS_APOP_FALLBACK);
|
||||
#if VMIME_HAVE_SASL_SUPPORT
|
||||
list.push_back(p.PROPERTY_OPTIONS_SASL);
|
||||
list.push_back(p.PROPERTY_OPTIONS_SASL_FALLBACK);
|
||||
#endif // VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
// Common properties
|
||||
list.push_back(p.PROPERTY_AUTH_USERNAME);
|
||||
list.push_back(p.PROPERTY_AUTH_PASSWORD);
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
if (!m_pop3s)
|
||||
{
|
||||
list.push_back(p.PROPERTY_CONNECTION_TLS);
|
||||
list.push_back(p.PROPERTY_CONNECTION_TLS_REQUIRED);
|
||||
}
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
list.push_back(p.PROPERTY_SERVER_ADDRESS);
|
||||
list.push_back(p.PROPERTY_SERVER_PORT);
|
||||
list.push_back(p.PROPERTY_SERVER_SOCKETFACTORY);
|
||||
|
||||
list.push_back(p.PROPERTY_TIMEOUT_FACTORY);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
} // pop3
|
||||
} // net
|
||||
} // vmime
|
||||
|
@ -31,14 +31,20 @@
|
||||
#include "vmime/security/sasl/SASLContext.hpp"
|
||||
#endif // VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
#include "vmime/net/tls/TLSSession.hpp"
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
// Helpers for service properties
|
||||
#define GET_PROPERTY(type, prop) \
|
||||
(sm_infos.getPropertyValue <type>(getSession(), sm_infos.getProperties().prop))
|
||||
(getInfos().getPropertyValue <type>(getSession(), \
|
||||
dynamic_cast <const POP3ServiceInfos&>(getInfos()).getProperties().prop))
|
||||
#define HAS_PROPERTY(prop) \
|
||||
(sm_infos.hasProperty(getSession(), sm_infos.getProperties().prop))
|
||||
(getInfos().hasProperty(getSession(), \
|
||||
dynamic_cast <const POP3ServiceInfos&>(getInfos()).getProperties().prop))
|
||||
|
||||
|
||||
namespace vmime {
|
||||
@ -46,9 +52,9 @@ namespace net {
|
||||
namespace pop3 {
|
||||
|
||||
|
||||
POP3Store::POP3Store(ref <session> sess, ref <security::authenticator> auth)
|
||||
POP3Store::POP3Store(ref <session> sess, ref <security::authenticator> auth, const bool secured)
|
||||
: store(sess, getInfosInstance(), auth), m_socket(NULL),
|
||||
m_authentified(false), m_timeoutHandler(NULL)
|
||||
m_authentified(false), m_timeoutHandler(NULL), m_secured(secured)
|
||||
{
|
||||
}
|
||||
|
||||
@ -130,6 +136,20 @@ void POP3Store::connect()
|
||||
getSocketFactory(GET_PROPERTY(string, PROPERTY_SERVER_SOCKETFACTORY));
|
||||
|
||||
m_socket = sf->create();
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
if (m_secured) // dedicated port/POP3S
|
||||
{
|
||||
ref <tls::TLSSession> tlsSession =
|
||||
vmime::create <tls::TLSSession>(getCertificateVerifier());
|
||||
|
||||
ref <tls::TLSSocket> tlsSocket =
|
||||
tlsSession->getSocket(m_socket);
|
||||
|
||||
m_socket = tlsSocket;
|
||||
}
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
m_socket->connect(address, port);
|
||||
|
||||
// Connection
|
||||
@ -146,6 +166,39 @@ void POP3Store::connect()
|
||||
throw exceptions::connection_greeting_error(response);
|
||||
}
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
// Setup secured connection, if requested
|
||||
const bool tls = HAS_PROPERTY(PROPERTY_CONNECTION_TLS)
|
||||
&& GET_PROPERTY(bool, PROPERTY_CONNECTION_TLS);
|
||||
const bool tlsRequired = HAS_PROPERTY(PROPERTY_CONNECTION_TLS_REQUIRED)
|
||||
&& GET_PROPERTY(bool, PROPERTY_CONNECTION_TLS_REQUIRED);
|
||||
|
||||
if (!m_secured && tls) // only if not POP3S
|
||||
{
|
||||
try
|
||||
{
|
||||
startTLS();
|
||||
}
|
||||
// Non-fatal error
|
||||
catch (exceptions::command_error&)
|
||||
{
|
||||
if (tlsRequired)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TLS is not required, so don't bother
|
||||
}
|
||||
}
|
||||
// Fatal error
|
||||
catch (...)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
// Start authentication process
|
||||
authenticate(messageId(response));
|
||||
}
|
||||
@ -235,6 +288,18 @@ void POP3Store::authenticate(const messageId& randomMID)
|
||||
internalDisconnect();
|
||||
throw exceptions::authentication_error(response);
|
||||
}
|
||||
|
||||
// Ensure connection is valid (cf. note above)
|
||||
try
|
||||
{
|
||||
string response2;
|
||||
sendRequest("NOOP");
|
||||
readResponse(response2, false);
|
||||
}
|
||||
catch (exceptions::socket_exception&)
|
||||
{
|
||||
throw exceptions::authentication_error(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -453,6 +518,46 @@ void POP3Store::authenticateSASL()
|
||||
#endif // VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
void POP3Store::startTLS()
|
||||
{
|
||||
try
|
||||
{
|
||||
sendRequest("STLS");
|
||||
|
||||
string response;
|
||||
readResponse(response, false);
|
||||
|
||||
if (getResponseCode(response) != RESPONSE_OK)
|
||||
throw exceptions::command_error("STLS", response);
|
||||
|
||||
ref <tls::TLSSession> tlsSession =
|
||||
vmime::create <tls::TLSSession>(getCertificateVerifier());
|
||||
|
||||
ref <tls::TLSSocket> tlsSocket =
|
||||
tlsSession->getSocket(m_socket);
|
||||
|
||||
tlsSocket->handshake(m_timeoutHandler);
|
||||
|
||||
m_socket = tlsSocket;
|
||||
}
|
||||
catch (exceptions::command_error&)
|
||||
{
|
||||
// Non-fatal error
|
||||
throw;
|
||||
}
|
||||
catch (exception&)
|
||||
{
|
||||
// Fatal error
|
||||
internalDisconnect();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
|
||||
const bool POP3Store::isConnected() const
|
||||
{
|
||||
return (m_socket && m_socket->isConnected() && m_authentified);
|
||||
@ -478,8 +583,14 @@ void POP3Store::internalDisconnect()
|
||||
|
||||
m_folders.clear();
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
sendRequest("QUIT");
|
||||
}
|
||||
catch (exception&)
|
||||
{
|
||||
// Not important
|
||||
}
|
||||
|
||||
m_socket->disconnect();
|
||||
m_socket = NULL;
|
||||
@ -627,6 +738,8 @@ void POP3Store::readResponse(string& buffer, const bool multiLine,
|
||||
{
|
||||
if (!m_timeoutHandler->handleTimeOut())
|
||||
throw exceptions::operation_timed_out();
|
||||
|
||||
m_timeoutHandler->resetTimeOut();
|
||||
}
|
||||
|
||||
// Receive data from the socket
|
||||
@ -844,78 +957,18 @@ const int POP3Store::getCapabilities() const
|
||||
|
||||
// Service infos
|
||||
|
||||
POP3Store::_infos POP3Store::sm_infos;
|
||||
POP3ServiceInfos POP3Store::sm_infos(false);
|
||||
|
||||
|
||||
const serviceInfos& POP3Store::getInfosInstance()
|
||||
{
|
||||
return (sm_infos);
|
||||
return sm_infos;
|
||||
}
|
||||
|
||||
|
||||
const serviceInfos& POP3Store::getInfos() const
|
||||
{
|
||||
return (sm_infos);
|
||||
}
|
||||
|
||||
|
||||
const string POP3Store::_infos::getPropertyPrefix() const
|
||||
{
|
||||
return "store.pop3.";
|
||||
}
|
||||
|
||||
|
||||
const POP3Store::_infos::props& POP3Store::_infos::getProperties() const
|
||||
{
|
||||
static props p =
|
||||
{
|
||||
// POP3-specific options
|
||||
property("options.apop", serviceInfos::property::TYPE_BOOL, "true"),
|
||||
property("options.apop.fallback", serviceInfos::property::TYPE_BOOL, "true"),
|
||||
#if VMIME_HAVE_SASL_SUPPORT
|
||||
property("options.sasl", serviceInfos::property::TYPE_BOOL, "true"),
|
||||
property("options.sasl.fallback", serviceInfos::property::TYPE_BOOL, "true"),
|
||||
#endif // VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
// Common properties
|
||||
property(serviceInfos::property::AUTH_USERNAME, serviceInfos::property::FLAG_REQUIRED),
|
||||
property(serviceInfos::property::AUTH_PASSWORD, serviceInfos::property::FLAG_REQUIRED),
|
||||
|
||||
property(serviceInfos::property::SERVER_ADDRESS, serviceInfos::property::FLAG_REQUIRED),
|
||||
property(serviceInfos::property::SERVER_PORT, "110"),
|
||||
property(serviceInfos::property::SERVER_SOCKETFACTORY),
|
||||
|
||||
property(serviceInfos::property::TIMEOUT_FACTORY)
|
||||
};
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
const std::vector <serviceInfos::property> POP3Store::_infos::getAvailableProperties() const
|
||||
{
|
||||
std::vector <property> list;
|
||||
const props& p = getProperties();
|
||||
|
||||
// POP3-specific options
|
||||
list.push_back(p.PROPERTY_OPTIONS_APOP);
|
||||
list.push_back(p.PROPERTY_OPTIONS_APOP_FALLBACK);
|
||||
#if VMIME_HAVE_SASL_SUPPORT
|
||||
list.push_back(p.PROPERTY_OPTIONS_SASL);
|
||||
list.push_back(p.PROPERTY_OPTIONS_SASL_FALLBACK);
|
||||
#endif // VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
// Common properties
|
||||
list.push_back(p.PROPERTY_AUTH_USERNAME);
|
||||
list.push_back(p.PROPERTY_AUTH_PASSWORD);
|
||||
|
||||
list.push_back(p.PROPERTY_SERVER_ADDRESS);
|
||||
list.push_back(p.PROPERTY_SERVER_PORT);
|
||||
list.push_back(p.PROPERTY_SERVER_SOCKETFACTORY);
|
||||
|
||||
list.push_back(p.PROPERTY_TIMEOUT_FACTORY);
|
||||
|
||||
return (list);
|
||||
return sm_infos;
|
||||
}
|
||||
|
||||
|
||||
|
65
src/net/sendmail/sendmailServiceInfos.cpp
Normal file
65
src/net/sendmail/sendmailServiceInfos.cpp
Normal file
@ -0,0 +1,65 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc., Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA..
|
||||
//
|
||||
|
||||
#include "vmime/net/sendmail/sendmailServiceInfos.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace sendmail {
|
||||
|
||||
|
||||
sendmailServiceInfos::sendmailServiceInfos()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const string sendmailServiceInfos::getPropertyPrefix() const
|
||||
{
|
||||
return "transport.sendmail.";
|
||||
}
|
||||
|
||||
|
||||
const sendmailServiceInfos::props& sendmailServiceInfos::getProperties() const
|
||||
{
|
||||
static props sendmailProps =
|
||||
{
|
||||
// Path to sendmail (override default)
|
||||
property("binpath", serviceInfos::property::TYPE_STRING, string(VMIME_SENDMAIL_PATH))
|
||||
};
|
||||
|
||||
return sendmailProps;
|
||||
}
|
||||
|
||||
|
||||
const std::vector <serviceInfos::property> sendmailServiceInfos::getAvailableProperties() const
|
||||
{
|
||||
std::vector <property> list;
|
||||
const props& p = getProperties();
|
||||
|
||||
list.push_back(p.PROPERTY_BINPATH);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
} // sendmail
|
||||
} // net
|
||||
} // vmime
|
||||
|
@ -33,9 +33,11 @@
|
||||
|
||||
// Helpers for service properties
|
||||
#define GET_PROPERTY(type, prop) \
|
||||
(sm_infos.getPropertyValue <type>(getSession(), sm_infos.getProperties().prop))
|
||||
(getInfos().getPropertyValue <type>(getSession(), \
|
||||
dynamic_cast <const sendmailServiceInfos&>(getInfos()).getProperties().prop))
|
||||
#define HAS_PROPERTY(prop) \
|
||||
(sm_infos.hasProperty(getSession(), sm_infos.getProperties().prop))
|
||||
(getInfos().hasProperty(getSession(), \
|
||||
dynamic_cast <const sendmailServiceInfos&>(getInfos()).getProperties().prop))
|
||||
|
||||
|
||||
#if VMIME_BUILTIN_PLATFORM_POSIX
|
||||
@ -177,47 +179,18 @@ void sendmailTransport::internalSend
|
||||
|
||||
// Service infos
|
||||
|
||||
sendmailTransport::_infos sendmailTransport::sm_infos;
|
||||
sendmailServiceInfos sendmailTransport::sm_infos;
|
||||
|
||||
|
||||
const serviceInfos& sendmailTransport::getInfosInstance()
|
||||
{
|
||||
return (sm_infos);
|
||||
return sm_infos;
|
||||
}
|
||||
|
||||
|
||||
const serviceInfos& sendmailTransport::getInfos() const
|
||||
{
|
||||
return (sm_infos);
|
||||
}
|
||||
|
||||
|
||||
const string sendmailTransport::_infos::getPropertyPrefix() const
|
||||
{
|
||||
return "transport.sendmail.";
|
||||
}
|
||||
|
||||
|
||||
const sendmailTransport::_infos::props& sendmailTransport::_infos::getProperties() const
|
||||
{
|
||||
static props p =
|
||||
{
|
||||
// Path to sendmail (override default)
|
||||
property("binpath", serviceInfos::property::TYPE_STRING, string(VMIME_SENDMAIL_PATH))
|
||||
};
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
const std::vector <serviceInfos::property> sendmailTransport::_infos::getAvailableProperties() const
|
||||
{
|
||||
std::vector <property> list;
|
||||
const props& p = getProperties();
|
||||
|
||||
list.push_back(p.PROPERTY_BINPATH);
|
||||
|
||||
return (list);
|
||||
return sm_infos;
|
||||
}
|
||||
|
||||
|
||||
|
@ -26,6 +26,10 @@
|
||||
#include "vmime/security/defaultAuthenticator.hpp"
|
||||
#endif // VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
#include "vmime/net/tls/defaultCertificateVerifier.hpp"
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
@ -45,6 +49,11 @@ service::service(ref <session> sess, const serviceInfos& /* infos */,
|
||||
<security::defaultAuthenticator>();
|
||||
#endif // VMIME_HAVE_SASL_SUPPORT
|
||||
}
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
m_certVerifier = vmime::create <tls::defaultCertificateVerifier>();
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -83,5 +92,21 @@ void service::setAuthenticator(ref <security::authenticator> auth)
|
||||
}
|
||||
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
void service::setCertificateVerifier(ref <tls::certificateVerifier> cv)
|
||||
{
|
||||
m_certVerifier = cv;
|
||||
}
|
||||
|
||||
|
||||
ref <tls::certificateVerifier> service::getCertificateVerifier()
|
||||
{
|
||||
return m_certVerifier;
|
||||
}
|
||||
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
|
||||
} // net
|
||||
} // vmime
|
||||
|
@ -46,6 +46,16 @@ const serviceInfos::property serviceInfos::property::AUTH_PASSWORD
|
||||
const serviceInfos::property serviceInfos::property::TIMEOUT_FACTORY
|
||||
("timeout.factory", serviceInfos::property::TYPE_STRING);
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
const serviceInfos::property serviceInfos::property::CONNECTION_TLS
|
||||
("connection.tls", serviceInfos::property::TYPE_BOOL, "false");
|
||||
|
||||
const serviceInfos::property serviceInfos::property::CONNECTION_TLS_REQUIRED
|
||||
("connection.tls.required", serviceInfos::property::TYPE_BOOL, "false");
|
||||
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
|
||||
|
||||
// serviceInfos
|
||||
|
66
src/net/smtp/SMTPSTransport.cpp
Normal file
66
src/net/smtp/SMTPSTransport.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc., Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA..
|
||||
//
|
||||
|
||||
#include "vmime/net/smtp/SMTPSTransport.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace smtp {
|
||||
|
||||
|
||||
SMTPSTransport::SMTPSTransport(ref <session> sess, ref <security::authenticator> auth)
|
||||
: SMTPTransport(sess, auth, true)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SMTPSTransport::~SMTPSTransport()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const string SMTPSTransport::getProtocolName() const
|
||||
{
|
||||
return "smtps";
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Service infos
|
||||
|
||||
SMTPServiceInfos SMTPSTransport::sm_infos(true);
|
||||
|
||||
|
||||
const serviceInfos& SMTPSTransport::getInfosInstance()
|
||||
{
|
||||
return sm_infos;
|
||||
}
|
||||
|
||||
|
||||
const serviceInfos& SMTPSTransport::getInfos() const
|
||||
{
|
||||
return sm_infos;
|
||||
}
|
||||
|
||||
|
||||
} // smtp
|
||||
} // net
|
||||
} // vmime
|
||||
|
136
src/net/smtp/SMTPServiceInfos.cpp
Normal file
136
src/net/smtp/SMTPServiceInfos.cpp
Normal file
@ -0,0 +1,136 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc., Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA..
|
||||
//
|
||||
|
||||
#include "vmime/net/smtp/SMTPServiceInfos.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace smtp {
|
||||
|
||||
|
||||
SMTPServiceInfos::SMTPServiceInfos(const bool smtps)
|
||||
: m_smtps(smtps)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const string SMTPServiceInfos::getPropertyPrefix() const
|
||||
{
|
||||
if (m_smtps)
|
||||
return "transport.smtps.";
|
||||
else
|
||||
return "transport.smtp.";
|
||||
}
|
||||
|
||||
|
||||
const SMTPServiceInfos::props& SMTPServiceInfos::getProperties() const
|
||||
{
|
||||
static props smtpProps =
|
||||
{
|
||||
// SMTP-specific options
|
||||
property("options.need-authentication", serviceInfos::property::TYPE_BOOL, "false"),
|
||||
#if VMIME_HAVE_SASL_SUPPORT
|
||||
property("options.sasl", serviceInfos::property::TYPE_BOOL, "true"),
|
||||
property("options.sasl.fallback", serviceInfos::property::TYPE_BOOL, "false"),
|
||||
#endif // VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
// Common properties
|
||||
property(serviceInfos::property::AUTH_USERNAME, serviceInfos::property::FLAG_REQUIRED),
|
||||
property(serviceInfos::property::AUTH_PASSWORD, serviceInfos::property::FLAG_REQUIRED),
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
property(serviceInfos::property::CONNECTION_TLS),
|
||||
property(serviceInfos::property::CONNECTION_TLS_REQUIRED),
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
property(serviceInfos::property::SERVER_ADDRESS, serviceInfos::property::FLAG_REQUIRED),
|
||||
property(serviceInfos::property::SERVER_PORT, "25"),
|
||||
property(serviceInfos::property::SERVER_SOCKETFACTORY),
|
||||
|
||||
property(serviceInfos::property::TIMEOUT_FACTORY)
|
||||
};
|
||||
|
||||
static props smtpsProps =
|
||||
{
|
||||
// SMTP-specific options
|
||||
property("options.need-authentication", serviceInfos::property::TYPE_BOOL, "false"),
|
||||
#if VMIME_HAVE_SASL_SUPPORT
|
||||
property("options.sasl", serviceInfos::property::TYPE_BOOL, "true"),
|
||||
property("options.sasl.fallback", serviceInfos::property::TYPE_BOOL, "false"),
|
||||
#endif // VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
// Common properties
|
||||
property(serviceInfos::property::AUTH_USERNAME, serviceInfos::property::FLAG_REQUIRED),
|
||||
property(serviceInfos::property::AUTH_PASSWORD, serviceInfos::property::FLAG_REQUIRED),
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
property(serviceInfos::property::CONNECTION_TLS),
|
||||
property(serviceInfos::property::CONNECTION_TLS_REQUIRED),
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
property(serviceInfos::property::SERVER_ADDRESS, serviceInfos::property::FLAG_REQUIRED),
|
||||
property(serviceInfos::property::SERVER_PORT, "465"),
|
||||
property(serviceInfos::property::SERVER_SOCKETFACTORY),
|
||||
|
||||
property(serviceInfos::property::TIMEOUT_FACTORY)
|
||||
};
|
||||
|
||||
return m_smtps ? smtpsProps : smtpProps;
|
||||
}
|
||||
|
||||
|
||||
const std::vector <serviceInfos::property> SMTPServiceInfos::getAvailableProperties() const
|
||||
{
|
||||
std::vector <property> list;
|
||||
const props& p = getProperties();
|
||||
|
||||
// SMTP-specific options
|
||||
list.push_back(p.PROPERTY_OPTIONS_NEEDAUTH);
|
||||
#if VMIME_HAVE_SASL_SUPPORT
|
||||
list.push_back(p.PROPERTY_OPTIONS_SASL);
|
||||
list.push_back(p.PROPERTY_OPTIONS_SASL_FALLBACK);
|
||||
#endif // VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
// Common properties
|
||||
list.push_back(p.PROPERTY_AUTH_USERNAME);
|
||||
list.push_back(p.PROPERTY_AUTH_PASSWORD);
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
if (!m_smtps)
|
||||
{
|
||||
list.push_back(p.PROPERTY_CONNECTION_TLS);
|
||||
list.push_back(p.PROPERTY_CONNECTION_TLS_REQUIRED);
|
||||
}
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
list.push_back(p.PROPERTY_SERVER_ADDRESS);
|
||||
list.push_back(p.PROPERTY_SERVER_PORT);
|
||||
list.push_back(p.PROPERTY_SERVER_SOCKETFACTORY);
|
||||
|
||||
list.push_back(p.PROPERTY_TIMEOUT_FACTORY);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
} // smtp
|
||||
} // net
|
||||
} // vmime
|
||||
|
@ -24,8 +24,6 @@
|
||||
#include "vmime/encoderB64.hpp"
|
||||
#include "vmime/mailboxList.hpp"
|
||||
|
||||
#include "vmime/net/authHelper.hpp"
|
||||
|
||||
#include "vmime/utility/filteredStream.hpp"
|
||||
#include "vmime/utility/stringUtils.hpp"
|
||||
|
||||
@ -33,12 +31,18 @@
|
||||
#include "vmime/security/sasl/SASLContext.hpp"
|
||||
#endif // VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
#include "vmime/net/tls/TLSSession.hpp"
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
|
||||
// Helpers for service properties
|
||||
#define GET_PROPERTY(type, prop) \
|
||||
(sm_infos.getPropertyValue <type>(getSession(), sm_infos.getProperties().prop))
|
||||
(getInfos().getPropertyValue <type>(getSession(), \
|
||||
dynamic_cast <const SMTPServiceInfos&>(getInfos()).getProperties().prop))
|
||||
#define HAS_PROPERTY(prop) \
|
||||
(sm_infos.hasProperty(getSession(), sm_infos.getProperties().prop))
|
||||
(getInfos().hasProperty(getSession(), \
|
||||
dynamic_cast <const SMTPServiceInfos&>(getInfos()).getProperties().prop))
|
||||
|
||||
|
||||
namespace vmime {
|
||||
@ -46,9 +50,10 @@ namespace net {
|
||||
namespace smtp {
|
||||
|
||||
|
||||
SMTPTransport::SMTPTransport(ref <session> sess, ref <security::authenticator> auth)
|
||||
SMTPTransport::SMTPTransport(ref <session> sess, ref <security::authenticator> auth, const bool secured)
|
||||
: transport(sess, getInfosInstance(), auth), m_socket(NULL),
|
||||
m_authentified(false), m_extendedSMTP(false), m_timeoutHandler(NULL)
|
||||
m_authentified(false), m_extendedSMTP(false), m_timeoutHandler(NULL),
|
||||
m_secured(secured)
|
||||
{
|
||||
}
|
||||
|
||||
@ -97,6 +102,20 @@ void SMTPTransport::connect()
|
||||
getSocketFactory(GET_PROPERTY(string, PROPERTY_SERVER_SOCKETFACTORY));
|
||||
|
||||
m_socket = sf->create();
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
if (m_secured) // dedicated port/SMTPS
|
||||
{
|
||||
ref <tls::TLSSession> tlsSession =
|
||||
vmime::create <tls::TLSSession>(getCertificateVerifier());
|
||||
|
||||
ref <tls::TLSSocket> tlsSocket =
|
||||
tlsSession->getSocket(m_socket);
|
||||
|
||||
m_socket = tlsSocket;
|
||||
}
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
m_socket->connect(address, port);
|
||||
|
||||
m_responseBuffer.clear();
|
||||
@ -146,6 +165,39 @@ void SMTPTransport::connect()
|
||||
m_extendedSMTPResponse = response;
|
||||
}
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
// Setup secured connection, if requested
|
||||
const bool tls = HAS_PROPERTY(PROPERTY_CONNECTION_TLS)
|
||||
&& GET_PROPERTY(bool, PROPERTY_CONNECTION_TLS);
|
||||
const bool tlsRequired = HAS_PROPERTY(PROPERTY_CONNECTION_TLS_REQUIRED)
|
||||
&& GET_PROPERTY(bool, PROPERTY_CONNECTION_TLS_REQUIRED);
|
||||
|
||||
if (!m_secured && tls) // only if not POP3S
|
||||
{
|
||||
try
|
||||
{
|
||||
startTLS();
|
||||
}
|
||||
// Non-fatal error
|
||||
catch (exceptions::command_error&)
|
||||
{
|
||||
if (tlsRequired)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TLS is not required, so don't bother
|
||||
}
|
||||
}
|
||||
// Fatal error
|
||||
catch (...)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
// Authentication
|
||||
if (GET_PROPERTY(bool, PROPERTY_OPTIONS_NEEDAUTH))
|
||||
authenticate();
|
||||
@ -369,6 +421,45 @@ void SMTPTransport::authenticateSASL()
|
||||
#endif // VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
void SMTPTransport::startTLS()
|
||||
{
|
||||
try
|
||||
{
|
||||
sendRequest("STARTTLS");
|
||||
|
||||
string response;
|
||||
|
||||
if (readAllResponses(response) != 220)
|
||||
throw exceptions::command_error("STARTTLS", response);
|
||||
|
||||
ref <tls::TLSSession> tlsSession =
|
||||
vmime::create <tls::TLSSession>(getCertificateVerifier());
|
||||
|
||||
ref <tls::TLSSocket> tlsSocket =
|
||||
tlsSession->getSocket(m_socket);
|
||||
|
||||
tlsSocket->handshake(m_timeoutHandler);
|
||||
|
||||
m_socket = tlsSocket;
|
||||
}
|
||||
catch (exceptions::command_error&)
|
||||
{
|
||||
// Non-fatal error
|
||||
throw;
|
||||
}
|
||||
catch (exception&)
|
||||
{
|
||||
// Fatal error
|
||||
internalDisconnect();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
|
||||
const bool SMTPTransport::isConnected() const
|
||||
{
|
||||
return (m_socket && m_socket->isConnected() && m_authentified);
|
||||
@ -516,6 +607,8 @@ const string SMTPTransport::readResponseLine()
|
||||
{
|
||||
if (!m_timeoutHandler->handleTimeOut())
|
||||
throw exceptions::operation_timed_out();
|
||||
|
||||
m_timeoutHandler->resetTimeOut();
|
||||
}
|
||||
|
||||
// Receive data from the socket
|
||||
@ -589,76 +682,18 @@ const int SMTPTransport::readAllResponses(string& outText, const bool allText)
|
||||
|
||||
// Service infos
|
||||
|
||||
SMTPTransport::_infos SMTPTransport::sm_infos;
|
||||
SMTPServiceInfos SMTPTransport::sm_infos(false);
|
||||
|
||||
|
||||
const serviceInfos& SMTPTransport::getInfosInstance()
|
||||
{
|
||||
return (sm_infos);
|
||||
return sm_infos;
|
||||
}
|
||||
|
||||
|
||||
const serviceInfos& SMTPTransport::getInfos() const
|
||||
{
|
||||
return (sm_infos);
|
||||
}
|
||||
|
||||
|
||||
const string SMTPTransport::_infos::getPropertyPrefix() const
|
||||
{
|
||||
return "transport.smtp.";
|
||||
}
|
||||
|
||||
|
||||
const SMTPTransport::_infos::props& SMTPTransport::_infos::getProperties() const
|
||||
{
|
||||
static props p =
|
||||
{
|
||||
// SMTP-specific options
|
||||
property("options.need-authentication", serviceInfos::property::TYPE_BOOL, "false"),
|
||||
#if VMIME_HAVE_SASL_SUPPORT
|
||||
property("options.sasl", serviceInfos::property::TYPE_BOOL, "true"),
|
||||
property("options.sasl.fallback", serviceInfos::property::TYPE_BOOL, "false"),
|
||||
#endif // VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
// Common properties
|
||||
property(serviceInfos::property::AUTH_USERNAME),
|
||||
property(serviceInfos::property::AUTH_PASSWORD),
|
||||
|
||||
property(serviceInfos::property::SERVER_ADDRESS, serviceInfos::property::FLAG_REQUIRED),
|
||||
property(serviceInfos::property::SERVER_PORT, "25"),
|
||||
property(serviceInfos::property::SERVER_SOCKETFACTORY),
|
||||
|
||||
property(serviceInfos::property::TIMEOUT_FACTORY)
|
||||
};
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
const std::vector <serviceInfos::property> SMTPTransport::_infos::getAvailableProperties() const
|
||||
{
|
||||
std::vector <property> list;
|
||||
const props& p = getProperties();
|
||||
|
||||
// SMTP-specific options
|
||||
list.push_back(p.PROPERTY_OPTIONS_NEEDAUTH);
|
||||
#if VMIME_HAVE_SASL_SUPPORT
|
||||
list.push_back(p.PROPERTY_OPTIONS_SASL);
|
||||
list.push_back(p.PROPERTY_OPTIONS_SASL_FALLBACK);
|
||||
#endif // VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
// Common properties
|
||||
list.push_back(p.PROPERTY_AUTH_USERNAME);
|
||||
list.push_back(p.PROPERTY_AUTH_PASSWORD);
|
||||
|
||||
list.push_back(p.PROPERTY_SERVER_ADDRESS);
|
||||
list.push_back(p.PROPERTY_SERVER_PORT);
|
||||
list.push_back(p.PROPERTY_SERVER_SOCKETFACTORY);
|
||||
|
||||
list.push_back(p.PROPERTY_TIMEOUT_FACTORY);
|
||||
|
||||
return (list);
|
||||
return sm_infos;
|
||||
}
|
||||
|
||||
|
||||
|
342
src/net/tls/TLSSession.cpp
Normal file
342
src/net/tls/TLSSession.cpp
Normal file
@ -0,0 +1,342 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
// Linking this library statically or dynamically with other modules is making
|
||||
// a combined work based on this library. Thus, the terms and conditions of
|
||||
// the GNU General Public License cover the whole combination.
|
||||
//
|
||||
|
||||
#include <gnutls/gnutls.h>
|
||||
#include <gnutls/extra.h>
|
||||
|
||||
#include "vmime/net/tls/TLSSession.hpp"
|
||||
|
||||
#include "vmime/exception.hpp"
|
||||
|
||||
|
||||
// Enable GnuTLS debugging by defining GNUTLS_DEBUG
|
||||
//#define GNUTLS_DEBUG 1
|
||||
|
||||
|
||||
#if VMIME_DEBUG && GNUTLS_DEBUG
|
||||
#include <iostream>
|
||||
#endif // VMIME_DEBUG && GNUTLS_DEBUG
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace tls {
|
||||
|
||||
|
||||
#ifndef VMIME_BUILDING_DOC
|
||||
|
||||
// Initialize GNU TLS library
|
||||
struct TLSGlobal
|
||||
{
|
||||
TLSGlobal()
|
||||
{
|
||||
gnutls_global_init();
|
||||
//gnutls_global_init_extra();
|
||||
|
||||
#if VMIME_DEBUG && GNUTLS_DEBUG
|
||||
gnutls_global_set_log_function(TLSLogFunc);
|
||||
gnutls_global_set_log_level(10);
|
||||
#endif // VMIME_DEBUG && GNUTLS_DEBUG
|
||||
|
||||
gnutls_anon_allocate_client_credentials(&anonCred);
|
||||
gnutls_certificate_allocate_credentials(&certCred);
|
||||
}
|
||||
|
||||
~TLSGlobal()
|
||||
{
|
||||
gnutls_anon_free_client_credentials(anonCred);
|
||||
gnutls_certificate_free_credentials(certCred);
|
||||
|
||||
gnutls_global_deinit();
|
||||
}
|
||||
|
||||
#if VMIME_DEBUG && GNUTLS_DEBUG
|
||||
|
||||
static void TLSLogFunc(int level, const char *str)
|
||||
{
|
||||
std::cerr << "GNUTLS: [" << level << "] " << str << std::endl;
|
||||
}
|
||||
|
||||
#endif // VMIME_DEBUG && GNUTLS_DEBUG
|
||||
|
||||
|
||||
gnutls_anon_client_credentials anonCred;
|
||||
gnutls_certificate_credentials certCred;
|
||||
};
|
||||
|
||||
static TLSGlobal g_gnutlsGlobal;
|
||||
|
||||
|
||||
#endif // VMIME_BUILDING_DOC
|
||||
|
||||
|
||||
|
||||
TLSSession::TLSSession(ref <certificateVerifier> cv)
|
||||
: m_certVerifier(cv)
|
||||
{
|
||||
int res;
|
||||
|
||||
m_gnutlsSession = new gnutls_session;
|
||||
|
||||
if (gnutls_init(m_gnutlsSession, GNUTLS_CLIENT) != 0)
|
||||
throw std::bad_alloc();
|
||||
|
||||
// Sets some default priority on the ciphers, key exchange methods,
|
||||
// macs and compression methods.
|
||||
gnutls_set_default_priority(*m_gnutlsSession);
|
||||
|
||||
// Sets the priority on the certificate types supported by gnutls.
|
||||
// Priority is higher for types specified before others. After
|
||||
// specifying the types you want, you must append a 0.
|
||||
const int certTypePriority[] = { GNUTLS_CRT_X509, 0 };
|
||||
|
||||
res = gnutls_certificate_type_set_priority
|
||||
(*m_gnutlsSession, certTypePriority);
|
||||
|
||||
if (res < 0)
|
||||
{
|
||||
throwTLSException
|
||||
("gnutls_certificate_type_set_priority", res);
|
||||
}
|
||||
|
||||
// Sets the priority on the protocol types
|
||||
const int protoPriority[] = { GNUTLS_TLS1, GNUTLS_SSL3, 0 };
|
||||
|
||||
res = gnutls_protocol_set_priority(*m_gnutlsSession, protoPriority);
|
||||
|
||||
if (res < 0)
|
||||
{
|
||||
throwTLSException
|
||||
("gnutls_certificate_type_set_priority", res);
|
||||
}
|
||||
|
||||
// Priority on the ciphers
|
||||
const int cipherPriority[] =
|
||||
{
|
||||
GNUTLS_CIPHER_ARCFOUR_128,
|
||||
GNUTLS_CIPHER_3DES_CBC,
|
||||
GNUTLS_CIPHER_AES_128_CBC,
|
||||
GNUTLS_CIPHER_AES_256_CBC,
|
||||
GNUTLS_CIPHER_ARCFOUR_40,
|
||||
GNUTLS_CIPHER_RC2_40_CBC,
|
||||
GNUTLS_CIPHER_DES_CBC,
|
||||
0
|
||||
};
|
||||
|
||||
gnutls_cipher_set_priority(*m_gnutlsSession, cipherPriority);
|
||||
|
||||
// Priority on MACs
|
||||
const int macPriority[] = { GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0};
|
||||
|
||||
gnutls_mac_set_priority(*m_gnutlsSession, macPriority);
|
||||
|
||||
// Priority on key exchange methods
|
||||
const int kxPriority[] =
|
||||
{
|
||||
GNUTLS_KX_RSA,
|
||||
GNUTLS_KX_DHE_DSS,
|
||||
GNUTLS_KX_DHE_RSA,
|
||||
GNUTLS_KX_ANON_DH,
|
||||
GNUTLS_KX_SRP,
|
||||
GNUTLS_KX_RSA_EXPORT,
|
||||
GNUTLS_KX_SRP_RSA,
|
||||
GNUTLS_KX_SRP_DSS,
|
||||
0
|
||||
};
|
||||
|
||||
gnutls_kx_set_priority(*m_gnutlsSession, kxPriority);
|
||||
|
||||
// Priority on compression methods
|
||||
const int compressionPriority[] =
|
||||
{
|
||||
GNUTLS_COMP_ZLIB,
|
||||
//GNUTLS_COMP_LZO,
|
||||
GNUTLS_COMP_NULL,
|
||||
0
|
||||
};
|
||||
|
||||
gnutls_compression_set_priority(*m_gnutlsSession, compressionPriority);
|
||||
|
||||
// Initialize credentials
|
||||
gnutls_credentials_set(*m_gnutlsSession,
|
||||
GNUTLS_CRD_ANON, &g_gnutlsGlobal.anonCred);
|
||||
|
||||
gnutls_credentials_set(*m_gnutlsSession,
|
||||
GNUTLS_CRD_CERTIFICATE, &g_gnutlsGlobal.certCred);
|
||||
}
|
||||
|
||||
|
||||
TLSSession::TLSSession(const TLSSession&)
|
||||
: object()
|
||||
{
|
||||
// Not used
|
||||
}
|
||||
|
||||
|
||||
TLSSession::~TLSSession()
|
||||
{
|
||||
if (m_gnutlsSession)
|
||||
{
|
||||
gnutls_deinit(*m_gnutlsSession);
|
||||
|
||||
delete m_gnutlsSession;
|
||||
m_gnutlsSession = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ref <TLSSocket> TLSSession::getSocket(ref <socket> sok)
|
||||
{
|
||||
return vmime::create <TLSSocket>
|
||||
(thisRef().dynamicCast <TLSSession>(), sok);
|
||||
}
|
||||
|
||||
|
||||
ref <tls::certificateVerifier> TLSSession::getCertificateVerifier()
|
||||
{
|
||||
return m_certVerifier;
|
||||
}
|
||||
|
||||
|
||||
void TLSSession::throwTLSException(const string& fname, const int code)
|
||||
{
|
||||
string msg = fname + "() returned ";
|
||||
|
||||
#define ERROR(x) \
|
||||
case x: msg += #x; break;
|
||||
|
||||
switch (code)
|
||||
{
|
||||
ERROR(GNUTLS_E_SUCCESS)
|
||||
ERROR(GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM)
|
||||
ERROR(GNUTLS_E_UNKNOWN_CIPHER_TYPE)
|
||||
ERROR(GNUTLS_E_LARGE_PACKET)
|
||||
ERROR(GNUTLS_E_UNSUPPORTED_VERSION_PACKET)
|
||||
ERROR(GNUTLS_E_UNEXPECTED_PACKET_LENGTH)
|
||||
ERROR(GNUTLS_E_INVALID_SESSION)
|
||||
ERROR(GNUTLS_E_FATAL_ALERT_RECEIVED)
|
||||
ERROR(GNUTLS_E_UNEXPECTED_PACKET)
|
||||
ERROR(GNUTLS_E_WARNING_ALERT_RECEIVED)
|
||||
ERROR(GNUTLS_E_ERROR_IN_FINISHED_PACKET)
|
||||
ERROR(GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET)
|
||||
ERROR(GNUTLS_E_UNKNOWN_CIPHER_SUITE)
|
||||
ERROR(GNUTLS_E_UNWANTED_ALGORITHM)
|
||||
ERROR(GNUTLS_E_MPI_SCAN_FAILED)
|
||||
ERROR(GNUTLS_E_DECRYPTION_FAILED)
|
||||
ERROR(GNUTLS_E_MEMORY_ERROR)
|
||||
ERROR(GNUTLS_E_DECOMPRESSION_FAILED)
|
||||
ERROR(GNUTLS_E_COMPRESSION_FAILED)
|
||||
ERROR(GNUTLS_E_AGAIN)
|
||||
ERROR(GNUTLS_E_EXPIRED)
|
||||
ERROR(GNUTLS_E_DB_ERROR)
|
||||
ERROR(GNUTLS_E_SRP_PWD_ERROR)
|
||||
ERROR(GNUTLS_E_INSUFFICIENT_CREDENTIALS)
|
||||
ERROR(GNUTLS_E_HASH_FAILED)
|
||||
ERROR(GNUTLS_E_BASE64_DECODING_ERROR)
|
||||
ERROR(GNUTLS_E_MPI_PRINT_FAILED)
|
||||
ERROR(GNUTLS_E_REHANDSHAKE)
|
||||
ERROR(GNUTLS_E_GOT_APPLICATION_DATA)
|
||||
ERROR(GNUTLS_E_RECORD_LIMIT_REACHED)
|
||||
ERROR(GNUTLS_E_ENCRYPTION_FAILED)
|
||||
ERROR(GNUTLS_E_PK_ENCRYPTION_FAILED)
|
||||
ERROR(GNUTLS_E_PK_DECRYPTION_FAILED)
|
||||
ERROR(GNUTLS_E_PK_SIGN_FAILED)
|
||||
ERROR(GNUTLS_E_X509_UNSUPPORTED_CRITICAL_EXTENSION)
|
||||
ERROR(GNUTLS_E_KEY_USAGE_VIOLATION)
|
||||
ERROR(GNUTLS_E_NO_CERTIFICATE_FOUND)
|
||||
ERROR(GNUTLS_E_INVALID_REQUEST)
|
||||
ERROR(GNUTLS_E_SHORT_MEMORY_BUFFER)
|
||||
ERROR(GNUTLS_E_INTERRUPTED)
|
||||
ERROR(GNUTLS_E_PUSH_ERROR)
|
||||
ERROR(GNUTLS_E_PULL_ERROR)
|
||||
ERROR(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER)
|
||||
ERROR(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
|
||||
ERROR(GNUTLS_E_PKCS1_WRONG_PAD)
|
||||
ERROR(GNUTLS_E_RECEIVED_ILLEGAL_EXTENSION)
|
||||
ERROR(GNUTLS_E_INTERNAL_ERROR)
|
||||
ERROR(GNUTLS_E_DH_PRIME_UNACCEPTABLE)
|
||||
ERROR(GNUTLS_E_FILE_ERROR)
|
||||
ERROR(GNUTLS_E_TOO_MANY_EMPTY_PACKETS)
|
||||
ERROR(GNUTLS_E_UNKNOWN_PK_ALGORITHM)
|
||||
ERROR(GNUTLS_E_INIT_LIBEXTRA)
|
||||
ERROR(GNUTLS_E_LIBRARY_VERSION_MISMATCH)
|
||||
ERROR(GNUTLS_E_NO_TEMPORARY_RSA_PARAMS)
|
||||
ERROR(GNUTLS_E_LZO_INIT_FAILED)
|
||||
ERROR(GNUTLS_E_NO_COMPRESSION_ALGORITHMS)
|
||||
ERROR(GNUTLS_E_NO_CIPHER_SUITES)
|
||||
ERROR(GNUTLS_E_OPENPGP_GETKEY_FAILED)
|
||||
ERROR(GNUTLS_E_PK_SIG_VERIFY_FAILED)
|
||||
ERROR(GNUTLS_E_ILLEGAL_SRP_USERNAME)
|
||||
ERROR(GNUTLS_E_SRP_PWD_PARSING_ERROR)
|
||||
ERROR(GNUTLS_E_NO_TEMPORARY_DH_PARAMS)
|
||||
ERROR(GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
|
||||
ERROR(GNUTLS_E_ASN1_IDENTIFIER_NOT_FOUND)
|
||||
ERROR(GNUTLS_E_ASN1_DER_ERROR)
|
||||
ERROR(GNUTLS_E_ASN1_VALUE_NOT_FOUND)
|
||||
ERROR(GNUTLS_E_ASN1_GENERIC_ERROR)
|
||||
ERROR(GNUTLS_E_ASN1_VALUE_NOT_VALID)
|
||||
ERROR(GNUTLS_E_ASN1_TAG_ERROR)
|
||||
ERROR(GNUTLS_E_ASN1_TAG_IMPLICIT)
|
||||
ERROR(GNUTLS_E_ASN1_TYPE_ANY_ERROR)
|
||||
ERROR(GNUTLS_E_ASN1_SYNTAX_ERROR)
|
||||
ERROR(GNUTLS_E_ASN1_DER_OVERFLOW)
|
||||
ERROR(GNUTLS_E_OPENPGP_TRUSTDB_VERSION_UNSUPPORTED)
|
||||
ERROR(GNUTLS_E_OPENPGP_UID_REVOKED)
|
||||
ERROR(GNUTLS_E_CERTIFICATE_ERROR)
|
||||
//ERROR(GNUTLS_E_X509_CERTIFICATE_ERROR)
|
||||
ERROR(GNUTLS_E_CERTIFICATE_KEY_MISMATCH)
|
||||
ERROR(GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE)
|
||||
ERROR(GNUTLS_E_X509_UNKNOWN_SAN)
|
||||
ERROR(GNUTLS_E_OPENPGP_FINGERPRINT_UNSUPPORTED)
|
||||
ERROR(GNUTLS_E_X509_UNSUPPORTED_ATTRIBUTE)
|
||||
ERROR(GNUTLS_E_UNKNOWN_HASH_ALGORITHM)
|
||||
ERROR(GNUTLS_E_UNKNOWN_PKCS_CONTENT_TYPE)
|
||||
ERROR(GNUTLS_E_UNKNOWN_PKCS_BAG_TYPE)
|
||||
ERROR(GNUTLS_E_INVALID_PASSWORD)
|
||||
ERROR(GNUTLS_E_MAC_VERIFY_FAILED)
|
||||
ERROR(GNUTLS_E_CONSTRAINT_ERROR)
|
||||
ERROR(GNUTLS_E_BASE64_ENCODING_ERROR)
|
||||
ERROR(GNUTLS_E_INCOMPATIBLE_GCRYPT_LIBRARY)
|
||||
//ERROR(GNUTLS_E_INCOMPATIBLE_CRYPTO_LIBRARY)
|
||||
ERROR(GNUTLS_E_INCOMPATIBLE_LIBTASN1_LIBRARY)
|
||||
ERROR(GNUTLS_E_OPENPGP_KEYRING_ERROR)
|
||||
ERROR(GNUTLS_E_X509_UNSUPPORTED_OID)
|
||||
//ERROR(GNUTLS_E_RANDOM_FAILED)
|
||||
ERROR(GNUTLS_E_UNIMPLEMENTED_FEATURE)
|
||||
|
||||
default:
|
||||
|
||||
msg += "unknown error";
|
||||
break;
|
||||
}
|
||||
|
||||
#undef ERROR
|
||||
|
||||
throw exceptions::tls_exception(msg);
|
||||
}
|
||||
|
||||
|
||||
} // tls
|
||||
} // net
|
||||
} // vmime
|
||||
|
391
src/net/tls/TLSSocket.cpp
Normal file
391
src/net/tls/TLSSocket.cpp
Normal file
@ -0,0 +1,391 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
// Linking this library statically or dynamically with other modules is making
|
||||
// a combined work based on this library. Thus, the terms and conditions of
|
||||
// the GNU General Public License cover the whole combination.
|
||||
//
|
||||
|
||||
#include <gnutls/gnutls.h>
|
||||
#include <gnutls/x509.h>
|
||||
|
||||
#include "vmime/net/tls/TLSSocket.hpp"
|
||||
#include "vmime/net/tls/TLSSession.hpp"
|
||||
|
||||
#include "vmime/platformDependant.hpp"
|
||||
|
||||
#include "vmime/net/tls/X509Certificate.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace tls {
|
||||
|
||||
|
||||
TLSSocket::TLSSocket(ref <TLSSession> session, ref <socket> sok)
|
||||
: m_session(session), m_wrapped(sok), m_connected(false),
|
||||
m_handshaking(false), m_ex(NULL)
|
||||
{
|
||||
gnutls_transport_set_ptr(*m_session->m_gnutlsSession, this);
|
||||
|
||||
gnutls_transport_set_push_function(*m_session->m_gnutlsSession, gnutlsPushFunc);
|
||||
gnutls_transport_set_pull_function(*m_session->m_gnutlsSession, gnutlsPullFunc);
|
||||
}
|
||||
|
||||
|
||||
TLSSocket::~TLSSocket()
|
||||
{
|
||||
try
|
||||
{
|
||||
disconnect();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// Don't throw exception in destructor
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TLSSocket::connect(const string& address, const port_t port)
|
||||
{
|
||||
m_wrapped->connect(address, port);
|
||||
|
||||
handshake(NULL);
|
||||
|
||||
m_connected = true;
|
||||
}
|
||||
|
||||
|
||||
void TLSSocket::disconnect()
|
||||
{
|
||||
if (m_connected)
|
||||
{
|
||||
gnutls_bye(*m_session->m_gnutlsSession, GNUTLS_SHUT_RDWR);
|
||||
|
||||
m_wrapped->disconnect();
|
||||
|
||||
m_connected = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const bool TLSSocket::isConnected() const
|
||||
{
|
||||
return m_wrapped->isConnected() && m_connected;
|
||||
}
|
||||
|
||||
|
||||
void TLSSocket::receive(string& buffer)
|
||||
{
|
||||
const int size = receiveRaw(m_buffer, sizeof(m_buffer));
|
||||
buffer = vmime::string(m_buffer, size);
|
||||
}
|
||||
|
||||
|
||||
void TLSSocket::send(const string& buffer)
|
||||
{
|
||||
sendRaw(buffer.data(), buffer.length());
|
||||
}
|
||||
|
||||
|
||||
const int TLSSocket::receiveRaw(char* buffer, const int count)
|
||||
{
|
||||
const ssize_t ret = gnutls_record_recv
|
||||
(*m_session->m_gnutlsSession,
|
||||
buffer, static_cast <size_t>(count));
|
||||
|
||||
if (m_ex)
|
||||
internalThrow();
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
if (ret == GNUTLS_E_AGAIN)
|
||||
return 0;
|
||||
|
||||
TLSSession::throwTLSException("gnutls_record_recv", ret);
|
||||
}
|
||||
|
||||
return static_cast <int>(ret);
|
||||
}
|
||||
|
||||
|
||||
void TLSSocket::sendRaw(const char* buffer, const int count)
|
||||
{
|
||||
gnutls_record_send
|
||||
(*m_session->m_gnutlsSession,
|
||||
buffer, static_cast <size_t>(count));
|
||||
|
||||
if (m_ex)
|
||||
internalThrow();
|
||||
}
|
||||
|
||||
|
||||
void TLSSocket::handshake(ref <timeoutHandler> toHandler)
|
||||
{
|
||||
if (toHandler)
|
||||
toHandler->resetTimeOut();
|
||||
|
||||
// Start handshaking process
|
||||
m_handshaking = true;
|
||||
m_toHandler = toHandler;
|
||||
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
const int ret = gnutls_handshake(*m_session->m_gnutlsSession);
|
||||
|
||||
if (m_ex)
|
||||
internalThrow();
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
if (ret == GNUTLS_E_AGAIN ||
|
||||
ret == GNUTLS_E_INTERRUPTED)
|
||||
{
|
||||
// Non-fatal error
|
||||
platformDependant::getHandler()->wait();
|
||||
}
|
||||
else
|
||||
{
|
||||
TLSSession::throwTLSException("gnutls_handshake", ret);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Successful handshake
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
m_handshaking = false;
|
||||
m_toHandler = NULL;
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
m_handshaking = false;
|
||||
m_toHandler = NULL;
|
||||
|
||||
// Verify server's certificate(s)
|
||||
ref <certificateChain> certs = getPeerCertificates();
|
||||
|
||||
if (certs == NULL)
|
||||
throw exceptions::tls_exception("No peer certificate.");
|
||||
|
||||
m_session->getCertificateVerifier()->verify(certs);
|
||||
|
||||
m_connected = true;
|
||||
}
|
||||
|
||||
|
||||
ssize_t TLSSocket::gnutlsPushFunc
|
||||
(gnutls_transport_ptr trspt, const void* data, size_t len)
|
||||
{
|
||||
TLSSocket* sok = reinterpret_cast <TLSSocket*>(trspt);
|
||||
|
||||
try
|
||||
{
|
||||
sok->m_wrapped->sendRaw
|
||||
(reinterpret_cast <const char*>(data), static_cast <int>(len));
|
||||
}
|
||||
catch (exception& e)
|
||||
{
|
||||
// Workaround for bad behaviour when throwing C++ exceptions
|
||||
// from C functions (GNU TLS)
|
||||
sok->m_ex = e.clone();
|
||||
return -1;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
ssize_t TLSSocket::gnutlsPullFunc
|
||||
(gnutls_transport_ptr trspt, void* data, size_t len)
|
||||
{
|
||||
TLSSocket* sok = reinterpret_cast <TLSSocket*>(trspt);
|
||||
|
||||
try
|
||||
{
|
||||
// Workaround for cross-platform asynchronous handshaking:
|
||||
// gnutls_handshake() only returns GNUTLS_E_AGAIN if recv()
|
||||
// returns -1 and errno is set to EGAIN...
|
||||
if (sok->m_handshaking)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
const ssize_t ret = static_cast <ssize_t>
|
||||
(sok->m_wrapped->receiveRaw
|
||||
(reinterpret_cast <char*>(data),
|
||||
static_cast <int>(len)));
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
// No data available yet
|
||||
platformDependant::getHandler()->wait();
|
||||
}
|
||||
else
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Check whether the time-out delay is elapsed
|
||||
if (sok->m_toHandler && sok->m_toHandler->isTimeOut())
|
||||
{
|
||||
if (!sok->m_toHandler->handleTimeOut())
|
||||
throw exceptions::operation_timed_out();
|
||||
|
||||
sok->m_toHandler->resetTimeOut();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const ssize_t n = static_cast <ssize_t>
|
||||
(sok->m_wrapped->receiveRaw
|
||||
(reinterpret_cast <char*>(data),
|
||||
static_cast <int>(len)));
|
||||
|
||||
if (n == 0)
|
||||
return GNUTLS_E_AGAIN; // This seems like a hack, really...
|
||||
|
||||
return n;
|
||||
}
|
||||
}
|
||||
catch (exception& e)
|
||||
{
|
||||
// Workaround for bad behaviour when throwing C++ exceptions
|
||||
// from C functions (GNU TLS)
|
||||
sok->m_ex = e.clone();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ref <certificateChain> TLSSocket::getPeerCertificates()
|
||||
{
|
||||
unsigned int certCount = 0;
|
||||
const gnutls_datum* rawData = gnutls_certificate_get_peers
|
||||
(*m_session->m_gnutlsSession, &certCount);
|
||||
|
||||
// Try X.509
|
||||
gnutls_x509_crt* x509Certs = new gnutls_x509_crt[certCount];
|
||||
|
||||
unsigned int count = certCount;
|
||||
|
||||
int res = gnutls_x509_crt_list_import
|
||||
(x509Certs, &count, rawData, GNUTLS_X509_FMT_PEM, 0);
|
||||
|
||||
if (res <= 0)
|
||||
{
|
||||
count = certCount;
|
||||
|
||||
res = gnutls_x509_crt_list_import
|
||||
(x509Certs, &count, rawData, GNUTLS_X509_FMT_DER, 0);
|
||||
}
|
||||
|
||||
if (res >= 1)
|
||||
{
|
||||
std::vector <ref <certificate> > certs;
|
||||
bool error = false;
|
||||
|
||||
count = static_cast <unsigned int>(res);
|
||||
|
||||
for (unsigned int i = 0 ; i < count ; ++i)
|
||||
{
|
||||
size_t dataSize = 0;
|
||||
|
||||
gnutls_x509_crt_export(x509Certs[i],
|
||||
GNUTLS_X509_FMT_DER, NULL, &dataSize);
|
||||
|
||||
byte* data = new byte[dataSize];
|
||||
|
||||
gnutls_x509_crt_export(x509Certs[i],
|
||||
GNUTLS_X509_FMT_DER, data, &dataSize);
|
||||
|
||||
ref <X509Certificate> cert =
|
||||
X509Certificate::import(data, dataSize);
|
||||
|
||||
if (cert != NULL)
|
||||
certs.push_back(cert);
|
||||
else
|
||||
error = true;
|
||||
|
||||
delete [] data;
|
||||
|
||||
gnutls_x509_crt_deinit(x509Certs[i]);
|
||||
}
|
||||
|
||||
delete [] x509Certs;
|
||||
|
||||
if (error)
|
||||
return NULL;
|
||||
|
||||
return vmime::create <certificateChain>(certs);
|
||||
}
|
||||
|
||||
delete [] x509Certs;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// Following is a workaround for C++ exceptions to pass correctly between
|
||||
// C and C++ calls.
|
||||
//
|
||||
// gnutls_record_recv() calls TLSSocket::gnutlsPullFunc, and exceptions
|
||||
// thrown by the socket can not not catched.
|
||||
|
||||
#ifndef VMIME_BUILDING_DOC
|
||||
|
||||
class TLSSocket_DeleteExWrapper : public object
|
||||
{
|
||||
public:
|
||||
|
||||
TLSSocket_DeleteExWrapper(exception* ex) : m_ex(ex) { }
|
||||
~TLSSocket_DeleteExWrapper() { delete m_ex; }
|
||||
|
||||
private:
|
||||
|
||||
exception* m_ex;
|
||||
};
|
||||
|
||||
#endif // VMIME_BUILDING_DOC
|
||||
|
||||
|
||||
void TLSSocket::internalThrow()
|
||||
{
|
||||
static std::vector <ref <TLSSocket_DeleteExWrapper> > exToDelete;
|
||||
|
||||
if (m_ex)
|
||||
{
|
||||
// To avoid memory leaks
|
||||
exToDelete.push_back(vmime::create <TLSSocket_DeleteExWrapper>(m_ex));
|
||||
|
||||
throw *m_ex;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // tls
|
||||
} // net
|
||||
} // vmime
|
||||
|
273
src/net/tls/X509Certificate.cpp
Normal file
273
src/net/tls/X509Certificate.cpp
Normal file
@ -0,0 +1,273 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
// Linking this library statically or dynamically with other modules is making
|
||||
// a combined work based on this library. Thus, the terms and conditions of
|
||||
// the GNU General Public License cover the whole combination.
|
||||
//
|
||||
|
||||
#include <gnutls/gnutls.h>
|
||||
#include <gnutls/x509.h>
|
||||
|
||||
#include <ctime>
|
||||
|
||||
#include "vmime/net/tls/X509Certificate.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace tls {
|
||||
|
||||
|
||||
#ifndef VMIME_BUILDING_DOC
|
||||
|
||||
struct X509CertificateInternalData
|
||||
{
|
||||
X509CertificateInternalData()
|
||||
{
|
||||
gnutls_x509_crt_init(&cert);
|
||||
}
|
||||
|
||||
~X509CertificateInternalData()
|
||||
{
|
||||
gnutls_x509_crt_deinit(cert);
|
||||
}
|
||||
|
||||
|
||||
gnutls_x509_crt cert;
|
||||
};
|
||||
|
||||
#endif // VMIME_BUILDING_DOC
|
||||
|
||||
|
||||
X509Certificate::X509Certificate()
|
||||
: m_data(new X509CertificateInternalData)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
X509Certificate::X509Certificate(const X509Certificate&)
|
||||
: certificate(), m_data(NULL)
|
||||
{
|
||||
// Not used
|
||||
}
|
||||
|
||||
|
||||
X509Certificate::~X509Certificate()
|
||||
{
|
||||
delete m_data;
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
ref <X509Certificate> X509Certificate::import(utility::inputStream& is)
|
||||
{
|
||||
byteArray bytes;
|
||||
utility::stream::value_type chunk[4096];
|
||||
|
||||
while (!is.eof())
|
||||
{
|
||||
const int len = is.read(chunk, sizeof(chunk));
|
||||
bytes.insert(bytes.end(), chunk, chunk + len);
|
||||
}
|
||||
|
||||
return import(&bytes[0], bytes.size());
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
ref <X509Certificate> X509Certificate::import
|
||||
(const byte* data, const unsigned int length)
|
||||
{
|
||||
ref <X509Certificate> cert = vmime::create <X509Certificate>();
|
||||
|
||||
gnutls_datum buffer;
|
||||
buffer.data = const_cast <byte*>(data);
|
||||
buffer.size = length;
|
||||
|
||||
// Try DER format
|
||||
if (gnutls_x509_crt_import(cert->m_data->cert, &buffer, GNUTLS_X509_FMT_DER) >= 0)
|
||||
return cert;
|
||||
|
||||
// Try PEM format
|
||||
if (gnutls_x509_crt_import(cert->m_data->cert, &buffer, GNUTLS_X509_FMT_PEM) >= 0)
|
||||
return cert;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void X509Certificate::write
|
||||
(utility::outputStream& os, const Format format) const
|
||||
{
|
||||
size_t dataSize = 0;
|
||||
gnutls_x509_crt_fmt fmt = GNUTLS_X509_FMT_DER;
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case FORMAT_DER: fmt = GNUTLS_X509_FMT_DER; break;
|
||||
case FORMAT_PEM: fmt = GNUTLS_X509_FMT_PEM; break;
|
||||
}
|
||||
|
||||
gnutls_x509_crt_export(m_data->cert, fmt, NULL, &dataSize);
|
||||
|
||||
byte* data = new byte[dataSize];
|
||||
|
||||
gnutls_x509_crt_export(m_data->cert, fmt, data, &dataSize);
|
||||
|
||||
try
|
||||
{
|
||||
os.write(reinterpret_cast <utility::stream::value_type*>(data), dataSize);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
delete [] data;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const byteArray X509Certificate::getSerialNumber() const
|
||||
{
|
||||
char serial[64];
|
||||
size_t serialSize = sizeof(serial);
|
||||
|
||||
gnutls_x509_crt_get_serial(m_data->cert, serial, &serialSize);
|
||||
|
||||
return byteArray(serial, serial + serialSize);
|
||||
}
|
||||
|
||||
|
||||
const bool X509Certificate::checkIssuer
|
||||
(ref <const X509Certificate> issuer) const
|
||||
{
|
||||
return (gnutls_x509_crt_check_issuer
|
||||
(m_data->cert, issuer->m_data->cert) >= 1);
|
||||
}
|
||||
|
||||
|
||||
const bool X509Certificate::verify(ref <const X509Certificate> caCert) const
|
||||
{
|
||||
unsigned int verify = 0;
|
||||
|
||||
const int res = gnutls_x509_crt_verify
|
||||
(m_data->cert, &(caCert->m_data->cert), 1,
|
||||
GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT,
|
||||
&verify);
|
||||
|
||||
return (res == 0 && verify == 0);
|
||||
}
|
||||
|
||||
|
||||
const datetime X509Certificate::getActivationDate() const
|
||||
{
|
||||
const time_t t = gnutls_x509_crt_get_activation_time(m_data->cert);
|
||||
return datetime(t);
|
||||
}
|
||||
|
||||
|
||||
const datetime X509Certificate::getExpirationDate() const
|
||||
{
|
||||
const time_t t = gnutls_x509_crt_get_expiration_time(m_data->cert);
|
||||
return datetime(t);
|
||||
}
|
||||
|
||||
|
||||
const byteArray X509Certificate::getFingerprint(const DigestAlgorithm algo) const
|
||||
{
|
||||
gnutls_digest_algorithm galgo;
|
||||
|
||||
switch (algo)
|
||||
{
|
||||
case DIGEST_MD5:
|
||||
|
||||
galgo = GNUTLS_DIG_MD5;
|
||||
break;
|
||||
|
||||
default:
|
||||
case DIGEST_SHA1:
|
||||
|
||||
galgo = GNUTLS_DIG_SHA;
|
||||
break;
|
||||
}
|
||||
|
||||
size_t bufferSize = 0;
|
||||
gnutls_x509_crt_get_fingerprint
|
||||
(m_data->cert, galgo, NULL, &bufferSize);
|
||||
|
||||
byte* buffer = new byte[bufferSize];
|
||||
|
||||
if (gnutls_x509_crt_get_fingerprint
|
||||
(m_data->cert, galgo, buffer, &bufferSize) == 0)
|
||||
{
|
||||
byteArray res;
|
||||
res.insert(res.end(), buffer, buffer + bufferSize);
|
||||
|
||||
delete [] buffer;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
delete [] buffer;
|
||||
|
||||
return byteArray();
|
||||
}
|
||||
|
||||
|
||||
const byteArray X509Certificate::getEncoded() const
|
||||
{
|
||||
byteArray bytes;
|
||||
utility::outputStreamByteArrayAdapter os(bytes);
|
||||
|
||||
write(os, FORMAT_DER);
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
|
||||
const string X509Certificate::getType() const
|
||||
{
|
||||
return "X.509";
|
||||
}
|
||||
|
||||
|
||||
const int X509Certificate::getVersion() const
|
||||
{
|
||||
return gnutls_x509_crt_get_version(m_data->cert);
|
||||
}
|
||||
|
||||
|
||||
const bool X509Certificate::equals(ref <const certificate> other) const
|
||||
{
|
||||
ref <const X509Certificate> otherX509 =
|
||||
other.dynamicCast <const X509Certificate>();
|
||||
|
||||
if (!otherX509)
|
||||
return false;
|
||||
|
||||
const byteArray fp1 = getFingerprint(DIGEST_MD5);
|
||||
const byteArray fp2 = otherX509->getFingerprint(DIGEST_MD5);
|
||||
|
||||
return fp1 == fp2;
|
||||
}
|
||||
|
||||
|
||||
} // tls
|
||||
} // net
|
||||
} // vmime
|
||||
|
@ -21,22 +21,33 @@
|
||||
// the GNU General Public License cover the whole combination.
|
||||
//
|
||||
|
||||
#ifndef VMIME_NET_AUTHHELPER_HPP_INCLUDED
|
||||
#define VMIME_NET_AUTHHELPER_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/types.hpp"
|
||||
#include "vmime/net/tls/certificateChain.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace tls {
|
||||
|
||||
|
||||
void hmac_md5(const string& text, const string& key, string& hexDigest);
|
||||
certificateChain::certificateChain(const std::vector <ref <certificate> >& certs)
|
||||
: m_certs(certs)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const unsigned int certificateChain::getCount() const
|
||||
{
|
||||
return static_cast <unsigned int>(m_certs.size());
|
||||
}
|
||||
|
||||
|
||||
ref <certificate> certificateChain::getAt(const unsigned int index)
|
||||
{
|
||||
return m_certs[index];
|
||||
}
|
||||
|
||||
|
||||
} // tls
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_AUTHHELPER_HPP_INCLUDED
|
164
src/net/tls/defaultCertificateVerifier.cpp
Normal file
164
src/net/tls/defaultCertificateVerifier.cpp
Normal file
@ -0,0 +1,164 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
// Linking this library statically or dynamically with other modules is making
|
||||
// a combined work based on this library. Thus, the terms and conditions of
|
||||
// the GNU General Public License cover the whole combination.
|
||||
//
|
||||
|
||||
#include "vmime/net/tls/defaultCertificateVerifier.hpp"
|
||||
|
||||
#include "vmime/net/tls/X509Certificate.hpp"
|
||||
|
||||
#include "vmime/exception.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace tls {
|
||||
|
||||
|
||||
defaultCertificateVerifier::defaultCertificateVerifier()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
defaultCertificateVerifier::~defaultCertificateVerifier()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
defaultCertificateVerifier::defaultCertificateVerifier(const defaultCertificateVerifier&)
|
||||
: certificateVerifier()
|
||||
{
|
||||
// Not used
|
||||
}
|
||||
|
||||
|
||||
void defaultCertificateVerifier::verify(ref <certificateChain> chain)
|
||||
{
|
||||
if (chain->getCount() == 0)
|
||||
return;
|
||||
|
||||
const string type = chain->getAt(0)->getType();
|
||||
|
||||
if (type == "X.509")
|
||||
verifyX509(chain);
|
||||
else
|
||||
throw exceptions::unsupported_certificate_type(type);
|
||||
}
|
||||
|
||||
|
||||
void defaultCertificateVerifier::verifyX509(ref <certificateChain> chain)
|
||||
{
|
||||
// For every certificate in the chain, verify that the certificate
|
||||
// has been issued by the next certificate in the chain
|
||||
if (chain->getCount() >= 2)
|
||||
{
|
||||
for (unsigned int i = 0 ; i < chain->getCount() - 1 ; ++i)
|
||||
{
|
||||
ref <X509Certificate> cert =
|
||||
chain->getAt(i).dynamicCast <X509Certificate>();
|
||||
|
||||
ref <X509Certificate> next =
|
||||
chain->getAt(i + 1).dynamicCast <X509Certificate>();
|
||||
|
||||
if (!cert->checkIssuer(next))
|
||||
{
|
||||
throw exceptions::certificate_verification_exception
|
||||
("Subject/issuer verification failed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For every certificate in the chain, verify that the certificate
|
||||
// is valid at the current time
|
||||
const datetime now = datetime::now();
|
||||
|
||||
for (unsigned int i = 0 ; i < chain->getCount() ; ++i)
|
||||
{
|
||||
ref <X509Certificate> cert =
|
||||
chain->getAt(i).dynamicCast <X509Certificate>();
|
||||
|
||||
const datetime begin = cert->getActivationDate();
|
||||
const datetime end = cert->getExpirationDate();
|
||||
|
||||
if (now < begin || now > end)
|
||||
{
|
||||
throw exceptions::certificate_verification_exception
|
||||
("Validity date check failed.");
|
||||
}
|
||||
}
|
||||
|
||||
// Check whether the certificate can be trusted
|
||||
|
||||
// -- First, verify that the the last certificate in the chain was
|
||||
// -- issued by a third-party that we trust
|
||||
ref <X509Certificate> lastCert =
|
||||
chain->getAt(chain->getCount() - 1).dynamicCast <X509Certificate>();
|
||||
|
||||
bool trusted = false;
|
||||
|
||||
for (unsigned int i = 0 ; !trusted && i < m_x509RootCAs.size() ; ++i)
|
||||
{
|
||||
ref <X509Certificate> rootCa = m_x509RootCAs[i];
|
||||
|
||||
if (lastCert->verify(rootCa))
|
||||
trusted = true;
|
||||
}
|
||||
|
||||
// -- Next, if the issuer certificate cannot be verified against
|
||||
// -- root CAs, compare the subject's certificate against the
|
||||
// -- trusted certificates
|
||||
ref <X509Certificate> firstCert =
|
||||
chain->getAt(0).dynamicCast <X509Certificate>();
|
||||
|
||||
for (unsigned int i = 0 ; !trusted && i < m_x509TrustedCerts.size() ; ++i)
|
||||
{
|
||||
ref <X509Certificate> cert = m_x509TrustedCerts[i];
|
||||
|
||||
if (firstCert->equals(cert))
|
||||
trusted = true;
|
||||
}
|
||||
|
||||
if (!trusted)
|
||||
{
|
||||
throw exceptions::certificate_verification_exception
|
||||
("Cannot verify certificate against trusted certificates.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void defaultCertificateVerifier::setX509RootCAs
|
||||
(const std::vector <ref <X509Certificate> >& caCerts)
|
||||
{
|
||||
m_x509RootCAs = caCerts;
|
||||
}
|
||||
|
||||
|
||||
void defaultCertificateVerifier::setX509TrustedCerts
|
||||
(const std::vector <ref <X509Certificate> >& trustedCerts)
|
||||
{
|
||||
m_x509TrustedCerts = trustedCerts;
|
||||
}
|
||||
|
||||
|
||||
} // tls
|
||||
} // net
|
||||
} // vmime
|
||||
|
@ -117,6 +117,22 @@ void outputStreamStringAdapter::write(const value_type* const data, const size_t
|
||||
|
||||
|
||||
|
||||
// outputStreamByteArrayAdapter
|
||||
|
||||
outputStreamByteArrayAdapter::outputStreamByteArrayAdapter(byteArray& array)
|
||||
: m_array(array)
|
||||
{
|
||||
m_array.clear();
|
||||
}
|
||||
|
||||
|
||||
void outputStreamByteArrayAdapter::write(const value_type* const data, const size_type count)
|
||||
{
|
||||
m_array.insert(m_array.end(), data, data + count);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// inputStreamAdapter
|
||||
|
||||
inputStreamAdapter::inputStreamAdapter(std::istream& is)
|
||||
|
@ -842,7 +842,7 @@ INCLUDE_FILE_PATTERNS =
|
||||
# or name=definition (no spaces). If the definition and the = are
|
||||
# omitted =1 is assumed.
|
||||
|
||||
PREDEFINED = VMIME_BUILDING_DOC
|
||||
PREDEFINED = VMIME_BUILDING_DOC VMIME_HAVE_SASL_SUPPORT VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
|
||||
# this tag can be used to specify a list of macro names that should be expanded.
|
||||
|
@ -77,11 +77,15 @@ public:
|
||||
*/
|
||||
virtual const char* name() const throw();
|
||||
|
||||
/** Clone this object.
|
||||
*
|
||||
* @return a new copy of this object
|
||||
*/
|
||||
virtual exception* clone() const;
|
||||
|
||||
protected:
|
||||
|
||||
static const exception NO_EXCEPTION;
|
||||
|
||||
virtual exception* clone() const;
|
||||
};
|
||||
|
||||
|
||||
@ -818,7 +822,7 @@ public:
|
||||
#if VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
|
||||
/** Base class for exceptions throw by SASL module.
|
||||
/** Base class for exceptions thrown by SASL module.
|
||||
*/
|
||||
|
||||
class sasl_exception : public vmime::exception
|
||||
@ -866,6 +870,63 @@ public:
|
||||
#endif // VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
|
||||
/** Base class for exceptions thrown by TLS module.
|
||||
*/
|
||||
|
||||
class tls_exception : public vmime::exception
|
||||
{
|
||||
public:
|
||||
|
||||
tls_exception(const string& what, const exception& other = NO_EXCEPTION);
|
||||
~tls_exception() throw();
|
||||
|
||||
exception* clone() const;
|
||||
const char* name() const throw();
|
||||
};
|
||||
|
||||
|
||||
class certificate_exception : public tls_exception
|
||||
{
|
||||
public:
|
||||
|
||||
certificate_exception(const string& what, const exception& other = NO_EXCEPTION);
|
||||
~certificate_exception() throw();
|
||||
|
||||
exception* clone() const;
|
||||
const char* name() const throw();
|
||||
};
|
||||
|
||||
|
||||
class certificate_verification_exception : public certificate_exception
|
||||
{
|
||||
public:
|
||||
|
||||
certificate_verification_exception(const string& what, const exception& other = NO_EXCEPTION);
|
||||
~certificate_verification_exception() throw ();
|
||||
|
||||
exception* clone() const;
|
||||
const char* name() const throw ();
|
||||
};
|
||||
|
||||
|
||||
class unsupported_certificate_type : public certificate_exception
|
||||
{
|
||||
public:
|
||||
|
||||
unsupported_certificate_type(const string& type, const exception& other = NO_EXCEPTION);
|
||||
~unsupported_certificate_type() throw ();
|
||||
|
||||
exception* clone() const;
|
||||
const char* name() const throw ();
|
||||
};
|
||||
|
||||
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
|
||||
|
||||
} // exceptions
|
||||
|
||||
|
@ -99,6 +99,10 @@ private:
|
||||
void authenticateSASL();
|
||||
#endif // VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
void startTLS();
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
|
||||
weak_ref <IMAPStore> m_store;
|
||||
|
||||
|
@ -94,6 +94,11 @@ public:
|
||||
return (m_tag);
|
||||
}
|
||||
|
||||
void setSocket(weak_ref <socket> sok)
|
||||
{
|
||||
m_socket = sok;
|
||||
}
|
||||
|
||||
|
||||
const string lastLine() const
|
||||
{
|
||||
|
63
vmime/net/imap/IMAPSStore.hpp
Normal file
63
vmime/net/imap/IMAPSStore.hpp
Normal file
@ -0,0 +1,63 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
// Linking this library statically or dynamically with other modules is making
|
||||
// a combined work based on this library. Thus, the terms and conditions of
|
||||
// the GNU General Public License cover the whole combination.
|
||||
//
|
||||
|
||||
#ifndef VMIME_NET_IMAP_IMAPSSTORE_HPP_INCLUDED
|
||||
#define VMIME_NET_IMAP_IMAPSSTORE_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/net/imap/IMAPStore.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace imap {
|
||||
|
||||
|
||||
/** IMAPS store service.
|
||||
*/
|
||||
|
||||
class IMAPSStore : public IMAPStore
|
||||
{
|
||||
public:
|
||||
|
||||
IMAPSStore(ref <session> sess, ref <security::authenticator> auth);
|
||||
~IMAPSStore();
|
||||
|
||||
const string getProtocolName() const;
|
||||
|
||||
static const serviceInfos& getInfosInstance();
|
||||
const serviceInfos& getInfos() const;
|
||||
|
||||
private:
|
||||
|
||||
static IMAPServiceInfos sm_infos;
|
||||
};
|
||||
|
||||
|
||||
} // imap
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_IMAP_IMAPSSTORE_HPP_INCLUDED
|
||||
|
87
vmime/net/imap/IMAPServiceInfos.hpp
Normal file
87
vmime/net/imap/IMAPServiceInfos.hpp
Normal file
@ -0,0 +1,87 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
// Linking this library statically or dynamically with other modules is making
|
||||
// a combined work based on this library. Thus, the terms and conditions of
|
||||
// the GNU General Public License cover the whole combination.
|
||||
//
|
||||
|
||||
#ifndef VMIME_NET_IMAP_IMAPSERVICEINFOS_HPP_INCLUDED
|
||||
#define VMIME_NET_IMAP_IMAPSERVICEINFOS_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/config.hpp"
|
||||
#include "vmime/net/serviceInfos.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace imap {
|
||||
|
||||
|
||||
/** Information about IMAP service.
|
||||
*/
|
||||
|
||||
class IMAPServiceInfos : public serviceInfos
|
||||
{
|
||||
public:
|
||||
|
||||
IMAPServiceInfos(const bool imaps);
|
||||
|
||||
struct props
|
||||
{
|
||||
// IMAP-specific options
|
||||
#if VMIME_HAVE_SASL_SUPPORT
|
||||
serviceInfos::property PROPERTY_OPTIONS_SASL;
|
||||
serviceInfos::property PROPERTY_OPTIONS_SASL_FALLBACK;
|
||||
#endif // VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
// Common properties
|
||||
serviceInfos::property PROPERTY_AUTH_USERNAME;
|
||||
serviceInfos::property PROPERTY_AUTH_PASSWORD;
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
serviceInfos::property PROPERTY_CONNECTION_TLS;
|
||||
serviceInfos::property PROPERTY_CONNECTION_TLS_REQUIRED;
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
serviceInfos::property PROPERTY_SERVER_ADDRESS;
|
||||
serviceInfos::property PROPERTY_SERVER_PORT;
|
||||
serviceInfos::property PROPERTY_SERVER_SOCKETFACTORY;
|
||||
|
||||
serviceInfos::property PROPERTY_TIMEOUT_FACTORY;
|
||||
};
|
||||
|
||||
const props& getProperties() const;
|
||||
|
||||
const string getPropertyPrefix() const;
|
||||
const std::vector <serviceInfos::property> getAvailableProperties() const;
|
||||
|
||||
private:
|
||||
|
||||
const bool m_imaps;
|
||||
};
|
||||
|
||||
|
||||
} // imap
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_IMAP_IMAPSERVICEINFOS_HPP_INCLUDED
|
||||
|
@ -31,7 +31,7 @@
|
||||
#include "vmime/net/socket.hpp"
|
||||
#include "vmime/net/folder.hpp"
|
||||
|
||||
#include <ostream>
|
||||
#include "vmime/net/imap/IMAPServiceInfos.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
@ -56,7 +56,7 @@ class IMAPStore : public store
|
||||
|
||||
public:
|
||||
|
||||
IMAPStore(ref <session> sess, ref <security::authenticator> auth);
|
||||
IMAPStore(ref <session> sess, ref <security::authenticator> auth, const bool secured = false);
|
||||
~IMAPStore();
|
||||
|
||||
const string getProtocolName() const;
|
||||
@ -78,7 +78,9 @@ public:
|
||||
|
||||
const int getCapabilities() const;
|
||||
|
||||
private:
|
||||
const bool isSecuredConnection() const;
|
||||
|
||||
protected:
|
||||
|
||||
// Connection
|
||||
ref <IMAPConnection> m_connection;
|
||||
@ -93,39 +95,10 @@ private:
|
||||
|
||||
std::list <IMAPFolder*> m_folders;
|
||||
|
||||
bool m_secured; // Use IMAPS
|
||||
|
||||
|
||||
// Service infos
|
||||
class _infos : public serviceInfos
|
||||
{
|
||||
public:
|
||||
|
||||
struct props
|
||||
{
|
||||
// IMAP-specific options
|
||||
#if VMIME_HAVE_SASL_SUPPORT
|
||||
serviceInfos::property PROPERTY_OPTIONS_SASL;
|
||||
serviceInfos::property PROPERTY_OPTIONS_SASL_FALLBACK;
|
||||
#endif // VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
// Common properties
|
||||
serviceInfos::property PROPERTY_AUTH_USERNAME;
|
||||
serviceInfos::property PROPERTY_AUTH_PASSWORD;
|
||||
|
||||
serviceInfos::property PROPERTY_SERVER_ADDRESS;
|
||||
serviceInfos::property PROPERTY_SERVER_PORT;
|
||||
serviceInfos::property PROPERTY_SERVER_SOCKETFACTORY;
|
||||
|
||||
serviceInfos::property PROPERTY_TIMEOUT_FACTORY;
|
||||
};
|
||||
|
||||
const props& getProperties() const;
|
||||
|
||||
const string getPropertyPrefix() const;
|
||||
const std::vector <serviceInfos::property> getAvailableProperties() const;
|
||||
};
|
||||
|
||||
static _infos sm_infos;
|
||||
static IMAPServiceInfos sm_infos;
|
||||
};
|
||||
|
||||
|
||||
|
64
vmime/net/maildir/maildirServiceInfos.hpp
Normal file
64
vmime/net/maildir/maildirServiceInfos.hpp
Normal file
@ -0,0 +1,64 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
// Linking this library statically or dynamically with other modules is making
|
||||
// a combined work based on this library. Thus, the terms and conditions of
|
||||
// the GNU General Public License cover the whole combination.
|
||||
//
|
||||
|
||||
#ifndef VMIME_NET_MAILDIR_MAILDIRSERVICEINFOS_HPP_INCLUDED
|
||||
#define VMIME_NET_MAILDIR_MAILDIRSERVICEINFOS_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/config.hpp"
|
||||
#include "vmime/net/serviceInfos.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace maildir {
|
||||
|
||||
|
||||
/** Information about maildir service.
|
||||
*/
|
||||
|
||||
class maildirServiceInfos : public serviceInfos
|
||||
{
|
||||
public:
|
||||
|
||||
maildirServiceInfos();
|
||||
|
||||
struct props
|
||||
{
|
||||
serviceInfos::property PROPERTY_SERVER_ROOTPATH;
|
||||
};
|
||||
|
||||
const props& getProperties() const;
|
||||
|
||||
const string getPropertyPrefix() const;
|
||||
const std::vector <serviceInfos::property> getAvailableProperties() const;
|
||||
};
|
||||
|
||||
|
||||
} // maildir
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_MAILDIR_MAILDIRSERVICEINFOS_HPP_INCLUDED
|
||||
|
@ -31,6 +31,8 @@
|
||||
#include "vmime/net/socket.hpp"
|
||||
#include "vmime/net/folder.hpp"
|
||||
|
||||
#include "vmime/net/maildir/maildirServiceInfos.hpp"
|
||||
|
||||
#include "vmime/utility/file.hpp"
|
||||
|
||||
#include <ostream>
|
||||
@ -91,22 +93,7 @@ private:
|
||||
|
||||
|
||||
// Service infos
|
||||
class _infos : public serviceInfos
|
||||
{
|
||||
public:
|
||||
|
||||
struct props
|
||||
{
|
||||
serviceInfos::property PROPERTY_SERVER_ROOTPATH;
|
||||
};
|
||||
|
||||
const props& getProperties() const;
|
||||
|
||||
const string getPropertyPrefix() const;
|
||||
const std::vector <serviceInfos::property> getAvailableProperties() const;
|
||||
};
|
||||
|
||||
static _infos sm_infos;
|
||||
static maildirServiceInfos sm_infos;
|
||||
};
|
||||
|
||||
|
||||
|
63
vmime/net/pop3/POP3SStore.hpp
Normal file
63
vmime/net/pop3/POP3SStore.hpp
Normal file
@ -0,0 +1,63 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
// Linking this library statically or dynamically with other modules is making
|
||||
// a combined work based on this library. Thus, the terms and conditions of
|
||||
// the GNU General Public License cover the whole combination.
|
||||
//
|
||||
|
||||
#ifndef VMIME_NET_POP3_POP3SSTORE_HPP_INCLUDED
|
||||
#define VMIME_NET_POP3_POP3SSTORE_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/net/pop3/POP3Store.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace pop3 {
|
||||
|
||||
|
||||
/** POP3S store service.
|
||||
*/
|
||||
|
||||
class POP3SStore : public POP3Store
|
||||
{
|
||||
public:
|
||||
|
||||
POP3SStore(ref <session> sess, ref <security::authenticator> auth);
|
||||
~POP3SStore();
|
||||
|
||||
const string getProtocolName() const;
|
||||
|
||||
static const serviceInfos& getInfosInstance();
|
||||
const serviceInfos& getInfos() const;
|
||||
|
||||
private:
|
||||
|
||||
static POP3ServiceInfos sm_infos;
|
||||
};
|
||||
|
||||
|
||||
} // pop3
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_POP3_POP3SSTORE_HPP_INCLUDED
|
||||
|
89
vmime/net/pop3/POP3ServiceInfos.hpp
Normal file
89
vmime/net/pop3/POP3ServiceInfos.hpp
Normal file
@ -0,0 +1,89 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
// Linking this library statically or dynamically with other modules is making
|
||||
// a combined work based on this library. Thus, the terms and conditions of
|
||||
// the GNU General Public License cover the whole combination.
|
||||
//
|
||||
|
||||
#ifndef VMIME_NET_POP3_POP3SERVICEINFOS_HPP_INCLUDED
|
||||
#define VMIME_NET_POP3_POP3SERVICEINFOS_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/config.hpp"
|
||||
#include "vmime/net/serviceInfos.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace pop3 {
|
||||
|
||||
|
||||
/** Information about POP3 service.
|
||||
*/
|
||||
|
||||
class POP3ServiceInfos : public serviceInfos
|
||||
{
|
||||
public:
|
||||
|
||||
POP3ServiceInfos(const bool pop3s);
|
||||
|
||||
struct props
|
||||
{
|
||||
// POP3-specific options
|
||||
serviceInfos::property PROPERTY_OPTIONS_APOP;
|
||||
serviceInfos::property PROPERTY_OPTIONS_APOP_FALLBACK;
|
||||
#if VMIME_HAVE_SASL_SUPPORT
|
||||
serviceInfos::property PROPERTY_OPTIONS_SASL;
|
||||
serviceInfos::property PROPERTY_OPTIONS_SASL_FALLBACK;
|
||||
#endif // VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
// Common properties
|
||||
serviceInfos::property PROPERTY_AUTH_USERNAME;
|
||||
serviceInfos::property PROPERTY_AUTH_PASSWORD;
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
serviceInfos::property PROPERTY_CONNECTION_TLS;
|
||||
serviceInfos::property PROPERTY_CONNECTION_TLS_REQUIRED;
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
serviceInfos::property PROPERTY_SERVER_ADDRESS;
|
||||
serviceInfos::property PROPERTY_SERVER_PORT;
|
||||
serviceInfos::property PROPERTY_SERVER_SOCKETFACTORY;
|
||||
|
||||
serviceInfos::property PROPERTY_TIMEOUT_FACTORY;
|
||||
};
|
||||
|
||||
const props& getProperties() const;
|
||||
|
||||
const string getPropertyPrefix() const;
|
||||
const std::vector <serviceInfos::property> getAvailableProperties() const;
|
||||
|
||||
private:
|
||||
|
||||
const bool m_pop3s;
|
||||
};
|
||||
|
||||
|
||||
} // pop3
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_POP3_POP3SERVICEINFOS_HPP_INCLUDED
|
||||
|
@ -31,6 +31,8 @@
|
||||
#include "vmime/net/socket.hpp"
|
||||
#include "vmime/net/timeoutHandler.hpp"
|
||||
|
||||
#include "vmime/net/pop3/POP3ServiceInfos.hpp"
|
||||
|
||||
#include "vmime/utility/stream.hpp"
|
||||
|
||||
|
||||
@ -52,7 +54,7 @@ class POP3Store : public store
|
||||
|
||||
public:
|
||||
|
||||
POP3Store(ref <session> sess, ref <security::authenticator> auth);
|
||||
POP3Store(ref <session> sess, ref <security::authenticator> auth, const bool secured = false);
|
||||
~POP3Store();
|
||||
|
||||
const string getProtocolName() const;
|
||||
@ -88,6 +90,10 @@ private:
|
||||
void authenticateSASL();
|
||||
#endif // VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
void startTLS();
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
const std::vector <string> getCapabilities();
|
||||
|
||||
static const bool isSuccessResponse(const string& buffer);
|
||||
@ -116,40 +122,11 @@ private:
|
||||
|
||||
ref <timeoutHandler> m_timeoutHandler;
|
||||
|
||||
bool m_secured;
|
||||
|
||||
|
||||
// Service infos
|
||||
class _infos : public serviceInfos
|
||||
{
|
||||
public:
|
||||
|
||||
struct props
|
||||
{
|
||||
// POP3-specific options
|
||||
serviceInfos::property PROPERTY_OPTIONS_APOP;
|
||||
serviceInfos::property PROPERTY_OPTIONS_APOP_FALLBACK;
|
||||
#if VMIME_HAVE_SASL_SUPPORT
|
||||
serviceInfos::property PROPERTY_OPTIONS_SASL;
|
||||
serviceInfos::property PROPERTY_OPTIONS_SASL_FALLBACK;
|
||||
#endif // VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
// Common properties
|
||||
serviceInfos::property PROPERTY_AUTH_USERNAME;
|
||||
serviceInfos::property PROPERTY_AUTH_PASSWORD;
|
||||
|
||||
serviceInfos::property PROPERTY_SERVER_ADDRESS;
|
||||
serviceInfos::property PROPERTY_SERVER_PORT;
|
||||
serviceInfos::property PROPERTY_SERVER_SOCKETFACTORY;
|
||||
|
||||
serviceInfos::property PROPERTY_TIMEOUT_FACTORY;
|
||||
};
|
||||
|
||||
const props& getProperties() const;
|
||||
|
||||
const string getPropertyPrefix() const;
|
||||
const std::vector <serviceInfos::property> getAvailableProperties() const;
|
||||
};
|
||||
|
||||
static _infos sm_infos;
|
||||
static POP3ServiceInfos sm_infos;
|
||||
};
|
||||
|
||||
|
||||
|
64
vmime/net/sendmail/sendmailServiceInfos.hpp
Normal file
64
vmime/net/sendmail/sendmailServiceInfos.hpp
Normal file
@ -0,0 +1,64 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
// Linking this library statically or dynamically with other modules is making
|
||||
// a combined work based on this library. Thus, the terms and conditions of
|
||||
// the GNU General Public License cover the whole combination.
|
||||
//
|
||||
|
||||
#ifndef VMIME_NET_SENDMAIL_SENDMAILSERVICEINFOS_HPP_INCLUDED
|
||||
#define VMIME_NET_SENDMAIL_SENDMAILSERVICEINFOS_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/config.hpp"
|
||||
#include "vmime/net/serviceInfos.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace sendmail {
|
||||
|
||||
|
||||
/** Information about sendmail service.
|
||||
*/
|
||||
|
||||
class sendmailServiceInfos : public serviceInfos
|
||||
{
|
||||
public:
|
||||
|
||||
sendmailServiceInfos();
|
||||
|
||||
struct props
|
||||
{
|
||||
serviceInfos::property PROPERTY_BINPATH;
|
||||
};
|
||||
|
||||
const props& getProperties() const;
|
||||
|
||||
const string getPropertyPrefix() const;
|
||||
const std::vector <serviceInfos::property> getAvailableProperties() const;
|
||||
};
|
||||
|
||||
|
||||
} // sendmail
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_SENDMAIL_SENDMAILSERVICEINFOS_HPP_INCLUDED
|
||||
|
@ -31,6 +31,8 @@
|
||||
#include "vmime/net/socket.hpp"
|
||||
#include "vmime/net/timeoutHandler.hpp"
|
||||
|
||||
#include "vmime/net/sendmail/sendmailServiceInfos.hpp"
|
||||
|
||||
|
||||
#if VMIME_BUILTIN_PLATFORM_POSIX
|
||||
|
||||
@ -77,22 +79,7 @@ private:
|
||||
|
||||
|
||||
// Service infos
|
||||
class _infos : public serviceInfos
|
||||
{
|
||||
public:
|
||||
|
||||
struct props
|
||||
{
|
||||
serviceInfos::property PROPERTY_BINPATH;
|
||||
};
|
||||
|
||||
const props& getProperties() const;
|
||||
|
||||
const string getPropertyPrefix() const;
|
||||
const std::vector <serviceInfos::property> getAvailableProperties() const;
|
||||
};
|
||||
|
||||
static _infos sm_infos;
|
||||
static sendmailServiceInfos sm_infos;
|
||||
};
|
||||
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#define VMIME_NET_SERVICE_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/config.hpp"
|
||||
#include "vmime/types.hpp"
|
||||
|
||||
#include "vmime/net/session.hpp"
|
||||
@ -32,6 +33,10 @@
|
||||
#include "vmime/net/serviceFactory.hpp"
|
||||
#include "vmime/net/serviceInfos.hpp"
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
#include "vmime/net/tls/certificateVerifier.hpp"
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
#include "vmime/utility/progressionListener.hpp"
|
||||
|
||||
|
||||
@ -52,7 +57,7 @@ public:
|
||||
|
||||
virtual ~service();
|
||||
|
||||
// Possible service types
|
||||
/** Possible service types. */
|
||||
enum Type
|
||||
{
|
||||
TYPE_STORE = 0, /**< The service is a message store. */
|
||||
@ -127,6 +132,20 @@ public:
|
||||
*/
|
||||
void setAuthenticator(ref <security::authenticator> auth);
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
/** Set the object responsible for verifying certificates when
|
||||
* using secured connections (TLS/SSL).
|
||||
*/
|
||||
void setCertificateVerifier(ref <tls::certificateVerifier> cv);
|
||||
|
||||
/** Get the object responsible for verifying certificates when
|
||||
* using secured connections (TLS/SSL).
|
||||
*/
|
||||
ref <tls::certificateVerifier> getCertificateVerifier();
|
||||
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
/** Set a property for this service (service prefix is added automatically).
|
||||
*
|
||||
* WARNING: this sets the property on the session object, so all service
|
||||
@ -148,10 +167,10 @@ public:
|
||||
{
|
||||
public:
|
||||
|
||||
initializer(const string& protocol)
|
||||
initializer(const string& protocol, const Type type)
|
||||
{
|
||||
serviceFactory::getInstance()->
|
||||
template registerServiceByProtocol <S>(protocol);
|
||||
template registerServiceByProtocol <S>(protocol, type);
|
||||
}
|
||||
};
|
||||
#endif // VMIME_BUILDING_DOC
|
||||
@ -160,6 +179,11 @@ private:
|
||||
|
||||
ref <session> m_session;
|
||||
ref <security::authenticator> m_auth;
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
ref <tls::certificateVerifier> m_certVerifier;
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -45,8 +45,8 @@ namespace vmime {
|
||||
namespace net {
|
||||
|
||||
|
||||
class service;
|
||||
class session;
|
||||
class service;
|
||||
|
||||
|
||||
/** A factory to create 'service' objects for a specified protocol.
|
||||
@ -78,6 +78,7 @@ public:
|
||||
(ref <session> sess,
|
||||
ref <security::authenticator> auth) const = 0;
|
||||
|
||||
virtual const int getType() const = 0;
|
||||
virtual const string& getName() const = 0;
|
||||
virtual const serviceInfos& getInfos() const = 0;
|
||||
};
|
||||
@ -92,8 +93,8 @@ private:
|
||||
|
||||
protected:
|
||||
|
||||
registeredServiceImpl(const string& name)
|
||||
: m_name(name), m_servInfos(S::getInfosInstance())
|
||||
registeredServiceImpl(const string& name, const int type)
|
||||
: m_type(type), m_name(name), m_servInfos(S::getInfosInstance())
|
||||
{
|
||||
}
|
||||
|
||||
@ -116,8 +117,14 @@ private:
|
||||
return (m_name);
|
||||
}
|
||||
|
||||
const int getType() const
|
||||
{
|
||||
return (m_type);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
const int m_type;
|
||||
const string m_name;
|
||||
const serviceInfos& m_servInfos;
|
||||
};
|
||||
@ -129,12 +136,13 @@ public:
|
||||
/** Register a new service by its protocol name.
|
||||
*
|
||||
* @param protocol protocol name
|
||||
* @param type service type
|
||||
*/
|
||||
template <class S>
|
||||
void registerServiceByProtocol(const string& protocol)
|
||||
void registerServiceByProtocol(const string& protocol, const int type)
|
||||
{
|
||||
const string name = utility::stringUtils::toLower(protocol);
|
||||
m_services.push_back(vmime::create <registeredServiceImpl <S> >(name));
|
||||
m_services.push_back(vmime::create <registeredServiceImpl <S> >(name, type));
|
||||
}
|
||||
|
||||
/** Create a new service instance from a protocol name.
|
||||
|
@ -95,6 +95,23 @@ public:
|
||||
* no time-out handler is used. */
|
||||
static const property TIMEOUT_FACTORY;
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
/** The common property 'connection.tls': this is used to
|
||||
* start a secured connection if it is supported by the
|
||||
* server (STARTTLS extension).
|
||||
*/
|
||||
static const property CONNECTION_TLS;
|
||||
|
||||
/** The common property 'connection.tls.required' should be
|
||||
* set to 'true' to make the connection process fail if the
|
||||
* server can't start a secured connection (no effect if
|
||||
* 'connection.tls' is not set to 'true').
|
||||
*/
|
||||
static const property CONNECTION_TLS_REQUIRED;
|
||||
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
|
||||
/** Value types.
|
||||
*/
|
||||
|
63
vmime/net/smtp/SMTPSTransport.hpp
Normal file
63
vmime/net/smtp/SMTPSTransport.hpp
Normal file
@ -0,0 +1,63 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
// Linking this library statically or dynamically with other modules is making
|
||||
// a combined work based on this library. Thus, the terms and conditions of
|
||||
// the GNU General Public License cover the whole combination.
|
||||
//
|
||||
|
||||
#ifndef VMIME_NET_SMTP_SMTPSSTORE_HPP_INCLUDED
|
||||
#define VMIME_NET_SMTP_SMTPSSTORE_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/net/smtp/SMTPTransport.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace smtp {
|
||||
|
||||
|
||||
/** SMTPS transport service.
|
||||
*/
|
||||
|
||||
class SMTPSTransport : public SMTPTransport
|
||||
{
|
||||
public:
|
||||
|
||||
SMTPSTransport(ref <session> sess, ref <security::authenticator> auth);
|
||||
~SMTPSTransport();
|
||||
|
||||
const string getProtocolName() const;
|
||||
|
||||
static const serviceInfos& getInfosInstance();
|
||||
const serviceInfos& getInfos() const;
|
||||
|
||||
private:
|
||||
|
||||
static SMTPServiceInfos sm_infos;
|
||||
};
|
||||
|
||||
|
||||
} // smtp
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_SMTP_SMTPSSTORE_HPP_INCLUDED
|
||||
|
88
vmime/net/smtp/SMTPServiceInfos.hpp
Normal file
88
vmime/net/smtp/SMTPServiceInfos.hpp
Normal file
@ -0,0 +1,88 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
// Linking this library statically or dynamically with other modules is making
|
||||
// a combined work based on this library. Thus, the terms and conditions of
|
||||
// the GNU General Public License cover the whole combination.
|
||||
//
|
||||
|
||||
#ifndef VMIME_NET_SMTP_SMTPSERVICEINFOS_HPP_INCLUDED
|
||||
#define VMIME_NET_SMTP_SMTPSERVICEINFOS_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/config.hpp"
|
||||
#include "vmime/net/serviceInfos.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace smtp {
|
||||
|
||||
|
||||
/** Information about SMTP service.
|
||||
*/
|
||||
|
||||
class SMTPServiceInfos : public serviceInfos
|
||||
{
|
||||
public:
|
||||
|
||||
SMTPServiceInfos(const bool smtps);
|
||||
|
||||
struct props
|
||||
{
|
||||
// SMTP-specific options
|
||||
serviceInfos::property PROPERTY_OPTIONS_NEEDAUTH;
|
||||
#if VMIME_HAVE_SASL_SUPPORT
|
||||
serviceInfos::property PROPERTY_OPTIONS_SASL;
|
||||
serviceInfos::property PROPERTY_OPTIONS_SASL_FALLBACK;
|
||||
#endif // VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
// Common properties
|
||||
serviceInfos::property PROPERTY_AUTH_USERNAME;
|
||||
serviceInfos::property PROPERTY_AUTH_PASSWORD;
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
serviceInfos::property PROPERTY_CONNECTION_TLS;
|
||||
serviceInfos::property PROPERTY_CONNECTION_TLS_REQUIRED;
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
serviceInfos::property PROPERTY_SERVER_ADDRESS;
|
||||
serviceInfos::property PROPERTY_SERVER_PORT;
|
||||
serviceInfos::property PROPERTY_SERVER_SOCKETFACTORY;
|
||||
|
||||
serviceInfos::property PROPERTY_TIMEOUT_FACTORY;
|
||||
};
|
||||
|
||||
const props& getProperties() const;
|
||||
|
||||
const string getPropertyPrefix() const;
|
||||
const std::vector <serviceInfos::property> getAvailableProperties() const;
|
||||
|
||||
private:
|
||||
|
||||
const bool m_smtps;
|
||||
};
|
||||
|
||||
|
||||
} // smtp
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_SMTP_SMTPSERVICEINFOS_HPP_INCLUDED
|
||||
|
@ -31,6 +31,8 @@
|
||||
#include "vmime/net/socket.hpp"
|
||||
#include "vmime/net/timeoutHandler.hpp"
|
||||
|
||||
#include "vmime/net/smtp/SMTPServiceInfos.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
@ -44,7 +46,7 @@ class SMTPTransport : public transport
|
||||
{
|
||||
public:
|
||||
|
||||
SMTPTransport(ref <session> sess, ref <security::authenticator> auth);
|
||||
SMTPTransport(ref <session> sess, ref <security::authenticator> auth, const bool secured = false);
|
||||
~SMTPTransport();
|
||||
|
||||
const string getProtocolName() const;
|
||||
@ -77,6 +79,9 @@ private:
|
||||
void authenticateSASL();
|
||||
#endif // VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
void startTLS();
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
ref <socket> m_socket;
|
||||
bool m_authentified;
|
||||
@ -89,39 +94,11 @@ private:
|
||||
|
||||
ref <timeoutHandler> m_timeoutHandler;
|
||||
|
||||
bool m_secured;
|
||||
|
||||
|
||||
// Service infos
|
||||
class _infos : public serviceInfos
|
||||
{
|
||||
public:
|
||||
|
||||
struct props
|
||||
{
|
||||
// SMTP-specific options
|
||||
serviceInfos::property PROPERTY_OPTIONS_NEEDAUTH;
|
||||
#if VMIME_HAVE_SASL_SUPPORT
|
||||
serviceInfos::property PROPERTY_OPTIONS_SASL;
|
||||
serviceInfos::property PROPERTY_OPTIONS_SASL_FALLBACK;
|
||||
#endif // VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
// Common properties
|
||||
serviceInfos::property PROPERTY_AUTH_USERNAME;
|
||||
serviceInfos::property PROPERTY_AUTH_PASSWORD;
|
||||
|
||||
serviceInfos::property PROPERTY_SERVER_ADDRESS;
|
||||
serviceInfos::property PROPERTY_SERVER_PORT;
|
||||
serviceInfos::property PROPERTY_SERVER_SOCKETFACTORY;
|
||||
|
||||
serviceInfos::property PROPERTY_TIMEOUT_FACTORY;
|
||||
};
|
||||
|
||||
const props& getProperties() const;
|
||||
|
||||
const string getPropertyPrefix() const;
|
||||
const std::vector <serviceInfos::property> getAvailableProperties() const;
|
||||
};
|
||||
|
||||
static _infos sm_infos;
|
||||
static SMTPServiceInfos sm_infos;
|
||||
};
|
||||
|
||||
|
||||
|
95
vmime/net/tls/TLSSession.hpp
Normal file
95
vmime/net/tls/TLSSession.hpp
Normal file
@ -0,0 +1,95 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
// Linking this library statically or dynamically with other modules is making
|
||||
// a combined work based on this library. Thus, the terms and conditions of
|
||||
// the GNU General Public License cover the whole combination.
|
||||
//
|
||||
|
||||
#ifndef VMIME_NET_TLS_TLSSESSION_HPP_INCLUDED
|
||||
#define VMIME_NET_TLS_TLSSESSION_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/types.hpp"
|
||||
|
||||
#include "vmime/net/tls/TLSSocket.hpp"
|
||||
|
||||
#include "vmime/net/tls/certificateVerifier.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace tls {
|
||||
|
||||
|
||||
/** Describe a TLS connection between a client and a server.
|
||||
*/
|
||||
class TLSSession : public object
|
||||
{
|
||||
friend class TLSSocket;
|
||||
|
||||
public:
|
||||
|
||||
~TLSSession();
|
||||
|
||||
/** Create and initialize a new TLS session.
|
||||
*
|
||||
* @param cv object responsible for verifying certificates
|
||||
* sent by the server
|
||||
* @return a new TLS session
|
||||
*/
|
||||
TLSSession(ref <certificateVerifier> cv);
|
||||
|
||||
/** Create a new socket that adds a TLS security layer around
|
||||
* an existing socket. You should create only one socket
|
||||
* per session.
|
||||
*
|
||||
* @param sok socket to wrap
|
||||
* @return TLS socket wrapper
|
||||
*/
|
||||
ref <TLSSocket> getSocket(ref <socket> sok);
|
||||
|
||||
/** Get the object responsible for verifying certificates when
|
||||
* using secured connections (TLS/SSL).
|
||||
*/
|
||||
ref <tls::certificateVerifier> getCertificateVerifier();
|
||||
|
||||
private:
|
||||
|
||||
TLSSession(const TLSSession&);
|
||||
|
||||
static void throwTLSException(const string& fname, const int code);
|
||||
|
||||
|
||||
#ifdef LIBGNUTLS_VERSION
|
||||
gnutls_session* m_gnutlsSession;
|
||||
#else
|
||||
void* m_gnutlsSession;
|
||||
#endif // LIBGNUTLS_VERSION
|
||||
|
||||
ref <certificateVerifier> m_certVerifier;
|
||||
};
|
||||
|
||||
|
||||
} // tls
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_TLS_TLSSESSION_HPP_INCLUDED
|
||||
|
125
vmime/net/tls/TLSSocket.hpp
Normal file
125
vmime/net/tls/TLSSocket.hpp
Normal file
@ -0,0 +1,125 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
// Linking this library statically or dynamically with other modules is making
|
||||
// a combined work based on this library. Thus, the terms and conditions of
|
||||
// the GNU General Public License cover the whole combination.
|
||||
//
|
||||
|
||||
#ifndef VMIME_NET_TLS_TLSSOCKET_HPP_INCLUDED
|
||||
#define VMIME_NET_TLS_TLSSOCKET_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/exception.hpp"
|
||||
|
||||
#include "vmime/net/socket.hpp"
|
||||
#include "vmime/net/timeoutHandler.hpp"
|
||||
|
||||
#include "vmime/net/tls/certificateChain.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace tls {
|
||||
|
||||
|
||||
class TLSSession;
|
||||
|
||||
|
||||
/** Add a TLS security layer to an existing socket.
|
||||
*/
|
||||
class TLSSocket : public socket
|
||||
{
|
||||
friend class vmime::creator;
|
||||
|
||||
protected:
|
||||
|
||||
/** Create a new socket object that adds a security layer
|
||||
* around an existing socket.
|
||||
*
|
||||
* @param session TLS session
|
||||
* @param sok socket to wrap
|
||||
*/
|
||||
TLSSocket(ref <TLSSession> session, ref <socket> sok);
|
||||
|
||||
public:
|
||||
|
||||
~TLSSocket();
|
||||
|
||||
|
||||
/** Starts a TLS handshake on this connection.
|
||||
*
|
||||
* @throw exceptions::tls_exception if a fatal error occurs
|
||||
* during the negociation process, exceptions::operation_timed_out
|
||||
* if a time-out occurs
|
||||
*/
|
||||
void handshake(ref <timeoutHandler> toHandler = NULL);
|
||||
|
||||
/** Return the peer's certificate (chain) as sent by the peer.
|
||||
*
|
||||
* @return server certificate chain, or NULL if the handshake
|
||||
* has not been performed yet
|
||||
*/
|
||||
ref <certificateChain> getPeerCertificates();
|
||||
|
||||
|
||||
// Implementation of 'socket'
|
||||
void connect(const string& address, const port_t port);
|
||||
void disconnect();
|
||||
const bool isConnected() const;
|
||||
|
||||
void receive(string& buffer);
|
||||
const int receiveRaw(char* buffer, const int count);
|
||||
|
||||
void send(const string& buffer);
|
||||
void sendRaw(const char* buffer, const int count);
|
||||
|
||||
private:
|
||||
|
||||
void internalThrow();
|
||||
|
||||
#ifdef LIBGNUTLS_VERSION
|
||||
static ssize_t gnutlsPushFunc(gnutls_transport_ptr trspt, const void* data, size_t len);
|
||||
static ssize_t gnutlsPullFunc(gnutls_transport_ptr trspt, void* data, size_t len);
|
||||
#else
|
||||
static ssize_t gnutlsPushFunc(void* trspt, const void* data, size_t len);
|
||||
static ssize_t gnutlsPullFunc(void* trspt, void* data, size_t len);
|
||||
#endif // LIBGNUTLS_VERSION
|
||||
|
||||
|
||||
ref <TLSSession> m_session;
|
||||
ref <socket> m_wrapped;
|
||||
|
||||
bool m_connected;
|
||||
|
||||
char m_buffer[65536];
|
||||
|
||||
bool m_handshaking;
|
||||
ref <timeoutHandler> m_toHandler;
|
||||
|
||||
exception* m_ex;
|
||||
};
|
||||
|
||||
|
||||
} // tls
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_TLS_TLSSOCKET_HPP_INCLUDED
|
||||
|
158
vmime/net/tls/X509Certificate.hpp
Normal file
158
vmime/net/tls/X509Certificate.hpp
Normal file
@ -0,0 +1,158 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
// Linking this library statically or dynamically with other modules is making
|
||||
// a combined work based on this library. Thus, the terms and conditions of
|
||||
// the GNU General Public License cover the whole combination.
|
||||
//
|
||||
|
||||
#ifndef VMIME_NET_TLS_X509CERTIFICATE_HPP_INCLUDED
|
||||
#define VMIME_NET_TLS_X509CERTIFICATE_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/net/tls/certificate.hpp"
|
||||
|
||||
#include "vmime/utility/stream.hpp"
|
||||
|
||||
#include "vmime/base.hpp"
|
||||
#include "vmime/dateTime.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace tls {
|
||||
|
||||
|
||||
/** Identity certificate based on X.509 standard.
|
||||
*/
|
||||
class X509Certificate : public certificate
|
||||
{
|
||||
friend class vmime::creator;
|
||||
|
||||
protected:
|
||||
|
||||
X509Certificate();
|
||||
X509Certificate(const X509Certificate&);
|
||||
|
||||
public:
|
||||
|
||||
~X509Certificate();
|
||||
|
||||
/** Supported encodings for X.509 certificates. */
|
||||
enum Format
|
||||
{
|
||||
FORMAT_DER, /**< DER encoding */
|
||||
FORMAT_PEM /**< PEM encoding */
|
||||
};
|
||||
|
||||
/** Supported digest algorithms (used for fingerprint). */
|
||||
enum DigestAlgorithm
|
||||
{
|
||||
DIGEST_MD5, /**< MD5 digest */
|
||||
DIGEST_SHA1 /**< SHA1 digest */
|
||||
};
|
||||
|
||||
|
||||
/** Imports a DER or PEM encoded X.509 certificate.
|
||||
*
|
||||
* @param is input stream to read data from
|
||||
* @return a X.509 certificate, or NULL if the given data does not
|
||||
* represent a valid certificate
|
||||
*/
|
||||
static ref <X509Certificate> import(utility::inputStream& is);
|
||||
|
||||
/** Imports a DER or PEM encoded X.509 certificate.
|
||||
*
|
||||
* @param data points to raw data
|
||||
* @param length size of data
|
||||
* @return a X.509 certificate, or NULL if the given data does not
|
||||
* represent a valid certificate
|
||||
*/
|
||||
static ref <X509Certificate> import(const byte* data, const unsigned int length);
|
||||
|
||||
/** Exports this X.509 certificate to the specified format.
|
||||
*
|
||||
* @param os output stream into which write data
|
||||
* @param format output format
|
||||
*/
|
||||
void write(utility::outputStream& os, const Format format) const;
|
||||
|
||||
/** Returns the X.509 certificate's serial number. This is obtained
|
||||
* by the X.509 Certificate 'serialNumber' field. Serial is not
|
||||
* always a 32 or 64bit number. Some CAs use large serial numbers,
|
||||
* thus it may be wise to handle it as something opaque.
|
||||
*
|
||||
* @return serial number of this certificate
|
||||
*/
|
||||
const byteArray getSerialNumber() const;
|
||||
|
||||
/** Checks if this certificate has the given issuer.
|
||||
*
|
||||
* @param issuer certificate of a possible issuer
|
||||
* @return true if this certificate was issued by the given issuer,
|
||||
* false otherwise
|
||||
*/
|
||||
const bool checkIssuer(ref <const X509Certificate> issuer) const;
|
||||
|
||||
/** Verifies this certificate against a given trusted one.
|
||||
*
|
||||
* @param caCert a certificate that is considered to be trusted one
|
||||
* @return true if the verification succeeded, false otherwise
|
||||
*/
|
||||
const bool verify(ref <const X509Certificate> caCert) const;
|
||||
|
||||
/** Gets the expiration date of this certificate. This is the date
|
||||
* at which this certificate will not be valid anymore.
|
||||
*
|
||||
* @return expiration date of this certificate
|
||||
*/
|
||||
const datetime getExpirationDate() const;
|
||||
|
||||
/** Gets the activation date of this certificate. This is the date
|
||||
* at which this certificate will be valid.
|
||||
*
|
||||
* @return activation date of this certificate
|
||||
*/
|
||||
const datetime getActivationDate() const;
|
||||
|
||||
/** Returns the fingerprint of this certificate.
|
||||
*
|
||||
* @return the fingerprint of this certificate
|
||||
*/
|
||||
const byteArray getFingerprint(const DigestAlgorithm algo) const;
|
||||
|
||||
|
||||
// Implementation of 'certificate'
|
||||
const byteArray getEncoded() const;
|
||||
const string getType() const;
|
||||
const int getVersion() const;
|
||||
const bool equals(ref <const certificate> other) const;
|
||||
|
||||
private:
|
||||
|
||||
class X509CertificateInternalData* m_data;
|
||||
};
|
||||
|
||||
|
||||
} // tls
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_TLS_X509CERTIFICATE_HPP_INCLUDED
|
||||
|
77
vmime/net/tls/certificate.hpp
Normal file
77
vmime/net/tls/certificate.hpp
Normal file
@ -0,0 +1,77 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
// Linking this library statically or dynamically with other modules is making
|
||||
// a combined work based on this library. Thus, the terms and conditions of
|
||||
// the GNU General Public License cover the whole combination.
|
||||
//
|
||||
|
||||
#ifndef VMIME_NET_TLS_CERTIFICATE_HPP_INCLUDED
|
||||
#define VMIME_NET_TLS_CERTIFICATE_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/types.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace tls {
|
||||
|
||||
|
||||
/** Identity certificate for a peer.
|
||||
*/
|
||||
class certificate : public object
|
||||
{
|
||||
public:
|
||||
|
||||
/** Returns the encoded form of this certificate (for example,
|
||||
* X.509 certificates are encoded as ASN.1 DER).
|
||||
*
|
||||
* @return the encoded form of this certificate
|
||||
*/
|
||||
virtual const byteArray getEncoded() const = 0;
|
||||
|
||||
/** Return the type of this certificate.
|
||||
*
|
||||
* @return the type of this certificate
|
||||
*/
|
||||
virtual const string getType() const = 0;
|
||||
|
||||
/** Return the version of this certificate.
|
||||
*
|
||||
* @return the version of this certificate
|
||||
*/
|
||||
virtual const int getVersion() const = 0;
|
||||
|
||||
/** Checks if two certificates are the same.
|
||||
*
|
||||
* @param other certificate to compare with
|
||||
* @return true if the two certificates are the same,
|
||||
* false otherwise
|
||||
*/
|
||||
virtual const bool equals(ref <const certificate> other) const = 0;
|
||||
};
|
||||
|
||||
|
||||
} // tls
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_TLS_CERTIFICATE_HPP_INCLUDED
|
||||
|
79
vmime/net/tls/certificateChain.hpp
Normal file
79
vmime/net/tls/certificateChain.hpp
Normal file
@ -0,0 +1,79 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
// Linking this library statically or dynamically with other modules is making
|
||||
// a combined work based on this library. Thus, the terms and conditions of
|
||||
// the GNU General Public License cover the whole combination.
|
||||
//
|
||||
|
||||
#ifndef VMIME_NET_TLS_CERTIFICATECHAIN_HPP_INCLUDED
|
||||
#define VMIME_NET_TLS_CERTIFICATECHAIN_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/types.hpp"
|
||||
|
||||
#include "vmime/net/tls/certificate.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace tls {
|
||||
|
||||
|
||||
/** An ordered list of certificates, from the subject certificate to
|
||||
* the issuer certificate.
|
||||
*/
|
||||
class certificateChain : public object
|
||||
{
|
||||
public:
|
||||
|
||||
/** Construct a new certificateChain object given an ordered list
|
||||
* of certificates.
|
||||
*
|
||||
* @param certs chain of certificates
|
||||
*/
|
||||
certificateChain(const std::vector <ref <certificate> >& certs);
|
||||
|
||||
/** Return the number of certificates in the chain.
|
||||
*
|
||||
* @return number of certificates in the chain
|
||||
*/
|
||||
const unsigned int getCount() const;
|
||||
|
||||
/** Return the certificate at the specified position. 0 is the
|
||||
* subject certificate, 1 is the issuer's certificate, 2 is
|
||||
* the issuer's issuer, etc.
|
||||
*
|
||||
* @param index position at which to retrieve certificate
|
||||
* @return certificate at the specified position
|
||||
*/
|
||||
ref <certificate> getAt(const unsigned int index);
|
||||
|
||||
protected:
|
||||
|
||||
std::vector <ref <certificate> > m_certs;
|
||||
};
|
||||
|
||||
|
||||
} // tls
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_TLS_CERTIFICATECHAIN_HPP_INCLUDED
|
||||
|
60
vmime/net/tls/certificateVerifier.hpp
Normal file
60
vmime/net/tls/certificateVerifier.hpp
Normal file
@ -0,0 +1,60 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
// Linking this library statically or dynamically with other modules is making
|
||||
// a combined work based on this library. Thus, the terms and conditions of
|
||||
// the GNU General Public License cover the whole combination.
|
||||
//
|
||||
|
||||
#ifndef VMIME_NET_TLS_CERTIFICATEVERIFIER_HPP_INCLUDED
|
||||
#define VMIME_NET_TLS_CERTIFICATEVERIFIER_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/types.hpp"
|
||||
|
||||
#include "vmime/net/tls/certificateChain.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace tls {
|
||||
|
||||
|
||||
/** Verify that a certificate path issued by a server can be trusted.
|
||||
*/
|
||||
class certificateVerifier : public object
|
||||
{
|
||||
public:
|
||||
|
||||
/** Verify that the specified certificate chain is trusted.
|
||||
*
|
||||
* @param chain certificate chain
|
||||
* @throw exceptions::certificate_verification_exception if one
|
||||
* or more certificates can not be trusted
|
||||
*/
|
||||
virtual void verify(ref <certificateChain> chain) = 0;
|
||||
};
|
||||
|
||||
|
||||
} // tls
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_TLS_CERTIFICATEVERIFIER_HPP_INCLUDED
|
||||
|
88
vmime/net/tls/defaultCertificateVerifier.hpp
Normal file
88
vmime/net/tls/defaultCertificateVerifier.hpp
Normal file
@ -0,0 +1,88 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
// Linking this library statically or dynamically with other modules is making
|
||||
// a combined work based on this library. Thus, the terms and conditions of
|
||||
// the GNU General Public License cover the whole combination.
|
||||
//
|
||||
|
||||
#ifndef VMIME_NET_TLS_DEFAULTCERTIFICATEVERIFIER_HPP_INCLUDED
|
||||
#define VMIME_NET_TLS_DEFAULTCERTIFICATEVERIFIER_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/net/tls/certificateVerifier.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace tls {
|
||||
|
||||
|
||||
class X509Certificate;
|
||||
|
||||
|
||||
/** Default implementation for certificate verification.
|
||||
*/
|
||||
class defaultCertificateVerifier : public certificateVerifier
|
||||
{
|
||||
private:
|
||||
|
||||
defaultCertificateVerifier(const defaultCertificateVerifier&);
|
||||
|
||||
public:
|
||||
|
||||
defaultCertificateVerifier();
|
||||
~defaultCertificateVerifier();
|
||||
|
||||
/** Sets a list of X.509 certificates that are trusted.
|
||||
*
|
||||
* @param trustedCerts list of trusted certificates
|
||||
*/
|
||||
void setX509TrustedCerts(const std::vector <ref <X509Certificate> >& trustedCerts);
|
||||
|
||||
/** Sets the X.509 root CAs used for certificate verification.
|
||||
*
|
||||
* @param caCerts list of root CAs
|
||||
*/
|
||||
void setX509RootCAs(const std::vector <ref <X509Certificate> >& caCerts);
|
||||
|
||||
|
||||
// Implementation of 'certificateVerifier'
|
||||
void verify(ref <certificateChain> chain);
|
||||
|
||||
private:
|
||||
|
||||
/** Verify a chain of X.509 certificates.
|
||||
*
|
||||
* @param chain list of X.509 certificates
|
||||
*/
|
||||
void verifyX509(ref <certificateChain> chain);
|
||||
|
||||
|
||||
std::vector <ref <X509Certificate> > m_x509RootCAs;
|
||||
std::vector <ref <X509Certificate> > m_x509TrustedCerts;
|
||||
};
|
||||
|
||||
|
||||
} // tls
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_TLS_DEFAULTCERTIFICATEVERIFIER_HPP_INCLUDED
|
||||
|
@ -229,6 +229,23 @@ private:
|
||||
};
|
||||
|
||||
|
||||
/** An adapter class for byte array output.
|
||||
*/
|
||||
|
||||
class outputStreamByteArrayAdapter : public outputStream
|
||||
{
|
||||
public:
|
||||
|
||||
outputStreamByteArrayAdapter(byteArray& array);
|
||||
|
||||
void write(const value_type* const data, const size_type count);
|
||||
|
||||
private:
|
||||
|
||||
byteArray m_array;
|
||||
};
|
||||
|
||||
|
||||
/** An adapter class for C++ standard input streams.
|
||||
*/
|
||||
|
||||
|
@ -119,5 +119,18 @@
|
||||
#include "vmime/net/message.hpp"
|
||||
#endif // VMIME_HAVE_MESSAGING_FEATURES
|
||||
|
||||
// Net/TLS
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
#include "vmime/net/tls/certificate.hpp"
|
||||
#include "vmime/net/tls/certificateChain.hpp"
|
||||
#include "vmime/net/tls/certificateVerifier.hpp"
|
||||
|
||||
#include "vmime/net/tls/X509Certificate.hpp"
|
||||
|
||||
#include "vmime/net/tls/defaultCertificateVerifier.hpp"
|
||||
|
||||
#include "vmime/net/tls/TLSSession.hpp"
|
||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
|
||||
#endif // VMIME_INCLUDED
|
||||
|
Loading…
Reference in New Issue
Block a user