fippo implements sender_verification

This commit is contained in:
psyc://psyced.org/~lynX 2011-07-31 10:33:35 +02:00
parent 2423c3adc5
commit 61ef5ce041
4 changed files with 101 additions and 99 deletions

View File

@ -343,6 +343,9 @@ int psyc_sendmsg(mixed target, string mc, mixed data, mapping vars,
// nothing else is possible, but some clients may // nothing else is possible, but some clients may
// no longer be able to connect to you... // no longer be able to connect to you...
} }
#ifdef USE_SPYC
o -> sender_verification(SERVER_UNIFORM, u[URoot]);
#endif
register_target($4, o); register_target($4, o);
register_target(psychopo, o); register_target(psychopo, o);
register_target(psycippo, o); register_target(psycippo, o);

View File

@ -38,6 +38,7 @@ mapping outstate;
mapping legal_senders; mapping legal_senders;
array(mixed) verify_queue = ({ });
volatile int flags = 0; volatile int flags = 0;
@ -74,24 +75,26 @@ varargs mixed croak(string mc, string data, vamapping vars, vamixed source) {
return 0; return 0;
} }
#ifdef USE_VERIFICATION
// request sender authentication and/or target acknowledgement // request sender authentication and/or target acknowledgement
// from the remote side // from the remote side
void sender_verification(array(string) sourcehosts, array(string) targethosts) void sender_verification(string sourcehost, mixed targethost)
{ {
// FIXME: wrong variables here unless(interactive()) {
mapping vars = ([ "_list_sources_hosts" : sourcehosts, verify_queue += ({ ({ sourcehost, targethost }) });
"_list_targets_hosts" : targethosts, return;
"_tag" : RANDHEXSTRING ]);
// assumption: we have already resolved all targethosts and
// they point to the remote ip
foreach(string ho : targethosts) {
sAuthenticated(ho);
} }
mapping vars = ([ "_uniform_source" : sourcehost,
msg(0, "_request_verification", 0, vars); "_uniform_target" : targethost,
"_tag" : RANDHEXSTRING ]);
P0(("sender_verification(%O, %O)\n", sourcehost, targethost))
// since we send packets to them we should trust them to
// send packets to us, eh?
if (stringp(targethost)) {
targethost = parse_uniform(targethost);
}
sAuthenticated(targethost[UHost]);
msg(0, "_request_authorization", 0, vars);
} }
#endif
// gets called during socket logon // gets called during socket logon
int logon(int failure) { int logon(int failure) {
@ -161,20 +164,12 @@ int logon(int failure) {
// FIXME // FIXME
unless(isServer()) { unless(isServer()) {
emit("|\n"); // initial greeting emit("|\n"); // initial greeting
#ifdef USE_FEATURES if (sizeof(verify_queue)) {
// we have no features to request or offer foreach(mixed t : verify_queue) {
msg(0, "_request_features", 0); sender_verification(t[0], t[1]);
#else }
# ifdef USE_VERIFICATION verify_queue = ({ });
// start hostname verification
// rather: look at Q and look for the hostnames we need
sender_verification(({ SERVER_HOST }), ({ peerhost }));
# else
if (function_exists("runQ")) {
runQ();
} }
# endif
#endif
} }
return 1; return 1;
} }
@ -209,74 +204,66 @@ first_response() {
// receives a msg from the remote side // receives a msg from the remote side
// note: this is circuit-messaging // note: this is circuit-messaging
void circuit_msg(string mc, mapping vars, string data) { void circuit_msg(string mc, mapping vars, string data) {
mapping rv = ([ ]);
mixed *u;
switch(mc) { switch(mc) {
case "_request_verification": case "_request_authorization":
if (tls_query_connection_state(ME) == 0) { if (vars["_tag"]) {
array(string) targethosts = ({ }); rv["_tag_relay"] = vars["_tag"];
foreach(string ho : vars["_list_targets_hosts"]) { }
if (is_localhost(ho)) { if (!vars["_uniform_source"] && vars["_uniform_target"]) {
targethosts += ({ ho }); CIRCUITERROR("_request_authorization without uniform source and/or target?!");
} }
}
if (sizeof(vars["_list_sources_hosts"]) == 1) {
// doing multiple resolutions in parallel is more complicated
string ho = vars["_list_sources_hosts"][0];
if (qAuthenticated(ho)) {
P0(("warning: trying to reverify authenticated host %O",ho))
} else {
dns_resolve(ho, (:
// FIXME: psyc/parse::deliver is much better here
mixed rv = (["_list_targets_accepted_hosts":targethosts]);
if (vars["_tag"]) rv["_tag_reply"] = vars["_tag"]; rv["_uniform_target"] = vars["_uniform_target"];
if ($1 == peerip) { rv["_uniform_source"] = vars["_uniform_source"];
sAuthenticated(NAMEPREP(ho));
rv["_list_sources_verified_hosts"] = ({ ho }); u = parse_uniform(vars["_uniform_target"]);
} else { if (!(u && is_localhost(u[UHost]))) {
rv["_list_sources_rejected_hosts"] = ({ ho }); msg(0, "_error_invalid_uniform_target", "[_uniform_target] is not hosted here.", rv);
} return;
msg(0, "_notice_verification", 0, rv); }
return; u = parse_uniform(vars["_uniform_source"]);
:)); u[UHost] = NAMEPREP(u[UHost]);
if (qAuthenticated(u[UHost])) {
// possibly different _uniform_target only
if (flags & TCP_PENDING_TIMEOUT) {
P0(("removing call out\n"))
remove_call_out(#'quit);
flags -= TCP_PENDING_TIMEOUT;
} }
} else { msg(0, "_status_authorization", 0, rv);
// FIXME!!!! // } else if (tls_query_connection_state(ME) == 1 && ...) {
CIRCUITERROR("sorry, no more than one element in _list_sources_hosts currently"); // FIXME
P0(("more than one element in _list_sources_hosts: %O\n", vars["_list_sources_hosts"]))
}
// keep tag if present!!!
// resolve all of _list_sources_hosts
// look at _list_targets_hosts and determine localhostiness
} else { } else {
CIRCUITERROR("_request_verification is not allowed on TLS circuits."); string ho = u[UHost];
// FIXME: this actually needs to consider srv, too...
dns_resolve(ho, (:
// FIXME: psyc/parse::deliver is much better here
P0(("resolved %O to %O, expecting %O\n", ho, $1, peerip))
if ($1 == peerip) {
sAuthenticated(ho);
if (flags & TCP_PENDING_TIMEOUT) {
P0(("removing call out\n"))
remove_call_out(#'quit);
flags -= TCP_PENDING_TIMEOUT;
}
msg(0, "_status_authorization", 0, rv);
} else {
msg(0, "_error_invalid_uniform_source", 0, rv);
}
return;
:));
} }
break; break;
case "_notice_features": case "_status_authorization":
// FIXME: watch for _list_using_modules P0(("_status authorization with %O\n", vars))
if (flags & TCP_PENDING_TIMEOUT) { // this means we can send from _uniform_source to _uniform_target
P0(("removing call out\n")) // we already did sAuthenticated _uniform_target before so we can't get
remove_call_out(#'quit); // tricked into it here
flags -= TCP_PENDING_TIMEOUT;
}
sTextPath();
#ifdef USE_FEATURES
if (tls_query_connection_state(ME) == 0) {
# ifdef USE_VERIFICATION
// start hostname verification
// rather: look at Q and look for the hostnames we need
sender_verification(({ SERVER_HOST }), ({ peerhost }));
# endif
} else {
if (function_exists("runQ")) {
runQ();
}
}
#endif
break;
case "_notice_verification":
P0(("_notice verification with %O\n", vars))
if (function_exists("runQ")) { if (function_exists("runQ")) {
runQ(); runQ();
// actually runQ(_uniform_source, _uniform_target)
} }
break; break;
default: default:
@ -290,6 +277,7 @@ varargs int msg(string source, string mc, string data,
mapping vars, int showingLog, mixed target) { mapping vars, int showingLog, mixed target) {
string buf = ""; string buf = "";
mixed u;
unless(vars) vars = ([ ]); unless(vars) vars = ([ ]);
buf = render_psyc(source, mc, data, vars, showingLog, target); buf = render_psyc(source, mc, data, vars, showingLog, target);

View File

@ -69,6 +69,7 @@ void greet() {
// should be sharing code with net/psyc and do a proper greeting // should be sharing code with net/psyc and do a proper greeting
// three separate packets follow (thus three emits) // three separate packets follow (thus three emits)
//emit(S_GLYPH_PACKET_DELIMITER "\n"); //emit(S_GLYPH_PACKET_DELIMITER "\n");
/*
emit("\ emit("\
:_source\t"+ SERVER_UNIFORM +"\n\ :_source\t"+ SERVER_UNIFORM +"\n\
:_target_peer\tpsyc://"+ peeraddr +"/\n\ :_target_peer\tpsyc://"+ peeraddr +"/\n\
@ -81,6 +82,7 @@ _status_circuit\n" S_GLYPH_PACKET_DELIMITER "\n");
#ifdef _flag_log_sockets_SPYC #ifdef _flag_log_sockets_SPYC
log_file("RAW_SPYC", "« %O greeted.\n", ME); log_file("RAW_SPYC", "« %O greeted.\n", ME);
#endif #endif
*/
} }
static void resolved(mixed host, mixed tag) { static void resolved(mixed host, mixed tag) {
@ -176,20 +178,27 @@ static void resolved(mixed host, mixed tag) {
sTextPath(); sTextPath();
greet(); greet();
// FIXME: determine response to greeting //msg(0, "_notice_features", 0, tag ? ([ "_tag_reply" : tag ]) : 0);
// instead of this dummy
msg(0, "_notice_features", 0, tag ? ([ "_tag_reply" : tag ]) : 0);
} }
void circuit_msg(string mc, mapping vars, string data) { int logon(int nothing) {
switch(mc) { P2(("%O accepted TCP from %O (%s:%O)\n", ME,
case "_request_features": // only servers handle _request_features query_ip_name(), query_ip_number(), peerport))
interrupt_parse(); // we could set the next_input_to and reply with _failure until
dns_rresolve(peerip, #'resolved, vars && vars["_tag"]); // hostname is resolved .. TODO ... no, we need some form
break; // of queuing for the scripts which do not wait.. why? don't we
default: // squeeze received packets thru dns-lambdas anyway?
return ::circuit_msg(mc, vars, data); // peerport has either positive or negative value
} //peeraddr = peerip+":"+peerport;
::logon(0);
#if 0 //def EXPERIMENTAL
// added this because greet() happens after dns resolution and
// some quick clients may not be waiting that long.. then again
// if they do, they deserve other treatment
sTextPath();
#endif
dns_rresolve(peerip, #'resolved);
return 1; // success
} }
#endif // LIBPSYC #endif // LIBPSYC

View File

@ -29,12 +29,14 @@ volatile mapping authhosts;
void sAuthenticated(string hostname) { void sAuthenticated(string hostname) {
P3(("sAuthenticated: %O\n", hostname)) P3(("sAuthenticated: %O\n", hostname))
unless(authhosts && mappingp(authhosts)) authhosts = ([ ]); unless(authhosts && mappingp(authhosts)) authhosts = ([ ]);
hostname = NAMEPREP(hostname);
authhosts[hostname] = 1; authhosts[hostname] = 1;
} }
int qAuthenticated(mixed hostname) { int qAuthenticated(mixed hostname) {
P3(("qAuthenticated %O, %O\n", hostname, authhosts)) P3(("qAuthenticated %O, %O\n", hostname, authhosts))
unless (authhosts && mappingp(authhosts)) return 0; unless (authhosts && mappingp(authhosts)) return 0;
hostname = NAMEPREP(hostname);
return member(authhosts, hostname); return member(authhosts, hostname);
} }