/[resiprocate]/main/reTurn/StunMessage.cxx
ViewVC logotype

Contents of /main/reTurn/StunMessage.cxx

Parent Directory Parent Directory | Revision Log Revision Log


Revision 11159 - (show annotations) (download)
Fri Apr 25 14:03:32 2014 UTC (5 years, 6 months ago) by sgodin
File MIME type: text/plain
File size: 57895 byte(s)
-modified asio and boost include file ordering to avoid multiply defined symbol errors on linking
 -in preparation for upgrade of asio drop and support for latest boost 
 -include asio/ssh.hpp everywhere asio.hpp is included
 -include boost headers before others, to ensure we are not redefining stdint definitions in some includes
  and not others

1
2 #if defined(HAVE_CONFIG_H)
3 #include "config.h"
4 #endif
5
6 #include <boost/crc.hpp>
7
8 #include "StunMessage.hxx"
9
10 #include <rutil/compat.hxx>
11 #include <rutil/Timer.hxx>
12 #include <rutil/Random.hxx>
13 #include <rutil/DataStream.hxx>
14 #include <rutil/MD5Stream.hxx>
15 #include <rutil/WinLeakCheck.hxx>
16 #include <rutil/Logger.hxx>
17 #include "ReTurnSubsystem.hxx"
18
19 #define RESIPROCATE_SUBSYSTEM ReTurnSubsystem::RETURN
20
21 #ifdef USE_SSL
22 #include <openssl/hmac.h>
23 #endif
24
25 using namespace std;
26 using namespace resip;
27
28 // What should we set these to? Used for short term password generation.
29 static const Data USERNAME_KEY("stunServerUsernameKey");
30 static const Data PASSWORD_KEY("stunServerPasswordKey");
31
32 #define MAX_USERNAME_BYTES 512
33 #define MAX_PASSWORD_BYTES 512
34 #define MAX_REALM_BYTES 763
35 #define MAX_NONCE_BYTES 763
36 #define MAX_SOFTWARE_BYTES 763
37 #define MAX_ERRORCODE_REASON_BYTES 763
38
39 #define STUN_CRC_FINAL_XOR 0x5354554e
40
41 namespace reTurn {
42
43 bool operator<(const UInt128& lhs, const UInt128& rhs)
44 {
45 if(lhs.longpart[0] != rhs.longpart[0])
46 {
47 return lhs.longpart[0] < rhs.longpart[0];
48 }
49 else if(lhs.longpart[1] != rhs.longpart[1])
50 {
51 return lhs.longpart[1] < rhs.longpart[1];
52 }
53 else if(lhs.longpart[2] != rhs.longpart[2])
54 {
55 return lhs.longpart[2] < rhs.longpart[2];
56 }
57
58 return lhs.longpart[3] < rhs.longpart[3];
59 }
60
61 bool operator==(const UInt128& lhs, const UInt128& rhs)
62 {
63 return lhs.longpart[0] == rhs.longpart[0] &&
64 lhs.longpart[1] == rhs.longpart[1] &&
65 lhs.longpart[2] == rhs.longpart[2] &&
66 lhs.longpart[3] == rhs.longpart[3];
67 }
68
69 StunMessage::StunMessage(const StunTuple& localTuple,
70 const StunTuple& remoteTuple,
71 char* buf, unsigned int bufLen) :
72 mLocalTuple(localTuple),
73 mRemoteTuple(remoteTuple),
74 mBuffer(buf, bufLen) // !slg! copies buffer from Socket buffer assuming for now that StunMessages will persist past one request/response transaction
75 // could make this more efficient by having the transports allocate buffer dynamically and pass ownership over
76 {
77 init();
78 mIsValid = stunParseMessage(buf, bufLen);
79
80 if(mIsValid)
81 {
82 DebugLog(<< "Successfully parsed StunMessage: " << mHeader);
83 }
84 }
85
86 StunMessage::StunMessage() :
87 mIsValid(true)
88 {
89 init();
90 }
91
92 StunMessage::StunMessage(const StunMessage& from)
93 {
94 *this = from;
95 }
96
97 StunMessage&
98 StunMessage::operator=(const StunMessage& rhs)
99 {
100 if (this != &rhs)
101 {
102 assert(false);
103 }
104
105 return *this;
106 }
107
108 StunMessage::~StunMessage()
109 {
110 if(mErrorCode.reason) delete mErrorCode.reason;
111 if(mUsername) delete mUsername;
112 if(mPassword) delete mPassword;
113 if(mRealm) delete mRealm;
114 if(mNonce) delete mNonce;
115 if(mSoftware) delete mSoftware;
116 if(mTurnData) delete mTurnData;
117 }
118
119 void
120 StunMessage::init()
121 {
122 mHasMappedAddress = false;
123 mHasResponseAddress = false;
124 mHasChangeRequest = false;
125 mHasSourceAddress = false;
126 mHasChangedAddress = false;
127 mHasUsername = false;
128 mHasNonce = false;
129 mHasRealm = false;
130 mHasPassword = false;
131 mHasMessageIntegrity = false;
132 mHasErrorCode = false;
133 mHasUnknownAttributes = false;
134 mHasReflectedFrom = false;
135 mHasXorMappedAddress = false;
136 mHasFingerprint = false;
137 mHasSoftware = false;
138 mHasAlternateServer = false;
139 mHasSecondaryAddress = false;
140 mHasTurnChannelNumber = false;
141 mHasTurnLifetime = false;
142 mHasTurnBandwidth = false;
143 mHasTurnData = false;
144 mHasTurnXorRelayedAddress = false;
145 mHasTurnEvenPort = false;
146 mHasTurnRequestedTransport = false;
147 mHasTurnDontFragment = false;
148 mHasTurnReservationToken = false;
149 mHasTurnConnectStat = false;
150 mCntTurnXorPeerAddress = 0;
151 mHasTurnRequestedAddressFamily = false;
152 mHasIcePriority = false;
153 mIcePriority = 0;
154 mHasIceUseCandidate = false;
155 mHasIceControlled = false;
156 mIceControlledTieBreaker = 0;
157 mHasIceControlling = false;
158 mIceControllingTieBreaker = 0;
159 mErrorCode.reason = 0;
160 mUsername = 0;
161 mPassword = 0;
162 mRealm = 0;
163 mNonce = 0;
164 mSoftware = 0;
165 mTurnData = 0;
166 mMessageIntegrityMsgLength = 0;
167 mUnknownRequiredAttributes.numAttributes = 0;
168 }
169
170 void
171 StunMessage::createHeader(UInt16 stunclass, UInt16 method)
172 {
173 mClass = stunclass;
174 mMethod = method;
175
176 // Assign a tid
177 mHeader.id.magicCookie = htonl(StunMagicCookie);
178 Data random = Random::getCryptoRandom(12);
179 memcpy(&mHeader.id.tid, random.data(), sizeof(mHeader.id.tid));
180 }
181
182 void
183 StunMessage::setErrorCode(unsigned short errorCode, const char* reason)
184 {
185 assert(errorCode >= 100 && errorCode <= 699);
186 mHasErrorCode = true;
187 mErrorCode.errorClass = errorCode / 100;
188 mErrorCode.number = errorCode % 100;
189 if(mErrorCode.reason)
190 {
191 *mErrorCode.reason = reason;
192 }
193 else
194 {
195 mErrorCode.reason = new Data(reason);
196 }
197 }
198
199 void
200 StunMessage::setUsername(const char* username)
201 {
202 mHasUsername = true;
203 if(mUsername)
204 {
205 *mUsername = username;
206 }
207 else
208 {
209 mUsername = new Data(username);
210 }
211 }
212
213 void
214 StunMessage::setPassword(const char* password)
215 {
216 mHasPassword = true;
217 if(mPassword)
218 {
219 *mPassword = password;
220 }
221 else
222 {
223 mPassword = new Data(password);
224 }
225 }
226
227 void
228 StunMessage::setRealm(const char* realm)
229 {
230 mHasRealm = true;
231 if(mRealm)
232 {
233 *mRealm = realm;
234 }
235 else
236 {
237 mRealm = new Data(realm);
238 }
239 }
240
241 void
242 StunMessage::setNonce(const char* nonce)
243 {
244 mHasNonce = true;
245 if(mNonce)
246 {
247 *mNonce = nonce;
248 }
249 else
250 {
251 mNonce = new Data(nonce);
252 }
253 }
254
255 void
256 StunMessage::setSoftware(const char* software)
257 {
258 mHasSoftware = true;
259 if(mSoftware)
260 {
261 *mSoftware = software;
262 }
263 else
264 {
265 mSoftware = new Data(software);
266 }
267 }
268
269 void
270 StunMessage::setTurnData(const char* data, unsigned int len)
271 {
272 mHasTurnData = true;
273 if(mTurnData)
274 {
275 mTurnData->clear();
276 mTurnData->append(data, len);
277 }
278 else
279 {
280 mTurnData = new Data(data, len);
281 }
282 }
283
284 void
285 StunMessage::setIcePriority(UInt32 priority)
286 {
287 mHasIcePriority = true;
288 mIcePriority = priority;
289 }
290
291 void
292 StunMessage::setIceUseCandidate()
293 {
294 mHasIceUseCandidate = true;
295 }
296
297 void
298 StunMessage::setIceControlled()
299 {
300 mHasIceControlled = true;
301 const resip::Data& tieBreaker = resip::Random::getCryptoRandom(8);
302 memcpy(&mIceControlledTieBreaker, tieBreaker.begin(), sizeof(mIceControlledTieBreaker));
303 }
304
305 void
306 StunMessage::setIceControlling()
307 {
308 mHasIceControlling = true;
309 const resip::Data& tieBreaker = resip::Random::getCryptoRandom(8);
310 memcpy(&mIceControllingTieBreaker, tieBreaker.begin(), sizeof(mIceControllingTieBreaker));
311 }
312
313 void
314 StunMessage::applyXorToAddress(const StunAtrAddress& in, StunAtrAddress& out)
315 {
316 if(&in != &out) memcpy(&out, &in, sizeof(out));
317
318 out.port = out.port^(StunMessage::StunMagicCookie>>16); // Xor with most significate 16 bits of magic cookie
319 if(out.family == IPv6Family)
320 {
321 for(int i = 0; i < 4; i++)
322 {
323 // Note: MagicCookieAndTid are stored in network byte order
324 out.addr.ipv6.longpart[i] = out.addr.ipv6.longpart[i]^mHeader.magicCookieAndTid.longpart[i];
325 }
326 }
327 else
328 {
329 out.addr.ipv4 = out.addr.ipv4^StunMessage::StunMagicCookie;
330 }
331 }
332
333 void
334 StunMessage::setStunAtrAddressFromTuple(StunAtrAddress& address, const StunTuple& tuple)
335 {
336 address.port = tuple.getPort();
337 if(tuple.getAddress().is_v6())
338 {
339 // Note: addr.ipv6 is stored in network byte order
340 address.family = StunMessage::IPv6Family;
341 memcpy(&address.addr.ipv6, tuple.getAddress().to_v6().to_bytes().data(), sizeof(address.addr.ipv6));
342 }
343 else
344 {
345 // Note: addr.ipv4 is stored in host byte order
346 address.family = StunMessage::IPv4Family;
347 address.addr.ipv4 = tuple.getAddress().to_v4().to_ulong();
348 }
349 }
350
351 void
352 StunMessage::setTupleFromStunAtrAddress(StunTuple& tuple, const StunAtrAddress& address)
353 {
354 tuple.setPort(address.port);
355 if(address.family == StunMessage::IPv6Family)
356 {
357 // Note: addr.ipv6 is stored in network byte order
358 asio::ip::address_v6::bytes_type bytes;
359 memcpy(bytes.data(), &address.addr.ipv6, bytes.size());
360 asio::ip::address_v6 addr(bytes);
361 tuple.setAddress(addr);
362 }
363 else
364 {
365 // Note: addr.ipv4 is stored in host byte order
366 asio::ip::address_v4 addr(address.addr.ipv4);
367 tuple.setAddress(addr);
368 }
369 }
370
371 bool
372 StunMessage::stunParseAtrXorAddress( char* body, unsigned int hdrLen, StunAtrAddress& result )
373 {
374 bool ret = stunParseAtrAddress(body, hdrLen, result);
375 if(ret)
376 {
377 applyXorToAddress(result, result);
378 }
379 return ret;
380 }
381
382 bool
383 StunMessage::stunParseAtrAddress( char* body, unsigned int hdrLen, StunAtrAddress& result )
384 {
385 if ( hdrLen != 8 /* ipv4 size */ && hdrLen != 20 /* ipv6 size */ )
386 {
387 WarningLog(<< "hdrLen wrong for Address");
388 return false;
389 }
390 body++; // Skip pad
391 result.family = *body++;
392
393 UInt16 nport;
394 memcpy(&nport, body, 2); body+=2;
395 result.port = ntohs(nport);
396
397 if (result.family == IPv4Family)
398 {
399 UInt32 naddr;
400 memcpy(&naddr, body, sizeof(UInt32)); body+=sizeof(UInt32);
401 result.addr.ipv4 = ntohl(naddr);
402 // Note: addr.ipv4 is stored in host byte order
403 return true;
404 }
405 else if (result.family == IPv6Family)
406 {
407 memcpy(&result.addr.ipv6, body, sizeof(result.addr.ipv6)); body+=sizeof(result.addr.ipv6);
408 // Note: addr.ipv6 is stored in host byte order
409 return true;
410 }
411 else
412 {
413 WarningLog(<< "bad address family: " << result.family);
414 }
415
416 return false;
417 }
418
419 bool
420 StunMessage::stunParseAtrEvenPort( char* body, unsigned int hdrLen, TurnAtrEvenPort& result )
421 {
422 if ( hdrLen != 1 )
423 {
424 WarningLog(<< "hdrLen wrong for EvenPort");
425 return false;
426 }
427 result.propType = *body & 0x80; // copy first 8 bits into propType - but only look at highest order
428
429 return true;
430 }
431
432 bool
433 StunMessage::stunParseAtrUInt32( char* body, unsigned int hdrLen, UInt32& result )
434 {
435 if ( hdrLen != 4 )
436 {
437 WarningLog(<< "hdrLen wrong for UInt32 attribute");
438 return false;
439 }
440 else
441 {
442 memcpy(&result, body, 4);
443 result = ntohl(result);
444 return true;
445 }
446 }
447
448 bool
449 StunMessage::stunParseAtrUInt64( char* body, unsigned int hdrLen, UInt64& result )
450 {
451 if ( hdrLen != 8 )
452 {
453 WarningLog(<< "hdrLen wrong for UInt64 attribute");
454 return false;
455 }
456 else
457 {
458 memcpy(&result, body, 8);
459 result = ntoh64(result);
460 return true;
461 }
462 }
463
464 bool
465 StunMessage::stunParseAtrError( char* body, unsigned int hdrLen, StunAtrError& result )
466 {
467 body+=2; // skip pad
468 result.errorClass = *body++ & 0x7;
469 result.number = *body++;
470
471 int reasonLen = (hdrLen -4) > MAX_ERRORCODE_REASON_BYTES ? MAX_ERRORCODE_REASON_BYTES : hdrLen-4;
472 result.reason = new resip::Data(resip::Data::Share, body, reasonLen);
473 return true;
474 }
475
476 bool
477 StunMessage::stunParseAtrUnknown( char* body, unsigned int hdrLen, StunAtrUnknown& result )
478 {
479 if ( hdrLen >= sizeof(result) )
480 {
481 WarningLog(<< "hdrLen wrong for Unknown attribute or too many unknown attributes present");
482 return false;
483 }
484 else
485 {
486 if (hdrLen % 2 != 0) return false;
487 result.numAttributes = hdrLen / 2;
488 for (int i=0; i<result.numAttributes; i++)
489 {
490 memcpy(&result.attrType[i], body, 2); body+=2;
491 result.attrType[i] = ntohs(result.attrType[i]);
492 }
493 return true;
494 }
495 }
496
497 bool
498 StunMessage::stunParseAtrIntegrity( char* body, unsigned int hdrLen, StunAtrIntegrity& result )
499 {
500 if ( hdrLen != 20)
501 {
502 WarningLog(<< "hdrLen wrong for message integrity");
503 return false;
504 }
505 else
506 {
507 memcpy(&result.hash, body, hdrLen);
508 return true;
509 }
510 }
511
512
513
514 bool
515 StunMessage::stunParseMessage( char* buf, unsigned int bufLen)
516 {
517 StackLog(<< "Received stun message: " << bufLen << " bytes");
518
519 if (sizeof(StunMsgHdr) > bufLen)
520 {
521 WarningLog(<< "Bad message, bufLen=" << bufLen);
522 return false;
523 }
524
525 memcpy(&mHeader, buf, sizeof(StunMsgHdr));
526 mHeader.msgType = ntohs(mHeader.msgType);
527 mHeader.msgLength = ntohs(mHeader.msgLength);
528
529 if (mHeader.msgLength + sizeof(StunMsgHdr) != bufLen)
530 {
531 WarningLog(<< "Message header length (" << mHeader.msgLength << ") + header size (" << sizeof(StunMsgHdr) << ") doesn't match message size (" << bufLen << ")");
532 return false;
533 }
534
535 // Check if class and method are valid
536 mClass = mHeader.msgType & 0x0110;
537 mMethod = mHeader.msgType & 0x000F;
538
539 // Look for stun magic cookie
540 mHasMagicCookie = mHeader.id.magicCookie == htonl(StunMagicCookie);
541 if(!mHasMagicCookie)
542 {
543 StackLog(<< "stun magic cookie not found.");
544 }
545
546 char* body = buf + sizeof(StunMsgHdr);
547 unsigned int size = mHeader.msgLength;
548 mUnknownRequiredAttributes.numAttributes = 0;
549
550 StackLog(<< "bytes after header = " << size);
551
552 while ( size > 0 )
553 {
554 // !jf! should check that there are enough bytes left in the buffer
555
556 StunAtrHdr* attr = reinterpret_cast<StunAtrHdr*>(body);
557
558 unsigned int attrLen = ntohs(attr->length);
559 // attrLen may not be on 4 byte boundary, in which case we need to pad to 4 bytes when advancing to next attribute
560 unsigned int attrLenPad = attrLen % 4 == 0 ? 0 : 4 - (attrLen % 4);
561 int atrType = ntohs(attr->type);
562
563 StackLog(<< "Found attribute type=" << atrType << " length=" << attrLen);
564 if ( attrLen+attrLenPad+4 > size )
565 {
566 WarningLog(<< "claims attribute is larger than size of message " <<"(attribute type="<<atrType<<")");
567 return false;
568 }
569
570 body += 4; // skip the length and type in attribute header
571 size -= 4;
572
573 switch ( atrType )
574 {
575 case MappedAddress:
576 if(!mHasMappedAddress)
577 {
578 mHasMappedAddress = true;
579 if ( stunParseAtrAddress( body, attrLen, mMappedAddress )== false )
580 {
581 WarningLog(<< "problem parsing MappedAddress");
582 return false;
583 }
584 StackLog(<< "MappedAddress = " << mMappedAddress);
585 }
586 else
587 {
588 WarningLog(<< "Duplicate MappedAddress in message - ignoring.");
589 }
590 break;
591
592 case ResponseAddress: // deprecated
593 if(!mHasResponseAddress)
594 {
595 mHasResponseAddress = true;
596 if ( stunParseAtrAddress( body, attrLen, mResponseAddress )== false )
597 {
598 WarningLog(<< "problem parsing ResponseAddress");
599 return false;
600 }
601 StackLog(<< "ResponseAddress = " << mResponseAddress);
602 }
603 else
604 {
605 WarningLog(<< "Duplicate ResponseAddress in message - ignoring.");
606 }
607 break;
608
609 case ChangeRequest: // deprecated
610 if(!mHasChangeRequest)
611 {
612 mHasChangeRequest = true;
613 if (stunParseAtrUInt32( body, attrLen, mChangeRequest) == false)
614 {
615 WarningLog(<< "problem parsing ChangeRequest");
616 return false;
617 }
618 StackLog(<< "ChangeRequest = " << mChangeRequest);
619 }
620 else
621 {
622 WarningLog(<< "Duplicate ChangeRequest in message - ignoring.");
623 }
624 break;
625
626 case SourceAddress: // deprecated
627 if(!mHasSourceAddress)
628 {
629 mHasSourceAddress = true;
630 if ( stunParseAtrAddress( body, attrLen, mSourceAddress )== false )
631 {
632 WarningLog(<< "problem parsing SourceAddress");
633 return false;
634 }
635 StackLog(<< "SourceAddress = " << mSourceAddress);
636 }
637 else
638 {
639 WarningLog(<< "Duplicate SourceAddress in message - ignoring.");
640 }
641 break;
642
643 case ChangedAddress: // deprecated
644 if(!mHasChangedAddress)
645 {
646 mHasChangedAddress = true;
647 if ( stunParseAtrAddress( body, attrLen, mChangedAddress )== false )
648 {
649 WarningLog(<< "problem parsing ChangedAddress");
650 return false;
651 }
652 StackLog(<< "ChangedAddress = " << mChangedAddress);
653 }
654 else
655 {
656 WarningLog(<< "Duplicate ChangedAddress in message - ignoring.");
657 }
658 break;
659
660 case Username:
661 if(!mHasUsername)
662 {
663 if(attrLen > MAX_USERNAME_BYTES)
664 {
665 WarningLog(<< "Username length=" << attrLen << " is longer than max allowed=" << MAX_USERNAME_BYTES);
666 return false;
667 }
668 mHasUsername = true;
669 mUsername = new resip::Data(resip::Data::Share, body, attrLen);
670 StackLog(<< "Username = " << *mUsername);
671 }
672 else
673 {
674 WarningLog(<< "Duplicate Username in message - ignoring.");
675 }
676 break;
677
678 case Password:
679 if(!mHasPassword)
680 {
681 if(attrLen > MAX_PASSWORD_BYTES)
682 {
683 WarningLog(<< "Password length=" << attrLen << " is longer than max allowed=" << MAX_PASSWORD_BYTES);
684 return false;
685 }
686 mHasPassword = true;
687 mPassword = new resip::Data(resip::Data::Share, body, attrLen);
688 StackLog(<< "Password = " << *mPassword);
689 }
690 else
691 {
692 WarningLog(<< "Duplicate Password in message - ignoring.");
693 }
694 break;
695
696 case MessageIntegrity:
697 if(!mHasMessageIntegrity)
698 {
699 mHasMessageIntegrity = true;
700 if (stunParseAtrIntegrity( body, attrLen, mMessageIntegrity) == false)
701 {
702 WarningLog(<< "problem parsing MessageIntegrity");
703 return false;
704 }
705 //StackLog(<< "MessageIntegrity = " << mMessageIntegrity.hash);
706 mMessageIntegrityMsgLength = body + attrLen - buf - sizeof(StunMsgHdr);
707 }
708 else
709 {
710 WarningLog(<< "Duplicate MessageIntegrity in message - ignoring.");
711 }
712 break;
713
714 case ErrorCode:
715 if(!mHasErrorCode)
716 {
717 if(attrLen-4 > MAX_ERRORCODE_REASON_BYTES)
718 {
719 WarningLog(<< "ErrorCode reason length=" << attrLen-4 << " is longer than max allowed=" << MAX_ERRORCODE_REASON_BYTES);
720 return false;
721 }
722 mHasErrorCode = true;
723 if (stunParseAtrError(body, attrLen, mErrorCode) == false)
724 {
725 WarningLog(<< "problem parsing ErrorCode");
726 return false;
727 }
728 StackLog(<< "ErrorCode = " << (int(mErrorCode.errorClass) * 100 + int(mErrorCode.number))
729 << " (" << *mErrorCode.reason << ")");
730 }
731 else
732 {
733 WarningLog(<< "Duplicate ErrorCode in message - ignoring.");
734 }
735 break;
736
737 case UnknownAttribute:
738 if(!mHasUnknownAttributes)
739 {
740 mHasUnknownAttributes = true;
741 if (stunParseAtrUnknown(body, attrLen, mUnknownAttributes) == false)
742 {
743 WarningLog(<< "problem parsing UnknownAttribute");
744 return false;
745 }
746 // TODO output
747 }
748 else
749 {
750 WarningLog(<< "Duplicate UnknownAttribute in message - ignoring.");
751 }
752 break;
753
754 case ReflectedFrom: // deprecated
755 if(!mHasReflectedFrom)
756 {
757 mHasReflectedFrom = true;
758 if ( stunParseAtrAddress( body, attrLen, mReflectedFrom ) == false )
759 {
760 WarningLog(<< "problem parsing ReflectedFrom");
761 return false;
762 }
763 StackLog(<< "ReflectedFrom = " << mReflectedFrom);
764 }
765 else
766 {
767 WarningLog(<< "Duplicate ReflectedFrom in message - ignoring.");
768 }
769 break;
770
771 case Realm:
772 if(!mHasRealm)
773 {
774 if(attrLen > MAX_REALM_BYTES)
775 {
776 WarningLog(<< "Realm length=" << attrLen << " is longer than max allowed=" << MAX_REALM_BYTES);
777 return false;
778 }
779 mHasRealm = true;
780 mRealm = new resip::Data(resip::Data::Share, body, attrLen);
781 StackLog(<< "Realm = " << *mRealm);
782 }
783 else
784 {
785 WarningLog(<< "Duplicate Realm in message - ignoring.");
786 }
787 break;
788
789 case Nonce:
790 if(!mHasNonce)
791 {
792 if(attrLen > MAX_NONCE_BYTES)
793 {
794 WarningLog(<< "Nonce length=" << attrLen << " is longer than max allowed=" << MAX_NONCE_BYTES);
795 return false;
796 }
797 mHasNonce = true;
798 mNonce = new resip::Data(resip::Data::Share, body, attrLen);
799 StackLog(<< "Nonce = " << *mNonce);
800 }
801 else
802 {
803 WarningLog(<< "Duplicate Nonce in message - ignoring.");
804 }
805 break;
806
807 case XorMappedAddress_old:
808 case XorMappedAddress:
809 if(!mHasXorMappedAddress)
810 {
811 mHasXorMappedAddress = true;
812 if ( stunParseAtrXorAddress( body, attrLen, mXorMappedAddress ) == false )
813 {
814 WarningLog(<< "problem parsing XorMappedAddress");
815 return false;
816 }
817 StackLog(<< "XorMappedAddress = " << mXorMappedAddress);
818 }
819 else
820 {
821 WarningLog(<< "Duplicate XorMappedAddress in message - ignoring.");
822 }
823 break;
824
825 case Fingerprint:
826 if(!mHasFingerprint)
827 {
828 mHasFingerprint = true;
829 if (stunParseAtrUInt32( body, attrLen, mFingerprint) == false)
830 {
831 WarningLog(<< "problem parsing Fingerprint");
832 return false;
833 }
834 StackLog(<< "Fingerprint = " << mFingerprint);
835 }
836 else
837 {
838 WarningLog(<< "Duplicate Fingerprint in message - ignoring.");
839 }
840 break;
841
842 case Software:
843 if(!mHasSoftware)
844 {
845 if(attrLen > MAX_SOFTWARE_BYTES)
846 {
847 WarningLog(<< "Software length=" << attrLen << " is longer than max allowed=" << MAX_SOFTWARE_BYTES);
848 return false;
849 }
850 mHasSoftware = true;
851 mSoftware = new resip::Data(resip::Data::Share, body, attrLen);
852 StackLog(<< "Software = " << *mSoftware);
853 }
854 else
855 {
856 WarningLog(<< "Duplicate Software in message - ignoring.");
857 }
858 break;
859
860 case AlternateServer:
861 if(!mHasAlternateServer)
862 {
863 mHasAlternateServer = true;
864 if ( stunParseAtrAddress( body, attrLen, mAlternateServer ) == false )
865 {
866 WarningLog(<< "problem parsing AlternateServer");
867 return false;
868 }
869 StackLog(<< "AlternateServer = " << mAlternateServer);
870 }
871 else
872 {
873 WarningLog(<< "Duplicate AlternateServer in message - ignoring.");
874 }
875 break;
876
877 case SecondaryAddress:
878 if(!mHasSecondaryAddress)
879 {
880 mHasSecondaryAddress = true;
881 if ( stunParseAtrAddress( body, attrLen, mSecondaryAddress ) == false )
882 {
883 WarningLog(<< "problem parsing secondaryAddress");
884 return false;
885 }
886 StackLog(<< "SecondaryAddress = " << mSecondaryAddress);
887 }
888 else
889 {
890 WarningLog(<< "Duplicate SecondaryAddress in message - ignoring.");
891 }
892 break;
893
894 // TURN attributes
895
896 case TurnChannelNumber:
897 if(!mHasTurnChannelNumber)
898 {
899 UInt32 channelNumber;
900 mHasTurnChannelNumber = true;
901 if(stunParseAtrUInt32( body, attrLen, channelNumber) == false)
902 {
903 WarningLog(<< "problem parsing channel number");
904 return false;
905 }
906 mTurnChannelNumber = (channelNumber & 0xFFFF0000) >> 16;
907 StackLog(<< "Turn ChannelNumber = " << mTurnChannelNumber);
908 }
909 else
910 {
911 WarningLog(<< "Duplicate TurnChannelNumber in message - ignoring.");
912 }
913 break;
914
915 case TurnLifetime:
916 if(!mHasTurnLifetime)
917 {
918 mHasTurnLifetime = true;
919 if (stunParseAtrUInt32( body, attrLen, mTurnLifetime) == false)
920 {
921 WarningLog(<< "problem parsing turn lifetime");
922 return false;
923 }
924 StackLog(<< "Turn Lifetime = " << mTurnLifetime);
925 }
926 else
927 {
928 WarningLog(<< "Duplicate TurnLifetime in message - ignoring.");
929 }
930 break;
931
932 case TurnBandwidth:
933 if(!mHasTurnBandwidth)
934 {
935 mHasTurnBandwidth = true;
936 if (stunParseAtrUInt32( body, attrLen, mTurnBandwidth) == false)
937 {
938 WarningLog(<< "problem parsing turn bandwidth");
939 return false;
940 }
941 StackLog(<< "Turn Bandwidth = " << mTurnBandwidth);
942 }
943 else
944 {
945 WarningLog(<< "Duplicate TurnBandwidth in message - ignoring.");
946 }
947 break;
948
949 case TurnXorPeerAddress:
950 if(mCntTurnXorPeerAddress < TURN_MAX_XOR_PEER_ADDR)
951 {
952 if ( stunParseAtrXorAddress( body, attrLen, mTurnXorPeerAddress[mCntTurnXorPeerAddress]) == false )
953 {
954 WarningLog(<< "problem parsing turn peer address");
955 return false;
956 }
957 StackLog(<< "Turn Peer Address = " << mTurnXorPeerAddress[mCntTurnXorPeerAddress]);
958 mCntTurnXorPeerAddress++;
959 }
960 else
961 {
962 WarningLog(<< "Duplicate TurnXorPeerAddress in message - ignoring.");
963 }
964 break;
965
966 //overlay on parse, ownership is buffer parsed from
967 case TurnData:
968 if(!mHasTurnData)
969 {
970 mHasTurnData = true;
971 mTurnData = new resip::Data(resip::Data::Share, body, attrLen);
972 }
973 else
974 {
975 WarningLog(<< "Duplicate TurnData in message - ignoring.");
976 }
977 break;
978
979 case TurnXorRelayedAddress:
980 if(!mHasTurnXorRelayedAddress)
981 {
982 mHasTurnXorRelayedAddress = true;
983 if ( stunParseAtrXorAddress( body, attrLen, mTurnXorRelayedAddress ) == false )
984 {
985 WarningLog(<< "problem parsing turn relay address");
986 return false;
987 }
988 StackLog(<< "Turn Relayed Address = " << mTurnXorRelayedAddress);
989 }
990 else
991 {
992 WarningLog(<< "Duplicate TurnXorRelayedAddress in message - ignoring.");
993 }
994 break;
995
996 case TurnEvenPort:
997 if(!mHasTurnEvenPort)
998 {
999 mHasTurnEvenPort = true;
1000 if (stunParseAtrEvenPort( body, attrLen, mTurnEvenPort) == false)
1001 {
1002 WarningLog(<< "problem parsing turn even port");
1003 return false;
1004 }
1005 StackLog(<< "Turn Even Port = " << (int)mTurnEvenPort.propType);
1006 }
1007 else
1008 {
1009 WarningLog(<< "Duplicate TurnEvenPort in message - ignoring.");
1010 }
1011 break;
1012
1013 case TurnRequestedTransport:
1014 if(!mHasTurnRequestedTransport)
1015 {
1016 mHasTurnRequestedTransport = true;
1017 UInt32 requestedTransport;
1018 if (stunParseAtrUInt32( body, attrLen, requestedTransport) == false)
1019 {
1020 WarningLog(<< "problem parsing turn requested transport");
1021 return false;
1022 }
1023 mTurnRequestedTransport = requestedTransport >> 24;
1024 StackLog(<< "Turn Requested Transport = " << (int)mTurnRequestedTransport);
1025 }
1026 else
1027 {
1028 WarningLog(<< "Duplicate TurnRequestedTransport in message - ignoring.");
1029 }
1030 break;
1031
1032 case TurnDontFragment:
1033 if(!mHasTurnDontFragment)
1034 {
1035 mHasTurnDontFragment = true;
1036 if(attrLen != 0)
1037 {
1038 WarningLog(<< "invalid attribute length for DontFragment attribute");
1039 return false;
1040 }
1041 StackLog(<< "Turn Dont Fragement = <exists>");
1042 }
1043 else
1044 {
1045 WarningLog(<< "Duplicate TurnDontFragment in message - ignoring.");
1046 }
1047 break;
1048
1049 case TurnReservationToken:
1050 if(!mHasTurnReservationToken)
1051 {
1052 mHasTurnReservationToken = true;
1053 if ( stunParseAtrUInt64( body, attrLen, mTurnReservationToken ) == false )
1054 {
1055 WarningLog(<< "problem parsing turn reservation token");
1056 return false;
1057 }
1058 StackLog(<< "Turn Reservation Token = " << mTurnReservationToken);
1059 }
1060 else
1061 {
1062 WarningLog(<< "Duplicate TurnReservationToken in message - ignoring.");
1063 }
1064 break;
1065
1066 case TurnConnectStat:
1067 if(!mHasTurnConnectStat)
1068 {
1069 mHasTurnConnectStat = true;
1070 if (stunParseAtrUInt32( body, attrLen, mTurnConnectStat) == false)
1071 {
1072 WarningLog(<< "problem parsing turn connect stat");
1073 return false;
1074 }
1075 StackLog(<< "Turn Connect Stat = " << mTurnConnectStat);
1076 }
1077 else
1078 {
1079 WarningLog(<< "Duplicate TurnConnectStat in message - ignoring.");
1080 }
1081 break;
1082
1083 // ICE attributes
1084 case IcePriority:
1085 if(!mHasIcePriority)
1086 {
1087 mHasIcePriority = true;
1088 if (stunParseAtrUInt32( body, attrLen, mIcePriority) == false)
1089 {
1090 WarningLog(<< "problem parsing ICE priority");
1091 return false;
1092 }
1093 StackLog(<< "Ice Priority = " << mIcePriority);
1094 }
1095 else
1096 {
1097 WarningLog(<< "Duplicate IcePriority in message - ignoring.");
1098 }
1099 break;
1100
1101 case IceUseCandidate:
1102 if(!mHasIceUseCandidate)
1103 {
1104 mHasIceUseCandidate = true;
1105 if(attrLen != 0)
1106 {
1107 WarningLog(<< "invalid attribute length for IceUseCandidate attribute");
1108 return false;
1109 }
1110 StackLog(<< "Ice UseCandidate = <exists>");
1111 }
1112 else
1113 {
1114 WarningLog(<< "Duplicate IceUseCandidate in message - ignoring.");
1115 }
1116 break;
1117
1118 case IceControlled:
1119 if(!mHasIceControlled)
1120 {
1121 mHasIceControlled = true;
1122 if (stunParseAtrUInt64( body, attrLen, mIceControlledTieBreaker) == false)
1123 {
1124 WarningLog(<< "problem parsing ICE controlled");
1125 return false;
1126 }
1127 StackLog(<< "Ice controlled = " << mIceControlledTieBreaker);
1128 }
1129 else
1130 {
1131 WarningLog(<< "Duplicate IceControlled in message - ignoring.");
1132 }
1133 break;
1134
1135 case IceControlling:
1136 if(!mHasIceControlling)
1137 {
1138 mHasIceControlling = true;
1139 if (stunParseAtrUInt64( body, attrLen, mIceControllingTieBreaker) == false)
1140 {
1141 WarningLog(<< "problem parsing ICE controlling");
1142 return false;
1143 }
1144 StackLog(<< "Ice controlling = " << mIceControllingTieBreaker);
1145 }
1146 else
1147 {
1148 WarningLog(<< "Duplicate IceControlling in message - ignoring.");
1149 }
1150 break;
1151
1152 default:
1153 if ( atrType <= 0x7FFF )
1154 {
1155 if(mUnknownRequiredAttributes.numAttributes < STUN_MAX_UNKNOWN_ATTRIBUTES)
1156 {
1157 mUnknownRequiredAttributes.attrType[mUnknownRequiredAttributes.numAttributes++] = atrType;
1158 }
1159 WarningLog(<< "Unknown comprehension required attribute: " << atrType);
1160 }
1161 else
1162 {
1163 InfoLog(<< "Ignoring unknown comprehension optional attribute: " << atrType);
1164 }
1165 }
1166
1167 body += attrLen+attrLenPad;
1168 size -= attrLen+attrLenPad;
1169 }
1170
1171 return true;
1172 }
1173
1174 EncodeStream&
1175 operator<< ( EncodeStream& strm, const UInt128& r )
1176 {
1177 strm << int(r.longpart[0]);
1178 for ( int i=1; i<4; i++ )
1179 {
1180 strm << ':' << int(r.longpart[i]);
1181 }
1182
1183 return strm;
1184 }
1185
1186 EncodeStream&
1187 operator<<( EncodeStream& strm, const StunMessage::StunAtrAddress& addr)
1188 {
1189 if(addr.family == StunMessage::IPv6Family)
1190 {
1191 asio::ip::address_v6::bytes_type bytes;
1192 memcpy(bytes.data(), &addr.addr.ipv6, bytes.size());
1193 asio::ip::address_v6 addrv6(bytes);
1194
1195 strm << "[" << addrv6.to_string() << "]:" << addr.port;
1196 }
1197 else
1198 {
1199 UInt32 ip = addr.addr.ipv4;
1200 strm << ((int)(ip>>24)&0xFF) << ".";
1201 strm << ((int)(ip>>16)&0xFF) << ".";
1202 strm << ((int)(ip>> 8)&0xFF) << ".";
1203 strm << ((int)(ip>> 0)&0xFF) ;
1204
1205 strm << ":" << addr.port;
1206 }
1207
1208 return strm;
1209 }
1210
1211 EncodeStream&
1212 operator<<(EncodeStream& os, const StunMessage::StunMsgHdr& h)
1213 {
1214 os << "STUN ";
1215 bool outputMethod=true;
1216
1217 switch(h.msgType & 0x0110)
1218 {
1219 case StunMessage::StunClassRequest:
1220 os << "Request: ";
1221 break;
1222 case StunMessage::StunClassIndication:
1223 os << "Indication: ";
1224 outputMethod = false;
1225 switch (h.msgType & 0x000F)
1226 {
1227 case StunMessage::TurnSendMethod:
1228 os << "Send";
1229 break;
1230 case StunMessage::TurnDataMethod:
1231 os << "Data";
1232 break;
1233 default:
1234 os << "Unknown ind method (" << int(h.msgType & 0x000F) << ")";
1235 break;
1236 }
1237 break;
1238 case StunMessage::StunClassSuccessResponse:
1239 os << "Success Response: ";
1240 break;
1241 case StunMessage::StunClassErrorResponse:
1242 os << "Error Response: ";
1243 break;
1244 default:
1245 os << "Unknown class (" << int(h.msgType & 0x0110) << "): ";
1246 }
1247
1248 if(outputMethod)
1249 {
1250 switch (h.msgType & 0x000F)
1251 {
1252 case StunMessage::BindMethod:
1253 os << "Bind";
1254 break;
1255 case StunMessage::SharedSecretMethod:
1256 os << "SharedSecret";
1257 break;
1258 case StunMessage::TurnAllocateMethod:
1259 os << "Allocate";
1260 break;
1261 case StunMessage::TurnRefreshMethod:
1262 os << "Refresh";
1263 break;
1264 case StunMessage::TurnCreatePermissionMethod:
1265 os << "CreatePermission";
1266 break;
1267 case StunMessage::TurnChannelBindMethod:
1268 os << "ChannelBind";
1269 break;
1270 default:
1271 os << "Unknown method (" << int(h.msgType & 0x000F) << ")";
1272 break;
1273 }
1274 }
1275
1276 os << ", id ";
1277
1278 os << std::hex;
1279 for (unsigned int i = 0; i < 4; i++) {
1280 os << static_cast<int>(h.magicCookieAndTid.longpart[i]);
1281 }
1282 os << std::dec;
1283
1284 return os;
1285 }
1286
1287 char*
1288 StunMessage::encode16(char* buf, UInt16 data)
1289 {
1290 UInt16 ndata = htons(data);
1291 memcpy(buf, reinterpret_cast<void*>(&ndata), sizeof(UInt16));
1292 return buf + sizeof(UInt16);
1293 }
1294
1295 char*
1296 StunMessage::encode32(char* buf, UInt32 data)
1297 {
1298 UInt32 ndata = htonl(data);
1299 memcpy(buf, reinterpret_cast<void*>(&ndata), sizeof(UInt32));
1300 return buf + sizeof(UInt32);
1301 }
1302
1303 char*
1304 StunMessage::encode64(char* buf, const UInt64 data)
1305 {
1306 UInt64 ndata = hton64(data);
1307 memcpy(buf, reinterpret_cast<void*>(&ndata), sizeof(UInt64));
1308 return buf + sizeof(UInt64);
1309 }
1310
1311 char*
1312 StunMessage::encode(char* buf, const char* data, unsigned int length)
1313 {
1314 memcpy(buf, data, length);
1315 return buf + length;
1316 }
1317
1318 char*
1319 StunMessage::encodeTurnData(char *ptr, const resip::Data* td)
1320 {
1321 UInt16 padsize = (UInt16)td->size() % 4 == 0 ? 0 : 4 - ((UInt16)td->size() % 4);
1322
1323 ptr = encode16(ptr, TurnData);
1324 ptr = encode16(ptr, (UInt16)td->size());
1325 memcpy(ptr, td->data(), td->size());
1326 ptr += td->size();
1327 memset(ptr, 0, padsize); // zero out padded data (note: this is not required by the RFC)
1328 return ptr+padsize;
1329 }
1330
1331 char*
1332 StunMessage::encodeAtrUInt32(char* ptr, UInt16 type, UInt32 value)
1333 {
1334 ptr = encode16(ptr, type);
1335 ptr = encode16(ptr, 4);
1336 ptr = encode32(ptr, value);
1337 return ptr;
1338 }
1339
1340 char*
1341 StunMessage::encodeAtrUInt64(char* ptr, UInt16 type, UInt64 value)
1342 {
1343 ptr = encode16(ptr, type);
1344 ptr = encode16(ptr, 8);
1345 ptr = encode64(ptr, value);
1346 return ptr;
1347 }
1348
1349 char*
1350 StunMessage::encodeAtrXorAddress(char* ptr, UInt16 type, const StunAtrAddress& atr)
1351 {
1352 StunAtrAddress xorAtr;
1353 applyXorToAddress(atr, xorAtr);
1354 return encodeAtrAddress(ptr, type, xorAtr);
1355 }
1356
1357 char*
1358 StunMessage::encodeAtrAddress(char* ptr, UInt16 type, const StunAtrAddress& atr)
1359 {
1360 ptr = encode16(ptr, type);
1361 ptr = encode16(ptr, atr.family == IPv6Family ? 20 : 8);
1362 *ptr++ = (UInt8)0; // pad
1363 *ptr++ = atr.family;
1364 ptr = encode16(ptr, atr.port);
1365 if(atr.family == IPv6Family)
1366 {
1367 // Note: addr.ipv6 is stored in network byte order
1368 memcpy(ptr, &atr.addr.ipv6, sizeof(atr.addr.ipv6));
1369 ptr += sizeof(atr.addr.ipv6);
1370 }
1371 else
1372 {
1373 // Note: addr.ipv4 is stored in host byte order - encode32 will conver to network byte order
1374 ptr = encode32(ptr, atr.addr.ipv4);
1375 }
1376
1377 return ptr;
1378 }
1379
1380 char*
1381 StunMessage::encodeAtrError(char* ptr, const StunAtrError& atr)
1382 {
1383 assert(atr.reason);
1384 UInt16 padsize = (unsigned int)atr.reason->size() % 4 == 0 ? 0 : 4 - ((unsigned int)atr.reason->size() % 4);
1385
1386 ptr = encode16(ptr, ErrorCode);
1387 ptr = encode16(ptr, 4 + (UInt16)atr.reason->size());
1388 ptr = encode16(ptr, 0); // pad
1389 *ptr++ = atr.errorClass & 0x7; // first 3 bits only
1390 *ptr++ = atr.number;
1391 ptr = encode(ptr, atr.reason->data(), (unsigned int)atr.reason->size());
1392 memset(ptr, 0, padsize);
1393 return ptr+padsize;
1394 }
1395
1396 char*
1397 StunMessage::encodeAtrUnknown(char* ptr, const StunAtrUnknown& atr)
1398 {
1399 UInt16 padsize = (2*atr.numAttributes) % 4 == 0 ? 0 : 4 - ((2*atr.numAttributes) % 4);
1400 ptr = encode16(ptr, UnknownAttribute);
1401 ptr = encode16(ptr, 2*atr.numAttributes);
1402 for (int i=0; i<atr.numAttributes; i++)
1403 {
1404 ptr = encode16(ptr, atr.attrType[i]);
1405 }
1406 return ptr+padsize;
1407 }
1408
1409 char*
1410 StunMessage::encodeAtrString(char* ptr, UInt16 type, const Data* atr, UInt16 maxBytes)
1411 {
1412 assert(atr);
1413 UInt16 size = atr->size() > maxBytes ? maxBytes : (UInt16)atr->size();
1414 UInt16 padsize = size % 4 == 0 ? 0 : 4 - (size % 4);
1415
1416 ptr = encode16(ptr, type);
1417 ptr = encode16(ptr, size);
1418 ptr = encode(ptr, atr->data(), size);
1419 memset(ptr, 0, padsize); // zero out padded data (note: this is not required by the RFC)
1420 return ptr + padsize;
1421 }
1422
1423 char*
1424 StunMessage::encodeAtrIntegrity(char* ptr, const StunAtrIntegrity& atr)
1425 {
1426 ptr = encode16(ptr, MessageIntegrity);
1427 ptr = encode16(ptr, 20);
1428 ptr = encode(ptr, atr.hash, sizeof(atr.hash));
1429 return ptr;
1430 }
1431
1432 char*
1433 StunMessage::encodeAtrEvenPort(char* ptr, const TurnAtrEvenPort& atr)
1434 {
1435 ptr = encode16(ptr, TurnEvenPort);
1436 ptr = encode16(ptr, 1);
1437 *ptr++ = atr.propType;
1438 *ptr++ = 0; // pad
1439 ptr = encode16(ptr, 0); // pad
1440 return ptr;
1441 }
1442
1443 bool
1444 StunMessage::hasMagicCookie()
1445 {
1446 return mHeader.id.magicCookie == htonl(StunMessage::StunMagicCookie);
1447 }
1448
1449 unsigned int
1450 StunMessage::stunEncodeMessage(char* buf, unsigned int bufLen)
1451 {
1452 assert(bufLen >= sizeof(StunMsgHdr));
1453 char* ptr = buf;
1454
1455 mHeader.msgType = mClass | mMethod;
1456
1457 ptr = encode16(ptr, mHeader.msgType);
1458 char* lengthp = ptr;
1459 ptr = encode16(ptr, 0);
1460 ptr = encode(ptr, reinterpret_cast<const char*>(&mHeader.id), sizeof(mHeader.id));
1461
1462 StackLog(<< "Encoding stun message: " << mHeader);
1463
1464 if (mHasMappedAddress)
1465 {
1466 StackLog(<< "Encoding MappedAddress: " << mMappedAddress);
1467 ptr = encodeAtrAddress (ptr, MappedAddress, mMappedAddress);
1468 }
1469 if (mHasResponseAddress)
1470 {
1471 StackLog(<< "Encoding ResponseAddress: " << mResponseAddress);
1472 ptr = encodeAtrAddress(ptr, ResponseAddress, mResponseAddress);
1473 }
1474 if (mHasChangeRequest)
1475 {
1476 StackLog(<< "Encoding ChangeRequest: " << mChangeRequest);
1477 ptr = encodeAtrUInt32(ptr, ChangeRequest, mChangeRequest);
1478 }
1479 if (mHasSourceAddress)
1480 {
1481 StackLog(<< "Encoding SourceAddress: " << mSourceAddress);
1482 ptr = encodeAtrAddress(ptr, SourceAddress, mSourceAddress);
1483 }
1484 if (mHasChangedAddress)
1485 {
1486 StackLog(<< "Encoding ChangedAddress: " << mChangedAddress);
1487 ptr = encodeAtrAddress(ptr, ChangedAddress, mChangedAddress);
1488 }
1489 if (mHasUsername)
1490 {
1491 StackLog(<< "Encoding Username: " << *mUsername);
1492 ptr = encodeAtrString(ptr, Username, mUsername, MAX_USERNAME_BYTES);
1493 }
1494 if (mHasPassword)
1495 {
1496 StackLog(<< "Encoding Password: " << *mPassword);
1497 ptr = encodeAtrString(ptr, Password, mPassword, MAX_PASSWORD_BYTES);
1498 }
1499 if (mHasErrorCode)
1500 {
1501 StackLog(<< "Encoding ErrorCode: "
1502 << int(mErrorCode.errorClass)
1503 << " number=" << int(mErrorCode.number)
1504 << " reason="
1505 << *mErrorCode.reason);
1506
1507 ptr = encodeAtrError(ptr, mErrorCode);
1508 }
1509 if (mHasUnknownAttributes)
1510 {
1511 StackLog(<< "Encoding UnknownAttribute: ???");
1512 ptr = encodeAtrUnknown(ptr, mUnknownAttributes);
1513 }
1514 if (mHasReflectedFrom)
1515 {
1516 StackLog(<< "Encoding ReflectedFrom: " << mReflectedFrom);
1517 ptr = encodeAtrAddress(ptr, ReflectedFrom, mReflectedFrom);
1518 }
1519 if (mHasRealm)
1520 {
1521 StackLog(<< "Encoding Realm: " << *mRealm);
1522 ptr = encodeAtrString(ptr, Realm, mRealm, MAX_REALM_BYTES);
1523 }
1524 if (mHasNonce)
1525 {
1526 StackLog(<< "Encoding Nonce: " << *mNonce);
1527 ptr = encodeAtrString(ptr, Nonce, mNonce, MAX_NONCE_BYTES);
1528 }
1529 if (mHasXorMappedAddress)
1530 {
1531 StackLog(<< "Encoding XorMappedAddress: " << mXorMappedAddress);
1532 ptr = encodeAtrXorAddress(ptr, XorMappedAddress, mXorMappedAddress);
1533 }
1534 if (mHasSoftware)
1535 {
1536 StackLog(<< "Encoding Software: " << *mSoftware);
1537 ptr = encodeAtrString(ptr, Software, mSoftware, MAX_SOFTWARE_BYTES);
1538 }
1539 if (mHasAlternateServer)
1540 {
1541 StackLog(<< "Encoding Alternate Server: " << mAlternateServer);
1542 ptr = encodeAtrAddress(ptr, AlternateServer, mAlternateServer);
1543 }
1544 if (mHasSecondaryAddress)
1545 {
1546 StackLog(<< "Encoding SecondaryAddress: " << mSecondaryAddress);
1547 ptr = encodeAtrAddress(ptr, SecondaryAddress, mSecondaryAddress);
1548 }
1549
1550 if (mHasTurnChannelNumber)
1551 {
1552 StackLog(<< "Encoding Turn ChannelNumber: " << mTurnChannelNumber);
1553 ptr = encodeAtrUInt32(ptr, TurnChannelNumber, UInt32(mTurnChannelNumber << 16));
1554 }
1555 if (mHasTurnLifetime)
1556 {
1557 StackLog(<< "Encoding Turn Lifetime: " << mTurnLifetime);
1558 ptr = encodeAtrUInt32(ptr, TurnLifetime, mTurnLifetime);
1559 }
1560 if (mHasTurnBandwidth)
1561 {
1562 StackLog(<< "Encoding Turn Bandwidth: " << mTurnBandwidth);
1563 ptr = encodeAtrUInt32(ptr, TurnBandwidth, mTurnBandwidth);
1564 }
1565 if (mCntTurnXorPeerAddress > 0)
1566 {
1567 for (int i = 0; i < mCntTurnXorPeerAddress; i++)
1568 {
1569 StackLog(<< "Encoding Turn XorPeerAddress: " << mTurnXorPeerAddress[i]);
1570 ptr = encodeAtrXorAddress (ptr, TurnXorPeerAddress, mTurnXorPeerAddress[i]);
1571 }
1572 }
1573 if (mHasTurnData)
1574 {
1575 StackLog(<< "Encoding TurnData (not shown)");
1576 ptr = encodeTurnData (ptr, mTurnData);
1577 }
1578 if (mHasTurnXorRelayedAddress)
1579 {
1580 StackLog(<< "Encoding Turn XorRelayedAddress: " << mTurnXorRelayedAddress);
1581 ptr = encodeAtrXorAddress (ptr, TurnXorRelayedAddress, mTurnXorRelayedAddress);
1582 }
1583 if (mHasTurnEvenPort)
1584 {
1585 StackLog(<< "Encoding Turn EvenPort: " << (int)mTurnEvenPort.propType);
1586 ptr = encodeAtrEvenPort(ptr, mTurnEvenPort);
1587 }
1588 if (mHasTurnRequestedTransport)
1589 {
1590 StackLog(<< "Encoding Turn RequestedTransport: " << (int)mTurnRequestedTransport);
1591 ptr = encodeAtrUInt32(ptr, TurnRequestedTransport, UInt32(mTurnRequestedTransport << 24));
1592 }
1593 if (mHasTurnDontFragment)
1594 {
1595 StackLog(<< "Encoding Turn DontFragment: <exists>");
1596 ptr = encode16(ptr, TurnDontFragment);
1597 ptr = encode16(ptr, 0); // 0 attribute length
1598 }
1599 if (mHasTurnReservationToken)
1600 {
1601 StackLog(<< "Encoding Turn ReservationToken: " << mTurnReservationToken);
1602 ptr = encodeAtrUInt64 (ptr, TurnReservationToken, mTurnReservationToken);
1603 }
1604 if (mHasTurnConnectStat)
1605 {
1606 StackLog(<< "Encoding Turn Connect Stat: " << mTurnConnectStat);
1607 ptr = encodeAtrUInt32(ptr, TurnConnectStat, mTurnConnectStat);
1608 }
1609 if (mHasTurnRequestedAddressFamily)
1610 {
1611 StackLog(<< "Encoding Turn RequestedAddressFamily: " << mTurnRequestedAddressFamily);
1612 ptr = encodeAtrUInt32(ptr, TurnRequestedAddressFamily, UInt32(mTurnRequestedAddressFamily << 16));
1613 }
1614 if (mHasIcePriority)
1615 {
1616 StackLog(<< "Encoding ICE Priority: " << mIcePriority);
1617 ptr = encodeAtrUInt32(ptr, IcePriority, mIcePriority);
1618 }
1619 if (mHasIceUseCandidate)
1620 {
1621 StackLog(<< "Encoding ICE UseCandidate: <exists>");
1622 ptr = encode16(ptr, IceUseCandidate);
1623 ptr = encode16(ptr, 0); // 0 attribute length
1624 }
1625 if (mHasIceControlled)
1626 {
1627 StackLog(<< "Encoding ICE Controlled: " << mIceControlledTieBreaker);
1628 ptr = encodeAtrUInt64(ptr, IceControlled, mIceControlledTieBreaker);
1629 }
1630 if (mHasIceControlling)
1631 {
1632 StackLog(<< "Encoding ICE Controlling: " << mIceControllingTieBreaker);
1633 ptr = encodeAtrUInt64(ptr, IceControlling, mIceControllingTieBreaker);
1634 }
1635
1636 // Update Length in header now - needed in message integrity calculations
1637 UInt16 msgSize = ptr - buf - sizeof(StunMsgHdr);
1638 if(mHasMessageIntegrity) msgSize += 24; // 4 (attribute header) + 20 (attribute value)
1639 encode16(lengthp, msgSize);
1640
1641 if (mHasMessageIntegrity)
1642 {
1643 int len = ptr - buf;
1644 StackLog(<< "Adding message integrity: buffer size=" << len << ", hmacKey=" << mHmacKey.hex());
1645 StunAtrIntegrity integrity;
1646 computeHmac(integrity.hash, buf, len, mHmacKey.c_str(), (int)mHmacKey.size());
1647 ptr = encodeAtrIntegrity(ptr, integrity);
1648 }
1649
1650 // Update Length in header now - may be needed in fingerprint calculations
1651 if(mHasFingerprint) msgSize += 8; // 4 (attribute header) + 4 (attribute value)
1652 encode16(lengthp, msgSize);
1653
1654 // add finger print if required
1655 if (mHasFingerprint)
1656 {
1657 StackLog(<< "Calculating fingerprint for data of size " << ptr-buf);
1658 boost::crc_32_type stun_crc;
1659 stun_crc.process_bytes(buf, ptr-buf); // Calculate CRC across entire message, except the fingerprint attribute
1660 UInt32 fingerprint = stun_crc.checksum() ^ STUN_CRC_FINAL_XOR;
1661 ptr = encodeAtrUInt32(ptr, Fingerprint, fingerprint);
1662 }
1663
1664 return int(ptr - buf);
1665 }
1666
1667 unsigned int
1668 StunMessage::stunEncodeFramedMessage(char* buf, unsigned int bufLen)
1669 {
1670 unsigned short size = (unsigned short)stunEncodeMessage(&buf[4], bufLen-4);
1671
1672 // Add Frame Header info
1673 buf[0] = 0; // Channel 0 for Stun Messages
1674 buf[1] = 0;
1675 UInt16 frameSize = htons(size);
1676 memcpy(&buf[2], (void*)&frameSize, 2); // size is not needed if udp - but should be harmless
1677 return size+4;
1678 }
1679
1680 #ifndef USE_SSL
1681 void
1682 StunMessage::computeHmac(char* hmac, const char* input, int length, const char* key, int sizeKey)
1683 {
1684 // !slg! TODO - use newly added rutil/SHA1.hxx class - will need to add new method to it to support this
1685 strncpy(hmac,"hmac-not-implemented",20);
1686 }
1687 #else
1688 void
1689 StunMessage::computeHmac(char* hmac, const char* input, int length, const char* key, int sizeKey)
1690 {
1691 //StackLog(<< "***computeHmac: input='" << Data(input, length).hex() << "', length=" << length << ", key='" << Data(key, sizeKey).hex() << "', keySize=" << sizeKey);
1692
1693 unsigned int resultSize=20;
1694 HMAC(EVP_sha1(),
1695 key, sizeKey,
1696 reinterpret_cast<const unsigned char*>(input), length,
1697 reinterpret_cast<unsigned char*>(hmac), &resultSize);
1698 assert(resultSize == 20);
1699 }
1700 #endif
1701
1702 void
1703 StunMessage::createUsernameAndPassword()
1704 {
1705 UInt64 time = resip::Timer::getTimeSecs();
1706 time -= (time % 20*60); // rounded time - current time modulo 20 minutes
1707 //UInt64 hitime = time >> 32;
1708 //UInt64 lotime = time & 0xFFFFFFFF;
1709
1710 mHasUsername = true;
1711 if(!mUsername)
1712 {
1713 mUsername = new Data;
1714 }
1715 assert(mUsername);
1716
1717 if(mRemoteTuple.getAddress().is_v6())
1718 {
1719 *mUsername = Data(mRemoteTuple.getAddress().to_v6().to_bytes().data(), mRemoteTuple.getAddress().to_v6().to_bytes().size()).base64encode() + ":";
1720 }
1721 else
1722 {
1723 *mUsername = Data(mRemoteTuple.getAddress().to_v4().to_bytes().data(), mRemoteTuple.getAddress().to_v4().to_bytes().size()).base64encode() + ":";
1724 }
1725 unsigned int port = mRemoteTuple.getPort();
1726 *mUsername += Data((char*)&port, sizeof(unsigned int)).base64encode() + ":";
1727 *mUsername += resip::Random::getCryptoRandomHex(8) + ":"; // 8 bytes, 64 bits of randomness
1728 *mUsername += Data((char*)&time, sizeof(time)).hex() + ":";
1729 char hmac[20];
1730 computeHmac(hmac, mUsername->data(), (int)mUsername->size(), USERNAME_KEY.data(), (int)USERNAME_KEY.size());
1731 *mUsername += Data(hmac, sizeof(hmac)).hex();
1732
1733 assert( mUsername->size()%4 == 0 );
1734
1735 StackLog(<< "computed username=" << *mUsername);
1736
1737 // Compute Password
1738 mHasPassword = true;
1739
1740 if(!mPassword)
1741 {
1742 mPassword = new Data;
1743 }
1744 assert(mPassword);
1745 generateShortTermPasswordForUsername(*mPassword);
1746
1747 StackLog(<< "computed password=" << *mPassword);
1748 }
1749
1750 void
1751 StunMessage::generateShortTermPasswordForUsername(Data& password)
1752 {
1753 char hmac[20];
1754 assert(mHasUsername && mUsername);
1755 computeHmac(hmac, mUsername->data(), (int)mUsername->size(), PASSWORD_KEY.data(), (int)PASSWORD_KEY.size());
1756 password = Data(hmac, sizeof(hmac)).hex();
1757 }
1758
1759 void
1760 StunMessage::getTupleFromUsername(StunTuple& tuple)
1761 {
1762 assert(mHasUsername);
1763 assert(mUsername && mUsername->size() >= 92);
1764 assert(mUsername->size() == 92 || mUsername->size() == 108);
1765
1766 if(mUsername->size() > 92) // if over a certain size, then contains IPv6 address
1767 {
1768 Data addressPart(Data::Share, mUsername->data(), 24);
1769 addressPart = addressPart.base64decode();
1770 asio::ip::address_v6::bytes_type bytes;
1771 memcpy(bytes.data(), addressPart.data(), bytes.size());
1772 asio::ip::address_v6 addressv6(bytes);
1773 tuple.setAddress(addressv6);
1774
1775 unsigned int port;
1776 Data portPart(Data::Share, mUsername->data()+25, 4);
1777 portPart = portPart.base64decode();
1778 memcpy(&port, portPart.data(), sizeof(port));
1779 tuple.setPort(port);
1780 }
1781 else
1782 {
1783 Data addressPart(Data::Share, mUsername->data(), 8);
1784 addressPart = addressPart.base64decode();
1785 asio::ip::address_v4::bytes_type bytes;
1786 memcpy(bytes.data(), addressPart.data(), bytes.size());
1787 asio::ip::address_v4 addressv4(bytes);
1788 tuple.setAddress(addressv4);
1789
1790 unsigned int port;
1791 Data portPart(Data::Share, mUsername->data()+9, 4);
1792 portPart = portPart.base64decode();
1793 memcpy(&port, portPart.data(), sizeof(port));
1794 tuple.setPort(port);
1795 }
1796 }
1797
1798 void
1799 StunMessage::calculateHmacKey(Data& hmacKey, const Data& longtermAuthenticationPassword)
1800 {
1801 assert(mHasUsername);
1802
1803 if(mHasRealm) // Longterm authenicationmode
1804 {
1805 calculateHmacKey(hmacKey, *mUsername, *mRealm, longtermAuthenticationPassword);
1806 }
1807 else
1808 {
1809 generateShortTermPasswordForUsername(hmacKey);
1810 }
1811 }
1812
1813 void
1814 StunMessage::calculateHmacKeyForHa1(Data& hmacKey, const Data& ha1)
1815 {
1816 assert(mHasUsername);
1817
1818 if(mHasRealm) // Longterm authenicationmode
1819 {
1820 hmacKey = ha1;
1821 }
1822 else
1823 {
1824 generateShortTermPasswordForUsername(hmacKey);
1825 }
1826 }
1827
1828 void
1829 StunMessage::calculateHmacKey(Data& hmacKey, const Data& username, const Data& realm, const Data& longtermAuthenticationPassword)
1830 {
1831 MD5Stream r;
1832 r << username << ":" << realm << ":" << longtermAuthenticationPassword;
1833 hmacKey = r.getBin();
1834
1835 StackLog(<< "calculateHmacKey: '" << username << ":" << realm << ":" << longtermAuthenticationPassword << "' = '" << hmacKey.hex() << "'");
1836 }
1837
1838 bool
1839 StunMessage::checkMessageIntegrity(const Data& hmacKey)
1840 {
1841 if(mHasMessageIntegrity)
1842 {
1843 unsigned char hmac[20];
1844
1845 // Store original stun message length from mBuffer
1846 char *lengthposition = (char*)mBuffer.data() + 2;
1847 UInt16 originalLength;
1848 memcpy(&originalLength, lengthposition, 2);
1849
1850 // Update stun message length in mBuffer for calculation
1851 UInt16 tempLength = htons(mMessageIntegrityMsgLength);
1852 memcpy(lengthposition, &tempLength, 2);
1853
1854 // Calculate HMAC
1855 int iHMACBufferSize = mMessageIntegrityMsgLength - 24 /* MessageIntegrity size */ + sizeof(StunMsgHdr); // The entire message proceeding the message integrity attribute
1856 StackLog(<< "Checking message integrity: length=" << mMessageIntegrityMsgLength << ", size=" << iHMACBufferSize << ", hmacKey=" << hmacKey.hex());
1857 computeHmac((char*)hmac, mBuffer.data(), iHMACBufferSize, hmacKey.c_str(), hmacKey.size());
1858
1859 // Restore original stun message length in mBuffer
1860 memcpy(lengthposition, &originalLength, 2);
1861
1862 if (memcmp(mMessageIntegrity.hash, hmac, 20) == 0)
1863 {
1864 return true;
1865 }
1866 else
1867 {
1868 return false;
1869 }
1870 }
1871 else
1872 {
1873 // No message integrity attribute present - return true
1874 return true;
1875 }
1876 }
1877
1878 bool
1879 StunMessage::checkFingerprint()
1880 {
1881 if(mHasFingerprint)
1882 {
1883 StackLog(<< "Calculating fingerprint to check for data of size " << mBuffer.size() - 8);
1884 boost::crc_32_type stun_crc;
1885 stun_crc.process_bytes(mBuffer.data(), mBuffer.size()-8); // Calculate CRC across entire message, except the fingerprint attribute
1886
1887 unsigned long crc = stun_crc.checksum() ^ STUN_CRC_FINAL_XOR;
1888 if(crc == mFingerprint)
1889 {
1890 return true;
1891 }
1892 else
1893 {
1894 WarningLog(<< "Fingerprint=" << mFingerprint << " does not match CRC=" << stun_crc.checksum());
1895 return false;
1896 }
1897 }
1898 return true;
1899 }
1900
1901 }
1902
1903
1904 /* ====================================================================
1905
1906 Copyright (c) 2007-2008, Plantronics, Inc.
1907 All rights reserved.
1908
1909 Redistribution and use in source and binary forms, with or without
1910 modification, are permitted provided that the following conditions are
1911 met:
1912
1913 1. Redistributions of source code must retain the above copyright
1914 notice, this list of conditions and the following disclaimer.
1915
1916 2. Redistributions in binary form must reproduce the above copyright
1917 notice, this list of conditions and the following disclaimer in the
1918 documentation and/or other materials provided with the distribution.
1919
1920 3. Neither the name of Plantronics nor the names of its contributors
1921 may be used to endorse or promote products derived from this
1922 software without specific prior written permission.
1923
1924 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1925 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1926 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1927 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1928 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1929 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
1930 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1931 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1932 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1933 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1934 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1935
1936 ==================================================================== */

Properties

Name Value
svn:eol-style native
svn:mime-type text/plain

webmaster AT resiprocate DOT org
ViewVC Help
Powered by ViewVC 1.1.27