Fossil SCM
Enhancement to robot defense. The auto-hyperlink setting can now be 2 (UserAgent only) in which case the UserAgent string is consulted and hyperlinks are generated if and only if the UserAgent looks human. Javascript does not come into play. When auto-hyperlink is 1, the traditional Javascript changes to href= in anchor tags are still used.
Commit
df337eb61c8e6327449f315bfd57ec14e57f346583826ec43ccb2ac910078454
Parent
cef15ed3d3dcfef…
7 files changed
+38
-5
+8
-7
+1
-1
+2
-2
+102
-49
+3
-3
+22
-22
M
src/db.c
+38
-5
| --- src/db.c | ||
| +++ src/db.c | ||
| @@ -3869,15 +3869,48 @@ | ||
| 3869 | 3869 | ** If enabled, the /login page provides a button that will automatically |
| 3870 | 3870 | ** fill in the captcha password. This makes things easier for human users, |
| 3871 | 3871 | ** at the expense of also making logins easier for malicious robots. |
| 3872 | 3872 | */ |
| 3873 | 3873 | /* |
| 3874 | -** SETTING: auto-hyperlink boolean default=on | |
| 3875 | -** Use javascript to enable hyperlinks on web pages | |
| 3876 | -** for all users (regardless of the "h" privilege) if the | |
| 3877 | -** User-Agent string in the HTTP header look like it came | |
| 3878 | -** from real person, not a spider or bot. | |
| 3874 | +** SETTING: auto-hyperlink width=16 default=1 | |
| 3875 | +** | |
| 3876 | +** If non-zero, enable hyperlinks on web pages even for users that lack | |
| 3877 | +** the "h" privilege as long as the UserAgent string in the HTTP request | |
| 3878 | +** (The HTTP_USER_AGENT cgi variable) looks like it comes from a human and | |
| 3879 | +** not a robot. Details depend on the value of the setting. | |
| 3880 | +** | |
| 3881 | +** (0) Off: No adjustments are made to the 'h' privilege based on | |
| 3882 | +** the user agent. | |
| 3883 | +** | |
| 3884 | +** (1) UserAgent and Javascript: The the href= values of hyperlinks | |
| 3885 | +** initially point to /honeypot and are changed to point to the | |
| 3886 | +** correct target by javascript that runs after the page loads. | |
| 3887 | +** The auto-hyperlink-delay and auto-hyperlink-mouseover settings | |
| 3888 | +** influence that javascript. | |
| 3889 | +** | |
| 3890 | +** (2) UserAgent only: If the HTTP_USER_AGENT looks human | |
| 3891 | +** then generate hyperlinks, otherwise do not. | |
| 3892 | +** | |
| 3893 | +** Better robot exclusion is obtained when this setting is 1 versus 2. | |
| 3894 | +** However, a value of 1 causes the visited/unvisited colors of hyperlinks | |
| 3895 | +** to stop working on Safari-derived web browsers. When this setting is 2, | |
| 3896 | +** the hyperlinks work better on Safari, but more robots are able to sneak | |
| 3897 | +** in. | |
| 3898 | +*/ | |
| 3899 | +/* SETTING: auto-hyperlink-delay width=16 default=0 | |
| 3900 | +** | |
| 3901 | +** When the auto-hyperlink setting is 1, the javascript that runs to set | |
| 3902 | +** the href= attributes of hyperlinks delays by this many milliseconds | |
| 3903 | +** after the page load. Suggested values: 50 to 200. | |
| 3904 | +*/ | |
| 3905 | +/* Setting: auto-hyperlink-mouseover boolean default=off | |
| 3906 | +** | |
| 3907 | +** When the auto-hyperlink setting is 1 and this setting is on, the | |
| 3908 | +** javascript that runs to set the href= attributes of hyperlinks waits | |
| 3909 | +** until either a mousedown or mousemove event is seen. This helps | |
| 3910 | +** to distinguish real users from robots. For maximum robot defense, | |
| 3911 | +** the recommended setting is ON. | |
| 3879 | 3912 | */ |
| 3880 | 3913 | /* |
| 3881 | 3914 | ** SETTING: auto-shun boolean default=on |
| 3882 | 3915 | ** If enabled, automatically pull the shunning list |
| 3883 | 3916 | ** from a server to which the client autosyncs. |
| 3884 | 3917 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -3869,15 +3869,48 @@ | |
| 3869 | ** If enabled, the /login page provides a button that will automatically |
| 3870 | ** fill in the captcha password. This makes things easier for human users, |
| 3871 | ** at the expense of also making logins easier for malicious robots. |
| 3872 | */ |
| 3873 | /* |
| 3874 | ** SETTING: auto-hyperlink boolean default=on |
| 3875 | ** Use javascript to enable hyperlinks on web pages |
| 3876 | ** for all users (regardless of the "h" privilege) if the |
| 3877 | ** User-Agent string in the HTTP header look like it came |
| 3878 | ** from real person, not a spider or bot. |
| 3879 | */ |
| 3880 | /* |
| 3881 | ** SETTING: auto-shun boolean default=on |
| 3882 | ** If enabled, automatically pull the shunning list |
| 3883 | ** from a server to which the client autosyncs. |
| 3884 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -3869,15 +3869,48 @@ | |
| 3869 | ** If enabled, the /login page provides a button that will automatically |
| 3870 | ** fill in the captcha password. This makes things easier for human users, |
| 3871 | ** at the expense of also making logins easier for malicious robots. |
| 3872 | */ |
| 3873 | /* |
| 3874 | ** SETTING: auto-hyperlink width=16 default=1 |
| 3875 | ** |
| 3876 | ** If non-zero, enable hyperlinks on web pages even for users that lack |
| 3877 | ** the "h" privilege as long as the UserAgent string in the HTTP request |
| 3878 | ** (The HTTP_USER_AGENT cgi variable) looks like it comes from a human and |
| 3879 | ** not a robot. Details depend on the value of the setting. |
| 3880 | ** |
| 3881 | ** (0) Off: No adjustments are made to the 'h' privilege based on |
| 3882 | ** the user agent. |
| 3883 | ** |
| 3884 | ** (1) UserAgent and Javascript: The the href= values of hyperlinks |
| 3885 | ** initially point to /honeypot and are changed to point to the |
| 3886 | ** correct target by javascript that runs after the page loads. |
| 3887 | ** The auto-hyperlink-delay and auto-hyperlink-mouseover settings |
| 3888 | ** influence that javascript. |
| 3889 | ** |
| 3890 | ** (2) UserAgent only: If the HTTP_USER_AGENT looks human |
| 3891 | ** then generate hyperlinks, otherwise do not. |
| 3892 | ** |
| 3893 | ** Better robot exclusion is obtained when this setting is 1 versus 2. |
| 3894 | ** However, a value of 1 causes the visited/unvisited colors of hyperlinks |
| 3895 | ** to stop working on Safari-derived web browsers. When this setting is 2, |
| 3896 | ** the hyperlinks work better on Safari, but more robots are able to sneak |
| 3897 | ** in. |
| 3898 | */ |
| 3899 | /* SETTING: auto-hyperlink-delay width=16 default=0 |
| 3900 | ** |
| 3901 | ** When the auto-hyperlink setting is 1, the javascript that runs to set |
| 3902 | ** the href= attributes of hyperlinks delays by this many milliseconds |
| 3903 | ** after the page load. Suggested values: 50 to 200. |
| 3904 | */ |
| 3905 | /* Setting: auto-hyperlink-mouseover boolean default=off |
| 3906 | ** |
| 3907 | ** When the auto-hyperlink setting is 1 and this setting is on, the |
| 3908 | ** javascript that runs to set the href= attributes of hyperlinks waits |
| 3909 | ** until either a mousedown or mousemove event is seen. This helps |
| 3910 | ** to distinguish real users from robots. For maximum robot defense, |
| 3911 | ** the recommended setting is ON. |
| 3912 | */ |
| 3913 | /* |
| 3914 | ** SETTING: auto-shun boolean default=on |
| 3915 | ** If enabled, automatically pull the shunning list |
| 3916 | ** from a server to which the client autosyncs. |
| 3917 |
+8
-7
| --- src/login.c | ||
| +++ src/login.c | ||
| @@ -1178,17 +1178,18 @@ | ||
| 1178 | 1178 | ** enabled for this repository and make appropriate adjustments to the |
| 1179 | 1179 | ** permission flags if it is. This should be done before the permissions |
| 1180 | 1180 | ** are (potentially) copied to the anonymous permission set; otherwise, |
| 1181 | 1181 | ** those will be out-of-sync. |
| 1182 | 1182 | */ |
| 1183 | - if( zCap[0] | |
| 1184 | - && !g.perm.Hyperlink | |
| 1185 | - && g.isHuman | |
| 1186 | - && db_get_boolean("auto-hyperlink",1) | |
| 1187 | - ){ | |
| 1188 | - g.perm.Hyperlink = 1; | |
| 1189 | - g.javascriptHyperlink = 1; | |
| 1183 | + if( zCap[0] && !g.perm.Hyperlink && g.isHuman ){ | |
| 1184 | + int autoLink = db_get_int("auto-hyperlink",1); | |
| 1185 | + if( autoLink==1 ){ | |
| 1186 | + g.jsHref = 1; | |
| 1187 | + g.perm.Hyperlink = 1; | |
| 1188 | + }else if( autoLink==2 ){ | |
| 1189 | + g.perm.Hyperlink = 1; | |
| 1190 | + } | |
| 1190 | 1191 | } |
| 1191 | 1192 | |
| 1192 | 1193 | /* |
| 1193 | 1194 | ** At this point, the capabilities for the logged in user are not going |
| 1194 | 1195 | ** to be modified anymore; therefore, we can copy them over to the ones |
| 1195 | 1196 |
| --- src/login.c | |
| +++ src/login.c | |
| @@ -1178,17 +1178,18 @@ | |
| 1178 | ** enabled for this repository and make appropriate adjustments to the |
| 1179 | ** permission flags if it is. This should be done before the permissions |
| 1180 | ** are (potentially) copied to the anonymous permission set; otherwise, |
| 1181 | ** those will be out-of-sync. |
| 1182 | */ |
| 1183 | if( zCap[0] |
| 1184 | && !g.perm.Hyperlink |
| 1185 | && g.isHuman |
| 1186 | && db_get_boolean("auto-hyperlink",1) |
| 1187 | ){ |
| 1188 | g.perm.Hyperlink = 1; |
| 1189 | g.javascriptHyperlink = 1; |
| 1190 | } |
| 1191 | |
| 1192 | /* |
| 1193 | ** At this point, the capabilities for the logged in user are not going |
| 1194 | ** to be modified anymore; therefore, we can copy them over to the ones |
| 1195 |
| --- src/login.c | |
| +++ src/login.c | |
| @@ -1178,17 +1178,18 @@ | |
| 1178 | ** enabled for this repository and make appropriate adjustments to the |
| 1179 | ** permission flags if it is. This should be done before the permissions |
| 1180 | ** are (potentially) copied to the anonymous permission set; otherwise, |
| 1181 | ** those will be out-of-sync. |
| 1182 | */ |
| 1183 | if( zCap[0] && !g.perm.Hyperlink && g.isHuman ){ |
| 1184 | int autoLink = db_get_int("auto-hyperlink",1); |
| 1185 | if( autoLink==1 ){ |
| 1186 | g.jsHref = 1; |
| 1187 | g.perm.Hyperlink = 1; |
| 1188 | }else if( autoLink==2 ){ |
| 1189 | g.perm.Hyperlink = 1; |
| 1190 | } |
| 1191 | } |
| 1192 | |
| 1193 | /* |
| 1194 | ** At this point, the capabilities for the logged in user are not going |
| 1195 | ** to be modified anymore; therefore, we can copy them over to the ones |
| 1196 |
+1
-1
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -206,11 +206,11 @@ | ||
| 206 | 206 | int markPrivate; /* All new artifacts are private if true */ |
| 207 | 207 | char *ckinLockFail; /* Check-in lock failure received from server */ |
| 208 | 208 | int clockSkewSeen; /* True if clocks on client and server out of sync */ |
| 209 | 209 | int wikiFlags; /* Wiki conversion flags applied to %W */ |
| 210 | 210 | char isHTTP; /* True if server/CGI modes, else assume CLI. */ |
| 211 | - char javascriptHyperlink; /* If true, set href= using script, not HTML */ | |
| 211 | + char jsHref; /* If true, set href= using javascript, not HTML */ | |
| 212 | 212 | Blob httpHeader; /* Complete text of the HTTP request header */ |
| 213 | 213 | UrlData url; /* Information about current URL */ |
| 214 | 214 | const char *zLogin; /* Login name. NULL or "" if not logged in. */ |
| 215 | 215 | const char *zCkoutAlias; /* doc/ uses this branch as an alias for "ckout" */ |
| 216 | 216 | const char *zMainMenuFile; /* --mainmenu FILE from server/ui/cgi */ |
| 217 | 217 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -206,11 +206,11 @@ | |
| 206 | int markPrivate; /* All new artifacts are private if true */ |
| 207 | char *ckinLockFail; /* Check-in lock failure received from server */ |
| 208 | int clockSkewSeen; /* True if clocks on client and server out of sync */ |
| 209 | int wikiFlags; /* Wiki conversion flags applied to %W */ |
| 210 | char isHTTP; /* True if server/CGI modes, else assume CLI. */ |
| 211 | char javascriptHyperlink; /* If true, set href= using script, not HTML */ |
| 212 | Blob httpHeader; /* Complete text of the HTTP request header */ |
| 213 | UrlData url; /* Information about current URL */ |
| 214 | const char *zLogin; /* Login name. NULL or "" if not logged in. */ |
| 215 | const char *zCkoutAlias; /* doc/ uses this branch as an alias for "ckout" */ |
| 216 | const char *zMainMenuFile; /* --mainmenu FILE from server/ui/cgi */ |
| 217 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -206,11 +206,11 @@ | |
| 206 | int markPrivate; /* All new artifacts are private if true */ |
| 207 | char *ckinLockFail; /* Check-in lock failure received from server */ |
| 208 | int clockSkewSeen; /* True if clocks on client and server out of sync */ |
| 209 | int wikiFlags; /* Wiki conversion flags applied to %W */ |
| 210 | char isHTTP; /* True if server/CGI modes, else assume CLI. */ |
| 211 | char jsHref; /* If true, set href= using javascript, not HTML */ |
| 212 | Blob httpHeader; /* Complete text of the HTTP request header */ |
| 213 | UrlData url; /* Information about current URL */ |
| 214 | const char *zLogin; /* Login name. NULL or "" if not logged in. */ |
| 215 | const char *zCkoutAlias; /* doc/ uses this branch as an alias for "ckout" */ |
| 216 | const char *zMainMenuFile; /* --mainmenu FILE from server/ui/cgi */ |
| 217 |
+2
-2
| --- src/security_audit.c | ||
| +++ src/security_audit.c | ||
| @@ -487,13 +487,13 @@ | ||
| 487 | 487 | @ Suggested remediation: |
| 488 | 488 | @ <ol type="a"> |
| 489 | 489 | @ <li>Remove the 'h' privilege from the |
| 490 | 490 | @ <a href="%R/setup_uedit?id=%d(nobodyId)">'nobody' user</a> so that |
| 491 | 491 | @ robots cannot see hyperlinks. |
| 492 | - @ <li>Activate <a href="%R/setup_access#autoh">autohyperlink</a> so that | |
| 492 | + @ <li>Activate <a href="%R/setup_robot">autohyperlink</a> so that | |
| 493 | 493 | @ human readers can still see hyperlinks even if they are not logged in. |
| 494 | - @ Set the delay to at least 50 milliseconds and require a mousedown | |
| 494 | + @ Set the delay to at least 50 milliseconds and require a mouse | |
| 495 | 495 | @ event for maximum robot defense. |
| 496 | 496 | if( anonId>0 ){ |
| 497 | 497 | @ <li>Perhaps set the 'h' privilege on the |
| 498 | 498 | @ <a href="%R/setup_uedit?id=%d(anonId)">'anonymous' user</a> so |
| 499 | 499 | @ that humans that have javascript disabled in their browsers can |
| 500 | 500 |
| --- src/security_audit.c | |
| +++ src/security_audit.c | |
| @@ -487,13 +487,13 @@ | |
| 487 | @ Suggested remediation: |
| 488 | @ <ol type="a"> |
| 489 | @ <li>Remove the 'h' privilege from the |
| 490 | @ <a href="%R/setup_uedit?id=%d(nobodyId)">'nobody' user</a> so that |
| 491 | @ robots cannot see hyperlinks. |
| 492 | @ <li>Activate <a href="%R/setup_access#autoh">autohyperlink</a> so that |
| 493 | @ human readers can still see hyperlinks even if they are not logged in. |
| 494 | @ Set the delay to at least 50 milliseconds and require a mousedown |
| 495 | @ event for maximum robot defense. |
| 496 | if( anonId>0 ){ |
| 497 | @ <li>Perhaps set the 'h' privilege on the |
| 498 | @ <a href="%R/setup_uedit?id=%d(anonId)">'anonymous' user</a> so |
| 499 | @ that humans that have javascript disabled in their browsers can |
| 500 |
| --- src/security_audit.c | |
| +++ src/security_audit.c | |
| @@ -487,13 +487,13 @@ | |
| 487 | @ Suggested remediation: |
| 488 | @ <ol type="a"> |
| 489 | @ <li>Remove the 'h' privilege from the |
| 490 | @ <a href="%R/setup_uedit?id=%d(nobodyId)">'nobody' user</a> so that |
| 491 | @ robots cannot see hyperlinks. |
| 492 | @ <li>Activate <a href="%R/setup_robot">autohyperlink</a> so that |
| 493 | @ human readers can still see hyperlinks even if they are not logged in. |
| 494 | @ Set the delay to at least 50 milliseconds and require a mouse |
| 495 | @ event for maximum robot defense. |
| 496 | if( anonId>0 ){ |
| 497 | @ <li>Perhaps set the 'h' privilege on the |
| 498 | @ <a href="%R/setup_uedit?id=%d(anonId)">'anonymous' user</a> so |
| 499 | @ that humans that have javascript disabled in their browsers can |
| 500 |
+102
-49
| --- src/setup.c | ||
| +++ src/setup.c | ||
| @@ -111,10 +111,12 @@ | ||
| 111 | 111 | "Configure the WWW components of the repository"); |
| 112 | 112 | } |
| 113 | 113 | setup_menu_entry("Security-Audit", "secaudit0", |
| 114 | 114 | "Analyze the current configuration for security problems"); |
| 115 | 115 | if( setup_user ){ |
| 116 | + setup_menu_entry("Robot-Defense", "setup_robot", | |
| 117 | + "Settings for configure defense against robots"); | |
| 116 | 118 | setup_menu_entry("Settings", "setup_settings", |
| 117 | 119 | "Web interface to the \"fossil settings\" command"); |
| 118 | 120 | } |
| 119 | 121 | setup_menu_entry("Timeline", "setup_timeline", |
| 120 | 122 | "Timeline display preferences"); |
| @@ -322,10 +324,105 @@ | ||
| 322 | 324 | @ <option value="%h(azChoice[i])"%s(zSel)>%h(azChoice[i+1])</option> |
| 323 | 325 | } |
| 324 | 326 | @ </select> <b>%h(zLabel)</b> |
| 325 | 327 | } |
| 326 | 328 | |
| 329 | +/* | |
| 330 | +** Insert code into the current page that allows the user to configure | |
| 331 | +** auto-hyperlink related robot defense settings. | |
| 332 | +*/ | |
| 333 | +static void addAutoHyperlinkSettings(void){ | |
| 334 | + static const char *const azDefenseOpts[] = { | |
| 335 | + "0", "Off", | |
| 336 | + "2", "UserAgent only", | |
| 337 | + "1", "UserAgent and Javascript", | |
| 338 | + }; | |
| 339 | + multiple_choice_attribute( | |
| 340 | + "Enable hyperlinks base on User-Agent and/or Javascript", | |
| 341 | + "auto-hyperlink", "autohyperlink", "1", | |
| 342 | + count(azDefenseOpts)/2, azDefenseOpts); | |
| 343 | + @ <p>Enable hyperlinks (the equivalent of the "h" permission) for all users, | |
| 344 | + @ including user "nobody", as long as the User-Agent string in the | |
| 345 | + @ HTTP header indicates that the request is coming from an actual human | |
| 346 | + @ being. If this setting is "UserAgent only" (2) then the | |
| 347 | + @ UserAgent string is the only factor considered. If the value of this | |
| 348 | + @ setting is "UserAgent And Javascript" (1) then Javascript is added that | |
| 349 | + @ runs after the page loads and fills in the href= values of <a> | |
| 350 | + @ elements. In either case, <a> tags are only generated if the | |
| 351 | + @ UserAgent string indicates that the request is coming from a human and | |
| 352 | + @ not a robot. | |
| 353 | + @ | |
| 354 | + @ <p>This setting is designed to give easy access to humans while | |
| 355 | + @ keeping out robots. | |
| 356 | + @ You do not normally want a robot to walk your entire repository because | |
| 357 | + @ if it does, your server will end up computing diffs and annotations for | |
| 358 | + @ every historical version of every file and creating ZIPs and tarballs of | |
| 359 | + @ every historical check-in, which can use a lot of CPU and bandwidth | |
| 360 | + @ even for relatively small projects.</p> | |
| 361 | + @ | |
| 362 | + @ <p>The "UserAgent and Javascript" value for this setting provides | |
| 363 | + @ superior protection from robots. However, that setting also prevents | |
| 364 | + @ the visited/unvisited colors on hyperlinks from displaying correctly | |
| 365 | + @ on Safara-derived browsers. (Chrome and Firefox work fine.) Since | |
| 366 | + @ Safari is the underlying rendering engine on all iPhones and iPads, | |
| 367 | + @ this means that hyperlink visited/unvisited colors will not operate | |
| 368 | + @ on those platforms when "UserAgent and Javascript" is selected.</p> | |
| 369 | + @ | |
| 370 | + @ <p>Additional parameters that control the behavior of Javascript:</p> | |
| 371 | + @ <blockquote> | |
| 372 | + entry_attribute("Delay in milliseconds before enabling hyperlinks", 5, | |
| 373 | + "auto-hyperlink-delay", "ah-delay", "50", 0); | |
| 374 | + @ <br /> | |
| 375 | + onoff_attribute("Also require a mouse event before enabling hyperlinks", | |
| 376 | + "auto-hyperlink-mouseover", "ahmo", 0, 0); | |
| 377 | + @ </blockquote> | |
| 378 | + @ <p>For maximum robot defense, "Delay" should be at least 50 milliseconds | |
| 379 | + @ and "require a mouse event" should be turned on. These values only come | |
| 380 | + @ into play when the main auto-hyperlink settings is 2 ("UserAgent and | |
| 381 | + @ Javascript").</p> | |
| 382 | + @ | |
| 383 | + @ <p>To see if Javascript-base hyperlink enabling mechanism is working, | |
| 384 | + @ visit the <a href="%R/test_env">/test_env</a> page (from a separate | |
| 385 | + @ web browser that is not logged in, even as "anonymous") and verify | |
| 386 | + @ that the "g.jsHref" value is "1".</p> | |
| 387 | + @ <p>(Properties: "auto-hyperlink", "auto-hyperlink-delay", and | |
| 388 | + @ "auto-hyperlink-mouseover"")</p> | |
| 389 | +} | |
| 390 | + | |
| 391 | +/* | |
| 392 | +** WEBPAGE: setup_robot | |
| 393 | +** | |
| 394 | +** Settings associated with defense against robots. Requires setup privilege. | |
| 395 | +*/ | |
| 396 | +void setup_robots(void){ | |
| 397 | + login_check_credentials(); | |
| 398 | + if( !g.perm.Setup ){ | |
| 399 | + login_needed(0); | |
| 400 | + return; | |
| 401 | + } | |
| 402 | + style_set_current_feature("setup"); | |
| 403 | + style_header("Robot Defense Settings"); | |
| 404 | + db_begin_transaction(); | |
| 405 | + @ <p>A Fossil website can have billions of pages in its tree, even for a | |
| 406 | + @ modest project. Many of those pages (examples: diffs and tarballs) | |
| 407 | + @ might be expensive to compute. A robot that tries to walk the entire | |
| 408 | + @ website can present a crippling CPU and bandwidth load. | |
| 409 | + @ | |
| 410 | + @ <p>The settings on this page are intended to help site administrators | |
| 411 | + @ defend the site against robots. | |
| 412 | + @ | |
| 413 | + @ <form action="%R/setup_robot" method="post"><div> | |
| 414 | + login_insert_csrf_secret(); | |
| 415 | + @ <input type="submit" name="submit" value="Apply Changes" /></p> | |
| 416 | + @ <hr /> | |
| 417 | + addAutoHyperlinkSettings(); | |
| 418 | + @ <hr /> | |
| 419 | + @ <p><input type="submit" name="submit" value="Apply Changes" /></p> | |
| 420 | + @ </div></form> | |
| 421 | + db_end_transaction(0); | |
| 422 | + style_finish_page(); | |
| 423 | +} | |
| 327 | 424 | |
| 328 | 425 | /* |
| 329 | 426 | ** WEBPAGE: setup_access |
| 330 | 427 | ** |
| 331 | 428 | ** The access-control settings page. Requires Setup privileges. |
| @@ -460,59 +557,15 @@ | ||
| 460 | 557 | @ This limit is only enforced on Unix servers. On Linux systems, |
| 461 | 558 | @ access to the /proc virtual filesystem is required, which means this limit |
| 462 | 559 | @ might not work inside a chroot() jail. |
| 463 | 560 | @ (Property: "max-loadavg")</p> |
| 464 | 561 | |
| 465 | - @ <hr /> | |
| 466 | - @ <p><input type="submit" name="submit" value="Apply Changes" /></p> | |
| 467 | - | |
| 468 | - @ <a id="autoh"></a> | |
| 469 | - @ <hr /> | |
| 470 | - onoff_attribute( | |
| 471 | - "Enable hyperlinks for \"nobody\" based on User-Agent and Javascript", | |
| 472 | - "auto-hyperlink", "autohyperlink", 1, 0); | |
| 473 | - @ <p>Enable hyperlinks (the equivalent of the "h" permission) for all users, | |
| 474 | - @ including user "nobody", as long as | |
| 475 | - @ <ol><li>the User-Agent string in the | |
| 476 | - @ HTTP header indicates that the request is coming from an actual human | |
| 477 | - @ being, and | |
| 478 | - @ <li>the user agent is able to | |
| 479 | - @ run Javascript in order to set the href= attribute of hyperlinks, and | |
| 480 | - @ <li>a number of milliseconds have passed since the page loaded, and | |
| 481 | - @ <li>a mousedown event is detected (optional - see the checkbox below) | |
| 482 | - @ </ol> | |
| 483 | - @ | |
| 484 | - @ <p>This setting is designed to give easy access to humans while | |
| 485 | - @ keeping out robots and spiders. | |
| 486 | - @ You do not normally want a robot to walk your entire repository because | |
| 487 | - @ if it does, your server will end up computing diffs and annotations for | |
| 488 | - @ every historical version of every file and creating ZIPs and tarballs of | |
| 489 | - @ every historical check-in, which can use a lot of CPU and bandwidth | |
| 490 | - @ even for relatively small projects.</p> | |
| 491 | - @ | |
| 492 | - @ <p>Limitation: Hyperlink visited/unvisited colors will not work | |
| 493 | - @ correctly with this option on Safari-based browsers. They work fine | |
| 494 | - @ on Chrome-based browsers and on Firefox, but not Safari. Since | |
| 495 | - @ Safari is the underlying rendering engine on all iPhones and iPads, | |
| 496 | - @ this means that hyperlink visited/unvisited colors will not operate | |
| 497 | - @ on those platforms when this option is enabled.</p> | |
| 498 | - @ | |
| 499 | - @ <p>Additional parameters that control this behavior:</p> | |
| 500 | - @ <blockquote> | |
| 501 | - entry_attribute("Delay in milliseconds before enabling hyperlinks", 5, | |
| 502 | - "auto-hyperlink-delay", "ah-delay", "50", 0); | |
| 503 | - @ <br /> | |
| 504 | - onoff_attribute("Also require a mouse event before enabling hyperlinks", | |
| 505 | - "auto-hyperlink-mouseover", "ahmo", 0, 0); | |
| 506 | - @ </blockquote> | |
| 507 | - @ <p>For maximum robot defense, "Delay" should be at least 50 milliseconds | |
| 508 | - @ and "require a mouse event" should be turned on. To test to see that | |
| 509 | - @ this mechanism is working, visit the <a href="%R/test_env">/test_env</a> | |
| 510 | - @ page (from a separate web browser that is not logged in, even as | |
| 511 | - @ "anonymous") and verify that the "g.javascriptHyperlink" value is "1".</p> | |
| 512 | - @ <p>(Properties: "auto-hyperlink", "auto-hyperlink-delay", and | |
| 513 | - @ "auto-hyperlink-mouseover"")</p> | |
| 562 | + /* Add the auto-hyperlink settings controls. These same controls | |
| 563 | + ** are also accessible from the /setup_robot page. | |
| 564 | + */ | |
| 565 | + @ <hr /> | |
| 566 | + addAutoHyperlinkSettings(); | |
| 514 | 567 | |
| 515 | 568 | @ <hr /> |
| 516 | 569 | onoff_attribute("Require a CAPTCHA if not logged in", |
| 517 | 570 | "require-captcha", "reqcapt", 1, 0); |
| 518 | 571 | @ <p>Require a CAPTCHA for edit operations (appending, creating, or |
| 519 | 572 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -111,10 +111,12 @@ | |
| 111 | "Configure the WWW components of the repository"); |
| 112 | } |
| 113 | setup_menu_entry("Security-Audit", "secaudit0", |
| 114 | "Analyze the current configuration for security problems"); |
| 115 | if( setup_user ){ |
| 116 | setup_menu_entry("Settings", "setup_settings", |
| 117 | "Web interface to the \"fossil settings\" command"); |
| 118 | } |
| 119 | setup_menu_entry("Timeline", "setup_timeline", |
| 120 | "Timeline display preferences"); |
| @@ -322,10 +324,105 @@ | |
| 322 | @ <option value="%h(azChoice[i])"%s(zSel)>%h(azChoice[i+1])</option> |
| 323 | } |
| 324 | @ </select> <b>%h(zLabel)</b> |
| 325 | } |
| 326 | |
| 327 | |
| 328 | /* |
| 329 | ** WEBPAGE: setup_access |
| 330 | ** |
| 331 | ** The access-control settings page. Requires Setup privileges. |
| @@ -460,59 +557,15 @@ | |
| 460 | @ This limit is only enforced on Unix servers. On Linux systems, |
| 461 | @ access to the /proc virtual filesystem is required, which means this limit |
| 462 | @ might not work inside a chroot() jail. |
| 463 | @ (Property: "max-loadavg")</p> |
| 464 | |
| 465 | @ <hr /> |
| 466 | @ <p><input type="submit" name="submit" value="Apply Changes" /></p> |
| 467 | |
| 468 | @ <a id="autoh"></a> |
| 469 | @ <hr /> |
| 470 | onoff_attribute( |
| 471 | "Enable hyperlinks for \"nobody\" based on User-Agent and Javascript", |
| 472 | "auto-hyperlink", "autohyperlink", 1, 0); |
| 473 | @ <p>Enable hyperlinks (the equivalent of the "h" permission) for all users, |
| 474 | @ including user "nobody", as long as |
| 475 | @ <ol><li>the User-Agent string in the |
| 476 | @ HTTP header indicates that the request is coming from an actual human |
| 477 | @ being, and |
| 478 | @ <li>the user agent is able to |
| 479 | @ run Javascript in order to set the href= attribute of hyperlinks, and |
| 480 | @ <li>a number of milliseconds have passed since the page loaded, and |
| 481 | @ <li>a mousedown event is detected (optional - see the checkbox below) |
| 482 | @ </ol> |
| 483 | @ |
| 484 | @ <p>This setting is designed to give easy access to humans while |
| 485 | @ keeping out robots and spiders. |
| 486 | @ You do not normally want a robot to walk your entire repository because |
| 487 | @ if it does, your server will end up computing diffs and annotations for |
| 488 | @ every historical version of every file and creating ZIPs and tarballs of |
| 489 | @ every historical check-in, which can use a lot of CPU and bandwidth |
| 490 | @ even for relatively small projects.</p> |
| 491 | @ |
| 492 | @ <p>Limitation: Hyperlink visited/unvisited colors will not work |
| 493 | @ correctly with this option on Safari-based browsers. They work fine |
| 494 | @ on Chrome-based browsers and on Firefox, but not Safari. Since |
| 495 | @ Safari is the underlying rendering engine on all iPhones and iPads, |
| 496 | @ this means that hyperlink visited/unvisited colors will not operate |
| 497 | @ on those platforms when this option is enabled.</p> |
| 498 | @ |
| 499 | @ <p>Additional parameters that control this behavior:</p> |
| 500 | @ <blockquote> |
| 501 | entry_attribute("Delay in milliseconds before enabling hyperlinks", 5, |
| 502 | "auto-hyperlink-delay", "ah-delay", "50", 0); |
| 503 | @ <br /> |
| 504 | onoff_attribute("Also require a mouse event before enabling hyperlinks", |
| 505 | "auto-hyperlink-mouseover", "ahmo", 0, 0); |
| 506 | @ </blockquote> |
| 507 | @ <p>For maximum robot defense, "Delay" should be at least 50 milliseconds |
| 508 | @ and "require a mouse event" should be turned on. To test to see that |
| 509 | @ this mechanism is working, visit the <a href="%R/test_env">/test_env</a> |
| 510 | @ page (from a separate web browser that is not logged in, even as |
| 511 | @ "anonymous") and verify that the "g.javascriptHyperlink" value is "1".</p> |
| 512 | @ <p>(Properties: "auto-hyperlink", "auto-hyperlink-delay", and |
| 513 | @ "auto-hyperlink-mouseover"")</p> |
| 514 | |
| 515 | @ <hr /> |
| 516 | onoff_attribute("Require a CAPTCHA if not logged in", |
| 517 | "require-captcha", "reqcapt", 1, 0); |
| 518 | @ <p>Require a CAPTCHA for edit operations (appending, creating, or |
| 519 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -111,10 +111,12 @@ | |
| 111 | "Configure the WWW components of the repository"); |
| 112 | } |
| 113 | setup_menu_entry("Security-Audit", "secaudit0", |
| 114 | "Analyze the current configuration for security problems"); |
| 115 | if( setup_user ){ |
| 116 | setup_menu_entry("Robot-Defense", "setup_robot", |
| 117 | "Settings for configure defense against robots"); |
| 118 | setup_menu_entry("Settings", "setup_settings", |
| 119 | "Web interface to the \"fossil settings\" command"); |
| 120 | } |
| 121 | setup_menu_entry("Timeline", "setup_timeline", |
| 122 | "Timeline display preferences"); |
| @@ -322,10 +324,105 @@ | |
| 324 | @ <option value="%h(azChoice[i])"%s(zSel)>%h(azChoice[i+1])</option> |
| 325 | } |
| 326 | @ </select> <b>%h(zLabel)</b> |
| 327 | } |
| 328 | |
| 329 | /* |
| 330 | ** Insert code into the current page that allows the user to configure |
| 331 | ** auto-hyperlink related robot defense settings. |
| 332 | */ |
| 333 | static void addAutoHyperlinkSettings(void){ |
| 334 | static const char *const azDefenseOpts[] = { |
| 335 | "0", "Off", |
| 336 | "2", "UserAgent only", |
| 337 | "1", "UserAgent and Javascript", |
| 338 | }; |
| 339 | multiple_choice_attribute( |
| 340 | "Enable hyperlinks base on User-Agent and/or Javascript", |
| 341 | "auto-hyperlink", "autohyperlink", "1", |
| 342 | count(azDefenseOpts)/2, azDefenseOpts); |
| 343 | @ <p>Enable hyperlinks (the equivalent of the "h" permission) for all users, |
| 344 | @ including user "nobody", as long as the User-Agent string in the |
| 345 | @ HTTP header indicates that the request is coming from an actual human |
| 346 | @ being. If this setting is "UserAgent only" (2) then the |
| 347 | @ UserAgent string is the only factor considered. If the value of this |
| 348 | @ setting is "UserAgent And Javascript" (1) then Javascript is added that |
| 349 | @ runs after the page loads and fills in the href= values of <a> |
| 350 | @ elements. In either case, <a> tags are only generated if the |
| 351 | @ UserAgent string indicates that the request is coming from a human and |
| 352 | @ not a robot. |
| 353 | @ |
| 354 | @ <p>This setting is designed to give easy access to humans while |
| 355 | @ keeping out robots. |
| 356 | @ You do not normally want a robot to walk your entire repository because |
| 357 | @ if it does, your server will end up computing diffs and annotations for |
| 358 | @ every historical version of every file and creating ZIPs and tarballs of |
| 359 | @ every historical check-in, which can use a lot of CPU and bandwidth |
| 360 | @ even for relatively small projects.</p> |
| 361 | @ |
| 362 | @ <p>The "UserAgent and Javascript" value for this setting provides |
| 363 | @ superior protection from robots. However, that setting also prevents |
| 364 | @ the visited/unvisited colors on hyperlinks from displaying correctly |
| 365 | @ on Safara-derived browsers. (Chrome and Firefox work fine.) Since |
| 366 | @ Safari is the underlying rendering engine on all iPhones and iPads, |
| 367 | @ this means that hyperlink visited/unvisited colors will not operate |
| 368 | @ on those platforms when "UserAgent and Javascript" is selected.</p> |
| 369 | @ |
| 370 | @ <p>Additional parameters that control the behavior of Javascript:</p> |
| 371 | @ <blockquote> |
| 372 | entry_attribute("Delay in milliseconds before enabling hyperlinks", 5, |
| 373 | "auto-hyperlink-delay", "ah-delay", "50", 0); |
| 374 | @ <br /> |
| 375 | onoff_attribute("Also require a mouse event before enabling hyperlinks", |
| 376 | "auto-hyperlink-mouseover", "ahmo", 0, 0); |
| 377 | @ </blockquote> |
| 378 | @ <p>For maximum robot defense, "Delay" should be at least 50 milliseconds |
| 379 | @ and "require a mouse event" should be turned on. These values only come |
| 380 | @ into play when the main auto-hyperlink settings is 2 ("UserAgent and |
| 381 | @ Javascript").</p> |
| 382 | @ |
| 383 | @ <p>To see if Javascript-base hyperlink enabling mechanism is working, |
| 384 | @ visit the <a href="%R/test_env">/test_env</a> page (from a separate |
| 385 | @ web browser that is not logged in, even as "anonymous") and verify |
| 386 | @ that the "g.jsHref" value is "1".</p> |
| 387 | @ <p>(Properties: "auto-hyperlink", "auto-hyperlink-delay", and |
| 388 | @ "auto-hyperlink-mouseover"")</p> |
| 389 | } |
| 390 | |
| 391 | /* |
| 392 | ** WEBPAGE: setup_robot |
| 393 | ** |
| 394 | ** Settings associated with defense against robots. Requires setup privilege. |
| 395 | */ |
| 396 | void setup_robots(void){ |
| 397 | login_check_credentials(); |
| 398 | if( !g.perm.Setup ){ |
| 399 | login_needed(0); |
| 400 | return; |
| 401 | } |
| 402 | style_set_current_feature("setup"); |
| 403 | style_header("Robot Defense Settings"); |
| 404 | db_begin_transaction(); |
| 405 | @ <p>A Fossil website can have billions of pages in its tree, even for a |
| 406 | @ modest project. Many of those pages (examples: diffs and tarballs) |
| 407 | @ might be expensive to compute. A robot that tries to walk the entire |
| 408 | @ website can present a crippling CPU and bandwidth load. |
| 409 | @ |
| 410 | @ <p>The settings on this page are intended to help site administrators |
| 411 | @ defend the site against robots. |
| 412 | @ |
| 413 | @ <form action="%R/setup_robot" method="post"><div> |
| 414 | login_insert_csrf_secret(); |
| 415 | @ <input type="submit" name="submit" value="Apply Changes" /></p> |
| 416 | @ <hr /> |
| 417 | addAutoHyperlinkSettings(); |
| 418 | @ <hr /> |
| 419 | @ <p><input type="submit" name="submit" value="Apply Changes" /></p> |
| 420 | @ </div></form> |
| 421 | db_end_transaction(0); |
| 422 | style_finish_page(); |
| 423 | } |
| 424 | |
| 425 | /* |
| 426 | ** WEBPAGE: setup_access |
| 427 | ** |
| 428 | ** The access-control settings page. Requires Setup privileges. |
| @@ -460,59 +557,15 @@ | |
| 557 | @ This limit is only enforced on Unix servers. On Linux systems, |
| 558 | @ access to the /proc virtual filesystem is required, which means this limit |
| 559 | @ might not work inside a chroot() jail. |
| 560 | @ (Property: "max-loadavg")</p> |
| 561 | |
| 562 | /* Add the auto-hyperlink settings controls. These same controls |
| 563 | ** are also accessible from the /setup_robot page. |
| 564 | */ |
| 565 | @ <hr /> |
| 566 | addAutoHyperlinkSettings(); |
| 567 | |
| 568 | @ <hr /> |
| 569 | onoff_attribute("Require a CAPTCHA if not logged in", |
| 570 | "require-captcha", "reqcapt", 1, 0); |
| 571 | @ <p>Require a CAPTCHA for edit operations (appending, creating, or |
| 572 |
+3
-3
| --- src/sitemap.c | ||
| +++ src/sitemap.c | ||
| @@ -74,11 +74,11 @@ | ||
| 74 | 74 | if( P("popup")!=0 ){ |
| 75 | 75 | /* The "popup" query parameter |
| 76 | 76 | ** then disable anti-robot defenses */ |
| 77 | 77 | isPopup = 1; |
| 78 | 78 | g.perm.Hyperlink = 1; |
| 79 | - g.javascriptHyperlink = 0; | |
| 79 | + g.jsHref = 0; | |
| 80 | 80 | } |
| 81 | 81 | srchFlags = search_restrict(SRCH_ALL); |
| 82 | 82 | if( !isPopup ){ |
| 83 | 83 | style_header("Site Map"); |
| 84 | 84 | style_adunit_config(ADUNIT_RIGHT_OK); |
| @@ -312,11 +312,11 @@ | ||
| 312 | 312 | if( P("popup")!=0 && cgi_csrf_safe(0) ){ |
| 313 | 313 | /* If this is a POST from the same origin with the popup=1 parameter, |
| 314 | 314 | ** then disable anti-robot defenses */ |
| 315 | 315 | isPopup = 1; |
| 316 | 316 | g.perm.Hyperlink = 1; |
| 317 | - g.javascriptHyperlink = 0; | |
| 317 | + g.jsHref = 0; | |
| 318 | 318 | } |
| 319 | 319 | if( !isPopup ){ |
| 320 | 320 | style_header("Test Page Map"); |
| 321 | 321 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 322 | 322 | } |
| @@ -364,11 +364,11 @@ | ||
| 364 | 364 | if( P("popup")!=0 && cgi_csrf_safe(0) ){ |
| 365 | 365 | /* If this is a POST from the same origin with the popup=1 parameter, |
| 366 | 366 | ** then disable anti-robot defenses */ |
| 367 | 367 | isPopup = 1; |
| 368 | 368 | g.perm.Hyperlink = 1; |
| 369 | - g.javascriptHyperlink = 0; | |
| 369 | + g.jsHref = 0; | |
| 370 | 370 | } |
| 371 | 371 | if( !isPopup ){ |
| 372 | 372 | style_header("Timeline Examples"); |
| 373 | 373 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 374 | 374 | } |
| 375 | 375 |
| --- src/sitemap.c | |
| +++ src/sitemap.c | |
| @@ -74,11 +74,11 @@ | |
| 74 | if( P("popup")!=0 ){ |
| 75 | /* The "popup" query parameter |
| 76 | ** then disable anti-robot defenses */ |
| 77 | isPopup = 1; |
| 78 | g.perm.Hyperlink = 1; |
| 79 | g.javascriptHyperlink = 0; |
| 80 | } |
| 81 | srchFlags = search_restrict(SRCH_ALL); |
| 82 | if( !isPopup ){ |
| 83 | style_header("Site Map"); |
| 84 | style_adunit_config(ADUNIT_RIGHT_OK); |
| @@ -312,11 +312,11 @@ | |
| 312 | if( P("popup")!=0 && cgi_csrf_safe(0) ){ |
| 313 | /* If this is a POST from the same origin with the popup=1 parameter, |
| 314 | ** then disable anti-robot defenses */ |
| 315 | isPopup = 1; |
| 316 | g.perm.Hyperlink = 1; |
| 317 | g.javascriptHyperlink = 0; |
| 318 | } |
| 319 | if( !isPopup ){ |
| 320 | style_header("Test Page Map"); |
| 321 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 322 | } |
| @@ -364,11 +364,11 @@ | |
| 364 | if( P("popup")!=0 && cgi_csrf_safe(0) ){ |
| 365 | /* If this is a POST from the same origin with the popup=1 parameter, |
| 366 | ** then disable anti-robot defenses */ |
| 367 | isPopup = 1; |
| 368 | g.perm.Hyperlink = 1; |
| 369 | g.javascriptHyperlink = 0; |
| 370 | } |
| 371 | if( !isPopup ){ |
| 372 | style_header("Timeline Examples"); |
| 373 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 374 | } |
| 375 |
| --- src/sitemap.c | |
| +++ src/sitemap.c | |
| @@ -74,11 +74,11 @@ | |
| 74 | if( P("popup")!=0 ){ |
| 75 | /* The "popup" query parameter |
| 76 | ** then disable anti-robot defenses */ |
| 77 | isPopup = 1; |
| 78 | g.perm.Hyperlink = 1; |
| 79 | g.jsHref = 0; |
| 80 | } |
| 81 | srchFlags = search_restrict(SRCH_ALL); |
| 82 | if( !isPopup ){ |
| 83 | style_header("Site Map"); |
| 84 | style_adunit_config(ADUNIT_RIGHT_OK); |
| @@ -312,11 +312,11 @@ | |
| 312 | if( P("popup")!=0 && cgi_csrf_safe(0) ){ |
| 313 | /* If this is a POST from the same origin with the popup=1 parameter, |
| 314 | ** then disable anti-robot defenses */ |
| 315 | isPopup = 1; |
| 316 | g.perm.Hyperlink = 1; |
| 317 | g.jsHref = 0; |
| 318 | } |
| 319 | if( !isPopup ){ |
| 320 | style_header("Test Page Map"); |
| 321 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 322 | } |
| @@ -364,11 +364,11 @@ | |
| 364 | if( P("popup")!=0 && cgi_csrf_safe(0) ){ |
| 365 | /* If this is a POST from the same origin with the popup=1 parameter, |
| 366 | ** then disable anti-robot defenses */ |
| 367 | isPopup = 1; |
| 368 | g.perm.Hyperlink = 1; |
| 369 | g.jsHref = 0; |
| 370 | } |
| 371 | if( !isPopup ){ |
| 372 | style_header("Timeline Examples"); |
| 373 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 374 | } |
| 375 |
+22
-22
| --- src/style.c | ||
| +++ src/style.c | ||
| @@ -106,35 +106,35 @@ | ||
| 106 | 106 | ** Generate and return a anchor tag like this: |
| 107 | 107 | ** |
| 108 | 108 | ** <a href="URL"> |
| 109 | 109 | ** or <a id="ID"> |
| 110 | 110 | ** |
| 111 | -** The form of the anchor tag is determined by the g.javascriptHyperlink | |
| 111 | +** The form of the anchor tag is determined by the g.jsHref | |
| 112 | 112 | ** and g.perm.Hyperlink variables. |
| 113 | 113 | ** |
| 114 | -** g.perm.Hyperlink g.javascriptHyperlink Returned anchor format | |
| 115 | -** ---------------- --------------------- ------------------------ | |
| 116 | -** 0 0 (empty string) | |
| 117 | -** 0 1 (empty string) | |
| 118 | -** 1 0 <a href="URL"> | |
| 119 | -** 1 1 <a data-href="URL"> | |
| 114 | +** g.perm.Hyperlink g.jsHref Returned anchor format | |
| 115 | +** ---------------- -------- ------------------------ | |
| 116 | +** 0 0 (empty string) | |
| 117 | +** 0 1 (empty string) | |
| 118 | +** 1 0 <a href="URL"> | |
| 119 | +** 1 1 <a data-href="URL"> | |
| 120 | 120 | ** |
| 121 | 121 | ** No anchor tag is generated if g.perm.Hyperlink is false. |
| 122 | -** The href="URL" form is used if g.javascriptHyperlink is false. | |
| 123 | -** If g.javascriptHyperlink is true then the data-href="URL" and | |
| 122 | +** The href="URL" form is used if g.jsHref is false. | |
| 123 | +** If g.jsHref is true then the data-href="URL" and | |
| 124 | 124 | ** href="/honeypot" is generated and javascript is added to the footer |
| 125 | 125 | ** to cause data-href values to be inserted into href |
| 126 | 126 | ** after the page has loaded. The use of the data-href="URL" form |
| 127 | 127 | ** instead of href="URL" is a defense against bots. |
| 128 | 128 | ** |
| 129 | 129 | ** If the user lacks the Hyperlink (h) property and the "auto-hyperlink" |
| 130 | 130 | ** setting is true, then g.perm.Hyperlink is changed from 0 to 1 and |
| 131 | -** g.javascriptHyperlink is set to 1 by login_check_credentials(). Thus | |
| 131 | +** g.jsHref is set to 1 by login_check_credentials(). Thus | |
| 132 | 132 | ** the g.perm.Hyperlink property will be true even if the user does not |
| 133 | 133 | ** have the "h" privilege if the "auto-hyperlink" setting is true. |
| 134 | 134 | ** |
| 135 | -** User has "h" auto-hyperlink g.perm.Hyperlink g.javascriptHyperlink | |
| 135 | +** User has "h" auto-hyperlink g.perm.Hyperlink g.jsHref | |
| 136 | 136 | ** ------------ -------------- ---------------- --------------------- |
| 137 | 137 | ** 0 0 0 0 |
| 138 | 138 | ** 1 0 1 0 |
| 139 | 139 | ** 0 1 1 1 |
| 140 | 140 | ** 1 1 1 0 |
| @@ -173,11 +173,11 @@ | ||
| 173 | 173 | va_list ap; |
| 174 | 174 | if( !g.perm.Hyperlink ) return fossil_strdup(""); |
| 175 | 175 | va_start(ap, zFormat); |
| 176 | 176 | zUrl = vmprintf(zFormat, ap); |
| 177 | 177 | va_end(ap); |
| 178 | - if( !g.javascriptHyperlink ){ | |
| 178 | + if( !g.jsHref ){ | |
| 179 | 179 | char *zHUrl; |
| 180 | 180 | if( zExtra ){ |
| 181 | 181 | zHUrl = mprintf("<a %s href=\"%h\">", zExtra, zUrl); |
| 182 | 182 | }else{ |
| 183 | 183 | zHUrl = mprintf("<a href=\"%h\">", zUrl); |
| @@ -198,11 +198,11 @@ | ||
| 198 | 198 | va_list ap; |
| 199 | 199 | if( !g.perm.Hyperlink ) return fossil_strdup(""); |
| 200 | 200 | va_start(ap, zFormat); |
| 201 | 201 | zUrl = vmprintf(zFormat, ap); |
| 202 | 202 | va_end(ap); |
| 203 | - if( !g.javascriptHyperlink ){ | |
| 203 | + if( !g.jsHref ){ | |
| 204 | 204 | char *zHUrl = mprintf("<a class=\"%s\" href=\"%h\">", zExtra, zUrl); |
| 205 | 205 | fossil_free(zUrl); |
| 206 | 206 | return zHUrl; |
| 207 | 207 | } |
| 208 | 208 | needHrefJs = 1; |
| @@ -214,11 +214,11 @@ | ||
| 214 | 214 | va_list ap; |
| 215 | 215 | if( !g.perm.Hyperlink ) return fossil_strdup(""); |
| 216 | 216 | va_start(ap, zFormat); |
| 217 | 217 | zUrl = vmprintf(zFormat, ap); |
| 218 | 218 | va_end(ap); |
| 219 | - if( !g.javascriptHyperlink ){ | |
| 219 | + if( !g.jsHref ){ | |
| 220 | 220 | char *zHUrl = mprintf("<a href=\"%h\">", zUrl); |
| 221 | 221 | fossil_free(zUrl); |
| 222 | 222 | return zHUrl; |
| 223 | 223 | } |
| 224 | 224 | needHrefJs = 1; |
| @@ -233,18 +233,18 @@ | ||
| 233 | 233 | ** As a defense against robots, the action=ARG might instead by data-action=ARG |
| 234 | 234 | ** and javascript (href.js) added to the page so that the data-action= is |
| 235 | 235 | ** changed into action= after the page loads. Whether or not this happens |
| 236 | 236 | ** depends on if the user has the "h" privilege and whether or not the |
| 237 | 237 | ** auto-hyperlink setting is on. These setings determine the values of |
| 238 | -** variables g.perm.Hyperlink and g.javascriptHyperlink. | |
| 238 | +** variables g.perm.Hyperlink and g.jsHref. | |
| 239 | 239 | ** |
| 240 | -** User has "h" auto-hyperlink g.perm.Hyperlink g.javascriptHyperlink | |
| 241 | -** ------------ -------------- ---------------- --------------------- | |
| 242 | -** 1: 0 0 0 0 | |
| 243 | -** 2: 1 0 1 0 | |
| 244 | -** 3: 0 1 1 1 | |
| 245 | -** 4: 1 1 1 0 | |
| 240 | +** User has "h" auto-hyperlink g.perm.Hyperlink g.jsHref | |
| 241 | +** ------------ -------------- ---------------- -------- | |
| 242 | +** 1: 0 0 0 0 | |
| 243 | +** 2: 1 0 1 0 | |
| 244 | +** 3: 0 1 1 1 | |
| 245 | +** 4: 1 1 1 0 | |
| 246 | 246 | ** |
| 247 | 247 | ** The data-action=ARG form is used for cases 1 and 3. In case 1, the href.js |
| 248 | 248 | ** javascript is omitted and so the form is effectively disabled. |
| 249 | 249 | */ |
| 250 | 250 | void form_begin(const char *zOtherArgs, const char *zAction, ...){ |
| @@ -1388,11 +1388,11 @@ | ||
| 1388 | 1388 | @ g.zTop = %h(g.zTop)<br /> |
| 1389 | 1389 | @ g.zPath = %h(g.zPath)<br /> |
| 1390 | 1390 | @ g.userUid = %d(g.userUid)<br /> |
| 1391 | 1391 | @ g.zLogin = %h(g.zLogin)<br /> |
| 1392 | 1392 | @ g.isHuman = %d(g.isHuman)<br /> |
| 1393 | - @ g.javascriptHyperlink = %d(g.javascriptHyperlink)<br /> | |
| 1393 | + @ g.jsHref = %d(g.jsHref)<br /> | |
| 1394 | 1394 | if( g.nRequest ){ |
| 1395 | 1395 | @ g.nRequest = %d(g.nRequest)<br /> |
| 1396 | 1396 | } |
| 1397 | 1397 | if( g.nPendingRequest>1 ){ |
| 1398 | 1398 | @ g.nPendingRequest = %d(g.nPendingRequest)<br /> |
| 1399 | 1399 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -106,35 +106,35 @@ | |
| 106 | ** Generate and return a anchor tag like this: |
| 107 | ** |
| 108 | ** <a href="URL"> |
| 109 | ** or <a id="ID"> |
| 110 | ** |
| 111 | ** The form of the anchor tag is determined by the g.javascriptHyperlink |
| 112 | ** and g.perm.Hyperlink variables. |
| 113 | ** |
| 114 | ** g.perm.Hyperlink g.javascriptHyperlink Returned anchor format |
| 115 | ** ---------------- --------------------- ------------------------ |
| 116 | ** 0 0 (empty string) |
| 117 | ** 0 1 (empty string) |
| 118 | ** 1 0 <a href="URL"> |
| 119 | ** 1 1 <a data-href="URL"> |
| 120 | ** |
| 121 | ** No anchor tag is generated if g.perm.Hyperlink is false. |
| 122 | ** The href="URL" form is used if g.javascriptHyperlink is false. |
| 123 | ** If g.javascriptHyperlink is true then the data-href="URL" and |
| 124 | ** href="/honeypot" is generated and javascript is added to the footer |
| 125 | ** to cause data-href values to be inserted into href |
| 126 | ** after the page has loaded. The use of the data-href="URL" form |
| 127 | ** instead of href="URL" is a defense against bots. |
| 128 | ** |
| 129 | ** If the user lacks the Hyperlink (h) property and the "auto-hyperlink" |
| 130 | ** setting is true, then g.perm.Hyperlink is changed from 0 to 1 and |
| 131 | ** g.javascriptHyperlink is set to 1 by login_check_credentials(). Thus |
| 132 | ** the g.perm.Hyperlink property will be true even if the user does not |
| 133 | ** have the "h" privilege if the "auto-hyperlink" setting is true. |
| 134 | ** |
| 135 | ** User has "h" auto-hyperlink g.perm.Hyperlink g.javascriptHyperlink |
| 136 | ** ------------ -------------- ---------------- --------------------- |
| 137 | ** 0 0 0 0 |
| 138 | ** 1 0 1 0 |
| 139 | ** 0 1 1 1 |
| 140 | ** 1 1 1 0 |
| @@ -173,11 +173,11 @@ | |
| 173 | va_list ap; |
| 174 | if( !g.perm.Hyperlink ) return fossil_strdup(""); |
| 175 | va_start(ap, zFormat); |
| 176 | zUrl = vmprintf(zFormat, ap); |
| 177 | va_end(ap); |
| 178 | if( !g.javascriptHyperlink ){ |
| 179 | char *zHUrl; |
| 180 | if( zExtra ){ |
| 181 | zHUrl = mprintf("<a %s href=\"%h\">", zExtra, zUrl); |
| 182 | }else{ |
| 183 | zHUrl = mprintf("<a href=\"%h\">", zUrl); |
| @@ -198,11 +198,11 @@ | |
| 198 | va_list ap; |
| 199 | if( !g.perm.Hyperlink ) return fossil_strdup(""); |
| 200 | va_start(ap, zFormat); |
| 201 | zUrl = vmprintf(zFormat, ap); |
| 202 | va_end(ap); |
| 203 | if( !g.javascriptHyperlink ){ |
| 204 | char *zHUrl = mprintf("<a class=\"%s\" href=\"%h\">", zExtra, zUrl); |
| 205 | fossil_free(zUrl); |
| 206 | return zHUrl; |
| 207 | } |
| 208 | needHrefJs = 1; |
| @@ -214,11 +214,11 @@ | |
| 214 | va_list ap; |
| 215 | if( !g.perm.Hyperlink ) return fossil_strdup(""); |
| 216 | va_start(ap, zFormat); |
| 217 | zUrl = vmprintf(zFormat, ap); |
| 218 | va_end(ap); |
| 219 | if( !g.javascriptHyperlink ){ |
| 220 | char *zHUrl = mprintf("<a href=\"%h\">", zUrl); |
| 221 | fossil_free(zUrl); |
| 222 | return zHUrl; |
| 223 | } |
| 224 | needHrefJs = 1; |
| @@ -233,18 +233,18 @@ | |
| 233 | ** As a defense against robots, the action=ARG might instead by data-action=ARG |
| 234 | ** and javascript (href.js) added to the page so that the data-action= is |
| 235 | ** changed into action= after the page loads. Whether or not this happens |
| 236 | ** depends on if the user has the "h" privilege and whether or not the |
| 237 | ** auto-hyperlink setting is on. These setings determine the values of |
| 238 | ** variables g.perm.Hyperlink and g.javascriptHyperlink. |
| 239 | ** |
| 240 | ** User has "h" auto-hyperlink g.perm.Hyperlink g.javascriptHyperlink |
| 241 | ** ------------ -------------- ---------------- --------------------- |
| 242 | ** 1: 0 0 0 0 |
| 243 | ** 2: 1 0 1 0 |
| 244 | ** 3: 0 1 1 1 |
| 245 | ** 4: 1 1 1 0 |
| 246 | ** |
| 247 | ** The data-action=ARG form is used for cases 1 and 3. In case 1, the href.js |
| 248 | ** javascript is omitted and so the form is effectively disabled. |
| 249 | */ |
| 250 | void form_begin(const char *zOtherArgs, const char *zAction, ...){ |
| @@ -1388,11 +1388,11 @@ | |
| 1388 | @ g.zTop = %h(g.zTop)<br /> |
| 1389 | @ g.zPath = %h(g.zPath)<br /> |
| 1390 | @ g.userUid = %d(g.userUid)<br /> |
| 1391 | @ g.zLogin = %h(g.zLogin)<br /> |
| 1392 | @ g.isHuman = %d(g.isHuman)<br /> |
| 1393 | @ g.javascriptHyperlink = %d(g.javascriptHyperlink)<br /> |
| 1394 | if( g.nRequest ){ |
| 1395 | @ g.nRequest = %d(g.nRequest)<br /> |
| 1396 | } |
| 1397 | if( g.nPendingRequest>1 ){ |
| 1398 | @ g.nPendingRequest = %d(g.nPendingRequest)<br /> |
| 1399 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -106,35 +106,35 @@ | |
| 106 | ** Generate and return a anchor tag like this: |
| 107 | ** |
| 108 | ** <a href="URL"> |
| 109 | ** or <a id="ID"> |
| 110 | ** |
| 111 | ** The form of the anchor tag is determined by the g.jsHref |
| 112 | ** and g.perm.Hyperlink variables. |
| 113 | ** |
| 114 | ** g.perm.Hyperlink g.jsHref Returned anchor format |
| 115 | ** ---------------- -------- ------------------------ |
| 116 | ** 0 0 (empty string) |
| 117 | ** 0 1 (empty string) |
| 118 | ** 1 0 <a href="URL"> |
| 119 | ** 1 1 <a data-href="URL"> |
| 120 | ** |
| 121 | ** No anchor tag is generated if g.perm.Hyperlink is false. |
| 122 | ** The href="URL" form is used if g.jsHref is false. |
| 123 | ** If g.jsHref is true then the data-href="URL" and |
| 124 | ** href="/honeypot" is generated and javascript is added to the footer |
| 125 | ** to cause data-href values to be inserted into href |
| 126 | ** after the page has loaded. The use of the data-href="URL" form |
| 127 | ** instead of href="URL" is a defense against bots. |
| 128 | ** |
| 129 | ** If the user lacks the Hyperlink (h) property and the "auto-hyperlink" |
| 130 | ** setting is true, then g.perm.Hyperlink is changed from 0 to 1 and |
| 131 | ** g.jsHref is set to 1 by login_check_credentials(). Thus |
| 132 | ** the g.perm.Hyperlink property will be true even if the user does not |
| 133 | ** have the "h" privilege if the "auto-hyperlink" setting is true. |
| 134 | ** |
| 135 | ** User has "h" auto-hyperlink g.perm.Hyperlink g.jsHref |
| 136 | ** ------------ -------------- ---------------- --------------------- |
| 137 | ** 0 0 0 0 |
| 138 | ** 1 0 1 0 |
| 139 | ** 0 1 1 1 |
| 140 | ** 1 1 1 0 |
| @@ -173,11 +173,11 @@ | |
| 173 | va_list ap; |
| 174 | if( !g.perm.Hyperlink ) return fossil_strdup(""); |
| 175 | va_start(ap, zFormat); |
| 176 | zUrl = vmprintf(zFormat, ap); |
| 177 | va_end(ap); |
| 178 | if( !g.jsHref ){ |
| 179 | char *zHUrl; |
| 180 | if( zExtra ){ |
| 181 | zHUrl = mprintf("<a %s href=\"%h\">", zExtra, zUrl); |
| 182 | }else{ |
| 183 | zHUrl = mprintf("<a href=\"%h\">", zUrl); |
| @@ -198,11 +198,11 @@ | |
| 198 | va_list ap; |
| 199 | if( !g.perm.Hyperlink ) return fossil_strdup(""); |
| 200 | va_start(ap, zFormat); |
| 201 | zUrl = vmprintf(zFormat, ap); |
| 202 | va_end(ap); |
| 203 | if( !g.jsHref ){ |
| 204 | char *zHUrl = mprintf("<a class=\"%s\" href=\"%h\">", zExtra, zUrl); |
| 205 | fossil_free(zUrl); |
| 206 | return zHUrl; |
| 207 | } |
| 208 | needHrefJs = 1; |
| @@ -214,11 +214,11 @@ | |
| 214 | va_list ap; |
| 215 | if( !g.perm.Hyperlink ) return fossil_strdup(""); |
| 216 | va_start(ap, zFormat); |
| 217 | zUrl = vmprintf(zFormat, ap); |
| 218 | va_end(ap); |
| 219 | if( !g.jsHref ){ |
| 220 | char *zHUrl = mprintf("<a href=\"%h\">", zUrl); |
| 221 | fossil_free(zUrl); |
| 222 | return zHUrl; |
| 223 | } |
| 224 | needHrefJs = 1; |
| @@ -233,18 +233,18 @@ | |
| 233 | ** As a defense against robots, the action=ARG might instead by data-action=ARG |
| 234 | ** and javascript (href.js) added to the page so that the data-action= is |
| 235 | ** changed into action= after the page loads. Whether or not this happens |
| 236 | ** depends on if the user has the "h" privilege and whether or not the |
| 237 | ** auto-hyperlink setting is on. These setings determine the values of |
| 238 | ** variables g.perm.Hyperlink and g.jsHref. |
| 239 | ** |
| 240 | ** User has "h" auto-hyperlink g.perm.Hyperlink g.jsHref |
| 241 | ** ------------ -------------- ---------------- -------- |
| 242 | ** 1: 0 0 0 0 |
| 243 | ** 2: 1 0 1 0 |
| 244 | ** 3: 0 1 1 1 |
| 245 | ** 4: 1 1 1 0 |
| 246 | ** |
| 247 | ** The data-action=ARG form is used for cases 1 and 3. In case 1, the href.js |
| 248 | ** javascript is omitted and so the form is effectively disabled. |
| 249 | */ |
| 250 | void form_begin(const char *zOtherArgs, const char *zAction, ...){ |
| @@ -1388,11 +1388,11 @@ | |
| 1388 | @ g.zTop = %h(g.zTop)<br /> |
| 1389 | @ g.zPath = %h(g.zPath)<br /> |
| 1390 | @ g.userUid = %d(g.userUid)<br /> |
| 1391 | @ g.zLogin = %h(g.zLogin)<br /> |
| 1392 | @ g.isHuman = %d(g.isHuman)<br /> |
| 1393 | @ g.jsHref = %d(g.jsHref)<br /> |
| 1394 | if( g.nRequest ){ |
| 1395 | @ g.nRequest = %d(g.nRequest)<br /> |
| 1396 | } |
| 1397 | if( g.nPendingRequest>1 ){ |
| 1398 | @ g.nPendingRequest = %d(g.nPendingRequest)<br /> |
| 1399 |