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, code);
26 lua_pushinteger(L, SSL_get_error(sock, code));
30 static int nixio__tls_sock_pstatus(lua_State *L, SSL *sock, int code) {
32 lua_pushboolean(L, 1);
35 return nixio__tls_sock_perror(L, sock, code);
39 static SSL* nixio__checktlssock(lua_State *L) {
40 nixio_tls_sock *sock = luaL_checkudata(L, 1, NIXIO_TLS_SOCK_META);
41 luaL_argcheck(L, sock->socket, 1, "invalid context");
45 static int nixio_tls_sock_recv(lua_State *L) {
46 SSL *sock = nixio__checktlssock(L);
47 int req = luaL_checkinteger(L, 2);
49 luaL_argcheck(L, req >= 0, 2, "out of range");
51 /* We limit the readsize to NIXIO_BUFFERSIZE */
52 req = (req > NIXIO_BUFFERSIZE) ? NIXIO_BUFFERSIZE : req;
56 char buffer[NIXIO_BUFFERSIZE];
57 int readc = SSL_read(sock, buffer, req);
60 return nixio__tls_sock_pstatus(L, sock, readc);
62 lua_pushlstring(L, buffer, readc);
69 lua_pushliteral(L, "");
73 nixio_tls_sock *t = lua_touserdata(L, 1);
75 /* AXTLS doesn't handle buffering for us, so we have to hack around*/
76 if (req < t->pbufsiz) {
77 lua_pushlstring(L, t->pbufpos, req);
85 /* while handshake pending */
86 while ((axread = ssl_read(sock, (uint8_t**)&axbuf)) == SSL_OK);
89 lua_pushlstring(L, t->pbufpos, t->pbufsiz);
93 /* There is an error */
95 t->pbuffer = t->pbufpos = NULL;
98 if (axread != SSL_ERROR_CONN_LOST) {
99 return nixio__tls_sock_perror(L, sock, axread);
102 lua_pushliteral(L, "");
106 int stillwant = req - t->pbufsiz;
107 if (stillwant < axread) {
108 /* we got more data than we need */
109 lua_pushlstring(L, axbuf, stillwant);
114 /* remaining data goes into the buffer */
115 t->pbufpos = t->pbuffer;
116 t->pbufsiz = axread - stillwant;
117 t->pbuffer = realloc(t->pbuffer, t->pbufsiz);
122 return luaL_error(L, "out of memory");
125 t->pbufpos = t->pbuffer;
126 memcpy(t->pbufpos, axbuf + stillwant, t->pbufsiz);
128 lua_pushlstring(L, axbuf, axread);
135 t->pbuffer = t->pbufpos = NULL;
142 #endif /* WITH_AXTLS */
146 static int nixio_tls_sock_send(lua_State *L) {
147 SSL *sock = nixio__checktlssock(L);
150 const char *data = luaL_checklstring(L, 2, &len);
151 sent = SSL_write(sock, data, len);
153 lua_pushinteger(L, sent);
156 return nixio__tls_sock_pstatus(L, sock, len);
160 static int nixio_tls_sock_accept(lua_State *L) {
161 SSL *sock = nixio__checktlssock(L);
162 return nixio__tls_sock_pstatus(L, sock, SSL_accept(sock));
165 static int nixio_tls_sock_connect(lua_State *L) {
166 SSL *sock = nixio__checktlssock(L);
167 return nixio__tls_sock_pstatus(L, sock, SSL_connect(sock));
170 static int nixio_tls_sock_shutdown(lua_State *L) {
171 SSL *sock = nixio__checktlssock(L);
172 return nixio__tls_sock_pstatus(L, sock, SSL_shutdown(sock));
175 static int nixio_tls_sock__gc(lua_State *L) {
176 nixio_tls_sock *sock = luaL_checkudata(L, 1, NIXIO_TLS_SOCK_META);
178 SSL_free(sock->socket);
187 static int nixio_tls_sock__tostring(lua_State *L) {
188 SSL *sock = nixio__checktlssock(L);
189 lua_pushfstring(L, "nixio TLS socket: %p", sock);
194 /* ctx function table */
195 static const luaL_reg M[] = {
196 {"recv", nixio_tls_sock_recv},
197 {"send", nixio_tls_sock_send},
198 {"accept", nixio_tls_sock_accept},
199 {"connect", nixio_tls_sock_connect},
200 {"shutdown", nixio_tls_sock_shutdown},
201 {"__gc", nixio_tls_sock__gc},
202 {"__tostring", nixio_tls_sock__tostring},
207 void nixio_open_tls_socket(lua_State *L) {
208 /* create socket metatable */
209 luaL_newmetatable(L, NIXIO_TLS_SOCK_META);
210 luaL_register(L, NULL, M);
211 lua_pushvalue(L, -1);
212 lua_setfield(L, -2, "__index");
213 lua_setfield(L, -2, "tls_socket_meta");