etc~ scripts and random things |
| git clone https://github.com/djnnvx/etc.git |
| log | files | refs | archive |
fuzz_lws_mock.c (7899B)
1 /* Mock implementations of libwebsockets runtime functions for fuzzing ttyd. 2 * lws_hdr_copy / lws_hdr_custom_* return fuzzer-controlled data so AFL++ 3 * can drive the auth logic. All other lws functions are safe no-ops. */ 4 5 #include "fuzz-include/libwebsockets.h" 6 #include "fuzz_lws_mock.h" 7 #include <string.h> 8 #include <stdio.h> 9 #include <stdint.h> 10 #include <stdlib.h> 11 12 /* ── fuzzer-controlled state ─────────────────────────────────────────── */ 13 char _fuzz_auth_header[4096]; 14 int _fuzz_auth_header_len; 15 char _fuzz_custom_header[4096]; 16 int _fuzz_custom_header_len; 17 char _fuzz_uri_path[4096]; 18 int _fuzz_uri_path_len; 19 char _fuzz_origin[4096]; 20 int _fuzz_origin_len; 21 char _fuzz_host[4096]; 22 int _fuzz_host_len; 23 24 char _fuzz_uri_args[FUZZ_MAX_URI_ARGS][256]; 25 int _fuzz_uri_args_len[FUZZ_MAX_URI_ARGS]; 26 int _fuzz_uri_args_count; 27 28 int _fuzz_is_final_fragment = 1; 29 size_t _fuzz_remaining_payload = 0; 30 31 void fuzz_lws_reset(void) { 32 memset(_fuzz_auth_header, 0, sizeof(_fuzz_auth_header)); 33 _fuzz_auth_header_len = 0; 34 memset(_fuzz_custom_header, 0, sizeof(_fuzz_custom_header)); 35 _fuzz_custom_header_len = 0; 36 memset(_fuzz_uri_path, 0, sizeof(_fuzz_uri_path)); 37 _fuzz_uri_path_len = 0; 38 memset(_fuzz_origin, 0, sizeof(_fuzz_origin)); 39 _fuzz_origin_len = 0; 40 memset(_fuzz_host, 0, sizeof(_fuzz_host)); 41 _fuzz_host_len = 0; 42 memset(_fuzz_uri_args, 0, sizeof(_fuzz_uri_args)); 43 memset(_fuzz_uri_args_len, 0, sizeof(_fuzz_uri_args_len)); 44 _fuzz_uri_args_count = 0; 45 _fuzz_is_final_fragment = 1; 46 _fuzz_remaining_payload = 0; 47 } 48 49 /* ── header accessors ────────────────────────────────────────────────── */ 50 51 /* Helper: copy from a source buffer into dest, return bytes copied */ 52 static int copy_hdr(char *dest, int len, const char *src, int srclen) { 53 if (!dest || len <= 0) return 0; 54 if (!src || srclen <= 0) { dest[0] = '\0'; return 0; } 55 int n = srclen < len - 1 ? srclen : len - 1; 56 memcpy(dest, src, n); 57 dest[n] = '\0'; 58 return n; 59 } 60 61 int lws_hdr_copy(struct lws *wsi, char *dest, int len, 62 enum lws_token_indexes h) { 63 switch (h) { 64 case WSI_TOKEN_HTTP_AUTHORIZATION: 65 return copy_hdr(dest, len, _fuzz_auth_header, _fuzz_auth_header_len); 66 case WSI_TOKEN_GET_URI: 67 case WSI_TOKEN_HTTP_COLON_PATH: 68 return copy_hdr(dest, len, _fuzz_uri_path, _fuzz_uri_path_len); 69 case WSI_TOKEN_ORIGIN: 70 return copy_hdr(dest, len, _fuzz_origin, _fuzz_origin_len); 71 case WSI_TOKEN_HOST: 72 return copy_hdr(dest, len, _fuzz_host, _fuzz_host_len); 73 default: 74 if (dest && len > 0) dest[0] = '\0'; 75 return 0; 76 } 77 } 78 79 int lws_hdr_custom_length(struct lws *wsi, const char *name, int nlen) { 80 return _fuzz_custom_header_len; 81 } 82 83 int lws_hdr_custom_copy(struct lws *wsi, char *dst, int len, 84 const char *name, int nlen) { 85 return copy_hdr(dst, len, _fuzz_custom_header, _fuzz_custom_header_len); 86 } 87 88 int lws_hdr_copy_fragment(struct lws *wsi, char *dst, int len, 89 enum lws_token_indexes h, int frag_idx) { 90 if (h == WSI_TOKEN_HTTP_URI_ARGS && 91 frag_idx < _fuzz_uri_args_count && frag_idx < FUZZ_MAX_URI_ARGS) { 92 return copy_hdr(dst, len, 93 _fuzz_uri_args[frag_idx], 94 _fuzz_uri_args_len[frag_idx]); 95 } 96 if (dst && len > 0) dst[0] = '\0'; 97 return 0; 98 } 99 100 /* ── URI parsing ─────────────────────────────────────────────────────── */ 101 /* Simple parser that extracts protocol, host, port, path from a URI. 102 * Modifies the input string in-place (like the real lws_parse_uri). */ 103 int lws_parse_uri(char *p, const char **prot, const char **host, 104 int *port, const char **path) { 105 if (!p || !*p) { 106 if (prot) *prot = ""; 107 if (host) *host = ""; 108 if (port) *port = 0; 109 if (path) *path = ""; 110 return -1; 111 } 112 113 /* Find protocol: "http://" or "https://" etc. */ 114 char *sep = strstr(p, "://"); 115 if (sep) { 116 *sep = '\0'; 117 if (prot) *prot = p; 118 p = sep + 3; 119 } else { 120 if (prot) *prot = ""; 121 } 122 123 /* host[:port][/path] */ 124 if (host) *host = p; 125 126 /* Find path separator */ 127 char *slash = strchr(p, '/'); 128 if (slash) { 129 if (path) *path = slash + 1; 130 *slash = '\0'; 131 } else { 132 if (path) *path = ""; 133 } 134 135 /* Find port in host part */ 136 char *colon = strchr(p, ':'); 137 if (colon) { 138 *colon = '\0'; 139 if (port) *port = atoi(colon + 1); 140 } else { 141 if (port) *port = 0; 142 } 143 144 return 0; 145 } 146 147 /* ── HTTP response helpers — all no-ops for fuzzing ─────────────────── */ 148 int lws_return_http_status(struct lws *wsi, unsigned int code, 149 const char *html_body) { return 0; } 150 int lws_add_http_header_status(struct lws *wsi, unsigned int code, 151 unsigned char **p, unsigned char *end) { return 0; } 152 int lws_add_http_header_content_length(struct lws *wsi, lws_filepos_t content_length, 153 unsigned char **p, unsigned char *end) { return 0; } 154 int lws_add_http_header_by_token(struct lws *wsi, enum lws_token_indexes h, 155 const unsigned char *v, int len, 156 unsigned char **p, unsigned char *end) { return 0; } 157 int lws_add_http_header_by_name(struct lws *wsi, const unsigned char *n, 158 const unsigned char *v, int len, 159 unsigned char **p, unsigned char *end) { return 0; } 160 int lws_finalize_http_header(struct lws *wsi, unsigned char **p, 161 unsigned char *end) { return 0; } 162 int lws_finalize_write_http_header(struct lws *wsi, unsigned char *start, 163 unsigned char **p, unsigned char *end) { return 0; } 164 int lws_write(struct lws *wsi, unsigned char *buf, size_t len, 165 enum lws_write_protocol protocol) { return (int)len; } 166 int lws_callback_on_writable(struct lws *wsi) { return 0; } 167 void lws_set_timeout(struct lws *wsi, enum pending_timeout reason, int secs) {} 168 void lws_close_reason(struct lws *wsi, int status, 169 unsigned char *buf, size_t len) {} 170 struct lws_context *lws_get_context(const struct lws *wsi) { return NULL; } 171 int lws_is_final_fragment(struct lws *wsi) { return _fuzz_is_final_fragment; } 172 size_t lws_remaining_packet_payload(struct lws *wsi) { return _fuzz_remaining_payload; } 173 int lws_get_peer_simple(struct lws *wsi, char *name, size_t namelen) { 174 if (name && namelen > 0) { strncpy(name, "127.0.0.1", namelen - 1); name[namelen-1] = '\0'; } 175 return 0; 176 } 177 int lws_serve_http_file(struct lws *wsi, const char *file, 178 const char *content_type, const char *other_headers, 179 int other_headers_len) { return 0; } 180 int lws_http_transaction_completed(struct lws *wsi) { return 0; } 181 struct lws_context *lws_create_context(struct lws_context_creation_info *i) { return NULL; } 182 void lws_context_destroy(struct lws_context *ctx) {} 183 int lws_service(struct lws_context *ctx, int timeout_ms) { return 0; } 184 void lws_cancel_service(struct lws_context *ctx) {} 185 void *lws_wsi_user(struct lws *wsi) { return NULL; } 186 struct lws *lws_get_network_wsi(struct lws *wsi) { return wsi; } 187 int lws_get_peer_write_allowance(struct lws *wsi) { return -1; } 188 int lws_write_http(struct lws *wsi, void *buf, size_t len) { return (int)len; } 189 int lws_send_pipe_choked(struct lws *wsi) { return 0; }