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