1 /*=========================================================================*\
2 * Internet domain functions
3 * LuaSocket toolkit
4 *
5 * RCS ID: $Id: inet.c,v 1.28 2005/10/07 04:40:59 diego Exp $
6 \*=========================================================================*/
7 #include <stdio.h>
8 #include <string.h>
9
10 #include "lua.h"
11 #include "lauxlib.h"
12
13 #include "inet.h"
14 //spring includes
15 #include "restrictions.h"
16 #include "System/Log/ILog.h"
17
18 /*=========================================================================*\
19 * Internal function prototypes.
20 \*=========================================================================*/
21 static int inet_global_toip(lua_State *L);
22 static int inet_global_tohostname(lua_State *L);
23 static void inet_pushresolved(lua_State *L, struct hostent *hp);
24 static int inet_global_gethostname(lua_State *L);
25
26 /* DNS functions */
27 static luaL_reg func[] = {
28 { "toip", inet_global_toip },
29 { "tohostname", inet_global_tohostname },
30 { "gethostname", inet_global_gethostname},
31 { NULL, NULL}
32 };
33
34 /*=========================================================================*\
35 * Exported functions
36 \*=========================================================================*/
37 /*-------------------------------------------------------------------------*\
38 * Initializes module
39 \*-------------------------------------------------------------------------*/
inet_open(lua_State * L)40 int inet_open(lua_State *L)
41 {
42 lua_pushstring(L, "dns");
43 lua_newtable(L);
44 luaI_openlib(L, NULL, func, 0);
45 lua_settable(L, -3);
46 return 0;
47 }
48
49 /*=========================================================================*\
50 * Global Lua functions
51 \*=========================================================================*/
52 /*-------------------------------------------------------------------------*\
53 * Returns all information provided by the resolver given a host name
54 * or ip address
55 \*-------------------------------------------------------------------------*/
inet_gethost(const char * address,struct hostent ** hp)56 static int inet_gethost(const char *address, struct hostent **hp) {
57 struct in_addr addr;
58 if (inet_aton(address, &addr))
59 return socket_gethostbyaddr((char *) &addr, sizeof(addr), hp);
60 else
61 return socket_gethostbyname(address, hp);
62 }
63
64 /*-------------------------------------------------------------------------*\
65 * Returns all information provided by the resolver given a host name
66 * or ip address
67 \*-------------------------------------------------------------------------*/
inet_global_tohostname(lua_State * L)68 static int inet_global_tohostname(lua_State *L) {
69 const char *address = luaL_checkstring(L, 1);
70 struct hostent *hp = NULL;
71 int err = inet_gethost(address, &hp);
72 luaSocketRestrictions->addIP(address, hp->h_name); //add resolved ip to rules
73 if (err != IO_DONE) {
74 lua_pushnil(L);
75 lua_pushstring(L, socket_hoststrerror(err));
76 return 2;
77 }
78 lua_pushstring(L, hp->h_name);
79 inet_pushresolved(L, hp);
80 return 2;
81 }
82
83 /*-------------------------------------------------------------------------*\
84 * Returns all information provided by the resolver given a host name
85 * or ip address
86 \*-------------------------------------------------------------------------*/
inet_global_toip(lua_State * L)87 static int inet_global_toip(lua_State *L)
88 {
89 const char *address = luaL_checkstring(L, 1);
90 if (!luaSocketRestrictions->isAllowed(CLuaSocketRestrictions::ALL_RULES, address)) {
91 lua_pushnil(L);
92 LOG_L(L_ERROR, "Access to '%s' denied", address);
93 lua_pushstring(L, "hostname not in allowed list");
94 return 2;
95 }
96 struct hostent *hp = NULL;
97 int err = inet_gethost(address, &hp);
98 if (err != IO_DONE) {
99 lua_pushnil(L);
100 lua_pushstring(L, socket_hoststrerror(err));
101 return 2;
102 }
103 const char* ip = inet_ntoa(*((struct in_addr *) hp->h_addr));
104 luaSocketRestrictions->addIP(address, ip);
105 lua_pushstring(L, ip);
106 inet_pushresolved(L, hp);
107 return 2;
108 }
109
110
111 /*-------------------------------------------------------------------------*\
112 * Gets the host name
113 \*-------------------------------------------------------------------------*/
inet_global_gethostname(lua_State * L)114 static int inet_global_gethostname(lua_State *L)
115 {
116 char name[257];
117 name[256] = '\0';
118 if (gethostname(name, 256) < 0) {
119 lua_pushnil(L);
120 lua_pushstring(L, "gethostname failed");
121 return 2;
122 } else {
123 lua_pushstring(L, name);
124 return 1;
125 }
126 }
127
128
129
130 /*=========================================================================*\
131 * Lua methods
132 \*=========================================================================*/
133 /*-------------------------------------------------------------------------*\
134 * Retrieves socket peer name
135 \*-------------------------------------------------------------------------*/
inet_meth_getpeername(lua_State * L,p_socket ps)136 int inet_meth_getpeername(lua_State *L, p_socket ps)
137 {
138 struct sockaddr_in peer;
139 socklen_t peer_len = sizeof(peer);
140 if (getpeername(*ps, (SA *) &peer, &peer_len) < 0) {
141 lua_pushnil(L);
142 lua_pushstring(L, "getpeername failed");
143 } else {
144 lua_pushstring(L, inet_ntoa(peer.sin_addr));
145 lua_pushnumber(L, ntohs(peer.sin_port));
146 }
147 return 2;
148 }
149
150 /*-------------------------------------------------------------------------*\
151 * Retrieves socket local name
152 \*-------------------------------------------------------------------------*/
inet_meth_getsockname(lua_State * L,p_socket ps)153 int inet_meth_getsockname(lua_State *L, p_socket ps)
154 {
155 struct sockaddr_in local;
156 socklen_t local_len = sizeof(local);
157 if (getsockname(*ps, (SA *) &local, &local_len) < 0) {
158 lua_pushnil(L);
159 lua_pushstring(L, "getsockname failed");
160 } else {
161 lua_pushstring(L, inet_ntoa(local.sin_addr));
162 lua_pushnumber(L, ntohs(local.sin_port));
163 }
164 return 2;
165 }
166
167 /*=========================================================================*\
168 * Internal functions
169 \*=========================================================================*/
170 /*-------------------------------------------------------------------------*\
171 * Passes all resolver information to Lua as a table
172 \*-------------------------------------------------------------------------*/
inet_pushresolved(lua_State * L,struct hostent * hp)173 static void inet_pushresolved(lua_State *L, struct hostent *hp)
174 {
175 char **alias;
176 struct in_addr **addr;
177 int i, resolved;
178 lua_newtable(L); resolved = lua_gettop(L);
179 lua_pushstring(L, "name");
180 lua_pushstring(L, hp->h_name);
181 lua_settable(L, resolved);
182 lua_pushstring(L, "ip");
183 lua_pushstring(L, "alias");
184 i = 1;
185 alias = hp->h_aliases;
186 lua_newtable(L);
187 if (alias) {
188 while (*alias) {
189 lua_pushnumber(L, i);
190 lua_pushstring(L, *alias);
191 lua_settable(L, -3);
192 i++; alias++;
193 }
194 }
195 lua_settable(L, resolved);
196 i = 1;
197 lua_newtable(L);
198 addr = (struct in_addr **) hp->h_addr_list;
199 if (addr) {
200 while (*addr) {
201 lua_pushnumber(L, i);
202 lua_pushstring(L, inet_ntoa(**addr));
203 lua_settable(L, -3);
204 i++; addr++;
205 }
206 }
207 lua_settable(L, resolved);
208 }
209
210 /*-------------------------------------------------------------------------*\
211 * Tries to create a new inet socket
212 \*-------------------------------------------------------------------------*/
inet_trycreate(p_socket ps,int type)213 const char *inet_trycreate(p_socket ps, int type) {
214 return socket_strerror(socket_create(ps, AF_INET, type, 0));
215 }
216
217
isAllowed(p_socket ps,const char * address,unsigned short port,bool connect)218 bool isAllowed(p_socket ps, const char *address, unsigned short port, bool connect){
219 int rawtype;
220 socklen_t len = sizeof(rawtype);
221 CLuaSocketRestrictions::RestrictType type;
222 int res = getsockopt(*ps, SOL_SOCKET, SO_TYPE, (char*)&rawtype, &len);
223 #ifdef WIN32
224 if (res == SOCKET_ERROR) {
225 LOG_L(L_ERROR, "Socket error (%d): %s", res, socket_strerror(WSAGetLastError()));
226 return false;
227 }
228 #else
229 if (res != 0) {
230 LOG_L(L_ERROR, "Socket error (%d): %s", res, socket_strerror(errno));
231 return false;
232 }
233 #endif
234 if (rawtype == SOCK_STREAM)
235 if (connect)
236 type = CLuaSocketRestrictions::TCP_CONNECT;
237 else
238 type = CLuaSocketRestrictions::TCP_LISTEN;
239 else //SOCK_DGRAM
240 if (connect)
241 type = CLuaSocketRestrictions::UDP_CONNECT;
242 else
243 type = CLuaSocketRestrictions::UDP_LISTEN;
244 if (!luaSocketRestrictions->isAllowed(type, address, port)) {
245 LOG_L(L_ERROR, "Access to '%s:%d' denied", address, port);
246 return false;
247 }
248 return true;
249 }
250
251 /*-------------------------------------------------------------------------*\
252 * Tries to connect to remote address (address, port)
253 \*-------------------------------------------------------------------------*/
inet_tryconnect(p_socket ps,const char * address,unsigned short port,p_timeout tm)254 const char *inet_tryconnect(p_socket ps, const char *address,
255 unsigned short port, p_timeout tm)
256 {
257 if (!isAllowed(ps, address, port, true))
258 return "connect denied";
259
260 struct sockaddr_in remote;
261 int err;
262 memset(&remote, 0, sizeof(remote));
263 remote.sin_family = AF_INET;
264 remote.sin_port = htons(port);
265 if (strcmp(address, "*")) {
266 if (!inet_aton(address, &remote.sin_addr)) {
267 struct hostent *hp = NULL;
268 struct in_addr **addr;
269 err = socket_gethostbyname(address, &hp);
270 if (err != IO_DONE) return socket_hoststrerror(err);
271 addr = (struct in_addr **) hp->h_addr_list;
272 memcpy(&remote.sin_addr, *addr, sizeof(struct in_addr));
273 luaSocketRestrictions->addIP(address, inet_ntoa(**addr));
274 }
275 } else remote.sin_family = AF_UNSPEC;
276 err = socket_connect(ps, (SA *) &remote, sizeof(remote), tm);
277 return socket_strerror(err);
278 }
279
280 /*-------------------------------------------------------------------------*\
281 * Tries to bind socket to (address, port)
282 \*-------------------------------------------------------------------------*/
inet_trybind(p_socket ps,const char * address,unsigned short port)283 const char *inet_trybind(p_socket ps, const char *address, unsigned short port)
284 {
285 if (!isAllowed(ps, address, port, false))
286 return "bind denied";
287
288 struct sockaddr_in local;
289 int err;
290 memset(&local, 0, sizeof(local));
291 /* address is either wildcard or a valid ip address */
292 local.sin_addr.s_addr = htonl(INADDR_ANY);
293 local.sin_port = htons(port);
294 local.sin_family = AF_INET;
295 if (strcmp(address, "*") && !inet_aton(address, &local.sin_addr)) {
296 struct hostent *hp = NULL;
297 struct in_addr **addr;
298 err = socket_gethostbyname(address, &hp);
299 if (err != IO_DONE) return socket_hoststrerror(err);
300 addr = (struct in_addr **) hp->h_addr_list;
301 memcpy(&local.sin_addr, *addr, sizeof(struct in_addr));
302 luaSocketRestrictions->addIP(address, inet_ntoa(**addr));
303 }
304 err = socket_bind(ps, (SA *) &local, sizeof(local));
305 if (err != IO_DONE) socket_destroy(ps);
306 return socket_strerror(err);
307 }
308
309 /*-------------------------------------------------------------------------*\
310 * Some systems do not provide this so that we provide our own. It's not
311 * marvelously fast, but it works just fine.
312 \*-------------------------------------------------------------------------*/
313 #ifdef INET_ATON
inet_aton(const char * cp,struct in_addr * inp)314 int inet_aton(const char *cp, struct in_addr *inp)
315 {
316 unsigned int a = 0, b = 0, c = 0, d = 0;
317 int n = 0, r;
318 unsigned long int addr = 0;
319 r = sscanf(cp, "%u.%u.%u.%u%n", &a, &b, &c, &d, &n);
320 if (r == 0 || n == 0) return 0;
321 cp += n;
322 if (*cp) return 0;
323 if (a > 255 || b > 255 || c > 255 || d > 255) return 0;
324 if (inp) {
325 addr += a; addr <<= 8;
326 addr += b; addr <<= 8;
327 addr += c; addr <<= 8;
328 addr += d;
329 inp->s_addr = htonl(addr);
330 }
331 return 1;
332 }
333 #endif
334
335
336