mirror of
git://git.psyced.org/git/psyced
synced 2024-08-15 03:25:10 +00:00
things that happened in 2008
This commit is contained in:
parent
8f98522570
commit
94530cc322
136 changed files with 3222 additions and 2873 deletions
|
@ -1,13 +1,10 @@
|
|||
// $Id: active.c,v 1.395 2008/04/01 09:38:26 lynx Exp $ // vim:syntax=lpc:ts=8
|
||||
|
||||
#include <net.h>
|
||||
#include <sys/time.h>
|
||||
#include <url.h>
|
||||
// $Id: active.c,v 1.404 2008/10/26 17:24:57 lynx Exp $ // vim:syntax=lpc:ts=8
|
||||
|
||||
// a jabber thing which actively connects something
|
||||
#define NO_INHERIT
|
||||
#include "jabber.h"
|
||||
#undef NO_INHERIT
|
||||
#include <url.h>
|
||||
|
||||
#ifdef ERQ_WITHOUT_SRV
|
||||
# define hostname host // hostname contains the name before SRV resolution
|
||||
|
@ -39,9 +36,9 @@ volatile int dialback_outgoing;
|
|||
|
||||
tls_logon(); // prototype
|
||||
|
||||
#ifdef NOT_EXPERIMENTAL // not strictly necessary, but more spec conformant
|
||||
// not strictly necessary, but more spec conformant
|
||||
quit() {
|
||||
emit("</stream:stream>");
|
||||
emitraw("</stream:stream>");
|
||||
#ifdef _flag_log_sockets_XMPP
|
||||
D0( log_file("RAW_XMPP", "\n%O: shutting down, quit called\n", ME); )
|
||||
#endif
|
||||
|
@ -49,7 +46,6 @@ quit() {
|
|||
// matter on an outgoing-only socket
|
||||
//destruct(ME);
|
||||
}
|
||||
#endif
|
||||
|
||||
sGateway(gw, ho, id) {
|
||||
// TODO: ho is obsolete
|
||||
|
@ -68,7 +64,7 @@ removeGateway(gw, id) {
|
|||
start_dialback() {
|
||||
string source_host, key;
|
||||
|
||||
source_host = NAMEPREP(JABBER_HOST);
|
||||
source_host = NAMEPREP(_host_XMPP);
|
||||
key = DIALBACK_KEY(streamid, hostname, source_host);
|
||||
|
||||
P3(("%O: starting dialback from %O to %O\n", ME, source_host, hostname))
|
||||
|
@ -137,7 +133,7 @@ handle_stream_features(XMLNode node) {
|
|||
// && !config(XMPP + hostname, "_tls_invalid")
|
||||
){
|
||||
// may use tls unless we already do so
|
||||
emit("<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
|
||||
emitraw("<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
|
||||
nodeHandler = #'handle_starttls;
|
||||
return;
|
||||
}
|
||||
|
@ -177,11 +173,11 @@ handle_stream_features(XMLNode node) {
|
|||
#ifndef _flag_disable_authentication_external_XMPP
|
||||
if (mechs["EXTERNAL"]) {
|
||||
// TODO we should check that the name in our
|
||||
// certificate is equal to JABBER_HOST
|
||||
// certificate is equal to _host_XMPP
|
||||
// but so should the other side!
|
||||
emit("<auth mechanism='EXTERNAL' "
|
||||
"xmlns='" NS_XMPP "xmpp-sasl'>" +
|
||||
encode_base64(JABBER_HOST)
|
||||
encode_base64(_host_XMPP)
|
||||
+ "</auth>");
|
||||
return;
|
||||
} else
|
||||
|
@ -191,7 +187,7 @@ handle_stream_features(XMLNode node) {
|
|||
PT(("jabber/active requesting to do digest md5\n"))
|
||||
emit("<auth mechanism='DIGEST-MD5' "
|
||||
"xmlns='" NS_XMPP "xmpp-sasl>" +
|
||||
encode_base64(JABBER_HOST) +
|
||||
encode_base64(_host_XMPP) +
|
||||
"</auth>");
|
||||
return;
|
||||
|
||||
|
@ -201,7 +197,7 @@ handle_stream_features(XMLNode node) {
|
|||
#ifdef SWITCH2PSYC
|
||||
else if (node["/switch"]) { // should check scheme
|
||||
PT(("upgrading %O from XMPP to PSYC.\n", ME))
|
||||
emit("<switching xmlns='http://switch.psyced.org'>"
|
||||
emitraw("<switching xmlns='http://switch.psyced.org'>"
|
||||
"<scheme>psyc</scheme>"
|
||||
"</switching>");
|
||||
return;
|
||||
|
@ -235,6 +231,11 @@ disconnected(remainder) {
|
|||
// nothing else happening here? no reconnect?
|
||||
// TODO: what about the dialback Q if any?
|
||||
::disconnected(remainder);
|
||||
// let's call this a special case of good will:
|
||||
// hopefully a sending side socket close operation
|
||||
if (remainder == "</stream:stream>") return 1;
|
||||
// we could forward remainder to feed(), but we haven't seen any other
|
||||
// cases of content than the one above.
|
||||
return flags & TCP_PENDING_DISCONNECT;
|
||||
}
|
||||
|
||||
|
@ -259,18 +260,20 @@ static int logon(int failure) {
|
|||
emit("<stream:stream xmlns:stream='http://etherx.jabber.org/streams' "
|
||||
"xmlns='jabber:server' xmlns:db='jabber:server:dialback' "
|
||||
"to='" + hostname + "' "
|
||||
"from='" + NAMEPREP(JABBER_HOST) + "' "
|
||||
"from='" + NAMEPREP(_host_XMPP) + "' "
|
||||
"xml:lang='en' "
|
||||
"version='1.0'>");
|
||||
#ifdef NOT_EXPERIMENTAL // not strictly necessary, but more spec conformant
|
||||
#if 1 // not strictly necessary, but more spec conformant
|
||||
} else if (!qSize(me)) { // no retry for dialback-only
|
||||
P0(("notify gateways %O of failure\n", gateways))
|
||||
if (sizeof(dialback_queue) > 1) {
|
||||
P0(("tell fippo that sizeof(dialback queue) was > 1\n"))
|
||||
}
|
||||
foreach(string id, mixed gw : gateways) {
|
||||
if (objectp(gw)) {
|
||||
gw->remote_connection_failed();
|
||||
if (sizeof(gateways)) {
|
||||
P0(("%O notifies gateways %O of failure\n", ME, gateways))
|
||||
foreach(string id, mixed gw : gateways) {
|
||||
if (objectp(gw)) {
|
||||
gw->remote_connection_failed();
|
||||
}
|
||||
}
|
||||
}
|
||||
dialback_queue = 0;
|
||||
|
@ -286,7 +289,8 @@ static int logon(int failure) {
|
|||
#ifdef WANT_S2S_TLS
|
||||
tls_logon(result) {
|
||||
if (result < 0) {
|
||||
PT(("%O tls_logon %d\n", ME, result))
|
||||
P1(("%O tls_logon %d: %O\n", ME, result, tls_error(result) ))
|
||||
// would be nice to insert the tls_error() message here.. TODO
|
||||
connect_failure("_encrypt", "Problems setting up an encrypted circuit");
|
||||
} else if (result == 0) {
|
||||
// we need to check the certificate
|
||||
|
@ -304,12 +308,12 @@ tls_logon(result) {
|
|||
"contains %O/%O",
|
||||
hostname, cert["2.5.4.3"],
|
||||
cert["2.5.29.17:1.3.6.1.5.5.7.8.5"]));
|
||||
#else
|
||||
P1(("TLS: %s presented a certificate with unexpected identity.\n", hostname))
|
||||
P2(("%O\n", cert))
|
||||
#endif
|
||||
#ifdef _flag_log_bogus_certificates
|
||||
log_file("CERTS", S("%O %O %O id?\n", ME, hostname, cert));
|
||||
#else
|
||||
P1(("TLS: %s presented a certificate with unexpected identity.\n", hostname))
|
||||
P2(("%O\n", cert))
|
||||
#endif
|
||||
#if 0 //def _flag_reject_bogus_certificates
|
||||
QUIT
|
||||
|
@ -321,12 +325,12 @@ tls_logon(result) {
|
|||
monitor_report("_error_untrusted_certificate",
|
||||
sprintf("%O certificate could not be verified",
|
||||
hostname));
|
||||
#else
|
||||
P1(("TLS: %s presented untrusted certificate.\n", hostname))
|
||||
P2(("%O\n", cert))
|
||||
#endif
|
||||
#ifdef _flag_log_bogus_certificates
|
||||
log_file("CERTS", S("%O %O %O\n", ME, hostname, cert));
|
||||
#else
|
||||
P1(("TLS: %s presented untrusted certificate.\n", hostname))
|
||||
P2(("%O\n", cert))
|
||||
#endif
|
||||
#if 0 //def _flag_reject_bogus_certificates
|
||||
// QUIT is wrong...
|
||||
|
@ -375,7 +379,7 @@ jabberMsg(XMLNode node) {
|
|||
* Server MUST terminate both the XML stream and the
|
||||
* underlying TCP connection.
|
||||
*/
|
||||
emit("</stream:stream>");
|
||||
emitraw("</stream:stream>");
|
||||
remove_interactive(ME);
|
||||
connect_failure("_dialback", "dialback gone wrong");
|
||||
}
|
||||
|
@ -390,7 +394,7 @@ jabberMsg(XMLNode node) {
|
|||
node["@type"]);
|
||||
// probably we can delete this...
|
||||
m_delete(gateways, t);
|
||||
#ifdef NOT_EXPERIMENTAL // not strictly necessary, but more spec conformant
|
||||
#if 1 // not strictly necessary, but more spec conformant
|
||||
} else if (member(gateways, t)) {
|
||||
P0(("%O found gateway for %O, but it is not an object: %O\n",
|
||||
ME, t, o))
|
||||
|
@ -413,7 +417,7 @@ jabberMsg(XMLNode node) {
|
|||
emit("<stream:stream xmlns:stream='http://etherx.jabber.org/streams' "
|
||||
"xmlns='jabber:server' xmlns:db='jabber:server:dialback' "
|
||||
"to='" + hostname + "' "
|
||||
"from='" + NAMEPREP(JABBER_HOST) + "' "
|
||||
"from='" + NAMEPREP(_host_XMPP) + "' "
|
||||
"xml:lang='en' "
|
||||
"version='1.0'>");
|
||||
authenticated = 1;
|
||||
|
@ -435,7 +439,7 @@ jabberMsg(XMLNode node) {
|
|||
data = sasl_parse(t);
|
||||
PT(("extracted %O\n", data))
|
||||
|
||||
data["username"] = JABBER_HOST;
|
||||
data["username"] = _host_XMPP;
|
||||
secret = config(XMPP + hostname, "_secret_shared");
|
||||
unless(secret) {
|
||||
// mh... this is a problem!
|
||||
|
@ -444,13 +448,13 @@ jabberMsg(XMLNode node) {
|
|||
}
|
||||
data["cnonce"] = RANDHEXSTRING;
|
||||
data["nc"] = "00000001";
|
||||
data["digest-uri"] = "xmpp/" JABBER_HOST;
|
||||
data["digest-uri"] = "xmpp/" _host_XMPP;
|
||||
|
||||
response = sasl_calculate_digestMD5(data, secret, 0);
|
||||
|
||||
// ok, the username is our hostname
|
||||
// note: qop must not be quoted, as we are 'client'
|
||||
t = "username=\"" JABBER_HOST "\","
|
||||
t = "username=\"" _host_XMPP "\","
|
||||
"realm=\"" + data["realm"] + "\","
|
||||
"nonce=\"" + data["nonce"] + "\","
|
||||
"cnonce=\"" + data["cnonce"] + "\","
|
||||
|
@ -584,7 +588,7 @@ int msg(string source, string mc, string data,
|
|||
if (interactive() && ready && dialback_outgoing == 0) {
|
||||
start_dialback();
|
||||
}
|
||||
#if JABBER_HOST == SERVER_HOST
|
||||
#if _host_XMPP == SERVER_HOST
|
||||
// we can only do this if mkjid patches the psyc host into jabber host
|
||||
// but that is terrifically complicated and requires parsing of things
|
||||
// we already knew.. so let's simply enqueue with object id and reject
|
||||
|
@ -596,7 +600,7 @@ int msg(string source, string mc, string data,
|
|||
#else
|
||||
// is this a bad idea? not sure.. we'll see..
|
||||
// if i don't have this here, a "tell lynX where it happened" will
|
||||
// be triggered from here -- best to never use JABBER_HOST really ;)
|
||||
// be triggered from here -- best to never use _host_XMPP really ;)
|
||||
vars["_source"] = source;
|
||||
// behaviour has changed.. so maybe we don't need this any longer TODO
|
||||
#endif
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
// $Id: common.c,v 1.270 2008/04/11 10:27:24 fippo Exp $ // vim:syntax=lpc:ts=8
|
||||
// $Id: common.c,v 1.276 2008/12/01 11:31:33 lynx Exp $ // vim:syntax=lpc:ts=8
|
||||
#define NO_INHERIT
|
||||
#include "jabber.h"
|
||||
#undef NO_INHERIT
|
||||
#include <net.h>
|
||||
|
||||
#include <net.h>
|
||||
#include <text.h>
|
||||
//virtual inherit NET_PATH "output";
|
||||
#include <url.h>
|
||||
|
@ -22,7 +22,7 @@ jabberMsg();
|
|||
inherit NET_PATH "xml/common";
|
||||
|
||||
volatile string buffer = "";
|
||||
closure jid_has_node_cl = (: int t, t2;
|
||||
volatile closure jid_has_node_cl = (: int t, t2;
|
||||
t = index($1, '@');
|
||||
if (t == -1) return 0;
|
||||
t2 = index($1, '/');
|
||||
|
@ -72,6 +72,15 @@ int emit(string message) {
|
|||
return ::emit(message);
|
||||
}
|
||||
|
||||
// don't check message, use this only where you are 100% sure
|
||||
// to be sending safe data
|
||||
int emitraw(string message) {
|
||||
#ifdef _flag_log_sockets_XMPP
|
||||
D0( log_file("RAW_XMPP", "\n« %O\t%s", ME, message); )
|
||||
#endif
|
||||
return ::emit(message);
|
||||
}
|
||||
|
||||
// this assumes the old ldmuddish charmode+combine-charset
|
||||
// if we ever get a input_bytes it needs to be rewrittn
|
||||
feed(a) {
|
||||
|
@ -131,7 +140,7 @@ varargs string mkjid(mixed who, mixed vars, mixed ignore_context, string target
|
|||
*/
|
||||
string t, *u;
|
||||
if (!who || who == "") return "";
|
||||
unless (jabberhost) jabberhost = JABBER_HOST;
|
||||
unless (jabberhost) jabberhost = _host_XMPP;
|
||||
P3(("%O mkjid(%O, %O, %O, %O, %O)\n", ME, who, vars, ignore_context, target, jabberhost))
|
||||
if (!ignore_context && vars && vars["_nick_place"]
|
||||
&& vars["_context"]) {
|
||||
|
@ -274,7 +283,14 @@ render(string mc, string data, mapping vars, mixed source) {
|
|||
+"' from='"+ vars["_INTERNAL_source_jabber"] +"' type='"
|
||||
+ (ISPLACEMSG(vars["_INTERNAL_source_jabber"]) && vars["_nick"] ?
|
||||
"groupchat" : "chat")
|
||||
+"'><body>"+ chomp(xmlquote(output)) +"</body></message>";
|
||||
+"'><body>"+
|
||||
#ifdef NEW_LINE
|
||||
xmlquote(output)
|
||||
#else
|
||||
// was: chomp after xmlquote.. but why?
|
||||
xmlquote(chomp(output))
|
||||
#endif
|
||||
+"</body></message>";
|
||||
#if DEBUG > 1
|
||||
// most of these message we are happy with, so we don't need this log
|
||||
log_file("XMPP_TODO", "%O %s %s\n", ME, mc, output);
|
||||
|
@ -384,7 +400,6 @@ certificate_check_jabbername(name, cert) {
|
|||
foreach(string cn : t) {
|
||||
if (NAMEPREP(cn) == name) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else if (name == NAMEPREP(t))
|
||||
return 1;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// $Id: component.c,v 1.68 2008/03/11 15:13:58 lynx Exp $ // vim:syntax=lpc
|
||||
// $Id: component.c,v 1.72 2008/10/01 10:59:24 lynx Exp $ // vim:syntax=lpc
|
||||
//
|
||||
// this implements a passive listener component
|
||||
#define NO_INHERIT
|
||||
|
@ -40,7 +40,7 @@ reboot(reason, restart, pass) {
|
|||
// close the stream according to XEP 0190
|
||||
if (interactive(ME)) {
|
||||
flags |= TCP_PENDING_DISCONNECT;
|
||||
emit("</stream:stream>");
|
||||
emitraw("</stream:stream>");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,7 +96,7 @@ waitfor_handshake(XMLNode node) {
|
|||
PT(("%O component auth succeded as %O\n", ME, componentname))
|
||||
nodeHandler = #'jabberMsg;
|
||||
authenticated = 1;
|
||||
emit("<handshake/>");
|
||||
emitraw("<handshake/>");
|
||||
onHandshake();
|
||||
} else {
|
||||
monitor_report("_error_invalid_password",
|
||||
|
@ -122,7 +122,7 @@ int msg(string source, string mc, string data,
|
|||
#ifdef PREFIXES
|
||||
if (abbrev("_prefix", mc)) return 1;
|
||||
#endif
|
||||
#ifndef EXPERIMENTAL // TODO: decide if this is good or bad
|
||||
#ifndef GAMMA // TODO: decide if this is good or bad
|
||||
else if (abbrev("_status_person_absent", mc)) {
|
||||
PT(("Intercepted absent from %O to %O\n", mc, source, ME))
|
||||
return 1;
|
||||
|
@ -172,7 +172,7 @@ open_stream(node) {
|
|||
if (node["@to"]) {
|
||||
packet += "from='" + node["@to"] + "' ";
|
||||
} else {
|
||||
packet += "from='" JABBER_HOST "' ";
|
||||
packet += "from='" _host_XMPP "' ";
|
||||
}
|
||||
if (!config) {
|
||||
/* reply with a stream error */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// $Id: disco.c,v 1.41 2008/01/05 13:44:38 lynx Exp $ // vim:syntax=lpc
|
||||
// $Id: disco.c,v 1.43 2008/09/12 15:54:38 lynx Exp $ // vim:syntax=lpc
|
||||
//
|
||||
// this gets included by user.c and gateway.c. you can distinguish this
|
||||
// by ifdeffing USER_PROGRAM. it may be renamed into disco.i one day.
|
||||
|
@ -19,7 +19,9 @@ disco_info_root(vars) {
|
|||
string featurelist;
|
||||
featurelist = "<feature var='http://jabber.org/protocol/muc'/>"
|
||||
#ifndef REGISTERED_USERS_ONLY
|
||||
# ifndef _flag_disable_registration_XMPP
|
||||
"<feature var='jabber:iq:register'/>"
|
||||
# endif
|
||||
#endif
|
||||
#ifndef VOLATILE
|
||||
"<feature var='msgoffline'/>"
|
||||
|
@ -95,8 +97,8 @@ disco_items_root(vars) {
|
|||
#ifdef PUBLIC_PLACES
|
||||
// see also: library advertised_places()
|
||||
#endif
|
||||
// TODO: is it safe to use JABBER_HOST here?
|
||||
vars["_list_item"] = "<item name='Chatrooms' jid='" JABBER_HOST "'/>";
|
||||
// is it safe to use _host_XMPP here?
|
||||
vars["_list_item"] = "<item name='Chatrooms' jid='" _host_XMPP "'/>";
|
||||
}
|
||||
|
||||
disco_items_place(name, vars) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// $Id: gateway.c,v 1.451 2008/03/29 16:07:30 fippo Exp $ // vim:syntax=lpc
|
||||
// $Id: gateway.c,v 1.461 2008/10/22 16:35:59 fippo Exp $ // vim:syntax=lpc
|
||||
/*
|
||||
* jabber/gateway
|
||||
* listens on jabber interserver port for incoming connections
|
||||
|
@ -56,6 +56,12 @@ quit() {
|
|||
disconnected(remainder) {
|
||||
// TODO: handle remainder
|
||||
P2(( "gateway %O disconnected\n", ME ))
|
||||
#ifdef GAMMA
|
||||
// sometimes we get complete presence packets in the socket close
|
||||
// remainder. probably broken xmpp implementations, let's try and
|
||||
// do the best we can with it by forwarding stuff to feed().
|
||||
if (remainder && strlen(remainder)) feed(remainder);
|
||||
#endif
|
||||
if (objectp(active)) active -> removeGateway(streamid);
|
||||
#ifdef _flag_log_sockets_XMPP
|
||||
D0( log_file("RAW_XMPP", "\n%O disc\t%O", ME, ctime()); )
|
||||
|
@ -85,13 +91,18 @@ void create() {
|
|||
}
|
||||
|
||||
#ifdef WANT_S2S_TLS
|
||||
// similar code in other files
|
||||
tls_logon(result) {
|
||||
P2(("%O tls_logon(%d)\n", ME, result))
|
||||
if (result < 0) {
|
||||
QUIT
|
||||
}
|
||||
else if (result == 0) {
|
||||
if (result == 0) {
|
||||
certinfo = tls_certificate(ME, 0);
|
||||
P3(("%O tls_logon fetching certificate: %O\n", ME, certinfo))
|
||||
# ifdef ERR_TLS_NOT_DETECTED
|
||||
} else if (result == ERR_TLS_NOT_DETECTED) {
|
||||
// just go on without encryption
|
||||
# endif
|
||||
} else if (result < 0) {
|
||||
P1(("%O TLS error %d: %O\n", ME, result, tls_error(result)))
|
||||
QUIT
|
||||
} else {
|
||||
P0(("tls_logon with result > 0?!?!\n"))
|
||||
// should not happen
|
||||
|
@ -121,7 +132,7 @@ verify_connection(string to, string from, string type) {
|
|||
emit(sprintf("<db:result from='%s' to='%s' type='%s'/>",
|
||||
to, from, type));
|
||||
if (type != "valid") {
|
||||
emit("</stream:stream>");
|
||||
emitraw("</stream:stream>");
|
||||
P2(("quitting invalid stream\n"))
|
||||
QUIT
|
||||
} else {
|
||||
|
@ -217,7 +228,7 @@ jabberMsg(XMLNode node) {
|
|||
|
||||
// <?xml version='1.0'?><stream:stream xmlns:stream='http://etherx.jabber.org/streams' xmlns='jabber:server' to='localhost' xmlns:db='jabber:server:dialback' version='1.0'><switching xmlns='http://switch.psyced.org'><scheme>psyc</scheme></switching>
|
||||
|
||||
emit("<switched xmlns='http://switch.psyced.org'/>");
|
||||
emitraw("<switched xmlns='http://switch.psyced.org'/>");
|
||||
PT(("received 'switching'. authhosts %O\n", authhosts))
|
||||
o = ("S:psyc:" + host) -> load();
|
||||
P1(("%O switching to %O for %O\n", ME, o, host))
|
||||
|
@ -237,8 +248,8 @@ jabberMsg(XMLNode node) {
|
|||
* a request for verification of a key
|
||||
*/
|
||||
// if we dont know the host, complain
|
||||
// put NAMEPREP(JABBER_HOST) into the localhost mapping pleeeease
|
||||
//if (target != NAMEPREP(JABBER_HOST)) {
|
||||
// put NAMEPREP(_host_XMPP) into the localhost mapping pleeeease
|
||||
//if (target != NAMEPREP(_host_XMPP)) {
|
||||
unless (is_localhost(lower_case(target))) {
|
||||
monitor_report("_error_unknown_host",
|
||||
sprintf("%O sent us a dialback packet believing we would be %O",
|
||||
|
@ -250,7 +261,7 @@ jabberMsg(XMLNode node) {
|
|||
sendmsg(origin,
|
||||
"_dialback_request_verify", 0,
|
||||
([ "_INTERNAL_target_jabber" : source,
|
||||
"_INTERNAL_source_jabber" : NAMEPREP(JABBER_HOST),
|
||||
"_INTERNAL_source_jabber" : NAMEPREP(_host_XMPP),
|
||||
"_dialback_key" : node[Cdata],
|
||||
"_tag" : streamid
|
||||
])
|
||||
|
@ -296,7 +307,7 @@ jabberMsg(XMLNode node) {
|
|||
/* we were calling this server, this packet is step 8
|
||||
* and we are doing step 9
|
||||
*/
|
||||
/* if we dont recognize target (currently: == JABBER_HOST)
|
||||
/* if we dont recognize target (currently: == _host_XMPP)
|
||||
* then croak with a host-unknown and commit suicide
|
||||
*/
|
||||
// same as above...
|
||||
|
@ -317,12 +328,15 @@ jabberMsg(XMLNode node) {
|
|||
case "starttls":
|
||||
#ifdef WANT_S2S_TLS
|
||||
if (tls_available()) {
|
||||
emit("<proceed xmlns='" NS_XMPP "xmpp-tls'/>");
|
||||
emitraw("<proceed xmlns='" NS_XMPP "xmpp-tls'/>");
|
||||
# if __EFUN_DEFINED__(tls_want_peer_certificate)
|
||||
tls_want_peer_certificate(ME);
|
||||
# endif
|
||||
tls_init_connection(ME, #'tls_logon);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
emit("<failure xmlns='" NS_XMPP "xmpp-tls'/>");
|
||||
emitraw("<failure xmlns='" NS_XMPP "xmpp-tls'/>");
|
||||
return;
|
||||
case "stream:error":
|
||||
if (node["/connection-timeout"]) {
|
||||
|
@ -351,7 +365,7 @@ jabberMsg(XMLNode node) {
|
|||
|
||||
success = certificate_check_jabbername(t, certinfo);
|
||||
if (success) {
|
||||
emit("<success xmlns='" NS_XMPP "xmpp-sasl'/>");
|
||||
emitraw("<success xmlns='" NS_XMPP "xmpp-sasl'/>");
|
||||
P2(("successful sasl external authentication with "
|
||||
"%O\n", t))
|
||||
sAuthenticated(t);
|
||||
|
@ -377,7 +391,7 @@ jabberMsg(XMLNode node) {
|
|||
encode_base64(sprintf("realm=\"%s\",nonce=\"%s\","
|
||||
"qop=\"auth\",charset=utf-8,"
|
||||
"algorithm=md5-sess",
|
||||
JABBER_HOST, RANDHEXSTRING)
|
||||
_host_XMPP, RANDHEXSTRING)
|
||||
) + "</challenge>");
|
||||
} else {
|
||||
// kind of 'unknown username'
|
||||
|
@ -469,7 +483,10 @@ open_stream(XMLNode node) {
|
|||
if (node["@to"]) {
|
||||
packet += "from='" + node["@to"] + "' ";
|
||||
} else {
|
||||
packet += "from='" JABBER_HOST "' ";
|
||||
packet += "from='" _host_XMPP "' ";
|
||||
}
|
||||
if (node["@from"]) {
|
||||
packet += "to='" + node["@from"] + "' ";
|
||||
}
|
||||
if (node["@to"] && !(is_localhost(lower_case(node["@to"])))) {
|
||||
emit(packet + ">");
|
||||
|
@ -505,7 +522,7 @@ open_stream(XMLNode node) {
|
|||
// let the other side decide if it knows a shared secret
|
||||
// with us
|
||||
// if it it has, it will use it with digest-md5
|
||||
# if __VERSION_MINOR__ > 3 || __VERSION_MICRO__ > 610
|
||||
# ifndef _flag_disable_authentication_digest_MD5
|
||||
if (node["@from"]
|
||||
&& config(XMPP + node["@from"],
|
||||
"_secret_shared")) {
|
||||
|
@ -517,7 +534,7 @@ open_stream(XMLNode node) {
|
|||
// and we have verified it as X509_V_OK (0)
|
||||
// we offer SASL external (authentication via name
|
||||
// presented in x509 certificate
|
||||
P3(("gateway::certinfo %O\n", certinfo))
|
||||
P0(("gateway::certinfo %O\n", certinfo))
|
||||
if (mappingp(certinfo) && certinfo[0] == 0) {
|
||||
// if from attribute is present we only offer
|
||||
// sasl external if we know that it will succeed
|
||||
|
@ -554,6 +571,6 @@ w(string mc, string data, mapping vars, mixed source) {
|
|||
P2(("%O using w() for %O, unimplemented... mc %O, source %O\n",
|
||||
ME, origin, mc, source))
|
||||
unless (vars) vars = ([ ]);
|
||||
vars["_INTERNAL_source_jabber"] = objectp(source) ? mkjid(source) : JABBER_HOST;
|
||||
vars["_INTERNAL_source_jabber"] = objectp(source) ? mkjid(source) : _host_XMPP;
|
||||
sendmsg(origin, mc, data, vars);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// $Id: interserver.c,v 1.12 2008/03/11 15:13:58 lynx Exp $ vim:syntax=lpc
|
||||
// $Id: interserver.c,v 1.13 2008/10/01 10:59:24 lynx Exp $ vim:syntax=lpc
|
||||
//
|
||||
// common things for interserver jabber.. included or maybe later inherited by
|
||||
// active.c and gateway.c. i am sure fippo will find some more nice things to
|
||||
|
@ -35,7 +35,7 @@ int clean_up(int refcount) {
|
|||
// and is therefore the correct way to timeout a connection.
|
||||
PT(("%O cleaning up: closing stream\n", ME))
|
||||
// close the stream according to XEP 0190
|
||||
emit("</stream:stream>");
|
||||
emitraw("</stream:stream>");
|
||||
// flag says the stream is in closing phase and nothing may be
|
||||
// delivered on it. but we aren't enforcing this. TODO!
|
||||
flags |= TCP_PENDING_DISCONNECT;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// $Id: jabber.h,v 1.74 2008/03/30 10:27:49 lynx Exp $ // vim:syntax=lpc
|
||||
// $Id: jabber.h,v 1.75 2008/09/12 15:54:39 lynx Exp $ // vim:syntax=lpc
|
||||
//
|
||||
// REMINDER:
|
||||
// there are plenty of calls to lower_case in the code, that is because
|
||||
|
@ -74,12 +74,12 @@ virtual inherit JABBER_PATH "common";
|
|||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef JABBER_HOST
|
||||
# define JABBER_HOST SERVER_HOST
|
||||
#ifndef _host_XMPP
|
||||
# define _host_XMPP SERVER_HOST
|
||||
#endif
|
||||
|
||||
// this is not ready for is_localhost
|
||||
#define is_localhost(a) (a) == JABBER_HOST
|
||||
#define is_localhost(a) (a) == _host_XMPP
|
||||
|
||||
|
||||
#define JABSOURCE "_INTERNAL_source_jabber"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <net.h> // vim:set syntax=lpc
|
||||
#include "jabber.h"
|
||||
#include <net.h> // vim:set syntax=lpc
|
||||
#include <url.h>
|
||||
#include "presence.h"
|
||||
#include <time.h>
|
||||
|
@ -48,7 +48,6 @@ jabberMsg(XMLNode node, mixed origin, mixed *su, array(mixed) tu) {
|
|||
// #define MYORIGIN XMPP + su[UUserAtHost]
|
||||
|
||||
unless(su) su = parse_uniform(origin);
|
||||
#if 1 //def NOT_EXPERIMENTAL
|
||||
origin = XMPP;
|
||||
if (su[UUser]) {
|
||||
origin += NODEPREP(su[UUser]) + "@";
|
||||
|
@ -59,7 +58,6 @@ jabberMsg(XMLNode node, mixed origin, mixed *su, array(mixed) tu) {
|
|||
origin += "/" + RESOURCEPREP(su[UResource]);
|
||||
}
|
||||
su = parse_uniform(origin);
|
||||
#endif
|
||||
if (node["/nick"] &&
|
||||
node["/nick"]["@xmlns"] == "http://jabber.org/protocol/nick" &&
|
||||
node["/nick"][Cdata]) {
|
||||
|
@ -133,7 +131,14 @@ jabberMsg(XMLNode node, mixed origin, mixed *su, array(mixed) tu) {
|
|||
data = "Talking to [_nick_target] is not possible: [_text_XMPP]";
|
||||
} else {
|
||||
mc = "_failure_unavailable_service_talk";
|
||||
data = "Talking to [_nick_target] is not possible. You may have to establish friendship first.";
|
||||
// data = "Talking to [_nick_target] is not possible. You may have to establish friendship first.";
|
||||
// google talk sends this quite frequently:
|
||||
// * when a friendship exchange hasn't been done
|
||||
// * when a friend has gone offline
|
||||
// and you never know if a message has been delivered to the
|
||||
// recipient just the same! so here's a more accurate error message,
|
||||
// effectively giving you less information, since that's what we have here.
|
||||
data = "Message to [_nick_target] may not have reached its recipient.";
|
||||
}
|
||||
} else if (1) { // TODO: what was that error?
|
||||
PT(("gateway TODO <error> in <message>: %O\n",
|
||||
|
@ -293,7 +298,7 @@ jabberMsg(XMLNode node, mixed origin, mixed *su, array(mixed) tu) {
|
|||
} else {
|
||||
// no relaying allowed, so we ignore hostname
|
||||
o = summon_person(tu[UUser]);
|
||||
#ifdef EXPERIMENTAL
|
||||
#ifdef GAMMA
|
||||
// xep 0085 typing notices - we even split active into a separate message
|
||||
// for now. could be sent as a flag
|
||||
if ((node[t="/composing"] || node[t="/active"] ||
|
||||
|
@ -379,7 +384,7 @@ jabberMsg(XMLNode node, mixed origin, mixed *su, array(mixed) tu) {
|
|||
// so there wont be circular error messages
|
||||
if (tu[UUser]) {
|
||||
o = summon_person(tu[UUser]);
|
||||
#ifndef EXPERIMENTAL
|
||||
#ifndef GAMMA
|
||||
if (o && o->execute_callback(node["@id"], ({ vars["_INTERNAL_identification"], vars, node }))) return 1;
|
||||
#else
|
||||
// the following should catch errors - in theory, requires testing
|
||||
|
@ -540,26 +545,20 @@ jabberMsg(XMLNode node, mixed origin, mixed *su, array(mixed) tu) {
|
|||
sendmsg(o, "_notice_place_leave_unicast", 0, vars, origin);
|
||||
#endif
|
||||
} else {
|
||||
#ifdef AVAILABILITY_OFFLINE
|
||||
o = summon_person(tu[UUser]);
|
||||
// http://www.psyc.eu/presence
|
||||
vars["_degree_availability"] = AVAILABILITY_OFFLINE;
|
||||
#ifdef CACHE_PRESENCE
|
||||
# ifdef CACHE_PRESENCE
|
||||
persistent_presence(XMPP + su[UUserAtHost],
|
||||
AVAILABILITY_OFFLINE);
|
||||
#endif
|
||||
# endif
|
||||
vars["_description_presence"] =
|
||||
(node["/status"] && node["/status"][Cdata]) ?
|
||||
node["/status"][Cdata] : ""; // "Get psyced!";
|
||||
vars["_INTERNAL_mood_jabber"] = "neutral";
|
||||
sendmsg(o, "_notice_presence_absent", 0,
|
||||
vars, origin);
|
||||
#if 0 // packen wir das doch wieder zusammen...
|
||||
} else {
|
||||
// one more famous fippoesque else case.. let's fill it ;)
|
||||
P0(("%O Surprise! Encountered absence with resource: %O\n",
|
||||
ME, node))
|
||||
// interessant... wir werden das wohl noch oefter sehen
|
||||
// ich bin nicht sicher, ob das ein bug der gegenseite ist
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
@ -637,11 +636,11 @@ jabberMsg(XMLNode node, mixed origin, mixed *su, array(mixed) tu) {
|
|||
// }
|
||||
P4(("_request_enter from %O to %O: %O\n", ME, o, vars))
|
||||
// dont send me a memberlist if i am a member already
|
||||
#ifndef HISTORY_AMOUNT
|
||||
# define HISTORY_AMOUNT 5
|
||||
#ifndef _limit_amount_history_place_default
|
||||
# define _limit_amount_history_place_default 5
|
||||
#endif
|
||||
unless(vars["_amount_history"])
|
||||
vars["_amount_history"] = HISTORY_AMOUNT;
|
||||
vars["_amount_history"] = _limit_amount_history_place_default;
|
||||
sendmsg(o,
|
||||
#ifdef SPEC
|
||||
"_request_context_enter"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "jabber.h"
|
||||
#include <net.h>
|
||||
#include <url.h>
|
||||
#include "jabber.h"
|
||||
|
||||
// just renderMembers
|
||||
#include NET_PATH "members.i"
|
||||
|
@ -37,9 +37,9 @@ int msg(string source, string mc, string data,
|
|||
// ignore these
|
||||
return 1;
|
||||
break;
|
||||
case "_request_description": // wir sollten uns da auf eins einigen :)
|
||||
case "_request_examine": // needs a tag also... probably all _request's do
|
||||
mc = "_request_examine_vCard";
|
||||
case "_request_examine": // don't use this, please remove in 2009
|
||||
case "_request_description": // this is the one.
|
||||
mc = "_request_description_vCard"; // pending rename.. TODO
|
||||
unless (vars["_tag"]) vars["_tag"] = RANDHEXSTRING;
|
||||
source->chain_callback(vars["_tag"], (:
|
||||
if ($3["@type"] == "result") {
|
||||
|
@ -245,6 +245,7 @@ int msg(string source, string mc, string data,
|
|||
$2 });
|
||||
:));
|
||||
break;
|
||||
#ifndef _flag_disable_module_authentication
|
||||
case "_request_authentication":
|
||||
// TODO: XEP 0070 says we should use <message/> when the recipient is a bare jid
|
||||
// but I prefer the iq method
|
||||
|
@ -255,6 +256,8 @@ int msg(string source, string mc, string data,
|
|||
return ({ $1, "_error_invalid_authentication", 0, $2 });
|
||||
:));
|
||||
break;
|
||||
#endif
|
||||
#ifndef _flag_disable_query_server
|
||||
case "_notice_list_feature":
|
||||
case "_notice_list_feature_person":
|
||||
case "_notice_list_feature_place":
|
||||
|
@ -266,6 +269,7 @@ int msg(string source, string mc, string data,
|
|||
vars["_list_feature"] = implode(map(vars["_list_feature"],
|
||||
(: return "<feature var='" + feat2jabber[$1] + "'/>"; :)), "");
|
||||
break;
|
||||
#endif
|
||||
case "_notice_list_item":
|
||||
t = "";
|
||||
// same stuff in user.c (what happened to code sharing?)
|
||||
|
@ -513,6 +517,10 @@ int msg(string source, string mc, string data,
|
|||
#endif
|
||||
if ($3["@type"] == "error") {
|
||||
// FIXME: could remove context
|
||||
//
|
||||
// also, we should implement the full choice of errors and
|
||||
// map them to appropriate psyc errors.. instead we just
|
||||
// have this silly lazy coder's message:
|
||||
return ({ t, "_failure_place_enter_XMPP",
|
||||
"[_nick_place] could not be entered for jabberish reasons.",
|
||||
$2 });
|
||||
|
@ -557,6 +565,9 @@ int msg(string source, string mc, string data,
|
|||
else if (abbrev("_failure_redirect", mc)) {
|
||||
if (vars["_tag_reply"]) { // wild guess that it is an iq then
|
||||
mc = "_jabber_iq_error";
|
||||
// <lynX> was spricht dagegen _failure_redirect als <redirect/> auszugeben?
|
||||
// <fippo> ich denke nicht, dass es irgendwer vernünftig implementiert...
|
||||
// außerdem musst du die jid des raumes in dem konkreten fall rausfinden
|
||||
vars["_jabber_XML"] = "<error type='modify'><gone xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/><text xmlns='urn:ietf:params:xml:ns:xmpp-stanzas' xml:lang='en'>" + psyctext(data, vars) + "</text></error>";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include <net.h>
|
||||
|
||||
/* a cache for the remote muc
|
||||
/* a slave for the remote muc
|
||||
* yes, this is for a SINGLE person
|
||||
* yes, that's horrible
|
||||
*
|
||||
|
@ -8,13 +8,6 @@
|
|||
* even /history if we'd like to have that.. ;)
|
||||
*/
|
||||
|
||||
// FIXME: should set "owner nick" and tag so
|
||||
// we can detect when the remote room does not
|
||||
// support tagging or when we are kicked
|
||||
// and this could even do echo detection
|
||||
// NOTE: this should work when using the
|
||||
// isecho check
|
||||
|
||||
object owner;
|
||||
mapping membercache = ([ ]);
|
||||
|
||||
|
@ -49,6 +42,8 @@ castmsg(source, method, data, mapping vars) {
|
|||
case "_notice_place_leave":
|
||||
if (isecho) {
|
||||
// got kicked or room does not support tagging
|
||||
// this works already for kick, but it might be nice to do that
|
||||
// as a KICK for irc
|
||||
P0(("%O left via _notice_place_leave, this is strange\n", vars["_context"]))
|
||||
}
|
||||
m_delete(membercache, source);
|
||||
|
@ -63,6 +58,5 @@ castmsg(source, method, data, mapping vars) {
|
|||
}
|
||||
|
||||
mapping qMembers() {
|
||||
P4(("membercache is %O\n", membercache))
|
||||
return m_indices(membercache);
|
||||
}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
// $Id: server.c,v 1.148 2008/03/11 15:13:58 lynx Exp $ // vim:syntax=lpc:ts=8
|
||||
// $Id: server.c,v 1.159 2008/10/01 10:59:24 lynx Exp $ // vim:syntax=lpc:ts=8
|
||||
#include "jabber.h"
|
||||
#include "server.h" // inherits net/server
|
||||
|
||||
#include "person.h" // find_person
|
||||
#include "url.h"
|
||||
#include <sys/tls.h>
|
||||
|
||||
volatile string tag;
|
||||
volatile string authtag;
|
||||
volatile string resource;
|
||||
volatile string streamid;
|
||||
volatile string pass;
|
||||
|
@ -16,12 +17,11 @@ volatile string sasluser;
|
|||
volatile string saslchallenge;
|
||||
|
||||
#ifdef __TLS__
|
||||
volatile mixed cert;
|
||||
volatile mixed certinfo;
|
||||
#endif
|
||||
|
||||
qScheme() { return "jabber"; }
|
||||
// qName() { } // we need that in common.c - probably no more
|
||||
qTag() { return tag; }
|
||||
|
||||
void create() {
|
||||
unless (clonep()) return;
|
||||
|
@ -30,13 +30,24 @@ void create() {
|
|||
}
|
||||
|
||||
#ifdef __TLS__
|
||||
tls_logon(result) {
|
||||
PT(("%O tls_logon(%d)\n", ME, result))
|
||||
PT(("%O tls? %O\n", ME, tls_query_connection_state(ME)))
|
||||
// we may write again
|
||||
# ifdef WANT_S2S_SASL
|
||||
cert = tls_certificate(ME, 0);
|
||||
// similar code in other files
|
||||
tls_logon(result) {
|
||||
if (result == 0) {
|
||||
# ifdef WANT_S2S_SASL /* hey wait.. this is not S2S here!? */
|
||||
certinfo = tls_certificate(ME, 0);
|
||||
# endif
|
||||
P3(("%O tls_logon fetching certificate: %O\n", ME, certinfo))
|
||||
# ifdef ERR_TLS_NOT_DETECTED
|
||||
} else if (result == ERR_TLS_NOT_DETECTED) {
|
||||
// no encryption. no problem.
|
||||
# endif
|
||||
} else if (result < 0) {
|
||||
P1(("%O TLS error %d: %O\n", ME, result, tls_error(result)))
|
||||
QUIT // don't fall back to plaintext instead
|
||||
} else {
|
||||
P0(("tls_logon with result > 0?!?!\n"))
|
||||
// should not happen
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -57,14 +68,13 @@ string *splitsasl(string data) {
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
promptForPassword(user) {
|
||||
P2(("promptForPassword with %O\n", user))
|
||||
if (reprompt == 1 || pass) {
|
||||
w("_error_invalid_password", "Invalid password.\n",
|
||||
([ "_tag_reply" : qTag(), "_nick" : nick,
|
||||
([ "_tag_reply" : authtag || "", "_nick" : nick,
|
||||
"_resource" : resource ]) );
|
||||
write("</stream:stream>");
|
||||
emitraw("</stream:stream>");
|
||||
QUIT
|
||||
return; // ?
|
||||
}
|
||||
|
@ -72,9 +82,9 @@ promptForPassword(user) {
|
|||
unless (pass) {
|
||||
reprompt = 1;
|
||||
w("_query_password", 0, //"Please provide your password.",
|
||||
([ "_nick": nick, "_tag_reply" : qTag() ]) );
|
||||
}
|
||||
return 1;
|
||||
([ "_nick": nick, "_tag_reply" : authtag || "" ]) );
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
logon(a) {
|
||||
|
@ -100,17 +110,17 @@ createUser(nick) {
|
|||
|
||||
|
||||
userLogon() {
|
||||
user->sTag(tag);
|
||||
user->sTag(authtag);
|
||||
user->sResource(resource);
|
||||
return ::userLogon();
|
||||
}
|
||||
|
||||
#ifdef EXPERIMENTAL
|
||||
#ifdef GAMMA
|
||||
authChecked(result, varargs array(mixed) args) {
|
||||
// a point where we could be sending our jabber:iq:auth reply
|
||||
// instead of letting _notice_login do that
|
||||
PT(("%O got authChecked %O, %O\n", ME, result, args))
|
||||
return ::authChecked(result, args);
|
||||
return ::authChecked(result, args...);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -119,12 +129,12 @@ jabberMsg(XMLNode node) {
|
|||
string id;
|
||||
mixed t;
|
||||
|
||||
id = node["@id"]; // tag?
|
||||
id = node["@id"] || ""; // tag?
|
||||
switch (node[Tag]) {
|
||||
case "iq":
|
||||
if (node["/bind"]) {
|
||||
// suppresses the jabber:iq:auth reply in the SASL case
|
||||
tag = -1;
|
||||
authtag = -1;
|
||||
unless (sasluser) {
|
||||
// not-allowed stanza error?
|
||||
return 0;
|
||||
|
@ -137,31 +147,28 @@ jabberMsg(XMLNode node) {
|
|||
if (!stringp(resource) || resource == "")
|
||||
resource = "PSYC";
|
||||
nick = sasluser;
|
||||
sasluser = "";
|
||||
sasluser = ""; // why an empty string? explanation needed
|
||||
|
||||
emit(sprintf("<iq type='result' id='%s'>"
|
||||
"<bind xmlns='" NS_XMPP "xmpp-bind'>"
|
||||
"<jid>%s</jid>"
|
||||
"</bind></iq>",
|
||||
id, nick + "@" SERVER_HOST "/" + resource));
|
||||
emit("<iq type='result' id='"+ id +"'>"
|
||||
"<bind xmlns='" NS_XMPP "xmpp-bind'><jid>"+
|
||||
nick +"@" SERVER_HOST "/"+ resource +"</jid>"
|
||||
"</bind></iq>");
|
||||
return 0;
|
||||
} else if (node["/session"]) {
|
||||
unless(user) return 0; // what then?
|
||||
if (!stringp(id))
|
||||
id = "";
|
||||
emit(sprintf("<iq type='result' id='%s' from='%s'/>",
|
||||
id, SERVER_HOST));
|
||||
emit("<iq type='result' id='"+ id +"' from='"
|
||||
SERVER_HOST "'/>");
|
||||
user -> vSet("language", language);
|
||||
return morph();
|
||||
}
|
||||
switch (node["/query"]["@xmlns"]) {
|
||||
// old-school style.. for clients that don't like SASL, like kopete
|
||||
// old-school style.. for clients that don't like SASL, like kopete, jabbin
|
||||
case "jabber:iq:auth":
|
||||
tag = id;
|
||||
authtag = id;
|
||||
if (node["@type"] == "get"){
|
||||
// hello(nick) ?
|
||||
w("_query_password", 0,
|
||||
([ "_nick": nick, "_tag_reply": tag ]), "");
|
||||
([ "_nick": nick, "_tag_reply": authtag || "" ]), "");
|
||||
} else if (node["@type"] == "set") {
|
||||
helper = node["/query"];
|
||||
resource = helper["/resource"][Cdata];
|
||||
|
@ -182,10 +189,11 @@ jabberMsg(XMLNode node) {
|
|||
case "jabber:iq:register":
|
||||
if (node["@type"] == "get"){
|
||||
string packet;
|
||||
#ifdef REGISTERED_USERS_ONLY
|
||||
#if defined(REGISTERED_USERS_ONLY) || defined(_flag_disable_registration_XMPP)
|
||||
// super dirty.. this should all be in textdb
|
||||
packet = sprintf("<iq type='result' id='%s'>"
|
||||
"<query xmlns='jabber:iq:register'/>"
|
||||
"<error code='501>No way!</error>" IQ_OFF,
|
||||
"<error code='501>Registration by XMPP not permitted.</error>" IQ_OFF,
|
||||
id);
|
||||
#else
|
||||
packet = sprintf("<iq type='result' id='%s'>"
|
||||
|
@ -228,6 +236,9 @@ jabberMsg(XMLNode node) {
|
|||
emit(packet);
|
||||
QUIT
|
||||
} else {
|
||||
#if defined(REGISTERED_USERS_ONLY) || defined(_flag_disable_registration_XMPP)
|
||||
// TODO: generate some error as above
|
||||
#else
|
||||
user -> vSet("password", t[Cdata]);
|
||||
if (t = helper["/email"]) {
|
||||
user -> vSet("email", helper["/email"]);
|
||||
|
@ -235,6 +246,7 @@ jabberMsg(XMLNode node) {
|
|||
// maybe immediate save is not really a good idea
|
||||
// user -> save();
|
||||
emit(sprintf("<iq type='result' id='%s'/>", id));
|
||||
#endif
|
||||
}
|
||||
user = 0;
|
||||
}
|
||||
|
@ -243,15 +255,14 @@ jabberMsg(XMLNode node) {
|
|||
case "starttls":
|
||||
#if __EFUN_DEFINED__(tls_available)
|
||||
if (tls_available()) {
|
||||
emit("<proceed xmlns='" NS_XMPP "xmpp-tls'/>");
|
||||
emitraw("<proceed xmlns='" NS_XMPP "xmpp-tls'/>");
|
||||
// we may not write until tls_logon is called!
|
||||
tls_init_connection(ME, #'tls_logon);
|
||||
} else {
|
||||
P1(("%O received a 'starttls' but TLS isn't available.\n", ME))
|
||||
}
|
||||
#else
|
||||
emit("<failure xmlns='" NS_XMPP "xmpp-tls'/>");
|
||||
emit("</stream:stream>");
|
||||
emitraw("<failure xmlns='" NS_XMPP "xmpp-tls'/></stream:stream>");
|
||||
destruct(ME);
|
||||
#endif
|
||||
break;
|
||||
|
@ -282,7 +293,7 @@ jabberMsg(XMLNode node) {
|
|||
{
|
||||
if (result) {
|
||||
sasluser = creds[1];
|
||||
emit("<success xmlns='" NS_XMPP "xmpp-sasl'/>");
|
||||
emitraw("<success xmlns='" NS_XMPP "xmpp-sasl'/>");
|
||||
} else {
|
||||
sasluser = 0;
|
||||
SASL_ERROR("temporary-auth-failure")
|
||||
|
@ -294,7 +305,7 @@ jabberMsg(XMLNode node) {
|
|||
#else
|
||||
&& user -> checkPassword(creds[2], "plain")) {
|
||||
sasluser = creds[1];
|
||||
emit("<success xmlns='" NS_XMPP "xmpp-sasl'/>");
|
||||
emitraw("<success xmlns='" NS_XMPP "xmpp-sasl'/>");
|
||||
#endif
|
||||
} else {
|
||||
SASL_ERROR("invalid-mechanism")
|
||||
|
@ -312,8 +323,8 @@ jabberMsg(XMLNode node) {
|
|||
unless (node[Cdata]) {
|
||||
SASL_ERROR("incorrect-encoding")
|
||||
QUIT
|
||||
} else unless (mappingp(cert) && cert[0] == 0
|
||||
&& cert["1.2.840.113549.1.9.1"]) {
|
||||
} else unless (mappingp(certinfo) && certinfo[0] == 0
|
||||
&& certinfo["1.2.840.113549.1.9.1"]) {
|
||||
SASL_ERROR("invalid-mechanism")
|
||||
QUIT
|
||||
} else {
|
||||
|
@ -322,7 +333,7 @@ jabberMsg(XMLNode node) {
|
|||
// incorrect-encoding sasl error
|
||||
deco = to_string(decode_base64(node[Cdata]));
|
||||
// TODO: the right thingie could be a list!
|
||||
unless (deco == cert["1.2.840.113549.1.9.1"]) {
|
||||
unless (deco == certinfo["1.2.840.113549.1.9.1"]) {
|
||||
// TODO: not sure about this one
|
||||
SASL_ERROR("invalid-mechanism")
|
||||
QUIT
|
||||
|
@ -340,7 +351,7 @@ jabberMsg(XMLNode node) {
|
|||
} else {
|
||||
user = find_person(u) || createUser(u);
|
||||
sasluser = u;
|
||||
emit("<success xmlns='" NS_XMPP "xmpp-sasl'/>");
|
||||
emitraw("<success xmlns='" NS_XMPP "xmpp-sasl'/>");
|
||||
}
|
||||
}
|
||||
# else
|
||||
|
@ -377,7 +388,7 @@ jabberMsg(XMLNode node) {
|
|||
QUIT
|
||||
}
|
||||
sasluser = u;
|
||||
emit("<success xmlns='" NS_XMPP "xmpp-sasl'/>");
|
||||
emitraw("<success xmlns='" NS_XMPP "xmpp-sasl'/>");
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
@ -402,11 +413,12 @@ jabberMsg(XMLNode node) {
|
|||
+ encode_base64("rspauth=" + result) +
|
||||
"</success>");
|
||||
} else {
|
||||
PT(("digest md5 failure\n"))
|
||||
P0(("digest md5 failure: %O\n", creds))
|
||||
sasluser = 0;
|
||||
SASL_ERROR("invalid-authzid")
|
||||
SASL_ERROR("invalid-authzid") // why do we get here?
|
||||
QUIT
|
||||
}
|
||||
return 0; // ignored, but avoids a warning
|
||||
});
|
||||
|
||||
user = find_person(creds["username"]) || createUser(creds["username"]);
|
||||
|
@ -422,7 +434,7 @@ jabberMsg(XMLNode node) {
|
|||
* wie auch immer haetten wir sonst mittlerweile net/queue fuer
|
||||
* diesen job
|
||||
*/
|
||||
P2(("jabber/server:jabberMsg default case\n"))
|
||||
P0(("jabber/server:jabberMsg default case\n"))
|
||||
}
|
||||
// return ::jabberMsg(from, cmd, args, data, all);
|
||||
return 0;
|
||||
|
@ -467,7 +479,7 @@ open_stream(XMLNode node) {
|
|||
} else {
|
||||
|
||||
features += "<mechanisms xmlns='" NS_XMPP "xmpp-sasl'>"
|
||||
#if __VERSION_MINOR__ > 3 || __VERSION_MICRO__ > 610
|
||||
#ifndef _flag_disable_authentication_digest_MD5
|
||||
"<mechanism>DIGEST-MD5</mechanism>"
|
||||
#endif
|
||||
"<mechanism>PLAIN</mechanism>";
|
||||
|
@ -477,8 +489,8 @@ open_stream(XMLNode node) {
|
|||
#endif
|
||||
#if __EFUN_DEFINED__(tls_available)
|
||||
if (tls_available() && tls_query_connection_state(ME) > 0
|
||||
&& mappingp(cert) && cert[0] == 0
|
||||
&& certificate_check_jabbername(0, cert)) {
|
||||
&& mappingp(certinfo) && certinfo[0] == 0
|
||||
&& certificate_check_jabbername(0, certinfo)) {
|
||||
features += "<mechanism>EXTERNAL</mechanism>";
|
||||
}
|
||||
#endif
|
||||
|
@ -496,7 +508,7 @@ open_stream(XMLNode node) {
|
|||
|
||||
// overrides certificate_check_jabbername from common.c with a function
|
||||
// that is approproate for authenticating users
|
||||
certificate_check_jabbername(name, cert) {
|
||||
certificate_check_jabbername(name, certinfo) {
|
||||
// plan: prefer subjectAltName:id-on-xmppAddr,
|
||||
// but allow email (1.2.840.113549.1.9.1)
|
||||
// and subjectAltName:rfc822Name
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// $Id: user.c,v 1.293 2008/04/15 19:18:12 lynx Exp $ // vim:syntax=lpc:ts=8
|
||||
// $Id: user.c,v 1.303 2008/09/12 15:54:39 lynx Exp $ // vim:syntax=lpc:ts=8
|
||||
#include "jabber.h"
|
||||
#include "user.h"
|
||||
#include "person.h"
|
||||
|
@ -6,9 +6,9 @@
|
|||
#include <peers.h>
|
||||
|
||||
// important to #include user.h first
|
||||
// then we also repatch JABBER_HOST so disco.c does the right thing for us
|
||||
#undef JABBER_HOST
|
||||
#define JABBER_HOST SERVER_HOST
|
||||
// then we also repatch _host_XMPP so disco.c does the right thing for us
|
||||
#undef _host_XMPP
|
||||
#define _host_XMPP SERVER_HOST
|
||||
|
||||
volatile string prefix; // used anywhere?
|
||||
volatile string tag;
|
||||
|
@ -42,6 +42,7 @@ msg(source, mc, data, mapping vars, showingLog) {
|
|||
int ret;
|
||||
string jid, buddy;
|
||||
string packet;
|
||||
mixed t;
|
||||
|
||||
P2(("%s beim jabber:user:msg\n", mc))
|
||||
// net/group/master says we should copy vars if we need to
|
||||
|
@ -124,11 +125,25 @@ msg(source, mc, data, mapping vars, showingLog) {
|
|||
mc = "_notice_place_leave";
|
||||
}
|
||||
switch (mc) {
|
||||
#ifndef EXPERIMENTAL
|
||||
case "_status_person_present":
|
||||
case "_status_person_present_implied":
|
||||
case "_status_person_absent":
|
||||
case "_status_person_absent_recorded":
|
||||
return;
|
||||
#endif
|
||||
PT(("%O got %O\n", ME, mc))
|
||||
|
||||
// actually.. we never send _time_idle with this
|
||||
if (member(vars, "_time_idle")) {
|
||||
t = vars["_time_idle"];
|
||||
if (stringp(t)) {
|
||||
t = to_int(t);
|
||||
PT(("_time_idle %O == %O, right?\n", vars["_time_idle"], t))
|
||||
}
|
||||
t = gmtime(time() - t);
|
||||
vars["_INTERNAL_time_jabber"] = JABBERTIME(t);
|
||||
} else {
|
||||
vars["_INTERNAL_time_jabber"] = JABBERTIME(gmtime(time()));
|
||||
}
|
||||
break;
|
||||
case "_notice_friendship_established":
|
||||
// TODO:
|
||||
// it should be checked that this request is valid
|
||||
|
@ -270,7 +285,7 @@ presence(XMLNode node) {
|
|||
if (!isplacemsg && getchild(node, "x", "http://jabber.org/protocol/muc#user")) {
|
||||
isplacemsg = 2;
|
||||
}
|
||||
/* directed presence */
|
||||
#ifndef _flag_disable_presence_directed_XMPP
|
||||
if (node["@to"]) {
|
||||
target = jid2unl(node["@to"]);
|
||||
if (isplacemsg) {
|
||||
|
@ -279,54 +294,56 @@ presence(XMLNode node) {
|
|||
if (node["@type"] == "unavailable") {
|
||||
P2(("requesting to leave %O\n", target))
|
||||
placeRequest(target,
|
||||
#ifdef SPEC
|
||||
# ifdef SPEC
|
||||
"_request_context_leave"
|
||||
#else
|
||||
# else
|
||||
"_request_leave"
|
||||
#endif
|
||||
# endif
|
||||
, 1);
|
||||
place = 0; // should we do it when we receive the notice?
|
||||
// anyway, w/out this we show up as still being
|
||||
// in that room in /p
|
||||
} else {
|
||||
#ifdef ENTER_MEMBERS
|
||||
# ifdef ENTER_MEMBERS
|
||||
// TODO: this might be needed and should work for remote rooms
|
||||
// doing it in local rooms is a bad idea
|
||||
if (is_formal(target))
|
||||
placeRequest(target,
|
||||
# ifdef SPEC
|
||||
# ifdef SPEC
|
||||
"_request_context_enter"
|
||||
# else
|
||||
# else
|
||||
"_request_enter"
|
||||
# endif
|
||||
# endif
|
||||
"_again", 0, 1, ([
|
||||
"_nick" : MYNICK,
|
||||
"_nick_local" : u[UResource]
|
||||
]));
|
||||
else
|
||||
placeRequest(target,
|
||||
# ifdef SPEC
|
||||
# ifdef SPEC
|
||||
"_request_context_enter"
|
||||
# else
|
||||
# else
|
||||
"_request_enter"
|
||||
# endif
|
||||
# endif
|
||||
"_again", 0, 1);
|
||||
#else
|
||||
# else
|
||||
P2(("teleporting to %O\n", target))
|
||||
teleport(target, "_join", 0, 1);
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
# ifndef _flag_disable_module_friendship
|
||||
} else if (node["@type"] == "subscribe") {
|
||||
// was: friend(({ jid2unl(node["@to"]) }), 0);
|
||||
friend(0, jid2unl(node["@to"]));
|
||||
} else if (node["@type"] == "unsubscribe") {
|
||||
friend(1, jid2unl(node["@to"]));
|
||||
# endif // _flag_disable_module_friendship
|
||||
} else if (abbrev(XMPP, target)) {
|
||||
// if the person is not on our buddylist,
|
||||
// this is usually a muc join
|
||||
// but i am not sure if there are other uses of
|
||||
// presence in jabber
|
||||
#ifdef JABBER_TRANSPARENCY
|
||||
# ifdef JABBER_TRANSPARENCY
|
||||
mapping vars = ([ "_nick" : MYNICK ]);
|
||||
mixed *u = parse_uniform(XMPP + node["@to"]);
|
||||
P3(("jtranz presence to %O\n", target))
|
||||
|
@ -339,7 +356,7 @@ presence(XMLNode node) {
|
|||
// unless(mappingp(presence_out)) presence_out = ([ ]);
|
||||
vars["_jabber_XML"] = innerxml;
|
||||
|
||||
// TODO: wir fliegen wir mit JABBER_HOST auf die
|
||||
// TODO: wir fliegen wir mit _host_XMPP auf die
|
||||
// NASE.
|
||||
// wir muessen die resource in die vars stecken...
|
||||
vars["_INTERNAL_source_jabber"] = myjidresource;
|
||||
|
@ -356,14 +373,15 @@ presence(XMLNode node) {
|
|||
"[_nick] is sending you a jabber presence.",
|
||||
vars);
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
} else {
|
||||
// TODO: what can we do in this case?
|
||||
// we can look at our buddylist, if target is a member
|
||||
// then this is a directed presence
|
||||
}
|
||||
} /* end of directed presence handling */
|
||||
|
||||
#endif // _flag_disable_presence_directed_XMPP
|
||||
#ifdef AVAILABILITY_AWAY
|
||||
else if (node["/show"]) {
|
||||
// else this is one of the so-called "presence broadcasts"
|
||||
// we will never support stupid broadcasts although we could
|
||||
|
@ -393,6 +411,7 @@ presence(XMLNode node) {
|
|||
// TODO: quiet?
|
||||
announce(AVAILABILITY_HERE);
|
||||
}
|
||||
#endif // AVAILABILITY_AWAY
|
||||
}
|
||||
|
||||
|
||||
|
@ -592,6 +611,7 @@ iq(XMLNode node) {
|
|||
break;
|
||||
}
|
||||
break;
|
||||
#if !defined(REGISTERED_USERS_ONLY) && !defined(_flag_disable_registration_XMPP)
|
||||
case "jabber:iq:register":
|
||||
switch(node["@type"]) {
|
||||
case "get":
|
||||
|
@ -632,6 +652,7 @@ iq(XMLNode node) {
|
|||
case "error":
|
||||
break;
|
||||
}
|
||||
#endif // jabber:iq:register
|
||||
case "jabber:iq:roster":
|
||||
switch(node["@type"]) {
|
||||
case "get":
|
||||
|
@ -716,8 +737,10 @@ iq(XMLNode node) {
|
|||
helper = helper["/item"];
|
||||
if (helper && helper["@subscription"] == "remove") {
|
||||
string buddy = jid2unl(helper["@jid"]);
|
||||
#ifndef _flag_disable_module_friendship
|
||||
P2(("remove %O from roster\n", helper["@jid"]))
|
||||
friend(1, buddy);
|
||||
#endif
|
||||
m_delete(xbuddylist, buddy);
|
||||
emit(sprintf("<iq type='result' id='%s'/>", tag));
|
||||
} else {
|
||||
|
@ -806,11 +829,14 @@ iq(XMLNode node) {
|
|||
}
|
||||
break;
|
||||
case "http://jabber.org/protocol/disco#items":
|
||||
// send a list of rooms to the client
|
||||
switch(node["@type"]) {
|
||||
case "get":
|
||||
if (!node["@to"])
|
||||
// "my" places - let person.c handle this
|
||||
sendmsg(ME, "_request_list_item", 0, vars);
|
||||
else if (is_localhost(lower_case(node["@to"])))
|
||||
// server's places - let root.c handle this
|
||||
sendmsg("/", "_request_list_item", 0, vars);
|
||||
/* else... TODO */
|
||||
break;
|
||||
|
@ -833,6 +859,9 @@ iq(XMLNode node) {
|
|||
"<query xmlns='jabber:iq:private'>"
|
||||
"<storage xmlns='storage:bookmarks'>",
|
||||
tag);
|
||||
// hey wait.. we are sending the list of places here..
|
||||
// why is it i have never seen a jabber client actually
|
||||
// executing autojoins? FIXME
|
||||
if (v("subscriptions"))
|
||||
foreach (string s in v("subscriptions")) {
|
||||
string jid;
|
||||
|
@ -1078,7 +1107,7 @@ string jid2unl(string jid) {
|
|||
return node;
|
||||
}
|
||||
# if 1
|
||||
else if (ISPLACEMSG(node)) {
|
||||
else if (strlen(node) && ISPLACEMSG(node)) {
|
||||
return "psyc://" + host + "/@" + PREFIXFREE(node);
|
||||
}
|
||||
# endif
|
||||
|
@ -1199,12 +1228,17 @@ w(string mc, string data, mapping vars, mixed source) {
|
|||
case "_notice_list_feature_place":
|
||||
case "_notice_list_feature_server":
|
||||
case "_notice_list_feature_newsfeed":
|
||||
#ifndef _flag_disable_query_server
|
||||
mixed id2jabber = shared_memory("disco_identity");
|
||||
mixed feat2jabber = shared_memory("disco_features");
|
||||
unless (mappingp(id2jabber)) return 1;
|
||||
vars["_identity"] = id2jabber[vars["_identity"]] || vars["_identity"];
|
||||
vars["_list_feature"] = implode(map(vars["_list_feature"],
|
||||
(: return "<feature var='" + feat2jabber[$1] + "'/>"; :)), "");
|
||||
(: return "<feature var='" + feat2jabber[$1] + "'/>"; :)), "");
|
||||
break;
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
case "_notice_list_item":
|
||||
t = "";
|
||||
// same stuff in user.c (what happened to code sharing?)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue