From 48deb41856d599e78ddbfd4e9d5f3ad6ac5bb55b Mon Sep 17 00:00:00 2001 From: Jaakko Keränen Date: Fri, 28 Aug 2020 19:16:20 +0300 Subject: Deleting identities --- src/gmcerts.c | 22 ++++++++++++++++ src/gmcerts.h | 8 ++++-- 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 iBlock *finger = fingerprint_TlsCertificate(cert); iGmIdentity *ident = findIdentity_GmCerts_(d, finger); if (!ident) { + /* User-provided certificate. */ ident = new_GmIdentity(); + ident->flags |= imported_GmIdentityFlag; iDate today; initCurrent_Date(&today); 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 return iTrue; } +iGmIdentity *identity_GmCerts(iGmCerts *d, unsigned int id) { + return at_PtrArray(&d->idents, id); +} + +const iGmIdentity *constIdentity_GmCerts(const iGmCerts *d, unsigned int id) { + return constAt_PtrArray(&d->idents, id); +} + const iGmIdentity *identityForUrl_GmCerts(const iGmCerts *d, const iString *url) { iConstForEach(PtrArray, i, &d->idents) { const iGmIdentity *ident = i.ptr; @@ -438,6 +448,18 @@ iGmIdentity *newIdentity_GmCerts(iGmCerts *d, int flags, iDate validUntil, const return id; } +void deleteIdentity_GmCerts(iGmCerts *d, iGmIdentity *identity) { + /* Only delete the files if we created them. */ + if (!(identity->flags & (temporary_GmIdentityFlag | imported_GmIdentityFlag))) { + const char *finger = cstrCollect_String(hexEncode_Block(&identity->fingerprint)); + const char *filename = concatPath_CStr(cstr_String(&d->saveDir), format_CStr("idents/%s", finger)); + remove(format_CStr("%s.crt", filename)); + remove(format_CStr("%s.key", filename)); + } + removeOne_PtrArray(&d->idents, identity); + collect_GmIdentity(identity); +} + const iPtrArray *identities_GmCerts(const iGmCerts *d) { return &d->idents; } 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) enum iGmIdentityFlags { temporary_GmIdentityFlag = 0x1, /* not saved persistently */ + imported_GmIdentityFlag = 0x2, /* user-provided files */ }; struct Impl_GmIdentity { @@ -56,8 +57,6 @@ iDeclareTypeConstructionArgs(GmCerts, const char *saveDir) iBool checkTrust_GmCerts (iGmCerts *, iRangecc domain, const iTlsCertificate *cert); -const iGmIdentity * identityForUrl_GmCerts (const iGmCerts *, const iString *url); - /** * Create a new self-signed TLS client certificate for identifying the user. * @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 const iString *domain, const iString *org, const iString *country); +void deleteIdentity_GmCerts (iGmCerts *, iGmIdentity *identity); + +iGmIdentity * identity_GmCerts (iGmCerts *, unsigned int id); +const iGmIdentity * constIdentity_GmCerts (const iGmCerts *, unsigned int id); +const iGmIdentity * identityForUrl_GmCerts (const iGmCerts *, const iString *url); 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 if (d->mode == identities_SidebarMode) { const iSidebarItem *hoverItem = constHoverItem_SidebarWidget_(d); if (hoverItem) { - return constAt_PtrArray(identities_GmCerts(certs_App()), hoverItem->id); + return identity_GmCerts(certs_App(), hoverItem->id); } } return NULL; @@ -492,6 +492,13 @@ static iGmIdentity *hoverIdentity_SidebarWidget_(const iSidebarWidget *d) { return iConstCast(iGmIdentity *, constHoverIdentity_SidebarWidget_(d)); } +static void setHoverItem_SidebarWidget_(iSidebarWidget *d, size_t index) { + if (d->hoverItem != index) { + d->hoverItem = index; + invalidate_SidebarWidget_(d); + } +} + static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) { iWidget *w = as_Widget(d); /* Handle commands. */ @@ -630,7 +637,7 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) else if (isCommand_Widget(w, ev, "ident.reveal")) { return iTrue; } - else if (isCommand_Widget(w, ev, "ident.delete")) { + else if (equal_Command(cmd, "ident.delete")) { iSidebarItem *item = hoverItem_SidebarWidget_(d); if (argLabel_Command(cmd, "confirm")) { makeQuestion_Widget(uiTextCaution_ColorEscape "DELETE IDENTITY", @@ -646,6 +653,8 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) 2); return iTrue; } + deleteIdentity_GmCerts(certs_App(), hoverIdentity_SidebarWidget_(d)); + updateItems_SidebarWidget_(d); return iTrue; } else if (equal_Command(cmd, "history.delete")) { @@ -708,10 +717,7 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) setCursor_Window(get_Window(), SDL_SYSTEM_CURSOR_ARROW); } } - if (hover != d->hoverItem) { - d->hoverItem = hover; - invalidate_SidebarWidget_(d); - } + setHoverItem_SidebarWidget_(d, hover); } if (ev->type == SDL_MOUSEWHEEL && isHover_Widget(w)) { #if defined (iPlatformApple) @@ -723,32 +729,42 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) return iTrue; } if (d->menu && ev->type == SDL_MOUSEBUTTONDOWN) { - if (d->hoverItem != iInvalidPos || isVisible_Widget(d->menu)) { - /* Update menu items. */ - if (d->mode == identities_SidebarMode) { - const iGmIdentity *ident = constHoverIdentity_SidebarWidget_(d); - const iString * docUrl = url_DocumentWidget(document_App()); - iForEach(ObjectList, i, children_Widget(d->menu)) { - if (isInstance_Object(i.object, &Class_LabelWidget)) { - iLabelWidget *menuItem = i.object; - const char * itemCmd = cstr_String(command_LabelWidget(menuItem)); - if (equal_Command(itemCmd, "ident.use")) { - setFlags_Widget(as_Widget(menuItem), - disabled_WidgetFlag, - (arg_Command(itemCmd) != 0) ^ - (!isUsed_GmIdentity(ident))); - } - else if (equal_Command(itemCmd, "ident.showuse")) { - setFlags_Widget(as_Widget(menuItem), - disabled_WidgetFlag, - !isUsed_GmIdentity(ident)); + if (ev->button.button == SDL_BUTTON_RIGHT) { + if (!isVisible_Widget(d->menu)) { + setHoverItem_SidebarWidget_( + d, itemIndex_SidebarWidget_(d, init_I2(ev->button.x, ev->button.y))); + } + if (d->hoverItem != iInvalidPos || isVisible_Widget(d->menu)) { + /* Update menu items. */ + if (d->mode == identities_SidebarMode) { + const iGmIdentity *ident = constHoverIdentity_SidebarWidget_(d); + const iString * docUrl = url_DocumentWidget(document_App()); + iForEach(ObjectList, i, children_Widget(d->menu)) { + if (isInstance_Object(i.object, &Class_LabelWidget)) { + iLabelWidget *menuItem = i.object; + const char * cmdItem = cstr_String(command_LabelWidget(menuItem)); + if (equal_Command(cmdItem, "ident.use")) { + const iBool cmdUse = arg_Command(cmdItem) != 0; + const iBool cmdClear = argLabel_Command(cmdItem, "clear") != 0; + setFlags_Widget( + as_Widget(menuItem), + disabled_WidgetFlag, + (cmdClear && !isUsed_GmIdentity(ident)) || + (!cmdClear && cmdUse && isUsedOn_GmIdentity(ident, docUrl)) || + (!cmdClear && !cmdUse && !isUsedOn_GmIdentity(ident, docUrl))); + } + else if (equal_Command(cmdItem, "ident.showuse")) { + setFlags_Widget(as_Widget(menuItem), + disabled_WidgetFlag, + !isUsed_GmIdentity(ident)); + } } } } } - processContextMenuEvent_Widget(d->menu, ev, {}); } } + processContextMenuEvent_Widget(d->menu, ev, {}); switch (processEvent_Click(&d->click, ev)) { case started_ClickResult: invalidate_SidebarWidget_(d); -- cgit v1.2.3