aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorglozow <gloriajzhao@gmail.com>2023-02-27 13:17:33 +0000
committerglozow <gloriajzhao@gmail.com>2023-02-27 13:17:48 +0000
commit873dcc19102f6017dac070fa83e2333f8bf6845b (patch)
treef3bb1af2145a37665328a0bf455904c0667a919d
parentbe2e748f378fc9ed40593a723dd18f2528705956 (diff)
parent14fac808bd6c12bce121011bbf50501960c7326f (diff)
Merge bitcoin/bitcoin#27058: contrib: Improve verify-commits.py to work with maintainers leaving
14fac808bd6c12bce121011bbf50501960c7326f verify-commits: Mention git v2.38.0 requirement (Andrew Chow) bb86887527d817ee2a015863ddf3541dac42080f verify-commits: Skip checks for commits older than trusted roots (Andrew Chow) 5497c1483097a9b582ef78089a2ce1101b7d722e verify-commits: Use merge-tree in clean merge check (Andrew Chow) 76923bfa09397568fb8eb72142468a986fc6f790 verify-commits: Remove all allowed commit exceptions (Andrew Chow) 53b07b2b47aa3d4ca80fac74e432783a1e724df3 verify-commits: Move trusted-keys valid sig check into verify-commits itself (Andrew Chow) Pull request description: Currently the `verify-commits.py` script does not work well with maintainers giving up their commit access. If a key is removed from `trusted-keys`, any commits it signed previously will fail to verify, however keys cannot be kept in the list as it would allow that person to continue to push new commits. Furthermore, the `trusted-keys` used depends on the working tree which `verify-commits.py` itself may be modifying. When the script is run, the `trusted-keys` may be the one that is intended to be used, but the script may change the tree to a different commit with a different `trusted-keys` and use that instead! To resolve these issues, I've updated `verify-commits.py` to load the `trusted-keys` file and check the keys itself rather than delegating that to `gpg.sh` (which previously read in `trusted-keys`). This avoids the issue with the tree changing. I've also updated the script so that it stops modifying the tree. It would do this for the clean merge check where it would checkout each individual commit and attempt to reapply the merges, and then checking out the commit given as a cli arg. `git merge-tree` lets us do basically that but without modifying the tree. It will give us the object id for the resulting tree which we can compare against the object id of the tree in the merge commit in question. This also appears to be quite a bit faster. Lastly I've removed all of the exception commits in `allow-revsig-commits`, `allow-incorrect-sha512-commits`, and `allow-unclean-merge-commits` since all of these predate the commits in `trusted-git-root` and `trusted-sha512-root`. I've also updated the script to skip verification of commits that predate `trusted-git-root`, and skip sha512 verification for those that predate `trusted-sha512-root`. ACKs for top commit: Sjors: ACK 14fac808bd6c12bce121011bbf50501960c7326f glozow: Concept ACK 14fac808bd6c12bce121011bbf50501960c7326f Tree-SHA512: f9b0c6e1f1aecb169cdd6c833b8871b15e31c2374dc589858df0523659b294220d327481cc36dd0f92e9040d868eee6a8a68502f3163e05fa751f9fc2fa8832a
-rw-r--r--contrib/verify-commits/README.md4
-rw-r--r--contrib/verify-commits/allow-incorrect-sha512-commits2
-rw-r--r--contrib/verify-commits/allow-revsig-commits820
-rw-r--r--contrib/verify-commits/allow-unclean-merge-commits4
-rwxr-xr-xcontrib/verify-commits/gpg.sh42
-rwxr-xr-xcontrib/verify-commits/verify-commits.py49
6 files changed, 45 insertions, 876 deletions
diff --git a/contrib/verify-commits/README.md b/contrib/verify-commits/README.md
index b8b15280ba..020890c366 100644
--- a/contrib/verify-commits/README.md
+++ b/contrib/verify-commits/README.md
@@ -27,6 +27,10 @@ Note that the above isn't a good UI/UX yet, and needs significant improvements
to make it more convenient and reduce the chance of errors; pull-reqs
improving this process would be much appreciated.
+Unless `--clean-merge 0` is specified, `verify-commits.py` will attempt to verify that
+each merge commit applies cleanly (with some exceptions). This requires using at least
+git v2.38.0.
+
Configuration files
-------------------
diff --git a/contrib/verify-commits/allow-incorrect-sha512-commits b/contrib/verify-commits/allow-incorrect-sha512-commits
index c572806f26..e69de29bb2 100644
--- a/contrib/verify-commits/allow-incorrect-sha512-commits
+++ b/contrib/verify-commits/allow-incorrect-sha512-commits
@@ -1,2 +0,0 @@
-f8feaa4636260b599294c7285bcf1c8b7737f74e
-8040ae6fc576e9504186f2ae3ff2c8125de1095c
diff --git a/contrib/verify-commits/allow-revsig-commits b/contrib/verify-commits/allow-revsig-commits
index 0c43d9cce5..e69de29bb2 100644
--- a/contrib/verify-commits/allow-revsig-commits
+++ b/contrib/verify-commits/allow-revsig-commits
@@ -1,820 +0,0 @@
-a06ede9a138d0fb86b0de17c42b936d9fe6e2158
-923dc447eaa8e017985b2afbbb12dd1283fbea0e
-71148b8947fe8b4d756822420a7f31c380159425
-6696b4635ceb9b47aaa63244bff9032fa7b08354
-812714fd80e96e28cd288c553c83838cecbfc2d9
-8a445c5651edb9a1f51497055b7ddf4402be9188
-e126d0c12ca66278d9e7b12187c5ff4fc02a7e6c
-3908fc4728059719bed0e1c7b1c8b388c2d4a8da
-8b66bf74e2a349e71eaa183af81fa63eaee76ad2
-05950427d310654774031764a7141a1a4fd9c6e4
-07fd147b9f12e9205afd66a624edce357977d615
-12e31127948fa4bb01c3bddc1b8c85b432f7465b
-8c87f175d335e9d9e93f987d871ae9f05f6a10a7
-46b249e578e8a3dfbe85bc7253a12e82ef4b658b
-a55716abe5662ec74c2f8af93023f1e7cca901fc
-f646275b90b1de93bc62b4c4d045d75ac0b96eee
-c252685aa5867631e9a5ef07ccae7c7c25cae8ff
-a7d55c93385359952d85decd5037843ac70ba3d4
-7dac1e5e9e887f5f6ff146e812a05bd3bf281eae
-2a524b8e8fe69ef487fd8ea1b4f7a03f473ed201
-ce5c1f4acae43477989cdf9a82ed33703919cda2
-2db4cbcc437f51f5dac82cc4de46f383b92e6f11
-7aa700424cbda387536373d8dfec88aee43f950e
-b99a093afed880f23fb279c443cc6ae5e379cc43
-b83264d9c7a8ddb79f64bd9540caddc8632ef31f
-57e337d40e94ba33d8cd265c134d6ef857b32b59
-a1dcf2e1087beaf3981739fd2bb74f35ecad630a
-d38b0d7a6b6056cba26999b702815775e2437d87
-815640ec6af9a38d6a2da4a4400056e2f4105080
-09c4fd157c5b88df2d97fad4826c79b094db90c9
-2efcfa5acfacb958973d9e8125e1d81f102e2dfd
-dc6dee41f7cf2ba93fcd0fea7c157e4b2775d439
-ad826b3df9f763b49f1e3e3d50c4efdd438c7547
-c1a52276848d8caa9a9789dff176408c1aa6b1ed
-3bf06e9bac57b5b5a746677b75e297a7b154bdbd
-72ae6f8cf0224370e8121d6769b21e612ca15d6f
-a143b88dbd4971ecfdd1d39a494489c8f2db0344
-76fec09d878d6dbf214bdb6228d480bd9195db4c
-93566e0c37c5ae104095474fea89f00dcb40f551
-407d9232ef5cb1ebf6cff21f3d13e07ea4158eeb
-9346f8429957e356d21c665bab59fe45bcf1f74e
-6eeac6e30d65f9a972067c1ea8c49978c8e631ac
-dc6b9406bdfab2af8c86cb080cb3e6cf8f2385d8
-9f554e03ebe5701c1b75ff03b3d6152095c0cad3
-05009935f9ac070197113954d680bc2c9150b9b3
-508404de98a8a5435f52916cef8f328e82651961
-ed0cc50afed146c27f6d8129c683c225fb940093
-6429cfa8a70308241c576aeb92ffe3db5203b2ef
-6898213409811b140843c3d89af43328c3b22fad
-5b2ea29cf4fd298346437bb16a54407f8c1f9dca
-e2a1a1ee895149c544d4ae295466611f0cec3094
-e82fb872ff5cc8fd22d43327c1ee3e755f61c562
-19b0f33de0efd9da788e8e4f3fdc2a9e159abdb1
-89de1538ce1f8c00f80e8d11f43e1b77e24d7dea
-de07fdcf77e97b8613091285e4d0a734f5de7492
-01680195f8aa586c55c44767397380def3a23b54
-05e1c85fb687c82ae477c72d4a7e2d6b0c692167
-c072b8fd95cd4fa84f08189a0cd8b173ea2dbb8e
-9a0ed08b40b15ae2b791aa8549b53e69934b4ea7
-53f8f226bd1d627c4a6dec5862a1d4ea5a933e45
-9d0f43b7ca7241d8a018fd35dd3bc01555235ec6
-f12d2b5a8ac397e4bcaefcc19898f8ff5705dea5
-8250de13587ed05ca45df3e12c5dc9bcb1500e2c
-d727f77e390426e9e463336bda08d50c451c7086
-484312bda2d43e3ea60047be076332299463adf8
-c7e05b35ab0a791c7a8e2d863e716fdec6f3f671
-b9c1cd81848da9de1baf9c2f29c19c50e549de13
-8ea7d31e384975019733b5778feabbd9955c79d8
-f798b891bcecea9548eedacae70eeb9906c1ddbf
-ebefe7a00b46579cdd1e033a8c7fd8ce9aa578e4
-ad087638ee4864d6244ec9381ff764bfa6ee5086
-66db2d62d59817320c9182fc18e75a93b76828ea
-7ce9ac5c83b1844a518ef2e12e87aae3cacdfe58
-4286f43025149cf44207c3ad98e4a1f068520ada
-cd0c5135ab2291aaa5410ac919bad3fc87249a4a
-66ed450d771a8fc01c159a8402648ebd1c35eb4c
-a82f03393a32842d49236e8666ee57805ca701f8
-f972b04d63eb8af79ff3cec1dc561ed13dfa6053
-ec45cc5e27668171b55271b0c735194c70e7da41
-715e9fd7454f7a48d7adba7d42f662c20a3e3367
-2e0a99037dcc35bc63ba0d54371bc678af737c8e
-7fa8d758598407f3bf0beb0118dc122ea5340736
-6a22373771edbc3c7513cacb9355f880c73c2cbf
-b89ef131147f71a96152a7b5c4374266cdf539b2
-01d8359983e2f77b5118fede3ffa947072c666c8
-58f0c929a3d70a4bff79cc200f1c186f71ef1675
-950be19727a581970591d8f8138dfe4725750382
-425278d17bd0edf8a3a7cc81e55016f7fd8e7726
-c028c7b7557da2baff7af8840108e8be4db8e0c6
-47a7cfb0aa2498f6801026d258a59f9de48f60b0
-f6b7df3155ddb4cedfbcf5d3eb3383d4614b3a85
-d72098038f3b55a714ed8adb34fab547b15eb0d5
-c49c825bd9f4764536b45df5a684d97173673fc7
-33799afe83eec4200ff140e9bf5eae83701a4d7f
-5c3f8ddcaa1164079105c452429fccf8127b01b6
-1f01443567b03ac75a91c810f1733f5c21b5699d
-b3e42b6d02e8d19658a9135e427ebceab5367779
-69b3a6dd9d9a0adf5506c8b9fde42187356bd4a8
-bafd075c5e6a1088ef0f1aa0b0b224e026a3d3e0
-7daa3adb242d9c8728fdb15c6af6596aaad5502f
-514993554c370f4cf30a109ac28d5d64893dbf0a
-c8d2473e6cb042e7275a10c49d3f6a4a91bf0166
-386f4385ab04b0b2c3d47bddc0dc0f2de7354964
-9f33dba05c01ecc5c56eb1284ab7d64d42f55171
-7466a26cab5d66665991433947964a638f5b957e
-b43aba89e356ff95b706e80d4802f60fc46a569a
-02b7e8319aef2a870264ad4fa2e3bb18664dcc36
-f686002a8eba820a40ac2f34a6e8f57b2b5cc54c
-2b1c50b9352ab1dc40b0f877db23c1fa4048fae3
-2405ce1df043f778b8efb9205009500cbc17313a
-4ad3b3c72c73d61e0a0cab541dca20acf651320d
-4ba3d4f4393d81148422d24d222fe7ed00130194
-8ee5c7b747171e335793c74cd9d2f7491da58164
-872c921c0a208b04bd0713758e52fcab5b7c1684
-00d1680498c5550e7db1f359202d3433a092fafd
-585db41e9ab7a6fb262c8bad7f427cdbdc497188
-18462960c0f13bd07d8f52b61e7d7bc17e991eea
-0630974647dacaf25e7fcb7f9cbb785bb078ede6
-0f58d7f3d62f012f2584f5e781fc73de4763dd9e
-3d16f581538b0974853e820508e8b3093269d2fd
-66e91420ab233cf1dac64504e0dc129019bf8c0d
-d8d9162f5bad39b2720dd2b2da237c6159e4755f
-29fad97c320c892ab6a480c81e2078ec22ab354b
-791c3ea61b4e49fd46a1a71b84ca99ddf69d2ff7
-a312e201ba56742499a5480b5f2115f01505c217
-ce56fdd2e8cdf94fd0ab76d71adbfa755e23ce7d
-480f42630cbd598c04fa59ee0e406f56904ecffb
-6012f1caf744ac9b53383d7d10a8f1b70ca2c0e1
-ded6a2afa549f693dcabb430ce0862f8631360c8
-07090c5339436f856e79a8036d1c85deeb453803
-0e265916d1c6a63e4a3821dab9db597b5ec64b46
-e4ffcacc2187d3419c8ea12b82fb06d82d8751d2
-e117cfe45eee9169409e74a44ef4a866be25bc35
-dcfe218626b05204e9fbc95ba5d95ca0eb72ec9b
-23481fa50301201ef5a60675ef899aa6ce94ca03
-27c59dc502f29cf1d76290556c21e366145e3b2e
-4a62ddd01873d18dbca96c81d756be1020249b45
-a233fb4f1d037e68ff70eef3a9f5b7bf1d631918
-b2089c51cc4af2f7e1c0ec75be9449ee222b1d69
-c997f8808256521397f1c003bb1e9896fee6eaa0
-5dc00f68c49c46a380a98d06233f90528b8e2557
-fe53d5f3636aed064823bc220d828c7ff08d1d52
-935eb8de039dec65669a96a1c3b86f4b03a1b86c
-0277173b1defb63216d40a8d8805ae6d5d563c26
-2a30e67d20f76bbcd9a7d445f616f005316e0a1a
-d32528e733f2711b34dbc41fbb2bb0f153bf7e9a
-4cad91663df381d0dff8526f3b4aa74569dfb626
-1b06ed136f17b526360617a70026aed5ded5746c
-895fbd768f0c89cea3f78acac58b233d4e3a145e
-f0295becbf3ef1fb78095306408789253fe0c114
-8d573198638e52e2dbd9abc609861430f9d2bcc3
-9d9c4185fadaf243bb97c226e2fef16b65299699
-eebe4580bc8d6484d79ecb24dd87412221cf2ea7
-9cf6393a4f82b9c81d3b4b468a17a89db10531a2
-598a9c4e4dcd03c6d80fba005de729a6a3aeba7e
-6970b30c6f1d2be7947295fe18f2390649b17a4b
-f359afcc410432ed5d30001acda0c66741ee8935
-126000ba9e7ff16271be2f4eef3df99ade8d624f
-b5e4b9b5100ec15217d43edb5f4149439f4b20a5
-b987ca4ee495a7fff82f0ac14ef0753bfb7586e2
-b03013396cb2f4bf25746388b3982a2c3616e16b
-9a97f39afaa890caa7987c6bc001b9a66e3e74e8
-cad504bf4c302f7a72e0a0e191f3fdbafda7340f
-45cf8a03cb57b8639a8d47323bde46ba22d9eeaf
-b7450cdbd89a1c862f4d4d8bf093f8a0b5448f9c
-0910cbe4ef31eb95fd76c7c2f820419fe64a3150
-92a810d04b906722c9efe60e3997243c71ff3d4c
-45173fa6fca9537abb0a0554f731d14b9f89c456
-fd4ca17360e6fc0c9bb76bf6b5b07c9102c12728
-ddff3447f29b62d79a33f728791f42fa9436216e
-36a5a4404836da323c755523fbd27563a8e84f94
-c991b304dee368f506cfee27ddaa333f1f82c518
-d38d1a3e75aa97ffa8755ddd431754a6d0942964
-a332a7d5a15214015f9553fdb2bcf80a1a4b8dc0
-604e08c83cf58ca7e7cda2ab284c1ace7bb12977
-18a1bbad98bd4321f15e7921d9aec91661499d90
-8049241e226c16bd07b029c0cb4b62ac40f0c923
-797441ee995aac59f55d59a93ecb55e8ecbe7dbc
-62fdf9b07087b80d2142799bdd2324f61483359d
-f60b4ad57912b78a96af08046a503f7905610a8c
-13e31dd6548d64a5992f439e74bb424bf88aca04
-fbce66a982679b5409a295be5c99a2eef429cabf
-9f2c2dba21855b8cb9b193b1819be73fa4a23a99
-a89221873a3ee2451c73b41bbe2d99d36f439d31
-3d6ad407770e13958e157bf026cae0bfb9254899
-901ba3e3819405306414628306746552b0aa1d28
-7a43fbb959c38e025e558e472ad57de357539894
-0d89fa0877930c6c8a539a656c1009ad8ab6755b
-54aedc013744c86b11157423fa3cffc9a51eef02
-f0c1f8abb0182da557d07372b938f3a0a4bb906f
-4ed818060ecf4a38a02c8cb48f6cbc78d2ee7708
-3bdf242fc68a8d767932c6214455d4d413effbc9
-5e468994fbb349e8eefc996954a31a67a34aaa15
-41aa9c4a801a01eca1fad22a7095372d23dace60
-2adbddb03840ad71e843c6c4a207a13e871cd1d4
-13e352dc53dec0127c5f94a60055d0ca829420dc
-95e14dc81dd30ee0d396ad08dca9a6980d16eee1
-61fb80660f73e5aa5b69302ecc7ac33da206ba5a
-05a761932edd05cf94ffe938908baf058f38632a
-ee92243e66f2df03b3a759a8ffb75dc06f0cea0d
-22cdf93c062eeaa0f8f9d6220f01b67240073dfb
-76b33491596736ca804e3a29bd8398d7a1516ab7
-6e4e98ee8ce2da3cca2e2fd210e9e8dbc9b1c936
-c838283ecdfb9490425bb071b7c22e542de46c7c
-5e3f5e4f25b65b583d3bfefac9e1148035781089
-f7388e93d3dd91a90239aedac4ec58404f103a2e
-0a2f46b0158b6fc7244a585913b0925c0acf707f
-dd561667cb7ccbbfed3134b05a565971ef6f5873
-6f01dcf63873a5e42798635ab4026c9a5f9fa213
-70fec9e36bcd1a3d93df019be084aaf89cecd7d7
-f9b74ef3fc74fd7d2aa94560820341f03cda8e12
-998c3046fab2b52bc9f141cfb588a18c05506a86
-89cc4f905e30b913ca20e4192d538cc5cbe2c38d
-87d90efd69b64f769116956a5db89e536e9e3714
-5aeaa9ccd1568a77e075dbe2bd2435bd60c87c91
-bfb270acfa30713dc8c968bb9ee40cf5a2360359
-1b8c88451b0554502435d3883c528ad0aad1b09b
-57ee73990f1ce29916adfd99f93eae1ccea1a43b
-808c84f89d0edcef9ddaab0b849a382719f6ec9e
-14b860bf64020451ced823b859da8cb912278ab9
-c63364610f4a041df1c1bd81d01b1f6856160749
-92eadc395071876d77f3babddc056b4325bdbabc
-e93fff1463ae906fc986bf98c3b118c82f171546
-9ccafb1d7bdd172a9b963444072a844da379c4f7
-b4a509a3f817121c3df98ddfd96b2769e18a3e5a
-dbc4ae03963014ab4b7957d62ba59dbd8f938c33
-8ddf60db7ad636b6a31b590251c671ded635fa1d
-f199b8a33d9443a258a1f49a1a29674cd9ee9a20
-e542728cde676f218c552d841d0af29b92f9800b
-763231051596b8e3455b839911ad6a3a1f1c3c74
-ff4cd6075b12fb32b9a906deea3ed033e3f9560a
-9c3c9cdae3e20b5bdea91a0631edac5116bbc89f
-93d20a734d2ee873832bed8ca5c05cf8e539c53c
-ef8340d25f7c5dd5682bdecea97ce84cfce1493c
-69c7ecef405d168f658a9cc7996da84c17f61e66
-4ce2f3d0d33346e9f0e96851689ee6550b2a72e3
-44e1fd926cfb0df0fbd8c41de8cd65ed8d5d6e18
-d6d2c8503c4039b682196d83a67dc28359c10c5c
-ae233c4ec3d14a97c6195059f52873cdba2b4755
-0f399a9ff227896265cafab9b2e9fab6cdb9b5b9
-f4ed44ab4a8f9a87ba678d5fd1449fbf636103dc
-7fcd61b2613c211bb042a82a889655178be6a212
-42973f834445d7735738bdba8847812ba3c34d95
-8df48b36ed3201d938b9974ecbee455d7dc2fb84
-96ac26e56627f0c24213fcd3a1cce9fc95f1f661
-cce94c518a46b7b0006f984bbe4d69e8749182d2
-801dd40666d1e6009920ad3ff755c7bb993b2a62
-ce829855cfca103dde55661fa1524e66b139d063
-b148803b181e30213e8a7f3bd89c8239e9dcb866
-c377feaad87f8109f85da6caf62602b30c20effc
-b37cab65c63e051ebc5b491da9bd687581df94df
-16e41844e7d6c5876d2caaeef6010656950c6ec5
-ee50c9e48786dea0d9df2e45805c25565c100fe3
-11dacc6154c42bc6fe3ba94c1823f8a46e4fe81a
-791a0e6ddade27d1b69f4861a6640de60b9553cf
-638e6c59da4fad987c437592174b188510193b2e
-52f8877525d5238f3440e73710507be889d14127
-2a56baf395bf11835d784c4f8634f4525deed6a1
-bc561b4b7d6a3f71649d37d5eb9047c29efa2b13
-31809d6f8514c4a8d5677e947e3f1ebb0db210b9
-a31e9ad4f027955d43c04a05517244647e250161
-777519bd96f68c18150a0f5942f8f97a91937f5e
-4eb1f39d421024d9666cec61deaf96715ffae4c6
-50fae68d416b4b8ec4ca192923dfd5ae9ea42773
-ce665863b137ac4a7470cf006a92aa7694faca71
-81f8c0378b2ab5ea0d7b65635cb529bd3c69127c
-108222b9c323a05cc9339368f10ddd0859f62b43
-28f788e47e58f2b462351d6989348a4e1a241b2b
-d81dccf191a48a6b59c3747d7b4ccbe3535dde40
-a90e6d2bffc422ddcdb771c53aac0bceb970a2c4
-91e49c51f1aecc9e1d75457f4920d52a4b0a133c
-60dd9cc470584960431de425e2a9ffbed0e8034a
-ede386c2193fc31351e193b3a8cf30030d6be62c
-a084767b40c0d3ba8fa8f8d60f1e8d99a9dc3457
-3f726c99f819f97f2ab21b94d34c6b3129cd883a
-77fc469fc78cdd87c29f398d46ac58dbb9ef62c0
-4ae6d0fbef60ccbecf8f23bb482e201b3678f7a3
-8858b6ddd3bce9daa08da6e05de3ca863a399c15
-22e301a3d56dc9e6878380ee92c7d19ca43119d2
-c484ec6c9b85ca4e331e395c564ae232fd0681dd
-a46a671e253528e450bd57645c400bf761da07ab
-655970d9c60ae6850daf452457e14e21047c0e1b
-b6a48914c50631914192aa11b19205436a9c664d
-7db65c363a0cc6ca7cdb04de9a973ab70013baad
-6366941275344dac7e2130b0c972e90117d37ed0
-4fb2586661471a1572c2df2a5a091011d45eb7c4
-d7be7b39fa1021ec4518186afe145ee948e12a94
-85aec87b11ec41295558175c63f1f5a849460fdf
-aeb31756276034dd506fdf97c8aaade0e7e584f5
-ac016e17d20253129a0287cee7e1d06b7ef15966
-bf74d377fb8e20140da6eac1407414928384bcea
-2c811e08db651a4aed6ea0f7c1972d60de6de8ab
-e5d26e47c7a482c072a7fe47bb84c56854734184
-96a63a3e0cefe920819bd42add0041837b1214a1
-e526ca6284b9e13be1b912b80dd73a34e739b539
-ecd21357f16106e541e9c2854ead2a906659b938
-4b5a7ce0c301ad971f383eb60f61bf9b4026efda
-929fd7276c0f0c30b9416f61a6f5f35d763d81e4
-fa8a0639f7b0ce04030b72b4d5be4f0aa36fc5cb
-f1f1605c22a6283bbfd757055fcf2b584a857709
-0c173a15ca1bf20999f74987988985508c9de463
-df0793f324e33066cc746c0cb1d053d35733d626
-2b0179d8a9b75397937126b36114df0dddeab40c
-bf0a08be281dc42241e7f264c2a20515eb4781bb
-3895e25a77363ae8b49358fb793f50fa8b271e2d
-1fc783fc08bc078239537535f174ab8a489772c0
-1d4805ce04645f3203b0cfd3d66ea710e7433eb4
-d3b58704d1d325875fc605580c1c02b825c1bbcc
-ed88e3194c4bc43aeafef929da7b419d03dea1ad
-dd07f47b79628668e29cc0143b21e790100ee445
-65cc7aacfbfc7b747926375280a1d839e88d576b
-080ec5209172ac9605f1434559dbb3c1e012b10a
-416af3edf5b5ab265acf95568f2bc9eabd3d96de
-e0a7801223fd573863939e76cb633f1dcc2d22c4
-4bc853b50fd9127687eb9e4f3b679dd261a4fa96
-c68a9a69278aa194fed96bd9733d32af3690a11e
-c38f540298f0e188df5ed68fd56c623b9ac8331b
-643fa0b22d70e459d7f7ec3d728ae4811dc5158f
-e053e05c130549f43953f1d70e724dc9ce3e1b85
-75e898c094eea533d1dfaf141c6afccc3072c49f
-2805d606bc46bf5589093a1b92d3542c13ce50c2
-32751807c9c06011eb689cba56b401a6302699c0
-30853e16d332816752dafcfca92147c7ffef5b54
-bea5b00cfe95cd37832305c0f93c339a22a7d79d
-c871f323b418fac27bf834843ca26985010df53f
-329fc1dce7a1c372c8b10c2f2f8732b2c60daff0
-1aefc94dd78d6e0c9209cb09fc16f53dedf42108
-8e5725666b519b61fcdc3141da5c6a57c1959909
-a4ca0b042365061020627a8c045cddacea3312ec
-8bd16ee12fc8ef6723e0572c29b979c15b92b4f4
-87abe20fc118721cc5efdbd94a8462468cd1da2b
-4b766fcdd4ca16399075d1e081a321b3b05ce516
-f6241b3e420e19f3f0507cbbc872fe9218916a02
-7ee523604851af62c0a47c07ee023a8710ef32f7
-776ba233e939fe41a74c6b2632b93a0679a32c71
-6a796b2b53fe542e0f340f250f4f20d69efed8d0
-23d78c4dd01bc74ba35db3e3df95280f6f1b2e22
-f4b15e2de97c4f8cdbb40bef4c9d0ab2807974d9
-fff72de5bf8ac7b70208e655f237b80e70e18851
-170bc2c381f86a523de2fc8b71d62ade66303c0d
-314ebdfcb38d4b4c977579f787d5e1a20d068c94
-e9274839bf316b1972d80d28e45759f898edbf86
-75171f099e82e3527d7c3469b15891bd92227ec2
-3c5e6c94caf40395e031fbde44a0cca46fdd76ec
-dc8fc0c73bebbc1c48ac5540026030c9cc00ec23
-492d22f92919d8d9d59568318c26c1e2ac4890cc
-80c3a734298e824f9321c4efdd446086a3baad89
-47535d7c3ec79c5978cdcc03a5351ddbbb22538d
-1b25b6df0f08f7474228c5b6ed13b58682e1e440
-c530c15180631cea95e9c292cf7fabde9dca9db3
-2723bcdce3248417e98e6c43207bef74d34076c1
-ed22eb4a62bd8d5369aaec87d4cbdc03c9f16368
-9111df9673beb6d6616d491a5478f09b5f14d040
-d86bb075bf6d1e78c1e4f3dd38b0ea828ef5ecfe
-50a1cc0f0aef1514b917a5a3f4476967170b429d
-6ce733747e160ca699711f2c47e686284ca9aa07
-b44adf92342ad4f9c343ba29c081a91687932936
-88799ea1b1c08f4bc1a487c9e3c2effd5e1650ae
-080d7c700fc3291560d79fc590e05b8e2bad984f
-12af74b289f8cdc6caf850dc6c802f9936b1e8b3
-8e4f7e72410df3ba430082c7cf385f26fd75b033
-8ac80412867118172dc4172494304e19969e9489
-f2734c2828f69d9cfd535e5eab0592a7674b2b61
-0b9fb682890b8fe10cec54072b809a5efe57d33d
-5b029aaedb5fcf7cadd249607dd28eb3f233ab8c
-79af9fbd8c3c0e54702a9c92b171f134bd4466c8
-c412fd805ddf3282dc2e1f28e30f51ffcb1f1da2
-111849345bb5140f86b48e730ceab4bff45fa2e9
-a0b1e57b20a17177ed5a9a54e4a8aab597a546b4
-ca209230c8e73745cf8cfc79f500c9c46e103306
-a230b0588788dbe1ac84622aea169c577b381241
-dfef6b6af08097f0676a2323085558fbbd3c48c6
-3192e5278abca7c1f3b4a2a7f77a0ce941c73985
-7c7ddd9ead99a8b5033a1a5d4698032c9e2b3a92
-10b930dde8f14e9cb661810e97a33bbf144fc55c
-9225de2cf652fe2bf6e50636824cdb641546f57d
-598ef9c44b3ea2cc142c175f077b493f39f5ba22
-c49355c7170a64bdd7864cc3ba9a64916b67fe7c
-857d1e171e051b254a617f27b39f6a551054cee2
-21833f9456f6ad5bc06321ad6d9590f42ce0195c
-8910b4717e5bb946ee6988f7fe9fd461f53a5935
-5703dff0939f05c7457cebd6fc61d88ab13afe41
-8bfa13b15b84cb372950fb7b25a1080173060b6a
-ac23a7c1f19b3d8c326ffe75c8e13edf285f90fe
-19be26afe3d04783a92d032b55bf3fb1e2ae63cc
-f7ec7cfd38b543ba81ac7bed5b77f9a19739460b
-36afd4db4442c45d4078b1a7ad16a1872b5bee0d
-88c2ae3ed2bb5d367dd408c9255cd8f1e7a36c7d
-a13a417cdcfdfd1f1b3bf997bb6ffe6e69b096b9
-d6064a89ac97dc0d2ce9da3982e1a4e25afaeda8
-7146d96de3e15a80cafbab2af48ff6f65d8e41bb
-5628c70f2a44567695e5331fe2293c5b7f35b629
-7ff4a538a8682cdf02a4bcd6f15499c841001b73
-aa5fa642b0e7ce2ea55e2298886f212f11a8894e
-8efd1c820b9a782d8608d54d924658536178295c
-50a226563cd8d7c0a5e8448e87fede0eb72a8354
-b860915f8b0dae98e57a254d11575ea41f5c5a79
-d304fef3746039183f51b3ac8f4774dcf3a64f59
-53ab12d9318d5d195ccc77028b0e3ae66dc6e1fd
-668de70be039a4f1ffcf20aeae2a22ee71fc55a8
-0fea960ca917b73aff853fe88476174c8a313863
-f89502306dcf6393a2c7b0efbb0fa728fc582137
-ff58b1c3bdff5e5f687f10f9e40ce495ca49674e
-0b96abc35f1a9d46a27eeddd7df418d107c29c57
-b0b57a17306a7e963a4fe463f84e2b150a00a859
-4105cb6fd964ad13099ca83b1fdf3d35f3961f74
-23281a4dc3afc42a001346caec4dbb8193f0bb53
-8daf103fa138f9a184448ebf1c2e03b9dbd96f21
-02e5308c1b9f3771bbe49bc5036215fa2bd66aa9
-a65ced1a66575c652baf5084644b8647f531be8c
-2456a835f0bc7796d9ff71f64837fa6790e2b7cc
-9ec1330b455c1ab2eb6b89f8a2ab885677d4ae8a
-0b738075bd43fbd4410e30a51e0498cbfd2b7513
-98c80e374b84e5a9c2d5c36889a0b1ebed5b814b
-25720fc394e27a951bcad26095fb5a711bfacb8f
-4cfd57d2e38207d78722ce8c9274ba8dd700d1cc
-0fc1c31a878e93d938c67db3f958e82e3c39659f
-df1ab5b4d67b46b5e9e840b1fbe0ff02520831f9
-5bc3b6cede8dabdf3f4f27ddb03723cbb7cde51a
-c2ea1e6561caba3abffce361abc800822b9e0efe
-caa2f106d704ec3ade63498031dd58d34510bc76
-dce853ef76ef90c46d84294225088d595467d08c
-dbc8a8c86ae50059fddb2d6834fa5f0c9bbf9b71
-0f921e6a0492c4e9f037a9ed91f474885032d68c
-041331e1da23e4136fd046ed870cdcc177464176
-e6ba5068f107ac234576e77cedbd748b665369c2
-76fcd9d5034143a5b041766552670d19f926097d
-72bf1b3d0962304850a3ef5fe375db4bff1d0a39
-919db037f1f5cc73cdcaef92dd9cb0e7f5c8dec3
-c36229b0b2e9d4554053f5c9fc451ac29a493b1f
-9e4bb312e6958d2baa309ba670e5eed1523c6f47
-d7ba4a233bd5a6f8fadee681c68a995e23fe36d7
-98514988a3d3e8b7dbf0463884a5c38f5ed5562d
-5412c08c3cf13577566064edd04da021c37b7cbe
-31bcc667863f368157efa1143a78623a5db8f0d1
-7bd1aa566fb4a4fe194f209085649f2c722b0cff
-c4522e71c7e1d8ecfd70112e9375b9d00d6733a8
-e22f409f18881b63a8e747036584a71217f40e6e
-97ec6e5c9098a1240655cfcab05b6cd5eedb6cd1
-bc121b0eb19713ec72002b5be03ba5ac35903a17
-c98f6b3d93a2cc1b49a6db425ea2b661089d0f9e
-0de7fd36de57a68e543b4c1f184fba192c398c73
-e662d281b837c25b2b70525aa8fe8af894339823
-44adf683ad232db8ce0cb89b3e236a1f5944cfb0
-cb2ed300a89ebf9f0654da869ced665ed8b2abe7
-0a6d48d9ed60b0b02177059ab116f8f46d2cbed3
-b42291334651fff46dbfe5947a726f65cb9d7dfe
-e5364991daecb73aca3bb5ac37f2619d7a89211b
-4a2b170c075ce703cbdc82519a48016a9ee3f99c
-924de0bd75a7f75df65d7d15f9d1587a2e794abf
-1253f8692fc3a11be9430685cd405236a68df6c3
-2b799ae9e1e0a540f9a5971ddf27d83254668279
-c9bdf9a75f9fde8cd011e4aa94be4ed4347078a3
-3d69ecb4edeb80003a1a41442e320898a30dbd9c
-f08222e882b18c1f279308636e03beceece2dbf1
-23e03f8d26d7bd03273a5dcbdcfe3905dfb49ffb
-03dd707dc027fbf6f24120213f8eb66571600374
-d0754799698de2c032abcb8198ee5d5401063213
-072116fceb2294b97d1c40f79305f2e3ff71812b
-e66cc1d58e16bf1650dd6479fed64ecaca8c6098
-f137753a2dcd8229f89d1d1ac28039364e5850b4
-61d191fbf953700ba8aeadc9c8cf4c195efbd10c
-76f3c02fb01a6df98fbd8c16ac21d159d4649d37
-6013c73b3312e11b447ed387426749014716f820
-6faffb8a83db3f209a303a4464dbdd597faad5a4
-cc9e8aca5f950c78dcfeff63c441ba993c1fe12f
-8ca69a2a88a77eb06149fa049ab1a7e6de38b321
-2f71490d21796594ca6f55e375558944de9db5a0
-08cc5fd666456cb476467473ed1880c90c92dedb
-e31a43c725ebe641d7c219c3886eee18eebf0bb8
-52b5a8785de760a204b2b0aab19dfaf79c2c3ff0
-483e8e4f4875a1a621ec9e9df2880d3037d95ed7
-1e5799c52535a3fc20e885916f1e7ed33ecc7f46
-a82e5d8220bbc8b5d786bed99b0876f530b9b7cc
-7fe6c5c993706e8395cdaf7977bee793c06f48f3
-2a0836f6d5e7c1d7e97bedb0e0ea33dcaf981f77
-ddc308068d69c6c9aa629ee3c4ce75e1d1cf08b5
-ec139a5621a9c9f03e1988391a3c7c6c5d849776
-c01a6c48b982d625fd9f4f69005878781d3d56fa
-95a983d56dbda457e3bf8766d59bac74c7aa5699
-760741a00833876976389ed7a6b73f36ee5b4c13
-6e5e5abba6f8bbbe61c22795df440dfafcfdc378
-cf2cecb18779ce83de9adebf382dff1c19b12840
-af9b7a9f2f73b1a2f9728106774dd13e8d1cdd8d
-115735d547fdeade822f547eb3e8c8f9961a9b07
-c2c69edf37b5c02aafa01d0407dadbf5ef8751b5
-a072d1a83787e786d074a4b5871b0b961781f7c6
-ed2cd59e258f756b2eaed7909a60956ade6ef7ee
-ae5575ba41c8a782805afb1c08730343cfc22397
-6ff2c8d29f6b5a5c2ce63f0a16f3bb0dbd049451
-a80de15113166354cdf208e3d8b6e25f4511a591
-06bd4f637f15e769f088d9051a5af94bbb0217a3
-6700cc993cc07fb0f5b8b577ff8c4afcf0b18274
-37f9a1f627c0995d89b62923e75cd092600894f9
-8844ef15ded02d5ed86fb95aaf251235fcef2396
-1b87e5b5b184a0a6c683eda23b36393822b57f03
-e2bf830bb6c1bfa038c943dd6f5d92a406bd723f
-423ca302a3ee87000530da3c105f269b8fabece7
-4e14afe42fdd468d5de11df8cc13defdcb8e83f8
-3e90fe6534206412ea22beaa445cf20d28fbe718
-88b77c7da0a672c89e24df37ea6e9085b4e2a05c
-0ad104190465d8d65c2344bbe10dcf3df025d86c
-5c7df7022bcd360e6af00b9458b1a3fd54e1cc9a
-59ad56851a342d2c62f6b38bf15002b23ab439e1
-d8cd7b137fb075616f31d2b43b85fa2e27ea7477
-655937ebcbf681ededf86b1f0f60aac45c73393d
-abdfd2d0e3ebec7dbead89317ee9192189a35809
-e439aeb30c0439001a781c5979aec41e1fc2aa50
-b9b26d9c3615d15669ae0a049c1dede39a9e59a9
-fdf146f3293c487afdc4d6d9f6b64099aa8bd28a
-16e3b175781caacee403a2dc40cd6c70448e12ef
-b30c62d4b954df05bf404cfbeb5b728282201496
-b3f377daaa86cd7755a552fa3adfeb195835f58e
-0a8f519a0626d7cd385114ce610d23215c051b3f
-544f3234384b2f6c290e987ad18576e1b50d7db9
-91482e5bf22d283d32c9f83c8057f10971848107
-e754c6e33194e9ed69ba5350c5139b0423b645fe
-dc1e54206d76e5fa378d28a18ae1fb2bcf714485
-b2863c0685a5c12f829095cbabaf26ccc49e46ec
-b14db5abab405a708f0166293f1ea12222a6bf03
-8010ded6da56842c09b14665343cd189d7e08401
-d387507aeca652a5569825af65243536f2ce26ea
-27bf14f6f3e0fb1f348f13c1b54fc6b67b3bef6e
-f8d470e24606297dab95e30b1d39ff664fbda31d
-b25a4c2284babdf1e8cf0ec3b1402200dd25f33f
-1329ef1f00e4fad83937ddd8721d0292ccfe7808
-9a1ad2c5cbdfa3114d05df57103c34f72e087f26
-1e90862f5d0b5f7dcc18fb018b2bbaa323dcca1d
-ad552a54c56a420be84b47154882c3e4c76f9bdd
-90b1c7e5c50551f39d4983008d1d5ab3b085803e
-d6b2235ca45e072961e25a35e6a159e97c9e556b
-2643fa50869f22672cbc72ac497d9c30234075b8
-01f909828d126d5443bc28758f51781eccdf5848
-f54f3738c8ce839c413d7b6b719be2ff341536ca
-418ae49ee1eac2c9d6cd4ba83c036a41f1afe922
-5a666428b0f11d62af2002bd54a45ff2f79f30cd
-a07e8caa5d5000286604458e6887f57fec7fdcbb
-8b262eb2d80bfa27ae8501078ce47bc1407e9c55
-5df84de583c900e00fef63bedaef32786f205a33
-4ba6da55743a55189164e29e45ac9e73a074d808
-88430cbab4dca36b6a867364cab319cde6a9ebca
-e0f7515f5500968c86e5a9f4912d83d4abc5b2b9
-9b8b1079ddab64ac955766536c38d23dc57bc499
-af20f9b1d485582b8c8aa8294bac4f2c540246d2
-7be9a9a570c1140048f8781ced1111e1d930e517
-2bac3e484114c30548e286972525dd799dbd0a5b
-df529dcc65e8037c5a3a3ad74545be294a770f07
-6acd8700bc0ee1d10207a362c1e07372ba274041
-ffc6e48b2983189dc0ce7de0a038e5329bc07b1b
-252ae7111cbff09a4cbc5caee9e02b6ed3580476
-b3ecb7bab6074377d87c700bf0c5d351e5d3174f
-d9fdac130a5ed1d96fcac6bb87c10bec9d596b17
-a07e8caa5d5000286604458e6887f57fec7fdcbb
-8b262eb2d80bfa27ae8501078ce47bc1407e9c55
-5df84de583c900e00fef63bedaef32786f205a33
-4ba6da55743a55189164e29e45ac9e73a074d808
-5bea05bc1d17aa43cbdf3a3413241f8132790d93
-c17f11f7b43ad3bd9e242c67db1f3679558a0581
-5ea932a51083837cdd27715e10a3a0d5d553af24
-033c78671b91b12d589ebff6c5ede8d94d7500f8
-ef8a634358848847e006c43ce621bc17a612fd1f
-ba216b5fa63e7e6cae847d1e3621f5c54840f898
-26fee4f6bd9aec62c6caa60683ad66574cf16aa6
-6ab0e4cf49549640b903bf5fce0e6035b8116397
-326a5652e0d25fdb60c337ef4f1c98a63e0748f0
-424be03305143cbe5da5d5adb54d73d3dc3747b6
-38c201f47c0bc388a05cdb35d6137150fa90193e
-12ed800ab870e0fc527a84d6e4584b10c8d239f5
-aeed345c9bade5d52a3fbf0a943203f6c82e6344
-c6223b3daab0328ca742b1cc3c15e89e698630bb
-877678710800a4d78afc12519424f232f1a583d3
-6c4fecfaf7beefad0d1c3f8520bf50bb515a0716
-98212745c8acb5cc4e688bbb3979bfd46b25f98a
-b9bceaf1c081a84d9fcc680372614e797b168a9e
-1afc22a7667a7a5c66b4b5d7f50832356dd5ec12
-3255d6347b1f9eccbec3d6d93d4a424087a3b35b
-ec20f01ba0945a3113797ac98a6b3500e24603d4
-75b5643c47c3b382ed97a9f5e2bdc883a0f98709
-fee0d803fb55c8d85b5cd1ff69d799c5ad522e18
-565494619d809655fa94d274bb2202d25553e485
-ad6fce67b9bb6eee864c8431ad3291aebaa2e5d2
-99c7db8731cc77f143b52f544b3fdd93033ed20d
-b4d03be3cac04da8b5d5fa17e29c5220b75d970b
-ef37f2033c4ae104585cd980141262f95d33166e
-5cfdda2503c995cdd563b1a2a29162ac298d173d
-c5904e871479514b2e2e18b4fdbbe468c4e5ec8e
-10b22e3141a603ec891d2cfc7100c29c7409aabe
-afd2fca911c4a5e3a4d1f0993a226d40f250aff4
-505955052e60e0681865f3064e005ca0d3aa90bf
-8fdd23a224ba236874ef662c4ca311b002dbcab3
-1c011ff430106b5f727f2eaa0f7f4883cd2122a3
-ec8a50b8d786a8cd1192e692ab19b46979add582
-f90603ac6d24f5263649675d51233f1fce8b2ecd
-b7d6623c76e1468f2a93db5a3120580e2784d74a
-66270a416edb1610f276124483feceef9cba93ff
-e4fcbf797ed3b472d352ac3794ec82f581209c50
-479afa0f8486146a35f1fb96be1826061ecbcf23
-2a09a3891fde052a585dc019eea9fba26d42445d
-90a002ea647dcea57a2ed4294eab77897168ba1d
-30c21306c17165c3925fea4ac9d1a4763c6d2a99
-b3eb0d6485510f2bdf36d256ab60ce29b8213744
-efbcf2b1d5ff4ee7132eae9c9e203d2b875c545b
-b33ca14f594e2cf2a16ef27778169deb7cc9f4dc
-d636f3943d39ec893dab2d2546f77f3f2607769d
-cafe24f039e117d53288387c2720f44f27deecd0
-de8db47b7ff351f3287c5efb85102ba8836058d6
-d76e84a21416ef77e78138e326d4d249454e79dc
-7a74f88a26cf251ba36b26f604f1ac9940fd9c92
-1ad3d4e1261f4a444d982a1470c257c78233bda3
-8d9f45ea6a5e4220e44d34139438eea75a07530b
-c98ebf1bfb29a8203b5090412afeb333384213cd
-f18bb49547095020a30e81b648075bc7e707515c
-76f268b9bd1b69eb7784c5324abbb67f3e395b97
-e801084decf4542d57cf5ddb95820643766a172a
-be3e042c20e2f3449b7b55d1cab0a80b0c6f00af
-400fdd08cc95f1e85afafd07ddd9c0bed11483ea
-098b01dc58ff555c473ae58c92c34b03a77eda5f
-7cc2c670e3d7cf26454ac8547a94ec2c8ca90b34
-1088b02f0ccd7358d2b7076bb9e122d59d502d02
-f94b7d5bfa911ea7125920589723ee63a3eec9f0
-b4b057a3e0712dd16b50cbcfe7d613e4413ffa1c
-b40ceed98a112f4f0d07351ce07270d9ff2bf796
-4cb8757aae1ae31e5519d81e854f44ed062d9836
-f2f7e97e8cc24cf7a2b7954cb74ecfd0f91a95ad
-ae786098bc58b1ca92f596a698b23aeade9cd2cd
-c33652576ce21694b33a94832378f737dd6959fb
-e317c0d19201ff75fa7afedf93a9d1cd2c560af2
-bee35299716cc72cb7d5bd4daa9fddca05c58378
-318ea50a1c2f612e750a93e36620dd0c4531e9cf
-b6ee855b411ee9bc39f935d0da3298a773a2ed37
-daf3e7def7b9e5db7a32f5a20b5c4e09e3f0dd18
-bc64b5aa0fc543fe8fd3dbaec275f89df44dc409
-3f57c55dba6ef1fda2bdf6fd9abd8ca7eb6828e4
-431a548faaf51c7a5fc89b6e479187a1c0e29805
-e4bbd3d230f22401ba0a0a72c8ed41ee1bd098a0
-c45da32047cac54afc99cf9b8a539389c577ded1
-ab1f1d32469180b3d011e9625d67c86a22b55903
-a550f6e415fd8aec8c45d4704712a408c37ecd18
-c73af5416b66f09cec0eb106f5a10f9bb6ef9cb1
-a077a90da88f12d9f10c8b85840bdb847a98b0a0
-c5e9e428a9198c8c4076f239b5eaa8dc95e7985b
-b7365f0545b1a6862e3277b2b2139ee0d5aee1cf
-4bd0e9b90a39c5c6a016b83882ae44cb4d28f1f8
-7438ceac716fdfe6621728c05e718eaa89dd89aa
-4e3efd47e0d50c6cd1dc81ccc9669a5b2658f495
-5ab6a942764bf6577ae311f2551153dde3d4830c
-b04f42efe31e23e15cc945efe0de906ed2eadb2b
-ceae0eb7e31f9d3495a13a23df7372e5e870b572
-5bf65ec66e5986c9188e3f6234f1c5c0f8dc7f90
-55c9e2d790fa2e137ccd0d91e6cf3e2d0bff4813
-ba29911e21c88f49780c6c87f94ff8ed6e764a9d
-fffff0abb9c71f0af83a7925db3c293b3bb12158
-aaeb315ff0f7956449a92736160795f0140369e3
-0dd34773334c7f4db7b05df30ee61b011795b46d
-2598720d6c1ef15288045599de7e65f8707d09bc
-bc83710fdcc09d8e427e77457df107acc9db1be5
-ddd7a39aa960ee3639ef1e59b2e53852e0862c52
-0808c88d7bd992d5c9ded0009c9563f6177b4035
-a085a554913ae8f4ed83afac830ce6dc39c9cc65
-b1a824dd06aa58618947783edee2dd891b5204dc
-a4e066af8573dcefb11dff120e1c09e8cf7f40c2
-58b9d6cf9e9b801be9c677a3ae121e5d2950ce66
-7377ed778c6d832ecd291e65b2789af7bac2ae2b
-c3a41ad980cc5149de3f9ec8414962c183b1fed9
-5884a47c367f6ff1aff3ae1ef6894881c5a5e0b7
-1d39c9ca0672e7ad4c1f0959f9d58d2fcc7dc46b
-e16f6441044fc2123e0cbdcbd8a5842ec3aae7a0
-6c6cc7989cac79450bf83b932ca82d390a37e17b
-bc28ca3afb7f6656a0bf50038a5e383ee7f9b219
-57a491bee17af88f75c2cea8c109d93b1cdbc9a8
-f8586b25f6a4f1e30a54e58f45dd28aaf580bbc6
-e5df0ba0d97e5f8cfd748f09d6ed77b7bfc45471
-1b0469199bdaedfd452eea718268be7fd50db3c0
-015717e2b873b7a2ce433bd3be2328a782aa5d91
-3b3c66f85959f3393a3a9e87a29004b526f91b93
-874529665c1c326fc86fc0d0d6c3512fab087ab8
-7f2c983e1cfdb58b6f84eabe5ff6a16f143f39aa
-0ea92cad5274f3939f09d6890da31a21b8481282
-489b5876698f9bb2d93b1b1d62d514148b31effd
-faf25b09d9e78f2ff129e25b90f67930d2fc1c4f
-df933596e7e9aa17f7e5cd6e1c850520f5b56f1b
-9e4fbebcc8e497016563e46de4c64fa094edab2d
-1557014378cc5a6234a9244fa60132955206fd27
-c5fbcf5f8d7b36bee54ac80d1027d0dccea2aa75
-cccbc5fe3ea5ae52426203f4485b11071fbe4b6e
-5174a139c92c1238f9700d06e362dc628d81a0a9
-9dae9f5f1e2bf29f58d3f49b0c612063d883b8b3
-e282764e049523439bc8adaadc002a1420122830
-d8ae5044488248d5eb134aa7c0a15c813a2f8715
-06ea2783a2c11e7b171e2809c3211bb3091d894d
-00ce8543f16f4357926eb6dc701ac6229142be80
-1f63b460a8506675ccacb4647941f07d391735e3
-a100c42a136da5ddfd09aa442543ec2190f24faf
-636991d0c0f969968c790d490c82c1d2fa4e8047
-dd52f79a73eca18301db1569d517197160018dbb
-e157b98640c7cfb94cae7e0faca3bcffc2dde990
-ad9e5eaf77bf7e19a926a43407c88386a8a1e58f
-c5e67be03bb06a5d7885c55db1f016fbf2333fe3
-48eec32347494da781f26478fa488b28336afbd2
-c324b07a541a04698954ece94e5879ae7131c1c7
-4901631dac6a883c6ddd0d4e5e3edd08b10d7609
-cacbdbaa95317b45cf2100702bca92410fb43b9a
-b4f686952a60bbadc7ed2250651d0d6af0959f4d
-90e49c1ececd6296c6ec6109cea525a208c0626e
-700808754884919916a5518e7ecfdabadef956d8
-0cd1a2eff9e0020ec1052a931f3863794d1a95d9
-51527ec1ec4264f7e24ef548bb049db07a89fc7f
-ed4eeafbb6e2e73ff9fb9c03bd66bbb049b8aacd
-d4475ea7ae70ad1a1f9374b88c68f01590a88d54
-5e1aacab576b8d8918da129097a9ac0816b6ead2
-fe6a299fc0020cd62156d4b7dd9c8dac358c69c5
-0047d9b89b9fa6be660c363961cf0af72fa62ecf
-037c5e511fe2185d244049cae25a98f99b878787
-8730bd3fc87c8a7d44347267e1ff3c7a8674201b
-47b8256da872722953693c4037d1b9e07caadcb1
-85aea18ae660b5edf7b6c1415f033cfcb15307f9
-132d5f8c2f2397a4600a42203f413dafdb6bcc37
-23ebd7a8027f12e722834d214113892fe8561fe1
-a19f641a80cb2841ca9f593e9be589dbc4b4ae7c
-1e7db37e76c510d373c4404eea2b97508b367aca
-16fa967d3cca66eef0f17b41fd8aaee6a1420fbc
-9eedbe98c86ff2a9214c24c37f6524ce67fd129b
-0342ae1d395ca82614f6d3b8fabb6a44403baf2a
-777b89b3008e53374eb13fdee70db315cd61a703
-8b686776ef5cbd6ef9d5281c3136eded25ea35a4
-c90b42bcdb594638c5759ef5ef0773314d0a1379
-7134327be5c1bdcef7919ed735049a6bbfc457ec
-e88a52e9a2fda971d34425bb80e42ad2d6623d68
-173c79626867e9f89d49be7dcbb0c2042c480553
-2513499348fa955d0e4b0970b08ba9e715e6316e
-43bb10661360d9f35d921d493a1f94ac95df00e2
-6f55ab57cbfa414d57a8e9fb9a47f9bcd8c836d7
-6300b9556ec927a61371053fafe1a4045f5afb00
-f8b2e9bcfc76fede05f5e12f7b15f0d9c9d0add5
-b297b945f7610772434817181ad12067b2832565
-57a73d71a36ce212977607d3e94de6ef55521bfc
-5fdf37e14bb3b66264a7e6868250c2084ac39054
-3059d4dd72af73b654077d9f72019c47edd47674
-333a41882c5ccd5f0c7f884f97d25449bdeec07b
-7da4f65a00a8d96da2119de613ed7fbee2a28a0d
-e14f0fa6a346afecbb1d5470aef5226a8cc33e57
-cf0a8b9c4870cc88254a757286140d9632e7b70c
-b69fd5eaa99f84b62a49d7c7f48d8cee1227592a
-1e3ed01faa77215a7c36308237280aaa58895532
-6c9bc14a3f2cfa50144607c820ebab5288f9571c
-8e3c266a4f02093d57d563f32ba73d3ab4b5f208
-decde9bba6f9d3671bdf0af4fe6ff4bf28992d1d
-9b7eb584ade2ce73dbfcda080935172c3857b758
-3bbc46ddafb61f68785c7e581817db952f99d93a
-bbb83f0b2b2671980c06453fd243b1f2801a1cc4
-6c9460edaeb6c89692b71f51be7b7ee386f4f5c4
-b3072799248fae8fc16f910b642edb9c5acf8bac
-696d39410fc3372d120a6e89695c1543ac2fc052
-c5c4fb31828107a5ded88627632e19e05b2c7e83
-9ce1c506a3a5d20b1bf254235bfae48af592d86c
-fe66dad8a779ed928b1c2fc0c3accf594b042877
-f421de5be611f874a027392d5fee7e113dce4f54
-d492dc1cdaabdc52b0766bf4cba4bd73178325d0
-6348bc61b533705a229f2c2ddcff2bdd98849d07
-83b26cb97cb46516aa4fdee3bcbfa751d28c1233
-afac75f140a3e7d89877f03420e1bc64a8d8c6cd
-171f6f2699dc27e77843318be2fefdfcd9e589fb
-50c806f001d66e20f314777b9fa7fefa01dc6893
-bdbabc50ba6c87ded97ea2bbacd3605c59cd12d0
-9e32adbb5c543885b2c01a984bf1e4b80e8cec16
-7c08d81e119570792648fe95bbacddbb1d5f9ae2
-65e9ca22785f4a799cbcff6d95cbe1ce4b4a6bd2
-2948d6dea098bf722828b969838668f833c2cb00
-deb847b75710d600e5b0d3d5c77fa5166d80808a
-05e5af5a6c884d2ade3d7acc766ad5380cb85b64
-cba41db327a241f992f9329b214d9070888255b8
-f6d335e82822ed8f2da56c1bcaddf7f99acd4997
-30308cc380a8176a5ec0e0bd2beed8b9c482ccf7
-8b6cd42c6226dea28c182a48a214d1c091b9b5bb
-267917f5632a99bb51fc3fe516d8308e79d31ed1
-ba11eb354b9f3420ebb8608227062fb639a07496
-848b11615b67a3c49f76ebbcaa241a322d8014d8
-25290071c434638e2719a99784572deef44542ad
-159f89c118645c0f9e23e453f01cede84abac795
-37637bea3a9a48c0d52d68d3f78f154f8249a009
-0a76bf848c72211f986a6cc5b1c13de820b861dd
-358fe779cbb2681666ae5ab23a19662db21a2c46
-c44e734dca64a15fae92255a5d848c04adaad2fa
-8add59d77dd621be57059229f378822e4b707318
-922c49a1389531d9fba30168257c466bd413f625
-df0825046acc7cb496c47666e36af18118beb030
-c23bf06492dddacfc0eece3d4dd12cce81496dd0
-3eec29ed3aa1c8eb293a7a7a6be356fc014f8813
-a7e80449c0811b361cdaea39b6bab78ca5fbf668
-5e8e0b3d7f6055e326bda61e60712b530e8920f0
-a5edd191be93aff8f9c0f60f04e711e2e78ecc77
-515200298b555845696a07ae2bc0a84a5dd02ae4
-e8a3882e20f0ffeeb9b3964c2c09d8aa5eb53fd4
-c545a7aeb1d559377933c7b2e6edc2d4a37b33fb
-df669230cf2001dd869e897bb4f2d9c46f9accd9
-56a0fbf8365343d73cdff2b0a0e16542294d7577
-196b4599201dbce3e0317e9b98753fa6a244b82d
-cf5bb048e80d4cde8828787b266b7f5f2e3b6d7b
-b94d0c7af11bd91dad4f180ce2a2ffa09e4b5668
-792d0d8d512cf8ddca200317b74ce550c1a1a428
-767ee2e3a1082468b4e2248bac3ef8bd54bb2ddb
-31db3dd874dfbba88616c96a5767e2c9861d9a7a
-018fd9620293582f0ce43d344ac3110e19c4dedc
-801aaac2b39564aa14009785146ba26d2506fb53
-121d47afe3e67ff7f94d26e08a39573dccf652aa
-af7fba3af788e91a460582351d40f8f5e2118760
-8f1c28a609b203e0d0a844d9cc5ada9eb9160a5e
-8319c4e906e6df5f2048e7c048942fde285a93a2
-66be456d93a66526322b7f36fd734a8dbd5e5524
-c006ab29ceec9274dc85a0de7f7d0502021a4b87
-1220af5e6d1072ea306f6ecaaa7effe3d386c379
-14ba286556faad794f288ef38493c540382897cb
-784a21d35466736a7a372364498ed94482a12a2a
-4ad59042b359f473d5888ecee0c9288dcf98f1c9
-fee16b15fa3425871670239c25d4e61ae961e0c5
-216f4ca9e7ccb1f0fcb9bab0f9940992a87ae55f
-2d0bdb2089644f5904629413423cdc897911b081
-50c502f54abd9eb15c8ddca013f0fdfae3d132a9
-c840ab0231bc29057172179f005001c9ab299554
-aab5e48d422d396aec09bd6389de68613b19def5
diff --git a/contrib/verify-commits/allow-unclean-merge-commits b/contrib/verify-commits/allow-unclean-merge-commits
index 7aab274b9a..e69de29bb2 100644
--- a/contrib/verify-commits/allow-unclean-merge-commits
+++ b/contrib/verify-commits/allow-unclean-merge-commits
@@ -1,4 +0,0 @@
-6052d509105790a26b3ad5df43dd61e7f1b24a12
-3798e5de334c3deb5f71302b782f6b8fbd5087f1
-326ffed09bfcc209a2efd6a2ebc69edf6bd200b5
-97d83739db0631be5d4ba86af3616014652c00ec
diff --git a/contrib/verify-commits/gpg.sh b/contrib/verify-commits/gpg.sh
index db5bfce208..cfd68e45b8 100755
--- a/contrib/verify-commits/gpg.sh
+++ b/contrib/verify-commits/gpg.sh
@@ -5,12 +5,9 @@
export LC_ALL=C
INPUT=$(cat /dev/stdin)
-VALID=false
-REVSIG=false
-IFS='
-'
if [ "$BITCOIN_VERIFY_COMMITS_ALLOW_SHA1" = 1 ]; then
- GPG_RES="$(printf '%s\n' "$INPUT" | gpg --trust-model always "$@" 2>/dev/null)"
+ printf '%s\n' "$INPUT" | gpg --trust-model always "$@" 2>/dev/null
+ exit $?
else
# Note how we've disabled SHA1 with the --weak-digest option, disabling
# signatures - including selfsigs - that use SHA1. While you might think that
@@ -20,12 +17,12 @@ else
# an attacker could construct a pull-req that results in a commit object that
# they've created a collision for. Not the most likely attack, but preventing
# it is pretty easy so we do so as a "belt-and-suspenders" measure.
- GPG_RES=""
for LINE in $(gpg --version); do
case "$LINE" in
"gpg (GnuPG) 1.4.1"*|"gpg (GnuPG) 2.0."*)
echo "Please upgrade to at least gpg 2.1.10 to check for weak signatures" > /dev/stderr
- GPG_RES="$(printf '%s\n' "$INPUT" | gpg --trust-model always "$@" 2>/dev/null)"
+ printf '%s\n' "$INPUT" | gpg --trust-model always "$@" 2>/dev/null
+ exit $?
;;
# We assume if you're running 2.1+, you're probably running 2.1.10+
# gpg will fail otherwise
@@ -33,33 +30,6 @@ else
# gpg will fail otherwise
esac
done
- [ "$GPG_RES" = "" ] && GPG_RES="$(printf '%s\n' "$INPUT" | gpg --trust-model always --weak-digest sha1 "$@" 2>/dev/null)"
-fi
-for LINE in $GPG_RES; do
- case "$LINE" in
- "[GNUPG:] VALIDSIG "*)
- while read KEY; do
- [ "${LINE#?GNUPG:? VALIDSIG * * * * * * * * * }" = "$KEY" ] && VALID=true
- done < ./contrib/verify-commits/trusted-keys
- ;;
- "[GNUPG:] REVKEYSIG "*)
- [ "$BITCOIN_VERIFY_COMMITS_ALLOW_REVSIG" != 1 ] && exit 1
- REVSIG=true
- GOODREVSIG="[GNUPG:] GOODSIG ${LINE#* * *}"
- ;;
- "[GNUPG:] EXPKEYSIG "*)
- [ "$BITCOIN_VERIFY_COMMITS_ALLOW_REVSIG" != 1 ] && exit 1
- REVSIG=true
- GOODREVSIG="[GNUPG:] GOODSIG ${LINE#* * *}"
- ;;
- esac
-done
-if ! $VALID; then
- exit 1
-fi
-if $VALID && $REVSIG; then
- printf '%s\n' "$INPUT" | gpg --trust-model always "$@" 2>/dev/null | grep "^\[GNUPG:\] \(NEWSIG\|SIG_ID\|VALIDSIG\)"
- echo "$GOODREVSIG"
-else
- printf '%s\n' "$INPUT" | gpg --trust-model always "$@" 2>/dev/null
+ printf '%s\n' "$INPUT" | gpg --trust-model always --weak-digest sha1 "$@" 2>/dev/null
+ exit $?
fi
diff --git a/contrib/verify-commits/verify-commits.py b/contrib/verify-commits/verify-commits.py
index 3825caf5de..f301964280 100755
--- a/contrib/verify-commits/verify-commits.py
+++ b/contrib/verify-commits/verify-commits.py
@@ -92,8 +92,10 @@ def main():
unclean_merge_allowed = f.read().splitlines()
with open(dirname + "/allow-incorrect-sha512-commits", "r", encoding="utf8") as f:
incorrect_sha512_allowed = f.read().splitlines()
+ with open(dirname + "/trusted-keys", "r", encoding="utf8") as f:
+ trusted_keys = f.read().splitlines()
- # Set commit and branch and set variables
+ # Set commit and variables
current_commit = args.commit
if ' ' in current_commit:
print("Commit must not contain spaces", file=sys.stderr)
@@ -102,7 +104,6 @@ def main():
no_sha1 = True
prev_commit = ""
initial_commit = current_commit
- branch = subprocess.check_output([GIT, 'show', '-s', '--format=%H', initial_commit]).decode('utf8').splitlines()[0]
# Iterate through commits
while True:
@@ -113,17 +114,41 @@ def main():
if current_commit == verified_root:
print('There is a valid path from "{}" to {} where all commits are signed!'.format(initial_commit, verified_root))
sys.exit(0)
- if current_commit == verified_sha512_root:
- if verify_tree:
+ else:
+ # Make sure this commit isn't older than trusted roots
+ check_root_older_res = subprocess.run([GIT, "merge-base", "--is-ancestor", verified_root, current_commit])
+ if check_root_older_res.returncode != 0:
+ print(f"\"{current_commit}\" predates the trusted root, stopping!")
+ sys.exit(0)
+
+ if verify_tree:
+ if current_commit == verified_sha512_root:
print("All Tree-SHA512s matched up to {}".format(verified_sha512_root), file=sys.stderr)
- verify_tree = False
- no_sha1 = False
+ verify_tree = False
+ no_sha1 = False
+ else:
+ # Skip the tree check if we are older than the trusted root
+ check_root_older_res = subprocess.run([GIT, "merge-base", "--is-ancestor", verified_sha512_root, current_commit])
+ if check_root_older_res.returncode != 0:
+ print(f"\"{current_commit}\" predates the trusted SHA512 root, disabling tree verification.")
+ verify_tree = False
+ no_sha1 = False
+
os.environ['BITCOIN_VERIFY_COMMITS_ALLOW_SHA1'] = "0" if no_sha1 else "1"
- os.environ['BITCOIN_VERIFY_COMMITS_ALLOW_REVSIG'] = "1" if current_commit in revsig_allowed else "0"
+ allow_revsig = current_commit in revsig_allowed
# Check that the commit (and parents) was signed with a trusted key
- if subprocess.call([GIT, '-c', 'gpg.program={}/gpg.sh'.format(dirname), 'verify-commit', current_commit], stdout=subprocess.DEVNULL):
+ valid_sig = False
+ verify_res = subprocess.run([GIT, '-c', 'gpg.program={}/gpg.sh'.format(dirname), 'verify-commit', "--raw", current_commit], capture_output=True)
+ for line in verify_res.stderr.decode().splitlines():
+ if line.startswith("[GNUPG:] VALIDSIG "):
+ key = line.split(" ")[-1]
+ valid_sig = key in trusted_keys
+ elif (line.startswith("[GNUPG:] REVKEYSIG ") or line.startswith("[GNUPG:] EXPKEYSIG ")) and not allow_revsig:
+ valid_sig = False
+ break
+ if not valid_sig:
if prev_commit != "":
print("No parent of {} was signed with a trusted key!".format(prev_commit), file=sys.stderr)
print("Parents are:", file=sys.stderr)
@@ -153,15 +178,11 @@ def main():
allow_unclean = current_commit in unclean_merge_allowed
if len(parents) == 2 and check_merge and not allow_unclean:
current_tree = subprocess.check_output([GIT, 'show', '--format=%T', current_commit]).decode('utf8').splitlines()[0]
- subprocess.call([GIT, 'checkout', '--force', '--quiet', parents[0]])
- subprocess.call([GIT, 'merge', '--no-ff', '--quiet', '--no-gpg-sign', parents[1]], stdout=subprocess.DEVNULL)
- recreated_tree = subprocess.check_output([GIT, 'show', '--format=format:%T', 'HEAD']).decode('utf8').splitlines()[0]
+ recreated_tree = subprocess.check_output([GIT, "merge-tree", parents[0], parents[1]]).decode('utf8').splitlines()[0]
if current_tree != recreated_tree:
print("Merge commit {} is not clean".format(current_commit), file=sys.stderr)
- subprocess.call([GIT, 'diff', current_commit])
- subprocess.call([GIT, 'checkout', '--force', '--quiet', branch])
+ subprocess.call([GIT, 'diff', recreated_tree, current_tree])
sys.exit(1)
- subprocess.call([GIT, 'checkout', '--force', '--quiet', branch])
prev_commit = current_commit
current_commit = parents[0]