Skip to content
Snippets Groups Projects
Commit fc421b06 authored by Niels Möller's avatar Niels Möller
Browse files

Moved sslfile into a separate file

Rev: lib/modules/SSL.pmod/sslport.pike:1.3
parent 6ecec953
No related branches found
No related tags found
No related merge requests found
...@@ -4,203 +4,29 @@ ...@@ -4,203 +4,29 @@
inherit Stdio.Port : socket; inherit Stdio.Port : socket;
inherit "context"; inherit "context";
inherit ADT.queue : accept_queue;
function(object:void) accept_callback; constant sslfile = (program) "sslfile";
class sslfile
{
inherit Stdio.File : socket;
inherit "connection" : connection;
object context;
string read_buffer; /* Data that is recieved before there is any
* read_callback */
string write_buffer; /* Data to be written */
function(mixed,string:void) read_callback;
function(mixed:void) write_callback;
function(mixed:void) close_callback;
int connected; /* 1 if the connect callback has been called */
private void die(int status)
{
if (status < 0)
{
/* Other end closed without sending a close_notify alert */
context->purge_session(this_object());
werror("SSL.sslfile: Killed\n");
}
if (close_callback)
close_callback(socket::query_id());
}
/* Return 0 if the connection is still alive,
* 1 if it was closed politely, and -1 if it died unexpectedly
*/
private int try_write()
{
int|string data = to_write();
// werror(sprintf("sslport->try_write: %O\n", data));
if (stringp(data))
{
write_buffer += data;
if (strlen(write_buffer))
{
int written = socket::write(write_buffer);
if (written > 0)
write_buffer = write_buffer[written..];
else
werror("SSL.sslfile->try_write: write failed\n");
}
return 0;
}
socket::close();
return data;
}
void close() function(object:void) accept_callback;
{
send_packet(Alert(ALERT_warning, ALERT_close_notify));
try_write();
read_callback = 0;
write_callback = 0;
close_callback = 0;
}
int write(string s)
{
object packet;
int res;
while(strlen(s))
{
packet = Packet();
packet->content_type = PACKET_application_data;
packet->fragment = s[..PACKET_MAX_SIZE-1];
send_packet(packet);
s = s[PACKET_MAX_SIZE..];
}
(res = try_write()) && die(res);
}
string read(mixed ...args)
{
throw( ({ "SSL->sslfile: read() is not supported.\n", backtrace() }) );
}
private void ssl_read_callback(mixed id, string s)
{
werror(sprintf("SSL.sslfile->ssl_read_callback\n"));
string|int data = got_data(s);
if (stringp(data))
{
werror(sprintf("SSL.sslfile: application_data: '%s'\n", data));
if (strlen(data))
{
read_buffer += data;
if (!connected)
{
connected = 1;
context->accept_callback(this_object());
}
if (read_callback && strlen(read_buffer))
{
read_callback(id, read_buffer + data);
read_buffer = "";
}
}
}
else
{
if (data < 0)
/* Fatal error, remove from session cache */
context->purge_session(this_object());
}
try_write() || (close_callback && close_callback());
}
private void ssl_write_callback(mixed id)
{
werror("SSL.sslport: ssl_write_callback\n");
int res;
if ( !(res = try_write()) && !strlen(write_buffer)
&& handshake_finished && write_callback)
{
write_callback(id);
res = try_write();
}
if (res)
die(res);
}
private void ssl_close_callback(mixed id)
{
werror("SSL.sslport: ssl_close_callback\n");
socket::close();
die(-1);
}
void set_read_callback(function(mixed,string:void) r)
{
read_callback = r;
}
void set_write_callback(function(mixed:void) w)
{
write_callback = w;
}
void set_close_callback(function(mixed:void) c)
{
close_callback = c;
}
void set_nonblocking(function ...args)
{
switch (sizeof(args))
{
case 0:
break;
case 3:
set_read_callback(args[0]);
set_write_callback(args[1]);
set_close_callback(args[2]);
break;
default:
throw( ({ "SSL.sslfile->set_blocking: Wrong number of arguments\n",
backtrace() }) );
}
}
void set_blocking()
{
throw( ({ "SSL.sslfile->set_blocking: Not supported\n",
backtrace() }) );
}
object accept()
{
/* Dummy method, for compatibility with Stdio.Port */
return this_object();
}
void create(object f, object c) void finished_callback(object f)
{ {
context = c; accept_queue::put(f);
read_buffer = write_buffer = ""; while (accept_callback && !accept_queue::is_empty())
socket::assign(f); accept_callback(query_id());
socket::set_nonblocking(ssl_read_callback, ssl_write_callback, ssl_close_callback);
connection::create(1);
}
} }
void ssl_callback(mixed id) void ssl_callback(mixed id)
{ {
object f = id->socket_accept(); object f = id->socket_accept();
if (f) if (f)
sslfile(f, this_object()); {
sslfile(f, this_object())->set_accept_callback(finished_callback);
}
} }
#if 0
void set_id(mixed id) void set_id(mixed id)
{ {
throw( ({ "SSL.sslport->set_id: Not supported\n", backtrace() }) ); throw( ({ "SSL.sslport->set_id: Not supported\n", backtrace() }) );
...@@ -210,6 +36,7 @@ mixed query_id() ...@@ -210,6 +36,7 @@ mixed query_id()
{ {
throw( ({ "SSL.sslport->query_id: Not supported\n", backtrace() }) ); throw( ({ "SSL.sslport->query_id: Not supported\n", backtrace() }) );
} }
#endif
int bind(int port, function callback, string|void ip) int bind(int port, function callback, string|void ip)
{ {
...@@ -230,5 +57,12 @@ object socket_accept() ...@@ -230,5 +57,12 @@ object socket_accept()
int accept() int accept()
{ {
throw( ({ "SSL.sslport->accept: Not supported\n", backtrace() }) ); return accept_queue::get();
}
void create()
{
werror("SSL.sslport->create\n");
context::create();
accept_queue::create();
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment