Mercurial > 510Connectbot
comparison src/com/five_ten_sg/connectbot/util/HostDatabase.java @ 0:0ce5cc452d02
initial version
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Thu, 22 May 2014 10:41:19 -0700 |
parents | |
children | ce8f13242339 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:0ce5cc452d02 |
---|---|
1 /* | |
2 * ConnectBot: simple, powerful, open-source SSH client for Android | |
3 * Copyright 2007 Kenny Root, Jeffrey Sharkey | |
4 * | |
5 * Licensed under the Apache License, Version 2.0 (the "License"); | |
6 * you may not use this file except in compliance with the License. | |
7 * You may obtain a copy of the License at | |
8 * | |
9 * http://www.apache.org/licenses/LICENSE-2.0 | |
10 * | |
11 * Unless required by applicable law or agreed to in writing, software | |
12 * distributed under the License is distributed on an "AS IS" BASIS, | |
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
14 * See the License for the specific language governing permissions and | |
15 * limitations under the License. | |
16 */ | |
17 | |
18 package com.five_ten_sg.connectbot.util; | |
19 | |
20 import java.nio.charset.Charset; | |
21 import java.util.Iterator; | |
22 import java.util.LinkedList; | |
23 import java.util.List; | |
24 import java.util.Map; | |
25 import java.util.Map.Entry; | |
26 | |
27 import com.five_ten_sg.connectbot.bean.HostBean; | |
28 import com.five_ten_sg.connectbot.bean.PortForwardBean; | |
29 import android.content.ContentValues; | |
30 import android.content.Context; | |
31 import android.database.Cursor; | |
32 import android.database.sqlite.SQLiteDatabase; | |
33 import android.database.sqlite.SQLiteException; | |
34 import android.util.Log; | |
35 | |
36 import com.trilead.ssh2.KnownHosts; | |
37 | |
38 /** | |
39 * Contains information about various SSH hosts, include public hostkey if known | |
40 * from previous sessions. | |
41 * | |
42 * @author jsharkey | |
43 */ | |
44 public class HostDatabase extends RobustSQLiteOpenHelper { | |
45 | |
46 public final static String TAG = "ConnectBot.HostDatabase"; | |
47 | |
48 public final static String DB_NAME = "hosts"; | |
49 public final static int DB_VERSION = 25; | |
50 | |
51 public final static String TABLE_HOSTS = "hosts"; | |
52 public final static String FIELD_HOST_NICKNAME = "nickname"; | |
53 public final static String FIELD_HOST_PROTOCOL = "protocol"; | |
54 public final static String FIELD_HOST_USERNAME = "username"; | |
55 public final static String FIELD_HOST_HOSTNAME = "hostname"; | |
56 public final static String FIELD_HOST_PORT = "port"; | |
57 public final static String FIELD_HOST_HOSTKEYALGO = "hostkeyalgo"; | |
58 public final static String FIELD_HOST_HOSTKEY = "hostkey"; | |
59 public final static String FIELD_HOST_LASTCONNECT = "lastconnect"; | |
60 public final static String FIELD_HOST_COLOR = "color"; | |
61 public final static String FIELD_HOST_USEKEYS = "usekeys"; | |
62 public final static String FIELD_HOST_USEAUTHAGENT = "useauthagent"; | |
63 public final static String FIELD_HOST_POSTLOGIN = "postlogin"; | |
64 public final static String FIELD_HOST_PUBKEYID = "pubkeyid"; | |
65 public final static String FIELD_HOST_WANTSESSION = "wantsession"; | |
66 public final static String FIELD_HOST_DELKEY = "delkey"; | |
67 public final static String FIELD_HOST_FONTSIZE = "fontsize"; | |
68 public final static String FIELD_HOST_COMPRESSION = "compression"; | |
69 public final static String FIELD_HOST_HTTPPROXY = "httpproxy"; | |
70 public final static String FIELD_HOST_ENCODING = "encoding"; | |
71 public final static String FIELD_HOST_STAYCONNECTED = "stayconnected"; | |
72 public final static String FIELD_HOST_WANTX11FORWARD = "wantx11forward"; | |
73 public final static String FIELD_HOST_X11HOST = "x11host"; | |
74 public final static String FIELD_HOST_X11PORT = "x11port"; | |
75 public final static String FIELD_HOST_MONITOR = "monitor"; | |
76 | |
77 public final static String TABLE_PORTFORWARDS = "portforwards"; | |
78 public final static String FIELD_PORTFORWARD_HOSTID = "hostid"; | |
79 public final static String FIELD_PORTFORWARD_NICKNAME = "nickname"; | |
80 public final static String FIELD_PORTFORWARD_TYPE = "type"; | |
81 public final static String FIELD_PORTFORWARD_SOURCEPORT = "sourceport"; | |
82 public final static String FIELD_PORTFORWARD_DESTADDR = "destaddr"; | |
83 public final static String FIELD_PORTFORWARD_DESTPORT = "destport"; | |
84 | |
85 public final static String TABLE_COLORS = "colors"; | |
86 public final static String FIELD_COLOR_SCHEME = "scheme"; | |
87 public final static String FIELD_COLOR_NUMBER = "number"; | |
88 public final static String FIELD_COLOR_VALUE = "value"; | |
89 | |
90 public final static String TABLE_COLOR_DEFAULTS = "colorDefaults"; | |
91 public final static String FIELD_COLOR_FG = "fg"; | |
92 public final static String FIELD_COLOR_BG = "bg"; | |
93 | |
94 public final static int DEFAULT_FG_COLOR = 7; | |
95 public final static int DEFAULT_BG_COLOR = 0; | |
96 | |
97 public final static String COLOR_RED = "red"; | |
98 public final static String COLOR_GREEN = "green"; | |
99 public final static String COLOR_BLUE = "blue"; | |
100 public final static String COLOR_GRAY = "gray"; | |
101 | |
102 public final static String PORTFORWARD_LOCAL = "local"; | |
103 public final static String PORTFORWARD_REMOTE = "remote"; | |
104 public final static String PORTFORWARD_DYNAMIC4 = "dynamic4"; | |
105 public final static String PORTFORWARD_DYNAMIC5 = "dynamic5"; | |
106 | |
107 public final static String DELKEY_DEL = "del"; | |
108 public final static String DELKEY_BACKSPACE = "backspace"; | |
109 | |
110 public final static String AUTHAGENT_NO = "no"; | |
111 public final static String AUTHAGENT_CONFIRM = "confirm"; | |
112 public final static String AUTHAGENT_YES = "yes"; | |
113 | |
114 public final static String ENCODING_DEFAULT = Charset.defaultCharset().name(); | |
115 | |
116 public final static String X11HOST_DEFAULT = "localhost"; | |
117 public final static int X11PORT_DEFAULT = 6000; | |
118 | |
119 public final static long PUBKEYID_NEVER = -2; | |
120 public final static long PUBKEYID_ANY = -1; | |
121 | |
122 public static final int DEFAULT_COLOR_SCHEME = 0; | |
123 | |
124 // Table creation strings | |
125 public static final String CREATE_TABLE_COLOR_DEFAULTS = | |
126 "CREATE TABLE " + TABLE_COLOR_DEFAULTS | |
127 + " (" + FIELD_COLOR_SCHEME + " INTEGER NOT NULL, " | |
128 + FIELD_COLOR_FG + " INTEGER NOT NULL DEFAULT " + DEFAULT_FG_COLOR + ", " | |
129 + FIELD_COLOR_BG + " INTEGER NOT NULL DEFAULT " + DEFAULT_BG_COLOR + ")"; | |
130 public static final String CREATE_TABLE_COLOR_DEFAULTS_INDEX = | |
131 "CREATE INDEX " + TABLE_COLOR_DEFAULTS + FIELD_COLOR_SCHEME + "index ON " | |
132 + TABLE_COLOR_DEFAULTS + " (" + FIELD_COLOR_SCHEME + ");"; | |
133 | |
134 private static final String WHERE_SCHEME_AND_COLOR = FIELD_COLOR_SCHEME + " = ? AND " | |
135 + FIELD_COLOR_NUMBER + " = ?"; | |
136 | |
137 static { | |
138 addTableName(TABLE_HOSTS); | |
139 addTableName(TABLE_PORTFORWARDS); | |
140 addIndexName(TABLE_PORTFORWARDS + FIELD_PORTFORWARD_HOSTID + "index"); | |
141 addTableName(TABLE_COLORS); | |
142 addIndexName(TABLE_COLORS + FIELD_COLOR_SCHEME + "index"); | |
143 addTableName(TABLE_COLOR_DEFAULTS); | |
144 addIndexName(TABLE_COLOR_DEFAULTS + FIELD_COLOR_SCHEME + "index"); | |
145 } | |
146 | |
147 public static final Object[] dbLock = new Object[0]; | |
148 | |
149 public HostDatabase(Context context) { | |
150 super(context, DB_NAME, null, DB_VERSION); | |
151 getWritableDatabase().close(); | |
152 } | |
153 | |
154 @Override | |
155 public void onCreate(SQLiteDatabase db) { | |
156 super.onCreate(db); | |
157 db.execSQL("CREATE TABLE " + TABLE_HOSTS | |
158 + " (_id INTEGER PRIMARY KEY, " | |
159 + FIELD_HOST_NICKNAME + " TEXT, " | |
160 + FIELD_HOST_PROTOCOL + " TEXT DEFAULT 'ssh', " | |
161 + FIELD_HOST_USERNAME + " TEXT, " | |
162 + FIELD_HOST_HOSTNAME + " TEXT, " | |
163 + FIELD_HOST_PORT + " INTEGER, " | |
164 + FIELD_HOST_HOSTKEYALGO + " TEXT, " | |
165 + FIELD_HOST_HOSTKEY + " BLOB, " | |
166 + FIELD_HOST_LASTCONNECT + " INTEGER, " | |
167 + FIELD_HOST_COLOR + " TEXT, " | |
168 + FIELD_HOST_USEKEYS + " TEXT, " | |
169 + FIELD_HOST_USEAUTHAGENT + " TEXT, " | |
170 + FIELD_HOST_POSTLOGIN + " TEXT, " | |
171 + FIELD_HOST_PUBKEYID + " INTEGER DEFAULT " + PUBKEYID_ANY + ", " | |
172 + FIELD_HOST_DELKEY + " TEXT DEFAULT '" + DELKEY_DEL + "', " | |
173 + FIELD_HOST_FONTSIZE + " INTEGER, " | |
174 + FIELD_HOST_WANTSESSION + " TEXT DEFAULT '" + Boolean.toString(true) + "', " | |
175 + FIELD_HOST_COMPRESSION + " TEXT DEFAULT '" + Boolean.toString(false) + "', " | |
176 + FIELD_HOST_HTTPPROXY + " TEXT, " | |
177 + FIELD_HOST_ENCODING + " TEXT DEFAULT '" + ENCODING_DEFAULT + "', " | |
178 + FIELD_HOST_STAYCONNECTED + " TEXT, " | |
179 + FIELD_HOST_WANTX11FORWARD + " TEXT DEFAULT '" + Boolean.toString(false) + "', " | |
180 + FIELD_HOST_X11HOST + " TEXT DEFAULT '" + X11HOST_DEFAULT + "', " | |
181 + FIELD_HOST_X11PORT + " INTEGER DEFAULT " + X11PORT_DEFAULT + ", " | |
182 + FIELD_HOST_MONITOR + " TEXT)"); | |
183 db.execSQL("CREATE TABLE " + TABLE_PORTFORWARDS | |
184 + " (_id INTEGER PRIMARY KEY, " | |
185 + FIELD_PORTFORWARD_HOSTID + " INTEGER, " | |
186 + FIELD_PORTFORWARD_NICKNAME + " TEXT, " | |
187 + FIELD_PORTFORWARD_TYPE + " TEXT NOT NULL DEFAULT " + PORTFORWARD_LOCAL + ", " | |
188 + FIELD_PORTFORWARD_SOURCEPORT + " INTEGER NOT NULL DEFAULT 8080, " | |
189 + FIELD_PORTFORWARD_DESTADDR + " TEXT, " | |
190 + FIELD_PORTFORWARD_DESTPORT + " TEXT)"); | |
191 db.execSQL("CREATE INDEX " + TABLE_PORTFORWARDS + FIELD_PORTFORWARD_HOSTID + "index ON " | |
192 + TABLE_PORTFORWARDS + " (" + FIELD_PORTFORWARD_HOSTID + ");"); | |
193 db.execSQL("CREATE TABLE " + TABLE_COLORS | |
194 + " (_id INTEGER PRIMARY KEY, " | |
195 + FIELD_COLOR_NUMBER + " INTEGER, " | |
196 + FIELD_COLOR_VALUE + " INTEGER, " | |
197 + FIELD_COLOR_SCHEME + " INTEGER)"); | |
198 db.execSQL("CREATE INDEX " + TABLE_COLORS + FIELD_COLOR_SCHEME + "index ON " | |
199 + TABLE_COLORS + " (" + FIELD_COLOR_SCHEME + ");"); | |
200 db.execSQL(CREATE_TABLE_COLOR_DEFAULTS); | |
201 db.execSQL(CREATE_TABLE_COLOR_DEFAULTS_INDEX); | |
202 } | |
203 | |
204 @Override | |
205 public void onRobustUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) throws SQLiteException { | |
206 // Versions of the database before the Android Market release will be | |
207 // shot without warning. | |
208 if (oldVersion <= 9) { | |
209 db.execSQL("DROP TABLE IF EXISTS " + TABLE_HOSTS); | |
210 onCreate(db); | |
211 return; | |
212 } | |
213 | |
214 switch (oldVersion) { | |
215 case 10: | |
216 db.execSQL("ALTER TABLE " + TABLE_HOSTS | |
217 + " ADD COLUMN " + FIELD_HOST_PUBKEYID + " INTEGER DEFAULT " + PUBKEYID_ANY); | |
218 | |
219 case 11: | |
220 db.execSQL("CREATE TABLE " + TABLE_PORTFORWARDS | |
221 + " (_id INTEGER PRIMARY KEY, " | |
222 + FIELD_PORTFORWARD_HOSTID + " INTEGER, " | |
223 + FIELD_PORTFORWARD_NICKNAME + " TEXT, " | |
224 + FIELD_PORTFORWARD_TYPE + " TEXT NOT NULL DEFAULT " + PORTFORWARD_LOCAL + ", " | |
225 + FIELD_PORTFORWARD_SOURCEPORT + " INTEGER NOT NULL DEFAULT 8080, " | |
226 + FIELD_PORTFORWARD_DESTADDR + " TEXT, " | |
227 + FIELD_PORTFORWARD_DESTPORT + " INTEGER)"); | |
228 | |
229 case 12: | |
230 db.execSQL("ALTER TABLE " + TABLE_HOSTS | |
231 + " ADD COLUMN " + FIELD_HOST_WANTSESSION + " TEXT DEFAULT '" + Boolean.toString(true) + "'"); | |
232 | |
233 case 13: | |
234 db.execSQL("ALTER TABLE " + TABLE_HOSTS | |
235 + " ADD COLUMN " + FIELD_HOST_COMPRESSION + " TEXT DEFAULT '" + Boolean.toString(false) + "'"); | |
236 | |
237 case 14: | |
238 db.execSQL("ALTER TABLE " + TABLE_HOSTS | |
239 + " ADD COLUMN " + FIELD_HOST_ENCODING + " TEXT DEFAULT '" + ENCODING_DEFAULT + "'"); | |
240 | |
241 case 15: | |
242 db.execSQL("ALTER TABLE " + TABLE_HOSTS | |
243 + " ADD COLUMN " + FIELD_HOST_PROTOCOL + " TEXT DEFAULT 'ssh'"); | |
244 | |
245 case 16: | |
246 db.execSQL("ALTER TABLE " + TABLE_HOSTS | |
247 + " ADD COLUMN " + FIELD_HOST_DELKEY + " TEXT DEFAULT '" + DELKEY_DEL + "'"); | |
248 | |
249 case 17: | |
250 db.execSQL("CREATE INDEX " + TABLE_PORTFORWARDS + FIELD_PORTFORWARD_HOSTID + "index ON " | |
251 + TABLE_PORTFORWARDS + " (" + FIELD_PORTFORWARD_HOSTID + ");"); | |
252 // Add colors | |
253 db.execSQL("CREATE TABLE " + TABLE_COLORS | |
254 + " (_id INTEGER PRIMARY KEY, " | |
255 + FIELD_COLOR_NUMBER + " INTEGER, " | |
256 + FIELD_COLOR_VALUE + " INTEGER, " | |
257 + FIELD_COLOR_SCHEME + " INTEGER)"); | |
258 db.execSQL("CREATE INDEX " + TABLE_COLORS + FIELD_COLOR_SCHEME + "index ON " | |
259 + TABLE_COLORS + " (" + FIELD_COLOR_SCHEME + ");"); | |
260 | |
261 case 18: | |
262 db.execSQL("ALTER TABLE " + TABLE_HOSTS | |
263 + " ADD COLUMN " + FIELD_HOST_USEAUTHAGENT + " TEXT DEFAULT '" + AUTHAGENT_NO + "'"); | |
264 | |
265 case 19: | |
266 db.execSQL("ALTER TABLE " + TABLE_HOSTS | |
267 + " ADD COLUMN " + FIELD_HOST_STAYCONNECTED + " TEXT"); | |
268 | |
269 case 20: | |
270 db.execSQL("ALTER TABLE " + TABLE_HOSTS | |
271 + " ADD COLUMN " + FIELD_HOST_FONTSIZE + " INTEGER"); | |
272 | |
273 case 21: | |
274 db.execSQL("DROP TABLE " + TABLE_COLOR_DEFAULTS); | |
275 db.execSQL(CREATE_TABLE_COLOR_DEFAULTS); | |
276 db.execSQL(CREATE_TABLE_COLOR_DEFAULTS_INDEX); | |
277 | |
278 case 22: | |
279 db.execSQL("ALTER TABLE " + TABLE_HOSTS | |
280 + " ADD COLUMN " + FIELD_HOST_WANTX11FORWARD + " TEXT DEFAULT '" + Boolean.toString(false) + "'"); | |
281 db.execSQL("ALTER TABLE " + TABLE_HOSTS | |
282 + " ADD COLUMN " + FIELD_HOST_X11HOST + " TEXT DEFAULT '" + X11HOST_DEFAULT + "'"); | |
283 db.execSQL("ALTER TABLE " + TABLE_HOSTS | |
284 + " ADD COLUMN " + FIELD_HOST_X11PORT + " INTEGER DEFAULT " + X11PORT_DEFAULT); | |
285 | |
286 case 23: | |
287 db.execSQL("ALTER TABLE " + TABLE_HOSTS | |
288 + " ADD COLUMN " + FIELD_HOST_HTTPPROXY + " TEXT"); | |
289 | |
290 case 24: | |
291 db.execSQL("ALTER TABLE " + TABLE_HOSTS | |
292 + " ADD COLUMN " + FIELD_HOST_MONITOR + " TEXT"); | |
293 } | |
294 } | |
295 | |
296 /** | |
297 * Touch a specific host to update its "last connected" field. | |
298 * @param nickname Nickname field of host to update | |
299 */ | |
300 public void touchHost(HostBean host) { | |
301 long now = System.currentTimeMillis() / 1000; | |
302 ContentValues values = new ContentValues(); | |
303 values.put(FIELD_HOST_LASTCONNECT, now); | |
304 | |
305 synchronized (dbLock) { | |
306 SQLiteDatabase db = this.getWritableDatabase(); | |
307 db.update(TABLE_HOSTS, values, "_id = ?", new String[] { String.valueOf(host.getId()) }); | |
308 } | |
309 } | |
310 | |
311 /** | |
312 * Create a new host using the given parameters. | |
313 */ | |
314 public HostBean saveHost(HostBean host) { | |
315 long id; | |
316 | |
317 synchronized (dbLock) { | |
318 SQLiteDatabase db = this.getWritableDatabase(); | |
319 id = db.insert(TABLE_HOSTS, null, host.getValues()); | |
320 } | |
321 | |
322 host.setId(id); | |
323 return host; | |
324 } | |
325 | |
326 /** | |
327 * Update a field in a host record. | |
328 */ | |
329 public boolean updateFontSize(HostBean host) { | |
330 long id = host.getId(); | |
331 | |
332 if (id < 0) | |
333 return false; | |
334 | |
335 ContentValues updates = new ContentValues(); | |
336 updates.put(FIELD_HOST_FONTSIZE, host.getFontSize()); | |
337 | |
338 synchronized (dbLock) { | |
339 SQLiteDatabase db = getWritableDatabase(); | |
340 db.update(TABLE_HOSTS, updates, "_id = ?", | |
341 new String[] { String.valueOf(id) }); | |
342 } | |
343 | |
344 return true; | |
345 } | |
346 | |
347 /** | |
348 * Delete a specific host by its <code>_id</code> value. | |
349 */ | |
350 public void deleteHost(HostBean host) { | |
351 if (host.getId() < 0) | |
352 return; | |
353 | |
354 synchronized (dbLock) { | |
355 SQLiteDatabase db = this.getWritableDatabase(); | |
356 db.delete(TABLE_HOSTS, "_id = ?", new String[] { String.valueOf(host.getId()) }); | |
357 } | |
358 } | |
359 | |
360 /** | |
361 * Return a cursor that contains information about all known hosts. | |
362 * @param sortColors If true, sort by color, otherwise sort by nickname. | |
363 */ | |
364 public List<HostBean> getHosts(boolean sortColors) { | |
365 String sortField = sortColors ? FIELD_HOST_COLOR : FIELD_HOST_NICKNAME; | |
366 List<HostBean> hosts; | |
367 | |
368 synchronized (dbLock) { | |
369 SQLiteDatabase db = this.getReadableDatabase(); | |
370 Cursor c = db.query(TABLE_HOSTS, null, null, null, null, null, sortField + " ASC"); | |
371 hosts = createHostBeans(c); | |
372 c.close(); | |
373 } | |
374 | |
375 return hosts; | |
376 } | |
377 | |
378 /** | |
379 * @param hosts | |
380 * @param c | |
381 */ | |
382 private List<HostBean> createHostBeans(Cursor c) { | |
383 List<HostBean> hosts = new LinkedList<HostBean>(); | |
384 final int COL_ID = c.getColumnIndexOrThrow("_id"), | |
385 COL_NICKNAME = c.getColumnIndexOrThrow(FIELD_HOST_NICKNAME), | |
386 COL_PROTOCOL = c.getColumnIndexOrThrow(FIELD_HOST_PROTOCOL), | |
387 COL_USERNAME = c.getColumnIndexOrThrow(FIELD_HOST_USERNAME), | |
388 COL_HOSTNAME = c.getColumnIndexOrThrow(FIELD_HOST_HOSTNAME), | |
389 COL_PORT = c.getColumnIndexOrThrow(FIELD_HOST_PORT), | |
390 COL_LASTCONNECT = c.getColumnIndexOrThrow(FIELD_HOST_LASTCONNECT), | |
391 COL_COLOR = c.getColumnIndexOrThrow(FIELD_HOST_COLOR), | |
392 COL_USEKEYS = c.getColumnIndexOrThrow(FIELD_HOST_USEKEYS), | |
393 COL_USEAUTHAGENT = c.getColumnIndexOrThrow(FIELD_HOST_USEAUTHAGENT), | |
394 COL_POSTLOGIN = c.getColumnIndexOrThrow(FIELD_HOST_POSTLOGIN), | |
395 COL_PUBKEYID = c.getColumnIndexOrThrow(FIELD_HOST_PUBKEYID), | |
396 COL_WANTSESSION = c.getColumnIndexOrThrow(FIELD_HOST_WANTSESSION), | |
397 COL_DELKEY = c.getColumnIndexOrThrow(FIELD_HOST_DELKEY), | |
398 COL_FONTSIZE = c.getColumnIndexOrThrow(FIELD_HOST_FONTSIZE), | |
399 COL_COMPRESSION = c.getColumnIndexOrThrow(FIELD_HOST_COMPRESSION), | |
400 COL_HTTPPROXY = c.getColumnIndexOrThrow(FIELD_HOST_HTTPPROXY), | |
401 COL_ENCODING = c.getColumnIndexOrThrow(FIELD_HOST_ENCODING), | |
402 COL_STAYCONNECTED = c.getColumnIndexOrThrow(FIELD_HOST_STAYCONNECTED), | |
403 COL_WANTX11FORWARD = c.getColumnIndexOrThrow(FIELD_HOST_WANTX11FORWARD), | |
404 COL_X11HOST = c.getColumnIndexOrThrow(FIELD_HOST_X11HOST), | |
405 COL_X11PORT = c.getColumnIndexOrThrow(FIELD_HOST_X11PORT), | |
406 COL_MONITOR = c.getColumnIndexOrThrow(FIELD_HOST_MONITOR); | |
407 | |
408 while (c.moveToNext()) { | |
409 HostBean host = new HostBean(); | |
410 host.setId(c.getLong(COL_ID)); | |
411 host.setNickname(c.getString(COL_NICKNAME)); | |
412 host.setProtocol(c.getString(COL_PROTOCOL)); | |
413 host.setUsername(c.getString(COL_USERNAME)); | |
414 host.setHostname(c.getString(COL_HOSTNAME)); | |
415 host.setPort(c.getInt(COL_PORT)); | |
416 host.setLastConnect(c.getLong(COL_LASTCONNECT)); | |
417 host.setColor(c.getString(COL_COLOR)); | |
418 host.setUseKeys(Boolean.valueOf(c.getString(COL_USEKEYS))); | |
419 host.setUseAuthAgent(c.getString(COL_USEAUTHAGENT)); | |
420 host.setPostLogin(c.getString(COL_POSTLOGIN)); | |
421 host.setPubkeyId(c.getLong(COL_PUBKEYID)); | |
422 host.setWantSession(Boolean.valueOf(c.getString(COL_WANTSESSION))); | |
423 host.setDelKey(c.getString(COL_DELKEY)); | |
424 host.setFontSize(c.getInt(COL_FONTSIZE)); | |
425 host.setCompression(Boolean.valueOf(c.getString(COL_COMPRESSION))); | |
426 host.setHttpproxy(c.getString(COL_HTTPPROXY)); | |
427 host.setEncoding(c.getString(COL_ENCODING)); | |
428 host.setStayConnected(Boolean.valueOf(c.getString(COL_STAYCONNECTED))); | |
429 host.setWantX11Forward(Boolean.valueOf(c.getString(COL_WANTX11FORWARD))); | |
430 host.setX11Host(c.getString(COL_X11HOST)); | |
431 host.setX11Port(c.getInt(COL_X11PORT)); | |
432 host.setMonitor(c.getString(COL_MONITOR)); | |
433 hosts.add(host); | |
434 } | |
435 | |
436 return hosts; | |
437 } | |
438 | |
439 /** | |
440 * @param c | |
441 * @return | |
442 */ | |
443 private HostBean getFirstHostBean(Cursor c) { | |
444 HostBean host = null; | |
445 List<HostBean> hosts = createHostBeans(c); | |
446 | |
447 if (hosts.size() > 0) | |
448 host = hosts.get(0); | |
449 | |
450 c.close(); | |
451 return host; | |
452 } | |
453 | |
454 /** | |
455 * @param nickname | |
456 * @param protocol | |
457 * @param username | |
458 * @param hostname | |
459 * @param hostname2 | |
460 * @param port | |
461 * @return | |
462 */ | |
463 public HostBean findHost(Map<String, String> selection) { | |
464 StringBuilder selectionBuilder = new StringBuilder(); | |
465 Iterator<Entry<String, String>> i = selection.entrySet().iterator(); | |
466 List<String> selectionValuesList = new LinkedList<String>(); | |
467 int n = 0; | |
468 | |
469 while (i.hasNext()) { | |
470 Entry<String, String> entry = i.next(); | |
471 | |
472 if (entry.getValue() == null) | |
473 continue; | |
474 | |
475 if (n++ > 0) | |
476 selectionBuilder.append(" AND "); | |
477 | |
478 selectionBuilder.append(entry.getKey()) | |
479 .append(" = ?"); | |
480 selectionValuesList.add(entry.getValue()); | |
481 } | |
482 | |
483 String selectionValues[] = new String[selectionValuesList.size()]; | |
484 selectionValuesList.toArray(selectionValues); | |
485 selectionValuesList = null; | |
486 HostBean host; | |
487 | |
488 synchronized (dbLock) { | |
489 SQLiteDatabase db = getReadableDatabase(); | |
490 Cursor c = db.query(TABLE_HOSTS, null, | |
491 selectionBuilder.toString(), | |
492 selectionValues, | |
493 null, null, null); | |
494 host = getFirstHostBean(c); | |
495 } | |
496 | |
497 return host; | |
498 } | |
499 | |
500 /** | |
501 * @param hostId | |
502 * @return | |
503 */ | |
504 public HostBean findHostById(long hostId) { | |
505 HostBean host; | |
506 | |
507 synchronized (dbLock) { | |
508 SQLiteDatabase db = getReadableDatabase(); | |
509 Cursor c = db.query(TABLE_HOSTS, null, | |
510 "_id = ?", new String[] { String.valueOf(hostId) }, | |
511 null, null, null); | |
512 host = getFirstHostBean(c); | |
513 } | |
514 | |
515 return host; | |
516 } | |
517 | |
518 /** | |
519 * Record the given hostkey into database under this nickname. | |
520 * @param hostname | |
521 * @param port | |
522 * @param hostkeyalgo | |
523 * @param hostkey | |
524 */ | |
525 public void saveKnownHost(String hostname, int port, String hostkeyalgo, byte[] hostkey) { | |
526 ContentValues values = new ContentValues(); | |
527 values.put(FIELD_HOST_HOSTKEYALGO, hostkeyalgo); | |
528 values.put(FIELD_HOST_HOSTKEY, hostkey); | |
529 | |
530 synchronized (dbLock) { | |
531 SQLiteDatabase db = getReadableDatabase(); | |
532 db.update(TABLE_HOSTS, values, | |
533 FIELD_HOST_HOSTNAME + " = ? AND " + FIELD_HOST_PORT + " = ?", | |
534 new String[] { hostname, String.valueOf(port) }); | |
535 Log.d(TAG, String.format("Finished saving hostkey information for '%s'", hostname)); | |
536 } | |
537 } | |
538 | |
539 /** | |
540 * Build list of known hosts for Trilead library. | |
541 * @return | |
542 */ | |
543 public KnownHosts getKnownHosts() { | |
544 KnownHosts known = new KnownHosts(); | |
545 | |
546 synchronized (dbLock) { | |
547 SQLiteDatabase db = this.getReadableDatabase(); | |
548 Cursor c = db.query(TABLE_HOSTS, new String[] { FIELD_HOST_HOSTNAME, | |
549 FIELD_HOST_PORT, FIELD_HOST_HOSTKEYALGO, FIELD_HOST_HOSTKEY | |
550 }, | |
551 null, null, null, null, null); | |
552 | |
553 if (c != null) { | |
554 int COL_HOSTNAME = c.getColumnIndexOrThrow(FIELD_HOST_HOSTNAME), | |
555 COL_PORT = c.getColumnIndexOrThrow(FIELD_HOST_PORT), | |
556 COL_HOSTKEYALGO = c.getColumnIndexOrThrow(FIELD_HOST_HOSTKEYALGO), | |
557 COL_HOSTKEY = c.getColumnIndexOrThrow(FIELD_HOST_HOSTKEY); | |
558 | |
559 while (c.moveToNext()) { | |
560 String hostname = c.getString(COL_HOSTNAME), | |
561 hostkeyalgo = c.getString(COL_HOSTKEYALGO); | |
562 int port = c.getInt(COL_PORT); | |
563 byte[] hostkey = c.getBlob(COL_HOSTKEY); | |
564 | |
565 if (hostkeyalgo == null || hostkeyalgo.length() == 0) continue; | |
566 | |
567 if (hostkey == null || hostkey.length == 0) continue; | |
568 | |
569 try { | |
570 known.addHostkey(new String[] { String.format("%s:%d", hostname, port) }, hostkeyalgo, hostkey); | |
571 } | |
572 catch (Exception e) { | |
573 Log.e(TAG, "Problem while adding a known host from database", e); | |
574 } | |
575 } | |
576 | |
577 c.close(); | |
578 } | |
579 } | |
580 | |
581 return known; | |
582 } | |
583 | |
584 /** | |
585 * Unset any hosts using a pubkey ID that has been deleted. | |
586 * @param pubkeyId | |
587 */ | |
588 public void stopUsingPubkey(long pubkeyId) { | |
589 if (pubkeyId < 0) return; | |
590 | |
591 ContentValues values = new ContentValues(); | |
592 values.put(FIELD_HOST_PUBKEYID, PUBKEYID_ANY); | |
593 | |
594 synchronized (dbLock) { | |
595 SQLiteDatabase db = this.getWritableDatabase(); | |
596 db.update(TABLE_HOSTS, values, FIELD_HOST_PUBKEYID + " = ?", new String[] { String.valueOf(pubkeyId) }); | |
597 } | |
598 | |
599 Log.d(TAG, String.format("Set all hosts using pubkey id %d to -1", pubkeyId)); | |
600 } | |
601 | |
602 /* | |
603 * Methods for dealing with port forwards attached to hosts | |
604 */ | |
605 | |
606 /** | |
607 * Returns a list of all the port forwards associated with a particular host ID. | |
608 * @param host the host for which we want the port forward list | |
609 * @return port forwards associated with host ID | |
610 */ | |
611 public List<PortForwardBean> getPortForwardsForHost(HostBean host) { | |
612 List<PortForwardBean> portForwards = new LinkedList<PortForwardBean>(); | |
613 | |
614 synchronized (dbLock) { | |
615 SQLiteDatabase db = this.getReadableDatabase(); | |
616 Cursor c = db.query(TABLE_PORTFORWARDS, new String[] { | |
617 "_id", FIELD_PORTFORWARD_NICKNAME, FIELD_PORTFORWARD_TYPE, FIELD_PORTFORWARD_SOURCEPORT, | |
618 FIELD_PORTFORWARD_DESTADDR, FIELD_PORTFORWARD_DESTPORT | |
619 }, | |
620 FIELD_PORTFORWARD_HOSTID + " = ?", new String[] { String.valueOf(host.getId()) }, | |
621 null, null, null); | |
622 | |
623 while (c.moveToNext()) { | |
624 PortForwardBean pfb = new PortForwardBean( | |
625 c.getInt(0), | |
626 host.getId(), | |
627 c.getString(1), | |
628 c.getString(2), | |
629 c.getInt(3), | |
630 c.getString(4), | |
631 c.getInt(5)); | |
632 portForwards.add(pfb); | |
633 } | |
634 | |
635 c.close(); | |
636 } | |
637 | |
638 return portForwards; | |
639 } | |
640 | |
641 /** | |
642 * Update the parameters of a port forward in the database. | |
643 * @param pfb {@link PortForwardBean} to save | |
644 * @return true on success | |
645 */ | |
646 public boolean savePortForward(PortForwardBean pfb) { | |
647 boolean success = false; | |
648 | |
649 synchronized (dbLock) { | |
650 SQLiteDatabase db = getWritableDatabase(); | |
651 | |
652 if (pfb.getId() < 0) { | |
653 long id = db.insert(TABLE_PORTFORWARDS, null, pfb.getValues()); | |
654 pfb.setId(id); | |
655 success = true; | |
656 } | |
657 else { | |
658 if (db.update(TABLE_PORTFORWARDS, pfb.getValues(), "_id = ?", new String[] { String.valueOf(pfb.getId()) }) > 0) | |
659 success = true; | |
660 } | |
661 } | |
662 | |
663 return success; | |
664 } | |
665 | |
666 /** | |
667 * Deletes a port forward from the database. | |
668 * @param pfb {@link PortForwardBean} to delete | |
669 */ | |
670 public void deletePortForward(PortForwardBean pfb) { | |
671 if (pfb.getId() < 0) | |
672 return; | |
673 | |
674 synchronized (dbLock) { | |
675 SQLiteDatabase db = this.getWritableDatabase(); | |
676 db.delete(TABLE_PORTFORWARDS, "_id = ?", new String[] { String.valueOf(pfb.getId()) }); | |
677 } | |
678 } | |
679 | |
680 public Integer[] getColorsForScheme(int scheme) { | |
681 Integer[] colors = Colors.defaults.clone(); | |
682 | |
683 synchronized (dbLock) { | |
684 SQLiteDatabase db = getReadableDatabase(); | |
685 Cursor c = db.query(TABLE_COLORS, new String[] { | |
686 FIELD_COLOR_NUMBER, FIELD_COLOR_VALUE | |
687 }, | |
688 FIELD_COLOR_SCHEME + " = ?", | |
689 new String[] { String.valueOf(scheme) }, | |
690 null, null, null); | |
691 | |
692 while (c.moveToNext()) { | |
693 colors[c.getInt(0)] = Integer.valueOf(c.getInt(1)); | |
694 } | |
695 | |
696 c.close(); | |
697 } | |
698 | |
699 return colors; | |
700 } | |
701 | |
702 public void setColorForScheme(int scheme, int number, int value) { | |
703 final SQLiteDatabase db; | |
704 final String[] whereArgs = new String[] { String.valueOf(scheme), String.valueOf(number) }; | |
705 | |
706 if (value == Colors.defaults[number]) { | |
707 synchronized (dbLock) { | |
708 db = getWritableDatabase(); | |
709 db.delete(TABLE_COLORS, | |
710 WHERE_SCHEME_AND_COLOR, whereArgs); | |
711 } | |
712 } | |
713 else { | |
714 final ContentValues values = new ContentValues(); | |
715 values.put(FIELD_COLOR_VALUE, value); | |
716 | |
717 synchronized (dbLock) { | |
718 db = getWritableDatabase(); | |
719 final int rowsAffected = db.update(TABLE_COLORS, values, | |
720 WHERE_SCHEME_AND_COLOR, whereArgs); | |
721 | |
722 if (rowsAffected == 0) { | |
723 values.put(FIELD_COLOR_SCHEME, scheme); | |
724 values.put(FIELD_COLOR_NUMBER, number); | |
725 db.insert(TABLE_COLORS, null, values); | |
726 } | |
727 } | |
728 } | |
729 } | |
730 | |
731 public void setGlobalColor(int number, int value) { | |
732 setColorForScheme(DEFAULT_COLOR_SCHEME, number, value); | |
733 } | |
734 | |
735 public int[] getDefaultColorsForScheme(int scheme) { | |
736 int[] colors = new int[] { DEFAULT_FG_COLOR, DEFAULT_BG_COLOR }; | |
737 | |
738 synchronized (dbLock) { | |
739 SQLiteDatabase db = getReadableDatabase(); | |
740 Cursor c = db.query(TABLE_COLOR_DEFAULTS, | |
741 new String[] { FIELD_COLOR_FG, FIELD_COLOR_BG }, | |
742 FIELD_COLOR_SCHEME + " = ?", | |
743 new String[] { String.valueOf(scheme) }, | |
744 null, null, null); | |
745 | |
746 if (c.moveToFirst()) { | |
747 colors[0] = c.getInt(0); | |
748 colors[1] = c.getInt(1); | |
749 } | |
750 | |
751 c.close(); | |
752 } | |
753 | |
754 return colors; | |
755 } | |
756 | |
757 public int[] getGlobalDefaultColors() { | |
758 return getDefaultColorsForScheme(DEFAULT_COLOR_SCHEME); | |
759 } | |
760 | |
761 public void setDefaultColorsForScheme(int scheme, int fg, int bg) { | |
762 SQLiteDatabase db; | |
763 String schemeWhere = null; | |
764 String[] whereArgs; | |
765 schemeWhere = FIELD_COLOR_SCHEME + " = ?"; | |
766 whereArgs = new String[] { String.valueOf(scheme) }; | |
767 ContentValues values = new ContentValues(); | |
768 values.put(FIELD_COLOR_FG, fg); | |
769 values.put(FIELD_COLOR_BG, bg); | |
770 | |
771 synchronized (dbLock) { | |
772 db = getWritableDatabase(); | |
773 int rowsAffected = db.update(TABLE_COLOR_DEFAULTS, values, | |
774 schemeWhere, whereArgs); | |
775 | |
776 if (rowsAffected == 0) { | |
777 values.put(FIELD_COLOR_SCHEME, scheme); | |
778 db.insert(TABLE_COLOR_DEFAULTS, null, values); | |
779 } | |
780 } | |
781 } | |
782 } |