📄 dialback.c
字号:
/* -------------------------------------------------------------------------- * * License * * The contents of this file are subject to the Jabber Open Source License * Version 1.0 (the "JOSL"). You may not copy or use this file, in either * source code or executable form, except in compliance with the JOSL. You * may obtain a copy of the JOSL at http://www.jabber.org/ or at * http://www.opensource.org/. * * Software distributed under the JOSL is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the JOSL * for the specific language governing rights and limitations under the * JOSL. * * Copyrights * * Portions created by or assigned to Jabber.com, Inc. are * Copyright (c) 1999-2002 Jabber.com, Inc. All Rights Reserved. Contact * information for Jabber.com, Inc. is available at http://www.jabber.com/. * * Portions Copyright (c) 1998-1999 Jeremie Miller. * * Acknowledgements * * Special thanks to the Jabber Open Source Contributors for their * suggestions and support of Jabber. * * Alternatively, the contents of this file may be used under the terms of the * GNU General Public License Version 2 or later (the "GPL"), in which case * the provisions of the GPL are applicable instead of those above. If you * wish to allow use of your version of this file only under the terms of the * GPL and not to allow others to use your version of this file under the JOSL, * indicate your decision by deleting the provisions above and replace them * with the notice and other provisions required by the GPL. If you do not * delete the provisions above, a recipient may use your version of this file * under either the JOSL or the GPL. * * * --------------------------------------------------------------------------*//** * @file dialback.c * @brief main file of the dialback component implementing server to server connections * * This is the main file of the dialback component (module) of the Jabber server. * * The dialback protocol is documented in XMPP-core. This module only supports * identity verification using dialback, SASL is not supported. *//*DIALBACK (see XMPP core for a detailed description of this protocol):A->B A: <db:result to=B from=A>...</db:result> B->A B: <db:verify to=A from=B id=asdf>...</db:verify> A: <db:verify type="valid" to=B from=A id=asdf/>A->B B: <db:result type="valid" to=A from=B/>*/#include "dialback.h"/** * generate a random string (not thead-safe) * * This function generates a random ASCII string. * * @returns pointer to a string with 40 characters of random data */char *dialback_randstr(void){ static char ret[41]; sprintf(ret,"%d",rand()); shahash_r(ret,ret); return ret;}/** * convenience function to generate your dialback key (not thread-safe) * * @todo we don't use our own hostname to generate the dialback key, but xmpp-core * requires that we use both end's hostname to generate the key * * @param p the memory pool used * @param secret our dialback secret * @param to the destination of the stream * @param challenge the stream ID that should be verified * @return the dialback key */char *dialback_merlin(pool p, char *secret, char *to, char *challenge){ static char res[41]; shahash_r(secret, res); shahash_r(spools(p, res, to, p), res); shahash_r(spools(p, res, challenge, p), res); log_debug2(ZONE, LOGT_AUTH, "merlin casts his spell(%s+%s+%s) %s",secret,to,challenge,res); return res;}/** * write to a managed I/O connection and update the idle time values * * @param md structure holding the mio handle and the elements to keep track of idle time * @param x the xmlnode that should be written to the connection */void dialback_miod_write(miod md, xmlnode x){ md->count++; md->last = time(NULL); mio_write(md->m, x, NULL, -1);}/** * process a packet that has been read from a managed I/O connection and update the idle time values * * @param md structure holding the elements to keep track of idle time (and other elements) * @param x the xmlnode that has been read from the connection */void dialback_miod_read(miod md, xmlnode x){ jpacket jp = jpacket_new(x); /* only accept valid jpackets! */ if(jp == NULL) { log_warn(md->d->i->id, "dropping invalid packet from server: %s",xmlnode2str(x)); xmlnode_free(x); return; } /* send it on! */ md->count++; md->last = time(NULL); deliver(dpacket_new(x),md->d->i);}/** * create a new wrapper around a managed I/O connection to be able to keep track about idle connections and the state of the dialback * * @param d structure that holds the context of the dialback component instance * @param m the managed I/O connection * @return pointer to the allocated miod structure */miod dialback_miod_new(db d, mio m){ miod md; md = pmalloco(m->p, sizeof(_miod)); md->m = m; md->d = d; md->last = time(NULL); return md;}/** * @brief little wrapper to keep our hash tables in check * * This structure is used to pass everything that is needed to the _dialback_miod_hash_cleanup * callback as only one pointer can be passed to this function (it is registered as a pool cleaner function) * but we need multiple values */struct miodc{ miod md; /**< structure holding the mio handle, idle time values and valid hosts */ xht ht; /**< hash containing outgoing connections */ jid key; /**< key of this connection in the ht hash, format "destination/source" */};/** * Unregister outgoing routings, that have been routed over this connection, that is closed now. * * clean up a hashtable entry containing this miod * * This function is called if the pool assocciated with the miod is freed. * * @param arg pointer to the miodc structure */void _dialback_miod_hash_cleanup(void *arg){ struct miodc *mdc = (struct miodc *)arg; if(xhash_get(mdc->ht,jid_full(mdc->key)) == mdc->md) xhash_zap(mdc->ht,jid_full(mdc->key)); log_debug2(ZONE, LOGT_CLEANUP|LOGT_AUTH, "miod cleaning out socket %d with key %s to hash %X",mdc->md->m->fd, jid_full(mdc->key), mdc->ht); /* cool place for logging, eh? interesting way of detecting things too, *g* */ if(mdc->ht == mdc->md->d->out_ok_db){ unregister_instance(mdc->md->d->i, mdc->key->server); /* dynamic host resolution thingie */ log_record(mdc->key->server, "out", "dialback", "%d %s %s", mdc->md->count, mdc->md->m->ip, mdc->key->resource); }else if(mdc->ht == mdc->md->d->in_ok_db){ log_record(mdc->key->server, "in", "dialback", "%d %s %s", mdc->md->count, mdc->md->m->ip, mdc->key->resource); }}/** * registering a connection in the hash of outgoing connections * * @param md structure representing the outgoing connection * @param ht hash table containing all outgoing s2s connections * @param key destination with our source domain as the resource */void dialback_miod_hash(miod md, xht ht, jid key){ struct miodc *mdc; log_debug2(ZONE, LOGT_AUTH, "miod registering socket %d with key %s to hash %X",md->m->fd, jid_full(key), ht); mdc = pmalloco(md->m->p,sizeof(struct miodc)); mdc->md = md; mdc->ht = ht; mdc->key = jid_new(md->m->p,jid_full(key)); pool_cleanup(md->m->p, _dialback_miod_hash_cleanup, (void *)mdc); xhash_put(ht, jid_full(mdc->key), md); /* dns saver, only when registering on outgoing hosts dynamically */ if(ht == md->d->out_ok_db) { dialback_ip_set(md->d, key, md->m->ip); /* save the ip since it won't be going through the dnsrv anymore */ register_instance(md->d->i, key->server); }}/** * get the cached IP address for an external server * * @param d db structure which contains the context of the dialback component instance * @param host the host for which we need the IP address * @param ip the IP if the caller already knows it (conveniance parameter) * @return the IP of the external server */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -