Rizin
unix-like reverse engineering framework and cli tools
socket_http_server.c File Reference
#include <rz_socket.h>
#include <rz_util.h>

Go to the source code of this file.

Functions

RZ_API void rz_socket_http_server_set_breaked (bool *b)
 
RZ_API RzSocketHTTPRequestrz_socket_http_accept (RzSocket *s, RzSocketHTTPOptions *so)
 
RZ_API void rz_socket_http_response (RzSocketHTTPRequest *rs, int code, const char *out, int len, const char *headers)
 
RZ_API ut8rz_socket_http_handle_upload (const ut8 *str, int len, int *retlen)
 
RZ_API void rz_socket_http_close (RzSocketHTTPRequest *rs)
 

Variables

static boolbreaked = NULL
 

Function Documentation

◆ rz_socket_http_accept()

RZ_API RzSocketHTTPRequest* rz_socket_http_accept ( RzSocket s,
RzSocketHTTPOptions so 
)

Definition at line 13 of file socket_http_server.c.

13  {
14  int content_length = 0, xx, yy;
15  int pxx = 1, first = 0;
16  char buf[1500], *p, *q;
18  if (!hr) {
19  return NULL;
20  }
21  if (so->accept_timeout) {
22  hr->s = rz_socket_accept_timeout(s, 1);
23  } else {
24  hr->s = rz_socket_accept(s);
25  }
26  if (!hr->s) {
27  free(hr);
28  return NULL;
29  }
30  if (so->timeout > 0) {
31  rz_socket_block_time(hr->s, true, so->timeout, 0);
32  }
33  hr->auth = !so->httpauth;
34  for (;;) {
35 #if __WINDOWS__
36  if (breaked && *breaked) {
38  return NULL;
39  }
40 #endif
41  memset(buf, 0, sizeof(buf));
42  xx = rz_socket_gets(hr->s, buf, sizeof(buf));
43  yy = rz_socket_ready(hr->s, 0, 20 * 1000); // this function uses usecs as argument
44  // eprintf ("READ %d (%s) READY %d\n", xx, buf, yy);
45  if (!yy || (!xx && !pxx)) {
46  break;
47  }
48  pxx = xx;
49 
50  if (first == 0) {
51  first = 1;
52  if (strlen(buf) < 3) {
54  return NULL;
55  }
56  p = strchr(buf, ' ');
57  if (p) {
58  *p = 0;
59  }
60  hr->method = strdup(buf);
61  if (p) {
62  q = strstr(p + 1, " HTTP"); // strchr (p+1, ' ');
63  if (q) {
64  *q = 0;
65  }
66  hr->path = strdup(p + 1);
67  }
68  } else {
69  if (!hr->referer && !strncmp(buf, "Referer: ", 9)) {
70  hr->referer = strdup(buf + 9);
71  } else if (!hr->agent && !strncmp(buf, "User-Agent: ", 12)) {
72  hr->agent = strdup(buf + 12);
73  } else if (!hr->host && !strncmp(buf, "Host: ", 6)) {
74  hr->host = strdup(buf + 6);
75  } else if (!strncmp(buf, "Content-Length: ", 16)) {
76  content_length = atoi(buf + 16);
77  } else if (so->httpauth && !strncmp(buf, "Authorization: Basic ", 21)) {
78  char *authtoken = buf + 21;
79  size_t authlen = strlen(authtoken);
80  char *curauthtoken;
82  char *decauthtoken = calloc(4, authlen + 1);
83  if (!decauthtoken) {
84  eprintf("Could not allocate decoding buffer\n");
85  return hr;
86  }
87 
88  if (rz_base64_decode((ut8 *)decauthtoken, authtoken, authlen) == -1) {
89  eprintf("Could not decode authorization token\n");
90  } else {
91  rz_list_foreach (so->authtokens, iter, curauthtoken) {
92  if (!strcmp(decauthtoken, curauthtoken)) {
93  hr->auth = true;
94  break;
95  }
96  }
97  }
98 
99  free(decauthtoken);
100 
101  if (!hr->auth) {
102  eprintf("Failed attempt login from '%s'\n", hr->host);
103  }
104  }
105  }
106  }
107  if (content_length > 0) {
108  rz_socket_read_block(hr->s, (ut8 *)buf, 1); // one missing byte
109  if (ST32_ADD_OVFCHK(content_length, 1)) {
111  eprintf("Could not allocate hr data\n");
112  return NULL;
113  }
114  hr->data = malloc(content_length + 1);
115  hr->data_length = content_length;
116  rz_socket_read_block(hr->s, hr->data, hr->data_length);
117  hr->data[content_length] = 0;
118  }
119  return hr;
120 }
#define NULL
Definition: cris-opc.c:27
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
return memset(p, 0, total)
void * p
Definition: libc.cpp:67
void * malloc(size_t size)
Definition: malloc.c:123
void * calloc(size_t number, size_t size)
Definition: malloc.c:102
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
#define eprintf(x, y...)
Definition: rlcc.c:7
static RzSocket * s
Definition: rtr.c:28
RZ_API int rz_base64_decode(ut8 *bout, const char *bin, int len)
Definition: ubase64.c:48
RZ_API int rz_socket_read_block(RzSocket *s, unsigned char *buf, int len)
Definition: socket.c:808
RZ_API int rz_socket_ready(RzSocket *s, int secs, int usecs)
Definition: socket.c:688
RZ_API RzSocket * rz_socket_accept(RzSocket *s)
Definition: socket.c:582
RZ_API bool rz_socket_block_time(RzSocket *s, bool block, int sec, int usec)
Definition: socket.c:649
RZ_API int rz_socket_gets(RzSocket *s, char *buf, int size)
Definition: socket.c:830
RZ_API RzSocket * rz_socket_accept_timeout(RzSocket *s, unsigned int timeout)
Definition: socket.c:626
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define ST32_ADD_OVFCHK(a, x)
static bool * breaked
RZ_API void rz_socket_http_close(RzSocketHTTPRequest *rs)

References rz_socket_http_options::accept_timeout, rz_socket_http_request::agent, rz_socket_http_request::auth, rz_socket_http_options::authtokens, breaked, calloc(), rz_socket_http_request::data, rz_socket_http_request::data_length, eprintf, free(), rz_socket_http_request::host, rz_socket_http_options::httpauth, malloc(), memset(), rz_socket_http_request::method, NULL, p, rz_socket_http_request::path, rz_socket_http_request::referer, rz_base64_decode(), RZ_NEW0, rz_socket_accept(), rz_socket_accept_timeout(), rz_socket_block_time(), rz_socket_gets(), rz_socket_http_close(), rz_socket_read_block(), rz_socket_ready(), s, rz_socket_http_request::s, ST32_ADD_OVFCHK, strdup(), and rz_socket_http_options::timeout.

Referenced by rz_core_rtr_http_run(), and rz_main_rz_agent().

◆ rz_socket_http_close()

RZ_API void rz_socket_http_close ( RzSocketHTTPRequest rs)

Definition at line 191 of file socket_http_server.c.

191  {
192  rz_socket_free(rs->s);
193  free(rs->path);
194  free(rs->host);
195  free(rs->agent);
196  free(rs->method);
197  free(rs->data);
198  free(rs);
199 }
#define rs()
RZ_API int rz_socket_free(RzSocket *s)
Definition: socket.c:453

References free(), rs, and rz_socket_free().

Referenced by rz_core_rtr_http_run(), rz_main_rz_agent(), and rz_socket_http_accept().

◆ rz_socket_http_handle_upload()

RZ_API ut8* rz_socket_http_handle_upload ( const ut8 str,
int  len,
int retlen 
)

Definition at line 144 of file socket_http_server.c.

144  {
145  if (retlen) {
146  *retlen = 0;
147  }
148  if (!strncmp((const char *)str, "----------", 10)) {
149  int datalen;
150  char *ret;
151  const char *data, *token = (const char *)str + 10;
152  const char *end = strchr(token, '\n');
153  if (!end) {
154  return NULL;
155  }
156  data = strstr(end, "Content-Disposition: form-data; ");
157  if (data) {
158  data = strchr(data, '\n');
159  if (data) {
160  data = strchr(data + 1, '\n');
161  }
162  }
163  if (data) {
164  while (*data == 10 || *data == 13) {
165  data++;
166  }
167  end = (const char *)str + len - 40;
168  while (*end == '-') {
169  end--;
170  }
171  if (*end == 10 || *end == 13) {
172  end--;
173  }
174  datalen = (size_t)(end - data);
175  ret = malloc(datalen + 1);
176  if (!ret) {
177  return NULL;
178  }
179  memcpy(ret, data, datalen);
180  ret[datalen] = 0;
181  if (retlen) {
182  *retlen = datalen;
183  }
184  return (ut8 *)ret;
185  }
186  }
187  return NULL;
188 }
size_t len
Definition: 6502dis.c:15
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
int size_t
Definition: sftypes.h:40

References test_evm::end, len, malloc(), memcpy(), NULL, and cmd_descs_generate::str.

Referenced by rz_core_rtr_http_run().

◆ rz_socket_http_response()

RZ_API void rz_socket_http_response ( RzSocketHTTPRequest rs,
int  code,
const char *  out,
int  len,
const char *  headers 
)

Definition at line 122 of file socket_http_server.c.

122  {
123  const char *strcode =
124  code == 200 ? "ok" : code == 301 ? "Moved permanently"
125  : code == 302 ? "Found"
126  : code == 401 ? "Unauthorized"
127  : code == 403 ? "Permission denied"
128  : code == 404 ? "not found"
129  : "UNKNOWN";
130  if (len < 1) {
131  len = out ? strlen(out) : 0;
132  }
133  if (!headers) {
134  headers = code == 401 ? "WWW-Authenticate: Basic realm=\"R2 Web UI Access\"\n" : "";
135  }
136  rz_socket_printf(rs->s, "HTTP/1.0 %d %s\r\n%s"
137  "Connection: close\r\nContent-Length: %d\r\n\r\n",
138  code, strcode, headers, len);
139  if (out && len > 0) {
140  rz_socket_write(rs->s, (void *)out, len);
141  }
142 }
const lzma_allocator const uint8_t size_t uint8_t * out
Definition: block.h:528
RZ_API void rz_socket_printf(RzSocket *s, const char *fmt,...) RZ_PRINTF_CHECK(2
RZ_API int rz_socket_write(RzSocket *s, void *buf, int len)
Definition: socket.c:724
Definition: inftree9.h:24

References len, out, rs, rz_socket_printf(), and rz_socket_write().

Referenced by rz_core_rtr_http_run(), and rz_main_rz_agent().

◆ rz_socket_http_server_set_breaked()

RZ_API void rz_socket_http_server_set_breaked ( bool b)

Definition at line 9 of file socket_http_server.c.

9  {
10  breaked = b;
11 }
#define b(i)
Definition: sha256.c:42

References b, and breaked.

Referenced by rz_core_rtr_http_stop().

Variable Documentation

◆ breaked

bool* breaked = NULL
static

Definition at line 7 of file socket_http_server.c.

Referenced by rz_socket_http_accept(), and rz_socket_http_server_set_breaked().