diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-07-13 10:41:00 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-07-13 10:41:00 +0300 |
commit | 07156681f635a18f0b4e8e76fce60a723c8cddd8 (patch) | |
tree | 5491820c9deb03ef02d174fe03bbe1bc6b012b98 | |
parent | 0076a605540337bd89d37b7887541144e44b20f3 (diff) |
GmCerts: Make the server port known
-rw-r--r-- | src/gmcerts.c | 15 | ||||
-rw-r--r-- | src/gmcerts.h | 6 | ||||
-rw-r--r-- | src/gmrequest.c | 10 | ||||
-rw-r--r-- | src/gmutil.c | 43 | ||||
-rw-r--r-- | src/gmutil.h | 5 | ||||
-rw-r--r-- | src/ui/documentwidget.c | 12 |
6 files changed, 74 insertions, 17 deletions
diff --git a/src/gmcerts.c b/src/gmcerts.c index 8577cf2b..4b84aa05 100644 --- a/src/gmcerts.c +++ b/src/gmcerts.c | |||
@@ -426,7 +426,7 @@ iBool verifyDomain_GmCerts(const iTlsCertificate *cert, iRangecc domain) { | |||
426 | return iFalse; | 426 | return iFalse; |
427 | } | 427 | } |
428 | 428 | ||
429 | iBool checkTrust_GmCerts(iGmCerts *d, iRangecc domain, const iTlsCertificate *cert) { | 429 | iBool checkTrust_GmCerts(iGmCerts *d, iRangecc domain, uint16_t port, const iTlsCertificate *cert) { |
430 | if (!cert) { | 430 | if (!cert) { |
431 | return iFalse; | 431 | return iFalse; |
432 | } | 432 | } |
@@ -441,6 +441,9 @@ iBool checkTrust_GmCerts(iGmCerts *d, iRangecc domain, const iTlsCertificate *ce | |||
441 | /* TODO: Could call setTrusted_GmCerts() instead of duplicating the trust-setting. */ | 441 | /* TODO: Could call setTrusted_GmCerts() instead of duplicating the trust-setting. */ |
442 | /* Good certificate. If not already trusted, add it now. */ | 442 | /* Good certificate. If not already trusted, add it now. */ |
443 | iString *key = newRange_String(domain); | 443 | iString *key = newRange_String(domain); |
444 | if (port && port != GEMINI_DEFAULT_PORT) { | ||
445 | appendFormat_String(key, ":%u", port); | ||
446 | } | ||
444 | iDate until; | 447 | iDate until; |
445 | validUntil_TlsCertificate(cert, &until); | 448 | validUntil_TlsCertificate(cert, &until); |
446 | iBlock *fingerprint = fingerprint_TlsCertificate(cert); | 449 | iBlock *fingerprint = fingerprint_TlsCertificate(cert); |
@@ -471,10 +474,13 @@ iBool checkTrust_GmCerts(iGmCerts *d, iRangecc domain, const iTlsCertificate *ce | |||
471 | return iTrue; | 474 | return iTrue; |
472 | } | 475 | } |
473 | 476 | ||
474 | void setTrusted_GmCerts(iGmCerts *d, iRangecc domain, const iBlock *fingerprint, | 477 | void setTrusted_GmCerts(iGmCerts *d, iRangecc domain, uint16_t port, const iBlock *fingerprint, |
475 | const iDate *validUntil) { | 478 | const iDate *validUntil) { |
476 | iString *key = collectNew_String(); | 479 | iString *key = collectNew_String(); |
477 | punyEncodeDomain_Rangecc(domain, key); | 480 | punyEncodeDomain_Rangecc(domain, key); |
481 | if (port && port != GEMINI_DEFAULT_PORT) { | ||
482 | appendFormat_String(key, ":%u", port); | ||
483 | } | ||
478 | lock_Mutex(d->mtx); | 484 | lock_Mutex(d->mtx); |
479 | iTrustEntry *trust = value_StringHash(d->trusted, key); | 485 | iTrustEntry *trust = value_StringHash(d->trusted, key); |
480 | if (trust) { | 486 | if (trust) { |
@@ -488,12 +494,15 @@ void setTrusted_GmCerts(iGmCerts *d, iRangecc domain, const iBlock *fingerprint, | |||
488 | unlock_Mutex(d->mtx); | 494 | unlock_Mutex(d->mtx); |
489 | } | 495 | } |
490 | 496 | ||
491 | iTime domainValidUntil_GmCerts(const iGmCerts *d, iRangecc domain) { | 497 | iTime domainValidUntil_GmCerts(const iGmCerts *d, iRangecc domain, uint16_t port) { |
492 | iTime expiry; | 498 | iTime expiry; |
493 | iZap(expiry); | 499 | iZap(expiry); |
494 | lock_Mutex(d->mtx); | 500 | lock_Mutex(d->mtx); |
495 | iString key; | 501 | iString key; |
496 | initRange_String(&key, domain); | 502 | initRange_String(&key, domain); |
503 | if (port && port != GEMINI_DEFAULT_PORT) { | ||
504 | appendFormat_String(&key, ":%u", port); | ||
505 | } | ||
497 | const iTrustEntry *trust = constValue_StringHash(d->trusted, &key); | 506 | const iTrustEntry *trust = constValue_StringHash(d->trusted, &key); |
498 | if (trust) { | 507 | if (trust) { |
499 | expiry = trust->validUntil; | 508 | expiry = trust->validUntil; |
diff --git a/src/gmcerts.h b/src/gmcerts.h index a962d8b6..1a9480f7 100644 --- a/src/gmcerts.h +++ b/src/gmcerts.h | |||
@@ -60,10 +60,10 @@ iDeclareTypeConstructionArgs(GmCerts, const char *saveDir) | |||
60 | 60 | ||
61 | typedef iBool (*iGmCertsIdentityFilterFunc)(void *context, const iGmIdentity *); | 61 | typedef iBool (*iGmCertsIdentityFilterFunc)(void *context, const iGmIdentity *); |
62 | 62 | ||
63 | iBool checkTrust_GmCerts (iGmCerts *, iRangecc domain, const iTlsCertificate *cert); | 63 | iBool checkTrust_GmCerts (iGmCerts *, iRangecc domain, uint16_t port, const iTlsCertificate *cert); |
64 | void setTrusted_GmCerts (iGmCerts *, iRangecc domain, const iBlock *fingerprint, | 64 | void setTrusted_GmCerts (iGmCerts *, iRangecc domain, uint16_t port, const iBlock *fingerprint, |
65 | const iDate *validUntil); | 65 | const iDate *validUntil); |
66 | iTime domainValidUntil_GmCerts(const iGmCerts *, iRangecc domain); | 66 | iTime domainValidUntil_GmCerts(const iGmCerts *, iRangecc domain, uint16_t port); |
67 | 67 | ||
68 | /** | 68 | /** |
69 | * Create a new self-signed TLS client certificate for identifying the user. | 69 | * Create a new self-signed TLS client certificate for identifying the user. |
diff --git a/src/gmrequest.c b/src/gmrequest.c index 672614a2..8ae8f736 100644 --- a/src/gmrequest.c +++ b/src/gmrequest.c | |||
@@ -149,7 +149,11 @@ struct Impl_GmRequest { | |||
149 | iDefineObjectConstructionArgs(GmRequest, (iGmCerts *certs), certs) | 149 | iDefineObjectConstructionArgs(GmRequest, (iGmCerts *certs), certs) |
150 | iDefineAudienceGetter(GmRequest, updated) | 150 | iDefineAudienceGetter(GmRequest, updated) |
151 | iDefineAudienceGetter(GmRequest, finished) | 151 | iDefineAudienceGetter(GmRequest, finished) |
152 | 152 | ||
153 | static uint16_t port_GmRequest_(iGmRequest *d) { | ||
154 | return urlPort_String(&d->url); | ||
155 | } | ||
156 | |||
153 | static void checkServerCertificate_GmRequest_(iGmRequest *d) { | 157 | static void checkServerCertificate_GmRequest_(iGmRequest *d) { |
154 | const iTlsCertificate *cert = d->req ? serverCertificate_TlsRequest(d->req) : NULL; | 158 | const iTlsCertificate *cert = d->req ? serverCertificate_TlsRequest(d->req) : NULL; |
155 | iGmResponse *resp = d->resp; | 159 | iGmResponse *resp = d->resp; |
@@ -165,7 +169,7 @@ static void checkServerCertificate_GmRequest_(iGmRequest *d) { | |||
165 | if (verifyDomain_GmCerts(cert, domain)) { | 169 | if (verifyDomain_GmCerts(cert, domain)) { |
166 | resp->certFlags |= domainVerified_GmCertFlag; | 170 | resp->certFlags |= domainVerified_GmCertFlag; |
167 | } | 171 | } |
168 | if (checkTrust_GmCerts(d->certs, domain, cert)) { | 172 | if (checkTrust_GmCerts(d->certs, domain, port_GmRequest_(d), cert)) { |
169 | resp->certFlags |= trusted_GmCertFlag; | 173 | resp->certFlags |= trusted_GmCertFlag; |
170 | } | 174 | } |
171 | if (verify_TlsCertificate(cert) == authority_TlsCertificateVerifyStatus) { | 175 | if (verify_TlsCertificate(cert) == authority_TlsCertificateVerifyStatus) { |
@@ -836,7 +840,7 @@ void submit_GmRequest(iGmRequest *d) { | |||
836 | iConnect(TlsRequest, d->req, readyRead, d, readIncoming_GmRequest_); | 840 | iConnect(TlsRequest, d->req, readyRead, d, readIncoming_GmRequest_); |
837 | iConnect(TlsRequest, d->req, finished, d, requestFinished_GmRequest_); | 841 | iConnect(TlsRequest, d->req, finished, d, requestFinished_GmRequest_); |
838 | if (port == 0) { | 842 | if (port == 0) { |
839 | port = 1965; /* default Gemini port */ | 843 | port = GEMINI_DEFAULT_PORT; /* default Gemini port */ |
840 | } | 844 | } |
841 | setHost_TlsRequest(d->req, host, port); | 845 | setHost_TlsRequest(d->req, host, port); |
842 | setContent_TlsRequest(d->req, | 846 | setContent_TlsRequest(d->req, |
diff --git a/src/gmutil.c b/src/gmutil.c index 846405c3..23f5142f 100644 --- a/src/gmutil.c +++ b/src/gmutil.c | |||
@@ -74,6 +74,35 @@ void init_Url(iUrl *d, const iString *text) { | |||
74 | } | 74 | } |
75 | } | 75 | } |
76 | 76 | ||
77 | uint16_t port_Url(const iUrl *d) { | ||
78 | uint16_t port = 0; | ||
79 | if (!isEmpty_Range(&d->port)) { | ||
80 | iString portStr; | ||
81 | initRange_String(&portStr, d->port); | ||
82 | port = toInt_String(&portStr); | ||
83 | deinit_String(&portStr); | ||
84 | } | ||
85 | if (port != 0) { | ||
86 | return port; | ||
87 | } | ||
88 | if (isEmpty_Range(&d->scheme) || equalCase_Rangecc(d->scheme, "gemini")) { | ||
89 | port = GEMINI_DEFAULT_PORT; | ||
90 | } | ||
91 | else if (equalCase_Rangecc(d->scheme, "gopher")) { | ||
92 | port = 70; | ||
93 | } | ||
94 | else if (equalCase_Rangecc(d->scheme, "finger")) { | ||
95 | port = 79; | ||
96 | } | ||
97 | else if (equalCase_Rangecc(d->scheme, "http")) { | ||
98 | port = 80; | ||
99 | } | ||
100 | else if (equalCase_Rangecc(d->scheme, "https")) { | ||
101 | port = 443; | ||
102 | } | ||
103 | return port; | ||
104 | } | ||
105 | |||
77 | static iRangecc dirPath_(iRangecc path) { | 106 | static iRangecc dirPath_(iRangecc path) { |
78 | const size_t pos = lastIndexOfCStr_Rangecc(path, "/"); | 107 | const size_t pos = lastIndexOfCStr_Rangecc(path, "/"); |
79 | if (pos == iInvalidPos) return path; | 108 | if (pos == iInvalidPos) return path; |
@@ -98,7 +127,8 @@ static iRangecc prevPathSeg_(const char *end, const char *start) { | |||
98 | void stripDefaultUrlPort_String(iString *d) { | 127 | void stripDefaultUrlPort_String(iString *d) { |
99 | iUrl parts; | 128 | iUrl parts; |
100 | init_Url(&parts, d); | 129 | init_Url(&parts, d); |
101 | if (equalCase_Rangecc(parts.scheme, "gemini") && equal_Rangecc(parts.port, "1965")) { | 130 | if (equalCase_Rangecc(parts.scheme, "gemini") && |
131 | equal_Rangecc(parts.port, GEMINI_DEFAULT_PORT_CSTR)) { | ||
102 | /* Always preceded by a colon. */ | 132 | /* Always preceded by a colon. */ |
103 | remove_Block(&d->chars, parts.port.start - 1 - constBegin_String(d), | 133 | remove_Block(&d->chars, parts.port.start - 1 - constBegin_String(d), |
104 | size_Range(&parts.port) + 1); | 134 | size_Range(&parts.port) + 1); |
@@ -169,6 +199,12 @@ iRangecc urlHost_String(const iString *d) { | |||
169 | return url.host; | 199 | return url.host; |
170 | } | 200 | } |
171 | 201 | ||
202 | uint16_t urlPort_String(const iString *d) { | ||
203 | iUrl url; | ||
204 | init_Url(&url, d); | ||
205 | return port_Url(&url); | ||
206 | } | ||
207 | |||
172 | iRangecc urlUser_String(const iString *d) { | 208 | iRangecc urlUser_String(const iString *d) { |
173 | static iRegExp *userPats_[2]; | 209 | static iRegExp *userPats_[2]; |
174 | if (!userPats_[0]) { | 210 | if (!userPats_[0]) { |
@@ -320,8 +356,9 @@ const iString *absoluteUrl_String(const iString *d, const iString *urlMaybeRelat | |||
320 | } | 356 | } |
321 | delete_String(decHost); | 357 | delete_String(decHost); |
322 | /* Default Gemini port is removed as redundant; normalization. */ | 358 | /* Default Gemini port is removed as redundant; normalization. */ |
323 | if (!isEmpty_Range(&selHost->port) && (!equalCase_Rangecc(scheme, "gemini") | 359 | if (!isEmpty_Range(&selHost->port) && |
324 | || !equal_Rangecc(selHost->port, "1965"))) { | 360 | (!equalCase_Rangecc(scheme, "gemini") || |
361 | !equal_Rangecc(selHost->port, GEMINI_DEFAULT_PORT_CSTR))) { | ||
325 | appendCStr_String(absolute, ":"); | 362 | appendCStr_String(absolute, ":"); |
326 | appendRange_String(absolute, selHost->port); | 363 | appendRange_String(absolute, selHost->port); |
327 | } | 364 | } |
diff --git a/src/gmutil.h b/src/gmutil.h index be6b471e..40fa1cf9 100644 --- a/src/gmutil.h +++ b/src/gmutil.h | |||
@@ -93,6 +93,9 @@ const iGmError * get_GmError (enum iGmStatusCode code); | |||
93 | 93 | ||
94 | iRegExp * newGemtextLink_RegExp (void); | 94 | iRegExp * newGemtextLink_RegExp (void); |
95 | 95 | ||
96 | #define GEMINI_DEFAULT_PORT ((uint16_t) 1965) | ||
97 | #define GEMINI_DEFAULT_PORT_CSTR "1965" | ||
98 | |||
96 | struct Impl_Url { | 99 | struct Impl_Url { |
97 | iRangecc scheme; | 100 | iRangecc scheme; |
98 | iRangecc host; | 101 | iRangecc host; |
@@ -103,9 +106,11 @@ struct Impl_Url { | |||
103 | }; | 106 | }; |
104 | 107 | ||
105 | void init_Url (iUrl *, const iString *text); | 108 | void init_Url (iUrl *, const iString *text); |
109 | uint16_t port_Url (const iUrl *); | ||
106 | 110 | ||
107 | iRangecc urlScheme_String (const iString *); | 111 | iRangecc urlScheme_String (const iString *); |
108 | iRangecc urlHost_String (const iString *); | 112 | iRangecc urlHost_String (const iString *); |
113 | uint16_t urlPort_String (const iString *); | ||
109 | iRangecc urlUser_String (const iString *); | 114 | iRangecc urlUser_String (const iString *); |
110 | iRangecc urlRoot_String (const iString *); | 115 | iRangecc urlRoot_String (const iString *); |
111 | const iString * absoluteUrl_String (const iString *, const iString *urlMaybeRelative); | 116 | const iString * absoluteUrl_String (const iString *, const iString *urlMaybeRelative); |
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index 6524d454..962ccc3b 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c | |||
@@ -2623,8 +2623,9 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) | |||
2623 | } | 2623 | } |
2624 | else if (equal_Command(cmd, "server.trustcert") && document_App() == d) { | 2624 | else if (equal_Command(cmd, "server.trustcert") && document_App() == d) { |
2625 | const iRangecc host = urlHost_String(d->mod.url); | 2625 | const iRangecc host = urlHost_String(d->mod.url); |
2626 | const uint16_t port = urlPort_String(d->mod.url); | ||
2626 | if (!isEmpty_Block(d->certFingerprint) && !isEmpty_Range(&host)) { | 2627 | if (!isEmpty_Block(d->certFingerprint) && !isEmpty_Range(&host)) { |
2627 | setTrusted_GmCerts(certs_App(), host, d->certFingerprint, &d->certExpiry); | 2628 | setTrusted_GmCerts(certs_App(), host, port, d->certFingerprint, &d->certExpiry); |
2628 | d->certFlags |= trusted_GmCertFlag; | 2629 | d->certFlags |= trusted_GmCertFlag; |
2629 | postCommand_Widget(w, "document.info"); | 2630 | postCommand_Widget(w, "document.info"); |
2630 | updateTrust_DocumentWidget_(d, NULL); | 2631 | updateTrust_DocumentWidget_(d, NULL); |
@@ -3993,7 +3994,8 @@ static void drawBannerRun_DrawContext_(iDrawContext *d, const iGmRun *run, iInt2 | |||
3993 | if (certFlags & timeVerified_GmCertFlag && certFlags & domainVerified_GmCertFlag) { | 3994 | if (certFlags & timeVerified_GmCertFlag && certFlags & domainVerified_GmCertFlag) { |
3994 | iUrl parts; | 3995 | iUrl parts; |
3995 | init_Url(&parts, d->widget->mod.url); | 3996 | init_Url(&parts, d->widget->mod.url); |
3996 | const iTime oldUntil = domainValidUntil_GmCerts(certs_App(), parts.host); | 3997 | const iTime oldUntil = |
3998 | domainValidUntil_GmCerts(certs_App(), parts.host, port_Url(&parts)); | ||
3997 | iDate exp; | 3999 | iDate exp; |
3998 | init_Date(&exp, &oldUntil); | 4000 | init_Date(&exp, &oldUntil); |
3999 | iTime now; | 4001 | iTime now; |
@@ -4192,7 +4194,7 @@ static void drawRun_DrawContext_(void *context, const iGmRun *run) { | |||
4192 | height_Rect(run->visBounds), | 4194 | height_Rect(run->visBounds), |
4193 | tmQuoteIcon_ColorId); | 4195 | tmQuoteIcon_ColorId); |
4194 | } | 4196 | } |
4195 | drawBoundRange_Text(run->font, visPos, width_Rect(run->bounds), fg, run->text); | 4197 | drawRange_Text(run->font, visPos, /*width_Rect(run->bounds),*/ fg, run->text); |
4196 | runDrawn:; | 4198 | runDrawn:; |
4197 | } | 4199 | } |
4198 | /* Presentation of links. */ | 4200 | /* Presentation of links. */ |
@@ -4324,8 +4326,8 @@ static void drawRun_DrawContext_(void *context, const iGmRun *run) { | |||
4324 | } | 4326 | } |
4325 | } | 4327 | } |
4326 | } | 4328 | } |
4327 | // drawRect_Paint(&d->paint, (iRect){ visPos, run->bounds.size }, green_ColorId); | 4329 | drawRect_Paint(&d->paint, (iRect){ visPos, run->bounds.size }, green_ColorId); |
4328 | // drawRect_Paint(&d->paint, (iRect){ visPos, run->visBounds.size }, red_ColorId); | 4330 | drawRect_Paint(&d->paint, (iRect){ visPos, run->visBounds.size }, red_ColorId); |
4329 | } | 4331 | } |
4330 | 4332 | ||
4331 | static int drawSideRect_(iPaint *p, iRect rect) { | 4333 | static int drawSideRect_(iPaint *p, iRect rect) { |