Let's go over the terminology:
System.keychain
and login.keychain
are keychains. These contain keychain items like password items and secure note items.
security delete-keychain
deletes an entire keychain. That's what my first comment was about: You usually do not want to delete the System keychain, including all its entries. You use this if you create your own keychains for specific uses.
security delete-keychain "/Users/danielbeck/Library/Keychains/Test.keychain"
Use security delete-generic-password
, security delete-internet-password
, or security delete-certificate
, depending on the kind of item you want to delete, instead.
The following command deletes an item, e.g. a Secure Note, named note
from the specified keychain Test2.keychain
:
security delete-generic-password -l note "/Users/danielbeck/Library/Keychains/Test2.keychain"
For information about the options that allow you to specify which items to delete, see man security
.
Non-interactive SSH sessions
If you don't need to have an interactive session on the remote server, you can execute ssh
in an environment without tty
, e.g. as part of a Run Shell Script action in Automator.
You need to create a program that when called prints the password to standard out, e.g. the following bash script you need to make executable using chmod +x pwd.sh
:
#!/usr/bin/env bash
echo "password"
Then, set the SSH_ASKPASS
environment variable to the path to this program, and then run ssh
in the Automator action, like this:
export SSH_ASKPASS=/Users/danielbeck/pwd.sh
ssh user@hostname ls
When there is no tty
, but SSH_ASKPASS
and DISPLAY
(for X11, set by default) are set, SSH executes the program specified by SSH_ASKPASS
and uses its output as password. This is intended to be used in graphical environments, so that a window can pop up asking for your password. In this case, we just skipped the window, returning the password from our program. You can use security
to read from your keychain instead, like this:
#!/usr/bin/env bash
security find-generic-password -l password-item-label -g 2>&1 1>/dev/null | cut -d'"' -f2
ls
(on the ssh
command line) is the command executed when ssh
has logged in, and its output is printed in Automator. You can, of course, redirect it to a file to log output of the program you start.
Interactive SSH sessions using sshpass
I downloaded, compiled and installed sshpass
and it worked perfectly. Here's what I did:
- Get the Apple developer tools
- Download and open
sshpass-1.05.tar.gz
- Open a shell to the directory
sshpass-1.05
- Run
./configure
- Run
make
- Run
make install
(you might need sudo
for it)
Now the program is installed to /usr/local/bin/sshpass
. Execute using a line like the following:
sshpass -pYourPassword ssh username@hostname
You can read the password from security
just before doing that, and use it like this:
SSHPASSWORD=$( security find-generic-password -l password-item-label -g 2>&1 1>/dev/null | cut -d'"' -f2 )
sshpass -p"$SSHPASSWORD" ssh username@hostname
Wrap this in a shell function and you can just type e.g. ssh-yourhostname
to connect, having it retrieve and enter the password automatically.
Best Answer
It's hard to say for certain without seeing the actual full command, but I'd guess that you're probably running into quoting issues because the command gets passed through two shells (local shell -> ssh tunnel -> remote shell -> codesign command). Each shell interprets and removes quotes and escapes before passing strings on, and you want those double-quotes to be interpreted by the final shell, so you may need to add another layer of quotes. Here are some examples:
This doesn't work because the double-quotes are interpreted and removed by the local shell, so the final command (effectively) has the cert name unquoted.
This works because the outer (single-) quotes are removed by the local shell, leaving the inner (double-) quotes to be interpreted by the remote shell, so it'll pass the entire cert name to the
codesign
command as a single argument.This also works, but here double-quotes are used for both the outer and inner layer, so the inner layer needs to be escaped.