summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gmcerts.c22
-rw-r--r--src/gmcerts.h8
-rw-r--r--src/ui/sidebarwidget.c68
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
395iGmIdentity *identity_GmCerts(iGmCerts *d, unsigned int id) {
396 return at_PtrArray(&d->idents, id);
397}
398
399const iGmIdentity *constIdentity_GmCerts(const iGmCerts *d, unsigned int id) {
400 return constAt_PtrArray(&d->idents, id);
401}
402
393const iGmIdentity *identityForUrl_GmCerts(const iGmCerts *d, const iString *url) { 403const 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
451void 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
441const iPtrArray *identities_GmCerts(const iGmCerts *d) { 463const 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
33enum iGmIdentityFlags { 33enum 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
37struct Impl_GmIdentity { 38struct Impl_GmIdentity {
@@ -56,8 +57,6 @@ iDeclareTypeConstructionArgs(GmCerts, const char *saveDir)
56 57
57iBool checkTrust_GmCerts (iGmCerts *, iRangecc domain, const iTlsCertificate *cert); 58iBool checkTrust_GmCerts (iGmCerts *, iRangecc domain, const iTlsCertificate *cert);
58 59
59const 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
76void deleteIdentity_GmCerts (iGmCerts *, iGmIdentity *identity);
77
78iGmIdentity * identity_GmCerts (iGmCerts *, unsigned int id);
79const iGmIdentity * constIdentity_GmCerts (const iGmCerts *, unsigned int id);
80const iGmIdentity * identityForUrl_GmCerts (const iGmCerts *, const iString *url);
77const iPtrArray * identities_GmCerts (const iGmCerts *); 81const 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
495static void setHoverItem_SidebarWidget_(iSidebarWidget *d, size_t index) {
496 if (d->hoverItem != index) {
497 d->hoverItem = index;
498 invalidate_SidebarWidget_(d);
499 }
500}
501
495static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) { 502static 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);