Coverage Report

Created: 2026-06-09 06:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/dovecot/src/lib-sasl/dsasl-client-mech-ntlm-dummy.c
Line
Count
Source
1
/* Copyright (c) 2023 Dovecot authors, see the included COPYING file */
2
3
#include "lib.h"
4
#include "dsasl-client-private.h"
5
#include "dsasl-client-mech-ntlm-dummy.h"
6
7
/* Dummy NTLM mechanism
8
9
   This has nothing to do with actual NTLM; it just serves as a means to test
10
   the winbind server mechanisms.
11
 */
12
13
enum ntlm_state {
14
  STATE_INIT = 0,
15
  STATE_RESPONSE
16
};
17
18
struct ntlm_dsasl_client {
19
  struct dsasl_client client;
20
  enum ntlm_state state;
21
};
22
23
void dasl_client_mech_ntlm_init_dummy(void);
24
25
static enum dsasl_client_result
26
mech_ntlm_input(struct dsasl_client *_client,
27
    const unsigned char *input, size_t input_len,
28
    const char **error_r)
29
0
{
30
0
  static const char *challenge = "Challenge";
31
0
  struct ntlm_dsasl_client *client =
32
0
    container_of(_client, struct ntlm_dsasl_client, client);
33
0
  size_t chal_size;
34
35
0
  if (client->state == STATE_RESPONSE) {
36
0
    *error_r = "Server didn't finish authentication";
37
0
    return DSASL_CLIENT_RESULT_ERR_PROTOCOL;
38
0
  }
39
0
  chal_size = strlen(challenge);
40
0
  if (input_len != chal_size ||
41
0
      memcmp(input, challenge, chal_size) != 0) {
42
0
    *error_r = "Invalid challenge";
43
0
    return DSASL_CLIENT_RESULT_ERR_PROTOCOL;
44
0
  }
45
0
  client->state++;
46
0
  return DSASL_CLIENT_RESULT_OK;
47
0
}
48
49
static enum dsasl_client_result
50
mech_ntlm_output(struct dsasl_client *_client,
51
      const unsigned char **output_r, size_t *output_len_r,
52
      const char **error_r)
53
0
{
54
0
  struct ntlm_dsasl_client *client =
55
0
    container_of(_client, struct ntlm_dsasl_client, client);
56
57
0
  if (_client->set.authid == NULL) {
58
0
    *error_r = "authid not set";
59
0
    return DSASL_CLIENT_RESULT_ERR_INTERNAL;
60
0
  }
61
0
  if (_client->password == NULL) {
62
0
    *error_r = "password not set";
63
0
    return DSASL_CLIENT_RESULT_ERR_INTERNAL;
64
0
  }
65
66
0
  const char *response;
67
68
0
  switch (client->state) {
69
0
  case STATE_INIT:
70
0
    *output_r = uchar_empty_ptr;
71
0
    *output_len_r = 0;
72
0
    return DSASL_CLIENT_RESULT_OK;
73
0
  case STATE_RESPONSE:
74
0
    response = t_strconcat("Response: ", _client->set.authid, NULL);
75
0
    *output_r = (const unsigned char *)response;
76
0
    *output_len_r = strlen(response);
77
0
    return DSASL_CLIENT_RESULT_OK;
78
0
  }
79
0
  i_unreached();
80
0
}
81
82
const struct dsasl_client_mech dsasl_client_mech_ntlm = {
83
  .name = SASL_MECH_NAME_NTLM,
84
  .struct_size = sizeof(struct ntlm_dsasl_client),
85
86
  .input = mech_ntlm_input,
87
  .output = mech_ntlm_output
88
};
89
90
void dsasl_client_mech_ntlm_init_dummy(void)
91
0
{
92
0
  dsasl_client_mech_register(&dsasl_client_mech_ntlm);
93
0
}