Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 130701790bf2d95e902edf16031ff596 > files > 2

autofs-5.0.1-0.rc2.164.el5_8.src.rpm

autofs-5.0.1 - add base64 password encode

From: Ian Kent <raven@themaw.net>

Add a trivial base64 password endoder to obscure password entries
in autofs_ldap_auth.conf. Note that there is no way to encrypt the
passwords without storing a password somewhere because there is no
interactive input to allow a pass phrase or password to be input.

The base64 encoded string can be generated using the coreutils
base64 utility with:

echo -n "<your text string>" | base64

autofs will use the encoded string if it finds a valid entry
"encoded_secret=<encoded string>" in autofs_ldap_auth.conf. If
this cvalue is present it will override a "secret=<string>" entry.
---

 include/base64.h              |   11 ++
 modules/Makefile              |    4 
 modules/base64.c              |  225 ++++++++++++++++++++++++++++++++++++++++++
 modules/lookup_ldap.c         |   29 ++++-
 samples/autofs_ldap_auth.conf |    5 
 5 files changed, 268 insertions(+), 6 deletions(-)
 create mode 100644 include/base64.h
 create mode 100644 modules/base64.c


--- /dev/null
+++ autofs-5.0.1/include/base64.h
@@ -0,0 +1,11 @@
+
+#ifndef BASE64_H
+#define BASE64_H
+
+#include <stdlib.h>
+#include <string.h>
+
+int base64_encode(char *, size_t, char *, size_t);
+size_t base64_decode(char *, char *, size_t);
+
+#endif
--- autofs-5.0.1.orig/modules/Makefile
+++ autofs-5.0.1/modules/Makefile
@@ -90,9 +90,9 @@ cyrus-sasl.o: cyrus-sasl.c
 cyrus-sasl-extern.o: cyrus-sasl-extern.c
 	$(CC) $(CFLAGS) $(LDAP_FLAGS) -c $<
 
-lookup_ldap.so: lookup_ldap.c dclist.o $(SASL_OBJ)
+lookup_ldap.so: lookup_ldap.c dclist.o base64.o $(SASL_OBJ)
 	$(CC) $(SOLDFLAGS) $(CFLAGS) $(LDAP_FLAGS) -o lookup_ldap.so \
-		lookup_ldap.c dclist.o $(SASL_OBJ) \
+		lookup_ldap.c dclist.o base64.o $(SASL_OBJ) \
 		$(AUTOFS_LIB) $(LIBLDAP) $(LIBRESOLV)
 	$(STRIP) lookup_ldap.so
 
--- /dev/null
+++ autofs-5.0.1/modules/base64.c
@@ -0,0 +1,225 @@
+#include <base64.h>
+
+/*
+ * characters used for Base64 encoding
+ */  
+static const char *BASE64_CHARS =
+	 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+/*
+ * encode three bytes using base64 (RFC 3548)
+ *
+ * @param triple three bytes that should be encoded
+ * @param result buffer of four characters where the result is stored
+ */  
+static void _base64_encode_triple(char triple[3], char result[4])
+{
+	int tripleValue, i;
+
+	tripleValue = triple[0];
+	tripleValue *= 256;
+	tripleValue += triple[1];
+	tripleValue *= 256;
+	tripleValue += triple[2];
+
+	for (i=0; i<4; i++) {
+		result[3 - i] = BASE64_CHARS[tripleValue % 64];
+		tripleValue /= 64;
+	}
+}
+
+/*
+ * encode an array of bytes using Base64 (RFC 3548)
+ *
+ * @param source the source buffer
+ * @param sourcelen the length of the source buffer
+ * @param target the target buffer
+ * @param targetlen the length of the target buffer
+ * @return 1 on success, 0 otherwise
+ */  
+int base64_encode(char *source, size_t sourcelen, char *target, size_t targetlen)
+{
+	/* check if the result will fit in the target buffer */
+	if ((sourcelen + 2)/ 3*4 > targetlen - 1)
+		return 0;
+
+	/* encode all full triples */
+	while (sourcelen >= 3) {
+		_base64_encode_triple(source, target);
+		sourcelen -= 3;
+		source += 3;
+		target += 4;
+	}
+
+	/* encode the last one or two characters */
+	if (sourcelen > 0) {
+		unsigned char temp[3];
+		memset(temp, 0, sizeof(temp));
+		memcpy(temp, source, sourcelen);
+		_base64_encode_triple(temp, target);
+		target[3] = '=';
+		if (sourcelen == 1)
+			target[2] = '=';
+		target += 4;
+	}
+
+	/* terminate the string */
+	target[0] = 0;
+
+	return 1;
+}
+
+/*
+ * determine the value of a base64 encoding character
+ *
+ * @param base64char the character of which the value is searched
+ * @return the value in case of success (0-63), -1 on failure
+ */  
+static int _base64_char_value(char base64char)
+{
+	if (base64char >= 'A' && base64char <= 'Z')
+		return base64char-'A';
+	if (base64char >= 'a' && base64char <= 'z')
+		return base64char-'a'+26;
+	if (base64char >= '0' && base64char <= '9')
+		return base64char-'0'+2*26;
+	if (base64char == '+')
+		return 2*26+10;
+	if (base64char == '/')
+		return 2*26+11;
+	return -1;
+}
+
+/*
+ * decode a 4 char base64 encoded byte triple
+ *
+ * @param quadruple the 4 characters that should be decoded
+ * @param result the decoded data
+ * @return lenth of the result (1, 2 or 3), 0 on failure
+ */  
+static int _base64_decode_triple(char quadruple[4], char *result)
+{
+	int i, triple_value, bytes_to_decode = 3, only_equals_yet = 1;
+	int char_value[4];
+
+	for (i=0; i<4; i++)
+		char_value[i] = _base64_char_value(quadruple[i]);
+
+	/* check if the characters are valid */
+	for (i=3; i>=0; i--) {
+		if (char_value[i]<0) {
+			if (only_equals_yet && quadruple[i]=='=') {
+				/* we will ignore this character anyway, make it
+				 * something that does not break our calculations */
+				char_value[i]=0;
+				bytes_to_decode--;
+				continue;
+			}
+			return 0;
+		}
+		/* after we got a real character, no other '=' are allowed anymore */
+		only_equals_yet = 0;
+	}
+
+	/* if we got "====" as input, bytes_to_decode is -1 */
+	if (bytes_to_decode < 0)
+		bytes_to_decode = 0;
+
+	/* make one big value out of the partial values */
+	triple_value = char_value[0];
+	triple_value *= 64;
+	triple_value += char_value[1];
+	triple_value *= 64;
+	triple_value += char_value[2];
+	triple_value *= 64;
+	triple_value += char_value[3];
+
+	/* break the big value into bytes */
+	for (i=bytes_to_decode; i<3; i++)
+		triple_value /= 256;
+	for (i=bytes_to_decode-1; i>=0; i--) {
+		result[i] = triple_value%256;
+		triple_value /= 256;
+	}
+
+	return bytes_to_decode;
+}
+
+/*
+ * decode base64 encoded data
+ *
+ * @param source the encoded data (zero terminated)
+ * @param target pointer to the target buffer
+ * @param targetlen length of the target buffer
+ * @return length of converted data on success, -1 otherwise
+ */  
+size_t base64_decode(char *source, char *target, size_t targetlen)
+{
+	char *src, *tmpptr;
+	char quadruple[4], tmpresult[3];
+	int i, tmplen = 3;
+	size_t converted = 0;
+
+	/* concatinate '===' to the source to handle unpadded base64 data */
+	src = malloc(strlen(source)+5);
+	if (src == NULL)
+		return -1;
+	strcpy(src, source);
+	strcat(src, "====");
+	tmpptr = src;
+
+	memset(target, 0, targetlen);
+
+	/* convert as long as we get a full result */
+	while (tmplen == 3) {
+		/* get 4 characters to convert */
+		for (i = 0; i < 4; i++) {
+			/* skip invalid characters - we won't reach the end */
+			while (*tmpptr != '=' && _base64_char_value(*tmpptr) < 0)
+				tmpptr++;
+			quadruple[i] = *(tmpptr++);
+		}
+
+		/* convert the characters */
+		tmplen = _base64_decode_triple(quadruple, tmpresult);
+
+		/* check if the fit in the result buffer */
+		if (targetlen < tmplen) {
+			free(src);
+			return -1;
+		}
+
+		/* put the partial result in the result buffer */
+		memcpy(target, tmpresult, tmplen);
+		target += tmplen;
+		targetlen -= tmplen;
+		converted += tmplen;
+	}
+
+	free(src);
+	return converted;
+} 
+
+#if 0
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+	char *source = "testt(estt#wot%est'ing";
+	int source_len = strlen(source);
+	char dest[80];
+	int dest_len = 79;
+	char decoded[80];
+	int decode_len = 79;
+	int len;
+
+	printf("string %s\n", source);
+
+	if (base64_encode(source, source_len, dest, dest_len))
+		printf("encoded %s len %d\n", dest, strlen(dest));
+
+	len = base64_decode(dest, decoded, decode_len);
+	if (len != -1)
+		printf("decoded %s len %d\n", decoded, len);
+}
+#endif
--- autofs-5.0.1.orig/modules/lookup_ldap.c
+++ autofs-5.0.1/modules/lookup_ldap.c
@@ -35,6 +35,7 @@
 #include "automount.h"
 #include "nsswitch.h"
 #include "lookup_ldap.h"
+#include "base64.h"
 
 #define MAPFMT_DEFAULT "sun"
 
@@ -1044,9 +1045,12 @@ int parse_ldap_config(unsigned logopt, s
 
 	if (auth_required == LDAP_AUTH_USESIMPLE ||
 	   (authtype && authtype_requires_creds(authtype))) {
+		char *s1 = NULL, *s2 = NULL;
 		ret = get_property(logopt, root, "user",  &user);
-		ret |= get_property(logopt, root, "secret", &secret);
-		if (ret != 0 || (!user || !secret)) {
+		ret |= get_property(logopt, root, "secret", &s1);
+		ret |= get_property(logopt, root, "encoded_secret", &s2);
+		if (ret != 0 || (!user || (!s1 && !s2))) {
+auth_fail:
 			error(logopt,
 			      MODPREFIX
 			      "%s authentication type requires a username "
@@ -1055,12 +1059,29 @@ int parse_ldap_config(unsigned logopt, s
 			free(authtype);
 			if (user)
 				free(user);
-			if (secret)
-				free(secret);
+			if (s1)
+				free(s1);
+			if (s2)
+				free(s2);
 
 			ret = -1;
 			goto out;
 		}
+		if (!s2)
+			secret = s1;
+		else {
+			char dec_buf[120];
+			int dec_len = base64_decode(s2, dec_buf, 119);
+			if (dec_len <= 0)
+				goto auth_fail;
+			secret = strdup(dec_buf);
+			if (!secret)
+				goto auth_fail;
+			if (s1)
+				free(s1);
+			if (s2)
+				free(s2);
+		}
 	} else if (auth_required == LDAP_AUTH_REQUIRED &&
 		  (authtype && !strncmp(authtype, "EXTERNAL", 8))) {
 		ret = get_property(logopt, root, "external_cert",  &extern_cert);
--- autofs-5.0.1.orig/samples/autofs_ldap_auth.conf
+++ autofs-5.0.1/samples/autofs_ldap_auth.conf
@@ -79,6 +79,11 @@ secret  -  This attribute holds the secr
 	    include any printable characters that can be used by the
 	    selected authentication mechanism.
 
+encoded_secret  -  This attribute holds the base64 encoded secret used
+	    by authentication mechanisms that require it. If this entry
+	    is present as well as the secret entry this value will take
+	    precedence.
+
 clientprinc  -  When using GSSAPI authentication, this attribute is
 	    consulted to determine the principal name to use when
 	    authenticating to the directory server.  By default, this will