diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | NEWS | 9 | ||||
-rw-r--r-- | doc/mailfromd.texi | 88 | ||||
-rw-r--r-- | gacopyz/gacopyz.c | 2 | ||||
-rw-r--r-- | src/engine.c | 111 | ||||
-rw-r--r-- | src/gram.y | 7 | ||||
-rw-r--r-- | src/status.mfi | 6 |
7 files changed, 182 insertions, 47 deletions
@@ -1,5 +1,11 @@ 2007-03-19 Sergey Poznyakoff <gray@gnu.org.ua> + * src/engine.c, src/gram.y, src/status.mfi, doc/mailfromd.texi: + Implement connect handler. Pass additional argument to envfrom and + envrcpt. + * gacopyz/gacopyz.c (shan_connect): Bugfix + * NEWS: Update + * src/mtasim.c (process_gacopyz_reply): Do not switch to quit state unless SMFIR_SHUTDOWN is received. @@ -7,6 +7,15 @@ Please send mailfromd bug reports to <bug-mailfromd@gnu.org.ua> Version 3.1.91, SVN +* connect handler + +Connect handler is implemented. + +* envfrom and envrcpt + +Both handlers take an additional second argument, containing the rest +of the SMTP command line. + * New functions - string db_name(string fmt) diff --git a/doc/mailfromd.texi b/doc/mailfromd.texi index f441ad98..c2295bfe 100644 --- a/doc/mailfromd.texi +++ b/doc/mailfromd.texi @@ -3787,6 +3787,7 @@ operator. @node Handlers @section Handlers +@UNREVISED{} @cindex milter stage handler, defined @cindex stage handler, defined @@ -3821,19 +3822,84 @@ table shows each handler with its arguments: @cindex handler arguments @float Table, handler-arguments @caption{State Handler Arguments} -@multitable @columnfractions 0.25 0.35 0.35 -@headitem Handler @tab $1 @tab $2 -@item connect @tab IP address of the remote host @tab N/A -@item helo @tab @code{HELO} domain @tab N/A -@item envfrom @tab Sender email address @tab N/A -@item envrcpt @tab Recipient email address @tab N/A -@item header @tab Header name @tab Header value -@item eoh @tab N/A @tab N/A -@item body @tab Body segment (string) @tab Length of the segment (numeric) -@item eom @tab N/A @tab N/A +@multitable @columnfractions 0.20 0.20 0.20 0.20 0.20 +@headitem Handler @tab $1 @tab $2 @tab $3 @tab $4 +@item connect @tab Hostname @tab Socket Family @tab Port @tab Remote address +@item helo @tab @code{HELO} domain @tab N/A @tab N/A @tab N/A +@item envfrom @tab Sender email address @tab Rest of arguments @tab N/A @tab N/A +@item envrcpt @tab Recipient email address @tab Rest of arguments @tab N/A @tab N/A +@item header @tab Header name @tab Header value @tab N/A @tab N/A +@item eoh @tab N/A @tab N/A @tab N/A @tab N/A +@item body @tab Body segment (string) @tab Length of the segment +(numeric) @tab N/A @tab N/A +@item eom @tab N/A @tab N/A @tab N/A @tab N/A @end multitable @end float - + +@deffn {Handler} connect (string $1, number $2, number $3, string $4) + +Takes four arguments: +@enumerate 1 +@item @code{string}; +The host name of the message sender, as reported by MTA. Usually it +is determined by a reverse lookup on the host address. If the reverse +lookup fails, @samp{$1} will contain the message sender's IP address +enclosed in square brackets (e.g. @samp{[127.0.0.1]}). + +@item @code{number}; +Socket address family. Include @file{status.mfh} to get symbolic +definitions for the address families. Supported families are: + +@cindex FAMILY_STDIO +@cindex FAMILY_UNIX +@cindex FAMILY_INET +@multitable @columnfractions 0.20 .10 0.70 +@headitem Constant @tab Value @tab Meaning +@item FAMILY_STDIO @tab 0 @tab Standard input/output (the MTA is +run with @option{-bs} option) +@item FAMILY_UNIX @tab 1 @tab @acronym{UNIX} socket +@item FAMILY_INET @tab 2 @tab IPv4 protocol +@end multitable + +@item @code{number}; +Port number if @samp{$2} is @samp{FAMILY_INET}. + +@item @code{string}; +Remote IP address if @samp{$2} is @samp{FAMILY_INET} or full file name +of the socket if @samp{$2} is @samp{FAMILY_UNIX}. If @samp{$2} is +@samp{FAMILY_STDIO}, @samp{$4} is an empty string +@end enumerate + +@end deffn + +@deffn {Handler} helo (string $1) +@FIXME{} +@end deffn + +@deffn {Handler} envfrom (string $1, string $2) +@FIXME{} +@end deffn + +@deffn {Handler} envrcpt (string $1, string $2) +@FIXME{} +@end deffn + +@deffn {Handler} header (string $1, string $2) +@FIXME{} +@end deffn + +@deffn {Handler} eoh +@FIXME{} +@end deffn + +@deffn {Handler} body (string $1, number $2) +@FIXME{} +@end deffn + +@deffn {Handler} eom +@FIXME{} +@end deffn + @node Functions @section Functions diff --git a/gacopyz/gacopyz.c b/gacopyz/gacopyz.c index 3d9ac8e8..1c71a142 100644 --- a/gacopyz/gacopyz.c +++ b/gacopyz/gacopyz.c @@ -870,7 +870,7 @@ shan_connect(SMFICTX *ctx, union state_arg *arg, unsigned char *cmd) s += sizeof port; len -= sizeof port; - if (len > 0 && s[len - 1]) + if (len > 0 && s[len]) return sret_abort; switch (family) { diff --git a/src/engine.c b/src/engine.c index 6aceec71..88c17136 100644 --- a/src/engine.c +++ b/src/engine.c @@ -917,6 +917,57 @@ mlfi_eval(SMFICTX *ctx, enum smtp_state tag) return status; } +#define MFAM_STDIO 0 +#define MFAM_UNIX 1 +#define MFAM_INET 2 + +sfsistat +mlfi_connect(SMFICTX *ctx, char *hostname, _SOCK_ADDR *hostaddr) +{ + sfsistat status; + struct message_data *md = priv_get(ctx); + int port; + char *addrstr; + int family; + + if (!hostaddr) { + family = MFAM_STDIO; + port = 0; + addrstr = ""; + } else switch (hostaddr->sa.sa_family) { + case PF_INET: + family = MFAM_INET; + port = ntohs(hostaddr->sin.sin_port); + addrstr = inet_ntoa(hostaddr->sin.sin_addr); + break; + + case PF_UNIX: + family = MFAM_UNIX; + port = 0; + addrstr = hostaddr->sunix.sun_path; + break; + + default: + mu_error("mlfi_connect: unsupported address family: %d", + hostaddr->sa.sa_family); + gacopyz_setreply(ctx, "410", NULL, + "Local configuration error; please try again later"); + return SMFIS_TEMPFAIL; + } + debug4(70, "Processing xxfi_connect: %s, %d, %u, %s", + hostname, family, port, addrstr); + + env_init(md->env); + env_push_string(md->env, addrstr); + env_push_number(md->env, port); + env_push_number(md->env, family); + env_push_string(md->env, hostname); + env_make_frame(md->env); + status = mlfi_eval(ctx, smtp_state_helo); + env_leave_frame(md->env, 4); + return status; +} + sfsistat mlfi_helo(SMFICTX *ctx, char *helohost) { @@ -933,32 +984,37 @@ mlfi_helo(SMFICTX *ctx, char *helohost) return status; } +static char * +concat_args(const char *fname, char **argv) +{ + size_t argc; + char *p = NULL; + + for (argc = 0; argv[argc]; argc++) + ; + if (mu_argcv_string(argc-1, argv+1, &p)) + debug3(70, "Processing %s: %s%s", + fname, argv[0], argv[1] ? " (more)" : ""); + else + debug2(70, "Processing %s: %s", fname, p); + return p; +} + sfsistat mlfi_envfrom(SMFICTX *ctx, char **argv) { sfsistat status; struct message_data *md = priv_get(ctx); + char *p = concat_args("xxfi_envfrom", argv); - __DBG(70) { - size_t argc; - char *p; - for (argc = 0; argv[argc]; argc++) - ; - if (mu_argcv_string(argc, argv, &p)) - __debug2("Processing xxfi_envfrom: %s%s", - argv[0], argv[1] ? " (more)" : ""); - else { - __debug1("Processing xxfi_envfrom: %s", p); - free(p); - } - } - env_init(md->env); capture_from(md->env, argv[0]); + env_push_string(md->env, p); + free(p); env_push_string(md->env, argv[0]); env_make_frame(md->env); status = mlfi_eval(ctx, smtp_state_envfrom); - env_leave_frame(md->env, 1); + env_leave_frame(md->env, 2); return status; } @@ -967,29 +1023,16 @@ mlfi_envrcpt(SMFICTX *ctx, char ** argv) { sfsistat status; struct message_data *md = priv_get(ctx); - - __DBG(70) { - size_t argc; - char *p; - for (argc = 0; argv[argc]; argc++) - ; - if (mu_argcv_string(argc, argv, &p)) - __debug3("Processing xxfi_envrcpt (#%lu): %s%s", - get_rcpt_count(md->env), - argv[0], argv[1] ? " (more)" : ""); - else { - __debug2("Processing xxfi_envrcpt (#%lu): %s", - get_rcpt_count(md->env), p); - free(p); - } - } + char *p = concat_args("xxfi_envrcpt", argv); env_init(md->env); + env_push_string(md->env, p); + free(p); env_push_string(md->env, argv[0]); env_make_frame(md->env); incr_rcpt_count(md->env); status = mlfi_eval(ctx, smtp_state_envrcpt); - env_leave_frame(md->env, 1); + env_leave_frame(md->env, 2); return status; } @@ -1157,6 +1200,10 @@ void milter_enable_state(enum smtp_state state) { switch (state) { + case smtp_state_connect: + smfilter.xxfi_connect = mlfi_connect; + break; + case smtp_state_helo: smfilter.xxfi_helo = mlfi_helo; break; @@ -97,10 +97,11 @@ struct state_parms { data_type_t types[2]; /* Their data types */ } state_parms[] = { { 0, }, /* smtp_state_none */ - { 0, }, /* smtp_state_connect */ + { 4, { dtype_string, dtype_number, dtype_number, dtype_string } }, + /* smtp_state_connect */ { 1, { dtype_string } }, /* smtp_state_helo */ - { 1, { dtype_string } }, /* smtp_state_envfrom */ - { 1, { dtype_string } }, /* smtp_state_envrcpt */ + { 1, { dtype_string, dtype_string } }, /* smtp_state_envfrom */ + { 1, { dtype_string, dtype_string } }, /* smtp_state_envrcpt */ { 0, }, /* smtp_state_data */ { 2, { dtype_string, dtype_string } }, /* smtp_state_header */ { 0, }, /* smtp_state_eoh */ diff --git a/src/status.mfi b/src/status.mfi index 6d150eb7..55d79986 100644 --- a/src/status.mfi +++ b/src/status.mfi @@ -1,2 +1,8 @@ TEMPLATE # +# Socket families + +const FAMILY_STDIO 0 +const FAMILY_UNIX 1 +const FAMILY_INET 2 + %{const %NAME %CODE%} |