Fossil SCM

Add the /phantoms webpage that lists public phantom artifacts. Check the number of public phantom artifacts and puts a warning if the number is non-zero on the Security Audit page.

drh 2020-04-14 13:32 trunk
Commit 83db244395090d8365b64c12e7b3a4d8896eb3dba76ef77042f37344c2b07f25
+64
--- src/name.c
+++ src/name.c
@@ -1325,10 +1325,74 @@
13251325
}
13261326
}else{
13271327
@ <td>&nbsp;
13281328
}
13291329
@ </tr>
1330
+ }
1331
+ @ </table>
1332
+ db_finalize(&q);
1333
+ style_footer();
1334
+}
1335
+
1336
+/*
1337
+** WEBPAGE: phantoms
1338
+**
1339
+** Show a list of all "phantom" artifacts that are not marked as "private".
1340
+**
1341
+** A "phantom" artifact is an artifact whose hash named appears in some
1342
+** artifact but whose content is unknown. For example, if a manifest
1343
+** references a particular SHA3 hash of a file, but that SHA3 hash is
1344
+** not on the shunning list and is not in the database, then the file
1345
+** is a phantom. We know it exists, but we do not know its content.
1346
+**
1347
+** Whenever a sync occurs, both each party looks at its phantom list
1348
+** and for every phantom that is not also marked private, it asks the
1349
+** other party to send it the content. This mechanism helps keep all
1350
+** repositories synced up.
1351
+**
1352
+** This page is similar to the /bloblist page in that it lists artifacts.
1353
+** But this page is a special case in that it only shows phantoms that
1354
+** are not private. In other words, this page shows all phantoms that
1355
+** generate extra network traffic on every sync request.
1356
+*/
1357
+void phantom_list_page(void){
1358
+ Stmt q;
1359
+ char *zRange;
1360
+
1361
+ login_check_credentials();
1362
+ if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
1363
+ style_header("Public Phantom Artifacts");
1364
+ if( g.perm.Admin ){
1365
+ style_submenu_element("Artifact Log", "rcvfromlist");
1366
+ style_submenu_element("Artifact List", "bloblist");
1367
+ }
1368
+ if( g.perm.Write ){
1369
+ style_submenu_element("Artifact Stats", "artifact_stats");
1370
+ }
1371
+ zRange = mprintf("IN (SELECT rid FROM phantom EXCEPT"
1372
+ " SELECT rid FROM private)");
1373
+ describe_artifacts(zRange);
1374
+ fossil_free(zRange);
1375
+ db_prepare(&q,
1376
+ "SELECT rid, uuid, summary, ref"
1377
+ " FROM description ORDER BY rid"
1378
+ );
1379
+ @ <table cellpadding="2" cellspacing="0" border="1">
1380
+ @ <tr><th>RID<th>Description<th>Source
1381
+ while( db_step(&q)==SQLITE_ROW ){
1382
+ int rid = db_column_int(&q,0);
1383
+ const char *zUuid = db_column_text(&q, 1);
1384
+ const char *zDesc = db_column_text(&q, 2);
1385
+ const char *zRef = db_column_text(&q,3);
1386
+ @ <tr><td valign="top">%d(rid)</td>
1387
+ @ <td valign="top" align="left">%h(zUuid)<br>%h(zDesc)</td>
1388
+ if( zRef && zRef[0] ){
1389
+ @ <td valign="top">%z(href("%R/info/%!S",zRef))%!S(zRef)</a>
1390
+ }else{
1391
+ @ <td>&nbsp;
1392
+ }
1393
+ @ </tr>
13301394
}
13311395
@ </table>
13321396
db_finalize(&q);
13331397
style_footer();
13341398
}
13351399
--- src/name.c
+++ src/name.c
@@ -1325,10 +1325,74 @@
1325 }
1326 }else{
1327 @ <td>&nbsp;
1328 }
1329 @ </tr>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1330 }
1331 @ </table>
1332 db_finalize(&q);
1333 style_footer();
1334 }
1335
--- src/name.c
+++ src/name.c
@@ -1325,10 +1325,74 @@
1325 }
1326 }else{
1327 @ <td>&nbsp;
1328 }
1329 @ </tr>
1330 }
1331 @ </table>
1332 db_finalize(&q);
1333 style_footer();
1334 }
1335
1336 /*
1337 ** WEBPAGE: phantoms
1338 **
1339 ** Show a list of all "phantom" artifacts that are not marked as "private".
1340 **
1341 ** A "phantom" artifact is an artifact whose hash named appears in some
1342 ** artifact but whose content is unknown. For example, if a manifest
1343 ** references a particular SHA3 hash of a file, but that SHA3 hash is
1344 ** not on the shunning list and is not in the database, then the file
1345 ** is a phantom. We know it exists, but we do not know its content.
1346 **
1347 ** Whenever a sync occurs, both each party looks at its phantom list
1348 ** and for every phantom that is not also marked private, it asks the
1349 ** other party to send it the content. This mechanism helps keep all
1350 ** repositories synced up.
1351 **
1352 ** This page is similar to the /bloblist page in that it lists artifacts.
1353 ** But this page is a special case in that it only shows phantoms that
1354 ** are not private. In other words, this page shows all phantoms that
1355 ** generate extra network traffic on every sync request.
1356 */
1357 void phantom_list_page(void){
1358 Stmt q;
1359 char *zRange;
1360
1361 login_check_credentials();
1362 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
1363 style_header("Public Phantom Artifacts");
1364 if( g.perm.Admin ){
1365 style_submenu_element("Artifact Log", "rcvfromlist");
1366 style_submenu_element("Artifact List", "bloblist");
1367 }
1368 if( g.perm.Write ){
1369 style_submenu_element("Artifact Stats", "artifact_stats");
1370 }
1371 zRange = mprintf("IN (SELECT rid FROM phantom EXCEPT"
1372 " SELECT rid FROM private)");
1373 describe_artifacts(zRange);
1374 fossil_free(zRange);
1375 db_prepare(&q,
1376 "SELECT rid, uuid, summary, ref"
1377 " FROM description ORDER BY rid"
1378 );
1379 @ <table cellpadding="2" cellspacing="0" border="1">
1380 @ <tr><th>RID<th>Description<th>Source
1381 while( db_step(&q)==SQLITE_ROW ){
1382 int rid = db_column_int(&q,0);
1383 const char *zUuid = db_column_text(&q, 1);
1384 const char *zDesc = db_column_text(&q, 2);
1385 const char *zRef = db_column_text(&q,3);
1386 @ <tr><td valign="top">%d(rid)</td>
1387 @ <td valign="top" align="left">%h(zUuid)<br>%h(zDesc)</td>
1388 if( zRef && zRef[0] ){
1389 @ <td valign="top">%z(href("%R/info/%!S",zRef))%!S(zRef)</a>
1390 }else{
1391 @ <td>&nbsp;
1392 }
1393 @ </tr>
1394 }
1395 @ </table>
1396 db_finalize(&q);
1397 style_footer();
1398 }
1399
--- src/security_audit.c
+++ src/security_audit.c
@@ -553,10 +553,28 @@
553553
stats_for_email();
554554
@ </table>
555555
}else{
556556
@ <li><p> Email alerts are disabled
557557
}
558
+
559
+ n = db_int(0,"SELECT count(*) FROM ("
560
+ "SELECT rid FROM phantom EXCEPT SELECT rid FROM private)");
561
+ if( n>0 ){
562
+ @ <li><p>\
563
+ if( n==1 ){
564
+ @ There is 1 public phantom artifact
565
+ }else{
566
+ @ There are %d(n) public phantom artifacts
567
+ }
568
+ @ (<a href="%R/phantoms">details</a>).
569
+ @ Phantom artifacts are artifacts whose hash name is referenced by some
570
+ @ other artifact but whose content is unknown. Some phantoms are marked
571
+ @ private and those are ignored. But public phantoms cause unnecessary
572
+ @ sync traffic and might represent malicious attempts to corrupt the
573
+ @ repository structure.
574
+ @ </p></li>
575
+ }
558576
559577
@ </ol>
560578
style_footer();
561579
}
562580
563581
--- src/security_audit.c
+++ src/security_audit.c
@@ -553,10 +553,28 @@
553 stats_for_email();
554 @ </table>
555 }else{
556 @ <li><p> Email alerts are disabled
557 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
558
559 @ </ol>
560 style_footer();
561 }
562
563
--- src/security_audit.c
+++ src/security_audit.c
@@ -553,10 +553,28 @@
553 stats_for_email();
554 @ </table>
555 }else{
556 @ <li><p> Email alerts are disabled
557 }
558
559 n = db_int(0,"SELECT count(*) FROM ("
560 "SELECT rid FROM phantom EXCEPT SELECT rid FROM private)");
561 if( n>0 ){
562 @ <li><p>\
563 if( n==1 ){
564 @ There is 1 public phantom artifact
565 }else{
566 @ There are %d(n) public phantom artifacts
567 }
568 @ (<a href="%R/phantoms">details</a>).
569 @ Phantom artifacts are artifacts whose hash name is referenced by some
570 @ other artifact but whose content is unknown. Some phantoms are marked
571 @ private and those are ignored. But public phantoms cause unnecessary
572 @ sync traffic and might represent malicious attempts to corrupt the
573 @ repository structure.
574 @ </p></li>
575 }
576
577 @ </ol>
578 style_footer();
579 }
580
581

Keyboard Shortcuts

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