@@ -75,6 +75,7 @@ extern "C" my_bool get_one_option(int optid, const struct my_option *opt,
7575 char *argument);
7676static my_bool sql_connect (MYSQL *mysql, uint wait);
7777static int execute_commands (MYSQL *mysql,int argc, char **argv);
78+ static char **mask_password (int argc, char ***argv);
7879static int drop_db (MYSQL *mysql,const char *db);
7980extern " C" sig_handler endprog (int signal_number);
8081static void nice_time (ulong sec,char *buff);
@@ -314,11 +315,11 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
314315
315316int main (int argc,char *argv[])
316317{
317- int error= 0 , ho_error;
318+ int error= 0 , ho_error, temp_argc ;
318319 int first_command;
319320 my_bool can_handle_passwords;
320321 MYSQL mysql;
321- char **commands, **save_argv;
322+ char **commands, **save_argv, **temp_argv ;
322323
323324 MY_INIT (argv[0 ]);
324325 mysql_init (&mysql);
@@ -333,6 +334,9 @@ int main(int argc,char *argv[])
333334 free_defaults (save_argv);
334335 exit (ho_error);
335336 }
337+ temp_argv= mask_password (argc, &argv);
338+ temp_argc= argc;
339+
336340 if (debug_info_flag)
337341 my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO;
338342 if (debug_check_flag)
@@ -343,7 +347,7 @@ int main(int argc,char *argv[])
343347 usage ();
344348 exit (1 );
345349 }
346- commands = argv ;
350+ commands = temp_argv ;
347351 if (tty_password)
348352 opt_password = get_tty_password (NullS);
349353
@@ -509,6 +513,13 @@ int main(int argc,char *argv[])
509513 my_free (shared_memory_base_name);
510514#endif
511515 free_defaults (save_argv);
516+ temp_argc--;
517+ while (temp_argc >= 0 )
518+ {
519+ my_free (temp_argv[temp_argc]);
520+ temp_argc--;
521+ }
522+ my_free (temp_argv);
512523 my_end (my_end_arg);
513524 exit (error ? 1 : 0 );
514525 return 0 ;
@@ -982,7 +993,10 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
982993 }
983994 }
984995 else
996+ {
997+ print_cmdline_password_warning ();
985998 typed_password= argv[1 ];
999+ }
9861000
9871001 if (typed_password[0 ])
9881002 {
@@ -1166,6 +1180,47 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
11661180 return 0 ;
11671181}
11681182
1183+ /* *
1184+ @brief Masking the password if it is passed as command line argument.
1185+
1186+ @details It works in Linux and changes cmdline in ps and /proc/pid/cmdline,
1187+ but it won't work for history file of shell.
1188+ The command line arguments are copied to another array and the
1189+ password in the argv is masked. This function is called just after
1190+ "handle_options" because in "handle_options", the agrv pointers
1191+ are altered which makes freeing of dynamically allocated memory
1192+ difficult. The password masking is done before all other operations
1193+ in order to minimise the time frame of password visibility via cmdline.
1194+
1195+ @param argc command line options (count)
1196+ @param argv command line options (values)
1197+
1198+ @return temp_argv copy of argv
1199+ */
1200+
1201+ static char **mask_password (int argc, char ***argv)
1202+ {
1203+ char **temp_argv;
1204+ temp_argv= (char **)(my_malloc (sizeof (char *) * argc, MYF (MY_WME)));
1205+ argc--;
1206+ while (argc > 0 )
1207+ {
1208+ temp_argv[argc]= my_strdup ((*argv)[argc], MYF (MY_FAE));
1209+ if (find_type ((*argv)[argc - 1 ],&command_typelib, FIND_TYPE_BASIC) == ADMIN_PASSWORD ||
1210+ find_type ((*argv)[argc - 1 ],&command_typelib, FIND_TYPE_BASIC) == ADMIN_OLD_PASSWORD)
1211+ {
1212+ char *start= (*argv)[argc];
1213+ while (*start)
1214+ *start++= ' x' ;
1215+ start= (*argv)[argc];
1216+ if (*start)
1217+ start[1 ]= 0 ; /* Cut length of argument */
1218+ }
1219+ argc--;
1220+ }
1221+ temp_argv[argc]= my_strdup ((*argv)[argc], MYF (MY_FAE));
1222+ return (temp_argv);
1223+ }
11691224
11701225static void print_version (void )
11711226{
0 commit comments