diff -r 2a939f4ddcc8 include/auth.h
--- a/include/auth.h	Wed May 11 15:26:13 2011 +0100
+++ b/include/auth.h	Wed May 11 15:48:34 2011 +0100
@@ -30,6 +30,7 @@
 #define AUTHTYPE_SHA1	    3 
 #define AUTHTYPE_SSL_CLIENTCERT 4
 #define AUTHTYPE_RIPEMD160  5
+#define AUTHTYPE_SSL_CLIENTCERTFP 6
 
 /* md5 is always available and enabled as of Unreal3.2.1 */
 #define AUTHENABLE_MD5
@@ -37,6 +38,7 @@
 #define AUTHENABLE_SHA1
 #define AUTHENABLE_SSL_CLIENTCERT
 #define AUTHENABLE_RIPEMD160
+#define AUTHENABLE_SSL_CLIENTCERTFP
 /* OpenSSL provides a crypt() */
 #ifndef AUTHENABLE_UNIXCRYPT
 #define AUTHENABLE_UNIXCRYPT
diff -r 2a939f4ddcc8 src/auth.c
--- a/src/auth.c	Wed May 11 15:26:13 2011 +0100
+++ b/src/auth.c	Wed May 11 15:48:34 2011 +0100
@@ -58,6 +58,9 @@
 	/* sure, this is ugly, but it's our fault. -- Syzop */
 	{"ripemd-160",	AUTHTYPE_RIPEMD160},
 #endif
+#ifdef AUTHENABLE_SSL_CLIENTCERTFP
+	{"sslclientcertfp", AUTHTYPE_SSL_CLIENTCERTFP},
+#endif
 	{NULL,		0}
 };
 
@@ -460,11 +463,24 @@
 	extern	char *crypt();
 #endif
 
+#if defined(AUTHENABLE_SSL_CLIENTCERT) || defined(AUTHENABLE_SSL_CLIENTCERTFP)
+	X509 *x509_clientcert = NULL;
+#endif
 #ifdef AUTHENABLE_SSL_CLIENTCERT
-	X509 *x509_clientcert = NULL;
 	X509 *x509_filecert = NULL;
 	FILE *x509_f = NULL;
 #endif
+#ifdef AUTHENABLE_SSL_CLIENTCERTFP
+	unsigned int n;
+	unsigned int i;
+	unsigned int j;
+	unsigned int k;
+	unsigned char md[EVP_MAX_MD_SIZE];
+	char hex[EVP_MAX_MD_SIZE * 2];
+	char hexc[EVP_MAX_MD_SIZE * 2 + EVP_MAX_MD_SIZE];
+	char hexchars[16] = "0123456789abcdef";
+	const EVP_MD *digest = EVP_sha1();
+#endif
 
 	if (!as)
 		return 1;
@@ -536,6 +552,37 @@
 			X509_free(x509_filecert);
 			return 2;	
 #endif
+#ifdef AUTHENABLE_SSL_CLIENTCERTFP
+		case AUTHTYPE_SSL_CLIENTCERTFP:
+			if (!para)
+				return -1;
+			if (!cptr->ssl)
+				return -1;
+			x509_clientcert = SSL_get_peer_certificate((SSL *)cptr->ssl);
+			if (!x509_clientcert)
+				return -1;
+			if (!X509_digest(x509_clientcert, digest, md, &n)) {
+				X509_free(x509_clientcert);
+				return -1;
+			}
+			j = 0;
+			k = 0;
+			for (i=0; i<n; i++) {
+				hex[j++] = hexchars[(md[i] >> 4) & 0xF];
+				hex[j++] = hexchars[md[i] & 0xF];
+				hexc[k++] = hexchars[(md[i] >> 4) & 0xF];
+				hexc[k++] = hexchars[md[i] & 0xF];
+				hexc[k++] = ':';
+			}
+			hex[j] = '\0';
+			hexc[--k] = '\0';
+			if (strcasecmp(as->data, hex) && strcasecmp(as->data, hexc)) {
+				X509_free(x509_clientcert);
+				return -1;
+			}
+			X509_free(x509_clientcert);
+			return 2;
+#endif
 	}
 	return -1;
 }
