| /* Copyright (c) 2004-2005, Sara Golemon <sarag@libssh2.org> |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, |
| * with or without modification, are permitted provided |
| * that the following conditions are met: |
| * |
| * Redistributions of source code must retain the above |
| * copyright notice, this list of conditions and the |
| * following disclaimer. |
| * |
| * Redistributions in binary form must reproduce the above |
| * copyright notice, this list of conditions and the following |
| * disclaimer in the documentation and/or other materials |
| * provided with the distribution. |
| * |
| * Neither the name of the copyright holder nor the names |
| * of any other contributors may be used to endorse or |
| * promote products derived from this software without |
| * specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
| * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, |
| * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
| * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE |
| * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY |
| * OF SUCH DAMAGE. |
| */ |
| |
| #include "libssh2_priv.h" |
| |
| /* {{{ libssh2_ntohu32 |
| */ |
| unsigned long libssh2_ntohu32(const unsigned char *buf) |
| { |
| return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; |
| } |
| /* }}} */ |
| |
| /* {{{ libssh2_ntohu64 |
| * Note: Some 32-bit platforms have issues with bitops on long longs |
| * Work around this by doing expensive (but safer) arithmetic ops with optimization defying parentheses |
| */ |
| libssh2_uint64_t libssh2_ntohu64(const unsigned char *buf) |
| { |
| unsigned long msl, lsl; |
| |
| msl = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; |
| lsl = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7]; |
| |
| return ((msl * 65536) * 65536) + lsl; |
| } |
| /* }}} */ |
| |
| /* {{{ libssh2_htonu32 |
| */ |
| void libssh2_htonu32(unsigned char *buf, unsigned long value) |
| { |
| buf[0] = (value >> 24) & 0xFF; |
| buf[1] = (value >> 16) & 0xFF; |
| buf[2] = (value >> 8) & 0xFF; |
| buf[3] = value & 0xFF; |
| } |
| /* }}} */ |
| |
| /* {{{ libssh2_htonu64 |
| */ |
| void libssh2_htonu64(unsigned char *buf, libssh2_uint64_t value) |
| { |
| unsigned long msl = (value / 65536) / 65536; |
| |
| buf[0] = (msl >> 24) & 0xFF; |
| buf[1] = (msl >> 16) & 0xFF; |
| buf[2] = (msl >> 8) & 0xFF; |
| buf[3] = msl & 0xFF; |
| |
| buf[4] = (value >> 24) & 0xFF; |
| buf[5] = (value >> 16) & 0xFF; |
| buf[6] = (value >> 8) & 0xFF; |
| buf[7] = value & 0xFF; |
| } |
| /* }}} */ |
| |
| /* Base64 Conversion */ |
| |
| /* {{{ */ |
| static const char libssh2_base64_table[] = |
| { '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', |
| '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', '+', '/', '\0' |
| }; |
| |
| static const char libssh2_base64_pad = '='; |
| |
| static const short libssh2_base64_reverse_table[256] = { |
| -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
| -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
| -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, |
| 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, |
| -1, 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, -1, -1, -1, -1, -1, |
| -1, 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, -1, -1, -1, -1, -1, |
| -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
| -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
| -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
| -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
| -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
| -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
| -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
| -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 |
| }; |
| /* }}} */ |
| |
| |
| /* {{{ libssh2_base64_decode |
| * Decode a base64 chunk and store it into a newly alloc'd buffer |
| */ |
| LIBSSH2_API int libssh2_base64_decode(LIBSSH2_SESSION *session, char **data, int *datalen, |
| char *src, int src_len) |
| { |
| unsigned char *s, *d; |
| short v; |
| int i = 0, len = 0; |
| |
| *data = d = LIBSSH2_ALLOC(session, (3 * src_len / 4) + 1); |
| if (!d) { |
| return -1; |
| } |
| |
| for(s = src; ((char*)s) < (src + src_len); s++) { |
| if ((v = libssh2_base64_reverse_table[*s]) < 0) continue; |
| switch (i % 4) { |
| case 0: |
| d[len] = v << 2; |
| break; |
| case 1: |
| d[len++] |= v >> 4; |
| d[len] = v << 4; |
| break; |
| case 2: |
| d[len++] |= v >> 2; |
| d[len] = v << 6; |
| break; |
| case 3: |
| d[len++] |= v; |
| break; |
| } |
| i++; |
| } |
| if ((i % 4) == 1) { |
| /* Invalid -- We have a byte which belongs exclusively to a partial octet */ |
| LIBSSH2_FREE(session, *data); |
| return -1; |
| } |
| |
| *datalen = len; |
| return 0; |
| } |
| /* }}} */ |
| |
| #ifdef LIBSSH2_DEBUG_ENABLED |
| /* {{{ _libssh2_debug |
| * Internal debug logging facility |
| * Just writes to stderr until a good reason comes up to support anything else |
| */ |
| void _libssh2_debug(LIBSSH2_SESSION *session, int context, const char *format, ...) |
| { |
| char buffer[1536]; |
| int len; |
| va_list vargs; |
| char *contexts[8] = { "Unknown", "Transport", "Key Exhange", "Userauth", "Connection", "scp", "SFTP", "Failure Event" }; |
| |
| if (context < 1 || context > 6) { |
| context = 0; |
| } |
| |
| len = snprintf(buffer, 1535, "[libssh2] %s: ", contexts[context]); |
| |
| va_start(vargs, format); |
| len += vsnprintf(buffer + len, 1535 - len, format, vargs); |
| buffer[len] = '\n'; |
| va_end(vargs); |
| write(2, buffer, len + 1); |
| } |
| /* }}} */ |
| #endif |