2 * nixio - Linux I/O library for lua
4 * Copyright (C) 2009 Steven Barth <steven@midlink.org>
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
19 #include "nixio-tls.h"
23 static int nixio__tls_sock_perror(lua_State
*L
, SSL
*sock
, int code
) {
25 lua_pushinteger(L
, SSL_get_error(sock
, code
));
29 static int nixio__tls_sock_pstatus(lua_State
*L
, SSL
*sock
, int code
) {
31 lua_pushboolean(L
, 1);
34 return nixio__tls_sock_perror(L
, sock
, code
);
38 static SSL
* nixio__checktlssock(lua_State
*L
) {
39 if (lua_istable(L
, 1)) {
40 lua_getfield(L
, 1, "connection");
43 nixio_tls_sock
*sock
= luaL_checkudata(L
, 1, NIXIO_TLS_SOCK_META
);
44 luaL_argcheck(L
, sock
->socket
, 1, "invalid context");
48 static int nixio_tls_sock_recv(lua_State
*L
) {
49 SSL
*sock
= nixio__checktlssock(L
);
50 int req
= luaL_checkinteger(L
, 2);
52 luaL_argcheck(L
, req
>= 0, 2, "out of range");
54 /* We limit the readsize to NIXIO_BUFFERSIZE */
55 req
= (req
> NIXIO_BUFFERSIZE
) ? NIXIO_BUFFERSIZE
: req
;
59 char buffer
[NIXIO_BUFFERSIZE
];
60 int readc
= SSL_read(sock
, buffer
, req
);
63 return nixio__tls_sock_pstatus(L
, sock
, readc
);
65 lua_pushlstring(L
, buffer
, readc
);
72 lua_pushliteral(L
, "");
76 nixio_tls_sock
*t
= lua_touserdata(L
, 1);
78 /* AXTLS doesn't handle buffering for us, so we have to hack around*/
79 if (req
< t
->pbufsiz
) {
80 lua_pushlstring(L
, t
->pbufpos
, req
);
88 /* while handshake pending */
89 while ((axread
= ssl_read(sock
, (uint8_t**)&axbuf
)) == SSL_OK
);
92 lua_pushlstring(L
, t
->pbufpos
, t
->pbufsiz
);
96 /* There is an error */
98 t
->pbuffer
= t
->pbufpos
= NULL
;
101 if (axread
!= SSL_ERROR_CONN_LOST
) {
102 return nixio__tls_sock_perror(L
, sock
, axread
);
105 lua_pushliteral(L
, "");
109 int stillwant
= req
- t
->pbufsiz
;
110 if (stillwant
< axread
) {
111 /* we got more data than we need */
112 lua_pushlstring(L
, axbuf
, stillwant
);
117 /* remaining data goes into the buffer */
118 t
->pbufpos
= t
->pbuffer
;
119 t
->pbufsiz
= axread
- stillwant
;
120 t
->pbuffer
= realloc(t
->pbuffer
, t
->pbufsiz
);
125 return luaL_error(L
, "out of memory");
128 t
->pbufpos
= t
->pbuffer
;
129 memcpy(t
->pbufpos
, axbuf
+ stillwant
, t
->pbufsiz
);
131 lua_pushlstring(L
, axbuf
, axread
);
138 t
->pbuffer
= t
->pbufpos
= NULL
;
145 #endif /* WITH_AXTLS */
149 static int nixio_tls_sock_send(lua_State
*L
) {
150 SSL
*sock
= nixio__checktlssock(L
);
153 const char *data
= luaL_checklstring(L
, 2, &len
);
154 sent
= SSL_write(sock
, data
, len
);
156 lua_pushinteger(L
, sent
);
159 return nixio__tls_sock_pstatus(L
, sock
, len
);
163 static int nixio_tls_sock_accept(lua_State
*L
) {
164 SSL
*sock
= nixio__checktlssock(L
);
165 return nixio__tls_sock_pstatus(L
, sock
, SSL_accept(sock
));
168 static int nixio_tls_sock_connect(lua_State
*L
) {
169 SSL
*sock
= nixio__checktlssock(L
);
170 return nixio__tls_sock_pstatus(L
, sock
, SSL_connect(sock
));
173 static int nixio_tls_sock_shutdown(lua_State
*L
) {
174 SSL
*sock
= nixio__checktlssock(L
);
175 return nixio__tls_sock_pstatus(L
, sock
, SSL_shutdown(sock
));
178 static int nixio_tls_sock__gc(lua_State
*L
) {
179 nixio_tls_sock
*sock
= luaL_checkudata(L
, 1, NIXIO_TLS_SOCK_META
);
181 SSL_free(sock
->socket
);
190 static int nixio_tls_sock__tostring(lua_State
*L
) {
191 SSL
*sock
= nixio__checktlssock(L
);
192 lua_pushfstring(L
, "nixio TLS connection: %p", sock
);
197 /* ctx function table */
198 static const luaL_reg M
[] = {
199 {"recv", nixio_tls_sock_recv
},
200 {"send", nixio_tls_sock_send
},
201 {"accept", nixio_tls_sock_accept
},
202 {"connect", nixio_tls_sock_connect
},
203 {"shutdown", nixio_tls_sock_shutdown
},
204 {"__gc", nixio_tls_sock__gc
},
205 {"__tostring", nixio_tls_sock__tostring
},
210 void nixio_open_tls_socket(lua_State
*L
) {
211 /* create socket metatable */
212 luaL_newmetatable(L
, NIXIO_TLS_SOCK_META
);
213 luaL_register(L
, NULL
, M
);
214 lua_pushvalue(L
, -1);
215 lua_setfield(L
, -2, "__index");
216 lua_setfield(L
, -2, "tls_socket_meta");