Fossil SCM

merged in trunk [06e0cb70054d3c3], resolved conflict in login.c.

stephan 2011-10-27 16:12 json-multitag-test merge
Commit 81d71d7b9ef90ccbbda360555ce1e17a71b2da7f
+2 -3
--- src/cgi.c
+++ src/cgi.c
@@ -1169,18 +1169,17 @@
11691169
cgi_setenv("HTTP_HOST", zVal);
11701170
}else if( fossil_strcmp(zFieldName,"if-none-match:")==0 ){
11711171
cgi_setenv("HTTP_IF_NONE_MATCH", zVal);
11721172
}else if( fossil_strcmp(zFieldName,"if-modified-since:")==0 ){
11731173
cgi_setenv("HTTP_IF_MODIFIED_SINCE", zVal);
1174
- }
11751174
#if 0
1176
- else if( fossil_strcmp(zFieldName,"referer:")==0 ){
1175
+ }else if( fossil_strcmp(zFieldName,"referer:")==0 ){
11771176
cgi_setenv("HTTP_REFERER", zVal);
1177
+#endif
11781178
}else if( fossil_strcmp(zFieldName,"user-agent:")==0 ){
11791179
cgi_setenv("HTTP_USER_AGENT", zVal);
11801180
}
1181
-#endif
11821181
}
11831182
11841183
cgi_init();
11851184
}
11861185
11871186
--- src/cgi.c
+++ src/cgi.c
@@ -1169,18 +1169,17 @@
1169 cgi_setenv("HTTP_HOST", zVal);
1170 }else if( fossil_strcmp(zFieldName,"if-none-match:")==0 ){
1171 cgi_setenv("HTTP_IF_NONE_MATCH", zVal);
1172 }else if( fossil_strcmp(zFieldName,"if-modified-since:")==0 ){
1173 cgi_setenv("HTTP_IF_MODIFIED_SINCE", zVal);
1174 }
1175 #if 0
1176 else if( fossil_strcmp(zFieldName,"referer:")==0 ){
1177 cgi_setenv("HTTP_REFERER", zVal);
 
1178 }else if( fossil_strcmp(zFieldName,"user-agent:")==0 ){
1179 cgi_setenv("HTTP_USER_AGENT", zVal);
1180 }
1181 #endif
1182 }
1183
1184 cgi_init();
1185 }
1186
1187
--- src/cgi.c
+++ src/cgi.c
@@ -1169,18 +1169,17 @@
1169 cgi_setenv("HTTP_HOST", zVal);
1170 }else if( fossil_strcmp(zFieldName,"if-none-match:")==0 ){
1171 cgi_setenv("HTTP_IF_NONE_MATCH", zVal);
1172 }else if( fossil_strcmp(zFieldName,"if-modified-since:")==0 ){
1173 cgi_setenv("HTTP_IF_MODIFIED_SINCE", zVal);
 
1174 #if 0
1175 }else if( fossil_strcmp(zFieldName,"referer:")==0 ){
1176 cgi_setenv("HTTP_REFERER", zVal);
1177 #endif
1178 }else if( fossil_strcmp(zFieldName,"user-agent:")==0 ){
1179 cgi_setenv("HTTP_USER_AGENT", zVal);
1180 }
 
1181 }
1182
1183 cgi_init();
1184 }
1185
1186
+2 -3
--- src/cgi.c
+++ src/cgi.c
@@ -1169,18 +1169,17 @@
11691169
cgi_setenv("HTTP_HOST", zVal);
11701170
}else if( fossil_strcmp(zFieldName,"if-none-match:")==0 ){
11711171
cgi_setenv("HTTP_IF_NONE_MATCH", zVal);
11721172
}else if( fossil_strcmp(zFieldName,"if-modified-since:")==0 ){
11731173
cgi_setenv("HTTP_IF_MODIFIED_SINCE", zVal);
1174
- }
11751174
#if 0
1176
- else if( fossil_strcmp(zFieldName,"referer:")==0 ){
1175
+ }else if( fossil_strcmp(zFieldName,"referer:")==0 ){
11771176
cgi_setenv("HTTP_REFERER", zVal);
1177
+#endif
11781178
}else if( fossil_strcmp(zFieldName,"user-agent:")==0 ){
11791179
cgi_setenv("HTTP_USER_AGENT", zVal);
11801180
}
1181
-#endif
11821181
}
11831182
11841183
cgi_init();
11851184
}
11861185
11871186
--- src/cgi.c
+++ src/cgi.c
@@ -1169,18 +1169,17 @@
1169 cgi_setenv("HTTP_HOST", zVal);
1170 }else if( fossil_strcmp(zFieldName,"if-none-match:")==0 ){
1171 cgi_setenv("HTTP_IF_NONE_MATCH", zVal);
1172 }else if( fossil_strcmp(zFieldName,"if-modified-since:")==0 ){
1173 cgi_setenv("HTTP_IF_MODIFIED_SINCE", zVal);
1174 }
1175 #if 0
1176 else if( fossil_strcmp(zFieldName,"referer:")==0 ){
1177 cgi_setenv("HTTP_REFERER", zVal);
 
1178 }else if( fossil_strcmp(zFieldName,"user-agent:")==0 ){
1179 cgi_setenv("HTTP_USER_AGENT", zVal);
1180 }
1181 #endif
1182 }
1183
1184 cgi_init();
1185 }
1186
1187
--- src/cgi.c
+++ src/cgi.c
@@ -1169,18 +1169,17 @@
1169 cgi_setenv("HTTP_HOST", zVal);
1170 }else if( fossil_strcmp(zFieldName,"if-none-match:")==0 ){
1171 cgi_setenv("HTTP_IF_NONE_MATCH", zVal);
1172 }else if( fossil_strcmp(zFieldName,"if-modified-since:")==0 ){
1173 cgi_setenv("HTTP_IF_MODIFIED_SINCE", zVal);
 
1174 #if 0
1175 }else if( fossil_strcmp(zFieldName,"referer:")==0 ){
1176 cgi_setenv("HTTP_REFERER", zVal);
1177 #endif
1178 }else if( fossil_strcmp(zFieldName,"user-agent:")==0 ){
1179 cgi_setenv("HTTP_USER_AGENT", zVal);
1180 }
 
1181 }
1182
1183 cgi_init();
1184 }
1185
1186
--- src/json_artifact.c
+++ src/json_artifact.c
@@ -351,11 +351,11 @@
351351
}else if(2==rc){
352352
g.json.resultCode = FSL_JSON_E_AMBIGUOUS_UUID;
353353
goto error;
354354
}
355355
zUuid = blob_str(&uuid);
356
- rid = db_int(0, "SELECT rid FROM blob WHERE uuid='%s'", zUuid);
356
+ rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", zUuid);
357357
if(0==rid){
358358
g.json.resultCode = FSL_JSON_E_RESOURCE_NOT_FOUND;
359359
goto error;
360360
}
361361
362362
--- src/json_artifact.c
+++ src/json_artifact.c
@@ -351,11 +351,11 @@
351 }else if(2==rc){
352 g.json.resultCode = FSL_JSON_E_AMBIGUOUS_UUID;
353 goto error;
354 }
355 zUuid = blob_str(&uuid);
356 rid = db_int(0, "SELECT rid FROM blob WHERE uuid='%s'", zUuid);
357 if(0==rid){
358 g.json.resultCode = FSL_JSON_E_RESOURCE_NOT_FOUND;
359 goto error;
360 }
361
362
--- src/json_artifact.c
+++ src/json_artifact.c
@@ -351,11 +351,11 @@
351 }else if(2==rc){
352 g.json.resultCode = FSL_JSON_E_AMBIGUOUS_UUID;
353 goto error;
354 }
355 zUuid = blob_str(&uuid);
356 rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", zUuid);
357 if(0==rid){
358 g.json.resultCode = FSL_JSON_E_RESOURCE_NOT_FOUND;
359 goto error;
360 }
361
362
--- src/json_artifact.c
+++ src/json_artifact.c
@@ -351,11 +351,11 @@
351351
}else if(2==rc){
352352
g.json.resultCode = FSL_JSON_E_AMBIGUOUS_UUID;
353353
goto error;
354354
}
355355
zUuid = blob_str(&uuid);
356
- rid = db_int(0, "SELECT rid FROM blob WHERE uuid='%s'", zUuid);
356
+ rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", zUuid);
357357
if(0==rid){
358358
g.json.resultCode = FSL_JSON_E_RESOURCE_NOT_FOUND;
359359
goto error;
360360
}
361361
362362
--- src/json_artifact.c
+++ src/json_artifact.c
@@ -351,11 +351,11 @@
351 }else if(2==rc){
352 g.json.resultCode = FSL_JSON_E_AMBIGUOUS_UUID;
353 goto error;
354 }
355 zUuid = blob_str(&uuid);
356 rid = db_int(0, "SELECT rid FROM blob WHERE uuid='%s'", zUuid);
357 if(0==rid){
358 g.json.resultCode = FSL_JSON_E_RESOURCE_NOT_FOUND;
359 goto error;
360 }
361
362
--- src/json_artifact.c
+++ src/json_artifact.c
@@ -351,11 +351,11 @@
351 }else if(2==rc){
352 g.json.resultCode = FSL_JSON_E_AMBIGUOUS_UUID;
353 goto error;
354 }
355 zUuid = blob_str(&uuid);
356 rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", zUuid);
357 if(0==rid){
358 g.json.resultCode = FSL_JSON_E_RESOURCE_NOT_FOUND;
359 goto error;
360 }
361
362
--- src/json_branch.c
+++ src/json_branch.c
@@ -204,11 +204,11 @@
204204
return FSL_JSON_E_INVALID_ARGS;
205205
}
206206
if( db_exists(
207207
"SELECT 1 FROM tagxref"
208208
" WHERE tagtype>0"
209
- " AND tagid=(SELECT tagid FROM tag WHERE tagname='sym-%s')",
209
+ " AND tagid=(SELECT tagid FROM tag WHERE tagname='sym-%q')",
210210
zBranch)!=0 ){
211211
zOpt->rcErrMsg = "Branch already exists.";
212212
return FSL_JSON_E_RESOURCE_ALREADY_EXISTS;
213213
}
214214
215215
--- src/json_branch.c
+++ src/json_branch.c
@@ -204,11 +204,11 @@
204 return FSL_JSON_E_INVALID_ARGS;
205 }
206 if( db_exists(
207 "SELECT 1 FROM tagxref"
208 " WHERE tagtype>0"
209 " AND tagid=(SELECT tagid FROM tag WHERE tagname='sym-%s')",
210 zBranch)!=0 ){
211 zOpt->rcErrMsg = "Branch already exists.";
212 return FSL_JSON_E_RESOURCE_ALREADY_EXISTS;
213 }
214
215
--- src/json_branch.c
+++ src/json_branch.c
@@ -204,11 +204,11 @@
204 return FSL_JSON_E_INVALID_ARGS;
205 }
206 if( db_exists(
207 "SELECT 1 FROM tagxref"
208 " WHERE tagtype>0"
209 " AND tagid=(SELECT tagid FROM tag WHERE tagname='sym-%q')",
210 zBranch)!=0 ){
211 zOpt->rcErrMsg = "Branch already exists.";
212 return FSL_JSON_E_RESOURCE_ALREADY_EXISTS;
213 }
214
215
--- src/json_branch.c
+++ src/json_branch.c
@@ -204,11 +204,11 @@
204204
return FSL_JSON_E_INVALID_ARGS;
205205
}
206206
if( db_exists(
207207
"SELECT 1 FROM tagxref"
208208
" WHERE tagtype>0"
209
- " AND tagid=(SELECT tagid FROM tag WHERE tagname='sym-%s')",
209
+ " AND tagid=(SELECT tagid FROM tag WHERE tagname='sym-%q')",
210210
zBranch)!=0 ){
211211
zOpt->rcErrMsg = "Branch already exists.";
212212
return FSL_JSON_E_RESOURCE_ALREADY_EXISTS;
213213
}
214214
215215
--- src/json_branch.c
+++ src/json_branch.c
@@ -204,11 +204,11 @@
204 return FSL_JSON_E_INVALID_ARGS;
205 }
206 if( db_exists(
207 "SELECT 1 FROM tagxref"
208 " WHERE tagtype>0"
209 " AND tagid=(SELECT tagid FROM tag WHERE tagname='sym-%s')",
210 zBranch)!=0 ){
211 zOpt->rcErrMsg = "Branch already exists.";
212 return FSL_JSON_E_RESOURCE_ALREADY_EXISTS;
213 }
214
215
--- src/json_branch.c
+++ src/json_branch.c
@@ -204,11 +204,11 @@
204 return FSL_JSON_E_INVALID_ARGS;
205 }
206 if( db_exists(
207 "SELECT 1 FROM tagxref"
208 " WHERE tagtype>0"
209 " AND tagid=(SELECT tagid FROM tag WHERE tagname='sym-%q')",
210 zBranch)!=0 ){
211 zOpt->rcErrMsg = "Branch already exists.";
212 return FSL_JSON_E_RESOURCE_ALREADY_EXISTS;
213 }
214
215
+46 -2
--- src/login.c
+++ src/login.c
@@ -117,15 +117,20 @@
117117
** But some clients are behind firewalls that shift the IP address
118118
** with each HTTP request. To allow such (broken) clients to log in,
119119
** extract just a prefix of the IP address.
120120
*/
121121
static char *ipPrefix(const char *zIP){
122
- int i, j;
122
+ int i, j;
123
+ static int ip_prefix_terms = -1;
124
+ if( ip_prefix_terms<0 ){
125
+ ip_prefix_terms = db_get_int("ip-prefix-terms",2);
126
+ }
127
+ if( ip_prefix_terms==0 ) return mprintf("0");
123128
for(i=j=0; zIP[i]; i++){
124129
if( zIP[i]=='.' ){
125130
j++;
126
- if( j==2 ) break;
131
+ if( j==ip_prefix_terms ) break;
127132
}
128133
}
129134
return mprintf("%.*s", i, zIP);
130135
}
131136
@@ -347,10 +352,45 @@
347352
** downstream problems here. We could alternately use "" here.
348353
*/
349354
;
350355
}
351356
}
357
+
358
+/*
359
+** Look at the HTTP_USER_AGENT parameter and try to determine if the user agent
360
+** is a manually operated browser or a bot. When in doubt, assume a bot. Return
361
+** true if we believe the agent is a real person.
362
+*/
363
+static int isHuman(const char *zAgent){
364
+ int i;
365
+ if( zAgent==0 ) return 0;
366
+ for(i=0; zAgent[i]; i++){
367
+ if( zAgent[i]=='b' && memcmp(&zAgent[i],"bot",3)==0 ) return 0;
368
+ if( zAgent[i]=='s' && memcmp(&zAgent[i],"spider",6)==0 ) return 0;
369
+ }
370
+ if( memcmp(zAgent, "Mozilla/", 8)==0 ){
371
+ return atoi(&zAgent[8])>=4;
372
+ }
373
+ if( memcmp(zAgent, "Opera/", 6)==0 ) return 1;
374
+ if( memcmp(zAgent, "Safari/", 7)==0 ) return 1;
375
+ if( memcmp(zAgent, "Lynx/", 5)==0 ) return 1;
376
+ return 0;
377
+}
378
+
379
+/*
380
+** COMMAND: test-ishuman
381
+**
382
+** Read lines of text from standard input. Interpret each line of text
383
+** as a User-Agent string from an HTTP header. Label each line as HUMAN
384
+** or ROBOT.
385
+*/
386
+void test_ishuman(void){
387
+ char zLine[3000];
388
+ while( fgets(zLine, sizeof(zLine), stdin) ){
389
+ fossil_print("%s %s", isHuman(zLine) ? "HUMAN" : "ROBOT", zLine);
390
+ }
391
+}
352392
353393
/*
354394
** SQL function for constant time comparison of two values.
355395
** Sets result to 0 if two values are equal.
356396
*/
@@ -831,10 +871,14 @@
831871
}
832872
833873
/* Set the capabilities */
834874
login_replace_capabilities(zCap, 0);
835875
login_set_anon_nobody_capabilities();
876
+ if( zCap[0] && !g.perm.History && db_get_boolean("auto-enable-hyperlinks",1)
877
+ && isHuman(P("HTTP_USER_AGENT")) ){
878
+ g.perm.History = 1;
879
+ }
836880
}
837881
838882
/*
839883
** Memory of settings
840884
*/
841885
--- src/login.c
+++ src/login.c
@@ -117,15 +117,20 @@
117 ** But some clients are behind firewalls that shift the IP address
118 ** with each HTTP request. To allow such (broken) clients to log in,
119 ** extract just a prefix of the IP address.
120 */
121 static char *ipPrefix(const char *zIP){
122 int i, j;
 
 
 
 
 
123 for(i=j=0; zIP[i]; i++){
124 if( zIP[i]=='.' ){
125 j++;
126 if( j==2 ) break;
127 }
128 }
129 return mprintf("%.*s", i, zIP);
130 }
131
@@ -347,10 +352,45 @@
347 ** downstream problems here. We could alternately use "" here.
348 */
349 ;
350 }
351 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
352
353 /*
354 ** SQL function for constant time comparison of two values.
355 ** Sets result to 0 if two values are equal.
356 */
@@ -831,10 +871,14 @@
831 }
832
833 /* Set the capabilities */
834 login_replace_capabilities(zCap, 0);
835 login_set_anon_nobody_capabilities();
 
 
 
 
836 }
837
838 /*
839 ** Memory of settings
840 */
841
--- src/login.c
+++ src/login.c
@@ -117,15 +117,20 @@
117 ** But some clients are behind firewalls that shift the IP address
118 ** with each HTTP request. To allow such (broken) clients to log in,
119 ** extract just a prefix of the IP address.
120 */
121 static char *ipPrefix(const char *zIP){
122 int i, j;
123 static int ip_prefix_terms = -1;
124 if( ip_prefix_terms<0 ){
125 ip_prefix_terms = db_get_int("ip-prefix-terms",2);
126 }
127 if( ip_prefix_terms==0 ) return mprintf("0");
128 for(i=j=0; zIP[i]; i++){
129 if( zIP[i]=='.' ){
130 j++;
131 if( j==ip_prefix_terms ) break;
132 }
133 }
134 return mprintf("%.*s", i, zIP);
135 }
136
@@ -347,10 +352,45 @@
352 ** downstream problems here. We could alternately use "" here.
353 */
354 ;
355 }
356 }
357
358 /*
359 ** Look at the HTTP_USER_AGENT parameter and try to determine if the user agent
360 ** is a manually operated browser or a bot. When in doubt, assume a bot. Return
361 ** true if we believe the agent is a real person.
362 */
363 static int isHuman(const char *zAgent){
364 int i;
365 if( zAgent==0 ) return 0;
366 for(i=0; zAgent[i]; i++){
367 if( zAgent[i]=='b' && memcmp(&zAgent[i],"bot",3)==0 ) return 0;
368 if( zAgent[i]=='s' && memcmp(&zAgent[i],"spider",6)==0 ) return 0;
369 }
370 if( memcmp(zAgent, "Mozilla/", 8)==0 ){
371 return atoi(&zAgent[8])>=4;
372 }
373 if( memcmp(zAgent, "Opera/", 6)==0 ) return 1;
374 if( memcmp(zAgent, "Safari/", 7)==0 ) return 1;
375 if( memcmp(zAgent, "Lynx/", 5)==0 ) return 1;
376 return 0;
377 }
378
379 /*
380 ** COMMAND: test-ishuman
381 **
382 ** Read lines of text from standard input. Interpret each line of text
383 ** as a User-Agent string from an HTTP header. Label each line as HUMAN
384 ** or ROBOT.
385 */
386 void test_ishuman(void){
387 char zLine[3000];
388 while( fgets(zLine, sizeof(zLine), stdin) ){
389 fossil_print("%s %s", isHuman(zLine) ? "HUMAN" : "ROBOT", zLine);
390 }
391 }
392
393 /*
394 ** SQL function for constant time comparison of two values.
395 ** Sets result to 0 if two values are equal.
396 */
@@ -831,10 +871,14 @@
871 }
872
873 /* Set the capabilities */
874 login_replace_capabilities(zCap, 0);
875 login_set_anon_nobody_capabilities();
876 if( zCap[0] && !g.perm.History && db_get_boolean("auto-enable-hyperlinks",1)
877 && isHuman(P("HTTP_USER_AGENT")) ){
878 g.perm.History = 1;
879 }
880 }
881
882 /*
883 ** Memory of settings
884 */
885
+46 -2
--- src/login.c
+++ src/login.c
@@ -117,15 +117,20 @@
117117
** But some clients are behind firewalls that shift the IP address
118118
** with each HTTP request. To allow such (broken) clients to log in,
119119
** extract just a prefix of the IP address.
120120
*/
121121
static char *ipPrefix(const char *zIP){
122
- int i, j;
122
+ int i, j;
123
+ static int ip_prefix_terms = -1;
124
+ if( ip_prefix_terms<0 ){
125
+ ip_prefix_terms = db_get_int("ip-prefix-terms",2);
126
+ }
127
+ if( ip_prefix_terms==0 ) return mprintf("0");
123128
for(i=j=0; zIP[i]; i++){
124129
if( zIP[i]=='.' ){
125130
j++;
126
- if( j==2 ) break;
131
+ if( j==ip_prefix_terms ) break;
127132
}
128133
}
129134
return mprintf("%.*s", i, zIP);
130135
}
131136
@@ -347,10 +352,45 @@
347352
** downstream problems here. We could alternately use "" here.
348353
*/
349354
;
350355
}
351356
}
357
+
358
+/*
359
+** Look at the HTTP_USER_AGENT parameter and try to determine if the user agent
360
+** is a manually operated browser or a bot. When in doubt, assume a bot. Return
361
+** true if we believe the agent is a real person.
362
+*/
363
+static int isHuman(const char *zAgent){
364
+ int i;
365
+ if( zAgent==0 ) return 0;
366
+ for(i=0; zAgent[i]; i++){
367
+ if( zAgent[i]=='b' && memcmp(&zAgent[i],"bot",3)==0 ) return 0;
368
+ if( zAgent[i]=='s' && memcmp(&zAgent[i],"spider",6)==0 ) return 0;
369
+ }
370
+ if( memcmp(zAgent, "Mozilla/", 8)==0 ){
371
+ return atoi(&zAgent[8])>=4;
372
+ }
373
+ if( memcmp(zAgent, "Opera/", 6)==0 ) return 1;
374
+ if( memcmp(zAgent, "Safari/", 7)==0 ) return 1;
375
+ if( memcmp(zAgent, "Lynx/", 5)==0 ) return 1;
376
+ return 0;
377
+}
378
+
379
+/*
380
+** COMMAND: test-ishuman
381
+**
382
+** Read lines of text from standard input. Interpret each line of text
383
+** as a User-Agent string from an HTTP header. Label each line as HUMAN
384
+** or ROBOT.
385
+*/
386
+void test_ishuman(void){
387
+ char zLine[3000];
388
+ while( fgets(zLine, sizeof(zLine), stdin) ){
389
+ fossil_print("%s %s", isHuman(zLine) ? "HUMAN" : "ROBOT", zLine);
390
+ }
391
+}
352392
353393
/*
354394
** SQL function for constant time comparison of two values.
355395
** Sets result to 0 if two values are equal.
356396
*/
@@ -831,10 +871,14 @@
831871
}
832872
833873
/* Set the capabilities */
834874
login_replace_capabilities(zCap, 0);
835875
login_set_anon_nobody_capabilities();
876
+ if( zCap[0] && !g.perm.History && db_get_boolean("auto-enable-hyperlinks",1)
877
+ && isHuman(P("HTTP_USER_AGENT")) ){
878
+ g.perm.History = 1;
879
+ }
836880
}
837881
838882
/*
839883
** Memory of settings
840884
*/
841885
--- src/login.c
+++ src/login.c
@@ -117,15 +117,20 @@
117 ** But some clients are behind firewalls that shift the IP address
118 ** with each HTTP request. To allow such (broken) clients to log in,
119 ** extract just a prefix of the IP address.
120 */
121 static char *ipPrefix(const char *zIP){
122 int i, j;
 
 
 
 
 
123 for(i=j=0; zIP[i]; i++){
124 if( zIP[i]=='.' ){
125 j++;
126 if( j==2 ) break;
127 }
128 }
129 return mprintf("%.*s", i, zIP);
130 }
131
@@ -347,10 +352,45 @@
347 ** downstream problems here. We could alternately use "" here.
348 */
349 ;
350 }
351 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
352
353 /*
354 ** SQL function for constant time comparison of two values.
355 ** Sets result to 0 if two values are equal.
356 */
@@ -831,10 +871,14 @@
831 }
832
833 /* Set the capabilities */
834 login_replace_capabilities(zCap, 0);
835 login_set_anon_nobody_capabilities();
 
 
 
 
836 }
837
838 /*
839 ** Memory of settings
840 */
841
--- src/login.c
+++ src/login.c
@@ -117,15 +117,20 @@
117 ** But some clients are behind firewalls that shift the IP address
118 ** with each HTTP request. To allow such (broken) clients to log in,
119 ** extract just a prefix of the IP address.
120 */
121 static char *ipPrefix(const char *zIP){
122 int i, j;
123 static int ip_prefix_terms = -1;
124 if( ip_prefix_terms<0 ){
125 ip_prefix_terms = db_get_int("ip-prefix-terms",2);
126 }
127 if( ip_prefix_terms==0 ) return mprintf("0");
128 for(i=j=0; zIP[i]; i++){
129 if( zIP[i]=='.' ){
130 j++;
131 if( j==ip_prefix_terms ) break;
132 }
133 }
134 return mprintf("%.*s", i, zIP);
135 }
136
@@ -347,10 +352,45 @@
352 ** downstream problems here. We could alternately use "" here.
353 */
354 ;
355 }
356 }
357
358 /*
359 ** Look at the HTTP_USER_AGENT parameter and try to determine if the user agent
360 ** is a manually operated browser or a bot. When in doubt, assume a bot. Return
361 ** true if we believe the agent is a real person.
362 */
363 static int isHuman(const char *zAgent){
364 int i;
365 if( zAgent==0 ) return 0;
366 for(i=0; zAgent[i]; i++){
367 if( zAgent[i]=='b' && memcmp(&zAgent[i],"bot",3)==0 ) return 0;
368 if( zAgent[i]=='s' && memcmp(&zAgent[i],"spider",6)==0 ) return 0;
369 }
370 if( memcmp(zAgent, "Mozilla/", 8)==0 ){
371 return atoi(&zAgent[8])>=4;
372 }
373 if( memcmp(zAgent, "Opera/", 6)==0 ) return 1;
374 if( memcmp(zAgent, "Safari/", 7)==0 ) return 1;
375 if( memcmp(zAgent, "Lynx/", 5)==0 ) return 1;
376 return 0;
377 }
378
379 /*
380 ** COMMAND: test-ishuman
381 **
382 ** Read lines of text from standard input. Interpret each line of text
383 ** as a User-Agent string from an HTTP header. Label each line as HUMAN
384 ** or ROBOT.
385 */
386 void test_ishuman(void){
387 char zLine[3000];
388 while( fgets(zLine, sizeof(zLine), stdin) ){
389 fossil_print("%s %s", isHuman(zLine) ? "HUMAN" : "ROBOT", zLine);
390 }
391 }
392
393 /*
394 ** SQL function for constant time comparison of two values.
395 ** Sets result to 0 if two values are equal.
396 */
@@ -831,10 +871,14 @@
871 }
872
873 /* Set the capabilities */
874 login_replace_capabilities(zCap, 0);
875 login_set_anon_nobody_capabilities();
876 if( zCap[0] && !g.perm.History && db_get_boolean("auto-enable-hyperlinks",1)
877 && isHuman(P("HTTP_USER_AGENT")) ){
878 g.perm.History = 1;
879 }
880 }
881
882 /*
883 ** Memory of settings
884 */
885
+18
--- src/setup.c
+++ src/setup.c
@@ -864,10 +864,17 @@
864864
"remote_user_ok", "remote_user_ok", 0);
865865
@ <p>When enabled, if the REMOTE_USER environment variable is set to the
866866
@ login name of a valid user and no other login credentials are available,
867867
@ then the REMOTE_USER is accepted as an authenticated user.
868868
@ </p>
869
+ @
870
+ @ <hr />
871
+ entry_attribute("IP address turns used in login cookie", 3, "ip-prefix-terms", "ipt",
872
+ "2");
873
+ @ <p>The number of octets of of the IP address used in the login cookie. Set to
874
+ @ zero to omit the IP address from the login cookie. A value of 2 is recommended.
875
+ @ </p>
869876
@
870877
@ <hr />
871878
entry_attribute("Login expiration time", 6, "cookie-expire", "cex", "8766");
872879
@ <p>The number of hours for which a login is valid. This must be a
873880
@ positive number. The default is 8760 hours which is approximately equal
@@ -879,10 +886,21 @@
879886
@ <p>Fossil tries to limit out-bound sync, clone, and pull packets
880887
@ to this many bytes, uncompressed. If the client requires more data
881888
@ than this, then the client will issue multiple HTTP requests.
882889
@ Values below 1 million are not recommended. 5 million is a
883890
@ reasonable number.</p>
891
+
892
+ @ <hr />
893
+ onoff_attribute("Enable hyperlinks for \"nobody\" based on User-Agent",
894
+ "auto-enable-hyperlinks", "autohyperlink", 1);
895
+ @ <p>Enable hyperlinks (the equivalent of the "h" permission) for all users
896
+ @ including user "nobody", as long as the User-Agent string in the HTTP header
897
+ @ indicates that the request is coming from an actual human being and not a
898
+ @ a robot or script. Note: Bots can specify whatever User-Agent string they
899
+ @ that want. So a bot that wants to impersonate a human can easily do so.
900
+ @ Hence, this technique does not necessarily exclude malicious bots.
901
+ @ </p>
884902
885903
@ <hr />
886904
onoff_attribute("Allow users to register themselves",
887905
"self-register", "selfregister", 0);
888906
@ <p>Allow users to register themselves through the HTTP UI.
889907
--- src/setup.c
+++ src/setup.c
@@ -864,10 +864,17 @@
864 "remote_user_ok", "remote_user_ok", 0);
865 @ <p>When enabled, if the REMOTE_USER environment variable is set to the
866 @ login name of a valid user and no other login credentials are available,
867 @ then the REMOTE_USER is accepted as an authenticated user.
868 @ </p>
 
 
 
 
 
 
 
869 @
870 @ <hr />
871 entry_attribute("Login expiration time", 6, "cookie-expire", "cex", "8766");
872 @ <p>The number of hours for which a login is valid. This must be a
873 @ positive number. The default is 8760 hours which is approximately equal
@@ -879,10 +886,21 @@
879 @ <p>Fossil tries to limit out-bound sync, clone, and pull packets
880 @ to this many bytes, uncompressed. If the client requires more data
881 @ than this, then the client will issue multiple HTTP requests.
882 @ Values below 1 million are not recommended. 5 million is a
883 @ reasonable number.</p>
 
 
 
 
 
 
 
 
 
 
 
884
885 @ <hr />
886 onoff_attribute("Allow users to register themselves",
887 "self-register", "selfregister", 0);
888 @ <p>Allow users to register themselves through the HTTP UI.
889
--- src/setup.c
+++ src/setup.c
@@ -864,10 +864,17 @@
864 "remote_user_ok", "remote_user_ok", 0);
865 @ <p>When enabled, if the REMOTE_USER environment variable is set to the
866 @ login name of a valid user and no other login credentials are available,
867 @ then the REMOTE_USER is accepted as an authenticated user.
868 @ </p>
869 @
870 @ <hr />
871 entry_attribute("IP address turns used in login cookie", 3, "ip-prefix-terms", "ipt",
872 "2");
873 @ <p>The number of octets of of the IP address used in the login cookie. Set to
874 @ zero to omit the IP address from the login cookie. A value of 2 is recommended.
875 @ </p>
876 @
877 @ <hr />
878 entry_attribute("Login expiration time", 6, "cookie-expire", "cex", "8766");
879 @ <p>The number of hours for which a login is valid. This must be a
880 @ positive number. The default is 8760 hours which is approximately equal
@@ -879,10 +886,21 @@
886 @ <p>Fossil tries to limit out-bound sync, clone, and pull packets
887 @ to this many bytes, uncompressed. If the client requires more data
888 @ than this, then the client will issue multiple HTTP requests.
889 @ Values below 1 million are not recommended. 5 million is a
890 @ reasonable number.</p>
891
892 @ <hr />
893 onoff_attribute("Enable hyperlinks for \"nobody\" based on User-Agent",
894 "auto-enable-hyperlinks", "autohyperlink", 1);
895 @ <p>Enable hyperlinks (the equivalent of the "h" permission) for all users
896 @ including user "nobody", as long as the User-Agent string in the HTTP header
897 @ indicates that the request is coming from an actual human being and not a
898 @ a robot or script. Note: Bots can specify whatever User-Agent string they
899 @ that want. So a bot that wants to impersonate a human can easily do so.
900 @ Hence, this technique does not necessarily exclude malicious bots.
901 @ </p>
902
903 @ <hr />
904 onoff_attribute("Allow users to register themselves",
905 "self-register", "selfregister", 0);
906 @ <p>Allow users to register themselves through the HTTP UI.
907

Keyboard Shortcuts

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