├── .carnet ├── cookies.d │ └── 1db590b59b0f72a48d4f.cookie ├── initialized ├── owners │ └── 1db590b59b0f72a48d4f.cert ├── seal-ignore.list └── seal │ ├── sealed │ ├── signatures.sha256 │ ├── signatures.sha256.1db590b59b0f72a48d4f.sig │ ├── signatures.sha384 │ └── signatures.sha384.1db590b59b0f72a48d4f.sig ├── .gitignore ├── .private-staging ├── CFkR6DH6kdLDOJ_-G5_Gxw ├── EuhXwWP3KHituntu6prfcumglts1vivVI9bAfw42R3I ├── H7SWYRC11570750265xLKvsAlVfDsOo8C2vXCY2Zcys ├── HpbujYyg0gNduDTF21pLFQ ├── XJmkw3Ts8j_ETYiJEOFiHVtK4iDEj-mjOsTgrg85yzQ ├── ZUj-Y4f_a3rP4LSLK7hvbXOR6HXCjWW9n0-Zke_B5h8 ├── ZaIe1V9LXefXitBMdpmgkg ├── gocryptfs.conf ├── gocryptfs.diriv └── qmUWAVhd-RYoVHC5eVxmOg ├── CONTRIBUTING.en.md ├── NEWS.en.md ├── README.en.md ├── README.md ├── carnet ├── etc ├── assemble.sh └── rust-preview │ ├── Cargo.toml │ └── src │ └── lib.rs ├── gpl-3.0.txt ├── lgpl-3.0.txt ├── src ├── authentication.sh ├── configuration.sh ├── dependencies.sh ├── fingerprint.sh ├── help.sh ├── identity.sh ├── init.sh ├── io.sh ├── main.sh ├── misc │ └── warning-message.sh ├── ownership.sh ├── packaging.sh ├── sandboxing.sh ├── session.sh ├── setup-and-upgrade-scripts.sh ├── trap.sh └── trust.sh └── tests ├── carnet-test.sh ├── cases ├── 00-sanity.sh ├── 0000-ignored.crates-io.sh ├── cargo-1.sh ├── messing-with-validation.sh ├── ownership-1.sh ├── ownership-2.sh ├── ownership-3.sh └── sandbox-1.sh └── common.sh /.carnet/cookies.d/1db590b59b0f72a48d4f.cookie: -------------------------------------------------------------------------------- 1 | 8ede68df4e3dd1681c59802c 2 | -------------------------------------------------------------------------------- /.carnet/initialized: -------------------------------------------------------------------------------- 1 | initialized 2 | -------------------------------------------------------------------------------- /.carnet/owners/1db590b59b0f72a48d4f.cert: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIKCzCCBfOgAwIBAgIUHm8KK+4UUBwo6GKRRXMZE426aKwwDQYJKoZIhvcNAQEM 3 | BQAwgYIxPjA8BgNVBAMMNVN1bGFpbWFuIEEuIEFsSWJyYWhpbSDYs9mE2YrZhdin 4 | 2YYg2KfZhNil2KjYsdin2YfZitmFMRwwGgYJKoZIhvcNAQkBFg1zYW1Aa2EuY29t 5 | Lmt3MRUwEwYDVQQKDAxLdXRvbWV0YSBTUEMxCzAJBgNVBAYTAktXMCAXDTIwMTIy 6 | NDA5MDA1OVoYDzIyOTQxMDA5MDkwMDU5WjCBgjE+MDwGA1UEAww1U3VsYWltYW4g 7 | QS4gQWxJYnJhaGltINiz2YTZitmF2KfZhiDYp9mE2KXYqNix2KfZh9mK2YUxHDAa 8 | BgkqhkiG9w0BCQEWDXNhbUBrYS5jb20ua3cxFTATBgNVBAoMDEt1dG9tZXRhIFNQ 9 | QzELMAkGA1UEBhMCS1cwggQiMA0GCSqGSIb3DQEBAQUAA4IEDwAwggQKAoIEAQCo 10 | sY8n9CDVHmlwuu7hkxViu9DunjrXrVjSaVfDpcRbKqHfgrW3RPvKoMai9OVNtdqp 11 | B2nYnM+eYoqaClLXuNaaNmGXELRhw1v4qSr4RvVDXS6m7YWIANDfyvWfDfCbrvlA 12 | ZIzGikxwPO14uB0VtOzOBGXm8LOOHm6tBNlKmIUEwqMTlXSPQ3nMfVQVR74cMdSh 13 | aVxvFKmcG9cCx3q8blTOPFriYm/FnBdEjrV3KUfCoHQvI0OMMyOcB5VaaZdGL33M 14 | dIX8GtmU4PJjxtb5Y6mbrbburNjCJ+Ycv52t8zDV1T+Ed86Dky+fxePImZXUl3dG 15 | qR6UQBH///vpd895GTzpc9uargjK7cJOsoAM0idFarL+Iv7zNgjeMFnAohfpyhBm 16 | MyxT/vlP6NK2bjIbBAhrmZUsejbe/aOtPh1D2tQOO57d8IW+5yHU+BQF7iPBK3gi 17 | 1sdOMl5QVTvAbBu7h8iezCGxtKN0Ht2vVLe8U0pnZ8xSbEt6psUSyt+oBRfFKLpx 18 | 0p2U4i0QhTfpnIYLnif7XqRFH+GaF2R7lLeKwtHR8QenOuxnsOdKVeNlCKp6XUfT 19 | /hjre+4Kf+w7jvSZl1IsjhOAgNlMrW8W5c6o6gyaJnZcM8MJUZ9jG+EfcCS85bMn 20 | 4o+kwPbbNrV9ha3BeUWCI9Pj5B3Wr9CT2qNWNjK3eVODnT8tH/PKDhkpX9BVLmpk 21 | 7kZBKGDcaaRUeaISnxX0pQ/8c1lcyamlRUcEeoJmUsYO7XFTZ6UEdgfxEuPh3Vxs 22 | 6iscNMCaTiRhmJlIAbwm++H1q7kTJoQiT7Rva0Rbb0M/HBhw+KXrDppoyy9DCHyh 23 | A/SEpFqvgemn/T0iJWIc8XdNERzS/ceI7plE8m0QTmV64ex4iajVAOYm3Wu7zOCF 24 | ltbh5vr6vnWMV9gKzLnASbr7dK8FnwJkhZwtpwHsfm1MKjkStWlZaP0rKlc986Bq 25 | otYL9s002AePzzfq9tcMy6JWXMmHRjVD4qDB9Qj0TotkrgiUQgz9LvJQyWFRGW/s 26 | 0YtCZd4Zq7uh9ac0qrhukVcj1i1TBgi1FowoBqpg/98mBahWB5l7yUvmLgliS81t 27 | Sg8tXgog6SecFWFL+m2wIzknQ2vL9f7VcPNkei/sd3vxFsxtbFLfZM/NAIP7hdDp 28 | gSkBKRP2ITuEBwZ6yDPxuDwOAohbew5dVN2YQc3GShkOTmUl4RjnPq18sVORuFNO 29 | QYmv7VTbGfLoyAhjuppfbk22LgH0oZnHUI1r/Bb/uoiceNJi8LnaM4cTsX/tp6eq 30 | T/dU2o+cSuhB92d2JROSrIvVxFiD8SJ0Ns8kDAVoNxIJdG2qz6z3gjkfjlfWxJWW 31 | DvIDX8usveJLjW57cn7vAgMBAAGjdTBzMB0GA1UdDgQWBBQN1nbSCiytRpByq40F 32 | 7fX103BXxTAfBgNVHSMEGDAWgBQN1nbSCiytRpByq40F7fX103BXxTAPBgNVHRMB 33 | Af8EBTADAQH/MAsGA1UdDwQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzANBgkq 34 | hkiG9w0BAQwFAAOCBAEAdd5kWC0vhhruJMMVW0RneAF0mM+OBrJfQxEsT4vxs2hT 35 | pxkxaLVLHxKb7E4QcEsIYzBhOumL9LNZrA3acBJSEDcXujlPomq9r/bva8XW2kFQ 36 | 4XEMxeBhCNQb2E1nquYmT/XhcBCJOlGO858NYYs5S4oR+2v7ROO8Df2VTDqPK3Yv 37 | AK7EF1L7lTsWtm1NwJq37cuxhHv9qW/LqrYt2lHye/nfPmyn9fzHERwOZ7LPPjy6 38 | zW2Zciaz+siJeutMnX/WZ+/l+kd48zFdohoVHwclHNjkBWsIJZKgBuLnSP/uyK79 39 | PvEhfI32ilCzQ4wqWdq/GirYFTDgumaQ8AaOgwuwbq9gG8apXJ4RV1X3cYcHPxSa 40 | /KGve08IfY1TvPNSXinDo0e9gOvZTq9HrN7Rbe2HLn1irlQc1ZWQbafUFdUDtjqb 41 | c54LG67JO0sTsGfV6Jcf2KLOiHg0GYxjFF+m+4szN3+GOsu/9vl5gFFPfHsf4w21 42 | 9ZxOAOCV+uY8IujFtSGjdR4Si2TfEkvH/6g6Gog4JlM5+zRcwkBbHrJWO5m88LRl 43 | 5NS2qGRA2bFlWAPA3HLDPIYxEyubrEhYscSdZk/VGJcPfGRCRwHiCJ5aLs4tMM+h 44 | Ov8VYUMjtKSZl3tWTXlkn7DxPFd2Kc5OPeC8fVqOIoRoh4zcMVoXQKEzfs4DuSpM 45 | FTlm19ASr8fao28Exa37xqQN3crfPeC5RRO+J/bFNbnA2THhaqEo0QuVRknGnqPR 46 | hePyDQ5bnliT9t8f+gosxNNEh00nAJ0r1EShqG3qrkmO/yYvdqmHIzrSgG0aVBQF 47 | n6o5Fa46mhsIpTvp+N3h/ju9cHZ4awAIvZC27wnZqO7Ciw+VX9cvjvWtsYtoAfbL 48 | gIYYVwtHFUOz24Pi+wZMkAAuVEBI2pQNG+yEEP5UkzO5EGBnOx3qHFIdOQ9GN5U3 49 | FzE6JJwE5IGB9jWO6NTPwlHcgFRVyFpqqtvtxZAQLZxR0Vo4gRp8QkjJR6IAwiPP 50 | M4amnYjIzN9Ofi7fRt2ibEoxk6LD6b9avn7iulefjalgyCGEF3TJFQbvy3X2KQUg 51 | ZLQmHyYhIM4XdmTCD6w2NxO6vd8Z4l5tet9DIUybII+wY9vYRbufhVuH6t8EcEqT 52 | uUaMyUtKhpdj3CUCcbyviQa/kR74dcfLEpK39zLu8kxnnCCW+aHnXIVTrIfcsXfV 53 | JeLsGspO3oNqePyEN/X/qwcs07WG+Z+QGADyDp3UXBVObyDHFW1rM2xKNhCzF1Zv 54 | pV9q6v5v9VCyXYoKv1o0omgYkeNRBTd/vzr7ZJCBlgqdw8AjDoZiaWcvggU7hZe3 55 | EyYBxDzznAccMQ7OZcFR1gGwbAriMHS9nYQXt/bb9g== 56 | -----END CERTIFICATE----- 57 | -------------------------------------------------------------------------------- /.carnet/seal-ignore.list: -------------------------------------------------------------------------------- 1 | /\.git/ 2 | /\.git$ 3 | ^\./target/ 4 | ^\./\.carnet/seal/ 5 | /\.private-staging-mountpoint/ 6 | /target/ 7 | /Cargo.lock 8 | 9 | -------------------------------------------------------------------------------- /.carnet/seal/sealed: -------------------------------------------------------------------------------- 1 | sealed 2 | -------------------------------------------------------------------------------- /.carnet/seal/signatures.sha256: -------------------------------------------------------------------------------- 1 | ./.carnet/cookies.d/1db590b59b0f72a48d4f.cookie f9d3f4861068d53268ce197cfc042c6d1af21f34870986532e05aa7971009bd8./.carnet/initialized 45df99afdb30dc04d8c57dc9fa1857f1cb1bcd89852d0200c356e8b168a093c1./.carnet/owners/1db590b59b0f72a48d4f.cert baed35e2a503149a5f2595386e9414cc09ea71d1ff8c35d60db1856310f000cb./.carnet/seal-ignore.list 6982ce4ecf02899d6eba148d4663b7b559236bb04b113818295af905162720a1./.gitignore a124e5b1e63212fef625dffd3545afe16c9c7c16061971a82134492b562294ed./.private-staging/CFkR6DH6kdLDOJ_-G5_Gxw 5a0e6650c507c828ed4e8ec31afb70449c63316f939ea4587ddeafbc410e7948./.private-staging/EuhXwWP3KHituntu6prfcumglts1vivVI9bAfw42R3I 85ea6d021899d47f1d130d30ffed0fc45b2a24a59db8bc4c4221567932f87241./.private-staging/H7SWYRC11570750265xLKvsAlVfDsOo8C2vXCY2Zcys e36adbf404f352cdab2bfdb585b22e8f9db9860f927d4e152ef5bcb4e5f85673./.private-staging/HpbujYyg0gNduDTF21pLFQ 3cdbe12e82e3228229a323b24132134aab6070b08ba975218130dd122ef89ff1./.private-staging/XJmkw3Ts8j_ETYiJEOFiHVtK4iDEj-mjOsTgrg85yzQ 057fd0d05484f928b2e8782c75faa900c1b0c74ef3d03d3d4bc2bf8280493464./.private-staging/ZUj-Y4f_a3rP4LSLK7hvbXOR6HXCjWW9n0-Zke_B5h8 6bd927ce863879fe3bff28d07d60ffae6fe0f382c65a399bfc01780216c20fac./.private-staging/ZaIe1V9LXefXitBMdpmgkg 7d580ce95967dbe54fb8077a7e7d3ef6f66c35113f471f8123a7f82bced244b7./.private-staging/gocryptfs.conf 4b9b39953b55bc07f1a93c432ed88552e486c616616cba2f9462915a608ed73b./.private-staging/gocryptfs.diriv 10121c675f0544a685ad0d8e63476803482bab1f8ed247c47aa824adeec7e558./.private-staging/qmUWAVhd-RYoVHC5eVxmOg 4310799341100e8a3a445428e4bc298b635be29e92966c94efb5c03afcd37cf2./CONTRIBUTING.en.md 49eed6c480ef52ba690a646f7ca9297e675dc8d1eab70b68a071122af5dc5607./NEWS.en.md abb5eaa893374deb56bebfd4592deb4715094e252d72c92da720e59d599ce358./README.en.md e733f4dd86c8b7411c74c67c12a761e71fb2311f4be3731a986a542dcd32a407./README.md 020adce34e828bce21e0993f60b70c82dd88f8c9eba8fa479380ac8b17e836aa./carnet 9ca8841f4bcf6062c770627878d3c7dba1bcdecbd15241d9ec274a2345f5457c./etc/assemble.sh 04edbf28a99a1b04a419ce324bf7e0994fe27142aef0372ed4c173d7bef10166./etc/rust-preview/Cargo.toml 3055ae6accc4babd7e8ca0eb89c50d1978e362b3384197ccaecc02ae0d86b6ad./etc/rust-preview/src/lib.rs f91aaf5abdd65b9b10086b5db84accb0aae1493795d510bf75ee6fdd02bd18b8./gpl-3.0.txt 3972dc9744f6499f0f9b2dbf76696f2ae7ad8af9b23dde66d6af86c9dfb36986./lgpl-3.0.txt e3a994d82e644b03a792a930f574002658412f62407f5fee083f2555c5f23118./src/authentication.sh bad4c26dcd922d4e346bcd75f3ff42cae67df4302d65cc1cb859c20920871ae3./src/configuration.sh 8707cab177bc5888d8f990a2f9c00ba23ea7cd5eab297b30040950b3fa078370./src/dependencies.sh 77ca8ebbb531ff7a00f74a7e2336d81f2011265ad96c89e36e4fd26c19dd1230./src/fingerprint.sh ce10f544b3d10fac343abba9263be38ef2a21f7590ac050316b0c460e17a8e6d./src/help.sh fef4e7be545962c7d7f69d1c28ff66acf5c0f2d0b0a115852ce37e753fb39aa7./src/identity.sh 1b17274c84ad33a8d579dbdf11719056d5bb96733eaf704bf39d7964b43152a2./src/init.sh 6ca45904ff96022833b144dffade4482f8f7cd50d12e22ddd4d3032e488efa2c./src/io.sh 1f65b401109860b64112531ebaef27313ef81c7370bba5b8284f414e7420a24c./src/main.sh fb6f9e9584d1ec7b5c4dd143eef235f9ea82f4ece578737f759ec6b6d02ffb67./src/misc/warning-message.sh de24f6ad164d976f69970e06d7fa006e4fed819bd544e34b1dc29041eeef8a33./src/ownership.sh 8024d0a4e16a47a4c7a0eaa8204b19f7bc52c16629a1829103db371022bea98d./src/packaging.sh 0e61adae35cb81e4cc02444de48587bd159db0cf5d6c38b95c2f7e89ee1b6b70./src/sandboxing.sh 93332ff16a107672f8dae1d58c9c7e144a3def97539cf0369d7b71e937635cf5./src/session.sh a5960eb9b0de738e51e1c83d6412cdf949424e0f21d937508893012a186d4f93./src/setup-and-upgrade-scripts.sh 238351716e44038a9d5b32590df05bb927b1fe9932478be9bf07df0a95b60fd3./src/trap.sh 3085f9c39940b5ad997bc3d1d93f4f41b3cc845f1f993462949558579ba5840b./src/trust.sh a8090dd7f4cfd3f95239ff61bf37306cea8fed6d143dd037033ca4a988a77e46./tests/carnet-test.sh c65795c7ff2487e64112e9106f90a8ec0c5adf260e3596dc5fcdccefa9f47894./tests/cases/00-sanity.sh 3e850da40507ee547843786ffd3fbe9de62954c345e76ffc1b8dbc7eeed1b6c6./tests/cases/0000-ignored.crates-io.sh a26d9cc8db88bbf7c4fe75e342d02048b06f30e42177b42b6eecd7f0d12858c6./tests/cases/cargo-1.sh c7a1e81e87236b933dc34337146843b094a8b14c5919fc125cfc5917da09e25c./tests/cases/messing-with-validation.sh 6773f0bf5ea67ef04084073341f2e5e2bfb195c1c135c94dcac7eb256bb03f2f./tests/cases/ownership-1.sh 26026bcd2515837afadfdd7a4dd4f1a920f55cfad72b279169005fba3998ff88./tests/cases/ownership-2.sh 5571a63fc2e44cf1a3caf97638a7334277c34cc2c444dfac8f891f5e23bf7071./tests/cases/ownership-3.sh bf987dcc1e1c8f19a0c516ae191d302c57b1eb1ce83021530e646182d0fc4a52./tests/cases/sandbox-1.sh 9cca6f9f1197f5881822b737c3a770a1064f0a6e4d7d9ea9939c9863c02313d4./tests/common.sh d200ecea86bf8e91c54ae540e13545c7849207fd7a42fd087a6ca199868f771d -------------------------------------------------------------------------------- /.carnet/seal/signatures.sha256.1db590b59b0f72a48d4f.sig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kutometa/carnet/b08bd931fee74e2ff636f6ee9cbe05313baaea2b/.carnet/seal/signatures.sha256.1db590b59b0f72a48d4f.sig -------------------------------------------------------------------------------- /.carnet/seal/signatures.sha384: -------------------------------------------------------------------------------- 1 | ./.carnet/cookies.d/1db590b59b0f72a48d4f.cookie c87e35eb55350ff775f08ca9d226b82c35a76884fed9db2afe9c5ad7310eb21cb6c223bf7a906d0125befcf877bbf356./.carnet/initialized 9fb2f9cf5bc9ae7103a7c304c367ecf88694bfc3973d5bc3bef3d0ba5a2435a6fb677eeceb8d08c43216db09853efcbb./.carnet/owners/1db590b59b0f72a48d4f.cert 1db590b59b0f72a48d4fb9a17f918da0640e585b8b0ba4501b35be0288b605adf089112a6d76f098a2259270b9a67922./.carnet/seal-ignore.list 4a245dac274cc52a0189e2449bb5c4c14c198b02454d9ec133cb54f45bdf00e325cf8ef62ad5daf7bdea19c046bb6ad5./.gitignore a5047eff5ce50d501f1a2162db68dac6936afec1717c23d3fb16740d18ac9f2b3e742e16aa7b695c1350929648d8464a./.private-staging/CFkR6DH6kdLDOJ_-G5_Gxw ac82e24c256ff34a3ef4b36b0bfdc9212faef61d4f97a3d3b7c1c8b44aff9212e08671501b83c7fca9890c15a759b8b7./.private-staging/EuhXwWP3KHituntu6prfcumglts1vivVI9bAfw42R3I 118d5312a6e19755adaf2d6b255bdfef99dfe47b1bc0c4a7e98fcd37d96d152a6292325f9583cd7cae75dd2a6209749a./.private-staging/H7SWYRC11570750265xLKvsAlVfDsOo8C2vXCY2Zcys 825858e6b4f9dd1388188258e0b4aebf2f821c3f8ef64e2a27429d0d27634785e94378768e7541e40713f7de23ce0c02./.private-staging/HpbujYyg0gNduDTF21pLFQ 8fc4f17a02f55749d4ba527602b10a6e982b4c46d8ca73dc808a76979f10466aa27e31d94094dec2b1b99b2f3ee5fa82./.private-staging/XJmkw3Ts8j_ETYiJEOFiHVtK4iDEj-mjOsTgrg85yzQ 5a19f03314d67f795c354fb7624e83fd1d7dc112707507a0b76669d5ee1e032291fb6b173aeff2c095681e1035f7d477./.private-staging/ZUj-Y4f_a3rP4LSLK7hvbXOR6HXCjWW9n0-Zke_B5h8 603c775689695f3d0eeac74171b508a2d63f8ab6927c228e9c758ee067227364e5650a19066b1e81955f2352b436c408./.private-staging/ZaIe1V9LXefXitBMdpmgkg 1328b6cac224bf42ecc06fea79e531b1fb3fe2706a0ea128559971f3cc4f80d3756b69c5cca463c0e0fc7cea4b965326./.private-staging/gocryptfs.conf fb88654a1547603649e3eacd7757686ce3d154454ea347f1c7943bf870b8c30d29b2d4dcd8ad7ad428788e9e2b83c45d./.private-staging/gocryptfs.diriv 6dbe62d89d95495883826470e58c9ade6fe6900cb635bcca112737835606cf6bdda79ffee0670936ba90870359d14166./.private-staging/qmUWAVhd-RYoVHC5eVxmOg 5ea245cc2238c7a397363ed3184b257971b49e11f105c0305f8647a5d5684d222d19a3137732fb8b2e5c4857bf270a05./CONTRIBUTING.en.md b06e45e280501cad8a1053a4cee3d63dc0529d861d08bd7b07b2fe3798146a9b03a0f47de0767efb2d9c0858891d8b42./NEWS.en.md 1d8276eb3630b044aa1aba19fbf7c1f6d2f8950c90a47f96f5fb0d94571752a60ab37cebef6b0e6330d2c7aaa0ad5384./README.en.md 61e4a024b6bd5b32f6c385a135637dbbfeb44eb27a7f3d170904e2166a83f49aa27ed42e07b8b4b73bd20e1cb7344463./README.md 365d767519b43427eab2e1bde475eeebd5a2b8661ea4864933176c508b7a06dde574969cd9b1c5d4e7ee2246fee4eb5c./carnet 6e5d8074ca7c5fba2e11d0c53ce0e611e462a7ed9a9807c7aef562946f323a9d9e90061faa97dca3c021dcf80d7b015c./etc/assemble.sh a316cf048b6aaad4f66bf97f908f467b8b8a716f6215c92b54a20695139e1933d748086a21eb097961d9869a4e405df1./etc/rust-preview/Cargo.toml 5f68ecd7a4ec130a99da1868ea597f21784a0487aa23fe0a24725b3913a4aa01acba3e6aef67c797abbd237a9f95f539./etc/rust-preview/src/lib.rs c8af676245b5a24137b937ea1992f20cdc4dbae20d3ef595eea62bf6bf3d756b8958e6f213e29303b57f45c106dcf369./gpl-3.0.txt cbd88145dc06c3001fce1e90150c511605835b2d7d53e2d88ade2591f035f4a616c1f6f171053fafa548dcbe7322fcf7./lgpl-3.0.txt 228f7f7b23d6b6b94e80b38e27c20fadbc2d75226cdbce6c795f270694b06bc3f32c1831ea7c78c6ca7a1c29b97bae20./src/authentication.sh 4b451747f85a0c56153cebc64628d782c99fbdad30c40d7e1b84a91fb95b2001b0a8c089f78e5859f7ea8550e19135c7./src/configuration.sh cfb6830e317e093056531348f548c4a45db14ab50b2682b73022df8a4c99db6f41bf53ce87d1406e12b51279a94d2fea./src/dependencies.sh eb5a469c1fa71dce433df4c5a99bcd081615eabb25cd28ca3a9795ecb9aba598add92f6a6530eafd63c5829bfa3b778f./src/fingerprint.sh a00f36b752ad78d91819a538d55733d906e2753eaa550f2f5afb70e9844de06e2bdadefab4278f35e31a5318febf16ba./src/help.sh 5ad239788e6f54548ff91c2b1cbb25a9cbb5ea9d0cde019f21f9164d5af60559eb79568262a3a7bb2d854192aa799a4c./src/identity.sh dd65fe365986ee511d2c0839e8b4a892de84253c1fe0e9f8217a5fedee933bb4177aa5a92b451e5401f2a023e06158e8./src/init.sh 3e907e1deb2f2ec6ac5750cbca5e24138556423c6c36f42bfe80a75be8ade03cd63bc9066bdc89ba0c5a8878b8d1ad4c./src/io.sh 1d10a0858f85d93dc091de68586173963b90a3bd517dcfa7e12976c6b751af3da53a48fd4740c6e55c3e782982ee6a64./src/main.sh 8b7f44624cca5e64637ba560e7fc46b72e930cad92afc807c6fc9c3338af0d9b788996edac47a2fd0da343d2ff2f6772./src/misc/warning-message.sh 3508dc5571f3f054e5900697248d522e3b0ae4f7610d18e7a46b555bc8eef2d4ff0290c27fdec9f468f4e5d42e9bf887./src/ownership.sh 4a36f34858eada73430f34f5783c801506b90985d067bb47dd69de6b23e44d7da11d373c0d8cbdaf0f8e87dbe9241ef3./src/packaging.sh 4b6feb6a8e04c54d07a7f1b9a9d4ba1b9d302e4f01b5107882beb66a902be38fc8b5582c45ebf49a09756ca167836585./src/sandboxing.sh 69e6b1c6b0886d239716254016275c947d88d71a083cd0f2dcba0b395bfbd26ca9a158d811fc71387dcfe1668142ac7c./src/session.sh 63988c6ddf4363d89428ba0dab4da824ecdaca890f106f165fc5996f5ff96522b1ccbe30c21e9bac17f1e1781bb2cd35./src/setup-and-upgrade-scripts.sh b54306ee31b891e322eda1231ffecf7903971d607c51a83f336e0c270ca97e2aa3bf8435fe28875e947a5dd482e8e344./src/trap.sh afd1265ffa1b14583d648e6c5e5ac77728e57320778eedbb4fb04ad8a0323a75fc5ef80f3e30178b6721513e8c87bb3f./src/trust.sh f14940bd85a3508dec9f6d28d26444ddf91b56653338c8467979f15406e38bc52554014d987ee252417e504e8173b0e0./tests/carnet-test.sh 55a981d04b91e35f9d05dc8e2f1f4aa5c98059ffed64ab3f142792c8dc6861a04c4b8d1f09d2a357682ee3c668fa001d./tests/cases/00-sanity.sh ab2a8078a8448bc46099d468b0390b9a3962b03e5542ebb1220395864eed541e4170cf6ef1fe5ce127980a13e50e9b52./tests/cases/0000-ignored.crates-io.sh 584a340afbf9b8d861b3b00666b23943e22358e881e85d8373c42a694e02d3af20646fa00e03647869cc2531c42a3c22./tests/cases/cargo-1.sh 4fac80a8f6e98de15522302162c647cf389f1126a966fd4729f5138aeae5f7f485175ae757b0ecd7d78849a07a84165a./tests/cases/messing-with-validation.sh 1e7415af7ba8bfb3ea02751f538a4a059b083ad8c3cf4090ae80208c32e1ea5604f7ca61900a01198cb8859abdddeb12./tests/cases/ownership-1.sh 5a40052472ccb42861524173de96bcb114a45df91840bb9cb44383e2d60cf3a153952538e06dc4992a886f455cce7fdd./tests/cases/ownership-2.sh a2da450762cc6697c9cd71ac6704b49ac319690a0fce06b5d1af2a7e4dca4e9afe1b0085d0fc7ea0510f3d17b42fd7d6./tests/cases/ownership-3.sh a01f75cae1eee945bd14dcfed40501a8990c191726f481474f03057c5fe6eb1952b7ebcba1a29ca96c3e7344bc712783./tests/cases/sandbox-1.sh 1301d28c272a720396ab395a97a1c85463425bfe7f7024b68c6fb49fabfcdf3b884b6175ac5f995a6f3614c4a2372394./tests/common.sh 5ee948c2e0305ab315e91ee700939f7024f0dcf0ec30de96964464a012726bc7fca1eed51a47dd38cbe6d7a9d18bfd1e -------------------------------------------------------------------------------- /.carnet/seal/signatures.sha384.1db590b59b0f72a48d4f.sig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kutometa/carnet/b08bd931fee74e2ff636f6ee9cbe05313baaea2b/.carnet/seal/signatures.sha384.1db590b59b0f72a48d4f.sig -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | etc/rust-preview/target 2 | etc/rust-preview/Cargo.lock 3 | .private-staging-mountpoint 4 | -------------------------------------------------------------------------------- /.private-staging/CFkR6DH6kdLDOJ_-G5_Gxw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kutometa/carnet/b08bd931fee74e2ff636f6ee9cbe05313baaea2b/.private-staging/CFkR6DH6kdLDOJ_-G5_Gxw -------------------------------------------------------------------------------- /.private-staging/EuhXwWP3KHituntu6prfcumglts1vivVI9bAfw42R3I: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kutometa/carnet/b08bd931fee74e2ff636f6ee9cbe05313baaea2b/.private-staging/EuhXwWP3KHituntu6prfcumglts1vivVI9bAfw42R3I -------------------------------------------------------------------------------- /.private-staging/H7SWYRC11570750265xLKvsAlVfDsOo8C2vXCY2Zcys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kutometa/carnet/b08bd931fee74e2ff636f6ee9cbe05313baaea2b/.private-staging/H7SWYRC11570750265xLKvsAlVfDsOo8C2vXCY2Zcys -------------------------------------------------------------------------------- /.private-staging/HpbujYyg0gNduDTF21pLFQ: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kutometa/carnet/b08bd931fee74e2ff636f6ee9cbe05313baaea2b/.private-staging/HpbujYyg0gNduDTF21pLFQ -------------------------------------------------------------------------------- /.private-staging/XJmkw3Ts8j_ETYiJEOFiHVtK4iDEj-mjOsTgrg85yzQ: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kutometa/carnet/b08bd931fee74e2ff636f6ee9cbe05313baaea2b/.private-staging/XJmkw3Ts8j_ETYiJEOFiHVtK4iDEj-mjOsTgrg85yzQ -------------------------------------------------------------------------------- /.private-staging/ZUj-Y4f_a3rP4LSLK7hvbXOR6HXCjWW9n0-Zke_B5h8: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kutometa/carnet/b08bd931fee74e2ff636f6ee9cbe05313baaea2b/.private-staging/ZUj-Y4f_a3rP4LSLK7hvbXOR6HXCjWW9n0-Zke_B5h8 -------------------------------------------------------------------------------- /.private-staging/ZaIe1V9LXefXitBMdpmgkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kutometa/carnet/b08bd931fee74e2ff636f6ee9cbe05313baaea2b/.private-staging/ZaIe1V9LXefXitBMdpmgkg -------------------------------------------------------------------------------- /.private-staging/gocryptfs.conf: -------------------------------------------------------------------------------- 1 | { 2 | "Creator": "gocryptfs 1.4.3", 3 | "EncryptedKey": "f6bZEDgnbYxwFprYDG9jnQkZ5GWojAETSFFo+9HH6mtXA2InvxlqnmDu+l6C25HYNCJb8LaNCuensTxVAuiwlA==", 4 | "ScryptObject": { 5 | "Salt": "y5yCSdWvvMJbf1bStAE8jW3wrYVEbjjUXJWMMXWpGa0=", 6 | "N": 65536, 7 | "R": 8, 8 | "P": 1, 9 | "KeyLen": 32 10 | }, 11 | "Version": 2, 12 | "FeatureFlags": [ 13 | "GCMIV128", 14 | "HKDF", 15 | "DirIV", 16 | "EMENames", 17 | "LongNames", 18 | "Raw64" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /.private-staging/gocryptfs.diriv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kutometa/carnet/b08bd931fee74e2ff636f6ee9cbe05313baaea2b/.private-staging/gocryptfs.diriv -------------------------------------------------------------------------------- /.private-staging/qmUWAVhd-RYoVHC5eVxmOg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kutometa/carnet/b08bd931fee74e2ff636f6ee9cbe05313baaea2b/.private-staging/qmUWAVhd-RYoVHC5eVxmOg -------------------------------------------------------------------------------- /CONTRIBUTING.en.md: -------------------------------------------------------------------------------- 1 | Thank you for your interest in contributing to our project. Please 2 | read this document carefully before you start working on a feature 3 | that you intend to contribute back to this repository. 4 | 5 | 6 | # Table of Contents 7 | 8 | 1. Building 9 | 2. Testing 10 | 3. Contributing 11 | 12 | 13 | # Building 14 | 15 | Carnet is developed as a set of partial bash files that require 16 | assembly into a single executable file before Carnet can be used 17 | normally. 18 | 19 | You can assemble carnet by using `./etc/assemble.sh`. To assemble 20 | carnet for testing or redistribution, run the following command in 21 | the root of this repository: 22 | 23 | ```sh 24 | bash ./etc/assemble.sh ./src/main.sh > ./carnet 25 | chmod +x ./carnet 26 | ``` 27 | 28 | 29 | # Testing 30 | 31 | Carnet is bundled with a test suite that can be used to check for 32 | regressions and other issues. To run the test suite, you first build 33 | the script then run the following command in the root of this 34 | repository. 35 | 36 | ```sh 37 | bash tests/carnet-test.sh 38 | ``` 39 | 40 | To run all tests, including those ignored by default, set the 41 | environment variable `TEST_IGNORED` to `yes`: 42 | 43 | ```sh 44 | TEST_IGNORED=yes bash tests/carnet-test.sh 45 | ``` 46 | 47 | 48 | # Contributing 49 | 50 | We classify contributions into one of the following two categories: 51 | 52 | 1. **Major** contributions where a substantial amount of code or other 53 | copyrightable material is provided or modified. 54 | 55 | 2. **Minor** contributions that do not meet the threshold of 56 | copyrightability. (e.g Typographical errors, One-line fixes, etc) 57 | 58 | If you are not sure whether your contribution will be treated as 59 | major or minor, please open an issue and ask. 60 | 61 | 62 | ### Major Contributions 63 | 64 | To have a major contribution merged into this project, please follow 65 | these steps: 66 | 67 | 1. Before you start working on your contribution, open a new issue to 68 | determine if your contribution is compatible with this project's 69 | goals and constraints. 70 | 71 | 2. Fill and submit the Kutometa Contributor License Agreement form if 72 | you haven't done so already. This agreement grants us the ability 73 | to license your contribution for commercial use and to address 74 | legal issues as they arise. This agreement does not assign your 75 | copyright to us. 76 | 77 | 3. Start implementing your contribution. 78 | 79 | 4. (Optional) add tests to the test suite. 80 | 81 | 5. Run the test suite and make sure all tests pass. 82 | 83 | 6. (Optional) Run the _full_ test suite and make sure all tests pass. 84 | 85 | 7. Update your issue and submit a patch or a pull request. 86 | 87 | 88 | ### Minor Contributions 89 | 90 | Minor contributions are exempt from the steps required for major 91 | contributions. We still recommend running the test suite especially 92 | when code is modified. 93 | 94 | # Questions 95 | 96 | Open a new issue! 97 | -------------------------------------------------------------------------------- /NEWS.en.md: -------------------------------------------------------------------------------- 1 | # Carnet News 2 | 3 | This file documents noteworthy changes between each version of 4 | Carnet. 5 | 6 | 7 | ### Noteworthy changes in v0.3.6 (2021-05-24) 8 | 9 | This release revamps the identity generation process for new users. 10 | Now new users can enter information directly into Carnet instead of 11 | having to set global environment variables. 12 | 13 | 14 | ##### Breaking Changes 15 | 16 | * Carnet input now requires direct input if relevant environment 17 | variables are not set. 18 | 19 | ##### New Features 20 | 21 | * Revamped identity generation for new users 22 | 23 | ##### Bug Fixes 24 | 25 | * None that we're aware of. 26 | 27 | 28 | ### Noteworthy changes in v0.3.5 (2021-05-23) 29 | 30 | This is a minor release that fixes minor issues with the last 31 | release. 32 | 33 | ### Noteworthy changes in v0.3.4 (2021-05-23) 34 | 35 | This release contains last minute changes prior to project 36 | announcement. 37 | 38 | ##### Breaking Changes 39 | 40 | * None that we're aware of. 41 | 42 | ##### New Features 43 | 44 | * Improved CLI ergonomics by showing expected help message when no 45 | arguments are given 46 | * Initializing, sealing, and verifying non-crate directories is now 47 | permitted 48 | * Improved documentation: The carnet:files command is now mentioned 49 | in --carnet:help 50 | * Improved Error messages 51 | * Dogfooding from now on: The Carnet repository is now being signed 52 | using Carnet. 53 | 54 | ##### Bug Fixes 55 | 56 | * Fixed argument parsing bugs 57 | 58 | 59 | 60 | ### Noteworthy changes in v0.3.3 (2021-05-21) 61 | 62 | This is the first publicly-released version of Carnet. 63 | 64 | ##### Breaking Changes 65 | 66 | * None 67 | 68 | ##### New Features 69 | 70 | * System-level sandboxing of Cargo and any process it spawns 71 | * Direct TOFU crate signing and verification support 72 | * Automatically expiring Developer Sessions 73 | 74 | ##### Bug Fixes 75 | 76 | * None 77 | 78 | -------------------------------------------------------------------------------- /README.en.md: -------------------------------------------------------------------------------- 1 | The English version of the README file is currently located in 2 | [README.md](README.md). It will be moved back here later. 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Carnet: Bureaucracy for Cargo 2 | 3 | > **IMPORTANT NOTICE**: Carnet is pre-alpha software. Sandboxing works. 4 | > Crate authentication is not ready yet. Identity and key 5 | > life-cycle management are WIH. 6 | 7 | Carnet is a small tool that imposes additional security constraints 8 | on Rust's official package manager, Cargo. This tool aims to prevent 9 | or otherwise limit the damage malicious crates can cause. 10 | 11 | Carnet imposes two types of security constraints on Cargo: 12 | 13 | 1. It can isolate Cargo to a separate system-enforced 14 | sandbox, only allowing access to a limited subset of 15 | system resources. 16 | 17 | 2. It can authenticate crates before allowing Cargo to 18 | operate on them. (This feature is incomplete and should 19 | not be used yet.) 20 | 21 | Carnet is meant as a temporary solution until Cargo gains the ability to 22 | impose these constraints on its own. 23 | 24 | ## Installing & Updating 25 | 26 | If your system is compatible with the FHS standard, you can install 27 | Carnet system-wide by downloading this repository and running the 28 | following command at the root of the repository: 29 | 30 | 31 | ```sh 32 | sudo install ./carnet /usr/local/bin/carnet 33 | ``` 34 | 35 | Alternatively, you can install Carnet to your user's `bin` directory 36 | by running the following command in the root of this repository if 37 | your system is configured to respect the XDG standard: 38 | 39 | ```sh 40 | install ./carnet ~/.local/bin 41 | ``` 42 | 43 | Carnet requires the following dependencies to be installed on your 44 | system: 45 | 46 | - A modern version of GNU Bash (>= 4.4, 2016) 47 | - GNU Core Utilities 48 | - Bubblewrap (`bwrap`) 49 | - OpenSSL CLI Tool (`openssl`) 50 | - Tiny C Compiler (`tcc`) 51 | 52 | 53 | ## Using Carnet 54 | 55 | Carnet can be used in place of Cargo, transparently accepting all 56 | its arguments: 57 | 58 | ```sh 59 | carnet test 60 | carnet build --release 61 | ``` 62 | 63 | In both the commands above, Carnet will first verify the 64 | authenticity of the crate and then run the corresponding cargo 65 | command in a restrictive sandbox (unless configured otherwise). 66 | This sandbox prevents Cargo from accessing the network, most of 67 | the user's home directory, most of the filesystem, and so on 68 | by default. 69 | 70 | Sandbox restrictions can be relaxed easily and can even be disabled 71 | entirely by simply passing the appropriate flag to Carnet: 72 | 73 | ```sh 74 | carnet --unsandbox-network ... 75 | carnet --unsandbox-cargo-home ... 76 | carnet --unsandbox-processes ... 77 | carnet --unsandbox-session ... 78 | carnet --unsandbox-filesystem ... 79 | ... and so on. 80 | ``` 81 | 82 | In addition to general flags that act on entire resource classes, 83 | Carnet can also expose individual files and directories within 84 | the sandbox via the flags `--carnet:ro-paths` and 85 | `--carnet:rw-paths`. 86 | 87 | To avoid ambiguity, flags intended for Carnet can be prefixed 88 | with `carnet:` while flags intend for Cargo can be prefixed with 89 | `cargo:`. If both Carnet and Cargo accept the same flag and 90 | prefixes are not used, the handling of this flag is unspecified. 91 | The following example illustrates the use of both prefixes: 92 | 93 | ```sh 94 | carnet --carnet:unsandbox-network test --cargo:release 95 | ``` 96 | 97 | Both the sandboxing of Cargo and the automatic verification of crates 98 | can be disabled, for a single invocation or persistently, through the 99 | use of the appropreate flag or by disabling the feature in Carnet's 100 | configuration settings: 101 | 102 | ```sh 103 | carnet --disable-sandbox ... 104 | carnet --disable-verification ... 105 | 106 | carnet disable sandbox 107 | carnet disable verification 108 | ``` 109 | 110 | Run `carnet carnet:help` or `carnet --carnet:help` for more 111 | information. 112 | 113 | 114 | ## History & Future Plans 115 | 116 | We originally wrote this version of Carnet to only serve as a 117 | prototype for when we wanted to implement Carnet more robustly 118 | (in Rust). However, we ultimately decided against this approach and 119 | published Carnet as-is. Our decision was in part because we couldn't 120 | guarantee when this rewrite would occur. We also hope to gather 121 | enough feedback to help us make a better Carnet when the rewrite 122 | eventually takes place. 123 | 124 | 125 | ## Feedback is Important 126 | 127 | Since we don't include any telemetry in Carnet, we rely on your 128 | feedback to gauge how successful this project is. If you use Carnet 129 | and don't mind sharing this fact publicly, let us know by leaving a 130 | comment on the Github issue here: 131 | https://github.com/kutometa/carnet/issues/3 132 | 133 | Alternatively, you can let us know by sending a short email to 134 | support@ka.com.kw. 135 | 136 | 137 | ## Contributing 138 | 139 | Please see [CONTRIBUTING.en.md](./CONTRIBUTING.en.md) in the root of 140 | this repository. 141 | 142 | 143 | ## Support & Licensing 144 | 145 | Official commercial support and custom licensing are available 146 | directly from the authors of this software. Please send your 147 | inquiries via any of our official communication channels. 148 | 149 | Our communication channels are listed at: 150 | https://www.ka.com.kw/en/contact 151 | 152 | 153 | ## Copyright 154 | 155 | #### Copyright © 2021 Kutometa SPC, Kuwait 156 | 157 | Unless expressly stated otherwise, this work and all related material 158 | are made available to you under the terms of version 3 of the GNU 159 | Lesser General Public License (hereinafter, the LGPL-3.0) and the 160 | following supplemental terms: 161 | 162 | 1. This work must retain all legal notices. These notices must 163 | not be altered or truncated in any way. 164 | 165 | 2. The origin of any derivative or modified versions of this work 166 | must not be presented in a way that may mislead a reasonable 167 | person into mistaking the derive work to originate from Kutometa 168 | or the authors of this work. 169 | 170 | 3. Derivative or modified versions of this work must be clearly 171 | and easily distinguishable from the original work by a 172 | reasonable person. 173 | 174 | 4. Unless express permission is granted in writing, The name of 175 | the original work may not be used within the name of any 176 | derivative or modified version of the work. 177 | 178 | 5. Unless express permission is granted in writing, Trade names, 179 | trademarks, and service marks used in this work may not be 180 | included in any derivative or modified versions of this work. 181 | 182 | 6. Unless express permission is granted in writing, the names and 183 | trademarks of Kutometa and other right holders may not be used 184 | to endorse derivative or modified versions of this work. 185 | 186 | 7. The licensee must defend, indemnify, and hold harmless 187 | Kutometa and authors of this software from any and all 188 | actions, claims, judgments, losses, penalties, liabilities, 189 | damages, expenses, demands, fees (including, but not limited 190 | to, reasonable legal and other professional fees), taxes, and 191 | cost that result from or in connection with any liability 192 | imposed on Kutometa or other authors of this software as a 193 | result of the licensee conveying this work or a derivative 194 | thereof with contractual assumptions of liability to a third 195 | party recipient. 196 | 197 | Unless expressly stated otherwise or required by applicable law, 198 | this work is provided AS-IS with NO WARRANTY OF ANY KIND, 199 | INCLUDING THE WARRANTY OF MERCHANTABILITY AND FITNESS FOR A 200 | PARTICULAR PURPOSE. Use this work at your own risk. 201 | 202 | This license agreement is governed by and is construed in accordance 203 | with the laws of the state of Kuwait. You must submit all disputes 204 | arising out of or in connection with this work to the exclusive 205 | jurisdiction of the courts of Kuwait. 206 | 207 | You should have received a copy of the LGPL-3.0 along with this 208 | program; if not, visit www.ka.com.kw/en/legal, write to 209 | legal@ka.com.kw, or write to Kutometa SPC, 760 SAFAT 13008, Kuwait. 210 | 211 | -------------------------------------------------------------------------------- /etc/assemble.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Assemble.sh recursivly collapses simple uses of `source` in bash 4 | # files. To work correctly, this script assumes: 5 | # 6 | # 1. `source` is argumentless 7 | # 2. No cycles exist between source files. 8 | # 9 | # Warning: This script will recurse infinitily if there is a cycle. 10 | # This can lead to OOM conditions or depletion of disk 11 | # space. 12 | 13 | set -eu 14 | set -H 15 | 16 | DELEMETER="$(head -c 8 /dev/urandom | sha384sum | cut -f 1 -d ' ')SOURCESOURCE " 17 | assemble() { 18 | printf "Sourcing from '%s' from '%s'..\n" "$1" "$PWD" >&2 19 | DIR="$(dirname "$1")" 20 | FILENAME="$(basename "$1")" 21 | 22 | ( 23 | set -eu 24 | set -H 25 | cd "$DIR" 26 | while IFS= read -r LINE; do 27 | PROCESSED_LINE="$(printf "%s" "$LINE" | sed -E 's/^ *source "([^$\\]+)" *(#.*)?$/'"$DELEMETER"'\1/g')" 28 | if [[ "$PROCESSED_LINE" =~ ^$DELEMETER ]]; then 29 | TARGET_PATH="$(printf "%s" "$PROCESSED_LINE" | cut -f 2 -d ' ')" 30 | assemble "$TARGET_PATH" 31 | else 32 | printf "%s\n" "$LINE" 33 | fi 34 | done < <(cat "$FILENAME") 35 | 36 | ) 37 | } 38 | 39 | assemble "$1" 40 | -------------------------------------------------------------------------------- /etc/rust-preview/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "carnet" 3 | version = "0.1.0" 4 | authors = ["Kutometa "] 5 | edition = "2018" 6 | license = "LGPL-3.0-only" 7 | description = "Carnet is a transparent wrapper for Cargo that implements a number of important security features currently missing from it. Carnet is meant as a temporary fix until Cargo gains these features." 8 | homepage = "https://www.ka.com.kw" 9 | 10 | [dependencies] 11 | -------------------------------------------------------------------------------- /etc/rust-preview/src/lib.rs: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright © 2021 Kutometa SPC, Kuwait 4 | 5 | Unless expressly stated otherwise, this work and all related material 6 | are made available to you under the terms of version 3 of the GNU 7 | Lesser General Public License (hereinafter, the LGPL-3.0) and the 8 | following supplemental terms: 9 | 10 | 1. This work must retain all legal notices. These notices must 11 | not be altered or truncated in any way. 12 | 13 | 2. The origin of any derivative or modified versions of this work 14 | must not be presented in a way that may mislead a reasonable 15 | person into mistaking the derive work to originate from Kutometa 16 | or the authors of this work. 17 | 18 | 3. Derivative or modified versions of this work must be clearly 19 | and easily distinguishable from the original work by a 20 | reasonable person. 21 | 22 | 4. Unless express permission is granted in writing, The name of 23 | the original work may not be used within the name of any 24 | derivative or modified version of the work. 25 | 26 | 5. Unless express permission is granted in writing, Trade names, 27 | trademarks, and service marks used in this work may not be 28 | included in any derivative or modified versions of this work. 29 | 30 | 6. Unless express permission is granted in writing, the names and 31 | trademarks of Kutometa and other right holders may not be used 32 | to endorse derivative or modified versions of this work. 33 | 34 | 7. The licensee must defend, indemnify, and hold harmless 35 | Kutometa and authors of this software from any and all 36 | actions, claims, judgments, losses, penalties, liabilities, 37 | damages, expenses, demands, fees (including, but not limited 38 | to, reasonable legal and other professional fees), taxes, and 39 | cost that result from or in connection with any liability 40 | imposed on Kutometa or other authors of this software as a 41 | result of the licensee conveying this work or a derivative 42 | thereof with contractual assumptions of liability to a third 43 | party recipient. 44 | 45 | Unless expressly stated otherwise or required by applicable law, 46 | this work is provided AS-IS with NO WARRANTY OF ANY KIND, 47 | INCLUDING THE WARRANTY OF MERCHANTABILITY AND FITNESS FOR A 48 | PARTICULAR PURPOSE. Use this work at your own risk. 49 | 50 | This license agreement is governed by and is construed in accordance 51 | with the laws of the state of Kuwait. You must submit all disputes 52 | arising out of or in connection with this work to the exclusive 53 | jurisdiction of the courts of Kuwait. 54 | 55 | You should have received a copy of the LGPL-3.0 along with this 56 | program; if not, visit www.ka.com.kw/en/legal, write to 57 | legal@ka.com.kw, or write to Kutometa SPC, 760 SAFAT 13008, Kuwait. 58 | 59 | 60 | */ 61 | 62 | 63 | pub fn to_whom_it_may_consern() -> &'static str { 64 | concat!("This is a placeholder for a legitimate project of the ", 65 | "same name. This will be populated with the rust ", 66 | "version of the project once it is ready for public ", 67 | "release. ", 68 | "If you have any questions, please reach out to me on ", 69 | "github or through any other method.") 70 | } 71 | 72 | pub fn is_ready() -> bool { 73 | false 74 | } 75 | 76 | #[cfg(test)] 77 | mod tests { 78 | #[test] 79 | fn it_works() { 80 | assert_eq!(crate::to_whom_it_may_consern().len(), 250); 81 | assert!(!crate::is_ready()); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /lgpl-3.0.txt: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /src/authentication.sh: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | # describe_mismatch path-TO-TRUSTED-HASH LIST PATH-TO-ROOT-OF-CRATE HASH-ALGO 6 | describe_mismatch() { 7 | local DISPLAY_CURRENT_SIGNATURES="$(generate_crate_seal_list "$hashalgo" "$2" | tr '\n' '␤' | tr '\0' '\n')" 8 | local DISPLAY_TRUSTED_SIGNATURES="$(cat "$1" | tr '\n' '␤' | tr '\0' '\n')" 9 | 10 | local CURRENT_LINECOUNT=$(printf "%s" "$DISPLAY_CURRENT_SIGNATURES" | wc -l) 11 | local TRUSTED_LINECOUNT=$(printf "%s" "$DISPLAY_TRUSTED_SIGNATURES" | wc -l) 12 | # Signed file manifest does not list files that are currently present in this directory. 13 | if [[ "$CURRENT_LINECOUNT" -lt "$TRUSTED_LINECOUNT" ]]; then 14 | warn "Missing files (and possibly edited and extra files) not accounted for in the signed manifest." 15 | elif [[ "$CURRENT_LINECOUNT" -gt "$TRUSTED_LINECOUNT" ]]; then 16 | warn "Extra files (and possibly edited and missing files) not accounted for in the signed manifest." 17 | else [[ "$CURRENT_LINECOUNT" == "$TRUSTED_LINECOUNT" ]] 18 | warn "Missing, edited, or missing files not accounted for in the signed manifest." 19 | fi 20 | 21 | set -e 22 | set -u 23 | set -H 24 | set -o pipefail 25 | # Some concerns: 26 | # Filenames can contain anything but nulls and forward slashs. This means that 27 | # an attacker can include newlines hashes. It's not clear to me if this can 28 | # be exploited (especially given how sha*sum handles newlines in filenames. 29 | # 30 | # TODO investigate this when you have more time. 31 | # 32 | comm --nocheck-order --output-delimiter= -3 <(printf "%s" "$DISPLAY_CURRENT_SIGNATURES") <(printf "%s" "$DISPLAY_TRUSTED_SIGNATURES") | sed -E 's/^([^ ]+)+[ ]*.*$/\1/g' | sort | uniq | while read -r l; do warn "Problem with file: $l"; done 33 | 34 | } 35 | 36 | 37 | # generate_crate_seal_list "sha384"|"sha256" INSECURE_KNOWN_CRATE_PATH 38 | # 39 | # Generate a sorted list of all files in $2, with the 40 | # exclusion of any relative paths that match one of the patterns 41 | # listed. 42 | generate_crate_seal_list() { 43 | local -a find_args 44 | 45 | if ! [[ "${1-}" ]]; then 46 | fatal "INTERNAL BUG: HASH ALGO REQUIRED" 47 | fi 48 | # "^\b$" 49 | if [[ -f "$2/.$PROJECT_NAME/seal-ignore.list" ]]; then 50 | while read -r pattern; do 51 | #find_args=( "${find_args[@]}" "-not" "-regex" "$pattern" ) 52 | find_args=( "${find_args[@]}" "-e" "$pattern" ) 53 | done < <( cat "$2/.$PROJECT_NAME/seal-ignore.list" | sed '/^\s*$/d' ) 54 | fi 55 | 56 | ( 57 | set -e 58 | set -u 59 | set -H; 60 | set -o pipefail; 61 | local PATHNAME; 62 | cd "$2" 63 | find "." -type f -print0 | grep -vzE "${find_args[@]}" -e "^\b$" | while read -d '' -r PATHNAME; do 64 | printf "%s %s\0" "$PATHNAME" "$(cat "$PATHNAME" | "$1"sum | cut -d ' ' -f 1)" 65 | done | env LC_ALL=C sort -z 66 | ) 67 | } 68 | 69 | 70 | 71 | # seal 72 | # 73 | # Sign current owned carnet crate, but ignore any files matching 74 | # .$PROJECT_NAME/seal-ignore.list. 75 | # 76 | # Will not sign any crate that is not registered and is not local/owned. 77 | seal() { 78 | if ! [[ "${KNOWN_CRATE_STATE-}" ]] || ! [[ "$KNOWN_CRATE_STATE" == "found" ]] || ! [[ "$KNOWN_CRATE_ORIGIN" == "local" ]]; then 79 | fatal "Cannot sign a crate that is not owned by you (${KNOWN_CRATE_PATH-}). Run $PROJECT_NAME carnet:crate-info for more information about the crate." 80 | fi 81 | 82 | if ! [[ -f "$USERCONFIGDIR/known/$KNOWN_CRATE_PATH_HASH/registered" ]]; then 83 | ignored_step_message "Sealing" "Cannot seal crate because it wasn't initialized by $PROJECT_NAME." 84 | return 0 85 | fi 86 | step_message "Sealing" "Signing crate root ($KNOWN_CRATE_PATH)" 87 | if [[ -f "$KNOWN_CRATE_PATH/.$PROJECT_NAME/seal" ]]; then rm -r "$KNOWN_CRATE_PATH/.$PROJECT_NAME/seal"; fi 88 | mkdir -p "$KNOWN_CRATE_PATH/.$PROJECT_NAME/seal" 89 | mkdir -p "$KNOWN_CRATE_PATH/.$PROJECT_NAME/owners" 90 | # mkdir -p "$KNOWN_CRATE_PATH/.$PROJECT_NAME/identity.blacklist.d" 91 | 92 | #cp "$LOCAL_IDENTITY_PUBKEY_PATH" "$KNOWN_CRATE_PATH/.$PROJECT_NAME/owners/$LOCAL_IDENTITY_FINGERPRINT.pub" 93 | cp "$LOCAL_IDENTITY_CERT_PATH" "$KNOWN_CRATE_PATH/.$PROJECT_NAME/owners/$LOCAL_IDENTITY_FINGERPRINT.cert" 94 | 95 | for hashalgo in "${HASH_ALGORITHMS[@]}"; do 96 | generate_crate_seal_list "$hashalgo" "$KNOWN_CRATE_PATH" > "$KNOWN_CRATE_PATH/.$PROJECT_NAME/seal/signatures.$hashalgo" 97 | 98 | openssl dgst -sign "$LOCAL_IDENTITY_PRIVKEY_PATH" \ 99 | -"$hashalgo" \ 100 | -out "$KNOWN_CRATE_PATH/.$PROJECT_NAME/seal/signatures.$hashalgo.$LOCAL_IDENTITY_FINGERPRINT.sig" \ 101 | "$KNOWN_CRATE_PATH/.$PROJECT_NAME/seal/signatures.$hashalgo" 102 | 103 | done 104 | echo "sealed" > "$KNOWN_CRATE_PATH/.$PROJECT_NAME/seal/sealed" 105 | } 106 | 107 | verify() { 108 | if ! [[ "${KNOWN_CRATE_STATE-}" ]] || [[ "$KNOWN_CRATE_STATE" != "found" ]]; then 109 | fatal "Cannot verify crate because it isn't known." 110 | return 0 111 | fi 112 | 113 | # To minimize the chances of accidentally relying on unverified crate content, 114 | # $KNOWN_CRATE_PATH is temporarly set to an invalid value. Only use INSECURE_KNOWN_CRATE_PATH 115 | # for informative purposes. Set back when the crate is verified 116 | local INSECURE_KNOWN_CRATE_PATH="$KNOWN_CRATE_PATH" 117 | KNOWN_CRATE_PATH="HIDDEN" 118 | 119 | step_message "Verifying" "Checking file signatures ($INSECURE_KNOWN_CRATE_PATH)" 120 | 121 | if ! [[ -f "$INSECURE_KNOWN_CRATE_PATH/.$PROJECT_NAME/seal/sealed" ]]; then 122 | fatal "Cannot verify crate because it wasn't sealed. See --carnet:help for more information." 123 | fi 124 | 125 | local CACHED_WHITELIST_DIR="$USERCONFIGDIR/known/$KNOWN_CRATE_PATH_HASH/owners" 126 | 127 | local -a issues; 128 | 129 | # Verify pk signatures 130 | local KEY="" 131 | for candidate_identity_cert in "$CACHED_WHITELIST_DIR"/*.cert; do 132 | # If the certificate isn't a file, skip it. 133 | if ! [[ -f "$candidate_identity_cert" ]]; then 134 | fatal "No owners were found or a non file was found in '$CACHED_WHITELIST_DIR'" 135 | return 1 136 | fi 137 | 138 | # Generate owner fingerprint from cert 139 | local cached_whitelist_fingerprint="$(file_fingerprint "$candidate_identity_cert")" 140 | 141 | # (Consistency check) Ensure that fingerprint of the cert matches its filename 142 | local expected_cached_whitelist_fingerprint="$(basename "$candidate_identity_cert")" 143 | expected_cached_whitelist_fingerprint="${expected_cached_whitelist_fingerprint::-5}" 144 | if [[ "$expected_cached_whitelist_fingerprint" != "$cached_whitelist_fingerprint" ]]; then 145 | fatal "The filename of the identity certificate for does not match its fingerprint: Found '$candidate_identity_cert' which should be named '$cached_whitelist_fingerprint'" 146 | return 1 147 | fi 148 | 149 | # If a crate owner is pinned, skip any crate owner that doesn't doesn't match it 150 | if [[ "${PINNED_OWNER_IDENTITY_FINGERPRINT-}" ]] && [[ "$PINNED_OWNER_IDENTITY_FINGERPRINT" != "$cached_whitelist_fingerprint" ]]; then 151 | debug "Ignored ${cached_whitelist_fingerprint} because it isn't the pinned owner $PINNED_OWNER_IDENTITY_FINGERPRINT" 152 | issues=( "${issues[@]}" "Ignored any signatures by identity ${cached_whitelist_fingerprint} because it doesn't match what was pinned ($PINNED_OWNER_IDENTITY_FINGERPRINT)" ) 153 | verified="no" 154 | break 155 | fi 156 | 157 | # Verifying public key against 158 | local candidate_identity_pubkey="$(dirname "$candidate_identity_cert")/$cached_whitelist_fingerprint.pub" 159 | if ! cmp -s -- "$candidate_identity_pubkey" < <(openssl x509 -pubkey -noout -in "$candidate_identity_cert"); then 160 | fatal "The on-disk public key '$candidate_identity_pubkey' does not correspond of that is generated from '$candidate_identity_cert'" 161 | return 1 162 | fi 163 | 164 | 165 | debug "looking for signatures made by '$cached_whitelist_fingerprint' in '$INSECURE_KNOWN_CRATE_PATH/.$PROJECT_NAME/seal'" 166 | 167 | # If this crate was signed by this particular crate owner 168 | if [[ -f "$INSECURE_KNOWN_CRATE_PATH/.$PROJECT_NAME/seal/signatures.sha384.$cached_whitelist_fingerprint.sig" ]]; then 169 | debug "signature found: 'signatures.sha384.$cached_whitelist_fingerprint.sig'" 170 | 171 | # Make sure that crate files are verified against the checksum files of ALL hash algorithms 172 | local verified="no" 173 | for hashalgo in "${HASH_ALGORITHMS[@]}"; do 174 | debug "Verifying signatures made using $hashalgo..." 175 | verified="no" 176 | local signature_file="$INSECURE_KNOWN_CRATE_PATH/.$PROJECT_NAME/seal/signatures.$hashalgo.$cached_whitelist_fingerprint.sig" 177 | local hashsum_file="$INSECURE_KNOWN_CRATE_PATH/.$PROJECT_NAME/seal/signatures.$hashalgo" 178 | local OPENSSL_OUTPUT 179 | 180 | # First verify the signature of the checksum file using the owner's public key 181 | debug "Verifying signature of '$hashsum_file' using '$candidate_identity_pubkey'" 182 | if ! OPENSSL_OUTPUT="$(openssl dgst \ 183 | -verify "$candidate_identity_pubkey" \ 184 | -keyform pem \ 185 | "-$hashalgo" \ 186 | -signature "$signature_file" \ 187 | "$hashsum_file" 2>&1)"; then 188 | debug "Invalid signature '$signature_file' for '$hashsum_file' with $hashalgo: $OPENSSL_OUTPUT" 189 | issues=( "${issues[@]}" "Bad signature for ${cached_whitelist_fingerprint}" ) 190 | verified="no" 191 | break 192 | fi 193 | 194 | # Then generate a local checksum list of all files using whatever /untrusted/ parameters in 'seal-ignore.list', 195 | # hash both checksum files (trusted and untrusted), and compare. 196 | 197 | debug "Generating checksums of unverified crate content" 198 | local CURRENT_SIGNATURES_HASH="$(generate_crate_seal_list "$hashalgo" "$INSECURE_KNOWN_CRATE_PATH" | "$hashalgo"sum)" 199 | local TRUSTED_SIGNATURES_HASH="$(cat "$hashsum_file" | "$hashalgo"sum)" 200 | 201 | debug "Verifying checksums against of '$hashsum_file'" 202 | if [[ "$CURRENT_SIGNATURES_HASH" != "$TRUSTED_SIGNATURES_HASH" ]]; then 203 | describe_mismatch "$hashsum_file" "$INSECURE_KNOWN_CRATE_PATH" "$hashalgo" 204 | fatal "$hashalgo checksum mismatch." 205 | fi 206 | verified="yes" 207 | done 208 | 209 | # If all hash checksum checks pass, consider the crate verified 210 | if [[ "$verified" == "yes" ]]; then 211 | KNOWN_CRATE_PATH="$INSECURE_KNOWN_CRATE_PATH" 212 | # Overwrite local crate owners with the list provided by the now trusted crate 213 | update_certs "$KNOWN_CRATE_PATH/.$PROJECT_NAME/owners" "$USERCONFIGDIR/known/$KNOWN_CRATE_PATH_HASH/owners" 214 | step_message "Verified" "Sealed by ${cached_whitelist_fingerprint}" 215 | debug "verification okay" 216 | return 217 | else 218 | debug "Verification failed for ${cached_whitelist_fingerprint}." 219 | continue 220 | fi 221 | else 222 | debug "signature not found." 223 | issues=( "${issues[@]}" "Signature missing for ${cached_whitelist_fingerprint}" ) 224 | fi 225 | done 226 | fatal "Could not verify crate:$(echo ""; for issue in "${issues[@]}"; do printf " - %s\n" "$issue"; done)" 227 | return 1 228 | } 229 | -------------------------------------------------------------------------------- /src/configuration.sh: -------------------------------------------------------------------------------- 1 | # code for setting configuration settings. 2 | 3 | configuration_settings() { 4 | if [[ "${1-}" == "enable" ]]; then 5 | val="enabled" 6 | elif [[ "${1-}" == "disable" ]]; then 7 | val="disabled" 8 | else 9 | fatal "internal error: first argument given to configuration_settings must be enable/disable. '${1-}' given. " 10 | fi 11 | 12 | mkdir -p "$USERCONFIGDIR/settings" 13 | 14 | if [[ "${2-}" == "verification" ]]; then 15 | echo "$val" > "$USERCONFIGDIR/settings/$2.setting" 16 | step_message "Settings" "Automatic verification is now $val" 17 | elif [[ "${2-}" == "sandbox" ]]; then 18 | echo "$val" > "$USERCONFIGDIR/settings/$2.setting" 19 | step_message "Settings" "Sandboxing is now $val" 20 | elif [[ "${2-}" == "eula-agreement" ]]; then 21 | echo "$val" > "$USERCONFIGDIR/settings/$2.setting" 22 | if [[ "${1-}" == "enable" ]]; then 23 | step_message "Settings" "You indicate that you agree to the terms and conditions of the EULA" 24 | else 25 | step_message "Settings" "You indicate that you do not agree to the terms and conditions of the EULA" 26 | fi 27 | 28 | else 29 | fatal "Setting '${2-}' is not known." 30 | fi 31 | 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/dependencies.sh: -------------------------------------------------------------------------------- 1 | # Check system for needed dependencies 2 | 3 | check_installed() { 4 | if ! hash "$1" > /dev/null 2>&1 || ! which "$1" > /dev/null 2>&1; then 5 | echo "An error occurred: The program '$1' is needed by $PROJECT_NAME, but that program wasn't found on this system." 6 | if [[ -x "/usr/lib/command-not-found" ]]; then 7 | /usr/lib/command-not-found "$1" 8 | else 9 | echo "It should be available for installation through your system's software repositories." 10 | fi 11 | exit 108 12 | fi 13 | } 14 | 15 | check_installed "bwrap" 16 | check_installed "printf" 17 | check_installed "realpath" 18 | check_installed "id" 19 | check_installed "openssl" 20 | check_installed "sha384sum" 21 | check_installed "sha256sum" 22 | check_installed "comm" 23 | check_installed "sort" 24 | check_installed "uniq" 25 | check_installed "tr" 26 | check_installed "sed" 27 | check_installed "cat" 28 | check_installed "tcc" 29 | -------------------------------------------------------------------------------- /src/fingerprint.sh: -------------------------------------------------------------------------------- 1 | # path_fingerprint STRING 2 | # 3 | # Generate a fingerprint from the first argument treated as a string 4 | path_fingerprint() { 5 | realpath -- "$1" | sha384sum | cut -d ' ' -f 1 | head -c 24 6 | } 7 | 8 | # file_fingerprint FILENAME 9 | # 10 | # Generate a fingerprint from the file pointed at by the path in the 11 | # first argument 12 | file_fingerprint() { 13 | sha384sum -- "$1" | cut -d ' ' -f 1 | head -c 20 14 | } 15 | 16 | -------------------------------------------------------------------------------- /src/help.sh: -------------------------------------------------------------------------------- 1 | # Help text 2 | 3 | HELP="${BOLD-}$(echo "${PROJECT_TITLE}" | tr '[:lower:]' '[:upper:]')${RESET-} 4 | 5 | ${BOLD-}USAGE${RESET-} 6 | 7 | carnet [OPTIONS] [CARGO COMMANDS & OPTIONS] 8 | carnet [OPTIONS] [CARNET COMMAND] 9 | 10 | ${BOLD-}GENERAL OPTIONS${RESET-} 11 | 12 | --carnet:config-dir=... Override default configuration 13 | directory. 14 | --carnet:end Stop processing Carnet flags and 15 | commands. 16 | --carnet:verbose Show debugging messages. 17 | --carnet:version Show version information and exit. 18 | --carnet:legal Show legal information and exit. 19 | --carnet:help Show this help message and exit. 20 | 21 | ${BOLD-}SANDBOX OPTIONS${RESET-} 22 | 23 | --carnet:disable-sandbox Bypass sandboxing completely. 24 | --carnet:unsandbox-filesystem Allow normal filesystem access. 25 | --carnet:unsandbox-processes Allow normal access to processes 26 | and IPC. 27 | --carnet:unsandbox-network Allow normal network access. 28 | --carnet:unsandbox-session Do not sandbox session. 29 | --carnet:unsandbox-cargo-home Allow read-write access to 30 | cargo's home directory. 31 | --carnet:ro-paths=... Allow read-only access to colon- 32 | separated list of paths. 33 | --carnet:rw-paths=... Allow read-write access to colon- 34 | separated list of paths. 35 | 36 | ${BOLD-}AUTHENTICATION OPTIONS${RESET-} 37 | 38 | --carnet:disable-verification Disable automatic verification. 39 | See carnet:edit and carnet:done. 40 | 41 | ${BOLD-}COMMANDS${RESET-} 42 | 43 | carnet:help Show this help message and exit. 44 | carnet:sandbox-run Run arbitrary commands in sandbox. 45 | carnet:seal Seal current crate. 46 | carnet:verify Verify current crate. 47 | carnet:files View all files that get sealed. 48 | carnet:own Set origin of current as local. 49 | carnet:disown Set origin of current crate as foreign. 50 | carnet:distrust Unregister the current crate from cache. 51 | carnet:init Initialize existing cargo crate. 52 | carnet:uninit Uninitialize and unregister current crate. 53 | 54 | ${BOLD-}CONFIGURATION SETTINGS${RESET-} 55 | 56 | carnet:enable Set a persistent configuration setting. 57 | carnet:disable Unset a persistent configuration setting. 58 | 59 | ${BOLD-}SESSION MANAGEMENT${RESET-} 60 | 61 | carnet:edit Temporarily suspend automatic verification. 62 | carnet:done Resume automatic verification. 63 | 64 | 65 | ${BOLD-}IMPORTANT NOTE${RESET-}: Carnet is pre-alpha software. Sandboxing works. 66 | Crate authentication is not ready yet. Identity and key life- 67 | cycle management are WIH. 68 | 69 | 70 | ${BOLD-}INTRODUCTION${RESET-} 71 | 72 | $(printf "${DESCRIPTION}" | tr -d '\n' | sed -E 's/ +/ /g' | fold -sw 66 | sed -E 's/^/ /g') 73 | 74 | Carnet imposes two types of security constraints on Cargo: 75 | 76 | 1. It can isolate Cargo to a separate system-enforced 77 | sandbox, only allowing access to a limited subset of 78 | system resources. 79 | 80 | 2. It can authenticate crates before allowing Cargo to 81 | operate on them. (This feature is incomplete and should 82 | not be used yet.) 83 | 84 | Carnet can be used in place of Cargo, transparently accepting all 85 | its arguments: 86 | 87 | ${DIM-}carnet test${RESET-} 88 | ${DIM-}carnet build --release${RESET-} 89 | 90 | In both the commands above, Carnet will first verify the 91 | authenticity of the crate and then run the corresponding cargo 92 | command in a restrictive sandbox (unless configured otherwise). 93 | This sandbox prevents Cargo from accessing the network, most of 94 | the user's home directory, most of the filesystem, and so on by 95 | default. 96 | 97 | Sandbox restrictions can be relaxed easily or even disabled 98 | entirely by passing the appropriate flag to Carnet: 99 | 100 | ${DIM-}carnet --unsandbox-network ...${RESET-} 101 | ${DIM-}carnet --unsandbox-cargo-home ...${RESET-} 102 | ${DIM-}carnet --unsandbox-processes ...${RESET-} 103 | ${DIM-}carnet --unsandbox-session ...${RESET-} 104 | ${DIM-}carnet --unsandbox-filesystem ...${RESET-} 105 | ${DIM-}... and so on.${RESET-} 106 | 107 | In addition to general flags that act on entire resource classes, 108 | Carnet can also expose individual files and directories within 109 | the sandbox via the flags '--carnet:ro-paths' and 110 | '--carnet:rw-paths'. 111 | 112 | To avoid ambiguity, flags intended for Carnet can be prefixed 113 | with 'carnet:' while flags intend for Cargo can be prefixed with 114 | 'cargo:'. If both Carnet and Cargo accept the same flag and 115 | prefixes are not used, the handling of this flag is unspecified. 116 | The following example illustrates the use of both prefixes: 117 | 118 | ${DIM-}carnet --carnet:unsandbox-network test --cargo:release${RESET-} 119 | 120 | Both the sandboxing of Cargo and the automatic verification of 121 | crates can be disabled, for a single invocation or persistently, 122 | through the use of the appropriate flag or by disabling the 123 | feature in Carnet's configuration settings: 124 | 125 | ${DIM-}carnet --disable-sandbox ...${RESET-} 126 | ${DIM-}carnet --disable-verification ...${RESET-} 127 | 128 | ${DIM-}carnet disable sandbox${RESET-} 129 | ${DIM-}carnet disable verification${RESET-} 130 | 131 | ${BOLD-}Sandboxing${RESET-} 132 | 133 | By default, Carnet's sandbox restricts Cargo in the following 134 | ways: 135 | 136 | - No network access 137 | - Separate process/IPC space 138 | - Read-only access to the following directories: 139 | - '/etc' 140 | - '/bin' 141 | - '/lib' 142 | - '/lib64' 143 | - '/sbin' 144 | - '/usr' 145 | - Read-Write access to crate root 146 | - Read-Write access to a private '/tmp' 147 | 148 | You can choose to relax these restrictions partially or fully by 149 | using the '--unsandbox-*' and '--*-paths' families of flags. 150 | 151 | You can explore how Cargo \"sees\" its environment from within 152 | the sandbox via sandbox-run: 153 | 154 | ${DIM-}carnet ... sandbox-run${RESET-} 155 | ${DIM-}(i.e. carnet --unsandbox-session sandbox-run bash)${RESET-} 156 | 157 | ${BOLD-}Identities (Unstable)${RESET-} 158 | 159 | Carnet uses Identities to authenticate crates. An Identity is a 160 | set of basic information about a natural, legal, or fictitious 161 | person coupled with a single public cryptographic key. One person 162 | can have multiple identities at the same time. Similarly, crates 163 | can be signed by multiple identities at the same time. 164 | 165 | Identities are meant to be ephemeral. They are designed to be 166 | trivially generatable, and to be introduced and blacklisted as 167 | developers join projects and leave them. Blacklisting an identity 168 | does not carry negative connotations by itself; blacklisting 169 | simply implies that the identity should no longer be \"trusted\" 170 | when verifying crates. 171 | 172 | Identities provide basic information to help users differentiate 173 | between trusted keys. Because this information is not verified 174 | in any way, a verified crate cannot provide any assurances about 175 | the person who signed it. The only 176 | assurance it can provide is that whoever signed the crate had 177 | access to the identity's private key. Carnet Identities are not 178 | designed to protect against the impersonation of 179 | others. 180 | 181 | The basic information identities provide is: 182 | 183 | 1. Name (required): The name or the person using the 184 | identity. 185 | 2. Email (required): An email address that can be used 186 | to contact this person. 187 | 3. Organization: The organization of which this 188 | person is member. 189 | 4. Country: The legal jurisdiction under which 190 | this person operates. 191 | 192 | When generating a new identity, Carnet attempts to obtain this 193 | information by looking at various sources in the order described 194 | bellow: 195 | 196 | ${BOLD-}Identity Name:${RESET-} 197 | 198 | CARNET_PUBLISHER_NAME (environment variable) 199 | CARGO_NAME (environment variable) 200 | GIT_AUTHOR_NAME (environment variable) 201 | GIT_COMMITTER_NAME (environment variable) 202 | user.name (git config) 203 | USER (environment variable) 204 | USERNAME (environment variable) 205 | NAME (environment variable) 206 | 207 | ${BOLD-}Identity Email:${RESET-} 208 | 209 | CARNET_PUBLISHER_EMAIL (environment variable) 210 | CARGO_EMAIL (environment variable) 211 | GIT_AUTHOR_EMAIL (environment variable) 212 | GIT_COMMITTER_EMAIL (environment variable) 213 | user.email (git config) 214 | EMAIL (environment variable) 215 | 216 | ${BOLD-}Identity Organization:${RESET-} 217 | 218 | CARNET_PUBLISHER_ORG (environment variable) 219 | CARNET_PUBLISHER_ORGANIZATION (environment variable) 220 | 221 | ${BOLD-}Identity Country:${RESET-} 222 | 223 | CARNET_PUBLISHER_COUNTRY (environment variable) 224 | 225 | 226 | To avoid situations where the private keys of all authorized 227 | identities become inaccessible, project authors should ensure 228 | identities are properly backed up. Project authors can also add 229 | a dedicated \"backup\". 230 | 231 | ${BOLD-}Local & Foreign Identity Management (Unstable)${RESET-} 232 | 233 | TBD 234 | 235 | ${BOLD-}Sealing Crates (Unstable)${RESET-} 236 | 237 | TBD 238 | 239 | ${BOLD-}Automatic Crate Verification (Unstable)${RESET-} 240 | 241 | Carnet verifies the signatures of registered crates automatically 242 | before running cargo by default. Verification only succeeds when 243 | at least one signature from a trusted identity is valid. 244 | 245 | To avoid having to repeatedly re-sign crates during development, 246 | Carnet can temporarily suspend crate verification, only resuming 247 | when a predefined period of time had elapsed or when a condition 248 | causes the session to end abruptly. Carnet calls this temporary 249 | state a Development Session. 250 | 251 | A development Session starts when the user issues the 'edit' 252 | command. The session ends when the user issues the 'done' 253 | command, time runs out, or when another condition causes the 254 | session to end abruptly. A developer session lasts 2 hours by 255 | default. 256 | 257 | The following example illustrates how development sessions can 258 | be manually started and ended: 259 | 260 | ${DIM-}carnet carnet:edit${RESET-} 261 | ${DIM-}# ... 262 | ${DIM-}carnet carnet:done${RESET-} 263 | 264 | ${BOLD-}Verification Flowchart (Unstable)${RESET-} 265 | 266 | The process used to verify a crate can be represented by the 267 | following flowchart: 268 | 269 | ${DIM-}Was this crate seen before? ${RESET-} 270 | ${DIM-} | ${RESET-} 271 | ${DIM-} +-> no: Is the user willing to trust this crate? ${RESET-} 272 | ${DIM-} | | ${RESET-} 273 | ${DIM-} | +-> no: Authentication Failure ${RESET-} 274 | ${DIM-} | | ${RESET-} 275 | ${DIM-} | +-> yes: Trust all identities found in this crate ${RESET-} 276 | ${DIM-} | | when verifying this crate in the future. ${RESET-} 277 | ${DIM-} | | ${RESET-} 278 | ${DIM-} |<--------+ ${RESET-} 279 | ${DIM-} | ${RESET-} 280 | ${DIM-} +-> yes: Does it have at least one valid signature issued ${RESET-} 281 | ${DIM-} | by an identity the user trusts? ${RESET-} 282 | ${DIM-} | ${RESET-} 283 | ${DIM-} +- no: Authentication Failure ${RESET-} 284 | ${DIM-} | ${RESET-} 285 | ${DIM-} +- yes: Authentication Complete ${RESET-} 286 | ${DIM-}${RESET-} 287 | 288 | Carnet associates crates with their paths on your system. This 289 | association is used to reliably associate identities with crates. 290 | For this reason, a crate should not be moved without first 291 | \"distrusting\" it. Once moved, a crate can be re-trusted and 292 | re-owned again. 293 | 294 | ${BOLD-}Crate State & Ownership (Unstable)${RESET-} 295 | 296 | TBD 297 | 298 | ${BOLD-}Configuration Settings${RESET-} 299 | 300 | Some Carnet settings can be configured persistently through the 301 | 'enable' and 'disable' commands. The following table describes 302 | each available setting along with its default state: 303 | 304 | Setting Name Description 305 | ---------------------+------------------------------------------- 306 | sandbox This setting indicates whether Cargo 307 | should be sandboxed. This setting is 308 | enabled by default. 309 | 310 | verification This setting indicates whether crates 311 | should be automatically verified. This 312 | setting is enabled by default. 313 | 314 | eula-agreement This setting indicates the user's 315 | agreement to the terms and conditions 316 | of this software's license agreement. 317 | This setting is disabled by default. 318 | 319 | ${BOLD-}Exit Status${RESET-} 320 | 321 | Cargo exits with code 101 when Cargo errors occur. Carnet exits 322 | with code 107 when normal Carnet errors occur and code 108 when 323 | internal errors occur. 324 | 325 | ${BOLD-}SUPPORT & LICENSING${RESET-} 326 | 327 | Official commercial support and custom licensing are available 328 | directly from the authors of this software. Please send your 329 | inquiries via any of our official communication channels. 330 | 331 | Our communication channels are listed at: 332 | https://www.ka.com.kw/en/contact 333 | 334 | 335 | ${BOLD-}LICENSE & COPYRIGHT${RESET-} 336 | $COPYRIGHT_BLURB 337 | " 338 | 339 | -------------------------------------------------------------------------------- /src/identity.sh: -------------------------------------------------------------------------------- 1 | # Code for handling identities 2 | 3 | # remove_certs removes user's identity cert from the cache 4 | # should this also remove the certs from the crate itself? 5 | # I don't think so because a crate author can transfer their 6 | remove_certs() { 7 | rm "$USERCONFIGDIR/known/$1/owners/$LOCAL_IDENTITY_FINGERPRINT.cert" 8 | } 9 | 10 | # copy_cert PATH_TO_CERT PATH_TO_KEY_DIR 11 | # 12 | # Copy a public openssl PEM certificate to a directory and rename it 13 | # to the hash of its file. Then generate the public key for that file 14 | # 15 | copy_cert() { 16 | local identity_fingerprint="$( file_fingerprint "$1" )" 17 | cp "$1" "$2/$identity_fingerprint.cert.part" 18 | mv "$2/$identity_fingerprint.cert.part" "$2/$identity_fingerprint.cert" 19 | openssl x509 -pubkey -noout -in "$2/$identity_fingerprint.cert" > "$2/$identity_fingerprint.pub" 20 | debug "Copied cert '$1' as '$2/$identity_fingerprint.cert'." 21 | debug "Extracted public key from '$1' as '$2/$identity_fingerprint.pub'." 22 | } 23 | 24 | # copy_certs PATH_TO_CERTS_DIR PATH_TO_KEY_DIR 25 | # 26 | # Same as `copy_cert` but treat first arg as directory and iterate 27 | # over each file in it. Ignore nonfiles. See `copy_cert`. 28 | # 29 | copy_certs() { 30 | mkdir -p "$2" 31 | for i in "$1"/*.cert; do 32 | if [[ -f "$i" ]]; then 33 | copy_cert "$i" "$2" 34 | else 35 | debug "Ignored '$i' while copying certs from '$1' to '$2'." 36 | fi 37 | done 38 | } 39 | 40 | 41 | swapname() { 42 | tcc -run - "$@" <<"CODE" 43 | #include 44 | #include 45 | #include 46 | #include 47 | 48 | // Ubuntu 18.04 doesn't define this constant 49 | // Obtained from '/usr/include/linux/fs.h' 50 | // Always test first! Might not always correspond to userland 51 | // RENAME_EXCHANGE 52 | int local_RENAME_EXCHANGE = (1 << 1); 53 | 54 | int main(int argc, char **argv) { 55 | if (argc != 3) { 56 | fprintf(stderr, "Error: Could not swap names. Usage: %s PATH1 PATH2\n", argv[0]); 57 | return 2; 58 | } 59 | int r = syscall( 60 | SYS_renameat2, 61 | AT_FDCWD, argv[1], 62 | AT_FDCWD, argv[2], 63 | local_RENAME_EXCHANGE 64 | ); 65 | if (r < 0) { 66 | perror("Error: Could not swap names"); 67 | return 1; 68 | } 69 | else return 0; 70 | } 71 | CODE 72 | } 73 | 74 | 75 | # Sanity test 76 | SWAPNAME_TEST_PATH_1="$(mktemp)" 77 | SWAPNAME_TEST_PATH_2="$(mktemp)" 78 | echo "A" >"$SWAPNAME_TEST_PATH_1" 79 | echo "B" >"$SWAPNAME_TEST_PATH_2" 80 | swapname "$SWAPNAME_TEST_PATH_1" "$SWAPNAME_TEST_PATH_2" 81 | if [[ "$(cat "$SWAPNAME_TEST_PATH_1")" != "B" ]]; then 82 | fatal "Internal tests failed: 'swapname' is not swapping files!" 83 | fi 84 | rm "$SWAPNAME_TEST_PATH_1" 85 | rm "$SWAPNAME_TEST_PATH_2" 86 | 87 | 88 | 89 | # update_certs PATH_TO_CERTS_DIR PATH_TO_KEY_DIR 90 | # 91 | # Replaces all keys in PATH_TO_KEY_DIR with those in 92 | # PATH_TO_CERTS_DIR, and do so in a manner that is resistant to 93 | # corruption. 94 | # 95 | update_certs() { 96 | mkdir -p "$2" 97 | if [[ -d "$2.partial" ]]; then 98 | rm -r "$2.partial" 99 | fi 100 | copy_certs "$1" "$2.partial" 101 | swapname "$2.partial" "$2" || fatal "Could not update owners in '$2'" 102 | } 103 | 104 | 105 | # show_cert_information PATH-TO-PEM-CERT ["identity-mode"] 106 | show_cert_information() { 107 | local AUTHOR_IDENT_ID="$(file_fingerprint "$1")" 108 | if [[ "$AUTHOR_IDENT_ID.cert" != "$(basename "$1")" ]] && [[ "${2-}" != "identity-mode" ]]; then 109 | fatal "Found corrupted identity certificate: the given certificate was not named correctly: '$1'" 110 | fi 111 | echo "" 112 | if [[ "${2-}" != "identity-mode" ]]; then 113 | printf " Identity $AUTHOR_IDENT_ID which claims:\n" 114 | fi 115 | openssl x509 -nameopt multiline,-esc_msb,utf8 -in "$1" -noout -subject \ 116 | | sed -E "/^subject=/d" \ 117 | | sed -E 's/^ commonName / Name /g' \ 118 | | sed -E 's/^ emailAddress / Email /g' \ 119 | | sed -E 's/^ organizationName / Organization /g' \ 120 | | sed -E 's/^ countryName / Country /g' 121 | 122 | } 123 | 124 | 125 | # List all identities found in the given directory 126 | list_identities() { 127 | if ! [[ -d "${1}" ]]; then 128 | fatal "Given identity directory doesn't contain any identities or does not exist (${1-})." 129 | fi 130 | for licert in "$1"/*.cert; do 131 | if [[ -f "$licert" ]]; then 132 | show_cert_information "$licert" 133 | else 134 | fatal "Found corrupted or missing identity certificates in '$1'. Has this crate been sealed yet?" 135 | fi 136 | done 137 | } 138 | -------------------------------------------------------------------------------- /src/init.sh: -------------------------------------------------------------------------------- 1 | PROJECT_NAME="carnet" 2 | PROJECT_TITLE="Carnet: Bureaucracy for Cargo" 3 | PROJECT_VERSION="0.3.6" 4 | PROJECT_DATE="2021-05-24" 5 | COPYRIGHT="Copyright © 2021 Kutometa SPC, Kuwait" 6 | DESCRIPTION="Carnet is a small tool that imposes additional 7 | security constraints on Rust's official package 8 | manager, Cargo. This tool aims to prevent or 9 | otherwise limit the damage malicious crates can 10 | cause." 11 | 12 | COPYRIGHT_BLURB=" 13 | $PROJECT_NAME $PROJECT_VERSION 14 | $COPYRIGHT 15 | 16 | Unless otherwise expressly stated, this work and all related 17 | material are made available to you under the terms of version 3 18 | of the GNU Lesser General Public License (hereinafter, the 19 | LGPL-3.0) and the following supplemental terms: 20 | 21 | 1. This work must retain all legal notices. These notices must 22 | not be altered or truncated in any way. 23 | 24 | 2. The origin of any derivative or modified versions of this 25 | work must not be presented in a way that may mislead a 26 | reasonable person into mistaking the derive work to originate 27 | from Kutometa or the authors of this work. 28 | 29 | 3. Derivative or modified versions of this work must be clearly 30 | and easily distinguishable from the original work by a 31 | reasonable person. 32 | 33 | 4. Unless express permission is granted in writing, The name of 34 | the original work may not be used within the name of any 35 | derivative or modified version of the work. 36 | 37 | 5. Unless express permission is granted in writing, Trade names, 38 | trademarks, and service marks used in this work may not be 39 | included in any derivative or modified versions of this work. 40 | 41 | 6. Unless express permission is granted in writing, the names and 42 | trademarks of Kutometa and other right holders may not be used 43 | to endorse derivative or modified versions of this work. 44 | 45 | 7. The licensee must defend, indemnify, and hold harmless 46 | Kutometa and authors of this software from any and all 47 | actions, claims, judgments, losses, penalties, liabilities, 48 | damages, expenses, demands, fees (including, but not limited 49 | to, reasonable legal and other professional fees), taxes, and 50 | cost that result from or in connection with any liability 51 | imposed on Kutometa or other authors of this software as a 52 | result of the licensee conveying this work or a derivative 53 | thereof with contractual assumptions of liability to a third 54 | party recipient. 55 | 56 | Unless expressly stated otherwise or required by applicable law, 57 | this work is provided AS-IS with NO WARRANTY OF ANY KIND, 58 | INCLUDING THE WARRANTY OF MERCHANTABILITY AND FITNESS FOR A 59 | PARTICULAR PURPOSE. Use this work at your own risk. 60 | 61 | This license agreement is governed by and is construed in 62 | accordance with the laws of the state of Kuwait. You must submit 63 | all disputes arising out of or in connection with this work to 64 | the exclusive jurisdiction of the courts of Kuwait. 65 | 66 | You should have received a copy of the LGPL-3.0 along with this 67 | program; if not, visit www.ka.com.kw/en/legal, write to 68 | legal@ka.com.kw, or write to Kutometa SPC, 760 SAFAT 13008, 69 | Kuwait. 70 | 71 | " 72 | 73 | set -euH 74 | set -o pipefail 75 | 76 | HASH_ALGORITHMS=(\ 77 | "sha256"\ 78 | "sha384"\ 79 | ) 80 | 81 | 82 | #exec 59>/tmp/logszz 83 | #export BASH_XTRACEFD=59 84 | #set -x 85 | 86 | if [[ -t 0 ]] && [[ -t 1 ]] && [[ -t 2 ]]; then 87 | RED="\e[1;31m" 88 | GREEN="\e[1;32m" 89 | YELLOW="\e[1;33m" 90 | WEIRD="\e[1;44m" 91 | DIM="\e[2m" 92 | BOLD="\e[1m" 93 | RESET="\e[0m" 94 | fi 95 | 96 | -------------------------------------------------------------------------------- /src/io.sh: -------------------------------------------------------------------------------- 1 | # IO functions and general process control 2 | 3 | step_message() { 4 | printf "${GREEN-}%12s${RESET-} %s\n" "$1" "$2" 1>&2 5 | } 6 | 7 | fail() { 8 | printf "\r${RED-}%s${RESET-} %s\n" "$1" "$2" 1>&2 9 | exit 107 10 | } 11 | 12 | ignored_step_message() { 13 | printf "${YELLOW-}%12s${RESET-} %s\n" "$1" "$2" 1>&2 14 | } 15 | 16 | fatal() { 17 | printf "${RED-}error${RESET-}${BOLD-}:${RESET-} ${DIM-} -- $PROJECT_NAME -- ${RESET-} $*\n" 1>&2 18 | exit 107 19 | } 20 | 21 | warn() { 22 | printf "${YELLOW-}warning${RESET-}${BOLD-}:${RESET-} ${DIM-} -- $PROJECT_NAME -- ${RESET-} $*\n" 1>&2 23 | } 24 | 25 | debug() { 26 | if [[ "${DEBUG-}" == "yes" ]]; then 27 | printf "${DIM-}verbose: -- $PROJECT_NAME -- $*${RESET-}\n" 1>&2 28 | fi 29 | } 30 | 31 | # 32 | prompt_yes_no() { 33 | read -r ANSWER 34 | if [[ "$ANSWER" == "${1-yes}" ]]; then 35 | return 0 36 | else 37 | return 1 38 | fi 39 | } 40 | 41 | 42 | # prompt_yes_no_and_require_yes PROMT Strings 43 | # Ask the user a yes/no question 44 | prompt_yes_no_and_require_yes() { 45 | printf "$* (enter 'yes' and hit the Enter key to continue) " 46 | if ! prompt_yes_no; then 47 | fatal "'yes' was not given. Aborting." 48 | fi 49 | } 50 | 51 | 52 | -------------------------------------------------------------------------------- /src/main.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Carnet © 2021 Kutometa SPC, Kuwait 4 | # 5 | # Unless otherwise expressly stated, this work and all related 6 | # material are made available to you under the terms of version 3 7 | # of the GNU Lesser General Public License (hereinafter, the 8 | # LGPL-3.0) and the following supplemental terms: 9 | # 10 | # 1. This work must retain all legal notices. These notices must 11 | # not be altered or truncated in any way. 12 | # 13 | # 2. The origin of any derivative or modified versions of this 14 | # work must not be presented in a way that may mislead a 15 | # reasonable person into mistaking the derive work to originate 16 | # from Kutometa or the authors of this work. 17 | # 18 | # 3. Derivative or modified versions of this work must be clearly 19 | # and easily distinguishable from the original work by a 20 | # reasonable person. 21 | # 22 | # 4. Unless express permission is granted in writing, The name of 23 | # the original work may not be used within the name of any 24 | # derivative or modified version of the work. 25 | # 26 | # 5. Unless express permission is granted in writing, Trade names, 27 | # trademarks, and service marks used in this work may not be 28 | # included in any derivative or modified versions of this work. 29 | # 30 | # 6. Unless express permission is granted in writing, the names and 31 | # trademarks of Kutometa and other right holders may not be used 32 | # to endorse derivative or modified versions of this work. 33 | # 34 | # 7. The licensee must defend, indemnify, and hold harmless 35 | # Kutometa and authors of this software from any and all 36 | # actions, claims, judgments, losses, penalties, liabilities, 37 | # damages, expenses, demands, fees (including, but not limited 38 | # to, reasonable legal and other professional fees), taxes, and 39 | # cost that result from or in connection with any liability 40 | # imposed on Kutometa or other authors of this software as a 41 | # result of the licensee conveying this work or a derivative 42 | # thereof with contractual assumptions of liability to a third 43 | # party recipient. 44 | # 45 | # Unless expressly stated otherwise or required by applicable law, 46 | # this work is provided AS-IS with NO WARRANTY OF ANY KIND, 47 | # INCLUDING THE WARRANTY OF MERCHANTABILITY AND FITNESS FOR A 48 | # PARTICULAR PURPOSE. Use this work at your own risk. 49 | # 50 | # This license agreement is governed by and is construed in 51 | # accordance with the laws of the state of Kuwait. You must submit 52 | # all disputes arising out of or in connection with this work to 53 | # the exclusive jurisdiction of the courts of Kuwait. 54 | # 55 | # You should have received a copy of the LGPL-3.0 along with this 56 | # program; if not, visit www.ka.com.kw/en/legal, write to 57 | # legal@ka.com.kw, or write to Kutometa SPC, 760 SAFAT 13008, 58 | # Kuwait. 59 | # 60 | 61 | 62 | source "misc/warning-message.sh" 63 | source "init.sh" 64 | source "trap.sh" 65 | source "io.sh" 66 | source "dependencies.sh" 67 | source "fingerprint.sh" 68 | source "help.sh" 69 | source "trust.sh" 70 | source "packaging.sh" 71 | source "ownership.sh" 72 | source "identity.sh" 73 | source "configuration.sh" 74 | source "authentication.sh" 75 | source "session.sh" 76 | source "sandboxing.sh" 77 | #source "commands/authentication.sh" 78 | 79 | 80 | 81 | # Find Cargo Directory 82 | KNOWN_CRATE_STATE="" # If set to 'found', the crate has been 83 | # 'seen'/registered by carnet on this system 84 | 85 | KNOWN_CRATE_PATH="." # Presumed root of carnet-initialized crate 86 | # root. This value is an untrustworthy 87 | # assumption unless KNOWN_CRATE_STATE is set 88 | # to "found". 89 | 90 | KNOWN_CRATE_PATH_HASH="" # Presumed path hash of carnet-initialized crate 91 | # root. This value is an untrustworthy 92 | # assumption unless KNOWN_CRATE_STATE is set 93 | # to "found". 94 | # 95 | # path hashes are what carnet uses to track 96 | # seen/registered crates on this system 97 | 98 | KNOWN_CRATE_ORIGIN="foreign" # Can be 'foreign', 'local', '', or any 99 | # other value. Used for crate authentication 100 | # and signing (sealing). 101 | 102 | SANDBOX_ALL="yes" # If yes, apply the most restrictive sandboxing 103 | # possible. This includes sandboxing resources 104 | # that aren't currently controllable by the user. 105 | # 106 | # You need to set this to no whenever granularity 107 | # is needed. 108 | 109 | SANDBOX_FILESYSTEM="yes" 110 | 111 | SANDBOX_NETWRORK="yes" 112 | 113 | SANDBOX_PROCESSES="yes" 114 | 115 | SANDBOX_SESSION="yes" 116 | 117 | SANDBOX_CARGO_HOME="yes" 118 | 119 | SANDBOX_RO_PATHS="" 120 | 121 | SANDBOX_RW_PATHS="" 122 | 123 | USERCONFIGDIR="$HOME/.config/kw.com.ka.$PROJECT_NAME" # Where "seen"/registered crates are tracked, user keys are stored, and all other "user" state maintained. 124 | 125 | DISABLE_AUTOVERIFICATION="no" # Disables automatic verification. 126 | # Manually set to yes when the appropriate 127 | # flag is given, and automatically set to yes 128 | # when the appropriate user configuration 129 | # setting is set or when a dev session is active. 130 | 131 | DISABLE_SANDBOX="no" # Disables sandboxing (bypassing bublewrap entirely) 132 | # Manually set to yes when the appropriate 133 | # flag is given, and automatically set to yes 134 | # when the appropriate user configuration 135 | # setting is set. 136 | 137 | COMMAND="" # The primary command carnet is supposed to execute. 138 | 139 | NEW_DEV_SESSION="no" # If set to yes, automatically start/extend a dev 140 | # session where autoverification is set to no. 141 | 142 | LOCAL_IDENTITY_CERT_PATH="" # The certificate used for signatures when sealing 143 | # a local crate. 144 | 145 | LOCAL_IDENTITY_PUBKEY_PATH="" # The public key used when sealing 146 | # a local crate. You should remove this in favor 147 | # of maintaining a single source of truth 148 | # LOCAL_IDENTITY_CERT_PATH 149 | 150 | LOCAL_IDENTITY_PRIVKEY_PATH="" # The private key used for signatures when sealing 151 | # a local crate. 152 | 153 | LOCAL_IDENTITY_FINGERPRINT="" # The local identity fingerprint used when sealing 154 | # a local crate. 155 | 156 | PINNED_OWNER_IDENTITY_FINGERPRINT="" # If set, only verify crates against this identity 157 | # and no other when verifying crates. 158 | 159 | declare -a UNHANDLED_NON_OPTIONS; # Any non-option (not prefixed by a dash) 160 | # that isn't consumed by carnet. '--cargo:'-style 161 | # flags are converted to their unprefixed counterparts 162 | 163 | declare -a FILTERED_ARGS # All arguments that aren't consumed by carnet. This 164 | # array is a superset of UNHANDLED_NON_OPTIONS. 165 | # '--cargo:'-style flags are converted to their 166 | # unprefixed counterparts. 167 | 168 | END_OF_OPTIONS="no" # Used when processing cli args. If set to 'yes', 169 | # treat args as opaque strings, possibly passing 170 | # them to cargo as-is with the exception of 171 | # '--cargo:' style flags which are converted to 172 | # normal cargo flags. 173 | 174 | # Sort CLI arguments. Set appropriate flags/vars if args are relevant or sort them into FILTERED_ARGS and UNHANDLED_NON_OPTIONS buckets 175 | for arg in "$@"; do 176 | if [[ "$END_OF_OPTIONS" == "no" ]] && ( [[ "$arg" == "--$PROJECT_NAME:disable-sandbox" ]] || [[ "$arg" == "--disable-sandbox" ]] ); then 177 | DISABLE_SANDBOX="yes" 178 | 179 | elif [[ "$END_OF_OPTIONS" == "no" ]] && ( [[ "$arg" == "--$PROJECT_NAME:disable-verification" ]] || [[ "$arg" == "--disable-verification" ]] ); then 180 | DISABLE_AUTOVERIFICATION="yes" 181 | 182 | elif [[ "$END_OF_OPTIONS" == "no" ]] && ( [[ "$arg" == "--$PROJECT_NAME:unsandbox-cargo-home" ]] || [[ "$arg" == "--unsandbox-cargo-home" ]] ); then 183 | SANDBOX_CARGO_HOME="no" 184 | SANDBOX_ALL="no" 185 | 186 | elif [[ "$END_OF_OPTIONS" == "no" ]] && ( [[ "$arg" == "--$PROJECT_NAME:unsandbox-filesystem" ]] || [[ "$arg" == "--unsandbox-filesystem" ]] ); then 187 | SANDBOX_FILESYSTEM="no" 188 | SANDBOX_ALL="no" 189 | 190 | elif [[ "$END_OF_OPTIONS" == "no" ]] && ( [[ "$arg" == "--$PROJECT_NAME:unsandbox-processes" ]] || [[ "$arg" == "--unsandbox-processes" ]] ); then 191 | SANDBOX_PROCESS="no" 192 | SANDBOX_ALL="no" 193 | 194 | elif [[ "$END_OF_OPTIONS" == "no" ]] && ( [[ "$arg" == "--$PROJECT_NAME:unsandbox-network" ]] || [[ "$arg" == "--unsandbox-network" ]] ); then 195 | SANDBOX_NETWORK="no" 196 | SANDBOX_ALL="no" 197 | 198 | elif [[ "$END_OF_OPTIONS" == "no" ]] && ( [[ "$arg" == "--$PROJECT_NAME:unsandbox-session" ]] || [[ "$arg" == "--unsandbox-session" ]] ) ; then 199 | SANDBOX_SESSION="no" 200 | SANDBOX_ALL="no" 201 | 202 | elif [[ "$END_OF_OPTIONS" == "no" ]] && ( [[ "$arg" == "--$PROJECT_NAME:verbose" ]] || [[ "$arg" == "--verbose" ]] ); then 203 | DEBUG="yes" 204 | 205 | elif [[ "$END_OF_OPTIONS" == "no" ]] && [[ "$arg" =~ ^--$PROJECT_NAME:config-dir= ]]; then 206 | USERCONFIGDIR="${arg:20}" 207 | if ! [[ -d "$(dirname "$USERCONFIGDIR" 2>/dev/null || true)" ]]; then 208 | fatal "Cannot find parent directory for '$USERCONFIGDIR'" 209 | fi 210 | USERCONFIGDIR="$(realpath -- "${USERCONFIGDIR}")" 211 | 212 | elif [[ "$END_OF_OPTIONS" == "no" ]] && [[ "$arg" =~ ^--config-dir= ]]; then 213 | USERCONFIGDIR="${arg:13}" 214 | if ! [[ -d "$(dirname "$USERCONFIGDIR" 2>/dev/null || true)" ]]; then 215 | fatal "Cannot find parent directory for '$USERCONFIGDIR'" 216 | fi 217 | USERCONFIGDIR="$(realpath -- "${USERCONFIGDIR}")" 218 | 219 | elif [[ "$END_OF_OPTIONS" == "no" ]] && [[ "$arg" =~ ^--$PROJECT_NAME:pinned-owner= ]]; then 220 | PINNED_OWNER_IDENTITY_FINGERPRINT="${arg:22}" 221 | 222 | elif [[ "$END_OF_OPTIONS" == "no" ]] && [[ "$arg" =~ ^--pinned-owner= ]]; then 223 | PINNED_OWNER_IDENTITY_FINGERPRINT="${arg:15}" 224 | 225 | elif [[ "$END_OF_OPTIONS" == "no" ]] && [[ "$arg" =~ ^--$PROJECT_NAME:ro-paths= ]]; then 226 | SANDBOX_RO_PATHS="${arg:18}" 227 | 228 | elif [[ "$END_OF_OPTIONS" == "no" ]] && [[ "$arg" =~ ^--ro-paths= ]]; then 229 | SANDBOX_RO_PATHS="${arg:11}" 230 | 231 | elif [[ "$END_OF_OPTIONS" == "no" ]] && [[ "$arg" =~ ^--$PROJECT_NAME:rw-paths= ]]; then 232 | SANDBOX_RW_PATHS="${arg:18}" 233 | 234 | elif [[ "$END_OF_OPTIONS" == "no" ]] && [[ "$arg" =~ ^--rw-paths= ]]; then 235 | SANDBOX_RW_PATHS="${arg:11}" 236 | 237 | elif [[ "$END_OF_OPTIONS" == "no" ]] && ! [[ "${COMMAND}" ]] && ( [[ "$arg" == "--$PROJECT_NAME:help" ]] || [[ "$arg" == "$PROJECT_NAME:help" ]] ) ; then 238 | if ! [[ "${COMMAND}" ]]; then COMMAND="help"; fi 239 | 240 | elif [[ "$END_OF_OPTIONS" == "no" ]] && ! [[ "${COMMAND}" ]] && ( [[ "$arg" == "--help" ]] || [[ "$arg" == "help" ]] || [[ "$arg" == "-h" ]]) ; then 241 | if ! [[ "${COMMAND}" ]]; then COMMAND="cargo-help"; fi 242 | 243 | elif [[ "$END_OF_OPTIONS" == "no" ]] && ! [[ "${COMMAND}" ]] && ( [[ "$arg" == "$PROJECT_NAME:sandbox-run" ]] || [[ "$arg" == "sandbox-run" ]] ); then 244 | if ! [[ "${COMMAND}" ]]; then COMMAND="sandbox-run"; fi 245 | 246 | elif [[ "$END_OF_OPTIONS" == "no" ]] && ! [[ "${COMMAND}" ]] && ( [[ "$arg" == "$PROJECT_NAME:seal" ]] || [[ "$arg" == "seal" ]] ); then 247 | if ! [[ "${COMMAND}" ]]; then COMMAND="seal"; fi 248 | 249 | elif [[ "$END_OF_OPTIONS" == "no" ]] && ! [[ "${COMMAND}" ]] && ( [[ "$arg" == "$PROJECT_NAME:disable" ]] || [[ "$arg" == "disable" ]] ); then 250 | if ! [[ "${COMMAND}" ]]; then COMMAND="disable"; fi 251 | 252 | elif [[ "$END_OF_OPTIONS" == "no" ]] && ! [[ "${COMMAND}" ]] && ( [[ "$arg" == "$PROJECT_NAME:enable" ]] || [[ "$arg" == "enable" ]] ); then 253 | if ! [[ "${COMMAND}" ]]; then COMMAND="enable"; fi 254 | 255 | elif [[ "$END_OF_OPTIONS" == "no" ]] && ! [[ "${COMMAND}" ]] && ( [[ "$arg" == "$PROJECT_NAME:verify" ]] || [[ "$arg" == "verify" ]] ); then 256 | if ! [[ "${COMMAND}" ]]; then COMMAND="verify"; fi 257 | 258 | elif [[ "$END_OF_OPTIONS" == "no" ]] && ! [[ "${COMMAND}" ]] && ( [[ "$arg" == "$PROJECT_NAME:owners" ]] || [[ "$arg" == "owners" ]] ); then 259 | if ! [[ "${COMMAND}" ]]; then COMMAND="list-owners"; fi 260 | 261 | elif [[ "$END_OF_OPTIONS" == "no" ]] && ! [[ "${COMMAND}" ]] && ( [[ "$arg" == "$PROJECT_NAME:files" ]] || [[ "$arg" == "files" ]] ); then 262 | if ! [[ "${COMMAND}" ]]; then COMMAND="list-seal-files"; fi 263 | 264 | elif [[ "$END_OF_OPTIONS" == "no" ]] && ! [[ "${COMMAND}" ]] && ( [[ "$arg" == "$PROJECT_NAME:own" ]] || [[ "$arg" == "own" ]] ); then 265 | if ! [[ "${COMMAND}" ]]; then COMMAND="own"; fi 266 | 267 | elif [[ "$END_OF_OPTIONS" == "no" ]] && ! [[ "${COMMAND}" ]] && ( [[ "$arg" == "$PROJECT_NAME:disown" ]] || [[ "$arg" == "disown" ]] ); then 268 | if ! [[ "${COMMAND}" ]]; then COMMAND="disown"; fi 269 | 270 | elif [[ "$END_OF_OPTIONS" == "no" ]] && ! [[ "${COMMAND}" ]] && ( [[ "$arg" == "$PROJECT_NAME:distrust" ]] || [[ "$arg" == "distrust" ]] ); then 271 | if ! [[ "${COMMAND}" ]]; then COMMAND="distrust"; fi 272 | 273 | elif [[ "$END_OF_OPTIONS" == "no" ]] && ! [[ "${COMMAND}" ]] && ( [[ "$arg" == "$PROJECT_NAME:init" ]] || [[ "$arg" == "init" ]] ); then 274 | if ! [[ "${COMMAND}" ]]; then COMMAND="init"; fi 275 | 276 | elif [[ "$END_OF_OPTIONS" == "no" ]] && ! [[ "${COMMAND}" ]] && ( [[ "$arg" == "$PROJECT_NAME:uninit" ]] || [[ "$arg" == "uninit" ]] ) ; then 277 | if ! [[ "${COMMAND}" ]]; then COMMAND="uninit"; fi 278 | 279 | elif [[ "$END_OF_OPTIONS" == "no" ]] && ! [[ "${COMMAND}" ]] && ( [[ "$arg" == "$PROJECT_NAME:identity" ]] || [[ "$arg" == "identity" ]] ); then 280 | if ! [[ "${COMMAND}" ]]; then COMMAND="identity"; fi 281 | 282 | elif [[ "$END_OF_OPTIONS" == "no" ]] && ! [[ "${COMMAND}" ]] && ( [[ "$arg" == "--$PROJECT_NAME:version" ]] || [[ "$arg" == "--version" ]] ); then 283 | if ! [[ "${COMMAND}" ]]; then COMMAND="version"; fi 284 | 285 | elif [[ "$END_OF_OPTIONS" == "no" ]] && ! [[ "${COMMAND}" ]] && ( [[ "$arg" == "--$PROJECT_NAME:legal" ]] || [[ "$arg" == "--legal" ]] ); then 286 | if ! [[ "${COMMAND}" ]]; then COMMAND="legal"; fi 287 | 288 | elif [[ "$END_OF_OPTIONS" == "no" ]] && ! [[ "${COMMAND}" ]] && ( [[ "$arg" == "$PROJECT_NAME:edit" ]] || [[ "$arg" == "edit" ]] ); then 289 | if ! [[ "${COMMAND}" ]]; then COMMAND="edit"; fi 290 | 291 | elif [[ "$END_OF_OPTIONS" == "no" ]] && ! [[ "${COMMAND}" ]] && ( [[ "$arg" == "$PROJECT_NAME:done" ]] || [[ "$arg" == "done" ]] ); then 292 | if ! [[ "${COMMAND}" ]]; then COMMAND="done"; fi 293 | 294 | elif [[ "$END_OF_OPTIONS" == "no" ]] && [[ "$arg" == "--$PROJECT_NAME:end" ]]; then 295 | END_OF_OPTIONS="yes" 296 | 297 | else 298 | if [[ "$arg" == "--" ]]; then 299 | END_OF_OPTIONS="yes" 300 | fi 301 | # strip namespaced cargo args 302 | if [[ "$END_OF_OPTIONS" == "no" ]]; then 303 | arg="$(printf "%s\n" "$arg" | sed 's/^--cargo:/--/g' | sed 's/^cargo://g')" 304 | fi 305 | # collect a copy of arg in UNHANDLED_NON_OPTIONS if it isn't a flag 306 | if ! [[ "$arg" =~ ^- ]]; then 307 | UNHANDLED_NON_OPTIONS=("${UNHANDLED_NON_OPTIONS[@]}" "$arg") 308 | fi 309 | FILTERED_ARGS=( "${FILTERED_ARGS[@]}" "$arg" ) 310 | fi 311 | done 312 | 313 | if ! [[ "${CARGO_PATH-}" ]]; then 314 | CARGO_PATH=$(which "cargo") || { 315 | fatal "Could not find cargo in PATH." 316 | } 317 | fi 318 | 319 | debug "Carnet command selected was '$COMMAND'. If empty, this means that this is a direct cargo pass though."; 320 | 321 | if [[ "$COMMAND" == "cargo-help" ]] || [[ "$#" -eq 0 ]]; then 322 | # TODO sandbox 323 | "$CARGO_PATH" "help" 324 | printf "%s\n\n" "See '$PROJECT_NAME $PROJECT_NAME:help' or '$PROJECT_NAME --$PROJECT_NAME:help' for more information about options and commands that are specific to carnet." 325 | exit 0 326 | elif [[ "$COMMAND" == "help" ]]; then 327 | printf "$HELP\n" | less -R 328 | exit 0 329 | elif [[ "$COMMAND" == "version" ]]; then 330 | echo "$PROJECT_NAME $PROJECT_VERSION ($PROJECT_DATE NCA)" 331 | # TODO sandbox 332 | "$CARGO_PATH" version 333 | exit 0 334 | elif [[ "$COMMAND" == "legal" ]]; then 335 | echo "$COPYRIGHT_BLURB" 336 | exit 0 337 | 338 | fi 339 | 340 | if ! [[ -d "$USERCONFIGDIR" ]]; then 341 | debug "Could not find identity directory '$USERCONFIGDIR'. Setting up new identity..." 342 | printf " 343 | This appears to be the first time Carnet runs on this system. 344 | Before you continue, you need to provide some information to 345 | generate a new identity for you. This information is shown to 346 | other users when they attempt to verify your crates for the first 347 | time. 348 | 349 | This information cannot be changed once the identity has been 350 | generated. 351 | " 352 | 353 | if ! [[ "${CARNET_PUBLISHER_NAME-}" ]]; then 354 | while true; do 355 | printf " 356 | What is your name? 357 | 358 | [ ]\r [ " 359 | read -r CARNET_PUBLISHER_NAME 360 | if [[ "$CARNET_PUBLISHER_NAME" ]]; then 361 | break 362 | else 363 | printf "\n" 364 | warn "A name is needed to generate a new Identity." 365 | fi 366 | done 367 | fi 368 | 369 | 370 | if ! [[ "${CARNET_PUBLISHER_EMAIL-}" ]]; then 371 | while true; do 372 | printf " 373 | What email address would you like to include? 374 | 375 | [ ]\r [ " 376 | read -r CARNET_PUBLISHER_EMAIL 377 | if [[ "$CARNET_PUBLISHER_EMAIL" ]]; then 378 | break 379 | else 380 | printf "\n" 381 | warn "An email address is needed to generate a new Identity." 382 | fi 383 | done 384 | fi 385 | 386 | 387 | if ! [[ "${CARNET_PUBLISHER_ORG-}" ]]; then 388 | printf " 389 | What is the name of your organization? (You can leave this empty) 390 | 391 | [ ]\r [ " 392 | read -r CARNET_PUBLISHER_ORG 393 | fi 394 | 395 | 396 | if ! [[ "${CARNET_PUBLISHER_COUNTRY-}" ]]; then 397 | printf " 398 | What is the two-letter ISO code of your country? (You can leave 399 | this empty) 400 | 401 | [ ]\r [ " 402 | read -r CARNET_PUBLISHER_COUNTRY 403 | fi 404 | 405 | 406 | 407 | mkdir -p "$USERCONFIGDIR" 408 | chmod 700 "$USERCONFIGDIR" 409 | printf "%s\n" "Generating new identity keys.." 410 | 411 | x509_escape() { 412 | printf "%s\n" "$1" | sed -E 's/([\/,;])/\\\1/g' 413 | } 414 | X509_CN="/CN=$(x509_escape "$CARNET_PUBLISHER_NAME")" 415 | X509_EMAIL="/emailAddress=$(x509_escape "$CARNET_PUBLISHER_EMAIL")" 416 | X509_O="" 417 | if [[ "$CARNET_PUBLISHER_ORG" ]]; then 418 | X509_O="/O=$(x509_escape "$CARNET_PUBLISHER_ORG")" 419 | fi 420 | X509_C="" 421 | if [[ "$CARNET_PUBLISHER_COUNTRY" ]]; then 422 | X509_C="/C=$(x509_escape "$CARNET_PUBLISHER_COUNTRY")" 423 | fi 424 | 425 | if [[ "${CARNET_UNSTABLE_RSA_BITS-}" ]]; then 426 | warn "WARNING: rsa key length is set to ${CARNET_UNSTABLE_RSA_BITS}" 427 | fi 428 | 429 | if ! openssl req -x509 \ 430 | -newkey "rsa:${CARNET_UNSTABLE_RSA_BITS:-8192}" \ 431 | -utf8 \ 432 | -nameopt multiline,utf8 \ 433 | -keyout "$USERCONFIGDIR/identity.key" \ 434 | -out "$USERCONFIGDIR/identity.cert" \ 435 | -days 100000 \ 436 | -sha384 \ 437 | -nodes \ 438 | -subj "${X509_CN}${X509_EMAIL}${X509_O}${X509_C}" \ 439 | -addext "keyUsage = digitalSignature" \ 440 | -addext "extendedKeyUsage = codeSigning" \ 441 | 1>&2; then 442 | #-subj "/" 1>&2; then 443 | fatal "Failed to generate a new certificate" 444 | fi 445 | openssl x509 -pubkey -noout -in "$USERCONFIGDIR/identity.cert" > "$USERCONFIGDIR/identity.pub" 446 | chmod 600 "$USERCONFIGDIR/identity.key" 447 | fi 448 | 449 | LOCAL_IDENTITY_CERT_PATH="$USERCONFIGDIR/identity.cert" 450 | LOCAL_IDENTITY_PUBKEY_PATH="$USERCONFIGDIR/identity.pub" 451 | LOCAL_IDENTITY_PRIVKEY_PATH="$USERCONFIGDIR/identity.key" 452 | LOCAL_IDENTITY_FINGERPRINT="$( file_fingerprint "$LOCAL_IDENTITY_CERT_PATH")" 453 | 454 | CONFIGURATION_DISABLED_VERIFICATION_PATH="$USERCONFIGDIR/settings/verification.setting" 455 | CONFIGURATION_DISABLED_SANDBOXING_PATH="$USERCONFIGDIR/settings/sandbox.setting" 456 | CONFIGURATION_EULA_AGREEMENT_PATH="$USERCONFIGDIR/settings/eula-agreement.setting" 457 | CONFIGURATION_DISABLED_VERIFICATION="$( if [[ -f "$CONFIGURATION_DISABLED_VERIFICATION_PATH" ]]; then cat "$CONFIGURATION_DISABLED_VERIFICATION_PATH"; fi )" 458 | CONFIGURATION_DISABLED_SANDBOXING="$( if [[ -f "$CONFIGURATION_DISABLED_SANDBOXING_PATH" ]]; then cat "$CONFIGURATION_DISABLED_SANDBOXING_PATH"; fi )" 459 | CONFIGURATION_EULA_AGREEMENT="$( if [[ -f "$CONFIGURATION_EULA_AGREEMENT_PATH" ]]; then cat "$CONFIGURATION_EULA_AGREEMENT_PATH"; fi )" 460 | 461 | 462 | source "setup-and-upgrade-scripts.sh" 463 | 464 | 465 | if [[ "${CONFIGURATION_DISABLED_VERIFICATION-}" == "disabled" ]]; then 466 | debug "Disabling automatic verification because ${CONFIGURATION_DISABLED_VERIFICATION_PATH} is set to disabled." 467 | DISABLE_AUTOVERIFICATION="yes" 468 | fi 469 | 470 | if [[ "${CONFIGURATION_DISABLED_SANDBOXING-}" == "disabled" ]]; then 471 | debug "Disabling sandbox because ${CONFIGURATION_DISABLED_SANDBOXING_PATH} is set to disabled." 472 | DISABLE_SANDBOX="yes" 473 | fi 474 | 475 | 476 | 477 | # Starting proper... 478 | if [[ "$COMMAND" ]]; then 479 | if [[ "$COMMAND" == "sandbox-run" ]]; then 480 | KNOWN_CRATE_PATH="." 481 | locate_known_crate_from_the_inside_and_set_up_global_variables 482 | sandbox "${FILTERED_ARGS[@]}" || exit "$?" 483 | 484 | elif [[ "$COMMAND" == "enable" ]] || [[ "$COMMAND" == "disable" ]]; then 485 | configuration_settings "$COMMAND" "${FILTERED_ARGS[@]}" 486 | 487 | elif [[ "$COMMAND" == "help" ]]; then 488 | printf "$HELP\n" | less -R 1>&2 489 | 490 | elif [[ "$COMMAND" == "seal" ]]; then 491 | KNOWN_CRATE_PATH="." 492 | locate_known_crate_from_the_inside_and_set_up_global_variables 493 | if [[ "$KNOWN_CRATE_ORIGIN" != "local" ]]; then 494 | fatal "You cannot seal crates you don't own. To own this crate, run $PROJECT_NAME $PROJECT_NAME:own. ($KNOWN_CRATE_PATH)" 495 | fi 496 | seal 497 | verify 498 | elif [[ "$COMMAND" == "init" ]]; then 499 | KNOWN_CRATE_PATH="." 500 | locate_known_crate_from_the_inside_and_set_up_global_variables 501 | crate_root="${UNHANDLED_NON_OPTIONS[0]:-.}" 502 | if ! [[ -d "$crate_root" ]]; then 503 | fatal "'$crate_root' is not a directory" 504 | fi 505 | if ! [[ -f "$crate_root/Cargo.toml" ]]; then 506 | warn "'$crate_root' doesn't seem to be a rust crate (no Cargo.toml). Proceeding anyway." 507 | fi 508 | initialize_crate "$crate_root" 509 | trust_crate "$crate_root" 510 | own_crate "$crate_root" 511 | elif [[ "$COMMAND" == "uninit" ]]; then 512 | KNOWN_CRATE_PATH="." 513 | locate_known_crate_from_the_inside_and_set_up_global_variables 514 | prompt_yes_no_and_require_yes "This command will remove this crate from" \ 515 | "your system's list of trusted crates. This"\ 516 | "command will also remove any cached"\ 517 | "identities. Would you like to proceed?" 518 | uninitialize_crate "${UNHANDLED_NON_OPTIONS[0]:-.}" 519 | 520 | elif [[ "$COMMAND" == "verify" ]]; then 521 | KNOWN_CRATE_PATH="." 522 | locate_known_crate_from_the_inside_and_set_up_global_variables 523 | verify 524 | 525 | elif [[ "$COMMAND" == "list-owners" ]]; then 526 | KNOWN_CRATE_PATH="." 527 | locate_known_crate_from_the_inside_and_set_up_global_variables 528 | if ! [[ "${KNOWN_CRATE_STATE-}" ]] || [[ "$KNOWN_CRATE_STATE" != "found" ]]; then 529 | fatal "Could not find a registered crate in '$PWD' or any parent directory" 530 | fi 531 | list_identities "$KNOWN_CRATE_PATH/.carnet/owners" 532 | printf "\n" 533 | elif [[ "$COMMAND" == "identity" ]]; then 534 | printf "Identity = ${LOCAL_IDENTITY_FINGERPRINT}" 535 | show_cert_information "$LOCAL_IDENTITY_CERT_PATH" "identity-mode" | sed -E 's/ +/ /g' | sed -E 's/^ //g' 536 | 537 | elif [[ "$COMMAND" == "list-seal-files" ]]; then 538 | KNOWN_CRATE_PATH="." 539 | locate_known_crate_from_the_inside_and_set_up_global_variables 540 | generate_crate_seal_list "sha384" "$KNOWN_CRATE_PATH" | tr '\n' '␤' | tr '\0' '\n' | cut -d ' ' -f 1 541 | 542 | elif [[ "$COMMAND" == "own" ]]; then 543 | KNOWN_CRATE_PATH="." 544 | locate_known_crate_from_the_inside_and_set_up_global_variables 545 | own_crate "${UNHANDLED_NON_OPTIONS[0]:-$KNOWN_CRATE_PATH}" 546 | 547 | elif [[ "$COMMAND" == "disown" ]]; then 548 | KNOWN_CRATE_PATH="." 549 | locate_known_crate_from_the_inside_and_set_up_global_variables 550 | disown_crate "${UNHANDLED_NON_OPTIONS[0]:-$KNOWN_CRATE_PATH}" 551 | 552 | elif [[ "$COMMAND" == "distrust" ]]; then 553 | KNOWN_CRATE_PATH="." 554 | locate_known_crate_from_the_inside_and_set_up_global_variables 555 | prompt_yes_no_and_require_yes "This command will remove this crate from" \ 556 | "your system's list of trusted crates. This"\ 557 | "command will also remove any cached" \ 558 | "identities. Would you like to proceed?" 559 | distrust_crate "${UNHANDLED_NON_OPTIONS[0]:-$KNOWN_CRATE_PATH}" 560 | 561 | elif [[ "$COMMAND" == "edit" ]]; then 562 | KNOWN_CRATE_PATH="." 563 | locate_known_crate_from_the_inside_and_set_up_global_variables 564 | NEW_DEV_SESSION="yes" 565 | refresh_dev_session 566 | 567 | elif [[ "$COMMAND" == "done" ]]; then 568 | KNOWN_CRATE_PATH="." 569 | locate_known_crate_from_the_inside_and_set_up_global_variables 570 | clear_dev_session 571 | 572 | elif [[ "$COMMAND" == "version" ]]; then 573 | echo "$PROJECT_NAME $PROJECT_VERSION ($PROJECT_DATE NCA)" 574 | sandbox "$CARGO_PATH" version 575 | else 576 | fatal "INTERNAL BUG: Unknown $PROJECT_NAME command" 577 | fi 578 | else 579 | KNOWN_CRATE_PATH="." 580 | locate_known_crate_from_the_inside_and_set_up_global_variables 581 | refresh_dev_session 582 | 583 | if [[ "${UNHANDLED_NON_OPTIONS[0]-}" == "new" ]]; then 584 | 585 | sandbox "$CARGO_PATH" "${FILTERED_ARGS[@]}" || exit "$?" 586 | 587 | if ! [[ "${UNHANDLED_NON_OPTIONS[1]-}" ]] || ! [[ -f "${UNHANDLED_NON_OPTIONS[1]}/Cargo.toml" ]]; then 588 | fatal "Carnet has failed to setup your new crate properly. You can try to use cargo directly and then run $PROJECT_NAME carnet:init manually inside your new crate. Please consider reporting this issue if you can reproduce it." 589 | Please consider reporting this issue. 590 | fi 591 | initialize_crate "${UNHANDLED_NON_OPTIONS[1]}" 592 | trust_crate "${UNHANDLED_NON_OPTIONS[1]}" 593 | own_crate "${UNHANDLED_NON_OPTIONS[1]}" 594 | 595 | if ! [[ "${UNHANDLED_NON_OPTIONS[1]-}" ]] || ! [[ -d "${UNHANDLED_NON_OPTIONS[1]}/.carnet" ]]; then 596 | fatal "Carnet has failed to setup your new crate properly. Try to run $PROJECT_NAME carnet:init manually inside your new crate. Please consider reporting this issue if you can reproduce it." 597 | fi 598 | elif [[ "${UNHANDLED_NON_OPTIONS[0]-}" == "version" ]]; then 599 | echo "$PROJECT_NAME $PROJECT_VERSION ($PROJECT_DATE NCA)" 600 | sandbox "$CARGO_PATH" version 601 | elif [[ "${UNHANDLED_NON_OPTIONS[0]-}" == "help" ]]; then 602 | sandbox "$CARGO_PATH" "${FILTERED_ARGS[@]}" 603 | printf "%s\n\n" "See '$PROJECT_NAME $PROJECT_NAME:help' or '$PROJECT_NAME --$PROJECT_NAME:help' for more information about the options and commands that are specific to Carnet." 604 | else 605 | if ! [[ "${KNOWN_CRATE_STATE-}" ]] || [[ "$KNOWN_CRATE_STATE" != "found" ]]; then 606 | fatal "Could not find a registered crate in current directory or any parent directory.\n See 'carnet new' and 'carnet init' commands." 607 | fi 608 | if [[ "$DISABLE_AUTOVERIFICATION" != "yes" ]]; then 609 | verify 610 | else 611 | ignored_step_message "Verifying" "Automatic verification is disabled" 612 | fi 613 | sandbox "$CARGO_PATH" "${FILTERED_ARGS[@]}" || exit "$?" 614 | fi 615 | fi 616 | 617 | exit 0 618 | 619 | 620 | -------------------------------------------------------------------------------- /src/misc/warning-message.sh: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | # 6 | # 7 | # mm mm mm mmmmmm mmm mm mmmmmm mmm mm mmmm 8 | # ## ## #### ##""""## ### ## ""##"" ### ## ##""""# 9 | # "#m ## m#" #### ## ## ##"# ## ## ##"# ## ## 10 | # ## ## ## ## ## ####### ## ## ## ## ## ## ## ## mmmm 11 | # ###""### ###### ## "##m ## #m## ## ## #m## ## ""## 12 | # ### ### m## ##m ## ## ## ### mm##mm ## ### ##mmm## 13 | # """ """ "" "" "" """ "" """ """""" "" """ """" 14 | # 15 | # ################################################################ 16 | # ################################################################ 17 | # 18 | # 19 | # ⚠️ This script is automatically assembled from `./src` using 20 | # `./etc/assemble.sh`. 21 | # 22 | # ⚠️ Read `./CONTRIBUTING.en.md` for more information on how to 23 | # build and contribute. 24 | # 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/ownership.sh: -------------------------------------------------------------------------------- 1 | # Functionality for marking a _registered_ crate as belonging to the 2 | # user (i.e a local crate as aposed to a forgin crate). 3 | 4 | # own_crate PATH 5 | own_crate() { 6 | local CRATE_PATH="$(realpath -- "$1")" 7 | local new_crate_fingerprint="$( path_fingerprint "$CRATE_PATH" )" 8 | 9 | if ! [[ -f "$USERCONFIGDIR/known/$new_crate_fingerprint/registered" ]]; then 10 | fatal "Crate at '$CRATE_PATH' is not known or trusted or it does not exist." 11 | fi 12 | 13 | # Adding user's identity to the local cache 14 | mkdir -p "$USERCONFIGDIR/known/$new_crate_fingerprint/owners" 15 | copy_cert "$LOCAL_IDENTITY_CERT_PATH" "$USERCONFIGDIR/known/$new_crate_fingerprint/owners" 16 | # We don't need to copy cert into the crate itself since seal() does this automatically. 17 | 18 | 19 | # Updating cookies (files to make sure that local keys don't get messed up when the user moves directories) 20 | # 21 | mkdir -p "$USERCONFIGDIR/known/$new_crate_fingerprint/cookies.d" 22 | mkdir -p "$CRATE_PATH/.$PROJECT_NAME/cookies.d" 23 | local local_cookie="$(head -c 12 /dev/urandom | base64)" 24 | local crate_cookie="$(printf "%s\n" "$local_cookie" | sha384sum | cut -d ' ' -f 1 | head -c 24)" 25 | printf "%s\n" "$crate_cookie" > "$CRATE_PATH/.$PROJECT_NAME/cookies.d/$LOCAL_IDENTITY_FINGERPRINT.cookie" 26 | printf "%s\n" "$local_cookie" > "$USERCONFIGDIR/known/$new_crate_fingerprint/cookies.d/$LOCAL_IDENTITY_FINGERPRINT.cookie" 27 | 28 | # Updating origin 29 | printf "local\n" > "$USERCONFIGDIR/known/$new_crate_fingerprint/origin" 30 | 31 | step_message "Owned" "Claimed ownership over ($CRATE_PATH)" 32 | } 33 | 34 | # disown_crate PATH 35 | disown_crate() { 36 | local CRATE_PATH="$(realpath -- "$1")" 37 | local new_crate_fingerprint="$( path_fingerprint "$CRATE_PATH" )" 38 | if ! [[ -f "$USERCONFIGDIR/known/$new_crate_fingerprint/registered" ]]; then 39 | fatal "Crate at '$CRATE_PATH' is not known or trusted or it does not exist." 40 | fi 41 | 42 | printf "forign\n" > "$USERCONFIGDIR/known/$new_crate_fingerprint/origin" 43 | 44 | remove_certs "$new_crate_fingerprint" 45 | 46 | step_message "Disowned" "Disclaimed ownership over ($CRATE_PATH)" 47 | } 48 | -------------------------------------------------------------------------------- /src/packaging.sh: -------------------------------------------------------------------------------- 1 | # initialize_crate PATH 2 | # 3 | # This function initializes a plain cargo crate as a carnet crate 4 | # This function does not register the given crate with the system 5 | # use trust_crate. 6 | initialize_crate() { 7 | local CRATE_PATH="$(realpath -- "$1")" 8 | if ! [[ -d "$CRATE_PATH/.$PROJECT_NAME/owners" ]]; then mkdir -p "$CRATE_PATH/.$PROJECT_NAME/owners"; fi 9 | # if ! [[ -d "$CRATE_PATH/.$PROJECT_NAME/identity.blacklist.d" ]]; then mkdir -p "$CRATE_PATH/.$PROJECT_NAME/identity.blacklist.d"; fi 10 | echo '/\.git/' > "$CRATE_PATH/.$PROJECT_NAME/seal-ignore.list" 11 | echo '/\.git$' >> "$CRATE_PATH/.$PROJECT_NAME/seal-ignore.list" 12 | echo '^\./target/' >> "$CRATE_PATH/.$PROJECT_NAME/seal-ignore.list" 13 | echo "^\./\.$PROJECT_NAME/seal/" >> "$CRATE_PATH/.$PROJECT_NAME/seal-ignore.list" 14 | 15 | echo "initialized" > "$CRATE_PATH/.$PROJECT_NAME/initialized" 16 | step_message "Initialized" "Initialized crate root ($CRATE_PATH)" 17 | } 18 | 19 | 20 | uninitialize_crate() { 21 | local CRATE_PATH="$(realpath -- "$1")" 22 | distrust_crate "$CRATE_PATH" 23 | if [[ -d "$KNOWN_CRATE_PATH/.$PROJECT_NAME" ]]; then 24 | rm -r "$KNOWN_CRATE_PATH/.$PROJECT_NAME" 25 | step_message "Uninit" "Uninitialized crate ($CRATE_PATH)" 26 | else 27 | step_message "Uninit" "Crate is already uninitialized ($CRATE_PATH)" 28 | fi 29 | } 30 | -------------------------------------------------------------------------------- /src/sandboxing.sh: -------------------------------------------------------------------------------- 1 | # Sandboxing 2 | 3 | 4 | # Runs args in a sandbox if sandboxing is not disabled. Run args 5 | # directly if it is. 6 | sandbox() { 7 | ( 8 | set -euH 9 | set -o pipefail 10 | trap - EXIT TERM INT 11 | 12 | if [[ "${DISABLE_SANDBOX-}" == "yes" ]]; then 13 | ignored_step_message "Sandbox" "Sandboxing is disabled" 14 | debug "Bypassing sandbox because sandboxing is disabled" 15 | exec "$@" 16 | fi 17 | 18 | 19 | local SANDBOX_ARGS=( "--die-with-parent" ) 20 | if [[ "${SANDBOX_ALL}" == "yes" ]]; then 21 | SANDBOX_ARGS=( "${SANDBOX_ARGS[@]}" "--unshare-all" ) 22 | else 23 | if ! [[ "${SANDBOX_NETWORK-}" == "no" ]]; then 24 | SANDBOX_ARGS=( "${SANDBOX_ARGS[@]}" "--unshare-net" ) 25 | fi 26 | if ! [[ "${SANDBOX_PROCESS-}" == "no" ]]; then 27 | SANDBOX_ARGS=( "${SANDBOX_ARGS[@]}" "--unshare-ipc" "--unshare-pid" ) 28 | fi 29 | # Note: Sandboxing/unsandboxing cargo home is done later 30 | # Note: Sandboxing/unsandboxing tty session is done later 31 | 32 | fi 33 | 34 | if [[ "$SANDBOX_ALL" == "yes" ]] || ! [[ "$SANDBOX_FILESYSTEM" == "no" ]]; then 35 | EFFECTIVE_CARGO_HOME="${CARGO_HOME-$HOME/.cargo/}" 36 | 37 | # only useful when cargo-home is unsandboxed and cargo was never run 38 | # on the current system 39 | mkdir -p "$EFFECTIVE_CARGO_HOME" 40 | 41 | SANDBOX_ARGS=( "${SANDBOX_ARGS[@]}" \ 42 | "--ro-bind" "/etc" "/etc" \ 43 | "--ro-bind" "/bin" "/bin" \ 44 | "--ro-bind" "/lib" "/lib" \ 45 | "--ro-bind" "/lib64" "/lib64" \ 46 | "--ro-bind" "/sbin" "/sbin" \ 47 | "--ro-bind" "/usr" "/usr" \ 48 | "--tmpfs" "/tmp" \ 49 | "--bind" "${KNOWN_CRATE_PATH:-$PWD}" "${KNOWN_CRATE_PATH:-$PWD}" \ 50 | "--dir" "/run/user/$(id -u)" \ 51 | "--proc" "/proc" \ 52 | "--dev" "/dev" ) 53 | 54 | if [[ "${SANDBOX_CARGO_HOME-}" == "no" ]]; then 55 | SANDBOX_ARGS=( "${SANDBOX_ARGS[@]}" "--bind" "$EFFECTIVE_CARGO_HOME" "$EFFECTIVE_CARGO_HOME" ) 56 | else 57 | SANDBOX_ARGS=( "${SANDBOX_ARGS[@]}" "--dir" "$HOME" ) 58 | fi 59 | 60 | if [[ -f "/run/systemd/resolve/stub-resolv.conf" ]]; then 61 | SANDBOX_ARGS=( "${SANDBOX_ARGS[@]}" "--ro-bind" "/run/systemd/resolve/stub-resolv.conf" "/run/systemd/resolve/stub-resolv.conf" ) 62 | fi 63 | 64 | if [[ "${SANDBOX_RW_PATHS-}" ]]; then 65 | OIFS="$IFS" 66 | IFS=":" 67 | for bind in $SANDBOX_RW_PATHS; do 68 | IFS="$OIFS" 69 | if ! [[ -e "$bind" ]]; then 70 | fatal "The following path does not exist: '$bind'" 71 | fi 72 | bind="$(realpath -- "$bind")" 73 | SANDBOX_ARGS=( "${SANDBOX_ARGS[@]}" "--bind" "$bind" "$bind") 74 | done 75 | IFS="$OIFS" 76 | fi 77 | if [[ "${SANDBOX_RO_PATHS-}" ]]; then 78 | OIFS="$IFS" 79 | IFS=":" 80 | for bind in $SANDBOX_RO_PATHS; do 81 | IFS="$OIFS" 82 | if ! [[ -e "$bind" ]]; then 83 | fatal "The following path does not exist: '$bind'" 84 | fi 85 | bind="$(realpath -- "$bind")" 86 | SANDBOX_ARGS=( "${SANDBOX_ARGS[@]}" "--ro-bind" "$bind" "$bind") 87 | done 88 | IFS="$OIFS" 89 | fi 90 | else 91 | SANDBOX_ARGS=( "${SANDBOX_ARGS[@]}" "--bind" "/" "/" "--dev" "/dev" ) 92 | fi 93 | 94 | if [[ "$SANDBOX_ALL" == "yes" ]] || ! [[ "$SANDBOX_SESSION" == "no" ]]; then 95 | SANDBOX_ARGS=( "${SANDBOX_ARGS[@]}" "--new-session" ) 96 | fi 97 | 98 | 99 | debug "Standard bublewrap options being applied are: " 100 | for opt in "${SANDBOX_ARGS[@]}"; do 101 | debug " $opt" 102 | done 103 | if [[ "$(printf '0.3.0\n%s\n' "$(bwrap --version | cut -d ' ' -f2)" | sort -V )" == "0.3.0" ]]; then 104 | exec bwrap "${SANDBOX_ARGS[@]}" --chdir "$PWD" -- "$@" 105 | else 106 | exec bwrap "${SANDBOX_ARGS[@]}" --chdir "$PWD" "$@" 107 | fi 108 | ) || return "$?" 109 | REQUESTED_PERMISSIONS="" 110 | } 111 | 112 | 113 | -------------------------------------------------------------------------------- /src/session.sh: -------------------------------------------------------------------------------- 1 | 2 | clear_dev_session() { 3 | if ! [[ "${KNOWN_CRATE_PATH_HASH-}" ]]; then 4 | debug "Not refreshing dev session because no crate was found" 5 | return 6 | fi 7 | local SESSION_DIR="$USERCONFIGDIR/known/$KNOWN_CRATE_PATH_HASH/session" 8 | mkdir -p "$SESSION_DIR" 9 | if ! [[ -f "$SESSION_DIR/starting.timestamp" ]]; then printf "%s\n" "0" > "$SESSION_DIR/starting.timestamp"; fi 10 | if ! [[ -f "$USERCONFIGDIR/session.duration" ]]; then printf "%s\n" "3600" > "$USERCONFIGDIR/session.duration"; fi 11 | 12 | printf "0\n" > "$SESSION_DIR/starting.timestamp" 13 | } 14 | refresh_dev_session() { 15 | if ! [[ "${KNOWN_CRATE_PATH_HASH-}" ]]; then 16 | debug "Not refreshing dev session because no crate was found" 17 | return 18 | fi 19 | local SESSION_DIR="$USERCONFIGDIR/known/$KNOWN_CRATE_PATH_HASH/session" 20 | mkdir -p "$SESSION_DIR" 21 | if ! [[ -f "$SESSION_DIR/starting.timestamp" ]]; then printf "%s\n" "0" > "$SESSION_DIR/starting.timestamp"; fi 22 | if ! [[ -f "$USERCONFIGDIR/session.duration" ]]; then printf "%s\n" "3600" > "$USERCONFIGDIR/session.duration"; fi 23 | 24 | local last_session_ts="$(cat "$SESSION_DIR/starting.timestamp")" 25 | local max_session_duration="$(cat "$USERCONFIGDIR/session.duration")" 26 | local now="$(date +%s)" 27 | [[ "$last_session_ts" -eq "$last_session_ts" ]] 28 | [[ "$max_session_duration" -eq "$max_session_duration" ]] 29 | 30 | if (( now < last_session_ts )) || (( now >= (last_session_ts + max_session_duration) )); then 31 | local session_status="inactive" 32 | else 33 | local session_status="active" 34 | fi 35 | 36 | if [[ "$NEW_DEV_SESSION" == "yes" ]]; then 37 | printf "%s\n" "$now" > "$SESSION_DIR/starting.timestamp" 38 | DISABLE_AUTOVERIFICATION="yes" 39 | NEW_DEV_SESSION="no" 40 | printf "\n" 41 | if [[ "$session_status" == "active" ]]; then 42 | printf "The edit session for this crate is still active " 43 | else 44 | printf "The edit session for this crate is now active " 45 | fi 46 | printf "and is set to expire after $(( $max_session_duration/60 )) minute(s). 47 | - To change this duration, edit '$USERCONFIGDIR/session.duration'. 48 | - To expire this duration, run 'carnet carnet:done'.\n\n" 49 | else 50 | if [[ "$session_status" == "active" ]]; then 51 | printf "%s\n" "$now" > "$SESSION_DIR/starting.timestamp" 52 | DISABLE_AUTOVERIFICATION="yes" 53 | NEW_DEV_SESSION="no" 54 | fi 55 | fi 56 | } 57 | -------------------------------------------------------------------------------- /src/setup-and-upgrade-scripts.sh: -------------------------------------------------------------------------------- 1 | if [[ "$CONFIGURATION_EULA_AGREEMENT" != "enabled" ]] && [[ "$COMMAND" != "enable" ]] && [[ "$COMMAND" != "disable" ]]; then 2 | printf " 3 | ${BOLD-}Welcome to version $PROJECT_VERSION of Carnet!${RESET-} 4 | 5 | This is experimental, alpha-grade software. This software should 6 | not be used in any environment without a proper understanding the 7 | risks involved. 8 | 9 | Crate authentication is not ready yet. We strongly encourage you 10 | to disable automatic verification by running the following 11 | command: 12 | 13 | carnet disable verification 14 | 15 | You can enable it again at any time if you want. 16 | 17 | The terms and conditions governing your use and redistribution of 18 | this software impose important limitations on warranty and 19 | liability. These terms and conditions can be viewed by running 20 | the command 'carnet --carnet:legal'. DO NOT USE THIS SOFTWARE if 21 | you do not or cannot agree to the terms and conditions of this 22 | license. 23 | 24 | If you would like to proceed, please type I AGREE in the box 25 | bellow: 26 | 27 | [ ]\r [ " 28 | 29 | if [[ -t 0 ]] && [[ -t 1 ]] && [[ -t 2 ]]; then 30 | if ! prompt_yes_no "I AGREE"; then 31 | echo "" 32 | fail "Aborted:" "User declined to agree. Aborting." 33 | else 34 | echo "" 35 | configuration_settings "enable" "eula-agreement" 36 | fi 37 | else 38 | fail "Aborted:" "Not connected to a normal tty. Note that you can indicate your agreement by running 'carnet enable eula-agreement' once." 39 | fi 40 | fi 41 | -------------------------------------------------------------------------------- /src/trap.sh: -------------------------------------------------------------------------------- 1 | # Trap setup: Trapping is used to detect when the script exits in 2 | # abnormal. 3 | 4 | # This global variables are exculsivly managed by this code. 5 | EXITING="no" 6 | EXITING_MESSAGE="no" 7 | 8 | at_exit_callback() { 9 | if [[ "$EXITING" != "yes" ]]; then 10 | if [[ "${EXITING_MESSAGE-}" != "yes" ]]; then 11 | debug "crashing.." 12 | printf "${RED-}A problem occurred and $PROJECT_NAME needs to exit in an unintended way. Specified operations may not have completed correctly or may have been left in an inconsistent state. Please report this issue.${RESET-}\n" 1>&2 13 | EXITING_MESSAGE="yes" 14 | fi 15 | builtin exit 108 16 | fi 17 | } 18 | 19 | trap at_exit_callback EXIT TERM INT 20 | 21 | # overiding bash's built-in to avoid trapping on normal exits. 22 | exit() { 23 | EXITING="yes" 24 | debug "exiting properly with exit $*." 25 | builtin exit "$@" 26 | } 27 | 28 | -------------------------------------------------------------------------------- /src/trust.sh: -------------------------------------------------------------------------------- 1 | # Functionality for making a forgin crate known to the system. 2 | 3 | # This function registers a carnet crate as a forign/disowned crate. 4 | # The second argument can be a directory of public keys and certificates, 5 | # a single file?, or nothing for trusting the repository's own credentials 6 | # 7 | # trust_crate PATH [KEYOVERRIDE] 8 | trust_crate() { 9 | local CRATE_PATH="$(realpath -- "$1")" 10 | local new_crate_fingerprint="$( path_fingerprint "$CRATE_PATH" )" 11 | if ! [[ -f "$USERCONFIGDIR/known/$new_crate_fingerprint/registered" ]]; then 12 | debug "Trusting new crate at '$CRATE_PATH' giving it id $new_crate_fingerprint.." 13 | mkdir -p "$USERCONFIGDIR/known/$new_crate_fingerprint" 14 | if [[ -d "${2-}" ]]; then 15 | update_certs "$2" "$USERCONFIGDIR/known/$new_crate_fingerprint/owners" 16 | # mkdir "$USERCONFIGDIR/known/$new_crate_fingerprint/identity.blacklist.d" 17 | elif [[ -f "${2-}" ]]; then 18 | false 19 | else 20 | update_certs "$CRATE_PATH/.$PROJECT_NAME/owners" "$USERCONFIGDIR/known/$new_crate_fingerprint/owners" 21 | # update_certs "$CRATE_PATH/.$PROJECT_NAME/identity.blacklist.d" "$USERCONFIGDIR/known/$new_crate_fingerprint/identity.blacklist.d" 22 | fi 23 | printf "forign\n" > "$USERCONFIGDIR/known/$new_crate_fingerprint/origin" 24 | echo "registered" > "$USERCONFIGDIR/known/$new_crate_fingerprint/registered" 25 | step_message "Trusted" "Registered crate with your system ($CRATE_PATH)" 26 | else 27 | fatal "Cannot trust crate '$CRATE_PATH' it is already trusted" 28 | fi 29 | } 30 | 31 | distrust_crate() { 32 | local CRATE_PATH="$(realpath -- "$1")" 33 | local new_crate_fingerprint="$( path_fingerprint "$CRATE_PATH" )" 34 | if ! [[ -f "$USERCONFIGDIR/known/$new_crate_fingerprint/registered" ]]; then 35 | step_message "Distrusted" "Given crate is not registered on your system ($CRATE_PATH)" 36 | else 37 | rm -r "$USERCONFIGDIR/known/$new_crate_fingerprint" 38 | step_message "Distrusted" "Unregistered crate from your system ($CRATE_PATH)" 39 | fi 40 | } 41 | 42 | 43 | # locate_known_crate_from_the_inside_and_set_up_global_variables 44 | # 45 | # 46 | locate_known_crate_from_the_inside_and_set_up_global_variables() { 47 | while true; do 48 | KNOWN_CRATE_PATH="$(realpath -- $KNOWN_CRATE_PATH)" 49 | KNOWN_CRATE_PATH_HASH="$( path_fingerprint "$KNOWN_CRATE_PATH" )" 50 | 51 | if ! [[ -f "$KNOWN_CRATE_PATH/.$PROJECT_NAME/initialized" ]] && [[ -f "$USERCONFIGDIR/known/$KNOWN_CRATE_PATH_HASH/registered" ]]; then 52 | fatal "Phantom crate found at '$KNOWN_CRATE_PATH'. This means that a crate at this path was previously registered with Carnet but has since been moved or deleted." 53 | fi 54 | 55 | if [[ -f "$KNOWN_CRATE_PATH/.$PROJECT_NAME/initialized" ]] && ! [[ -f "$USERCONFIGDIR/known/$KNOWN_CRATE_PATH_HASH/registered" ]]; then 56 | echo "Found a new unknown crate at '$KNOWN_CRATE_PATH' that was signed by the following identity(s):" 57 | list_identities "$KNOWN_CRATE_PATH/.$PROJECT_NAME/owners" 58 | echo "" 59 | prompt_yes_no_and_require_yes "Would you like to trust this crate?" 60 | trust_crate "$KNOWN_CRATE_PATH" 61 | fi 62 | 63 | if [[ -f "$KNOWN_CRATE_PATH/.$PROJECT_NAME/initialized" ]] && [[ -f "$USERCONFIGDIR/known/$KNOWN_CRATE_PATH_HASH/registered" ]]; then 64 | KNOWN_CRATE_STATE="found" 65 | KNOWN_CRATE_ORIGIN="$(cat "$USERCONFIGDIR/known/$KNOWN_CRATE_PATH_HASH/origin")" 66 | 67 | if [[ "$KNOWN_CRATE_ORIGIN" == "local" ]]; then 68 | local crate_cookie="$KNOWN_CRATE_PATH/.$PROJECT_NAME/cookies.d/$LOCAL_IDENTITY_FINGERPRINT.cookie" 69 | local cached_cookie="$USERCONFIGDIR/known/$KNOWN_CRATE_PATH_HASH/cookies.d/$LOCAL_IDENTITY_FINGERPRINT.cookie" 70 | local crate_cookie_content="$(cat "$crate_cookie")" 71 | local cached_cookie_content="$(cat "$cached_cookie" | sha384sum | cut -d ' ' -f 1 | head -c 24)" 72 | if [[ "$crate_cookie_content" != "$cached_cookie_content" ]] ; then 73 | debug "Crate cookies do not match: crate:'$crate_cookie_content', cached:'$cached_cookie_content'" 74 | fatal "Crate cookies do not match. This means that the crate was likely replaced since it was last owned." 75 | fi 76 | fi 77 | debug "Root crate path: '${KNOWN_CRATE_PATH-}'" 78 | debug "Root crate path hash: '${KNOWN_CRATE_PATH_HASH-}'" 79 | debug "Root crate path origin: '${KNOWN_CRATE_ORIGIN-}'" 80 | break 81 | fi 82 | if [[ "$( realpath -- "$KNOWN_CRATE_PATH" )" == "/" ]]; then 83 | debug "Could not find a crate in this directory or any of its parents.\n" 84 | unset KNOWN_CRATE_PATH 85 | unset KNOWN_CRATE_PATH_HASH 86 | unset KNOWN_CRATE_ORIGIN 87 | unset KNOWN_CRATE_STATE 88 | debug "Could not find root of crate." 89 | debug "Could not derive Root crate's path hash." 90 | break 91 | fi 92 | KNOWN_CRATE_PATH="$KNOWN_CRATE_PATH/.." 93 | done 94 | } 95 | -------------------------------------------------------------------------------- /tests/carnet-test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # Carnet © 2021 Kutometa SPC, Kuwait 5 | # 6 | # Unless otherwise expressly stated, this work and all related 7 | # material are made available to you under the terms of version 3 8 | # of the GNU Lesser General Public License (hereinafter, the 9 | # LGPL-3.0) and the following supplemental terms: 10 | # 11 | # 1. This work must retain all legal notices. These notices must 12 | # not be altered or truncated in any way. 13 | # 14 | # 2. The origin of any derivative or modified versions of this 15 | # work must not be presented in a way that may mislead a 16 | # reasonable person into mistaking the derive work to originate 17 | # from Kutometa or the authors of this work. 18 | # 19 | # 3. Derivative or modified versions of this work must be clearly 20 | # and easily distinguishable from the original work by a 21 | # reasonable person. 22 | # 23 | # 4. Unless express permission is granted in writing, The name of 24 | # the original work may not be used within the name of any 25 | # derivative or modified version of the work. 26 | # 27 | # 5. Unless express permission is granted in writing, Trade names, 28 | # trademarks, and service marks used in this work may not be 29 | # included in any derivative or modified versions of this work. 30 | # 31 | # 6. Unless express permission is granted in writing, the names and 32 | # trademarks of Kutometa and other right holders may not be used 33 | # to endorse derivative or modified versions of this work. 34 | # 35 | # 7. The licensee must defend, indemnify, and hold harmless 36 | # Kutometa and authors of this software from any and all 37 | # actions, claims, judgments, losses, penalties, liabilities, 38 | # damages, expenses, demands, fees (including, but not limited 39 | # to, reasonable legal and other professional fees), taxes, and 40 | # cost that result from or in connection with any liability 41 | # imposed on Kutometa or other authors of this software as a 42 | # result of the licensee conveying this work or a derivative 43 | # thereof with contractual assumptions of liability to a third 44 | # party recipient. 45 | # 46 | # Unless expressly stated otherwise or required by applicable law, 47 | # this work is provided AS-IS with NO WARRANTY OF ANY KIND, 48 | # INCLUDING THE WARRANTY OF MERCHANTABILITY AND FITNESS FOR A 49 | # PARTICULAR PURPOSE. Use this work at your own risk. 50 | # 51 | # This license agreement is governed by and is construed in 52 | # accordance with the laws of the state of Kuwait. You must submit 53 | # all disputes arising out of or in connection with this work to 54 | # the exclusive jurisdiction of the courts of Kuwait. 55 | # 56 | # You should have received a copy of the LGPL-3.0 along with this 57 | # program; if not, visit www.ka.com.kw/en/legal, write to 58 | # legal@ka.com.kw, or write to Kutometa SPC, 760 SAFAT 13008, 59 | # Kuwait. 60 | # 61 | 62 | set -euH 63 | set -o pipefail 64 | 65 | cd $(dirname "${BASH_SOURCE[0]}") 66 | source "common.sh" 67 | 68 | 69 | if ! CARNET_PATH=$(which "${CARNET_PATH:-$(realpath ../carnet)}"); then 70 | fatal "Could not find carnet on this path" 71 | else 72 | step "BINARY" "found carnet executable at '$CARNET_PATH'. Set CARNET_PATH to override." 73 | fi 74 | 75 | export CARNET_PATH 76 | 77 | 78 | run_case() { 79 | if [[ -f "$1" ]]; then 80 | RESULT=0 81 | # bash -- "$1" 2>/dev/null || RESULT="$?" 82 | bash -- "$1" || RESULT="$?" 83 | if [[ "$RESULT" != 0 ]]; then 84 | fatal "Test case '$1' has failed. set FAIL_SHELL to yes to drop into a shell inside the test's env." 85 | else 86 | step "PASS" "Test case '$1' has passed." 87 | fi 88 | else 89 | fatal "Test case '$1' is not a file." 90 | fi 91 | } 92 | 93 | 94 | 95 | if [[ "${1-}" ]]; then 96 | step "STARTING UP" "running test 'cases/$1.sh'.." 97 | if [[ -f "cases/$1.sh" ]]; then 98 | run_case "cases/$1.sh" 99 | else 100 | fatal "Test cases/$1.sh does not exist" 101 | fi 102 | else 103 | step "STARTING UP" "running all tests in 'cases/'.." 104 | for case in "cases/"*; do 105 | case_name="$(basename "$case")" 106 | if [[ "${case_name::12}" == "0000-ignored" ]] && [[ "${TEST_IGNORED-}" == "" ]]; then 107 | step "ignored" "$case_name (Set env TEST_IGNORED to 'yes' to test)" 108 | else 109 | run_case "$case" 110 | fi 111 | done 112 | fi 113 | 114 | 115 | 116 | 117 | 118 | step "DONE" "all tests have passed." 119 | -------------------------------------------------------------------------------- /tests/cases/00-sanity.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # Carnet © 2021 Kutometa SPC, Kuwait 5 | # 6 | # Unless otherwise expressly stated, this work and all related 7 | # material are made available to you under the terms of version 3 8 | # of the GNU Lesser General Public License (hereinafter, the 9 | # LGPL-3.0) and the following supplemental terms: 10 | # 11 | # 1. This work must retain all legal notices. These notices must 12 | # not be altered or truncated in any way. 13 | # 14 | # 2. The origin of any derivative or modified versions of this 15 | # work must not be presented in a way that may mislead a 16 | # reasonable person into mistaking the derive work to originate 17 | # from Kutometa or the authors of this work. 18 | # 19 | # 3. Derivative or modified versions of this work must be clearly 20 | # and easily distinguishable from the original work by a 21 | # reasonable person. 22 | # 23 | # 4. Unless express permission is granted in writing, The name of 24 | # the original work may not be used within the name of any 25 | # derivative or modified version of the work. 26 | # 27 | # 5. Unless express permission is granted in writing, Trade names, 28 | # trademarks, and service marks used in this work may not be 29 | # included in any derivative or modified versions of this work. 30 | # 31 | # 6. Unless express permission is granted in writing, the names and 32 | # trademarks of Kutometa and other right holders may not be used 33 | # to endorse derivative or modified versions of this work. 34 | # 35 | # 7. The licensee must defend, indemnify, and hold harmless 36 | # Kutometa and authors of this software from any and all 37 | # actions, claims, judgments, losses, penalties, liabilities, 38 | # damages, expenses, demands, fees (including, but not limited 39 | # to, reasonable legal and other professional fees), taxes, and 40 | # cost that result from or in connection with any liability 41 | # imposed on Kutometa or other authors of this software as a 42 | # result of the licensee conveying this work or a derivative 43 | # thereof with contractual assumptions of liability to a third 44 | # party recipient. 45 | # 46 | # Unless expressly stated otherwise or required by applicable law, 47 | # this work is provided AS-IS with NO WARRANTY OF ANY KIND, 48 | # INCLUDING THE WARRANTY OF MERCHANTABILITY AND FITNESS FOR A 49 | # PARTICULAR PURPOSE. Use this work at your own risk. 50 | # 51 | # This license agreement is governed by and is construed in 52 | # accordance with the laws of the state of Kuwait. You must submit 53 | # all disputes arising out of or in connection with this work to 54 | # the exclusive jurisdiction of the courts of Kuwait. 55 | # 56 | # You should have received a copy of the LGPL-3.0 along with this 57 | # program; if not, visit www.ka.com.kw/en/legal, write to 58 | # legal@ka.com.kw, or write to Kutometa SPC, 760 SAFAT 13008, 59 | # Kuwait. 60 | # 61 | 62 | set -euH 63 | set -o pipefail 64 | source "common.sh" 65 | 66 | [[ -e "$CARNET_PATH" ]] || { 67 | fatal "'$CARNET_PATH' is not an executable!" 68 | } 69 | 70 | environment_one() { 71 | set -euH 72 | set -o pipefail 73 | export CARNET_UNSTABLE_RSA_BITS="1024" 74 | export CARNET_PUBLISHER_NAME="TEST NAME" 75 | export CARNET_PUBLISHER_EMAIL="TEST_EMAIL" 76 | export CARNET_PUBLISHER_ORG="ORGANIZATION" 77 | export CARNET_PUBLISHER_COUNTRY="KW" 78 | 79 | -- "[LINENO:$LINENO]" "Agree to EULA and set up new user at the same time" 80 | ACTIVE_USER="userA" 81 | run "0" "$CARNET_PATH" --carnet:config-dir="../configs/$ACTIVE_USER" enable "eula-agreement" 82 | 83 | -- "[LINENO:$LINENO]" "Construct a new cate through carnet" 84 | ACTIVE_USER="userA" 85 | run "0" "$CARNET_PATH" --carnet:config-dir="../configs/$ACTIVE_USER" new "lib1" --lib 86 | 87 | -- "[LINENO:$LINENO]" "Cargo fails because the crate already exists" 88 | ACTIVE_USER="userA" 89 | run "101" "$CARNET_PATH" --carnet:config-dir="../configs/$ACTIVE_USER" new "lib1" --lib 90 | 91 | cd "lib1" 92 | 93 | -- "[LINENO:$LINENO]" "Carnet fails because it isn't sealed yet" 94 | ACTIVE_USER="userA" 95 | run "107" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" test 96 | 97 | 98 | -- "[LINENO:$LINENO]" "Seal the crate" 99 | ACTIVE_USER="userA" 100 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" seal 101 | 102 | -- "[LINENO:$LINENO]" "Verify the crate explicitly" 103 | ACTIVE_USER="userA" 104 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" verify 105 | 106 | -- "[LINENO:$LINENO]" "Edit src/lib.rs" 107 | echo "#[test] fn new_testing_function() { assert_eq!(9,9); } " >> "src/lib.rs" 108 | 109 | -- "[LINENO:$LINENO]" "Carnet fails because the change wasn't signed. The user must sign it or start a dev session" 110 | ACTIVE_USER="userA" 111 | run "107" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" test 112 | 113 | -- "[LINENO:$LINENO]" "Seal the crate" 114 | ACTIVE_USER="userA" 115 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" seal 116 | 117 | -- "[LINENO:$LINENO]" "Run tests which should pass" 118 | ACTIVE_USER="userA" 119 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" test 120 | 121 | -- "[LINENO:$LINENO]" "Edit src/lib.rs again" 122 | echo "#[test] fn new_testing_function_2() { assert_eq!(9,9); } " >> "src/lib.rs" 123 | 124 | -- "[LINENO:$LINENO]" "Tests should fail again" 125 | ACTIVE_USER="userA" 126 | run "107" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" test 127 | 128 | -- "[LINENO:$LINENO]" "This time start a dev session" 129 | ACTIVE_USER="userA" 130 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" edit 131 | 132 | -- "[LINENO:$LINENO]" "Then run tests which should work" 133 | ACTIVE_USER="userA" 134 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" test 135 | 136 | -- "[LINENO:$LINENO]" "Set dev duration to 2 seconds" 137 | echo "2" > "../../configs/$ACTIVE_USER/session.duration" 138 | 139 | -- "[LINENO:$LINENO]" "Then run tests which should still work provided it runs withing 1 second of the last test" 140 | ACTIVE_USER="userA" 141 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" test 142 | 143 | -- "[LINENO:$LINENO]" "Sleep 2.6 seconds" 144 | sleep 2.6 145 | 146 | -- "[LINENO:$LINENO]" "Run tests again which should fail because dev session has expired" 147 | ACTIVE_USER="userA" 148 | run "107" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" test 149 | 150 | -- "[LINENO:$LINENO]" "Seal changes" 151 | ACTIVE_USER="userA" 152 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" seal 153 | 154 | -- "[LINENO:$LINENO]" "Test one more time.." 155 | ACTIVE_USER="userA" 156 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" test 157 | 158 | -- "[LINENO:$LINENO]" "Agree to EULA for new user 'userB' and set up new user at the same time" 159 | ACTIVE_USER="userB" 160 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" enable "eula-agreement" 161 | 162 | -- "[LINENO:$LINENO]" "Test with new user 'userB' which should propmt the user to trust the new crate. we will decline first" 163 | ACTIVE_USER="userB" 164 | set +o pipefail 165 | run "107" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" test < <(echo "no" ) 166 | 167 | -- "[LINENO:$LINENO]" "Test with new user 'userB', but this time we accept" 168 | ACTIVE_USER="userB" 169 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" test < <( echo "yes" ) 170 | 171 | -- "[LINENO:$LINENO]" "UserB attempts to add a new test and then runs the tests without signing the crate which should fail" 172 | ACTIVE_USER="userB" 173 | echo "#[test] fn new_testing_function_3() { assert_eq!(1,1); } " >> "src/lib.rs" 174 | run "107" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" test 175 | 176 | -- "[LINENO:$LINENO]" "UserB attempts to seal the crate but the user isn't an owner which should fail" 177 | ACTIVE_USER="userB" 178 | run "107" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" seal 179 | 180 | -- "[LINENO:$LINENO]" "UserB attempts to own the crate" 181 | ACTIVE_USER="userB" 182 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" own 183 | 184 | -- "[LINENO:$LINENO]" "UserB attempts to test the crate again but it fails again because he hasn't sealed it yet.. bless" 185 | ACTIVE_USER="userB" 186 | run "107" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" test 187 | 188 | -- "[LINENO:$LINENO]" "So he seals it and then runs the tests" 189 | ACTIVE_USER="userB" 190 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" seal 191 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" test 192 | 193 | 194 | -- "[LINENO:$LINENO]" "Now comes USER-A wanting to work on his crate, but he's in for a big suprise" 195 | ACTIVE_USER="userA" 196 | run "107" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" test 197 | 198 | -- "[LINENO:$LINENO]" "Upon diffing the changes, A decided to trust B" 199 | ACTIVE_USER="userA" 200 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" seal 201 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" test 202 | 203 | 204 | -- "[LINENO:$LINENO]" "Agree to EULA for new user 'userB' and set up new user at the same time" 205 | ACTIVE_USER="userC" 206 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" enable "eula-agreement" 207 | 208 | -- "[LINENO:$LINENO]" "But what's this! In comes C, steathely adding his key to the whitelist directory, will he succeed? Let's find out..." 209 | ACTIVE_USER="userC" 210 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" test < <(echo "yes" ) # To generate the pub key for C 211 | C_CERT="../../configs/$ACTIVE_USER/identity.cert" 212 | C_IDENT="$(sha384sum -- "$C_CERT" | cut -d ' ' -f 1 | head -c 20)" 213 | run "0" cp "../../configs/$ACTIVE_USER/identity.cert" ".carnet/owners/$C_IDENT.cert" 214 | 215 | 216 | #TODO make blacklisting a carnet action 217 | -- "[LINENO:$LINENO]" "UserA attempts to test his crate but finds C's key. He doesn't take kindly to this and removes it." 218 | ACTIVE_USER="userA" 219 | run "107" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" test 220 | ACTIVE_USER="userB" 221 | run "107" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" verify 222 | 223 | run "0" rm ".carnet/owners/$C_IDENT.cert" 224 | ACTIVE_USER="userA" 225 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" test 226 | ACTIVE_USER="userB" 227 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" verify 228 | 229 | # -- "Being the compuslive tester that C is, he was estatic about the prospect of inserting tons of useless tests into the project" 230 | # ACTIVE_USER="userC" 231 | # run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" own 232 | # echo "// Useless tests were clipped for A's benift" > "src/useless.rs" # He isn't a very good rust developer and forgot to add the module to lib.rs. 233 | 234 | # # First verification works because the blacklisted key isn't been copied into the cache until the crate is varified 235 | # # this is currently an implementation detail and might be changed in the future 236 | # run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" seal 237 | # run "107" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" seal 238 | 239 | 240 | # -- "verification fails for userA and userB" 241 | # ACTIVE_USER="userA" 242 | # run "107" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" verify 243 | # ACTIVE_USER="userB" 244 | # run "107" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" verify 245 | 246 | 247 | } 248 | 249 | test_environment environment_one "Basic Sanity" "Random tests with no rhyme or methodology behind them." 250 | -------------------------------------------------------------------------------- /tests/cases/0000-ignored.crates-io.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # Carnet © 2021 Kutometa SPC, Kuwait 5 | # 6 | # Unless otherwise expressly stated, this work and all related 7 | # material are made available to you under the terms of version 3 8 | # of the GNU Lesser General Public License (hereinafter, the 9 | # LGPL-3.0) and the following supplemental terms: 10 | # 11 | # 1. This work must retain all legal notices. These notices must 12 | # not be altered or truncated in any way. 13 | # 14 | # 2. The origin of any derivative or modified versions of this 15 | # work must not be presented in a way that may mislead a 16 | # reasonable person into mistaking the derive work to originate 17 | # from Kutometa or the authors of this work. 18 | # 19 | # 3. Derivative or modified versions of this work must be clearly 20 | # and easily distinguishable from the original work by a 21 | # reasonable person. 22 | # 23 | # 4. Unless express permission is granted in writing, The name of 24 | # the original work may not be used within the name of any 25 | # derivative or modified version of the work. 26 | # 27 | # 5. Unless express permission is granted in writing, Trade names, 28 | # trademarks, and service marks used in this work may not be 29 | # included in any derivative or modified versions of this work. 30 | # 31 | # 6. Unless express permission is granted in writing, the names and 32 | # trademarks of Kutometa and other right holders may not be used 33 | # to endorse derivative or modified versions of this work. 34 | # 35 | # 7. The licensee must defend, indemnify, and hold harmless 36 | # Kutometa and authors of this software from any and all 37 | # actions, claims, judgments, losses, penalties, liabilities, 38 | # damages, expenses, demands, fees (including, but not limited 39 | # to, reasonable legal and other professional fees), taxes, and 40 | # cost that result from or in connection with any liability 41 | # imposed on Kutometa or other authors of this software as a 42 | # result of the licensee conveying this work or a derivative 43 | # thereof with contractual assumptions of liability to a third 44 | # party recipient. 45 | # 46 | # Unless expressly stated otherwise or required by applicable law, 47 | # this work is provided AS-IS with NO WARRANTY OF ANY KIND, 48 | # INCLUDING THE WARRANTY OF MERCHANTABILITY AND FITNESS FOR A 49 | # PARTICULAR PURPOSE. Use this work at your own risk. 50 | # 51 | # This license agreement is governed by and is construed in 52 | # accordance with the laws of the state of Kuwait. You must submit 53 | # all disputes arising out of or in connection with this work to 54 | # the exclusive jurisdiction of the courts of Kuwait. 55 | # 56 | # You should have received a copy of the LGPL-3.0 along with this 57 | # program; if not, visit www.ka.com.kw/en/legal, write to 58 | # legal@ka.com.kw, or write to Kutometa SPC, 760 SAFAT 13008, 59 | # Kuwait. 60 | # 61 | 62 | set -euH 63 | set -o pipefail 64 | source "common.sh" 65 | 66 | [[ -e "$CARNET_PATH" ]] || { 67 | fatal "'$CARNET_PATH' is not an executable!" 68 | } 69 | 70 | testing_logic() { 71 | export CARNET_UNSTABLE_RSA_BITS="1024" 72 | export CARNET_PUBLISHER_NAME="TEST NAME" 73 | export CARNET_PUBLISHER_EMAIL="TEST_EMAIL" 74 | export CARNET_PUBLISHER_ORG="ORGANIZATION" 75 | export CARNET_PUBLISHER_COUNTRY="KW" 76 | 77 | -- "[LINENO:$LINENO]" "Agree to EULA and set up new user at the same time" 78 | ACTIVE_USER="ORIGINAL_OWNER" 79 | run "0" "$CARNET_PATH" --carnet:config-dir="../configs/$ACTIVE_USER" enable "eula-agreement" 80 | 81 | ACTIVE_USER="ORIGINAL_OWNER" 82 | run "0" "$CARNET_PATH" --carnet:config-dir="../configs/$ACTIVE_USER" new "main1" 83 | 84 | cd "main1" 85 | 86 | echo 'rand = "0.8.0"' >> Cargo.toml 87 | 88 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" edit 89 | run "101" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" test # no network 90 | 91 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" --unsandbox-network vendor 92 | 93 | run "0" mkdir ".cargo" 94 | run "0" cat > ".cargo/config" <
> "src/lib.rs" 94 | run "107" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" test 95 | printf "%s\n" "$BACKUP" > "src/lib.rs" 96 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" test 97 | 98 | rm "src/lib.rs" 99 | run "107" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" test 100 | printf "%s\n" "$BACKUP" > "src/lib.rs" 101 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" test 102 | 103 | printf "%s\n" "extra" > "src/extra" 104 | run "107" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" test 105 | rm "src/extra" 106 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" test 107 | 108 | 109 | printf "%s\n" "extra" > "src/extra" 110 | run "107" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" test 111 | printf "%s\n" "^\./src/extra" >> ".carnet/seal-ignore.list" 112 | run "107" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" test 113 | printf "%s\n" "^\./\.carnet/seal-ignore\.list" >> ".carnet/seal-ignore.list" 114 | run "107" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" test 115 | printf "%s\n" ".*" >> ".carnet/seal-ignore.list" 116 | run "107" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" test 117 | 118 | 119 | } 120 | 121 | test_environment testing_logic "Messing with validation" "-" 122 | -------------------------------------------------------------------------------- /tests/cases/ownership-1.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # Carnet © 2021 Kutometa SPC, Kuwait 5 | # 6 | # Unless otherwise expressly stated, this work and all related 7 | # material are made available to you under the terms of version 3 8 | # of the GNU Lesser General Public License (hereinafter, the 9 | # LGPL-3.0) and the following supplemental terms: 10 | # 11 | # 1. This work must retain all legal notices. These notices must 12 | # not be altered or truncated in any way. 13 | # 14 | # 2. The origin of any derivative or modified versions of this 15 | # work must not be presented in a way that may mislead a 16 | # reasonable person into mistaking the derive work to originate 17 | # from Kutometa or the authors of this work. 18 | # 19 | # 3. Derivative or modified versions of this work must be clearly 20 | # and easily distinguishable from the original work by a 21 | # reasonable person. 22 | # 23 | # 4. Unless express permission is granted in writing, The name of 24 | # the original work may not be used within the name of any 25 | # derivative or modified version of the work. 26 | # 27 | # 5. Unless express permission is granted in writing, Trade names, 28 | # trademarks, and service marks used in this work may not be 29 | # included in any derivative or modified versions of this work. 30 | # 31 | # 6. Unless express permission is granted in writing, the names and 32 | # trademarks of Kutometa and other right holders may not be used 33 | # to endorse derivative or modified versions of this work. 34 | # 35 | # 7. The licensee must defend, indemnify, and hold harmless 36 | # Kutometa and authors of this software from any and all 37 | # actions, claims, judgments, losses, penalties, liabilities, 38 | # damages, expenses, demands, fees (including, but not limited 39 | # to, reasonable legal and other professional fees), taxes, and 40 | # cost that result from or in connection with any liability 41 | # imposed on Kutometa or other authors of this software as a 42 | # result of the licensee conveying this work or a derivative 43 | # thereof with contractual assumptions of liability to a third 44 | # party recipient. 45 | # 46 | # Unless expressly stated otherwise or required by applicable law, 47 | # this work is provided AS-IS with NO WARRANTY OF ANY KIND, 48 | # INCLUDING THE WARRANTY OF MERCHANTABILITY AND FITNESS FOR A 49 | # PARTICULAR PURPOSE. Use this work at your own risk. 50 | # 51 | # This license agreement is governed by and is construed in 52 | # accordance with the laws of the state of Kuwait. You must submit 53 | # all disputes arising out of or in connection with this work to 54 | # the exclusive jurisdiction of the courts of Kuwait. 55 | # 56 | # You should have received a copy of the LGPL-3.0 along with this 57 | # program; if not, visit www.ka.com.kw/en/legal, write to 58 | # legal@ka.com.kw, or write to Kutometa SPC, 760 SAFAT 13008, 59 | # Kuwait. 60 | # 61 | 62 | set -euH 63 | set -o pipefail 64 | source "common.sh" 65 | 66 | [[ -e "$CARNET_PATH" ]] || { 67 | fatal "'$CARNET_PATH' is not an executable!" 68 | } 69 | 70 | testing_logic() { 71 | export CARNET_UNSTABLE_RSA_BITS="1024" 72 | export CARNET_PUBLISHER_NAME="TEST NAME" 73 | export CARNET_PUBLISHER_EMAIL="TEST_EMAIL" 74 | export CARNET_PUBLISHER_ORG="ORGANIZATION" 75 | export CARNET_PUBLISHER_COUNTRY="KW" 76 | 77 | -- "[LINENO:$LINENO]" "Agree to EULA for new user setup at the same time" 78 | ACTIVE_USER="ORIGINAL_OWNER" 79 | run "0" "$CARNET_PATH" --carnet:config-dir="../configs/$ACTIVE_USER" enable "eula-agreement" 80 | 81 | -- "[LINENO:$LINENO]" "ORIGINAL_OWNER new crate" 82 | ACTIVE_USER="ORIGINAL_OWNER" 83 | run "0" "$CARNET_PATH" --carnet:config-dir="../configs/$ACTIVE_USER" new "lib1" --lib 84 | 85 | cd "lib1" 86 | 87 | -- "[LINENO:$LINENO]" "ORIGINAL_OWNER edit crate" 88 | ACTIVE_USER="ORIGINAL_OWNER" 89 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" edit 90 | 91 | -- "[LINENO:$LINENO]" "ORIGINAL_OWNER test crate" 92 | ACTIVE_USER="ORIGINAL_OWNER" 93 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" test 94 | 95 | -- "[LINENO:$LINENO]" "ORIGINAL_OWNER seal crate" 96 | ACTIVE_USER="ORIGINAL_OWNER" 97 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" seal 98 | 99 | 100 | -- "[LINENO:$LINENO]" "Agree to EULA for new user setup at the same time" 101 | ACTIVE_USER="CONSUMER" 102 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" enable "eula-agreement" 103 | 104 | -- "[LINENO:$LINENO]" "CONSUMER regester crate" 105 | ACTIVE_USER="CONSUMER" 106 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" test < <(echo "yes") 107 | 108 | -- "[LINENO:$LINENO]" "Agree to EULA for new user setup at the same time" 109 | ACTIVE_USER="CO-OWNER" 110 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" enable "eula-agreement" 111 | 112 | -- "[LINENO:$LINENO]" "CO-OWNER regester crate" 113 | ACTIVE_USER="CO-OWNER" 114 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" test < <(echo "yes") 115 | 116 | -- "[LINENO:$LINENO]" "CO-OWNER own crate" 117 | ACTIVE_USER="CO-OWNER" 118 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" own 119 | 120 | -- "[LINENO:$LINENO]" "CO-OWNER own crate" 121 | ACTIVE_USER="CO-OWNER" 122 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" seal 123 | 124 | -- "[LINENO:$LINENO]" "CO-OWNER own crate" 125 | ACTIVE_USER="CO-OWNER" 126 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" test 127 | 128 | if [[ "${1-}" ]]; then 129 | -- "CO-OWNER add new func to lib.rs" 130 | echo "#[test] fn new_testing_function() { assert_eq!(9,9); } " >> "src/lib.rs" 131 | 132 | -- "CO-OWNER seal crate" 133 | ACTIVE_USER="CO-OWNER" 134 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" seal 135 | fi 136 | 137 | 138 | -- "[LINENO:$LINENO]" "Verify crate by the three users" 139 | ACTIVE_USER="CO-OWNER" 140 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" verify 141 | ACTIVE_USER="CO-OWNER" 142 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" verify 143 | ACTIVE_USER="ORIGINAL_OWNER" 144 | run "107" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" verify 145 | ACTIVE_USER="CONSUMER" 146 | run "107" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" verify 147 | 148 | 149 | -- "[LINENO:$LINENO]" "ORIGINAL_OWNER seal crate" 150 | ACTIVE_USER="ORIGINAL_OWNER" 151 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" seal 152 | 153 | 154 | -- "[LINENO:$LINENO]" "Verify crate by the three users" 155 | ACTIVE_USER="CO-OWNER" 156 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" verify 157 | ACTIVE_USER="ORIGINAL_OWNER" 158 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" verify 159 | ACTIVE_USER="CONSUMER" 160 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" verify 161 | 162 | ACTIVE_USER="CONSUMER" 163 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" test 164 | 165 | exit 0 166 | } 167 | 168 | testing_logic_2() { 169 | testing_logic "yep" 170 | } 171 | test_environment testing_logic "Ownership without modification" "-" 172 | test_environment testing_logic_2 "Ownership with modification" "-" 173 | -------------------------------------------------------------------------------- /tests/cases/ownership-2.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # Carnet © 2021 Kutometa SPC, Kuwait 5 | # 6 | # Unless otherwise expressly stated, this work and all related 7 | # material are made available to you under the terms of version 3 8 | # of the GNU Lesser General Public License (hereinafter, the 9 | # LGPL-3.0) and the following supplemental terms: 10 | # 11 | # 1. This work must retain all legal notices. These notices must 12 | # not be altered or truncated in any way. 13 | # 14 | # 2. The origin of any derivative or modified versions of this 15 | # work must not be presented in a way that may mislead a 16 | # reasonable person into mistaking the derive work to originate 17 | # from Kutometa or the authors of this work. 18 | # 19 | # 3. Derivative or modified versions of this work must be clearly 20 | # and easily distinguishable from the original work by a 21 | # reasonable person. 22 | # 23 | # 4. Unless express permission is granted in writing, The name of 24 | # the original work may not be used within the name of any 25 | # derivative or modified version of the work. 26 | # 27 | # 5. Unless express permission is granted in writing, Trade names, 28 | # trademarks, and service marks used in this work may not be 29 | # included in any derivative or modified versions of this work. 30 | # 31 | # 6. Unless express permission is granted in writing, the names and 32 | # trademarks of Kutometa and other right holders may not be used 33 | # to endorse derivative or modified versions of this work. 34 | # 35 | # 7. The licensee must defend, indemnify, and hold harmless 36 | # Kutometa and authors of this software from any and all 37 | # actions, claims, judgments, losses, penalties, liabilities, 38 | # damages, expenses, demands, fees (including, but not limited 39 | # to, reasonable legal and other professional fees), taxes, and 40 | # cost that result from or in connection with any liability 41 | # imposed on Kutometa or other authors of this software as a 42 | # result of the licensee conveying this work or a derivative 43 | # thereof with contractual assumptions of liability to a third 44 | # party recipient. 45 | # 46 | # Unless expressly stated otherwise or required by applicable law, 47 | # this work is provided AS-IS with NO WARRANTY OF ANY KIND, 48 | # INCLUDING THE WARRANTY OF MERCHANTABILITY AND FITNESS FOR A 49 | # PARTICULAR PURPOSE. Use this work at your own risk. 50 | # 51 | # This license agreement is governed by and is construed in 52 | # accordance with the laws of the state of Kuwait. You must submit 53 | # all disputes arising out of or in connection with this work to 54 | # the exclusive jurisdiction of the courts of Kuwait. 55 | # 56 | # You should have received a copy of the LGPL-3.0 along with this 57 | # program; if not, visit www.ka.com.kw/en/legal, write to 58 | # legal@ka.com.kw, or write to Kutometa SPC, 760 SAFAT 13008, 59 | # Kuwait. 60 | # 61 | 62 | set -euH 63 | set -o pipefail 64 | source "common.sh" 65 | 66 | [[ -e "$CARNET_PATH" ]] || { 67 | fatal "'$CARNET_PATH' is not an executable!" 68 | } 69 | 70 | testing_logic() { 71 | export CARNET_UNSTABLE_RSA_BITS="1024" 72 | export CARNET_PUBLISHER_NAME="TEST NAME" 73 | export CARNET_PUBLISHER_EMAIL="TEST_EMAIL" 74 | export CARNET_PUBLISHER_ORG="ORGANIZATION" 75 | export CARNET_PUBLISHER_COUNTRY="KW" 76 | 77 | #ACTIVE_USER="ORIGINAL_OWNER" 78 | #run "107" "$CARNET_PATH" --config-dir="config-$ACTIVE_USER" init 79 | 80 | cargo new "binary-1" 81 | cd binary-1 82 | 83 | 84 | -- "[LINENO:$LINENO]" "Agree to EULA for new user setup at the same time" 85 | ACTIVE_USER="ORIGINAL_OWNER" 86 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" enable "eula-agreement" 87 | 88 | -- "ORIGINAL_OWNER new crate" 89 | ACTIVE_USER="ORIGINAL_OWNER" 90 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" init 91 | 92 | 93 | -- "ORIGINAL_OWNER edit crate" 94 | ACTIVE_USER="ORIGINAL_OWNER" 95 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" edit 96 | 97 | -- "ORIGINAL_OWNER test crate" 98 | ACTIVE_USER="ORIGINAL_OWNER" 99 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" test 100 | 101 | 102 | -- "ORIGINAL_OWNER edit crate" 103 | ACTIVE_USER="ORIGINAL_OWNER" 104 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" done 105 | 106 | -- "ORIGINAL_OWNER test crate" 107 | ACTIVE_USER="ORIGINAL_OWNER" 108 | run "107" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" test 109 | 110 | 111 | -- "ORIGINAL_OWNER seal crate" 112 | ACTIVE_USER="ORIGINAL_OWNER" 113 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" seal 114 | 115 | 116 | -- "[LINENO:$LINENO]" "Agree to EULA for new user setup at the same time" 117 | ACTIVE_USER="CONSUMER" 118 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" enable "eula-agreement" 119 | 120 | -- "CONSUMER regester crate" 121 | ACTIVE_USER="CONSUMER" 122 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" test < <(echo "yes") 123 | 124 | -- "[LINENO:$LINENO]" "Agree to EULA for new user setup at the same time" 125 | ACTIVE_USER="CO-OWNER" 126 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" enable "eula-agreement" 127 | 128 | -- "CO-OWNER regester crate" 129 | ACTIVE_USER="CO-OWNER" 130 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" test < <(echo "yes") 131 | 132 | -- "CO-OWNER own crate" 133 | ACTIVE_USER="CO-OWNER" 134 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" own 135 | 136 | -- "CO-OWNER own crate" 137 | ACTIVE_USER="CO-OWNER" 138 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" seal 139 | 140 | -- "CO-OWNER own crate" 141 | ACTIVE_USER="CO-OWNER" 142 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" test 143 | 144 | if [[ "${1-}" ]]; then 145 | -- "CO-OWNER add new func to lib.rs" 146 | echo "#[test] fn new_testing_function() { assert_eq!(9,9); } " >> "src/lib.rs" 147 | 148 | -- "CO-OWNER seal crate" 149 | ACTIVE_USER="CO-OWNER" 150 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" seal 151 | fi 152 | 153 | 154 | -- "Verify crate by the three users" 155 | ACTIVE_USER="CO-OWNER" 156 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" verify 157 | ACTIVE_USER="CO-OWNER" 158 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" verify 159 | ACTIVE_USER="ORIGINAL_OWNER" 160 | run "107" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" verify 161 | ACTIVE_USER="CONSUMER" 162 | run "107" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" verify 163 | 164 | 165 | -- "ORIGINAL_OWNER seal crate" 166 | ACTIVE_USER="ORIGINAL_OWNER" 167 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" seal 168 | 169 | 170 | -- "Verify crate by the three users" 171 | ACTIVE_USER="CO-OWNER" 172 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" verify 173 | ACTIVE_USER="ORIGINAL_OWNER" 174 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" verify 175 | ACTIVE_USER="CONSUMER" 176 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" verify 177 | 178 | ACTIVE_USER="CONSUMER" 179 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" test 180 | 181 | 182 | -- "ORIGINAL_OWNER untrust crate" 183 | ACTIVE_USER="ORIGINAL_OWNER" 184 | run "107" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" distrust < <(echo "") 185 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" distrust < <(echo "yes") 186 | 187 | -- "ORIGINAL_OWNER test crate" 188 | ACTIVE_USER="ORIGINAL_OWNER" 189 | run "107" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" test < <(echo "") 190 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" test < <(echo "yes") 191 | 192 | 193 | 194 | -- "ORIGINAL_OWNER uninit crate" 195 | ACTIVE_USER="ORIGINAL_OWNER" 196 | run "107" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" uninit < <(echo "") 197 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" uninit < <(echo "yes") 198 | 199 | -- "init crate again" 200 | ACTIVE_USER="ORIGINAL_OWNER" 201 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" init 202 | 203 | -- "Seal crate" 204 | ACTIVE_USER="ORIGINAL_OWNER" 205 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" seal 206 | 207 | -- "Edit src/lib.rs" 208 | echo "#[test] fn new_testing_function() { assert_eq!(9,9); } " >> "src/lib.rs" 209 | 210 | -- "Test crate" 211 | ACTIVE_USER="ORIGINAL_OWNER" 212 | run "107" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" test 213 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" seal 214 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" test 215 | 216 | 217 | exit 0 218 | } 219 | 220 | test_environment testing_logic "Ownership 2" "Initializing a preexisting crate" 221 | -------------------------------------------------------------------------------- /tests/cases/ownership-3.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # Carnet © 2021 Kutometa SPC, Kuwait 5 | # 6 | # Unless otherwise expressly stated, this work and all related 7 | # material are made available to you under the terms of version 3 8 | # of the GNU Lesser General Public License (hereinafter, the 9 | # LGPL-3.0) and the following supplemental terms: 10 | # 11 | # 1. This work must retain all legal notices. These notices must 12 | # not be altered or truncated in any way. 13 | # 14 | # 2. The origin of any derivative or modified versions of this 15 | # work must not be presented in a way that may mislead a 16 | # reasonable person into mistaking the derive work to originate 17 | # from Kutometa or the authors of this work. 18 | # 19 | # 3. Derivative or modified versions of this work must be clearly 20 | # and easily distinguishable from the original work by a 21 | # reasonable person. 22 | # 23 | # 4. Unless express permission is granted in writing, The name of 24 | # the original work may not be used within the name of any 25 | # derivative or modified version of the work. 26 | # 27 | # 5. Unless express permission is granted in writing, Trade names, 28 | # trademarks, and service marks used in this work may not be 29 | # included in any derivative or modified versions of this work. 30 | # 31 | # 6. Unless express permission is granted in writing, the names and 32 | # trademarks of Kutometa and other right holders may not be used 33 | # to endorse derivative or modified versions of this work. 34 | # 35 | # 7. The licensee must defend, indemnify, and hold harmless 36 | # Kutometa and authors of this software from any and all 37 | # actions, claims, judgments, losses, penalties, liabilities, 38 | # damages, expenses, demands, fees (including, but not limited 39 | # to, reasonable legal and other professional fees), taxes, and 40 | # cost that result from or in connection with any liability 41 | # imposed on Kutometa or other authors of this software as a 42 | # result of the licensee conveying this work or a derivative 43 | # thereof with contractual assumptions of liability to a third 44 | # party recipient. 45 | # 46 | # Unless expressly stated otherwise or required by applicable law, 47 | # this work is provided AS-IS with NO WARRANTY OF ANY KIND, 48 | # INCLUDING THE WARRANTY OF MERCHANTABILITY AND FITNESS FOR A 49 | # PARTICULAR PURPOSE. Use this work at your own risk. 50 | # 51 | # This license agreement is governed by and is construed in 52 | # accordance with the laws of the state of Kuwait. You must submit 53 | # all disputes arising out of or in connection with this work to 54 | # the exclusive jurisdiction of the courts of Kuwait. 55 | # 56 | # You should have received a copy of the LGPL-3.0 along with this 57 | # program; if not, visit www.ka.com.kw/en/legal, write to 58 | # legal@ka.com.kw, or write to Kutometa SPC, 760 SAFAT 13008, 59 | # Kuwait. 60 | # 61 | 62 | set -euH 63 | set -o pipefail 64 | source "common.sh" 65 | 66 | [[ -e "$CARNET_PATH" ]] || { 67 | fatal "'$CARNET_PATH' is not an executable!" 68 | } 69 | 70 | testing_logic() { 71 | export CARNET_UNSTABLE_RSA_BITS="1024" 72 | export CARNET_PUBLISHER_NAME="TEST NAME" 73 | export CARNET_PUBLISHER_EMAIL="TEST_EMAIL" 74 | export CARNET_PUBLISHER_ORG="ORGANIZATION" 75 | export CARNET_PUBLISHER_COUNTRY="KW" 76 | 77 | -- "[LINENO:$LINENO]" "Agree to EULA for new user setup at the same time" 78 | ACTIVE_USER="ORIGINAL_OWNER" 79 | run "0" "$CARNET_PATH" --carnet:config-dir="../configs/$ACTIVE_USER" enable "eula-agreement" 80 | 81 | -- "[LINENO:$LINENO]" "ORIGINAL_OWNER new crate" 82 | ACTIVE_USER="ORIGINAL_OWNER" 83 | run "0" "$CARNET_PATH" --carnet:config-dir="../configs/$ACTIVE_USER" new "lib1" --lib 84 | 85 | cd "lib1" 86 | 87 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" edit 88 | 89 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" test 90 | 91 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" seal 92 | 93 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" new "vendor/sublib1" --lib 94 | 95 | cd "vendor/sublib1" 96 | 97 | run "0" "$CARNET_PATH" --carnet:config-dir="../../../../configs/$ACTIVE_USER" seal 98 | run "0" "$CARNET_PATH" --carnet:config-dir="../../../../configs/$ACTIVE_USER" test 99 | echo "pub fn add(a: usize, b: usize) -> usize { a + b } " > "src/lib.rs" 100 | echo "#[test] fn add_test() { assert_eq!(add(1,2), 3); } " >> "src/lib.rs" 101 | run "107" "$CARNET_PATH" --carnet:config-dir="../../../../configs/$ACTIVE_USER" test 102 | run "0" "$CARNET_PATH" --carnet:config-dir="../../../../configs/$ACTIVE_USER" edit 103 | run "0" "$CARNET_PATH" --carnet:config-dir="../../../../configs/$ACTIVE_USER" test 104 | run "0" "$CARNET_PATH" --carnet:config-dir="../../../../configs/$ACTIVE_USER" done 105 | run "0" "$CARNET_PATH" --carnet:config-dir="../../../../configs/$ACTIVE_USER" seal 106 | cd "../.." 107 | 108 | run "0" "$CARNET_PATH" --config-dir="../../configs/$ACTIVE_USER" test 109 | echo "sublib1 = { path=\"vendor/sublib1\" }" >> "Cargo.toml" 110 | cat > "src/lib.rs" <
/dev/null 96 | run "1" stat "/run/blkid/blkid.tab.ne" > /dev/null 97 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" sandbox-run which stat 98 | run "1" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" sandbox-run stat "/run/blkid/blkid.tab" 99 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" sandbox-run --unsandbox-filesystem stat "/run/blkid/blkid.tab" > /dev/null 100 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" sandbox-run --disable-sandbox stat "/run/blkid/blkid.tab" > /dev/null 101 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" sandbox-run --ro-paths="/run/blkid/blkid.tab" stat "/run/blkid/blkid.tab" > /dev/null 102 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" sandbox-run --ro-paths="/run/blkid" stat "/run/blkid/blkid.tab" > /dev/null 103 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" sandbox-run --ro-paths="/run" stat "/run/blkid/blkid.tab" > /dev/null 104 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" sandbox-run --rw-paths="/run/blkid/blkid.tab" stat "/run/blkid/blkid.tab" > /dev/null 105 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" sandbox-run --rw-paths="/run/blkid" stat "/run/blkid/blkid.tab" > /dev/null 106 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" sandbox-run --rw-paths="/run" stat "/run/blkid/blkid.tab" > /dev/null 107 | run "1" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" sandbox-run --rw-paths="/run" stat "/run/blkid/blkid.tab.ne" > /dev/null 108 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" sandbox-run --carnet:ro-paths="/run/blkid/blkid.tab" stat "/run/blkid/blkid.tab" > /dev/null 109 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" sandbox-run --carnet:ro-paths="/run/blkid" stat "/run/blkid/blkid.tab" > /dev/null 110 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" sandbox-run --carnet:ro-paths="/run" stat "/run/blkid/blkid.tab" > /dev/null 111 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" sandbox-run --carnet:rw-paths="/run/blkid/blkid.tab" stat "/run/blkid/blkid.tab" > /dev/null 112 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" sandbox-run --carnet:rw-paths="/run/blkid" stat "/run/blkid/blkid.tab" > /dev/null 113 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" sandbox-run --carnet:rw-paths="/run" stat "/run/blkid/blkid.tab" > /dev/null 114 | run "1" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" sandbox-run --carnet:rw-paths="/run" stat "/run/blkid/blkid.tab.ne" > /dev/null 115 | 116 | TESTFILE="$(mktemp)" # messy 117 | echo "0" > "$TESTFILE" 118 | run "0" bash -c "[[ \$(cat '$TESTFILE') == '0' ]]" 119 | run "1" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" sandbox-run bash -c "[[ \$(cat '$TESTFILE') == '0' ]]" 120 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" sandbox-run --unsandbox-filesystem bash -c "[[ \$(cat '$TESTFILE') == '0' ]]" 121 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" sandbox-run --unsandbox-filesystem bash -c "echo '1' >'$TESTFILE'" 122 | run "0" bash -c "[[ \$(cat '$TESTFILE') == '1' ]]" 123 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" sandbox-run --unsandbox-filesystem bash -c "[[ \$(cat '$TESTFILE') == '1' ]]" 124 | run "1" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" sandbox-run bash -c "[[ \$(cat '$TESTFILE') == '1' ]]" 125 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" sandbox-run --carnet:ro-paths="$TESTFILE" bash -c "[[ \$(cat '$TESTFILE') == '1' ]]" 126 | run "1" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" sandbox-run --carnet:ro-paths="$TESTFILE" bash -c "echo '2' >'$TESTFILE'" 127 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" sandbox-run --carnet:ro-paths="$TESTFILE" bash -c "[[ \$(cat '$TESTFILE') == '1' ]]" 128 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" sandbox-run --carnet:rw-paths="$TESTFILE" bash -c "echo '2' >'$TESTFILE'" 129 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" sandbox-run --carnet:ro-paths="$TESTFILE" bash -c "[[ \$(cat '$TESTFILE') == '2' ]]" 130 | run "0" bash -c "[[ \$(cat '$TESTFILE') == '2' ]]" 131 | rm "$TESTFILE" 132 | 133 | 134 | -- "[LINENO:$LINENO]" "ORIGINAL_OWNER checking process sandboxing, may take a while..." 135 | # Racy but should pass on most systems most of the time 136 | SLEEP_PID="---" 137 | start_sleep() { 138 | sleep 10d & 139 | SLEEP_PID="$!" 140 | } 141 | start_sleep 142 | run "0" test -d "/proc/$SLEEP_PID" 143 | run "1" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" sandbox-run test -d "/proc/$SLEEP_PID" 144 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" sandbox-run --unsandbox-processes test -d "/proc/$SLEEP_PID" 145 | run "1" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" sandbox-run kill "$SLEEP_PID" 146 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" sandbox-run --unsandbox-processes kill "$SLEEP_PID" 147 | 148 | 149 | -- "[LINENO:$LINENO]" "ORIGINAL_OWNER checking network sandbox, may take a while..." 150 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" sandbox-run which wget 151 | run "4" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" sandbox-run wget 'http://www.example.com' 152 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" sandbox-run --unsandbox-network wget 'http://www.example.com' 153 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" sandbox-run --disable-sandbox wget 'http://www.example.com' 154 | 155 | 156 | -- "[LINENO:$LINENO]" "ORIGINAL_OWNER testing terminal/session isolation" 157 | # Federico Bento's poc: 158 | gcc -o "escape.bin" -x c - < 160 | #include 161 | #include 162 | 163 | int main() 164 | { 165 | char *c = "echo \"Escaped from sandbox!\"\n"; 166 | while(*c) ioctl(0, TIOCSTI, c++); 167 | return 0; 168 | } 169 | ESCAPE 170 | # assumes an tty input buffer, so disabled 171 | #run "0" ./escape.bin 172 | #read -r INJECTED; # Reads from terminal buffer. Don't type anyting. 173 | #run "0" test "$INJECTED" == "echo \"Escaped from sandbox!\"" 174 | ACTIVE_USER="ORIGINAL_OWNER" 175 | run "0" "$CARNET_PATH" --carnet:config-dir="../../configs/$ACTIVE_USER" sandbox-run ./escape.bin 176 | run "1" test -f "escaped" 177 | } 178 | 179 | test_environment testing_logic "Testing the sandbox" "This preforms a few santiy tests to check that the sandbox is doing its job" 180 | -------------------------------------------------------------------------------- /tests/common.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # Carnet © 2021 Kutometa SPC, Kuwait 5 | # 6 | # Unless otherwise expressly stated, this work and all related 7 | # material are made available to you under the terms of version 3 8 | # of the GNU Lesser General Public License (hereinafter, the 9 | # LGPL-3.0) and the following supplemental terms: 10 | # 11 | # 1. This work must retain all legal notices. These notices must 12 | # not be altered or truncated in any way. 13 | # 14 | # 2. The origin of any derivative or modified versions of this 15 | # work must not be presented in a way that may mislead a 16 | # reasonable person into mistaking the derive work to originate 17 | # from Kutometa or the authors of this work. 18 | # 19 | # 3. Derivative or modified versions of this work must be clearly 20 | # and easily distinguishable from the original work by a 21 | # reasonable person. 22 | # 23 | # 4. Unless express permission is granted in writing, The name of 24 | # the original work may not be used within the name of any 25 | # derivative or modified version of the work. 26 | # 27 | # 5. Unless express permission is granted in writing, Trade names, 28 | # trademarks, and service marks used in this work may not be 29 | # included in any derivative or modified versions of this work. 30 | # 31 | # 6. Unless express permission is granted in writing, the names and 32 | # trademarks of Kutometa and other right holders may not be used 33 | # to endorse derivative or modified versions of this work. 34 | # 35 | # 7. The licensee must defend, indemnify, and hold harmless 36 | # Kutometa and authors of this software from any and all 37 | # actions, claims, judgments, losses, penalties, liabilities, 38 | # damages, expenses, demands, fees (including, but not limited 39 | # to, reasonable legal and other professional fees), taxes, and 40 | # cost that result from or in connection with any liability 41 | # imposed on Kutometa or other authors of this software as a 42 | # result of the licensee conveying this work or a derivative 43 | # thereof with contractual assumptions of liability to a third 44 | # party recipient. 45 | # 46 | # Unless expressly stated otherwise or required by applicable law, 47 | # this work is provided AS-IS with NO WARRANTY OF ANY KIND, 48 | # INCLUDING THE WARRANTY OF MERCHANTABILITY AND FITNESS FOR A 49 | # PARTICULAR PURPOSE. Use this work at your own risk. 50 | # 51 | # This license agreement is governed by and is construed in 52 | # accordance with the laws of the state of Kuwait. You must submit 53 | # all disputes arising out of or in connection with this work to 54 | # the exclusive jurisdiction of the courts of Kuwait. 55 | # 56 | # You should have received a copy of the LGPL-3.0 along with this 57 | # program; if not, visit www.ka.com.kw/en/legal, write to 58 | # legal@ka.com.kw, or write to Kutometa SPC, 760 SAFAT 13008, 59 | # Kuwait. 60 | # 61 | 62 | set -euH 63 | set -o pipefail 64 | 65 | 66 | if [[ -t 2 ]]; then 67 | RED="\e[1;31m" 68 | GREEN="\e[1;34m" 69 | YELLOW="\e[1;33m" 70 | WEIRD="\e[1;44m" 71 | DIM="\e[2m" 72 | BOLD="\e[1m" 73 | RESET="\e[0m" 74 | fi 75 | 76 | 77 | 78 | step() { 79 | printf "${GREEN}%12s${RESET} %s\n" "$1" "$2" 1>&2 80 | } 81 | substep() { 82 | printf "\n\n${DIM}TESTING_SCRIPTS :: Step: %s${RESET}\n" "$*" 1>&2 83 | } 84 | ignored_step() { 85 | printf "${YELLOW}%12s${RESET} %s\n" "$1" "$2" 1>&2 86 | } 87 | 88 | fatal() { 89 | printf "${RED-}TESTING SCRIPTS :: error${RESET-}${BOLD-}:${RESET-} ${DIM-} ${RESET-} $*\n" 1>&2 90 | exit 104 91 | } 92 | 93 | warn() { 94 | printf "${YELLOW-}TESTING SCRIPTS :: warning${RESET-}${BOLD-}:${RESET-} ${DIM-} ${RESET-} $*\n" 1>&2 95 | } 96 | 97 | debug() { 98 | if [[ "${DEBUG-}" == "yes" ]]; then 99 | printf "${DIM-}verbose: -- $PROJECT_NAME -- $*${RESET-}\n" 1>&2 100 | fi 101 | } 102 | 103 | XX() { 104 | substep "$@" 105 | } 106 | 107 | --() { 108 | substep "$@" 109 | } 110 | 111 | 112 | test_environment() { 113 | step "$2" "$3" 1>&2 114 | local RESULT="0" 115 | local TESTDIR="$(mktemp -d)" 116 | ( 117 | cd "$TESTDIR" 118 | mkdir "configs" 119 | mkdir "crates" 120 | cd "crates" 121 | "$1" 122 | ) || RESULT="$?" 123 | if [[ "$RESULT" != "0" ]] && [[ "${FAIL_SHELL-}" == "yes" ]]; then 124 | echo "Entering into interactive prompt..." 1>&2 125 | ( cd "$TESTDIR" && sh ) || true 126 | fi 127 | rm -r "$TESTDIR" 128 | return "$RESULT" 129 | } 130 | 131 | 132 | run() { 133 | local RESULT="0" 134 | local EXPECTED="$1" 135 | shift 136 | "$@" || RESULT="$?" 137 | if [[ "$RESULT" == "$EXPECTED" ]]; then 138 | printf "OKAY (expected $RESULT): %s\n" "$*" 1>&2 139 | return 0 140 | else 141 | fatal "ERROR (expected $EXPECTED but got $RESULT): $*" 1>&2 142 | return 1 143 | fi 144 | } 145 | --------------------------------------------------------------------------------