Fossil SCM

More information on Setup and in Security-Audit to help admins configure Public Pages with the correct capabilities.

drh 2020-02-27 19:16 trunk
Commit 0c374456b3f8be0070a2521b8aa73a220bcb60d465403fefb38e250c131cb7a0
--- src/capabilities.c
+++ src/capabilities.c
@@ -359,26 +359,38 @@
359359
** Generate a "capability summary table" that shows the major capabilities
360360
** against the various user categories.
361361
*/
362362
void capability_summary(void){
363363
Stmt q;
364
+ CapabilityString *pCap;
365
+ char *zSelfCap;
366
+ char *zPubPages = db_get("public-pages",0);
367
+ int hasPubPages = zPubPages && zPubPages[0];
368
+
369
+ pCap = capability_add(0, db_get("default-perms",0));
370
+ capability_expand(pCap);
371
+ zSelfCap = capability_string(pCap);
372
+ capability_free(pCap);
373
+
364374
db_prepare(&q,
365375
"WITH t(id,seq) AS (VALUES('nobody',1),('anonymous',2),('reader',3),"
366376
"('developer',4))"
367377
" SELECT id, CASE WHEN user.login='nobody' THEN user.cap"
368378
" ELSE fullcap(user.cap) END,seq,1"
369379
" FROM t LEFT JOIN user ON t.id=user.login"
370380
" UNION ALL"
371
- " SELECT 'New User Default', fullcap(%Q), 10, 1"
381
+ " SELECT 'Public Pages', %Q, 100, %d"
382
+ " UNION ALL"
383
+ " SELECT 'New User Default', %Q, 110, 1"
372384
" UNION ALL"
373
- " SELECT 'Regular User', fullcap(capunion(cap)), 20, count(*) FROM user"
385
+ " SELECT 'Regular User', fullcap(capunion(cap)), 200, count(*) FROM user"
374386
" WHERE cap NOT GLOB '*[as]*' AND login NOT IN (SELECT id FROM t)"
375387
" UNION ALL"
376
- " SELECT 'Adminstrator', fullcap(capunion(cap)), 30, count(*) FROM user"
388
+ " SELECT 'Adminstrator', fullcap(capunion(cap)), 300, count(*) FROM user"
377389
" WHERE cap GLOB '*[as]*'"
378390
" ORDER BY 3 ASC",
379
- db_get("default-perms","")
391
+ zSelfCap, hasPubPages, zSelfCap
380392
);
381393
@ <table id='capabilitySummary' cellpadding="0" cellspacing="0" border="1">
382394
@ <tr><th>&nbsp;<th>Code<th>Forum<th>Tickets<th>Wiki\
383395
@ <th>Unversioned Content</th></tr>
384396
while( db_step(&q)==SQLITE_ROW ){
@@ -385,11 +397,12 @@
385397
const char *zId = db_column_text(&q, 0);
386398
const char *zCap = db_column_text(&q, 1);
387399
int n = db_column_int(&q, 3);
388400
int eType;
389401
static const char *const azType[] = { "off", "read", "write" };
390
- static const char *const azClass[] = { "capsumOff", "capsumRead", "capsumWrite" };
402
+ static const char *const azClass[] =
403
+ { "capsumOff", "capsumRead", "capsumWrite" };
391404
392405
if( n==0 ) continue;
393406
394407
/* Code */
395408
if( db_column_int(&q,2)<10 ){
396409
--- src/capabilities.c
+++ src/capabilities.c
@@ -359,26 +359,38 @@
359 ** Generate a "capability summary table" that shows the major capabilities
360 ** against the various user categories.
361 */
362 void capability_summary(void){
363 Stmt q;
 
 
 
 
 
 
 
 
 
 
364 db_prepare(&q,
365 "WITH t(id,seq) AS (VALUES('nobody',1),('anonymous',2),('reader',3),"
366 "('developer',4))"
367 " SELECT id, CASE WHEN user.login='nobody' THEN user.cap"
368 " ELSE fullcap(user.cap) END,seq,1"
369 " FROM t LEFT JOIN user ON t.id=user.login"
370 " UNION ALL"
371 " SELECT 'New User Default', fullcap(%Q), 10, 1"
 
 
372 " UNION ALL"
373 " SELECT 'Regular User', fullcap(capunion(cap)), 20, count(*) FROM user"
374 " WHERE cap NOT GLOB '*[as]*' AND login NOT IN (SELECT id FROM t)"
375 " UNION ALL"
376 " SELECT 'Adminstrator', fullcap(capunion(cap)), 30, count(*) FROM user"
377 " WHERE cap GLOB '*[as]*'"
378 " ORDER BY 3 ASC",
379 db_get("default-perms","")
380 );
381 @ <table id='capabilitySummary' cellpadding="0" cellspacing="0" border="1">
382 @ <tr><th>&nbsp;<th>Code<th>Forum<th>Tickets<th>Wiki\
383 @ <th>Unversioned Content</th></tr>
384 while( db_step(&q)==SQLITE_ROW ){
@@ -385,11 +397,12 @@
385 const char *zId = db_column_text(&q, 0);
386 const char *zCap = db_column_text(&q, 1);
387 int n = db_column_int(&q, 3);
388 int eType;
389 static const char *const azType[] = { "off", "read", "write" };
390 static const char *const azClass[] = { "capsumOff", "capsumRead", "capsumWrite" };
 
391
392 if( n==0 ) continue;
393
394 /* Code */
395 if( db_column_int(&q,2)<10 ){
396
--- src/capabilities.c
+++ src/capabilities.c
@@ -359,26 +359,38 @@
359 ** Generate a "capability summary table" that shows the major capabilities
360 ** against the various user categories.
361 */
362 void capability_summary(void){
363 Stmt q;
364 CapabilityString *pCap;
365 char *zSelfCap;
366 char *zPubPages = db_get("public-pages",0);
367 int hasPubPages = zPubPages && zPubPages[0];
368
369 pCap = capability_add(0, db_get("default-perms",0));
370 capability_expand(pCap);
371 zSelfCap = capability_string(pCap);
372 capability_free(pCap);
373
374 db_prepare(&q,
375 "WITH t(id,seq) AS (VALUES('nobody',1),('anonymous',2),('reader',3),"
376 "('developer',4))"
377 " SELECT id, CASE WHEN user.login='nobody' THEN user.cap"
378 " ELSE fullcap(user.cap) END,seq,1"
379 " FROM t LEFT JOIN user ON t.id=user.login"
380 " UNION ALL"
381 " SELECT 'Public Pages', %Q, 100, %d"
382 " UNION ALL"
383 " SELECT 'New User Default', %Q, 110, 1"
384 " UNION ALL"
385 " SELECT 'Regular User', fullcap(capunion(cap)), 200, count(*) FROM user"
386 " WHERE cap NOT GLOB '*[as]*' AND login NOT IN (SELECT id FROM t)"
387 " UNION ALL"
388 " SELECT 'Adminstrator', fullcap(capunion(cap)), 300, count(*) FROM user"
389 " WHERE cap GLOB '*[as]*'"
390 " ORDER BY 3 ASC",
391 zSelfCap, hasPubPages, zSelfCap
392 );
393 @ <table id='capabilitySummary' cellpadding="0" cellspacing="0" border="1">
394 @ <tr><th>&nbsp;<th>Code<th>Forum<th>Tickets<th>Wiki\
395 @ <th>Unversioned Content</th></tr>
396 while( db_step(&q)==SQLITE_ROW ){
@@ -385,11 +397,12 @@
397 const char *zId = db_column_text(&q, 0);
398 const char *zCap = db_column_text(&q, 1);
399 int n = db_column_int(&q, 3);
400 int eType;
401 static const char *const azType[] = { "off", "read", "write" };
402 static const char *const azClass[] =
403 { "capsumOff", "capsumRead", "capsumWrite" };
404
405 if( n==0 ) continue;
406
407 /* Code */
408 if( db_column_int(&q,2)<10 ){
409
--- src/security_audit.c
+++ src/security_audit.c
@@ -96,12 +96,14 @@
9696
*/
9797
void secaudit0_page(void){
9898
const char *zAnonCap; /* Capabilities of user "anonymous" and "nobody" */
9999
const char *zPubPages; /* GLOB pattern for public pages */
100100
const char *zSelfCap; /* Capabilities of self-registered users */
101
+ int hasSelfReg = 0; /* True if able to self-register */
101102
char *z;
102103
int n;
104
+ CapabilityString *pCap;
103105
char **azCSP; /* Parsed content security policy */
104106
105107
login_check_credentials();
106108
if( !g.perm.Admin ){
107109
login_needed(0);
@@ -115,27 +117,23 @@
115117
** "Private" repos require (non-anonymous) login to access all content,
116118
** though some content may be accessible anonymously.
117119
*/
118120
zAnonCap = db_text("", "SELECT fullcap(NULL)");
119121
zPubPages = db_get("public-pages",0);
120
- if( db_get_boolean("self-register",0) ){
121
- CapabilityString *pCap;
122
- pCap = capability_add(0, db_get("default-perms",0));
123
- capability_expand(pCap);
124
- zSelfCap = capability_string(pCap);
125
- capability_free(pCap);
126
- }else{
127
- zSelfCap = fossil_strdup("");
128
- }
122
+ hasSelfReg = db_get_boolean("self-register",0);
123
+ pCap = capability_add(0, db_get("default-perms",0));
124
+ capability_expand(pCap);
125
+ zSelfCap = capability_string(pCap);
126
+ capability_free(pCap);
129127
if( hasAnyCap(zAnonCap,"as") ){
130128
@ <li><p>This repository is <big><b>Wildly INSECURE</b></big> because
131129
@ it grants administrator privileges to anonymous users. You
132130
@ should <a href="takeitprivate">take this repository private</a>
133131
@ immediately! Or, at least remove the Setup and Admin privileges
134132
@ for users "anonymous" and "login" on the
135133
@ <a href="setup_ulist">User Configuration</a> page.
136
- }else if( hasAnyCap(zSelfCap,"as") ){
134
+ }else if( hasAnyCap(zSelfCap,"as") && hasSelfReg ){
137135
@ <li><p>This repository is <big><b>Wildly INSECURE</b></big> because
138136
@ it grants administrator privileges to self-registered users. You
139137
@ should <a href="takeitprivate">take this repository private</a>
140138
@ and/or disable self-registration
141139
@ immediately! Or, at least remove the Setup and Admin privileges
@@ -154,43 +152,48 @@
154152
@ by disabling self-registration.
155153
}else if( hasAnyCap(zAnonCap,"goz") ){
156154
@ <li><p>This repository is <big><b>PUBLIC</b></big>. All
157155
@ checked-in content can be accessed by anonymous users.
158156
@ <a href="takeitprivate">Take it private</a>.<p>
159
- }else if( hasAnyCap(zSelfCap,"goz") ){
157
+ }else if( hasAnyCap(zSelfCap,"goz") && hasSelfReg ){
160158
@ <li><p>This repository is <big><b>PUBLIC</b></big> because all
161159
@ checked-in content can be accessed by self-registered users.
162160
@ This repostory would be private if you disabled self-registration.</p>
163161
}else if( !hasAnyCap(zAnonCap, "jrwy234567")
164
- && !hasAnyCap(zSelfCap, "jrwy234567")
162
+ && (!hasSelfReg || !hasAnyCap(zSelfCap, "jrwy234567"))
165163
&& (zPubPages==0 || zPubPages[0]==0) ){
166164
@ <li><p>This repository is <big><b>Completely PRIVATE</b></big>.
167165
@ A valid login and password is required to access any content.
168166
}else{
169167
@ <li><p>This repository is <big><b>Mostly PRIVATE</b></big>.
170168
@ A valid login and password is usually required, however some
171169
@ content can be accessed either anonymously or by self-registered
172170
@ users:
173171
@ <ul>
174
- if( hasAnyCap(zAnonCap,"j") || hasAnyCap(zSelfCap,"j") ){
175
- @ <li> Wiki pages
176
- }
177
- if( hasAnyCap(zAnonCap,"r") || hasAnyCap(zSelfCap,"r") ){
178
- @ <li> Tickets
179
- }
180
- if( hasAnyCap(zAnonCap,"234567") || hasAnyCap(zSelfCap,"234567") ){
181
- @ <li> Forum posts
172
+ if( hasSelfReg ){
173
+ if( hasAnyCap(zAnonCap,"j") || hasAnyCap(zSelfCap,"j") ){
174
+ @ <li> Wiki pages
175
+ }
176
+ if( hasAnyCap(zAnonCap,"r") || hasAnyCap(zSelfCap,"r") ){
177
+ @ <li> Tickets
178
+ }
179
+ if( hasAnyCap(zAnonCap,"234567") || hasAnyCap(zSelfCap,"234567") ){
180
+ @ <li> Forum posts
181
+ }
182182
}
183183
if( zPubPages && zPubPages[0] ){
184184
Glob *pGlob = glob_create(zPubPages);
185185
int i;
186
- @ <li> URLs that match any of these GLOB patterns:
187
- @ <ul>
186
+ @ <li> "Public Pages" are URLs that match any of these GLOB patterns:
187
+ @ <p><ul>
188188
for(i=0; i<pGlob->nPattern; i++){
189189
@ <li> %h(pGlob->azPattern[i])
190190
}
191191
@ </ul>
192
+ @ <p>Anoymous users are vested with capabilities "%h(zSelfCap)" on
193
+ @ public pages. See the "Public Pages" entry in the
194
+ @ "User capability summary" below.
192195
}
193196
@ </ul>
194197
if( zPubPages && zPubPages[0] ){
195198
@ <p>Change GLOB patterns exceptions using the "Public pages" setting
196199
@ on the <a href="setup_access">Access Settings</a> page.</p>
197200
--- src/security_audit.c
+++ src/security_audit.c
@@ -96,12 +96,14 @@
96 */
97 void secaudit0_page(void){
98 const char *zAnonCap; /* Capabilities of user "anonymous" and "nobody" */
99 const char *zPubPages; /* GLOB pattern for public pages */
100 const char *zSelfCap; /* Capabilities of self-registered users */
 
101 char *z;
102 int n;
 
103 char **azCSP; /* Parsed content security policy */
104
105 login_check_credentials();
106 if( !g.perm.Admin ){
107 login_needed(0);
@@ -115,27 +117,23 @@
115 ** "Private" repos require (non-anonymous) login to access all content,
116 ** though some content may be accessible anonymously.
117 */
118 zAnonCap = db_text("", "SELECT fullcap(NULL)");
119 zPubPages = db_get("public-pages",0);
120 if( db_get_boolean("self-register",0) ){
121 CapabilityString *pCap;
122 pCap = capability_add(0, db_get("default-perms",0));
123 capability_expand(pCap);
124 zSelfCap = capability_string(pCap);
125 capability_free(pCap);
126 }else{
127 zSelfCap = fossil_strdup("");
128 }
129 if( hasAnyCap(zAnonCap,"as") ){
130 @ <li><p>This repository is <big><b>Wildly INSECURE</b></big> because
131 @ it grants administrator privileges to anonymous users. You
132 @ should <a href="takeitprivate">take this repository private</a>
133 @ immediately! Or, at least remove the Setup and Admin privileges
134 @ for users "anonymous" and "login" on the
135 @ <a href="setup_ulist">User Configuration</a> page.
136 }else if( hasAnyCap(zSelfCap,"as") ){
137 @ <li><p>This repository is <big><b>Wildly INSECURE</b></big> because
138 @ it grants administrator privileges to self-registered users. You
139 @ should <a href="takeitprivate">take this repository private</a>
140 @ and/or disable self-registration
141 @ immediately! Or, at least remove the Setup and Admin privileges
@@ -154,43 +152,48 @@
154 @ by disabling self-registration.
155 }else if( hasAnyCap(zAnonCap,"goz") ){
156 @ <li><p>This repository is <big><b>PUBLIC</b></big>. All
157 @ checked-in content can be accessed by anonymous users.
158 @ <a href="takeitprivate">Take it private</a>.<p>
159 }else if( hasAnyCap(zSelfCap,"goz") ){
160 @ <li><p>This repository is <big><b>PUBLIC</b></big> because all
161 @ checked-in content can be accessed by self-registered users.
162 @ This repostory would be private if you disabled self-registration.</p>
163 }else if( !hasAnyCap(zAnonCap, "jrwy234567")
164 && !hasAnyCap(zSelfCap, "jrwy234567")
165 && (zPubPages==0 || zPubPages[0]==0) ){
166 @ <li><p>This repository is <big><b>Completely PRIVATE</b></big>.
167 @ A valid login and password is required to access any content.
168 }else{
169 @ <li><p>This repository is <big><b>Mostly PRIVATE</b></big>.
170 @ A valid login and password is usually required, however some
171 @ content can be accessed either anonymously or by self-registered
172 @ users:
173 @ <ul>
174 if( hasAnyCap(zAnonCap,"j") || hasAnyCap(zSelfCap,"j") ){
175 @ <li> Wiki pages
176 }
177 if( hasAnyCap(zAnonCap,"r") || hasAnyCap(zSelfCap,"r") ){
178 @ <li> Tickets
179 }
180 if( hasAnyCap(zAnonCap,"234567") || hasAnyCap(zSelfCap,"234567") ){
181 @ <li> Forum posts
 
 
182 }
183 if( zPubPages && zPubPages[0] ){
184 Glob *pGlob = glob_create(zPubPages);
185 int i;
186 @ <li> URLs that match any of these GLOB patterns:
187 @ <ul>
188 for(i=0; i<pGlob->nPattern; i++){
189 @ <li> %h(pGlob->azPattern[i])
190 }
191 @ </ul>
 
 
 
192 }
193 @ </ul>
194 if( zPubPages && zPubPages[0] ){
195 @ <p>Change GLOB patterns exceptions using the "Public pages" setting
196 @ on the <a href="setup_access">Access Settings</a> page.</p>
197
--- src/security_audit.c
+++ src/security_audit.c
@@ -96,12 +96,14 @@
96 */
97 void secaudit0_page(void){
98 const char *zAnonCap; /* Capabilities of user "anonymous" and "nobody" */
99 const char *zPubPages; /* GLOB pattern for public pages */
100 const char *zSelfCap; /* Capabilities of self-registered users */
101 int hasSelfReg = 0; /* True if able to self-register */
102 char *z;
103 int n;
104 CapabilityString *pCap;
105 char **azCSP; /* Parsed content security policy */
106
107 login_check_credentials();
108 if( !g.perm.Admin ){
109 login_needed(0);
@@ -115,27 +117,23 @@
117 ** "Private" repos require (non-anonymous) login to access all content,
118 ** though some content may be accessible anonymously.
119 */
120 zAnonCap = db_text("", "SELECT fullcap(NULL)");
121 zPubPages = db_get("public-pages",0);
122 hasSelfReg = db_get_boolean("self-register",0);
123 pCap = capability_add(0, db_get("default-perms",0));
124 capability_expand(pCap);
125 zSelfCap = capability_string(pCap);
126 capability_free(pCap);
 
 
 
 
127 if( hasAnyCap(zAnonCap,"as") ){
128 @ <li><p>This repository is <big><b>Wildly INSECURE</b></big> because
129 @ it grants administrator privileges to anonymous users. You
130 @ should <a href="takeitprivate">take this repository private</a>
131 @ immediately! Or, at least remove the Setup and Admin privileges
132 @ for users "anonymous" and "login" on the
133 @ <a href="setup_ulist">User Configuration</a> page.
134 }else if( hasAnyCap(zSelfCap,"as") && hasSelfReg ){
135 @ <li><p>This repository is <big><b>Wildly INSECURE</b></big> because
136 @ it grants administrator privileges to self-registered users. You
137 @ should <a href="takeitprivate">take this repository private</a>
138 @ and/or disable self-registration
139 @ immediately! Or, at least remove the Setup and Admin privileges
@@ -154,43 +152,48 @@
152 @ by disabling self-registration.
153 }else if( hasAnyCap(zAnonCap,"goz") ){
154 @ <li><p>This repository is <big><b>PUBLIC</b></big>. All
155 @ checked-in content can be accessed by anonymous users.
156 @ <a href="takeitprivate">Take it private</a>.<p>
157 }else if( hasAnyCap(zSelfCap,"goz") && hasSelfReg ){
158 @ <li><p>This repository is <big><b>PUBLIC</b></big> because all
159 @ checked-in content can be accessed by self-registered users.
160 @ This repostory would be private if you disabled self-registration.</p>
161 }else if( !hasAnyCap(zAnonCap, "jrwy234567")
162 && (!hasSelfReg || !hasAnyCap(zSelfCap, "jrwy234567"))
163 && (zPubPages==0 || zPubPages[0]==0) ){
164 @ <li><p>This repository is <big><b>Completely PRIVATE</b></big>.
165 @ A valid login and password is required to access any content.
166 }else{
167 @ <li><p>This repository is <big><b>Mostly PRIVATE</b></big>.
168 @ A valid login and password is usually required, however some
169 @ content can be accessed either anonymously or by self-registered
170 @ users:
171 @ <ul>
172 if( hasSelfReg ){
173 if( hasAnyCap(zAnonCap,"j") || hasAnyCap(zSelfCap,"j") ){
174 @ <li> Wiki pages
175 }
176 if( hasAnyCap(zAnonCap,"r") || hasAnyCap(zSelfCap,"r") ){
177 @ <li> Tickets
178 }
179 if( hasAnyCap(zAnonCap,"234567") || hasAnyCap(zSelfCap,"234567") ){
180 @ <li> Forum posts
181 }
182 }
183 if( zPubPages && zPubPages[0] ){
184 Glob *pGlob = glob_create(zPubPages);
185 int i;
186 @ <li> "Public Pages" are URLs that match any of these GLOB patterns:
187 @ <p><ul>
188 for(i=0; i<pGlob->nPattern; i++){
189 @ <li> %h(pGlob->azPattern[i])
190 }
191 @ </ul>
192 @ <p>Anoymous users are vested with capabilities "%h(zSelfCap)" on
193 @ public pages. See the "Public Pages" entry in the
194 @ "User capability summary" below.
195 }
196 @ </ul>
197 if( zPubPages && zPubPages[0] ){
198 @ <p>Change GLOB patterns exceptions using the "Public pages" setting
199 @ on the <a href="setup_access">Access Settings</a> page.</p>
200
+5 -2
--- src/setup.c
+++ src/setup.c
@@ -497,12 +497,15 @@
497497
@ <hr />
498498
entry_attribute("Public pages", 30, "public-pages",
499499
"pubpage", "", 0);
500500
@ <p>A comma-separated list of glob patterns for pages that are accessible
501501
@ without needing a login and using the privileges given by the
502
- @ "Default privileges" setting below. Example use case: Set this field
503
- @ to "/doc/trunk/www/*" to give anonymous users read-only permission to the
502
+ @ "Default privileges" setting below.
503
+ @
504
+ @ <p>Example use case: Set this field to "/doc/trunk/www/*" and set
505
+ @ the "Default privileges" to include the "o" privilege
506
+ @ to give anonymous users read-only permission to the
504507
@ latest version of the embedded documentation in the www/ folder without
505508
@ allowing them to see the rest of the source code.
506509
@ (Property: "public-pages")
507510
@ </p>
508511
509512
--- src/setup.c
+++ src/setup.c
@@ -497,12 +497,15 @@
497 @ <hr />
498 entry_attribute("Public pages", 30, "public-pages",
499 "pubpage", "", 0);
500 @ <p>A comma-separated list of glob patterns for pages that are accessible
501 @ without needing a login and using the privileges given by the
502 @ "Default privileges" setting below. Example use case: Set this field
503 @ to "/doc/trunk/www/*" to give anonymous users read-only permission to the
 
 
 
504 @ latest version of the embedded documentation in the www/ folder without
505 @ allowing them to see the rest of the source code.
506 @ (Property: "public-pages")
507 @ </p>
508
509
--- src/setup.c
+++ src/setup.c
@@ -497,12 +497,15 @@
497 @ <hr />
498 entry_attribute("Public pages", 30, "public-pages",
499 "pubpage", "", 0);
500 @ <p>A comma-separated list of glob patterns for pages that are accessible
501 @ without needing a login and using the privileges given by the
502 @ "Default privileges" setting below.
503 @
504 @ <p>Example use case: Set this field to "/doc/trunk/www/*" and set
505 @ the "Default privileges" to include the "o" privilege
506 @ to give anonymous users read-only permission to the
507 @ latest version of the embedded documentation in the www/ folder without
508 @ allowing them to see the rest of the source code.
509 @ (Property: "public-pages")
510 @ </p>
511
512

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button