diff options
| author | Paul Buetow <paul@buetow.org> | 2009-01-27 23:25:11 +0000 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2009-01-27 23:25:11 +0000 |
| commit | 19f9940dc968afae01b54377ee23ec59069c9646 (patch) | |
| tree | f3aeb664f44aec07de640bce0326ec1b5e478c51 /0.8/src/sock | |
| parent | 1c8047e99b6a7199e447bb5a70438837cc5f7890 (diff) | |
Diffstat (limited to '0.8/src/sock')
| -rw-r--r-- | 0.8/src/sock/context.cpp | 62 | ||||
| -rw-r--r-- | 0.8/src/sock/context.h | 57 | ||||
| -rw-r--r-- | 0.8/src/sock/sock.cpp | 446 | ||||
| -rw-r--r-- | 0.8/src/sock/sock.h | 121 | ||||
| -rw-r--r-- | 0.8/src/sock/sslsock.cpp | 160 | ||||
| -rw-r--r-- | 0.8/src/sock/sslsock.h | 65 |
6 files changed, 911 insertions, 0 deletions
diff --git a/0.8/src/sock/context.cpp b/0.8/src/sock/context.cpp new file mode 100644 index 0000000..be46a07 --- /dev/null +++ b/0.8/src/sock/context.cpp @@ -0,0 +1,62 @@ +/*:* + *: File: ./src/sock/context.cpp + *: + *: yChat; Homepage: ychat.buetow.org; Version 0.9.0-CURRENT + *: + *: Copyright (C) 2003 Paul C. Buetow, Volker Richter + *: Copyright (C) 2004 Paul C. Buetow + *: Copyright (C) 2005 EXA Digital Solutions GbR + *: Copyright (C) 2006, 2007 Paul C. Buetow + *: + *: This program is free software; you can redistribute it and/or + *: modify it under the terms of the GNU General Public License + *: as published by the Free Software Foundation; either version 2 + *: of the License, or (at your option) any later version. + *: + *: This program is distributed in the hope that it will be useful, + *: but WITHOUT ANY WARRANTY; without even the implied warranty of + *: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + *: GNU General Public License for more details. + *: + *: You should have received a copy of the GNU General Public License + *: along with this program; if not, write to the Free Software + *: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *:*/ + +#ifndef CONTEXT_CPP +#define CONTEXT_CPP + +#include "context.h" + +using namespace std; + +context::context(sock *p_sock, struct event *p_event, int i_fd) +{ + this->p_sock = p_sock; + this->p_event = p_event; + this->i_fd = i_fd; +} + +context::~context() +{ + shutdown(i_fd, 2); + close(i_fd); + + if (this->p_event) + delete this->p_event; + + if (this->p_map_params) + delete this->p_map_params; + + if (this->p_response) + delete this->p_response; +} + +void +context::del_event() +{ + if (this->p_event) + delete this->p_event; + this->p_event = NULL; +} +#endif diff --git a/0.8/src/sock/context.h b/0.8/src/sock/context.h new file mode 100644 index 0000000..a604cda --- /dev/null +++ b/0.8/src/sock/context.h @@ -0,0 +1,57 @@ +/*:* + *: File: ./src/sock/context.h + *: + *: yChat; Homepage: ychat.buetow.org; Version 0.9.0-CURRENT + *: + *: Copyright (C) 2003 Paul C. Buetow, Volker Richter + *: Copyright (C) 2004 Paul C. Buetow + *: Copyright (C) 2005 EXA Digital Solutions GbR + *: Copyright (C) 2006, 2007 Paul C. Buetow + *: + *: This program is free software; you can redistribute it and/or + *: modify it under the terms of the GNU General Public License + *: as published by the Free Software Foundation; either version 2 + *: of the License, or (at your option) any later version. + *: + *: This program is distributed in the hope that it will be useful, + *: but WITHOUT ANY WARRANTY; without even the implied warranty of + *: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + *: GNU General Public License for more details. + *: + *: You should have received a copy of the GNU General Public License + *: along with this program; if not, write to the Free Software + *: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *:*/ + +#include "../incl.h" + +#ifndef CONTEXT_H +#define CONTEXT_H + +#include <map> +#include <string> +#include <sys/time.h> +#include <event.h> + +using namespace std; + +class sock; +class user; + +struct context +{ + sock *p_sock; + struct event* p_event; + char c_buf[READSOCK+1]; + //string s_request; + map<string,string> *p_map_params; + int i_fd; + string *p_response; + user *p_user; + + context(sock *p_sock, struct event *p_event, int i_fd); + ~context(); + void del_event(); +}; + +#endif diff --git a/0.8/src/sock/sock.cpp b/0.8/src/sock/sock.cpp new file mode 100644 index 0000000..fdba716 --- /dev/null +++ b/0.8/src/sock/sock.cpp @@ -0,0 +1,446 @@ +/*:* + *: File: ./src/sock/sock.cpp + *: + *: yChat; Homepage: ychat.buetow.org; Version 0.9.0-CURRENT + *: + *: Copyright (C) 2003 Paul C. Buetow, Volker Richter + *: Copyright (C) 2004 Paul C. Buetow + *: Copyright (C) 2005 EXA Digital Solutions GbR + *: Copyright (C) 2006, 2007 Paul C. Buetow + *: + *: This program is free software; you can redistribute it and/or + *: modify it under the terms of the GNU General Public License + *: as published by the Free Software Foundation; either version 2 + *: of the License, or (at your option) any later version. + *: + *: This program is distributed in the hope that it will be useful, + *: but WITHOUT ANY WARRANTY; without even the implied warranty of + *: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + *: GNU General Public License for more details. + *: + *: You should have received a copy of the GNU General Public License + *: along with this program; if not, write to the Free Software + *: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *:*/ + +#ifndef SOCK_CPP +#define SOCK_CPP + +#include <arpa/inet.h> +#include <errno.h> +#include <sys/types.h> +#include <unistd.h> +#include <fcntl.h> + +#include "sock.h" +#include "../tool/tool.h" + +using namespace std; + +vector< sock* > sock::vec_socks; +int sock::i_id_counter = 0; + +sock::sock() +{ + this->i_id = ++i_id_counter; + + this->b_run = true; + this->i_req = 0; + this->p_reqp = new reqp(); + +#ifdef LOGGING + this->log_daemon = new logd( wrap::CONF->get_elem( "httpd.logging.accessfile" ), + wrap::CONF->get_elem( "httpd.logging.access_lines" ) ); +#endif + + this->p_ip_cache_map = new shashmap < string, unsigned, self_hash<unsigned>, equals_allocator<unsigned> >; + vec_socks.push_back(this); +} + +//<<* +/* +void +sock::chat_stream(context *p_context, string s_msg) +{ + p_user->set_context(p_sock); + + _send(p_sock, s_msg.c_str(), s_msg.size()); // FOOBAR + + for (int i = 0; i < PUSHSTR; ++i) + _send(p_sock, " \n", 2); + + p_user->set_sock(p_sock); +} +*/ +//*>> + +int +sock::_make_server_socket( int i_port ) +{ + size_t i_sock; + struct sockaddr_in name; + + // create the server socket. + i_sock = socket (AF_INET, SOCK_STREAM, 0); + // i_sock = socket (PF_INET, SOCK_STREAM, 0); + if (i_sock < 0) + { + wrap::system_message(SOCKERR, errno); + + if ( ++i_port > MAXPORT ) + exit(1); + + wrap::system_message(SOCKERR, errno); + + return _make_server_socket( i_port ); + } + + // give the server socket a name. + name.sin_family = AF_INET; + name.sin_addr.s_addr = htonl(INADDR_ANY); + name.sin_port = htons(i_port); + int i_optval = 1; + + if (bind(i_sock, (struct sockaddr *) &name, sizeof (name)) < 0) + { + wrap::system_message(BINDERR, errno); + + if (++i_port > MAXPORT) + exit(1); + + wrap::system_message(string(SOCKERR) + tool::int2string(i_port)); + + // Re-run recursive. + return _make_server_socket(i_port); + } + + setsockopt(i_sock, SOL_SOCKET, SO_REUSEADDR, (char*)&i_optval, sizeof(int)); + + if (set_nonblock(i_server_sock) < 0) + { + wrap::system_message(NONBLER, errno); + exit(EXIT_FAILURE); + } + + wrap::system_message(SOCKCRT + string("localhost:") + tool::int2string(i_port)); + + i_server_port = i_port; + i_server_sock = i_sock; + + if (listen(i_sock, BACKLOG) < 0) + { + wrap::system_message(LISTERR, errno); + exit(EXIT_FAILURE); + } + + wrap::system_message(SOCKRDY); + return i_sock; +} + +#ifdef OPENSSL +// This method is virtual, and is overloaded by sslsock! +bool +sock::_main_loop_do_ssl_stuff(int &i_new_sock) +{ + return 0; +} +#endif + +void +sock::process_request() +{ + int i; + struct sockaddr_in clientname; + socklen_t size; + + ++i_req; + int i_client_sock = accept(i_server_sock, (struct sockaddr *) &clientname, &size); + + if (i_client_sock == -1) + { + switch (errno) + { + case EAGAIN: + case EINTR: + return; + } + } + + if (0 < set_nonblock(i_client_sock)) + { + wrap::system_message(NONBCER, errno); + } + +#ifdef OPENSSL + _main_loop_do_ssl_stuff(i_client_sock); +#endif + +#ifdef VERBOSE + wrap::system_message(NEWREQU + + tool::int2string(i_req) + " " + + string(inet_ntoa( clientname.sin_addr )) + ":" + + tool::int2string(ntohs ( clientname.sin_port )) + + " @" + tool::int2string(get_id()) + ); +#endif + + context *p_context = new context(this, new struct event, i_client_sock); + + event_set(p_context->p_event, i_client_sock, EV_READ , handle_client_read, p_context); + event_add(p_context->p_event, NULL); +} + +void +sock::clean_ipcache() +{ + int i_ipcachesize = wrap::CONF->get_int("httpd.ipcachesize"); + int i_currentsize = p_ip_cache_map->size(); + + if (i_currentsize > 0 && (i_ipcachesize == 0 || i_ipcachesize <= i_currentsize)) + wrap::system_message(SOCKCA2+tool::int2string(i_currentsize)+","+tool::int2string(i_ipcachesize)+")"); +} + +void +sock::init_event_handlers() +{ + for (vector< sock* >::iterator iter = sock::vec_socks.begin(); + iter != sock::vec_socks.end(); ++iter) + { + wrap::system_message(EVENTSO, (*iter)->get_id()); + (*iter)->init_server_event_handler(); + } +} + +void +sock::init_server_event_handler() +{ + event_set(&ev_handle_server_accept, i_server_sock, EV_READ | EV_PERSIST, handle_server_accept, this); + event_add(&ev_handle_server_accept, NULL); +} + +void +sock::handle_server_accept(int i_fd, short event, void *p_arg) +{ + sock *p_sock = static_cast<sock*>(p_arg); + p_sock->process_request(); +} + +void +sock::handle_client_read(int i_fd, short event, void *p_arg) +{ + static int i_size = READSOCK * sizeof(char); + context *p_context = static_cast<context*>(p_arg); + + if (-1 == read(i_fd, p_context->c_buf, i_size)) + { + switch (errno) + { + case EAGAIN: + case EINTR: + event_add(p_context->p_event, NULL); + return; + } + } + p_context->del_event(); + + string s_buf(p_context->c_buf); + string s_query(""); + + bool b_is_post_request; + + if (strncmp("POST", p_context->c_buf, 4) == 0) + { + b_is_post_request = true;; + + int i_pos = s_buf.find(" HTTP", 0) + 1; + + if (i_pos == string::npos && i_pos <= 5) + { + wrap::system_message(HTTPERR); + delete p_context; + return; + } + + s_query.append(s_buf.substr(5, i_pos - 5)); + } + + else if (strncmp("GET", p_context->c_buf, 3) == 0) + { + b_is_post_request = false; + int i_pos = s_buf.find(" HTTP", 0) + 1; + + if (i_pos == string::npos && i_pos <= 5) + { + wrap::system_message(HTTPERR); + delete p_context; + return; + } + + s_query.append(s_buf.substr(5, i_pos - 5)); + } + + // Invalid request + else + { + wrap::system_message(HTTPERR); + delete p_context; + return; + } + + // Remove /.. from the query + int i_pos, i_pos2; + while ( (i_pos = s_query.find("/..")) != string::npos ) + s_query.replace(i_pos, 3, "/"); + + sock *p_sock = p_context->p_sock; + + p_context->p_map_params = new map<string, string>; + map<string, string>& map_params = *p_context->p_map_params; + + struct sockaddr_in client; + static socklen_t client_size = sizeof(client); + getpeername(i_fd, (struct sockaddr *) &client, &client_size); + + shashmap< string, unsigned, self_hash<unsigned>, equals_allocator<unsigned> > *p_ip_cache_map + = p_sock->get_ip_cache_map(); + + unsigned &i_addr = client.sin_addr.s_addr; + + if ( (map_params["REMOTE_ADDR"] = p_ip_cache_map->get_elem(i_addr)) == "" ) + { + map_params["REMOTE_ADDR"] = string(inet_ntoa(client.sin_addr)); + p_ip_cache_map->set_elem(map_params["REMOTE_ADDR"], i_addr); + wrap::system_message(SOCKCAC+map_params["REMOTE_ADDR"]); + } + + // Get HTTP Header values + i_pos = s_buf.find("\n"); + if (i_pos != string::npos) + { + map_params["QUERY_STRING"] = tool::trim(s_buf.substr(0,i_pos-1)); + + do + { + string s_line(s_buf.substr(0, i_pos)); + i_pos2 = s_line.find(":"); + + if (i_pos2 != string::npos && s_line.length() > i_pos2+1) + map_params[ tool::trim(s_line.substr(0, i_pos2)) ] = tool::trim(s_line.substr(i_pos2+1)); + + s_buf = s_buf.substr(s_line.size() + 1); + i_pos = s_buf.find("\n"); + + } + while (i_pos != string::npos); + } + + // Get request string parameters + string s_parameters = tool::url_decode(s_query); + string s_tmp, s_request(""); + + if ( (i_pos = s_parameters.find("?")) != string::npos) + { + s_request.append(s_parameters.substr(0, i_pos)); + s_parameters = s_parameters.substr(i_pos+1); + } + + else if ( (i_pos = s_parameters.find(" ")) != string::npos) + { + s_request.append(s_parameters.substr(0, i_pos)); + } + + else + { + s_request.append(s_parameters); + } + + if (b_is_post_request) + s_parameters = s_buf; + + while ( (i_pos = s_parameters.find("&")) != string::npos ) + { + s_tmp = s_parameters.substr(0, i_pos ); + + if ( (i_pos2 = s_tmp.find("=")) != string::npos ) + map_params[ s_tmp.substr(0, i_pos2) ] = tool::replace( s_tmp.substr( i_pos2+1 ), "\\AND", "&"); + + s_parameters = s_parameters.substr(i_pos+1); + } + + // Get the last request parameter, which does not have a "&" on the end! + if ( (i_pos = s_parameters.find("=")) != string::npos ) + { + if ( (i_pos2 = s_parameters.find(" ")) != string::npos ) + map_params[ s_parameters.substr(0, i_pos) ] = s_parameters.substr(i_pos+1, i_pos2-i_pos-1); + else + map_params[ s_parameters.substr(0, i_pos) ] = s_parameters.substr(i_pos+1); + } + +#ifdef VERBOSE + wrap::system_message(REQUEST + s_request); +#endif + + if (s_request.empty()) + s_request = wrap::CONF->get_elem("httpd.startsite"); + + map_params["request"] = s_request; + + { + string s_ext(tool::get_extension(s_request)); + + if ( s_ext == "" ) + s_ext = "default"; + + map_params["content-type"] = wrap::CONF->get_elem( "httpd.contenttypes." + s_ext ); + } + +//#ifdef VERBOSE +// for (map<string, string>::iterator i = map_params.begin(); i != map_params.end(); ++i) +// cout << "=>" << i->first << "=" << i->second << "<=" << endl; +//#endif + + p_context->p_response = new string(""); + p_sock->get_req_parser()->parse(p_context); + + struct event *p_ev_handle_client_write = new struct event; + p_context->p_event = p_ev_handle_client_write; + + event_set(p_ev_handle_client_write, i_fd, EV_WRITE, handle_client_write, p_context); + event_add(p_ev_handle_client_write, NULL); +} + +void +sock::handle_client_write(int i_fd, short event, void *p_arg) +{ + static int i_char_size = sizeof(char); + + context *p_context = static_cast<context*>(p_arg); + string *p_response = p_context->p_response; + + if (-1 == write(i_fd, p_response->c_str(), p_response->length()*i_char_size)) + { + switch (errno) + { + case EAGAIN: + case EINTR: + event_add(p_context->p_event, NULL); + return; + } + } + + delete p_context; +} + +int +sock::set_nonblock(int i_sock) +{ + if (fcntl(i_sock, F_SETFL, O_NONBLOCK) < 0) + { + wrap::system_message(SOCKER5, errno); + return -1; + } + + return 0; +} + +#endif diff --git a/0.8/src/sock/sock.h b/0.8/src/sock/sock.h new file mode 100644 index 0000000..b09afb1 --- /dev/null +++ b/0.8/src/sock/sock.h @@ -0,0 +1,121 @@ +/*:* + *: File: ./src/sock/sock.h + *: + *: yChat; Homepage: ychat.buetow.org; Version 0.9.0-CURRENT + *: + *: Copyright (C) 2003 Paul C. Buetow, Volker Richter + *: Copyright (C) 2004 Paul C. Buetow + *: Copyright (C) 2005 EXA Digital Solutions GbR + *: Copyright (C) 2006, 2007 Paul C. Buetow + *: + *: This program is free software; you can redistribute it and/or + *: modify it under the terms of the GNU General Public License + *: as published by the Free Software Foundation; either version 2 + *: of the License, or (at your option) any later version. + *: + *: This program is distributed in the hope that it will be useful, + *: but WITHOUT ANY WARRANTY; without even the implied warranty of + *: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + *: GNU General Public License for more details. + *: + *: You should have received a copy of the GNU General Public License + *: along with this program; if not, write to the Free Software + *: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *:*/ + +#include "../incl.h" + +#ifndef SOCK_H +#define SOCK_H + +#include <vector> +#include <queue> +#include <netdb.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/socket.h> +#include <netinet/in.h> + +#include "../reqp.h" +#include "../chat/user.h" +#include "../maps/shashmap.h" + +#ifdef LOGGING +#include "../logd.h" +#endif + +#include <sys/time.h> +#include <event.h> + +using namespace std; + +class sock +{ +private: + static vector< sock* > vec_socks; + static int i_id_counter; + long i_id; + +protected: +#ifdef LOGGING + logd *log_daemon; // the log daemon +#endif + shashmap< string, unsigned, self_hash<unsigned>, equals_allocator<unsigned> > *p_ip_cache_map; + + int i_server_sock; + int i_server_port; + unsigned long long i_req; // total number of server requests. + bool b_run; // true while socket manager is running. + reqp *p_reqp; // parses the http requests from clients. + + struct event ev_handle_server_accept; + static void handle_server_accept(int i_fd, short event, void *p_arg); + static void handle_client_read(int i_fd, short event, void *p_arg); + static void handle_client_write(int i_fd, short event, void *p_arg); + static void handle_client_stream_write(int i_fd, short event, void *p_arg); + + int set_nonblock(int i_sock); + +public: + explicit sock(); + void process_request(); + + shashmap< string, unsigned, self_hash<unsigned>, equals_allocator<unsigned> > * get_ip_cache_map() + { + return p_ip_cache_map; + } + reqp *get_req_parser() const + { + return p_reqp; + } + int get_id() const + { + return i_id; + } + string dump() + { + return p_ip_cache_map->dump(); + } + bool get_server_() const + { + return b_run; + } + bool get_run() const + { + return b_run; + } + bool set_run( bool b_run ) + { + this->b_run = b_run; + } + void clean_ipcache(); + virtual int _make_server_socket(int i_port); +#ifdef OPENSSL + virtual bool _main_loop_do_ssl_stuff(int& i_new_sock); +#endif + + static void init_event_handlers(); + void init_server_event_handler(); +}; +#endif diff --git a/0.8/src/sock/sslsock.cpp b/0.8/src/sock/sslsock.cpp new file mode 100644 index 0000000..1541a23 --- /dev/null +++ b/0.8/src/sock/sslsock.cpp @@ -0,0 +1,160 @@ +/*:* + *: File: ./src/sock/sslsock.cpp + *: + *: yChat; Homepage: ychat.buetow.org; Version 0.9.0-CURRENT + *: + *: Copyright (C) 2003 Paul C. Buetow, Volker Richter + *: Copyright (C) 2004 Paul C. Buetow + *: Copyright (C) 2005 EXA Digital Solutions GbR + *: Copyright (C) 2006, 2007 Paul C. Buetow + *: + *: This program is free software; you can redistribute it and/or + *: modify it under the terms of the GNU General Public License + *: as published by the Free Software Foundation; either version 2 + *: of the License, or (at your option) any later version. + *: + *: This program is distributed in the hope that it will be useful, + *: but WITHOUT ANY WARRANTY; without even the implied warranty of + *: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + *: GNU General Public License for more details. + *: + *: You should have received a copy of the GNU General Public License + *: along with this program; if not, write to the Free Software + *: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *:*/ + +#include "../incl.h" + +#ifdef OPENSSL +#ifndef SSLSOCK_CPP +#define SSLSOCK_CPP + +#include "sslsock.h" + +using namespace std; + +sslsock::sslsock() : sock() +{ + s_certificate_path = wrap::CONF->get_elem( "httpd.ssl.certificatepath" ); + s_privatekey_path = wrap::CONF->get_elem( "httpd.ssl.privatekeypath" ); + p_ctx = NULL; +} + +int +sslsock::_send(_socket *p_sock, const char *sz, int len) +{ + return SSL_write((SSL*)p_sock->p_ssl_context,sz, len); +} + +int +sslsock::_read(_socket *p_sock, char *sz, int len) +{ + return SSL_read((SSL*)p_sock->p_ssl_context,sz,len); +} + +int +sslsock::_close(_socket *p_sock) +{ + SSL_free((SSL*)p_sock->p_ssl_context); + sock::_close(p_sock); +} + +int +sslsock::_make_server_socket(int i_port) +{ + SSL_METHOD *p_ssl_method; + unsigned long e; + char sz[1024]; + string s_error; + + int i_sock = sock::_make_server_socket(i_port); + + if (i_sock <= 0) + { + wrap::system_message(SSLERR1); + return -1; + } + + SSL_load_error_strings(); + SSLeay_add_ssl_algorithms(); + + p_ssl_method = SSLv23_server_method(); + p_ctx = SSL_CTX_new (p_ssl_method); + if (!p_ctx) + { + e = ERR_get_error(); + ERR_error_string_n(e, sz, sizeof(sz) - 1); + s_error = sz; + wrap::system_message(SSLERR1); + return -1; + } + + if (SSL_CTX_use_certificate_file(p_ctx, s_certificate_path.c_str(), SSL_FILETYPE_PEM) <= 0) + { + e = ERR_get_error(); + ERR_error_string_n(e, sz, sizeof(sz) - 1); + s_error = sz; + wrap::system_message(SSLERR1); + return -1; + } + + if (SSL_CTX_use_PrivateKey_file(p_ctx, s_privatekey_path.c_str(), SSL_FILETYPE_PEM) <= 0) + { + e = ERR_get_error(); + ERR_error_string_n(e, sz, sizeof(sz) - 1); + s_error = sz; + wrap::system_message(SSLERR1); + return -1; + } + + if (!SSL_CTX_check_private_key(p_ctx)) + { + wrap::system_message(SSLERR2); + return -1; + } + + return i_sock; +} + +bool +sslsock::_main_loop_do_ssl_stuff(int& i_new_sock) +{ + SSL* p_ssl = SSL_new(p_ctx); + + if (p_ssl == NULL || i_new_sock < 0) + { + wrap::system_message(SSLERR3); + + close(i_new_sock); + if (p_ssl != NULL) + SSL_free(p_ssl); + + return 1; + } + + else + { + SSL_set_fd(p_ssl, i_new_sock); + if (SSL_accept(p_ssl) == -1) + { + wrap::system_message(SSLERR4); + close(i_new_sock); + return 1; + } + + map_certs[i_new_sock] = p_ssl; + } + + return 0; +} + +_socket* +sslsock::_create_container(int &i_sock) +{ + _socket* p_sock = sock::_create_container(i_sock); + p_sock->p_ssl_context = map_certs[i_sock]; + return p_sock; +} + +#endif +#endif diff --git a/0.8/src/sock/sslsock.h b/0.8/src/sock/sslsock.h new file mode 100644 index 0000000..9f1fce8 --- /dev/null +++ b/0.8/src/sock/sslsock.h @@ -0,0 +1,65 @@ +/*:* + *: File: ./src/sock/sslsock.h + *: + *: yChat; Homepage: ychat.buetow.org; Version 0.9.0-CURRENT + *: + *: Copyright (C) 2003 Paul C. Buetow, Volker Richter + *: Copyright (C) 2004 Paul C. Buetow + *: Copyright (C) 2005 EXA Digital Solutions GbR + *: Copyright (C) 2006, 2007 Paul C. Buetow + *: + *: This program is free software; you can redistribute it and/or + *: modify it under the terms of the GNU General Public License + *: as published by the Free Software Foundation; either version 2 + *: of the License, or (at your option) any later version. + *: + *: This program is distributed in the hope that it will be useful, + *: but WITHOUT ANY WARRANTY; without even the implied warranty of + *: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + *: GNU General Public License for more details. + *: + *: You should have received a copy of the GNU General Public License + *: along with this program; if not, write to the Free Software + *: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *:*/ + +#include "../incl.h" + +#ifdef OPENSSL +#ifndef SSLSOCK_H +#define SSLSOCK_H + +#include "sock.h" + +#include <openssl/rsa.h> +#include <openssl/crypto.h> +#include <openssl/x509.h> +#include <openssl/pem.h> +#include <openssl/ssl.h> +#include <openssl/err.h> + +using namespace std; + +class sslsock : public sock +{ +private: + SSL_CTX* p_ctx; + string s_certificate_path; + string s_privatekey_path; + map<int,void*> map_certs; + +public: + + sslsock( ); + ~sslsock( ); + + int _send(_socket *p_sock, const char *sz, int len); + int _read(_socket *p_sock, char *sz, int len); + int _close(_socket *p_sock); + bool _main_loop_do_ssl_stuff(int &i_new_sock); + _socket* _create_container(int& i_sock); + int _make_server_socket(int i_port); +}; + +#endif +#endif |
