reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
Auth.cxx
Go to the documentation of this file.
1#if defined(HAVE_CONFIG_H)
2#include "config.h"
3#endif
4
7#include "rutil/Data.hxx"
8#include "rutil/DnsUtil.hxx"
9#include "rutil/Logger.hxx"
10#include "rutil/ParseBuffer.hxx"
11//#include "rutil/WinLeakCheck.hxx" // not compatible with placement new used below
12
13using namespace resip;
14using namespace std;
15
16#define RESIPROCATE_SUBSYSTEM Subsystem::SIP
17
18//====================
19// Auth:
20//====================
24
26 : ParserCategory(hfv, type, pool)
27{}
28
29Auth::Auth(const Auth& rhs, PoolBase* pool)
30 : ParserCategory(rhs, pool),
31 mScheme(rhs.mScheme)
32{}
33
34Auth&
36{
37 if (this != &rhs)
38 {
40 mScheme = rhs.mScheme;
41 }
42 return *this;
43}
44
45Data&
47{
48 checkParsed();
49 return mScheme;
50}
51
52const Data&
54{
55 checkParsed();
56 return mScheme;
57}
58
59void
61{
62 const char* start;
63 start = pb.skipWhitespace();
64 static const std::bitset<256> schemeDelimiter(Data::toBitset("\r\n\t ="));
65 pb.skipToOneOf(schemeDelimiter);
66
67 if (!pb.eof() && *pb.position() == Symbols::EQUALS[0])
68 {
69 // Authentication-Info only
70 // back up, and then parse
71 pb.reset(start);
73 }
74 else
75 {
76 // everything else
77 pb.data(mScheme, start);
78
79 pb.skipWhitespace();
81 }
82}
83
85Auth::encodeParsed(EncodeStream& str) const
86{
87 if (!mScheme.empty())
88 {
89 str << mScheme << Symbols::SPACE;
90 }
91
93
94 return str;
95}
96
99{
100 return new Auth(*this);
101}
102
104Auth::clone(void* location) const
105{
106 return new (location) Auth(*this);
107}
108
111{
112 return new (pool) Auth(*this, pool);
113}
114
115void
117{
118 while (!pb.eof())
119 {
120 const char* keyStart = pb.position();
121 static std::bitset<256> paramBegin=Data::toBitset(" \t\r\n=");
122 static std::bitset<256> terminators=Data::toBitset(" \t\r\n,");
123 const char* keyEnd = pb.skipToOneOf(paramBegin);
124 if((int)(keyEnd-keyStart) != 0)
125 {
126 ParameterTypes::Type type = ParameterTypes::getType(keyStart, (unsigned int)(keyEnd - keyStart));
127 Parameter* p=createParam(type, pb, terminators, getPool());
128 if (!p)
129 {
130 UnknownParameter* unknownParam = new UnknownParameter(keyStart,
131 int((keyEnd - keyStart)),
132 pb,
133 terminators);
134
135 if(!addParameter(unknownParam))
136 {
137 freeParameter(unknownParam);
138 }
139 }
140 else
141 {
142 if(!addParameter(p))
143 {
144 freeParameter(p);
145 }
146 }
147 }
148 else
149 {
150 // empty parameter name - skip and advance pb to next parameter
151 pb.skipToOneOf(terminators);
152 }
153
154 pb.skipWhitespace();
155 if (pb.eof() || *pb.position() != Symbols::COMMA[0])
156 {
157 break;
158 }
159 pb.skipChar();
160 pb.skipWhitespace();
161 }
162}
163
165Auth::encodeAuthParameters(EncodeStream& str) const
166{
167 bool first = true;
168 for (ParameterList::const_iterator it = mParameters.begin();
169 it != mParameters.end(); it++)
170 {
171 if (!first)
172 {
173 str << Symbols::COMMA;
174 }
175 first = false;
176 (*it)->encode(str);
177 }
178
179 for (ParameterList::const_iterator it = mUnknownParameters.begin();
180 it != mUnknownParameters.end(); it++)
181 {
182 if (!first)
183 {
184 str << Symbols::COMMA;
185 }
186 first = false;
187 (*it)->encode(str);
188 }
189 return str;
190}
191
192ParameterTypes::Factory Auth::ParameterFactories[ParameterTypes::MAX_PARAMETER]={0};
193
194Parameter*
195Auth::createParam(ParameterTypes::Type type, ParseBuffer& pb, const std::bitset<256>& terminators, PoolBase* pool)
196{
197 if(type==ParameterTypes::qop)
198 {
199 DataParameter* qop = 0;
200 switch(mHeaderType)
201 {
202 case Headers::ProxyAuthenticate:
203 case Headers::WWWAuthenticate:
204 qop = new (pool) DataParameter(ParameterTypes::qopOptions,pb,terminators);
205 qop->setQuoted(true);
206 break;
207 case Headers::ProxyAuthorization:
208 case Headers::Authorization:
209 case Headers::AuthenticationInfo:
210 default:
211 qop = new (pool) DataParameter(ParameterTypes::qop,pb,terminators);
212 qop->setQuoted(false);
213 }
214 return qop;
215 }
216
217 if(type > ParameterTypes::UNKNOWN && type < ParameterTypes::MAX_PARAMETER && ParameterFactories[type])
218 {
219 return ParameterFactories[type](type, pb, terminators, pool);
220 }
221 return 0;
222}
223
224bool
225Auth::exists(const Param<Auth>& paramType) const
226{
227 checkParsed();
228 bool ret = getParameterByEnum(paramType.getTypeNum()) != NULL;
229 return ret;
230}
231
232void
233Auth::remove(const Param<Auth>& paramType)
234{
235 checkParsed();
237}
238
239#define defineParam(_enum, _name, _type, _RFC_ref_ignored) \
240_enum##_Param::DType& \
241Auth::param(const _enum##_Param& paramType) \
242{ \
243 checkParsed(); \
244 _enum##_Param::Type* p = static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum())); \
245 if (!p) \
246 { \
247 p = new _enum##_Param::Type(paramType.getTypeNum()); \
248 mParameters.push_back(p); \
249 } \
250 return p->value(); \
251} \
252const _enum##_Param::DType& \
253Auth::param(const _enum##_Param& paramType) const \
254{ \
255 checkParsed(); \
256 _enum##_Param::Type* p = static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum())); \
257 if (!p) \
258 { \
259 InfoLog(<< "Missing parameter " << ParameterTypes::ParameterNames[paramType.getTypeNum()]); \
260 DebugLog(<< *this); \
261 throw Exception("Missing parameter", __FILE__, __LINE__); \
262 } \
263 return p->value(); \
264}
265
266defineParam(algorithm, "algorithm", DataParameter, "RFC 2617");
267defineParam(cnonce, "cnonce", QuotedDataParameter, "RFC 2617");
268defineParam(domain, "domain", QuotedDataParameter, "RFC 3261");
269defineParam(nc, "nc", DataParameter, "RFC 2617");
270defineParam(nonce, "nonce", QuotedDataParameter, "RFC 2617");
271defineParam(opaque, "opaque", QuotedDataParameter, "RFC 2617");
272defineParam(realm, "realm", QuotedDataParameter, "RFC 2617");
273defineParam(response, "response", QuotedDataParameter, "RFC 3261");
274defineParam(stale, "stale", DataParameter, "RFC 2617");
275defineParam(uri, "uri", QuotedDataParameter, "RFC 3261");
276defineParam(username, "username", QuotedDataParameter, "RFC 3261");
277
279Auth::param(const qop_Param& paramType)
280{
281 checkParsed();
282 DataParameter* p = static_cast<DataParameter*>(getParameterByEnum(paramType.getTypeNum()));
283 if (!p)
284 {
285 p = new DataParameter(ParameterTypes::qop);
286 p->setQuoted(false);
287 mParameters.push_back(p);
288 }
289 return p->value();
290}
292Auth::param(const qop_Param& paramType) const
293{
294 checkParsed();
295 DataParameter* p = static_cast<DataParameter*>(getParameterByEnum(paramType.getTypeNum()));
296 if (!p)
297 {
298 InfoLog(<< "Missing parameter " << ParameterTypes::ParameterNames[paramType.getTypeNum()]);
299 DebugLog(<< *this);
300 throw Exception("Missing parameter", __FILE__, __LINE__);
301 }
302 return p->value();
303}
304
306Auth::param(const qopOptions_Param& paramType)
307{
308 checkParsed();
309 DataParameter* p = static_cast<DataParameter*>(getParameterByEnum(paramType.getTypeNum()));
310 if (!p)
311 {
312 p = new DataParameter(ParameterTypes::qopOptions);
313 p->setQuoted(true);
314 mParameters.push_back(p);
315 }
316 return p->value();
317}
319Auth::param(const qopOptions_Param& paramType) const
320{
321 checkParsed();
322 DataParameter* p = static_cast<DataParameter*>(getParameterByEnum(paramType.getTypeNum()));
323 if (!p)
324 {
325 InfoLog(<< "Missing parameter " << ParameterTypes::ParameterNames[paramType.getTypeNum()]);
326 DebugLog(<< *this);
327 throw Exception("Missing parameter", __FILE__, __LINE__);
328 }
329 return p->value();
330}
331
332
333#undef defineParam
334
335/* ====================================================================
336 * The Vovida Software License, Version 1.0
337 *
338 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
339 *
340 * Redistribution and use in source and binary forms, with or without
341 * modification, are permitted provided that the following conditions
342 * are met:
343 *
344 * 1. Redistributions of source code must retain the above copyright
345 * notice, this list of conditions and the following disclaimer.
346 *
347 * 2. Redistributions in binary form must reproduce the above copyright
348 * notice, this list of conditions and the following disclaimer in
349 * the documentation and/or other materials provided with the
350 * distribution.
351 *
352 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
353 * and "Vovida Open Communication Application Library (VOCAL)" must
354 * not be used to endorse or promote products derived from this
355 * software without prior written permission. For written
356 * permission, please contact vocal@vovida.org.
357 *
358 * 4. Products derived from this software may not be called "VOCAL", nor
359 * may "VOCAL" appear in their name, without prior written
360 * permission of Vovida Networks, Inc.
361 *
362 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
363 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
364 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
365 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
366 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
367 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
368 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
369 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
370 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
371 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
372 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
373 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
374 * DAMAGE.
375 *
376 * ====================================================================
377 *
378 * This software consists of voluntary contributions made by Vovida
379 * Networks, Inc. and many individuals on behalf of Vovida Networks,
380 * Inc. For more information on Vovida Networks, Inc., please see
381 * <http://www.vovida.org/>.
382 *
383 */
#define defineParam(_enum, _name, _type, _RFC_ref_ignored)
Definition Auth.cxx:239
#define DebugLog(args_)
Definition Logger.hxx:128
#define InfoLog(args_)
Definition Logger.hxx:131
Represents the "credentials" and "challenge" elements in the SIP grammar.
Definition Auth.hxx:18
bool exists(const Param< Auth > &paramType) const
Definition Auth.cxx:225
virtual void parse(ParseBuffer &pb)
Definition Auth.cxx:60
virtual EncodeStream & encodeParsed(EncodeStream &str) const
Definition Auth.cxx:85
virtual ParserCategory * clone() const
Definition Auth.cxx:98
void parseAuthParameters(ParseBuffer &pb)
Definition Auth.cxx:116
EncodeStream & encodeAuthParameters(EncodeStream &str) const
Definition Auth.cxx:165
virtual Parameter * createParam(ParameterTypes::Type type, ParseBuffer &pb, const std::bitset< 256 > &terminators, PoolBase *pool)
Definition Auth.cxx:195
Auth & operator=(const Auth &)
Definition Auth.cxx:35
Data & scheme()
Definition Auth.cxx:46
void remove(const Param< Auth > &paramType)
Definition Auth.cxx:233
const Data & param(const ExtensionParameter &param) const
Const accessor for non-natively-supported parameter types.
Generically represents miscellaneous parameter data.
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
Definition Data.hxx:90
bool empty() const noexcept
Checks whether the Data is empty.
Definition Data.hxx:591
static std::bitset< 256 > toBitset(const resip::Data &chars)
Creates a bitset reflecting the contents of this data (as a set) ie.
Definition Data.cxx:2477
void checkParsed() const
virtual ParameterTypes::Type getTypeNum() const =0
Parameter *(* Factory)(ParameterTypes::Type, ParseBuffer &, const std::bitset< 256 > &terminators, PoolBase *pool)
static Type getType(const char *start, size_t length)
does a convert to enum from a pointer into the HFV raw buffer
static Data ParameterNames[MAX_PARAMETER]
static array of ParameterNames indexed by the 2nd element in defineParam(...)
Provides string-parsing functionality with protection from buffer overflow.
CurrentPosition skipWhitespace()
CurrentPosition position() const
void reset(const char *pos)
CurrentPosition skipToOneOf(const char *cs)
CurrentPosition skipChar()
void data(Data &data, const char *start) const
make the passed in data share memory with the buffer (uses Data::Share)
Base class for all SIP grammar elements that can have parameters.
Parameter * getParameterByEnum(ParameterTypes::Type type) const
ParameterList mUnknownParameters
ParserCategory & operator=(const ParserCategory &rhs)
void removeParameterByEnum(ParameterTypes::Type type)
bool addParameter(Parameter *param)
void freeParameter(Parameter *p)
Generically represents miscellaneous parameter data that is encoded using double quotes.
static const char * SPACE
Definition Symbols.hxx:34
static const char * COMMA
Definition Symbols.hxx:35
static const char * EQUALS
Definition Symbols.hxx:29
Generically used to represent any parameter that is not known by the implmentation.
dcm! – add UnusedChecking(_enum) below;
#define EncodeStream