net.c (6386B)
1 /* 2 * Copy me if you can. 3 * by 20h 4 */ 5 6 #include <unistd.h> 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <stdarg.h> 10 #include <string.h> 11 #include <strings.h> 12 #include <poll.h> 13 #include <arpa/inet.h> 14 #include <netinet/in.h> 15 #include <sys/types.h> 16 #include <sys/socket.h> 17 #include <netdb.h> 18 19 #include <tls.h> 20 21 #include "ind.h" 22 #include "net.h" 23 24 /* 25 * net format: 26 * net!addr!service 27 */ 28 enum { 29 NET_NET = 0x00, 30 NET_TCP, 31 NET_TCPS 32 }; 33 static char *netnames[] = { 34 [NET_NET] = "net", 35 [NET_TCP] = "tcp", 36 [NET_TCPS] = "tcps" 37 }; 38 39 int 40 net_gettype(char *str) 41 { 42 int i; 43 44 for (i = 0; i < nelem(netnames); i++) 45 if (!strcmp(netnames[i], str)) 46 return i; 47 return -1; 48 } 49 50 net_t * 51 net_new(char *desc) 52 { 53 net_t *ret; 54 int state; 55 char *tok, *buf, *toks; 56 57 state = -1; 58 toks = NULL; 59 ret = NULL; 60 buf = memdup(desc, strlen(desc)+1); 61 62 tok = strtok_r(buf, "!", &toks); 63 if (tok == NULL) 64 goto netnewerror; 65 66 ret = mallocz(sizeof(net_t), 2); 67 do { 68 state++; 69 switch(state) { 70 case 0: 71 ret->net = memdup(tok, strlen(tok)+1); 72 ret->type = net_gettype(ret->net); 73 break; 74 case 1: 75 ret->addr = memdup(tok, strlen(tok)+1); 76 break; 77 case 2: 78 ret->service = memdup(tok, strlen(tok)+1); 79 break; 80 case 3: 81 ret->options = memdup(tok, strlen(tok)+1); 82 break; 83 default: 84 break; 85 } 86 } while ((tok = strtok_r(NULL, "!", &toks)) != NULL); 87 if (state < 2) 88 goto netnewerror; 89 free(buf); 90 91 return ret; 92 netnewerror: 93 if (buf != NULL) 94 free(buf); 95 96 switch (state) { 97 case 1: 98 free(ret->addr); 99 case 0: 100 free(ret->net); 101 default: 102 break; 103 } 104 if (ret != NULL) 105 free(ret); 106 107 return NULL; 108 } 109 110 void 111 net_free(net_t *net) 112 { 113 switch (net->type) { 114 case NET_TCPS: 115 tls_free((struct tls *)net->data[0]); 116 tls_config_free((struct tls_config *)net->data[1]); 117 } 118 119 if (net->net != NULL) 120 free(net->net); 121 if (net->addr != NULL) 122 free(net->addr); 123 if (net->service != NULL) 124 free(net->service); 125 free(net); 126 } 127 128 int 129 net_connecttcp(net_t *net) 130 { 131 struct addrinfo hints, *ai, *rp; 132 133 memset(&hints, 0, sizeof(hints)); 134 /* 135 * Anyone knowing a real check for IPv6, instead of failing 136 * everything, should contact me. 137 */ 138 hints.ai_family = AF_UNSPEC; 139 hints.ai_socktype = SOCK_STREAM; 140 hints.ai_protocol = IPPROTO_TCP; 141 if (getaddrinfo(net->addr, net->service, &hints, &ai)) 142 return 1; 143 if (ai == NULL) 144 return 1; 145 146 for (rp = ai; rp != NULL; rp = rp->ai_next) { 147 net->fd = socket(rp->ai_family, rp->ai_socktype, 148 rp->ai_protocol); 149 if (net->fd < 0) 150 continue; 151 if (!connect(net->fd, rp->ai_addr, rp->ai_addrlen)) 152 break; 153 close(net->fd); 154 } 155 if (rp == NULL) 156 return 1; 157 freeaddrinfo(ai); 158 159 return 0; 160 } 161 162 int 163 net_addssl(net_t *net) 164 { 165 struct tls *tls = NULL; 166 struct tls_config *config = NULL; 167 168 if (tls_init() < 0) 169 return 1; 170 if ((tls = tls_client()) == NULL) 171 return 1; 172 if ((config = tls_config_new()) == NULL) { 173 tls_free(tls); 174 return 1; 175 } 176 177 if (net->options != NULL) { 178 if (strstr(net->options, "tlscertverify=off")) 179 tls_config_insecure_noverifycert(config); 180 if (strstr(net->options, "tlsnameverify=off")) 181 tls_config_insecure_noverifyname(config); 182 } 183 184 if (tls_configure(tls, config) < 0) { 185 fprintf(stderr, "tls_configure: %s\n", tls_error(tls)); 186 tls_free(tls); 187 tls_config_free(config); 188 return 1; 189 } 190 191 if (tls_connect_socket(tls, net->fd, net->addr) < 0) { 192 fprintf(stderr, "tls_connect_socket: %s\n", tls_error(tls)); 193 tls_free(tls); 194 tls_config_free(config); 195 return 1; 196 } 197 198 switch (net->type) { 199 case NET_NET: 200 case NET_TCP: 201 free(net->net); 202 net->net = memdup("tcps", 5); 203 net->type = net_gettype(net->net); 204 case NET_TCPS: 205 default: 206 break; 207 } 208 209 net->data[0] = tls; 210 net->data[1] = config; 211 212 return 0; 213 } 214 215 int 216 net_connecttcps(net_t *net) 217 { 218 if (net_connecttcp(net)) 219 return 1; 220 if (net_addssl(net)) 221 return 1; 222 223 return 0; 224 } 225 226 int 227 net_connect(net_t *net) 228 { 229 switch (net->type) { 230 case NET_NET: 231 case NET_TCP: 232 return net_connecttcp(net); 233 case NET_TCPS: 234 return net_connecttcps(net); 235 default: 236 return 1; 237 } 238 return 0; 239 } 240 241 void 242 net_closetcp(net_t *net) 243 { 244 shutdown(net->fd, SHUT_RDWR); 245 close(net->fd); 246 } 247 248 void 249 net_closetcps(net_t *net) 250 { 251 tls_close((struct tls *)net->data[0]); 252 } 253 254 void 255 net_close(net_t *net) 256 { 257 switch (net->type) { 258 case NET_NET: 259 case NET_TCP: 260 net_closetcp(net); 261 case NET_TCPS: 262 net_closetcps(net); 263 default: 264 break; 265 } 266 } 267 268 int 269 net_writetcp(net_t *net, char *buf, int len) 270 { 271 return send(net->fd, buf, len, MSG_NOSIGNAL); 272 } 273 274 int 275 net_writetcps(net_t *net, char *buf, int len) 276 { 277 int r = TLS_WANT_POLLIN; 278 279 while (r == TLS_WANT_POLLIN || r == TLS_WANT_POLLOUT) 280 r = tls_write((struct tls *)net->data[0], buf, len); 281 282 return r; 283 } 284 285 int 286 net_write(net_t *net, char *buf, int len) 287 { 288 switch (net->type) { 289 case NET_NET: 290 case NET_TCP: 291 return net_writetcp(net, buf, len); 292 case NET_TCPS: 293 return net_writetcps(net, buf, len); 294 default: 295 return -1; 296 } 297 return -1; 298 } 299 300 int 301 net_writeall(net_t *net, char *buf, int len) 302 { 303 int olen, nlen; 304 305 for (olen = 0; 306 (nlen = net_write(net, &buf[olen], len-olen)) >= 0 307 && olen < len; 308 olen += nlen); 309 310 return 0; 311 } 312 313 int 314 net_printf(net_t *net, char *fmt, ...) 315 { 316 va_list fmtargs; 317 char *buf; 318 int len; 319 320 va_start(fmtargs, fmt); 321 len = vsnprintf(NULL, 0, fmt, fmtargs); 322 va_end(fmtargs); 323 324 va_start(fmtargs, fmt); 325 buf = vsmprintf(fmt, fmtargs, len); 326 va_end(fmtargs); 327 328 len = net_writeall(net, buf, strlen(buf)); 329 free(buf); 330 return len; 331 } 332 333 int 334 net_readtcp(net_t *net, char *buf, int len) 335 { 336 return recv(net->fd, buf, len, 0); 337 } 338 339 int 340 net_readtcps(net_t *net, char *buf, int len) 341 { 342 int r = TLS_WANT_POLLIN; 343 344 while (r == TLS_WANT_POLLIN || r == TLS_WANT_POLLOUT) 345 r = tls_read((struct tls *)net->data[0], buf, len); 346 347 return r; 348 } 349 350 int 351 net_read(net_t *net, char *buf, int len) 352 { 353 switch (net->type) { 354 case NET_NET: 355 case NET_TCP: 356 return net_readtcp(net, buf, len); 357 case NET_TCPS: 358 return net_readtcps(net, buf, len); 359 default: 360 return -1; 361 } 362 return -1; 363 } 364 365 int 366 net_readall(net_t *net, char *buf, int len) 367 { 368 int olen, nlen; 369 370 for (olen = 0; 371 (nlen = net_read(net, &buf[olen], len-olen)) 372 && olen < len; 373 olen += nlen); 374 375 return 0; 376 } 377 378 char * 379 net_gets(net_t *net) 380 { 381 char *ret; 382 int len; 383 384 len = 1; 385 ret = mallocz(len, 2); 386 while (net_read(net, &ret[len-1], 1) > 0 && ret[len-1] != '\n' 387 && len < MAXLINESIZE) 388 ret = reallocz(ret, ++len + 1, 0); 389 /* 390 if (ret[len-1] != '\n') { 391 free(ret); 392 return NULL; 393 } 394 ret[len-1] = '\0'; 395 */ 396 ret[len] = '\0'; 397 398 return ret; 399 } 400