reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
AmIResponsible.cxx
Go to the documentation of this file.
1#if defined(HAVE_CONFIG_H)
2#include "config.h"
3#endif
4
10#include "repro/Proxy.hxx"
11#include <ostream>
12#include <utility>
13
14#include "rutil/Logger.hxx"
15#define RESIPROCATE_SUBSYSTEM resip::Subsystem::REPRO
16
17using namespace resip;
18using namespace repro;
19using namespace std;
20
21AmIResponsible::AmIResponsible(bool alwaysAllowRelaying) :
22 Processor("AmIResponsible"),
23 mAlwaysAllowRelaying(alwaysAllowRelaying)
24{}
25
28
31{
32 DebugLog(<< "Monkey handling request: " << *this
33 << "; reqcontext = " << context);
34
35 resip::SipMessage& request = context.getOriginalRequest();
36
37 // This call is placed after the DigestAuthenticator, so that we only account for
38 // authenticated sessions.
39 context.getProxy().doSessionAccounting(request, true /* received */, context);
40
41 // There should be no Routes on the request at this point, if there was a route, then
42 // the StrictRouteFixup monkey would have routed to it already
43 resip_assert (!request.exists(h_Routes) ||
44 request.header(h_Routes).empty());
45
46 // Topmost route had a flow-token; this is our problem
47 if(context.isTopRouteFlowTupleSet())
48 {
49 std::unique_ptr<Target> target(new Target(request.header(h_RequestLine).uri()));
50 target->rec().mReceivedFrom = context.getTopRouteFlowTuple();
51 target->rec().mUseFlowRouting = true;
52 context.getResponseContext().addTarget(std::move(target));
53 return SkipThisChain;
54 }
55
56 // this if is just to be safe
57 if (!request.exists(h_Routes) ||
58 request.header(h_Routes).empty())
59 {
60 // !RjS! - Jason - check the RURI to see if the domain is
61 // something this request is responsible for. If yes, then
62 // just return Continue. If no make this call below.
63 const Uri& uri = request.header(h_RequestLine).uri();
64 if (!context.getProxy().isMyUri(uri))
65 {
66 // if this is not for a domain for which the proxy is responsible,
67 // check that this sender is in our domain and send to the Request URI
68
69 // Ensure To header is well formed
70 if(!request.header(h_To).isWellFormed())
71 {
72 resip::SipMessage response;
73 InfoLog(<<"Garbage in To header: needed for relay check.");
74 Helper::makeResponse(response,context.getOriginalRequest(), 400, "Malformed To: header");
75 context.sendResponse(response);
77 }
78
79 // only perform relay check for out-of-dialog requests
80 // !bwc! Um, then all anyone has to do to get us to be their relay
81 // is throw in a spurious to-tag...
82 // This smells funny. I am commenting it out.
83 // .slg. Putting the old check back in and clarifying the funny smell...
84 // We only want to do this check for out of dialog requests, since
85 // mid-dialog requests could be 403'd otherwise. Consider
86 // an INVITE request from a repro domain user to a user in
87 // another domain. The resulting ACK/200, BYE or any other
88 // mid-dialog request coming from the remote domain, will contain
89 // the repro users contact address in the RequestUri and a
90 // foreign domain in the from header. We want to ensure these
91 // requests are not 403'd. Byron's comment about an endpoint getting
92 // us to relay by placing a spurious to tag in the request still
93 // stands. Perhaps we ought to be checking the To header domain in
94 // this case - however that is also weak, since the To header is not
95 // used in routing and can easily be set to a URI in our domain to
96 // trick repro into forwarding. Note: From header domain checking is
97 // stronger than To header domain checking, since if the domain is
98 // ours, then it must pass Digest Authentication (at least for non
99 // ACK and BYE requests).
100 // .bwc. I think that the only real way to solve the
101 // I-don't-want-to-be-used-as-a-relay problem is crypto; specifically
102 // Record-Route with crypto that states "Yeah, I set up this dialog,
103 // let it through".
104 if (!request.header(h_To).exists(p_tag) && !mAlwaysAllowRelaying)
105 {
106 // Ensure From header is well formed
107 if(!request.header(h_From).isWellFormed())
108 {
109 resip::SipMessage response;
110 InfoLog(<<"Garbage in From header: needed for relay check.");
111 Helper::makeResponse(response,context.getOriginalRequest(), 400, "Malformed From: header");
112 context.sendResponse(response);
114 }
115
116 // !rwm! verify the AuthenticatioInfo object here.
117
118 // !rwm! TODO check some kind of relay list here
119 // for now, just see if the sender claims to be from one of our domains
120 // send a 403 if not on the list
121
122 // .slg. Allow trusted nodes to relay
124 !context.getProxy().isMyUri(request.header(h_From).uri()) &&
125 !request.hasForceTarget())
126 {
127 // make 403, send, dispose of memory
128 resip::SipMessage response;
129 InfoLog (<< *this << ": will not relay to " << uri << " from "
130 << request.header(h_From).uri() << ", send 403");
131 Helper::makeResponse(response, context.getOriginalRequest(), 403, "Relaying Forbidden");
132 context.sendResponse(response);
134 }
135 }
136
137 std::unique_ptr<Target> target(new Target(uri));
138 context.getResponseContext().addTarget(std::move(target));
139
140 InfoLog (<< "Sending to requri: " << uri);
141 // skip the rest of the monkeys
143 }
144 }
145 return Processor::Continue;
146}
147
148
149/* ====================================================================
150 * The Vovida Software License, Version 1.0
151 *
152 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
153 *
154 * Redistribution and use in source and binary forms, with or without
155 * modification, are permitted provided that the following conditions
156 * are met:
157 *
158 * 1. Redistributions of source code must retain the above copyright
159 * notice, this list of conditions and the following disclaimer.
160 *
161 * 2. Redistributions in binary form must reproduce the above copyright
162 * notice, this list of conditions and the following disclaimer in
163 * the documentation and/or other materials provided with the
164 * distribution.
165 *
166 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
167 * and "Vovida Open Communication Application Library (VOCAL)" must
168 * not be used to endorse or promote products derived from this
169 * software without prior written permission. For written
170 * permission, please contact vocal@vovida.org.
171 *
172 * 4. Products derived from this software may not be called "VOCAL", nor
173 * may "VOCAL" appear in their name, without prior written
174 * permission of Vovida Networks, Inc.
175 *
176 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
177 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
178 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
179 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
180 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
181 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
182 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
183 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
184 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
185 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
186 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
187 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
188 * DAMAGE.
189 *
190 * ====================================================================
191 *
192 * This software consists of voluntary contributions made by Vovida
193 * Networks, Inc. and many individuals on behalf of Vovida Networks,
194 * Inc. For more information on Vovida Networks, Inc., please see
195 * <http://www.vovida.org/>.
196 *
197 */
#define DebugLog(args_)
Definition Logger.hxx:128
#define InfoLog(args_)
Definition Logger.hxx:131
#define resip_assert(x)
This file needs to work for both C and C++ code.
virtual processor_action_t process(RequestContext &)
AmIResponsible(bool alwaysAllowRelaying=false)
static resip::KeyValueStore::Key mFromTrustedNodeKey
virtual bool isMyUri(const resip::Uri &uri) const
Definition Proxy.cxx:600
void doSessionAccounting(const resip::SipMessage &sip, bool received, RequestContext &context)
Definition Proxy.cxx:703
resip::SipMessage & getOriginalRequest()
Returns the SipMessage associated with the server transaction.
ResponseContext & getResponseContext()
resip::Tuple & getTopRouteFlowTuple()
void sendResponse(resip::SipMessage &response)
resip::KeyValueStore & getKeyValueStore()
resip::Data addTarget(const resip::NameAddr &target, bool beginImmediately=false)
Adds this Target as a SimpleTarget to the collection of Targets.
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
const bool & getBoolValue(Key key) const
bool isWellFormed() const
Returns true iff this element was parsed successfully, according to the implementation of parse().
const Uri & uri() const
Represents a SIP message.
bool hasForceTarget() 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.
Represents the "SIP-URI" and "SIPS-URI" elements in the RFC 3261 grammar.
Definition Uri.hxx:22
This Class is used to implement a primitive form of RPC using loose XML formatting.
dcm! – add UnusedChecking(_enum) below;
RequestLineType h_RequestLine
Definition Headers.cxx:347