reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
CookieAuthenticator.cxx
Go to the documentation of this file.
1
2#if defined(HAVE_CONFIG_H)
3 #include "config.h"
4#endif
5
6#include "rutil/DnsUtil.hxx"
11#include "rutil/Logger.hxx"
13#include "rutil/stun/Stun.hxx"
14
18#include "repro/Proxy.hxx"
20#include "repro/UserStore.hxx"
23#include "rutil/ParseBuffer.hxx"
25
26#include <time.h>
27
28#define RESIPROCATE_SUBSYSTEM resip::Subsystem::REPRO
29
30using namespace resip;
31using namespace repro;
32using namespace std;
33
34
35CookieAuthenticator::CookieAuthenticator(const Data& wsCookieAuthSharedSecret,
36 const Data& wsCookieExtraHeaderName,
37 resip::SipStack* stack) :
38 Processor("CookieAuthenticator"),
39 mWsCookieExtraHeader(wsCookieExtraHeaderName.empty() ? 0 : new resip::ExtensionHeader(wsCookieExtraHeaderName))
40{
41}
42
46
49{
50 DebugLog(<< "Monkey handling request: " << *this << "; reqcontext = " << rc);
51
52 Message *message = rc.getCurrentEvent();
53
54 SipMessage *sipMessage = dynamic_cast<SipMessage*>(message);
55 Proxy &proxy = rc.getProxy();
56
57 if (sipMessage)
58 {
59 // Only check message coming over WebSockets
61 {
62 return Continue;
63 }
64
65 if (sipMessage->method() == ACK ||
66 sipMessage->method() == BYE)
67 {
68 return Continue;
69 }
70
71 if(!sipMessage->header(h_From).isWellFormed() ||
72 sipMessage->header(h_From).isAllContacts() )
73 {
74 InfoLog(<<"Malformed From header: cannot verify against cookie. Rejecting.");
75 rc.sendResponse(*unique_ptr<SipMessage>
76 (Helper::makeResponse(*sipMessage, 400, "Malformed From header")));
77 return SkipAllChains;
78 }
79
80 const WsCookieContext &wsCookieContext = *(sipMessage->getWsCookieContext());
81 if (proxy.isMyDomain(sipMessage->header(h_From).uri().host()))
82 {
83 if(authorizedForThisIdentity(sipMessage->header(h_RequestLine).method(), wsCookieContext, sipMessage->header(h_From).uri(), sipMessage->header(h_To).uri()))
84 {
85 if(mWsCookieExtraHeader.get() && sipMessage->exists(*mWsCookieExtraHeader))
86 {
88 StringCategory& sc = extra.front();
89 if(sc.value() == wsCookieContext.getWsSessionExtra())
90 {
91 return Continue;
92 }
93 else
94 {
95 WarningLog(<<"mWsCookieExtraHeader does not match wsCookieContext value");
96 }
97 }
98 else
99 {
100 return Continue;
101 }
102 }
103 rc.sendResponse(*unique_ptr<SipMessage>
104 (Helper::makeResponse(*sipMessage, 403, "Authentication against cookie failed")));
105 return SkipAllChains;
106 }
107 else
108 {
109 rc.sendResponse(*unique_ptr<SipMessage>
110 (Helper::makeResponse(*sipMessage, 403, "Authentication against cookie failed")));
111 return SkipAllChains;
112 }
113 }
114
115 return Continue;
116}
117
118bool
120{
121 return(
122 (isEqualNoCase(first.user(), second.user()) || first.user() == "*") &&
123 (isEqualNoCase(first.host(), second.host()) || first.host() == "*")
124 );
125}
126
127bool
129 const WsCookieContext& wsCookieContext,
130 resip::Uri &fromUri,
131 resip::Uri &toUri)
132{
133 if(difftime(wsCookieContext.getExpiresTime(), time(NULL)) < 0)
134 {
135 WarningLog(<< "Received expired cookie");
136 return false;
137 }
138
139 Uri wsFromUri = wsCookieContext.getWsFromUri();
140 Uri wsDestUri = wsCookieContext.getWsDestUri();
141 if(cookieUriMatch(wsFromUri, fromUri))
142 {
143 DebugLog(<< "Matched cookie source URI field" << wsFromUri << " against request From header field URI " << fromUri);
144 // When registering, "From" URI == "To" URI, so we can ignore the
145 // "To" URI restriction from the cookie when processing REGISTER
146 if(method == REGISTER && isEqualNoCase(fromUri.user(), toUri.user()) && isEqualNoCase(fromUri.host(), toUri.host()))
147 {
148 return true;
149 }
150 if(cookieUriMatch(wsDestUri, toUri))
151 {
152 DebugLog(<< "Matched cookie destination URI field" << wsDestUri << " against request To header field URI " << toUri);
153 return true;
154 }
155 }
156
157 // catch-all: access denied
158 return false;
159}
160
161void
162CookieAuthenticator::dump(EncodeStream &os) const
163{
164 os << "CookieAuthentication monkey" << std::endl;
165}
166
167/* ====================================================================
168 * BSD License
169 *
170 * Copyright (c) 2013 Catalin Constantin Usurelu All rights reserved.
171 *
172 * Redistribution and use in source and binary forms, with or without
173 * modification, are permitted provided that the following conditions
174 * are met:
175 *
176 * 1. Redistributions of source code must retain the above copyright
177 * notice, this list of conditions and the following disclaimer.
178 *
179 * 2. Redistributions in binary form must reproduce the above copyright
180 * notice, this list of conditions and the following disclaimer in
181 * the documentation and/or other materials provided with the
182 * distribution.
183 *
184 * 3. Neither the name of the author(s) nor the names of any contributors
185 * may be used to endorse or promote products derived from this software
186 * without specific prior written permission.
187 *
188 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND
189 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
190 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
191 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
192 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
193 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
194 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
195 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
196 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
197 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
198 * SUCH DAMAGE.
199 *
200 * ====================================================================
201 *
202 */
#define DebugLog(args_)
Definition Logger.hxx:128
#define InfoLog(args_)
Definition Logger.hxx:131
#define WarningLog(args_)
Definition Logger.hxx:134
static Mimes empty
virtual void dump(EncodeStream &os) const
CookieAuthenticator(const Data &wsCookieAuthSharedSecret, const Data &wsCookieExtraHeaderName, resip::SipStack *stack)
bool cookieUriMatch(const resip::Uri &first, const resip::Uri &second)
virtual processor_action_t process(RequestContext &)
std::unique_ptr< resip::ExtensionHeader > mWsCookieExtraHeader
bool authorizedForThisIdentity(const MethodTypes method, const WsCookieContext &wsCookieContext, resip::Uri &fromUri, resip::Uri &toUri)
resip::Message * getCurrentEvent()
Returns the event that we are currently working on.
void sendResponse(resip::SipMessage &response)
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
Definition Data.hxx:90
static void makeResponse(SipMessage &response, const SipMessage &request, int responseCode, const Data &reason=Data::Empty, const Data &hostname=Data::Empty, const Data &warning=Data::Empty)
Make a response to a provided request.
Definition Helper.cxx:412
bool isWellFormed() const
Returns true iff this element was parsed successfully, according to the implementation of parse().
The base-class used for message-passing.
Definition Message.hxx:21
Container class for ParserCategory, used by SipMessage to represent multi-valued headers (Contact,...
T & front()
Returns the first header field value in this container.
const Uri & uri() const
MethodTypes & method()
Represents a SIP message.
const Tuple & getReceivedTransportTuple() const
const RequestLine & header(const RequestLineType &l) const
Returns the RequestLine. This is only valid for request messages.
bool exists(const HeaderBase &headerType) const
Returns true if the given header field is present, false otherwise.
std::shared_ptr< WsCookieContext > getWsCookieContext() const noexcept
resip::MethodTypes method() const
returns the method type of the message
This is the primary point of interaction between the app-layer and the stack.
Definition SipStack.hxx:160
Represents the "header-value" element in the RFC 3261 grammar (ie, an unknown header field value).
const Data & value() const
bool isMyDomain(const Data &domain) const
Returns true iff domain matches one of the domains that this TransactionUser is responsible for.
TransportType getType() const
Definition Tuple.hxx:122
Represents the "SIP-URI" and "SIPS-URI" elements in the RFC 3261 grammar.
Definition Uri.hxx:22
Data & user()
Definition Uri.hxx:42
Data & host()
Definition Uri.hxx:40
time_t getExpiresTime() const
This Class is used to implement a primitive form of RPC using loose XML formatting.
dcm! – add UnusedChecking(_enum) below;
bool isEqualNoCase(const Data &left, const Data &right)
Definition Data.hxx:1116
bool isWebSocket(TransportType type)
Returns true if passed in transport type is a WebSocket transport protocol.
RequestLineType h_RequestLine
Definition Headers.cxx:347