34 m_result(
GSmtp::VerifierStatus::invalid({})) ,
35 m_range(G::Range::range(1000,32767))
37 std::string_view spec_view( spec ) ;
41 m_range = G::Range::range( t() ) ;
42 else if( ( t().size() <= 3U && t().find(
'l') != std::string::npos ) || t() ==
"lowercase"_sv )
44 else if( ( t().size() <= 3U && t().find(
'r') != std::string::npos ) || t() ==
"remote"_sv )
45 m_config_remote = true ;
46 else if( ( t().size() <= 3U && t().find(
'c') != std::string::npos ) || t() ==
"check"_sv )
47 m_config_check = true ;
49 G_DEBUG(
"GVerifiers::UserVerifier: uid range " << G::Range::str(m_range) ) ;
54 m_command = request.command ;
56 std::string_view request_address = dequote( request.address ) ;
58 std::size_t at_pos = request_address.rfind(
'@' ) ;
59 std::string_view user = dequote(
G::Str::headView( request_address , at_pos , request_address ) ) ;
64 if( user ==
"postmaster" && domain.empty() )
66 else if( lookup(user,domain,&reason,&mailbox) )
70 GSmtp::VerifierStatus::local( request.address , {} , m_config_lc?
G::Str::lower(mailbox):mailbox ) ;
71 else if( m_config_check )
76 m_timer.startTimer( 0U ) ;
79bool GVerifiers::UserVerifier::lookup( std::string_view user , std::string_view domain ,
80 std::string * reason_p , std::string * mailbox_p )
const
83 std::ostringstream ss ;
86 ss <<
"[" << domain <<
"] does not match [" << m_config.domain <<
"]" ;
97 ss <<
"[" << user <<
"] is not a valid account name" ;
99 else if( !pair.first.match( m_range ) )
101 ss <<
"uid " << pair.first.userid() <<
" is not in the range " << G::Range::str(m_range) ;
106 *mailbox_p = pair.second ;
110 if( !result && reason_p ) *reason_p = ss.str() ;
116 return m_done_signal ;
119void GVerifiers::UserVerifier::cancel()
121 m_timer.cancelTimer() ;
124void GVerifiers::UserVerifier::onTimeout()
126 m_done_signal.emit( m_command , m_result ) ;
129std::string_view GVerifiers::UserVerifier::dequote( std::string_view s )
131 if( s.size() >= 2U && s.at(0) ==
'"' && s.at(s.size()-1U) ==
'"' )
132 return s.substr( 1U , s.size()-2U ) ;
A lightweight object containing an ExceptionHandler pointer, optional ExceptionSource pointer and opt...
static VerifierStatus local(const std::string &recipient, const std::string &full_name, const std::string &mbox)
Constructor for a valid local mailbox.
static VerifierStatus invalid(const std::string &recipient, bool temporary=false, const std::string &response={}, const std::string &reason={})
Factory function for an invalid address.
static VerifierStatus remote(const std::string &recipient, const std::string &address={})
Constructor for a valid remote mailbox.
A concrete Verifier class that verifies against the password database (ie.
UserVerifier(GNet::EventState es, const GSmtp::Verifier::Config &config, const std::string &spec)
Constructor.
static Identity invalid() noexcept
Returns an invalid identity.
static std::pair< Identity, std::string > lookup(std::string_view user)
Does a username lookup returning the identity and the canonical name.
static std::string lower(std::string_view)
Returns a copy of 's' in which all seven-bit upper-case characters have been replaced by lower-case c...
static bool imatch(char, char) noexcept
Returns true if the two characters are the same, ignoring seven-bit case.
static bool isNumeric(std::string_view s, bool allow_minus_sign=false) noexcept
Returns true if every character is a decimal digit.
static std::string_view tailView(std::string_view in, std::size_t pos, std::string_view default_={}) noexcept
Like tail() but returning a view into the input string.
static std::string_view headView(std::string_view in, std::size_t pos, std::string_view default_={}) noexcept
Like head() but returning a view into the input string.
static bool isPrintableAscii(std::string_view s) noexcept
Returns true if every character is between 0x20 and 0x7e inclusive.
A zero-copy string token iterator where the token separators are runs of whitespace characters,...
Configuration passed to address verifier constructors.
Verification request passed to various GSmtp::Verifier::verify() overrides.