R_API void r_core_rtr_cmd(RCore *core, const char *input) { char bufw[1024], bufr[8]; const char *cmd = NULL, *cmd_output = NULL; int i, cmd_len, fd = atoi (input); if (*input==':' && !strchr (input+1, ':')) { r_core_cmdf (core, "o rap://%s", input); return; } if (fd != 0) { if (rtr_host[rtr_n].fd) for (rtr_n = 0; rtr_host[rtr_n].fd->fd != fd && rtr_n < RTR_MAX_HOSTS - 1; rtr_n++); if (!(cmd = strchr (input, ' '))) { eprintf ("Error\n"); return; } } else cmd = input; if (!rtr_host[rtr_n].fd){ eprintf ("Error: Unknown host\n"); core->num->value = 1; // fail return; } if (!rtr_host[rtr_n].proto == RTR_PROT_RAP){ eprintf ("Error: Not a rap:// host\n"); return; } core->num->value = 0; // that's fine if (!strlen (cmd)) { // just check if we can connect r_socket_close (rtr_host[rtr_n].fd); return; } /* send */ bufw[0] = RTR_RAP_CMD; i = strlen (cmd) + 1; r_mem_copyendian ((ut8*)bufw+1, (ut8*)&i, 4, endian); memcpy (bufw+5, cmd, i); r_socket_write (rtr_host[rtr_n].fd, bufw, 5+i); /* read */ r_socket_read (rtr_host[rtr_n].fd, (ut8*)bufr, 5); if (bufr[0] != (char)(RTR_RAP_CMD|RTR_RAP_REPLY)) { eprintf ("Error: Wrong reply\n"); return; } r_mem_copyendian ((ut8*)&cmd_len, (ut8*)bufr+1, 4, endian); cmd_output = malloc (cmd_len); if (!cmd_output) { eprintf ("Error: Allocating cmd output\n"); return; } r_socket_read (rtr_host[rtr_n].fd, (ut8*)cmd_output, cmd_len); r_cons_printf ("%s\n", cmd_output); free ((void *)cmd_output); }
R_API void r_core_rtr_cmd(RCore *core, const char *input) { char bufw[1024], bufr[8]; const char *cmd = NULL, *cmd_output = NULL; int i, cmd_len, fd = atoi (input); if (fd != 0) { if (rtr_host[rtr_n].fd) for (rtr_n = 0; rtr_host[rtr_n].fd->fd != fd && rtr_n < RTR_MAX_HOSTS; rtr_n++); if (!(cmd = strchr (input, ' '))) { eprintf ("Error\n"); return; } } else cmd = input; if (!rtr_host[rtr_n].fd){ eprintf ("Error: Unknown host\n"); return; } if (!rtr_host[rtr_n].proto == RTR_PROT_RAP){ eprintf ("Error: Not a rap:// host\n"); return; } /* send */ bufw[0] = RTR_RAP_CMD; i = strlen (cmd) + 1; r_mem_copyendian ((ut8*)bufw+1, (ut8*)&i, 4, endian); memcpy (bufw+5, cmd, i); r_socket_write (rtr_host[rtr_n].fd, bufw, 5+i); /* read */ r_socket_read (rtr_host[rtr_n].fd, (ut8*)bufr, 5); if (bufr[0] != (char)(RTR_RAP_CMD|RTR_RAP_REPLY)) { eprintf ("Error: Wrong reply\n"); return; } r_mem_copyendian ((ut8*)&cmd_len, (ut8*)bufr+1, 4, endian); if (i == 0) return; if (i < 0) { eprintf ("Error: cmd length < 0\n"); return; } cmd_output = malloc (cmd_len); if (!cmd_output) { eprintf ("Error: Allocating cmd output\n"); return; } r_socket_read (rtr_host[rtr_n].fd, (ut8*)cmd_output, cmd_len); r_cons_printf ("%s\n", cmd_output); free ((void *)cmd_output); }
static char *r_socket_http_answer (RSocket *s, int *code, int *rlen) { char *p; int i, len; char *buf = malloc (32768); // XXX: use r_buffer here /* Read Header */ i = 0; do { len = r_socket_gets (s, buf+i, sizeof (buf)-i); i += len; r_socket_gets (s, buf+i, 1); buf[i++] = '\n'; } while (len > 0); buf[i] = 0; /* Parse Code */ p = strchr (buf, ' '); if (code) *code = (p)? atoi (p+1):-1; /* Parse Len */ p = strstr (buf, "Content-Length: "); if (p) { len = atoi (p+16); if (len>0) len = r_socket_read_block (s, (ut8*)buf+i, len); else len = 0; } else { len = 32768-i; len = r_socket_read (s, (ut8*)buf+i, len); } r_socket_close (s); if (rlen) *rlen = len+i; return buf; }
// TODO: support len for binary data? R_API char *r_core_rtr_cmds_query (RCore *core, const char *host, const char *port, const char *cmd) { int retries = 6; unsigned char buf[1024]; char *rbuf = NULL; const int timeout = 0; RSocket *s = r_socket_new (0); for (;retries>0; r_sys_usleep (10*1000)) { if (r_socket_connect (s, host, port, R_SOCKET_PROTO_TCP, timeout)) break; retries--; } if (retries>0) { rbuf = strdup (""); r_socket_write (s, (void*)cmd, strlen (cmd)); //r_socket_write (s, "px\n", 3); for (;;) { int ret = r_socket_read (s, buf, sizeof (buf)); if (ret<1) break; buf[ret] = 0; rbuf = r_str_concat (rbuf, (const char *)buf); } } else { eprintf ("Cannot connect\n"); } r_socket_free (s); return rbuf; }
int read_packet(libgdbr_t *g) { struct parse_ctx ctx = {0}; int ret; if (!g) { eprintf ("Initialize libgdbr_t first\n"); return -1; } g->data_len = 0; while (r_socket_ready (g->sock, 0, READ_TIMEOUT) > 0) { int sz; sz = r_socket_read (g->sock, (void *)g->read_buff, g->read_max); if (sz <= 0) { eprintf ("%s: read failed\n", __func__); return -1; } ret = unpack (g, &ctx, sz); if (ret < 0) { eprintf ("%s: unpack failed\n", __func__); return -1; } if (!ret) { return 0; } } return -1; }
static int rap__write(RIO *io, RIODesc *fd, const ut8 *buf, int count) { RSocket *s = RIORAP_FD (fd); ut8 *tmp; int ret; if (count < 1) { return count; } // TOOD: if count > RMT_MAX iterate ! if (count > RMT_MAX) { count = RMT_MAX; } if (!(tmp = (ut8 *)malloc (count + 5))) { eprintf ("rap__write: malloc failed\n"); return -1; } tmp[0] = RMT_WRITE; r_write_be32 (tmp + 1, count); memcpy (tmp + 5, buf, count); ret = r_socket_write (s, tmp, count + 5); r_socket_flush (s); if (r_socket_read (s, tmp, 5) != 5) { // TODO read_block? eprintf ("rap__write: error\n"); ret = -1; } else { ret = r_read_be32 (tmp + 1); if (!ret) { ret = -1; } } free (tmp); return ret; }
R_API int r_socket_gets(RSocket *s, char *buf, int size) { int i = 0; int ret = 0; if (s->fd == -1) return -1; while (i<size) { ret = r_socket_read (s, (ut8 *)buf+i, 1); if (ret==0) break; if (ret<0) { r_socket_close (s); return i; } if (buf[i]=='\r'||buf[i]=='\n') { buf[i]='\0'; break; } i += ret; } buf[i]='\0'; return i; }
R_API ut8* r_socket_slurp(RSocket *s, int *len) { int blockSize = 4096; ut8 *ptr, *buf = malloc (blockSize); int copied = 0; if (len) { *len = 0; } for (;;) { int rc = r_socket_read (s, buf + copied, blockSize); if (rc > 0) { copied += rc; } ptr = realloc (buf, copied + blockSize); if (ptr) { buf = ptr; } else { break; } if (rc < 1) { break; } } if (copied == 0) { R_FREE (buf); } if (len) { *len = copied; } return buf; }
static int rap__read(struct r_io_t *io, RIODesc *fd, ut8 *buf, int count) { RSocket *s = RIORAP_FD (fd); int ret; int i = (int)count; ut8 tmp[5]; if (count>RMT_MAX) count = RMT_MAX; // send tmp[0] = RMT_READ; r_mem_copyendian (tmp+1, (ut8*)&count, 4, ENDIAN); r_socket_write (s, tmp, 5); r_socket_flush (s); // recv ret = r_socket_read (s, tmp, 5); if (ret != 5 || tmp[0] != (RMT_READ|RMT_REPLY)) { eprintf ("rap__read: Unexpected rap read reply (%d=0x%02x) expected (%d=0x%02x)\n", ret, tmp[0], 2, (RMT_READ|RMT_REPLY)); return -1; } r_mem_copyendian ((ut8*)&i, tmp+1, 4, ENDIAN); if (i>count) { eprintf ("rap__read: Unexpected data size %d\n", i); return -1; } r_socket_read_block (s, buf, i); if (count>0 && count<RMT_MAX) { //eprintf ("READ %d\n" ,i); } else count = 0; return count; }
static int rap__system(RIO *io, RIODesc *fd, const char *command) { RSocket *s = RIORAP_FD (fd); ut8 buf[RMT_MAX]; char *ptr; int op, ret, i, j = 0; // send if (*command=='!') { op = RMT_SYSTEM; command++; } else op = RMT_CMD; buf[0] = op; i = strlen (command)+1; if (i>RMT_MAX) { eprintf ("Command too long\n"); return -1; } r_mem_copyendian (buf+1, (ut8*)&i, 4, ENDIAN); memcpy (buf+5, command, i); r_socket_write (s, buf, i+5); r_socket_flush (s); // read ret = r_socket_read_block (s, buf, 5); if (ret != 5) return -1; if (buf[0] != (op | RMT_REPLY)) { eprintf ("Unexpected system reply\n"); return -1; } r_mem_copyendian ((ut8*)&i, buf+1, 4, ENDIAN); if (i == -1) return -1; ret = 0; ptr = (char *)malloc (i); if (ptr) { int ir, tr = 0; do { ir = r_socket_read_block (s, (ut8*)ptr+tr, i-tr); if (ir>0) tr += ir; else break; } while (tr<i); // TODO: use io->printf() with support for \x00 ptr[i] = 0; if (io->printf) { io->printf ("%s", ptr); j = i; } else j = write (1, ptr, i); free (ptr); } /* Clean */ if (ret > 0) { ret -= r_socket_read (s, (ut8*)buf, RMT_MAX); } return i-j; }
R_API int r_socket_read_block(RSocket *s, unsigned char *buf, int len) { int r, ret = 0; for (ret=0;ret<len;) { r = r_socket_read (s, buf+ret, len-ret); if (r==-1) break; ret += r; } return ret; }
static int rap__system(RIO *io, RIODesc *fd, const char *command) { RSocket *s = RIORAP_FD (fd); ut8 buf[RMT_MAX]; char *ptr; int op, ret, i, j = 0; // send if (*command=='!') { op = RMT_SYSTEM; command++; } else op = RMT_CMD; buf[0] = op; i = strlen (command); if (i>RMT_MAX) { eprintf ("Command too long\n"); return -1; } r_mem_copyendian (buf+1, (ut8*)&i, 4, ENDIAN); memcpy (buf+5, command, i); r_socket_write (s, buf, i+5); r_socket_flush (s); // read ret = r_socket_read_block (s, buf, 5); if (ret != 5) return -1; if (buf[0] != (op | RMT_REPLY)) { eprintf ("Unexpected system reply\n"); return -1; } r_mem_copyendian ((ut8*)&i, buf+1, 4, ENDIAN); if (i == -1) return -1; ret = 0; if (i>RMT_MAX) { ret = i-RMT_MAX; i = RMT_MAX; } ptr = (char *)malloc (i); if (ptr) { r_socket_read_block (s, (ut8*)ptr, i); j = write (1, ptr, i); free (ptr); } /* Clean */ if (ret > 0) { ret -= r_socket_read (s, (ut8*)buf, RMT_MAX); } return i-j; }
static void haret_wait_until_prompt(RSocket *s) { unsigned char buf; int off = 0; for (;;) { if (r_socket_read (s, &buf, 1) != 1) { eprintf ("haret_wait_until_prompt: Unexpected eof in socket\n"); return; } switch (off) { case 0: if (buf == ')') off = 1; break; case 1: if (buf == '#') return; off = 0; break; } } }
R_API int r_core_rtr_cmds (RCore *core, const char *port) { unsigned char buf[4097]; RSocket *ch, *s; int i, ret; char *str; if (!port || port[0]=='?') { r_cons_printf ("Usage: .:[tcp-port] run r2 commands for clients\n"); return R_FALSE; } s = r_socket_new (0); if (!r_socket_listen (s, port, NULL)) { eprintf ("Error listening on port %s\n", port); r_socket_free (s); return R_FALSE; } eprintf ("Listening for commands on port %s\n", port); listenport = port; for (;;) { r_cons_break ((RConsBreak)http_break, core); ch = r_socket_accept (s); buf[0] = 0; ret = r_socket_read (ch, buf, sizeof (buf) - 1); if (ret>0) { buf[ret] = 0; for (i=0; buf[i]; i++) if (buf[i] == '\n') buf[i] = buf[i+1]? ';': '\0'; if (!r_config_get_i (core->config, "scr.prompt") \ && !strcmp ((char*)buf, "q!")) break; str = r_core_cmd_str (core, (const char *)buf); if (str &&*str) { r_socket_write (ch, str, strlen (str)); } else r_socket_write (ch, "\n", 1); free (str); } if (r_cons_singleton()->breaked) break; r_socket_close (ch); r_cons_break_end (); } r_socket_free(s); r_socket_free(ch); return 0; }
int main (int argc, char ** argv) { ut8 buf [MAX_LINE+1]; memset (buf, 0, MAX_LINE+1); RSocket *s = r_socket_new (true); if (s == NULL) { fprintf (stderr, "Error, cannot create new socket \n"); return 1; } if (!r_socket_connect_tcp (s, SERVER, PORT)) { fprintf (stderr, "Error, cannot connect to "SERVER"\n"); return 1; } printf ("%i\n",r_socket_puts (s, "GET /\r\n\r\n")); while(r_socket_read (s, buf, MAX_LINE)>0) printf ("%s", buf); r_socket_free (s); return 0; }
static char *runcmd (const char *cmd) { char buf[4096] = {0}; if (cmd) { r_socket_printf (gs, "%s\n", cmd); } int timeout = 1000000; char * str = NULL; r_socket_block_time (gs, 1, timeout); while (true) { memset (buf, 0, sizeof (buf)); r_socket_read (gs, (ut8*)buf, sizeof (buf) - 1); // NULL-terminate the string always char *promptFound = strstr (buf, "Wine-dbg>"); if (promptFound) { *promptFound = 0; return r_str_append (str, buf); } str = r_str_append (str, buf); } return NULL; }
static int rap__write(struct r_io_t *io, RIODesc *fd, const ut8 *buf, int count) { RSocket *s = RIORAP_FD (fd); int ret; ut8 *tmp; if (count>RMT_MAX) count = RMT_MAX; if (!(tmp = (ut8 *)malloc (count+5))) { eprintf ("rap__write: malloc failed\n"); return -1; } tmp[0] = RMT_WRITE; r_mem_copyendian ((ut8 *)tmp+1, (ut8*)&count, 4, ENDIAN); memcpy (tmp+5, buf, count); ret = r_socket_write (s, tmp, count+5); r_socket_flush (s); if (r_socket_read (s, tmp, 5) != 5) { // TODO read_block? eprintf ("rap__write: error\n"); ret = -1; } free (tmp); // TODO: get reply return ret; }
R_API int r_socket_proc_read (RSocketProc *sp, unsigned char *buf, int len) { RSocket s; s.is_ssl = false; s.fd = sp->fd1[0]; return r_socket_read (&s, buf, len); }
static int rap__system(RIO *io, RIODesc *fd, const char *command) { RSocket *s = RIORAP_FD (fd); ut8 buf[RMT_MAX]; char *ptr; int op, ret; unsigned int i, j = 0; // send if (*command=='!') { op = RMT_SYSTEM; command++; } else { op = RMT_CMD; } buf[0] = op; i = strlen (command)+1; if (i>RMT_MAX-5) { eprintf ("Command too long\n"); return -1; } r_mem_copyendian (buf+1, (ut8*)&i, 4, ENDIAN); memcpy (buf+5, command, i); r_socket_write (s, buf, i+5); r_socket_flush (s); /* read reverse cmds */ for (;;) { ret = r_socket_read_block (s, buf, 1); if (ret != 1) { return -1; } /* system back in the middle */ /* TODO: all pkt handlers should check for reverse queries */ if (buf[0] == RMT_SYSTEM || buf[0] == RMT_CMD) { char *res, *str; ut32 reslen = 0, cmdlen = 0; // run io->cmdstr // return back the string buf[0] |= RMT_REPLY; ret = r_socket_read_block (s, buf+1, 4); r_mem_copyendian ((ut8*)&cmdlen, buf+1, 4, ENDIAN); if (cmdlen+1==0) // check overflow cmdlen = 0; str = calloc (1, cmdlen+1); ret = r_socket_read_block (s, (ut8*)str, cmdlen); //eprintf ("RUN CMD(%s)\n", str); res = io->cb_core_cmdstr (io->user, str); eprintf ("[%s]=>(%s)\n", str, res); reslen = strlen (res); free (str); r_mem_copyendian ((ut8*)buf+1, (const ut8*)&reslen, sizeof(ut32), ENDIAN); memcpy (buf+5, res, reslen); free (res); r_socket_write (s, buf, 5+reslen); r_socket_flush (s); } else { break; } } // read ret = r_socket_read_block (s, buf+1, 4); if (ret != 4) return -1; if (buf[0] != (op | RMT_REPLY)) { eprintf ("Unexpected system reply\n"); return -1; } r_mem_copyendian ((ut8*)&i, buf+1, 4, ENDIAN); ret = 0; if (i>0xffffffff) { eprintf ("Invalid length\n"); return -1; } ptr = (char *)malloc (i+1); if (ptr) { int ir; unsigned int tr = 0; do { ir = r_socket_read_block (s, (ut8*)ptr+tr, i-tr); if (ir>0) tr += ir; else break; } while (tr<i); // TODO: use io->cb_printf() with support for \x00 ptr[i] = 0; if (io->cb_printf) { io->cb_printf ("%s", ptr); j = i; } else j = write (1, ptr, i); free (ptr); } /* Clean */ if (ret > 0) { ret -= r_socket_read (s, (ut8*)buf, RMT_MAX); } return i-j; }
static RIODesc *rap__open(RIO *io, const char *pathname, int rw, int mode) { int i, p, listenmode; char *file, *port; const char *ptr; RSocket *rap_fd; char buf[1024]; RIORap *rior; if (!rap__plugin_open (io, pathname, 0)) { return NULL; } bool is_ssl = (!strncmp (pathname, "raps://", 7)); ptr = pathname + (is_ssl? 7: 6); if (!(port = strchr (ptr, ':'))) { eprintf ("rap: wrong uri\n"); return NULL; } listenmode = (*ptr == ':'); *port++ = 0; if (!*port) { return NULL; } p = atoi (port); if ((file = strchr (port + 1, '/'))) { *file = 0; file++; } if (r_sandbox_enable (0)) { eprintf ("sandbox: Cannot use network\n"); return NULL; } if (listenmode) { if (p <= 0) { eprintf ("rap: cannot listen here. Try rap://:9999\n"); return NULL; } //TODO: Handle ^C signal (SIGINT, exit); // ??? eprintf ("rap: listening at port %s ssl %s\n", port, (is_ssl)?"on":"off"); rior = R_NEW0 (RIORap); rior->listener = true; rior->client = rior->fd = r_socket_new (is_ssl); if (!rior->fd) { free (rior); return NULL; } if (is_ssl) { if (file && *file) { if (!r_socket_listen (rior->fd, port, file)) { free (rior); return NULL; } } else { free (rior); return NULL; } } else { if (!r_socket_listen (rior->fd, port, NULL)) { return NULL; } } return r_io_desc_new (&r_io_plugin_rap, rior->fd->fd, pathname, rw, mode, rior); } if (!(rap_fd = r_socket_new (is_ssl))) { eprintf ("Cannot create new socket\n"); return NULL; } if (r_socket_connect_tcp (rap_fd, ptr, port, 30) == false) { eprintf ("Cannot connect to '%s' (%d)\n", ptr, p); r_socket_free (rap_fd); return NULL; } eprintf ("Connected to: %s at port %s\n", ptr, port); rior = R_NEW0 (RIORap); rior->listener = false; rior->client = rior->fd = rap_fd; if (file && *file) { // send buf[0] = RMT_OPEN; buf[1] = rw; buf[2] = (ut8)strlen (file); memcpy (buf + 3, file, buf[2]); r_socket_write (rap_fd, buf, buf[2] + 3); r_socket_flush (rap_fd); // read eprintf ("waiting... "); buf[0] = 0; r_socket_read_block (rap_fd, (ut8*)buf, 5); if (buf[0] != (char)(RMT_OPEN | RMT_REPLY)) { eprintf ("rap: Expecting OPEN|REPLY packet. got %02x\n", buf[0]); r_socket_free (rap_fd); free (rior); return NULL; } i = r_read_at_be32 (buf, 1); if (i > 0) { eprintf ("ok\n"); } #if 0 /* Read meta info */ r_socket_read (rap_fd, (ut8 *)&buf, 4); r_mem_copyendian ((ut8 *)&i, (ut8*)buf, 4, ENDIAN); while (i>0) { int n = r_socket_read (rap_fd, (ut8 *)&buf, i); if (n<1) break; buf[i] = 0; io->core_cmd_cb (io->user, buf); n = r_socket_read (rap_fd, (ut8 *)&buf, 4); if (n<1) break; r_mem_copyendian ((ut8 *)&i, (ut8*)buf, 4, ENDIAN); i -= n; } #endif } else { // r_socket_free (rap_fd); // free (rior); //return NULL; } //r_socket_free (rap_fd); return r_io_desc_new (&r_io_plugin_rap, rior->fd->fd, pathname, rw, mode, rior); }
R_API void r_core_rtr_add(RCore *core, const char *_input) { char *port, input[1024], *host = NULL, *file = NULL, *ptr = NULL, buf[1024]; int proto, i; RSocket *fd; strncpy (input, _input, sizeof (input)-4); /* Parse uri */ if ((ptr = strstr(input, "tcp://"))) { proto = RTR_PROT_TCP; host = ptr+6; } else if ((ptr = strstr(input, "udp://"))) { proto = RTR_PROT_UDP; host = ptr+6; } else if ((ptr = strstr(input, "rap://"))) { proto = RTR_PROT_RAP; host = ptr+6; } else { proto = RTR_PROT_RAP; host = input; } while (*host&&iswhitechar(*host)) host++; if (!(ptr = strchr (host, ':'))) { eprintf ("Error: Port is not specified\n"); return; } ptr[0] = '\0'; ptr = ptr+1; if (!(file = strchr (ptr, '/'))) { eprintf("Error: Missing '/'\n"); return; } file[0] = '\0'; file = file+1; port = ptr; fd = r_socket_new (R_FALSE); if (!fd) { eprintf ("Error: Cannot create new socket\n"); return; } switch (proto) { case RTR_PROT_RAP: if (!r_socket_connect_tcp (fd, host, port)) { //TODO: Use rap.ssl eprintf ("Error: Cannot connect to '%s' (%s)\n", host, port); return; } eprintf ("Connected to: %s at port %s\n", host, port); /* send */ buf[0] = RTR_RAP_OPEN; buf[1] = 0; buf[2] = (ut8)(strlen (file)+1); memcpy (buf+3, file, buf[2]); r_socket_write(fd, buf, 3+buf[2]); /* read */ eprintf ("waiting... "); fflush(stdout); r_socket_read (fd, (ut8*)buf, 5); r_mem_copyendian ((ut8 *)&i, (ut8*)buf+1, 4, core->assembler->big_endian); if (buf[0] != (char)(RTR_RAP_OPEN|RTR_RAP_REPLY) || i<= 0) { eprintf ("Error: Wrong reply\n"); return; } eprintf ("ok\n"); break; case RTR_PROT_TCP: if (!r_socket_connect_tcp (fd, host, port)) { //TODO: Use rap.ssl eprintf("Error: Cannot connect to '%s' (%s)\n", host, port); return; } eprintf ("Connected to: %s at port %s\n", host, port); break; case RTR_PROT_UDP: if (!r_socket_connect_udp(fd, host, port)) { //TODO: Use rap.ssl eprintf("Error: Cannot connect to '%s' (%s)\n", host, port); return; } eprintf("Connected to: %s at port %s\n", host, port); break; } for (i = 0; i < RTR_MAX_HOSTS; i++) if (!rtr_host[i].fd) { rtr_host[i].proto = proto; memcpy (rtr_host[i].host, host, 512); rtr_host[i].port = atoi(port); memcpy (rtr_host[i].file, file, 1024); rtr_host[i].fd = fd; rtr_n = i; break; } r_core_rtr_list (core); }
static int rap__system(RIO *io, RIODesc *fd, const char *command) { int ret, reslen = 0, cmdlen = 0; RSocket *s = RIORAP_FD (fd); unsigned int i, j = 0; char *ptr, *res, *str; ut8 buf[RMT_MAX]; buf[0] = RMT_CMD; i = strlen (command) + 1; if (i > RMT_MAX - 5) { eprintf ("Command too long\n"); return -1; } r_write_be32 (buf + 1, i); memcpy (buf + 5, command, i); r_socket_write (s, buf, i+5); r_socket_flush (s); /* read reverse cmds */ for (;;) { ret = r_socket_read_block (s, buf, 1); if (ret != 1) { return -1; } /* system back in the middle */ /* TODO: all pkt handlers should check for reverse queries */ if (buf[0] != RMT_CMD) { break; } // run io->cmdstr // return back the string buf[0] |= RMT_REPLY; memset (buf + 1, 0, 4); ret = r_socket_read_block (s, buf + 1, 4); cmdlen = r_read_at_be32 (buf, 1); if (cmdlen + 1 == 0) // check overflow cmdlen = 0; str = calloc (1, cmdlen + 1); ret = r_socket_read_block (s, (ut8*)str, cmdlen); eprintf ("RUN %d CMD(%s)\n", ret, str); if (str && *str) { res = io->cb_core_cmdstr (io->user, str); } else { res = strdup (""); } eprintf ("[%s]=>(%s)\n", str, res); reslen = strlen (res); free (str); r_write_be32 (buf + 1, reslen); memcpy (buf + 5, res, reslen); free (res); r_socket_write (s, buf, reslen + 5); r_socket_flush (s); } // read ret = r_socket_read_block (s, buf + 1, 4); if (ret != 4) { return -1; } if (buf[0] != (RMT_CMD | RMT_REPLY)) { eprintf ("Unexpected rap cmd reply\n"); return -1; } i = r_read_at_be32 (buf, 1); ret = 0; if (i > ST32_MAX) { eprintf ("Invalid length\n"); return -1; } ptr = (char *)calloc (1, i + 1); if (ptr) { int ir, tr = 0; do { ir = r_socket_read_block (s, (ut8*)ptr + tr, i - tr); if (ir < 1) break; tr += ir; } while (tr < i); // TODO: use io->cb_printf() with support for \x00 ptr[i] = 0; if (io->cb_printf) { io->cb_printf ("%s", ptr); j = i; } else { j = write (1, ptr, i); } free (ptr); } #if DEAD_CODE /* Clean */ if (ret > 0) { ret -= r_socket_read (s, (ut8*)buf, RMT_MAX); } #endif return i - j; }
R_API void r_core_rtr_add(RCore *core, const char *_input) { char *port, input[1024], *host = NULL, *file = NULL, *ptr = NULL, buf[1024]; int proto, i, timeout, ret; RSocket *fd; timeout = r_config_get_i (core->config, "http.timeout"); strncpy (input, _input, sizeof (input)-4); /* Parse uri */ if ((ptr = strstr (input, "tcp://"))) { proto = RTR_PROT_TCP; host = ptr+6; } else if ((ptr = strstr(input, "http://"))) { proto = RTR_PROT_HTTP; host = ptr+7; } else if ((ptr = strstr(input, "udp://"))) { proto = RTR_PROT_UDP; host = ptr+6; } else if ((ptr = strstr(input, "rap://"))) { proto = RTR_PROT_RAP; host = ptr+6; } else { proto = RTR_PROT_RAP; host = input; } while (*host && iswhitechar (*host)) host++; if (!(ptr = strchr (host, ':'))) { ptr = host; port = "80"; } else { *ptr++ = '\0'; port = ptr; } if (!(file = strchr (ptr, '/'))) { eprintf("Error: Missing '/'\n"); return; } *file++ = 0; port = r_str_chop (port); while (*file==' ') file++; if (r_sandbox_enable (0)) { eprintf ("sandbox: connect disabled\n"); return; } fd = r_socket_new (R_FALSE); if (!fd) { eprintf ("Error: Cannot create new socket\n"); return; } switch (proto) { case RTR_PROT_HTTP: { char uri[1024], prompt[64]; int len; char *str, *res; if (file[strlen (file)-1]=='/') { snprintf (prompt, sizeof (prompt), "[http://%s:%s/%s]> ", host, port, file); r_line_set_prompt (prompt); for (;;) { char *ptr, *str = r_line_readline (); if (!str || !*str) break; if (*str == 'q') break; ptr = r_str_uri_encode (str); if (ptr) str = ptr; snprintf (uri, sizeof (uri), "http://%s:%s/%s%s", host, port, file, str); if (ptr == str) free (ptr); str = r_socket_http_get (uri, NULL, &len); if (str) { str[len] = 0; res = strstr (str, "\n\n"); if (res) res = strstr (res+1, "\n\n"); if (res) res += 2; else res = str; printf ("%s%s", res, (res[strlen (res)-1]=='\n')?"":"\n"); r_line_hist_add (str); free (str); } } r_socket_free (fd); return; } snprintf (uri, sizeof (uri), "http://%s:%s/%s", host, port, file); str = r_socket_http_get (uri, NULL, &len); if (str) { str[len] = 0; res = strstr (str, "\n\n"); if (res) res = strstr (res+1, "\n\n"); if (res) res += 2; else res = str; printf ("%s", res); free (str); } else eprintf ("HTTP connection has failed\n"); // do not add connection. wtf return; } break; case RTR_PROT_RAP: if (!r_socket_connect_tcp (fd, host, port, timeout)) { //TODO: Use rap.ssl eprintf ("Error: Cannot connect to '%s' (%s)\n", host, port); return; } eprintf ("Connected to %s at port %s\n", host, port); /* send */ buf[0] = RTR_RAP_OPEN; buf[1] = 0; buf[2] = (ut8)(strlen (file)+1); memcpy (buf+3, file, buf[2]); r_socket_write(fd, buf, 3+buf[2]); /* read */ eprintf ("waiting... "); fflush(stdout); r_socket_read (fd, (ut8*)buf, 5); r_mem_copyendian ((ut8 *)&i, (ut8*)buf+1, 4, core->assembler->big_endian); if (buf[0] != (char)(RTR_RAP_OPEN|RTR_RAP_REPLY) || i<= 0) { eprintf ("Error: Wrong reply\n"); return; } eprintf ("ok\n"); break; case RTR_PROT_TCP: if (!r_socket_connect_tcp (fd, host, port, timeout)) { //TODO: Use rap.ssl core->num->value = 1; eprintf("Error: Cannot connect to '%s' (%s)\n", host, port); return; } core->num->value = 0; eprintf ("Connected to: %s at port %s\n", host, port); break; case RTR_PROT_UDP: if (!r_socket_connect_udp (fd, host, port, timeout)) { //TODO: Use rap.ssl core->num->value = 1; eprintf ("Error: Cannot connect to '%s' (%s)\n", host, port); return; } core->num->value = 0; eprintf("Connected to: %s at port %s\n", host, port); break; } ret = core->num->value; for (i = 0; i < RTR_MAX_HOSTS; i++) if (!rtr_host[i].fd) { rtr_host[i].proto = proto; memcpy (rtr_host[i].host, host, 512); rtr_host[i].port = r_num_get (core->num, port); memcpy (rtr_host[i].file, file, 1024); rtr_host[i].fd = fd; rtr_n = i; break; } core->num->value = ret; r_socket_free(fd); //r_core_rtr_list (core); }