I would like to create a simple java app (for mac) that takes in a website and outputs my password associated with the website in Keychain.
My problem is that my app can't read the password from the output. If I manually write:
security find-internet-password -gs www.google.com
into the Terminal I get a few lines of info and then -> password: "mypassword". But in my application I only see the lines of info but the last line which should be the password is not there or null.
My code:
public static void command(){
try{
String command = "security find-internet-password -gs www.google.com";
Process child = Runtime.getRuntime().exec(command);
BufferedReader r = new BufferedReader(new InputStreamReader(child.getInputStream()));
String s;
while ((s = r.readLine()) != null) {
System.out.println(s);
}
System.out.println(r.readLine());
r.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
I'm not getting any errors but simply the code above is not showing the password. I'm using Eclipse if that matters. Thanks
The application prints:
keychain: "/Users/*username*/Library/Keychains/login.keychain"
class: "inet"
attributes:
0x00000007 <blob>="www.google.com"
0x00000008 <blob>=<NULL>
"acct"<blob>="*username*"
"atyp"<blob>="http"
"cdat"<timedate>=0x323031*numbers*3333325A00 "2011*numbers*132Z\000"
"crtr"<uint32>="rimZ"
"cusi"<sint32>=<NULL>
"desc"<blob>=<NULL>
"icmt"<blob>=<NULL>
"invi"<sint32>=<NULL>
"mdat"<timedate>=0x3230331*numbers*33834375A00 "20115*numbers*3847Z\000"
"nega"<sint32>=<NULL>
"path"<blob>="/"
"port"<uint32>=0x00000000
"prot"<blob>=<NULL>
"ptcl"<uint32>="htps"
"scrp"<sint32>=<NULL>
"sdmn"<blob>="www.google.com"
"srvr"<blob>="www.google.com"
"type"<uint32>=<NULL>
but the last line is missing and should be
password: "mypassword"
Edited
Is it the InputStreamReader that does not read the password? Is there another way to get the password?
The reason why you do not get the password in the output is that it is not printed to the stdout but to the stderr instead.
If you replace child.getInputStream()
with child.getErrorStream()
in your code will get you righ that Password:secret!
line.
You could use e.g. the following modified version of your code:
public static boolean command(String host) {
try {
String command = "security find-internet-password -gs " + host;
Process child = Runtime.getRuntime().exec(command);
try (BufferedReader out = new BufferedReader(new InputStreamReader(
child.getInputStream()));
BufferedReader err = new BufferedReader(
new InputStreamReader(child.getErrorStream()))) {
String user = null;
String password = null;
String s;
while ((s = out.readLine()) != null) {
if (s.matches(" *\"acct\".*")) {
user = s.replaceAll("^.*=\"", "").replace("\"", "");
}
}
s = err.readLine();
password = s.replaceAll("^.*: *\"", "").replace("\"", "");
System.out.println("user: " + user);
System.out.println("pwd: " + password);
return true;
}
} catch (IOException e) {
return false;
}
}
User contributions licensed under CC BY-SA 3.0