Skip to content

Commit cfc3f39

Browse files
authored
Merge pull request #17 from ethomson/no_assert
api: soft-fail input errors
2 parents bbc5d10 + 096d96a commit cfc3f39

File tree

4 files changed

+85
-22
lines changed

4 files changed

+85
-22
lines changed

include/ntlmclient.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,19 @@ extern "C" {
2222

2323
typedef struct ntlm_client ntlm_client;
2424

25+
typedef enum {
26+
/**
27+
* An error occurred; more details are available by querying
28+
* `ntlm_client_errmsg`.
29+
*/
30+
NTLM_CLIENT_ERROR = -1,
31+
32+
/**
33+
* The input provided to the function is missing or invalid.
34+
*/
35+
NTLM_CLIENT_ERROR_INVALID_INPUT = -2,
36+
} ntlm_error_code;
37+
2538
/*
2639
* Flags for initializing the `ntlm_client` context. A combination of
2740
* these flags can be provided to `ntlm_client_init`.

src/ntlm.c

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
#include <stdlib.h>
1010
#include <stdint.h>
1111
#include <string.h>
12-
#include <assert.h>
1312
#include <errno.h>
1413
#include <ctype.h>
1514
#include <unistd.h>
@@ -24,6 +23,18 @@
2423
#include "compat.h"
2524
#include "util.h"
2625

26+
#define NTLM_ASSERT_ARG(expr) do { \
27+
if (!(expr)) \
28+
return NTLM_CLIENT_ERROR_INVALID_INPUT; \
29+
} while(0)
30+
31+
#define NTLM_ASSERT(ntlm, expr) do { \
32+
if (!(expr)) { \
33+
ntlm_client_set_errmsg(ntlm, "internal error: " #expr); \
34+
return -1; \
35+
} \
36+
} while(0)
37+
2738
unsigned char ntlm_client_signature[] = NTLM_SIGNATURE;
2839

2940
static bool supports_unicode(ntlm_client *ntlm)
@@ -74,7 +85,9 @@ void ntlm_client_set_errmsg(ntlm_client *ntlm, const char *errmsg)
7485

7586
const char *ntlm_client_errmsg(ntlm_client *ntlm)
7687
{
77-
assert(ntlm);
88+
if (!ntlm)
89+
return "internal error";
90+
7891
return ntlm->errmsg ? ntlm->errmsg : "no error";
7992
}
8093

@@ -84,7 +97,7 @@ int ntlm_client_set_version(
8497
uint8_t minor,
8598
uint16_t build)
8699
{
87-
assert(ntlm);
100+
NTLM_ASSERT_ARG(ntlm);
88101

89102
ntlm->host_version.major = major;
90103
ntlm->host_version.minor = minor;
@@ -111,8 +124,7 @@ int ntlm_client_set_hostname(
111124
const char *hostname,
112125
const char *domain)
113126
{
114-
assert(ntlm);
115-
127+
NTLM_ASSERT_ARG(ntlm);
116128
ENSURE_INITIALIZED(ntlm);
117129

118130
free_hostname(ntlm);
@@ -168,8 +180,7 @@ int ntlm_client_set_credentials(
168180
const char *domain,
169181
const char *password)
170182
{
171-
assert(ntlm);
172-
183+
NTLM_ASSERT_ARG(ntlm);
173184
ENSURE_INITIALIZED(ntlm);
174185

175186
free_credentials(ntlm);
@@ -218,8 +229,7 @@ int ntlm_client_set_credentials(
218229

219230
int ntlm_client_set_target(ntlm_client *ntlm, const char *target)
220231
{
221-
assert(ntlm);
222-
232+
NTLM_ASSERT_ARG(ntlm);
223233
ENSURE_INITIALIZED(ntlm);
224234

225235
free(ntlm->target);
@@ -248,14 +258,16 @@ int ntlm_client_set_target(ntlm_client *ntlm, const char *target)
248258

249259
int ntlm_client_set_nonce(ntlm_client *ntlm, uint64_t nonce)
250260
{
251-
assert(ntlm);
261+
NTLM_ASSERT_ARG(ntlm);
262+
252263
ntlm->nonce = nonce;
253264
return 0;
254265
}
255266

256267
int ntlm_client_set_timestamp(ntlm_client *ntlm, uint64_t timestamp)
257268
{
258-
assert(ntlm);
269+
NTLM_ASSERT_ARG(ntlm);
270+
259271
ntlm->timestamp = timestamp;
260272
return 0;
261273
}
@@ -601,7 +613,9 @@ int ntlm_client_negotiate(
601613
size_t hostname_offset = 0;
602614
uint32_t flags = 0;
603615

604-
assert(out && out_len && ntlm);
616+
NTLM_ASSERT_ARG(out);
617+
NTLM_ASSERT_ARG(out_len);
618+
NTLM_ASSERT_ARG(ntlm);
605619

606620
*out = NULL;
607621
*out_len = 0;
@@ -684,20 +698,22 @@ int ntlm_client_negotiate(
684698
return -1;
685699

686700
if (hostname_len > 0) {
687-
assert(hostname_offset == ntlm->negotiate.pos);
701+
NTLM_ASSERT(ntlm, hostname_offset == ntlm->negotiate.pos);
702+
688703
if (!write_buf(ntlm, &ntlm->negotiate,
689704
(const unsigned char *)ntlm->hostname, hostname_len))
690705
return -1;
691706
}
692707

693708
if (domain_len > 0) {
694-
assert(domain_offset == ntlm->negotiate.pos);
709+
NTLM_ASSERT(ntlm, domain_offset == ntlm->negotiate.pos);
710+
695711
if (!write_buf(ntlm, &ntlm->negotiate,
696712
(const unsigned char *)ntlm->hostdomain, domain_len))
697713
return -1;
698714
}
699715

700-
assert(ntlm->negotiate.pos == ntlm->negotiate.len);
716+
NTLM_ASSERT(ntlm, ntlm->negotiate.pos == ntlm->negotiate.len);
701717

702718
ntlm->state = NTLM_STATE_CHALLENGE;
703719

@@ -719,7 +735,8 @@ int ntlm_client_set_challenge(
719735
uint32_t name_offset, info_offset = 0;
720736
bool unicode, has_target_info = false;
721737

722-
assert(ntlm && (challenge_msg || !challenge_msg_len));
738+
NTLM_ASSERT_ARG(ntlm);
739+
NTLM_ASSERT_ARG(challenge_msg || !challenge_msg_len);
723740

724741
ENSURE_INITIALIZED(ntlm);
725742

@@ -1101,7 +1118,7 @@ static bool generate_ntlm2_hash(
11011118
return false;
11021119
}
11031120

1104-
assert(out_len == NTLM_NTLM2_HASH_LEN);
1121+
NTLM_ASSERT(ntlm, out_len == NTLM_NTLM2_HASH_LEN);
11051122
return true;
11061123
}
11071124

@@ -1122,7 +1139,7 @@ static bool generate_ntlm2_challengehash(
11221139
return false;
11231140
}
11241141

1125-
assert(out_len == 16);
1142+
NTLM_ASSERT(ntlm, out_len == 16);
11261143
return true;
11271144
}
11281145

@@ -1143,7 +1160,7 @@ static bool generate_lm2_response(ntlm_client *ntlm,
11431160
return false;
11441161
}
11451162

1146-
assert(lm2_len == 16);
1163+
NTLM_ASSERT(ntlm, lm2_len == 16);
11471164

11481165
memcpy(&ntlm->lm_response[0], lm2_challengehash, 16);
11491166
memcpy(&ntlm->lm_response[16], &local_nonce, 8);
@@ -1237,7 +1254,9 @@ int ntlm_client_response(
12371254
uint32_t flags = 0;
12381255
bool unicode;
12391256

1240-
assert(out && out_len && ntlm);
1257+
NTLM_ASSERT_ARG(out);
1258+
NTLM_ASSERT_ARG(out_len);
1259+
NTLM_ASSERT_ARG(ntlm);
12411260

12421261
ENSURE_INITIALIZED(ntlm);
12431262

@@ -1362,7 +1381,7 @@ int ntlm_client_response(
13621381
!write_buf(ntlm, &ntlm->response, session, session_len))
13631382
return -1;
13641383

1365-
assert(ntlm->response.pos == ntlm->response.len);
1384+
NTLM_ASSERT(ntlm, ntlm->response.pos == ntlm->response.len);
13661385

13671386
ntlm->state = NTLM_STATE_COMPLETE;
13681387

@@ -1374,7 +1393,8 @@ int ntlm_client_response(
13741393

13751394
void ntlm_client_reset(ntlm_client *ntlm)
13761395
{
1377-
assert(ntlm);
1396+
if (!ntlm)
1397+
return;
13781398

13791399
ntlm->state = NTLM_STATE_NEGOTIATE;
13801400

tests/inputs.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "clar.h"
22
#include "ntlm.h"
3+
#include "ntlm_tests.h"
34

45
static ntlm_client *ntlm;
56

@@ -13,6 +14,31 @@ void test_inputs__cleanup(void)
1314
ntlm_client_free(ntlm);
1415
}
1516

17+
void test_inputs__null(void)
18+
{
19+
const unsigned char *msg;
20+
size_t msg_len;
21+
22+
cl_assert(ntlm_client_errmsg(NULL) != NULL);
23+
24+
cl_must_fail_with(NTLM_CLIENT_ERROR_INVALID_INPUT, ntlm_client_set_hostname(NULL, "hostname", "HOSTDOMAIN"));
25+
cl_must_fail_with(NTLM_CLIENT_ERROR_INVALID_INPUT, ntlm_client_set_credentials(NULL, "user", "DOMAIN", "pass!"));
26+
cl_must_fail_with(NTLM_CLIENT_ERROR_INVALID_INPUT, ntlm_client_set_target(NULL, "target"));
27+
28+
cl_must_fail_with(NTLM_CLIENT_ERROR_INVALID_INPUT, ntlm_client_negotiate(NULL, &msg_len, ntlm));
29+
cl_must_fail_with(NTLM_CLIENT_ERROR_INVALID_INPUT, ntlm_client_negotiate(&msg, NULL, ntlm));
30+
cl_must_fail_with(NTLM_CLIENT_ERROR_INVALID_INPUT, ntlm_client_negotiate(&msg, &msg_len, NULL));
31+
cl_must_fail_with(NTLM_CLIENT_ERROR_INVALID_INPUT, ntlm_client_negotiate(NULL, NULL, NULL));
32+
33+
cl_must_fail_with(NTLM_CLIENT_ERROR_INVALID_INPUT, ntlm_client_set_challenge(NULL, (const unsigned char *)"foo", 3));
34+
cl_must_fail_with(NTLM_CLIENT_ERROR_INVALID_INPUT, ntlm_client_set_challenge(ntlm, NULL, 3));
35+
36+
cl_must_fail_with(NTLM_CLIENT_ERROR_INVALID_INPUT, ntlm_client_response(NULL, &msg_len, ntlm));
37+
cl_must_fail_with(NTLM_CLIENT_ERROR_INVALID_INPUT, ntlm_client_response(&msg, NULL, ntlm));
38+
cl_must_fail_with(NTLM_CLIENT_ERROR_INVALID_INPUT, ntlm_client_response(&msg, &msg_len, NULL));
39+
cl_must_fail_with(NTLM_CLIENT_ERROR_INVALID_INPUT, ntlm_client_response(NULL, NULL, NULL));
40+
}
41+
1642
void test_inputs__set_hostname(void)
1743
{
1844
cl_must_pass(ntlm_client_set_hostname(ntlm, "hostname", "HOSTDOMAIN"));

tests/ntlm_tests.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
#include "ntlm.h"
66
#include "util.h"
77

8+
#define cl_must_fail_with_(val, expr, desc) clar__assert((expr) == (val), __FILE__, __LINE__, "Expected function call to fail with " #val ": " #expr, desc, 0)
9+
10+
#define cl_must_fail_with(val, expr) cl_must_fail_with_(val, expr, NULL)
11+
812
#define cl_ntlm_pass(ntlm, expr) cl_ntlm_expect((ntlm), (expr), 0, __FILE__, __LINE__)
913

1014
#define cl_ntlm_expect(ntlm, expr, expected, file, line) do { \

0 commit comments

Comments
 (0)