diff --git a/Jupiter/Base64.cpp b/Jupiter/Base64.cpp index 654e27b..159e974 100644 --- a/Jupiter/Base64.cpp +++ b/Jupiter/Base64.cpp @@ -1,5 +1,5 @@ /** - * Copyright (C) 2014-2015 Jessica James. + * Copyright (C) 2014-2016 Jessica James. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -19,14 +19,16 @@ #include "Base64.h" #include "Functions.h" -unsigned int Jupiter::base64encode(const void *data, size_t dataLength, char *result) +size_t Jupiter::base64encode(const void *data, size_t dataLength, char *result) { return Jupiter_base64encode(data, dataLength, result); } -unsigned int Jupiter::base64encode(const void *data, size_t dataLength, char *result, size_t resultSize) +size_t Jupiter::base64encode(const void *data, size_t dataLength, char *result, size_t resultSize) { - if (resultSize < (dataLength / 3) * 4 + 5) return 0; + if (resultSize < (dataLength / 3) * 4 + 5) + return 0; + return Jupiter::base64encode(data, dataLength, result); } @@ -34,7 +36,9 @@ char *Jupiter::base64encode(const void *data, size_t dataLength) { size_t resultSize = (dataLength / 3) * 4 + 5; char *result = new char[resultSize]; + Jupiter::base64encode(data, dataLength, result, resultSize); + return result; } @@ -43,14 +47,16 @@ char *Jupiter::base64encode(const char *str) return Jupiter::base64encode(str, strlen(str)); } -unsigned int Jupiter::base64decode(const char *data, size_t dataLength, unsigned char *result) +size_t Jupiter::base64decode(const char *data, size_t dataLength, unsigned char *result) { return Jupiter_base64decode_s(data, dataLength, result); } -unsigned int Jupiter::base64decode(const char *data, size_t dataLength, unsigned char *result, size_t resultSize) +size_t Jupiter::base64decode(const char *data, size_t dataLength, unsigned char *result, size_t resultSize) { - if (resultSize < Jupiter_minBase64DecodeLength(data, dataLength)) return 0; + if (resultSize < Jupiter_minBase64DecodeLength(data, dataLength)) + return 0; + return Jupiter::base64decode(data, dataLength, result); } @@ -65,3 +71,230 @@ char *Jupiter::base64decode(const char *data) { return Jupiter::base64decode(data, strlen(data)); } + + +size_t Jupiter_base64encode(const void *data_buf, size_t dataLength, char *result) +{ + const char base64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + const uint8_t *data = (const uint8_t *)data_buf; + char *resultPtr = result; + uint32_t n = 0; + int padCount = dataLength % 3; + uint8_t n0, n1, n2, n3; + + /* increment over the length of the string, three characters at a time */ + for (size_t x = 0; x < dataLength; x += 3) + { + /* these three 8-bit (ASCII) characters become one 24-bit number */ + n = data[x] << 16; + + if ((x + 1) < dataLength) n += data[x + 1] << 8; + if ((x + 2) < dataLength) n += data[x + 2]; + + /* this 24-bit number gets separated into four 6-bit numbers */ + n0 = (uint8_t)(n >> 18) & 63; + n1 = (uint8_t)(n >> 12) & 63; + n2 = (uint8_t)(n >> 6) & 63; + n3 = (uint8_t)n & 63; + + /* + * if we have one byte available, then its encoding is spread + * out over two characters + */ + *resultPtr = base64chars[n0]; + resultPtr++; + *resultPtr = base64chars[n1]; + resultPtr++; + + /* + * if we have only two bytes available, then their encoding is + * spread out over three chars + */ + if ((x + 1) < dataLength) + { + *resultPtr = base64chars[n2]; + resultPtr++; + } + + /* + * if we have all three bytes available, then their encoding is spread + * out over four characters + */ + if ((x + 2) < dataLength) + { + *resultPtr = base64chars[n3]; + resultPtr++; + } + } + + /* + * create and add padding that is required if we did not have a multiple of 3 + * number of characters available + */ + if (padCount > 0) + { + while (padCount < 3) + { + *resultPtr = '='; + resultPtr++; + padCount++; + } + } + *resultPtr = 0; + return resultPtr - result; +} + +const unsigned char Jupiter_base64DecodeTable[256] = { + 66, 66, 66, 66, 66, 66, 66, 66, 66, 64, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 62, 66, 66, 66, 63, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 66, 66, 66, 65, 66, 66, 66, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 66, 66, 66, 66, 66, 66, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66 +}; + +size_t Jupiter_minBase64DecodeLength(const char *data, size_t inLen) +{ + if (inLen == 0) return 0; + data += inLen - 1; + if (*data == '=') + { + data--; + if (*data == '=') + return inLen / 4 * 3 - 2; + + return inLen / 4 * 3 - 1; + } + return inLen / 4 * 3; +} + +bool Jupiter_isBase64(const char *in) +{ + while (*in != 0) + { + switch (Jupiter_base64DecodeTable[*in++]) + { + case 66: + return false; + default: + break; + } + } + return true; +} + +bool Jupiter_isBase64_s(const char *in, size_t inLen) +{ + if (inLen % 4 != 0) + { + return false; + } + const char *end = in + inLen; + while (in != end) + { + switch (Jupiter_base64DecodeTable[*in++]) + { + case 66: + return false; + default: + break; + } + } + return true; +} + +size_t Jupiter_base64decode(const char *in, unsigned char *out) +{ + unsigned char *outOrig = out; + size_t buf = 1; + + while (*in != 0) + { + unsigned char c = Jupiter_base64DecodeTable[*in++]; + + switch (c) + { + case 66: + /* invalid input */ + return 0; + case 65: + /* pad character, end of data */ + goto endLoop; + case 64: + break; + default: + buf = buf << 6 | c; + + /* If the buffer is full, split it into bytes */ + if (buf & 0x1000000) + { + *out++ = (unsigned char)(buf >> 16); + *out++ = (unsigned char)(buf >> 8); + *out++ = (unsigned char)buf; + buf = 1; + } + break; + } + } +endLoop: + + if (buf & 0x40000) + { + *out++ = (unsigned char)(buf >> 10); + *out++ = (unsigned char)(buf >> 2); + } + else if (buf & 0x1000) *out++ = (unsigned char)(buf >> 4); + + return out - outOrig; +} + +size_t Jupiter_base64decode_s(const char *in, size_t inLen, unsigned char *out) +{ + unsigned char *outOrig = out; + const char *end = in + inLen; + size_t buf = 1; + + while (in != end) + { + unsigned char c = Jupiter_base64DecodeTable[*in++]; + + switch (c) + { + case 66: + /* invalid input */ + return false; + case 65: + /* pad character, end of data */ + in = end; + case 64: + break; + default: + buf = buf << 6 | c; + + /* If the buffer is full, split it into bytes */ + if (buf & 0x1000000) + { + *out++ = (unsigned char)(buf >> 16); + *out++ = (unsigned char)(buf >> 8); + *out++ = (unsigned char)buf; + buf = 1; + } + break; + } + } + + if (buf & 0x40000) + { + *out++ = (unsigned char)(buf >> 10); + *out++ = (unsigned char)(buf >> 2); + } + else if (buf & 0x1000) + *out++ = (unsigned char)(buf >> 4); + + return out - outOrig; +} diff --git a/Jupiter/Base64.h b/Jupiter/Base64.h index 22c15fe..eb5a8af 100644 --- a/Jupiter/Base64.h +++ b/Jupiter/Base64.h @@ -1,5 +1,5 @@ /** - * Copyright (C) 2014-2015 Jessica James. + * Copyright (C) 2014-2016 Jessica James. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -24,12 +24,10 @@ * @brief Provides C and C++ functions to encode/decode using base64. */ -#include "Jupiter.h" - -#if defined __cplusplus - #include #include +#include "Jupiter.h" +#include "String.h" namespace Jupiter { @@ -41,7 +39,7 @@ namespace Jupiter * @param result Character buffer for output. * @return Number of bytes written to the output buffer. */ - JUPITER_API unsigned int base64encode(const void *data, size_t dataLength, char *result); + JUPITER_API size_t base64encode(const void *data, size_t dataLength, char *result); /** * @brief Checks if a buffer is large enough, and if so, encodes an input buffer into a base64 C-String. @@ -52,7 +50,7 @@ namespace Jupiter * @param outputSize Size of the "result" buffer. * @return Number of bytes written to the output buffer. */ - JUPITER_API unsigned int base64encode(const void *data, size_t dataLength, char *result, size_t outputSize); + JUPITER_API size_t base64encode(const void *data, size_t dataLength, char *result, size_t outputSize); /** * @brief Encodes an input C-String into a base64 C-String. @@ -78,7 +76,7 @@ namespace Jupiter * @param result Data buffer for output. * @return Number of bytes written to the output buffer. */ - JUPITER_API unsigned int base64decode(const char *data, size_t dataLength, unsigned char *result, size_t resultSize); + JUPITER_API size_t base64decode(const char *data, size_t dataLength, unsigned char *result, size_t resultSize); /** * @brief Decodes an input base64 character string into a C-String buffer. @@ -87,7 +85,7 @@ namespace Jupiter * @param dataLength Length of the data to decode. * @return Number of bytes written to the output buffer. */ - JUPITER_API unsigned int base64decode(const char *data, size_t dataLength, unsigned char *result); + JUPITER_API size_t base64decode(const char *data, size_t dataLength, unsigned char *result); /** * @brief Decodes an input base64 character string into a C-String buffer. @@ -107,14 +105,6 @@ namespace Jupiter JUPITER_API char *base64decode(const char *str); } -extern "C" -{ -#else -#include -#include -#include -#endif // __cplusplus - /** * @brief Encodes an input buffer into a base64 C-String. * @@ -123,7 +113,7 @@ extern "C" * @param result Character buffer for output. * @return Number of bytes written to the output buffer. */ -JUPITER_API unsigned int Jupiter_base64encode(const void *data, size_t dataLength, char *result); +JUPITER_API size_t Jupiter_base64encode(const void *data, size_t dataLength, char *result); /** * @brief Calculates the minimum buffer size to decode a specified base64 string. @@ -133,7 +123,7 @@ JUPITER_API unsigned int Jupiter_base64encode(const void *data, size_t dataLengt * @param inLen Length of the input string. * @return Minimum number of bytes to fit the decoded buffer. */ -JUPITER_API unsigned int Jupiter_minBase64DecodeLength(const char *data, size_t inLen); +JUPITER_API size_t Jupiter_minBase64DecodeLength(const char *data, size_t inLen); /** * @brief Checks if a buffer is a valid base64 string. @@ -159,7 +149,7 @@ JUPITER_API bool Jupiter_isBase64_s(const char *data, size_t dataLength); * @param result Data buffer for output. * @return Number of bytes written to the output buffer. */ -JUPITER_API unsigned int Jupiter_base64decode(const char *str, unsigned char *result); +JUPITER_API size_t Jupiter_base64decode(const char *str, unsigned char *result); /** * @brief Decodes an input base64 string into a data buffer. @@ -169,10 +159,6 @@ JUPITER_API unsigned int Jupiter_base64decode(const char *str, unsigned char *re * @param result Data buffer for output. * @return Number of bytes written to the output buffer. */ -JUPITER_API unsigned int Jupiter_base64decode_s(const char *data, size_t dataLength, unsigned char *result); - -#if defined __cplusplus -} -#endif // __cplusplus +JUPITER_API size_t Jupiter_base64decode_s(const char *data, size_t dataLength, unsigned char *result); #endif // _BASE64_H_HEADER \ No newline at end of file diff --git a/Jupiter/Base64C.c b/Jupiter/Base64C.c deleted file mode 100644 index a550636..0000000 --- a/Jupiter/Base64C.c +++ /dev/null @@ -1,243 +0,0 @@ -/** - * Copyright (C) 2014-2015 Jessica James. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Written by Jessica James - */ - -#include "Base64.h" - -unsigned int Jupiter_base64encode(const void *data_buf, size_t dataLength, char *result) -{ - const char base64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - const uint8_t *data = (const uint8_t *)data_buf; - char *resultPtr = result; - uint32_t n = 0; - int padCount = dataLength % 3; - uint8_t n0, n1, n2, n3; - - /* increment over the length of the string, three characters at a time */ - for (size_t x = 0; x < dataLength; x += 3) - { - /* these three 8-bit (ASCII) characters become one 24-bit number */ - n = data[x] << 16; - - if ((x + 1) < dataLength) n += data[x + 1] << 8; - if ((x + 2) < dataLength) n += data[x + 2]; - - /* this 24-bit number gets separated into four 6-bit numbers */ - n0 = (uint8_t)(n >> 18) & 63; - n1 = (uint8_t)(n >> 12) & 63; - n2 = (uint8_t)(n >> 6) & 63; - n3 = (uint8_t)n & 63; - - /* - * if we have one byte available, then its encoding is spread - * out over two characters - */ - *resultPtr = base64chars[n0]; - resultPtr++; - *resultPtr = base64chars[n1]; - resultPtr++; - - /* - * if we have only two bytes available, then their encoding is - * spread out over three chars - */ - if ((x + 1) < dataLength) - { - *resultPtr = base64chars[n2]; - resultPtr++; - } - - /* - * if we have all three bytes available, then their encoding is spread - * out over four characters - */ - if ((x + 2) < dataLength) - { - *resultPtr = base64chars[n3]; - resultPtr++; - } - } - - /* - * create and add padding that is required if we did not have a multiple of 3 - * number of characters available - */ - if (padCount > 0) - { - while (padCount < 3) - { - *resultPtr = '='; - resultPtr++; - padCount++; - } - } - *resultPtr = 0; - return resultPtr - result; -} - -static const unsigned char Jupiter_base64DecodeTable[256] = { - 66, 66, 66, 66, 66, 66, 66, 66, 66, 64, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 62, 66, 66, 66, 63, 52, 53, - 54, 55, 56, 57, 58, 59, 60, 61, 66, 66, 66, 65, 66, 66, 66, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 66, 66, 66, 66, 66, 66, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66 -}; - -unsigned int Jupiter_minBase64DecodeLength(const char *data, size_t inLen) -{ - if (inLen == 0) return 0; - data += inLen - 1; - if (*data == '=') - { - data--; - if (*data == '=') return inLen / 4 * 3 - 2; - return inLen / 4 * 3 - 1; - } - return inLen / 4 * 3; -} - -bool Jupiter_isBase64(const char *in) -{ - while (*in != 0) - { - switch (Jupiter_base64DecodeTable[*in++]) - { - case 66: - return false; - default: - break; - } - } - return true; -} - -bool Jupiter_isBase64_s(const char *in, size_t inLen) -{ - if (inLen % 4 != 0) - { - return false; - } - const char *end = in + inLen; - while (in != end) - { - switch (Jupiter_base64DecodeTable[*in++]) - { - case 66: - return false; - default: - break; - } - } - return true; -} - -unsigned int Jupiter_base64decode(const char *in, unsigned char *out) -{ - unsigned char *outOrig = out; - size_t buf = 1; - - while (*in != 0) - { - unsigned char c = Jupiter_base64DecodeTable[*in++]; - - switch (c) - { - case 66: - /* invalid input */ - return 0; - case 65: - /* pad character, end of data */ - goto endLoop; - case 64: - break; - default: - buf = buf << 6 | c; - - /* If the buffer is full, split it into bytes */ - if (buf & 0x1000000) - { - *out++ = (unsigned char) (buf >> 16); - *out++ = (unsigned char) (buf >> 8); - *out++ = (unsigned char) buf; - buf = 1; - } - break; - } - } -endLoop: - - if (buf & 0x40000) - { - *out++ = (unsigned char) (buf >> 10); - *out++ = (unsigned char) (buf >> 2); - } - else if (buf & 0x1000) *out++ = (unsigned char) (buf >> 4); - - return out - outOrig; -} - -unsigned int Jupiter_base64decode_s(const char *in, size_t inLen, unsigned char *out) -{ - unsigned char *outOrig = out; - const char *end = in + inLen; - size_t buf = 1; - - while (in != end) - { - unsigned char c = Jupiter_base64DecodeTable[*in++]; - - switch (c) - { - case 66: - /* invalid input */ - return false; - case 65: - /* pad character, end of data */ - in = end; - case 64: - break; - default: - buf = buf << 6 | c; - - /* If the buffer is full, split it into bytes */ - if (buf & 0x1000000) - { - *out++ = (unsigned char) (buf >> 16); - *out++ = (unsigned char) (buf >> 8); - *out++ = (unsigned char) buf; - buf = 1; - } - break; - } - } - - if (buf & 0x40000) - { - *out++ = (unsigned char) (buf >> 10); - *out++ = (unsigned char) (buf >> 2); - } - else if (buf & 0x1000) - *out++ = (unsigned char) (buf >> 4); - - return out - outOrig; -} diff --git a/Jupiter/IRC_Client.cpp b/Jupiter/IRC_Client.cpp index 1dc7f24..b216634 100644 --- a/Jupiter/IRC_Client.cpp +++ b/Jupiter/IRC_Client.cpp @@ -1267,20 +1267,11 @@ int Jupiter::IRC::Client::process_line(const Jupiter::ReadableString &line) { if (Jupiter::IRC::Client::data_->saslPass.isNotEmpty()) { - size_t authStringLen = Jupiter::IRC::Client::data_->nickname.size() + Jupiter::IRC::Client::data_->saslAccount.size() + Jupiter::IRC::Client::data_->saslPass.size() + 2; - char *authString = new char[authStringLen + 1]; - int offset = sprintf(authString, "%.*s", Jupiter::IRC::Client::data_->nickname.size(), Jupiter::IRC::Client::data_->nickname.ptr()) + 1; - offset += sprintf(authString + offset, "%.*s", Jupiter::IRC::Client::data_->saslAccount.size(), Jupiter::IRC::Client::data_->saslAccount.ptr()) + 1; - offset += sprintf(authString + offset, "%.*s", Jupiter::IRC::Client::data_->saslPass.size(), Jupiter::IRC::Client::data_->saslPass.ptr()); + Jupiter::StringS auth_str = Jupiter::IRC::Client::data_->nickname + '\0' + Jupiter::IRC::Client::data_->saslAccount + '\0' + Jupiter::IRC::Client::data_->saslPass; - char *enc = Jupiter::base64encode(authString, authStringLen); - delete[] authString; - - char *out = new char[strlen(enc) + 16]; - int len = sprintf(out, "AUTHENTICATE %s" ENDL, enc); + char *enc = Jupiter::base64encode(auth_str.ptr(), auth_str.size()); + Jupiter::IRC::Client::data_->sock->send("AUTHENTICATE "_jrs + enc); delete[] enc; - Jupiter::IRC::Client::data_->sock->send(out, len); - delete[] out; } Jupiter::IRC::Client::data_->sock->send("CAP END" ENDL); Jupiter::IRC::Client::data_->registerClient(); diff --git a/Jupiter/Jupiter.vcxproj b/Jupiter/Jupiter.vcxproj index 8672ab1..4a19d04 100644 --- a/Jupiter/Jupiter.vcxproj +++ b/Jupiter/Jupiter.vcxproj @@ -177,7 +177,6 @@ - diff --git a/Jupiter/Jupiter.vcxproj.filters b/Jupiter/Jupiter.vcxproj.filters index 64463f3..173037a 100644 --- a/Jupiter/Jupiter.vcxproj.filters +++ b/Jupiter/Jupiter.vcxproj.filters @@ -102,9 +102,6 @@ Source Files - - Source Files - Source Files\IRC