#include "s_misc.h"
#include "s_user.h"
#include "send.h"
+#include "ssl.h"
#include "struct.h"
#include "sys.h"
#include "uping.h"
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,
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;
}
{
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);
* @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;
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;
++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
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)
{
return 0;
}
}
-
+
/*
* For server connections, we process as many as we can without
* worrying about the time of day or anything :)
if (length > 0 && dbuf_put(&(cli_recvQ(cptr)), readbuf, length) == 0)
return exit_client(cptr, cptr, &me, "dbuf_put fail");
- if (DBufLength(&(cli_recvQ(cptr))) > feature_int(FEAT_CLIENT_FLOOD))
+ int HasUnlimitFlood = HasPriv(cptr, PRIV_UNLIMIT_FLOOD);
+
+ if (DBufLength(&(cli_recvQ(cptr))) > feature_int(FEAT_CLIENT_FLOOD) && !HasUnlimitFlood)
return exit_client(cptr, cptr, &me, "Excess Flood");
while (DBufLength(&(cli_recvQ(cptr))) && !NoNewLine(cptr) &&
- (IsTrusted(cptr) || cli_since(cptr) - CurrentTime < 10))
+ (IsTrusted(cptr) || cli_since(cptr) - CurrentTime < 10 || HasUnlimitFlood))
{
dolen = dbuf_getmsg(&(cli_recvQ(cptr)), cli_buffer(cptr), BUFSIZE);
/*
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;