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/password_specifics.pb.h"
9 #include "sync/protocol/sync.pb.h"
10 #include "sync/util/cryptographer.h"
16 bool EndsWithSpace(const std::string
& string
) {
17 return !string
.empty() && *string
.rbegin() == ' ';
22 sync_pb::PasswordSpecificsData
* DecryptPasswordSpecifics(
23 const sync_pb::EntitySpecifics
& specifics
, Cryptographer
* crypto
) {
24 if (!specifics
.has_password())
26 const sync_pb::PasswordSpecifics
& password_specifics
= specifics
.password();
27 if (!password_specifics
.has_encrypted())
29 const sync_pb::EncryptedData
& encrypted
= password_specifics
.encrypted();
30 scoped_ptr
<sync_pb::PasswordSpecificsData
> data(
31 new sync_pb::PasswordSpecificsData
);
32 if (!crypto
->Decrypt(encrypted
, data
.get()))
34 return data
.release();
37 // The list of names which are reserved for use by the server.
38 static const char* kForbiddenServerNames
[] = { "", ".", ".." };
40 // When taking a name from the syncapi, append a space if it matches the
41 // pattern of a server-illegal name followed by zero or more spaces.
42 void SyncAPINameToServerName(const std::string
& syncer_name
,
45 if (IsNameServerIllegalAfterTrimming(*out
))
49 // In the reverse direction, if a server name matches the pattern of a
50 // server-illegal name followed by one or more spaces, remove the trailing
52 void ServerNameToSyncAPIName(const std::string
& server_name
,
55 int length_to_copy
= server_name
.length();
56 if (IsNameServerIllegalAfterTrimming(server_name
) &&
57 EndsWithSpace(server_name
)) {
60 *out
= server_name
.substr(0, length_to_copy
);
63 // Checks whether |name| is a server-illegal name followed by zero or more space
64 // characters. The three server-illegal names are the empty string, dot, and
65 // dot-dot. Very long names (>255 bytes in UTF-8 Normalization Form C) are
66 // also illegal, but are not considered here.
67 bool IsNameServerIllegalAfterTrimming(const std::string
& name
) {
68 size_t untrimmed_count
= name
.find_last_not_of(' ') + 1;
69 for (size_t i
= 0; i
< arraysize(kForbiddenServerNames
); ++i
) {
70 if (name
.compare(0, untrimmed_count
, kForbiddenServerNames
[i
]) == 0)
76 // Compare the values of two EntitySpecifics, accounting for encryption.
77 bool AreSpecificsEqual(const Cryptographer
* cryptographer
,
78 const sync_pb::EntitySpecifics
& left
,
79 const sync_pb::EntitySpecifics
& right
) {
80 // Note that we can't compare encrypted strings directly as they are seeded
81 // with a random value.
82 std::string left_plaintext
, right_plaintext
;
83 if (left
.has_encrypted()) {
84 if (!cryptographer
->CanDecrypt(left
.encrypted())) {
85 NOTREACHED() << "Attempting to compare undecryptable data.";
88 left_plaintext
= cryptographer
->DecryptToString(left
.encrypted());
90 left_plaintext
= left
.SerializeAsString();
92 if (right
.has_encrypted()) {
93 if (!cryptographer
->CanDecrypt(right
.encrypted())) {
94 NOTREACHED() << "Attempting to compare undecryptable data.";
97 right_plaintext
= cryptographer
->DecryptToString(right
.encrypted());
99 right_plaintext
= right
.SerializeAsString();
101 if (left_plaintext
== right_plaintext
) {
107 } // namespace syncer