Skip to content

Commit

Permalink
add support for server name indication
Browse files Browse the repository at this point in the history
  • Loading branch information
d99kris committed Jun 15, 2024
1 parent 8ef456b commit ca49b7c
Show file tree
Hide file tree
Showing 10 changed files with 56 additions and 6 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ Full example of a config file `~/.nmail/main.conf`:
smtp_host=smtp.example.com
smtp_port=587
smtp_user=
sni_enabled=1
text_to_html_cmd=
trash=Trash
[email protected]
Expand Down Expand Up @@ -522,6 +523,10 @@ case the email account has different username and password for sending emails
for sending emails). If not specified, the configured `user` field will be
used.

### sni_enabled

Controls whether to enable Server Name Indication (SNI) during TLS handshaking.

### spell_cmd

This field specifies a custom command to use for spell checking composed
Expand Down
22 changes: 20 additions & 2 deletions src/imap.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// imap.cpp
//
// Copyright (c) 2019-2023 Kristofer Berggren
// Copyright (c) 2019-2024 Kristofer Berggren
// All rights reserved.
//
// nmail is distributed under the MIT license, see LICENSE for details.
Expand All @@ -27,6 +27,7 @@ Imap::Imap(const std::string& p_User, const std::string& p_Pass, const std::stri
const uint16_t p_Port, const int64_t p_Timeout,
const bool p_CacheEncrypt, const bool p_CacheIndexEncrypt,
const std::set<std::string>& p_FoldersExclude,
const bool p_SniEnabled,
const std::function<void(const StatusUpdate&)>& p_StatusHandler)
: m_User(p_User)
, m_Pass(p_Pass)
Expand All @@ -36,6 +37,7 @@ Imap::Imap(const std::string& p_User, const std::string& p_Pass, const std::stri
, m_CacheEncrypt(p_CacheEncrypt)
, m_CacheIndexEncrypt(p_CacheIndexEncrypt)
, m_FoldersExclude(p_FoldersExclude)
, m_SniEnabled(p_SniEnabled)
{
if (Log::GetTraceEnabled())
{
Expand Down Expand Up @@ -90,6 +92,15 @@ void Imap::CleanupImap()
}
}

static void SslContextCallback(struct mailstream_ssl_context* p_SslContext, void* p_Data)
{
if (p_Data != nullptr)
{
char* host = (char*)p_Data;
LOG_IF_IMAP_ERR(mailstream_ssl_set_server_name(p_SslContext, host));
}
}

bool Imap::Login()
{
LOG_DEBUG_FUNC(STR());
Expand All @@ -105,7 +116,14 @@ bool Imap::Login()
int rv = 0;
if (isSSL)
{
rv = LOG_IF_IMAP_ERR(mailimap_ssl_connect(m_Imap, m_Host.c_str(), m_Port));
char* sni = (m_SniEnabled && !Util::IsIpAddress(m_Host))
? strdup(m_Host.c_str())
: nullptr;
rv = LOG_IF_IMAP_ERR(mailimap_ssl_connect_with_callback(m_Imap, m_Host.c_str(), m_Port, SslContextCallback, sni));
if (sni != nullptr)
{
free(sni);
}
}
else if (isStartTLS)
{
Expand Down
4 changes: 3 additions & 1 deletion src/imap.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// imap.h
//
// Copyright (c) 2019-2023 Kristofer Berggren
// Copyright (c) 2019-2024 Kristofer Berggren
// All rights reserved.
//
// nmail is distributed under the MIT license, see LICENSE for details.
Expand Down Expand Up @@ -48,6 +48,7 @@ class Imap
const uint16_t p_Port, const int64_t p_Timeout,
const bool p_CacheEncrypt, const bool p_CacheIndexEncrypt,
const std::set<std::string>& p_FoldersExclude,
const bool p_SniEnabled,
const std::function<void(const StatusUpdate&)>& p_StatusHandler);
virtual ~Imap();

Expand Down Expand Up @@ -109,6 +110,7 @@ class Imap
bool m_CacheEncrypt = false;
bool m_CacheIndexEncrypt = false;
std::set<std::string> m_FoldersExclude;
bool m_SniEnabled = false;

std::mutex m_ImapMutex;
struct mailimap* m_Imap = NULL;
Expand Down
3 changes: 2 additions & 1 deletion src/imapmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ ImapManager::ImapManager(const std::string& p_User, const std::string& p_Pass,
const bool p_CacheIndexEncrypt,
const uint32_t p_IdleTimeout,
const std::set<std::string>& p_FoldersExclude,
const bool p_SniEnabled,
const std::function<void(const ImapManager::Request&,
const ImapManager::Response&)>& p_ResponseHandler,
const std::function<void(const ImapManager::Action&,
Expand All @@ -30,7 +31,7 @@ ImapManager::ImapManager(const std::string& p_User, const std::string& p_Pass,
const bool p_IdleInbox,
const std::string& p_Inbox)
: m_Imap(p_User, p_Pass, p_Host, p_Port, p_Timeout,
p_CacheEncrypt, p_CacheIndexEncrypt, p_FoldersExclude, p_StatusHandler)
p_CacheEncrypt, p_CacheIndexEncrypt, p_FoldersExclude, p_SniEnabled, p_StatusHandler)
, m_Connect(p_Connect)
, m_ResponseHandler(p_ResponseHandler)
, m_ResultHandler(p_ResultHandler)
Expand Down
1 change: 1 addition & 0 deletions src/imapmanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ class ImapManager
const bool p_CacheIndexEncrypt,
const uint32_t p_IdleTimeout,
const std::set<std::string>& p_FoldersExclude,
const bool p_SniEnabled,
const std::function<void(const ImapManager::Request&, const ImapManager::Response&)>& p_ResponseHandler,
const std::function<void(const ImapManager::Action&, const ImapManager::Result&)>& p_ResultHandler,
const std::function<void(const StatusUpdate&)>& p_StatusHandler,
Expand Down
3 changes: 3 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ int main(int argc, char* argv[])
{ "file_picker_cmd", "" },
{ "downloads_dir", "" },
{ "idle_timeout", "29" },
{ "sni_enabled", "1" },
};
const std::string mainConfigPath(Util::GetApplicationDir() + std::string("main.conf"));
std::shared_ptr<Config> mainConfig = std::make_shared<Config>(mainConfigPath, defaultMainConfig);
Expand Down Expand Up @@ -283,6 +284,7 @@ int main(int argc, char* argv[])
Util::SetFilePickerCmd(mainConfig->Get("file_picker_cmd"));
Util::SetDownloadsDir(mainConfig->Get("downloads_dir"));
const bool isCoredumpEnabled = (mainConfig->Get("coredump_enabled") == "1");
const bool sniEnabled = (mainConfig->Get("sni_enabled") == "1");

// Set logging verbosity level based on config, if not specified with command line arguments
if (Log::GetVerboseLevel() == Log::INFO_LEVEL)
Expand Down Expand Up @@ -394,6 +396,7 @@ int main(int argc, char* argv[])
cacheEncrypt, cacheIndexEncrypt,
idleTimeout,
foldersExclude,
sniEnabled,
std::bind(&Ui::ResponseHandler, std::ref(ui), std::placeholders::_1,
std::placeholders::_2),
std::bind(&Ui::ResultHandler, std::ref(ui), std::placeholders::_1,
Expand Down
2 changes: 1 addition & 1 deletion src/nmail.1
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man.
.TH NMAIL "1" "June 2024" "nmail v4.66" "User Commands"
.TH NMAIL "1" "June 2024" "nmail v4.67" "User Commands"
.SH NAME
nmail \- ncurses mail
.SH SYNOPSIS
Expand Down
19 changes: 19 additions & 0 deletions src/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,14 @@
#include <execinfo.h>
#endif
#include <libgen.h>
#include <netdb.h>
#include <termios.h>
#include <unistd.h>
#include <wordexp.h>

#include <sys/resource.h>
#include <sys/socket.h>
#include <sys/types.h>

#ifdef __APPLE__
#include <libproc.h>
Expand Down Expand Up @@ -2271,3 +2274,19 @@ std::string Util::ExtractString(const std::string& p_Str, const std::string& p_P

return "";
}

bool Util::IsIpAddress(const std::string& p_Str)
{
struct addrinfo addrhints;
memset(&addrhints, 0, sizeof(struct addrinfo));
addrhints.ai_family = AF_UNSPEC;
addrhints.ai_flags = AI_NUMERICHOST;
struct addrinfo* addr = nullptr;
bool rv = (getaddrinfo(p_Str.c_str(), NULL, &addrhints, &addr) == 0);
if (rv && (addr != nullptr))
{
freeaddrinfo(addr);
}

return rv;
}
1 change: 1 addition & 0 deletions src/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ class Util
static std::string GetCompiler();
static std::string GetOsArch();
static std::string ExtractString(const std::string& p_Str, const std::string& p_Prefix, const std::string& p_Suffix);
static bool IsIpAddress(const std::string& p_Str);

template<typename T>
static inline void Unused(const T& p_Arg)
Expand Down
2 changes: 1 addition & 1 deletion src/version.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

#include "version.h"

#define NMAIL_VERSION "4.66"
#define NMAIL_VERSION "4.67"

std::string Version::GetBuildOs()
{
Expand Down

0 comments on commit ca49b7c

Please sign in to comment.