Coverage Report

Created: 2026-07-16 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/dovecot/src/lib-sasl/sasl-server-mech-plain.c
Line
Count
Source
1
/* Copyright (c) Dovecot authors, see top-level COPYING file */
2
3
#include "lib.h"
4
#include "safe-memset.h"
5
6
#include "sasl-server-protected.h"
7
8
static void
9
mech_plain_auth_continue(struct sasl_server_mech_request *request,
10
       const unsigned char *data, size_t data_size)
11
622
{
12
622
  const char *authid, *authenid;
13
622
  char *pass;
14
622
  size_t i, len;
15
622
  int count;
16
17
  /* authorization ID \0 authentication ID \0 pass. */
18
622
  authid = (const char *) data;
19
622
  authenid = NULL; pass = NULL;
20
21
622
  count = 0;
22
216k
  for (i = 0; i < data_size; i++) {
23
215k
    if (data[i] == '\0') {
24
1.23k
      if (++count == 1)
25
616
        authenid = (const char *) data + i+1;
26
619
      else if (count == 2) {
27
615
        i++;
28
615
        len = data_size - i;
29
615
        pass = p_strndup(unsafe_data_stack_pool,
30
615
             data+i, len);
31
615
      }
32
4
      else
33
4
        break;
34
1.23k
    }
35
215k
  }
36
37
622
  if (count == 2 && authenid != NULL && strcmp(authid, authenid) == 0) {
38
    /* the login username isn't different */
39
1
    authid = "";
40
1
  }
41
42
622
  if (count != 2) {
43
    /* invalid input */
44
11
    e_info(request->event, "invalid input");
45
11
    sasl_server_request_failure(request);
46
611
  } else if (!sasl_server_request_set_authid(
47
611
      request, SASL_SERVER_AUTHID_TYPE_USERNAME, authenid)) {
48
    /* invalid username */
49
2
    sasl_server_request_failure(request);
50
609
  } else if (*authid != '\0' &&
51
369
       !sasl_server_request_set_authzid(request, authid)) {
52
    /* invalid login username */
53
10
    sasl_server_request_failure(request);
54
599
  } else {
55
599
    sasl_server_request_verify_plain(
56
599
      request, pass, sasl_server_mech_plain_verify_callback);
57
599
  }
58
59
  /* make sure it's cleared */
60
622
  if (pass != NULL)
61
615
    safe_memset(pass, 0, strlen(pass));
62
622
}
63
64
static const struct sasl_server_mech_funcs mech_plain_funcs = {
65
  .auth_initial = sasl_server_mech_generic_auth_initial,
66
  .auth_continue = mech_plain_auth_continue,
67
};
68
69
static const struct sasl_server_mech_def mech_plain = {
70
  .name = SASL_MECH_NAME_PLAIN,
71
72
  .flags = SASL_MECH_SEC_PLAINTEXT | SASL_MECH_SEC_ALLOW_NULS,
73
  .passdb_need = SASL_MECH_PASSDB_NEED_VERIFY_PLAIN,
74
75
  .funcs = &mech_plain_funcs,
76
};
77
78
void sasl_server_mech_register_plain(struct sasl_server_instance *sinst)
79
8.27k
{
80
8.27k
  sasl_server_mech_register(sinst, &mech_plain, NULL);
81
8.27k
}