From 6d932bfaf11e4699355fedc45e28b353b8877130 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Thu, 18 Sep 2014 21:52:10 +0000 Subject: merge into trunk git-svn-id: http://svn.miranda-ng.org/main/trunk@10515 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- .../WhatsApp/src/WhatsAPI++/BinTreeNodeReader.cpp | 3 - .../WhatsApp/src/WhatsAPI++/BinTreeNodeWriter.cpp | 1 - protocols/WhatsApp/src/WhatsAPI++/ByteArray.cpp | 6 - protocols/WhatsApp/src/WhatsAPI++/FMessage.cpp | 1 - protocols/WhatsApp/src/WhatsAPI++/PhoneNumber.cpp | 297 +++++++++++++++++++++ protocols/WhatsApp/src/WhatsAPI++/PhoneNumber.h | 23 ++ .../WhatsApp/src/WhatsAPI++/ProtocolTreeNode.cpp | 2 - protocols/WhatsApp/src/WhatsAPI++/WAConnection.h | 1 - protocols/WhatsApp/src/WhatsAPI++/WARegister.cpp | 94 +++++++ protocols/WhatsApp/src/WhatsAPI++/WARegister.h | 23 ++ protocols/WhatsApp/src/WhatsAPI++/utilities.cpp | 267 +++++++++--------- protocols/WhatsApp/src/WhatsAPI++/utilities.h | 7 - 12 files changed, 557 insertions(+), 168 deletions(-) create mode 100644 protocols/WhatsApp/src/WhatsAPI++/PhoneNumber.cpp create mode 100644 protocols/WhatsApp/src/WhatsAPI++/PhoneNumber.h create mode 100644 protocols/WhatsApp/src/WhatsAPI++/WARegister.cpp create mode 100644 protocols/WhatsApp/src/WhatsAPI++/WARegister.h (limited to 'protocols/WhatsApp/src/WhatsAPI++') diff --git a/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeReader.cpp b/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeReader.cpp index 9da677ba87..388bf10e4a 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeReader.cpp +++ b/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeReader.cpp @@ -342,6 +342,3 @@ int BinTreeNodeReader::readInt24(ISocketConnection* in) { return value; } - - - diff --git a/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeWriter.cpp b/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeWriter.cpp index 2c244d53b7..6936de9a8b 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeWriter.cpp +++ b/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeWriter.cpp @@ -264,4 +264,3 @@ BinTreeNodeWriter::~BinTreeNodeWriter() { if (this->out != NULL) delete this->out; } - diff --git a/protocols/WhatsApp/src/WhatsAPI++/ByteArray.cpp b/protocols/WhatsApp/src/WhatsAPI++/ByteArray.cpp index c9117bcfee..d52b10c549 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/ByteArray.cpp +++ b/protocols/WhatsApp/src/WhatsAPI++/ByteArray.cpp @@ -147,9 +147,3 @@ void ByteArrayOutputStream::print() { _LOGDATA("%s", numbers.c_str()); _LOGDATA("]"); } - - - - - - diff --git a/protocols/WhatsApp/src/WhatsAPI++/FMessage.cpp b/protocols/WhatsApp/src/WhatsAPI++/FMessage.cpp index b8586eb538..0eca3aeef7 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/FMessage.cpp +++ b/protocols/WhatsApp/src/WhatsAPI++/FMessage.cpp @@ -125,4 +125,3 @@ unsigned char FMessage::getMessage_WA_Type(std::string* type) { return WA_TYPE_UNDEFINED; } - diff --git a/protocols/WhatsApp/src/WhatsAPI++/PhoneNumber.cpp b/protocols/WhatsApp/src/WhatsAPI++/PhoneNumber.cpp new file mode 100644 index 0000000000..8171094d5c --- /dev/null +++ b/protocols/WhatsApp/src/WhatsAPI++/PhoneNumber.cpp @@ -0,0 +1,297 @@ +/* + * PhoneNumber.cpp + * + */ + +#include "PhoneNumber.h" +#include "WAException.h" + +struct CountryDescr +{ + char *name; + int countryCode, mcc, mnc; + char *ISO3166, *ISO639; +} +static countries[] = +{ + { "Russia", 7, 250, 20, "RU", "ru" }, + { "Kazakhstan", 7, 401, 77, "KZ", "kk" }, + { "Afghanistan", 93, 412, 1, "AF", "ps" }, + { "Albania", 355, 276, 1, "AL", "sq" }, + { "Alberta", 1403, 302, 720, "CA", "en" }, + { "Alberta", 1780, 302, 720, "CA", "en" }, + { "Algeria", 213, 603, 1, "DZ", "ar" }, + { "Andorra", 376, 213, 3, "AD", "ca" }, + { "Angola", 244, 631, 2, "AO", "pt" }, + { "Anguilla", 1264, 365, 10, "AI", "en" }, + { "Antarctica (Australian bases)", 6721, 232, 1, "AQ", "en" }, + { "Antigua and Barbuda", 1268, 344, 50, "AG", "en" }, + { "Argentina", 54, 722, 10, "AR", "es" }, + { "Armenia", 374, 283, 10, "AM", "hy" }, + { "Aruba", 297, 363, 1, "AW", "nl" }, + { "Ascension", 247, 658, 1, "AC", "en" }, + { "Australia", 61, 505, 1, "AU", "en" }, + { "Austria", 43, 232, 3, "AT", "de" }, + { "Azerbaijan", 994, 400, 1, "AZ", "az" }, + { "Bahamas", 1242, 364, 39, "BS", "en" }, + { "Bahrain", 973, 426, 1, "BH", "ar" }, + { "Bangladesh", 880, 470, 1, "BD", "bn" }, + { "Barbados", 1246, 342, 750, "BB", "en" }, + { "Belarus", 375, 257, 1, "BY", "be" }, + { "Belgium", 32, 206, 1, "BE", "nl" }, + { "Belize", 501, 702, 67, "BZ", "es" }, + { "Benin", 229, 616, 1, "BJ", "fr" }, + { "Bermuda", 1441, 350, 1, "BM", "en" }, + { "Bhutan", 975, 402, 11, "BT", "dz" }, + { "Bolivia", 591, 736, 1, "BO", "es" }, + { "Bosnia and Herzegovina", 387, 218, 3, "BA", "bs" }, + { "Botswana", 267, 652, 4, "BW", "en" }, + { "Brazil", 55, 724, 2, "BR", "pt" }, + { "British Columbia", 1250, 302, 720, "CA", "en" }, + { "British Columbia", 1604, 302, 720, "CA", "en" }, + { "British Columbia", 1778, 302, 720, "CA", "en" }, + { "British Indian Ocean Territory", 246, 348, 1, "IO", "en" }, + { "British Virgin Islands", 1284, 348, 170, "GB", "en" }, + { "Brunei", 673, 528, 11, "BN", "ms" }, + { "Bulgaria", 359, 284, 3, "BG", "bg" }, + { "Burkina Faso", 226, 613, 1, "BF", "fr" }, + { "Burundi", 257, 642, 82, "BI", "rn" }, + { "Cambodia", 855, 456, 2, "KH", "km" }, + { "Cameroon", 237, 624, 1, "CM", "fr" }, + { "Cape Verde", 238, 625, 1, "CV", "pt" }, + { "Cayman Islands", 1345, 346, 50, "GB", "en" }, + { "Central African Republic", 236, 623, 3, "CF", "sg" }, + { "Chad", 235, 622, 4, "TD", "fr" }, + { "Chile", 56, 730, 2, "CL", "es" }, + { "China", 86, 460, 3, "CN", "en" }, + { "Colombia", 57, 732, 102, "CO", "es" }, + { "Comoros", 269, 654, 1, "KM", "fr" }, + { "Democratic Republic of the Congo", 243, 630, 1, "CD", "fr" }, + { "Republic of the Congo", 242, 629, 1, "CG", "fr" }, + { "Cook Islands", 682, 548, 1, "CK", "en" }, + { "Costa Rica", 506, 658, 4, "CR", "es" }, + { "Cote d'Ivoire", 712, 612, 1, "CI", "fr" }, + { "Croatia", 385, 219, 1, "HR", "hr" }, + { "Cuba", 53, 368, 1, "CU", "es" }, + { "Cyprus", 357, 280, 1, "CY", "el" }, + { "Czech Republic", 420, 230, 2, "CZ", "cs" }, + { "Denmark", 45, 238, 1, "DK", "da" }, + { "Djibouti", 253, 638, 1, "DJ", "fr" }, + { "Dominica", 1767, 366, 20, "DM", "en" }, + { "Dominican Republic", 1809, 370, 1, "DO", "es" }, + { "Dominican Republic", 1829, 370, 1, "DO", "en" }, + { "East Timor", 670, 514, 1, "TL", "pt" }, + { "Ecuador", 593, 740, 0, "EC", "es" }, + { "Egypt", 20, 602, 2, "EG", "ar" }, + { "El Salvador", 503, 706, 1, "SV", "es" }, + { "Equatorial Guinea", 240, 627, 3, "GQ", "es" }, + { "Eritrea", 291, 657, 1, "ER", "ti" }, + { "Estonia", 372, 248, 3, "EE", "et" }, + { "Ethiopia", 251, 636, 11, "ET", "am" }, + { "Falkland Islands", 500, 750, 1, "FK", "en" }, + { "Faroe Islands", 298, 288, 2, "FO", "fo" }, + { "Fiji", 679, 542, 1, "FJ", "en" }, + { "Finland", 358, 244, 5, "FI", "fi" }, + { "France", 33, 208, 9, "FR", "fr" }, + { "French Guiana", 594, 742, 1, "GF", "fr" }, + { "French Polynesia", 689, 547, 15, "PF", "fr" }, + { "Gabon", 241, 628, 1, "GA", "fr" }, + { "Gambia", 220, 607, 1, "GM", "en" }, + { "Gaza Strip", 970, 0, 0, "PS", "ar" }, + { "Georgia", 995, 282, 1, "GE", "ka" }, + { "Germany", 49, 262, 1, "DE", "de" }, + { "Ghana", 233, 620, 2, "GH", "ak" }, + { "Gibraltar", 350, 266, 9, "GI", "en" }, + { "Greece", 30, 202, 5, "GR", "el" }, + { "Greenland", 299, 290, 1, "GL", "kl" }, + { "Grenada", 1473, 352, 30, "GD", "en" }, + { "Guadeloupe", 590, 340, 1, "GP", "fr" }, + { "Guam", 1671, 535, 32, "GU", "en" }, + { "Guatemala", 502, 704, 1, "GT", "es" }, + { "Guinea", 224, 611, 1, "GN", "fr" }, + { "Guinea-Bissau", 245, 632, 3, "GW", "pt" }, + { "Guyana", 592, 738, 1, "GY", "pt" }, + { "Haiti", 509, 372, 2, "HT", "fr" }, + { "Honduras", 504, 708, 2, "HN", "es" }, + { "Hong Kong", 852, 454, 0, "HK", "zh" }, + { "Hungary", 36, 216, 70, "HU", "hu" }, + { "Iceland", 354, 274, 2, "IS", "is" }, + { "India", 91, 404, 30, "IN", "hi" }, + { "Indonesia", 62, 510, 10, "ID", "id" }, + { "Iraq", 964, 418, 20, "IQ", "ar" }, + { "Iran", 98, 432, 35, "IR", "fa" }, + { "Ireland (Eire)", 353, 272, 1, "IE", "en" }, + { "Israel", 972, 425, 1, "IL", "he" }, + { "Italy", 39, 222, 10, "IT", "it" }, + { "Jamaica", 1876, 338, 50, "JM", "en" }, + { "Japan", 81, 440, 1, "JP", "ja" }, + { "Jordan", 962, 416, 77, "JO", "ar" }, + { "Kenya", 254, 639, 7, "KE", "sw" }, + { "Kiribati", 686, 545, 1, "KI", "en" }, + { "Kuwait", 965, 419, 4, "KW", "ar" }, + { "Kyrgyzstan", 996, 437, 1, "KG", "ky" }, + { "Laos", 856, 457, 1, "LA", "lo" }, + { "Latvia", 371, 247, 2, "LV", "lv" }, + { "Lebanon", 961, 415, 1, "LB", "ar" }, + { "Lesotho", 266, 651, 1, "LS", "st" }, + { "Liberia", 231, 618, 7, "LR", "en" }, + { "Libya", 218, 606, 0, "LY", "ar" }, + { "Liechtenstein", 423, 295, 2, "LI", "de" }, + { "Lithuania", 370, 246, 3, "LT", "lt" }, + { "Luxembourg", 352, 270, 99, "LU", "fr" }, + { "Macau", 853, 455, 2, "MO", "pt" }, + { "Republic of Macedonia", 389, 294, 1, "MK", "mk" }, + { "Madagascar", 261, 646, 2, "MG", "mg" }, + { "Malawi", 265, 650, 1, "MW", "ny" }, + { "Malaysia", 60, 502, 16, "MY", "en" }, + { "Maldives", 960, 472, 1, "MV", "dv" }, + { "Mali", 223, 610, 2, "ML", "fr" }, + { "Malta", 356, 278, 1, "MT", "mt" }, + { "Manitoba", 1204, 302, 720, "CA", "en" }, + { "Marshall Islands", 692, 551, 1, "MH", "mh" }, + { "Martinique", 596, 340, 1, "MQ", "fr" }, + { "Mauritania", 222, 609, 2, "MR", "ar" }, + { "Mauritius", 230, 617, 1, "MU", "en" }, + { "Mayotte", 262, 654, 1, "YT", "fr" }, + { "Mexico", 52, 334, 3, "MX", "es" }, + { "Federated States of Micronesia", 691, 550, 1, "FM", "en" }, + { "Moldova", 373, 259, 1, "MD", "ru" }, + { "Monaco", 377, 212, 1, "MC", "fr" }, + { "Mongolia", 976, 428, 91, "MN", "mn" }, + { "Montenegro", 382, 297, 2, "ME", "sr" }, + { "Montserrat", 1664, 354, 860, "MS", "en" }, + { "Morocco", 212, 604, 0, "MA", "ar" }, + { "Mozambique", 258, 643, 4, "MZ", "pt" }, + { "Myanmar", 95, 414, 1, "MM", "my" }, + { "Namibia", 264, 649, 3, "NA", "en" }, + { "Nauru", 674, 536, 2, "NR", "na" }, + { "Netherlands", 31, 204, 4, "NL", "nl" }, + { "Netherlands Antilles", 599, 362, 51, "AN", "nl" }, + { "Nepal", 977, 429, 1, "NP", "ne" }, + { "New Brunswick", 1506, 302, 720, "CA", "en" }, + { "New Caledonia", 687, 546, 1, "NC", "fr" }, + { "New Zealand", 64, 530, 1, "NZ", "en" }, + { "Newfoundland", 1709, 302, 720, "CA", "en" }, + { "Nicaragua", 505, 710, 30, "NI", "es" }, + { "Niger", 227, 614, 4, "NE", "fr" }, + { "Nigeria", 234, 621, 20, "NG", "ha" }, + { "Niue", 683, 555, 1, "NU", "en" }, + { "Norfolk Island", 6723, 505, 10, "NF", "en" }, + { "North Korea", 850, 467, 193, "KP", "ko" }, + { "Northern Mariana Islands", 1670, 534, 1, "MP", "en" }, + { "Northwest Territories", 1867, 302, 720, "CA", "en" }, + { "Norway", 47, 242, 4, "NO", "nb" }, + { "Nova Scotia", 1902, 302, 720, "CA", "en" }, + { "Oman", 968, 422, 2, "OM", "ar" }, + { "Ontario", 1416, 302, 720, "CA", "en" }, + { "Ontario", 1519, 302, 720, "CA", "en" }, + { "Ontario", 1613, 302, 720, "CA", "en" }, + { "Ontario", 1647, 302, 720, "CA", "en" }, + { "Ontario", 1705, 302, 720, "CA", "en" }, + { "Ontario", 1807, 302, 720, "CA", "en" }, + { "Ontario", 1905, 302, 720, "CA", "en" }, + { "Pakistan", 92, 410, 1, "PK", "en" }, + { "Palau", 680, 552, 80, "PW", "en" }, + { "Palestine", 970, 425, 6, "PS", "ar" }, + { "Panama", 507, 714, 2, "PA", "es" }, + { "Papua New Guinea", 675, 537, 3, "PG", "ho" }, + { "Paraguay", 595, 744, 6, "PY", "es" }, + { "Peru", 51, 716, 6, "PE", "es" }, + { "Philippines", 63, 515, 2, "PH", "fil" }, + { "Poland", 48, 260, 3, "PL", "pl" }, + { "Portugal", 351, 268, 1, "PT", "pt" }, + { "Qatar", 974, 427, 2, "QA", "ar" }, + { "Quebec", 1418, 302, 720, "CA", "en" }, + { "Quebec", 1450, 302, 720, "CA", "en" }, + { "Quebec", 1514, 302, 720, "CA", "en" }, + { "Quebec", 1819, 302, 720, "CA", "en" }, + { "Reunion", 262, 647, 0, "RE", "fr" }, + { "Romania", 40, 226, 1, "RO", "ro" }, + { "Rwanda", 250, 635, 10, "RW", "rw" }, + { "Saint-Barthelemy", 590, 340, 1, "BL", "fr" }, + { "Saint Helena", 290, 658, 1, "SH", "en" }, + { "Saint Kitts and Nevis", 1869, 356, 50, "KN", "en" }, + { "Saint Lucia", 1758, 358, 50, "LC", "en" }, + { "Saint Martin (French side)", 590, 340, 1, "MF", "fr" }, + { "Saint Pierre and Miquelon", 508, 308, 2, "PM", "fr" }, + { "Saint Vincent and the Grenadines", 1670, 360, 70, "VC", "en" }, + { "Samoa", 685, 549, 1, "WS", "sm" }, + { "Sao Tome and Principe", 239, 626, 1, "ST", "pt" }, + { "Saskatchewan", 1306, 302, 720, "CA", "en" }, + { "Saudi Arabia", 966, 420, 4, "SA", "ar" }, + { "Senegal", 221, 608, 1, "SN", "wo" }, + { "Serbia", 381, 220, 1, "RS", "sr" }, + { "Seychelles", 248, 633, 10, "SC", "fr" }, + { "Sierra Leone", 232, 619, 4, "SL", "en" }, + { "Singapore", 65, 525, 1, "SG", "en" }, + { "Slovakia", 421, 231, 4, "SK", "sk" }, + { "Slovenia", 386, 293, 31, "SI", "sl" }, + { "Solomon Islands", 677, 540, 2, "SB", "en" }, + { "Somalia", 252, 637, 82, "SO", "so" }, + { "South Africa", 27, 655, 1, "ZA", "xh" }, + { "South Korea", 82, 450, 5, "KR", "ko" }, + { "South Sudan", 211, 659, 2, "SS", "en" }, + { "Spain", 34, 214, 1, "ES", "es" }, + { "Sri Lanka", 94, 413, 1, "LK", "si" }, + { "Sudan", 249, 634, 7, "SD", "ar" }, + { "Suriname", 597, 746, 3, "SR", "nl" }, + { "Swaziland", 268, 653, 10, "SZ", "ss" }, + { "Sweden", 46, 240, 7, "SE", "sv" }, + { "Switzerland", 41, 228, 3, "CH", "de" }, + { "Syria", 963, 417, 1, "SY", "ar" }, + { "Taiwan", 886, 466, 1, "TW", "cmn" }, + { "Tajikistan", 992, 436, 1, "TJ", "tg" }, + { "Tanzania", 255, 640, 4, "TZ", "sw" }, + { "Thailand", 66, 520, 0, "TH", "th" }, + { "Togo", 228, 615, 1, "TG", "fr" }, + { "Tokelau", 690, 690, 1, "TK", "tkl" }, + { "Tonga", 676, 539, 1, "TO", "to" }, + { "Trinidad and Tobago", 1868, 374, 12, "TT", "en" }, + { "Tunisia", 216, 605, 1, "TN", "ar" }, + { "Turkey", 90, 286, 2, "TR", "tr" }, + { "Turkmenistan", 993, 438, 1, "TM", "tk" }, + { "Turks and Caicos Islands", 1649, 376, 50, "TC", "en" }, + { "Tuvalu", 688, 553, 1, "TV", "tvl" }, + { "Uganda", 256, 641, 14, "UG", "sw" }, + { "Ukraine", 380, 255, 1, "UA", "uk" }, + { "United Arab Emirates", 971, 424, 2, "AE", "ar" }, + { "United Kingdom", 44, 234, 10, "GB", "en" }, + { "United States of America", 1, 310, 4, "US", "en" }, + { "Uruguay", 598, 748, 7, "UY", "es" }, + { "Uzbekistan", 998, 434, 7, "UZ", "uz" }, + { "Vanuatu", 678, 541, 5, "VU", "bi" }, + { "Venezuela", 58, 734, 4, "VE", "es" }, + { "Vietnam", 84, 452, 1, "VN", "vi" }, + { "U.S. Virgin Islands", 1340, 332, 4, "VI", "en" }, + { "Wallis and Futuna", 681, 543, 1, "WF", "fr" }, + { "West Bank", 970, 0, 1, "PS", "ar" }, + { "Yemen", 967, 421, 2, "YE", "ar" }, + { "Zambia", 260, 645, 2, "ZM", "en" }, + { "Zimbabwe", 263, 648, 2, "ZW", "en" } +}; + +PhoneNumber::PhoneNumber(const std::string &szNumber) +{ + int cc1 = atoi(szNumber.substr(0, 1).c_str()), cc2 = atoi(szNumber.substr(0, 2).c_str()), cc3 = atoi(szNumber.substr(0, 3).c_str()); + + for (int i = 0; i < _countof(countries); i++) { + CountryDescr &p = countries[i]; + if (p.countryCode != cc1 && p.countryCode != cc2 && p.countryCode != cc3) + continue; + + if (p.countryCode == 7) + if (i == 0 && (cc2 == '77' || cc2 == '76')) + continue; + + this->Country = p.name; + this->countryCode = p.countryCode; + this->Number = szNumber.substr(1 + (size_t)floor(log10(double(p.countryCode)))); + this->ISO3166 = p.ISO3166; + this->ISO639 = p.ISO639; + this->mcc = p.mcc; + this->mnc = p.mnc; + return; + } + + throw new WAException("Could not dissect phone number " + szNumber); +} diff --git a/protocols/WhatsApp/src/WhatsAPI++/PhoneNumber.h b/protocols/WhatsApp/src/WhatsAPI++/PhoneNumber.h new file mode 100644 index 0000000000..aa3dd16ef9 --- /dev/null +++ b/protocols/WhatsApp/src/WhatsAPI++/PhoneNumber.h @@ -0,0 +1,23 @@ +/* + * PhoneNumber.h + * + */ + +#ifndef PHONENUMBER_H_ +#define PHONENUMBER_H_ + +#include + +struct PhoneNumber +{ + PhoneNumber(const std::string &number); + + std::string Country; + std::string Number; + + const char *ISO3166, *ISO639; + int countryCode; + int mcc, mnc; +}; + +#endif /* PHONENUMBER_H_ */ diff --git a/protocols/WhatsApp/src/WhatsAPI++/ProtocolTreeNode.cpp b/protocols/WhatsApp/src/WhatsAPI++/ProtocolTreeNode.cpp index be6a658acb..a44fa27812 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/ProtocolTreeNode.cpp +++ b/protocols/WhatsApp/src/WhatsAPI++/ProtocolTreeNode.cpp @@ -131,5 +131,3 @@ void ProtocolTreeNode::require(ProtocolTreeNode *node, const string& tag) { if (!tagEquals(node, tag)) throw WAException("failed require. node:" + node->toString() + "tag: " + tag, WAException::CORRUPT_STREAM_EX, 0); } - - diff --git a/protocols/WhatsApp/src/WhatsAPI++/WAConnection.h b/protocols/WhatsApp/src/WhatsAPI++/WAConnection.h index 9ee5d3e48f..96a813ecd0 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/WAConnection.h +++ b/protocols/WhatsApp/src/WhatsAPI++/WAConnection.h @@ -462,5 +462,4 @@ class WAConnection { void sendDeleteAccount() throw(WAException); }; - #endif /* WACONNECTION_H_ */ diff --git a/protocols/WhatsApp/src/WhatsAPI++/WARegister.cpp b/protocols/WhatsApp/src/WhatsAPI++/WARegister.cpp new file mode 100644 index 0000000000..d67d2f4a8c --- /dev/null +++ b/protocols/WhatsApp/src/WhatsAPI++/WARegister.cpp @@ -0,0 +1,94 @@ +/* + * WARegister.cpp + * + */ + +#include "../common.h" // #TODO Remove Miranda-dependency + +#include "WARegister.h" +#include "PhoneNumber.h" + +using namespace Utilities; + +///////////////////////////////////////////////////////////////////////////////////////// +// Token generation + +static char WaKey[] = "/UIGKU1FVQa+ATM2A0za7G2KI9S/CwPYjgAbc67v7ep42eO/WeTLx1lb1cHwxpsEgF4+PmYpLd2YpGUdX/A2JQitsHzDwgcdBpUf7psX1BU="; +static char WaSignature[] = "MIIDMjCCAvCgAwIBAgIETCU2pDALBgcqhkjOOAQDBQAwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFDASBgNVBAcTC1NhbnRhIENsYXJhMRYwFAYDVQQKEw1XaGF0c0FwcCBJbmMuMRQwEgYDVQQLEwtFbmdpbmVlcmluZzEUMBIGA1UEAxMLQnJpYW4gQWN0b24wHhcNMTAwNjI1MjMwNzE2WhcNNDQwMjE1MjMwNzE2WjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEUMBIGA1UEBxMLU2FudGEgQ2xhcmExFjAUBgNVBAoTDVdoYXRzQXBwIEluYy4xFDASBgNVBAsTC0VuZ2luZWVyaW5nMRQwEgYDVQQDEwtCcmlhbiBBY3RvbjCCAbgwggEsBgcqhkjOOAQBMIIBHwKBgQD9f1OBHXUSKVLfSpwu7OTn9hG3UjzvRADDHj+AtlEmaUVdQCJR+1k9jVj6v8X1ujD2y5tVbNeBO4AdNG/yZmC3a5lQpaSfn+gEexAiwk+7qdf+t8Yb+DtX58aophUPBPuD9tPFHsMCNVQTWhaRMvZ1864rYdcq7/IiAxmd0UgBxwIVAJdgUI8VIwvMspK5gqLrhAvwWBz1AoGBAPfhoIXWmz3ey7yrXDa4V7l5lK+7+jrqgvlXTAs9B4JnUVlXjrrUWU/mcQcQgYC0SRZxI+hMKBYTt88JMozIpuE8FnqLVHyNKOCjrh4rs6Z1kW6jfwv6ITVi8ftiegEkO8yk8b6oUZCJqIPf4VrlnwaSi2ZegHtVJWQBTDv+z0kqA4GFAAKBgQDRGYtLgWh7zyRtQainJfCpiaUbzjJuhMgo4fVWZIvXHaSHBU1t5w//S0lDK2hiqkj8KpMWGywVov9eZxZy37V26dEqr/c2m5qZ0E+ynSu7sqUD7kGx/zeIcGT0H+KAVgkGNQCo5Uc0koLRWYHNtYoIvt5R3X6YZylbPftF/8ayWTALBgcqhkjOOAQDBQADLwAwLAIUAKYCp0d6z4QQdyN74JDfQ2WCyi8CFDUM4CaNB+ceVXdKtOrNTQcc0e+t"; +static char WaClassesMd5[] = "iV15qOB/jPIidogqfJ/oJA=="; + +std::string WAToken::GenerateToken(const string &number) +{ + unsigned int keyLen, dataLen, classesLen; + mir_ptr key((BYTE*)mir_base64_decode(WaKey, &keyLen)); + mir_ptr data((BYTE*)mir_base64_decode(WaSignature, &dataLen)); + mir_ptr classes((BYTE*)mir_base64_decode(WaClassesMd5, &classesLen)); + + BYTE opad[64], ipad[64]; + memset(opad, 0x5C, sizeof(opad)); + memset(ipad, 0x36, sizeof(ipad)); + for (int i = 0; i < sizeof(opad); i++) { + opad[i] = (BYTE)(opad[i] ^ key[i]); + ipad[i] = (BYTE)(ipad[i] ^ key[i]); + } + + BYTE hash1[MIR_SHA1_HASH_SIZE], hash2[MIR_SHA1_HASH_SIZE]; + mir_sha1_ctx ctx; + mir_sha1_init(&ctx); + mir_sha1_append(&ctx, ipad, sizeof(ipad)); + mir_sha1_append(&ctx, data, dataLen); + mir_sha1_append(&ctx, classes, classesLen); + mir_sha1_append(&ctx, (PBYTE)number.c_str(), (int)number.size()); + mir_sha1_finish(&ctx, hash1); + + mir_sha1_init(&ctx); + mir_sha1_append(&ctx, opad, sizeof(opad)); + mir_sha1_append(&ctx, hash1, sizeof(hash1)); + mir_sha1_finish(&ctx, hash2); + + ptrA result(mir_urlEncode(ptrA(mir_base64_encode(hash2, sizeof(hash2))))); + return std::string(result); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Account registration + +CMStringA WARegister::RequestCodeUrl(const std::string &phoneNumber, const std::string &code) +{ + try { + std::string id = GenerateIdentity(phoneNumber); + + PhoneNumber pn(phoneNumber); + std::string token = WAToken::GenerateToken(pn.Number); + + const char *n = pn.Number.c_str(); + + if (!code.empty()) + return CMStringA(FORMAT, "https://v.whatsapp.net/v2/register?cc=%d&in=%s&id=%s&code=%s", pn.countryCode, n, id.c_str(), code.c_str()); + + return CMStringA(FORMAT, "https://v.whatsapp.net/v2/code?cc=%d&in=%s&to=%d%s&method=sms&mcc=%03d&mnc=%03d&token=%s&id=%s&lg=%s&lc=%s", + pn.countryCode, n, pn.countryCode, n, pn.mcc, pn.mnc, token.c_str(), id.c_str(), pn.ISO639, pn.ISO3166); + } + catch (...) + {} + + return CMStringA(); +} + +std::string WARegister::GenerateIdentity(const std::string &phone) +{ + std::string id = phone; + std::reverse(id.begin(), id.end()); + + BYTE hash[MIR_SHA1_HASH_SIZE]; + mir_sha1_hash((PBYTE)id.c_str(), (int)id.length(), hash); + + id.clear(); + for (int i = 0; i < sizeof(hash); i++) { + char buf[10]; + sprintf_s(buf, "%%%02x", hash[i]); + id += buf; + } + + return id; +} diff --git a/protocols/WhatsApp/src/WhatsAPI++/WARegister.h b/protocols/WhatsApp/src/WhatsAPI++/WARegister.h new file mode 100644 index 0000000000..f2fe0e230b --- /dev/null +++ b/protocols/WhatsApp/src/WhatsAPI++/WARegister.h @@ -0,0 +1,23 @@ +/* + * WARegister.h + */ + +#ifndef WAREGISTER_H_ +#define WAREGISTER_H_ + +#include + +struct WAToken +{ + static std::string GenerateToken(const std::string &number); +}; + +class WARegister +{ + static std::string GenerateIdentity(const std::string &phone); + +public: + static CMStringA RequestCodeUrl(const std::string &phone, const std::string &code); +}; + +#endif /* WAREGISTER_H_ */ diff --git a/protocols/WhatsApp/src/WhatsAPI++/utilities.cpp b/protocols/WhatsApp/src/WhatsAPI++/utilities.cpp index f2603f9f8d..dc28b86c69 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/utilities.cpp +++ b/protocols/WhatsApp/src/WhatsAPI++/utilities.cpp @@ -13,41 +13,24 @@ #include #include -namespace Utilities{ - +namespace Utilities { + const static char digits[] = { - '0' , '1' , '2' , '3' , '4' , '5' , - '6' , '7' , '8' , '9' , 'a' , 'b' , - 'c' , 'd' , 'e' , 'f' , 'g' , 'h' , - 'i' , 'j' , 'k' , 'l' , 'm' , 'n' , - 'o' , 'p' , 'q' , 'r' , 's' , 't' , - 'u' , 'v' , 'w' , 'x' , 'y' , 'z' + '0', '1', '2', '3', '4', '5', + '6', '7', '8', '9', 'a', 'b', + 'c', 'd', 'e', 'f', 'g', 'h', + 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', + 'u', 'v', 'w', 'x', 'y', 'z' }; -void configureLogging(const char* ident) { -#ifndef _LOGWIN32 - openlog(ident, 0, LOG_USER); -#endif -} - -void closeLog() { -#ifndef _LOGWIN32 - closelog(); -#endif -} - -std::string getCountryCode(){ - return "34"; -} - std::string reverseString(const std::string& str) { return std::string(str.rbegin(), str.rend()); } - - -std::string itoa(int value, unsigned int base) { +std::string itoa(int value, unsigned int base) +{ const char digitMap[] = "0123456789abcdef"; @@ -70,8 +53,8 @@ std::string itoa(int value, unsigned int base) { // Translating number to string with base: - for (int i = 30; _value && i ; --i) { - buf = digitMap[ _value % base ] + buf; + for (int i = 30; _value && i; --i) { + buf = digitMap[_value % base] + buf; _value /= base; } @@ -79,24 +62,26 @@ std::string itoa(int value, unsigned int base) { } -std::string processIdentity(const std::string& id){ +std::string processIdentity(const std::string& id) +{ std::string buffer_str = reverseString(id); - unsigned char digest[16]; - md5_string(buffer_str, digest); + unsigned char digest[16]; + md5_string(buffer_str, digest); buffer_str.clear(); - for(int i =0; i < 16; i++){ - int tmp = digest[i]+128; + for (int i = 0; i < 16; i++) { + int tmp = digest[i] + 128; int f = tmp & 0xff; - buffer_str = buffer_str.append(itoa(f,16)); + buffer_str = buffer_str.append(itoa(f, 16)); } return buffer_str; } -void debug(const std::string& msg) { +void debug(const std::string& msg) +{ #ifdef _LOGWIN32 cout << "DEBUG: " << msg << endl; #else @@ -104,7 +89,8 @@ void debug(const std::string& msg) { #endif } -std::string str(int64_t i, int radix ) { +std::string str(int64_t i, int radix) +{ if (radix < 2 || radix > 36) throw WAException("radix must be in 2..36"); char buf[65]; @@ -130,34 +116,39 @@ std::string str(int64_t i, int radix ) { return std::string(aux, charPos, (65 - charPos)); } -int64_t randLong() { +int64_t randLong() +{ std::srand((unsigned)time(NULL)); - int64_t r = (int64_t) ((char) (std::rand() % 256)); + int64_t r = (int64_t)((char)(std::rand() % 256)); - for (int i = 0; i < 7 ; i++) - r = (r << 8) + ((char) (std::rand() % 256)); + for (int i = 0; i < 7; i++) + r = (r << 8) + ((char)(std::rand() % 256)); return r; } -int64_t absLong(int64_t num) { - return (num >= 0? num: -num); +int64_t absLong(int64_t num) +{ + return (num >= 0 ? num : -num); } -std::string intToStr(int i) { +std::string intToStr(int i) +{ std::stringstream convert; convert << i; return convert.str(); } -std::string doubleToStr(double d) { +std::string doubleToStr(double d) +{ std::stringstream convert; convert << d; return convert.str(); } -time_t parseBBDate(const string& s) { +time_t parseBBDate(const string& s) +{ _LOGDATA("parse DATE %s", s.c_str()); if (s.length() < 17) return time(NULL); @@ -165,16 +156,17 @@ time_t parseBBDate(const string& s) { struct tm timeinfo; timeinfo.tm_year = atoi(s.substr(0, 4).c_str()) - 1900; timeinfo.tm_mon = atoi(s.substr(4, 2).c_str()) - 1; - timeinfo.tm_mday = atoi(s.substr(6,2).c_str()); - timeinfo.tm_hour = atoi(s.substr(9,2).c_str()); - timeinfo.tm_min = atoi(s.substr(12,2).c_str()); - timeinfo.tm_sec = atoi(s.substr(15,2).c_str()); + timeinfo.tm_mday = atoi(s.substr(6, 2).c_str()); + timeinfo.tm_hour = atoi(s.substr(9, 2).c_str()); + timeinfo.tm_min = atoi(s.substr(12, 2).c_str()); + timeinfo.tm_sec = atoi(s.substr(15, 2).c_str()); //return timegm(&timeinfo); - return mktime(&timeinfo); + return mktime(&timeinfo); } -void logData(const char *format, ...) { +void logData(const char *format, ...) +{ va_list args; va_start(args, format); #ifdef _LOGWIN32 @@ -186,7 +178,8 @@ void logData(const char *format, ...) { } -long long parseLongLong(const std::string& str) { +long long parseLongLong(const std::string& str) +{ std::stringstream sstr(str); long long val; sstr >> val; @@ -194,8 +187,9 @@ long long parseLongLong(const std::string& str) { return val; } -string bytesToHex(unsigned char* bytes, int length) { - string ret(length*2, ' '); +string bytesToHex(unsigned char* bytes, int length) +{ + string ret(length * 2, ' '); string::iterator p = ret.begin(); int i = 0; for (int c = 0; c < length; c++) { @@ -207,13 +201,15 @@ string bytesToHex(unsigned char* bytes, int length) { return ret; } -unsigned char forDigit(int b) { +unsigned char forDigit(int b) +{ if (b < 10) - return (unsigned char) (48 + b); - return (unsigned char) (97 + b - 10); + return (unsigned char)(48 + b); + return (unsigned char)(97 + b - 10); } -bool saveStringToFile(const string& data, const string& filePath) { +bool saveStringToFile(const string& data, const string& filePath) +{ std::ofstream out(filePath.c_str()); if (out.fail()) return false; out << data; @@ -223,10 +219,11 @@ bool saveStringToFile(const string& data, const string& filePath) { return true; } -bool saveBytesToFile(const std::vector& data, const string& filePath) { +bool saveBytesToFile(const std::vector& data, const string& filePath) +{ std::fstream out(filePath.c_str(), ios::out | ios::binary); if (out.fail()) return false; - out.write((const char*) &data[0], data.size()); + out.write((const char*)&data[0], data.size()); if (out.fail()) return false; out.close(); if (out.fail()) return false; @@ -234,7 +231,8 @@ bool saveBytesToFile(const std::vector& data, const string& fileP } -bool saveBytesToFile(const string& data, const string& filePath) { +bool saveBytesToFile(const string& data, const string& filePath) +{ std::fstream out(filePath.c_str(), ios::out | ios::binary); if (out.fail()) return false; out.write(data.c_str(), data.length()); @@ -244,7 +242,8 @@ bool saveBytesToFile(const string& data, const string& filePath) { return true; } -vector* loadFileToBytes(const string& path) { +vector* loadFileToBytes(const string& path) +{ vector* bytes = NULL; std::ifstream in(path.c_str(), ios::in | ios::binary | ios::ate); size_t size = in.tellg(); @@ -254,19 +253,21 @@ vector* loadFileToBytes(const string& path) { char *buffer = new char[size]; in.read(buffer, size); bytes = new vector(buffer, buffer + size); - delete [] buffer; + delete[] buffer; in.close(); if (in.fail()) return NULL; return bytes; } -bool fileExists(const std::string& path) { +bool fileExists(const std::string& path) +{ return _access(path.c_str(), 0) == 0; } -string removeWaDomainFromJid(const string& jid) { +string removeWaDomainFromJid(const string& jid) +{ string result = jid; size_t index = jid.find("@s.whatsapp.net"); @@ -284,7 +285,8 @@ string removeWaDomainFromJid(const string& jid) { return jid; } -string getNameFromPath(const std::string& path) { +string getNameFromPath(const std::string& path) +{ size_t i = path.rfind('/'); if (i == string::npos) i = 0; @@ -293,11 +295,13 @@ string getNameFromPath(const std::string& path) { return path.substr(i); } -vector* getChallengeData(const std::string& challengeFile) { +vector* getChallengeData(const std::string& challengeFile) +{ return loadFileToBytes(challengeFile); } -bool saveChallengeData(const std::vector& data, const std::string& challengeFile) { +bool saveChallengeData(const std::vector& data, const std::string& challengeFile) +{ return saveBytesToFile(data, challengeFile); } @@ -305,42 +309,34 @@ std::string utf8_to_utf16(const std::string& utf8) { std::vector unicode; size_t i = 0; - while (i < utf8.size()) - { + while (i < utf8.size()) { unsigned long uni; size_t todo; bool error = false; unsigned char ch = utf8[i++]; - if (ch <= 0x7F) - { + if (ch <= 0x7F) { uni = ch; todo = 0; } - else if (ch <= 0xBF) - { + else if (ch <= 0xBF) { throw std::logic_error("not a UTF-8 string"); } - else if (ch <= 0xDF) - { - uni = ch&0x1F; + else if (ch <= 0xDF) { + uni = ch & 0x1F; todo = 1; } - else if (ch <= 0xEF) - { - uni = ch&0x0F; + else if (ch <= 0xEF) { + uni = ch & 0x0F; todo = 2; } - else if (ch <= 0xF7) - { - uni = ch&0x07; + else if (ch <= 0xF7) { + uni = ch & 0x07; todo = 3; } - else - { + else { throw std::logic_error("not a UTF-8 string"); } - for (size_t j = 0; j < todo; ++j) - { + for (size_t j = 0; j < todo; ++j) { if (i == utf8.size()) throw std::logic_error("not a UTF-8 string"); unsigned char ch = utf8[i++]; @@ -356,86 +352,63 @@ std::string utf8_to_utf16(const std::string& utf8) unicode.push_back(uni); } std::string utf16; - for (size_t i = 0; i < unicode.size(); ++i) - { + for (size_t i = 0; i < unicode.size(); ++i) { unsigned long uni = unicode[i]; if (uni <= 0x7F) { - utf16 += (char) uni; + utf16 += (char)uni; } else - if (uni <= 0xFFFF) - { + if (uni <= 0xFFFF) { stringstream value; value << std::setw(4) << std::setfill('0') << Utilities::itoa(uni, 16).c_str(); utf16 += "\\u" + value.str(); - } - else - { - stringstream value1, value2; - uni -= 0x10000; - value1 << std::setw(4) << std::setfill('0') << Utilities::itoa(((uni >> 10) + 0xD800), 16); - utf16 += "\\u" + value1.str(); - - value2 << std::setw(4) << std::setfill('0') << Utilities::itoa(((uni & 0x3FF) + 0xDC00), 16); - utf16 += "\\u" + value2.str(); - } + } + else { + stringstream value1, value2; + uni -= 0x10000; + value1 << std::setw(4) << std::setfill('0') << Utilities::itoa(((uni >> 10) + 0xD800), 16); + utf16 += "\\u" + value1.str(); + + value2 << std::setw(4) << std::setfill('0') << Utilities::itoa(((uni & 0x3FF) + 0xDC00), 16); + utf16 += "\\u" + value2.str(); + } } return utf16; } std::string string_format(const char* fmt, va_list ap) { - int size = 100; - std::string str; - while (1) { - str.resize(size); - //va_start(ap, fmt); - int n = vsnprintf((char *)str.c_str(), size, fmt, ap); - //va_end(ap); - if (n > -1 && n < size) { - str.resize(n); - return str; - } - if (n > -1) - size = n + 1; - else - size *= 2; - } - return str; + int size = 100; + std::string str; + while (1) { + str.resize(size); + //va_start(ap, fmt); + int n = vsnprintf((char *)str.c_str(), size, fmt, ap); + //va_end(ap); + if (n > -1 && n < size) { + str.resize(n); + return str; + } + if (n > -1) + size = n + 1; + else + size *= 2; + } + return str; } std::string string_format(const std::string fmt, va_list ap) { - return string_format(fmt.c_str(), ap); - /* - int size = 100; - std::string str; - //va_list ap; - while (1) { - str.resize(size); - //va_start(ap, fmt); - int n = vsnprintf((char *)str.c_str(), size, fmt.c_str(), ap); - //va_end(ap); - if (n > -1 && n < size) { - str.resize(n); - return str; - } - if (n > -1) - size = n + 1; - else - size *= 2; - } - return str; - */ + return string_format(fmt.c_str(), ap); } std::string string_format(const std::string fmt, ...) { - va_list ap; - va_start(ap, fmt); - std::string ret = string_format(fmt, ap); - va_end(ap); - return ret; + va_list ap; + va_start(ap, fmt); + std::string ret = string_format(fmt, ap); + va_end(ap); + return ret; } } diff --git a/protocols/WhatsApp/src/WhatsAPI++/utilities.h b/protocols/WhatsApp/src/WhatsAPI++/utilities.h index fec1b29862..d0096489e2 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/utilities.h +++ b/protocols/WhatsApp/src/WhatsAPI++/utilities.h @@ -49,9 +49,6 @@ std::string base64_encode(void*, size_t); void md5_string(const std::string& data, unsigned char digest[16]); namespace Utilities{ - void configureLogging(const char* ident); - void closeLog(); - string getCountryCode(); string getMcc(); string getMnc(); string reverseString(const string& str); @@ -78,9 +75,5 @@ namespace Utilities{ std::vector* getChallengeData(const std::string& file); bool saveChallengeData(const std::vector& data, const std::string& file); std::string utf8_to_utf16(const std::string& utf8); - std::string string_format(const std::string fmt, ...); - std::string string_format(const std::string fmt, va_list ap); - std::string string_format(const char* fmt, va_list ap); } #endif - -- cgit v1.2.3