static int rap__close(RIODesc *fd) { int ret = -1; if (RIORAP_IS_VALID (fd)) { if (RIORAP_FD (fd) != NULL) { RIORap *r = fd->data; ret = r_socket_close (r->fd); ret = r_socket_close (r->client); //ret = r_socket_close (r->client); free (fd->data); fd->data = NULL; } } else eprintf ("rap__close: fdesc is not a r_io_rap plugin\n"); 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; }
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; }
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 int r_socket_free (RSocket *s) { int res = r_socket_close (s); #if HAVE_LIB_SSL if (s->is_ssl) { if (s->sfd) SSL_free (s->sfd); if (s->ctx) SSL_CTX_free (s->ctx); } #endif free (s); return res; }
int gdbr_disconnect(libgdbr_t *g) { // TODO Disconnect maybe send something to gdbserver if (!g || !r_socket_close (g->sock)) { return -1; } reg_cache.valid = false; free (reg_cache.buf); if (g->target.valid) { free (g->target.regprofile); } g->connected = 0; return 0; }
static char *r_socket_http_answer (RSocket *s, int *code, int *rlen) { const char *p; int ret, olen, len = 0, bufsz = 32768, delta = 0; char *dn, *res, *buf = malloc (bufsz + 32); // XXX: use r_buffer here if (!buf) return NULL; r_socket_block_time (s, 1, 5); res = NULL; olen = r_socket_read_block (s, (unsigned char*) buf, bufsz); if (olen < 1) goto fail; buf[olen] = 0; if ((dn = (char*)r_str_casestr (buf, "\n\n"))) { delta += 2; } else if ((dn = (char*)r_str_casestr (buf, "\r\n\r\n"))) { delta += 4; } else goto fail; olen -= delta; *dn = 0; // chop headers /* Parse Len */ p = r_str_casestr (buf, "Content-Length: "); if (p) len = atoi (p+16); else len = olen - (dn - buf); if (len >0) { if (len > olen) { res = malloc (len+2); memcpy (res, dn+delta, olen); do { ret = r_socket_read_block (s, (ut8*) res+olen, len-olen); if (ret < 1) break; olen += ret; } while (olen<len); res[len] = 0; } else { res = malloc (len+1); if (res) { memcpy (res, dn+delta, len); res[len] = 0; } } } else res = NULL; fail: free (buf); // is 's' free'd? isnt this going to cause a double free? r_socket_close (s); if (rlen) *rlen = len; return res; }
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; }
R_API bool r_socket_spawn(RSocket *s, const char *cmd, unsigned int timeout) { // XXX TODO: dont use sockets, we can achieve the same with pipes const int port = 2000 + r_num_rand (2000); int childPid = r_sys_fork (); if (childPid == 0) { char *a = r_str_replace (strdup (cmd), "\\", "\\\\", true); int res = r_sys_cmdf ("rarun2 system=\"%s\" listen=%d", a, port); free (a); #if 0 // TODO: use the api char *profile = r_str_newf ( "system=%s\n" "listen=%d\n", cmd, port); RRunProfile *rp = r_run_new (profile); r_run_start (rp); r_run_free (rp); free (profile); #endif if (res != 0) { eprintf ("r_socket_spawn: rarun2 failed\n"); exit (1); } eprintf ("r_socket_spawn: %s is dead\n", cmd); exit (0); } r_sys_sleep (1); r_sys_usleep (timeout); char aport[32]; sprintf (aport, "%d", port); // redirect stdin/stdout/stderr bool sock = r_socket_connect (s, "127.0.0.1", aport, R_SOCKET_PROTO_TCP, 2000); if (!sock) { return false; } #if __UNIX__ r_sys_sleep (4); r_sys_usleep (timeout); int status = 0; int ret = waitpid (childPid, &status, WNOHANG); if (ret != 0) { r_socket_close (s); return false; } #endif return true; }
R_API int r_socket_rap_server_continue (RSocketRapServer *rap_s) { int endian, i, pipe_fd, ret; ut64 offset; char *ptr = NULL; if ( !rap_s || !rap_s->fd || !r_socket_is_connected (rap_s->fd)) return R_FALSE; r_socket_read_block (rap_s->fd, rap_s->buf, 1); endian = getEndian(); ret = rap_s->buf[0]; switch (rap_s->buf[0]) { case RAP_RMT_OPEN: r_socket_read_block (rap_s->fd, &rap_s->buf[1], 2); r_socket_read_block (rap_s->fd, &rap_s->buf[3], (int)rap_s->buf[2]); rap_s->open (rap_s->user, (const char *)&rap_s->buf[3], (int)rap_s->buf[1], 0); rap_s->buf[0] = RAP_RMT_OPEN | RAP_RMT_REPLY; r_socket_write (rap_s->fd, rap_s->buf, 5); r_socket_flush (rap_s->fd); break; case RAP_RMT_READ: r_socket_read_block (rap_s->fd, &rap_s->buf[1], 4); r_mem_copyendian ((ut8*)&i, &rap_s->buf[1], 4, !endian); if (i > RAP_RMT_MAX || i < 0) i = RAP_RMT_MAX; rap_s->read (rap_s->user, &rap_s->buf[5], i); rap_s->buf[0] = RAP_RMT_READ | RAP_RMT_REPLY; r_socket_write (rap_s->fd, rap_s->buf, i + 5); r_socket_flush (rap_s->fd); break; case RAP_RMT_WRITE: r_socket_read_block (rap_s->fd, &rap_s->buf[1], 4); r_mem_copyendian ((ut8*)&i, &rap_s->buf[1], 4, !endian); if (i > RAP_RMT_MAX || i < 0) i = RAP_RMT_MAX; r_socket_read_block (rap_s->fd, &rap_s->buf[5], i); rap_s->write(rap_s->user, &rap_s->buf[5], i); rap_s->buf[0] = RAP_RMT_WRITE | RAP_RMT_REPLY; r_socket_write (rap_s->fd, rap_s->buf, 1); r_socket_flush (rap_s->fd); break; case RAP_RMT_SEEK: r_socket_read_block (rap_s->fd, &rap_s->buf[1], 9); i = rap_s->buf[1]; r_mem_copyendian ((ut8*)&offset, &rap_s->buf[2], 8, !endian); rap_s->seek (rap_s->user, offset, i); rap_s->buf[0] = RAP_RMT_WRITE | RAP_RMT_REPLY; r_socket_write (rap_s->fd, rap_s->buf, 1); r_socket_flush (rap_s->fd); break; case RAP_RMT_SYSTEM: r_socket_read_block (rap_s->fd, &rap_s->buf[1], 4); r_mem_copyendian ((ut8 *)&i, &rap_s->buf[1], 4, !endian); r_socket_read_block (rap_s->fd, &rap_s->buf[5], i); ptr = rap_s->system (rap_s->user, &rap_s->buf[5]); if (ptr) i = strlen (ptr) + 1; else i = 0; r_mem_copyendian (&rap_s->buf[1], (ut8 *)&i, 4, !endian); rap_s->buf[0] = RAP_RMT_SYSTEM | RAP_RMT_REPLY; r_socket_write (rap_s->fd, rap_s->buf, 5); if (i) r_socket_write (rap_s->fd, ptr, i); r_socket_flush (rap_s->fd); free (ptr); ptr = NULL; break; case RAP_RMT_CMD: r_socket_read_block (rap_s->fd, &rap_s->buf[1], 4); r_mem_copyendian ((ut8 *)&i, &rap_s->buf[1], 4, !endian); r_socket_read_block (rap_s->fd, &rap_s->buf[5], i); ptr = rap_s->cmd (rap_s->user, &rap_s->buf[5]); if (ptr) i = strlen (ptr) + 1; else i = 0; r_mem_copyendian (&rap_s->buf[1], (ut8 *)&i, 4, !endian); rap_s->buf[0] = RAP_RMT_CMD | RAP_RMT_REPLY; r_socket_write (rap_s->fd, rap_s->buf, 5); if (i) r_socket_write (rap_s->fd, ptr, i); r_socket_flush (rap_s->fd); free (ptr); ptr = NULL; break; case RAP_RMT_CLOSE: r_socket_read_block (rap_s->fd, &rap_s->buf[1], 4); r_mem_copyendian ((ut8 *)&i, &rap_s->buf[1], 4, !endian); rap_s->close (rap_s->user, i); rap_s->buf[0] = RAP_RMT_CLOSE | RAP_RMT_REPLY; r_socket_write (rap_s->fd, rap_s->buf, 5); r_socket_flush (rap_s->fd); break; default: eprintf ("unknown command 0x%02hhx\n", rap_s->buf[0]); r_socket_close (rap_s->fd); ret = -1; break; } return ret; }
static int haret__close(RIODesc *fd) { if (!fd || HARET_FD (fd)->fd==-1) return -1; return r_socket_close (HARET_FD (fd)); }
int gdbr_disconnect(libgdbr_t* g) { // TODO Disconnect maybe send something to gdbserver if (!r_socket_close (g->sock)) return -1; g->connected = 0; return 0; }
R_API bool r_socket_rap_server_continue (RSocketRapServer *rap_s) { int i, whence, ret = true; ut64 offset; char *ptr = NULL; if (!rap_s || !rap_s->fd) return false; if (!r_socket_is_connected (rap_s->fd)) return false; r_socket_read_block (rap_s->fd, rap_s->buf, 1); ret = rap_s->buf[0]; switch (ret) { case RAP_RMT_OPEN: r_socket_read_block (rap_s->fd, &rap_s->buf[1], 2); r_socket_read_block (rap_s->fd, &rap_s->buf[3], (int)rap_s->buf[2]); rap_s->open (rap_s->user, (const char *)&rap_s->buf[3], (int)rap_s->buf[1], 0); rap_s->buf[0] = RAP_RMT_OPEN | RAP_RMT_REPLY; r_socket_write (rap_s->fd, rap_s->buf, 5); r_socket_flush (rap_s->fd); break; case RAP_RMT_READ: r_socket_read_block (rap_s->fd, &rap_s->buf[1], 4); i = r_read_be32 (&rap_s->buf[1]); if (i > RAP_RMT_MAX || i < 0) i = RAP_RMT_MAX; rap_s->read (rap_s->user, &rap_s->buf[5], i); rap_s->buf[0] = RAP_RMT_READ | RAP_RMT_REPLY; r_socket_write (rap_s->fd, rap_s->buf, i + 5); r_socket_flush (rap_s->fd); break; case RAP_RMT_WRITE: r_socket_read_block (rap_s->fd, rap_s->buf + 1, 4); i = r_read_be32 (rap_s->buf + 1); if (i > RAP_RMT_MAX || i < 0) { i = RAP_RMT_MAX; } r_socket_read_block (rap_s->fd, rap_s->buf + 5, i); int ret = rap_s->write (rap_s->user, rap_s->buf + 5, i); r_write_be32 (rap_s->buf + 1, ret); rap_s->buf[0] = RAP_RMT_WRITE | RAP_RMT_REPLY; r_socket_write (rap_s->fd, rap_s->buf, 5); r_socket_flush (rap_s->fd); break; case RAP_RMT_SEEK: r_socket_read_block (rap_s->fd, &rap_s->buf[1], 9); whence = rap_s->buf[1]; offset = r_read_be64 (rap_s->buf + 2); offset = rap_s->seek (rap_s->user, offset, whence); /* prepare reply */ rap_s->buf[0] = RAP_RMT_SEEK | RAP_RMT_REPLY; r_write_be64 (rap_s->buf + 1, offset); r_socket_write (rap_s->fd, rap_s->buf, 9); r_socket_flush (rap_s->fd); break; case RAP_RMT_CMD: r_socket_read_block (rap_s->fd, &rap_s->buf[1], 4); i = r_read_be32 (&rap_s->buf[1]); r_socket_read_block (rap_s->fd, &rap_s->buf[5], i); ptr = rap_s->cmd (rap_s->user, (const char *)&rap_s->buf[5]); i = (ptr)? strlen (ptr) + 1: 0; r_write_be32 (&rap_s->buf[1], i); rap_s->buf[0] = RAP_RMT_CMD | RAP_RMT_REPLY; r_socket_write (rap_s->fd, rap_s->buf, 5); if (i) r_socket_write (rap_s->fd, ptr, i); r_socket_flush (rap_s->fd); free (ptr); ptr = NULL; break; case RAP_RMT_CLOSE: r_socket_read_block (rap_s->fd, &rap_s->buf[1], 4); i = r_read_be32 (&rap_s->buf[1]); rap_s->close (rap_s->user, i); rap_s->buf[0] = RAP_RMT_CLOSE | RAP_RMT_REPLY; r_socket_write (rap_s->fd, rap_s->buf, 5); r_socket_flush (rap_s->fd); break; default: eprintf ("unknown command 0x%02x\n", \ (unsigned int)(unsigned char)rap_s->buf[0]); r_socket_close (rap_s->fd); ret = false; break; } return ret; }