From 9b65b4de6c8491dd7ba0c26ed6923e67984c90ec Mon Sep 17 00:00:00 2001 From: bmagistro Date: Sun, 31 Dec 2023 10:03:30 -0500 Subject: Configurable email add domain (#287) * Allow appending of local hostname to be configured via parsing context Signed-off-by: Ben Magistro Co-authored-by: Vincent Richard --- src/vmime/emailAddress.cpp | 40 ++++++++++++++++++++++++++++------------ src/vmime/parsingContext.cpp | 12 ++++++++++++ src/vmime/parsingContext.hpp | 19 +++++++++++++++++++ src/vmime/path.cpp | 10 ++++++++++ 4 files changed, 69 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/vmime/emailAddress.cpp b/src/vmime/emailAddress.cpp index 1be678a5..00ae418f 100644 --- a/src/vmime/emailAddress.cpp +++ b/src/vmime/emailAddress.cpp @@ -176,7 +176,7 @@ emailAddress::emailAddress(const word& localName, const word& domainName) void emailAddress::parseImpl( - const parsingContext& /* ctx */, + const parsingContext& ctx, const string& buffer, const size_t position, const size_t end, @@ -541,7 +541,7 @@ void emailAddress::parseImpl( } else { // If the domain part is missing, use local host name - if (domainPart.str().empty() && !atFound) { + if (ctx.getUseMyHostname() && domainPart.str().empty() && !atFound) { domainPart << platform::getHandler()->getHostName(); } @@ -595,16 +595,28 @@ void emailAddress::generateImpl( domainPart = domainNameToIDNA(m_domainName.getConvertedText(vmime::charsets::UTF_8)); } - os << localPart - << "@" - << domainPart; - if (newLinePos) { + if (!domainPart.empty()) { + os << localPart + << "@" + << domainPart; - *newLinePos = curLinePos - + localPart.length() - + 1 // @ - + domainPart.length(); + if (newLinePos) { + *newLinePos = curLinePos + + localPart.length() + + 1 // @ + + domainPart.length(); + } + } else { + // this should only be true if m_useMyHostname is false and an address without + // an `@` is encountered + + os << localPart; + + if (newLinePos) { + *newLinePos = curLinePos + + localPart.length(); + } } } @@ -698,8 +710,12 @@ const text emailAddress::toText() const { text txt; txt.appendWord(make_shared (m_localName)); - txt.appendWord(make_shared ("@", vmime::charsets::US_ASCII)); - txt.appendWord(make_shared (m_domainName)); + if (!m_domainName.empty()) { + // this should only be skipped if m_useMyHostname is false and an address without + // an `@` is encountered + txt.appendWord(make_shared ("@", vmime::charsets::US_ASCII)); + txt.appendWord(make_shared (m_domainName)); + } return txt; } diff --git a/src/vmime/parsingContext.cpp b/src/vmime/parsingContext.cpp index 2ffdfa87..ae14715f 100644 --- a/src/vmime/parsingContext.cpp +++ b/src/vmime/parsingContext.cpp @@ -61,4 +61,16 @@ void parsingContext::setHeaderParseErrorRecoveryMethod( } +bool parsingContext::getUseMyHostname() const { + + return m_useMyHostname; +} + + +void parsingContext::setUseMyHostname(bool useMyHostname) { + + m_useMyHostname = useMyHostname; +} + + } // vmime diff --git a/src/vmime/parsingContext.hpp b/src/vmime/parsingContext.hpp index 1107fd57..f8feabfb 100644 --- a/src/vmime/parsingContext.hpp +++ b/src/vmime/parsingContext.hpp @@ -77,9 +77,28 @@ public: */ headerParseRecoveryMethod::headerLineError getHeaderParseErrorRecoveryMethod() const; + /** Return the current hostname adding behavior when parsing/creating a header field that + * utilizes a domain name. + * + * @retval true The local hostname will be appended if a domain is not present + * @retval false The local hostname will not be appended even if a domain is not present + */ + bool getUseMyHostname() const; + + /** Enables/disables appending the local hostname in header fields if a domain is not + * not provided and it is required. The default is to append. Changing this can result + * in fields that would violate various RFCs. + */ + void setUseMyHostname(bool useMyHostname); + protected: headerParseRecoveryMethod::headerLineError m_headerParseErrorRecovery; + + /** Flag to indicate if the local hostname should be used/appended + * for header fields when one is not present. + */ + bool m_useMyHostname{true}; }; diff --git a/src/vmime/path.cpp b/src/vmime/path.cpp index f57d1285..9b94875a 100644 --- a/src/vmime/path.cpp +++ b/src/vmime/path.cpp @@ -192,6 +192,16 @@ void path::generateImpl( *newLinePos = curLinePos + 2; } + } else if (!m_localPart.empty() && m_domain.empty()) { + // this should only be true if m_useMyHostname is false and an address without + // an `@` is encountered + + os << "<" << m_localPart << ">"; + + if (newLinePos) { + *newLinePos = curLinePos + m_localPart.length() + 2; + } + } else { os << "<" << m_localPart << "@" << m_domain << ">"; -- cgit v1.2.3