secur32: base64 codec to communicate with ntlm_auth
Kai Blin
blin at gmx.net
Sat Aug 27 10:21:05 CDT 2005
This is a simple base64 codec to communicate with ntlm_auth, which also
uses base64.
Changelog:
Kai Blin <blin at gmx.net>
Base64 codec for use with NTLM and Negotiate.
--
Kai Blin, (blin at gmx dot net)
Coward, n.:
One who in a perilous emergency thinks with his legs.
-- Ambrose Bierce, "The Devil's Dictionary"
-------------- next part --------------
Index: dlls/secur32/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/secur32/Makefile.in,v
retrieving revision 1.6
diff -u -3 -r1.6 Makefile.in
--- dlls/secur32/Makefile.in 17 Aug 2005 09:52:30 -0000 1.6
+++ dlls/secur32/Makefile.in 27 Aug 2005 15:08:41 -0000
@@ -7,6 +7,7 @@
IMPORTS = user32 advapi32 kernel32 ntdll
C_SRCS = \
+ base64_codec.c \
negotiate.c \
ntlm.c \
schannel.c \
Index: dlls/secur32/secur32_priv.h
===================================================================
RCS file: /home/wine/wine/dlls/secur32/secur32_priv.h,v
retrieving revision 1.4
diff -u -3 -r1.4 secur32_priv.h
--- dlls/secur32/secur32_priv.h 17 Aug 2005 09:52:30 -0000 1.4
+++ dlls/secur32/secur32_priv.h 27 Aug 2005 15:08:42 -0000
@@ -82,4 +82,12 @@
void SECUR32_initNegotiateSP(void);
void SECUR32_initNTLMSP(void);
+/* Functions from base64_codec.c used elsewhere */
+SECURITY_STATUS encodeBase64(PBYTE in_buf, int in_len, char* out_buf,
+ int max_len, int *out_len);
+
+SECURITY_STATUS decodeBase64(char *in_buf, int in_len, BYTE *out_buf,
+ int max_len, int *out_len);
+
+
#endif /* ndef __SECUR32_PRIV_H__ */
--- /dev/null 2005-08-19 11:42:14.099901488 +0200
+++ dlls/secur32/base64_codec.c 2005-08-27 16:56:00.407618528 +0200
@@ -0,0 +1,199 @@
+/*
+ * base64 encode/decode functions
+ *
+ * Copyright 2005 Kai Blin
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Based on code by Matthias Gaertner.
+ */
+
+#include <string.h>
+#include "windef.h"
+#include "winerror.h"
+#include "sspi.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(secur32);
+
+static const char* to_b64 =
+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+SECURITY_STATUS encodeBase64(PBYTE in_buf, int in_len, char* out_buf,
+ int max_len, int *out_len)
+{
+ unsigned int div;
+ unsigned int rem;
+ unsigned int num_out = 0;
+ char res[4 + (in_len * 4)/3];
+ BYTE *pIn = in_buf;
+
+ if(in_len == 0){
+ memset(out_buf, '\0', max_len);
+ *out_len = 0;
+ return SEC_E_OK;
+ }
+
+ div = in_len / 3;
+ rem = in_len % 3;
+
+ TRACE("in_len = %d, rem = %d, div = %d\n", in_len, rem, div);
+
+ while(div > 0)
+ {
+ res[num_out + 0] = to_b64[ (pIn[0] >> 2) & 0x3f];
+ res[num_out + 1] = to_b64[((pIn[0] << 4) & 0x30) + ((pIn[1] >> 4) & 0xf)];
+ res[num_out + 2] = to_b64[((pIn[1] << 2) & 0x3c) + ((pIn[2] >> 6) & 0x3)];
+ res[num_out + 3] = to_b64[ pIn[2] & 0x3f];
+
+ pIn += 3;
+ num_out += 4;
+ div--;
+ }
+
+ switch(rem)
+ {
+ case 2:
+ res[num_out + 0] = to_b64[ (pIn[0] >> 2) & 0x3f];
+ res[num_out + 1] = to_b64[((pIn[0] << 4) & 0x30) + ((pIn[1] >> 4) & 0xf)];
+ res[num_out + 2] = to_b64[((pIn[1] << 2) & 0x3c)];
+ res[num_out + 3] = '=';
+
+ num_out += 4;
+ break;
+
+ case 1:
+ res[num_out + 0] = to_b64[ (pIn[0] >> 2) & 0x3f];
+ res[num_out + 1] = to_b64[((pIn[0] << 4) & 0x30)];
+ res[num_out + 2] = '=';
+ res[num_out + 3] = '=';
+
+ num_out += 4;
+ break;
+ }
+
+ /* Input buffer was too long */
+ if(num_out + 1 > max_len){
+ memset(out_buf, '\0', max_len);
+ *out_len = 0;
+ TRACE("Buffer size is too small: num out is %d, max_len is %d\n",
+ num_out, max_len);
+ return SEC_E_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ res[num_out] = '\0';
+ num_out++;
+ strncpy(out_buf, res, num_out);
+ *out_len = num_out;
+ return SEC_E_OK;
+ }
+
+ /* We never get here, but some compilers whine about it */
+ return SEC_E_INTERNAL_ERROR;
+}
+
+BYTE decode(char c)
+{
+ if( (c >= 'A') && (c <= 'Z'))
+ return (unsigned char) (c - 'A');
+ if( (c >= 'a') && (c <= 'z'))
+ return (unsigned char) (c - 'a' + (char)26);
+ if( (c >= '0') && (c <= '9'))
+ return (unsigned char) (c - '0' + (char)52);
+ if( c == '+')
+ return (unsigned char)62;
+ if( c == '/')
+ return (unsigned char)63;
+ return -1;
+}
+
+
+SECURITY_STATUS decodeBase64(char *in_buf, int in_len, BYTE *out_buf,
+ int max_len, int *out_len)
+{
+ BYTE data[in_len+1];
+ BYTE *pIn = (PBYTE) in_buf;
+ unsigned int num_data = 0;
+ unsigned int div;
+
+ if( (in_len % 4) != 0)
+ {
+ TRACE("in_len = %d\n", in_len);
+ TRACE("message is %s\n", debugstr_a(in_buf));
+ return SEC_E_ILLEGAL_MESSAGE;
+ }
+
+ if( (div = in_len/4) < 1)
+ {
+ TRACE("div = %d\n", div);
+ return SEC_E_ILLEGAL_MESSAGE;
+ }
+ TRACE("in_len = %d, div = %d\n", in_len, div);
+
+ while(div > 1)
+ {
+ data[num_data + 0] = ((decode(pIn[0])<<2) & 0xfc) | ((decode(pIn[1])>>4) & 0x03);
+ data[num_data + 1] = ((decode(pIn[1])<<4) & 0xf0) | ((decode(pIn[2])>>2) & 0x0f);
+ data[num_data + 2] = ((decode(pIn[2])<<6) & 0xc0) | ( decode(pIn[3]) & 0x3f);
+
+ num_data += 3;
+ pIn += 4;
+ div--;
+ }
+
+ if(pIn[2] == '=')
+ {
+ /* We have two bytes of padding */
+ data[num_data] = ((decode(pIn[0])<<2) & 0xfc) | ((decode(pIn[1])>>4) & 0x03);
+ num_data++;
+ }
+ else if(pIn[3] == '=')
+ {
+ /* One byte of padding */
+ data[num_data + 0] = ((decode(pIn[0])<<2) & 0xfc) | ((decode(pIn[1])>>4) & 0x03);
+ data[num_data + 1] = ((decode(pIn[1])<<4) & 0xf0) | ((decode(pIn[2])>>2) & 0x0f);
+ num_data += 2;
+ }
+ else
+ {
+ /* No padding */
+ data[num_data + 0] = ((decode(pIn[0])<<2) & 0xfc) | ((decode(pIn[1])>>4) & 0x03);
+ data[num_data + 1] = ((decode(pIn[1])<<4) & 0xf0) | ((decode(pIn[2])>>2) & 0x0f);
+ data[num_data + 2] = ((decode(pIn[2])<<6) & 0xc0) | ( decode(pIn[3]) & 0x3f);
+ num_data += 3;
+ }
+
+ TRACE("num_data = %d\n", num_data);
+
+ if(num_data > max_len)
+ {
+ /* Input data too big for output buffer */
+ memset(out_buf, 0, (size_t)max_len);
+ *out_len = 0;
+ return SEC_E_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ memcpy(out_buf, data, (size_t)num_data);
+ *out_len = num_data;
+ return SEC_E_OK;
+ }
+
+ /* This is never reached, but some compilers whine if they don't have it. */
+ return SEC_E_INTERNAL_ERROR;
+}
+
+
More information about the wine-patches
mailing list