In regard to your update:
When a process is started it has a dedicated area of memory where arguments are stored and a int which tells how many arguments was passed.
MEMORY
argc 2
argv[0] program_name
argv[1] foo
argv[2] bar
MySQL check if password was passed on command line by -p
, and if it was copy it to a new variable that is not visible, then overwrite that region of memory with x
'es.
In simple terms e.g.:
argc 2
argv[1] -p
argv[2] p4ssw0rd
new_var = copy(argv[2]);
argv[2] = "xxxxx";
You can find it e.g. in client/mysqladmin.cc
of the source code:
case 'p':
...
opt_password=my_strdup(argument,MYF(MY_FAE));
while (*argument)
*argument++= 'x'; /* Destroy argument */
When ps
run it reads the memory region of the arguments, (argv[N]
), and thus it is xxxx
.
For a very short while the password is visible, but only for a few CPU cycles.
You can update the MySQL password using the special --init-file
option and procedure. C.5.4.1.2. Resetting the Root Password: Unix Systems
mysqld_safe --init-file=/home/me/mysql-init &
Edit:
As @Gilles say, you can echo
, printf
or use here
document from a script.
You can also add this to .my.cnf
of your home directory or in a (temporary) file and use the --defaults-extra-file
option. (Believe you have to add that option early on the command line.) optionally also include user. Also note the extra in the option name unless you want to use only that file as configuration:
[client]
user=foo
password='password!'
shell> chmod 400 my_tmp.cnf
shell> mysql --defaults-extra-file=my_tmp.conf -...
Optionally the [client]
grouping makes mysqld
skip the configuration.
One can also use MYSQL_PWD
environment variable, but that should never be used as you can list environment, in many ps
implementations by ps -e
, in the /proc/<PID>/environ
file on Linux etc.
tr '\0' '\n' < /proc/<PID>/environ
More on the topic here.
You might also want to have a look at the MySQL Configuration Utility which enables you to store password in a encrypted file in your home directory – .mylogin.cnf
.
If you really want to go this path and there's no passwd parameter, you can use this Expect script:
#!/usr/bin/env expect -f
set old_timeout $timeout
set timeout -1
stty -echo
send_user "Current password: "
expect_user -re "(.*)\n"
set old_password $expect_out(1,string)
stty echo
send_user "\nNew password: "
expect_user -re "(.*)\n"
set new_password $expect_out(1,string)
set timeout $old_timeout
spawn passwd
expect "password:"
send "$old_password\r"
expect "password:"
send "$new_password\r"
expect "password:"
send "$new_password\r"
expect eof
How it works:
[dave@hal9000 ~]$ ./passwd.tcl
Current password:
New password: bowman
spawn passwd
Changing password for user dave.
Changing password for dave.
(current) UNIX password:
New password:
Retype new password:
passwd: all authentication tokens updated successfully.
This shell script might also work (tested on Fedora 20 with bash-4.2.47-2 and passwd-0.79-2):
#!/bin/sh
stty -echo
echo -n "Current password: "
read old_password
stty echo
echo
echo -n "New password: "
read new_password
passwd << EOF
$old_password
$new_password
$new_password
EOF
How it works:
[dave@hal9000 ~]$ ./passwd.sh
Current password:
New password: bowman
Changing password for user dave.
Changing password for dave.
(current) UNIX password: New password: Retype new password: passwd: all authentication tokens updated successfully.
Best Answer
Idea #1 - Hidden OS
As an alternative method you could make use of TrueCrypt's "Hidden Operating System". This allows you to access a fake alternative OS when a certain password is used, rather than the primary OS.
excerpt
Bruce Schneier covers the efficacy of using these (Deniable File Systems, so you might want to investigate it further before diving in.
The whole idea of Deniable Encryption is a bit of a can of worms, so caution around using it in certain situations needs to be well thought out ahead of time.
Idea #2 - Add a script to /etc/passwd
You can insert alternative scripts to a user's entry in the
/etc/passwd
file.Example
You could setup a user's account so that it runs a script such as
/usr/local/etc/sdshell
which will check to see what password was provided. If it's the magical password that triggers the wipe, it could begin this process (backgrounded even) and either drop to a shell or do something else.If the password provided is not this magical password, then continue on running a normal shell,
/bin/bash
, for example.Source: 19.6.1 Integrating One-Time Passwords with Unix