Ejemplo n.º 1
0
R_API int r_socket_connect (RSocket *s, const char *host, const char *port, int proto, unsigned int timeout) {
#if __WINDOWS__ && !defined(__CYGWIN__) && !defined(__MINGW64__)
	struct sockaddr_in sa;
	struct hostent *he;
	WSADATA wsadata;
	if (WSAStartup (MAKEWORD (1, 1), &wsadata) == SOCKET_ERROR) {
		eprintf ("Error creating socket.");
		return false;
	}
	s->fd = socket (AF_INET, SOCK_STREAM, 0);
	if (s->fd == -1)
		return false;

	memset (&sa, 0, sizeof(sa));
	sa.sin_family = AF_INET;
	he = (struct hostent *)gethostbyname (host);
	if (he == (struct hostent*)0) {
		close (s->fd);
		return false;
	}

	sa.sin_addr = *((struct in_addr *)he->h_addr);

	s->port = r_socket_port_by_name (port);
	sa.sin_port = htons (s->port);
#warning TODO: implement connect timeout on w32
	if (connect (s->fd, (const struct sockaddr*)&sa, sizeof (struct sockaddr))) {
		close (s->fd);
		return false;
	}
	return true;
#elif __UNIX__ || defined(__CYGWIN__)
	int gai, ret;
	struct addrinfo hints, *res, *rp;
	if (!proto) proto = R_SOCKET_PROTO_TCP;
	signal (SIGPIPE, SIG_IGN);
	if (proto == R_SOCKET_PROTO_UNIX) {
		if (!r_socket_unix_connect (s, host))
			return false;
	} else {
		memset (&hints, 0, sizeof (struct addrinfo));
		hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
		hints.ai_protocol = proto;
		gai = getaddrinfo (host, port, &hints, &res);
		if (gai != 0) {
			//eprintf ("Error in getaddrinfo: %s\n", gai_strerror (gai));
			return false;
		}
		for (rp = res; rp != NULL; rp = rp->ai_next) {
			int flag = 1;

			s->fd = socket (rp->ai_family, rp->ai_socktype, rp->ai_protocol);
			if (s->fd == -1)
				continue;

			ret = setsockopt (s->fd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag));
			if (ret < 0) {
				close (s->fd);
				s->fd = -1;
				continue;
			}

			if (timeout>0) {
				r_socket_block_time (s, 1, timeout);
				//fcntl (s->fd, F_SETFL, O_NONBLOCK, 1);
			}
			ret = connect (s->fd, rp->ai_addr, rp->ai_addrlen);

			if (timeout == 0 && ret == 0) {
				freeaddrinfo (res);
				return true;

			} else if (ret == 0 /* || nonblocking */) {

				struct timeval tv;
				fd_set fdset, errset;
				FD_ZERO (&fdset);
				FD_SET (s->fd, &fdset);
				tv.tv_sec = 1; //timeout;
				tv.tv_usec = 0;

				if (r_socket_is_connected (s)) {
					freeaddrinfo (res);
					return true;
				}
				if (select (s->fd + 1, NULL, NULL, &errset, &tv) == 1) {
					int so_error;
					socklen_t len = sizeof so_error;
					ret = getsockopt (s->fd, SOL_SOCKET,
						SO_ERROR, &so_error, &len);

					if (ret == 0 && so_error == 0) {
						//fcntl (s->fd, F_SETFL, O_NONBLOCK, 0);
						//r_socket_block_time (s, 0, 0);
						freeaddrinfo (res);
						return true;
					}
				}
			}
			close (s->fd);
			s->fd = -1;
		}
		freeaddrinfo (res);
		if (rp == NULL) {
			eprintf ("Could not resolve address '%s'\n", host);
			return false;
		}
	}
#endif
#if HAVE_LIB_SSL
	if (s->is_ssl) {
		s->ctx = SSL_CTX_new (SSLv23_client_method ());
		if (s->ctx == NULL) {
			r_socket_free (s);
			return false;
		}
		s->sfd = SSL_new (s->ctx);
		SSL_set_fd (s->sfd, s->fd);
		if (SSL_connect (s->sfd) != 1) {
			r_socket_free (s);
			return false;
		}
	}
#endif
	return true;
}
Ejemplo n.º 2
0
R_API int r_socket_listen (RSocket *s, const char *port, const char *certfile) {
#if __UNIX__ || defined(__CYGWIN__)
	int optval = 1;
	int ret;
	struct linger linger = { 0 };
#endif
	if (r_sandbox_enable (0))
		return false;
#if __WINDOWS__ && !defined(__CYGWIN__) && !defined(__MINGW64__)
	WSADATA wsadata;
	if (WSAStartup (MAKEWORD (1, 1), &wsadata) == SOCKET_ERROR) {
		eprintf ("Error creating socket.");
		return false;
	}
#endif
	if ((s->fd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP))<0)
		return false;
#if __UNIX__ || defined(__CYGWIN__)
	linger.l_onoff = 1;
	linger.l_linger = 1;
	ret = setsockopt (s->fd, SOL_SOCKET, SO_LINGER, (void*)&linger, sizeof (linger));
	if (ret < 0)
		return false;
	{ // fix close after write bug //
	int x = 1500; // FORCE MTU
	ret = setsockopt (s->fd, SOL_SOCKET, SO_SNDBUF, (void*)&x, sizeof (int));
	if (ret < 0)
		return false;
	}
	ret = setsockopt (s->fd, SOL_SOCKET, SO_REUSEADDR, (void*)&optval, sizeof optval);
	if (ret < 0)
		return false;
#endif
	memset (&s->sa, 0, sizeof (s->sa));
	s->sa.sin_family = AF_INET;
	s->sa.sin_addr.s_addr = htonl (s->local? INADDR_LOOPBACK: INADDR_ANY);
	s->port = r_socket_port_by_name (port);
	if (s->port <1)
		return false;
	s->sa.sin_port = htons (s->port); // TODO honor etc/services

	if (bind (s->fd, (struct sockaddr *)&s->sa, sizeof(s->sa)) < 0) {
		r_sys_perror ("bind");
		close (s->fd);
		return false;
	}
#if __UNIX__ || defined(__CYGWIN__)
	signal (SIGPIPE, SIG_IGN);
#endif
	if (listen (s->fd, 32) < 0) {
		close (s->fd);
		return false;
	}
#if HAVE_LIB_SSL
	if (s->is_ssl) {
		s->ctx = SSL_CTX_new (SSLv23_method ());
		if (s->ctx == NULL) {
			r_socket_free (s);
			return false;
		}
		if (!SSL_CTX_use_certificate_chain_file (s->ctx, certfile)) {
			r_socket_free (s);
			return false;
		}
		if (!SSL_CTX_use_PrivateKey_file (s->ctx, certfile, SSL_FILETYPE_PEM)) {
			r_socket_free (s);
			return false;
		}
		SSL_CTX_set_verify_depth (s->ctx, 1);
	}
#endif
	return true;
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
R_API void r_socket_rap_server_free (RSocketRapServer *rap_s) {
	if (rap_s)
		r_socket_free (rap_s->fd);
	free (rap_s);
}
Ejemplo n.º 6
0
static RIODesc *rap__open(struct r_io_t *io, const char *pathname, int rw, int mode) {
	RSocket *rap_fd;
	RIORap *rior;
	const char *ptr;
	char *file, *port;
	char buf[1024];
	int i, p, listenmode, is_ssl;

	if (!rap__plugin_open (io, pathname,0))
		return NULL;
	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 == NULL) {
			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)) == NULL) {
		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_NEW (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, 3+buf[2]);
		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;
		}
		r_mem_copyendian ((ut8 *)&i, (ut8*)buf+1, 4, ENDIAN);
		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);
}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
0
R_API bool r_socket_connect(RSocket *s, const char *host, const char *port, int proto, unsigned int timeout) {
#if __WINDOWS__
	struct sockaddr_in sa;
	struct hostent *he;
	WSADATA wsadata;
	TIMEVAL Timeout;
	Timeout.tv_sec = timeout;
	Timeout.tv_usec = 0;

	if (WSAStartup (MAKEWORD (1, 1), &wsadata) == SOCKET_ERROR) {
		eprintf ("Error creating socket.");
		return false;
	}
	s->fd = socket (AF_INET, SOCK_STREAM, 0);
#ifdef _MSC_VER
	if (s->fd == INVALID_SOCKET) {
#else
	if (s->fd == -1) {
#endif
		return false;
	}

	unsigned long iMode = 1;
	int iResult = ioctlsocket (s->fd, FIONBIO, &iMode);
	if (iResult != NO_ERROR) {
		eprintf ("ioctlsocket error: %d\n", iResult);
	}
	memset (&sa, 0, sizeof(sa));
	sa.sin_family = AF_INET;
	he = (struct hostent *)gethostbyname (host);
	if (he == (struct hostent*)0) {
#ifdef _MSC_VER
		closesocket (s->fd);
#else
		close (s->fd);
#endif
		return false;
	}
	sa.sin_addr = *((struct in_addr *)he->h_addr);
	s->port = r_socket_port_by_name (port);
	sa.sin_port = htons (s->port);
	if (!connect (s->fd, (const struct sockaddr*)&sa, sizeof (struct sockaddr))) {
#ifdef _MSC_VER
		closesocket (s->fd);
#else
		close (s->fd);
#endif
		return false;
	}
	iMode = 0;
	iResult = ioctlsocket (s->fd, FIONBIO, &iMode);
	if (iResult != NO_ERROR) {
		eprintf ("ioctlsocket error: %d\n", iResult);
	}
	if (timeout > 0) {
		r_socket_block_time (s, 1, timeout);
	}
	fd_set Write, Err;
	FD_ZERO (&Write);
	FD_ZERO (&Err);
	FD_SET (s->fd, &Write);
	FD_SET (s->fd, &Err);
	select (0, NULL, &Write, &Err, &Timeout);
	if (FD_ISSET (s->fd, &Write)) {
		return true;
	}
	return false;
#elif __UNIX__
	int ret;
	struct addrinfo hints = {0};
	struct addrinfo *res, *rp;
	if (!proto) {
		proto = R_SOCKET_PROTO_TCP;
	}
	signal (SIGPIPE, SIG_IGN);
	if (proto == R_SOCKET_PROTO_UNIX) {
		if (!r_socket_unix_connect (s, host)) {
			return false;
		}
	} else {
		hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
		hints.ai_protocol = proto;
		int gai = getaddrinfo (host, port, &hints, &res);
		if (gai != 0) {
			eprintf ("Error in getaddrinfo: %s\n", gai_strerror (gai));
			return false;
		}
		for (rp = res; rp != NULL; rp = rp->ai_next) {
			int flag = 1;

			s->fd = socket (rp->ai_family, rp->ai_socktype, rp->ai_protocol);
			if (s->fd == -1) {
				perror ("socket");
				continue;
			}
			ret = setsockopt (s->fd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof (flag));
			if (ret < 0) {
				perror ("setsockopt");
				close (s->fd);
				s->fd = -1;
				continue;
			}
			if (timeout > 0) {
				r_socket_block_time (s, 1, timeout);
				//fcntl (s->fd, F_SETFL, O_NONBLOCK, 1);
			}
			ret = connect (s->fd, rp->ai_addr, rp->ai_addrlen);

			if (timeout == 0 && ret == 0) {
				freeaddrinfo (res);
				return true;
			}
			if (ret == 0 /* || nonblocking */) {
				struct timeval tv;
				fd_set fdset, errset;
				FD_ZERO (&fdset);
				FD_SET (s->fd, &fdset);
				tv.tv_sec = 1; //timeout;
				tv.tv_usec = 0;

				if (r_socket_is_connected (s)) {
					freeaddrinfo (res);
					return true;
				}
				if (select (s->fd + 1, NULL, NULL, &errset, &tv) == 1) {
					int so_error;
					socklen_t len = sizeof so_error;
					ret = getsockopt (s->fd, SOL_SOCKET,
						SO_ERROR, &so_error, &len);

					if (ret == 0 && so_error == 0) {
						//fcntl (s->fd, F_SETFL, O_NONBLOCK, 0);
						//r_socket_block_time (s, 0, 0);
						freeaddrinfo (res);
						return true;
					}
				}
			}
			close (s->fd);
			s->fd = -1;
		}
		freeaddrinfo (res);
		if (!rp) {
			eprintf ("Could not resolve address '%s' or failed to connect\n", host);
			return false;
		}
	}
#endif
#if HAVE_LIB_SSL
	if (s->is_ssl) {
		s->ctx = SSL_CTX_new (SSLv23_client_method ());
		if (!s->ctx) {
			r_socket_free (s);
			return false;
		}
		s->sfd = SSL_new (s->ctx);
		SSL_set_fd (s->sfd, s->fd);
		if (SSL_connect (s->sfd) != 1) {
			r_socket_free (s);
			return false;
		}
	}
#endif
	return true;
}

/* close the file descriptor associated with the RSocket s */
R_API int r_socket_close_fd(RSocket *s) {
#ifdef _MSC_VER
	return s->fd != INVALID_SOCKET ? closesocket (s->fd) : false;
#else
	return s->fd != -1 ? close (s->fd) : false;
#endif
}

/* shutdown the socket and close the file descriptor */
R_API int r_socket_close(RSocket *s) {
	int ret = false;
	if (!s) {
		return false;
	}
	if (s->fd != -1) {
#if __UNIX__
		shutdown (s->fd, SHUT_RDWR);
#endif
#if __WINDOWS__
		// https://msdn.microsoft.com/en-us/library/windows/desktop/ms740481(v=vs.85).aspx
		shutdown (s->fd, SD_SEND);
		if (r_socket_ready (s, 0, 250)) {
			do {
				char buf = 0;
				ret = recv (s->fd, &buf, 1, 0);
			} while (ret != 0 && ret != SOCKET_ERROR);
		}
		ret = closesocket (s->fd);
#else
		ret = close (s->fd);
#endif
	}
#if HAVE_LIB_SSL
	if (s->is_ssl && s->sfd) {
		SSL_free (s->sfd);
		s->sfd = NULL;
	}
#endif
	return ret;
}
Ejemplo n.º 9
0
Archivo: run.c Proyecto: f0829/radare2
static int redirect_socket_to_pty(RSocket *sock) {
#if HAVE_PTY
	// directly duplicating the fds using dup2() creates problems
	// in case of interactive applications
	int fdm, fds;

	if (openpty (&fdm, &fds, NULL, NULL, NULL) == -1) {
		perror ("opening pty");
		return -1;
	}

	pid_t child_pid = r_sys_fork ();

	if (child_pid == -1) {
		eprintf ("cannot fork\n");
		close(fdm);
		close(fds);
		return -1;
	}

	if (child_pid == 0) {
		// child process
		close (fds);

		char *buff = NULL;
		int sockfd = sock->fd;
		int max_fd = fdm > sockfd ? fdm : sockfd;

		while (true) {
			fd_set readfds;
			FD_ZERO (&readfds);
			FD_SET (fdm, &readfds);
			FD_SET (sockfd, &readfds);

			if (select (max_fd + 1, &readfds, NULL, NULL, NULL) == -1) {
				perror ("select error");
				break;
			}

			if (FD_ISSET (fdm, &readfds)) {
				if (fd_forward (fdm, sockfd, &buff) != 0) {
					break;
				}
			}

			if (FD_ISSET (sockfd, &readfds)) {
				if (fd_forward (sockfd, fdm, &buff) != 0) {
					break;
				}
			}
		}

		free (buff);
		close (fdm);
		r_socket_free (sock);
		exit (0);
	}

	// parent
	r_socket_close_fd (sock);
	login_tty (fds);
	close (fdm);

	// disable the echo on slave stdin
	struct termios t;
	tcgetattr (0, &t);
	cfmakeraw (&t);
	tcsetattr (0, TCSANOW, &t);

	return 0;
#else
	// Fallback to socket to I/O redirection
	return redirect_socket_to_stdio (sock);
#endif
}
Ejemplo n.º 10
0
Archivo: run.c Proyecto: f0829/radare2
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;
}
Ejemplo n.º 11
0
static int runfile () {
	int ret;
	if (!_program && !_system) {
		printf ("No program or system rule defined\n");
		return 1;
	}
	if (_stdin) {
		int f = open (_stdin, O_RDONLY);
		if (f < 0)
			return 1;
		close (0);
		dup2 (f, 0);
	}
	if (_stdout) {
		int f = open (_stdout, O_WRONLY);
		if (f < 0)
			return 1;
		close (1);
		dup2 (f, 1);
	}
	if (_stderr) {
		int f = open (_stderr, O_WRONLY);
		if (f < 0)
			return 1;
		close (2);
		dup2 (f, 2);
	}
#if __UNIX__
	set_limit (_docore, RLIMIT_CORE, RLIM_INFINITY);
	set_limit (_maxfd, RLIMIT_NOFILE, _maxfd);
	set_limit (_maxproc, RLIMIT_NPROC, _maxproc);
	set_limit (_maxstack, RLIMIT_STACK, _maxstack);
#else
	if (_docore || _maxfd || _maxproc || _maxstack)
		eprintf ("Warning: setrlimits not supported for this platform\n");
#endif

	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");
			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 (_r2sleep != 0) {
		r_sys_sleep (_r2sleep);
	}
	if (_chgdir) {
		ret = chdir (_chgdir);
		if (ret < 0)
			return 1;
	}
	if (_chroot) {
		ret = chdir (_chroot);
		if (ret < 0)
			return 1;
	}
#if __UNIX__
	if (_chroot) {
		if (chroot (_chroot)) {
			eprintf ("rarun2: cannot chroot\n");
			return 1;
		}
	}
	if (_setuid) {
		ret = setuid (atoi (_setuid));
		if (ret < 0)
			return 1;
	}
	if (_seteuid) {
		ret = seteuid (atoi (_seteuid));
		if (ret < 0)
			return 1;
	}
	if (_setgid) {
		ret = setgid (atoi (_setgid));
		if (ret < 0)
			return 1;
	}
	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));
}
Ejemplo n.º 12
0
/* TODO: simplify using r_write */
static int cmd_write(void *data, const char *input) {
	int wseek, i, size, len;
	RCore *core = (RCore *)data;
	char *tmp, *str, *ostr;
	const char *arg, *filename = "";
	char _fn[32];
	ut64 off;
	ut8 *buf;
	st64 num = 0;
	const char* help_msg[] = {
		"Usage:","w[x] [str] [<file] [<<EOF] [@addr]","",
		"w","[1248][+-][n]","increment/decrement byte,word..",
		"w"," foobar","write string 'foobar'",
		"w0"," [len]","write 'len' bytes with value 0x00",
		"w6","[de] base64/hex","write base64 [d]ecoded or [e]ncoded string",
		"wa","[?] push ebp","write opcode, separated by ';' (use '\"' around the command)",
		"waf"," file","assemble file and write bytes",
		"wao"," [?] op","modify opcode (change conditional of jump. nop, etc)",
		"wA"," [?] r 0","alter/modify opcode at current seek (see wA?)",
		"wb"," 010203","fill current block with cyclic hexpairs",
		"wB","[-]0xVALUE","set or unset bits with given value",
		"wc","","list all write changes",
		"wc","[?][ir*?]","write cache undo/commit/reset/list (io.cache)",
		"wd"," [off] [n]","duplicate N bytes from offset at current seek (memcpy) (see y?)",
		"we","[?] [nNsxX] [arg]","extend write operations (insert instead of replace)",
		"wf"," -|file","write contents of file at current offset",
		"wh"," r2","whereis/which shell command",
		"wm"," f0ff","set binary mask hexpair to be used as cyclic write mask",
		"wo","[?] hex","write in block with operation. 'wo?' fmi",
		"wp"," [?] -|file","apply radare patch file. See wp? fmi",
		"wr"," 10","write 10 random bytes",
		"ws"," pstring","write 1 byte for length and then the string",
		"wt[f]"," [?] file [sz]","write to file (from current seek, blocksize or sz bytes)",
		"wts"," host:port [sz]", "send data to remote host:port via tcp://",
		"ww"," foobar","write wide string 'f\\x00o\\x00o\\x00b\\x00a\\x00r\\x00'",
		"wx","[?][fs] 9090","write two intel nops (from wxfile or wxseek)",
		"wv","[?] eip+34","write 32-64 bit value",
		"wz"," string","write zero terminated string (like w + \\x00)",
		NULL
	};

	if (!input) {
		return 0;
	}

	len = strlen (input);
	wseek = r_config_get_i (core->config, "cfg.wseek");
	str = ostr = strdup (*input? input + 1: "");
	_fn[0] = 0;

	switch (*input) {
	case 'B':
		switch (input[1]) {
		case ' ':
			cmd_write_bits (core, 1, r_num_math (core->num, input + 2));
			break;
		case '-':
			cmd_write_bits (core, 0, r_num_math (core->num, input + 2));
			break;
		default:
			eprintf ("Usage: wB 0x2000  # or wB-0x2000\n");
			break;
		}
		break;
	case '0':
		{
			ut64 len = r_num_math (core->num, input+1);
			if (len>0) {
				ut8 *buf = calloc (1, len);
				if (buf) {
					r_io_write_at (core->io, core->offset, buf, len);
					r_core_block_read (core);
					free (buf);
				} else eprintf ("Cannot allocate %d bytes\n", (int)len);
			}
		}
		break;
	case '1':
	case '2':
	case '4':
	case '8':
		if (input[1] && input[2]) {
			if (input[1]==input[2]) {
				num = 1;
			} else num = r_num_math (core->num, input+2);
		}
		switch (input[2] ? input[1] : 0) {
		case '+':
			cmd_write_inc (core, *input-'0', num);
			break;
		case '-':
			cmd_write_inc (core, *input-'0', -num);
			break;
		default:
			eprintf ("Usage: w[1248][+-][num]   # inc/dec byte/word/..\n");
		}
		break;
	case '6':
		{
		int fail = 0;
		ut8 *buf = NULL;
		int len = 0, str_len;
		const char *str;

		if (input[1] && input[2] != ' ')
			fail = 1;

		if (input[1] && input[2] && input[3])
			str = input + 3;
		else
			str = "";
		str_len = strlen (str) + 1;
		if (!fail) {
			switch (input[1]) {
			case 'd':
				buf = malloc (str_len);
				len = r_base64_decode (buf, str, 0);
				if(len == 0) {
					free(buf);
					fail = 1;
				}
				break;
			case 'e':
				{
				ut8 *bin_buf = malloc (str_len);
				const int bin_len = r_hex_str2bin (str, bin_buf);
				if (bin_len <= 0) {
					fail = 1;
				} else {
					buf = calloc (str_len + 1, 4);
					len = r_base64_encode ((char *)buf, bin_buf, bin_len);
					if(len == 0) {
						free (buf);
						fail = 1;
					}
				}
				free (bin_buf);
				break;
				}
			default:
				fail = 1;
				break;
			}
		}
		if (!fail) {
			r_core_write_at (core, core->offset, buf, len);
			WSEEK (core, len);
			r_core_block_read (core);
			free (buf);
		} else {
			eprintf ("Usage: w6[de] base64/hex\n");
		}
		break;
		}
	case 'h':
		{
		char *p = strchr (input, ' ');
		if (p) {
			while (*p==' ') p++;
			p = r_file_path (p);
			if (p) {
				r_cons_println (p);
				free (p);
			}
		}
		}
		break;
	case 'e':
		{
		ut64 addr = 0, len = 0, b_size = 0;
		st64 dist = 0;
		ut8* bytes = NULL;
		int cmd_suc = false;
		char *input_shadow = NULL, *p = NULL;

		switch (input[1]) {
		case 'n':
			if (input[2] == ' ') {
				len = *input ? r_num_math (core->num, input+3) : 0;
				if (len > 0) {
					const ut64 cur_off = core->offset;
					cmd_suc = r_core_extend_at (core, core->offset, len);
					core->offset = cur_off;
					r_core_block_read (core);
				}
			}
			break;
		case 'N':
			if (input[2] == ' ') {
				input += 3;
				while (*input && *input == ' ') input++;
				addr = r_num_math (core->num, input);
				while (*input && *input != ' ') input++;
				input++;
				len = *input ? r_num_math (core->num, input) : 0;
				if (len > 0){
					ut64 cur_off = core->offset;
					cmd_suc = r_core_extend_at (core, addr, len);
					cmd_suc = r_core_seek (core, cur_off, 1);
					core->offset = addr;
					r_core_block_read (core);
				}
			}
			break;
		case 'x':
			if (input[2] == ' ') {
				input += 2;
				len = *input ? strlen (input) : 0;
				bytes = len > 1? malloc (len+1) : NULL;
				len = bytes ? r_hex_str2bin (input, bytes) : 0;
				if (len > 0) {
					ut64 cur_off = core->offset;
					cmd_suc = r_core_extend_at (core, cur_off, len);
					if (cmd_suc) {
						r_core_write_at (core, cur_off, bytes, len);
					}
					core->offset = cur_off;
					r_core_block_read (core);
				}
				free (bytes);
			}
			break;
		case 'X':
			if (input[2] == ' ') {
				addr = r_num_math (core->num, input+3);
				input += 3;
				while (*input && *input != ' ') input++;
				input++;
				len = *input ? strlen (input) : 0;
				bytes = len > 1? malloc (len+1) : NULL;
				len = bytes ? r_hex_str2bin (input, bytes) : 0;
				if (len > 0) {
					//ut64 cur_off = core->offset;
					cmd_suc = r_core_extend_at (core, addr, len);
					if (cmd_suc) {
						r_core_write_at (core, addr, bytes, len);
					}
					core->offset = addr;
					r_core_block_read (core);
				}
				free (bytes);
			}
			break;
		case 's':
			input +=  3;
			while (*input && *input == ' ') input++;
			len = strlen (input);
			input_shadow = len > 0? malloc (len+1): 0;

			// since the distance can be negative,
			// the r_num_math will perform an unwanted operation
			// the solution is to tokenize the string :/
			if (input_shadow) {
				strncpy (input_shadow, input, len+1);
				p = strtok (input_shadow, " ");
				addr = p && *p ? r_num_math (core->num, p) : 0;

				p = strtok (NULL, " ");
				dist = p && *p ? r_num_math (core->num, p) : 0;

				p = strtok (NULL, " ");
				b_size = p && *p ? r_num_math (core->num, p) : 0;
				if (dist != 0){
					r_core_shift_block (core, addr, b_size, dist);
					r_core_seek (core, addr, 1);
					cmd_suc = true;
				}
			}
			free (input_shadow);
			break;
		case '?':
		default:
			cmd_suc = false;
		}


		if (cmd_suc == false) {
			const char* help_msg[] = {
			"Usage", "", "write extend",
			"wen", " <num>", "insert num null bytes at current offset",
			"wex", " <hex_bytes>", "insert bytes at current offset",
			"weN", " <addr> <len>", "insert bytes at address",
			"weX", " <addr> <hex_bytes>", "insert bytes at address",
			"wes", " <addr>  <dist> <block_size>", "shift a blocksize left or write in the editor",
			NULL};
			r_core_cmd_help (core, help_msg);
		}
		}
		break;
	case 'p':
		if (input[1]=='-' || (input[1]==' ' && input[2]=='-')) {
			char *out = r_core_editor (core, NULL, NULL);
			if (out) {
				r_core_patch (core, out);
				free (out);
			}
		} else {
			if (input[1]==' ' && input[2]) {
				char *data = r_file_slurp (input+2, NULL);
				if (data) {
					r_core_patch (core, data);
					free (data);
				}
			} else {
				r_cons_printf ("Usage: wp [-|r2patch-file]\n"
					" ^# -> comments\n"
					" . -> execute command\n"
					" ! -> execute command\n"
					" OFFSET { code block }\n"
					" OFFSET \"string\"\n"
					" OFFSET 01020304\n"
					" OFFSET : assembly\n"
					" + {code}|\"str\"|0210|: asm\n");
			}
		}
		break;
	case 'u':
		// TODO: implement it in an API RCore.write_unified_hexpatch() is ETOOLONG
		if (input[1]==' ') {
			char *data = r_file_slurp (input+2, NULL);
			if (data) {
				char sign = ' ';
				int line = 0, offs = 0, hexa = 0;
				int newline = 1;
				for (i=0; data[i]; i++) {
					switch (data[i]) {
					case '+':
						if (newline)
							sign = 1;
						break;
					case '-':
						if (newline) {
							sign = 0;
							offs = i + ((data[i+1]==' ')?2:1);
						}
						break;
					case ' ':
						data[i] = 0;
						if (sign) {
							if (!line) line = i+1;
							else
							if (!hexa) hexa = i+1;
						}
						break;
					case '\r':
						break;
					case '\n':
						newline = 1;
						if (sign == -1) {
							offs = 0;
							line = 0;
							hexa = 0;
						} else if (sign) {
							if (offs && hexa) {
								r_cons_printf ("wx %s @ %s\n", data+hexa, data+offs);
							} else eprintf ("food\n");
							offs = 0;
							line = 0;
						} else hexa = 0;
						sign = -1;
						continue;
					}
					newline = 0;
				}
				free (data);
			}
		} else {
			eprintf ("|Usage: wu [unified-diff-patch]    # see 'cu'\n");
		}
		break;
	case 'r': //wr
		off = r_num_math (core->num, input+1);
		len = (int)off;
		if (len > 0) {
			buf = malloc (len);
			if (buf != NULL) {
				r_num_irand ();
				for (i=0; i<len; i++)
					buf[i] = r_num_rand (256);
				r_core_write_at (core, core->offset, buf, len);
				WSEEK (core, len);
				free (buf);
			} else eprintf ("Cannot allocate %d bytes\n", len);
		}
		break;
	case 'A':
		switch (input[1]) {
		case ' ':
			if (input[2] && input[3]==' ') {
				r_asm_set_pc (core->assembler, core->offset);
				eprintf ("modify (%c)=%s\n", input[2], input+4);
				len = r_asm_modify (core->assembler, core->block, input[2],
					r_num_math (core->num, input+4));
				eprintf ("len=%d\n", len);
				if (len>0) {
					r_core_write_at (core, core->offset, core->block, len);
					WSEEK (core, len);
				} else eprintf ("r_asm_modify = %d\n", len);
			} else eprintf ("Usage: wA [type] [value]\n");
			break;
		case '?':
		default:
			{
			const char* help_msg[] = {
				"Usage:", " wA", "[type] [value]",
				"Types", "", "",
				"r", "", "raw write value",
				"v", "", "set value (taking care of current address)",
				"d", "", "destination register",
				"0", "", "1st src register",
				"1", "", "2nd src register",
				"Example:",  "wA r 0", "# e800000000",
				NULL};
			r_core_cmd_help (core, help_msg);
			break;
			}
		}
		break;
	case 'c':
		switch (input[1]) {
		case 'i':
			r_io_cache_commit (core->io, 0, UT64_MAX);
			r_core_block_read (core);
			break;
		case 'r':
			r_io_cache_reset (core->io, true);
			/* Before loading the core block we have to make sure that if
			 * the cache wrote past the original EOF these changes are no
			 * longer displayed. */
			memset (core->block, 0xff, core->blocksize);
			r_core_block_read (core);
			break;
		case '+':
			if (input[2]=='*') {
				//r_io_cache_reset (core->io, true);
				eprintf ("TODO\n");
			} else if (input[2]==' ') {
				char *p = strchr (input+3, ' ');
				ut64 to, from;
				from = r_num_math (core->num, input+3);
				if (p) {
					*p = 0;
					to = r_num_math (core->num, input+3);
					if (to<from) {
						eprintf ("Invalid range (from>to)\n");
						return 0;
					}
				} else {
					to = from + core->blocksize;
				}
				r_io_cache_commit (core->io, from, to);
			} else {
				eprintf ("Invalidate write cache at 0x%08"PFMT64x"\n", core->offset);
				r_io_cache_commit (core->io, core->offset, core->offset+1);
			}
			break;
		case '-':
			if (input[2]=='*') {
				r_io_cache_reset (core->io, true);
			} else if (input[2]==' ') {
				char *p = strchr (input+3, ' ');
				ut64 to, from;
				if (p) {
					*p = 0;
					from = r_num_math (core->num, input+3);
					to = r_num_math (core->num, input+3);
					if (to<from) {
						eprintf ("Invalid range (from>to)\n");
						return 0;
					}
				} else {
					from = r_num_math (core->num, input+3);
					to = from + core->blocksize;
				}
				r_io_cache_invalidate (core->io, from, to);
			} else {
				eprintf ("Invalidate write cache at 0x%08"PFMT64x"\n", core->offset);
				r_io_cache_invalidate (core->io, core->offset, core->offset+core->blocksize);
			}
			/* See 'r' above. */
			memset (core->block, 0xff, core->blocksize);
			r_core_block_read (core);
			break;
		case '?':
			{
				const char* help_msg[] = {
					"Usage:", "wc[ir+-*?]","  # NOTE: Uses io.cache=true",
					"wc","","list all write changes",
					"wc-"," [from] [to]","remove write op at curseek or given addr",
					"wc+"," [addr]","commit change from cache to io",
					"wc*","","\"\" in radare commands",
					"wcr","","reset all write changes in cache",
					"wci","","commit write cache",
					NULL
				};
				r_core_cmd_help (core, help_msg);
			}
			break;
		case '*':
			r_io_cache_list (core->io, 1);
			break;
		case 'j':
			r_io_cache_list (core->io, 2);
			break;
		case '\0':
			//if (!r_config_get_i (core->config, "io.cache"))
			//	eprintf ("[warning] e io.cache must be true\n");
			r_io_cache_list (core->io, 0);
			break;
		}
		break;
	case ' ': // "w"
		/* write string */
		len = r_str_unescape (str);
		r_core_write_at (core, core->offset, (const ut8*)str, len);
#if 0
		r_io_use_desc (core->io, core->file->desc);
		r_io_write_at (core->io, core->offset, (const ut8*)str, len);
#endif
		WSEEK (core, len);
		r_core_block_read (core);
		break;
	case 'z': // "wz"
		/* write zero-terminated string */
		len = r_str_unescape (str);
		r_core_write_at (core, core->offset, (const ut8*)str + 1, len);
		if (len > 0) {
			core->num->value = len;
		} else {
			core->num->value = 0;
		}
#if 0
		r_io_use_desc (core->io, core->file->desc);
#endif
		WSEEK (core, len + 1);
		r_core_block_read (core);
		break;
	case 't': // "wt"
		if (*str == 's') { // "wts"
			if (str[1] == ' ') {
				eprintf ("Write to server\n");
				st64 sz = r_io_size (core->io);
				if (sz > 0) {
					ut64 addr = 0;
					char *host = str + 2;
					char *port = strchr (host, ':');
					if (port) {
						*port ++= 0;
						char *space = strchr (port, ' ');
						if (space) {
							*space++ = 0;
							sz = r_num_math (core->num, space);
							addr = core->offset;
						}
						ut8 *buf = calloc (1, sz);
						r_io_read_at (core->io, addr, buf, sz);
						RSocket *s = r_socket_new (false);
						if (r_socket_connect (s, host, port, R_SOCKET_PROTO_TCP, 0)) {
							int done = 0;
							eprintf ("Transfering file to the end-point...\n");
							while (done < sz) {
								int rc = r_socket_write (s, buf + done, sz - done);
								if (rc <1) {
									eprintf ("oops\n");
									break;
								}
								done += rc;
							}
						} else {
							eprintf ("Cannot connect\n");
						}
						r_socket_free (s);
						free (buf);
					} else {
						eprintf ("Usage wts host:port [sz]\n");
					}
				} else {
					eprintf ("Unknown file size\n");
				}
			} else {
				eprintf ("Usage wts host:port [sz]\n");
			}
		} else if (*str == '?' || *str == '\0') {
			const char* help_msg[] = {
				"Usage:", "wt[a] file [size]", " Write 'size' bytes in current blok to 'file'",
				"wta", " [filename]", "append to 'filename'",
				"wtf", " [filename] [size]", "write to file (see also 'wxf' and 'wf?')",
				"wtf!", " [filename]", "write to file from current addresss to eof",
				NULL};
			r_core_cmd_help (core, help_msg);
			free (ostr);
			return 0;
		} else {
			bool append = false;
			bool toend = false;
			st64 sz = core->blocksize;
			if (*str == 'f') { // "wtf"
				str++;
				if (*str == '!') {
					toend = true;
					str++;
				}
				if (*str) {
					filename = str + ((*str == ' ')? 1: 0);
				} else {
					filename = "";
				}
			} else if (*str=='a') { // "wta"
				append = 1;
				str++;
				if (str[0] == ' ') {
					filename = str + 1;
				} else {
					const char* prefix = r_config_get (core->config, "cfg.prefixdump");
					snprintf (_fn, sizeof (_fn), "%s.0x%08"PFMT64x, prefix, core->offset);
					filename = _fn;
				}
			} else if (*str != ' ') {
				const char* prefix = r_config_get (core->config, "cfg.prefixdump");
				snprintf (_fn, sizeof (_fn), "%s.0x%08"PFMT64x, prefix, core->offset);
				filename = _fn;
			} else {
				filename = str + 1;
			}
			tmp = strchr (str + 1, ' ');
			if (!filename || !*filename) {
				const char* prefix = r_config_get (core->config, "cfg.prefixdump");
				snprintf (_fn, sizeof (_fn), "%s.0x%08"PFMT64x, prefix, core->offset);
				filename = _fn;
			}
			if (tmp) {
				if (toend) {
					sz = r_io_desc_size (core->io, core->file->desc) - core->offset;
				} else {
					sz = (st64) r_num_math (core->num, tmp + 1);
					if (!sz) {
						sz = core->blocksize;
					}
					*tmp = 0;
				}
				if (sz < 1) {
					eprintf ("Invalid length\n");
				} else {
					r_core_dump (core, filename, core->offset, (ut64)sz, append);
				}
			} else {
				if (toend) {
					sz = r_io_desc_size (core->io, core->file->desc) - core->offset;
					r_core_dump (core, filename, core->offset, (ut64)sz, append);
				} else {
					if (!r_file_dump (filename, core->block, core->blocksize, append)) {
						sz = 0;
					} else {
						sz = core->blocksize;
					}
				}
			}
			eprintf ("Dumped %"PFMT64d" bytes from 0x%08"PFMT64x" into %s\n",
				sz, core->offset, filename);
		}
		break;
	case 'f':
		cmd_wf (core, input);
		break;
	case 'w':
		str++;
		len = (len - 1) << 1;
		tmp = (len > 0) ? malloc (len + 1) : NULL;
		if (tmp) {
			for (i=0; i<len; i++) {
				if (i%2) tmp[i] = 0;
				else tmp[i] = str[i>>1];
			}
			str = tmp;
			r_io_use_desc (core->io, core->file->desc);
			r_io_write_at (core->io, core->offset, (const ut8*)str, len);
			WSEEK (core, len);
			r_core_block_read (core);
			free (tmp);
		} else {
			eprintf ("Cannot malloc %d\n", len);
		}
		break;
	case 'x': // "wx"
		switch (input[1]) {
		case 'f': // "wxf"
			arg = (const char *)(input + ((input[2]==' ')? 3: 2));
			if (!strcmp (arg, "-")) {
				int len;
				ut8 *out;
				char *in = r_core_editor (core, NULL, NULL);
				if (in) {
					out = (ut8 *)strdup (in);
					if (out) {
						len = r_hex_str2bin (in, out);
						if (len > 0) {
							r_io_write_at (core->io, core->offset, out, len);
							core->num->value = len;
						} else {
							core->num->value = 0;
						}
						free (out);
					}
					free (in);
				}
			} else if (r_file_exists (arg)) {
				if ((buf = r_file_slurp_hexpairs (arg, &size))) {
					r_io_use_desc (core->io, core->file->desc);
					if (r_io_write_at (core->io, core->offset, buf, size) > 0) {
						core->num->value = size;
						WSEEK (core, size);
					}
					free (buf);
					r_core_block_read (core);
				} else {
					eprintf ("This file doesnt contains hexpairs\n");
				}
			} else {
				eprintf ("Cannot open file '%s'\n", arg);
			}
			break;
		case 's': // "wxs"
			{
				int len = cmd_write_hexpair (core, input + 2);
				if (len > 0) {
					r_core_seek_delta (core, len);
					core->num->value = len;
				} else {
					core->num->value = 0;
				}
			}
			break;
		case ' ': // "wx ..."
			cmd_write_hexpair (core, input + 1);
			break;
		default:
			{
			const char* help_msg[] = {
				"Usage:", "wx[f] [arg]", "",
				"wx", " 9090", "write two intel nops",
				"wxf", " -|file", "write contents of hexpairs file here",
				"wxs", " 9090", "write hexpairs and seek at the end",
				NULL};
			r_core_cmd_help (core, help_msg);
			break;
			}
		}
		break;
	case 'a': // "wa"
		switch (input[1]) {
		case 'o': // "wao"
			if (input[2] == ' ')
				r_core_hack (core, input+3);
			else r_core_hack_help (core);
			break;
		case ' ':
		case '*':
			{ const char *file = input[1]=='*'? input+2: input+1;
			RAsmCode *acode;
			r_asm_set_pc (core->assembler, core->offset);
			acode = r_asm_massemble (core->assembler, file);
			if (acode) {
				if (input[1]=='*') {
					cmd_write_hexpair(core, acode->buf_hex);
				} else {
					if (r_config_get_i (core->config, "scr.prompt"))
						eprintf ("Written %d bytes (%s) = wx %s\n", acode->len, input+2, acode->buf_hex);
					r_core_write_at (core, core->offset, acode->buf, acode->len);
					WSEEK (core, acode->len);
					r_core_block_read (core);
				}
				r_asm_code_free (acode);
			}
			} break;
		case 'f': // "wof"
			if ((input[2]==' '||input[2]=='*')) {
				const char *file = input[2]=='*'? input+4: input+3;
				RAsmCode *acode;
				r_asm_set_pc (core->assembler, core->offset);
				acode = r_asm_assemble_file (core->assembler, file);
				if (acode) {
					if (input[2]=='*') {
						cmd_write_hexpair(core, acode->buf_hex);
					} else {
						if (r_config_get_i (core->config, "scr.prompt"))
						eprintf ("Written %d bytes (%s)=wx %s\n", acode->len, input+1, acode->buf_hex);
						r_core_write_at (core, core->offset, acode->buf, acode->len);
						WSEEK (core, acode->len);
						r_core_block_read (core);
					}
					r_asm_code_free (acode);
				} else eprintf ("Cannot assemble file\n");
			} else eprintf ("Wrong argument\n");
			break;
		default:
			{
			const char* help_msg[] = {
				"Usage:", "wa[of*] [arg]", "",
				"wa", " nop", "write nopcode using asm.arch and asm.bits",
				"wa*", " mov eax, 33", "show 'wx' op with hexpair bytes of assembled opcode",
				"\"wa nop;nop\"", "" , "assemble more than one instruction (note the quotes)",
				"waf", "foo.asm" , "assemble file and write bytes",
				"wao?", "", "show help for assembler operation on current opcode (hack)",
				NULL};
			r_core_cmd_help (core, help_msg);
			break;
			}
		}
		break;
	case 'b': // "wb"
		{
		int len = strlen (input);
		ut8 *buf = malloc (len+1);
		if (buf) {
			len = r_hex_str2bin (input+1, buf);
			if (len > 0) {
				r_mem_copyloop (core->block, buf, core->blocksize, len);
				r_core_write_at (core, core->offset, core->block, core->blocksize);
				WSEEK (core, core->blocksize);
				r_core_block_read (core);
			} else eprintf ("Wrong argument\n");
			free (buf);
		} else eprintf ("Cannot malloc %d\n", len+1);
		}
		break;
	case 'm':
		size = r_hex_str2bin (input+1, (ut8*)str);
		switch (input[1]) {
		case '\0':
			eprintf ("Current write mask: TODO\n");
			// TODO
			break;
		case '?':
			break;
		case '-':
			r_io_set_write_mask (core->io, 0, 0);
			eprintf ("Write mask disabled\n");
			break;
		case ' ':
			if (size>0) {
				r_io_use_desc (core->io, core->file->desc);
				r_io_set_write_mask (core->io, (const ut8*)str, size);
				WSEEK (core, size);
				eprintf ("Write mask set to '");
				for (i=0; i<size; i++)
					eprintf ("%02x", str[i]);
				eprintf ("'\n");
			} else eprintf ("Invalid string\n");
			break;
		}
		break;
	case 'v':
		cmd_write_value (core, input);
		break;
	case 'o':
		cmd_write_op (core, input);
		break;
	case 'd':
		if (input[1] && input[1]==' ') {
			char *arg, *inp = strdup (input+2);
			arg = strchr (inp, ' ');
			if (arg) {
				*arg = 0;
				ut64 addr = r_num_math (core->num, input+2);
				ut64 len = r_num_math (core->num, arg+1);
				ut8 *data = malloc (len);
				r_io_read_at (core->io, addr, data, len);
				r_io_write_at (core->io, core->offset, data, len);
				free (data);
			} else eprintf ("See wd?\n");
			free (inp);
		} else eprintf ("Usage: wd [source-offset] [length] @ [dest-offset]\n");
		break;
	case 's':
		if (str && *str && str[1]) {
			len = r_str_unescape (str+1);
			if (len>255) {
				eprintf ("Too large\n");
			} else {
				ut8 ulen = (ut8)len;
				r_core_write_at (core, core->offset, &ulen, 1);
				r_core_write_at (core, core->offset+1, (const ut8*)str+1, len);
				WSEEK (core, len);
				r_core_block_read (core);
			}
		} else eprintf ("Too short.\n");
		break;
	default:
	case '?':
		if (core->oobi) {
			eprintf ("Writing oobi buffer!\n");
			r_io_use_desc (core->io, core->file->desc);
			r_io_write (core->io, core->oobi, core->oobi_len);
			WSEEK (core, core->oobi_len);
			r_core_block_read (core);
		} else {
			r_core_cmd_help (core, help_msg);
		}
		break;
	}
Ejemplo n.º 13
0
R_API int r_socket_connect (RSocket *s, const char *host, const char *port, int proto) {
#if __WINDOWS__
	struct sockaddr_in sa;
	struct hostent *he;
	WSADATA wsadata;
	if (WSAStartup (MAKEWORD (1, 1), &wsadata) == SOCKET_ERROR) {
		eprintf ("Error creating socket.");
		return R_FALSE;
	}
	s->fd = socket (AF_INET, SOCK_STREAM, 0);
	if (s->fd == -1)
		return R_FALSE;

	memset (&sa, 0, sizeof(sa));
	sa.sin_family = AF_INET;
	he = (struct hostent *)gethostbyname (host);
	if (he == (struct hostent*)0) {
		close (s->fd);
		return R_FALSE;
	}

	sa.sin_addr = *((struct in_addr *)he->h_addr);
	sa.sin_port = htons (atoi (port));

	if (connect (s->fd, (const struct sockaddr*)&sa, sizeof (struct sockaddr))) {
		close (s->fd);
		return R_FALSE;
	}
	return R_TRUE;
#elif __UNIX__
	int gai;
	struct addrinfo hints, *res, *rp;
	signal (SIGPIPE, SIG_IGN);
	if (proto == R_SOCKET_PROTO_UNIX) {
		if (!r_socket_unix_connect (s, host))
			return R_FALSE;
	} else {
		memset (&hints, 0, sizeof (struct addrinfo));
		hints.ai_family = AF_UNSPEC;		/* Allow IPv4 or IPv6 */
		hints.ai_protocol = proto;
		gai = getaddrinfo (host, port, &hints, &res);
		if (gai != 0) {
			eprintf ("Error in getaddrinfo: %s\n", gai_strerror (gai));
			return R_FALSE;
		}
		for (rp = res; rp != NULL; rp = rp->ai_next) {
			s->fd = socket (rp->ai_family, rp->ai_socktype, rp->ai_protocol);
			if (s->fd == -1)
				continue;
			if (connect (s->fd, rp->ai_addr, rp->ai_addrlen) != -1)
				break;
			close (s->fd);
		}
		if (rp == NULL) {
			eprintf ("Could not connect\n");
			return R_FALSE;
		}
		freeaddrinfo (res);
	}
#endif
#if HAVE_LIB_SSL
	if (s->is_ssl) {
		s->ctx = SSL_CTX_new (SSLv23_client_method ());
		if (s->ctx == NULL) {
			r_socket_free (s);
			return R_FALSE;
		}
		s->sfd = SSL_new (s->ctx);
		SSL_set_fd (s->sfd, s->fd);
		if (SSL_connect (s->sfd) != 1) {
			r_socket_free (s);
			return R_FALSE;
		}
	}
#endif
	return R_TRUE;
}
Ejemplo n.º 14
0
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;
}
Ejemplo n.º 15
0
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);
}