ssl: Add ssl:ca_path and ssl:cipher_list methods (v0.9.4) v0.9.4
authorMyhailo Danylenko <isbear@ukrpost.net>
Sat, 05 Mar 2016 15:43:04 +0200
changeset 59 19cfaceda6bb
parent 58 24998d36f3e4
child 60 1dbd1898058f
ssl: Add ssl:ca_path and ssl:cipher_list methods (v0.9.4)
CMakeLists.txt
config.h.in
docs/todo.mdwn
lm.lua
lm_ssl.c
--- a/CMakeLists.txt	Sat Mar 05 14:57:58 2016 +0200
+++ b/CMakeLists.txt	Sat Mar 05 15:43:04 2016 +0200
@@ -1,4 +1,4 @@
-## Copyright 2009,2011 Myhailo Danylenko
+## Copyright 2009-2016 Myhailo Danylenko
 # This file is part of lua-lm
 #
 # lua-lm is free software: you can redistribute it and/or modify
@@ -16,7 +16,7 @@
 
 cmake_minimum_required(VERSION 2.6)
 project(lua-lm C)
-set(PROJECT_VERSION "0.9.3")
+set(PROJECT_VERSION "0.9.4")
 
 ## User options
 option(DEBUG      "Enable debugging output" OFF)
@@ -57,6 +57,8 @@
 set(CMAKE_REQUIRED_FLAGS ${LM_LDFLAGS} ${LM_CFLAGS})
 check_function_exists(lm_connection_get_keep_alive_rate HAVE_LM_CONNECTION_GET_KEEP_ALIVE_RATE)
 check_function_exists(lm_connection_unregister_reply_handler HAVE_LM_CONNECTION_UNREGISTER_REPLY_HANDLER)
+check_function_exists(lm_ssl_set_ca HAVE_LM_SSL_SET_CA)
+check_function_exists(lm_ssl_set_cipher_list HAVE_LM_SSL_SET_CIPHER_LIST)
 find_program(DOCGEN_EXECUTABLE NAMES docgen.pl docgen DOC "Docgen documentation generator script (optional)")
 # (this should be before targets definitions)
 link_directories(${LUA_LIBRARY_DIRS} ${GLIB_LIBRARY_DIRS} ${LM_LIBRARY_DIRS})
--- a/config.h.in	Sat Mar 05 14:57:58 2016 +0200
+++ b/config.h.in	Sat Mar 05 15:43:04 2016 +0200
@@ -1,5 +1,5 @@
 
-/* Copyright 2009 Myhailo Danylenko
+/* Copyright 2009-2016 Myhailo Danylenko
 
 This file is part of lua-lm.
 
@@ -34,6 +34,12 @@
 // define this, if your loudmouth have lm_connection_unregister_reply_handler ()
 #cmakedefine HAVE_LM_CONNECTION_UNREGISTER_REPLY_HANDLER
 
+// define this, if your loudmouth have lm_ssl_set_ca ()
+#cmakedefine HAVE_LM_SSL_SET_CA
+
+// define this, if your loudmouth have lm_ssl_set_cipher_list ()
+#cmakedefine HAVE_LM_SSL_SET_CIPHER_LIST
+
 #ifndef HAVE_LUA52
 #  define lua_rawlen lua_objlen
 #  define luaL_setfuncs(STATE, REGTABLE, IGZERO) luaL_register ( STATE, NULL, REGTABLE )
--- a/docs/todo.mdwn	Sat Mar 05 14:57:58 2016 +0200
+++ b/docs/todo.mdwn	Sat Mar 05 15:43:04 2016 +0200
@@ -10,7 +10,4 @@
   * Get child value method
   * Xml console interception means?
   * Attribute list retrieval method
-  * update:
-      - ssl ca
-      - ssl cipher list
 
--- a/lm.lua	Sat Mar 05 14:57:58 2016 +0200
+++ b/lm.lua	Sat Mar 05 15:43:04 2016 +0200
@@ -1,4 +1,4 @@
---[[ Copyright 2009 Myhailo Danylenko
+--[[ Copyright 2009-2016 Myhailo Danylenko
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -15,8 +15,12 @@
 
 local lm = require 'loudmouth'
 
--- argument is a table with keys,
--- corresponding to method names.
+-- Argument is a table with keys:
+-- * server   - server name to connect to
+-- * port     - port to connect to
+-- * type     - proxy type
+-- * username - uername to authenticate on proxy
+-- * password - password to authenticate with
 function lm.proxy.create ( a )
 	if type ( a ) ~= "table" then
 		error "arguments should be in a table"
@@ -40,21 +44,35 @@
 	return p
 end
 
--- argument is a table with two keys:
--- callback and fingerprint
+-- Argument is a table with keys:
+-- * fingerprint - fingerprint string
+-- * callback    - ssl error callback
+-- * tls         - string - one of "on", "required", "off" (default)
+-- * ca_path     - path to trusted certificates
+-- * cipher_list - list of allowed ciphers to ues
 function lm.ssl.create ( a )
 	if not lm.ssl.supported () then
 		-- XXX
 		-- error "ssl is not supported by your loudmouth library"
 		return nil
 	end
-	local fp, cb, ut, rt
+	local fp, cb, ut, rt, ca, cl
 	local st = type ( a )
 	if st == "table" then
 		fp = a.fingerprint
 		cb = a.callback
-		ut = a.tls
-		rt = a.require_tls
+		ca = a.ca_path
+		cl = a.cipher_list
+		tl = a.tls
+		if tl ~= nil then
+			if tl == "on" then
+				ut = true
+				rt = false
+			elseif tl == "required" then
+				ut = true
+				rt = true
+			end
+		end
 	elseif st == "function" then
 		cb = a
 	elseif st == "string" then
@@ -76,24 +94,28 @@
 			ssl = lm.ssl.new ()
 		end
 	end
+	if ca ~= nil then
+		ssl:ca_path ( ca )
+	end
+	if cl ~= nil then
+		ssl:cipher_list ( cl )
+	end
 	if ut ~= nil then
 		ssl:tls ( ut, rt )
 	end
 	return ssl
 end
 
--- basically, it just provides a way
--- to initialize many parameters at once.
--- keys in a table correspond to methods
--- of connection object, except for handlers,
--- where format is {
---     "type/priority" = function/object,
---     ...
--- }
--- two extra keys - server and context.
--- ssl and proxy objects can either be objects
--- or tables, directly passed to corresponding
--- create routine.
+-- Argument is a table with keys:
+-- * server          - server name
+-- * context         - glib main context
+-- * port            - server port
+-- * jid             - jid to connect with
+-- * keep_alive_rate - rate of keep alive packets
+-- * proxy           - lm.proxy object or table
+-- * ssl             - lm.ssl object or table
+-- * ondisconnect    - disconnect callback
+-- * handlers        - table with { "type/priority" = function/object } mapping
 function lm.connection.create ( a )
 	local at = type (a)
 	if at == "string" then
@@ -205,14 +227,14 @@
 	return r
 end
 
--- the same table, as for lm.connection.create, but with few more fields:
--- ssl.validate - boolean
--- preopen      - callback to call after connection creation but before opening (to install log handler, for example)
--- onopen       - callback to call after connection is established, but before authentication
--- onconnect    - callback to call after connection will be established
--- username
--- password
--- resource
+-- The same table, as for lm.connection.create, but with few more fields:
+-- * ssl.validate - boolean
+-- * preopen      - callback to call after connection creation but before opening (to install log handler, for example)
+-- * onopen       - callback to call after connection is established, but before authentication
+-- * onconnect    - callback to call after connection will be established
+-- * username     - username to authenticate with
+-- * password     - password to authenticate with
+-- * resource     - jabber resource to use
 function lm.connect ( a )
 	if type ( a ) ~= "table" then
 		error "table expected as argument"
--- a/lm_ssl.c	Sat Mar 05 14:57:58 2016 +0200
+++ b/lm_ssl.c	Sat Mar 05 15:43:04 2016 +0200
@@ -1,5 +1,5 @@
 
-/* Copyright 2009 Myhailo Danylenko
+/* Copyright 2009-2016 Myhailo Danylenko
 
 This file is part of lua-lm.
 
@@ -167,6 +167,34 @@
 	return 1;
 }
 
+#ifdef HAVE_LM_SSL_SET_CA
+/// ssl:ca_path
+/// Set path to trusted ssl certificates. Argument must be a name of a PEM file
+/// or a name of directory with hashed certificates.
+/// A: string (path)
+static int ca_path_lm_ssl (lua_State *L)
+{
+	llm_ssl_t *object = luaL_checklm_ssl (L, 1);
+	const gchar *path = luaL_checkstring (L, 2);
+	lm_ssl_set_ca (object -> ssl, path);
+	return 0;
+}
+#endif
+
+#ifdef HAVE_LM_SSL_SET_CIPHER_LIST
+/// ssl:cipher_list
+/// Set list of allowed ciphers (colon-separated). Names may vary depending on ssl
+/// implementation in use.
+/// A: string (cipher list)
+static int cipher_list_lm_ssl (lua_State *L)
+{
+	llm_ssl_t *object = luaL_checklm_ssl (L, 1);
+	const gchar *list = luaL_checkstring (L, 2);
+	lm_ssl_set_cipher_list (object -> ssl, list);
+	return 0;
+}
+#endif
+
 /// ssl:fingerprint
 /// Returns fingerprint of remote server.
 /// R: string or nil
@@ -240,6 +268,12 @@
 };
 
 const static luaL_Reg reg_m_lm_ssl[] = {
+#ifdef HAVE_LM_SSL_SET_CA
+	{ "ca_path",     ca_path_lm_ssl     },
+#endif
+#ifdef HAVE_LM_SSL_SET_CIPHER_LIST
+	{ "cipher_list", cipher_list_lm_ssl },
+#endif
 	{ "fingerprint", fingerprint_lm_ssl },
 	{ "tls",         tls_lm_ssl         },
 	{ "pointer",     pointer_lm_ssl     },