Is the milter API function smfi_setsymlist supported?

classic Classic list List threaded Threaded
20 messages Options
Reply | Threaded
Open this post in threaded view
|

Is the milter API function smfi_setsymlist supported?

David Bürgin
In section ‘What macros will Postfix send to Milters?’, MILTER_README
says:

> As of Sendmail 8.14.0, Milter applications can specify what macros
> they want to receive at different Milter protocol stages. An
> application-specified list takes precedence over a Postfix-specified
> list.

This refers to the API function smfi_setsymlist, right? When I hook a
little test milter into Postfix, requesting a few non-default macros (eg
‘{client_connections}’) with this function during negotiation, it
doesn’t have any effect. Postfix doesn’t send the macros.

Is smfi_setsymlist supported? Did I misunderstand something?

Thank you.
Reply | Threaded
Open this post in threaded view
|

Re: Is the milter API function smfi_setsymlist supported?

Wietse Venema
David B?rgin:
> In section ?What macros will Postfix send to Milters??, MILTER_README
> says:
>
> > As of Sendmail 8.14.0, Milter applications can specify what macros
> > they want to receive at different Milter protocol stages. An
> > application-specified list takes precedence over a Postfix-specified
> > list.
>
> This refers to the API function smfi_setsymlist, right? When I hook a

The Milter docs say: "This function must only be called during
xxfi_negotiate()". Thus, you cannot call it at any other time.
(found with a Google query, because milter.org is gone).

Postfix test code calls smfi_setsymlist during initial Milter
connection negotiation, through the xxfi_negotiate callback in the
smfiDesc structure. It's been ~10 years, but that code presumably
worked. The program is included with Postfix source as
src/milter/test_milter.c. Maybe you can play with that.

        Wietse

> little test milter into Postfix, requesting a few non-default macros (eg
> ?{client_connections}?) with this function during negotiation, it
> doesn?t have any effect. Postfix doesn?t send the macros.
>
> Is smfi_setsymlist supported? Did I misunderstand something?
>
> Thank you.
>
Reply | Threaded
Open this post in threaded view
|

Re: Is the milter API function smfi_setsymlist supported?

David Bürgin
On 14/01/2020 18:22, Wietse Venema wrote:

>> In section ?What macros will Postfix send to Milters??, MILTER_README
>> says:
>>
>>> As of Sendmail 8.14.0, Milter applications can specify what macros
>>> they want to receive at different Milter protocol stages. An
>>> application-specified list takes precedence over a Postfix-specified
>>> list.
>>
>> This refers to the API function smfi_setsymlist, right? When I hook a
>
> The Milter docs say: "This function must only be called during
> xxfi_negotiate()". Thus, you cannot call it at any other time.
> (found with a Google query, because milter.org is gone).

Yes, I’m using the API correctly, and get the MI_SUCCESS return code.

> Postfix test code calls smfi_setsymlist during initial Milter
> connection negotiation, through the xxfi_negotiate callback in the
> smfiDesc structure. It's been ~10 years, but that code presumably
> worked. The program is included with Postfix source as
> src/milter/test_milter.c. Maybe you can play with that.

I suspect this code doesn’t work and perhaps never did work – in Postfix
source there is only one occurrence of smfi_setsymlist, in a code path
that is never executed.

smfi_setsymlist would be a useful function to have, because it lets
milter applications request the macros they need for operation
themselves. Just recently there was a thread on this list where someone
struggled to set up the required macros for a milter application.
Reply | Threaded
Open this post in threaded view
|

Re: Is the milter API function smfi_setsymlist supported?

Wietse Venema
David B?rgin:

> On 14/01/2020 18:22, Wietse Venema wrote:
> >> In section ?What macros will Postfix send to Milters??, MILTER_README
> >> says:
> >>
> >>> As of Sendmail 8.14.0, Milter applications can specify what macros
> >>> they want to receive at different Milter protocol stages. An
> >>> application-specified list takes precedence over a Postfix-specified
> >>> list.
> >>
> >> This refers to the API function smfi_setsymlist, right? When I hook a
> >
> > The Milter docs say: "This function must only be called during
> > xxfi_negotiate()". Thus, you cannot call it at any other time.
> > (found with a Google query, because milter.org is gone).
>
> Yes, I?m using the API correctly, and get the MI_SUCCESS return code.
>
> > Postfix test code calls smfi_setsymlist during initial Milter
> > connection negotiation, through the xxfi_negotiate callback in the
> > smfiDesc structure. It's been ~10 years, but that code presumably
> > worked. The program is included with Postfix source as
> > src/milter/test_milter.c. Maybe you can play with that.
>
> I suspect this code doesn?t work and perhaps never did work ? in Postfix
> source there is only one occurrence of smfi_setsymlist, in a code path
> that is never executed.

smfi_setsymlist() is called by test_negotiate():

static sfsistat test_negotiate(SMFICTX *ctx,
                                       unsigned long f0,
                                       unsigned long f1,
                                       unsigned long f2,
                                       unsigned long f3,
                                       unsigned long *pf0,
                                       unsigned long *pf1,
                                       unsigned long *pf2,
                                       unsigned long *pf3)
{
    if (set_macro_list) {
        if (verbose)
            printf("set symbol list %s to \"%s\"\n",
                   macro_states[set_macro_state], set_macro_list);
        smfi_setsymlist(ctx, set_macro_state, set_macro_list);
    ...
}

test_negotiate() is referenced in:

static struct smfiDesc smfilter =
{
    "test-milter",
    SMFI_VERSION,
    SMFIF_ADDRCPT | SMFIF_DELRCPT | SMFIF_ADDHDRS | SMFIF_CHGHDRS | SMFIF_CHGBOD
Y | SMFIF_CHGFROM,
    test_connect,
    ...
#if SMFI_VERSION > 5
    test_negotiate,
#endif
};

Which is in turn referenced at the end of the test-milter main program.

    if (smfi_register(smfilter) == MI_FAILURE) {
        fprintf(stderr, "smfi_register failed\n");
        exit(1);
    }
    return (smfi_main());
}

I can lead the horse to the water,. but I cannot force it to drink.

        Wietse
Reply | Threaded
Open this post in threaded view
|

Re: Is the milter API function smfi_setsymlist supported?

David Bürgin
Wietse,

On 14/01/2020 18:58, Wietse Venema wrote:

> smfi_setsymlist() is called by test_negotiate():
>
> static sfsistat test_negotiate(SMFICTX *ctx,
>                                        unsigned long f0,
>                                        unsigned long f1,
>                                        unsigned long f2,
>                                        unsigned long f3,
>                                        unsigned long *pf0,
>                                        unsigned long *pf1,
>                                        unsigned long *pf2,
>                                        unsigned long *pf3)
> {
>     if (set_macro_list) {
>         if (verbose)
>             printf("set symbol list %s to \"%s\"\n",
>                    macro_states[set_macro_state], set_macro_list);
>         smfi_setsymlist(ctx, set_macro_state, set_macro_list);
>     ...
> }

the call to smfi_setsymlist is guarded by the flag set_macro_list. This
flag is enabled with the -M command-line option. However, that option is
never used, as far as I can see. Therefore, the code path is not taken.
Reply | Threaded
Open this post in threaded view
|

Re: Is the milter API function smfi_setsymlist supported?

Wietse Venema
David B?rgin:
> Wietse,
>
> On 14/01/2020 18:58, Wietse Venema wrote:
> > smfi_setsymlist() is called by test_negotiate():
> >
> > static sfsistat test_negotiate(SMFICTX *ctx,
> >                                        unsigned long f0,
..

> >                                        unsigned long *pf3)
> > {
> >     if (set_macro_list) {
> >         if (verbose)
> >             printf("set symbol list %s to \"%s\"\n",
> >                    macro_states[set_macro_state], set_macro_list);
> >         smfi_setsymlist(ctx, set_macro_state, set_macro_list);
> >     ...
> > }
>
> the call to smfi_setsymlist is guarded by the flag set_macro_list. This
> flag is enabled with the -M command-line option. However, that option is
> never used, as far as I can see. Therefore, the code path is not taken.

To 'use' the -M command-line option:

        $ make test-milter
        $ ./test-milter -m state -M macros ...

Where state is one of connect, helo, mail. etc.
Where macros is a list of macros. Example: "{rcpt_mailer} {rcpt_host}".

Here is the code that sets set_macro_list:

        case 'm':
#if SMFI_VERSION > 5
            if (set_macro_state_arg) {
                fprintf(stderr, "too many -m options\n");
                exit(1);
            }
            set_macro_state_arg = optarg;
#else
            fprintf(stderr, "no libmilter support to specify macro list\n");
            exit(1);
#endif
            break;
        case 'M':
#if SMFI_VERSION > 5
            if (set_macro_list) {
                fprintf(stderr, "too many -M options\n");
                exit(1);
            }
            set_macro_list = optarg;
#else
            fprintf(stderr, "no libmilter support to specify macro list\n");
#endif
            break;

        Wietse
Reply | Threaded
Open this post in threaded view
|

Re: Is the milter API function smfi_setsymlist supported?

David Bürgin
On 14/01/2020 19:39, Wietse Venema wrote:

>>>                                        unsigned long *pf3)
>>> {
>>>     if (set_macro_list) {
>>>         if (verbose)
>>>             printf("set symbol list %s to \"%s\"\n",
>>>                    macro_states[set_macro_state], set_macro_list);
>>>         smfi_setsymlist(ctx, set_macro_state, set_macro_list);
>>>     ...
>>> }
>>
>> the call to smfi_setsymlist is guarded by the flag set_macro_list. This
>> flag is enabled with the -M command-line option. However, that option is
>> never used, as far as I can see. Therefore, the code path is not taken.
>
> To 'use' the -M command-line option:
>
> $ make test-milter
> $ ./test-milter -m state -M macros ...
>
> Where state is one of connect, helo, mail. etc.
> Where macros is a list of macros. Example: "{rcpt_mailer} {rcpt_host}".

Thank you, Wietse.

test-milter confirms that smfi_setsymlist does not work:

    $ test-milter -v -p inet:3000@localhost -m connect -M '{client_connections}'
    set symbol list connect to "{client_connections}"
    negotiate f0=1ff *pf0 = 1ff f1=1fffff *pf1=400 nosend=0 noreply=0 misc=0
    test_connect localhost AF_INET (127.0.0.1:0)
    macro: j="mail.my.org"
    macro: v="Postfix 3.3.0"
    macro: {daemon_addr}="127.0.0.1"
    macro: {daemon_name}="mail.my.org"
    test_reply 0

The {client_connections} macro is not available in connect, even though
it was requested.

It is a great pity if we cannot use smfi_setsymlist with Postfix, it is
such a useful (and obviously underappreciated) little API.
Reply | Threaded
Open this post in threaded view
|

Re: Is the milter API function smfi_setsymlist supported?

Bill Cole-3
In reply to this post by David Bürgin
On 14 Jan 2020, at 12:40, David Bürgin wrote:

> smfi_setsymlist would be a useful function to have, because it lets
> milter applications request the macros they need for operation
> themselves. Just recently there was a thread on this list where
> someone
> struggled to set up the required macros for a milter application.

I can confirm that a milter absolutely can request and receive macros
from postfix, PROVIDED those macros are available. I use the MIMEDefang
milter, which optionally uses smfi_setsymlist() to request macros and
includes options to ask for specific arbitrary macros. On one testbed I
happen to have this set up in a debug mode which logs which macros are
available to MD at RCPT time, showing me these recently:

  Jan 14 14:01:35 bigsky mimedefang.pl[79121]: 47y0Db2FRdz3SRhl: Macros
are _ daemon_name mail_host mail_mailer j daemon_port client_port
mail_addr
  Jan 14 14:01:52 bigsky mimedefang.pl[79121]: 47y0Dw15yXz3SRjV: Macros
are tls_version cipher daemon_name _ j mail_mailer mail_host client_port
daemon_port cipher_bits mail_addr
  Jan 14 14:02:50 bigsky mimedefang.pl[79121]: 47y0G25N4wz3SRjt: Macros
are daemon_port client_port auth_authen cipher_bits mail_addr auth_type
tls_version cipher j mail_host mail_mailer daemon_name _
  Jan 14 14:06:03 bigsky mimedefang.pl[79121]: 47y0Kl45zxz3SRsL: Macros
are tls_version cipher mail_mailer mail_host j daemon_name _ daemon_port
client_port mail_addr cipher_bits
  Jan 14 14:06:36 bigsky mimedefang.pl[79121]: 47y0LN3dBLz3SRsx: Macros
are tls_version cipher _ daemon_name j mail_mailer mail_host client_port
daemon_port cipher_bits mail_addr
  Jan 14 14:07:34 bigsky mimedefang.pl[79121]: 47y0MV0CwGz3SRtj: Macros
are tls_version cipher mail_mailer mail_host j _ daemon_name daemon_port
client_port mail_addr cipher_bits
  Jan 14 14:13:38 bigsky mimedefang.pl[79121]: 47y0VT6hNPz3SRvm: Macros
are daemon_port client_port mail_addr mail_host mail_mailer j _
daemon_name
  Jan 14 14:23:05 bigsky mimedefang.pl[79121]: 47y0jP4hxNz3SRwW: Macros
are _ daemon_name mail_mailer mail_host j client_port daemon_port
mail_addr

This is quite different from the Postfix config, which has the default
value:

  bigsky:~ bill$ postconf  milter_rcpt_macros
  milter_rcpt_macros = i {rcpt_addr} {rcpt_host} {rcpt_mailer}

So, whatever problem you are having with getting the macros you want is
NOT intrinsic to Postfix.



--
Bill Cole
[hidden email] or [hidden email]
(AKA @grumpybozo and many *@billmail.scconsult.com addresses)
Not Currently Available For Hire
Reply | Threaded
Open this post in threaded view
|

Re: Is the milter API function smfi_setsymlist supported?

Wietse Venema
In reply to this post by David Bürgin
David B?rgin:

> On 14/01/2020 19:39, Wietse Venema wrote:
> >>>                                        unsigned long *pf3)
> >>> {
> >>>     if (set_macro_list) {
> >>>         if (verbose)
> >>>             printf("set symbol list %s to \"%s\"\n",
> >>>                    macro_states[set_macro_state], set_macro_list);
> >>>         smfi_setsymlist(ctx, set_macro_state, set_macro_list);
> >>>     ...
> >>> }
> >>
> >> the call to smfi_setsymlist is guarded by the flag set_macro_list. This
> >> flag is enabled with the -M command-line option. However, that option is
> >> never used, as far as I can see. Therefore, the code path is not taken.
> >
> > To 'use' the -M command-line option:
> >
> > $ make test-milter
> > $ ./test-milter -m state -M macros ...
> >
> > Where state is one of connect, helo, mail. etc.
> > Where macros is a list of macros. Example: "{rcpt_mailer} {rcpt_host}".
>
> Thank you, Wietse.
>
> test-milter confirms that smfi_setsymlist does not work:
>
>     $ test-milter -v -p inet:3000@localhost -m connect -M '{client_connections}'
>     set symbol list connect to "{client_connections}"
>     negotiate f0=1ff *pf0 = 1ff f1=1fffff *pf1=400 nosend=0 noreply=0 misc=0
>     test_connect localhost AF_INET (127.0.0.1:0)
>     macro: j="mail.my.org"
>     macro: v="Postfix 3.3.0"
>     macro: {daemon_addr}="127.0.0.1"
>     macro: {daemon_name}="mail.my.org"
>     test_reply 0

Couple observations.

1) Note that all this requires SMFI_VERSION > 5. Did you verify that?

2) Note that it is up to libmilter to send that macro list to
Postfix.  Did you verify that? This requires a single -v option to
the smtpd configuration in master.cf and doing "postfix reload".

If libmilter sends macros, they are logged like this:

        while (data_len > 0
               && milter8_read_data(milter, &data_len,
                                    MILTER8_DATA_HLONG, &mac_type,
                                    MILTER8_DATA_STRING, buf,
                                    MILTER8_DATA_MORE) == 0) {
            smfim_name = str_name_code(smfim_table, mac_type);
            if (smfim_name == 0) {
                msg_warn("milter %s: ignoring unknown macro type %u",
                         milter->m.name, (unsigned) mac_type);
            } else {
                if (msg_verbose)
                    msg_info("override %s macro list with \"%s\"",
                             smfim_name, STR(buf));
                mac_value_ptr = MILTER8_MACRO_PTR(milter->m.macros, mac_type);
                myfree(*mac_value_ptr);
                *mac_value_ptr = mystrdup(STR(buf));
            }
        }

If libmilter does not send them, then that is the problem.

        Wietse
Reply | Threaded
Open this post in threaded view
|

Re: Is the milter API function smfi_setsymlist supported?

David Bürgin
On 14/01/2020 20:48, Wietse Venema wrote:

>> test-milter confirms that smfi_setsymlist does not work:
>>
>>     $ test-milter -v -p inet:3000@localhost -m connect -M '{client_connections}'
>>     set symbol list connect to "{client_connections}"
>>     negotiate f0=1ff *pf0 = 1ff f1=1fffff *pf1=400 nosend=0 noreply=0 misc=0
>>     test_connect localhost AF_INET (127.0.0.1:0)
>>     macro: j="mail.my.org"
>>     macro: v="Postfix 3.3.0"
>>     macro: {daemon_addr}="127.0.0.1"
>>     macro: {daemon_name}="mail.my.org"
>>     test_reply 0
>
> Couple observations.
>
> 1) Note that all this requires SMFI_VERSION > 5. Did you verify that?
>
> 2) Note that it is up to libmilter to send that macro list to
> Postfix.  Did you verify that? This requires a single -v option to
> the smtpd configuration in master.cf and doing "postfix reload".

Yes, I have an up-to-date Postfix and SMFI_VERSION > 5.

The message

    postfix/smtpd[17351]: override SMFIM_CONNECT macro list with "{client_connections} j _"

does get logged, but right after that there is a line

    postfix/smtpd[17351]: event: SMFIC_CONNECT; macros: j=mail.gluet.ch {daemon_name}=mail.gluet.ch {daemon_addr}=10.52.16.62 v=Postfix 3.3.0

Those are the default macros, not the ones requested.
Reply | Threaded
Open this post in threaded view
|

Re: Is the milter API function smfi_setsymlist supported?

David Bürgin
In reply to this post by Bill Cole-3
On 14/01/2020 20:31, Bill Cole wrote:

> I can confirm that a milter absolutely can request and receive macros from postfix, PROVIDED those macros are available. I use the MIMEDefang milter, which optionally uses smfi_setsymlist() to request macros and includes options to ask for specific arbitrary macros. On one testbed I happen to have this set up in a debug mode which logs which macros are available to MD at RCPT time, showing me these recently:
>
>  Jan 14 14:01:35 bigsky mimedefang.pl[79121]: 47y0Db2FRdz3SRhl: Macros are _ daemon_name mail_host mail_mailer j daemon_port client_port mail_addr
>  Jan 14 14:01:52 bigsky mimedefang.pl[79121]: 47y0Dw15yXz3SRjV: Macros are tls_version cipher daemon_name _ j mail_mailer mail_host client_port daemon_port cipher_bits mail_addr
>  Jan 14 14:02:50 bigsky mimedefang.pl[79121]: 47y0G25N4wz3SRjt: Macros are daemon_port client_port auth_authen cipher_bits mail_addr auth_type tls_version cipher j mail_host mail_mailer daemon_name _
>  Jan 14 14:06:03 bigsky mimedefang.pl[79121]: 47y0Kl45zxz3SRsL: Macros are tls_version cipher mail_mailer mail_host j daemon_name _ daemon_port client_port mail_addr cipher_bits
>  Jan 14 14:06:36 bigsky mimedefang.pl[79121]: 47y0LN3dBLz3SRsx: Macros are tls_version cipher _ daemon_name j mail_mailer mail_host client_port daemon_port cipher_bits mail_addr
>  Jan 14 14:07:34 bigsky mimedefang.pl[79121]: 47y0MV0CwGz3SRtj: Macros are tls_version cipher mail_mailer mail_host j _ daemon_name daemon_port client_port mail_addr cipher_bits
>  Jan 14 14:13:38 bigsky mimedefang.pl[79121]: 47y0VT6hNPz3SRvm: Macros are daemon_port client_port mail_addr mail_host mail_mailer j _ daemon_name
>  Jan 14 14:23:05 bigsky mimedefang.pl[79121]: 47y0jP4hxNz3SRwW: Macros are _ daemon_name mail_mailer mail_host j client_port daemon_port mail_addr
>
> This is quite different from the Postfix config, which has the default value:
>
>  bigsky:~ bill$ postconf  milter_rcpt_macros
>  milter_rcpt_macros = i {rcpt_addr} {rcpt_host} {rcpt_mailer}
>
> So, whatever problem you are having with getting the macros you want is NOT intrinsic to Postfix.

Thanks Bill,

I have reproduced this both with an independent milter application and
with the Postfix test-milter program. Are you sure MIMEDefang uses the
libmilter API? It isn’t a pure Perl milter implementation?

Beginning to get a little confused ...
Reply | Threaded
Open this post in threaded view
|

Re: Is the milter API function smfi_setsymlist supported?

Wietse Venema
In reply to this post by David Bürgin
David B?rgin:

> On 14/01/2020 20:48, Wietse Venema wrote:
> >> test-milter confirms that smfi_setsymlist does not work:
> >>
> >>     $ test-milter -v -p inet:3000@localhost -m connect -M '{client_connections}'
> >>     set symbol list connect to "{client_connections}"
> >>     negotiate f0=1ff *pf0 = 1ff f1=1fffff *pf1=400 nosend=0 noreply=0 misc=0
> >>     test_connect localhost AF_INET (127.0.0.1:0)
> >>     macro: j="mail.my.org"
> >>     macro: v="Postfix 3.3.0"
> >>     macro: {daemon_addr}="127.0.0.1"
> >>     macro: {daemon_name}="mail.my.org"
> >>     test_reply 0
> >
> > Couple observations.
> >
> > 1) Note that all this requires SMFI_VERSION > 5. Did you verify that?
> >
> > 2) Note that it is up to libmilter to send that macro list to
> > Postfix.  Did you verify that? This requires a single -v option to
> > the smtpd configuration in master.cf and doing "postfix reload".
>
> Yes, I have an up-to-date Postfix and SMFI_VERSION > 5.
>
> The message
>
>     postfix/smtpd[17351]: override SMFIM_CONNECT macro list with "{client_connections} j _"
>
> does get logged, but right after that there is a line
>
>     postfix/smtpd[17351]: event: SMFIC_CONNECT; macros: j=mail.gluet.ch {daemon_name}=mail.gluet.ch {daemon_addr}=10.52.16.62 v=Postfix 3.3.0
>
> Those are the default macros, not the ones requested.

This is taking to much time. I will look into this later, maybe the wekeend.

        Wietse
Reply | Threaded
Open this post in threaded view
|

Re: Is the milter API function smfi_setsymlist supported?

Bill Cole-3
In reply to this post by David Bürgin
On 14 Jan 2020, at 15:16, David Bürgin wrote:

> I have reproduced this both with an independent milter application and
> with the Postfix test-milter program. Are you sure MIMEDefang uses the
> libmilter API?

Absolutely certain.

> It isn’t a pure Perl milter implementation?

No. The core mimedefang daemon is compiled C, linked with libmilter. In
this case, v8.15.2.

> Beginning to get a little confused ...

I can understand why.

Is it certain that the macro you want is non-null when you're asking for
it?

--
Bill Cole
[hidden email] or [hidden email]
(AKA @grumpybozo and many *@billmail.scconsult.com addresses)
Not Currently Available For Hire
Reply | Threaded
Open this post in threaded view
|

Re: Is the milter API function smfi_setsymlist supported?

David Bürgin
On 14/01/2020 21:59, Bill Cole wrote:
>> Beginning to get a little confused ...
>
> I can understand why.
>
> Is it certain that the macro you want is non-null when you're asking for it?

I will post a minimal C reproducer some time later hopefully.

As a summary, another quick illustration of the problem I’m seeing:

• I can request macros for the connect stage in /etc/postfix/main.cf:
  milter_connect_macros = j _ {client_addr} {client_connections} {client_name} {client_port} {client_ptr} {daemon_addr} {daemon_name} {daemon_port} v
• These macros are then all available in the connect callback of a test
  milter, I can print out the value of each macro.
• If instead of the setting in /etc/postfix/main.cf, I request exactly
  the same macros in the negotiate callback of my milter with
  smfi_setsymlist(ctx, SMFIM_CONNECT, "j _ {client_addr} {client_connections} {client_name} {client_port} {client_ptr} {daemon_addr} {daemon_name} {daemon_port} v");
  this does not have the same effect as in item 1. Only the default
  connect macros are available.

I think anyone should be able to reproduce this easily. (Or even better:
point out the basic mistake I’m making, silly me!)

Cheers,
Reply | Threaded
Open this post in threaded view
|

Re: Is the milter API function smfi_setsymlist supported?

David Bürgin
If someone wants to try … Make sure you have libmilter installed.
Compile and run:

c99 -Wall nosetsymlist.c -lmilter -o nosetsymlist
./nosetsymlist

Enable in /etc/postfix/main.cf with:

smtpd_milters = inet:localhost:3000

Then both requested macros, _ and {client_port}, are *not* available
during connect. If I request these macros in /etc/postfix/main.cf with

milter_connect_macros = _ {client_port}

then they *are* available and do get printed. Either smfi_setsymlist
doesn’t do anything, or – perhaps more likely – I’m making a mistake!
Very grateful for any hints.


#include <stdio.h>
#include <assert.h>
#include "libmilter/mfapi.h"

sfsistat test_negotiate(
    SMFICTX *ctx,
    unsigned long f0, unsigned long f1, unsigned long f2, unsigned long f3,
    unsigned long *pf0, unsigned long *pf1, unsigned long *pf2, unsigned long *pf3
) {
    *pf0 = *pf1 = *pf2 = *pf3 = 0;

    int status = smfi_setsymlist(ctx, SMFIM_CONNECT, "_ {client_port}");
    assert(status == MI_SUCCESS);

    return SMFIS_CONTINUE;
}

sfsistat test_connect(SMFICTX *ctx, char *hostname, struct sockaddr *hostaddr) {
    char *_macro = smfi_getsymval(ctx, "_");
    printf("_: %s\n", _macro == NULL ? "NULL" : _macro);

    char *cpmacro = smfi_getsymval(ctx, "{client_port}");
    printf("{client_port}: %s\n", cpmacro == NULL ? "NULL" : cpmacro);

    return SMFIS_CONTINUE;
}

int main() {
    int connstatus = smfi_setconn("inet:3000@localhost");
    assert(connstatus == MI_SUCCESS);

    int regstatus = smfi_register((struct smfiDesc) {
        .xxfi_name = "nosetsymlist",
        .xxfi_version = SMFI_VERSION,
        .xxfi_connect = test_connect,
        .xxfi_negotiate = test_negotiate,
    });
    assert(regstatus == MI_SUCCESS);

    return smfi_main();
}
Reply | Threaded
Open this post in threaded view
|

Re: Is the milter API function smfi_setsymlist supported?

Wietse Venema
David B?rgin:

> If someone wants to try ? Make sure you have libmilter installed.
> Compile and run:
>
> c99 -Wall nosetsymlist.c -lmilter -o nosetsymlist
> ./nosetsymlist
>
> Enable in /etc/postfix/main.cf with:
>
> smtpd_milters = inet:localhost:3000
>
> Then both requested macros, _ and {client_port}, are *not* available
> during connect. If I request these macros in /etc/postfix/main.cf with
>
> milter_connect_macros = _ {client_port}
>
> then they *are* available and do get printed. Either smfi_setsymlist
> doesn?t do anything, or ? perhaps more likely ? I?m making a mistake!
> Very grateful for any hints.

Please try any OTHER stage than connect. It might be a bug
that exists only in the connect handler. You would help
narrow down the search for me.

        Wietse
Reply | Threaded
Open this post in threaded view
|

Re: Is the milter API function smfi_setsymlist supported?

David Bürgin
On 15/01/2020 13:32, Wietse Venema wrote:> Please try any OTHER stage than connect. It might be a bug
> that exists only in the connect handler. You would help
> narrow down the search for me.

You’re right, I just tried requesting _ for the data stage and that does
work!

I have to take a break from this, sorry. And thanks for looking.
Reply | Threaded
Open this post in threaded view
|

Re: Is the milter API function smfi_setsymlist supported?

Wietse Venema
David B?rgin:
> On 15/01/2020 13:32, Wietse Venema wrote:> Please try any OTHER stage than connect. It might be a bug
> > that exists only in the connect handler. You would help
> > narrow down the search for me.
>
> You?re right, I just tried requesting _ for the data stage and that does
> work!

Thanks for checking that.

I noticed that the Postfix implementation does the postfix<->milter
setup while reporting the SMTP connect event.

This evaluates the connect macros before the postfix<->milter setup
has a chance to override them.

Fix would be a some swap of some code.

        Wietse
Reply | Threaded
Open this post in threaded view
|

PATCH: milter API function smfi_setsymlist

Wietse Venema
Wietse Venema:
> I noticed that the Postfix implementation does the postfix<->milter
> setup while reporting the SMTP connect event.
> This evaluates the connect macros before the postfix<->milter setup
> has a chance to override them.
>
> Fix would be a some swap of some code.

As implemented in this patch: move the on-the-fly connect before
the macroi evaluation. Should work for Postfix 2.5 and later.

        Wietse


20200115-milter-connect-macros-patch.txt (4K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: PATCH: milter API function smfi_setsymlist

David Bürgin
On 15/01/2020 16:37, Wietse Venema wrote:
> As implemented in this patch: move the on-the-fly connect before
> the macroi evaluation. Should work for Postfix 2.5 and later.

Thank you very much.

I would try it out, unfortunately I have never set up Postfix from the
raw materials myself (I’m using the Debian/Ubuntu package). So I don’t
know when I will get around to doing so. Thanks again.