Слияние кода завершено, страница обновится автоматически
#!/usr/bin/env python3
# Author: Joshua Chen
# Date: 2015-12-05
# Location: Shenzhen
# Desc: secure data before pushing it to the remote,
# it pushes one branch at a time.
import os, sys
prog_path = os.path.realpath(__file__)
prog_dir = os.path.dirname(prog_path)
sys.path.insert(0, prog_dir)
import lib
class Pusher():
""" Find out all commits created since the last secure-push in the given
branch; archive all objects of all the commits found, encrypt it and save
it to a blob object, create a tree for it, then a commit; the file name,
author info can be faked . Encrypted commit will be placed in a totally
separated branch named like this: cipher-origin-master. After transforming
all plaintext commits into ciphertext, call git-push to actually push.
"""
def __init__(self, remote, branch, force=False):
lc_p_branch = 'plain-%s-%s' % (remote, branch)
self.checkBranch(lc_p_branch) # may raise an exception
self.remote = remote
self.branch = branch
self.force = force
self.lc_c_branch = 'cipher-%s-%s' % (remote, branch)
self.rmt_c_branch = 'cipher-%s' % branch
position_record = lib.get_position_record(remote, branch)
self.plain_position = position_record[0]
self.cipher_position = position_record[1]
self.new_objects = []
self.transformed = False
self.transform()
def checkBranch(self, branch):
""" If the branch exists, raise an exception
"""
msg = "%s exists, push not allowed" % branch
assert not lib.branch_exists(branch), msg
def transform(self):
""" Transform plaintext commits into one ciphertext commit, including
all objects directly or indirectly referenced by the commits;
create or update the cipher branch to point to the newly created
cipher commit; encrypt the symmetric key and create a new tag for it.
"""
commits = lib.find_all_commits(self.plain_position, self.branch)
if not commits:
print('Nothing to push')
return
parent = self.cipher_position
name = lib.dense_time_str()
dname = name
fname = name + '.txz.ci'
key = lib.generate_key()
for commit in commits:
lib.copy_out_objects(commit, topdir=dname)
blob = lib.encrypt_path(dname, key)
tree = lib.create_tree(blob, fname, base=parent)
message = 'CIPHER\n\nTree: %s\nBlob: %s\nTop: %s\nBot: %s\n' % (tree, blob, commits[-1], commits[0])
new_commit = lib.create_commit(tree, parent, message)
tname = lib.symkey_tag_prefix + tree
key_blob = lib.secure_key(key, tname)
reason = "prepare for shadow-push"
lib.update_branch(self.lc_c_branch, new_commit, reason)
self.new_objects.extend([new_commit, tree, blob, key_blob])
self.cipher_key_tag = tname
self.transformed = True
self.newest_plain_commit = commits[-1]
self.newest_cipher_commit = new_commit
lib.cleanup(dname)
def push(self):
""" Push the transformed (encrypted) branch to the remote.
On success, update the last-pushed record mapping for the plain
and cipher; on failure, reset the cipher branch back to the last
pushed, remove the tag of the symmetric key, remove all objects
created thus far.
"""
if not self.transformed: return True
if lib.push(self.remote, self.lc_c_branch,
self.rmt_c_branch, self.cipher_key_tag, self.force):
lib.update_position_record(self.remote, self.branch,
self.newest_plain_commit,
self.newest_cipher_commit)
return True
else:
print('Push failed, rolling back...', file=sys.stderr)
reason = "shadow-push failed, roll back"
lib.update_branch(self.lc_c_branch, self.cipher_position, reason)
lib.remove_tag(self.cipher_key_tag)
lib.prune_objects(self.new_objects)
return False
def help(ofile=sys.stdout):
""" Show help message
"""
msg = 'Usage: %s [-f] remote branch' % os.path.basename(sys.argv[0])
print(msg, file=ofile)
if __name__ == '__main__':
if not lib.env_ok():
exit(1)
if len(sys.argv) < 3:
help(sys.stderr)
exit(1)
if '-f' in sys.argv:
force = True
sys.argv.remove('-f')
else:
force = False
remote, branch = sys.argv[1:3]
try:
pusher = Pusher(remote, branch, force)
stat = pusher.push()
code = 0 if stat else 1
exit(code)
except KeyboardInterrupt:
exit(1)
except Exception as e:
print(str(e))
exit(1)
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )