Fossil SCM

Fix enforcement of access restrictions on reports. Do not allow reports to show the content of fields whose names begin with "private_" unless the "e" permission is enabled.

drh 2008-07-19 15:12 trunk
Commit 21326fb6f7d3e2d175a80c3a603095c1f5b92f1b
+1 -1
--- src/main.c
+++ src/main.c
@@ -116,11 +116,11 @@
116116
int okRdTkt; /* r: view tickets via web */
117117
int okNewTkt; /* n: create new tickets */
118118
int okApndTkt; /* c: append to tickets via the web */
119119
int okWrTkt; /* w: make changes to tickets via web */
120120
int okTktFmt; /* t: create new ticket report formats */
121
- int okRdAddr; /* e: read email addresses on tickets */
121
+ int okRdAddr; /* e: read email addresses or other private data */
122122
123123
FILE *fDebug; /* Write debug information here, if the file exists */
124124
125125
/* Storage for the aux() and/or option() SQL function arguments */
126126
int nAux; /* Number of distinct aux() or option() values */
127127
--- src/main.c
+++ src/main.c
@@ -116,11 +116,11 @@
116 int okRdTkt; /* r: view tickets via web */
117 int okNewTkt; /* n: create new tickets */
118 int okApndTkt; /* c: append to tickets via the web */
119 int okWrTkt; /* w: make changes to tickets via web */
120 int okTktFmt; /* t: create new ticket report formats */
121 int okRdAddr; /* e: read email addresses on tickets */
122
123 FILE *fDebug; /* Write debug information here, if the file exists */
124
125 /* Storage for the aux() and/or option() SQL function arguments */
126 int nAux; /* Number of distinct aux() or option() values */
127
--- src/main.c
+++ src/main.c
@@ -116,11 +116,11 @@
116 int okRdTkt; /* r: view tickets via web */
117 int okNewTkt; /* n: create new tickets */
118 int okApndTkt; /* c: append to tickets via the web */
119 int okWrTkt; /* w: make changes to tickets via web */
120 int okTktFmt; /* t: create new ticket report formats */
121 int okRdAddr; /* e: read email addresses or other private data */
122
123 FILE *fDebug; /* Write debug information here, if the file exists */
124
125 /* Storage for the aux() and/or option() SQL function arguments */
126 int nAux; /* Number of distinct aux() or option() values */
127
+22 -7
--- src/report.c
+++ src/report.c
@@ -154,12 +154,12 @@
154154
const char *zArg1,
155155
const char *zArg2,
156156
const char *zArg3,
157157
const char *zArg4
158158
){
159
- char *zError = *(char**)pError;
160
- if( zError ){
159
+ int rc = SQLITE_OK;
160
+ if( *(char**)pError ){
161161
/* We've already seen an error. No need to continue. */
162162
return SQLITE_OK;
163163
}
164164
switch( code ){
165165
case SQLITE_SELECT:
@@ -180,20 +180,24 @@
180180
int i;
181181
for(i=0; i<sizeof(azAllowed)/sizeof(azAllowed[0]); i++){
182182
if( strcasecmp(zArg1, azAllowed[i])==0 ) break;
183183
}
184184
if( i>=sizeof(azAllowed)/sizeof(azAllowed[0]) ){
185
- zError = mprintf("cannot access table %s", zArg1);
185
+ *(char**)pError = mprintf("access to table \"%s\" is restricted",zArg1);
186
+ rc = SQLITE_DENY;
187
+ }else if( !g.okRdAddr && strncmp(zArg2, "private_", 8)==0 ){
188
+ rc = SQLITE_IGNORE;
186189
}
187190
break;
188191
}
189192
default: {
190
- zError = mprintf("only SELECT statements are allowed");
193
+ *(char**)pError = mprintf("only SELECT statements are allowed");
194
+ rc = SQLITE_DENY;
191195
break;
192196
}
193197
}
194
- return SQLITE_OK;
198
+ return rc;
195199
}
196200
197201
198202
/*
199203
** Check the given SQL to see if is a valid query that does not
@@ -875,10 +879,12 @@
875879
char *zTitle;
876880
char *zOwner;
877881
char *zClrKey;
878882
int tabs;
879883
Stmt q;
884
+ char *zErr1 = 0;
885
+ char *zErr2 = 0;
880886
881887
login_check_credentials();
882888
if( !g.okRead ){ login_needed(); return; }
883889
rn = atoi(PD("rn","0"));
884890
if( rn==0 ){
@@ -932,13 +938,22 @@
932938
output_color_key(zClrKey, 1,
933939
"border=0 cellpadding=3 cellspacing=0 class=\"report\"");
934940
@ <table border=1 cellpadding=2 cellspacing=0 class="report">
935941
sState.rn = rn;
936942
sState.nCount = 0;
937
- sqlite3_exec(g.db, zSql, generate_html, &sState, 0);
943
+ sqlite3_set_authorizer(g.db, report_query_authorizer, (void*)&zErr1);
944
+ sqlite3_exec(g.db, zSql, generate_html, &sState, &zErr2);
945
+ sqlite3_set_authorizer(g.db, 0, 0);
938946
@ </table>
947
+ if( zErr1 ){
948
+ @ <p><font color="red"><b>Error: %h(zErr1)</b></font></p>
949
+ }else if( zErr2 ){
950
+ @ <p><font color="red"><b>Error: %h(zErr2)</b></font></p>
951
+ }
939952
style_footer();
940953
}else{
941
- sqlite3_exec(g.db, zSql, output_tab_separated, &count, 0);
954
+ sqlite3_set_authorizer(g.db, report_query_authorizer, (void*)&zErr1);
955
+ sqlite3_exec(g.db, zSql, output_tab_separated, &count, &zErr2);
956
+ sqlite3_set_authorizer(g.db, 0, 0);
942957
cgi_set_content_type("text/plain");
943958
}
944959
}
945960
--- src/report.c
+++ src/report.c
@@ -154,12 +154,12 @@
154 const char *zArg1,
155 const char *zArg2,
156 const char *zArg3,
157 const char *zArg4
158 ){
159 char *zError = *(char**)pError;
160 if( zError ){
161 /* We've already seen an error. No need to continue. */
162 return SQLITE_OK;
163 }
164 switch( code ){
165 case SQLITE_SELECT:
@@ -180,20 +180,24 @@
180 int i;
181 for(i=0; i<sizeof(azAllowed)/sizeof(azAllowed[0]); i++){
182 if( strcasecmp(zArg1, azAllowed[i])==0 ) break;
183 }
184 if( i>=sizeof(azAllowed)/sizeof(azAllowed[0]) ){
185 zError = mprintf("cannot access table %s", zArg1);
 
 
 
186 }
187 break;
188 }
189 default: {
190 zError = mprintf("only SELECT statements are allowed");
 
191 break;
192 }
193 }
194 return SQLITE_OK;
195 }
196
197
198 /*
199 ** Check the given SQL to see if is a valid query that does not
@@ -875,10 +879,12 @@
875 char *zTitle;
876 char *zOwner;
877 char *zClrKey;
878 int tabs;
879 Stmt q;
 
 
880
881 login_check_credentials();
882 if( !g.okRead ){ login_needed(); return; }
883 rn = atoi(PD("rn","0"));
884 if( rn==0 ){
@@ -932,13 +938,22 @@
932 output_color_key(zClrKey, 1,
933 "border=0 cellpadding=3 cellspacing=0 class=\"report\"");
934 @ <table border=1 cellpadding=2 cellspacing=0 class="report">
935 sState.rn = rn;
936 sState.nCount = 0;
937 sqlite3_exec(g.db, zSql, generate_html, &sState, 0);
 
 
938 @ </table>
 
 
 
 
 
939 style_footer();
940 }else{
941 sqlite3_exec(g.db, zSql, output_tab_separated, &count, 0);
 
 
942 cgi_set_content_type("text/plain");
943 }
944 }
945
--- src/report.c
+++ src/report.c
@@ -154,12 +154,12 @@
154 const char *zArg1,
155 const char *zArg2,
156 const char *zArg3,
157 const char *zArg4
158 ){
159 int rc = SQLITE_OK;
160 if( *(char**)pError ){
161 /* We've already seen an error. No need to continue. */
162 return SQLITE_OK;
163 }
164 switch( code ){
165 case SQLITE_SELECT:
@@ -180,20 +180,24 @@
180 int i;
181 for(i=0; i<sizeof(azAllowed)/sizeof(azAllowed[0]); i++){
182 if( strcasecmp(zArg1, azAllowed[i])==0 ) break;
183 }
184 if( i>=sizeof(azAllowed)/sizeof(azAllowed[0]) ){
185 *(char**)pError = mprintf("access to table \"%s\" is restricted",zArg1);
186 rc = SQLITE_DENY;
187 }else if( !g.okRdAddr && strncmp(zArg2, "private_", 8)==0 ){
188 rc = SQLITE_IGNORE;
189 }
190 break;
191 }
192 default: {
193 *(char**)pError = mprintf("only SELECT statements are allowed");
194 rc = SQLITE_DENY;
195 break;
196 }
197 }
198 return rc;
199 }
200
201
202 /*
203 ** Check the given SQL to see if is a valid query that does not
@@ -875,10 +879,12 @@
879 char *zTitle;
880 char *zOwner;
881 char *zClrKey;
882 int tabs;
883 Stmt q;
884 char *zErr1 = 0;
885 char *zErr2 = 0;
886
887 login_check_credentials();
888 if( !g.okRead ){ login_needed(); return; }
889 rn = atoi(PD("rn","0"));
890 if( rn==0 ){
@@ -932,13 +938,22 @@
938 output_color_key(zClrKey, 1,
939 "border=0 cellpadding=3 cellspacing=0 class=\"report\"");
940 @ <table border=1 cellpadding=2 cellspacing=0 class="report">
941 sState.rn = rn;
942 sState.nCount = 0;
943 sqlite3_set_authorizer(g.db, report_query_authorizer, (void*)&zErr1);
944 sqlite3_exec(g.db, zSql, generate_html, &sState, &zErr2);
945 sqlite3_set_authorizer(g.db, 0, 0);
946 @ </table>
947 if( zErr1 ){
948 @ <p><font color="red"><b>Error: %h(zErr1)</b></font></p>
949 }else if( zErr2 ){
950 @ <p><font color="red"><b>Error: %h(zErr2)</b></font></p>
951 }
952 style_footer();
953 }else{
954 sqlite3_set_authorizer(g.db, report_query_authorizer, (void*)&zErr1);
955 sqlite3_exec(g.db, zSql, output_tab_separated, &count, &zErr2);
956 sqlite3_set_authorizer(g.db, 0, 0);
957 cgi_set_content_type("text/plain");
958 }
959 }
960
+1 -1
--- src/setup.c
+++ src/setup.c
@@ -136,11 +136,11 @@
136136
@ <li><p>The permission flags are as follows:</p>
137137
@ <ol type="a">
138138
@ <li value="1"><b>Admin</b>: Create and delete users</li>
139139
@ <li value="3"><b>Append-Tkt</b>: Append to tickets</li>
140140
@ <li value="4"><b>Delete</b>: Delete wiki and tickets</li>
141
- @ <li value="5"><b>Email</b>: View EMail addresses on tickets</li>
141
+ @ <li value="5"><b>Email</b>: View sensitive data such as EMail addresses</li>
142142
@ <li value="6"><b>New-Wiki</b>: Create new wiki pages</li>
143143
@ <li value="7"><b>Clone</b>: Clone the repository</li>
144144
@ <li value="8"><b>History</b>: View detail repository history</li>
145145
@ <li value="9"><b>Check-In</b>: Commit new versions in the repository</li>
146146
@ <li value="10"><b>Read-Wiki</b>: View wiki pages</li>
147147
--- src/setup.c
+++ src/setup.c
@@ -136,11 +136,11 @@
136 @ <li><p>The permission flags are as follows:</p>
137 @ <ol type="a">
138 @ <li value="1"><b>Admin</b>: Create and delete users</li>
139 @ <li value="3"><b>Append-Tkt</b>: Append to tickets</li>
140 @ <li value="4"><b>Delete</b>: Delete wiki and tickets</li>
141 @ <li value="5"><b>Email</b>: View EMail addresses on tickets</li>
142 @ <li value="6"><b>New-Wiki</b>: Create new wiki pages</li>
143 @ <li value="7"><b>Clone</b>: Clone the repository</li>
144 @ <li value="8"><b>History</b>: View detail repository history</li>
145 @ <li value="9"><b>Check-In</b>: Commit new versions in the repository</li>
146 @ <li value="10"><b>Read-Wiki</b>: View wiki pages</li>
147
--- src/setup.c
+++ src/setup.c
@@ -136,11 +136,11 @@
136 @ <li><p>The permission flags are as follows:</p>
137 @ <ol type="a">
138 @ <li value="1"><b>Admin</b>: Create and delete users</li>
139 @ <li value="3"><b>Append-Tkt</b>: Append to tickets</li>
140 @ <li value="4"><b>Delete</b>: Delete wiki and tickets</li>
141 @ <li value="5"><b>Email</b>: View sensitive data such as EMail addresses</li>
142 @ <li value="6"><b>New-Wiki</b>: Create new wiki pages</li>
143 @ <li value="7"><b>Clone</b>: Clone the repository</li>
144 @ <li value="8"><b>History</b>: View detail repository history</li>
145 @ <li value="9"><b>Check-In</b>: Commit new versions in the repository</li>
146 @ <li value="10"><b>Read-Wiki</b>: View wiki pages</li>
147
+10 -4
--- src/tktsetup.c
+++ src/tktsetup.c
@@ -56,10 +56,14 @@
5656
"The default color key for reports.");
5757
@ </table>
5858
style_footer();
5959
}
6060
61
+/*
62
+** NOTE: When changing the table definition below, also change the
63
+** equivalent definition found in schema.c.
64
+*/
6165
/* @-comment: ** */
6266
static const char zDefaultTicketTable[] =
6367
@ CREATE TABLE ticket(
6468
@ -- Do not change any column that begins with tkt_
6569
@ tkt_id INTEGER PRIMARY KEY,
@@ -70,11 +74,11 @@
7074
@ status TEXT,
7175
@ subsystem TEXT,
7276
@ priority TEXT,
7377
@ severity TEXT,
7478
@ foundin TEXT,
75
-@ contact TEXT,
79
+@ private_contact TEXT,
7680
@ resolution TEXT,
7781
@ title TEXT,
7882
@ comment TEXT,
7983
@ -- Do not alter this UNIQUE clause:
8084
@ UNIQUE(tkt_uuid, tkt_mtime)
@@ -125,10 +129,11 @@
125129
if( xText && (zErr = xText(z))!=0 ){
126130
@ <p><font color="red"><b>ERROR: %h(zErr)</b></font></p>
127131
}else{
128132
db_set(zDbField, z, 0);
129133
if( xRebuild ) xRebuild();
134
+ cgi_redirect("tktsetup");
130135
}
131136
}
132137
@ <form action="%s(g.zBaseURL)/%s(g.zPath)" method="POST">
133138
@ <p>%s(zDesc)</p>
134139
@ <textarea name="x" rows="%d(height)" cols="80">%h(z)</textarea>
@@ -276,11 +281,11 @@
276281
@ effect the operation of the product?</td>
277282
@ </tr>
278283
@
279284
@ <tr>
280285
@ <td align="right">EMail:
281
-@ <input type="text" name="contact" value="$<contact>" size="30">
286
+@ <input type="text" name="private_contact" value="$<private_contact>" size="30">
282287
@ </td>
283288
@ <td><u>Not publicly visible</u>. Used by developers to contact you with
284289
@ questions.</td>
285290
@ </tr>
286291
@
@@ -377,11 +382,11 @@
377382
@ <tr><td align="right">Last&nbsp;Modified:</td><td bgcolor="#d0d0d0">
378383
@ $<tkt_datetime>
379384
@ </td>
380385
@ <th1>enable_output [hascap e]</th1>
381386
@ <td align="right">Contact:</td><td bgcolor="#d0d0d0">
382
-@ $<contact>
387
+@ $<private_contact>
383388
@ </td>
384389
@ <th1>enable_output 1</th1>
385390
@ </tr>
386391
@ <tr><td align="right">Version&nbsp;Found&nbsp;In:</td>
387392
@ <td colspan="3" valign="top" bgcolor="#d0d0d0">
@@ -461,11 +466,12 @@
461466
@ <tr><td align="right">Subsystem:</td><td>
462467
@ <th1>combobox subsystem $subsystem_choices 1</th1>
463468
@ </td></tr>
464469
@ <th1>enable_output [hascap e]</th1>
465470
@ <tr><td align="right">Contact:</td><td>
466
-@ <input type="text" name="contact" size="40" value="$<contact>">
471
+@ <input type="text" name="private_contact" size="40"
472
+@ value="$<private_contact>">
467473
@ </td></tr>
468474
@ <th1>enable_output 1</th1>
469475
@ <tr><td align="right">Version&nbsp;Found&nbsp;In:</td><td>
470476
@ <input type="text" name="foundin" size="50" value="$<foundin>">
471477
@ </td></tr>
472478
--- src/tktsetup.c
+++ src/tktsetup.c
@@ -56,10 +56,14 @@
56 "The default color key for reports.");
57 @ </table>
58 style_footer();
59 }
60
 
 
 
 
61 /* @-comment: ** */
62 static const char zDefaultTicketTable[] =
63 @ CREATE TABLE ticket(
64 @ -- Do not change any column that begins with tkt_
65 @ tkt_id INTEGER PRIMARY KEY,
@@ -70,11 +74,11 @@
70 @ status TEXT,
71 @ subsystem TEXT,
72 @ priority TEXT,
73 @ severity TEXT,
74 @ foundin TEXT,
75 @ contact TEXT,
76 @ resolution TEXT,
77 @ title TEXT,
78 @ comment TEXT,
79 @ -- Do not alter this UNIQUE clause:
80 @ UNIQUE(tkt_uuid, tkt_mtime)
@@ -125,10 +129,11 @@
125 if( xText && (zErr = xText(z))!=0 ){
126 @ <p><font color="red"><b>ERROR: %h(zErr)</b></font></p>
127 }else{
128 db_set(zDbField, z, 0);
129 if( xRebuild ) xRebuild();
 
130 }
131 }
132 @ <form action="%s(g.zBaseURL)/%s(g.zPath)" method="POST">
133 @ <p>%s(zDesc)</p>
134 @ <textarea name="x" rows="%d(height)" cols="80">%h(z)</textarea>
@@ -276,11 +281,11 @@
276 @ effect the operation of the product?</td>
277 @ </tr>
278 @
279 @ <tr>
280 @ <td align="right">EMail:
281 @ <input type="text" name="contact" value="$<contact>" size="30">
282 @ </td>
283 @ <td><u>Not publicly visible</u>. Used by developers to contact you with
284 @ questions.</td>
285 @ </tr>
286 @
@@ -377,11 +382,11 @@
377 @ <tr><td align="right">Last&nbsp;Modified:</td><td bgcolor="#d0d0d0">
378 @ $<tkt_datetime>
379 @ </td>
380 @ <th1>enable_output [hascap e]</th1>
381 @ <td align="right">Contact:</td><td bgcolor="#d0d0d0">
382 @ $<contact>
383 @ </td>
384 @ <th1>enable_output 1</th1>
385 @ </tr>
386 @ <tr><td align="right">Version&nbsp;Found&nbsp;In:</td>
387 @ <td colspan="3" valign="top" bgcolor="#d0d0d0">
@@ -461,11 +466,12 @@
461 @ <tr><td align="right">Subsystem:</td><td>
462 @ <th1>combobox subsystem $subsystem_choices 1</th1>
463 @ </td></tr>
464 @ <th1>enable_output [hascap e]</th1>
465 @ <tr><td align="right">Contact:</td><td>
466 @ <input type="text" name="contact" size="40" value="$<contact>">
 
467 @ </td></tr>
468 @ <th1>enable_output 1</th1>
469 @ <tr><td align="right">Version&nbsp;Found&nbsp;In:</td><td>
470 @ <input type="text" name="foundin" size="50" value="$<foundin>">
471 @ </td></tr>
472
--- src/tktsetup.c
+++ src/tktsetup.c
@@ -56,10 +56,14 @@
56 "The default color key for reports.");
57 @ </table>
58 style_footer();
59 }
60
61 /*
62 ** NOTE: When changing the table definition below, also change the
63 ** equivalent definition found in schema.c.
64 */
65 /* @-comment: ** */
66 static const char zDefaultTicketTable[] =
67 @ CREATE TABLE ticket(
68 @ -- Do not change any column that begins with tkt_
69 @ tkt_id INTEGER PRIMARY KEY,
@@ -70,11 +74,11 @@
74 @ status TEXT,
75 @ subsystem TEXT,
76 @ priority TEXT,
77 @ severity TEXT,
78 @ foundin TEXT,
79 @ private_contact TEXT,
80 @ resolution TEXT,
81 @ title TEXT,
82 @ comment TEXT,
83 @ -- Do not alter this UNIQUE clause:
84 @ UNIQUE(tkt_uuid, tkt_mtime)
@@ -125,10 +129,11 @@
129 if( xText && (zErr = xText(z))!=0 ){
130 @ <p><font color="red"><b>ERROR: %h(zErr)</b></font></p>
131 }else{
132 db_set(zDbField, z, 0);
133 if( xRebuild ) xRebuild();
134 cgi_redirect("tktsetup");
135 }
136 }
137 @ <form action="%s(g.zBaseURL)/%s(g.zPath)" method="POST">
138 @ <p>%s(zDesc)</p>
139 @ <textarea name="x" rows="%d(height)" cols="80">%h(z)</textarea>
@@ -276,11 +281,11 @@
281 @ effect the operation of the product?</td>
282 @ </tr>
283 @
284 @ <tr>
285 @ <td align="right">EMail:
286 @ <input type="text" name="private_contact" value="$<private_contact>" size="30">
287 @ </td>
288 @ <td><u>Not publicly visible</u>. Used by developers to contact you with
289 @ questions.</td>
290 @ </tr>
291 @
@@ -377,11 +382,11 @@
382 @ <tr><td align="right">Last&nbsp;Modified:</td><td bgcolor="#d0d0d0">
383 @ $<tkt_datetime>
384 @ </td>
385 @ <th1>enable_output [hascap e]</th1>
386 @ <td align="right">Contact:</td><td bgcolor="#d0d0d0">
387 @ $<private_contact>
388 @ </td>
389 @ <th1>enable_output 1</th1>
390 @ </tr>
391 @ <tr><td align="right">Version&nbsp;Found&nbsp;In:</td>
392 @ <td colspan="3" valign="top" bgcolor="#d0d0d0">
@@ -461,11 +466,12 @@
466 @ <tr><td align="right">Subsystem:</td><td>
467 @ <th1>combobox subsystem $subsystem_choices 1</th1>
468 @ </td></tr>
469 @ <th1>enable_output [hascap e]</th1>
470 @ <tr><td align="right">Contact:</td><td>
471 @ <input type="text" name="private_contact" size="40"
472 @ value="$<private_contact>">
473 @ </td></tr>
474 @ <th1>enable_output 1</th1>
475 @ <tr><td align="right">Version&nbsp;Found&nbsp;In:</td><td>
476 @ <input type="text" name="foundin" size="50" value="$<foundin>">
477 @ </td></tr>
478

Keyboard Shortcuts

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