From 23952703c59f9bc0456a806035dca8c606033d08 Mon Sep 17 00:00:00 2001 From: aestetix Date: Fri, 19 May 2017 19:45:50 +0200 Subject: [PATCH] First commit for pgpfs --- README.md | 43 ++++++++++++++ pgpfs.py | 127 +++++++++++++++++++++++++++++++++++++++ requirements.txt | 1 + sample.kat | 152 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 323 insertions(+) create mode 100644 README.md create mode 100755 pgpfs.py create mode 100644 requirements.txt create mode 100644 sample.kat diff --git a/README.md b/README.md new file mode 100644 index 0000000..802732a --- /dev/null +++ b/README.md @@ -0,0 +1,43 @@ +# PGP File System + +PGP File System (pgpfs) is a tool to turn your friendly pgp keyserver into a +redundant persistant filesystem. + +## Installation + +From a base Ubuntu 14.04.5 installation, please install the following packages: + +``` +apt-get install git python-pip python-virtualenv rng-tools +``` + +Check out the repository onto your local machine: +``` +git clone git@gitlab.com:aestetix/pgpfs.git +``` +This creates a directory called "pgpfs." Go into the directory and run +``` +virtualenv . +source bin/activate +pip install -r requirements.txt +``` + +## Usage +pgpfs is simple to use. It is able to both `store` and `fetch` documents from +the keyserver. Here are examples of usage: + +### `store` +To store the file sample.mp3 and save the Key Allocation Table (kat) in +sample.kat, run: +``` +python pgpfs.py store sample.mp3 sample.kat +``` +This will create a file called sample.kat to be used when you want to retrieve +your file. + +### `fetch` +To fetch the file sample.mp3 from the keyserver, assuming the kat file is called +sample.kat, run: +``` +python pgpfs.py fetch sample.kat sample.mp3 +``` diff --git a/pgpfs.py b/pgpfs.py new file mode 100755 index 0000000..14044cd --- /dev/null +++ b/pgpfs.py @@ -0,0 +1,127 @@ +#!bin/python +""" pgpfs is a tool to turn your friendly pgp keyserver into a redundant +persistant filesystem.""" + +import os +import sys +import re +import base64 +from hashlib import sha256 +import gnupg + +os.system('rm -rf gpg') +GPG = gnupg.GPG(gnupghome='gpg') +KEYSERVER = 'pgp.mit.edu' + +# trial and error lead to this number +SPLIT_LENGTH = 986 + +# store file + +def read_file_into_list(source_file): + """ reads file into list""" + with open(source_file, 'r') as source: + data = base64.b64encode(source.read()) + return [data[i:i+SPLIT_LENGTH] for i in range(0, len(data), SPLIT_LENGTH)] + +def create_comment(data): + """ takes data bit and turns it into a key comment""" + checksum = sha256(data).hexdigest() + comment = checksum + ' ' + data + return comment + +def create_key(name): + """ creates gpg key out of given data""" + input_data = GPG.gen_key_input( + key_type='RSA', + key_length='1024', + name_real='PGP File System', + name_comment=create_comment(name), + name_email='placeholder@email.address' + ) + return GPG.gen_key(input_data) + +def send_key(key_id): + """ uploads given key to keyserver""" + key_id = str(key_id) + GPG.send_keys(KEYSERVER, key_id) + if key_id == GPG.search_keys(key_id, KEYSERVER)[0]['keyid']: + return key_id + else: + error = 'Error uploading key ', key_id + return error + +def store_file(filename1, filename2): + """ overall function to upload file to keyserver""" + print 'Splitting ', filename1, ' into encoded comments for keys' + file_list = read_file_into_list(filename1) + output_file = open(filename2, 'w') + counter_length = len(file_list) + counter = 0 + for chunk in file_list: + print 'Creating key ', counter, ' of ', counter_length + counter = counter + 1 + key_id = create_key(chunk) + output_file.write(send_key(key_id)+'\n') + print '--> key has been created and uploaded' + print 'File has been successfully uploaded to ', KEYSERVER + +# fetch file + +def get_key_comment(key_id): + """ returns comment section of a given key""" + return GPG.search_keys(key_id, KEYSERVER)[0]['uids'] + +def parse_key(key_id): + """" parses file bit out of key comment""" + comment = get_key_comment(key_id)[0] + regex = re.compile(".*?\\((.*?)\\)") + comment_bits = re.findall(regex, comment)[0].split(' ') + if comment_bits[0] == sha256(comment_bits[1]).hexdigest(): + return comment_bits[1] + +def fetch_file(index_file, filename): + """ overall function to fetch component file parts from keyserver""" + with open(index_file, 'r') as index, open(filename, 'w+') as download: + print 'Fetching keys from ', KEYSERVER, ' to create ', filename + fetched_file = '' + index_length = len(index.readlines()) + index.seek(0) # because python is stupid + counter = 0 + for key in index.readlines(): + print 'Fetching key ', counter, ' of ', index_length + counter = counter + 1 + fetched_file = fetched_file + parse_key(key.rstrip('\n')) + print 'All keys have been downloaded' + download.write(base64.b64decode(fetched_file)) + print 'File has been decoded and saved as ', filename + +# handle command line input + +if len(sys.argv) < 3: + print """Usage: ./pgpfs.py [action] filename1 filename2' + action can be either ''store'' or ''fetch''' + + When action is 'store': + filename1 is the file to upload, filename2 is the name of the key allocation table + When action is 'fetch': + filename1 is the key allocation table, filename2 is the output file + + Example uses: + - To store 'sample.mp3' on the keyserver + ./pgpfs.py store sample.mp3 sample.kat + - To fetch the file contained in 'sample.kat' and store it as 'sample.mp3' + ./pgpfs.py fetch sample.kat sample.mp3 + """ + sys.exit(0) + +ACTION = sys.argv[1] + +if ACTION not in ['store', 'fetch']: + print 'Please specific either ''store'' or ''fetch''' + sys.exit(0) + +if ACTION == 'store': + store_file(sys.argv[2], sys.argv[3]) +elif ACTION == 'fetch': + fetch_file(sys.argv[2], sys.argv[3]) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..45ce307 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +python-gnupg diff --git a/sample.kat b/sample.kat new file mode 100644 index 0000000..3828ee6 --- /dev/null +++ b/sample.kat @@ -0,0 +1,152 @@ +FC7E32931156981F45C8921403FC6E2E71437504 +AEFD299201F29D9A214F12A6ED67FD5C097D395E +77D8C204A22D1B95A94F8F968B7D7D6C067F03D0 +DC1860F1F31B97CF0B4C810CC93F45CBF53899DF +7F2DB84F62FB6FB92DDAEBF2C72CE0BEFF30B39C +6855D9307D0D028EC9331D2035A7073251DA8706 +8D9F2349B9985C9ABAA8CFEB97D7987A2E590F51 +C2A4FA1711BA44AE4FA4BD6D64968C33EBD48804 +1A14F953CF068E31B024B14C9E32560C66B72DE6 +9761655B70B37C151A0F8BF91DC037FE91467EB5 +381ADF37F08AD6EC68C29C2BD5D8C50ECB9D2C92 +6E02EF0894D791B14763C3F9C08DE00FF0FAC72C +83BAB626A749B42BFB0DD9A089C1C980B54BFADD +70172D0D8250348D39A8DCC35BBCAEA9CEAD5095 +5641A421CC6EC4D653A5DF7A7E7E6310223F40BB +B18D5207DB52F67B8B887C2EF29F46D59EB47057 +B61017BB57CD67E799F00030F4DA2ABC40AD954F +553A1FA1BC4B2E134FD8B599EE1DD665ADDBA5F3 +C784F793E7F5227E5DE0990C9A974A93412D38F0 +C21D729AB22E32E8D099805F7CD229CE467C1070 +85327227E8F88651D289585306D03094A219DAFB +15BCDE4302088E55E4BD0F350802FDCDF9EFCBE9 +713E962F520A26E4053E2BC6651D639B47AC77C2 +43D14E04CDD79D91F170AFE4CC1E9F4C98C5ADA5 +54F165ED18B2AE530646EFFF0C3148F8FFBC2BAF +E20BC2E85EF4710D865ACED955BD03C4BC1242CF +DFB4A066437EA239C214B8A1029F1C141CECAB4B +C35F3F42A0EE1CD4D667DFB54265422B6F59D6D2 +EBCF384AE04B4819825DB50274CF2B8B25013663 +DA50EF1B63294B0F0C8F3EB8E764A10D813D6161 +504929CCB20136D2C4F6EBE000AAD0977A175F76 +C3E57059241C861E776D2C67E5C355A967BC95C7 +25F9417ADD87117A6F7142FDFE376CC87EA544AC +C12E9E766A9171CB308D2A13043CBC2ED8DD46FC +C342DE30EC6C4EABB9ECA01921C3F45C9E113BA3 +ABCBCF7C746F88C62599373850D271251650DA5E +3A8915A4E29751BF9749CCDE8994FD78F9BD69D8 +1DE994F81F3BF045D0BAA2F3BA569CF9D577522F +D14A65F9C9BD9B7DB809BA75A014CF92C9099A15 +A66CCEC87D2086A7076DB7A9F727E06B4DD0F1CB +98C2188983492CD882094E13899D5A303B2D4699 +EF736B36CB5BD35676251A25165E198CE0E50B0B +9A0B6A1716BE118373E44A196FF6E04971BF30B5 +4D600F90080B05F3556896A51D50FFE827650A1A +5E04FE85AEB4EBC5B7EBEC1DD6795EEAE7255BEC +9FF2074D485AB4F9EE10261C497EB569D2826268 +A8F4F7279CDBBBC8F8CAE7655EA0C8261B474D63 +77AE3944D5D3F29BB6DEE7417DE5AD276BB812FE +BF510C2FCD094E326016EF3F1D68B879C07A3554 +3FEEB6AD801F0D890BDC1E856AEA8066240F72CC +74EF6FDC61394F11B3D30BAAB2E0D0E03B90FD9A +E8743554CE30989683BA6968183E80E5530955C9 +1D916686C99DA213922A2AA3C92E09DAF83ADFA6 +9C68F90DDD04573E01CC784095E8AD7AFBD3A958 +1D7D8F2E058AF51D259E40889E1F54F298C9CF39 +B62E99A68496D7BC364DD6AA078EA3575D0C9BC1 +A27EBF1A05F69D35D31C7D7D0BD466AD4FD2632B +17F0964EC2CBDC03DB95DAA41C2F125B7F959119 +D2D5A6C6811E010FB704EAA6FF6436C30F7C0A8D +231A76CFF6A01447CC10C402AEF4FB526EEBE04F +F51F6DD8E7C54F38F44BFF28F2EE02A71D7DCA05 +6C7F4EA5A1D5389A285576A5059B7508FF62A143 +3240819055A4C33C63038C07AB074E7B1193A46E +E212CE4C6AF43342869D63069FD534087F60E0DD +840460655FB874FF8F9A80F3AF200143EDE39C01 +7D397CF95C2390FEFFC992A1A27CC1069E6B430F +34760DE6285F5BE3A1CD587BC780D2C719D32EA4 +FFBE5077A12BB8F634C3443D62EC8D0C5B8EB58E +396B6CD12626EF54B60EBF3EB8E741069F505795 +F92215F565A48FF1CE555430DFC12645D735BB4D +9186E87CD5268E242BB741B504C3F6E6A68D8DB5 +C8B2AAE555130CD59DADB4D1ADC481E2CF4F22F9 +3027B0DF6EFC9A65CC0C96B03C529763A9DF0441 +888D93910A811942A08849917630E274C7B25212 +A54FF2D620F7FFB2C8BAE3D1FE5BA6D0E011A85C +3C3682B68B081467D238ABF533FAE9DC18023471 +236373230F09D348F4297B930286CF184DB8D58D +0E8EA256ACB357FAE5EEE7CBF4FCD45553D9B5FD +9382FEB1F294763DAEE1B3A2E0447BC888F372D6 +5C7DC7EE295B4526D931B9960D7BFC942A406849 +B021623CA67F9D9FEC2F185980C61BF5FB794FEF +17570A0A21DF24ECD23798378EA6BFA5435E88FC +2E2DEDB85EF6CBEFE52FAD7FD361BC7B659A993F +0619E510B69066E2D905AA8196C45E01B8B88AFD +46B542E6C1C052971A9600A157587967E6B06949 +5B5B738391ADC1E399E8D4E90E1056C5E5466261 +71B97797C1D4BEC8D5C5F94DA64595EC29ACB387 +0273561D3A2E4EBA7052C4306E18F92BEEB5CADE +74E59E4DFAB3AD26FD7F2A929A574B2C9EC8B307 +7436750D2DCF366EA438B9CAF67D8491E0CCFD83 +2336143F7FFEE099A562C79F940E1FB8B5185CBD +E19149A9A44C0930CADA2B00A4E159A380B82CF4 +69588D2817EDE5A47EB76C95D996B5FC32559BCD +99A36ACEE0AAC24636E9C352206162305D3AF7D5 +025CE5B6CD9ED7C7E155CFA71DCEE7230FF06C92 +923BC863D50ADFB81D59216187818104A4FA6647 +78A648F27596C388342AF41FABC12C3EF8D19419 +0BFC560C358749C97B27455B3725A2B7B2170A44 +0FB6FC2AB8203DC1B766B35B13E223590AAE0E62 +5246CBB8A6BC2A1940FA5C1EB33CE9AD5678E6F1 +B3CDB213917711608B10F67623FF8BC2990FB01A +8E9DCDF64E34576F508B2AC1160DF9EB39753351 +729C7801E2B34E43F8677840C62892C25EAB9C31 +CCAF6D87C4367C6D411A416AE47DCD9100CFCC87 +11CB8E5E9632470811409CA26D76D79EB014E736 +E300526068BC9859B801E044EB04C2FFEE00A325 +5FDD54931FB220529B3E239BCB39E20E6AB49E6D +1620368CA99E94FE680691929A9EC6963AAF981E +BA150F4D664C3FF2D0EBEAD54D6B84D86C546D92 +3CCE2C670F46C85A438CC74C93EC3DCE6B61E397 +63D5A2432B606145AFDC033A335FEC7F906E83B3 +CE93757422A3B579FCDEE93B377210563332F891 +177B9AA184E5E9BA6E242C876011ABF4979F4BAF +FC46D820A1ADC9D377A5AF3D3669B7F0A590D9F8 +8E507A347FEFA1BCC694A8A8834240896566791A +B0A28BD84FD258881AE543FF4F3A00C91FC4A734 +BBF485E9CA9E81AA048BA19B2635E10063ACF01E +CFBCEE242835D4FAB673C5FE1E16657256582989 +583E7794847191DBD38183873F633627D0508A26 +DDD1EC1314122342EB547F8C541157A89945D3E7 +120D681444A7B4F59E39FFFD2DAB5E0B4DC17009 +4FDCBCF0C75B35DF4F570E921892BB17B16D8062 +D736015EB64E9FBE622CCEC7B9EF951E8C2D3E3A +D36DB784C7A565E76C9C40776017D134B4447C6F +343B530F95B2CAFB8620A4FD4B31102D02061543 +90AB64DFE7D280E96EAF2B7DA5E522634012C79E +DAA9CE75C9A1F8AB54C51CA153AC4C95C3C6EE6B +F18D849F47A56A55DD00B21C638B2212C7518CDC +F7C035D8A5C597BB579E591EDE497BA0E1162B09 +CC48F8C613A12DE9AD9CFE6B195320FDBDE38F31 +745730E07AF64A794CDBEA9739726598CB17327B +79118B75E03CED3485F715DA9DA60399AEBEBCFE +90D01EB404B84FCA5BF12E183C2D178E076DB003 +4EF9B48377F764E46E3599FF7917A48396D59870 +2F75D55AED2691AE70A90CE3D85D872AB02EE17D +987F3F0A5746FCC011B565E2D7BDE6A4BA3E1E70 +51172E0EE67884A08DFD14628B334CCE66A5B2A5 +0D161D7D63FA04BB6A74214347677220DBAD0E34 +3554DC686D53C10C4C847A4DED57FEEBBC609A67 +3D66E2C78F486457596F8819FDFBBD8E3409E9D7 +B94447C1FC5172C2E8877699E1EEA744F052220B +A1AB1EAC0E84A116D348E04CA44EEA033F5AC4AD +A3CB4E3827F195B6FDC8ECCF6D036631AF1D1866 +56FEB79F69F10DDB33E778ADE835AA029804292B +E827BF52999953B93214F796760B8C3771490129 +CBD1C8C8B3946A83A5D8233876CA0CFA5D4302C2 +8A65DBFD30294CF8AB556D89E04D7D476AEBF597 +96F4EABCF809FD1802C1BF0A8000A3FAF9C1C6F5 +CDED5632BC11999E545D981CCFFCDD3ACC04BA17 +9B524CCB9647E4FE6ED79D129049AA1FAD18DA23 +4D296FBBB9FB6732EC3CD24C674BAA29B827002C +11D08E00DBC668225E6AA084AF1C68F6519C4C31