Lines 56-68
Link Here
|
56 |
|
56 |
|
57 |
/** |
57 |
/** |
58 |
* |
58 |
* |
59 |
* @author psychollek |
59 |
* @author psychollek, ynov |
60 |
*/ |
60 |
*/ |
61 |
@ServiceProvider(service=KeyringProvider.class, position=99) |
61 |
@ServiceProvider(service=KeyringProvider.class, position=99) |
62 |
public class KWalletProvider implements KeyringProvider{ |
62 |
public class KWalletProvider implements KeyringProvider{ |
63 |
|
63 |
|
64 |
private static final Logger logger = Logger.getLogger(KWalletProvider.class.getName()); |
64 |
private static final Logger logger = Logger.getLogger(KWalletProvider.class.getName()); |
65 |
private char[] handler = "0".toCharArray(); |
65 |
private char[] handler = "0".toCharArray(); |
|
|
66 |
private boolean timeoutHappened = false; |
66 |
|
67 |
|
67 |
@Override |
68 |
@Override |
68 |
public boolean enabled(){ |
69 |
public boolean enabled(){ |
Lines 70-132
Link Here
|
70 |
logger.fine("native keyring integration disabled"); |
71 |
logger.fine("native keyring integration disabled"); |
71 |
return false; |
72 |
return false; |
72 |
} |
73 |
} |
73 |
if (new String(runCommand("isEnabled")).equals("true")){ |
74 |
CommandResult result = runCommand("isEnabled"); |
|
|
75 |
if(new String(result.retVal).equals("true")) { |
74 |
return updateHandler(); |
76 |
return updateHandler(); |
75 |
} |
77 |
} |
76 |
return false; |
78 |
return false; |
77 |
}; |
79 |
}; |
78 |
|
80 |
|
79 |
@Override |
81 |
@Override |
80 |
public char[] read(String key){ |
82 |
public char[] read(String key){ |
81 |
if (updateHandler()){ |
83 |
if (!timeoutHappened && updateHandler()){ |
82 |
char[] pwd = runCommand("readPassword", handler, getApplicationName(), key.toCharArray(), getApplicationName(true)); |
84 |
CommandResult result = runCommand("readPassword", handler, getApplicationName(), key.toCharArray(), getApplicationName(true)); |
83 |
return pwd.length > 0 ? pwd : null; |
85 |
if (result.exitCode != 0){ |
|
|
86 |
error("read action returned not 0 exitCode"); |
87 |
} |
88 |
return result.retVal.length > 0 ? result.retVal : null; |
84 |
} |
89 |
} |
85 |
throw new KwalletException("read"); |
90 |
return null; |
|
|
91 |
//throw new KwalletException("read"); |
86 |
}; |
92 |
}; |
87 |
|
93 |
|
88 |
@Override |
94 |
@Override |
89 |
public void save(String key, char[] password, String description){ |
95 |
public void save(String key, char[] password, String description){ |
90 |
//description is forgoten ! kdewallet dosen't have any facility to store |
96 |
//description is forgoten ! kdewallet dosen't have any facility to store |
91 |
//it by default and I don't want to do it by adding new fields to kwallet |
97 |
//it by default and I don't want to do it by adding new fields to kwallet |
92 |
if (updateHandler()){ |
98 |
if (!timeoutHappened && updateHandler()){ |
93 |
if (new String(runCommand("writePassword", handler , getApplicationName() |
99 |
CommandResult result = runCommand("writePassword", handler , getApplicationName() |
94 |
, key.toCharArray(), password , getApplicationName(true)) |
100 |
, key.toCharArray(), password , getApplicationName(true)); |
95 |
).equals("-1")){ |
101 |
if (result.exitCode != 0 || (new String(result.retVal)).equals("-1")){ |
96 |
throw new KwalletException("save"); |
102 |
error("save action failed"); |
97 |
} |
103 |
} |
98 |
return; |
104 |
return; |
99 |
} |
105 |
} |
100 |
throw new KwalletException("save"); |
106 |
//throw new KwalletException("save"); |
101 |
}; |
107 |
}; |
102 |
|
108 |
|
103 |
@Override |
109 |
@Override |
104 |
public void delete(String key){ |
110 |
public void delete(String key){ |
105 |
if (updateHandler()){ |
111 |
if (!timeoutHappened && updateHandler()){ |
106 |
if (new String(runCommand("removeEntry" ,handler, |
112 |
CommandResult result = runCommand("removeEntry" ,handler, |
107 |
getApplicationName() , key.toCharArray() , getApplicationName(true) |
113 |
getApplicationName() , key.toCharArray() , getApplicationName(true)); |
108 |
)).equals("-1")){ |
114 |
if (result.exitCode != 0 || (new String(result.retVal)).equals("-1")){ |
109 |
throw new KwalletException("delete"); |
115 |
error("delete action failed"); |
110 |
} |
116 |
} |
111 |
return; |
117 |
return; |
112 |
} |
118 |
} |
113 |
throw new KwalletException("delete"); |
119 |
//throw new KwalletException("delete"); |
114 |
}; |
120 |
}; |
115 |
|
121 |
|
116 |
private boolean updateHandler(){ |
122 |
private boolean updateHandler(){ |
117 |
handler = new String(handler).equals("")? "0".toCharArray() : handler; |
123 |
handler = new String(handler).equals("")? "0".toCharArray() : handler; |
118 |
if(new String(runCommand("isOpen",handler)).equals("true")){ |
124 |
CommandResult result = runCommand("isOpen",handler); |
|
|
125 |
if(new String(result.retVal).equals("true")){ |
119 |
return true; |
126 |
return true; |
120 |
} |
127 |
} |
121 |
char[] localWallet = runCommand("localWallet"); |
128 |
char[] localWallet = runCommand("localWallet").retVal; |
122 |
handler = runCommand("open", localWallet , "0".toCharArray() , getApplicationName(true)); |
129 |
|
123 |
if(!(new String(handler)).equals("-1")){ |
130 |
result = runCommand("open", localWallet , "0".toCharArray() , getApplicationName(true)); |
124 |
return true; |
131 |
if(result.exitCode == 2) { //time out error |
|
|
132 |
error("time out happened while accessing KWallet"); |
133 |
//don't try to open KWallet anymore until bug https://bugs.kde.org/show_bug.cgi?id=259229 is fixed |
134 |
timeoutHappened = true; |
135 |
return false; |
125 |
} |
136 |
} |
126 |
return false; |
137 |
if(result.exitCode != 0 || new String(result.retVal).equals("-1")) { |
|
|
138 |
error("failed to access KWallet"); |
139 |
return false; |
140 |
} |
141 |
handler = result.retVal; |
142 |
return true; |
127 |
} |
143 |
} |
|
|
144 |
|
145 |
|
128 |
|
146 |
|
129 |
private char[] runCommand(String command,char[]... commandArgs){ |
147 |
private CommandResult runCommand(String command,char[]... commandArgs) { |
130 |
String[] argv = new String[commandArgs.length+4]; |
148 |
String[] argv = new String[commandArgs.length+4]; |
131 |
argv[0] = "qdbus"; |
149 |
argv[0] = "qdbus"; |
132 |
argv[1] = "org.kde.kwalletd"; |
150 |
argv[1] = "org.kde.kwalletd"; |
Lines 137-145
Link Here
|
137 |
//TODO: find a way to avoid changing char[] into String |
155 |
//TODO: find a way to avoid changing char[] into String |
138 |
argv[i+4] = new String(commandArgs[i]); |
156 |
argv[i+4] = new String(commandArgs[i]); |
139 |
} |
157 |
} |
140 |
|
|
|
141 |
Runtime rt = Runtime.getRuntime(); |
158 |
Runtime rt = Runtime.getRuntime(); |
142 |
String retVal = ""; |
159 |
String retVal = ""; |
|
|
160 |
String errVal = ""; |
161 |
int exitCode = 0; |
143 |
try { |
162 |
try { |
144 |
if (logger.isLoggable(Level.FINE)) { |
163 |
if (logger.isLoggable(Level.FINE)) { |
145 |
logger.log(Level.FINE, "executing {0}", Arrays.toString(argv)); |
164 |
logger.log(Level.FINE, "executing {0}", Arrays.toString(argv)); |
Lines 154-176
Link Here
|
154 |
retVal = retVal.concat("\n"); |
173 |
retVal = retVal.concat("\n"); |
155 |
} |
174 |
} |
156 |
retVal = retVal.concat(line); |
175 |
retVal = retVal.concat(line); |
157 |
} |
176 |
} |
158 |
input.close(); |
177 |
input.close(); |
159 |
input = new BufferedReader(new InputStreamReader(pr.getErrorStream())); |
178 |
input = new BufferedReader(new InputStreamReader(pr.getErrorStream())); |
160 |
|
179 |
|
161 |
while((line = input.readLine()) != null) { |
180 |
while((line = input.readLine()) != null) { |
162 |
if (!retVal.equals("")){ |
181 |
if (!errVal.equals("")){ |
163 |
retVal = retVal.concat("\n"); |
182 |
errVal = errVal.concat("\n"); |
164 |
} |
183 |
} |
165 |
retVal = retVal.concat(line); |
184 |
errVal = errVal.concat(line); |
166 |
} |
185 |
} |
167 |
input.close(); |
186 |
input.close(); |
168 |
|
187 |
|
169 |
|
188 |
exitCode = pr.waitFor(); |
170 |
int exitVal = pr.waitFor(); |
|
|
171 |
if (logger.isLoggable(Level.FINE)) { |
189 |
if (logger.isLoggable(Level.FINE)) { |
172 |
logger.log(Level.FINE, "application exit with code {0} for commandString: {1}", new Object[]{exitVal, Arrays.toString(argv)}); |
190 |
logger.log(Level.FINE, "application exit with code {0} for commandString: {1}; errVal: {2}", |
173 |
} |
191 |
new Object[]{exitCode, Arrays.toString(argv), errVal}); |
|
|
192 |
} |
174 |
} catch (InterruptedException ex) { |
193 |
} catch (InterruptedException ex) { |
175 |
logger.log(Level.FINE, |
194 |
logger.log(Level.FINE, |
176 |
"exception thrown while invoking the command \""+Arrays.toString(argv)+"\"", |
195 |
"exception thrown while invoking the command \""+Arrays.toString(argv)+"\"", |
Lines 180-187
Link Here
|
180 |
"exception thrown while invoking the command \""+Arrays.toString(argv)+"\"", |
199 |
"exception thrown while invoking the command \""+Arrays.toString(argv)+"\"", |
181 |
ex); |
200 |
ex); |
182 |
} |
201 |
} |
183 |
return retVal.trim().toCharArray(); |
202 |
return new CommandResult(exitCode, retVal.trim().toCharArray(), errVal.trim()); |
184 |
} |
203 |
} |
185 |
|
204 |
|
186 |
private char[] getApplicationName(){ |
205 |
private char[] getApplicationName(){ |
187 |
return getApplicationName(false); |
206 |
return getApplicationName(false); |
Lines 197-208
Link Here
|
197 |
return appName.toCharArray(); |
216 |
return appName.toCharArray(); |
198 |
} |
217 |
} |
199 |
|
218 |
|
200 |
public class KwalletException extends RuntimeException{ |
219 |
private void error(String descr) { |
|
|
220 |
logger.log(Level.WARNING, "Something went wrong: {0}", descr); |
221 |
} |
222 |
|
223 |
private class CommandResult { |
224 |
private int exitCode; |
225 |
private char[] retVal; |
226 |
private String errVal; |
201 |
|
227 |
|
202 |
public KwalletException(String desc) { |
228 |
public CommandResult(int exitCode, char[] retVal, String errVal) { |
203 |
super("error while trying to access KWallet, during "+desc); |
229 |
this.exitCode = exitCode; |
204 |
} |
230 |
this.retVal = retVal; |
205 |
|
231 |
this.errVal = errVal; |
|
|
232 |
} |
206 |
} |
233 |
} |
207 |
|
234 |
|
208 |
} |
235 |
} |