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