示例#1
0
def test_decryptorfile_for_tarfile(tmpdir):
    testdata = b"file contents"
    data_tmp_name = tmpdir.join("plain.data").strpath
    with open(data_tmp_name, mode="wb") as data_tmp:
        data_tmp.write(testdata)

    tar_data = io.BytesIO()
    with tarfile.open(name="foo", fileobj=tar_data, mode="w") as tar:
        tar.add(data_tmp_name, arcname="archived_content")
    plaintext = tar_data.getvalue()

    encryptor = Encryptor(CONSTANT_TEST_RSA_PUBLIC_KEY)
    ciphertext = encryptor.update(plaintext) + encryptor.finalize()
    enc_tar_name = tmpdir.join("enc.tar.data").strpath
    with open(enc_tar_name, "w+b") as enc_tar:
        enc_tar.write(ciphertext)
        enc_tar.seek(0)

        dfile = DecryptorFile(enc_tar, CONSTANT_TEST_RSA_PRIVATE_KEY)
        with tarfile.open(fileobj=dfile, mode="r") as tar:
            info = tar.getmember("archived_content")
            assert info.isfile() is True
            assert info.size == len(testdata)
            content_file = tar.extractfile("archived_content")
            content = content_file.read()  # pylint: disable=no-member
            content_file.close()  # pylint: disable=no-member
            assert testdata == content

            decout = tmpdir.join("dec_out_dir").strpath
            os.makedirs(decout)
            tar.extract("archived_content", decout)
            extracted_path = os.path.join(decout, "archived_content")
            with open(extracted_path, "rb") as ext_fp:
                assert testdata == ext_fp.read()
示例#2
0
 def test_get_encrypted_archived_file(self, pghoard):
     xlog_seg = "000000090000000000000010"
     content = wal_header_for_file(xlog_seg)
     compressor = pghoard.Compressor()
     compressed_content = compressor.compress(content) + (compressor.flush() or b"")
     encryptor = Encryptor(CONSTANT_TEST_RSA_PUBLIC_KEY)
     encrypted_content = encryptor.update(compressed_content) + encryptor.finalize()
     pgdata = os.path.dirname(pghoard.config["backup_sites"][pghoard.test_site]["pg_xlog_directory"])
     archive_path = os.path.join(pghoard.test_site, "xlog", xlog_seg)
     metadata = {
         "compression-algorithm": pghoard.config["compression"]["algorithm"],
         "original-file-size": len(content),
         "encryption-key-id": "testkey",
     }
     store = pghoard.transfer_agents[0].get_object_storage(pghoard.test_site)
     store.store_file_from_memory(archive_path, encrypted_content, metadata=metadata)
     pghoard.webserver.config["backup_sites"][pghoard.test_site]["encryption_keys"] = {
         "testkey": {
             "public": CONSTANT_TEST_RSA_PUBLIC_KEY,
             "private": CONSTANT_TEST_RSA_PRIVATE_KEY,
         },
     }
     restore_target = os.path.join(pgdata, "pg_xlog", xlog_seg)
     restore_command(site=pghoard.test_site, xlog=xlog_seg, output=restore_target,
                     host="127.0.0.1", port=pghoard.config["http_port"])
     assert os.path.exists(restore_target)
     with open(restore_target, "rb") as fp:
         restored_data = fp.read()
     assert content == restored_data
示例#3
0
    def test_decryptorfile(self):
        # create a plaintext blob bigger than IO_BLOCK_SIZE
        plaintext1 = b"rvdmfki6iudmx8bb25tx1sozex3f4u0nm7uba4eibscgda0ckledcydz089qw1p1"
        repeat = int(1.5 * IO_BLOCK_SIZE / len(plaintext1))
        plaintext = repeat * plaintext1
        encryptor = Encryptor(CONSTANT_TEST_RSA_PUBLIC_KEY)
        ciphertext = encryptor.update(plaintext) + encryptor.finalize()
        plain_fp = tempfile.TemporaryFile(prefix="test-pghoard.", mode="r+b")
        plain_fp.write(ciphertext)
        plain_fp.seek(0)
        fp = DecryptorFile(plain_fp, CONSTANT_TEST_RSA_PRIVATE_KEY)  # pylint: disable=redefined-variable-type
        assert fp.fileno() == plain_fp.fileno()
        assert fp.readable() is True
        assert fp.writable() is False
        fp.flush()
        result = fp.read()
        assert plaintext == result

        assert fp.seekable() is True
        with pytest.raises(ValueError):
            fp.seek(-1)
        fp.seek(0, os.SEEK_SET)
        with pytest.raises(io.UnsupportedOperation):
            fp.seek(1, os.SEEK_CUR)
        with pytest.raises(io.UnsupportedOperation):
            fp.seek(1, os.SEEK_END)
        with pytest.raises(ValueError):
            fp.seek(1, 0xff)
        assert fp.seek(0, os.SEEK_END) == len(plaintext)
        assert fp.seek(0, os.SEEK_CUR) == len(plaintext)

        fp.seek(0)
        result = fp.read()
        assert plaintext == result
        assert fp.read(1234) == b""
        assert fp.read() == b""

        fp.seek(0)
        result = fp.read(8192)
        assert result == plaintext[:8192]
        result = fp.read(8192)
        assert result == plaintext[8192:8192 * 2]
        result = fp.read(IO_BLOCK_SIZE * 2)
        assert plaintext[8192 * 2:] == result
        assert fp.seek(IO_BLOCK_SIZE // 2) == IO_BLOCK_SIZE // 2
        result = fp.read()
        assert len(result) == len(plaintext) - IO_BLOCK_SIZE // 2
        assert plaintext[IO_BLOCK_SIZE // 2:] == result

        fp.seek(2)
        result = fp.read(1)
        assert plaintext[2:3] == result
        assert fp.tell() == 3
        with pytest.raises(io.UnsupportedOperation):
            fp.truncate()
        # close the file (this can be safely called multiple times), other ops should fail after that
        fp.close()
        fp.close()
        with pytest.raises(ValueError):
            fp.truncate()
示例#4
0
    def test_decryptorfile_for_tarfile(self):
        testdata = b"file contents"
        data_tmp = tempfile.NamedTemporaryFile(prefix="test-pghoard.",
                                               mode="r+b")
        data_tmp.write(testdata)
        data_tmp.flush()

        tmp = tempfile.TemporaryFile(prefix="test-pghoard.", mode="r+b")
        tar = tarfile.open(name="foo", fileobj=tmp, mode="w")
        tar.add(data_tmp.name, arcname="archived_content")
        tar.close()

        tmp.seek(0)
        plaintext = tmp.read()

        tmp.seek(0)
        tmp.truncate()
        encryptor = Encryptor(CONSTANT_TEST_RSA_PUBLIC_KEY)
        ciphertext = encryptor.update(plaintext) + encryptor.finalize()
        tmp.write(ciphertext)

        tmp.seek(0)
        tmp = DecryptorFile(tmp, CONSTANT_TEST_RSA_PRIVATE_KEY)  # pylint: disable=redefined-variable-type
        tar = tarfile.open(fileobj=tmp, mode="r")
        info = tar.getmember("archived_content")
        assert info.isfile() is True
        assert info.size == len(testdata)
        content_file = tar.extractfile("archived_content")
        tar.extract("archived_content", "/tmp/testout")
        content = content_file.read()  # pylint: disable=no-member
        content_file.close()  # pylint: disable=no-member
        assert testdata == content
        tar.close()
        tmp.close()
        data_tmp.close()
示例#5
0
def test_encryptor_decryptor():
    plaintext = b"test"
    for op in (None, "json"):
        if op == "json":
            public_key = json.loads(json.dumps(CONSTANT_TEST_RSA_PUBLIC_KEY))
            private_key = json.loads(json.dumps(CONSTANT_TEST_RSA_PRIVATE_KEY))
        else:
            public_key = CONSTANT_TEST_RSA_PUBLIC_KEY
            private_key = CONSTANT_TEST_RSA_PRIVATE_KEY

        encryptor = Encryptor(public_key)
        decryptor = Decryptor(private_key)
        encrypted = encryptor.update(plaintext) + encryptor.finalize()
        assert plaintext not in encrypted
        offset = 0
        while decryptor.expected_header_bytes() > 0:
            chunk = encrypted[offset:offset +
                              decryptor.expected_header_bytes()]
            decryptor.process_header(chunk)
            offset += len(chunk)
        decrypted_size = len(
            encrypted) - decryptor.header_size() - decryptor.footer_size()
        decrypted = decryptor.process_data(
            encrypted[decryptor.header_size():decryptor.header_size() +
                      decrypted_size])
        decrypted += decryptor.finalize(encrypted[-decryptor.footer_size():])
        assert plaintext == decrypted
示例#6
0
def test_decryptorfile(tmpdir):
    # create a plaintext blob bigger than IO_BLOCK_SIZE
    plaintext1 = b"rvdmfki6iudmx8bb25tx1sozex3f4u0nm7uba4eibscgda0ckledcydz089qw1p1"
    repeat = int(1.5 * IO_BLOCK_SIZE / len(plaintext1))
    plaintext = repeat * plaintext1
    encryptor = Encryptor(CONSTANT_TEST_RSA_PUBLIC_KEY)
    ciphertext = encryptor.update(plaintext) + encryptor.finalize()
    plain_fp = open(tmpdir.join("plain").strpath, mode="w+b")
    plain_fp.write(ciphertext)
    plain_fp.seek(0)
    fp = DecryptorFile(plain_fp, CONSTANT_TEST_RSA_PRIVATE_KEY)  # pylint: disable=redefined-variable-type
    assert fp.fileno() == plain_fp.fileno()
    assert fp.readable() is True
    assert fp.writable() is False
    fp.flush()
    result = fp.read()
    assert plaintext == result

    assert fp.seekable() is True
    with pytest.raises(ValueError):
        fp.seek(-1)
    fp.seek(0, os.SEEK_SET)
    with pytest.raises(io.UnsupportedOperation):
        fp.seek(1, os.SEEK_CUR)
    with pytest.raises(io.UnsupportedOperation):
        fp.seek(1, os.SEEK_END)
    with pytest.raises(ValueError):
        fp.seek(1, 0xff)
    assert fp.seek(0, os.SEEK_END) == len(plaintext)
    assert fp.seek(0, os.SEEK_CUR) == len(plaintext)

    fp.seek(0)
    result = fp.read()
    assert plaintext == result
    assert fp.read(1234) == b""
    assert fp.read() == b""

    fp.seek(0)
    result = fp.read(8192)
    assert result == plaintext[:8192]
    result = fp.read(8192)
    assert result == plaintext[8192:8192 * 2]
    result = fp.read(IO_BLOCK_SIZE * 2)
    assert plaintext[8192 * 2:] == result
    assert fp.seek(IO_BLOCK_SIZE // 2) == IO_BLOCK_SIZE // 2
    result = fp.read()
    assert len(result) == len(plaintext) - IO_BLOCK_SIZE // 2
    assert plaintext[IO_BLOCK_SIZE // 2:] == result

    fp.seek(2)
    result = fp.read(1)
    assert plaintext[2:3] == result
    assert fp.tell() == 3
    with pytest.raises(io.UnsupportedOperation):
        fp.truncate()
    # close the file (this can be safely called multiple times), other ops should fail after that
    fp.close()
    fp.close()
    with pytest.raises(ValueError):
        fp.truncate()
示例#7
0
def test_decryptorfile_for_tarfile(tmpdir):
    testdata = b"file contents"
    data_tmp_name = tmpdir.join("plain.data").strpath
    with open(data_tmp_name, mode="wb") as data_tmp:
        data_tmp.write(testdata)

    tar_data = io.BytesIO()
    with tarfile.open(name="foo", fileobj=tar_data, mode="w") as tar:
        tar.add(data_tmp_name, arcname="archived_content")
    plaintext = tar_data.getvalue()

    encryptor = Encryptor(CONSTANT_TEST_RSA_PUBLIC_KEY)
    ciphertext = encryptor.update(plaintext) + encryptor.finalize()
    enc_tar_name = tmpdir.join("enc.tar.data").strpath
    with open(enc_tar_name, "w+b") as enc_tar:
        enc_tar.write(ciphertext)
        enc_tar.seek(0)

        dfile = DecryptorFile(enc_tar, CONSTANT_TEST_RSA_PRIVATE_KEY)
        with tarfile.open(fileobj=dfile, mode="r") as tar:
            info = tar.getmember("archived_content")
            assert info.isfile() is True
            assert info.size == len(testdata)
            content_file = tar.extractfile("archived_content")
            content = content_file.read()  # pylint: disable=no-member
            content_file.close()  # pylint: disable=no-member
            assert testdata == content

            decout = tmpdir.join("dec_out_dir").strpath
            os.makedirs(decout)
            tar.extract("archived_content", decout)
            extracted_path = os.path.join(decout, "archived_content")
            with open(extracted_path, "rb") as ext_fp:
                assert testdata == ext_fp.read()
示例#8
0
 def test_get_encrypted_archived_file(self, pghoard):
     wal_seg = "000000090000000000000010"
     content = wal_header_for_file(wal_seg)
     compressor = pghoard.Compressor()
     compressed_content = compressor.compress(content) + (compressor.flush() or b"")
     encryptor = Encryptor(CONSTANT_TEST_RSA_PUBLIC_KEY)
     encrypted_content = encryptor.update(compressed_content) + encryptor.finalize()
     wal_dir = get_pg_wal_directory(pghoard.config["backup_sites"][pghoard.test_site])
     archive_path = os.path.join(pghoard.test_site, "xlog", wal_seg)
     metadata = {
         "compression-algorithm": pghoard.config["compression"]["algorithm"],
         "original-file-size": len(content),
         "encryption-key-id": "testkey",
     }
     store = pghoard.transfer_agents[0].get_object_storage(pghoard.test_site)
     store.store_file_from_memory(archive_path, encrypted_content, metadata=metadata)
     pghoard.webserver.config["backup_sites"][pghoard.test_site]["encryption_keys"] = {
         "testkey": {
             "public": CONSTANT_TEST_RSA_PUBLIC_KEY,
             "private": CONSTANT_TEST_RSA_PRIVATE_KEY,
         },
     }
     restore_target = os.path.join(wal_dir, wal_seg)
     restore_command(site=pghoard.test_site, xlog=wal_seg, output=restore_target,
                     host="127.0.0.1", port=pghoard.config["http_port"])
     assert os.path.exists(restore_target)
     with open(restore_target, "rb") as fp:
         restored_data = fp.read()
     assert content == restored_data
示例#9
0
    def test_decryptorfile_for_tarfile(self):
        testdata = b"file contents"
        data_tmp = tempfile.NamedTemporaryFile(prefix="test-pghoard.", mode="r+b")
        data_tmp.write(testdata)
        data_tmp.flush()

        tmp = tempfile.TemporaryFile(prefix="test-pghoard.", mode="r+b")
        tar = tarfile.open(name="foo", fileobj=tmp, mode="w")
        tar.add(data_tmp.name, arcname="archived_content")
        tar.close()

        tmp.seek(0)
        plaintext = tmp.read()

        tmp.seek(0)
        tmp.truncate()
        encryptor = Encryptor(CONSTANT_TEST_RSA_PUBLIC_KEY)
        ciphertext = encryptor.update(plaintext) + encryptor.finalize()
        tmp.write(ciphertext)

        tmp.seek(0)
        tmp = DecryptorFile(tmp, CONSTANT_TEST_RSA_PRIVATE_KEY)  # pylint: disable=redefined-variable-type
        tar = tarfile.open(fileobj=tmp, mode="r")
        info = tar.getmember("archived_content")
        assert info.isfile() is True
        assert info.size == len(testdata)
        content_file = tar.extractfile("archived_content")
        tar.extract("archived_content", "/tmp/testout")
        content = content_file.read()  # pylint: disable=no-member
        content_file.close()  # pylint: disable=no-member
        assert testdata == content
        tar.close()
        tmp.close()
        data_tmp.close()
示例#10
0
 def test_decryptorfile(self):
     plaintext = b"test"
     encryptor = Encryptor(CONSTANT_TEST_RSA_PUBLIC_KEY)
     ciphertext = encryptor.update(plaintext) + encryptor.finalize()
     fp = tempfile.TemporaryFile(prefix="test-pghoard.", mode="r+b")
     fp.write(ciphertext)
     fp.seek(0)
     fp = DecryptorFile(fp, CONSTANT_TEST_RSA_PRIVATE_KEY)  # pylint: disable=redefined-variable-type
     result = fp.read()
     assert plaintext == result
     fp.seek(0)
     result = fp.read()
     assert plaintext == result
     fp.seek(2)
     result = fp.read(1)
     assert plaintext[2:3] == result
示例#11
0
 def test_encryptor_decryptor(self):
     plaintext = b"test"
     encryptor = Encryptor(CONSTANT_TEST_RSA_PUBLIC_KEY)
     ciphertext = encryptor.update(plaintext) + encryptor.finalize()
     assert plaintext not in ciphertext
     decryptor = Decryptor(CONSTANT_TEST_RSA_PRIVATE_KEY)
     result = decryptor.update(ciphertext) + decryptor.finalize()
     assert plaintext == result
     public_key = json.loads(json.dumps(CONSTANT_TEST_RSA_PUBLIC_KEY))
     private_key = json.loads(json.dumps(CONSTANT_TEST_RSA_PRIVATE_KEY))
     encryptor = Encryptor(public_key)
     decryptor = Decryptor(private_key)
     assert plaintext == decryptor.update(
         encryptor.update(plaintext) +
         encryptor.finalize()) + decryptor.finalize()
示例#12
0
def test_encryptor_decryptor():
    plaintext = b"test"
    for op in (None, "json"):
        if op == "json":
            public_key = json.loads(json.dumps(CONSTANT_TEST_RSA_PUBLIC_KEY))
            private_key = json.loads(json.dumps(CONSTANT_TEST_RSA_PRIVATE_KEY))
        else:
            public_key = CONSTANT_TEST_RSA_PUBLIC_KEY
            private_key = CONSTANT_TEST_RSA_PRIVATE_KEY

        encryptor = Encryptor(public_key)
        decryptor = Decryptor(private_key)
        encrypted = encryptor.update(plaintext) + encryptor.finalize()
        assert plaintext not in encrypted
        offset = 0
        while decryptor.expected_header_bytes() > 0:
            chunk = encrypted[offset:offset + decryptor.expected_header_bytes()]
            decryptor.process_header(chunk)
            offset += len(chunk)
        decrypted_size = len(encrypted) - decryptor.header_size() - decryptor.footer_size()
        decrypted = decryptor.process_data(encrypted[decryptor.header_size():decryptor.header_size() + decrypted_size])
        decrypted += decryptor.finalize(encrypted[-decryptor.footer_size():])
        assert plaintext == decrypted
示例#13
0
def test_encryptor_decryptor():
    plaintext = b"test"
    encryptor = Encryptor(CONSTANT_TEST_RSA_PUBLIC_KEY)
    ciphertext = encryptor.update(plaintext) + encryptor.finalize()
    assert plaintext not in ciphertext
    decryptor = Decryptor(CONSTANT_TEST_RSA_PRIVATE_KEY)
    result = decryptor.update(ciphertext) + decryptor.finalize()
    assert plaintext == result
    public_key = json.loads(json.dumps(CONSTANT_TEST_RSA_PUBLIC_KEY))
    private_key = json.loads(json.dumps(CONSTANT_TEST_RSA_PRIVATE_KEY))
    encryptor = Encryptor(public_key)
    decryptor = Decryptor(private_key)
    assert plaintext == decryptor.update(encryptor.update(plaintext) + encryptor.finalize()) + decryptor.finalize()