/*
 * Copyright (C) Tildeslash Ltd. All rights reserved.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License version 3.
 *
 * 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 Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * In addition, as a special exception, the copyright holders give
 * permission to link the code of portions of this program with the
 * OpenSSL library under certain conditions as described in each
 * individual source file, and distribute linked combinations
 * including the two.
 *
 * You must obey the GNU Affero General Public License in all respects
 * for all of the code used other than OpenSSL.  
 */


#include "config.h"

#ifdef HAVE_STDIO_H
#include <stdio.h>
#endif

#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif

#ifdef HAVE_STDARG_H
#include <stdarg.h>
#endif

#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif

#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif

#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif 

#ifdef HAVE_SETJMP_H
#include <setjmp.h>
#endif 

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#ifdef HAVE_STRING_H
#include <string.h>
#endif

#include "monit.h"
#include "net.h"
#include "socket.h"
#include "base64.h"

// libmonit
#include "system/Time.h"


/**
 *  Connect to a SMTP server and send mail.
 *
 *  @file
 */


/* ------------------------------------------------------------- Definitions */


typedef struct {
  Socket_T socket;
  sigjmp_buf error;
  const char *server;
  int port;
  const char *username;
  const char *password;
  Ssl_T ssl;
  char localhost[STRLEN];
} SendMail_T;


/* -------------------------------------------------------------- Prototypes */


static void do_status(SendMail_T *S);
static void open_server(SendMail_T *S);
static void do_send(SendMail_T *S, const char *, ...);


/* ------------------------------------------------------------------ Public */


/**
 * Send mail messages via SMTP
 * @param mail A Mail object
 * @return FALSE if failed, TRUE if succeeded
 */
int sendmail(Mail_T mail) {

  int i;
  int rv;
  Mail_T m;
  SendMail_T S;
  char *b64 = NULL;
  char now[STRLEN];
  
  ASSERT(mail);
  
  S.socket = NULL;
  if(sigsetjmp(S.error, TRUE)) {
    rv = FALSE;
    goto exit;
  } else {
    rv = TRUE;
  }
  
  open_server(&S);
  
  Time_gmtstring(Time_now(), now);
  
  snprintf(S.localhost, sizeof(S.localhost), "%s", Run.mail_hostname ? Run.mail_hostname : Run.localhostname);
  
  do_status(&S);

  /* Use EHLO if TLS or Authentication is requested */
  if((S.ssl.use_ssl && S.ssl.version == SSL_VERSION_TLS) || S.username) {
    do_send(&S, "EHLO %s\r\n", S.localhost);
  } else {
    do_send(&S, "HELO %s\r\n", S.localhost);
  }
  do_status(&S);

  /* Switch to TLS now if configured */
  if(S.ssl.use_ssl && S.ssl.version == SSL_VERSION_TLS) {
    do_send(&S, "STARTTLS\r\n"); 
    do_status(&S);
    if(!socket_switch2ssl(S.socket, S.ssl)) {
      rv = FALSE;
      goto exit;
    }
    /* After starttls, send ehlo again: RFC 3207: 4.2 Result of the STARTTLS Command */
    do_send(&S, "EHLO %s\r\n", S.localhost);
    do_status(&S);
  }

  /* Authenticate if possible */
  if(S.username) {
    unsigned char buffer[STRLEN];
    int len;

    len = snprintf((char *)buffer, STRLEN, "%c%s%c%s", '\0', S.username, '\0', S.password?S.password:"");
    b64 = encode_base64(len, buffer);
    do_send(&S, "AUTH PLAIN %s\r\n", b64); 
    do_status(&S);
  }
  
  for(i = 0, m= mail; m; m= m->next, i++) { 
    do_send(&S, "MAIL FROM: <%s>\r\n", m->from);
    do_status(&S);
    do_send(&S, "RCPT TO: <%s>\r\n", m->to);
    do_status(&S);
    do_send(&S, "DATA\r\n");
    do_status(&S);
    do_send(&S, "From: %s\r\n", m->from);
    if (m->replyto)
      do_send(&S, "Reply-To: %s\r\n", m->replyto);
    do_send(&S, "To: %s\r\n", m->to);
    do_send(&S, "Subject: %s\r\n", m->subject);
    do_send(&S, "Date: %s\r\n", now);
    do_send(&S, "X-Mailer: %s %s\r\n", prog, VERSION);
    do_send(&S, "Mime-Version: 1.0\r\n");
    do_send(&S, "Content-Type: text/plain; charset=\"iso-8859-1\"\r\n");
    do_send(&S, "Content-Transfer-Encoding: 8bit\r\n");
    do_send(&S, "Message-id: <%ld.%lu@%s>\r\n", time(NULL), random(), S.localhost);
    do_send(&S, "\r\n");
    do_send(&S, "%s\r\n", m->message);
    do_send(&S, ".\r\n");
    do_status(&S);
  }
  do_send(&S, "QUIT\r\n");
  do_status(&S);
  
exit:
  if(S.socket)
    socket_free(&S.socket);
  
  FREE(b64);

  return rv;
}


/* ----------------------------------------------------------------- Private */


void do_send(SendMail_T *S, const char *s, ...) {
  va_list ap;
  char *msg= NULL;
  
  va_start(ap,s);
  msg= Str_vcat(s, ap);
  va_end(ap);
  
  if (socket_write(S->socket, msg, strlen(msg)) <= 0) {
    FREE(msg);
    LogError("Sendmail: error sending data to the server '%s' -- %s\n",
	S->server, STRERROR);
    siglongjmp(S->error, TRUE);
  }
  
  FREE(msg);
  
}


static void do_status(SendMail_T *S) {
  
  int  status;
  char buf[STRLEN];
  
  if(!socket_readln(S->socket, buf, sizeof(buf))) {
    LogError("Sendmail: error receiving data from the mailserver '%s' -- %s\n",
	S->server, STRERROR);
    siglongjmp(S->error, TRUE);
  }
  
  Str_chomp(buf);
  
  sscanf(buf, "%d", &status);
  
  if(status >= 400) {
    LogError("Sendmail error: %s\n", buf);
    siglongjmp(S->error, TRUE);
  }
  
}


static void open_server(SendMail_T *S) {

  MailServer_T mta= Run.mailservers;

  if(mta) {
    S->server      = mta->host;
    S->port        = mta->port;
    S->username    = mta->username;
    S->password    = mta->password;
    S->ssl         = mta->ssl;
  } else {
    LogError("No mail servers are defined -- see manual for 'set mailserver' statement\n");
    siglongjmp(S->error, TRUE);
  }
  
  do {

    /* wait with ssl-connect if SSL_VERSION_TLS is set (rfc2487) */
    if(!S->ssl.use_ssl || S->ssl.version == SSL_VERSION_TLS) {
      S->socket= socket_new(S->server, S->port, SOCKET_TCP, FALSE,
                   Run.mailserver_timeout);
    } else {
      S->socket= socket_create_t(S->server, S->port, SOCKET_TCP,
                   S->ssl, Run.mailserver_timeout);
    }
    if(S->socket)
      break;
      
    LogError("Cannot open a connection to the mailserver '%s:%i' -- %s\n",
	S->server, S->port, STRERROR);

    if(mta && (mta= mta->next)) {
      S->server   = mta->host;
      S->port     = mta->port;
      S->username = mta->username;
      S->password = mta->password;
      S->ssl      = mta->ssl;
      LogInfo("Trying the next mail server '%s:%i'\n", S->server, S->port);
      continue;
    } else {
      LogError("No mail servers are available\n");
      siglongjmp(S->error, TRUE);
    }
  } while(TRUE);
  
}

