======SMTP Server Lua Scripting====== The SMTP Server [[http://wiki.pscs.co.uk/reference;lua_scripting|Lua Script]] is called SMTPSVR.LUA and can be edited from the Settings -> Scripts page in the VPOP3 settings. This script is called whenever an instance of the VPOP3 SMTP server is launched - ie whenever someone opens a connection to port 25 on the VPOP3 server to send it a message, whether from a local user or an incoming SMTP message. Each SMTP server instance has its own instance of the SMTPSVR.LUA script. No threading conflicts will occur. During the lifetime of the SMTP server instance, there are several global variables which are available to the Lua script. These may change as the script is called on different callbacks, and may be changed by the Lua script itself in order to change the VPOP3 behaviour. VPOP3 will call the following Lua functions in the script at the following times: * **Start()** - called when the SMTP service session starts up, before the welcome message is sent to the SMTP client * **RBLResults()** - (VPOP3 Enterprise Only) - called after the RBL checks have been performed * **GetMaxMessageSize()** - called at startup, and when the HELO and EHLO commands are received * **GetEHLOCapabilities()** - called when the EHLO command is received * **DoHELO()** - called when the HELO or EHLO command is received * **DoHELP()** - called when the HELP command is received * **DoQUIT()** - called when the QUIT command is received * **DoNOOP()** - called when the NOOP command is received * **DoRSET()** - called when the RSET command is received * **DoVRFY()** - (v5+) called when the VRFY command is received * **DoEXPN()** - (v5+) called when the EXPN command is received * **DoMAILFROM()** - called when a valid MAIL FROM command is received * **DoRCPTTO()** - called when a valid RCPT TO command is received * **DoDATAStart()** - called when VPOP3 receives a valid DATA command * **DoUnrecognised()** - called when VPOP3 receives an unrecognised SMTP command * **ProcessMessage()** - called when an entire message has been received by VPOP3 * **StartMessage()** - (v5+) called at the start of each message * **MessageLineRaw()** - (v5+) called each time a message line is received by VPOP3 * **MessageLine()** - (v5+) called after processing each message line received by VPOP3 * **EndMessage()** - (v5+) called when the message terminator . has been received at the end of a message * **CheckRecipients()** - (v6.3+ Enterprise Only) called at the end of a message to check if recipients are allowed * **MonitorBcc()** - (v6.3+ Enterprise Only) called to customise monitoring of messages with BCCs * **LogRecipients()** - (v6.3+ Enterprise Only) called at the end of a message to allow customised logging of recipients * **LogRecipientsBlocked()** - (v6.3+ Enterprise Only) called at the end of a message if recipients have been blocked to allow customised logging of recipients * **End()** - called when the SMTP service session ends =====SMTP Server Global Variables===== The following variables are defined for the SMTP Server Lua script. They are accessible to all callback functions in the script, and can often be modified by the script to modify the VPOP3 behaviour. If the variable is marked as (IN) then it should be treated as read-only by the script. If it is marked as (IN/OUT) then the script can modify it if desired. * **IPAddress** - (IN) - string - dotted notation client IP address (eg "192.168.1.1") * **ValidClientAddress** - (IN/OUT) - boolean - TRUE if the client IP address is in an 'allowed' IP address range * **LocalClientAddress** - (IN/OUT) - boolean - TRUE if client IP address is in an 'allowed' IP address range and anti-relay protection is 'check client IP address', and no SMTP authentication is needed * **AuthenticationRequired** - (IN/OUT) - boolean - TRUE if SMTP authentication is required * **AllowedUsers** - (IN/OUT) - string - List of allowed usernames (separated by spaces) if there are any username restrictions for this client IP address ===V5 and later=== * **AuthenticatedUser** - (IN) - string - username of authenticated sender (using SMTP or POP3-then-SMTP authentication) * **SMTPAuthenticatedUser** - (IN) - string - username of authenticated sender (using SMTP authentication only) * **ForceDisconnect** - (IN/OUT) - boolean - drop the connection as soon as possible * **UseBATV** - (IN/OUT) - boolean - use [[http://en.wikipedia.org/wiki/Bounce_Address_Tag_Validation|BATV]] (Bounce Address Tag Validation) ===V6 and later=== * **MaxRecipientsPerLocalMessage** - (IN/OUT) - number - maximum number of recipients allowed for locally sent messages * **MaxRecipientsPerIncomingMessage** - (IN/OUT) - number - maximum number of recipients allowed for incoming messages * **MaxMessagesPerLocalSession** - (IN/OUT) - number - maximum number of messages allowed per local session * **MaxLineLength** - (IN/OUT) - number - maximum line length * **AddUserAddresses** - (IN/OUT) - boolean - add recipients of locally sent messages to the autocomplete address list ===V6.5 and later=== * **ServerID** - (IN) - number - ID of SMTP Service in VPOP3 * **ServerName** - (IN) - string - name of SMTP Service in VPOP3 ====In VPOP3 Enterprise Only==== * **CheckRBL** * **RBLFound** * **RBLBlackhole** * **RBLAccept** * **RBLRedirect** * **RBLRejectMessage** * **RBLHeader** ===V7.10 and later=== * **Encryption** - (IN) - boolean - Is the session encrypted * **EncryptionDetails** - (IN) - string - SSL/TLS version and SSL/TLS cipher being used (if encrypted) =====SMTP Server "Start()"===== ''Start()'' This function is called by VPOP3 when the SMTP Server session starts, before the welcome message is sent to the SMTP client Can return "" to give the default welcome message, or another string (including the SMTP result code). VPOP3 will terminate the connection if a **5xx** or **4xx** result code is given In VPOP3 Enterprise, there are also the following global variables defined. These can be changed by the **Start()** function if desired: * **RBLServers** - table containing a list of RBL servers to query * **RBLWhitelist** - table containing a list of white-listed servers (wildcards are supported) * **RBLCheckAllServers** - if TRUE then all RBL servers will be checked, if FALSE, then VPOP3 will stop testing as soon as one returns a match result. =====SMTP Server - RBLResults()===== ''RBLResults()'' (Only supported in VPOP3 Enterprise) This function is called by VPOP3 after the RBL (Realtime Black List) processing has taken place For this function the standard SMTP Server Global Variables will give the result of the RBL processing. Also there is a table called **RBLResultInfo** which contains the raw result information in the form of a table of entries indexed on the name of the RBL database, with the entry data being the IP address resulting from the RBL query in the form of a single number (so a resulting value of '127.0.0.1' which be stored as 0x0100007f or 16777343) (Note a bug in VPOP3 2.1.0 and earlier means that this will not work. It was fixed in 2.1.0a and later) This function should return a text string which can be used to block connections. This text string is used as the 'welcome' response from the VPOP3 SMTP server. If the return string is "", then the default VPOP3 welcome text will be used, or the return value from the **Start()** function if any. Otherwise the text returned from this function will be used. The text string returned should contain the SMTP result code - VPOP3 will terminate the connection if a **5xx** or **4xx** result code is given. =====GetMaxMessageSize()===== ''GetMaxMessageSize("", )'' This function is called by VPOP3 when the SMTP service session starts, and also when VPOP3 receives a //EHLO// or //HELO// command At session start the **** value is the SMTP client IP address. At the //EHLO/HELO// time it's the parameter to the //EHLO// or //HELO// command. This function should return the new maximum message size in bytes (0 = no limit) =====GetEHLOCapabilities===== ''GetEHLOCapabilities("", "")'' This function is called by VPOP3 when it receives a //EHLO// command The **** value is the value of the parameter to the //EHLO// command.\\ The **** value is the current capabilities string which will be returned to the SMTP client This function should return the new capabilities string (see the relevant RFCs for the syntax) =====DoHELO()===== ''DoHELO("", bRefuse, bEHLO)'' This function is called by VPOP3 when it receives a //HELO// or //EHLO// command The **** value is the value of the parameter to the //EHLO// or //HELO// command.\\ The **** value is if VPOP3 is going to refuse this SMTP connection already\\ The **** value is TRUE if this function is being called after a //EHLO// command, or FALSE if it's being called after a //HELO// command This function should return **, ""** * **bRefuse** is true if VPOP3 should refuse this SMTP connection * the **response string** is the SMTP response which VPOP3 should give to the //EHLO/HELO// command. (Leave blank to use the standard VPOP3 response) =====DoHELP()===== ''DoHELP("")'' This function is called by VPOP3 when it receives a //HELP// command The **** value is the text which VPOP3 will return to the SMTP client This function should return the new help text to return to the client (see the RFCs for the syntax) =====DoQUIT()===== ''DoQUIT()'' This function is called by VPOP3 when it receives a //QUIT// command This function should return the text to return to the client (or "" to use the default VPOP3 text) =====DoNOOP()===== ''DoNOOP()'' This function is called by VPOP3 when it receives a //NOOP// command This function should return the text to return to the client (or "" to use the default VPOP3 text) =====DoRSET()===== ''DoRSET()'' This function is called by VPOP3 when it receives a //RSET// command This function should return the text to return to the client (or "" to use the default VPOP3 text) =====DoVRFY()===== ''DoVRFY(, ")'' This function is called by VPOP3 when it receives a //VRFY// command The 'Recipient list' contains the expanded list of recipients which the command's parameter expands to. The 'current response' contains the response which VPOP3 would return if the script doesn't exist. This function should return the text to return to the client (return the value of the parameter to return VPOP3's normal response) =====DoEXPN()===== ''DoEXPN(, ")'' This function is called by VPOP3 when it receives a //EXPN// command The 'Recipient list' contains the expanded list of recipients which the command's parameter expands to. The 'current response' contains the response which VPOP3 would return if the script doesn't exist. This function should return the text to return to the client (return the value of the parameter to return VPOP3's normal response) =====DoMAILFROM()===== DoMAILFROM("", "", , "", "") This function is called by VPOP3 when it receives a valid //MAIL FROM// command The **** is the raw data after the //MAIL FROM:// command\\ The **** is the address after the //MAIL FROM:// command\\ The **** is a table of parameters to the //MAIL FROM:// command (if any) with the table entry key being the parameter name and the table entry value being the parameter value\\ The **** is the result (pass, fail, softfail, etc) of the SPF check (if any) on the connection (in v5 and later). This function should return **, ** Starting in version 5, the script can add a new 'parameter' with name 'MAILFROM' and a new value for the return path to be used by VPOP3. =====DoRCPTTO()===== ''DoRCPTTO("", "", , )'' This function is called by VPOP3 when it receives a valid //RCPT TO// command The **** is the raw data after the //RCPT TO:// command\\ The **** is the address after the //RCPT TO:// command\\ The **** is a table of parameters to the //RCPT TO:// command (if any) with the table entry key being the parameter name and the table entry value being the parameter value \\ The **** is a table containing the list of recipient email addresses for this message so far (not including this one) This function should return **, ** =====DoDATAStart()===== ''DoDATAStart()'' This function is called by VPOP3 when it receives a valid //DATA// command The **** is a table containing the list of recipient email addresses for this message This function should return **,
** =====DoUnrecognised()===== ''DoUnrecognised()'' This function is called by VPOP3 when it receives a command it doesn't recognise The **** is a raw command line that VPOP3 received This function should return **** =====ProcessMessage()===== ''ProcessMessage("", "", , , , , )'' This function is called by VPOP3 when a message has been received by the SMTP service. * is the SMTP 'MAIL FROM' address * is the message subject line * is a table containing a list of the recipient email addresses (from the RCPT TO envelope) * is a table with the following entries * SendToOriginalRecipients boolean - should the message be sent to the originally specified recipients * Delete boolean - should the message be deleted after retrieving (see below) * Ignore boolean - should the message be ignored * Reason string - text string to use if a reason is needed for the action * Recipients table - table containing new/replacement recipients for the message * HeaderModifiers table - list of message header modifications to make - each entry is the full header line (eg "From: ") * is a table with one or more of the following entries * Path string - the IMAP style path to the message section * ContentType string - the main content type (eg 'text', 'image' etc) * ContentSubtype string - the content subtype (eg 'html', 'plain', 'gif', etc) * ContentTypeFilename string - the filename from the ContentType header * ContentDisposition string - usually 'inline' or 'attachment' or blank * ContentDispositionFilename string - the filename from the ContentDisposition header * Start number - the offset from the start of the message where this section starts * End number - the offset from the start of the message where this section ends * is the size of the message in bytes * is a table with zero or more of the following entries, referring to the attachments in the message * MIMESection number - the MIME section that this attachment occurred in * Name string - the name of the attachment * MIMEType string - the MIME type of the attachment * Size number - the size of the attachment * Type string - the type of attachment (MIME, UUE, BINHEX, MIMEUUE, MIMEBINHEX, TNEF) In , 'Delete' is implied for all SMTP messages (it's not possible to not delete a mesage). If Delete and Ignore are both TRUE then the message is rejected with a 5xx SMTP error code. If Ignore is TRUE, but Delete is FALSE, then the message is accepted, but not processed (ie 'blackholed') This function should return , (In version 7.0 and later, the returned 'results string' is ignored) In this function the [[lua_scripting#only_in_pop3cltlua_and_smtpsvrlua_processmessage_function|VPOP3 ProcessMessage helper functions]] can be used. =====CheckRecipients()===== ''CheckRecipients(, , , , "", "", "", "Subject", , '' This function is called after the entire message has been received (so the message headers can be parsed by VPOP3) and allows a script to check that the recipients, and recipient types (eg Bcc) are allowed for this message * Recipient List - table containing a list of the recipient email addresses (from the RCPT TO envelope) * To Recipients - table containing a list of the recipient email addresses parsed from the To header field * Cc Recipients - table containing a list of the recipient email addresses parsed from the Cc header field * Bcc Recipients - table containing a list of the Bcc recipient email addresses. (This is calculated as taking the recipient list, and removing any entries from the To or Cc header fields) * Sender IP Address - string containing the IP address of the sender * Authenticated Sender - string containing the authenticated user name of the sender (if any) * Sender Address - string containing the email address of the sender * Subject - string containing the message's subject * Locally Sent - boolean containing whether the message was sent by a local user (true) or is incoming SMTP (false) * Message Size - number containing the size of the message This function should return either nothing, or a 4xx/5xx error response to return to the email client if the message is to be rejected =====End()===== ''End()'' This function is called by VPOP3 when the SMTP service session ends