diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gmcerts.c | 22 | ||||
-rw-r--r-- | src/gmcerts.h | 8 | ||||
-rw-r--r-- | src/ui/sidebarwidget.c | 68 |
3 files changed, 70 insertions, 28 deletions
diff --git a/src/gmcerts.c b/src/gmcerts.c index 923987b1..3c10fff2 100644 --- a/src/gmcerts.c +++ b/src/gmcerts.c | |||
@@ -271,7 +271,9 @@ static void loadIdentityFromCertificate_GmCerts_(iGmCerts *d, const iString *crt | |||
271 | iBlock *finger = fingerprint_TlsCertificate(cert); | 271 | iBlock *finger = fingerprint_TlsCertificate(cert); |
272 | iGmIdentity *ident = findIdentity_GmCerts_(d, finger); | 272 | iGmIdentity *ident = findIdentity_GmCerts_(d, finger); |
273 | if (!ident) { | 273 | if (!ident) { |
274 | /* User-provided certificate. */ | ||
274 | ident = new_GmIdentity(); | 275 | ident = new_GmIdentity(); |
276 | ident->flags |= imported_GmIdentityFlag; | ||
275 | iDate today; | 277 | iDate today; |
276 | initCurrent_Date(&today); | 278 | initCurrent_Date(&today); |
277 | set_String(&ident->notes, collect_String(format_Date(&today, "Imported on %b %d, %Y"))); | 279 | set_String(&ident->notes, collect_String(format_Date(&today, "Imported on %b %d, %Y"))); |
@@ -390,6 +392,14 @@ iBool checkTrust_GmCerts(iGmCerts *d, iRangecc domain, const iTlsCertificate *ce | |||
390 | return iTrue; | 392 | return iTrue; |
391 | } | 393 | } |
392 | 394 | ||
395 | iGmIdentity *identity_GmCerts(iGmCerts *d, unsigned int id) { | ||
396 | return at_PtrArray(&d->idents, id); | ||
397 | } | ||
398 | |||
399 | const iGmIdentity *constIdentity_GmCerts(const iGmCerts *d, unsigned int id) { | ||
400 | return constAt_PtrArray(&d->idents, id); | ||
401 | } | ||
402 | |||
393 | const iGmIdentity *identityForUrl_GmCerts(const iGmCerts *d, const iString *url) { | 403 | const iGmIdentity *identityForUrl_GmCerts(const iGmCerts *d, const iString *url) { |
394 | iConstForEach(PtrArray, i, &d->idents) { | 404 | iConstForEach(PtrArray, i, &d->idents) { |
395 | const iGmIdentity *ident = i.ptr; | 405 | const iGmIdentity *ident = i.ptr; |
@@ -438,6 +448,18 @@ iGmIdentity *newIdentity_GmCerts(iGmCerts *d, int flags, iDate validUntil, const | |||
438 | return id; | 448 | return id; |
439 | } | 449 | } |
440 | 450 | ||
451 | void deleteIdentity_GmCerts(iGmCerts *d, iGmIdentity *identity) { | ||
452 | /* Only delete the files if we created them. */ | ||
453 | if (!(identity->flags & (temporary_GmIdentityFlag | imported_GmIdentityFlag))) { | ||
454 | const char *finger = cstrCollect_String(hexEncode_Block(&identity->fingerprint)); | ||
455 | const char *filename = concatPath_CStr(cstr_String(&d->saveDir), format_CStr("idents/%s", finger)); | ||
456 | remove(format_CStr("%s.crt", filename)); | ||
457 | remove(format_CStr("%s.key", filename)); | ||
458 | } | ||
459 | removeOne_PtrArray(&d->idents, identity); | ||
460 | collect_GmIdentity(identity); | ||
461 | } | ||
462 | |||
441 | const iPtrArray *identities_GmCerts(const iGmCerts *d) { | 463 | const iPtrArray *identities_GmCerts(const iGmCerts *d) { |
442 | return &d->idents; | 464 | return &d->idents; |
443 | } | 465 | } |
diff --git a/src/gmcerts.h b/src/gmcerts.h index 04904d51..37419b9e 100644 --- a/src/gmcerts.h +++ b/src/gmcerts.h | |||
@@ -32,6 +32,7 @@ iDeclareTypeSerialization(GmIdentity) | |||
32 | 32 | ||
33 | enum iGmIdentityFlags { | 33 | enum iGmIdentityFlags { |
34 | temporary_GmIdentityFlag = 0x1, /* not saved persistently */ | 34 | temporary_GmIdentityFlag = 0x1, /* not saved persistently */ |
35 | imported_GmIdentityFlag = 0x2, /* user-provided files */ | ||
35 | }; | 36 | }; |
36 | 37 | ||
37 | struct Impl_GmIdentity { | 38 | struct Impl_GmIdentity { |
@@ -56,8 +57,6 @@ iDeclareTypeConstructionArgs(GmCerts, const char *saveDir) | |||
56 | 57 | ||
57 | iBool checkTrust_GmCerts (iGmCerts *, iRangecc domain, const iTlsCertificate *cert); | 58 | iBool checkTrust_GmCerts (iGmCerts *, iRangecc domain, const iTlsCertificate *cert); |
58 | 59 | ||
59 | const iGmIdentity * identityForUrl_GmCerts (const iGmCerts *, const iString *url); | ||
60 | |||
61 | /** | 60 | /** |
62 | * Create a new self-signed TLS client certificate for identifying the user. | 61 | * Create a new self-signed TLS client certificate for identifying the user. |
63 | * @a commonName and the other name parameters are inserted in the subject field | 62 | * @a commonName and the other name parameters are inserted in the subject field |
@@ -74,4 +73,9 @@ iGmIdentity * newIdentity_GmCerts (iGmCerts *, int flags, iDate validU | |||
74 | const iString *domain, const iString *org, | 73 | const iString *domain, const iString *org, |
75 | const iString *country); | 74 | const iString *country); |
76 | 75 | ||
76 | void deleteIdentity_GmCerts (iGmCerts *, iGmIdentity *identity); | ||
77 | |||
78 | iGmIdentity * identity_GmCerts (iGmCerts *, unsigned int id); | ||
79 | const iGmIdentity * constIdentity_GmCerts (const iGmCerts *, unsigned int id); | ||
80 | const iGmIdentity * identityForUrl_GmCerts (const iGmCerts *, const iString *url); | ||
77 | const iPtrArray * identities_GmCerts (const iGmCerts *); | 81 | const iPtrArray * identities_GmCerts (const iGmCerts *); |
diff --git a/src/ui/sidebarwidget.c b/src/ui/sidebarwidget.c index 7fd0d7f1..19886964 100644 --- a/src/ui/sidebarwidget.c +++ b/src/ui/sidebarwidget.c | |||
@@ -482,7 +482,7 @@ static const iGmIdentity *constHoverIdentity_SidebarWidget_(const iSidebarWidget | |||
482 | if (d->mode == identities_SidebarMode) { | 482 | if (d->mode == identities_SidebarMode) { |
483 | const iSidebarItem *hoverItem = constHoverItem_SidebarWidget_(d); | 483 | const iSidebarItem *hoverItem = constHoverItem_SidebarWidget_(d); |
484 | if (hoverItem) { | 484 | if (hoverItem) { |
485 | return constAt_PtrArray(identities_GmCerts(certs_App()), hoverItem->id); | 485 | return identity_GmCerts(certs_App(), hoverItem->id); |
486 | } | 486 | } |
487 | } | 487 | } |
488 | return NULL; | 488 | return NULL; |
@@ -492,6 +492,13 @@ static iGmIdentity *hoverIdentity_SidebarWidget_(const iSidebarWidget *d) { | |||
492 | return iConstCast(iGmIdentity *, constHoverIdentity_SidebarWidget_(d)); | 492 | return iConstCast(iGmIdentity *, constHoverIdentity_SidebarWidget_(d)); |
493 | } | 493 | } |
494 | 494 | ||
495 | static void setHoverItem_SidebarWidget_(iSidebarWidget *d, size_t index) { | ||
496 | if (d->hoverItem != index) { | ||
497 | d->hoverItem = index; | ||
498 | invalidate_SidebarWidget_(d); | ||
499 | } | ||
500 | } | ||
501 | |||
495 | static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) { | 502 | static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) { |
496 | iWidget *w = as_Widget(d); | 503 | iWidget *w = as_Widget(d); |
497 | /* Handle commands. */ | 504 | /* Handle commands. */ |
@@ -630,7 +637,7 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) | |||
630 | else if (isCommand_Widget(w, ev, "ident.reveal")) { | 637 | else if (isCommand_Widget(w, ev, "ident.reveal")) { |
631 | return iTrue; | 638 | return iTrue; |
632 | } | 639 | } |
633 | else if (isCommand_Widget(w, ev, "ident.delete")) { | 640 | else if (equal_Command(cmd, "ident.delete")) { |
634 | iSidebarItem *item = hoverItem_SidebarWidget_(d); | 641 | iSidebarItem *item = hoverItem_SidebarWidget_(d); |
635 | if (argLabel_Command(cmd, "confirm")) { | 642 | if (argLabel_Command(cmd, "confirm")) { |
636 | makeQuestion_Widget(uiTextCaution_ColorEscape "DELETE IDENTITY", | 643 | makeQuestion_Widget(uiTextCaution_ColorEscape "DELETE IDENTITY", |
@@ -646,6 +653,8 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) | |||
646 | 2); | 653 | 2); |
647 | return iTrue; | 654 | return iTrue; |
648 | } | 655 | } |
656 | deleteIdentity_GmCerts(certs_App(), hoverIdentity_SidebarWidget_(d)); | ||
657 | updateItems_SidebarWidget_(d); | ||
649 | return iTrue; | 658 | return iTrue; |
650 | } | 659 | } |
651 | else if (equal_Command(cmd, "history.delete")) { | 660 | else if (equal_Command(cmd, "history.delete")) { |
@@ -708,10 +717,7 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) | |||
708 | setCursor_Window(get_Window(), SDL_SYSTEM_CURSOR_ARROW); | 717 | setCursor_Window(get_Window(), SDL_SYSTEM_CURSOR_ARROW); |
709 | } | 718 | } |
710 | } | 719 | } |
711 | if (hover != d->hoverItem) { | 720 | setHoverItem_SidebarWidget_(d, hover); |
712 | d->hoverItem = hover; | ||
713 | invalidate_SidebarWidget_(d); | ||
714 | } | ||
715 | } | 721 | } |
716 | if (ev->type == SDL_MOUSEWHEEL && isHover_Widget(w)) { | 722 | if (ev->type == SDL_MOUSEWHEEL && isHover_Widget(w)) { |
717 | #if defined (iPlatformApple) | 723 | #if defined (iPlatformApple) |
@@ -723,32 +729,42 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) | |||
723 | return iTrue; | 729 | return iTrue; |
724 | } | 730 | } |
725 | if (d->menu && ev->type == SDL_MOUSEBUTTONDOWN) { | 731 | if (d->menu && ev->type == SDL_MOUSEBUTTONDOWN) { |
726 | if (d->hoverItem != iInvalidPos || isVisible_Widget(d->menu)) { | 732 | if (ev->button.button == SDL_BUTTON_RIGHT) { |
727 | /* Update menu items. */ | 733 | if (!isVisible_Widget(d->menu)) { |
728 | if (d->mode == identities_SidebarMode) { | 734 | setHoverItem_SidebarWidget_( |
729 | const iGmIdentity *ident = constHoverIdentity_SidebarWidget_(d); | 735 | d, itemIndex_SidebarWidget_(d, init_I2(ev->button.x, ev->button.y))); |
730 | const iString * docUrl = url_DocumentWidget(document_App()); | 736 | } |
731 | iForEach(ObjectList, i, children_Widget(d->menu)) { | 737 | if (d->hoverItem != iInvalidPos || isVisible_Widget(d->menu)) { |
732 | if (isInstance_Object(i.object, &Class_LabelWidget)) { | 738 | /* Update menu items. */ |
733 | iLabelWidget *menuItem = i.object; | 739 | if (d->mode == identities_SidebarMode) { |
734 | const char * itemCmd = cstr_String(command_LabelWidget(menuItem)); | 740 | const iGmIdentity *ident = constHoverIdentity_SidebarWidget_(d); |
735 | if (equal_Command(itemCmd, "ident.use")) { | 741 | const iString * docUrl = url_DocumentWidget(document_App()); |
736 | setFlags_Widget(as_Widget(menuItem), | 742 | iForEach(ObjectList, i, children_Widget(d->menu)) { |
737 | disabled_WidgetFlag, | 743 | if (isInstance_Object(i.object, &Class_LabelWidget)) { |
738 | (arg_Command(itemCmd) != 0) ^ | 744 | iLabelWidget *menuItem = i.object; |
739 | (!isUsed_GmIdentity(ident))); | 745 | const char * cmdItem = cstr_String(command_LabelWidget(menuItem)); |
740 | } | 746 | if (equal_Command(cmdItem, "ident.use")) { |
741 | else if (equal_Command(itemCmd, "ident.showuse")) { | 747 | const iBool cmdUse = arg_Command(cmdItem) != 0; |
742 | setFlags_Widget(as_Widget(menuItem), | 748 | const iBool cmdClear = argLabel_Command(cmdItem, "clear") != 0; |
743 | disabled_WidgetFlag, | 749 | setFlags_Widget( |
744 | !isUsed_GmIdentity(ident)); | 750 | as_Widget(menuItem), |
751 | disabled_WidgetFlag, | ||
752 | (cmdClear && !isUsed_GmIdentity(ident)) || | ||
753 | (!cmdClear && cmdUse && isUsedOn_GmIdentity(ident, docUrl)) || | ||
754 | (!cmdClear && !cmdUse && !isUsedOn_GmIdentity(ident, docUrl))); | ||
755 | } | ||
756 | else if (equal_Command(cmdItem, "ident.showuse")) { | ||
757 | setFlags_Widget(as_Widget(menuItem), | ||
758 | disabled_WidgetFlag, | ||
759 | !isUsed_GmIdentity(ident)); | ||
760 | } | ||
745 | } | 761 | } |
746 | } | 762 | } |
747 | } | 763 | } |
748 | } | 764 | } |
749 | processContextMenuEvent_Widget(d->menu, ev, {}); | ||
750 | } | 765 | } |
751 | } | 766 | } |
767 | processContextMenuEvent_Widget(d->menu, ev, {}); | ||
752 | switch (processEvent_Click(&d->click, ev)) { | 768 | switch (processEvent_Click(&d->click, ev)) { |
753 | case started_ClickResult: | 769 | case started_ClickResult: |
754 | invalidate_SidebarWidget_(d); | 770 | invalidate_SidebarWidget_(d); |