X-Git-Url: http://git.pk910.de/?p=ircu2.10.12-pk.git;a=blobdiff_plain;f=ircd%2Fs_bsd.c;fp=ircd%2Fs_bsd.c;h=5fd6d9193eb1ed0e1d55fd2727754abfcb05ee4a;hp=7e3205af764cf2f3d72694d4d54363cb3b262f0f;hb=7fbfc390d32f9acc3192d011b813f66f35370faa;hpb=0400a5a6479398d82526785c18c0df8bc8b92dce diff --git a/ircd/s_bsd.c b/ircd/s_bsd.c index 7e3205a..5fd6d91 100644 --- a/ircd/s_bsd.c +++ b/ircd/s_bsd.c @@ -53,6 +53,7 @@ #include "s_misc.h" #include "s_user.h" #include "send.h" +#include "ssl.h" #include "struct.h" #include "sys.h" #include "uping.h" @@ -248,6 +249,7 @@ static int connect_inet(struct ConfItem* aconf, struct Client* cptr) cli_fd(cptr) = -1; return 0; } + if (!socket_add(&(cli_socket(cptr)), client_sock_callback, (void*) cli_connect(cptr), (result == IO_SUCCESS) ? SS_CONNECTED : SS_CONNECTING, @@ -258,6 +260,21 @@ static int connect_inet(struct ConfItem* aconf, struct Client* cptr) cli_fd(cptr) = -1; return 0; } + + if(aconf->usessl) { + struct SSLConnection *ssl = ssl_create_connect(cli_fd(cptr), cptr, SSLData_Client); + cli_connect(cptr)->con_ssl = ssl; + if(ssl_handshake(ssl)) { + unsigned int events = 0; + if(ssl_wantread(ssl)) + events |= SOCK_EVENT_READABLE; + if(ssl_wantwrite(ssl)) + events |= SOCK_EVENT_WRITABLE; + socket_events(&(cli_socket(cptr)), SOCK_ACTION_SET | events); + result = IO_BLOCKED; + } + } + cli_freeflag(cptr) |= FREEFLAG_SOCKET; return 1; } @@ -274,9 +291,16 @@ unsigned int deliver_it(struct Client *cptr, struct MsgQ *buf) { unsigned int bytes_written = 0; unsigned int bytes_count = 0; + IOResult result; assert(0 != cptr); - switch (os_sendv_nonb(cli_fd(cptr), buf, &bytes_count, &bytes_written)) { + if(cli_connect(cptr)->con_ssl) { + result = ssl_send_encrypt(cli_connect(cptr)->con_ssl, buf, &bytes_count, &bytes_written); + } else { + result = os_sendv_nonb(cli_fd(cptr), buf, &bytes_count, &bytes_written); + } + + switch (result) { case IO_SUCCESS: ClrFlag(cptr, FLAG_BLOCKED); @@ -302,7 +326,7 @@ unsigned int deliver_it(struct Client *cptr, struct MsgQ *buf) * @param cptr Client to which we have connected, with all ConfItem structs attached. * @return Zero on failure (caller should exit_client()), non-zero on success. */ -static int completed_connection(struct Client* cptr) +int completed_connection(struct Client* cptr) { struct ConfItem *aconf; time_t newts; @@ -403,6 +427,11 @@ void close_connection(struct Client *cptr) else ServerStats->is_ni++; + if(cli_connect(cptr)->con_ssl) { + ssl_free_connection(cli_connect(cptr)->con_ssl); + cli_connect(cptr)->con_ssl = NULL; + } + if (-1 < cli_fd(cptr)) { flush_connections(cptr); LocalClientArray[cli_fd(cptr)] = 0; @@ -540,8 +569,20 @@ void add_connection(struct Listener* listener, int fd) { ++listener->ref_count; Count_newunknown(UserStats); - /* if we've made it this far we can put the client on the auth query pile */ - start_auth(new_client); + + if(listener_ssl(listener)) { + struct Connection* con = cli_connect(new_client); + con->con_ssl = ssl_start_handshake_listener(listener->ssl_listener, fd, new_client, SSLData_Client); + unsigned int events = 0; + if(ssl_wantread(con->con_ssl)) + events |= SOCK_EVENT_READABLE; + if(ssl_wantwrite(con->con_ssl)) + events |= SOCK_EVENT_WRITABLE; + socket_events(&(cli_socket(new_client)), SOCK_ACTION_SET | events); + } else { + /* if we've made it this far we can put the client on the auth query pile */ + start_auth(new_client); + } } /** Determines whether to tell the events engine we're interested in @@ -577,7 +618,16 @@ static int read_packet(struct Client *cptr, int socket_ready) if (socket_ready && !(IsUser(cptr) && DBufLength(&(cli_recvQ(cptr))) > feature_int(FEAT_CLIENT_FLOOD))) { - switch (os_recv_nonb(cli_fd(cptr), readbuf, sizeof(readbuf), &length)) { + + /* Handle SSL Sockets + */ + int recvret; + if(cli_connect(cptr)->con_ssl) { + recvret = ssl_recv_decrypt(cli_connect(cptr)->con_ssl, readbuf, sizeof(readbuf), &length); + } else { + recvret = os_recv_nonb(cli_fd(cptr), readbuf, sizeof(readbuf), &length); + } + switch (recvret) { case IO_SUCCESS: if (length) { @@ -596,7 +646,7 @@ static int read_packet(struct Client *cptr, int socket_ready) return 0; } } - + /* * For server connections, we process as many as we can without * worrying about the time of day or anything :) @@ -855,7 +905,10 @@ static void client_sock_callback(struct Event* ev) break; case ET_CONNECT: /* socket connection completed */ - if (!completed_connection(cptr) || IsDead(cptr)) + if(cli_connect(cptr)->con_ssl) { + ssl_start_handshake_connect(cli_connect(cptr)->con_ssl); + } + else if (!completed_connection(cptr) || IsDead(cptr)) fallback = cli_info(cptr); break;