Skip to content

Instantly share code, notes, and snippets.

@MatiasBjorling
Created April 23, 2012 13:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MatiasBjorling/2471055 to your computer and use it in GitHub Desktop.
Save MatiasBjorling/2471055 to your computer and use it in GitHub Desktop.
Patch for pure-ftpd that adds support for phpass as a "nearly" native wrapper.
diff -rup pure-ftpd-1.0.36/src/crypto.c pure-ftpd-1.0.36-phpass/src/crypto.c
--- pure-ftpd-1.0.36/src/crypto.c 2011-04-17 08:05:54.000000000 -0700
+++ pure-ftpd-1.0.36-phpass/src/crypto.c 2012-04-20 02:07:08.288870553 -0700
@@ -47,6 +47,78 @@ static char *hexify(char * const result,
return result;
}
+/**
+ * characters used for Base64 encoding
+ */
+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
+ */
+void _base64_encode_triple(unsigned 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(unsigned 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;
+}
+
/* Encode a buffer to Base64 */
static char *base64ify(char * const result, const unsigned char *digest,
@@ -167,7 +239,6 @@ char *crypto_hash_sha1(const char *strin
return hexify(result, digest, sizeof result, sizeof digest);
}
-
/* Compute a simple hex MD5 digest of a C-string */
char *crypto_hash_md5(const char *string, const int hex)
Only in pure-ftpd-1.0.36-phpass/src: .deps
diff -rup pure-ftpd-1.0.36/src/log_mysql.c pure-ftpd-1.0.36-phpass/src/log_mysql.c
--- pure-ftpd-1.0.36/src/log_mysql.c 2012-03-15 18:01:37.000000000 -0700
+++ pure-ftpd-1.0.36-phpass/src/log_mysql.c 2012-04-20 02:25:53.020895435 -0700
@@ -324,7 +324,7 @@ void pw_mysql_check(AuthResult * const r
char *escaped_decimal_ip = NULL;
int committed = 1;
int crypto_crypt = 0, crypto_mysql = 0, crypto_md5 = 0, crypto_sha1 = 0,
- crypto_plain = 0;
+ crypto_plain = 0, crypto_phpass = 0;
unsigned long decimal_ip_num = 0UL;
char decimal_ip[42];
char hbuf[NI_MAXHOST];
@@ -419,6 +419,7 @@ void pw_mysql_check(AuthResult * const r
crypto_mysql++;
crypto_md5++;
crypto_sha1++;
+ crypto_phpass++;
} else if (strcasecmp(crypto, PASSWD_SQL_CRYPT) == 0) {
crypto_crypt++;
} else if (strcasecmp(crypto, PASSWD_SQL_MYSQL) == 0) {
@@ -427,6 +428,8 @@ void pw_mysql_check(AuthResult * const r
crypto_md5++;
} else if (strcasecmp(crypto, PASSWD_SQL_SHA1) == 0) {
crypto_sha1++;
+ } else if (strcasecmp(crypto, PASSWD_SQL_PHPASS) == 0) {
+ crypto_phpass++;
} else { /* default to plaintext */
crypto_plain++;
}
@@ -484,6 +487,25 @@ void pw_mysql_check(AuthResult * const r
goto auth_ok;
}
}
+ if (crypto_phpass != 0) {
+ char str_clear_base64[512];
+ char str_hashe_base64[512];
+
+ base64_encode(password, strlen(password), str_clear_base64, 512 );
+ base64_encode(spwd, strlen(spwd), str_hashe_base64, 512);
+
+ char cmd[512];
+ sprintf(cmd, "phpass-wrapper.php \"%s\" \"%s\"", str_clear_base64, str_hashe_base64);
+
+ int r = system (cmd);
+
+ if (r == 256)
+ goto bye;
+ else if (r == 512)
+ goto auth_ok;
+ else
+ goto bye;
+ }
if (crypto_plain != 0) {
if (*password != 0 && /* refuse null cleartext passwords */
strcmp(password, spwd) == 0) {
diff -rup pure-ftpd-1.0.36/src/log_mysql.h pure-ftpd-1.0.36-phpass/src/log_mysql.h
--- pure-ftpd-1.0.36/src/log_mysql.h 2011-05-01 18:22:54.000000000 -0700
+++ pure-ftpd-1.0.36-phpass/src/log_mysql.h 2012-04-20 01:59:00.248859759 -0700
@@ -6,6 +6,7 @@
#define PASSWD_SQL_MYSQL "password"
#define PASSWD_SQL_MD5 "md5"
#define PASSWD_SQL_SHA1 "sha1"
+#define PASSWD_SQL_PHPASS "phpass"
#define PASSWD_SQL_ANY "any"
#define MYSQL_DEFAULT_SERVER "localhost"
#define MYSQL_DEFAULT_PORT 3306
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment