Fossil SCM

Verify the repository fingerprint whenever a repository is opened from a checkout database. For now, abort with an error if the fingerprint is incorrect. To do: have Fossil automatically adjust RIDs in the checkout database if the fingerprint is incorrect.

drh 2019-01-11 03:31 repo-fingerprint
Commit 6036bc621e10c14a0fa3ef47f79b875512b7f98a84aafc6f349717b728bf8378
1 file changed +52 -2
+52 -2
--- src/db.c
+++ src/db.c
@@ -1655,10 +1655,29 @@
16551655
16561656
/* Make a change to the CHECK constraint on the BLOB table for
16571657
** version 2.0 and later.
16581658
*/
16591659
rebuild_schema_update_2_0(); /* Do the Fossil-2.0 schema updates */
1660
+
1661
+ /* If the checkout database was opened first, then check to make
1662
+ ** sure that the repository database that was just opened has not
1663
+ ** be replaced by a clone of the same project, with different RID
1664
+ ** values.
1665
+ */
1666
+ if( g.localOpen && !db_fingerprint_ok() ){
1667
+ fossil_print(
1668
+ "Oops. It looks like the repository database file located at\n"
1669
+ " \"%s\"\n", zDbName
1670
+ );
1671
+ fossil_print(
1672
+ "has been swapped with a clone that may have different\n"
1673
+ "integer keys for the various artifacts. As of 2019-01-11,\n"
1674
+ "we are working on enhancing Fossil to be able to deal with\n"
1675
+ "that automatically, but we are not there yet. Sorry.\n\n"
1676
+ );
1677
+ fossil_fatal("bad fingerprint");
1678
+ }
16601679
}
16611680
16621681
/*
16631682
** Return true if there have been any changes to the repository
16641683
** database since it was opened.
@@ -3758,16 +3777,23 @@
37583777
}
37593778
37603779
/*
37613780
** COMMAND: test-fingerprint
37623781
**
3763
-** Usage: %fossil test-fingerprint ?RCVID?
3782
+** Usage: %fossil test-fingerprint ?RCVID? ?--check?
37643783
**
3765
-** Display the repository fingerprint.
3784
+** Display the repository fingerprint. Or if the --check option
3785
+** is provided and this command is run from a checkout, invoke the
3786
+** db_fingerprint_ok() method and print its result.
37663787
*/
37673788
void test_fingerprint(void){
37683789
int rcvid = 0;
3790
+ if( find_option("check",0,0)!=0 ){
3791
+ db_must_be_within_tree();
3792
+ fossil_print("db_fingerprint_ok() => %d\n", db_fingerprint_ok());
3793
+ return;
3794
+ }
37693795
db_find_and_open_repository(OPEN_ANY_SCHEMA,0);
37703796
if( g.argc==3 ){
37713797
rcvid = atoi(g.argv[2]);
37723798
}else if( g.argc!=2 ){
37733799
fossil_fatal("wrong number of arguments");
@@ -3788,5 +3814,29 @@
37883814
fossil_free(z);
37893815
z = db_fingerprint(0);
37903816
db_lset("fingerprint", z);
37913817
fossil_free(z);
37923818
}
3819
+
3820
+/*
3821
+** Verify that the fingerprint recorded in the "fingerprint" entry
3822
+** of the VVAR table matches the fingerprint on the currently
3823
+** connected repository. Return true if the fingerprint is ok, and
3824
+** return false if the fingerprint does not match.
3825
+*/
3826
+int db_fingerprint_ok(void){
3827
+ char *zCkout; /* The fingerprint recorded in the checkout database */
3828
+ char *zRepo; /* The fingerprint of the repository */
3829
+ int rc; /* Result */
3830
+
3831
+ zCkout = db_text(0,"SELECT value FROM localdb.vvar WHERE name='fingerprint'");
3832
+ if( zCkout==0 ){
3833
+ /* This is an older checkout that does not record a fingerprint.
3834
+ ** We have to assume everything is ok */
3835
+ return 2;
3836
+ }
3837
+ zRepo = db_fingerprint(atoi(zCkout));
3838
+ rc = fossil_strcmp(zCkout,zRepo)==0;
3839
+ fossil_free(zCkout);
3840
+ fossil_free(zRepo);
3841
+ return rc;
3842
+}
37933843
--- src/db.c
+++ src/db.c
@@ -1655,10 +1655,29 @@
1655
1656 /* Make a change to the CHECK constraint on the BLOB table for
1657 ** version 2.0 and later.
1658 */
1659 rebuild_schema_update_2_0(); /* Do the Fossil-2.0 schema updates */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1660 }
1661
1662 /*
1663 ** Return true if there have been any changes to the repository
1664 ** database since it was opened.
@@ -3758,16 +3777,23 @@
3758 }
3759
3760 /*
3761 ** COMMAND: test-fingerprint
3762 **
3763 ** Usage: %fossil test-fingerprint ?RCVID?
3764 **
3765 ** Display the repository fingerprint.
 
 
3766 */
3767 void test_fingerprint(void){
3768 int rcvid = 0;
 
 
 
 
 
3769 db_find_and_open_repository(OPEN_ANY_SCHEMA,0);
3770 if( g.argc==3 ){
3771 rcvid = atoi(g.argv[2]);
3772 }else if( g.argc!=2 ){
3773 fossil_fatal("wrong number of arguments");
@@ -3788,5 +3814,29 @@
3788 fossil_free(z);
3789 z = db_fingerprint(0);
3790 db_lset("fingerprint", z);
3791 fossil_free(z);
3792 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3793
--- src/db.c
+++ src/db.c
@@ -1655,10 +1655,29 @@
1655
1656 /* Make a change to the CHECK constraint on the BLOB table for
1657 ** version 2.0 and later.
1658 */
1659 rebuild_schema_update_2_0(); /* Do the Fossil-2.0 schema updates */
1660
1661 /* If the checkout database was opened first, then check to make
1662 ** sure that the repository database that was just opened has not
1663 ** be replaced by a clone of the same project, with different RID
1664 ** values.
1665 */
1666 if( g.localOpen && !db_fingerprint_ok() ){
1667 fossil_print(
1668 "Oops. It looks like the repository database file located at\n"
1669 " \"%s\"\n", zDbName
1670 );
1671 fossil_print(
1672 "has been swapped with a clone that may have different\n"
1673 "integer keys for the various artifacts. As of 2019-01-11,\n"
1674 "we are working on enhancing Fossil to be able to deal with\n"
1675 "that automatically, but we are not there yet. Sorry.\n\n"
1676 );
1677 fossil_fatal("bad fingerprint");
1678 }
1679 }
1680
1681 /*
1682 ** Return true if there have been any changes to the repository
1683 ** database since it was opened.
@@ -3758,16 +3777,23 @@
3777 }
3778
3779 /*
3780 ** COMMAND: test-fingerprint
3781 **
3782 ** Usage: %fossil test-fingerprint ?RCVID? ?--check?
3783 **
3784 ** Display the repository fingerprint. Or if the --check option
3785 ** is provided and this command is run from a checkout, invoke the
3786 ** db_fingerprint_ok() method and print its result.
3787 */
3788 void test_fingerprint(void){
3789 int rcvid = 0;
3790 if( find_option("check",0,0)!=0 ){
3791 db_must_be_within_tree();
3792 fossil_print("db_fingerprint_ok() => %d\n", db_fingerprint_ok());
3793 return;
3794 }
3795 db_find_and_open_repository(OPEN_ANY_SCHEMA,0);
3796 if( g.argc==3 ){
3797 rcvid = atoi(g.argv[2]);
3798 }else if( g.argc!=2 ){
3799 fossil_fatal("wrong number of arguments");
@@ -3788,5 +3814,29 @@
3814 fossil_free(z);
3815 z = db_fingerprint(0);
3816 db_lset("fingerprint", z);
3817 fossil_free(z);
3818 }
3819
3820 /*
3821 ** Verify that the fingerprint recorded in the "fingerprint" entry
3822 ** of the VVAR table matches the fingerprint on the currently
3823 ** connected repository. Return true if the fingerprint is ok, and
3824 ** return false if the fingerprint does not match.
3825 */
3826 int db_fingerprint_ok(void){
3827 char *zCkout; /* The fingerprint recorded in the checkout database */
3828 char *zRepo; /* The fingerprint of the repository */
3829 int rc; /* Result */
3830
3831 zCkout = db_text(0,"SELECT value FROM localdb.vvar WHERE name='fingerprint'");
3832 if( zCkout==0 ){
3833 /* This is an older checkout that does not record a fingerprint.
3834 ** We have to assume everything is ok */
3835 return 2;
3836 }
3837 zRepo = db_fingerprint(atoi(zCkout));
3838 rc = fossil_strcmp(zCkout,zRepo)==0;
3839 fossil_free(zCkout);
3840 fossil_free(zRepo);
3841 return rc;
3842 }
3843

Keyboard Shortcuts

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