lm_ssl.c
changeset 11 a8c6460d612b
parent 9 50f55d494efb
child 12 63f06a23c235
equal deleted inserted replaced
10:aed141accdd9 11:a8c6460d612b
    14 /// Create, set parameters, and attach to connection with 'ssl' method.
    14 /// Create, set parameters, and attach to connection with 'ssl' method.
    15 
    15 
    16 /// ssl status
    16 /// ssl status
    17 /// String, representing what problem have current ssl session.
    17 /// String, representing what problem have current ssl session.
    18 /// G:
    18 /// G:
    19 const string2enum_t llm_ssl_status[] = {
    19 const string2enum_t status_lm_ssl[] = {
    20 	{ "no cert found",             LM_SSL_STATUS_NO_CERT_FOUND             },
    20 	{ "no cert found",             LM_SSL_STATUS_NO_CERT_FOUND             },
    21 	{ "untrusted cert",            LM_SSL_STATUS_UNTRUSTED_CERT            },
    21 	{ "untrusted cert",            LM_SSL_STATUS_UNTRUSTED_CERT            },
    22 	{ "cert expired",              LM_SSL_STATUS_CERT_EXPIRED              },
    22 	{ "cert expired",              LM_SSL_STATUS_CERT_EXPIRED              },
    23 	{ "cert not activated",        LM_SSL_STATUS_CERT_NOT_ACTIVATED        },
    23 	{ "cert not activated",        LM_SSL_STATUS_CERT_NOT_ACTIVATED        },
    24 	{ "cert hostname mismatch",    LM_SSL_STATUS_CERT_HOSTNAME_MISMATCH    },
    24 	{ "cert hostname mismatch",    LM_SSL_STATUS_CERT_HOSTNAME_MISMATCH    },
    31 /// User function, called when ssl error happens.
    31 /// User function, called when ssl error happens.
    32 /// XXX: add lm connection object to args? it is not in API, but can be useful,
    32 /// XXX: add lm connection object to args? it is not in API, but can be useful,
    33 /// though, with upvalues it is not required.
    33 /// though, with upvalues it is not required.
    34 /// A: lm ssl object, ssl status
    34 /// A: lm ssl object, ssl status
    35 /// R: boolean (false if connection process should be terminated)
    35 /// R: boolean (false if connection process should be terminated)
    36 LmSSLResponse llm_ssl_callback (LmSSL *ssl, LmSSLStatus status, llm_callback_t *cb)
    36 LmSSLResponse callback_lm_ssl (LmSSL *ssl, LmSSLStatus status, llm_callback_t *cb)
    37 {
    37 {
    38 	int ret;
    38 	int ret;
    39 	lua_rawgeti (cb->L, LUA_REGISTRYINDEX, cb->reference);
    39 	lua_rawgeti (cb->L, LUA_REGISTRYINDEX, cb->reference);
    40 	llm_ssl_bless (cb->L, ssl);
    40 	bless_lm_ssl (cb->L, ssl);
    41 	// XXX lm_ssl_unref (ssl);
    41 	// XXX lm_ssl_unref (ssl);
    42 	luaL_pushenum (cb->L, status, llm_ssl_status);
    42 	luaL_pushenum (cb->L, status, status_lm_ssl);
    43 	if (lua_pcall (cb->L, 2, 0, 0)) {
    43 	if (lua_pcall (cb->L, 2, 0, 0)) {
    44 		W ("SSL callback error: %s", lua_tostring (cb->L, -1));
    44 		W ("SSL callback error: %s", lua_tostring (cb->L, -1));
    45 		lua_pop (cb->L, 1);
    45 		lua_pop (cb->L, 1);
    46 		return LM_SSL_RESPONSE_CONTINUE;
    46 		return LM_SSL_RESPONSE_CONTINUE;
    47 	}
    47 	}
    68 /// You can specify server key fingerprint, callback function for error handling,
    68 /// You can specify server key fingerprint, callback function for error handling,
    69 /// both, or neither. Though, fingerprint should go before callback function.
    69 /// both, or neither. Though, fingerprint should go before callback function.
    70 /// SSL fingerprint is a string like '01:23:45:67:89:AB:CD:EF:FE:DC:BA:98:76:54:32:10'.
    70 /// SSL fingerprint is a string like '01:23:45:67:89:AB:CD:EF:FE:DC:BA:98:76:54:32:10'.
    71 /// A: string (optional ssl fingerprint), ssl callback function (optional)
    71 /// A: string (optional ssl fingerprint), ssl callback function (optional)
    72 /// R: lm ssl object
    72 /// R: lm ssl object
    73 static int llm_ssl_new (lua_State *L)
    73 static int new_lm_ssl (lua_State *L)
    74 {
    74 {
    75 	int args = lua_gettop (L);
    75 	int args = lua_gettop (L);
    76 	LmSSL *ssl;
    76 	LmSSL *ssl;
    77 	if (args == 0)
    77 	if (args == 0)
    78 		ssl = lm_ssl_new (NULL, NULL, NULL, NULL);
    78 		ssl = lm_ssl_new (NULL, NULL, NULL, NULL);
    97 		
    97 		
    98 		cb = luaL_malloc (L, sizeof (llm_callback_t));
    98 		cb = luaL_malloc (L, sizeof (llm_callback_t));
    99 		cb->reference = luaL_ref (L, LUA_REGISTRYINDEX);
    99 		cb->reference = luaL_ref (L, LUA_REGISTRYINDEX);
   100 		cb->L = L;
   100 		cb->L = L;
   101 
   101 
   102 		ssl = lm_ssl_new ((args > 1) ? buffer : NULL, (LmSSLFunction)llm_ssl_callback,
   102 		ssl = lm_ssl_new ((args > 1) ? buffer : NULL, (LmSSLFunction)callback_lm_ssl,
   103 							cb, (GDestroyNotify)llm_callback_destroy);
   103 							cb, (GDestroyNotify)llm_callback_destroy);
   104 	}
   104 	}
   105 	llm_ssl_bless (L, ssl);
   105 	bless_lm_ssl (L, ssl);
   106 	lm_ssl_unref (ssl); // XXX
   106 	lm_ssl_unref (ssl); // XXX
   107 	D ("SSL %X created", (int) ssl);
   107 	D ("SSL %X created", (int) ssl);
   108 	return 1;
   108 	return 1;
   109 }
   109 }
   110 
   110 
   111 /// lm.ssl.bless
   111 /// lm.ssl.bless
   112 /// Blesses given pointer to lm ssl object.
   112 /// Blesses given pointer to lm ssl object.
   113 /// A: lightuserdata (C lm ssl object)
   113 /// A: lightuserdata (C lm ssl object)
   114 /// R: lm ssl object
   114 /// R: lm ssl object
   115 static int llm_ssl_bless_lua (lua_State *L)
   115 static int bless_lua_lm_ssl (lua_State *L)
   116 {
   116 {
   117 	luaL_argcheck (L, lua_islightuserdata (L, 1), 1, "lm ssl lightuserdata expected");
   117 	luaL_argcheck (L, lua_islightuserdata (L, 1), 1, "lm ssl lightuserdata expected");
   118 	llm_ssl_bless (L, lua_touserdata (L, 1));
   118 	bless_lm_ssl (L, lua_touserdata (L, 1));
   119 	return 1;
   119 	return 1;
   120 }
   120 }
   121 
   121 
   122 /// lm.ssl.supported
   122 /// lm.ssl.supported
   123 /// Indicates if SSL is supported by loudmouth library.
   123 /// Indicates if SSL is supported by loudmouth library.
   124 /// R: boolean
   124 /// R: boolean
   125 static int llm_ssl_supported (lua_State *L)
   125 static int supported_lm_ssl (lua_State *L)
   126 {
   126 {
   127 	lua_pushboolean (L, lm_ssl_is_supported ());
   127 	lua_pushboolean (L, lm_ssl_is_supported ());
   128 	return 1;
   128 	return 1;
   129 }
   129 }
   130 
   130 
   131 /// ssl:fingerprint
   131 /// ssl:fingerprint
   132 /// Returns fingerprint of remote server.
   132 /// Returns fingerprint of remote server.
   133 /// R: string or nil
   133 /// R: string or nil
   134 static int llm_ssl_fingerprint (lua_State *L)
   134 static int fingerprint_lm_ssl (lua_State *L)
   135 {
   135 {
   136 	char buffer[48];
   136 	char buffer[48];
   137 	llm_ssl_t *object = luaL_checklm_ssl (L, 1);
   137 	llm_ssl_t *object = luaL_checklm_ssl (L, 1);
   138 	const gchar *fingerprint = lm_ssl_get_fingerprint (object->ssl);
   138 	const gchar *fingerprint = lm_ssl_get_fingerprint (object->ssl);
   139 	if (fingerprint == NULL)
   139 	if (fingerprint == NULL)
   152 }
   152 }
   153 
   153 
   154 /// ssl:pointer
   154 /// ssl:pointer
   155 /// Returns pointer to underlying C structure.
   155 /// Returns pointer to underlying C structure.
   156 /// R: lightuserdata
   156 /// R: lightuserdata
   157 static int llm_ssl_pointer (lua_State *L)
   157 static int pointer_lm_ssl (lua_State *L)
   158 {
   158 {
   159 	llm_ssl_t *object = luaL_checklm_ssl (L, 1);
   159 	llm_ssl_t *object = luaL_checklm_ssl (L, 1);
   160 	lua_pushlightuserdata (L, object->ssl);
   160 	lua_pushlightuserdata (L, object->ssl);
   161 	return 1;
   161 	return 1;
   162 }
   162 }
   163 
   163 
   164 static int llm_ssl_gc (lua_State *L)
   164 static int gc_lm_ssl (lua_State *L)
   165 {
   165 {
   166 	llm_ssl_t *object = luaL_checklm_ssl (L, 1);
   166 	llm_ssl_t *object = luaL_checklm_ssl (L, 1);
   167 	D ("SSL %X gc called", (int) object);
   167 	D ("SSL %X gc called", (int) object);
   168 	lm_ssl_unref (object->ssl);
   168 	lm_ssl_unref (object->ssl);
   169 	return 0;
   169 	return 0;
   170 }
   170 }
   171 
   171 
   172 const static luaL_Reg llm_ssl_reg_f[] = {
   172 const static luaL_Reg reg_f_lm_ssl[] = {
   173 	{ "new",       llm_ssl_new       },
   173 	{ "new",       new_lm_ssl       },
   174 	{ "bless",     llm_ssl_bless_lua },
   174 	{ "bless",     bless_lua_lm_ssl },
   175 	{ "supported", llm_ssl_supported },
   175 	{ "supported", supported_lm_ssl },
   176 	{ NULL,        NULL              },
   176 	{ NULL,        NULL              },
   177 };
   177 };
   178 
   178 
   179 const static luaL_Reg llm_ssl_reg_m[] = {
   179 const static luaL_Reg reg_m_lm_ssl[] = {
   180 	{ "fingerprint", llm_ssl_fingerprint },
   180 	{ "fingerprint", fingerprint_lm_ssl },
   181 	{ "pointer",     llm_ssl_pointer     },
   181 	{ "pointer",     pointer_lm_ssl     },
   182 	{ "__gc",        llm_ssl_gc          },
   182 	{ "__gc",        gc_lm_ssl          },
   183 	{ NULL,          NULL                },
   183 	{ NULL,          NULL                },
   184 };
   184 };
   185 
   185 
   186 int luaopen_lm_ssl (lua_State *L)
   186 int luaopen_lm_ssl (lua_State *L)
   187 {
   187 {
   188 	luaL_newmetatable (L, "loudmouth.ssl");
   188 	luaL_newmetatable (L, "loudmouth.ssl");
   189 	lua_pushstring (L, "__index");
   189 	lua_pushstring (L, "__index");
   190 	lua_pushvalue (L, -2);
   190 	lua_pushvalue (L, -2);
   191 	lua_settable (L, -3);
   191 	lua_settable (L, -3);
   192 	luaL_register (L, NULL, llm_ssl_reg_m);
   192 	luaL_register (L, NULL, reg_m_lm_ssl);
   193 	lua_pop (L, 1);
   193 	lua_pop (L, 1);
   194 	luaL_register (L, "lm.ssl", llm_ssl_reg_f);
   194 	luaL_register (L, "lm.ssl", reg_f_lm_ssl);
   195 	return 1;
   195 	return 1;
   196 }
   196 }
   197 
   197