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.
5 #include "sync/internal_api/syncapi_internal.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "sync/protocol/attachments.pb.h"
9 #include "sync/protocol/password_specifics.pb.h"
10 #include "sync/protocol/sync.pb.h"
11 #include "sync/util/cryptographer.h"
17 bool EndsWithSpace(const std::string
& string
) {
18 return !string
.empty() && *string
.rbegin() == ' ';
23 sync_pb::PasswordSpecificsData
* DecryptPasswordSpecifics(
24 const sync_pb::EntitySpecifics
& specifics
, Cryptographer
* crypto
) {
25 if (!specifics
.has_password())
27 const sync_pb::PasswordSpecifics
& password_specifics
= specifics
.password();
28 if (!password_specifics
.has_encrypted())
30 const sync_pb::EncryptedData
& encrypted
= password_specifics
.encrypted();
31 scoped_ptr
<sync_pb::PasswordSpecificsData
> data(
32 new sync_pb::PasswordSpecificsData
);
33 if (!crypto
->CanDecrypt(encrypted
))
35 if (!crypto
->Decrypt(encrypted
, data
.get()))
37 return data
.release();
40 // The list of names which are reserved for use by the server.
41 static const char* kForbiddenServerNames
[] = { "", ".", ".." };
43 // When taking a name from the syncapi, append a space if it matches the
44 // pattern of a server-illegal name followed by zero or more spaces.
45 void SyncAPINameToServerName(const std::string
& syncer_name
,
48 if (IsNameServerIllegalAfterTrimming(*out
))
52 // In the reverse direction, if a server name matches the pattern of a
53 // server-illegal name followed by one or more spaces, remove the trailing
55 void ServerNameToSyncAPIName(const std::string
& server_name
,
58 int length_to_copy
= server_name
.length();
59 if (IsNameServerIllegalAfterTrimming(server_name
) &&
60 EndsWithSpace(server_name
)) {
63 *out
= server_name
.substr(0, length_to_copy
);
66 // Checks whether |name| is a server-illegal name followed by zero or more space
67 // characters. The three server-illegal names are the empty string, dot, and
68 // dot-dot. Very long names (>255 bytes in UTF-8 Normalization Form C) are
69 // also illegal, but are not considered here.
70 bool IsNameServerIllegalAfterTrimming(const std::string
& name
) {
71 size_t untrimmed_count
= name
.find_last_not_of(' ') + 1;
72 for (size_t i
= 0; i
< arraysize(kForbiddenServerNames
); ++i
) {
73 if (name
.compare(0, untrimmed_count
, kForbiddenServerNames
[i
]) == 0)
79 // Compare the values of two EntitySpecifics, accounting for encryption.
80 bool AreSpecificsEqual(const Cryptographer
* cryptographer
,
81 const sync_pb::EntitySpecifics
& left
,
82 const sync_pb::EntitySpecifics
& right
) {
83 // Note that we can't compare encrypted strings directly as they are seeded
84 // with a random value.
85 std::string left_plaintext
, right_plaintext
;
86 if (left
.has_encrypted()) {
87 if (!cryptographer
->CanDecrypt(left
.encrypted())) {
88 NOTREACHED() << "Attempting to compare undecryptable data.";
91 left_plaintext
= cryptographer
->DecryptToString(left
.encrypted());
93 left_plaintext
= left
.SerializeAsString();
95 if (right
.has_encrypted()) {
96 if (!cryptographer
->CanDecrypt(right
.encrypted())) {
97 NOTREACHED() << "Attempting to compare undecryptable data.";
100 right_plaintext
= cryptographer
->DecryptToString(right
.encrypted());
102 right_plaintext
= right
.SerializeAsString();
104 if (left_plaintext
== right_plaintext
) {
110 bool AreAttachmentMetadataEqual(const sync_pb::AttachmentMetadata
& left
,
111 const sync_pb::AttachmentMetadata
& right
) {
112 if (left
.SerializeAsString() == right
.SerializeAsString()) {
118 } // namespace syncer