2
* Support classes for the Pedro mini-XMPP client
7
* Copyright (C) 2005-2007 Bob Jamison
9
* This library is free software; you can redistribute it and/or
10
* modify it under the terms of the GNU Lesser General Public
11
* License as published by the Free Software Foundation; either
12
* version 2.1 of the License, or (at your option) any later version.
14
* This library is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17
* Lesser General Public License for more details.
19
* You should have received a copy of the GNU Lesser General Public
20
* License along with this library; if not, write to the Free Software
21
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
30
#include "pedroutil.h"
40
#include <sys/types.h>
41
#include <sys/socket.h>
42
#include <netinet/in.h>
45
#include <sys/ioctl.h>
63
//########################################################################
64
//########################################################################
66
//########################################################################
67
//########################################################################
75
static const char *base64encode =
76
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
81
* Writes the specified byte to the output buffer
83
void Base64Encoder::append(int ch)
86
outBuf |= (ch & 0xff);
90
int indx = (int)((outBuf & 0x00fc0000L) >> 18);
91
int obyte = (int)base64encode[indx & 63];
94
indx = (int)((outBuf & 0x0003f000L) >> 12);
95
obyte = (int)base64encode[indx & 63];
98
indx = (int)((outBuf & 0x00000fc0L) >> 6);
99
obyte = (int)base64encode[indx & 63];
100
buf.push_back(obyte);
102
indx = (int)((outBuf & 0x0000003fL) );
103
obyte = (int)base64encode[indx & 63];
104
buf.push_back(obyte);
112
* Writes the specified string to the output buffer
114
void Base64Encoder::append(char *str)
121
* Writes the specified string to the output buffer
123
void Base64Encoder::append(unsigned char *str, int len)
133
* Writes the specified string to the output buffer
135
void Base64Encoder::append(const DOMString &str)
137
append((char *)str.c_str());
141
* Closes this output stream and releases any system resources
142
* associated with this stream.
144
DOMString Base64Encoder::finish()
146
//get any last bytes (1 or 2) out of the buffer
149
outBuf <<= 2; //pad to make 18 bits
151
int indx = (int)((outBuf & 0x0003f000L) >> 12);
152
int obyte = (int)base64encode[indx & 63];
153
buf.push_back(obyte);
155
indx = (int)((outBuf & 0x00000fc0L) >> 6);
156
obyte = (int)base64encode[indx & 63];
157
buf.push_back(obyte);
159
indx = (int)((outBuf & 0x0000003fL) );
160
obyte = (int)base64encode[indx & 63];
161
buf.push_back(obyte);
165
else if (bitCount == 8)
167
outBuf <<= 4; //pad to make 12 bits
169
int indx = (int)((outBuf & 0x00000fc0L) >> 6);
170
int obyte = (int)base64encode[indx & 63];
171
buf.push_back(obyte);
173
indx = (int)((outBuf & 0x0000003fL) );
174
obyte = (int)base64encode[indx & 63];
175
buf.push_back(obyte);
187
DOMString Base64Encoder::encode(const DOMString &str)
189
Base64Encoder encoder;
191
DOMString ret = encoder.finish();
201
static int base64decode[] =
203
/*00*/ -1, -1, -1, -1, -1, -1, -1, -1,
204
/*08*/ -1, -1, -1, -1, -1, -1, -1, -1,
205
/*10*/ -1, -1, -1, -1, -1, -1, -1, -1,
206
/*18*/ -1, -1, -1, -1, -1, -1, -1, -1,
207
/*20*/ -1, -1, -1, -1, -1, -1, -1, -1,
208
/*28*/ -1, -1, -1, 62, -1, -1, -1, 63,
209
/*30*/ 52, 53, 54, 55, 56, 57, 58, 59,
210
/*38*/ 60, 61, -1, -1, -1, -1, -1, -1,
211
/*40*/ -1, 0, 1, 2, 3, 4, 5, 6,
212
/*48*/ 7, 8, 9, 10, 11, 12, 13, 14,
213
/*50*/ 15, 16, 17, 18, 19, 20, 21, 22,
214
/*58*/ 23, 24, 25, -1, -1, -1, -1, -1,
215
/*60*/ -1, 26, 27, 28, 29, 30, 31, 32,
216
/*68*/ 33, 34, 35, 36, 37, 38, 39, 40,
217
/*70*/ 41, 42, 43, 44, 45, 46, 47, 48,
218
/*78*/ 49, 50, 51, -1, -1, -1, -1, -1
224
* Appends one char to the decoder
226
void Base64Decoder::append(int ch)
230
else if (ch == '=') //padding
232
inBytes[inCount++] = 0;
236
int byteVal = base64decode[ch & 0x7f];
237
//printf("char:%c %d\n", ch, byteVal);
242
inBytes[inCount++] = byteVal;
247
unsigned char b0 = ((inBytes[0]<<2) & 0xfc) | ((inBytes[1]>>4) & 0x03);
248
unsigned char b1 = ((inBytes[1]<<4) & 0xf0) | ((inBytes[2]>>2) & 0x0f);
249
unsigned char b2 = ((inBytes[2]<<6) & 0xc0) | ((inBytes[3] ) & 0x3f);
258
void Base64Decoder::append(char *str)
264
void Base64Decoder::append(const DOMString &str)
266
append((char *)str.c_str());
269
std::vector<unsigned char> Base64Decoder::finish()
271
std::vector<unsigned char> ret = buf;
276
std::vector<unsigned char> Base64Decoder::decode(const DOMString &str)
278
Base64Decoder decoder;
280
std::vector<unsigned char> ret = decoder.finish();
284
DOMString Base64Decoder::decodeToString(const DOMString &str)
286
Base64Decoder decoder;
288
std::vector<unsigned char> ret = decoder.finish();
290
for (unsigned int i=0 ; i<ret.size() ; i++)
291
buf.push_back(ret[i]);
301
//########################################################################
302
//########################################################################
303
//### S H A 1 H A S H I N G
304
//########################################################################
305
//########################################################################
307
void Sha1::hash(unsigned char *dataIn, int len, unsigned char *digest)
310
sha1.append(dataIn, len);
314
static const char *sha1hex = "0123456789abcdef";
316
DOMString Sha1::hashHex(unsigned char *dataIn, int len)
318
unsigned char hashout[20];
319
hash(dataIn, len, hashout);
321
for (int i=0 ; i<20 ; i++)
323
unsigned char ch = hashout[i];
324
ret.push_back(sha1hex[ (ch>>4) & 15 ]);
325
ret.push_back(sha1hex[ ch & 15 ]);
331
DOMString Sha1::hashHex(const DOMString &str)
333
return hashHex((unsigned char *)str.c_str(), str.size());
345
// Initialize H with the magic constants (see FIPS180 for constants)
346
hashBuf[0] = 0x67452301L;
347
hashBuf[1] = 0xefcdab89L;
348
hashBuf[2] = 0x98badcfeL;
349
hashBuf[3] = 0x10325476L;
350
hashBuf[4] = 0xc3d2e1f0L;
352
for (int i = 0; i < 4; i++)
355
for (int i = 0; i < 80; i++)
360
void Sha1::append(unsigned char ch)
362
if (nrBytesLo == 0xffffffffL)
370
inb[byteNr++] = (unsigned long)ch;
373
inBuf[longNr++] = inb[0] << 24 | inb[1] << 16 |
374
inb[2] << 8 | inb[3];
385
void Sha1::append(unsigned char *dataIn, int len)
387
for (int i = 0; i < len; i++)
392
void Sha1::append(const DOMString &str)
394
append((unsigned char *)str.c_str(), str.size());
398
void Sha1::finish(unsigned char digest[20])
400
//snapshot the bit count now before padding
401
unsigned long nrBitsLo = (nrBytesLo << 3) & 0xffffffff;
402
unsigned long nrBitsHi = (nrBytesHi << 3) | ((nrBytesLo >> 29) & 7);
404
//Append terminal char
407
//pad until we have a 56 of 64 bytes, allowing for 8 bytes at the end
412
//##### Append length in bits
413
append((unsigned char)((nrBitsHi>>24) & 0xff));
414
append((unsigned char)((nrBitsHi>>16) & 0xff));
415
append((unsigned char)((nrBitsHi>> 8) & 0xff));
416
append((unsigned char)((nrBitsHi ) & 0xff));
417
append((unsigned char)((nrBitsLo>>24) & 0xff));
418
append((unsigned char)((nrBitsLo>>16) & 0xff));
419
append((unsigned char)((nrBitsLo>> 8) & 0xff));
420
append((unsigned char)((nrBitsLo ) & 0xff));
425
for (int i=0 ; i<5 ; i++)
427
digest[indx++] = (unsigned char)((hashBuf[i] >> 24) & 0xff);
428
digest[indx++] = (unsigned char)((hashBuf[i] >> 16) & 0xff);
429
digest[indx++] = (unsigned char)((hashBuf[i] >> 8) & 0xff);
430
digest[indx++] = (unsigned char)((hashBuf[i] ) & 0xff);
433
// Re-initialize the context (also zeroizes contents)
439
#define SHA_ROTL(X,n) ((((X) << (n)) & 0xffffffff) | (((X) >> (32-(n))) & 0xffffffff))
441
void Sha1::transform()
443
unsigned long *W = inBuf;
444
unsigned long *H = hashBuf;
446
for (int t = 16; t <= 79; t++)
447
W[t] = SHA_ROTL(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16], 1);
449
unsigned long A = H[0];
450
unsigned long B = H[1];
451
unsigned long C = H[2];
452
unsigned long D = H[3];
453
unsigned long E = H[4];
457
for (int t = 0; t <= 19; t++)
459
TEMP = (SHA_ROTL(A,5) + ((B&C)|((~B)&D)) +
460
E + W[t] + 0x5a827999L) & 0xffffffffL;
461
E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP;
463
for (int t = 20; t <= 39; t++)
465
TEMP = (SHA_ROTL(A,5) + (B^C^D) +
466
E + W[t] + 0x6ed9eba1L) & 0xffffffffL;
467
E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP;
469
for (int t = 40; t <= 59; t++)
471
TEMP = (SHA_ROTL(A,5) + ((B&C)|(B&D)|(C&D)) +
472
E + W[t] + 0x8f1bbcdcL) & 0xffffffffL;
473
E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP;
475
for (int t = 60; t <= 79; t++)
477
TEMP = (SHA_ROTL(A,5) + (B^C^D) +
478
E + W[t] + 0xca62c1d6L) & 0xffffffffL;
479
E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP;
482
H[0] = (H[0] + A) & 0xffffffffL;
483
H[1] = (H[1] + B) & 0xffffffffL;
484
H[2] = (H[2] + C) & 0xffffffffL;
485
H[3] = (H[3] + D) & 0xffffffffL;
486
H[4] = (H[4] + E) & 0xffffffffL;
491
//########################################################################
492
//########################################################################
493
//### M D 5 H A S H I N G
494
//########################################################################
495
//########################################################################
500
void Md5::hash(unsigned char *dataIn, unsigned long len, unsigned char *digest)
503
md5.append(dataIn, len);
507
DOMString Md5::hashHex(unsigned char *dataIn, unsigned long len)
510
md5.append(dataIn, len);
511
DOMString ret = md5.finishHex();
515
DOMString Md5::hashHex(const DOMString &str)
519
DOMString ret = md5.finishHex();
525
* Initialize MD5 polynomials and storage
529
hashBuf[0] = 0x67452301;
530
hashBuf[1] = 0xefcdab89;
531
hashBuf[2] = 0x98badcfe;
532
hashBuf[3] = 0x10325476;
544
* Update with one character
546
void Md5::append(unsigned char ch)
548
if (nrBytesLo == 0xffffffff)
556
//pack 64 bytes into 16 longs
557
inb[byteNr++] = (unsigned long)ch;
561
inb[3] << 24 | inb[2] << 16 | inb[1] << 8 | inb[0];
562
inBuf[longNr++] = val;
574
* Update context to reflect the concatenation of another buffer full
577
void Md5::append(unsigned char *source, unsigned long len)
585
* Update context to reflect the concatenation of another string
587
void Md5::append(const DOMString &str)
589
append((unsigned char *)str.c_str(), str.size());
594
* Final wrapup - pad to 64-byte boundary with the bit pattern
595
* 1 0* (64-bit count of bits processed, MSB-first)
597
void Md5::finish(unsigned char *digest)
599
//snapshot the bit count now before padding
600
unsigned long nrBitsLo = (nrBytesLo << 3) & 0xffffffff;
601
unsigned long nrBitsHi = (nrBytesHi << 3) | ((nrBytesLo >> 29) & 7);
603
//Append terminal char
606
//pad until we have a 56 of 64 bytes, allowing for 8 bytes at the end
610
//##### Append length in bits
611
append((unsigned char)((nrBitsLo ) & 0xff));
612
append((unsigned char)((nrBitsLo>> 8) & 0xff));
613
append((unsigned char)((nrBitsLo>>16) & 0xff));
614
append((unsigned char)((nrBitsLo>>24) & 0xff));
615
append((unsigned char)((nrBitsHi ) & 0xff));
616
append((unsigned char)((nrBitsHi>> 8) & 0xff));
617
append((unsigned char)((nrBitsHi>>16) & 0xff));
618
append((unsigned char)((nrBitsHi>>24) & 0xff));
622
for (int i=0 ; i<4 ; i++)
624
digest[indx++] = (unsigned char)((hashBuf[i] ) & 0xff);
625
digest[indx++] = (unsigned char)((hashBuf[i] >> 8) & 0xff);
626
digest[indx++] = (unsigned char)((hashBuf[i] >> 16) & 0xff);
627
digest[indx++] = (unsigned char)((hashBuf[i] >> 24) & 0xff);
630
init(); // Security! ;-)
635
static const char *md5hex = "0123456789abcdef";
637
DOMString Md5::finishHex()
639
unsigned char hashout[16];
642
for (int i=0 ; i<16 ; i++)
644
unsigned char ch = hashout[i];
645
ret.push_back(md5hex[ (ch>>4) & 15 ]);
646
ret.push_back(md5hex[ ch & 15 ]);
653
//# The four core functions - F1 is optimized somewhat
655
// #define F1(x, y, z) (x & y | ~x & z)
656
#define M(x) ((x) &= 0xffffffff)
657
#define F1(x, y, z) (z ^ (x & (y ^ z)))
658
#define F2(x, y, z) F1(z, x, y)
659
#define F3(x, y, z) (x ^ y ^ z)
660
#define F4(x, y, z) (y ^ (x | ~z))
662
// ## This is the central step in the MD5 algorithm.
663
#define MD5STEP(f, w, x, y, z, data, s) \
664
( w += (f(x, y, z) + data), M(w), w = w<<s | w>>(32-s), w += x, M(w) )
667
* The core of the MD5 algorithm, this alters an existing MD5 hash to
668
* reflect the addition of 16 longwords of new data. MD5Update blocks
669
* the data and converts bytes into longwords for this routine.
670
* @parm buf points to an array of 4 unsigned 32bit (at least) integers
671
* @parm in points to an array of 16 unsigned 32bit (at least) integers
673
void Md5::transform()
675
unsigned long *i = inBuf;
676
unsigned long a = hashBuf[0];
677
unsigned long b = hashBuf[1];
678
unsigned long c = hashBuf[2];
679
unsigned long d = hashBuf[3];
681
MD5STEP(F1, a, b, c, d, i[ 0] + 0xd76aa478, 7);
682
MD5STEP(F1, d, a, b, c, i[ 1] + 0xe8c7b756, 12);
683
MD5STEP(F1, c, d, a, b, i[ 2] + 0x242070db, 17);
684
MD5STEP(F1, b, c, d, a, i[ 3] + 0xc1bdceee, 22);
685
MD5STEP(F1, a, b, c, d, i[ 4] + 0xf57c0faf, 7);
686
MD5STEP(F1, d, a, b, c, i[ 5] + 0x4787c62a, 12);
687
MD5STEP(F1, c, d, a, b, i[ 6] + 0xa8304613, 17);
688
MD5STEP(F1, b, c, d, a, i[ 7] + 0xfd469501, 22);
689
MD5STEP(F1, a, b, c, d, i[ 8] + 0x698098d8, 7);
690
MD5STEP(F1, d, a, b, c, i[ 9] + 0x8b44f7af, 12);
691
MD5STEP(F1, c, d, a, b, i[10] + 0xffff5bb1, 17);
692
MD5STEP(F1, b, c, d, a, i[11] + 0x895cd7be, 22);
693
MD5STEP(F1, a, b, c, d, i[12] + 0x6b901122, 7);
694
MD5STEP(F1, d, a, b, c, i[13] + 0xfd987193, 12);
695
MD5STEP(F1, c, d, a, b, i[14] + 0xa679438e, 17);
696
MD5STEP(F1, b, c, d, a, i[15] + 0x49b40821, 22);
698
MD5STEP(F2, a, b, c, d, i[ 1] + 0xf61e2562, 5);
699
MD5STEP(F2, d, a, b, c, i[ 6] + 0xc040b340, 9);
700
MD5STEP(F2, c, d, a, b, i[11] + 0x265e5a51, 14);
701
MD5STEP(F2, b, c, d, a, i[ 0] + 0xe9b6c7aa, 20);
702
MD5STEP(F2, a, b, c, d, i[ 5] + 0xd62f105d, 5);
703
MD5STEP(F2, d, a, b, c, i[10] + 0x02441453, 9);
704
MD5STEP(F2, c, d, a, b, i[15] + 0xd8a1e681, 14);
705
MD5STEP(F2, b, c, d, a, i[ 4] + 0xe7d3fbc8, 20);
706
MD5STEP(F2, a, b, c, d, i[ 9] + 0x21e1cde6, 5);
707
MD5STEP(F2, d, a, b, c, i[14] + 0xc33707d6, 9);
708
MD5STEP(F2, c, d, a, b, i[ 3] + 0xf4d50d87, 14);
709
MD5STEP(F2, b, c, d, a, i[ 8] + 0x455a14ed, 20);
710
MD5STEP(F2, a, b, c, d, i[13] + 0xa9e3e905, 5);
711
MD5STEP(F2, d, a, b, c, i[ 2] + 0xfcefa3f8, 9);
712
MD5STEP(F2, c, d, a, b, i[ 7] + 0x676f02d9, 14);
713
MD5STEP(F2, b, c, d, a, i[12] + 0x8d2a4c8a, 20);
715
MD5STEP(F3, a, b, c, d, i[ 5] + 0xfffa3942, 4);
716
MD5STEP(F3, d, a, b, c, i[ 8] + 0x8771f681, 11);
717
MD5STEP(F3, c, d, a, b, i[11] + 0x6d9d6122, 16);
718
MD5STEP(F3, b, c, d, a, i[14] + 0xfde5380c, 23);
719
MD5STEP(F3, a, b, c, d, i[ 1] + 0xa4beea44, 4);
720
MD5STEP(F3, d, a, b, c, i[ 4] + 0x4bdecfa9, 11);
721
MD5STEP(F3, c, d, a, b, i[ 7] + 0xf6bb4b60, 16);
722
MD5STEP(F3, b, c, d, a, i[10] + 0xbebfbc70, 23);
723
MD5STEP(F3, a, b, c, d, i[13] + 0x289b7ec6, 4);
724
MD5STEP(F3, d, a, b, c, i[ 0] + 0xeaa127fa, 11);
725
MD5STEP(F3, c, d, a, b, i[ 3] + 0xd4ef3085, 16);
726
MD5STEP(F3, b, c, d, a, i[ 6] + 0x04881d05, 23);
727
MD5STEP(F3, a, b, c, d, i[ 9] + 0xd9d4d039, 4);
728
MD5STEP(F3, d, a, b, c, i[12] + 0xe6db99e5, 11);
729
MD5STEP(F3, c, d, a, b, i[15] + 0x1fa27cf8, 16);
730
MD5STEP(F3, b, c, d, a, i[ 2] + 0xc4ac5665, 23);
732
MD5STEP(F4, a, b, c, d, i[ 0] + 0xf4292244, 6);
733
MD5STEP(F4, d, a, b, c, i[ 7] + 0x432aff97, 10);
734
MD5STEP(F4, c, d, a, b, i[14] + 0xab9423a7, 15);
735
MD5STEP(F4, b, c, d, a, i[ 5] + 0xfc93a039, 21);
736
MD5STEP(F4, a, b, c, d, i[12] + 0x655b59c3, 6);
737
MD5STEP(F4, d, a, b, c, i[ 3] + 0x8f0ccc92, 10);
738
MD5STEP(F4, c, d, a, b, i[10] + 0xffeff47d, 15);
739
MD5STEP(F4, b, c, d, a, i[ 1] + 0x85845dd1, 21);
740
MD5STEP(F4, a, b, c, d, i[ 8] + 0x6fa87e4f, 6);
741
MD5STEP(F4, d, a, b, c, i[15] + 0xfe2ce6e0, 10);
742
MD5STEP(F4, c, d, a, b, i[ 6] + 0xa3014314, 15);
743
MD5STEP(F4, b, c, d, a, i[13] + 0x4e0811a1, 21);
744
MD5STEP(F4, a, b, c, d, i[ 4] + 0xf7537e82, 6);
745
MD5STEP(F4, d, a, b, c, i[11] + 0xbd3af235, 10);
746
MD5STEP(F4, c, d, a, b, i[ 2] + 0x2ad7d2bb, 15);
747
MD5STEP(F4, b, c, d, a, i[ 9] + 0xeb86d391, 21);
759
//########################################################################
760
//########################################################################
762
//########################################################################
763
//########################################################################
772
static DWORD WINAPI WinThreadFunction(LPVOID context)
774
Thread *thread = (Thread *)context;
783
HANDLE hThread = CreateThread(NULL, 0, WinThreadFunction,
784
(LPVOID)this, 0, &dwThreadId);
785
//Make sure the thread is started before 'this' is deallocated
788
CloseHandle(hThread);
791
void Thread::sleep(unsigned long millis)
799
void *PthreadThreadFunction(void *context)
801
Thread *thread = (Thread *)context;
811
int ret = pthread_create(&thread, NULL,
812
PthreadThreadFunction, (void *)this);
814
printf("Thread::start: thread creation failed: %s\n", strerror(ret));
816
//Make sure the thread is started before 'this' is deallocated
822
void Thread::sleep(unsigned long millis)
825
requested.tv_sec = millis / 1000;
826
requested.tv_nsec = (millis % 1000 ) * 1000000L;
827
nanosleep(&requested, NULL);
839
//########################################################################
840
//########################################################################
842
//########################################################################
843
//########################################################################
849
//#########################################################################
851
//#########################################################################
853
static void mybzero(void *s, size_t n)
855
unsigned char *p = (unsigned char *)s;
858
*p++ = (unsigned char)0;
863
static void mybcopy(void *src, void *dest, size_t n)
865
unsigned char *p = (unsigned char *)dest;
866
unsigned char *q = (unsigned char *)src;
876
//#########################################################################
877
//# T C P C O N N E C T I O N
878
//#########################################################################
880
TcpSocket::TcpSocket()
886
TcpSocket::TcpSocket(const std::string &hostnameArg, int port)
889
hostname = hostnameArg;
898
static void cryptoLockCallback(int mode, int type, const char */*file*/, int /*line*/)
900
//printf("########### LOCK\n");
901
static int modes[CRYPTO_NUM_LOCKS]; /* = {0, 0, ... } */
902
const char *errstr = NULL;
904
int rw = mode & (CRYPTO_READ|CRYPTO_WRITE);
905
if (!((rw == CRYPTO_READ) || (rw == CRYPTO_WRITE)))
907
errstr = "invalid mode";
911
if (type < 0 || type >= CRYPTO_NUM_LOCKS)
913
errstr = "type out of bounds";
917
if (mode & CRYPTO_LOCK)
921
errstr = "already locked";
922
/* must not happen in a single-threaded program
930
else if (mode & CRYPTO_UNLOCK)
934
errstr = "not locked";
938
if (modes[type] != rw)
940
errstr = (rw == CRYPTO_READ) ?
941
"CRYPTO_r_unlock on write lock" :
942
"CRYPTO_w_unlock on read lock";
949
errstr = "invalid mode";
956
//how do we pass a context pointer here?
957
//error("openssl (lock_dbg_cb): %s (mode=%d, type=%d) at %s:%d",
958
// errstr, mode, type, file, line);
962
static unsigned long cryptoIdCallback()
965
unsigned long ret = (unsigned long) GetCurrentThreadId();
967
unsigned long ret = (unsigned long) pthread_self();
975
TcpSocket::TcpSocket(const TcpSocket &other)
979
hostname = other.hostname;
980
portno = other.portno;
984
void TcpSocket::error(const char *fmt, ...)
986
static char buf[256];
987
lastError = "TcpSocket err: ";
990
vsnprintf(buf, 255, fmt, args);
992
lastError.append(buf);
993
fprintf(stderr, "%s\n", lastError.c_str());
997
DOMString &TcpSocket::getLastError()
1004
static bool tcp_socket_inited = false;
1006
void TcpSocket::init()
1008
if (!tcp_socket_inited)
1011
WORD wVersionRequested = MAKEWORD( 2, 2 );
1013
WSAStartup( wVersionRequested, &wsaData );
1016
if (libssl_is_present)
1020
CRYPTO_set_locking_callback(cryptoLockCallback);
1021
CRYPTO_set_id_callback(cryptoIdCallback);
1023
SSL_load_error_strings();
1026
tcp_socket_inited = true;
1036
TcpSocket::~TcpSocket()
1041
bool TcpSocket::isConnected()
1043
if (!connected || sock < 0)
1048
bool TcpSocket::getHaveSSL()
1051
if (libssl_is_present)
1062
void TcpSocket::enableSSL(bool val)
1067
bool TcpSocket::getEnableSSL()
1074
bool TcpSocket::connect(const std::string &hostnameArg, int portnoArg)
1076
hostname = hostnameArg;
1085
static int password_cb(char *buf, int bufLen, int rwflag, void *userdata)
1087
char *password = "password";
1088
if (bufLen < (int)(strlen(password)+1))
1091
strcpy(buf,password);
1092
int ret = strlen(password);
1096
static void infoCallback(const SSL *ssl, int where, int ret)
1102
printf("## %d SSL ALERT: %s\n", where, SSL_alert_desc_string_long(ret));
1107
printf("## %d SSL: %s\n", where, SSL_state_string_long(ssl));
1116
bool TcpSocket::startTls()
1119
error("SSL starttls() error: client not compiled with SSL enabled");
1122
if (!libssl_is_present)
1124
error("SSL starttls() error: the correct version of libssl was not found");
1131
//SSL_METHOD *meth = SSLv23_method();
1132
//SSL_METHOD *meth = SSLv3_client_method();
1133
SSL_METHOD *meth = TLSv1_client_method();
1134
sslContext = SSL_CTX_new(meth);
1135
//SSL_CTX_set_info_callback(sslContext, infoCallback);
1138
* For now, let's accept all connections. Ignore this
1141
char *keyFile = "client.pem";
1142
char *caList = "root.pem";
1143
//# Load our keys and certificates
1144
if (!(SSL_CTX_use_certificate_chain_file(sslContext, keyFile)))
1146
fprintf(stderr, "Can't read certificate file\n");
1151
SSL_CTX_set_default_passwd_cb(sslContext, password_cb);
1153
if (!(SSL_CTX_use_PrivateKey_file(sslContext, keyFile, SSL_FILETYPE_PEM)))
1155
fprintf(stderr, "Can't read key file\n");
1160
//## Load the CAs we trust
1161
if (!(SSL_CTX_load_verify_locations(sslContext, caList, 0)))
1163
fprintf(stderr, "Can't read CA list\n");
1169
/* Connect the SSL socket */
1170
sslStream = SSL_new(sslContext);
1171
SSL_set_fd(sslStream, sock);
1173
int ret = SSL_connect(sslStream);
1176
error("SSL connection not successful");
1182
int err = SSL_get_error(sslStream, ret);
1183
error("SSL connect error %d", err);
1190
#endif /* HAVE_SSL */
1194
bool TcpSocket::connect()
1196
if (hostname.size()<1)
1198
error("open: null hostname");
1204
error("open: bad port number");
1208
sock = socket(PF_INET, SOCK_STREAM, 0);
1211
error("open: error creating socket");
1215
char *c_hostname = (char *)hostname.c_str();
1216
struct hostent *server = gethostbyname(c_hostname);
1219
error("open: could not locate host '%s'", c_hostname);
1223
struct sockaddr_in serv_addr;
1224
mybzero((char *) &serv_addr, sizeof(serv_addr));
1225
serv_addr.sin_family = AF_INET;
1226
mybcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr,
1228
serv_addr.sin_port = htons(portno);
1230
int ret = ::connect(sock, (const sockaddr *)&serv_addr, sizeof(serv_addr));
1233
error("open: could not connect to host '%s'", c_hostname);
1246
bool TcpSocket::disconnect()
1251
if (libssl_is_present)
1257
int r = SSL_shutdown(sslStream);
1261
break; /* Success */
1265
error("Shutdown failed");
1268
SSL_free(sslStream);
1271
SSL_CTX_free(sslContext);
1291
bool TcpSocket::setReceiveTimeout(unsigned long millis)
1293
receiveTimeout = millis;
1298
* For normal sockets, return the number of bytes waiting to be received.
1299
* For SSL, just return >0 when something is ready to be read.
1301
long TcpSocket::available()
1308
if (ioctlsocket(sock, FIONREAD, (unsigned long *)&count) != 0)
1311
if (ioctl(sock, FIONREAD, &count) != 0)
1314
if (count<=0 && sslEnabled)
1317
if (libssl_is_present)
1319
return SSL_pending(sslStream);
1328
bool TcpSocket::write(int ch)
1332
error("write: socket closed");
1335
unsigned char c = (unsigned char)ch;
1340
if (libssl_is_present)
1342
int r = SSL_write(sslStream, &c, 1);
1345
switch(SSL_get_error(sslStream, r))
1348
error("SSL write problem");
1357
if (send(sock, (const char *)&c, 1, 0) < 0)
1358
//if (send(sock, &c, 1, 0) < 0)
1360
error("write: could not send data");
1367
bool TcpSocket::write(char *str)
1371
error("write(str): socket closed");
1374
int len = strlen(str);
1379
if (libssl_is_present)
1381
int r = SSL_write(sslStream, (unsigned char *)str, len);
1384
switch(SSL_get_error(sslStream, r))
1387
error("SSL write problem");
1396
if (send(sock, str, len, 0) < 0)
1397
//if (send(sock, &c, 1, 0) < 0)
1399
error("write: could not send data");
1406
bool TcpSocket::write(const std::string &str)
1408
return write((char *)str.c_str());
1411
int TcpSocket::read()
1416
//We'll use this loop for timeouts, so that SSL and plain sockets
1417
//will behave the same way
1418
if (receiveTimeout > 0)
1420
unsigned long tim = 0;
1423
int avail = available();
1426
if (tim >= receiveTimeout)
1441
if (libssl_is_present)
1445
int r = SSL_read(sslStream, &ch, 1);
1446
unsigned long err = SSL_get_error(sslStream, r);
1449
case SSL_ERROR_NONE:
1451
case SSL_ERROR_ZERO_RETURN:
1453
case SSL_ERROR_SYSCALL:
1454
error("SSL read problem(syscall) %s",
1455
ERR_error_string(ERR_get_error(), NULL));
1458
error("SSL read problem %s",
1459
ERR_error_string(ERR_get_error(), NULL));
1467
if (recv(sock, (char *)&ch, 1, 0) <= 0)
1469
error("read: could not receive data");
1477
std::string TcpSocket::readLine()
1481
while (isConnected())
1486
if (ch=='\r' || ch=='\n')
1488
ret.push_back((char)ch);
1503
//########################################################################
1504
//# E N D O F F I L E
1505
//########################################################################