jabberd2
2.2.16
|
00001 /* 00002 * jabberd - Jabber Open Source Server 00003 * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney, 00004 * Ryan Eatmon, Robert Norris 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA 00019 */ 00020 00021 #include "s2s.h" 00022 00024 int s2s_router_sx_callback(sx_t s, sx_event_t e, void *data, void *arg) { 00025 s2s_t s2s = (s2s_t) arg; 00026 sx_buf_t buf = (sx_buf_t) data; 00027 sx_error_t *sxe; 00028 nad_t nad; 00029 int len, ns, elem, attr, i; 00030 pkt_t pkt; 00031 00032 switch(e) { 00033 case event_WANT_READ: 00034 log_debug(ZONE, "want read"); 00035 mio_read(s2s->mio, s2s->fd); 00036 break; 00037 00038 case event_WANT_WRITE: 00039 log_debug(ZONE, "want write"); 00040 mio_write(s2s->mio, s2s->fd); 00041 break; 00042 00043 case event_READ: 00044 log_debug(ZONE, "reading from %d", s2s->fd->fd); 00045 00046 /* do the read */ 00047 len = recv(s2s->fd->fd, buf->data, buf->len, 0); 00048 00049 if(len < 0) { 00050 if(MIO_WOULDBLOCK) { 00051 buf->len = 0; 00052 return 0; 00053 } 00054 00055 log_write(s2s->log, LOG_NOTICE, "[%d] [router] read error: %s (%d)", s2s->fd->fd, MIO_STRERROR(MIO_ERROR), MIO_ERROR); 00056 00057 sx_kill(s); 00058 00059 return -1; 00060 } 00061 00062 else if(len == 0) { 00063 /* they went away */ 00064 sx_kill(s); 00065 00066 return -1; 00067 } 00068 00069 log_debug(ZONE, "read %d bytes", len); 00070 00071 buf->len = len; 00072 00073 return len; 00074 00075 case event_WRITE: 00076 log_debug(ZONE, "writing to %d", s2s->fd->fd); 00077 00078 len = send(s2s->fd->fd, buf->data, buf->len, 0); 00079 if(len >= 0) { 00080 log_debug(ZONE, "%d bytes written", len); 00081 return len; 00082 } 00083 00084 if(MIO_WOULDBLOCK) 00085 return 0; 00086 00087 log_write(s2s->log, LOG_NOTICE, "[%d] [router] write error: %s (%d)", s2s->fd->fd, MIO_STRERROR(MIO_ERROR), MIO_ERROR); 00088 00089 sx_kill(s); 00090 00091 return -1; 00092 00093 case event_ERROR: 00094 sxe = (sx_error_t *) data; 00095 log_write(s2s->log, LOG_NOTICE, "error from router: %s (%s)", sxe->generic, sxe->specific); 00096 00097 if(sxe->code == SX_ERR_AUTH) 00098 sx_close(s); 00099 00100 break; 00101 00102 case event_STREAM: 00103 break; 00104 00105 case event_OPEN: 00106 log_write(s2s->log, LOG_NOTICE, "connection to router established"); 00107 00108 /* set connection attempts counter */ 00109 s2s->retry_left = s2s->retry_lost; 00110 00111 nad = nad_new(); 00112 ns = nad_add_namespace(nad, uri_COMPONENT, NULL); 00113 nad_append_elem(nad, ns, "bind", 0); 00114 nad_append_attr(nad, -1, "name", s2s->id); 00115 if(s2s->router_default) 00116 nad_append_elem(nad, ns, "default", 1); 00117 00118 log_debug(ZONE, "requesting component bind for '%s'", s2s->id); 00119 00120 sx_nad_write(s2s->router, nad); 00121 00122 break; 00123 00124 case event_PACKET: 00125 nad = (nad_t) data; 00126 00127 /* drop unqualified packets */ 00128 if(NAD_ENS(nad, 0) < 0) { 00129 nad_free(nad); 00130 return 0; 00131 } 00132 00133 /* watch for the features packet */ 00134 if(s->state == state_STREAM) { 00135 if(NAD_NURI_L(nad, NAD_ENS(nad, 0)) != strlen(uri_STREAMS) || strncmp(uri_STREAMS, NAD_NURI(nad, NAD_ENS(nad, 0)), strlen(uri_STREAMS)) != 0 || NAD_ENAME_L(nad, 0) != 8 || strncmp("features", NAD_ENAME(nad, 0), 8) != 0) { 00136 log_debug(ZONE, "got a non-features packet on an unauth'd stream, dropping"); 00137 nad_free(nad); 00138 return 0; 00139 } 00140 00141 #ifdef HAVE_SSL 00142 /* starttls if we can */ 00143 if(s2s->sx_ssl != NULL && s2s->router_pemfile != NULL && s->ssf == 0) { 00144 ns = nad_find_scoped_namespace(nad, uri_TLS, NULL); 00145 if(ns >= 0) { 00146 elem = nad_find_elem(nad, 0, ns, "starttls", 1); 00147 if(elem >= 0) { 00148 if(sx_ssl_client_starttls(s2s->sx_ssl, s, s2s->router_pemfile) == 0) { 00149 nad_free(nad); 00150 return 0; 00151 } 00152 log_write(s2s->log, LOG_NOTICE, "unable to establish encrypted session with router"); 00153 } 00154 } 00155 } 00156 #endif 00157 00158 /* !!! pull the list of mechanisms, and choose the best one. 00159 * if there isn't an appropriate one, error and bail */ 00160 00161 /* authenticate */ 00162 sx_sasl_auth(s2s->sx_sasl, s, "jabberd-router", "DIGEST-MD5", s2s->router_user, s2s->router_pass); 00163 00164 nad_free(nad); 00165 return 0; 00166 } 00167 00168 /* watch for the bind response */ 00169 if(s->state == state_OPEN && !s2s->online) { 00170 if(NAD_NURI_L(nad, NAD_ENS(nad, 0)) != strlen(uri_COMPONENT) || strncmp(uri_COMPONENT, NAD_NURI(nad, NAD_ENS(nad, 0)), strlen(uri_COMPONENT)) != 0 || NAD_ENAME_L(nad, 0) != 4 || strncmp("bind", NAD_ENAME(nad, 0), 4)) { 00171 log_debug(ZONE, "got a packet from router, but we're not online, dropping"); 00172 nad_free(nad); 00173 return 0; 00174 } 00175 00176 /* catch errors */ 00177 attr = nad_find_attr(nad, 0, -1, "error", NULL); 00178 if(attr >= 0) { 00179 log_write(s2s->log, LOG_NOTICE, "router refused bind request (%.*s)", NAD_AVAL_L(nad, attr), NAD_AVAL(nad, attr)); 00180 exit(1); 00181 } 00182 00183 log_debug(ZONE, "coming online"); 00184 00185 /* if we're coming online for the first time, setup listening sockets */ 00186 if(s2s->server_fd == 0) { 00187 if(s2s->local_port != 0) { 00188 s2s->server_fd = mio_listen(s2s->mio, s2s->local_port, s2s->local_ip, in_mio_callback, (void *) s2s); 00189 if(s2s->server_fd == NULL) { 00190 log_write(s2s->log, LOG_ERR, "[%s, port=%d] failed to listen", s2s->local_ip, s2s->local_port); 00191 exit(1); 00192 } else 00193 log_write(s2s->log, LOG_NOTICE, "[%s, port=%d] listening for connections", s2s->local_ip, s2s->local_port); 00194 } 00195 } 00196 00197 /* we're online */ 00198 s2s->online = s2s->started = 1; 00199 log_write(s2s->log, LOG_NOTICE, "ready for connections", s2s->id); 00200 00201 nad_free(nad); 00202 return 0; 00203 } 00204 00205 log_debug(ZONE, "got a packet"); 00206 00207 /* sanity checks */ 00208 if(NAD_NURI_L(nad, NAD_ENS(nad, 0)) != strlen(uri_COMPONENT) || strncmp(uri_COMPONENT, NAD_NURI(nad, NAD_ENS(nad, 0)), strlen(uri_COMPONENT)) != 0) { 00209 log_debug(ZONE, "unknown namespace, dropping packet"); 00210 nad_free(nad); 00211 return 0; 00212 } 00213 00214 if(NAD_ENAME_L(nad, 0) != 5 || strncmp("route", NAD_ENAME(nad, 0), 5) != 0) { 00215 log_debug(ZONE, "dropping non-route packet"); 00216 nad_free(nad); 00217 return 0; 00218 } 00219 00220 if(nad_find_attr(nad, 0, -1, "type", NULL) >= 0) { 00221 log_debug(ZONE, "dropping non-unicast packet"); 00222 nad_free(nad); 00223 return 0; 00224 } 00225 00226 /* packets to us */ 00227 attr = nad_find_attr(nad, 0, -1, "to", NULL); 00228 if(NAD_AVAL_L(nad, attr) == strlen(s2s->id) && strncmp(s2s->id, NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr)) == 0) { 00229 log_debug(ZONE, "dropping unknown or invalid packet for s2s component proper"); 00230 nad_free(nad); 00231 00232 return 0; 00233 } 00234 00235 /* mangle error packet to create bounce */ 00236 if((attr = nad_find_attr(nad, 0, -1, "error", NULL)) >= 0) { 00237 log_debug(ZONE, "bouncing error packet"); 00238 elem = stanza_err_REMOTE_SERVER_NOT_FOUND; 00239 if(attr >= 0) { 00240 for(i=0; _stanza_errors[i].code != NULL; i++) 00241 if(strncmp(_stanza_errors[i].code, NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr)) == 0) { 00242 elem = stanza_err_BAD_REQUEST + i; 00243 break; 00244 } 00245 } 00246 stanza_tofrom(stanza_tofrom(stanza_error(nad, 1, elem), 1), 0); 00247 if( (elem = nad_find_attr(nad, 1, -1, "to", NULL)) >= 0 ) 00248 nad_set_attr(nad, 0, -1, "to", NAD_AVAL(nad, elem), NAD_AVAL_L(nad, elem)); 00249 } 00250 00251 /* new packet */ 00252 pkt = (pkt_t) calloc(1, sizeof(struct pkt_st)); 00253 00254 pkt->nad = nad; 00255 00256 if((attr = nad_find_attr(pkt->nad, 1, -1, "from", NULL)) >= 0 && NAD_AVAL_L(pkt->nad, attr) > 0) 00257 pkt->from = jid_new(NAD_AVAL(pkt->nad, attr), NAD_AVAL_L(pkt->nad, attr)); 00258 else { 00259 attr = nad_find_attr(nad, 0, -1, "from", NULL); 00260 pkt->from = jid_new(NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr)); 00261 } 00262 00263 if((attr = nad_find_attr(pkt->nad, 1, -1, "to", NULL)) >= 0 && NAD_AVAL_L(pkt->nad, attr) > 0) 00264 pkt->to = jid_new(NAD_AVAL(pkt->nad, attr), NAD_AVAL_L(pkt->nad, attr)); 00265 else { 00266 attr = nad_find_attr(nad, 0, -1, "to", NULL); 00267 pkt->to = jid_new(NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr)); 00268 } 00269 00270 /* change the packet so it looks like it came to us, so the router won't reject it if we bounce it later */ 00271 nad_set_attr(nad, 0, -1, "to", s2s->id, 0); 00272 00273 /* flag dialback */ 00274 if(NAD_NURI_L(pkt->nad, 0) == uri_DIALBACK_L && strncmp(uri_DIALBACK, NAD_NURI(pkt->nad, 0), uri_DIALBACK_L) == 0) 00275 pkt->db = 1; 00276 00277 /* send it out */ 00278 out_packet(s2s, pkt); 00279 00280 return 0; 00281 00282 case event_CLOSED: 00283 mio_close(s2s->mio, s2s->fd); 00284 s2s->fd = NULL; 00285 return -1; 00286 } 00287 00288 return 0; 00289 } 00290 00291 int s2s_router_mio_callback(mio_t m, mio_action_t a, mio_fd_t fd, void *data, void *arg) { 00292 s2s_t s2s = (s2s_t) arg; 00293 int nbytes; 00294 00295 switch(a) { 00296 case action_READ: 00297 log_debug(ZONE, "read action on fd %d", fd->fd); 00298 00299 ioctl(fd->fd, FIONREAD, &nbytes); 00300 if(nbytes == 0) { 00301 sx_kill(s2s->router); 00302 return 0; 00303 } 00304 00305 return sx_can_read(s2s->router); 00306 00307 case action_WRITE: 00308 log_debug(ZONE, "write action on fd %d", fd->fd); 00309 return sx_can_write(s2s->router); 00310 00311 case action_CLOSE: 00312 log_debug(ZONE, "close action on fd %d", fd->fd); 00313 log_write(s2s->log, LOG_NOTICE, "connection to router closed"); 00314 00315 s2s_lost_router = 1; 00316 00317 /* we're offline */ 00318 s2s->online = 0; 00319 00320 break; 00321 00322 case action_ACCEPT: 00323 break; 00324 } 00325 00326 return 0; 00327 }