diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-09-07 23:06:07 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-09-07 23:06:07 +0300 |
commit | 6145c27ad68f3f49bdc8e5c621ef7209edf81545 (patch) | |
tree | f721ccb1377209e0b4525521338ad3244380790b | |
parent | 320791c629e988f4634590aadf1bee5ee53d1785 (diff) |
LookupWidget: Finding identities
-rw-r--r-- | src/gmcerts.c | 40 | ||||
-rw-r--r-- | src/gmcerts.h | 3 | ||||
-rw-r--r-- | src/ui/lookupwidget.c | 54 |
3 files changed, 80 insertions, 17 deletions
diff --git a/src/gmcerts.c b/src/gmcerts.c index a39b303a..0dc52041 100644 --- a/src/gmcerts.c +++ b/src/gmcerts.c | |||
@@ -179,7 +179,7 @@ iDefineTypeConstruction(GmIdentity) | |||
179 | /*-----------------------------------------------------------------------------------------------*/ | 179 | /*-----------------------------------------------------------------------------------------------*/ |
180 | 180 | ||
181 | struct Impl_GmCerts { | 181 | struct Impl_GmCerts { |
182 | iMutex mtx; | 182 | iMutex *mtx; |
183 | iString saveDir; | 183 | iString saveDir; |
184 | iStringHash *trusted; | 184 | iStringHash *trusted; |
185 | iPtrArray idents; | 185 | iPtrArray idents; |
@@ -337,7 +337,7 @@ static void load_GmCerts_(iGmCerts *d) { | |||
337 | } | 337 | } |
338 | 338 | ||
339 | void init_GmCerts(iGmCerts *d, const char *saveDir) { | 339 | void init_GmCerts(iGmCerts *d, const char *saveDir) { |
340 | init_Mutex(&d->mtx); | 340 | d->mtx = new_Mutex(); |
341 | initCStr_String(&d->saveDir, saveDir); | 341 | initCStr_String(&d->saveDir, saveDir); |
342 | d->trusted = new_StringHash(); | 342 | d->trusted = new_StringHash(); |
343 | init_PtrArray(&d->idents); | 343 | init_PtrArray(&d->idents); |
@@ -345,7 +345,7 @@ void init_GmCerts(iGmCerts *d, const char *saveDir) { | |||
345 | } | 345 | } |
346 | 346 | ||
347 | void deinit_GmCerts(iGmCerts *d) { | 347 | void deinit_GmCerts(iGmCerts *d) { |
348 | iGuardMutex(&d->mtx, { | 348 | iGuardMutex(d->mtx, { |
349 | saveIdentities_GmCerts_(d); | 349 | saveIdentities_GmCerts_(d); |
350 | iForEach(PtrArray, i, &d->idents) { | 350 | iForEach(PtrArray, i, &d->idents) { |
351 | delete_GmIdentity(i.ptr); | 351 | delete_GmIdentity(i.ptr); |
@@ -354,7 +354,7 @@ void deinit_GmCerts(iGmCerts *d) { | |||
354 | iRelease(d->trusted); | 354 | iRelease(d->trusted); |
355 | deinit_String(&d->saveDir); | 355 | deinit_String(&d->saveDir); |
356 | }); | 356 | }); |
357 | deinit_Mutex(&d->mtx); | 357 | delete_Mutex(d->mtx); |
358 | } | 358 | } |
359 | 359 | ||
360 | iBool checkTrust_GmCerts(iGmCerts *d, iRangecc domain, const iTlsCertificate *cert) { | 360 | iBool checkTrust_GmCerts(iGmCerts *d, iRangecc domain, const iTlsCertificate *cert) { |
@@ -372,7 +372,7 @@ iBool checkTrust_GmCerts(iGmCerts *d, iRangecc domain, const iTlsCertificate *ce | |||
372 | iDate until; | 372 | iDate until; |
373 | validUntil_TlsCertificate(cert, &until); | 373 | validUntil_TlsCertificate(cert, &until); |
374 | iBlock *fingerprint = fingerprint_TlsCertificate(cert); | 374 | iBlock *fingerprint = fingerprint_TlsCertificate(cert); |
375 | lock_Mutex(&d->mtx); | 375 | lock_Mutex(d->mtx); |
376 | iTrustEntry *trust = value_StringHash(d->trusted, key); | 376 | iTrustEntry *trust = value_StringHash(d->trusted, key); |
377 | if (trust) { | 377 | if (trust) { |
378 | /* We already have it, check if it matches the one we trust for this domain (if it's | 378 | /* We already have it, check if it matches the one we trust for this domain (if it's |
@@ -382,7 +382,7 @@ iBool checkTrust_GmCerts(iGmCerts *d, iRangecc domain, const iTlsCertificate *ce | |||
382 | if (secondsSince_Time(&trust->validUntil, &now) > 0) { | 382 | if (secondsSince_Time(&trust->validUntil, &now) > 0) { |
383 | /* Trusted cert is still valid. */ | 383 | /* Trusted cert is still valid. */ |
384 | const iBool isTrusted = cmp_Block(fingerprint, &trust->fingerprint) == 0; | 384 | const iBool isTrusted = cmp_Block(fingerprint, &trust->fingerprint) == 0; |
385 | unlock_Mutex(&d->mtx); | 385 | unlock_Mutex(d->mtx); |
386 | delete_Block(fingerprint); | 386 | delete_Block(fingerprint); |
387 | delete_String(key); | 387 | delete_String(key); |
388 | return isTrusted; | 388 | return isTrusted; |
@@ -395,7 +395,7 @@ iBool checkTrust_GmCerts(iGmCerts *d, iRangecc domain, const iTlsCertificate *ce | |||
395 | insert_StringHash(d->trusted, key, iClob(new_TrustEntry(fingerprint, &until))); | 395 | insert_StringHash(d->trusted, key, iClob(new_TrustEntry(fingerprint, &until))); |
396 | } | 396 | } |
397 | save_GmCerts_(d); | 397 | save_GmCerts_(d); |
398 | unlock_Mutex(&d->mtx); | 398 | unlock_Mutex(d->mtx); |
399 | delete_Block(fingerprint); | 399 | delete_Block(fingerprint); |
400 | delete_String(key); | 400 | delete_String(key); |
401 | return iTrue; | 401 | return iTrue; |
@@ -410,16 +410,21 @@ const iGmIdentity *constIdentity_GmCerts(const iGmCerts *d, unsigned int id) { | |||
410 | } | 410 | } |
411 | 411 | ||
412 | const iGmIdentity *identityForUrl_GmCerts(const iGmCerts *d, const iString *url) { | 412 | const iGmIdentity *identityForUrl_GmCerts(const iGmCerts *d, const iString *url) { |
413 | lock_Mutex(d->mtx); | ||
414 | const iGmIdentity *found = NULL; | ||
413 | iConstForEach(PtrArray, i, &d->idents) { | 415 | iConstForEach(PtrArray, i, &d->idents) { |
414 | const iGmIdentity *ident = i.ptr; | 416 | const iGmIdentity *ident = i.ptr; |
415 | iConstForEach(StringSet, j, ident->useUrls) { | 417 | iConstForEach(StringSet, j, ident->useUrls) { |
416 | const iString *used = j.value; | 418 | const iString *used = j.value; |
417 | if (startsWithCase_String(url, cstr_String(used))) { | 419 | if (startsWithCase_String(url, cstr_String(used))) { |
418 | return ident; | 420 | found = ident; |
421 | goto done; | ||
419 | } | 422 | } |
420 | } | 423 | } |
421 | } | 424 | } |
422 | return NULL; | 425 | done: |
426 | unlock_Mutex(d->mtx); | ||
427 | return found; | ||
423 | } | 428 | } |
424 | 429 | ||
425 | iGmIdentity *newIdentity_GmCerts(iGmCerts *d, int flags, iDate validUntil, const iString *commonName, | 430 | iGmIdentity *newIdentity_GmCerts(iGmCerts *d, int flags, iDate validUntil, const iString *commonName, |
@@ -454,7 +459,7 @@ iGmIdentity *newIdentity_GmCerts(iGmCerts *d, int flags, iDate validUntil, const | |||
454 | return NULL; | 459 | return NULL; |
455 | } | 460 | } |
456 | } | 461 | } |
457 | pushBack_PtrArray(&d->idents, id); | 462 | iGuardMutex(d->mtx, pushBack_PtrArray(&d->idents, id)); |
458 | return id; | 463 | return id; |
459 | } | 464 | } |
460 | 465 | ||
@@ -467,6 +472,7 @@ static const char *certPath_GmCerts_(const iGmCerts *d, const iGmIdentity *ident | |||
467 | } | 472 | } |
468 | 473 | ||
469 | void deleteIdentity_GmCerts(iGmCerts *d, iGmIdentity *identity) { | 474 | void deleteIdentity_GmCerts(iGmCerts *d, iGmIdentity *identity) { |
475 | lock_Mutex(d->mtx); | ||
470 | /* Only delete the files if we created them. */ | 476 | /* Only delete the files if we created them. */ |
471 | const char *filename = certPath_GmCerts_(d, identity); | 477 | const char *filename = certPath_GmCerts_(d, identity); |
472 | if (filename) { | 478 | if (filename) { |
@@ -475,6 +481,7 @@ void deleteIdentity_GmCerts(iGmCerts *d, iGmIdentity *identity) { | |||
475 | } | 481 | } |
476 | removeOne_PtrArray(&d->idents, identity); | 482 | removeOne_PtrArray(&d->idents, identity); |
477 | collect_GmIdentity(identity); | 483 | collect_GmIdentity(identity); |
484 | unlock_Mutex(d->mtx); | ||
478 | } | 485 | } |
479 | 486 | ||
480 | const iString *certificatePath_GmCerts(const iGmCerts *d, const iGmIdentity *identity) { | 487 | const iString *certificatePath_GmCerts(const iGmCerts *d, const iGmIdentity *identity) { |
@@ -499,3 +506,16 @@ void signOut_GmCerts(iGmCerts *d, const iString *url) { | |||
499 | setUse_GmIdentity(i.ptr, url, iFalse); | 506 | setUse_GmIdentity(i.ptr, url, iFalse); |
500 | } | 507 | } |
501 | } | 508 | } |
509 | |||
510 | const iPtrArray *listIdentities_GmCerts(const iGmCerts *d, iGmCertsIdentityFilterFunc filter, | ||
511 | void *context) { | ||
512 | iPtrArray *list = collectNew_PtrArray(); | ||
513 | lock_Mutex(d->mtx); | ||
514 | iConstForEach(PtrArray, i, &d->idents) { | ||
515 | if (!filter || filter(context, i.ptr)) { | ||
516 | pushBack_PtrArray(list, i.ptr); | ||
517 | } | ||
518 | } | ||
519 | unlock_Mutex(d->mtx); | ||
520 | return list; | ||
521 | } | ||
diff --git a/src/gmcerts.h b/src/gmcerts.h index 92a12a6a..2ab4396e 100644 --- a/src/gmcerts.h +++ b/src/gmcerts.h | |||
@@ -57,6 +57,8 @@ const iString *name_GmIdentity(const iGmIdentity *); | |||
57 | iDeclareType(GmCerts) | 57 | iDeclareType(GmCerts) |
58 | iDeclareTypeConstructionArgs(GmCerts, const char *saveDir) | 58 | iDeclareTypeConstructionArgs(GmCerts, const char *saveDir) |
59 | 59 | ||
60 | typedef iBool (*iGmCertsIdentityFilterFunc)(void *context, const iGmIdentity *); | ||
61 | |||
60 | iBool checkTrust_GmCerts (iGmCerts *, iRangecc domain, const iTlsCertificate *cert); | 62 | iBool checkTrust_GmCerts (iGmCerts *, iRangecc domain, const iTlsCertificate *cert); |
61 | 63 | ||
62 | /** | 64 | /** |
@@ -83,6 +85,7 @@ iGmIdentity * identity_GmCerts (iGmCerts *, unsigned int id); | |||
83 | const iGmIdentity * constIdentity_GmCerts (const iGmCerts *, unsigned int id); | 85 | const iGmIdentity * constIdentity_GmCerts (const iGmCerts *, unsigned int id); |
84 | const iGmIdentity * identityForUrl_GmCerts (const iGmCerts *, const iString *url); | 86 | const iGmIdentity * identityForUrl_GmCerts (const iGmCerts *, const iString *url); |
85 | const iPtrArray * identities_GmCerts (const iGmCerts *); | 87 | const iPtrArray * identities_GmCerts (const iGmCerts *); |
88 | const iPtrArray * listIdentities_GmCerts (const iGmCerts *, iGmCertsIdentityFilterFunc filter, void *context); | ||
86 | 89 | ||
87 | void signIn_GmCerts (iGmCerts *, iGmIdentity *identity, const iString *url); | 90 | void signIn_GmCerts (iGmCerts *, iGmIdentity *identity, const iString *url); |
88 | void signOut_GmCerts (iGmCerts *, const iString *url); | 91 | void signOut_GmCerts (iGmCerts *, const iString *url); |
diff --git a/src/ui/lookupwidget.c b/src/ui/lookupwidget.c index 5fcbaacd..dbe734bf 100644 --- a/src/ui/lookupwidget.c +++ b/src/ui/lookupwidget.c | |||
@@ -21,17 +21,19 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||
21 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | 21 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ |
22 | 22 | ||
23 | #include "lookupwidget.h" | 23 | #include "lookupwidget.h" |
24 | |||
25 | #include "app.h" | ||
26 | #include "bookmarks.h" | ||
27 | #include "command.h" | ||
24 | #include "documentwidget.h" | 28 | #include "documentwidget.h" |
25 | #include "lookup.h" | 29 | #include "gmcerts.h" |
26 | #include "listwidget.h" | 30 | #include "gmutil.h" |
31 | #include "history.h" | ||
27 | #include "inputwidget.h" | 32 | #include "inputwidget.h" |
33 | #include "listwidget.h" | ||
34 | #include "lookup.h" | ||
28 | #include "util.h" | 35 | #include "util.h" |
29 | #include "command.h" | ||
30 | #include "bookmarks.h" | ||
31 | #include "history.h" | ||
32 | #include "visited.h" | 36 | #include "visited.h" |
33 | #include "gmutil.h" | ||
34 | #include "app.h" | ||
35 | 37 | ||
36 | #include <the_Foundation/mutex.h> | 38 | #include <the_Foundation/mutex.h> |
37 | #include <the_Foundation/thread.h> | 39 | #include <the_Foundation/thread.h> |
@@ -156,6 +158,14 @@ static float bookmarkRelevance_LookupJob_(const iLookupJob *d, const iBookmark * | |||
156 | return h + iMax(p, t) + 2 * g; /* extra weight for tags */ | 158 | return h + iMax(p, t) + 2 * g; /* extra weight for tags */ |
157 | } | 159 | } |
158 | 160 | ||
161 | static float identityRelevance_LookupJob_(const iLookupJob *d, const iGmIdentity *identity) { | ||
162 | iString *cn = subject_TlsCertificate(identity->cert); | ||
163 | const float c = scoreMatch_(d->term, range_String(cn)); | ||
164 | const float n = scoreMatch_(d->term, range_String(&identity->notes)); | ||
165 | delete_String(cn); | ||
166 | return c + 2 * n; /* extra weight for notes */ | ||
167 | } | ||
168 | |||
159 | static float visitedRelevance_LookupJob_(const iLookupJob *d, const iVisitedUrl *vis) { | 169 | static float visitedRelevance_LookupJob_(const iLookupJob *d, const iVisitedUrl *vis) { |
160 | iUrl parts; | 170 | iUrl parts; |
161 | init_Url(&parts, &vis->url); | 171 | init_Url(&parts, &vis->url); |
@@ -169,6 +179,10 @@ static iBool matchBookmark_LookupJob_(void *context, const iBookmark *bm) { | |||
169 | return bookmarkRelevance_LookupJob_(context, bm) > 0; | 179 | return bookmarkRelevance_LookupJob_(context, bm) > 0; |
170 | } | 180 | } |
171 | 181 | ||
182 | static iBool matchIdentity_LookupJob_(void *context, const iGmIdentity *identity) { | ||
183 | return identityRelevance_LookupJob_(context, identity) > 0; | ||
184 | } | ||
185 | |||
172 | static void searchBookmarks_LookupJob_(iLookupJob *d) { | 186 | static void searchBookmarks_LookupJob_(iLookupJob *d) { |
173 | /* Note: Called in a background thread. */ | 187 | /* Note: Called in a background thread. */ |
174 | /* TODO: Thread safety! What if a bookmark gets deleted while its being accessed here? */ | 188 | /* TODO: Thread safety! What if a bookmark gets deleted while its being accessed here? */ |
@@ -230,6 +244,25 @@ static void searchHistory_LookupJob_(iLookupJob *d) { | |||
230 | } | 244 | } |
231 | } | 245 | } |
232 | 246 | ||
247 | static void searchIdentities_LookupJob_(iLookupJob *d) { | ||
248 | /* Note: Called in a background thread. */ | ||
249 | iConstForEach(PtrArray, i, listIdentities_GmCerts(certs_App(), matchIdentity_LookupJob_, d)) { | ||
250 | const iGmIdentity *identity = i.ptr; | ||
251 | iLookupResult *res = new_LookupResult(); | ||
252 | res->type = identity_LookupResultType; | ||
253 | res->relevance = identityRelevance_LookupJob_(d, identity); | ||
254 | appendChar_String(&res->label, identity->icon); | ||
255 | appendChar_String(&res->label, ' '); | ||
256 | iString *cn = subject_TlsCertificate(identity->cert); | ||
257 | append_String(&res->label, cn); | ||
258 | delete_String(cn); | ||
259 | set_String(&res->meta, | ||
260 | collect_String( | ||
261 | hexEncode_Block(collect_Block(fingerprint_TlsCertificate(identity->cert))))); | ||
262 | pushBack_PtrArray(&d->results, res); | ||
263 | } | ||
264 | } | ||
265 | |||
233 | static iThreadResult worker_LookupWidget_(iThread *thread) { | 266 | static iThreadResult worker_LookupWidget_(iThread *thread) { |
234 | iLookupWidget *d = userData_Thread(thread); | 267 | iLookupWidget *d = userData_Thread(thread); |
235 | printf("[LookupWidget] worker is running\n"); fflush(stdout); | 268 | printf("[LookupWidget] worker is running\n"); fflush(stdout); |
@@ -271,6 +304,7 @@ static iThreadResult worker_LookupWidget_(iThread *thread) { | |||
271 | if (termLen >= 3) { | 304 | if (termLen >= 3) { |
272 | searchHistory_LookupJob_(job); | 305 | searchHistory_LookupJob_(job); |
273 | } | 306 | } |
307 | searchIdentities_LookupJob_(job); | ||
274 | } | 308 | } |
275 | /* Submit the result. */ | 309 | /* Submit the result. */ |
276 | lock_Mutex(d->mtx); | 310 | lock_Mutex(d->mtx); |
@@ -433,6 +467,12 @@ static void presentResults_LookupWidget_(iLookupWidget *d) { | |||
433 | format_String(&item->command, "open url:%s", cstr_String(&res->url)); | 467 | format_String(&item->command, "open url:%s", cstr_String(&res->url)); |
434 | break; | 468 | break; |
435 | } | 469 | } |
470 | case identity_LookupResultType: { | ||
471 | item->fg = uiText_ColorId; | ||
472 | item->font = uiContent_FontId; | ||
473 | format_String(&item->text, "%s", cstr_String(&res->label)); | ||
474 | break; | ||
475 | } | ||
436 | } | 476 | } |
437 | addItem_ListWidget(d->list, item); | 477 | addItem_ListWidget(d->list, item); |
438 | iRelease(item); | 478 | iRelease(item); |