1/*
2 *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "webrtc/libjingle/xmpp/xmppauth.h"
12
13#include <algorithm>
14
15#include "webrtc/libjingle/xmpp/constants.h"
16#include "webrtc/libjingle/xmpp/saslcookiemechanism.h"
17#include "webrtc/libjingle/xmpp/saslplainmechanism.h"
18
19XmppAuth::XmppAuth() : done_(false) {
20}
21
22XmppAuth::~XmppAuth() {
23}
24
25void XmppAuth::StartPreXmppAuth(const buzz::Jid& jid,
26                                const rtc::SocketAddress& server,
27                                const rtc::CryptString& pass,
28                                const std::string& auth_mechanism,
29                                const std::string& auth_token) {
30  jid_ = jid;
31  passwd_ = pass;
32  auth_mechanism_ = auth_mechanism;
33  auth_token_ = auth_token;
34  done_ = true;
35
36  SignalAuthDone();
37}
38
39static bool contains(const std::vector<std::string>& strings,
40                     const std::string& string) {
41  return std::find(strings.begin(), strings.end(), string) != strings.end();
42}
43
44std::string XmppAuth::ChooseBestSaslMechanism(
45    const std::vector<std::string>& mechanisms,
46    bool encrypted) {
47  // First try Oauth2.
48  if (GetAuthMechanism() == buzz::AUTH_MECHANISM_OAUTH2 &&
49      contains(mechanisms, buzz::AUTH_MECHANISM_OAUTH2)) {
50    return buzz::AUTH_MECHANISM_OAUTH2;
51  }
52
53  // A token is the weakest auth - 15s, service-limited, so prefer it.
54  if (GetAuthMechanism() == buzz::AUTH_MECHANISM_GOOGLE_TOKEN &&
55      contains(mechanisms, buzz::AUTH_MECHANISM_GOOGLE_TOKEN)) {
56    return buzz::AUTH_MECHANISM_GOOGLE_TOKEN;
57  }
58
59  // A cookie is the next weakest - 14 days.
60  if (GetAuthMechanism() == buzz::AUTH_MECHANISM_GOOGLE_COOKIE &&
61      contains(mechanisms, buzz::AUTH_MECHANISM_GOOGLE_COOKIE)) {
62    return buzz::AUTH_MECHANISM_GOOGLE_COOKIE;
63  }
64
65  // As a last resort, use plain authentication.
66  if (contains(mechanisms, buzz::AUTH_MECHANISM_PLAIN)) {
67    return buzz::AUTH_MECHANISM_PLAIN;
68  }
69
70  // No good mechanism found
71  return "";
72}
73
74buzz::SaslMechanism* XmppAuth::CreateSaslMechanism(
75    const std::string& mechanism) {
76  if (mechanism == buzz::AUTH_MECHANISM_OAUTH2) {
77    return new buzz::SaslCookieMechanism(
78        mechanism, jid_.Str(), auth_token_, "oauth2");
79  } else if (mechanism == buzz::AUTH_MECHANISM_GOOGLE_TOKEN) {
80    return new buzz::SaslCookieMechanism(mechanism, jid_.Str(), auth_token_);
81  // } else if (mechanism == buzz::AUTH_MECHANISM_GOOGLE_COOKIE) {
82  //   return new buzz::SaslCookieMechanism(mechanism, jid.Str(), sid_);
83  } else if (mechanism == buzz::AUTH_MECHANISM_PLAIN) {
84    return new buzz::SaslPlainMechanism(jid_, passwd_);
85  } else {
86    return NULL;
87  }
88}
89