|
| 1 | +#!/usr/bin/env ruby |
| 2 | + |
| 3 | +require_relative '../boot' |
| 4 | +require 'minitest/autorun' |
| 5 | +require 'pry-rescue/minitest' unless ENV['CI'] |
| 6 | + |
| 7 | +def make_xor_key() |
| 8 | + random = Random.new.bytes(8) |
| 9 | + res = Array.new(2*random.length) |
| 10 | + i = 0 |
| 11 | + random.each_byte { |c| |
| 12 | + res[2*i] = c & 0xf |
| 13 | + res[2*i+1] = c >> 4 |
| 14 | + i += 1 |
| 15 | + } |
| 16 | + res |
| 17 | +end |
| 18 | + |
| 19 | +def xor_id(id, key) |
| 20 | + l = key.length |
| 21 | + buf = id.bytes.to_a |
| 22 | + buf.each_with_index { |c, i| |
| 23 | + if 48 <= c && c <= 57 |
| 24 | + c = (c - 48) ^ key[i%l].ord |
| 25 | + elsif 97 <= c && c <= 102 |
| 26 | + c = (c - 87) ^ key[i%l].ord |
| 27 | + elsif 65 <= c && c <= 70 |
| 28 | + c = (c - 55) ^ key[i%l].ord |
| 29 | + else |
| 30 | + next |
| 31 | + end |
| 32 | + if c < 10 |
| 33 | + buf[i] = c + 48 |
| 34 | + else |
| 35 | + buf[i] = (c - 10) + 97 |
| 36 | + end |
| 37 | + } |
| 38 | + buf.pack('c*') |
| 39 | +end |
| 40 | + |
| 41 | +describe "A sharing" do |
| 42 | + Helpers.scenario "integrity" |
| 43 | + Helpers.start_mailhog |
| 44 | + |
| 45 | + it "cannot reveal information on existing files" do |
| 46 | + |
| 47 | + recipient_name = "Bob" |
| 48 | + |
| 49 | + # Create the instance |
| 50 | + inst = Instance.create name: "Alice" |
| 51 | + inst_recipient = Instance.create name: recipient_name |
| 52 | + |
| 53 | + # Create the folder |
| 54 | + folder = Folder.create inst |
| 55 | + folder.couch_id.wont_be_empty |
| 56 | + child1 = Folder.create inst, {dir_id: folder.couch_id} |
| 57 | + file = "../fixtures/wet-cozy_20160910__©M4Dz.jpg" |
| 58 | + opts = CozyFile.options_from_fixture(file, dir_id: folder.couch_id) |
| 59 | + file = CozyFile.create inst, opts |
| 60 | + |
| 61 | + # Create the sharing |
| 62 | + contact = Contact.create inst, givenName: recipient_name |
| 63 | + sharing = Sharing.new |
| 64 | + sharing.rules << Rule.sync(folder) |
| 65 | + sharing.members << inst << contact |
| 66 | + inst.register sharing |
| 67 | + |
| 68 | + # Manually set the xor_key |
| 69 | + db = Helpers.db_name inst.domain, Sharing.doctype |
| 70 | + doc = Helpers.couch.get_doc db, sharing.couch_id |
| 71 | + key = make_xor_key() |
| 72 | + doc["credentials"][0]["xor_key"] = key |
| 73 | + Helpers.couch.update_doc db, doc |
| 74 | + |
| 75 | + # Create a folder on the recipient side, with a fixed id being the |
| 76 | + # xor_id of the child1 folder |
| 77 | + doc = { |
| 78 | + type: "directory", |
| 79 | + name: name, |
| 80 | + dir_id: Folder::ROOT_DIR, |
| 81 | + path: "/#{Faker::Internet.slug}", |
| 82 | + created_at: "2018-05-11T12:18:37.558389182+02:00", |
| 83 | + updated_at: "2018-05-11T12:18:37.558389182+02:00" |
| 84 | + } |
| 85 | + db = Helpers.db_name inst_recipient.domain, Folder.doctype |
| 86 | + id = xor_id(child1.couch_id, key) |
| 87 | + Helpers.couch.create_named_doc db, id, doc |
| 88 | + |
| 89 | + # Accept the sharing |
| 90 | + sleep 1 |
| 91 | + inst_recipient.accept sharing |
| 92 | + sleep 2 |
| 93 | + |
| 94 | + # Make an update |
| 95 | + child1.rename inst, Faker::Internet.slug |
| 96 | + sleep 4 |
| 97 | + |
| 98 | + # The child1 folder shouldn't be part of the sharing as its id exists |
| 99 | + # on the recipient side |
| 100 | + child1_recipient = Folder.find inst_recipient, id |
| 101 | + assert(child1.name != child1_recipient.name) |
| 102 | + path = File.join Helpers.current_dir, inst_recipient.domain, |
| 103 | + Helpers::SHARED_WITH_ME, sharing.rules.first.title, |
| 104 | + child1_recipient.name |
| 105 | + assert !Helpers.file_exists_in_fs(path) |
| 106 | + |
| 107 | + end |
| 108 | +end |
0 commit comments