mirror of
https://github.com/tmate-io/tmate.git
synced 2024-11-07 16:54:01 +01:00
Remove the internal tmux locking and instead detach each client and run the
command specified by a new option "lock-command" (by default "lock -np") in each client. This means each terminal has to be unlocked individually but simplifies the code and allows the system password to be used to unlock. Note that the set-password command is gone, so it will need to be removed from configuration files, and the -U command line flag has been removed. This is the third protocol version change so again it is best to stop the tmux server before upgrading.
This commit is contained in:
parent
962fa20b36
commit
b01dcd7971
2
Makefile
2
Makefile
@ -20,7 +20,7 @@ SRCS= attributes.c buffer-poll.c buffer.c cfg.c client-fn.c \
|
||||
cmd-scroll-mode.c cmd-select-layout.c cmd-select-pane.c \
|
||||
cmd-select-prompt.c cmd-select-window.c cmd-send-keys.c \
|
||||
cmd-send-prefix.c cmd-server-info.c cmd-set-buffer.c cmd-set-option.c \
|
||||
cmd-set-password.c cmd-set-window-option.c cmd-show-buffer.c \
|
||||
cmd-set-window-option.c cmd-show-buffer.c \
|
||||
cmd-show-options.c cmd-show-window-options.c cmd-source-file.c \
|
||||
cmd-split-window.c cmd-start-server.c cmd-string.c cmd-if-shell.c \
|
||||
cmd-run-shell.c cmd-suspend-client.c cmd-swap-pane.c cmd-swap-window.c \
|
||||
|
10
client.c
10
client.c
@ -242,6 +242,7 @@ client_msg_dispatch(struct client_ctx *cctx)
|
||||
{
|
||||
struct imsg imsg;
|
||||
struct msg_print_data printdata;
|
||||
struct msg_lock_data lockdata;
|
||||
ssize_t n, datalen;
|
||||
|
||||
for (;;) {
|
||||
@ -295,6 +296,15 @@ client_msg_dispatch(struct client_ctx *cctx)
|
||||
|
||||
client_suspend();
|
||||
break;
|
||||
case MSG_LOCK:
|
||||
if (datalen != sizeof lockdata)
|
||||
fatalx("bad MSG_LOCK size");
|
||||
memcpy(&lockdata, imsg.data, sizeof lockdata);
|
||||
|
||||
lockdata.cmd[(sizeof lockdata.cmd) - 1] = '\0';
|
||||
system(lockdata.cmd);
|
||||
client_write_server(cctx, MSG_UNLOCK, NULL, 0);
|
||||
break;
|
||||
default:
|
||||
fatalx("unexpected message");
|
||||
}
|
||||
|
@ -62,6 +62,7 @@ const struct set_option_entry set_option_table[] = {
|
||||
{ "display-time", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
|
||||
{ "history-limit", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
|
||||
{ "lock-after-time", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
|
||||
{ "lock-command", SET_OPTION_STRING, 0, 0, NULL },
|
||||
{ "message-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
|
||||
{ "message-bg", SET_OPTION_COLOUR, 0, 0, NULL },
|
||||
{ "message-fg", SET_OPTION_COLOUR, 0, 0, NULL },
|
||||
|
@ -1,145 +0,0 @@
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <pwd.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "tmux.h"
|
||||
|
||||
/*
|
||||
* Set server password.
|
||||
*/
|
||||
|
||||
int cmd_set_password_parse(struct cmd *, int, char **, char **);
|
||||
int cmd_set_password_exec(struct cmd *, struct cmd_ctx *);
|
||||
void cmd_set_password_free(struct cmd *);
|
||||
void cmd_set_password_init(struct cmd *, int);
|
||||
size_t cmd_set_password_print(struct cmd *, char *, size_t);
|
||||
|
||||
struct cmd_set_password_data {
|
||||
char *password;
|
||||
int flag_encrypted;
|
||||
};
|
||||
|
||||
const struct cmd_entry cmd_set_password_entry = {
|
||||
"set-password", "pass",
|
||||
"[-c] password",
|
||||
0, 0,
|
||||
cmd_set_password_init,
|
||||
cmd_set_password_parse,
|
||||
cmd_set_password_exec,
|
||||
cmd_set_password_free,
|
||||
cmd_set_password_print
|
||||
};
|
||||
|
||||
void
|
||||
cmd_set_password_init(struct cmd *self, unused int arg)
|
||||
{
|
||||
struct cmd_set_password_data *data;
|
||||
|
||||
self->data = data = xmalloc(sizeof *data);
|
||||
data->password = NULL;
|
||||
data->flag_encrypted = 0;
|
||||
}
|
||||
|
||||
int
|
||||
cmd_set_password_parse(struct cmd *self, int argc, char **argv, char **cause)
|
||||
{
|
||||
struct cmd_set_password_data *data;
|
||||
int opt;
|
||||
char *out;
|
||||
|
||||
self->entry->init(self, KEYC_NONE);
|
||||
data = self->data;
|
||||
|
||||
while ((opt = getopt(argc, argv, "c")) != -1) {
|
||||
switch (opt) {
|
||||
case 'c':
|
||||
data->flag_encrypted = 1;
|
||||
break;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
if (argc != 1)
|
||||
goto usage;
|
||||
|
||||
if (!data->flag_encrypted) {
|
||||
if ((out = crypt(argv[0], "$1")) != NULL)
|
||||
data->password = xstrdup(out);
|
||||
} else
|
||||
data->password = xstrdup(argv[0]);
|
||||
|
||||
return (0);
|
||||
|
||||
usage:
|
||||
xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
|
||||
|
||||
self->entry->free(self);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
cmd_set_password_exec(struct cmd *self, struct cmd_ctx *ctx)
|
||||
{
|
||||
struct cmd_set_password_data *data = self->data;
|
||||
|
||||
if (data->password == NULL) {
|
||||
ctx->error(ctx, "failed to encrypt password");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (server_password != NULL)
|
||||
xfree(server_password);
|
||||
if (*data->password == '\0')
|
||||
server_password = NULL;
|
||||
else
|
||||
server_password = xstrdup(data->password);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
cmd_set_password_free(struct cmd *self)
|
||||
{
|
||||
struct cmd_set_password_data *data = self->data;
|
||||
|
||||
if (data->password != NULL)
|
||||
xfree(data->password);
|
||||
xfree(data);
|
||||
}
|
||||
|
||||
size_t
|
||||
cmd_set_password_print(struct cmd *self, char *buf, size_t len)
|
||||
{
|
||||
struct cmd_set_password_data *data = self->data;
|
||||
size_t off = 0;
|
||||
|
||||
off += xsnprintf(buf, len, "%s", self->entry->name);
|
||||
if (data == NULL)
|
||||
return (off);
|
||||
if (off < len && data->flag_encrypted)
|
||||
off += xsnprintf(buf + off, len - off, " -c");
|
||||
if (off < len && data->password != NULL)
|
||||
off += xsnprintf(buf + off, len - off, " password");
|
||||
return (off);
|
||||
}
|
5
cmd.c
5
cmd.c
@ -89,7 +89,6 @@ const struct cmd_entry *cmd_table[] = {
|
||||
&cmd_set_buffer_entry,
|
||||
&cmd_set_environment_entry,
|
||||
&cmd_set_option_entry,
|
||||
&cmd_set_password_entry,
|
||||
&cmd_set_window_option_entry,
|
||||
&cmd_show_buffer_entry,
|
||||
&cmd_show_environment_entry,
|
||||
@ -260,10 +259,6 @@ usage:
|
||||
int
|
||||
cmd_exec(struct cmd *cmd, struct cmd_ctx *ctx)
|
||||
{
|
||||
if (server_locked) {
|
||||
ctx->error(ctx, "server is locked");
|
||||
return (-1);
|
||||
}
|
||||
return (cmd->entry->exec(cmd, ctx));
|
||||
}
|
||||
|
||||
|
110
server-fn.c
110
server-fn.c
@ -18,16 +18,12 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <login_cap.h>
|
||||
#include <pwd.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "tmux.h"
|
||||
|
||||
int server_lock_callback(void *, const char *);
|
||||
|
||||
void
|
||||
server_fill_environ(struct session *s, struct environ *env)
|
||||
{
|
||||
@ -161,110 +157,30 @@ server_status_window(struct window *w)
|
||||
void
|
||||
server_lock(void)
|
||||
{
|
||||
struct client *c;
|
||||
static struct passwd *pw, pwstore;
|
||||
static char pwbuf[_PW_BUF_LEN];
|
||||
u_int i;
|
||||
|
||||
if (server_locked)
|
||||
return;
|
||||
|
||||
if (getpwuid_r(getuid(), &pwstore, pwbuf, sizeof pwbuf, &pw) != 0) {
|
||||
server_locked_pw = NULL;
|
||||
return;
|
||||
}
|
||||
server_locked_pw = pw;
|
||||
struct client *c;
|
||||
const char *cmd;
|
||||
struct msg_lock_data lockdata;
|
||||
u_int i;
|
||||
|
||||
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
||||
c = ARRAY_ITEM(&clients, i);
|
||||
if (c == NULL || c->session == NULL)
|
||||
continue;
|
||||
|
||||
status_prompt_clear(c);
|
||||
status_prompt_set(c,
|
||||
"Password:", server_lock_callback, NULL, c, PROMPT_HIDDEN);
|
||||
server_redraw_client(c);
|
||||
}
|
||||
|
||||
server_locked = 1;
|
||||
}
|
||||
|
||||
int
|
||||
server_lock_callback(unused void *data, const char *s)
|
||||
{
|
||||
return (server_unlock(s));
|
||||
}
|
||||
|
||||
int
|
||||
server_unlock(const char *s)
|
||||
{
|
||||
struct client *c;
|
||||
login_cap_t *lc;
|
||||
u_int i;
|
||||
char *out;
|
||||
u_int failures, tries, backoff;
|
||||
|
||||
if (!server_locked || server_locked_pw == NULL)
|
||||
return (0);
|
||||
server_activity = time(NULL);
|
||||
if (server_activity < password_backoff)
|
||||
return (-2);
|
||||
|
||||
if (server_password != NULL) {
|
||||
if (s == NULL)
|
||||
return (-1);
|
||||
out = crypt(s, server_password);
|
||||
if (strcmp(out, server_password) != 0)
|
||||
goto wrong;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
||||
c = ARRAY_ITEM(&clients, i);
|
||||
if (c == NULL)
|
||||
if (c->flags & CLIENT_SUSPENDED)
|
||||
continue;
|
||||
|
||||
status_prompt_clear(c);
|
||||
server_redraw_client(c);
|
||||
}
|
||||
|
||||
server_locked = 0;
|
||||
password_failures = 0;
|
||||
password_backoff = 0;
|
||||
return (0);
|
||||
|
||||
wrong:
|
||||
password_failures++;
|
||||
password_backoff = 0;
|
||||
|
||||
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
||||
c = ARRAY_ITEM(&clients, i);
|
||||
if (c == NULL || c->prompt_buffer == NULL)
|
||||
cmd = options_get_string(&c->session->options, "lock-command");
|
||||
if (strlcpy(lockdata.cmd,
|
||||
cmd, sizeof lockdata.cmd) >= sizeof lockdata.cmd)
|
||||
continue;
|
||||
|
||||
*c->prompt_buffer = '\0';
|
||||
c->prompt_index = 0;
|
||||
server_redraw_client(c);
|
||||
}
|
||||
tty_stop_tty(&c->tty);
|
||||
tty_raw(&c->tty, tty_term_string(c->tty.term, TTYC_SMCUP));
|
||||
tty_raw(&c->tty, tty_term_string(c->tty.term, TTYC_CLEAR));
|
||||
|
||||
/*
|
||||
* Start slowing down after "login-backoff" attempts and reset every
|
||||
* "login-tries" attempts.
|
||||
*/
|
||||
lc = login_getclass(server_locked_pw->pw_class);
|
||||
if (lc != NULL) {
|
||||
tries = login_getcapnum(lc, (char *) "login-tries", 10, 10);
|
||||
backoff = login_getcapnum(lc, (char *) "login-backoff", 3, 3);
|
||||
} else {
|
||||
tries = 10;
|
||||
backoff = 3;
|
||||
c->flags |= CLIENT_SUSPENDED;
|
||||
server_write_client(c, MSG_LOCK, &lockdata, sizeof lockdata);
|
||||
}
|
||||
failures = password_failures % tries;
|
||||
if (failures > backoff) {
|
||||
password_backoff =
|
||||
server_activity + ((failures - backoff) * tries / 2);
|
||||
return (-2);
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
void
|
||||
|
21
server-msg.c
21
server-msg.c
@ -40,7 +40,6 @@ server_msg_dispatch(struct client *c)
|
||||
struct imsg imsg;
|
||||
struct msg_command_data commanddata;
|
||||
struct msg_identify_data identifydata;
|
||||
struct msg_unlock_data unlockdata;
|
||||
struct msg_environ_data environdata;
|
||||
ssize_t n, datalen;
|
||||
|
||||
@ -95,31 +94,15 @@ server_msg_dispatch(struct client *c)
|
||||
tty_close(&c->tty);
|
||||
server_write_client(c, MSG_EXITED, NULL, 0);
|
||||
break;
|
||||
case MSG_UNLOCK:
|
||||
if (datalen != sizeof unlockdata)
|
||||
fatalx("bad MSG_UNLOCK size");
|
||||
memcpy(&unlockdata, imsg.data, sizeof unlockdata);
|
||||
|
||||
unlockdata.pass[(sizeof unlockdata.pass) - 1] = '\0';
|
||||
switch (server_unlock(unlockdata.pass)) {
|
||||
case -1:
|
||||
server_write_error(c, "bad password");
|
||||
break;
|
||||
case -2:
|
||||
server_write_error(c,
|
||||
"too many bad passwords, sleeping");
|
||||
break;
|
||||
}
|
||||
memset(&unlockdata, 0, sizeof unlockdata);
|
||||
server_write_client(c, MSG_EXIT, NULL, 0);
|
||||
break;
|
||||
case MSG_WAKEUP:
|
||||
case MSG_UNLOCK:
|
||||
if (datalen != 0)
|
||||
fatalx("bad MSG_WAKEUP size");
|
||||
|
||||
c->flags &= ~CLIENT_SUSPENDED;
|
||||
tty_start_tty(&c->tty);
|
||||
server_redraw_client(c);
|
||||
server_activity = time(NULL);
|
||||
break;
|
||||
case MSG_ENVIRON:
|
||||
if (datalen != sizeof environdata)
|
||||
|
83
server.c
83
server.c
@ -67,7 +67,6 @@ void server_lost_client(struct client *);
|
||||
void server_check_window(struct window *);
|
||||
void server_check_redraw(struct client *);
|
||||
void server_set_title(struct client *);
|
||||
void server_redraw_locked(struct client *);
|
||||
void server_check_timers(struct client *);
|
||||
void server_second_timers(void);
|
||||
int server_update_socket(void);
|
||||
@ -160,8 +159,6 @@ server_start(char *path)
|
||||
key_bindings_init();
|
||||
utf8_build();
|
||||
|
||||
server_locked = 0;
|
||||
server_password = NULL;
|
||||
server_activity = time(NULL);
|
||||
|
||||
start_time = time(NULL);
|
||||
@ -382,8 +379,6 @@ server_main(int srv_fd)
|
||||
|
||||
options_free(&global_s_options);
|
||||
options_free(&global_w_options);
|
||||
if (server_password != NULL)
|
||||
xfree(server_password);
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -541,10 +536,7 @@ server_check_redraw(struct client *c)
|
||||
}
|
||||
|
||||
if (c->flags & CLIENT_REDRAW) {
|
||||
if (server_locked)
|
||||
server_redraw_locked(c);
|
||||
else
|
||||
screen_redraw_screen(c, 0);
|
||||
screen_redraw_screen(c, 0);
|
||||
c->flags &= ~CLIENT_STATUS;
|
||||
} else {
|
||||
TAILQ_FOREACH(wp, &c->session->curw->window->panes, entry) {
|
||||
@ -581,49 +573,6 @@ server_set_title(struct client *c)
|
||||
xfree(title);
|
||||
}
|
||||
|
||||
/* Redraw client when locked. */
|
||||
void
|
||||
server_redraw_locked(struct client *c)
|
||||
{
|
||||
struct screen_write_ctx ctx;
|
||||
struct screen screen;
|
||||
struct grid_cell gc;
|
||||
u_int colour, xx, yy, i;
|
||||
int style;
|
||||
|
||||
xx = c->tty.sx;
|
||||
yy = c->tty.sy - 1;
|
||||
if (xx == 0 || yy == 0)
|
||||
return;
|
||||
colour = options_get_number(&global_w_options, "clock-mode-colour");
|
||||
style = options_get_number(&global_w_options, "clock-mode-style");
|
||||
|
||||
memcpy(&gc, &grid_default_cell, sizeof gc);
|
||||
colour_set_fg(&gc, colour);
|
||||
gc.attr |= GRID_ATTR_BRIGHT;
|
||||
|
||||
screen_init(&screen, xx, yy, 0);
|
||||
|
||||
screen_write_start(&ctx, NULL, &screen);
|
||||
clock_draw(&ctx, colour, style);
|
||||
|
||||
if (password_failures != 0) {
|
||||
screen_write_cursormove(&ctx, 0, 0);
|
||||
screen_write_puts(
|
||||
&ctx, &gc, "%u failed attempts", password_failures);
|
||||
if (time(NULL) < password_backoff)
|
||||
screen_write_puts(&ctx, &gc, "; sleeping");
|
||||
}
|
||||
|
||||
screen_write_stop(&ctx);
|
||||
|
||||
for (i = 0; i < screen_size_y(&screen); i++)
|
||||
tty_draw_line(&c->tty, &screen, i, 0, 0);
|
||||
screen_redraw_screen(c, 1);
|
||||
|
||||
screen_free(&screen);
|
||||
}
|
||||
|
||||
/* Check for timers on client. */
|
||||
void
|
||||
server_check_timers(struct client *c)
|
||||
@ -836,8 +785,6 @@ server_handle_client(struct client *c)
|
||||
status_prompt_key(c, key);
|
||||
continue;
|
||||
}
|
||||
if (server_locked)
|
||||
continue;
|
||||
|
||||
/* Check for mouse keys. */
|
||||
if (key == KEYC_MOUSE) {
|
||||
@ -929,8 +876,6 @@ server_handle_client(struct client *c)
|
||||
tty_cursor(&c->tty, s->cx, s->cy, wp->xoff, wp->yoff);
|
||||
|
||||
mode = s->mode;
|
||||
if (server_locked)
|
||||
mode &= ~TTY_NOCURSOR;
|
||||
tty_update_mode(&c->tty, mode);
|
||||
tty_reset(&c->tty);
|
||||
}
|
||||
@ -1235,12 +1180,9 @@ void
|
||||
server_second_timers(void)
|
||||
{
|
||||
struct window *w;
|
||||
struct client *c;
|
||||
struct window_pane *wp;
|
||||
u_int i;
|
||||
int xtimeout;
|
||||
struct tm now, then;
|
||||
static time_t last_t = 0;
|
||||
time_t t;
|
||||
|
||||
t = time(NULL);
|
||||
@ -1259,29 +1201,6 @@ server_second_timers(void)
|
||||
wp->mode->timer(wp);
|
||||
}
|
||||
}
|
||||
|
||||
if (password_backoff != 0 && t >= password_backoff) {
|
||||
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
||||
if ((c = ARRAY_ITEM(&clients, i)) != NULL)
|
||||
server_redraw_client(c);
|
||||
}
|
||||
password_backoff = 0;
|
||||
}
|
||||
|
||||
/* Check for a minute having passed. */
|
||||
gmtime_r(&t, &now);
|
||||
gmtime_r(&last_t, &then);
|
||||
if (now.tm_min == then.tm_min)
|
||||
return;
|
||||
last_t = t;
|
||||
|
||||
/* If locked, redraw all clients. */
|
||||
if (server_locked) {
|
||||
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
||||
if ((c = ARRAY_ITEM(&clients, i)) != NULL)
|
||||
server_redraw_client(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Update socket execute permissions based on whether sessions are attached. */
|
||||
|
9
status.c
9
status.c
@ -890,9 +890,6 @@ status_prompt_key(struct client *c, int key)
|
||||
}
|
||||
break;
|
||||
case MODEKEYEDIT_HISTORYUP:
|
||||
if (server_locked)
|
||||
break;
|
||||
|
||||
if (ARRAY_LENGTH(&c->prompt_hdata) == 0)
|
||||
break;
|
||||
if (c->prompt_flags & PROMPT_HIDDEN)
|
||||
@ -908,9 +905,6 @@ status_prompt_key(struct client *c, int key)
|
||||
c->flags |= CLIENT_STATUS;
|
||||
break;
|
||||
case MODEKEYEDIT_HISTORYDOWN:
|
||||
if (server_locked)
|
||||
break;
|
||||
|
||||
if (c->prompt_flags & PROMPT_HIDDEN)
|
||||
memset(c->prompt_buffer, 0, strlen(c->prompt_buffer));
|
||||
xfree(c->prompt_buffer);
|
||||
@ -1003,9 +997,6 @@ status_prompt_key(struct client *c, int key)
|
||||
void
|
||||
status_prompt_add_history(struct client *c)
|
||||
{
|
||||
if (server_locked)
|
||||
return;
|
||||
|
||||
if (ARRAY_LENGTH(&c->prompt_hdata) > 0 &&
|
||||
strcmp(ARRAY_LAST(&c->prompt_hdata), c->prompt_buffer) == 0)
|
||||
return;
|
||||
|
40
tmux.1
40
tmux.1
@ -23,7 +23,7 @@
|
||||
.Sh SYNOPSIS
|
||||
.Nm tmux
|
||||
.Bk -words
|
||||
.Op Fl 28dlqUuv
|
||||
.Op Fl 28dlquv
|
||||
.Op Fl f Ar file
|
||||
.Op Fl L Ar socket-name
|
||||
.Op Fl S Ar socket-path
|
||||
@ -154,8 +154,6 @@ If
|
||||
is specified, the default socket directory is not used and any
|
||||
.Fl L
|
||||
flag is ignored.
|
||||
.It Fl U
|
||||
Unlock the server.
|
||||
.It Fl u
|
||||
.Nm
|
||||
attempts to guess if the terminal is likely to support UTF-8 by checking the
|
||||
@ -337,8 +335,6 @@ rename-session -tfirst newname
|
||||
set-window-option -t:0 monitor-activity on
|
||||
|
||||
new-window ; split-window -d
|
||||
|
||||
bind-key D detach-client \e\; lock-server
|
||||
.Ed
|
||||
.Sh CLIENTS AND SESSIONS
|
||||
The following commands are available:
|
||||
@ -1213,17 +1209,20 @@ Set the maximum number of lines held in window history.
|
||||
This setting applies only to new windows - existing window histories are not
|
||||
resized and retain the limit at the point they were created.
|
||||
.It Ic lock-after-time Ar number
|
||||
Lock the server after
|
||||
Lock the server (like the
|
||||
.Ic lock-server
|
||||
command) after
|
||||
.Ar number
|
||||
seconds of inactivity.
|
||||
The default is off (set to 0).
|
||||
This has no effect as a session option; it must be set as a global option using
|
||||
.Fl g .
|
||||
When passwords are entered incorrectly,
|
||||
.Nm
|
||||
follows the behaviour of
|
||||
.Xr login 1
|
||||
and ignores further password attempts for an increasing timeout.
|
||||
.It Ic lock-command Ar command
|
||||
Command to run when locking each client.
|
||||
The default is to run
|
||||
.Xr lock 1
|
||||
with
|
||||
.Fl np .
|
||||
.It Ic message-attr Ar attributes
|
||||
Set status line message attributes, where
|
||||
.Ar attributes
|
||||
@ -1962,7 +1961,9 @@ if
|
||||
returns success.
|
||||
.It Ic lock-server
|
||||
.D1 (alias: Ic lock )
|
||||
Lock the server until a password is entered.
|
||||
Lock each client individually by running the command specified by the
|
||||
.Ic lock-command
|
||||
option.
|
||||
.It Ic run-shell Ar command
|
||||
.D1 (alias: Ic run )
|
||||
Execute
|
||||
@ -1975,21 +1976,6 @@ doesn't return success, the exit status is also displayed.
|
||||
.It Ic server-info
|
||||
.D1 (alias: Ic info )
|
||||
Show server information and terminal details.
|
||||
.It Xo Ic set-password
|
||||
.Op Fl c
|
||||
.Ar password
|
||||
.Xc
|
||||
.D1 (alias: Ic pass )
|
||||
Set the server password.
|
||||
If the
|
||||
.Fl c
|
||||
option is given, a pre-encrypted password may be specified.
|
||||
By default, the password is blank, thus any entered password will be accepted
|
||||
when unlocking the server (see the
|
||||
.Ic lock-server
|
||||
command).
|
||||
To prevent variable expansion when an encrypted password is read from a
|
||||
configuration file, enclose it in single quotes (').
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width "/etc/tmux.confXXX" -compact
|
||||
|
58
tmux.c
58
tmux.c
@ -46,11 +46,6 @@ struct options global_s_options; /* session options */
|
||||
struct options global_w_options; /* window options */
|
||||
struct environ global_environ;
|
||||
|
||||
int server_locked;
|
||||
struct passwd *server_locked_pw;
|
||||
u_int password_failures;
|
||||
time_t password_backoff;
|
||||
char *server_password;
|
||||
time_t server_activity;
|
||||
|
||||
int debug_level;
|
||||
@ -61,7 +56,6 @@ int login_shell;
|
||||
|
||||
__dead void usage(void);
|
||||
char *makesockpath(const char *);
|
||||
int prepare_unlock(enum msgtype *, void **, size_t *, int);
|
||||
int prepare_cmd(enum msgtype *, void **, size_t *, int, char **);
|
||||
int dispatch_imsg(struct client_ctx *, int *);
|
||||
|
||||
@ -69,7 +63,7 @@ __dead void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage: %s [-28dlqUuv] [-f file] [-L socket-name]\n"
|
||||
"usage: %s [-28dlquv] [-f file] [-L socket-name]\n"
|
||||
" [-S socket-path] [command [flags]]\n",
|
||||
__progname);
|
||||
exit(1);
|
||||
@ -250,35 +244,6 @@ makesockpath(const char *label)
|
||||
return (path);
|
||||
}
|
||||
|
||||
int
|
||||
prepare_unlock(enum msgtype *msg, void **buf, size_t *len, int argc)
|
||||
{
|
||||
static struct msg_unlock_data unlockdata;
|
||||
char *pass;
|
||||
|
||||
if (argc != 0) {
|
||||
log_warnx("can't specify a command when unlocking");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if ((pass = getpass("Password:")) == NULL)
|
||||
return (-1);
|
||||
|
||||
if (strlen(pass) >= sizeof unlockdata.pass) {
|
||||
log_warnx("password too long");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
strlcpy(unlockdata.pass, pass, sizeof unlockdata.pass);
|
||||
memset(pass, 0, strlen(pass));
|
||||
|
||||
*buf = &unlockdata;
|
||||
*len = sizeof unlockdata;
|
||||
|
||||
*msg = MSG_UNLOCK;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
prepare_cmd(enum msgtype *msg, void **buf, size_t *len, int argc, char **argv)
|
||||
{
|
||||
@ -314,10 +279,10 @@ main(int argc, char **argv)
|
||||
char cwd[MAXPATHLEN];
|
||||
void *buf;
|
||||
size_t len;
|
||||
int retcode, opt, flags, unlock, cmdflags = 0;
|
||||
int retcode, opt, flags, cmdflags = 0;
|
||||
int nfds;
|
||||
|
||||
unlock = flags = 0;
|
||||
flags = 0;
|
||||
label = path = NULL;
|
||||
login_shell = (**argv == '-');
|
||||
while ((opt = getopt(argc, argv, "28df:lL:qS:uUv")) != -1) {
|
||||
@ -357,9 +322,6 @@ main(int argc, char **argv)
|
||||
case 'u':
|
||||
flags |= IDENTIFY_UTF8;
|
||||
break;
|
||||
case 'U':
|
||||
unlock = 1;
|
||||
break;
|
||||
case 'v':
|
||||
debug_level++;
|
||||
break;
|
||||
@ -407,6 +369,7 @@ main(int argc, char **argv)
|
||||
options_set_number(so, "display-time", 750);
|
||||
options_set_number(so, "history-limit", 2000);
|
||||
options_set_number(so, "lock-after-time", 0);
|
||||
options_set_string(so, "lock-command", "lock -np");
|
||||
options_set_number(so, "message-attr", 0);
|
||||
options_set_number(so, "message-bg", 3);
|
||||
options_set_number(so, "message-fg", 0);
|
||||
@ -514,17 +477,10 @@ main(int argc, char **argv)
|
||||
}
|
||||
xfree(label);
|
||||
|
||||
if (unlock) {
|
||||
if (prepare_unlock(&msg, &buf, &len, argc) != 0)
|
||||
exit(1);
|
||||
} else {
|
||||
if (prepare_cmd(&msg, &buf, &len, argc, argv) != 0)
|
||||
exit(1);
|
||||
}
|
||||
if (prepare_cmd(&msg, &buf, &len, argc, argv) != 0)
|
||||
exit(1);
|
||||
|
||||
if (unlock)
|
||||
cmdflags &= ~CMD_STARTSERVER;
|
||||
else if (argc == 0) /* new-session is the default */
|
||||
if (argc == 0) /* new-session is the default */
|
||||
cmdflags |= CMD_STARTSERVER|CMD_SENDENVIRON;
|
||||
else {
|
||||
/*
|
||||
|
18
tmux.h
18
tmux.h
@ -19,7 +19,7 @@
|
||||
#ifndef TMUX_H
|
||||
#define TMUX_H
|
||||
|
||||
#define PROTOCOL_VERSION 3
|
||||
#define PROTOCOL_VERSION 4
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
@ -304,10 +304,11 @@ enum msgtype {
|
||||
MSG_RESIZE,
|
||||
MSG_SHUTDOWN,
|
||||
MSG_SUSPEND,
|
||||
MSG_UNLOCK,
|
||||
MSG_VERSION,
|
||||
MSG_WAKEUP,
|
||||
MSG_ENVIRON
|
||||
MSG_ENVIRON,
|
||||
MSG_UNLOCK,
|
||||
MSG_LOCK
|
||||
};
|
||||
|
||||
/*
|
||||
@ -339,8 +340,8 @@ struct msg_identify_data {
|
||||
int flags;
|
||||
};
|
||||
|
||||
struct msg_unlock_data {
|
||||
char pass[PASS_MAX];
|
||||
struct msg_lock_data {
|
||||
char cmd[COMMAND_LENGTH];
|
||||
};
|
||||
|
||||
struct msg_environ_data {
|
||||
@ -1108,11 +1109,6 @@ extern struct options global_s_options;
|
||||
extern struct options global_w_options;
|
||||
extern struct environ global_environ;
|
||||
extern char *cfg_file;
|
||||
extern int server_locked;
|
||||
extern struct passwd *server_locked_pw;
|
||||
extern u_int password_failures;
|
||||
extern time_t password_backoff;
|
||||
extern char *server_password;
|
||||
extern time_t server_activity;
|
||||
extern int debug_level;
|
||||
extern int be_quiet;
|
||||
@ -1179,6 +1175,7 @@ void environ_unset(struct environ *, const char *);
|
||||
void environ_update(const char *, struct environ *, struct environ *);
|
||||
|
||||
/* tty.c */
|
||||
void tty_raw(struct tty *, const char *);
|
||||
u_char tty_get_acs(struct tty *, u_char);
|
||||
void tty_attributes(struct tty *, const struct grid_cell *);
|
||||
void tty_reset(struct tty *);
|
||||
@ -1352,7 +1349,6 @@ extern const struct cmd_entry cmd_server_info_entry;
|
||||
extern const struct cmd_entry cmd_set_buffer_entry;
|
||||
extern const struct cmd_entry cmd_set_environment_entry;
|
||||
extern const struct cmd_entry cmd_set_option_entry;
|
||||
extern const struct cmd_entry cmd_set_password_entry;
|
||||
extern const struct cmd_entry cmd_set_window_option_entry;
|
||||
extern const struct cmd_entry cmd_show_buffer_entry;
|
||||
extern const struct cmd_entry cmd_show_environment_entry;
|
||||
|
Loading…
Reference in New Issue
Block a user