| | @@ -1250,10 +1250,98 @@ |
| 1250 | 1250 | } |
| 1251 | 1251 | fossil_free(zDecode); |
| 1252 | 1252 | return uid; |
| 1253 | 1253 | } |
| 1254 | 1254 | |
| 1255 | +/* |
| 1256 | +** SETTING: robot-limiter boolean default=off |
| 1257 | +** If enabled, HTTP requests with one or more query parameters and |
| 1258 | +** without a REFERER string and without a valid login cookie are |
| 1259 | +** assumed to be hostile robots and are redirected to the honeypot. |
| 1260 | +** See also the robot-allow and robot-restrict settings which can |
| 1261 | +** be used to override the value of this setting for specific pages. |
| 1262 | +*/ |
| 1263 | +/* |
| 1264 | +** SETTING: robot-allow width=40 block-text |
| 1265 | +** The VALUE of this setting is a list of GLOB patterns which match |
| 1266 | +** pages for which the robot-limiter is overwritten to false. If this |
| 1267 | +** setting is missing or an empty string, then it is assumed to match |
| 1268 | +** nothing. |
| 1269 | +*/ |
| 1270 | +/* |
| 1271 | +** SETTING: robot-restrict width=40 block-text |
| 1272 | +** The VALUE of this setting is a list of GLOB patterns which match |
| 1273 | +** pages for which the robot-limiter setting should be enforced. |
| 1274 | +** In other words, if the robot-limiter is true and this setting either |
| 1275 | +** does not exist or is empty or matches the current page, then a |
| 1276 | +** redirect to the honeypot is issues. If this setting exists |
| 1277 | +** but does not match the current page, then the robot-limiter setting |
| 1278 | +** is overridden to false. |
| 1279 | +*/ |
| 1280 | + |
| 1281 | +/* |
| 1282 | +** Check to see if the current HTTP request is a complex request that |
| 1283 | +** is coming from a robot and if access should restricted for such robots. |
| 1284 | +** For the purposes of this module, a "complex request" is an HTTP |
| 1285 | +** request with one or more query parameters. |
| 1286 | +** |
| 1287 | +** If this routine determines that robots should be restricted, then |
| 1288 | +** this routine publishes a redirect to the honeypot and exits without |
| 1289 | +** returning to the caller. |
| 1290 | +** |
| 1291 | +** This routine believes that this is a complex request is coming from |
| 1292 | +** a robot if all of the following are true: |
| 1293 | +** |
| 1294 | +** * The user is "nobody". |
| 1295 | +** * The REFERER field of the HTTP header is missing or empty. |
| 1296 | +** * There are one or more query parameters other than "name". |
| 1297 | +** |
| 1298 | +** Robot restrictions are governed by settings. |
| 1299 | +** |
| 1300 | +** robot-limiter The restrictions implemented by this routine only |
| 1301 | +** apply if this setting exists and is true. |
| 1302 | +** |
| 1303 | +** robot-allow If this setting exists and the page of the request |
| 1304 | +** matches the comma-separate GLOB list that is the |
| 1305 | +** value of this setting, then no robot restrictions |
| 1306 | +** are applied. |
| 1307 | +** |
| 1308 | +** robot-restrict If this setting exists then robot restrictions only |
| 1309 | +** apply to pages that match the comma-separated |
| 1310 | +** GLOB list that is the value of this setting. |
| 1311 | +*/ |
| 1312 | +void login_restrict_robot_access(void){ |
| 1313 | + const char *zReferer; |
| 1314 | + const char *zGlob; |
| 1315 | + Glob *pGlob; |
| 1316 | + int go = 1; |
| 1317 | + if( g.zLogin!=0 ) return; |
| 1318 | + zReferer = P("HTTP_REFERER"); |
| 1319 | + if( zReferer && zReferer[0]!=0 ) return; |
| 1320 | + if( !db_get_boolean("robot-limiter",0) ) return; |
| 1321 | + if( cgi_qp_count()<1 ) return; |
| 1322 | + zGlob = db_get("robot-allow",0); |
| 1323 | + if( zGlob && zGlob[0] ){ |
| 1324 | + pGlob = glob_create(zGlob); |
| 1325 | + go = glob_match(pGlob, g.zPath); |
| 1326 | + glob_free(pGlob); |
| 1327 | + if( go ) return; |
| 1328 | + } |
| 1329 | + zGlob = db_get("robot-restrict",0); |
| 1330 | + if( zGlob && zGlob[0] ){ |
| 1331 | + pGlob = glob_create(zGlob); |
| 1332 | + go = glob_match(pGlob, g.zPath); |
| 1333 | + glob_free(pGlob); |
| 1334 | + if( !go ) return; |
| 1335 | + } |
| 1336 | + |
| 1337 | + /* If we reach this point, it means we have a situation where we |
| 1338 | + ** want to restrict the activity of a robot. |
| 1339 | + */ |
| 1340 | + cgi_redirectf("%R/honeypot"); |
| 1341 | +} |
| 1342 | + |
| 1255 | 1343 | /* |
| 1256 | 1344 | ** This routine examines the login cookie to see if it exists and |
| 1257 | 1345 | ** is valid. If the login cookie checks out, it then sets global |
| 1258 | 1346 | ** variables appropriately. |
| 1259 | 1347 | ** |
| | @@ -1413,10 +1501,13 @@ |
| 1413 | 1501 | } |
| 1414 | 1502 | login_create_csrf_secret("none"); |
| 1415 | 1503 | } |
| 1416 | 1504 | |
| 1417 | 1505 | login_set_uid(uid, zCap); |
| 1506 | + |
| 1507 | + /* Maybe restrict access to robots */ |
| 1508 | + login_restrict_robot_access(); |
| 1418 | 1509 | } |
| 1419 | 1510 | |
| 1420 | 1511 | /* |
| 1421 | 1512 | ** Set the current logged in user to be uid. zCap is precomputed |
| 1422 | 1513 | ** (override) capabilities. If zCap==0, then look up the capabilities |
| 1423 | 1514 | |