OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "sync/internal_api/syncapi_internal.h" | |
6 | |
7 #include <stddef.h> | |
8 | |
9 #include <memory> | |
10 | |
11 #include "base/macros.h" | |
12 #include "sync/protocol/attachments.pb.h" | |
13 #include "sync/protocol/password_specifics.pb.h" | |
14 #include "sync/protocol/sync.pb.h" | |
15 #include "sync/util/cryptographer.h" | |
16 | |
17 namespace syncer { | |
18 | |
19 namespace { | |
20 | |
21 bool EndsWithSpace(const std::string& string) { | |
22 return !string.empty() && *string.rbegin() == ' '; | |
23 } | |
24 | |
25 } | |
26 | |
27 sync_pb::PasswordSpecificsData* DecryptPasswordSpecifics( | |
28 const sync_pb::EntitySpecifics& specifics, Cryptographer* crypto) { | |
29 if (!specifics.has_password()) | |
30 return NULL; | |
31 const sync_pb::PasswordSpecifics& password_specifics = specifics.password(); | |
32 if (!password_specifics.has_encrypted()) | |
33 return NULL; | |
34 const sync_pb::EncryptedData& encrypted = password_specifics.encrypted(); | |
35 std::unique_ptr<sync_pb::PasswordSpecificsData> data( | |
36 new sync_pb::PasswordSpecificsData); | |
37 if (!crypto->CanDecrypt(encrypted)) | |
38 return NULL; | |
39 if (!crypto->Decrypt(encrypted, data.get())) | |
40 return NULL; | |
41 return data.release(); | |
42 } | |
43 | |
44 // The list of names which are reserved for use by the server. | |
45 static const char* kForbiddenServerNames[] = { "", ".", ".." }; | |
46 | |
47 // When taking a name from the syncapi, append a space if it matches the | |
48 // pattern of a server-illegal name followed by zero or more spaces. | |
49 void SyncAPINameToServerName(const std::string& syncer_name, | |
50 std::string* out) { | |
51 *out = syncer_name; | |
52 if (IsNameServerIllegalAfterTrimming(*out)) | |
53 out->append(" "); | |
54 } | |
55 | |
56 // In the reverse direction, if a server name matches the pattern of a | |
57 // server-illegal name followed by one or more spaces, remove the trailing | |
58 // space. | |
59 void ServerNameToSyncAPIName(const std::string& server_name, | |
60 std::string* out) { | |
61 CHECK(out); | |
62 int length_to_copy = server_name.length(); | |
63 if (IsNameServerIllegalAfterTrimming(server_name) && | |
64 EndsWithSpace(server_name)) { | |
65 --length_to_copy; | |
66 } | |
67 *out = server_name.substr(0, length_to_copy); | |
68 } | |
69 | |
70 // Checks whether |name| is a server-illegal name followed by zero or more space | |
71 // characters. The three server-illegal names are the empty string, dot, and | |
72 // dot-dot. Very long names (>255 bytes in UTF-8 Normalization Form C) are | |
73 // also illegal, but are not considered here. | |
74 bool IsNameServerIllegalAfterTrimming(const std::string& name) { | |
75 size_t untrimmed_count = name.find_last_not_of(' ') + 1; | |
76 for (size_t i = 0; i < arraysize(kForbiddenServerNames); ++i) { | |
77 if (name.compare(0, untrimmed_count, kForbiddenServerNames[i]) == 0) | |
78 return true; | |
79 } | |
80 return false; | |
81 } | |
82 | |
83 // Compare the values of two EntitySpecifics, accounting for encryption. | |
84 bool AreSpecificsEqual(const Cryptographer* cryptographer, | |
85 const sync_pb::EntitySpecifics& left, | |
86 const sync_pb::EntitySpecifics& right) { | |
87 // Note that we can't compare encrypted strings directly as they are seeded | |
88 // with a random value. | |
89 std::string left_plaintext, right_plaintext; | |
90 if (left.has_encrypted()) { | |
91 if (!cryptographer->CanDecrypt(left.encrypted())) { | |
92 NOTREACHED() << "Attempting to compare undecryptable data."; | |
93 return false; | |
94 } | |
95 left_plaintext = cryptographer->DecryptToString(left.encrypted()); | |
96 } else { | |
97 left_plaintext = left.SerializeAsString(); | |
98 } | |
99 if (right.has_encrypted()) { | |
100 if (!cryptographer->CanDecrypt(right.encrypted())) { | |
101 NOTREACHED() << "Attempting to compare undecryptable data."; | |
102 return false; | |
103 } | |
104 right_plaintext = cryptographer->DecryptToString(right.encrypted()); | |
105 } else { | |
106 right_plaintext = right.SerializeAsString(); | |
107 } | |
108 if (left_plaintext == right_plaintext) { | |
109 return true; | |
110 } | |
111 return false; | |
112 } | |
113 | |
114 bool AreAttachmentMetadataEqual(const sync_pb::AttachmentMetadata& left, | |
115 const sync_pb::AttachmentMetadata& right) { | |
116 if (left.SerializeAsString() == right.SerializeAsString()) { | |
117 return true; | |
118 } | |
119 return false; | |
120 } | |
121 | |
122 } // namespace syncer | |
OLD | NEW |