Hi,

Last week I discovered your great product and installed it on a server. The
only feature missing was smtp-auth. So I wrote this patch. I hope this will
be integrated in monit...

Notes:
- Code does only support "PLAIN" mechanism which sends username and password
unencrypted.
- Does cleanly compile on release-4.9 (I was not able to compile current CVS
even without this patch).
- Integration in parser is very rudimental because I don't know lex & yacc
(see below).
- Works-for-me...

How to use it:
set mailserver MAILSERVER USERNAME PASSWORD

It would be great if someone is able to cleanly integrate this features.

Thomas
Index: monitor.h
===================================================================
RCS file: /sources/monit/monit/monitor.h,v
retrieving revision 1.192
diff -u -r1.192 monitor.h
--- monitor.h	3 Jan 2007 13:46:21 -0000	1.192
+++ monitor.h	29 Jul 2007 19:28:39 -0000
@@ -324,6 +324,8 @@
 typedef struct mymailserver {
   char *host;     /**< Server host address, may be a IP or a hostname string */
   int   port;                                               /**< Server port */
+  const char *username;                         /** < Username for SMTP_AUTH */
+  const char *password;                         /** < Password for SMTP_AUTH */
   /** For internal use */
   struct mymailserver *next;        /**< Next server to try on connect error */
 } *MailServer_T;
Index: p.y
===================================================================
RCS file: /sources/monit/monit/p.y,v
retrieving revision 1.248
diff -u -r1.248 p.y
--- p.y	12 Jan 2007 17:03:24 -0000	1.248
+++ p.y	29 Jul 2007 19:28:40 -0000
@@ -192,7 +192,7 @@
   static void  addcommand(int);
   static void  addargument(char *);
   static void  addcollector(URL_T, int, int, char *);
-  static void  addmailserver(char *, int);
+  static void  addmailserver(char *, int, char *, char *);
   static int   addcredentials(char *, char *, int, int);
   static void  addhtpasswdentry(char *, char *, int);
   static uid_t get_uid(char *, uid_t);
@@ -548,7 +548,15 @@
                     argyytext= xstrdup($1);
 
                     check_hostname($1);
-                    addmailserver($1, PORT_SMTP);
+                    addmailserver($1, PORT_SMTP, 0, 0);
+                  }
+		| STRING STRING STRING {
+                    /* Restore the current text overriden by lookahead */
+                    FREE(argyytext);
+                    argyytext= xstrdup($1);
+
+                    check_hostname($1);
+                    addmailserver($1, PORT_SMTP, $2, $3);
                   }
                 | STRING PORT NUMBER {
                     /* Restore the current text overriden by lookahead */
@@ -556,7 +564,7 @@
                     argyytext= xstrdup($1);
 
                     check_hostname($1);
-                    addmailserver($1, $<number>3);
+                    addmailserver($1, $<number>3, 0, 0);
                   }
                 ;
 
@@ -2623,7 +2631,7 @@
 /*
  * Add a new smtp server to the mail server list
  */
-static void addmailserver(char *host, int port) {
+static void addmailserver(char *host, int port, char *username, char *password) {
 
   MailServer_T s;
   
@@ -2632,6 +2640,8 @@
   NEW(s);
   s->host= host;
   s->port= port;
+  s->username = username;
+  s->password = password;
   s->next= NULL;
 
   if(Run.mailservers) {
Index: sendmail.c
===================================================================
RCS file: /sources/monit/monit/sendmail.c,v
retrieving revision 1.44
diff -u -r1.44 sendmail.c
--- sendmail.c	3 Jan 2007 09:31:01 -0000	1.44
+++ sendmail.c	29 Jul 2007 19:28:40 -0000
@@ -80,6 +80,8 @@
   sigjmp_buf error;
   const char *server;
   int port;
+  const char *username;
+  const char *password;
   char localhost[STRLEN];
 } SendMail_T;
 
@@ -90,6 +92,7 @@
 static void do_status(SendMail_T *S);
 static void open_server(SendMail_T *S);
 static void do_send(SendMail_T *S, const char *, ...);
+static void b64encodeblock(unsigned char[], unsigned char[], int);
 
 
 /* ------------------------------------------------------------------ Public */
@@ -118,8 +121,29 @@
     snprintf(S.localhost, sizeof(S.localhost), "%s", LOCALHOST);
   }
   do_status(&S);
-  do_send(&S, "HELO %s\r\n", S.localhost); 
+  do_send(&S, "EHLO %s\r\n", S.localhost); 
   do_status(&S);
+
+  /* Authenticate if possible */
+  if ( S.username != 0 ) {
+    unsigned char in_buffer[STRLEN];
+    unsigned char out_buffer[STRLEN];
+    int inpos=0;
+    int outpos=0;
+    int len;
+
+    // Encode to BASE64
+    len = snprintf((char *)in_buffer, STRLEN, "%c%s%c%s", '\0', S.username, '\0', S.password);
+    len++; // Add last \0
+    for ( ; inpos < len; inpos +=3, outpos +=4) {
+      b64encodeblock(in_buffer + inpos, out_buffer + outpos, len - inpos -1);
+    }
+    out_buffer[outpos] = 0; //Finish string with trailing \0
+    
+    do_send(&S, "AUTH PLAIN %s\r\n", out_buffer); 
+    do_status(&S);
+  }
+
   for(m= mail; m; m= m->next) { 
     do_send(&S, "MAIL FROM: <%s>\r\n", m->from);
     do_status(&S);
@@ -196,6 +220,8 @@
 
   S->server= mta?mta->host:LOCALHOST;
   S->port=   mta?mta->port:PORT_SMTP;
+  S->username = mta?mta->username:0;
+  S->password = mta?mta->password:0;
   do {
     S->socket= socket_new(S->server, S->port, SOCKET_TCP, FALSE,
 			  Run.mailserver_timeout);
@@ -206,6 +232,8 @@
     if(mta && (mta= mta->next)) {
       S->server= mta->host;
       S->port=   mta->port;
+      S->username = mta?mta->username:0;
+      S->password = mta?mta->password:0;
       LogInfo("Trying the next mail server '%s:%i'\n", S->server, S->port);
       continue;
     } else {
@@ -215,3 +243,13 @@
   } while(TRUE);
 }
 
+
+static void b64encodeblock( unsigned char in[3], unsigned char out[4], int len )
+{
+  char table[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+  out[0] = table[in[0] >> 2];
+  out[1] = table[((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4)];
+  out[2] = len > 1 ? table[((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6)] : '=';
+  out[3] = len > 2 ? table[in[2] & 0x3f] : '=';
+}
_______________________________________________
monit-dev mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/monit-dev

Reply via email to