ssl: Support for SHA256 fingerprints (v0.9.3) v0.9.3
authorMyhailo Danylenko <isbear@ukrpost.net>
Sat, 05 Mar 2016 14:57:47 +0200
changeset 57 37ed3c7ac1b6
parent 56 d53804c0fb6f
child 58 24998d36f3e4
ssl: Support for SHA256 fingerprints (v0.9.3)
CMakeLists.txt
config.h.in
docs/todo.mdwn
lm_ssl.c
test.lua
--- a/CMakeLists.txt	Sat Mar 05 14:55:50 2016 +0200
+++ b/CMakeLists.txt	Sat Mar 05 14:57:47 2016 +0200
@@ -16,7 +16,7 @@
 
 cmake_minimum_required(VERSION 2.6)
 project(lua-lm C)
-set(PROJECT_VERSION "0.9.2")
+set(PROJECT_VERSION "0.9.3")
 
 ## User options
 option(DEBUG      "Enable debugging output" OFF)
@@ -45,7 +45,12 @@
 	execute_process(COMMAND ${LUA_EXECUTABLE} -e "print ( package.cpath )" OUTPUT_VARIABLE LUA_CPATH OUTPUT_STRIP_TRAILING_WHITESPACE)
 endif()
 pkg_check_modules(GLIB REQUIRED glib-2.0)
-pkg_check_modules(LM REQUIRED loudmouth-1.0)
+pkg_check_modules(LM loudmouth-1.0>=1.5.3)
+if ( LM_FOUND )
+	set(HAVE_LM_SHA256_FINGERPRINTS TRUE)
+else()
+	pkg_check_modules(LM REQUIRED loudmouth-1.0)
+endif()
 include(CheckFunctionExists)
 set(CMAKE_REQUIRED_INCLUDES ${LM_INCLUDE_DIRS})
 set(CMAKE_REQUIRED_LIBRARIES ${LM_LIBRARIES})
--- a/config.h.in	Sat Mar 05 14:55:50 2016 +0200
+++ b/config.h.in	Sat Mar 05 14:57:47 2016 +0200
@@ -25,6 +25,9 @@
 // define this, if you are building with liblua 5.2
 #cmakedefine HAVE_LUA52
 
+// define this, if your loudmouth uses SHA256 fingerprints
+#cmakedefine HAVE_LM_SHA256_FINGERPRINTS
+
 // define this, if your loudmouth have lm_connection_get_keep_alive_rate ()
 #cmakedefine HAVE_LM_CONNECTION_GET_KEEP_ALIVE_RATE
 
--- a/docs/todo.mdwn	Sat Mar 05 14:55:50 2016 +0200
+++ b/docs/todo.mdwn	Sat Mar 05 14:57:47 2016 +0200
@@ -10,4 +10,7 @@
   * Get child value method
   * Xml console interception means?
   * Attribute list retrieval method
+  * update:
+      - ssl ca
+      - ssl cipher list
 
--- a/lm_ssl.c	Sat Mar 05 14:55:50 2016 +0200
+++ b/lm_ssl.c	Sat Mar 05 14:57:47 2016 +0200
@@ -68,6 +68,7 @@
 		return LM_SSL_RESPONSE_STOP;
 }
 
+#ifndef HAVE_LM_SHA256_FINGERPRINTS
 static void string2fingerprint (const char *string, char *buffer)
 {
 	int i;
@@ -77,12 +78,14 @@
 		buffer[i] = (char) ((h >= 0 && l >= 0) ? h*16 + l : 0);
 	}
 }
+#endif
 
 /// lm.ssl.new
 /// Creates new ssl object for use with connection.
 /// You can specify server key fingerprint, callback function for error handling,
 /// both, or neither. Though, fingerprint should go before callback function.
-/// SSL fingerprint is a string like '01:23:45:67:89:AB:CD:EF:FE:DC:BA:98:76:54:32:10'.
+/// SSL fingerprint is a string like 'SHA256:ABCDEF123456...' (or
+/// '01:23:45:67:89:AB:CD:EF:FE:DC:BA:98:76:54:32:10' for LM versions, older than 1.5.3).
 /// A: string (optional ssl fingerprint), ssl callback function (optional)
 /// R: userdata (lm ssl object)
 static int new_lm_ssl (lua_State *L)
@@ -92,20 +95,32 @@
 	if (args == 0)
 		ssl = lm_ssl_new (NULL, NULL, NULL, NULL);
 	else if (args == 1 && !lua_isfunction (L, 1)) {
+		const char *fingerprint = luaL_checkstring (L, 1);
+#ifndef HAVE_LM_SHA256_FINGERPRINTS
 		gchar buffer[16] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
-		const char *fingerprint = luaL_checkstring (L, 1);
 
-		if (lua_rawlen (L, 1) > 46)
+		if (lua_rawlen (L, 1) > 46) {
 			string2fingerprint (fingerprint, buffer);
-		ssl = lm_ssl_new (buffer, NULL, NULL, NULL);
+			fingerprint = buffer;
+		} else
+			fingerprint = NULL;
+#endif
+		ssl = lm_ssl_new (fingerprint, NULL, NULL, NULL);
 	} else {
 		llm_callback_t *cb;
-		gchar buffer[16] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
+		const char *fingerprint = NULL;
 
 		if (args > 1) {
-			const char *fingerprint = luaL_checkstring (L, 1);
-			if (lua_rawlen (L, 1) > 46)
+			fingerprint = luaL_checkstring (L, 1);
+#ifndef HAVE_LM_SHA256_FINGERPRINTS
+			gchar buffer[16] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
+
+			if (lua_rawlen (L, 1) > 46) {
 				string2fingerprint (fingerprint, buffer);
+				fingerprint = buffer;
+			} else
+				fingerprint = NULL;
+#endif
 			luaL_argcheck (L, lua_isfunction (L, 2), 2, "function expected");
 		} else
 			luaL_argcheck (L, lua_isfunction (L, 1), 1, "function expected");
@@ -114,7 +129,7 @@
 		cb->reference = luaL_ref (L, LUA_REGISTRYINDEX);
 		cb->L = L;
 
-		ssl = lm_ssl_new ((args > 1) ? buffer : NULL, (LmSSLFunction)callback_lm_ssl,
+		ssl = lm_ssl_new (fingerprint, (LmSSLFunction)callback_lm_ssl,
 							cb, (GDestroyNotify)llm_callback_destroy);
 	}
 	bless_lm_ssl (L, ssl);
@@ -135,11 +150,20 @@
 }
 
 /// lm.ssl.supported
-/// Indicates if SSL is supported by loudmouth library.
-/// R: boolean
+/// Indicates if SSL is supported by loudmouth library and what kind of
+/// ssl fingerprint is used.
+/// R: nil or string ("MD5" or "SHA256")
 static int supported_lm_ssl (lua_State *L)
 {
-	lua_pushboolean (L, lm_ssl_is_supported ());
+	if (lm_ssl_is_supported ()) {
+#ifdef HAVE_LM_SHA256_FINGERPRINTS
+		lua_pushliteral (L, "SHA256");
+#else
+		lua_pushliteral (L, "MD5");
+#endif
+	} else {
+		lua_pushnil (L);
+	}
 	return 1;
 }
 
@@ -148,12 +172,15 @@
 /// R: string or nil
 static int fingerprint_lm_ssl (lua_State *L)
 {
-	char buffer[48];
 	llm_ssl_t *object = luaL_checklm_ssl (L, 1);
 	const gchar *fingerprint = lm_ssl_get_fingerprint (object->ssl);
 	if (fingerprint == NULL)
 		lua_pushnil (L);
 	else {
+#ifdef HAVE_LM_SHA256_FINGERPRINTS
+		lua_pushstring (L, fingerprint);
+#else
+		char buffer[48];
 		snprintf (buffer, 48,
 			  "%02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX:"
 			  "%02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX",
@@ -162,6 +189,7 @@
 			  fingerprint[8], fingerprint[9], fingerprint[10], fingerprint[11],
 			  fingerprint[12], fingerprint[13], fingerprint[14], fingerprint[15]);
 		lua_pushlstring (L, buffer, 47);
+#endif
 	}
 	return 1;
 }
--- a/test.lua	Sat Mar 05 14:55:50 2016 +0200
+++ b/test.lua	Sat Mar 05 14:57:47 2016 +0200
@@ -30,7 +30,18 @@
 local username, server = arg[1]:match ( '(.+)@(.+)' )
 local password         = arg[2]
 local recipient        = arg[3] or arg[1]
-local fingerprint      = arg[4] or '01:23:45:67:89:ab:cd:ef:fe:dc:ba:98:76:54:32:10'
+local fingerprint      = arg[4]
+
+if not fingerprint then
+	local ssl_fp_format = lm.ssl.supported ()
+	if ssl_fp_format then
+		if ssl_fp_format == 'MD5' then
+			fingerprint = '01:23:45:67:89:ab:cd:ef:fe:dc:ba:98:76:54:32:10'
+		else
+			fingerprint = 'SHA256:0123456789abcdeffedcba98765432100123456789acbdeffedcba9876543210'
+		end
+	end
+end
 
 print ( ("Connectng to %s with username %s\nWill contact %s."):format ( server, username, recipient ) )
 
@@ -145,4 +156,4 @@
 conn:close ()
 print ( "Bye" )
 
--- vim: se ts=4: --
+-- vim: se ts=4 sw=4: --