{'E', 0, "step-through-eval"},
#ifndef _WIN32
{'l', 1, "listen"},
+ {'a', 1, "address-or-any"},
#endif
{'-', 0, NULL}
}; /* }}} */
} /* }}} */
#ifndef _WIN32
-int phpdbg_open_socket(short port) /* {{{ */
+int phpdbg_open_socket(const char *interface, short port) /* {{{ */
{
int fd = socket(AF_INET, SOCK_STREAM, 0);
address.sin_port = htons(port);
address.sin_family = AF_INET;
- if (!inet_pton(AF_INET, "127.0.0.1", &address.sin_addr)) {
+ if ((*interface == '*')) {
+ address.sin_addr.s_addr = htonl(INADDR_ANY);
+ } else if (!inet_pton(AF_INET, interface, &address.sin_addr)) {
close(fd);
return -3;
}
/* don't inline this, want to debug it easily, will inline when done */
-int phpdbg_open_sockets(int port[2], int (*listen)[2], int (*socket)[2], FILE* streams[2]) /* {{{ */
+int phpdbg_open_sockets(char *address, int port[2], int (*listen)[2], int (*socket)[2], FILE* streams[2]) /* {{{ */
{
if (((*listen)[0]) < 0 && ((*listen)[1]) < 0) {
- ((*listen)[0]) = phpdbg_open_socket((short)port[0]);
- ((*listen)[1]) = phpdbg_open_socket((short)port[1]);
+ ((*listen)[0]) = phpdbg_open_socket(address, (short)port[0]);
+ ((*listen)[1]) = phpdbg_open_socket(address, (short)port[1]);
}
streams[0] = NULL;
int step = 0;
char *bp_tmp_file;
#ifndef _WIN32
+ char *address;
int listen[2];
int server[2];
int socket[2];
#endif
#ifndef _WIN32
+ address = strdup("127.0.0.1");
socket[0] = -1;
socket[1] = -1;
listen[0] = -1;
/* if you pass a listen port, we will accept input on listen port */
/* and write output to listen port * 2 */
- case 'l': { /* set listen settings */
+ case 'l': { /* set listen ports */
if (sscanf(php_optarg, "%d/%d", &listen[0], &listen[1]) != 2) {
if (sscanf(php_optarg, "%d", &listen[0]) != 1) {
/* default to hardcoded ports */
}
}
} break;
+
+ case 'a': { /* set bind address */
+ free(address);
+ if (!php_optarg) {
+ address = strdup("*");
+ } else address = strdup(php_optarg);
+ } break;
#endif
}
}
/* setup remote server if necessary */
if (!cleaning &&
(listen[0] > 0 && listen[1] > 0)) {
- if (phpdbg_open_sockets(listen, &server, &socket, streams) == FAILURE) {
+ if (phpdbg_open_sockets(address, listen, &server, &socket, streams) == FAILURE) {
remote = 0;
exit(0);
}
/* renegociate connections */
phpdbg_open_sockets(
- listen, &server, &socket, streams);
+ address, listen, &server, &socket, streams);
/* set streams */
if (streams[0] && streams[1]) {
goto phpdbg_interact;
}
#endif
+
if (ini_entries) {
free(ini_entries);
}
/* bugggy */
/* tsrm_shutdown(); */
#endif
+
+#ifndef _WIN32
+ if (address) {
+ free(address);
+ }
+#endif
free(bp_tmp_file);
phpdbg_writeln(" -O\t-Omy.oplog\t\tSets oplog output file");
phpdbg_writeln(" -r\tN/A\t\t\tRun execution context");
phpdbg_writeln(" -E\tN/A\t\t\tEnable step through eval, careful !");
- phpdbg_writeln(" -l\t-l4000\t\t\tSetup remote console, see docs");
+#ifndef _WIN32
+ phpdbg_writeln(" -l\t-l4000\t\t\tSetup remote console ports");
+ phpdbg_writeln(" -a\t-a192.168.0.3\t\tSetup remote console bind address");
+#endif
phpdbg_notice("Passing -rr will quit automatically after execution");
+#ifndef _WIN32
+ phpdbg_writeln("Remote Console Mode");
+ phpdbg_notice("For security, phpdbg will bind only to the loopback interface by default");
+ phpdbg_writeln("-a without an argument implies all; phpdbg will bind to all available interfaces.");
+ phpdbg_writeln("specify both stdin and stdout with -lstdin/stdout; by default stdout is stdin * 2.");
+ phpdbg_notice("Steps should be taken to secure this service if bound to a public interface/port");
+#endif
phpdbg_help_footer();
return SUCCESS;
} /* }}} */