1 /*
2  *
3  * Inter Asterisk Exchange 2
4  *
5  * Implementation of the classes to carry Information Elements
6  *
7  * Open Phone Abstraction Library (OPAL)
8  *
9  * Copyright (c) 2005 Indranet Technologies Ltd.
10  *
11  * The contents of this file are subject to the Mozilla Public License
12  * Version 1.0 (the "License"); you may not use this file except in
13  * compliance with the License. You may obtain a copy of the License at
14  * http://www.mozilla.org/MPL/
15  *
16  * Software distributed under the License is distributed on an "AS IS"
17  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
18  * the License for the specific language governing rights and limitations
19  * under the License.
20  *
21  * The Original Code is Open Phone Abstraction Library.
22  *
23  * The Initial Developer of the Original Code is Indranet Technologies Ltd.
24  *
25  * The author of this code is Derek J Smithies
26  *
27  * $Revision: 25595 $
28  * $Author: rjongbloed $
29  * $Date: 2011-04-18 22:57:14 -0500 (Mon, 18 Apr 2011) $
30  */
31 
32 #include <ptlib.h>
33 #include <opal/buildopts.h>
34 #include <ptclib/random.h>
35 
36 #if OPAL_IAX2
37 
38 #ifdef P_USE_PRAGMA
39 #pragma implementation "ies.h"
40 #endif
41 
42 #include <iax2/ies.h>
43 #include <iax2/frame.h>
44 #include <iax2/causecode.h>
45 
46 #include <ptclib/cypher.h>
47 
48 #define new PNEW
49 
IAX2Ie()50 IAX2Ie::IAX2Ie()
51 {
52   validData = PFalse;
53 }
54 
BuildInformationElement(BYTE _typeCode,BYTE length,BYTE * srcData)55 IAX2Ie * IAX2Ie::BuildInformationElement(BYTE _typeCode, BYTE length, BYTE *srcData)
56 {
57   switch (_typeCode) {
58   case ie_calledNumber    : return new IAX2IeCalledNumber(length, srcData);
59   case ie_callingNumber   : return new IAX2IeCallingNumber(length, srcData);
60   case ie_callingAni      : return new IAX2IeCallingAni(length, srcData);
61   case ie_callingName     : return new IAX2IeCallingName(length, srcData);
62   case ie_calledContext   : return new IAX2IeCalledContext(length, srcData);
63   case ie_userName        : return new IAX2IeUserName(length, srcData);
64   case ie_password        : return new IAX2IePassword(length, srcData);
65   case ie_capability      : return new IAX2IeCapability(length, srcData);
66   case ie_format          : return new IAX2IeFormat(length, srcData);
67   case ie_language        : return new IAX2IeLanguage(length, srcData);
68   case ie_version         : return new IAX2IeVersion(length, srcData);
69   case ie_adsicpe         : return new IAX2IeAdsicpe(length, srcData);
70   case ie_dnid            : return new IAX2IeDnid(length, srcData);
71   case ie_authMethods     : return new IAX2IeAuthMethods(length, srcData);
72   case ie_challenge       : return new IAX2IeChallenge(length, srcData);
73   case ie_md5Result       : return new IAX2IeMd5Result(length, srcData);
74   case ie_rsaResult       : return new IAX2IeRsaResult(length, srcData);
75   case ie_apparentAddr    : return new IAX2IeApparentAddr(length, srcData);
76   case ie_refresh         : return new IAX2IeRefresh(length, srcData);
77   case ie_dpStatus        : return new IAX2IeDpStatus(length, srcData);
78   case ie_callNo          : return new IAX2IeCallNo(length, srcData);
79   case ie_cause           : return new IAX2IeCause(length, srcData);
80   case ie_iaxUnknown      : return new IAX2IeIaxUnknown(length, srcData);
81   case ie_msgCount        : return new IAX2IeMsgCount(length, srcData);
82   case ie_autoAnswer      : return new IAX2IeAutoAnswer(length, srcData);
83   case ie_musicOnHold     : return new IAX2IeMusicOnHold(length, srcData);
84   case ie_transferId      : return new IAX2IeTransferId(length, srcData);
85   case ie_rdnis           : return new IAX2IeRdnis(length, srcData);
86   case ie_provisioning    : return new IAX2IeProvisioning(length, srcData);
87   case ie_aesProvisioning : return new IAX2IeAesProvisioning(length, srcData);
88   case ie_dateTime        : return new IAX2IeDateTime(length, srcData);
89   case ie_deviceType      : return new IAX2IeDeviceType(length, srcData);
90   case ie_serviceIdent    : return new IAX2IeServiceIdent(length, srcData);
91   case ie_firmwareVer     : return new IAX2IeFirmwareVer(length, srcData);
92   case ie_fwBlockDesc     : return new IAX2IeFwBlockDesc(length, srcData);
93   case ie_fwBlockData     : return new IAX2IeFwBlockData(length, srcData);
94   case ie_provVer         : return new IAX2IeProvVer(length, srcData);
95   case ie_callingPres     : return new IAX2IeCallingPres(length, srcData);
96   case ie_callingTon      : return new IAX2IeCallingTon(length, srcData);
97   case ie_callingTns      : return new IAX2IeCallingTns(length, srcData);
98   case ie_samplingRate    : return new IAX2IeSamplingRate(length, srcData);
99   case ie_causeCode       : return new IAX2IeCauseCode(length, srcData);
100   case ie_encryption      : return new IAX2IeEncryption(length, srcData);
101   case ie_encKey          : return new IAX2IeEncKey(length, srcData);
102   case ie_codecPrefs      : return new IAX2IeCodecPrefs(length, srcData);
103   case ie_recJitter       : return new IAX2IeReceivedJitter(length, srcData);
104   case ie_recLoss         : return new IAX2IeReceivedLoss(length, srcData);
105   case ie_recPackets      : return new IAX2IeDroppedFrames(length, srcData);
106   case ie_recDelay        : return new IAX2IeReceivedDelay(length, srcData);
107   case ie_recDropped      : return new IAX2IeDroppedFrames(length, srcData);
108   case ie_recOoo          : return new IAX2IeReceivedOoo(length, srcData);
109   case ie_callToken       : return new IAX2IeCallToken(length, srcData);
110   default: PTRACE(1, "Ie\t Invalid IE type code " << ::hex << ((int)_typeCode) << ::dec);
111   };
112 
113   return new IAX2IeInvalidElement();
114 }
115 
116 
PrintOn(ostream & str) const117 void IAX2Ie::PrintOn(ostream & str) const
118 {
119   if (validData)
120     str << setw(17) << Class() << " information element " ;
121   else
122     str << setw(17) << Class() << " information element-invalid data " ;
123 }
124 
125 
WriteBinary(void * _data,PINDEX & writeIndex)126 void IAX2Ie::WriteBinary(void *_data, PINDEX &writeIndex)
127 {
128   BYTE *data = (BYTE *)_data;
129   data[writeIndex] = GetKeyValue();
130   data[writeIndex + 1] = GetLengthOfData();
131 
132   writeIndex +=2;
133 
134   WriteBinary(data + writeIndex);
135   writeIndex += GetLengthOfData();
136 }
137 
138 ////////////////////////////////////////////////////////////////////////////////
139 
IAX2IeNone(BYTE,BYTE *)140 IAX2IeNone::IAX2IeNone(BYTE /*length*/, BYTE * /*srcData*/)
141 {
142   validData = PTrue;
143 }
144 
145 
PrintOn(ostream & str) const146 void IAX2IeNone::PrintOn(ostream & str) const
147 {
148   str << setw(17) << Class();
149 }
150 
151 ////////////////////////////////////////////////////////////////////////////////
152 
IAX2IeDateAndTime(BYTE length,BYTE * srcData)153 IAX2IeDateAndTime::IAX2IeDateAndTime(BYTE length, BYTE *srcData)
154 {
155   if (length != sizeof(unsigned int)) {
156     validData = PFalse;
157     return;
158   }
159 
160   unsigned int tmp = (srcData[0] << 24) | (srcData[1] << 16) | (srcData[2] << 8) | (srcData[3]);
161   int second = (tmp & 0x1f) << 1;
162   int minute = (tmp >> 5) & 0x3f;
163   int hour   = (tmp >> 11) & 0x1f;
164   int day    = (tmp >> 16) & 0x1f;
165   int month  = (tmp >> 21) & 0x0f;
166   int year   = ((tmp >> 25) & 0x7f) + 2000;
167   dataValue = PTime(second, minute, hour, day, month, year, PTime::Local);
168 
169   validData = PTrue;
170 }
171 
172 
PrintOn(ostream & str) const173 void IAX2IeDateAndTime::PrintOn(ostream & str) const
174 {
175   str << setw(17) << Class() << dataValue;
176 }
177 
WriteBinary(BYTE * data)178 void IAX2IeDateAndTime::WriteBinary(BYTE *data)
179 {
180   unsigned int second = dataValue.GetSecond() >> 1;
181   unsigned int minute = dataValue.GetMinute()        << 5;
182   unsigned int hour   = dataValue.GetHour()          << 11;
183   unsigned int day    = dataValue.GetDay()           << 16;
184   unsigned int month  = dataValue.GetMonth()         << 21;
185   unsigned int year   = ((unsigned int)(dataValue.GetYear() - 2000)) << 25;
186 
187   unsigned int res = second | minute | hour | day | month | year;
188   data[0] = (BYTE)((res >> 24) & 0xff);
189   data[1] = (BYTE)((res >> 16) & 0xff);
190   data[2] = (BYTE)((res >>  8) & 0xff);
191   data[3] = (BYTE)((res      ) & 0xff);
192 }
193 ////////////////////////////////////////////////////////////////////////////////
194 
IAX2IeByte(BYTE length,BYTE * srcData)195 IAX2IeByte::IAX2IeByte(BYTE length, BYTE *srcData)
196   : IAX2Ie()
197 {
198   if (length != sizeof(BYTE)) {
199     validData = PFalse;
200     return;
201   }
202 
203   validData = PTrue;
204   dataValue = *((BYTE *)srcData);
205 }
206 
207 
PrintOn(ostream & str) const208 void IAX2IeByte::PrintOn(ostream & str) const
209 {
210   if (validData)
211     str << setw(17) << Class() << " " << ((int) dataValue);
212   else
213     str << setw(17) << Class() << " does not hold valid data" ;
214 }
215 
216 ////////////////////////////////////////////////////////////////////////////////
IAX2IeChar(BYTE length,BYTE * srcData)217 IAX2IeChar::IAX2IeChar(BYTE length, BYTE *srcData)
218   : IAX2Ie()
219 {
220   if (length != sizeof(BYTE)) {
221     validData = PFalse;
222     return;
223   }
224 
225   validData = PTrue;
226   dataValue = *((char *)srcData);
227 }
228 
229 
PrintOn(ostream & str) const230 void IAX2IeChar::PrintOn(ostream & str) const
231 {
232   if (validData)
233     str << setw(17) << Class() << " " << dataValue;
234   else
235     str << setw(17) << Class() << " does not hold valid data" ;
236 }
237 
238 ////////////////////////////////////////////////////////////////////////////////
239 
IAX2IeUShort(BYTE length,BYTE * srcData)240 IAX2IeUShort::IAX2IeUShort(BYTE length, BYTE *srcData)
241   : IAX2Ie()
242 {
243   if (length != sizeof(unsigned short)) {
244     validData = PFalse;
245     return;
246   }
247 
248   validData = PTrue;
249   dataValue = (unsigned short)((srcData[0] << 8) | srcData[1]);
250 }
251 
252 
PrintOn(ostream & str) const253 void IAX2IeUShort::PrintOn(ostream & str) const
254 {
255   if (validData)
256     str << setw(17) << Class() << " " << dataValue << "UShort";
257   else
258     str << setw(17) << Class() << " does not hold valid data" ;
259 }
260 
WriteBinary(BYTE * data)261 void IAX2IeUShort::WriteBinary(BYTE *data)
262 {
263   data[0] = (BYTE)((dataValue >> 8) & 0xff);
264   data[1] = (BYTE)(dataValue & 0xff);
265 }
266 ////////////////////////////////////////////////////////////////////////////////
267 
IAX2IeShort(BYTE length,BYTE * srcData)268 IAX2IeShort::IAX2IeShort(BYTE length, BYTE *srcData)
269   : IAX2Ie()
270 {
271   if (length != sizeof(short)) {
272     validData = PFalse;
273     return;
274   }
275 
276   validData = PTrue;
277   dataValue = (short)((srcData[0] << 8) | srcData[1]);
278 }
279 
280 
PrintOn(ostream & str) const281 void IAX2IeShort::PrintOn(ostream & str) const
282 {
283   if (validData)
284     str << setw(17) << Class() << " " << dataValue;
285   else
286     str << setw(17) << Class() << " does not hold valid data" ;
287 }
288 
WriteBinary(BYTE * data)289 void IAX2IeShort::WriteBinary(BYTE *data)
290 {
291   data[0] = (BYTE)((dataValue >> 8) & 0xff);
292   data[1] = (BYTE)(dataValue & 0xff);
293 }
294 ////////////////////////////////////////////////////////////////////////////////
295 
IAX2IeInt(BYTE length,BYTE * srcData)296 IAX2IeInt::IAX2IeInt(BYTE length, BYTE *srcData)
297   : IAX2Ie()
298 {
299   if (length != sizeof(int)) {
300     validData = PFalse;
301     return;
302   }
303 
304   validData = PTrue;
305   dataValue = (srcData[0] << 24) | (srcData[1] << 16) | (srcData[2] << 8) | srcData[3];
306 }
307 
308 
PrintOn(ostream & str) const309 void IAX2IeInt::PrintOn(ostream & str) const
310 {
311   if (validData)
312     str << setw(17) << Class() << " " << dataValue;
313   else
314     str << setw(17) << Class() << " does not hold valid data" ;
315 }
316 
WriteBinary(BYTE * data)317 void IAX2IeInt::WriteBinary(BYTE *data)
318 {
319   data[0] = (BYTE)((dataValue >> 24) & 0xff);
320   data[1] = (BYTE)((dataValue >> 16) & 0xff);
321   data[2] = (BYTE)((dataValue >> 8) & 0xff);
322   data[3] = (BYTE)(dataValue & 0xff);
323 }
324 
325 ////////////////////////////////////////////////////////////////////////////////
326 
IAX2IeUInt(BYTE length,BYTE * srcData)327 IAX2IeUInt::IAX2IeUInt(BYTE length, BYTE *srcData)
328   : IAX2Ie()
329 {
330   if (length != sizeof(unsigned int)) {
331     validData = PFalse;
332     return;
333   }
334 
335   validData = PTrue;
336   dataValue = (srcData[0] << 24) | (srcData[1] << 16) | (srcData[2] << 8) | srcData[3];
337 }
338 
339 
PrintOn(ostream & str) const340 void IAX2IeUInt::PrintOn(ostream & str) const
341 {
342   if (validData)
343     str << setw(17) << Class() << " " << dataValue;
344   else
345     str << setw(17) << Class() << " does not hold valid data" ;
346 }
347 
WriteBinary(BYTE * data)348 void IAX2IeUInt::WriteBinary(BYTE *data)
349 {
350   data[0] = (BYTE)((dataValue >> 24) & 0xff);
351   data[1] = (BYTE)((dataValue >> 16) & 0xff);
352   data[2] = (BYTE)((dataValue >> 8) & 0xff);
353   data[3] = (BYTE)(dataValue & 0xff);
354 }
355 ////////////////////////////////////////////////////////////////////////////////
356 
IAX2IeString(BYTE length,BYTE * srcData)357 IAX2IeString::IAX2IeString(BYTE length, BYTE *srcData)
358   : IAX2Ie()
359 {
360   validData = PTrue;
361   dataValue = PString((const char *)srcData, length);
362 }
363 
364 
PrintOn(ostream & str) const365 void IAX2IeString::PrintOn(ostream & str) const
366 {
367   if (validData)
368     str << setw(17) << Class() << " " << dataValue;
369   else
370     str << setw(17) << Class() << " does not hold valid data" ;
371 }
372 
WriteBinary(BYTE * data)373 void IAX2IeString::WriteBinary(BYTE *data)
374 {
375   if(validData)
376     memcpy(data, dataValue.GetPointer(), GetLengthOfData());
377 }
378 
GetLengthOfData()379 BYTE IAX2IeString::GetLengthOfData()
380 {
381   if (dataValue.GetSize() == 0)
382     return 0;
383   else
384     return (BYTE)(dataValue.GetSize() - 1);
385 }
386 
SetData(const PString & newData)387 void IAX2IeString::SetData(const PString & newData)
388 {
389   dataValue = newData;
390   validData = PTrue;
391 }
392 
SetData(const char * newData)393 void IAX2IeString::SetData(const char * newData)
394 {
395   dataValue = PString(newData);
396   validData = PTrue;
397 }
398 
399 /////////////////////////////////////////////////////////////////////////////
IAX2IeBinary(BYTE length,BYTE * srcData)400 IAX2IeBinary::IAX2IeBinary(BYTE length, BYTE *srcData)
401   : IAX2Ie()
402 {
403   validData = PTrue;
404   if (length == 0)
405     dataValue = PBYTEArray(); /*A zero sized array */
406   else
407     dataValue = PBYTEArray(srcData, length);
408 }
409 
PrintOn(ostream & str) const410 void IAX2IeBinary::PrintOn(ostream & str) const
411 {
412   if (validData)
413     str << setw(17) << Class() << " " << dataValue;
414   else
415     str << setw(17) << Class() << " does not hold valid data" ;
416 }
417 
WriteBinary(BYTE * data)418 void IAX2IeBinary::WriteBinary(BYTE *data)
419 {
420   if(validData) {
421     memcpy(data, dataValue.GetPointer(), GetLengthOfData());
422   }
423   else {
424     PTRACE(3, "Iax2IeBinary\tError - major error in IAX2IeBinary");
425     PAssertAlways("Attempt to use faulty data");
426   }
427 }
428 
GetData(PBYTEArray & answer)429 void IAX2IeBinary::GetData(PBYTEArray & answer)
430 {
431   if (!validData) {
432     answer.SetSize(0);
433     return;
434   }
435 
436   answer = dataValue;
437 }
438 
CopyData(IAX2IeBinary * src)439 void IAX2IeBinary::CopyData(IAX2IeBinary *src)
440 {
441   dataValue = src->dataValue;
442   validData = src->validData;
443 }
444 
SetData(const PBYTEArray & newData)445 void IAX2IeBinary::SetData(const PBYTEArray & newData)
446 {
447   dataValue = newData;
448   validData = PTrue;
449 }
450 
451 ////////////////////////////////////////////////////////////////////////////////
452 
IAX2IeSockaddrIn(BYTE length,BYTE * srcData)453 IAX2IeSockaddrIn::IAX2IeSockaddrIn(BYTE length, BYTE *srcData)
454   : IAX2Ie()
455 {
456   if (length != sizeof(sockaddr_in)) {
457     validData = PFalse;
458     return;
459   }
460 
461   validData = PTrue;
462 
463   sockaddr_in a = * (sockaddr_in *)(srcData);
464   portNumber = a.sin_port;
465 
466   dataValue = PIPSocket::Address(a.sin_addr);
467 }
468 
469 
PrintOn(ostream & str) const470 void IAX2IeSockaddrIn::PrintOn(ostream & str) const
471 {
472   if (validData)
473     str << setw(17) << Class() << " " << dataValue << ":" << portNumber;
474   else
475     str << setw(17) << Class() << " does not hold valid data" ;
476 }
477 
WriteBinary(BYTE * data)478 void IAX2IeSockaddrIn::WriteBinary(BYTE *data)
479 {
480   sockaddr_in a;
481   memset(&a, 0, sizeof(sockaddr_in));
482   a.sin_addr = (in_addr)dataValue;
483   a.sin_port = (unsigned short)portNumber;
484 
485   *((sockaddr_in *)data) = a;
486 }
487 
488 ////////////////////////////////////////////////////////////////////////////////
489 
IAX2IeBlockOfData(BYTE length,BYTE * srcData)490 IAX2IeBlockOfData::IAX2IeBlockOfData(BYTE length, BYTE *srcData)
491   : IAX2Ie()
492 {
493   validData = PTrue;
494 
495   dataValue = PBYTEArray(srcData, length);
496 }
497 
498 
PrintOn(ostream & str) const499 void IAX2IeBlockOfData::PrintOn(ostream & str) const
500 {
501   str << setw(17) << Class() << " " << dataValue;
502 }
503 
504 
WriteBinary(BYTE * data)505 void IAX2IeBlockOfData::WriteBinary(BYTE *data)
506 {
507   memcpy(data, dataValue.GetPointer(), dataValue.GetSize());
508 }
509 
510 
511 ///////////////////////////////////////////////////////////////////////////
PrintOn(ostream & strm) const512 void IAX2IeCallToken::PrintOn(ostream & strm) const
513 {
514   if (validData)
515     strm << Class() << " " << dataValue.GetSize()
516 	 << " bytes ";
517   else
518     strm << "Invalid contents in " << Class();
519 }
520 
521 
InitialiseKey()522 void IAX2IeCallToken::InitialiseKey()
523 {
524   PINDEX i;
525   for (i = 0; i < blockSize; i++) {
526     iKeyPad[i] = iKeyValue;
527     oKeyPad[i] = oKeyValue;
528   }
529   PStringStream msg;
530   msg << ::hex << PRandom::Number() << ::dec;
531   secretKey = msg;
532 
533   BYTE block[20];
534   memcpy(block, secretKey.GetPointer(), secretKey.GetLength());
535   for (i = 0; i < secretKey.GetLength(); i++) {
536     iKeyPad[i] ^= block[i];
537     oKeyPad[i] ^= block[i];
538   }
539 }
540 
WriteKeySequence(PIPSocket::Address & remote)541 void IAX2IeCallToken::WriteKeySequence(PIPSocket::Address & remote)
542 {
543   PString srcTime = PString(PTime().GetTimeInSeconds());
544   PString answer = srcTime + PString("?") + ReportKeySequence(srcTime, remote);
545 
546   PBYTEArray data;
547   data.SetSize(answer.GetLength());
548   memcpy(data.GetPointer(), answer.GetPointer(), answer.GetLength());
549   SetData(data);
550 }
551 
ValidKeySequence(IAX2IeCallToken & cf,PIPSocket::Address & remote)552 PBoolean IAX2IeCallToken::ValidKeySequence (IAX2IeCallToken & cf,
553 					    PIPSocket::Address & remote)
554 {
555   time_t startTime = PTime().GetTimeInSeconds();
556   PBYTEArray srcData;
557   cf.GetData(srcData);
558   PString src((const char *)srcData.GetPointer(), srcData.GetSize());
559   PStringList bits = src.Tokenise("?");
560   if (bits.GetSize() != 2)
561     return PFalse;
562   time_t srcTime = bits[0].AsInteger();
563 
564   if ((srcTime != startTime)        &&
565       (srcTime != (startTime + 1))  &&
566       (srcTime != (startTime + 2)))
567     return PFalse;
568 
569   PString keySequence = ReportKeySequence(bits[0], remote);
570 
571   return keySequence == bits[1];
572 }
573 
574 #if P_SSL
ReportKeySequence(const PString & srcTime,PIPSocket::Address & remote)575 PString IAX2IeCallToken::ReportKeySequence(const PString & srcTime, PIPSocket::Address & remote)
576 {
577   BYTE block[1000];
578 
579   memcpy(block, iKeyPad, blockSize);
580   PString message = srcTime + remote.AsString();
581   memcpy(block + blockSize, message.GetPointer(), message.GetLength());
582 
583   PMessageDigest::Result bin_digest;
584   PMessageDigestSHA1::Encode((const void *)block,
585 			     blockSize + message.GetLength(), bin_digest);
586   memcpy(block, oKeyPad, blockSize);
587   const BYTE *data = bin_digest.GetPointer();
588   memcpy(block + blockSize, data, bin_digest.GetSize());
589   PMessageDigestSHA1::Encode((const void *)block,
590 			     blockSize + bin_digest.GetSize(),
591 			     bin_digest);
592 
593   PString answer;
594   PINDEX max;
595   PINDEX i;
596   for (i = 0, max = bin_digest.GetSize(); i < max ; i++)
597     answer.sprintf("%02x", (unsigned)data[i]);
598 
599   return answer;
600 }
601 #else
ReportKeySequence(const PString &,PIPSocket::Address &)602 PString IAX2IeCallToken::ReportKeySequence(const PString &, PIPSocket::Address &)
603 {
604   PAssertAlways("SSL should be enabled in the build when call token is used");
605   return PString::Empty();
606 }
607 #endif
608 
609 
610 /************
611   These variables are static, as they are only accessed from the
612   IAX2IeCallToken class, and they never ever change during program
613   execution. they are initialised and setup at program startup, which
614   saves time on processing each incoming call packet*/
615 
616 /**The key used in generating the SHA1-HMAC hash. Key is required for
617    handling incoming calls. This key is set to a random value (hex
618    representation of a random number, which is in the range of
619    1..2^32 */
620 PString IAX2IeCallToken::secretKey;
621 
622 /**Used for generating the SHA1-HMAC hash.  Initialised at program
623      startup, saves on time later. */
624 BYTE IAX2IeCallToken::iKeyPad[IAX2IeCallToken::blockSize];
625 
626 /**Similar to the iKeyPad, an internal variable*/
627 BYTE IAX2IeCallToken::oKeyPad[IAX2IeCallToken::blockSize];
628 /////////////////////////////////////////////////////////////////////////////
629 
~IAX2IeList()630 IAX2IeList::~IAX2IeList()
631 {
632     AllowDeleteObjects();
633 }
634 
RemoveIeAt(PINDEX i)635 IAX2Ie *IAX2IeList::RemoveIeAt(PINDEX i)
636 {
637   if (i >= GetSize())
638     return NULL;
639 
640   return (IAX2Ie *) PAbstractList::RemoveAt(i);
641 }
642 
RemoveLastIe()643 IAX2Ie *IAX2IeList::RemoveLastIe()
644 {
645   PINDEX elems = PAbstractList::GetSize();
646   if (elems > 0) {
647     return RemoveIeAt(elems - 1);
648   }
649 
650   return NULL;
651 }
652 
DeleteAt(PINDEX idex)653 void IAX2IeList::DeleteAt(PINDEX idex)
654 {
655   if (idex >= PAbstractList::GetSize())
656     return;
657 
658   IAX2Ie *obj = RemoveIeAt(idex);
659 
660   delete obj;
661 }
662 
GetBinaryDataSize() const663 int IAX2IeList::GetBinaryDataSize() const
664 {
665   PINDEX totalSize = 0;
666   for (PINDEX i = 0; i < PAbstractList::GetSize(); i++)
667     totalSize += GetIeAt(i)->GetBinarySize();
668 
669   return totalSize;
670 }
671 
GetIeAt(int i) const672 IAX2Ie *IAX2IeList::GetIeAt(int i) const
673 {
674   if (i >= GetSize())
675     return NULL;
676 
677   return (IAX2Ie *)GetAt(i);
678 }
679 
680 
681 ////////////////////////////////////////////////////////////////////////////////
682 
PrintOn(ostream & str) const683 void IAX2IeCalledNumber::PrintOn(ostream & str) const
684 {
685   if (validData)
686     str << setw(17) << Class() << " " << dataValue;
687   else
688     str << setw(17) << Class() << " does not contain valid data";
689 }
690 ////////////////////////////////////////////////////////////////////////////////
691 
PrintOn(ostream & str) const692 void IAX2IeCallingNumber::PrintOn(ostream & str) const
693 {
694   if (validData)
695     str << setw(17) << Class() << " " << dataValue;
696   else
697     str << setw(17) << Class() << " does not contain valid data";
698 }
699 ////////////////////////////////////////////////////////////////////////////////
700 
PrintOn(ostream & str) const701 void IAX2IeCallingAni::PrintOn(ostream & str) const
702 {
703   if (validData)
704     str << setw(17) << Class() << " " << dataValue;
705   else
706     str << setw(17) << Class() << " does not contain valid data";
707 }
708 ////////////////////////////////////////////////////////////////////////////////
709 
PrintOn(ostream & str) const710 void IAX2IeCallingName::PrintOn(ostream & str) const
711 {
712   if (validData)
713     str << setw(17) << Class() << " " << dataValue;
714   else
715     str << setw(17) << Class() << " does not contain valid data";
716 }
717 ////////////////////////////////////////////////////////////////////////////////
718 
PrintOn(ostream & str) const719 void IAX2IeCalledContext::PrintOn(ostream & str) const
720 {
721   if (validData)
722     str << setw(17) << Class() << " " << dataValue;
723   else
724     str << setw(17) << Class() << " does not contain valid data";
725 }
726 ////////////////////////////////////////////////////////////////////////////////
727 
PrintOn(ostream & str) const728 void IAX2IeUserName::PrintOn(ostream & str) const
729 {
730   if (validData)
731     str << setw(17) << Class() << " " << dataValue;
732   else
733     str << setw(17) << Class() << " does not contain valid data";
734 }
735 ////////////////////////////////////////////////////////////////////////////////
736 
PrintOn(ostream & str) const737 void IAX2IePassword::PrintOn(ostream & str) const
738 {
739   if (validData)
740     str << setw(17) << Class() << " " << dataValue;
741   else
742     str << setw(17) << Class() << " does not contain valid data";
743 }
744 ////////////////////////////////////////////////////////////////////////////////
745 
PrintOn(ostream & str) const746 void IAX2IeCapability::PrintOn(ostream & str) const
747 {
748   if (validData)
749     str << setw(17) << Class() << " " << dataValue;
750   else
751     str << setw(17) << Class() << " does not contain valid data";
752 }
753 ////////////////////////////////////////////////////////////////////////////////
754 
PrintOn(ostream & str) const755 void IAX2IeFormat::PrintOn(ostream & str) const
756 {
757   if (validData)
758     str << setw(17) << Class() << " " << dataValue;
759   else
760     str << setw(17) << Class() << " does not contain valid data";
761 }
762 ////////////////////////////////////////////////////////////////////////////////
763 
PrintOn(ostream & str) const764 void IAX2IeLanguage::PrintOn(ostream & str) const
765 {
766   if (validData)
767     str << setw(17) << Class() << " " << dataValue;
768   else
769     str << setw(17) << Class() << " does not contain valid data";
770 }
771 ////////////////////////////////////////////////////////////////////////////////
772 
PrintOn(ostream & str) const773 void IAX2IeVersion::PrintOn(ostream & str) const
774 {
775   if (validData)
776     str << setw(17) << Class() << " " << dataValue;
777   else
778     str << setw(17) << Class() << " does not contain valid data";
779 }
780 ////////////////////////////////////////////////////////////////////////////////
781 
PrintOn(ostream & str) const782 void IAX2IeAdsicpe::PrintOn(ostream & str) const
783 {
784   if (validData)
785     str << setw(17) << Class() << " " << dataValue;
786   else
787     str << setw(17) << Class() << " does not contain valid data";
788 }
789 ////////////////////////////////////////////////////////////////////////////////
790 
PrintOn(ostream & str) const791 void IAX2IeDnid::PrintOn(ostream & str) const
792 {
793   if (validData)
794     str << setw(17) << Class() << " " << dataValue;
795   else
796     str << setw(17) << Class() << " does not contain valid data";
797 }
798 ////////////////////////////////////////////////////////////////////////////////
799 
PrintOn(ostream & str) const800 void IAX2IeAuthMethods::PrintOn(ostream & str) const
801 {
802   if (validData)
803     str << setw(17) << Class() << " " << dataValue;
804   else
805     str << setw(17) << Class() << " does not contain valid data";
806 }
807 ////////////////////////////////////////////////////////////////////////////////
808 
PrintOn(ostream & str) const809 void IAX2IeChallenge::PrintOn(ostream & str) const
810 {
811   if (validData)
812     str << setw(17) << Class() << " " << dataValue;
813   else
814     str << setw(17) << Class() << " does not contain valid data";
815 }
816 ////////////////////////////////////////////////////////////////////////////////
817 
IAX2IeMd5Result(IAX2Encryption & encryption)818 IAX2IeMd5Result::IAX2IeMd5Result(IAX2Encryption & encryption)
819 {
820   InitializeChallengePassword(encryption.ChallengeKey(), encryption.EncryptionKey());
821 }
822 
IAX2IeMd5Result(const PString & challenge,const PString & password)823 IAX2IeMd5Result::IAX2IeMd5Result(const PString & challenge, const PString &password)
824 {
825   InitializeChallengePassword(challenge, password);
826 }
827 
828 
InitializeChallengePassword(const PString & newChallenge,const PString & newPassword)829 void IAX2IeMd5Result::InitializeChallengePassword(const PString &newChallenge, const PString & newPassword)
830 {
831   PMessageDigest5 stomach;
832   stomach.Process(newChallenge);
833   stomach.Process(newPassword);
834   PMessageDigest5::Code digester;
835   stomach.Complete(digester);
836 
837   dataBlock.SetSize(sizeof(digester));
838   memcpy(dataBlock.GetPointer(), &digester, dataBlock.GetSize());
839 
840   PStringStream res;
841   for (PINDEX i = 0; i < (PINDEX)sizeof(digester); i++)
842     res  << ::hex << ::setfill('0') << ::setw(2) << (int)(*(((BYTE *)&digester)+i));
843 
844   res.Trim();
845   res.MakeMinimumSize();
846 
847   SetData(res);
848 
849   PTRACE(3, "IAX2IeMd5Result\tChallenge is " << newChallenge);
850   PTRACE(3, "IAX2IeMd5Result\tPassword  is " << newPassword);
851   PTRACE(3, "IAX2IeMd5Result\tresult    is " << res);
852 }
853 
PrintOn(ostream & str) const854 void IAX2IeMd5Result::PrintOn(ostream & str) const
855 {
856   if (validData)
857     str << setw(17) << Class() << " " << dataValue;
858   else
859     str << setw(17) << Class() << " does not contain valid data";
860 }
861 ////////////////////////////////////////////////////////////////////////////////
862 
PrintOn(ostream & str) const863 void IAX2IeRsaResult::PrintOn(ostream & str) const
864 {
865   if (validData)
866     str << setw(17) << Class() << " " << dataValue;
867   else
868     str << setw(17) << Class() << " does not contain valid data";
869 }
870 ////////////////////////////////////////////////////////////////////////////////
871 
PrintOn(ostream & str) const872 void IAX2IeApparentAddr::PrintOn(ostream & str) const
873 {
874   if (validData)
875     str << setw(17) << Class() << " " << dataValue;
876   else
877     str << setw(17) << Class() << " does not contain valid data";
878 }
879 ////////////////////////////////////////////////////////////////////////////////
880 
PrintOn(ostream & str) const881 void IAX2IeRefresh::PrintOn(ostream & str) const
882 {
883   if (validData)
884     str << setw(17) << Class() << " " << dataValue;
885   else
886     str << setw(17) << Class() << " does not contain valid data";
887 }
888 ////////////////////////////////////////////////////////////////////////////////
889 
PrintOn(ostream & str) const890 void IAX2IeDpStatus::PrintOn(ostream & str) const
891 {
892   if (validData)
893     str << setw(17) << Class() << " " << dataValue;
894   else
895     str << setw(17) << Class() << " does not contain valid data";
896 }
897 ////////////////////////////////////////////////////////////////////////////////
898 
PrintOn(ostream & str) const899 void IAX2IeCallNo::PrintOn(ostream & str) const
900 {
901   if (validData)
902     str << setw(17) << Class() << " " << dataValue;
903   else
904     str << setw(17) << Class() << " does not contain valid data";
905 }
906 ////////////////////////////////////////////////////////////////////////////////
907 
PrintOn(ostream & str) const908 void IAX2IeCause::PrintOn(ostream & str) const
909 {
910   if (validData)
911     str << setw(17) << Class() << " \"" << dataValue;
912   else
913     str << setw(17) << Class() << " does not contain valid data";
914 }
915 ////////////////////////////////////////////////////////////////////////////////
916 
PrintOn(ostream & str) const917 void IAX2IeIaxUnknown::PrintOn(ostream & str) const
918 {
919   if (validData)
920     str << setw(17) << Class() << " " << dataValue;
921   else
922     str << setw(17) << Class() << " does not contain valid data";
923 }
924 ////////////////////////////////////////////////////////////////////////////////
925 
PrintOn(ostream & str) const926 void IAX2IeMsgCount::PrintOn(ostream & str) const
927 {
928   if (validData)
929     str << setw(17) << Class() << " " << dataValue;
930   else
931     str << setw(17) << Class() << " does not contain valid data";
932 }
933 ////////////////////////////////////////////////////////////////////////////////
934 
PrintOn(ostream & str) const935 void IAX2IeAutoAnswer::PrintOn(ostream & str) const
936 {
937   str << setw(17) << Class() << "   key(" << ((int) GetKeyValue()) << ")";
938 }
939 ////////////////////////////////////////////////////////////////////////////////
940 
PrintOn(ostream & str) const941 void IAX2IeMusicOnHold::PrintOn(ostream & str) const
942 {
943   str << setw(17) << Class() << "    key(" << ((int) GetKeyValue()) << ")";
944 }
945 ////////////////////////////////////////////////////////////////////////////////
946 
PrintOn(ostream & str) const947 void IAX2IeTransferId::PrintOn(ostream & str) const
948 {
949   if (validData)
950     str << setw(17) << Class() << " " << dataValue;
951   else
952     str << setw(17) << Class() << " does not contain valid data";
953 }
954 ////////////////////////////////////////////////////////////////////////////////
955 
PrintOn(ostream & str) const956 void IAX2IeRdnis::PrintOn(ostream & str) const
957 {
958   if (validData)
959     str << setw(17) << Class() << " " << dataValue;
960   else
961     str << setw(17) << Class() << " does not contain valid data";
962 }
963 ////////////////////////////////////////////////////////////////////////////////
964 
PrintOn(ostream & str) const965 void IAX2IeProvisioning::PrintOn(ostream & str) const
966 {
967   if (validData)
968     str << setw(17) << Class() << " " << dataValue;
969   else
970     str << setw(17) << Class() << " does not contain valid data";
971 }
972 ////////////////////////////////////////////////////////////////////////////////
973 
PrintOn(ostream & str) const974 void IAX2IeAesProvisioning::PrintOn(ostream & str) const
975 {
976   str << setw(17) << Class() << "   key(" << ((int) GetKeyValue()) << ")";
977 }
978 ////////////////////////////////////////////////////////////////////////////////
979 
PrintOn(ostream & str) const980 void IAX2IeDateTime::PrintOn(ostream & str) const
981 {
982   if (validData)
983     str << setw(17) << Class() << " " << dataValue;
984   else
985     str << setw(17) << Class() << " does not contain valid data";
986 }
987 ////////////////////////////////////////////////////////////////////////////////
988 
PrintOn(ostream & str) const989 void IAX2IeDeviceType::PrintOn(ostream & str) const
990 {
991   if (validData)
992     str << setw(17) << Class() << " " << dataValue;
993   else
994     str << setw(17) << Class() << " does not contain valid data";
995 }
996 ////////////////////////////////////////////////////////////////////////////////
997 
PrintOn(ostream & str) const998 void IAX2IeServiceIdent::PrintOn(ostream & str) const
999 {
1000   if (validData)
1001     str << setw(17) << Class() << " " << dataValue;
1002   else
1003     str << setw(17) << Class() << " does not contain valid data";
1004 }
1005 ////////////////////////////////////////////////////////////////////////////////
1006 
PrintOn(ostream & str) const1007 void IAX2IeFirmwareVer::PrintOn(ostream & str) const
1008 {
1009   if (validData)
1010     str << setw(17) << Class() << " " << dataValue;
1011   else
1012     str << setw(17) << Class() << " does not contain valid data";
1013 }
1014 ////////////////////////////////////////////////////////////////////////////////
1015 
PrintOn(ostream & str) const1016 void IAX2IeFwBlockDesc::PrintOn(ostream & str) const
1017 {
1018   if (validData)
1019     str << setw(17) << Class() << " " << dataValue;
1020   else
1021     str << setw(17) << Class() << " does not contain valid data";
1022 }
1023 ////////////////////////////////////////////////////////////////////////////////
1024 
PrintOn(ostream & str) const1025 void IAX2IeFwBlockData::PrintOn(ostream & str) const
1026 {
1027   if (validData)
1028     str << setw(17) << Class() << " " << dataValue;
1029   else
1030     str << setw(17) << Class() << " does not contain valid data";
1031 }
1032 ////////////////////////////////////////////////////////////////////////////////
1033 
PrintOn(ostream & str) const1034 void IAX2IeProvVer::PrintOn(ostream & str) const
1035 {
1036   if (validData)
1037     str << setw(17) << Class() << " " << dataValue;
1038   else
1039     str << setw(17) << Class() << " does not contain valid data";
1040 }
1041 ////////////////////////////////////////////////////////////////////////////////
1042 
PrintOn(ostream & str) const1043 void IAX2IeCallingPres::PrintOn(ostream & str) const
1044 {
1045   if (validData)
1046     str << setw(17) << Class() << " " << dataValue;
1047   else
1048     str << setw(17) << Class() << " does not contain valid data";
1049 }
1050 ////////////////////////////////////////////////////////////////////////////////
1051 
PrintOn(ostream & str) const1052 void IAX2IeCallingTon::PrintOn(ostream & str) const
1053 {
1054   if (validData)
1055     str << setw(17) << Class() << " " << dataValue;
1056   else
1057     str << setw(17) << Class() << " does not contain valid data";
1058 }
1059 ////////////////////////////////////////////////////////////////////////////////
1060 
PrintOn(ostream & str) const1061 void IAX2IeCallingTns::PrintOn(ostream & str) const
1062 {
1063   if (validData)
1064     str << setw(17) << Class() << " " << dataValue;
1065   else
1066     str << setw(17) << Class() << " does not contain valid data";
1067 }
1068 ////////////////////////////////////////////////////////////////////////////////
1069 
PrintOn(ostream & str) const1070 void IAX2IeSamplingRate::PrintOn(ostream & str) const
1071 {
1072   if (validData)
1073     str << setw(17) << Class() << " " << dataValue;
1074   else
1075     str << setw(17) << Class() << " does not contain valid data";
1076 }
1077 ////////////////////////////////////////////////////////////////////////////////
1078 
IAX2IeEncryption(IAX2IeEncryptionMethod method)1079 IAX2IeEncryption::IAX2IeEncryption(IAX2IeEncryptionMethod method)
1080 {
1081   SetData((unsigned short)method);
1082 }
1083 
PrintOn(ostream & str) const1084 void IAX2IeEncryption::PrintOn(ostream & str) const
1085 {
1086   if (validData)
1087     str << setw(17) << Class() << " " << dataValue;
1088   else
1089     str << setw(17) << Class() << " does not contain valid data";
1090 }
1091 ////////////////////////////////////////////////////////////////////////////////
1092 
PrintOn(ostream & str) const1093 void IAX2IeEncKey::PrintOn(ostream & str) const
1094 {
1095   if (validData)
1096     str << setw(17) << Class() << " " << dataValue;
1097   else
1098     str << setw(17) << Class() << " does not contain valid data";
1099 }
1100 ////////////////////////////////////////////////////////////////////////////////
1101 
PrintOn(ostream & str) const1102 void IAX2IeCodecPrefs::PrintOn(ostream & str) const
1103 {
1104   if (validData)
1105     str << setw(17) << Class() << " " << dataValue;
1106   else
1107     str << setw(17) << Class() << " does not contain valid data";
1108 }
1109 ////////////////////////////////////////////////////////////////////////////////
PrintOn(ostream & str) const1110 void IAX2IeCauseCode::PrintOn(ostream & str) const
1111 {
1112   if (validData)
1113     str << setw(17) << Class() << " " << ((int)dataValue);
1114   else
1115     str << setw(17) << Class() << " does not contain valid data";
1116 }
1117 ////////////////////////////////////////////////////////////////////////////////
1118 
PrintOn(ostream & str) const1119 void IAX2IeReceivedJitter::PrintOn(ostream & str) const
1120 {
1121   if (validData)
1122     str << setw(17) << Class() << " " << ((unsigned int)dataValue);
1123   else
1124     str << setw(17) << Class() << " does not contain valid data";
1125 }
1126 
1127 ////////////////////////////////////////////////////////////////////////////////
1128 
PrintOn(ostream & str) const1129 void IAX2IeReceivedLoss::PrintOn(ostream & str) const
1130 {
1131   if (validData)
1132     str << setw(17) << Class() << " " << ((unsigned int)dataValue);
1133   else
1134     str << setw(17) << Class() << " does not contain valid data";
1135 }
1136 ////////////////////////////////////////////////////////////////////////////////
PrintOn(ostream & str) const1137 void IAX2IeReceivedFrames::PrintOn(ostream & str) const
1138 {
1139   if (validData)
1140     str << setw(17) << Class() << " " << ((unsigned int)dataValue);
1141   else
1142     str << setw(17) << Class() << " does not contain valid data";
1143 }
1144 ////////////////////////////////////////////////////////////////////////////////
1145 
PrintOn(ostream & str) const1146 void IAX2IeReceivedDelay::PrintOn(ostream & str) const
1147 {
1148   if (validData)
1149     str << setw(17) << Class() << " " << ((unsigned short)dataValue);
1150   else
1151     str << setw(17) << Class() << " does not contain valid data";
1152 }
1153 
1154 ////////////////////////////////////////////////////////////////////////////////
1155 
PrintOn(ostream & str) const1156 void IAX2IeDroppedFrames::PrintOn(ostream & str) const
1157 {
1158   if (validData)
1159     str << setw(17) << Class() << " " << ((unsigned int)dataValue);
1160   else
1161     str << setw(17) << Class() << " does not contain valid data";
1162 }
1163 ////////////////////////////////////////////////////////////////////////////////
1164 
PrintOn(ostream & str) const1165 void IAX2IeReceivedOoo::PrintOn(ostream & str) const
1166 {
1167   if (validData)
1168     str << setw(17) << Class() << " " << ((unsigned int)dataValue);
1169   else
1170     str << setw(17) << Class() << " does not contain valid data";
1171 }
1172 ////////////////////////////////////////////////////////////////////////////////
1173 
1174 
1175 #endif // OPAL_IAX2
1176 
1177 ////////////////////////////////////////////////////////////////////////////////
1178 /* The comment below is magic for those who use emacs to edit this file.
1179  * With the comment below, the tab key does auto indent to 2 spaces.
1180  *
1181  * Local Variables:
1182  * mode:c
1183  * c-basic-offset:2
1184  * End:
1185  */
1186 
1187