unrealircd- supernets unrealircd source & configuration |
git clone git://git.acid.vegas/unrealircd.git |
Log | Files | Refs | Archive | README | LICENSE |
starttls.c (3062B)
1 /* 2 * IRC - Internet Relay Chat, src/modules/starttls.c 3 * (C) 2009 Syzop & The UnrealIRCd Team 4 * 5 * See file AUTHORS in IRC package for additional names of 6 * the programmers. 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 1, or (at your option) 11 * any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 */ 22 23 #include "unrealircd.h" 24 25 CMD_FUNC(cmd_starttls); 26 27 #define MSG_STARTTLS "STARTTLS" 28 29 ModuleHeader MOD_HEADER 30 = { 31 "starttls", 32 "5.0", 33 "command /starttls", 34 "UnrealIRCd Team", 35 "unrealircd-6", 36 }; 37 38 long CLICAP_STARTTLS; 39 40 MOD_INIT() 41 { 42 ClientCapabilityInfo cap; 43 44 MARK_AS_OFFICIAL_MODULE(modinfo); 45 CommandAdd(modinfo->handle, MSG_STARTTLS, cmd_starttls, MAXPARA, CMD_UNREGISTERED); 46 memset(&cap, 0, sizeof(cap)); 47 cap.name = "tls"; 48 ClientCapabilityAdd(modinfo->handle, &cap, &CLICAP_STARTTLS); 49 50 return MOD_SUCCESS; 51 } 52 53 MOD_LOAD() 54 { 55 return MOD_SUCCESS; 56 } 57 58 MOD_UNLOAD() 59 { 60 return MOD_SUCCESS; 61 } 62 63 CMD_FUNC(cmd_starttls) 64 { 65 SSL_CTX *ctx; 66 int tls_options; 67 68 if (!MyConnect(client) || !IsUnknown(client)) 69 return; 70 71 ctx = client->local->listener->ssl_ctx ? client->local->listener->ssl_ctx : ctx_server; 72 tls_options = client->local->listener->tls_options ? client->local->listener->tls_options->options : iConf.tls_options->options; 73 74 /* This should never happen? */ 75 if (!ctx) 76 { 77 /* Pretend STARTTLS is an unknown command, this is the safest approach */ 78 sendnumeric(client, ERR_NOTREGISTERED); 79 return; 80 } 81 82 /* Is STARTTLS disabled? (same response as above) */ 83 if (tls_options & TLSFLAG_NOSTARTTLS) 84 { 85 sendnumeric(client, ERR_NOTREGISTERED); 86 return; 87 } 88 89 if (IsSecure(client)) 90 { 91 sendnumeric(client, ERR_STARTTLS, "STARTTLS failed. Already using TLS."); 92 return; 93 } 94 95 dbuf_delete(&client->local->recvQ, DBufLength(&client->local->recvQ)); /* Clear up any remaining plaintext commands */ 96 sendnumeric(client, RPL_STARTTLS); 97 send_queued(client); 98 99 SetStartTLSHandshake(client); 100 if ((client->local->ssl = SSL_new(ctx)) == NULL) 101 goto fail; 102 SetTLS(client); 103 SSL_set_fd(client->local->ssl, client->local->fd); 104 SSL_set_nonblocking(client->local->ssl); 105 if (!unreal_tls_accept(client, client->local->fd)) 106 { 107 SSL_set_shutdown(client->local->ssl, SSL_RECEIVED_SHUTDOWN); 108 SSL_smart_shutdown(client->local->ssl); 109 SSL_free(client->local->ssl); 110 goto fail; 111 } 112 113 /* HANDSHAKE IN PROGRESS */ 114 return; 115 fail: 116 /* Failure */ 117 sendnumeric(client, ERR_STARTTLS, "STARTTLS failed"); 118 client->local->ssl = NULL; 119 ClearTLS(client); 120 SetUnknown(client); 121 }