mirror of
https://github.com/MidnightCommander/mc
synced 2025-01-03 10:04:32 +03:00
Merge branch '2760_passwords_in_history'
* 2760_passwords_in_history: Ticket #2760: The password for session ftp remains in input history
This commit is contained in:
commit
47096e5c8e
@ -203,53 +203,65 @@ do_show_hist (WInput * in)
|
||||
in->history_changed = TRUE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/** Strip password from incomplete url (just user:pass@host without VFS prefix).
|
||||
*
|
||||
* @param url partial URL
|
||||
* @return newly allocated string without password
|
||||
*/
|
||||
|
||||
static char *
|
||||
input_history_strip_password (const char *url)
|
||||
{
|
||||
char *at, *delim, *colon;
|
||||
|
||||
at = strrchr (url, '@');
|
||||
if (at == NULL)
|
||||
return g_strdup (url);
|
||||
|
||||
/* TODO: handle ':' and '@' in password */
|
||||
|
||||
delim = strstr (url, VFS_PATH_URL_DELIMITER);
|
||||
if (delim != NULL)
|
||||
colon = strchr (delim + strlen (VFS_PATH_URL_DELIMITER), ':');
|
||||
else
|
||||
colon = strchr (url, ':');
|
||||
|
||||
if (colon == NULL)
|
||||
return g_strdup (url);
|
||||
*colon = '\0';
|
||||
|
||||
return g_strconcat (url, at, NULL);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
push_history (WInput * in, const char *text)
|
||||
{
|
||||
/* input widget where urls with passwords are entered without any
|
||||
vfs prefix */
|
||||
const char *password_input_fields[] = {
|
||||
" Link to a remote machine ",
|
||||
" FTP to machine ",
|
||||
" SMB link to machine "
|
||||
};
|
||||
const size_t ELEMENTS = (sizeof (password_input_fields) / sizeof (password_input_fields[0]));
|
||||
|
||||
char *t;
|
||||
size_t i;
|
||||
gboolean empty;
|
||||
|
||||
if (text == NULL)
|
||||
return;
|
||||
|
||||
#ifdef ENABLE_NLS
|
||||
for (i = 0; i < ELEMENTS; i++)
|
||||
password_input_fields[i] = _(password_input_fields[i]);
|
||||
#endif
|
||||
|
||||
t = g_strstrip (g_strdup (text));
|
||||
empty = *t == '\0';
|
||||
g_free (t);
|
||||
t = g_strdup (empty ? "" : text);
|
||||
|
||||
if (in->history_name != NULL)
|
||||
if (!empty && in->history_name != NULL && in->strip_password)
|
||||
{
|
||||
/* FIXME: It is the strange code. Rewrite is needed. */
|
||||
const char *p = in->history_name + 3;
|
||||
/*
|
||||
We got string user:pass@host without any VFS prefixes
|
||||
and vfs_path_to_str_flags (t, VPF_STRIP_PASSWORD) doesn't work.
|
||||
Therefore we want to strip password in separate algorithm
|
||||
*/
|
||||
char *url_with_stripped_password;
|
||||
|
||||
for (i = 0; i < ELEMENTS; i++)
|
||||
if (strcmp (p, password_input_fields[i]) == 0)
|
||||
{
|
||||
vfs_path_t *vpath;
|
||||
|
||||
vpath = vfs_path_from_str (t);
|
||||
g_free (t);
|
||||
t = vfs_path_to_str_flags (vpath, 0, VPF_STRIP_PASSWORD);
|
||||
vfs_path_free (vpath);
|
||||
break;
|
||||
}
|
||||
url_with_stripped_password = input_history_strip_password (t);
|
||||
g_free (t);
|
||||
t = url_with_stripped_password;
|
||||
}
|
||||
|
||||
if (in->history == NULL || in->history->data == NULL || strcmp (in->history->data, t) != 0 ||
|
||||
@ -979,6 +991,7 @@ input_new (int y, int x, const int *input_colors, int width, const char *def_tex
|
||||
in->need_push = TRUE;
|
||||
in->is_password = FALSE;
|
||||
in->charpoint = 0;
|
||||
in->strip_password = FALSE;
|
||||
|
||||
/* in->buffer will be corrected in "history_load" event handler */
|
||||
in->current_max_size = width + 1;
|
||||
|
@ -62,6 +62,7 @@ typedef struct
|
||||
GList *history; /* the history */
|
||||
gboolean history_changed; /* the history has changed */
|
||||
gboolean need_push; /* need to push the current Input on hist? */
|
||||
gboolean strip_password; /* need to strip password before placing string to history */
|
||||
char **completions; /* possible completions array */
|
||||
input_complete_t completion_flags;
|
||||
char charbuf[MB_LEN_MAX]; /* buffer for multibytes characters */
|
||||
|
@ -109,6 +109,8 @@ quick_dialog_skip (QuickDialog * qd, int nskip)
|
||||
in->is_password = (qw->u.input.flags == 1);
|
||||
if ((qw->u.input.flags & 2) != 0)
|
||||
in->completion_flags |= INPUT_COMPLETE_CD;
|
||||
if ((qw->u.input.flags & 4) != 0)
|
||||
in->strip_password = TRUE;
|
||||
qw->widget = (Widget *) in;
|
||||
*qw->u.input.result = NULL;
|
||||
break;
|
||||
|
@ -186,6 +186,7 @@ typedef struct
|
||||
int flags; /* 1 -- is_password, 2 -- INPUT_COMPLETE_CD */
|
||||
const char *histname;
|
||||
char **result;
|
||||
gboolean strip_password;
|
||||
} input;
|
||||
|
||||
struct
|
||||
|
@ -180,14 +180,14 @@ bg_message (int dummy, int *flags, char *title, const char *text)
|
||||
*/
|
||||
static char *
|
||||
fg_input_dialog_help (const char *header, const char *text, const char *help,
|
||||
const char *history_name, const char *def_text)
|
||||
const char *history_name, const char *def_text, gboolean strip_password)
|
||||
{
|
||||
char *my_str;
|
||||
|
||||
int flags = (strip_password) ? 4 : 0;
|
||||
QuickWidget quick_widgets[] = {
|
||||
/* 0 */ QUICK_BUTTON (6, 64, 1, 0, N_("&Cancel"), B_CANCEL, NULL),
|
||||
/* 1 */ QUICK_BUTTON (3, 64, 1, 0, N_("&OK"), B_ENTER, NULL),
|
||||
/* 2 */ QUICK_INPUT (3, 64, 0, 0, def_text, 58, 0, NULL, &my_str),
|
||||
/* 2 */ QUICK_INPUT (3, 64, 0, 0, def_text, 58, flags, NULL, &my_str),
|
||||
/* 3 */ QUICK_LABEL (3, 64, 2, 0, ""),
|
||||
QUICK_END
|
||||
};
|
||||
@ -474,7 +474,7 @@ message (int flags, const char *title, const char *text, ...)
|
||||
|
||||
char *
|
||||
input_dialog_help (const char *header, const char *text, const char *help,
|
||||
const char *history_name, const char *def_text)
|
||||
const char *history_name, const char *def_text, gboolean strip_password)
|
||||
{
|
||||
#ifdef ENABLE_BACKGROUND
|
||||
if (mc_global.we_are_background)
|
||||
@ -482,18 +482,20 @@ input_dialog_help (const char *header, const char *text, const char *help,
|
||||
union
|
||||
{
|
||||
void *p;
|
||||
char *(*f) (const char *, const char *, const char *, const char *, const char *);
|
||||
char *(*f) (const char *, const char *, const char *, const char *, const char *,
|
||||
gboolean);
|
||||
} func;
|
||||
func.f = fg_input_dialog_help;
|
||||
return wtools_parent_call_string (func.p, 5,
|
||||
return wtools_parent_call_string (func.p, 6,
|
||||
strlen (header), header, strlen (text),
|
||||
text, strlen (help), help,
|
||||
strlen (history_name), history_name,
|
||||
strlen (def_text), def_text);
|
||||
strlen (def_text), def_text,
|
||||
sizeof (gboolean), strip_password);
|
||||
}
|
||||
else
|
||||
#endif /* ENABLE_BACKGROUND */
|
||||
return fg_input_dialog_help (header, text, help, history_name, def_text);
|
||||
return fg_input_dialog_help (header, text, help, history_name, def_text, strip_password);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
@ -502,7 +504,7 @@ input_dialog_help (const char *header, const char *text, const char *help,
|
||||
char *
|
||||
input_dialog (const char *header, const char *text, const char *history_name, const char *def_text)
|
||||
{
|
||||
return input_dialog_help (header, text, "[Input Line Keys]", history_name, def_text);
|
||||
return input_dialog_help (header, text, "[Input Line Keys]", history_name, def_text, FALSE);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
@ -33,7 +33,7 @@ enum
|
||||
char *input_dialog (const char *header, const char *text,
|
||||
const char *history_name, const char *def_text);
|
||||
char *input_dialog_help (const char *header, const char *text, const char *help,
|
||||
const char *history_name, const char *def_text);
|
||||
const char *history_name, const char *def_text, gboolean strip_password);
|
||||
char *input_expand_dialog (const char *header, const char *text,
|
||||
const char *history_name, const char *def_text);
|
||||
|
||||
|
@ -234,7 +234,7 @@ set_panel_filter (WPanel * p)
|
||||
|
||||
reg_exp = input_dialog_help (_("Filter"),
|
||||
_("Set expression for filtering filenames"),
|
||||
"[Filter...]", MC_HISTORY_FM_PANEL_FILTER, x);
|
||||
"[Filter...]", MC_HISTORY_FM_PANEL_FILTER, x, FALSE);
|
||||
if (!reg_exp)
|
||||
return;
|
||||
set_panel_filter_to (p, reg_exp);
|
||||
@ -539,7 +539,7 @@ transform_prefix (const char *prefix)
|
||||
|
||||
static void
|
||||
nice_cd (const char *text, const char *xtext, const char *help,
|
||||
const char *history_name, const char *prefix, int to_home)
|
||||
const char *history_name, const char *prefix, int to_home, gboolean strip_password)
|
||||
{
|
||||
char *machine;
|
||||
char *cd_path;
|
||||
@ -547,7 +547,7 @@ nice_cd (const char *text, const char *xtext, const char *help,
|
||||
if (!SELECTED_IS_PANEL)
|
||||
return;
|
||||
|
||||
machine = input_dialog_help (text, xtext, help, history_name, "");
|
||||
machine = input_dialog_help (text, xtext, help, history_name, "", strip_password);
|
||||
if (!machine)
|
||||
return;
|
||||
|
||||
@ -1537,7 +1537,7 @@ void
|
||||
ftplink_cmd (void)
|
||||
{
|
||||
nice_cd (_("FTP to machine"), _(machine_str),
|
||||
"[FTP File System]", ":ftplink_cmd: FTP to machine ", "/#ftp:", 1);
|
||||
"[FTP File System]", ":ftplink_cmd: FTP to machine ", "/#ftp:", 1, TRUE);
|
||||
}
|
||||
#endif /* ENABLE_VFS_FTP */
|
||||
|
||||
@ -1549,7 +1549,7 @@ fishlink_cmd (void)
|
||||
{
|
||||
nice_cd (_("Shell link to machine"), _(machine_str),
|
||||
"[FIle transfer over SHell filesystem]", ":fishlink_cmd: Shell link to machine ",
|
||||
"/#sh:", 1);
|
||||
"/#sh:", 1, TRUE);
|
||||
}
|
||||
#endif /* ENABLE_VFS_FISH */
|
||||
|
||||
@ -1560,7 +1560,7 @@ void
|
||||
smblink_cmd (void)
|
||||
{
|
||||
nice_cd (_("SMB link to machine"), _(machine_str),
|
||||
"[SMB File System]", ":smblink_cmd: SMB link to machine ", "/#smb:", 0);
|
||||
"[SMB File System]", ":smblink_cmd: SMB link to machine ", "/#smb:", 0, TRUE);
|
||||
}
|
||||
#endif /* ENABLE_VFS_SMB */
|
||||
#endif /* ENABLE_VFS_NET */
|
||||
@ -1573,7 +1573,7 @@ undelete_cmd (void)
|
||||
{
|
||||
nice_cd (_("Undelete files on an ext2 file system"),
|
||||
_("Enter device (without /dev/) to undelete\nfiles on: (F1 for details)"),
|
||||
"[Undelete File System]", ":undelete_cmd: Undel on ext2 fs ", "/#undel:", 0);
|
||||
"[Undelete File System]", ":undelete_cmd: Undel on ext2 fs ", "/#undel:", 0, FALSE);
|
||||
}
|
||||
#endif /* ENABLE_VFS_UNDELFS */
|
||||
|
||||
|
@ -159,6 +159,11 @@ START_TEST(test_path_to_str_flags)
|
||||
vfs_test_ops1.prefix = "test1";
|
||||
vfs_register_class (&vfs_test_ops1);
|
||||
|
||||
vpath = vfs_path_from_str_flags ("test1://user:passwd@127.0.0.1", VPF_NO_CANON);
|
||||
str_path = vfs_path_to_str_flags (vpath, 0, VPF_STRIP_PASSWORD);
|
||||
fail_unless (strcmp ("test1://user@127.0.0.1/", str_path) == 0, "\nstr=%s\n", str_path);
|
||||
g_free (str_path);
|
||||
vfs_path_free (vpath);
|
||||
|
||||
vpath = vfs_path_from_str ("/test1://user:passwd@host.name/#enc:KOI8-R/тестовый/путь");
|
||||
str_path = vfs_path_to_str_flags (vpath, 0, VPF_STRIP_PASSWORD);
|
||||
|
Loading…
Reference in New Issue
Block a user