// TLS handler for HaxServ // // Written by: Test_User // // This is free and unencumbered software released into the public // domain. // // Anyone is free to copy, modify, publish, use, compile, sell, or // distribute this software, either in source code form or as a compiled // binary, for any purpose, commercial or non-commercial, and by any // means. // // In jurisdictions that recognize copyright laws, the author or authors // of this software dedicate any and all copyright interest in the // software to the public domain. We make this dedication for the benefit // of the public at large and to the detriment of our heirs and // successors. We intend this dedication to be an overt act of // relinquishment in perpetuity of all present and future rights to this // software under copyright law. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. #include #include #include #include #include "network.h" #include "config.h" #include "types.h" #include "tls.h" gnutls_session_t session; int fd; int connect_tls(void) { // TODO: free used things on failure if (gnutls_global_init() < 0) return 1; gnutls_certificate_credentials_t xcred; // TODO: if we reconnect if (gnutls_certificate_allocate_credentials(&xcred) < 0) return 2; if (gnutls_certificate_set_x509_system_trust(xcred) < 0) return 3; if (gnutls_init(&session, GNUTLS_CLIENT) < 0) return 4; if (gnutls_server_name_set(session, GNUTLS_NAME_DNS, address.data, address.len) < 0) return 5; if (gnutls_set_default_priority(session) < 0) return 6; if (gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred) < 0) return 7; gnutls_session_set_verify_cert(session, address.data, 0); fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (fd == -1) return 8; struct sockaddr sockaddr; resolve(address.data, port.data, &sockaddr); int ret = connect(fd, &sockaddr, sizeof(sockaddr)); if (ret != 0) return 9; gnutls_transport_set_int(session, fd); gnutls_handshake_set_timeout(session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT); do { ret = gnutls_handshake(session); } while (ret < 0 && gnutls_error_is_fatal(ret) == 0); if (ret < 0) return 10; gnutls_record_set_timeout(session, 60000); // 60s return 0; } extern inline size_t RECV(char *buf, size_t buflen, char *timeout); // Should force it to get compiled into tls.o #if LOGALL ssize_t SEND(struct string msg) { static char printprefix = 1; if (printprefix) { #if COLORIZE WRITES(1, STRING("\x1b[33m[Us->Server] \x1b[34m")); #else WRITES(1, STRING("[Us->Server] ")); #endif printprefix = 0; } WRITES(1, msg); if (msg.len == 0 || msg.data[msg.len - 1] == '\n') { printprefix = 1; #if COLORIZE WRITES(1, STRING("\x1b[0m\n")); #else WRITES(1, STRING("\n")); #endif } return gnutls_record_send(session, msg.data, msg.len); } #endif