Coverage Report

Created: 2026-01-09 06:28

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) 2002-2018 Dovecot authors, see the included 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
607
{
12
607
  const char *authid, *authenid;
13
607
  char *pass;
14
607
  size_t i, len;
15
607
  int count;
16
17
  /* authorization ID \0 authentication ID \0 pass. */
18
607
  authid = (const char *) data;
19
607
  authenid = NULL; pass = NULL;
20
21
607
  count = 0;
22
45.0k
  for (i = 0; i < data_size; i++) {
23
44.4k
    if (data[i] == '\0') {
24
1.20k
      if (++count == 1)
25
601
        authenid = (const char *) data + i+1;
26
604
      else if (count == 2) {
27
599
        i++;
28
599
        len = data_size - i;
29
599
        pass = p_strndup(unsafe_data_stack_pool,
30
599
             data+i, len);
31
599
      }
32
5
      else
33
5
        break;
34
1.20k
    }
35
44.4k
  }
36
37
607
  if (count == 2 && authenid != NULL && strcmp(authid, authenid) == 0) {
38
    /* the login username isn't different */
39
1
    authid = "";
40
1
  }
41
42
607
  if (count != 2) {
43
    /* invalid input */
44
13
    e_info(request->event, "invalid input");
45
13
    sasl_server_request_failure(request);
46
594
  } else if (!sasl_server_request_set_authid(
47
594
      request, SASL_SERVER_AUTHID_TYPE_USERNAME, authenid)) {
48
    /* invalid username */
49
2
    sasl_server_request_failure(request);
50
592
  } else if (*authid != '\0' &&
51
364
       !sasl_server_request_set_authzid(request, authid)) {
52
    /* invalid login username */
53
2
    sasl_server_request_failure(request);
54
590
  } else {
55
590
    sasl_server_request_verify_plain(
56
590
      request, pass, sasl_server_mech_plain_verify_callback);
57
590
  }
58
59
  /* make sure it's cleared */
60
607
  if (pass != NULL)
61
599
    safe_memset(pass, 0, strlen(pass));
62
607
}
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.34k
{
80
8.34k
  sasl_server_mech_register(sinst, &mech_plain, NULL);
81
8.34k
}