mirror of
git://git.psyced.org/git/psyced
synced 2024-08-15 03:25:10 +00:00
+
This commit is contained in:
commit
c9b3d242a3
22 changed files with 414 additions and 245 deletions
|
@ -31,6 +31,7 @@ inherit NET_PATH "name";
|
|||
|
||||
volatile mixed gateways;
|
||||
volatile mixed *dialback_queue;
|
||||
volatile mapping certinfo;
|
||||
|
||||
volatile string streamid;
|
||||
volatile float streamversion;
|
||||
|
@ -312,39 +313,39 @@ tls_logon(result) {
|
|||
//
|
||||
// if the cert is ok, we can set authenticated to 1
|
||||
// to skip dialback
|
||||
mixed cert = tls_certificate(ME, 0);
|
||||
P3(("active::certinfo %O\n", cert))
|
||||
if (mappingp(cert)) {
|
||||
unless (certificate_check_name(hostname, cert, "xmpp-server")) {
|
||||
certinfo = tls_certificate(ME, 0);
|
||||
P3(("active::certinfo %O\n", certinfo))
|
||||
if (mappingp(certinfo)) {
|
||||
unless (tls_check_service_identity(hostname, certinfo, "xmpp-server")) {
|
||||
#ifdef _flag_report_bogus_certificates
|
||||
monitor_report("_error_invalid_certificate_identity",
|
||||
sprintf("%O presented a certificate that "
|
||||
"contains %O/%O",
|
||||
hostname, cert["2.5.4.3"],
|
||||
cert["2.5.29.17:1.3.6.1.5.5.7.8.5"]));
|
||||
hostname, certinfo["2.5.4.3"],
|
||||
certinfo["2.5.29.17:1.3.6.1.5.5.7.8.5"]));
|
||||
#endif
|
||||
#ifdef _flag_log_bogus_certificates
|
||||
log_file("CERTS", S("%O %O %O id?\n", ME, hostname, cert));
|
||||
log_file("CERTS", S("%O %O %O id?\n", ME, hostname, certinfo));
|
||||
#else
|
||||
P1(("TLS: %s presented a certificate with unexpected identity.\n", hostname))
|
||||
P2(("%O\n", cert))
|
||||
P2(("%O\n", certinfo))
|
||||
#endif
|
||||
#if 0 //def _flag_reject_bogus_certificates
|
||||
QUIT
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
else if (cert[0] != 0) {
|
||||
else if (certinfo[0] != 0) {
|
||||
#ifdef _flag_report_bogus_certificates
|
||||
monitor_report("_error_untrusted_certificate",
|
||||
sprintf("%O certificate could not be verified",
|
||||
hostname));
|
||||
#endif
|
||||
#ifdef _flag_log_bogus_certificates
|
||||
log_file("CERTS", S("%O %O %O\n", ME, hostname, cert));
|
||||
log_file("CERTS", S("%O %O %O\n", ME, hostname, certinfo));
|
||||
#else
|
||||
P1(("TLS: %s presented untrusted certificate.\n", hostname))
|
||||
P2(("%O\n", cert))
|
||||
P2(("%O\n", certinfo))
|
||||
#endif
|
||||
#if 0 //def _flag_reject_bogus_certificates
|
||||
// QUIT is wrong...
|
||||
|
|
|
@ -393,7 +393,9 @@ xmpp_error(node, xmpperror) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
// deprecated - use certificate_check_name from library/tls.c instead
|
||||
// deprecated - use tls_check_service_identity from library/tls.c instead
|
||||
// is this being used at all? -- no longer, but keep it around a little
|
||||
// for backward compat
|
||||
#ifdef WANT_S2S_TLS
|
||||
certificate_check_jabbername(name, cert) {
|
||||
mixed t;
|
||||
|
|
|
@ -291,7 +291,7 @@ jabberMsg(XMLNode node) {
|
|||
// paranoia note: as with XEP 0178 we might want to check dns anyway to
|
||||
// protect against stolen certificates
|
||||
if (mappingp(certinfo) && certinfo[0] == 0
|
||||
&& node["@from"] && certificate_check_name(node["@from"], certinfo, "xmpp-server")) {
|
||||
&& node["@from"] && tls_check_service_identity(node["@from"], certinfo, "xmpp-server")) {
|
||||
P2(("dialback without dialback %O\n", certinfo))
|
||||
verify_connection(node["@to"], node["@from"], "valid");
|
||||
} else {
|
||||
|
@ -414,7 +414,7 @@ jabberMsg(XMLNode node) {
|
|||
*/
|
||||
int success = 0;
|
||||
|
||||
success = certificate_check_name(t, certinfo, "xmpp-server");
|
||||
success = tls_check_service_identity(t, certinfo, "xmpp-server");
|
||||
if (success) {
|
||||
emitraw("<success xmlns='" NS_XMPP "xmpp-sasl'/>");
|
||||
P2(("successful sasl external authentication with "
|
||||
|
@ -542,8 +542,8 @@ open_stream(XMLNode node) {
|
|||
// sasl external if we know that it will succeed
|
||||
// later on
|
||||
if (node["@from"] &&
|
||||
certificate_check_name(node["@from"],
|
||||
certinfo, "xmpp-server")) {
|
||||
tls_check_service_identity(node["@from"], certinfo,
|
||||
"xmpp-server")) {
|
||||
packet += "<mechanisms xmlns='" NS_XMPP "xmpp-sasl'>";
|
||||
packet += "<mechanism>EXTERNAL</mechanism>";
|
||||
packet += "</mechanisms>";
|
||||
|
|
|
@ -490,6 +490,7 @@ open_stream(XMLNode node) {
|
|||
#if __EFUN_DEFINED__(tls_available)
|
||||
if (tls_available() && tls_query_connection_state(ME) > 0
|
||||
&& mappingp(certinfo) && certinfo[0] == 0
|
||||
// why do we use the old one here?
|
||||
&& certificate_check_jabbername(0, certinfo)) {
|
||||
features += "<mechanism>EXTERNAL</mechanism>";
|
||||
}
|
||||
|
@ -512,5 +513,6 @@ certificate_check_jabbername(name, certinfo) {
|
|||
// plan: prefer subjectAltName:id-on-xmppAddr,
|
||||
// but allow email (1.2.840.113549.1.9.1)
|
||||
// and subjectAltName:rfc822Name
|
||||
// FIXME: do something useful here...
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -614,6 +614,13 @@ void dns_srv_resolve(string hostname, string service, string proto, closure call
|
|||
// dumme bevormundung. wegen der musste ich jetzt ewig lang suchen:
|
||||
//unless (proto == "tcp" || proto == "udp") return;
|
||||
// da wir mit nem String arbeiten muessen
|
||||
|
||||
#ifdef __IDNA__
|
||||
if (catch(hostname = idna_to_ascii(TO_UTF8(hostname)); nolog)) {
|
||||
P0(("catch: punycode %O in %O\n", hostname, ME))
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
req = sprintf("_%s._%s.%s", service, proto, hostname);
|
||||
rc = send_erq(ERQ_LOOKUP_SRV, req, lambda(({ 'wu }),
|
||||
({ (#',),
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
#include <net.h> // vim syntax=lpc
|
||||
#include <proto.h>
|
||||
#include <sys/tls.h>
|
||||
|
||||
mapping tls_certificate(object who, int longnames) {
|
||||
mixed *extra, extensions;
|
||||
mapping cert;
|
||||
|
@ -85,7 +88,7 @@ mapping tls_certificate(object who, int longnames) {
|
|||
|
||||
// generalized variant of the old certificate_check_jabbername
|
||||
// RFC 6125 describes the process in more detail
|
||||
int certificate_check_name(string name, mixed cert, string scheme) {
|
||||
int tls_check_service_identity(string name, mixed cert, string scheme) {
|
||||
mixed t;
|
||||
string idn;
|
||||
// FIXME: should probably be more careful about internationalized
|
||||
|
@ -111,6 +114,8 @@ int certificate_check_name(string name, mixed cert, string scheme) {
|
|||
|
||||
// subjectAlternativeName - SRV ID - FIXME
|
||||
// unfortunately, the only ones I have encountered so far were ... unusable
|
||||
// what they should like is "_psyc.name" - i.e. "_" + scheme + "." + name
|
||||
// no wildcards probably
|
||||
if ((t = cert["2.5.29.17:1.3.6.1.5.5.7.8.7"])) {
|
||||
P2(("encountered SRVName, please tell fippo: %O\n", t))
|
||||
}
|
||||
|
@ -121,6 +126,7 @@ int certificate_check_name(string name, mixed cert, string scheme) {
|
|||
#if 0
|
||||
// id-on-xmppAddr - have not seen them issued by anyone but
|
||||
// startcom and those usually include dnsname, too
|
||||
// utf8-encoded
|
||||
if ((t = cert["2.5.29.17:1.3.6.1.5.5.7.8.5"])) {
|
||||
if (pointerp(t)) {
|
||||
if (member(t, name) != -1) return 1;
|
||||
|
@ -142,7 +148,11 @@ int certificate_check_name(string name, mixed cert, string scheme) {
|
|||
|
||||
// look for idn encoded stuff
|
||||
foreach(string cn : t) {
|
||||
#ifdef __IDNA__
|
||||
idn = NAMEPREP(idna_to_unicode(cn));
|
||||
#else
|
||||
idn = NAMEPREP(cn);
|
||||
#endif
|
||||
if (idn == name) return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -157,3 +167,20 @@ int certificate_check_name(string name, mixed cert, string scheme) {
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tls_check_cipher(object sock, string scheme) {
|
||||
string t;
|
||||
mixed m = tls_query_connection_info(sock);
|
||||
|
||||
P3(("%O is using the %O cipher.\n", sock, m[TLS_CIPHER]))
|
||||
// shouldn't our negotiation have ensured we have PFS?
|
||||
|
||||
if (stringp(t = m[TLS_CIPHER]) &&! abbrev("DHE", t)) {
|
||||
monitor_report("_warning_circuit_encryption_cipher_details",
|
||||
object_name(sock) +" · using "+ t +" cipher");
|
||||
// we can't expect that degree of privacy from jabber, for now
|
||||
if (scheme != "xmpp") return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -209,48 +209,41 @@ int logon(int neverfails) {
|
|||
|
||||
#ifdef __TLS__
|
||||
sAuthHosts(([ ])); // reset authhosts
|
||||
if (tls_available() && tls_query_connection_state(ME) == 1 && mappingp(cert = tls_certificate(ME, 0))) {
|
||||
if (cert[0] != 0) {
|
||||
// log error 17 or 18 + cert here
|
||||
P0(("%O encountered a cert verify error %O in %O\n", ME,
|
||||
cert[0], cert))
|
||||
// and goodbye.
|
||||
if (tls_available() && tls_query_connection_state(ME) == 1) {
|
||||
unless (tls_check_cipher(ME, "psyc")) {
|
||||
croak("_error_circuit_encryption_cipher",
|
||||
"Your cipher choice does not provide forward secrecy.");
|
||||
QUIT
|
||||
}
|
||||
if (mappingp(cert = tls_certificate(ME, 0))) {
|
||||
if (cert[0] != 0) {
|
||||
// log error 17 or 18 + cert here
|
||||
P0(("%O encountered a cert verify error %O in %O\n", ME,
|
||||
cert[0], cert))
|
||||
// and goodbye.
|
||||
# ifdef _flag_enable_certificate_any
|
||||
remove_interactive(ME);
|
||||
return 0;
|
||||
remove_interactive(ME);
|
||||
return 0;
|
||||
# endif
|
||||
}
|
||||
if (m = cert["2.5.29.17:dNSName"]) {
|
||||
// FIXME: this does not yet handle wildcard DNS names
|
||||
P1(("%O believing dNSName %O\n", ME, m))
|
||||
// probably also: register_target?
|
||||
// but be careful never to register_target wildcards
|
||||
if (stringp(m)) sAuthenticated(m);
|
||||
else foreach(t : m) sAuthenticated(t);
|
||||
}
|
||||
//#ifdef _flag_allow_certificate_name_common // to be switched this year
|
||||
# ifndef _flag_disallow_certificate_name_common
|
||||
// assume that CN is a host
|
||||
// as this is an assumption only, we may NEVER register_target it
|
||||
// note: CN is deprecated for good reasons.
|
||||
else if (t = cert["2.5.4.3"]) {
|
||||
P1(("%O believing CN %O\n", ME, t))
|
||||
sAuthenticated(t);
|
||||
}
|
||||
# endif
|
||||
if (m = tls_query_connection_info(ME)) {
|
||||
P2(("%O is using the %O cipher.\n", ME, m[TLS_CIPHER]))
|
||||
// shouldn't our negotiation have ensured we have PFS?
|
||||
if (stringp(t = m[TLS_CIPHER]) &&! abbrev("DHE", t)) {
|
||||
// croak("_warning_circuit_encryption_cipher",
|
||||
// "Your cipher choice does not provide forward secrecy.");
|
||||
monitor_report(
|
||||
"_warning_circuit_encryption_cipher_details",
|
||||
object_name(ME) +" · using "+ t +" cipher");
|
||||
//debug_message(sprintf(
|
||||
// "TLS connection info for %O is %O\n", ME, m));
|
||||
//QUIT // are we ready for *this* !???
|
||||
}
|
||||
if (m = cert["2.5.29.17:dNSName"]) {
|
||||
// FIXME: this does not yet handle wildcard DNS names
|
||||
P1(("%O believing dNSName %O\n", ME, m))
|
||||
// probably also: register_target?
|
||||
// but be careful never to register_target wildcards
|
||||
if (stringp(m)) sAuthenticated(m);
|
||||
else foreach(t : m) sAuthenticated(t);
|
||||
}
|
||||
//#ifdef _flag_allow_certificate_name_common // to be switched this year
|
||||
# ifndef _flag_disallow_certificate_name_common
|
||||
// assume that CN is a host
|
||||
// as this is an assumption only, we may NEVER register_target it
|
||||
// note: CN is deprecated for good reasons.
|
||||
else if (t = cert["2.5.4.3"]) {
|
||||
P1(("%O believing CN %O\n", ME, t))
|
||||
sAuthenticated(t);
|
||||
}
|
||||
# endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -36,9 +36,13 @@ volatile string netloc;
|
|||
mapping instate = ([ ]);
|
||||
mapping outstate;
|
||||
|
||||
mapping legal_senders;
|
||||
volatile mapping legal_senders;
|
||||
|
||||
array(mixed) verify_queue = ({ });
|
||||
volatile array(mixed) verify_queue = ({ });
|
||||
|
||||
#ifdef __TLS__
|
||||
volatile mapping certinfo;
|
||||
#endif
|
||||
|
||||
volatile int flags = 0;
|
||||
|
||||
|
@ -103,52 +107,23 @@ int logon(int failure) {
|
|||
instate = ([ "_INTERNAL_origin" : ME ]);
|
||||
outstate = ([ ]);
|
||||
#ifdef __TLS__
|
||||
mixed cert;
|
||||
if (tls_available() && tls_query_connection_state(ME) == 1 && mappingp(cert = tls_certificate(ME, 0))) {
|
||||
mixed m, t;
|
||||
if (cert[0] != 0) {
|
||||
// log error 17 + cert here
|
||||
// and goodbye.
|
||||
P0(("%O encountered a cert verify error %O in %O\n", ME,
|
||||
cert[0], cert))
|
||||
remove_interactive(ME);
|
||||
return 0;
|
||||
}
|
||||
if (m = cert["2.5.29.17:dNSName"]) {
|
||||
// FIXME: this does not yet handle wildcard DNS names
|
||||
P1(("%O believing dNSName %O\n", ME, m))
|
||||
// probably also: register_target?
|
||||
// but be careful never to register_target wildcards
|
||||
if (stringp(m))
|
||||
sAuthenticated(m);
|
||||
else
|
||||
foreach(t : m)
|
||||
sAuthenticated(t);
|
||||
}
|
||||
//#ifdef _flag_allow_certificate_name_common // to be switched this year
|
||||
#ifndef _flag_disallow_certificate_name_common
|
||||
// assume that CN is a host
|
||||
// as this is an assumption only, we may NEVER register_target it
|
||||
// note: CN is deprecated for good reasons.
|
||||
else if (t = cert["2.5.4.3"]) {
|
||||
P1(("%O believing CN %O\n", ME, t))
|
||||
sAuthenticated(t);
|
||||
}
|
||||
#endif
|
||||
if (m = tls_query_connection_info(ME)) {
|
||||
P2(("%O is using the %O cipher.\n", ME, m[TLS_CIPHER]))
|
||||
// shouldn't our negotiation have ensured we have PFS?
|
||||
if (stringp(t = m[TLS_CIPHER]) &&! abbrev("DHE", t)) {
|
||||
// croak("_warning_circuit_encryption_cipher",
|
||||
// "Your cipher choice does not provide forward secrecy.");
|
||||
monitor_report(
|
||||
"_warning_circuit_encryption_cipher_details",
|
||||
object_name(ME) +" · using "+ t +" cipher");
|
||||
//debug_message(sprintf(
|
||||
// "TLS connection info for %O is %O\n", ME, m));
|
||||
//QUIT // are we ready for *this* !???
|
||||
P0(("circuit logon %O %O\n", tls_available(), tls_query_connection_state(ME)))
|
||||
// FIXME: needs to handle the not-detected case
|
||||
if (tls_available()) {
|
||||
if (tls_query_connection_state(ME) == 0 && !isServer()) {
|
||||
P0(("%O turning on TLS\n", ME))
|
||||
tls_init_connection(ME, #'logon);
|
||||
return 1;
|
||||
} else if (tls_query_connection_state(ME) == 1) {
|
||||
certinfo = tls_certificate(ME, 0);
|
||||
P0(("certinfo: %O\n", certinfo))
|
||||
unless (tls_check_cipher(ME, "psyc")) {
|
||||
croak("_error_circuit_encryption_cipher",
|
||||
"Your cipher choice does not provide forward secrecy.");
|
||||
//destruct(ME);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -205,7 +180,8 @@ first_response() {
|
|||
// note: this is circuit-messaging
|
||||
void circuit_msg(string mc, mapping vars, string data) {
|
||||
mapping rv = ([ ]);
|
||||
mixed *u;
|
||||
mixed *su;
|
||||
mixed *tu;
|
||||
switch(mc) {
|
||||
case "_request_authorization":
|
||||
if (vars["_tag"]) {
|
||||
|
@ -218,14 +194,14 @@ void circuit_msg(string mc, mapping vars, string data) {
|
|||
rv["_uniform_target"] = vars["_uniform_target"];
|
||||
rv["_uniform_source"] = vars["_uniform_source"];
|
||||
|
||||
u = parse_uniform(vars["_uniform_target"]);
|
||||
if (!(u && is_localhost(u[UHost]))) {
|
||||
tu = parse_uniform(vars["_uniform_target"]);
|
||||
if (!(tu && is_localhost(tu[UHost]))) {
|
||||
msg(0, "_error_invalid_uniform_target", "[_uniform_target] is not hosted here.", rv);
|
||||
return;
|
||||
}
|
||||
u = parse_uniform(vars["_uniform_source"]);
|
||||
su = parse_uniform(vars["_uniform_source"]);
|
||||
// qAuthenticated does that:u[UHost] = NAMEPREP(u[UHost]);
|
||||
if (qAuthenticated(u[UHost])) {
|
||||
if (qAuthenticated(su[UHost])) {
|
||||
// possibly different _uniform_target only
|
||||
if (flags & TCP_PENDING_TIMEOUT) {
|
||||
P0(("removing call out\n"))
|
||||
|
@ -233,10 +209,22 @@ void circuit_msg(string mc, mapping vars, string data) {
|
|||
flags -= TCP_PENDING_TIMEOUT;
|
||||
}
|
||||
msg(0, "_status_authorization", 0, rv);
|
||||
// } else if (tls_query_connection_state(ME) == 1 && ...) {
|
||||
// FIXME
|
||||
#ifdef __TLS__
|
||||
} else if (tls_query_connection_state(ME) == 1
|
||||
&& mappingp(certinfo)
|
||||
&& certinfo[0] == 0
|
||||
&& tls_check_service_identity(su[UHost], certinfo, "psyc") == 1) {
|
||||
sAuthenticated(su[UHost]);
|
||||
if (flags & TCP_PENDING_TIMEOUT) {
|
||||
P0(("removing call out\n"))
|
||||
remove_call_out(#'quit);
|
||||
flags -= TCP_PENDING_TIMEOUT;
|
||||
}
|
||||
msg(0, "_status_authorization", 0, rv);
|
||||
#endif
|
||||
} else {
|
||||
string ho = u[UHost];
|
||||
// FIXME: lynX wants to do that only for trusted hosts
|
||||
string ho = su[UHost];
|
||||
// FIXME: this actually needs to consider srv, too...
|
||||
dns_resolve(ho, (:
|
||||
// FIXME: psyc/parse::deliver is much better here
|
||||
|
|
|
@ -72,7 +72,7 @@ object load(object usr, mapping opts) {
|
|||
void check_status_update(string body, string headers, int http_status) {
|
||||
P3(("twitter/client:parse_status_update(%O, %O, %O)\n", body, headers, http_status))
|
||||
if (http_status != R_OK)
|
||||
sendmsg(user, "_error_twitter_status_update", "Error: failed to post status update on twitter.");
|
||||
sendmsg(user, "_failure_update_twitter", "Unable to post status update on twitter.");
|
||||
}
|
||||
|
||||
void status_update(string text) {
|
||||
|
|
|
@ -1545,16 +1545,6 @@ logon() {
|
|||
string t;
|
||||
|
||||
P2(("LOGON %O from %O\n", ME, query_ip_name() ))
|
||||
unless (legal_host(query_ip_number(), 0, 0, 0)) {
|
||||
// this happens when people reconnect during the shutdown
|
||||
// procedure.. and also when they are banned, but huh..
|
||||
// that hardly ever happens :)
|
||||
w("_error_rejected_address",
|
||||
"You are temporarily not permitted to connect here.");
|
||||
//"I'm afraid you are no longer welcome here.");
|
||||
return remove_interactive(ME);
|
||||
// and the object will deteriorate when user gives up..
|
||||
}
|
||||
// shouldn't this be qScheme() instead? little paranoid TODO
|
||||
// but then we would have to move qScheme() from the server.c's
|
||||
// into the common.c's .. well, we could do that some day
|
||||
|
@ -1564,7 +1554,32 @@ logon() {
|
|||
beQuiet = -1; // never turn off less interesting enter/leave echoes
|
||||
// makeToken() isn't a good idea here, apparently
|
||||
sTextPath(v("layout"), v("language"), t);
|
||||
// cannot if (greeting) this since jabber:iq:auth depends on this
|
||||
unless (legal_host(query_ip_number(), 0, 0, 0)) {
|
||||
// this happens when people reconnect during the shutdown
|
||||
// procedure.. and also when they are banned, but huh..
|
||||
// that hardly ever happens :)
|
||||
//
|
||||
// w() needs to be called *after* sTextPath
|
||||
w("_error_rejected_address",
|
||||
"You are currently not permitted to connect here.");
|
||||
return remove_interactive(ME);
|
||||
// and the object will deteriorate when user gives up..
|
||||
//
|
||||
// with the #'quit call_out.. or was it meant to
|
||||
// deteriorate differently?
|
||||
}
|
||||
#ifdef __TLS__
|
||||
if (tls_query_connection_state(ME) == 1) {
|
||||
if (tls_check_cipher(ME, t)) {
|
||||
unless (beQuiet) w("_status_circuit_encryption_cipher");
|
||||
} else {
|
||||
// i bet jabber users will love this
|
||||
w("_warning_circuit_encryption_cipher");
|
||||
//return remove_interactive(ME);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// cannot if (greeting) here this since jabber:iq:auth depends on this
|
||||
// also greeting will only be defined after ::logon()
|
||||
// (use another w() maybe?)
|
||||
w("_notice_login", 0, ([ "_nick": MYNICK,
|
||||
|
|
|
@ -2455,9 +2455,15 @@ friend(rm, entity, ni, trustee) {
|
|||
// normally auto-acknowledge this request
|
||||
sendmsg(entity, "_request_friendship_implied",
|
||||
0, ([ "_nick": MYNICK, "_degree_availability": availability ]) );
|
||||
sendmsg(entity, "_request_status_person",
|
||||
0, ([ "_nick": MYNICK ]) );
|
||||
// did i just say something about symmetry?
|
||||
// don't know how this hack got here but it drives some
|
||||
// jabber servers nuts as you are not supposed to probe
|
||||
// people that you aren't subscribed to, yet
|
||||
//sendmsg(entity, "_request_status_person",
|
||||
// 0, ([ "_nick": MYNICK ]) );
|
||||
// we should instead ensure we are always sending our presence
|
||||
// status once a subscription is completed.. FIXME
|
||||
// or we just scrap it all and redo context subscription
|
||||
// strictly as suggested by the new specs.. sigh
|
||||
#ifdef TRY_THIS
|
||||
// currently friend() only gets called from
|
||||
// online commands. so we skip the if
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue