annotate fuzz.h @ 1788:1fc0012b9c38

Fix handling of replies to global requests (#112) The current code assumes that all global requests want / need a reply. This isn't always true and the request itself indicates if it wants a reply or not. It causes a specific problem with [email protected] messages. These are sent by OpenSSH after authentication to inform the client of potential other host keys for the host. This can be used to add a new type of host key or to rotate host keys. The initial information message from the server is sent as a global request, but with want_reply set to false. This means that the server doesn't expect an answer to this message. Instead the client needs to send a prove request as a reply if it wants to receive proof of ownership for the host keys. The bug doesn't cause any current problems with due to how OpenSSH treats receiving the failure message. It instead treats it as a keepalive message and further ignores it. Arguably this is a protocol violation though of Dropbear and it is only accidental that it doesn't cause a problem with OpenSSH. The bug was found when adding host keys support to libssh, which is more strict protocol wise and treats the unexpected failure message an error, also see https://gitlab.com/libssh/libssh-mirror/-/merge_requests/145 for more information. The fix here is to honor the want_reply flag in the global request and to only send a reply if the other side expects a reply.
author Dirkjan Bussink <d.bussink@gmail.com>
date Thu, 10 Dec 2020 16:13:13 +0100
parents a3b39df57c8b
children 685b47d8faf7
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1348
5c2899e35b63 fuzz harness
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1 #ifndef DROPBEAR_FUZZ_H
5c2899e35b63 fuzz harness
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2 #define DROPBEAR_FUZZ_H
5c2899e35b63 fuzz harness
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3
1357
08f4fa4dc6a0 closer to working
Matt Johnston <matt@ucc.asn.au>
parents: 1356
diff changeset
4 #include "config.h"
1559
92c93b4a3646 Fix to be able to compile normal(ish) binaries with --enable-fuzz
Matt Johnston <matt@ucc.asn.au>
parents: 1558
diff changeset
5
1558
2f64cb3d3007 - #if not #ifdef for DROPBEAR_FUZZ
Matt Johnston <matt@ucc.asn.au>
parents: 1456
diff changeset
6 #if DROPBEAR_FUZZ
1357
08f4fa4dc6a0 closer to working
Matt Johnston <matt@ucc.asn.au>
parents: 1356
diff changeset
7
1348
5c2899e35b63 fuzz harness
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
8 #include "includes.h"
5c2899e35b63 fuzz harness
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
9 #include "buffer.h"
1357
08f4fa4dc6a0 closer to working
Matt Johnston <matt@ucc.asn.au>
parents: 1356
diff changeset
10 #include "algo.h"
1778
19cdeb3d2aac Fix fuzzing build
Matt Johnston <matt@ucc.asn.au>
parents: 1777
diff changeset
11 #include "netio.h"
1357
08f4fa4dc6a0 closer to working
Matt Johnston <matt@ucc.asn.au>
parents: 1356
diff changeset
12 #include "fuzz-wrapfd.h"
1348
5c2899e35b63 fuzz harness
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
13
1356
3677a510f545 add wrapfd. improve fuzzer in makefile
Matt Johnston <matt@ucc.asn.au>
parents: 1348
diff changeset
14 // once per process
1456
a90fdd2d2ed8 add fuzzer-preauth_nomaths
Matt Johnston <matt@ucc.asn.au>
parents: 1385
diff changeset
15 void fuzz_common_setup(void);
a90fdd2d2ed8 add fuzzer-preauth_nomaths
Matt Johnston <matt@ucc.asn.au>
parents: 1385
diff changeset
16 void fuzz_svr_setup(void);
1741
d1b279aa5ed1 Get client fuzzer building and starting (fails straight away)
Matt Johnston <matt@ucc.asn.au>
parents: 1740
diff changeset
17 void fuzz_cli_setup(void);
1348
5c2899e35b63 fuzz harness
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
18
1758
1365661f6be6 Disable stderr output for fuzzer by default
Matt Johnston <matt@ucc.asn.au>
parents: 1757
diff changeset
19 // constructor attribute so it runs before main(), including
1365661f6be6 Disable stderr output for fuzzer by default
Matt Johnston <matt@ucc.asn.au>
parents: 1757
diff changeset
20 // in non-fuzzing mode.
1365661f6be6 Disable stderr output for fuzzer by default
Matt Johnston <matt@ucc.asn.au>
parents: 1757
diff changeset
21 void fuzz_early_setup(void) __attribute__((constructor));
1365661f6be6 Disable stderr output for fuzzer by default
Matt Johnston <matt@ucc.asn.au>
parents: 1757
diff changeset
22
1377
d4cc85e6c569 rearrange, all fuzzers now call fuzzer_set_input()
Matt Johnston <matt@ucc.asn.au>
parents: 1369
diff changeset
23 // must be called once per fuzz iteration.
d4cc85e6c569 rearrange, all fuzzers now call fuzzer_set_input()
Matt Johnston <matt@ucc.asn.au>
parents: 1369
diff changeset
24 // returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE
1456
a90fdd2d2ed8 add fuzzer-preauth_nomaths
Matt Johnston <matt@ucc.asn.au>
parents: 1385
diff changeset
25 int fuzz_set_input(const uint8_t *Data, size_t Size);
a90fdd2d2ed8 add fuzzer-preauth_nomaths
Matt Johnston <matt@ucc.asn.au>
parents: 1385
diff changeset
26
1782
a6da10ac64b5 fuzz: make postauth set authdone properly
Matt Johnston <matt@ucc.asn.au>
parents: 1779
diff changeset
27 int fuzz_run_server(const uint8_t *Data, size_t Size, int skip_kexmaths, int postauth);
1746
28ab2cdb84bf Fix fuzzer build
Matt Johnston <matt@ucc.asn.au>
parents: 1741
diff changeset
28 int fuzz_run_client(const uint8_t *Data, size_t Size, int skip_kexmaths);
1589
35af85194268 Add kexdh and kexecdh fuzzers
Matt Johnston <matt@ucc.asn.au>
parents: 1561
diff changeset
29 const void* fuzz_get_algo(const algo_type *algos, const char* name);
1356
3677a510f545 add wrapfd. improve fuzzer in makefile
Matt Johnston <matt@ucc.asn.au>
parents: 1348
diff changeset
30
1369
ddfcadca3c4c fuzzer-pubkey
Matt Johnston <matt@ucc.asn.au>
parents: 1358
diff changeset
31 // fuzzer functions that intrude into general code
1357
08f4fa4dc6a0 closer to working
Matt Johnston <matt@ucc.asn.au>
parents: 1356
diff changeset
32 void fuzz_kex_fakealgos(void);
1369
ddfcadca3c4c fuzzer-pubkey
Matt Johnston <matt@ucc.asn.au>
parents: 1358
diff changeset
33 int fuzz_checkpubkey_line(buffer* line, int line_num, char* filename,
ddfcadca3c4c fuzzer-pubkey
Matt Johnston <matt@ucc.asn.au>
parents: 1358
diff changeset
34 const char* algo, unsigned int algolen,
ddfcadca3c4c fuzzer-pubkey
Matt Johnston <matt@ucc.asn.au>
parents: 1358
diff changeset
35 const unsigned char* keyblob, unsigned int keybloblen);
ddfcadca3c4c fuzzer-pubkey
Matt Johnston <matt@ucc.asn.au>
parents: 1358
diff changeset
36 extern const char * const * fuzz_signkey_names;
1757
517fb7b62438 Add some more variation to fuzzer random number generation
Matt Johnston <matt@ucc.asn.au>
parents: 1751
diff changeset
37 void fuzz_seed(const unsigned char* dat, unsigned int len);
1782
a6da10ac64b5 fuzz: make postauth set authdone properly
Matt Johnston <matt@ucc.asn.au>
parents: 1779
diff changeset
38 void fuzz_svr_hook_preloop(void);
1741
d1b279aa5ed1 Get client fuzzer building and starting (fails straight away)
Matt Johnston <matt@ucc.asn.au>
parents: 1740
diff changeset
39
1778
19cdeb3d2aac Fix fuzzing build
Matt Johnston <matt@ucc.asn.au>
parents: 1777
diff changeset
40 typedef void(*connect_callback)(int result, int sock, void* data, const char* errstring);
19cdeb3d2aac Fix fuzzing build
Matt Johnston <matt@ucc.asn.au>
parents: 1777
diff changeset
41 struct dropbear_progress_connection *fuzz_connect_remote(const char* remotehost, const char* remoteport,
19cdeb3d2aac Fix fuzzing build
Matt Johnston <matt@ucc.asn.au>
parents: 1777
diff changeset
42 connect_callback cb, void* cb_data,
19cdeb3d2aac Fix fuzzing build
Matt Johnston <matt@ucc.asn.au>
parents: 1777
diff changeset
43 const char* bind_address, const char* bind_port);
19cdeb3d2aac Fix fuzzing build
Matt Johnston <matt@ucc.asn.au>
parents: 1777
diff changeset
44
1786
a3b39df57c8b fuzz: add an always-failing dropbear_listen() replacement
Matt Johnston <matt@ucc.asn.au>
parents: 1782
diff changeset
45 int fuzz_dropbear_listen(const char* address, const char* port,
a3b39df57c8b fuzz: add an always-failing dropbear_listen() replacement
Matt Johnston <matt@ucc.asn.au>
parents: 1782
diff changeset
46 int *socks, unsigned int sockcount, char **errstring, int *maxfd);
a3b39df57c8b fuzz: add an always-failing dropbear_listen() replacement
Matt Johnston <matt@ucc.asn.au>
parents: 1782
diff changeset
47
1741
d1b279aa5ed1 Get client fuzzer building and starting (fails straight away)
Matt Johnston <matt@ucc.asn.au>
parents: 1740
diff changeset
48 // helpers
1383
f03cfe9c76ac Disable setnonblocking(), get_socket_address(), set_sock_priority()
Matt Johnston <matt@ucc.asn.au>
parents: 1377
diff changeset
49 void fuzz_get_socket_address(int fd, char **local_host, char **local_port,
f03cfe9c76ac Disable setnonblocking(), get_socket_address(), set_sock_priority()
Matt Johnston <matt@ucc.asn.au>
parents: 1377
diff changeset
50 char **remote_host, char **remote_port, int host_lookup);
1456
a90fdd2d2ed8 add fuzzer-preauth_nomaths
Matt Johnston <matt@ucc.asn.au>
parents: 1385
diff changeset
51 void fuzz_fake_send_kexdh_reply(void);
1740
dfbe947bdf0d Make wrapfd share a common buffer for all FDs
Matt Johnston <matt@ucc.asn.au>
parents: 1589
diff changeset
52 int fuzz_spawn_command(int *ret_writefd, int *ret_readfd, int *ret_errfd, pid_t *ret_pid);
1751
3b9b427925a0 Load password and key for client fuzzer.
Matt Johnston <matt@ucc.asn.au>
parents: 1746
diff changeset
53 void fuzz_dump(const unsigned char* data, size_t len);
1357
08f4fa4dc6a0 closer to working
Matt Johnston <matt@ucc.asn.au>
parents: 1356
diff changeset
54
08f4fa4dc6a0 closer to working
Matt Johnston <matt@ucc.asn.au>
parents: 1356
diff changeset
55 // fake IO wrappers
08f4fa4dc6a0 closer to working
Matt Johnston <matt@ucc.asn.au>
parents: 1356
diff changeset
56 #ifndef FUZZ_SKIP_WRAP
08f4fa4dc6a0 closer to working
Matt Johnston <matt@ucc.asn.au>
parents: 1356
diff changeset
57 #define select(nfds, readfds, writefds, exceptfds, timeout) \
08f4fa4dc6a0 closer to working
Matt Johnston <matt@ucc.asn.au>
parents: 1356
diff changeset
58 wrapfd_select(nfds, readfds, writefds, exceptfds, timeout)
08f4fa4dc6a0 closer to working
Matt Johnston <matt@ucc.asn.au>
parents: 1356
diff changeset
59 #define write(fd, buf, count) wrapfd_write(fd, buf, count)
08f4fa4dc6a0 closer to working
Matt Johnston <matt@ucc.asn.au>
parents: 1356
diff changeset
60 #define read(fd, buf, count) wrapfd_read(fd, buf, count)
1358
6b89eb92f872 glaring wrapfd problems fixed
Matt Johnston <matt@ucc.asn.au>
parents: 1357
diff changeset
61 #define close(fd) wrapfd_close(fd)
1357
08f4fa4dc6a0 closer to working
Matt Johnston <matt@ucc.asn.au>
parents: 1356
diff changeset
62 #endif // FUZZ_SKIP_WRAP
08f4fa4dc6a0 closer to working
Matt Johnston <matt@ucc.asn.au>
parents: 1356
diff changeset
63
1348
5c2899e35b63 fuzz harness
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
64 struct dropbear_fuzz_options {
5c2899e35b63 fuzz harness
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
65 int fuzzing;
5c2899e35b63 fuzz harness
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
66
5c2899e35b63 fuzz harness
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
67 // fuzzing input
1356
3677a510f545 add wrapfd. improve fuzzer in makefile
Matt Johnston <matt@ucc.asn.au>
parents: 1348
diff changeset
68 buffer *input;
1357
08f4fa4dc6a0 closer to working
Matt Johnston <matt@ucc.asn.au>
parents: 1356
diff changeset
69 struct dropbear_cipher recv_cipher;
08f4fa4dc6a0 closer to working
Matt Johnston <matt@ucc.asn.au>
parents: 1356
diff changeset
70 struct dropbear_hash recv_mac;
08f4fa4dc6a0 closer to working
Matt Johnston <matt@ucc.asn.au>
parents: 1356
diff changeset
71 int wrapfds;
1348
5c2899e35b63 fuzz harness
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
72
1456
a90fdd2d2ed8 add fuzzer-preauth_nomaths
Matt Johnston <matt@ucc.asn.au>
parents: 1385
diff changeset
73 // whether to skip slow bignum maths
a90fdd2d2ed8 add fuzzer-preauth_nomaths
Matt Johnston <matt@ucc.asn.au>
parents: 1385
diff changeset
74 int skip_kexmaths;
1782
a6da10ac64b5 fuzz: make postauth set authdone properly
Matt Johnston <matt@ucc.asn.au>
parents: 1779
diff changeset
75 // whether is svr_postauth mode
a6da10ac64b5 fuzz: make postauth set authdone properly
Matt Johnston <matt@ucc.asn.au>
parents: 1779
diff changeset
76 int svr_postauth;
1456
a90fdd2d2ed8 add fuzzer-preauth_nomaths
Matt Johnston <matt@ucc.asn.au>
parents: 1385
diff changeset
77
1348
5c2899e35b63 fuzz harness
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
78 // dropbear_exit() jumps back
1385
6c92e97553f1 Add a flag whether to longjmp, missed that last commit
Matt Johnston <matt@ucc.asn.au>
parents: 1383
diff changeset
79 int do_jmp;
1348
5c2899e35b63 fuzz harness
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
80 sigjmp_buf jmp;
1751
3b9b427925a0 Load password and key for client fuzzer.
Matt Johnston <matt@ucc.asn.au>
parents: 1746
diff changeset
81
3b9b427925a0 Load password and key for client fuzzer.
Matt Johnston <matt@ucc.asn.au>
parents: 1746
diff changeset
82 // write out decrypted session data to this FD if it's set
3b9b427925a0 Load password and key for client fuzzer.
Matt Johnston <matt@ucc.asn.au>
parents: 1746
diff changeset
83 // flag - this needs to be set manually in cli-main.c etc
3b9b427925a0 Load password and key for client fuzzer.
Matt Johnston <matt@ucc.asn.au>
parents: 1746
diff changeset
84 int dumping;
3b9b427925a0 Load password and key for client fuzzer.
Matt Johnston <matt@ucc.asn.au>
parents: 1746
diff changeset
85 // the file descriptor
3b9b427925a0 Load password and key for client fuzzer.
Matt Johnston <matt@ucc.asn.au>
parents: 1746
diff changeset
86 int recv_dumpfd;
1758
1365661f6be6 Disable stderr output for fuzzer by default
Matt Johnston <matt@ucc.asn.au>
parents: 1757
diff changeset
87
1365661f6be6 Disable stderr output for fuzzer by default
Matt Johnston <matt@ucc.asn.au>
parents: 1757
diff changeset
88 // avoid filling fuzzing logs, this points to /dev/null
1768
096a66e45212 Fix fuzzing stderr override on os x
Matt Johnston <matt@ucc.asn.au>
parents: 1758
diff changeset
89 FILE *fake_stderr;
1348
5c2899e35b63 fuzz harness
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
90 };
5c2899e35b63 fuzz harness
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
91
5c2899e35b63 fuzz harness
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
92 extern struct dropbear_fuzz_options fuzz;
5c2899e35b63 fuzz harness
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
93
1768
096a66e45212 Fix fuzzing stderr override on os x
Matt Johnston <matt@ucc.asn.au>
parents: 1758
diff changeset
94 /* guard for when fuzz.h is included by fuzz-common.c */
096a66e45212 Fix fuzzing stderr override on os x
Matt Johnston <matt@ucc.asn.au>
parents: 1758
diff changeset
95 #ifndef FUZZ_NO_REPLACE_STDERR
096a66e45212 Fix fuzzing stderr override on os x
Matt Johnston <matt@ucc.asn.au>
parents: 1758
diff changeset
96
1758
1365661f6be6 Disable stderr output for fuzzer by default
Matt Johnston <matt@ucc.asn.au>
parents: 1757
diff changeset
97 /* This is a bodge but seems to work.
1365661f6be6 Disable stderr output for fuzzer by default
Matt Johnston <matt@ucc.asn.au>
parents: 1757
diff changeset
98 glibc stdio.h has the comment
1365661f6be6 Disable stderr output for fuzzer by default
Matt Johnston <matt@ucc.asn.au>
parents: 1757
diff changeset
99 "C89/C99 say they're macros. Make them happy." */
1768
096a66e45212 Fix fuzzing stderr override on os x
Matt Johnston <matt@ucc.asn.au>
parents: 1758
diff changeset
100 /* OS X has it as a macro */
1758
1365661f6be6 Disable stderr output for fuzzer by default
Matt Johnston <matt@ucc.asn.au>
parents: 1757
diff changeset
101 #ifdef stderr
1365661f6be6 Disable stderr output for fuzzer by default
Matt Johnston <matt@ucc.asn.au>
parents: 1757
diff changeset
102 #undef stderr
1365661f6be6 Disable stderr output for fuzzer by default
Matt Johnston <matt@ucc.asn.au>
parents: 1757
diff changeset
103 #endif
1768
096a66e45212 Fix fuzzing stderr override on os x
Matt Johnston <matt@ucc.asn.au>
parents: 1758
diff changeset
104 #define stderr (fuzz.fake_stderr)
096a66e45212 Fix fuzzing stderr override on os x
Matt Johnston <matt@ucc.asn.au>
parents: 1758
diff changeset
105
096a66e45212 Fix fuzzing stderr override on os x
Matt Johnston <matt@ucc.asn.au>
parents: 1758
diff changeset
106 #endif /* FUZZ_NO_REPLACE_STDERR */
1758
1365661f6be6 Disable stderr output for fuzzer by default
Matt Johnston <matt@ucc.asn.au>
parents: 1757
diff changeset
107
1779
36d4c027cba7 fuzzing: add workaround getpwuid/getpwnam
Matt Johnston <matt@ucc.asn.au>
parents: 1778
diff changeset
108 struct passwd* fuzz_getpwuid(uid_t uid);
36d4c027cba7 fuzzing: add workaround getpwuid/getpwnam
Matt Johnston <matt@ucc.asn.au>
parents: 1778
diff changeset
109 struct passwd* fuzz_getpwnam(const char *login);
36d4c027cba7 fuzzing: add workaround getpwuid/getpwnam
Matt Johnston <matt@ucc.asn.au>
parents: 1778
diff changeset
110 /* guard for when fuzz.h is included by fuzz-common.c */
36d4c027cba7 fuzzing: add workaround getpwuid/getpwnam
Matt Johnston <matt@ucc.asn.au>
parents: 1778
diff changeset
111 #ifndef FUZZ_NO_REPLACE_GETPW
36d4c027cba7 fuzzing: add workaround getpwuid/getpwnam
Matt Johnston <matt@ucc.asn.au>
parents: 1778
diff changeset
112 #define getpwnam(x) fuzz_getpwnam(x)
36d4c027cba7 fuzzing: add workaround getpwuid/getpwnam
Matt Johnston <matt@ucc.asn.au>
parents: 1778
diff changeset
113 #define getpwuid(x) fuzz_getpwuid(x)
36d4c027cba7 fuzzing: add workaround getpwuid/getpwnam
Matt Johnston <matt@ucc.asn.au>
parents: 1778
diff changeset
114 #endif // FUZZ_NO_REPLACE_GETPW
36d4c027cba7 fuzzing: add workaround getpwuid/getpwnam
Matt Johnston <matt@ucc.asn.au>
parents: 1778
diff changeset
115
1357
08f4fa4dc6a0 closer to working
Matt Johnston <matt@ucc.asn.au>
parents: 1356
diff changeset
116 #endif // DROPBEAR_FUZZ
1348
5c2899e35b63 fuzz harness
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
117
5c2899e35b63 fuzz harness
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
118 #endif /* DROPBEAR_FUZZ_H */