⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dialback_out.c

📁 jabber server jabber server jabber server jabber server
💻 C
📖 第 1 页 / 共 3 页
字号:
	    /* deprecated non-dialback protocol, reject connection */	    if (version < 1 && dbns == NULL) {		/* Muahahaha!  you suck! *click* */		log_notice(c->key->server,"Legacy server access denied");		mio_write(m, NULL, "<stream:error><not-authorized xmlns='urn:ietf:params:xml:ns:xmpp-streams'/><text xmlns='urn:ietf:params:xml:ns:xmpp-streams' xml:lang='en'>Legacy Access Denied!</text></stream:error>", -1);		mio_close(m);		break;	    }	    /* peer is XMPP server, but does not support dialback */	    if (dbns == NULL) {		log_notice(c->d->i->id, "We cannot send to %s. This XMPP server does not support dialback.", c->key->server);		mio_write(m, NULL, "<stream:error><not-authorized xmlns='urn:ietf:params:xml:ns:xmpp-streams'/><text xml:lang='en' xmlns='urn:ietf:params:xml:ns:xmpp-streams'>Sorry, we only support dialback to 'authenticate' our peers. SASL is not supported by us. It seems we cannot communicate to you :-(</text></stream:error>", -1);		mio_close(m);		break;	    }	    /* create and send our result request to initiate dialback for non XMPP-sessions (XMPP has to wait for stream features) */	    if (version < 1) {		log_debug2(ZONE, LOGT_IO, "pre-XMPP stream could now send <db:result/>");		if (c->db_state == want_request) {		    cur = xmlnode_new_tag("db:result");		    xmlnode_put_attrib(cur, "to", c->key->server);		    xmlnode_put_attrib(cur, "from", c->key->resource);		    xmlnode_insert_cdata(cur,  dialback_merlin(xmlnode_pool(cur), c->d->secret, c->key->server, c->stream_id), -1);		    mio_write(m,cur, NULL, 0);		    c->db_state = sent_request;		    c->connection_state = sent_db_request;		    log_debug2(ZONE, LOGT_IO, "... and we wanted ... and we sent <db:result/>");		} else if (c->db_state == not_requested) {		    c->db_state = could_request;		    log_debug2(ZONE, LOGT_IO, "... but we didn't want yet");		}	    } else {		c->connection_state = waiting_features;	    }	    /* well, we're connected to a dialback server, we can at least send verify requests now */	    c->m = m;	    if (version < 1) {		for(cur = xmlnode_get_firstchild(c->verifies); cur != NULL; cur = xmlnode_get_nextsibling(cur)) {		    mio_write(m, xmlnode_dup(cur), NULL, -1);		    xmlnode_hide(cur);		}	    }	    break;	case MIO_XML_NODE:	    /* watch for stream errors */	    if (j_strcmp(xmlnode_get_name(x), "stream:error") == 0) {		spool s = spool_new(x->p);		streamerr errstruct = pmalloco(x->p, sizeof(_streamerr));		char *errmsg = NULL;		/* generate error message */		xstream_parse_error(x->p, x, errstruct);		xstream_format_error(s, errstruct);		errmsg = spool_print(s);		/* append error message to connect_results */		if (c->connect_results != NULL && errmsg != NULL) {		    spool_add(c->connect_results, " (");		    spool_add(c->connect_results, pstrdup(c->connect_results->p, errmsg));		    spool_add(c->connect_results, ")");		}		/* logging */		switch (errstruct->severity) {		    case normal:			log_debug2(ZONE, LOGT_IO, "stream error on outgoing %s conn to %s (%s): %s", c->xmpp_version < 1 ? "preXMPP" : "XMPP1.0", mio_ip(m), jid_full(c->key), errmsg);			break;		    case configuration:		    case feature_lack:		    case unknown:			log_warn(c->d->i->id, "received stream error on outgoing %s conn to %s (%s): %s", c->xmpp_version < 1 ? "preXMPP" : "XMPP1.0", mio_ip(m), jid_full(c->key), errmsg);			break;		    case error:		    default:			log_error(c->d->i->id, "received stream error on outgoing %s conn to %s (%s): %s", c->xmpp_version < 1 ? "preXMPP" : "XMPP1.0", mio_ip(m), jid_full(c->key), errmsg);		}		mio_close(m);		break;	    }	    /* watch for stream:features */	    if (j_strcmp(xmlnode_get_name(x), "stream:features") == 0) {		c->connection_state = got_features;#ifdef HAVE_SSL		/* is starttls supported? */		if (xmlnode_get_tag(x, "starttls?xmlns=" NS_XMPP_TLS) != NULL) {		    /* don't start if forbidden by caller (configuration) */		    if (c->xmpp_no_tls) {			log_notice(c->d->i->id, "Server %s advertized starttls, but disabled by our configuration.", c->key->server);		    } else if (mio_ssl_starttls_possible(m, c->key->resource)) {			/* our side is prepared for starttls */			xmlnode starttls = NULL;			/* request to start tls on this connection */			log_debug2(ZONE, LOGT_IO, "requesting starttls for an outgoing connection to %s", c->key->server);			starttls = xmlnode_new_tag("starttls");			xmlnode_put_attrib(starttls, "xmlns", NS_XMPP_TLS);			mio_write(m, starttls, NULL, 0);			break;		    }		}#endif /* HAVE_SSL */		/* no stream:feature we'd like to use, we can now send the outstanding db:result - or we could, if we did not want */		log_debug2(ZONE, LOGT_IO, "XMPP-stream: we could now send <db:result/>s");		if (c->db_state == want_request) {		    cur = xmlnode_new_tag("db:result");		    xmlnode_put_attrib(cur, "to", c->key->server);		    xmlnode_put_attrib(cur, "from", c->key->resource);		    xmlnode_insert_cdata(cur,  dialback_merlin(xmlnode_pool(cur), c->d->secret, c->key->server, c->stream_id), -1);		    mio_write(m,cur, NULL, 0);		    c->db_state = sent_request;		    c->connection_state = sent_db_request;		    log_debug2(ZONE, LOGT_IO, "... and we wanted ... and we did sent a <db:result/>");		} else if (c->db_state == not_requested) {		    c->db_state = could_request;		    log_debug2(ZONE, LOGT_IO, "... but we did not want to");		}		/* and we can send the verify requests */		for(cur = xmlnode_get_firstchild(c->verifies); cur != NULL; cur = xmlnode_get_nextsibling(cur)) {		    mio_write(m, xmlnode_dup(cur), NULL, -1);		    xmlnode_hide(cur);		}		/* finished processing stream:features */		break;	    }#ifdef HAVE_SSL	    /* watch for positive starttls result */	    if (j_strcmp(xmlnode_get_name(x), "proceed") == 0 && j_strcmp(xmlnode_get_attrib(x, "xmlns"), NS_XMPP_TLS) == 0) {		/* start tls on our side */		if (mio_xml_starttls(m, 1, c->key->resource)) {		    /* starting tls failed */		    log_warn(c->d->i->id, "Starting TLS on an outgoing s2s to %s failed on our side (%s).", c->key->server, c->key->resource);		    mio_close(m);		    break;		}		/* we forget about the headers we got now again */		c->connection_state = connected;		/* send stream header again */		dialback_out_read(m, MIO_NEW, c, NULL);		break;	    }	    /* watch for negative starttls result */	    if (j_strcmp(xmlnode_get_name(x), "failure") == 0 && j_strcmp(xmlnode_get_attrib(x, "xmlns"), NS_XMPP_TLS) == 0) {		log_warn(c->d->i->id, "Starting TLS on an outgoing s2s to %s failed on the other side.", c->key->server);		mio_close(m);		break;	    }#endif /* HAVE_SSL */	    /* watch for a valid result, then we're set to rock! */	    if(j_strcmp(xmlnode_get_name(x),"db:result") == 0) {		if(j_strcmp(xmlnode_get_attrib(x,"from"),c->key->server) != 0 || j_strcmp(xmlnode_get_attrib(x,"to"),c->key->resource) != 0) {		    /* naughty... *click* */		    log_warn(c->d->i->id,"Received illegal dialback validation remote %s != %s or to %s != %s",c->key->server,xmlnode_get_attrib(x,"from"),c->key->resource,xmlnode_get_attrib(x,"to"));		    mio_write(m, NULL, "<stream:error><not-authorized xmlns='urn:ietf:params:xml:ns:xmpp-streams'/><text xmlns='urn:ietf:params:xml:ns:xmpp-streams' xml:lang='en'>Invalid Dialback Result</text></stream:error>", -1);		    mio_close(m);		    break;		}		/* process the returned result */		if(j_strcmp(xmlnode_get_attrib(x,"type"),"valid") == 0) {		    c->connection_state = db_succeeded;		    mio_reset(m, dialback_out_read_db, (void *)(c->d)); /* different handler now */		    md = dialback_miod_new(c->d, m); /* set up the mio wrapper */		    dialback_miod_hash(md, c->d->out_ok_db, c->key); /* this registers us to get stuff directly now */		    /* flush the queue of packets */		    dialback_out_qflush(md, c->q);		    c->q = NULL;		    /* we are connected, and can trash this now */		    dialback_out_connection_cleanup(c);		    break;		}		/* something went wrong, we were invalid? */		c->connection_state = db_failed;		if (c->connect_results != NULL) {		    char *type_attribute = pstrdup(c->connect_results->p, xmlnode_get_attrib(x, "type"));		    spool_add(c->connect_results, " (dialback result: ");		    spool_add(c->connect_results, type_attribute ? type_attribute : "no type attribute");		    spool_add(c->connect_results, ")");		}		log_alert(c->d->i->id,"We were told by %s that our sending name %s is invalid, either something went wrong on their end, we tried using that name improperly, or dns does not resolve to us",c->key->server,c->key->resource);		/* close the stream (in former times we sent a stream error, but I think we shouldn't. There is stream fault by the other entity!) */ 		mio_write(m, NULL, "</stream:stream>", -1);		mio_close(m);		break;	    }	    /* otherwise it's either a verify response, or bust! */	    if(j_strcmp(xmlnode_get_name(x),"db:verify") == 0)	    {		dialback_in_verify(c->d, x);		return;	    }	    log_warn(c->d->i->id,"Dropping connection due to illegal incoming packet on an unverified socket from %s to %s (%s): %s",c->key->resource,c->key->server,m->ip,xmlnode2str(x));	    mio_write(m, NULL, "<stream:error><not-authorized xmlns='urn:ietf:params:xml:ns:xmpp-streams'/><text xmlns='urn:ietf:params:xml:ns:xmpp-streams' xml:lang='en'>Not Allowed to send data on this socket!</text></stream:error>", -1);	    mio_close(m);	    break;	case MIO_CLOSED:	    /* add the connect error message to the list of messages for the tried hosts */	    if (c->connect_results != NULL) {		spool_add(c->connect_results, mio_connect_errmsg(m));	    }	    if(c->ip == NULL) {		dialback_out_connection_cleanup(c); /* buh bye! */	    } else {		if (c->connect_results != NULL) {		    spool_add(c->connect_results, " / ");		}		dialback_out_connect(c); /* this one failed, try another */	    }	    return;	default:	    return;    }    xmlnode_free(x);}/** * callback for walking the connecting hash tree: timing out connections that did not get * authorized in time (default is 30 seconds, can be configured with <queuetimeout/> in * the configuration file) * * @param h the hash containing all pending connections * @param key destination/source address * @param data the dboc * @param arg unused/ignored */void _dialback_out_beat_packets(xht h, const char *key, void *data, void *arg){    dboc c = (dboc)data;    dboq cur, next, last;    int now = time(NULL);    char *bounce_reason = NULL;    /* time out individual queue'd packets */    cur = c->q;    while(cur != NULL) {        if((now - cur->stamp) <= c->d->timeout_packets) {            last = cur;            cur = cur->next;            continue;        }        /* timed out sukkah! */        next = cur->next;        if(c->q == cur)            c->q = next;        else            last->next = next;	if (bounce_reason == NULL) {	    spool errmsg = spool_new(c->p);	    spool_add(errmsg, "Server connect timeout while ");	    spool_add(errmsg, dialback_out_connection_state_string(c->connection_state));	    if (c->connect_results != NULL) {		spool_add(errmsg, ": ");		spool_add(errmsg, spool_print(c->connect_results));	    }	    bounce_reason = spool_print(errmsg);	}        deliver_fail(dpacket_new(cur->x), bounce_reason ? bounce_reason : "Server Connect Timeout");        cur = next;    }}/** * start walking the connection hash tree, to see if connections dig not get authorizsed in time * * @param db the dialback instance * @return allways r_DONE */result dialback_out_beat_packets(void *arg){    db d = (db)arg;    xhash_walk(d->out_connecting,_dialback_out_beat_packets,NULL);    return r_DONE;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -