1/*
2 * Copyright (C) 2007 Apple Inc.  All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25#include "config.h"
26#include "Credential.h"
27
28namespace WebCore {
29
30// Need to enforce empty, non-null strings due to the pickiness of the String == String operator
31// combined with the semantics of the String(NSString*) constructor
32Credential::Credential()
33    : m_user("")
34    , m_password("")
35    , m_persistence(CredentialPersistenceNone)
36#if CERTIFICATE_CREDENTIALS_SUPPORTED
37    , m_type(CredentialTypePassword)
38#endif
39{
40}
41
42// Need to enforce empty, non-null strings due to the pickiness of the String == String operator
43// combined with the semantics of the String(NSString*) constructor
44Credential::Credential(const String& user, const String& password, CredentialPersistence persistence)
45    : m_user(user.length() ? user : "")
46    , m_password(password.length() ? password : "")
47    , m_persistence(persistence)
48#if CERTIFICATE_CREDENTIALS_SUPPORTED
49    , m_type(CredentialTypePassword)
50#endif
51{
52}
53
54Credential::Credential(const Credential& original, CredentialPersistence persistence)
55    : m_user(original.user())
56    , m_password(original.password())
57    , m_persistence(persistence)
58#if CERTIFICATE_CREDENTIALS_SUPPORTED
59    , m_identity(original.identity())
60    , m_certificates(original.certificates())
61    , m_type(original.type())
62#endif
63{
64}
65
66bool Credential::isEmpty() const
67{
68#if CERTIFICATE_CREDENTIALS_SUPPORTED
69    if (m_type == CredentialTypeClientCertificate && (m_identity || m_certificates))
70        return false;
71#endif
72
73    return m_user.isEmpty() && m_password.isEmpty();
74}
75
76const String& Credential::user() const
77{
78    return m_user;
79}
80
81const String& Credential::password() const
82{
83    return m_password;
84}
85
86bool Credential::hasPassword() const
87{
88    return !m_password.isEmpty();
89}
90
91CredentialPersistence Credential::persistence() const
92{
93    return m_persistence;
94}
95
96#if CERTIFICATE_CREDENTIALS_SUPPORTED
97Credential::Credential(SecIdentityRef identity, CFArrayRef certificates, CredentialPersistence persistence)
98    : m_user("")
99    , m_password("")
100    , m_persistence(persistence)
101    , m_identity(identity)
102    , m_certificates(certificates)
103    , m_type(CredentialTypeClientCertificate)
104{
105}
106
107SecIdentityRef Credential::identity() const
108{
109    return m_identity.get();
110}
111
112CFArrayRef Credential::certificates() const
113{
114    return m_certificates.get();
115}
116
117CredentialType Credential::type() const
118{
119    return m_type;
120}
121#endif
122
123bool operator==(const Credential& a, const Credential& b)
124{
125    // Check persistence first since all credential types
126    // have the persistence property.
127    if (a.persistence() != b.persistence())
128        return false;
129
130#if CERTIFICATE_CREDENTIALS_SUPPORTED
131    CredentialType aType = a.type();
132    if (aType != b.type())
133        return false;
134
135    // Comparing identity and certificate chain pointers is valid only
136    // for client certificate type credentials.
137    //
138    // FIXME: Is pointer comparison of the identity and certificates properties sufficient?
139    if (aType == CredentialTypeClientCertificate) {
140        if (a.identity() != b.identity())
141            return false;
142        if (a.certificates() != b.certificates())
143            return false;
144
145        // We only need to check identity and certificates to compare
146        // client certificate based credentials.
147        return true;
148    }
149
150    ASSERT(a.type() == CredentialTypePassword && b.type() == CredentialTypePassword);
151#endif
152
153    if (a.user() != b.user())
154        return false;
155    if (a.password() != b.password())
156        return false;
157
158    return true;
159}
160
161}
162
163