Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add functionality to write to a temp file through url arguments #747

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
4 changes: 4 additions & 0 deletions man/ttyd.1
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ Cross platform: macOS, Linux, FreeBSD/OpenBSD, OpenWrt/LEDE, Windows
Allow client to send command line arguments in URL (eg:
\[la]http://localhost:7681?arg=foo&arg=bar\[ra])

.PP
\-f, \-\-arg\-file
Allow client to write URL arguments to a temporary file; the file name is then passed in as a command line argument

.PP
\-R, \-\-readonly
Do not allow clients to write to the TTY
Expand Down
3 changes: 3 additions & 0 deletions man/ttyd.man.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ ttyd 1 "September 2016" ttyd "User Manual"
-a, --url-arg
Allow client to send command line arguments in URL (eg: http://localhost:7681?arg=foo&arg=bar)

-f, --arg-file
Allow client to write URL arguments to a temporary file; the file name is then passed in as a command line argument

-R, --readonly
Do not allow clients to write to the TTY

Expand Down
27 changes: 24 additions & 3 deletions src/protocol.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,30 @@ static bool spawn_process(struct pss_tty *pss, uint16_t columns, uint16_t rows)
for (i = 0; i < server->argc; i++) {
argv[n++] = server->argv[i];
}
for (i = 0; i < pss->argc; i++) {
argv[n++] = pss->args[i];
if (server->url_arg) {
for (i = 0; i < pss->argc; i++) {
argv[n++] = pss->args[i];
}
}
else if (server->arg_file) {
int fd = -1;
char filePath[] = "/tmp/XXXXXX";

if ((fd = mkstemp(filePath)) == -1) {
lwsl_err("Creation of temp file failed with error: %d (%s)\n", errno, strerror(errno));
return false;
}

for (i = 0; i < pss->argc; i++) {
if (dprintf(fd, "%s\n", pss->args[i]) < 0) {
lwsl_err("Write to temp file failed with error: %d (%s)\n", errno, strerror(errno));
return false;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will leak fd too.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

filePath is not freed too.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

}
}

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need to close the file

argv[n++] = filePath;
}

argv[n] = NULL;

pty_process *process = process_init((void *) pss, server->loop, argv);
Expand Down Expand Up @@ -178,7 +199,7 @@ int callback_tty(struct lws *wsi, enum lws_callback_reasons reason, void *user,
pss->wsi = wsi;
pss->lws_close_status = LWS_CLOSE_STATUS_NOSTATUS;

if (server->url_arg) {
if (server->url_arg || server->arg_file) {
while (lws_hdr_copy_fragment(wsi, buf, sizeof(buf), WSI_TOKEN_HTTP_URI_ARGS, n++) > 0) {
if (strncmp(buf, "arg=", 4) == 0) {
pss->args = xrealloc(pss->args, (pss->argc + 1) * sizeof(char *));
Expand Down
14 changes: 11 additions & 3 deletions src/server.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ static const struct option options[] = {
{"ssl-key", required_argument, NULL, 'K'},
{"ssl-ca", required_argument, NULL, 'A'},
{"url-arg", no_argument, NULL, 'a'},
{"arg-file", no_argument, NULL, 'f'},
{"readonly", no_argument, NULL, 'R'},
{"terminal-type", required_argument, NULL, 'T'},
{"client-option", required_argument, NULL, 't'},
Expand All @@ -86,10 +87,10 @@ static const struct option options[] = {
{NULL, 0, 0, 0}};

#if LWS_LIBRARY_VERSION_NUMBER < 4000000
static const char *opt_string = "p:i:c:u:g:s:I:b:6aSC:K:A:Rt:T:Om:oBd:vh";
static const char *opt_string = "p:i:c:u:g:s:I:b:6afSC:K:A:Rt:T:Om:oBd:vh";
#endif
#if LWS_LIBRARY_VERSION_NUMBER >= 4000000
static const char *opt_string = "p:i:c:u:g:s:I:b:P:6aSC:K:A:Rt:T:Om:oBd:vh";
static const char *opt_string = "p:i:c:u:g:s:I:b:P:6afSC:K:A:Rt:T:Om:oBd:vh";
#endif

static void print_help() {
Expand All @@ -107,6 +108,7 @@ static void print_help() {
" -g, --gid Group id to run with\n"
" -s, --signal Signal to send to the command when exit it (default: 1, SIGHUP)\n"
" -a, --url-arg Allow client to send command line arguments in URL (eg: http://localhost:7681?arg=foo&arg=bar)\n"
" -f, --arg-file Allow client to write URL arguments to a temporary file; the file name is then passed in as a command line argument\n"
" -R, --readonly Do not allow clients to write to the TTY\n"
" -t, --client-option Send option to client (format: key=value), repeat to add more options\n"
" -T, --terminal-type Terminal type to report, default: xterm-256color\n"
Expand Down Expand Up @@ -321,6 +323,11 @@ int main(int argc, char **argv) {
break;
case 'a':
server->url_arg = true;
server->arg_file = false;
break;
case 'f':
server->arg_file = true;
server->url_arg = false;
break;
case 'R':
server->readonly = true;
Expand Down Expand Up @@ -537,7 +544,8 @@ int main(int argc, char **argv) {
lwsl_notice(" websocket: %s\n", endpoints.ws);
}
if (server->check_origin) lwsl_notice(" check origin: true\n");
if (server->url_arg) lwsl_notice(" allow url arg: true\n");
if (server->url_arg) lwsl_notice(" allow url arg to cli arg: true\n");
if (server->arg_file) lwsl_notice(" allow url arg to tmp file: true\n");
if (server->readonly) lwsl_notice(" readonly: true\n");
if (server->max_clients > 0)
lwsl_notice(" max clients: %d\n", server->max_clients);
Expand Down
1 change: 1 addition & 0 deletions src/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ struct server {
int sig_code; // close signal
char sig_name[20]; // human readable signal string
bool url_arg; // allow client to send cli arguments in URL
bool arg_file; // allow client to write to a temp file through URL arguments
bool readonly; // whether not allow clients to write to the TTY
bool check_origin; // whether allow websocket connection from different origin
int max_clients; // maximum clients to support
Expand Down