/*
* smtp.h
*
* This file is part of msmtp, an SMTP client.
*
* Copyright (C) 2000, 2003, 2004, 2005, 2006
* Martin Lambers <marlam@marlam.de>
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*/
#ifndef SMTP_H
#define SMTP_H
#include <stdio.h>
#include "list.h"
#include "net.h"
#ifdef HAVE_TLS
# include "tls.h"
#endif /* HAVE_TLS */
/* SMTP errors */
/*
* If a function with an 'errstr' argument returns a value != SMTP_EOK,
* '*errstr' either points to an allocates string containing an error
* description or is NULL.
* If such a function returns SMTP_EOK, 'errstr' will not be changed.
*/
#define SMTP_EOK 0 /* no error */
#define SMTP_EIO 1 /* Input/output error */
#define SMTP_EPROTO 2 /* Protocol violation */
#define SMTP_EINVAL 3 /* Invalid input data */
#define SMTP_EUNAVAIL 4 /* Requested service unavailable */
#define SMTP_EAUTHFAIL 5 /* Authentication failed */
#define SMTP_ELIBFAILED 6 /* An underlying library failed */
#define SMTP_EINSECURE 7 /* The requested action would be
insecure */
/* SMTP sub protocols */
#define SMTP_PROTO_SMTP 0 /* default: SMTP / ESMTP */
#define SMTP_PROTO_LMTP 1 /* LMTP, RFC 2033 */
/* SMTP capabilities */
#define SMTP_CAP_STARTTLS (1 << 0)
#define SMTP_CAP_DSN (1 << 1)
#define SMTP_CAP_PIPELINING (1 << 2)
#define SMTP_CAP_SIZE (1 << 3)
#define SMTP_CAP_AUTH (1 << 4)
#define SMTP_CAP_AUTH_PLAIN (1 << 5)
#define SMTP_CAP_AUTH_LOGIN (1 << 6)
#define SMTP_CAP_AUTH_CRAM_MD5 (1 << 7)
#define SMTP_CAP_AUTH_DIGEST_MD5 (1 << 8)
#define SMTP_CAP_AUTH_GSSAPI (1 << 9)
#define SMTP_CAP_AUTH_EXTERNAL (1 << 10)
#define SMTP_CAP_AUTH_NTLM (1 << 11)
#define SMTP_CAP_ETRN (1 << 12)
/*
* This structure describes the capabilities of an SMTP server.
* 'flags' is a combination of the SMTP_CAP_* values above.
* If (flags & SMTP_CAP_SIZE), 'size' contains the max size of a message that
* the SMTP server will accept (0 means there is no limit).
*/
typedef struct
{
int flags;
long size;
} smtp_cap_t;
/*
* This structure represents an SMTP server. Do not access it directly.
*/
typedef struct
{
int fd;
net_readbuf_t readbuf;
#ifdef HAVE_TLS
tls_t tls;
#endif /* HAVE_TLS */
int protocol;
smtp_cap_t cap;
FILE *debug;
} smtp_server_t;
/*
* smtp_new()
*
* Create a new smtp_server_t. If 'debug' is not NULL, the complete
* conversation with the SMTP server will be logged to the referenced file.
* Beware: this log may contain user passwords.
* 'protocol' must be one of the SMTP_PROTO_* constants.
*/
smtp_server_t smtp_new(FILE *debug, int protocol);
/*
* smtp_connect()
*
* Connect to a SMTP server.
* If 'server_canonical_name' is not NULL, a pointer to a string containing the
* canonical hostname of the server will be stored in '*server_canonical_name',
* or NULL if this information is not available.
* If 'server_address' is not NULL, a pointer to a string containing the
* network address of the server will be stored in '*server_address',
* or NULL if this information is not available.
* Both strings are allocated.
* Used error codes: NET_EHOSTNOTFOUND, NET_ESOCKET, NET_ECONNECT
* Success: NET_EOK
*/
int smtp_connect(smtp_server_t *srv, const char *host, int port, int timeout,
char **server_canonical_name, char **server_address,
char **errstr);
/*
* smtp_msg_status()
*
* Returns the three digit status code of the SMTP server message 'msg', which
* *must* be a valid SMTP server message.
*/
int smtp_msg_status(list_t *msg);
/*
* smtp_get_greeting()
*
* Get the greeting message from the SMTP server.
* If 'buf' is not NULL, it will contain a pointer to an allocated string
* containing the identificatin string of the SMTP server (untrusted data!)
* Used error codes: SMTP_EIO, SMTP_EPROTO
*/
int smtp_get_greeting(smtp_server_t *srv, list_t **errmsg, char **buf,
char **errstr);
/*
* smtp_init()
*
* Initialize an SMTP session with the connected SMTP server 'srv'
* (via the SMTP EHLO/HELO command). This function must be used after
* the server is connected and before any mail is send. It must also be used
* (a second time) after TLS is started via the STARTTLS command.
* This function determines the capabilities of the SMTP server.
* 'ehlo_domain' is the parameter for the EHLO/HELO command. If you don't know
* what to use, use "localhost".
* 'error_msg' contains an error message from the SMTP server or NULL.
* Used error codes: SMTP_EIO, SMTP_EPROTO, SMTP_EINVAL
*/
int smtp_init(smtp_server_t *srv, const char *ehlo_domain, list_t **msg,
char **errstr);
/*
* smtp_tls_init()
*
* Prepare TLS encryption. See tls_init() for a description of the arguments.
* Used error codes: TLS_ELIBFAILED, TLS_EFILE
* Success: TLS_EOK
*/
#ifdef HAVE_TLS
int smtp_tls_init(smtp_server_t *srv, const char *tls_key_file,
const char *tls_ca_file, const char *tls_trust_file,
int force_sslv3, char **errstr);
#endif /* HAVE_TLS */
/*
* smtp_tls_starttls()
*
* Announce the start of TLS encryption with an initialized SMTP server,
* using the STARTTLS command.
* Use this function after smtp_init(). The SMTP server must have the
* SMTP_CAP_STARTTLS capability.
* Call smtp_tls() afterwards. Finally, call smtp_init() again (the SMTP server
* might advertise different capabilities when TLS is active, for example plain
* text authentication mechanisms).
* 'error_msg' contains the error message from the SMTP server or NULL.
* Used error codes: SMTP_EIO, SMTP_EPROTO, SMTP_EINVAL
*/
#ifdef HAVE_TLS
int smtp_tls_starttls(smtp_server_t *srv, list_t **error_msg, char **errstr);
#endif /* HAVE_TLS */
/*
* smtp_tls()
*
* Start TLS with a connected SMTP server.
* Use this function either after smtp_connect() for SMTP servers
* that use TLS without the STARTTLS command (service ssmtp; default port 465),
* or after smtp_tls_starttls() for SMTP servers that support the STARTTLS
* command.
* See tls_start() for a description of the arguments.
* Used error codes: TLS_ELIBFAILED, TLS_ECERT, TLS_EHANDSHAKE
* Success: TLS_EOK
*/
#ifdef HAVE_TLS
int smtp_tls(smtp_server_t *srv, const char *hostname, int tls_nocertcheck,
tls_cert_info_t *tci, char **errstr);
#endif /* HAVE_TLS */
/*
* smtp_client_supports_authmech()
*
* Returns 1 if the authentication mechanism is supported by the underlying
* authentication code and 0 otherwise.
*/
int smtp_client_supports_authmech(const char *mech);
/*
* smtp_server_supports_authmech()
*
* Returns 1 if the authentication mechanism is supported by the SMTP server
* and 0 otherwise.
*/
int smtp_server_supports_authmech(smtp_server_t *srv, const char *mech);
/*
* smtp_auth()
*
* Authentication.
* Use smtp_client_supports_authmech() and smtp_server_supports_authmech()
* to find out which authentication mechanisms are available.
* The special value "" for 'auth_mech' causes the function to choose the best
* authentication method supported by the server, unless TLS is incative and the
* method sends plain text passwords. In this case, the function fails with
* SMTP_EINSECURE.
* The hostname is the name of the SMTP server. It may be needed for
* authentication.
* The ntlmdomain may be NULL (even if you use NTLM authentication).
* If 'password' is NULL, but the authentication method needs a password,
* the 'password_callback' function is called (if 'password_callback' is not
* NULL). It is expected to return a * password in an allocated buffer or NULL
* (if it fails).
* 'error_msg' contains the error message from the SMTP server or NULL.
* Used error codes: SMTP_EIO, SMTP_EINVAL, SMTP_EPROTO, SMTP_EAUTHFAIL,
* SMTP_ELIBFAILED, SMTP_EINSECURE, SMTP_EUNAVAIL
*/
int smtp_auth(smtp_server_t *srv,
const char *hostname,
const char *user,
const char *password,
const char *ntlmdomain,
const char *auth_mech,
char *(*password_callback)(const char *hostname, const char *user),
list_t **error_msg,
char **errstr);
/*
* smtp_envelope()
*
* Sends the mail envelope (sender, recipients, ...)
* The mail data must be sent immediately afterwards with smtp_send_mail()
* envelope_from: The envelope from address
* recipients: The list of recipients
* dsn_notify: Delivery Status Notification request string (see man
* page) or NULL. The SMTP server must support
* SMTP_CAP_DSN.
* dsn_return: Either "HDRS", "FULL" or NULL. The SMTP server must
* support SMTP_CAP_DSN.
* error_msg: If an error occurs, this will contain the SMTP server
* message (or NULL)
* Used error codes: SMTP_EIO, SMTP_EPROTO, SMTP_EINVAL, SMTP_EUNAVAIL
*/
int smtp_send_envelope(smtp_server_t *srv,
const char *envelope_from,
list_t *recipients,
const char *dsn_notify,
const char *dsn_return,
list_t **error_msg,
char **errstr);
/*
* smtp_send_mail()
*
* Sends a mail via the SMTP server 'srv'.
* You can use this function more than once to send the mail in chunks.
* When you're done, call smtp_end_mail().
* keep_bcc: Set this flag in one of the following situation:
* 1. The mail data contains a Bcc header that you want to keep
* (highly unlikely)
* 2. The mail data contains no headers at all. This prevents
* accidental removal of mail body contents.
* The default (unset) is to expect headers in the mail data and
* remove the Bcc header.
* mailf: The file containing the mail
* mailsize: This counter will be increased by the number of bytes
* of the mail (as transferred to the SMTP server) in case
* of successful delivery; the contents are undefined in
* case of failure).
* error_msg: If an error occurs, this will contain the SMTP server
* message (or NULL)
* Used error codes: SMTP_EIO
*/
int smtp_send_mail(smtp_server_t *srv, FILE *mailf, int keep_bcc,
long *mailsize, char **errstr);
/*
* smtp_end_mail()
*
* Sends a single dot on a line to the SMTP server, signalling that the
* transmission of mail data is complete.
* This function only works for the SMTP protocol; for LMTP, use
* smtp_end_mail_lmtp() instead.
* Used error codes: SMTP_EIO, SMTP_EUNAVAIL
*/
int smtp_end_mail(smtp_server_t *srv, list_t **msg, char **errstr);
/*
* smtp_end_mail_lmtp()
*
* This function only works for the LMTP protocol; for SMTP, use
* smtp_end_mail() instead.
*
* It sends a single dot on a line to the SMTP server, signalling that the
* transmission of mail data is complete.
*
* The server sends one reply per recipient (therefore 'recipients' must be
* the same list that was given to smtp_send_envelope()).
*
* If all of these replies are positive, SMTP_EOK will be returned.
* If an IO error occured, SMTP_EIO will be returned (as always).
* In both cases, 'errstrs' and 'error_msgs' will be NULL.
*
* If one or more of the replies are negative, SMTP_EUNAVAIL will be returned,
* and 'errstrs' and 'error_msgs' will contain one entry for each entry in the
* 'recipients' list. If the corresponding recipient caused a positive reply,
* both the 'errstrs' and 'error_msgs' entries will be NULL; if it caused a
* negative reply, the 'errstrs' entry will contain an error message and the
* 'error_msgs' entry will contain the negative reply.
*
* Used error codes: SMTP_EIO, SMTP_EUNAVAIL
*/
int smtp_end_mail_lmtp(smtp_server_t *srv,
list_t *recipients,
list_t **errstrs,
list_t **error_msgs,
char **errstr);
/*
* smtp_etrn()
*
* Send a Remote Message Queue Starting request to the SMTP server via the ETRN
* command (RFC 1985).
* Used error codes: SMTP_EIO, SMTP_EINVAL, SMTP_EUNAVAIL, SMTP_EPROTO
*/
int smtp_etrn(smtp_server_t *srv, const char *etrn_argument,
list_t **msg, char **errstr);
/*
* smtp_quit()
*
* Sends the QUIT command to the SMTP server 'srv' to end the current session.
* Use smtp_close() after this function.
* Used error codes: SMTP_EIO, SMTP_EPROTO, SMTP_EINVAL
*/
int smtp_quit(smtp_server_t *srv, char **errstr);
/*
* smtp_close()
*
* Closes the connection to the SMTP server 'srv'.
* 'srv' is unusable afterwards; reinitialize it with smtp_new() if you want
* to reuse it.
*/
void smtp_close(smtp_server_t *srv);
#endif
syntax highlighted by Code2HTML, v. 0.9.1