int main() { RSocket *s = r_socket_new (R_FALSE); if (!r_socket_listen (s, "8080", NULL)) { eprintf ("Cannot listen here\n"); return 1; } for (;;) { RSocketHTTPRequest *rs = r_socket_http_accept (s, 0); if (!rs) continue; if (!strcmp (rs->method, "GET")) { r_socket_http_response (rs, 200, "<html><body><form method=post action=/>" "<input name=a /><input type=button></form></body>"); } else if (!strcmp (rs->method, "POST")) { char *buf = malloc (rs->data_length+ 50); strcpy (buf, "<html><body><h2>XSS test</h2>\n"); r_str_unescape (rs->data); strcat (buf, rs->data); r_socket_http_response (rs, 200, buf); free (buf); } else { r_socket_http_response (rs, 404, "Invalid protocol"); } r_socket_http_close (rs); } }
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; }
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); }
static int runfile () { if (!_program && !_system) { printf ("No program or system rule defined\n"); return 1; } if (_stdin) { int f = open (_stdin, O_RDONLY); close (0); dup2 (f, 0); } if (_stdout) { int f = open (_stdout, O_WRONLY); close (1); dup2 (f, 1); } if (_stderr) { int f = open (_stderr, O_WRONLY); close (2); dup2 (f, 2); } if (_connect) { char *p = strchr (_connect, ':'); if (p) { RSocket *fd = r_socket_new (0); *p=0; if (!r_socket_connect_tcp (fd, _connect, p+1, 30)) { eprintf ("Cannot connect\n"); return 1; } eprintf ("connected\n"); close (0); close (1); close (2); dup2 (fd->fd, 0); dup2 (fd->fd, 1); dup2 (fd->fd, 2); } else { eprintf ("Invalid format for connect. missing ':'\n"); return 1; } } if (_listen) { RSocket *child, *fd = r_socket_new (0); if (!r_socket_listen (fd, _listen, NULL)) { eprintf ("rarun2: cannot listen\n"); return 1; } child = r_socket_accept (fd); if (child) { eprintf ("connected\n"); close (0); close (1); close (2); dup2 (child->fd, 0); dup2 (child->fd, 1); dup2 (child->fd, 2); } } if (_chgdir) chdir (_chgdir); if (_chroot) chdir (_chroot); #if __UNIX__ if (_chroot) { if (chroot (".")) { eprintf ("rarun2: cannot chroot\n"); return 1; } } if (_setuid) setuid (atoi (_setuid)); if (_seteuid) seteuid (atoi (_seteuid)); if (_setgid) setgid (atoi (_setgid)); if (_input) { int f2[2]; pipe (f2); close (0); dup2 (f2[0], 0); parseinput (_input); write (f2[1], _input, strlen (_input)); } #endif if (_r2preload) { if (_preload) { eprintf ("WARNING: Only one library can be opened at a time\n"); } _preload = R2_LIBDIR"/libr2."R_LIB_EXT; } if (_libpath) { #if __WINDOWS__ eprintf ("rarun2: libpath unsupported for this platform\n"); #elif __APPLE__ r_sys_setenv ("DYLD_LIBRARY_PATH", _libpath); #else r_sys_setenv ("LD_LIBRARY_PATH", _libpath); #endif } if (_preload) { #if __APPLE__ // 10.6 r_sys_setenv ("DYLD_PRELOAD", _preload); r_sys_setenv ("DYLD_INSERT_LIBRARIES", _preload); // 10.8 r_sys_setenv ("DYLD_FORCE_FLAT_NAMESPACE", "1"); #else r_sys_setenv ("LD_PRELOAD", _preload); #endif } if (_timeout) { #if __UNIX__ int mypid = getpid (); if (!fork ()) { sleep (_timeout); if (!kill (mypid, 0)) eprintf ("\nrarun2: Interrupted by timeout\n"); kill (mypid, SIGKILL); exit (0); } #else eprintf ("timeout not supported for this platform\n"); #endif } if (_system) { exit (r_sys_cmd (_system)); } if (!r_file_exists (_program)) { eprintf ("rarun2: %s: file not found\n", _program); return 1; } exit (execv (_program, _args)); }
R_API int r_run_start(RRunProfile *p) { #if __APPLE__ posix_spawnattr_t attr = {0}; pid_t pid = -1; #endif int ret; if (!p->_program && !p->_system) { printf ("No program or system rule defined\n"); return 1; } if (p->_stdin) { int f = open (p->_stdin, O_RDONLY); if (f < 0) return 1; close (0); dup2 (f, 0); } if (p->_stdout) { int f = open (p->_stdout, O_WRONLY); if (f < 0) return 1; close (1); dup2 (f, 1); } if (p->_stderr) { int f = open (p->_stderr, O_WRONLY); if (f < 0) return 1; close (2); dup2 (f, 2); } if (p->_aslr != -1) setASLR (p->_aslr); #if __UNIX__ set_limit (p->_docore, RLIMIT_CORE, RLIM_INFINITY); if (p->_maxfd) set_limit (p->_maxfd, RLIMIT_NOFILE, p->_maxfd); #ifdef RLIMIT_NPROC if (p->_maxproc) set_limit (p->_maxproc, RLIMIT_NPROC, p->_maxproc); #endif if (p->_maxstack) set_limit (p->_maxstack, RLIMIT_STACK, p->_maxstack); #else if (p->_docore || p->_maxfd || p->_maxproc || p->_maxstack) eprintf ("Warning: setrlimits not supported for this platform\n"); #endif if (p->_connect) { char *q = strchr (p->_connect, ':'); if (q) { RSocket *fd = r_socket_new (0); *q = 0; if (!r_socket_connect_tcp (fd, p->_connect, q+1, 30)) { eprintf ("Cannot connect\n"); return 1; } eprintf ("connected\n"); close (0); close (1); close (2); dup2 (fd->fd, 0); dup2 (fd->fd, 1); dup2 (fd->fd, 2); } else { eprintf ("Invalid format for connect. missing ':'\n"); return 1; } } if (p->_listen) { RSocket *child, *fd = r_socket_new (0); if (!r_socket_listen (fd, p->_listen, NULL)) { eprintf ("rarun2: cannot listen\n"); r_socket_free (fd); return 1; } child = r_socket_accept (fd); if (child) { eprintf ("connected\n"); close (0); close (1); close (2); dup2 (child->fd, 0); dup2 (child->fd, 1); dup2 (child->fd, 2); } } if (p->_r2sleep != 0) { r_sys_sleep (p->_r2sleep); } if (p->_chgdir) { ret = chdir (p->_chgdir); if (ret < 0) return 1; } if (p->_chroot) { ret = chdir (p->_chroot); if (ret < 0) return 1; } #if __UNIX__ if (p->_chroot) { if (chroot (p->_chroot)) { eprintf ("rarun2: cannot chroot\n"); return 1; } chdir("/"); } if (p->_setuid) { ret = setgroups(0, NULL); if (ret < 0) return 1; ret = setuid (atoi (p->_setuid)); if (ret < 0) return 1; } if (p->_seteuid) { ret = seteuid (atoi (p->_seteuid)); if (ret < 0) return 1; } if (p->_setgid) { ret = setgid (atoi (p->_setgid)); if (ret < 0) return 1; } if (p->_input) { int f2[2]; pipe (f2); close (0); dup2 (f2[0], 0); parseinput (p->_input); write (f2[1], p->_input, strlen (p->_input)); } #endif if (p->_r2preload) { if (p->_preload) { eprintf ("WARNING: Only one library can be opened at a time\n"); } p->_preload = R2_LIBDIR"/libr2."R_LIB_EXT; } if (p->_libpath) { #if __WINDOWS__ eprintf ("rarun2: libpath unsupported for this platform\n"); #elif __HAIKU__ r_sys_setenv ("LIBRARY_PATH", p->_libpath); #elif __APPLE__ r_sys_setenv ("DYLD_LIBRARY_PATH", p->_libpath); #else r_sys_setenv ("LD_LIBRARY_PATH", p->_libpath); #endif } if (p->_preload) { #if __APPLE__ // 10.6 r_sys_setenv ("DYLD_PRELOAD", p->_preload); r_sys_setenv ("DYLD_INSERT_LIBRARIES", p->_preload); // 10.8 r_sys_setenv ("DYLD_FORCE_FLAT_NAMESPACE", "1"); #else r_sys_setenv ("LD_PRELOAD", p->_preload); #endif } if (p->_timeout) { #if __UNIX__ int mypid = getpid (); if (!fork ()) { sleep (p->_timeout); if (!kill (mypid, 0)) eprintf ("\nrarun2: Interrupted by timeout\n"); kill (mypid, SIGKILL); exit (0); } #else eprintf ("timeout not supported for this platform\n"); #endif } #if __APPLE__ posix_spawnattr_init (&attr); if (p->_args[0]) { char **envp = r_sys_get_environ(); ut32 spflags = 0; //POSIX_SPAWN_START_SUSPENDED; spflags |= POSIX_SPAWN_SETEXEC; if (p->_aslr == 0) { #define _POSIX_SPAWN_DISABLE_ASLR 0x0100 spflags |= _POSIX_SPAWN_DISABLE_ASLR; } (void)posix_spawnattr_setflags (&attr, spflags); if (p->_bits) { size_t copied = 1; cpu_type_t cpu; #if __i386__ || __x86_64__ cpu = CPU_TYPE_I386; if (p->_bits == 64) cpu |= CPU_ARCH_ABI64; #else cpu = CPU_TYPE_ANY; #endif posix_spawnattr_setbinpref_np ( &attr, 1, &cpu, &copied); } ret = posix_spawnp (&pid, p->_args[0], NULL, &attr, p->_args, envp); switch (ret) { case 0: break; case 22: eprintf ("posix_spawnp: Invalid argument\n"); break; case 86: eprintf ("posix_spawnp: Unsupported architecture\n"); break; default: eprintf ("posix_spawnp: unknown error %d\n", ret); perror ("posix_spawnp"); break; } exit (ret); } #endif if (p->_system) { if (p->_pid) { eprintf ("PID: Cannot determine pid with 'system' directive. Use 'program'.\n"); } exit (r_sys_cmd (p->_system)); } if (p->_program) { if (!r_file_exists (p->_program)) { char *progpath = r_file_path (p->_program); if (progpath && *progpath) { free (p->_program); p->_program = progpath; } else { free (progpath); eprintf ("rarun2: %s: file not found\n", p->_program); return 1; } } #if __UNIX__ // XXX HACK close all non-tty fds { int i; for (i=3; i<10; i++) close (i); } // TODO: use posix_spawn if (p->_setgid) { ret = setgid (atoi (p->_setgid)); if (ret < 0) return 1; } if (p->_pid) { eprintf ("PID: %d\n", getpid ()); } if (p->_pidfile) { char pidstr[32]; snprintf (pidstr, sizeof (pidstr), "%d\n", getpid ()); r_file_dump (p->_pidfile, (const ut8*)pidstr, strlen (pidstr), 0); } #endif if (p->_nice) { #if __UNIX__ errno = 0; ret = nice(p->_nice); if (ret == -1) { if (errno != 0) { return 1; } } #else eprintf ("nice not supported for this platform\n"); #endif } exit (execv (p->_program, (char* const*)p->_args)); } return 0; }
int main(int argc, char **argv) { RSocket *s; RSocketHTTPRequest *rs; int c, timeout = 3; int dodaemon = 0; int dosandbox = 0; const char *port = "8080"; // TODO: add flag to specify if listen in local or 0.0.0.0 while ((c = getopt (argc, argv, "hp:ds")) != -1) { switch (c) { case 's': dosandbox = 1; break; case 'd': dodaemon = 1; break; case 'h': return usage (1); case 'p': port = optarg; break; } } if (dodaemon) { int pid = fork (); if (pid >0) { printf ("%d\n", pid); return 0; } } s = r_socket_new (R_FALSE); s->local = 1; // by default if (!r_socket_listen (s, port, NULL)) { eprintf ("Cannot listen on http.port\n"); return 1; } r_sandbox_enable (dosandbox); while (!r_cons_singleton ()->breaked) { char *result_heap = NULL; const char *result = page_index; rs = r_socket_http_accept (s, timeout); if (!rs) continue; if (!strcmp (rs->method, "GET")) { if (!memcmp (rs->path, "/proc/kill/", 11)) { // TODO: show page here? int pid = atoi (rs->path+11); if (pid>0) kill (pid, 9); } else if (!memcmp (rs->path, "/file/open/", 11)) { int pid; int session_port = 3000 + r_num_rand (1024); char *filename = rs->path +11; int filename_len = strlen (filename); char *cmd; if (!(cmd = malloc (filename_len+40))) { perror ("malloc"); return 1; } sprintf (cmd, "r2 -q -e http.port=%d -c=h \"%s\"", session_port, filename); // TODO: use r_sys api to get pid when running in bg pid = r_sys_cmdbg (cmd); free (cmd); result = result_heap = malloc (1024+filename_len); if (!result) { perror ("malloc"); return 1; } sprintf (result_heap, "<html><body>" "<a href='/'>back</a><hr size=1/>" " - <a target='_blank' href='http://localhost:%d/'>open</a><br />" " - <a href='/proc/kill/%d'>kill</a><br />" "</body></html>", session_port, pid); eprintf ("\nchild pid %d\n\n", pid); } } r_socket_http_response (rs, 200, result, 0, NULL); r_socket_http_close (rs); free (result_heap); } r_socket_free (s); return 0; }
R_API int r_socket_rap_server_listen (RSocketRapServer *rap_s, const char *certfile) { if (!rap_s || !rap_s->port) return R_FALSE; return r_socket_listen (rap_s->fd, rap_s->port, certfile); }
int main(int argc, char **argv) { RSocket *s; RSocketHTTPRequest *rs; int c, timeout = 3; int dodaemon = 0; int dosandbox = 0; bool listenlocal = true; const char *port = "8080"; while ((c = getopt (argc, argv, "adhp:sv")) != -1) { switch (c) { case 'a': listenlocal = false; break; case 's': dosandbox = 1; break; case 'd': dodaemon = 1; break; case 'h': return usage (1); case 'v': return showversion (); case 'p': port = optarg; break; default: return usage (0); } } if (optind != argc) { return usage (0); } #if USE_IOS_JETSAM memorystatus_control (MEMORYSTATUS_CMD_SET_JETSAM_TASK_LIMIT, getpid (), 256, NULL, 0); #endif if (dodaemon) { #if LIBC_HAVE_FORK int pid = fork (); #else int pid = -1; #endif if (pid > 0) { printf ("%d\n", pid); return 0; } } s = r_socket_new (false); s->local = listenlocal; if (!r_socket_listen (s, port, NULL)) { eprintf ("Cannot listen on %d\n", s->port); r_socket_free (s); return 1; } eprintf ("http://localhost:%d/\n", s->port); if (dosandbox && !r_sandbox_enable (true)) { eprintf ("sandbox: Cannot be enabled.\n"); return 1; } while (!r_cons_singleton ()->breaked) { char *result_heap = NULL; const char *result = page_index; rs = r_socket_http_accept (s, timeout); if (!rs) continue; if (!strcmp (rs->method, "GET")) { if (!strncmp (rs->path, "/proc/kill/", 11)) { // TODO: show page here? int pid = atoi (rs->path + 11); if (pid > 0) { kill (pid, 9); } } else if (!strncmp (rs->path, "/file/open/", 11)) { int pid; int session_port = 3000 + r_num_rand (1024); char *filename = rs->path + 11; int filename_len = strlen (filename); char *cmd; if (!(cmd = malloc (filename_len + 40))) { perror ("malloc"); return 1; } sprintf (cmd, "r2 -q %s-e http.port=%d -c=h \"%s\"", listenlocal? "": "-e http.bind=public ", session_port, filename); // TODO: use r_sys api to get pid when running in bg pid = r_sys_cmdbg (cmd); free (cmd); result = result_heap = malloc (1024 + filename_len); if (!result) { perror ("malloc"); return 1; } sprintf (result_heap, "<html><body>" "<a href='/'>back</a><hr size=1/>" " - <a target='_blank' href='http://localhost:%d/'>open</a><br />" " - <a href='/proc/kill/%d'>kill</a><br />" "</body></html>", session_port, pid); eprintf ("\nchild pid %d\n\n", pid); } } r_socket_http_response (rs, 200, result, 0, NULL); r_socket_http_close (rs); free (result_heap); result_heap = NULL; } r_socket_free (s); return 0; }
R_API int r_run_config_env(RRunProfile *p) { int ret; if (!p->_program && !p->_system && !p->_runlib) { printf ("No program, system or runlib rule defined\n"); return 1; } // when IO is redirected to a process, handle them together if (handle_redirection (p->_stdio, true, true, false) != 0) { return 1; } if (handle_redirection (p->_stdin, true, false, false) != 0) { return 1; } if (handle_redirection (p->_stdout, false, true, false) != 0) { return 1; } if (handle_redirection (p->_stderr, false, false, true) != 0) { return 1; } if (p->_aslr != -1) { setASLR (p, p->_aslr); } #if __UNIX__ set_limit (p->_docore, RLIMIT_CORE, RLIM_INFINITY); if (p->_maxfd) { set_limit (p->_maxfd, RLIMIT_NOFILE, p->_maxfd); } #ifdef RLIMIT_NPROC if (p->_maxproc) { set_limit (p->_maxproc, RLIMIT_NPROC, p->_maxproc); } #endif if (p->_maxstack) { set_limit (p->_maxstack, RLIMIT_STACK, p->_maxstack); } #else if (p->_docore || p->_maxfd || p->_maxproc || p->_maxstack) eprintf ("Warning: setrlimits not supported for this platform\n"); #endif if (p->_connect) { char *q = strchr (p->_connect, ':'); if (q) { RSocket *fd = r_socket_new (0); *q = 0; if (!r_socket_connect_tcp (fd, p->_connect, q+1, 30)) { eprintf ("Cannot connect\n"); return 1; } if (p->_pty) { if (redirect_socket_to_pty (fd) != 0) { eprintf ("socket redirection failed\n"); r_socket_free (fd); return 1; } } else { redirect_socket_to_stdio (fd); } } else { eprintf ("Invalid format for connect. missing ':'\n"); return 1; } } if (p->_listen) { RSocket *child, *fd = r_socket_new (0); bool is_child = false; if (!r_socket_listen (fd, p->_listen, NULL)) { eprintf ("rarun2: cannot listen\n"); r_socket_free (fd); return 1; } while (true) { child = r_socket_accept (fd); if (child) { is_child = true; if (p->_dofork && !p->_dodebug) { #ifdef _MSC_VER int child_pid = r_sys_fork (); #else pid_t child_pid = r_sys_fork (); #endif if (child_pid == -1) { eprintf("rarun2: cannot fork\n"); r_socket_free (child); r_socket_free (fd); return 1; } else if (child_pid != 0){ // parent code is_child = false; } } if (is_child) { r_socket_close_fd (fd); eprintf ("connected\n"); if (p->_pty) { if (redirect_socket_to_pty (child) != 0) { eprintf ("socket redirection failed\n"); r_socket_free (child); r_socket_free (fd); return 1; } } else { redirect_socket_to_stdio (child); } break; } else { r_socket_close_fd (child); } } } if (!is_child) { r_socket_free (child); } r_socket_free (fd); } if (p->_r2sleep != 0) { r_sys_sleep (p->_r2sleep); } #if __UNIX__ if (p->_chroot) { if (chdir (p->_chroot) == -1) { eprintf ("Cannot chdir to chroot in %s\n", p->_chroot); return 1; } else { if (chroot (".") == -1) { eprintf ("Cannot chroot to %s\n", p->_chroot); return 1; } else { // Silenting pedantic meson flags... if (chdir ("/") == -1) { eprintf ("Cannot chdir to /\n"); return 1; } if (p->_chgdir) { if (chdir (p->_chgdir) == -1) { eprintf ("Cannot chdir after chroot to %s\n", p->_chgdir); return 1; } } } } } else if (p->_chgdir) { if (chdir (p->_chgdir) == -1) { eprintf ("Cannot chdir after chroot to %s\n", p->_chgdir); return 1; } } #else if (p->_chgdir) { ret = chdir (p->_chgdir); if (ret < 0) { return 1; } } if (p->_chroot) { ret = chdir (p->_chroot); if (ret < 0) { return 1; } } #endif #if __UNIX__ if (p->_setuid) { ret = setgroups (0, NULL); if (ret < 0) { return 1; } ret = setuid (atoi (p->_setuid)); if (ret < 0) { return 1; } } if (p->_seteuid) { ret = seteuid (atoi (p->_seteuid)); if (ret < 0) { return 1; } } if (p->_setgid) { ret = setgid (atoi (p->_setgid)); if (ret < 0) { return 1; } } if (p->_input) { char *inp; int f2[2]; if (pipe (f2) != -1) { close (0); dup2 (f2[0], 0); } else { eprintf ("[ERROR] rarun2: Cannot create pipe\n"); return 1; } inp = getstr (p->_input); if (inp) { size_t inpl = strlen (inp); if (write (f2[1], inp, inpl) != inpl) { eprintf ("[ERROR] rarun2: Cannot write to the pipe\n"); } close (f2[1]); free (inp); } else { eprintf ("Invalid input\n"); } } #endif if (p->_r2preload) { if (p->_preload) { eprintf ("WARNING: Only one library can be opened at a time\n"); } p->_preload = R2_LIBDIR"/libr2."R_LIB_EXT; } if (p->_libpath) { #if __WINDOWS__ eprintf ("rarun2: libpath unsupported for this platform\n"); #elif __HAIKU__ r_sys_setenv ("LIBRARY_PATH", p->_libpath); #elif __APPLE__ r_sys_setenv ("DYLD_LIBRARY_PATH", p->_libpath); #else r_sys_setenv ("LD_LIBRARY_PATH", p->_libpath); #endif } if (p->_preload) { #if __APPLE__ // 10.6 #ifndef __MAC_10_7 r_sys_setenv ("DYLD_PRELOAD", p->_preload); #endif r_sys_setenv ("DYLD_INSERT_LIBRARIES", p->_preload); // 10.8 r_sys_setenv ("DYLD_FORCE_FLAT_NAMESPACE", "1"); #else r_sys_setenv ("LD_PRELOAD", p->_preload); #endif } if (p->_timeout) { #if __UNIX__ int mypid = getpid (); if (!r_sys_fork ()) { int use_signal = p->_timeout_sig; if (use_signal < 1) { use_signal = SIGKILL; } sleep (p->_timeout); if (!kill (mypid, 0)) { eprintf ("\nrarun2: Interrupted by timeout\n"); } kill (mypid, use_signal); exit (0); } #else eprintf ("timeout not supported for this platform\n"); #endif } return 0; }
static int runfile () { if (!_program) { printf ("No program rule defined\n"); return 1; } if (_stdin) { int f = open (_stdin, O_RDONLY); close (0); dup2 (f, 0); } if (_stdout) { int f = open (_stdout, O_RDONLY); close (1); dup2 (f, 1); } if (_stderr) { int f = open (_stderr, O_RDONLY); close (2); dup2 (f, 2); } if (_connect) { char *p = strchr (_connect, ':'); if (p) { RSocket *fd = r_socket_new (0); *p=0; if (!r_socket_connect_tcp (fd, _connect, p+1, 30)) { eprintf ("Cannot connect\n"); return 1; } eprintf ("connected\n"); close (0); close (1); close (2); dup2 (fd->fd, 0); dup2 (fd->fd, 1); dup2 (fd->fd, 2); } else { eprintf ("Invalid format for connect. missing ':'\n"); return 1; } } if (_listen) { RSocket *child, *fd = r_socket_new (0); if (!r_socket_listen (fd, _listen, NULL)) { eprintf ("rarun2: cannot listen\n"); return 1; } child = r_socket_accept (fd); if (child) { eprintf ("connected\n"); close (0); close (1); close (2); dup2 (child->fd, 0); dup2 (child->fd, 1); dup2 (child->fd, 2); } } if (_chgdir) chdir (_chgdir); if (_chroot) chdir (_chroot); #if __UNIX__ if (_chroot) { if (chroot (".")) { eprintf ("rarun2: cannot chroot\n"); return 1; } } if (_setuid) setuid (atoi (_setuid)); if (_seteuid) seteuid (atoi (_seteuid)); if (_setgid) setgid (atoi (_setgid)); if (_input) { int f2[2]; pipe (f2); close (0); dup2 (f2[0], 0); parseinput (_input); write (f2[1], _input, strlen (_input)); } #endif if (_preload) { #if __APPLE__ r_sys_setenv ("DYLD_PRELOAD", _preload); #else r_sys_setenv ("LD_PRELOAD", _preload); #endif } if (_timeout) { #if __UNIX__ int mypid = getpid (); if (!fork ()) { sleep (_timeout); if (!kill (mypid, 0)) fprintf (stderr, "\nrarun2: Interrupted by timeout\n"); kill (mypid, SIGKILL); exit (0); } #else eprintf ("timeout not supported for this platform\n"); #endif } if (!r_file_exists (_program)) { eprintf ("rarun2: %s: file not found\n", _program); return 1; } exit (execv (_program, _args)); }
- follow symlinks #endif R_API int r_core_rtr_http(RCore *core, int launch, const char *path) { RSocketHTTPRequest *rs; int oldsandbox = -1; int timeout = r_config_get_i (core->config, "http.timeout"); int x = r_config_get_i (core->config, "scr.html"); int y = r_config_get_i (core->config, "scr.color"); int z = r_config_get_i (core->config, "asm.bytes"); int u = r_config_get_i (core->config, "scr.interactive"); int v = r_config_get_i (core->config, "asm.cmtright"); const char *port = r_config_get (core->config, "http.port"); if (r_sandbox_enable (0)) { eprintf ("sandbox: connect disabled\n"); return 1; } s = r_socket_new (R_FALSE); s->local = !r_config_get_i (core->config, "http.public"); if (!r_socket_listen (s, port, NULL)) { eprintf ("Cannot listen on http.port\n"); return 1; } if (launch) { char cmd[128]; const char *browser = r_config_get (core->config, "http.browser"); snprintf (cmd, sizeof (cmd)-1, "%s http://localhost:%d/%s", browser, atoi (port), path?path:""); r_sys_cmd (cmd); } r_config_set (core->config, "asm.cmtright", "false"); r_config_set (core->config, "scr.html", "true"); r_config_set (core->config, "scr.color", "false"); r_config_set (core->config, "asm.bytes", "false"); r_config_set (core->config, "scr.interactive", "false"); if (r_config_get_i (core->config, "http.sandbox")) { oldsandbox = r_config_get_i (core->config, "cfg.sandbox"); r_config_set (core->config, "cfg.sandbox", "true"); } eprintf ("Starting http server...\n"); eprintf ("http://localhost:%d/\n", atoi (port)); while (!r_cons_singleton ()->breaked) { r_cons_break (http_break, core); rs = r_socket_http_accept (s, timeout); if (!rs) { if (!s) break; r_sys_usleep (200); continue; } if (!rs->method || !rs->path) { r_socket_http_close (rs); continue; } if (!strcmp (rs->method, "GET")) { if (!memcmp (rs->path, "/up", 3)) { if (r_config_get_i (core->config, "http.upget")) { const char *uproot = r_config_get (core->config, "http.uproot"); if (!rs->path[3] || (rs->path[3]=='/'&&!rs->path[4])) { char *ptr = strdup ("<html><body>\n"); const char *file; RListIter *iter; // list files RList *files = r_sys_dir (uproot); eprintf ("Listing directory %s\n", uproot); r_list_foreach (files, iter, file) { if (file[0] == '.') continue; ptr = r_str_concatf (ptr, "<a href=\"/up/%s\">%s</a><br />\n", file, file); } r_list_free (files); ptr = r_str_concat (ptr, "<html><body>\n"); r_socket_http_response (rs, 200, ptr, 0, NULL); } else { char *path = r_file_root (uproot, rs->path + 4); if (r_file_exists (path)) { int sz = 0; char *f = r_file_slurp (path, &sz); if (f) { r_socket_http_response (rs, 200, f, sz, NULL); free (f); } else { r_socket_http_response (rs, 403, "Permission denied", 0, NULL); eprintf ("http: Cannot open '%s'\n", path); } } else { eprintf ("File '%s' not found\n", path); r_socket_http_response (rs, 404, "File not found\n", 0, NULL); } free (path); } } else { r_socket_http_response (rs, 403, "Permission denied\n", 0, NULL); } } else if (!memcmp (rs->path, "/cmd/", 5)) {
R_API int r_core_rtr_http(RCore *core, int launch, const char *path) { char buf[32]; RSocketHTTPRequest *rs; int iport, oldsandbox = -1; int timeout = r_config_get_i (core->config, "http.timeout"); int x = r_config_get_i (core->config, "scr.html"); int y = r_config_get_i (core->config, "scr.color"); int z = r_config_get_i (core->config, "asm.bytes"); int u = r_config_get_i (core->config, "scr.interactive"); int v = r_config_get_i (core->config, "asm.cmtright"); const char *port = r_config_get (core->config, "http.port"); char *allow = (char *)r_config_get (core->config, "http.allow"); if (core->http_up) { eprintf ("http server is already running\n"); return 1; } if (r_sandbox_enable (0)) { eprintf ("sandbox: connect disabled\n"); return 1; } if (path && atoi (path)) { port = path; path = NULL; } if (!strcmp (port, "0")) { r_num_irand (); iport = 1024+r_num_rand (45256); snprintf (buf, sizeof (buf), "%d", iport); port = buf; } s = r_socket_new (R_FALSE); s->local = !r_config_get_i (core->config, "http.public"); if (!r_socket_listen (s, port, NULL)) { eprintf ("Cannot listen on http.port\n"); return 1; } if (launch) { char cmd[128]; const char *browser = r_config_get (core->config, "http.browser"); snprintf (cmd, sizeof (cmd)-1, "%s http://localhost:%d/%s &", browser, atoi (port), path?path:""); r_sys_cmd (cmd); } r_config_set (core->config, "asm.cmtright", "false"); r_config_set (core->config, "scr.html", "true"); r_config_set (core->config, "scr.color", "false"); r_config_set (core->config, "asm.bytes", "false"); r_config_set (core->config, "scr.interactive", "false"); if (r_config_get_i (core->config, "http.sandbox")) { oldsandbox = r_config_get_i (core->config, "cfg.sandbox"); r_config_set (core->config, "cfg.sandbox", "true"); } eprintf ("Starting http server...\n"); eprintf ("http://localhost:%d/\n", atoi (port)); core->http_up = R_TRUE; while (!r_cons_singleton ()->breaked) { r_cons_break ((RConsBreak)http_break, core); rs = r_socket_http_accept (s, timeout); if (!rs) { if (!s) break; r_sys_usleep (100); continue; } if (allow && *allow) { int accepted = R_FALSE; const char *host; char *p, *peer = r_socket_to_string (rs->s); char *allows = strdup (allow); //eprintf ("Firewall (%s)\n", allows); int i, count = r_str_split (allows, ','); p = strchr (peer, ':'); if (p) *p = 0; for (i=0; i<count; i++) { host = r_str_word_get0 (allows, i); //eprintf ("--- (%s) (%s)\n", host, peer); if (!strcmp (host, peer)) { accepted = R_TRUE; break; } } free (peer); free (allows); if (!accepted) { r_socket_http_close (rs); continue; } } if (!rs->method || !rs->path) { eprintf ("Invalid http headers received from client\n"); r_socket_http_close (rs); continue; } char *dir = NULL; if (r_config_get_i (core->config, "http.dirlist")) if (r_file_is_directory (rs->path)) dir = strdup (rs->path); if (!strcmp (rs->method, "GET")) { if (!memcmp (rs->path, "/up", 3)) { if (r_config_get_i (core->config, "http.upget")) { const char *uproot = r_config_get (core->config, "http.uproot"); if (!rs->path[3] || (rs->path[3]=='/'&&!rs->path[4])) { char *ptr = rtr_dir_files (uproot); r_socket_http_response (rs, 200, ptr, 0, NULL); free (ptr); } else { char *path = r_file_root (uproot, rs->path + 4); if (r_file_exists (path)) { int sz = 0; char *f = r_file_slurp (path, &sz); if (f) { r_socket_http_response (rs, 200, f, sz, NULL); free (f); } else { r_socket_http_response (rs, 403, "Permission denied", 0, NULL); eprintf ("http: Cannot open '%s'\n", path); } } else { if (dir) { char *resp = rtr_dir_files (dir); r_socket_http_response (rs, 404, resp, 0, NULL); free (resp); } else { eprintf ("File '%s' not found\n", path); r_socket_http_response (rs, 404, "File not found\n", 0, NULL); } } free (path); } } else { r_socket_http_response (rs, 403, "Permission denied\n", 0, NULL); } } else if (!memcmp (rs->path, "/cmd/", 5)) { char *cmd = rs->path +5; char foo[32]; const char *httpcmd = r_config_get (core->config, "http.uri"); while (*cmd=='/') cmd++; if (httpcmd && *httpcmd) { int len; char *res; // do remote http query and proxy response snprintf (foo, sizeof (foo), "%s/%s", httpcmd, cmd); res = r_socket_http_get (foo, NULL, &len); if (res) { res[len]=0; r_cons_printf ("%s\n", res); } } else { char *out, *cmd = rs->path+5; r_str_uri_decode (cmd); // eprintf ("CMD (%s)\n", cmd); out = r_core_cmd_str_pipe (core, cmd); // eprintf ("\nOUT LEN = %d\n", strlen (out)); if (out) { char *res = r_str_uri_encode (out); r_socket_http_response (rs, 200, out, 0, "Content-Type: text/plain\n"); free (out); free (res); } else r_socket_http_response (rs, 200, "", 0, NULL); } } else { const char *root = r_config_get (core->config, "http.root"); char *path = r_file_root (root, rs->path); // FD IS OK HERE if (rs->path [strlen (rs->path)-1] == '/') { path = r_str_concat (path, "index.html"); //rs->path = r_str_concat (rs->path, "index.html"); } else { //snprintf (path, sizeof (path), "%s/%s", root, rs->path); if (r_file_is_directory (path)) { char res[128]; snprintf (res, sizeof (res), "Location: %s/\n", rs->path); r_socket_http_response (rs, 302, NULL, 0, res); r_socket_http_close (rs); free (path); free (dir); dir = NULL; continue; } } if (r_file_exists (path)) { int sz = 0; char *f = r_file_slurp (path, &sz); if (f) { const char *contenttype = NULL; if (strstr (path, ".js")) contenttype = "Content-Type: application/javascript\n"; if (strstr (path, ".css")) contenttype = "Content-Type: text/css\n"; if (strstr (path, ".html")) contenttype = "Content-Type: text/html\n"; r_socket_http_response (rs, 200, f, sz, contenttype); free (f); } else { r_socket_http_response (rs, 403, "Permission denied", 0, NULL); eprintf ("http: Cannot open '%s'\n", path); } } else { if (dir) { char *resp = rtr_dir_files (dir); eprintf ("Dirlisting %s\n", dir); r_socket_http_response (rs, 404, resp, 0, NULL); free (resp); } else { eprintf ("File '%s' not found\n", path); r_socket_http_response (rs, 404, "File not found\n", 0, NULL); } } free (path); } } else if (!strcmp (rs->method, "POST")) { ut8 *ret; int retlen; char buf[128]; if (r_config_get_i (core->config, "http.upload")) { ret = r_socket_http_handle_upload ( rs->data, rs->data_length, &retlen); if (ret) { ut64 size = r_config_get_i (core->config, "http.maxsize"); if (size && retlen > size) { r_socket_http_response (rs, 403, "403 File too big\n", 0, NULL); } else { char *filename = r_file_root ( r_config_get (core->config, "http.uproot"), rs->path + 4); eprintf ("UPLOADED '%s'\n", filename); r_file_dump (filename, ret, retlen); free (filename); snprintf (buf, sizeof (buf), "<html><body><h2>uploaded %d bytes. Thanks</h2>\n", retlen); r_socket_http_response (rs, 200, buf, 0, NULL); } free (ret); } } else { r_socket_http_response (rs, 403, "403 Forbidden\n", 0, NULL); } } else { r_socket_http_response (rs, 404, "Invalid protocol", 0, NULL); } r_socket_http_close (rs); free (dir); } core->http_up = R_FALSE; r_socket_free (s); r_cons_break_end (); r_config_set_i (core->config, "scr.html", x); r_config_set_i (core->config, "scr.color", y); r_config_set_i (core->config, "asm.bytes", z); r_config_set_i (core->config, "scr.interactive", u); r_config_set_i (core->config, "asm.cmtright", v); if (oldsandbox != -1) r_config_set_i (core->config, "cfg.sandbox", oldsandbox); return 0; }
R_API int r_socket_rap_server_listen (RSocketRapServer *rap_s, const char *certfile) { if (!rap_s || rap_s->port[0] == '\0') return false; return r_socket_listen (rap_s->fd, rap_s->port, certfile); }