I'm not sure how you like patches so here's a crude git diff patch of my
first attempt :-)

diff --git a/Symbols.list b/Symbols.list
index a73487d..360ae2a 100644
--- a/Symbols.list
+++ b/Symbols.list
@@ -14,6 +14,7 @@ osmtpd_register_filter_noop
 osmtpd_register_filter_help
 osmtpd_register_filter_wiz
 osmtpd_register_filter_commit
+osmtpd_register_report_auth
 osmtpd_register_report_connect
 osmtpd_register_report_disconnect
 osmtpd_register_report_identify
diff --git a/opensmtpd.c b/opensmtpd.c
index 71b0691..7953973 100644
--- a/opensmtpd.c
+++ b/opensmtpd.c
@@ -72,6 +72,8 @@ static void osmtpd_connect(struct osmtpd_callback *, struct 
osmtpd_ctx *,
     char *, char *);
 static void osmtpd_identify(struct osmtpd_callback *, struct osmtpd_ctx *,
     char *, char *);
+static void osmtpd_link_auth(struct osmtpd_callback *, struct osmtpd_ctx *,
+    char *, char *);
 static void osmtpd_link_connect(struct osmtpd_callback *, struct osmtpd_ctx *,
     char *, char *);
 static void osmtpd_link_disconnect(struct osmtpd_callback *,
@@ -241,6 +243,15 @@ static struct osmtpd_callback osmtpd_callbacks[] = {
            0,
            0
        },
+       {
+           OSMTPD_TYPE_REPORT,
+           OSMTPD_PHASE_LINK_AUTH,
+           1,
+           osmtpd_link_auth,
+           NULL,
+           0,
+           0
+       },
        {
            OSMTPD_TYPE_REPORT,
            OSMTPD_PHASE_LINK_CONNECT,
@@ -829,6 +840,16 @@ osmtpd_register_report_timeout(int incoming, void 
(*cb)(struct osmtpd_ctx *))
            incoming, 0, NULL);
 }

+void
+osmtpd_register_report_auth(int incoming, void (*cb)(struct osmtpd_ctx *,
+    const char * username, enum osmtpd_auth_result))
+{
+       osmtpd_register(OSMTPD_TYPE_REPORT, OSMTPD_PHASE_LINK_AUTH,
+           incoming, 0, (void *)cb);
+       osmtpd_register(OSMTPD_TYPE_REPORT, OSMTPD_PHASE_LINK_DISCONNECT,
+           incoming, 0, NULL);
+}
+
 void
 osmtpd_local_session(void *(*oncreate)(struct osmtpd_ctx *),
     void (*ondelete)(struct osmtpd_ctx *, void *))
@@ -1267,6 +1288,34 @@ osmtpd_identify(struct osmtpd_callback *cb, struct 
osmtpd_ctx *ctx,
        f(ctx, identity);
 }

+static void
+osmtpd_link_auth(struct osmtpd_callback *cb, struct osmtpd_ctx *ctx,
+    char *params, char *linedup)
+{
+       enum osmtpd_auth_result auth_res;
+       char * username, *end;
+       void (*f)(struct osmtpd_ctx *, const char *, enum osmtpd_auth_result);
+
+       if ((end = strchr(params, '|')) == NULL)
+               osmtpd_errx(1, "Invalid line received: missing username: %s",
+                   linedup);
+       end++[0] = '\0';
+       username = params;
+       params = end;
+       if (strcmp(params, "pass") == 0)
+               auth_res = OSMTPD_AUTH_PASS;
+       else if (strcmp(params, "fail") == 0)
+               auth_res = OSMTPD_AUTH_FAIL;
+       else if (strcmp(params, "error") == 0)
+               auth_res = OSMTPD_AUTH_ERROR;
+       else
+               osmtpd_errx(1, "Invalid line received: invalid result: %s",
+                   linedup);
+
+       if ((f = cb->cb) != NULL)
+               f(ctx, username, auth_res);
+}
+
 static void
 osmtpd_link_connect(struct osmtpd_callback *cb, struct osmtpd_ctx *ctx,
     char *params, char *linedup)
@@ -1870,6 +1919,8 @@ osmtpd_strtophase(const char *phase, const char *linedup)
                return OSMTPD_PHASE_WIZ;
        if (strcmp(phase, "commit") == 0)
                return OSMTPD_PHASE_COMMIT;
+       if (strcmp(phase, "link-auth") == 0)
+               return OSMTPD_PHASE_LINK_AUTH;
        if (strcmp(phase, "link-connect") == 0)
                return OSMTPD_PHASE_LINK_CONNECT;
        if (strcmp(phase, "link-disconnect") == 0)
@@ -1951,6 +2002,8 @@ osmtpd_phasetostr(enum osmtpd_phase phase)
                return "wiz";
        case OSMTPD_PHASE_COMMIT:
                return "commit";
+       case OSMTPD_PHASE_LINK_AUTH:
+               return "link-auth";
        case OSMTPD_PHASE_LINK_CONNECT:
                return "link-connect";
        case OSMTPD_PHASE_LINK_DISCONNECT:
diff --git a/opensmtpd.h b/opensmtpd.h
index eef3237..d59d220 100644
--- a/opensmtpd.h
+++ b/opensmtpd.h
@@ -13,6 +13,7 @@
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
+#include <stdint.h>
 #include <sys/socket.h>

 #ifndef __dead
@@ -49,6 +50,7 @@ enum osmtpd_phase {
        OSMTPD_PHASE_HELP,
        OSMTPD_PHASE_WIZ,
        OSMTPD_PHASE_COMMIT,
+       OSMTPD_PHASE_LINK_AUTH,
        OSMTPD_PHASE_LINK_CONNECT,
        OSMTPD_PHASE_LINK_DISCONNECT,
        OSMTPD_PHASE_LINK_GREETING,
@@ -67,6 +69,12 @@ enum osmtpd_phase {
        OSMTPD_PHASE_TIMEOUT
 };

+enum osmtpd_auth_result {
+       OSMTPD_AUTH_PASS,
+       OSMTPD_AUTH_FAIL,
+       OSMTPD_AUTH_ERROR
+};
+
 #define OSMTPD_NEED_SRC 1 << 0
 #define OSMTPD_NEED_DST 1 << 1
 #define OSMTPD_NEED_RDNS 1 << 2
@@ -156,6 +164,8 @@ void osmtpd_register_report_server(int, void (*)(struct 
osmtpd_ctx *,
 void osmtpd_register_report_response(int, void (*)(struct osmtpd_ctx *,
     const char *));
 void osmtpd_register_report_timeout(int, void (*)(struct osmtpd_ctx *));
+void osmtpd_register_report_auth(int, void (*)(struct osmtpd_ctx *,
+    const char *, enum osmtpd_auth_result));
 void osmtpd_local_session(void *(*)(struct osmtpd_ctx *),
     void (*)(struct osmtpd_ctx *, void *));
 void osmtpd_local_message(void *(*)(struct osmtpd_ctx *),


On Tue, Oct 18 2022, Martijn van Duren <opensm...@list.imperialat.at> wrote:

> There's no particular reason why I didn't implement it.
> It should be relatively straight forward, if you have a patch
> which is up to par I'm willing to add it to my repo.
>
> martijn@
>
> On Tue, 2022-10-18 at 10:34 +0200, Martin Kjær Jørgensen wrote:
>> Hello,
>>
>> I came across your libopensmtpd while developing a relative simple
>> reporting plugin for smtpd. I see the API has alot of existing calls,
>> but I'm basically missing the following function or something like it;
>>
>> void osmtpd_register_report_auth(int, void (*)(struct osmtpd_ctx *,
>> const char * username, enum osmtpd_auth status));
>>
>> I wan't to monitor amount of failed auth attempts and block IP/port
>> temporarily based on statistics.
>>
>> Do you consider it a bad or unneeded feature, or would you accept the
>> feature if I write a patch;
>>
>> /Martin
>>

Reply via email to