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 "c2s.h" 00022 #include <stringprep.h> 00023 #ifdef _WIN32 00024 #include <windows.h> 00025 #define LIBRARY_DIR "." 00026 #else 00027 #include <dlfcn.h> 00028 #endif 00029 00030 /* authreg module manager */ 00031 00032 typedef struct _authreg_error_st { 00033 char *class; 00034 char *name; 00035 char *code; 00036 char *uri; 00037 } *authreg_error_t; 00038 00040 authreg_t authreg_init(c2s_t c2s, char *name) { 00041 char mod_fullpath[PATH_MAX], *modules_path; 00042 ar_module_init_fn init_fn = NULL; 00043 authreg_t ar; 00044 void *handle; 00045 00046 /* load authreg module */ 00047 modules_path = config_get_one(c2s->config, "authreg.path", 0); 00048 if (modules_path != NULL) 00049 log_write(c2s->log, LOG_NOTICE, "modules search path: %s", modules_path); 00050 else 00051 log_write(c2s->log, LOG_NOTICE, "modules search path undefined, using default: "LIBRARY_DIR); 00052 00053 log_write(c2s->log, LOG_INFO, "loading '%s' authreg module", name); 00054 #ifndef _WIN32 00055 if (modules_path != NULL) 00056 snprintf(mod_fullpath, PATH_MAX, "%s/authreg_%s.so", modules_path, name); 00057 else 00058 snprintf(mod_fullpath, PATH_MAX, "%s/authreg_%s.so", LIBRARY_DIR, name); 00059 handle = dlopen(mod_fullpath, RTLD_LAZY); 00060 if (handle != NULL) 00061 init_fn = dlsym(handle, "ar_init"); 00062 #else 00063 if (modules_path != NULL) 00064 snprintf(mod_fullpath, PATH_MAX, "%s\\authreg_%s.dll", modules_path, name); 00065 else 00066 snprintf(mod_fullpath, PATH_MAX, "authreg_%s.dll", name); 00067 handle = (void*) LoadLibrary(mod_fullpath); 00068 if (handle != NULL) 00069 init_fn = (ar_module_init_fn)GetProcAddress((HMODULE) handle, "ar_init"); 00070 #endif 00071 00072 if (handle != NULL && init_fn != NULL) { 00073 log_debug(ZONE, "preloaded module '%s' (not initialized yet)", name); 00074 } else { 00075 #ifndef _WIN32 00076 log_write(c2s->log, LOG_ERR, "failed loading authreg module '%s' (%s)", name, dlerror()); 00077 if (handle != NULL) 00078 dlclose(handle); 00079 #else 00080 log_write(c2s->log, LOG_ERR, "failed loading authreg module '%s' (errcode: %x)", name, GetLastError()); 00081 if (handle != NULL) 00082 FreeLibrary((HMODULE) handle); 00083 #endif 00084 return NULL; 00085 } 00086 00087 /* make a new one */ 00088 ar = (authreg_t) calloc(1, sizeof(struct authreg_st)); 00089 00090 ar->c2s = c2s; 00091 00092 /* call the initialiser */ 00093 if((init_fn)(ar) != 0) 00094 { 00095 log_write(c2s->log, LOG_ERR, "failed to initialize auth module '%s'", name); 00096 authreg_free(ar); 00097 return NULL; 00098 } 00099 00100 /* we need user_exists(), at the very least */ 00101 if(ar->user_exists == NULL) 00102 { 00103 log_write(c2s->log, LOG_ERR, "auth module '%s' has no check for user existence", name); 00104 authreg_free(ar); 00105 return NULL; 00106 } 00107 00108 /* its good */ 00109 log_write(c2s->log, LOG_NOTICE, "initialized auth module '%s'", name); 00110 00111 return ar; 00112 } 00113 00115 void authreg_free(authreg_t ar) { 00116 if (ar) { 00117 if(ar->free != NULL) (ar->free)(ar); 00118 free(ar); 00119 } 00120 } 00121 00123 inline static void _authreg_auth_log(c2s_t c2s, sess_t sess, char *method, char *username, char *resource, int success) { 00124 log_write(c2s->log, LOG_NOTICE, "[%d] %s authentication %s: %s@%s/%s %s:%d%s%s", 00125 sess->s->tag, method, success ? "succeeded" : "failed", 00126 username, sess->host->realm, resource, 00127 sess->s->ip, sess->s->port, 00128 sess->s->ssf ? " TLS" : "", sess->s->compressed ? " ZLIB" : "" 00129 ); 00130 } 00131 00133 static void _authreg_auth_get(c2s_t c2s, sess_t sess, nad_t nad) { 00134 int ns, elem, attr; 00135 char username[1024], id[128]; 00136 int ar_mechs; 00137 00138 /* can't auth if they're active */ 00139 if(sess->active) { 00140 sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_NOT_ALLOWED), 0)); 00141 return; 00142 } 00143 00144 /* sort out the username */ 00145 ns = nad_find_scoped_namespace(nad, uri_AUTH, NULL); 00146 elem = nad_find_elem(nad, 1, ns, "username", 1); 00147 if(elem < 0) 00148 { 00149 log_debug(ZONE, "auth get with no username, bouncing it"); 00150 00151 sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_BAD_REQUEST), 0)); 00152 00153 return; 00154 } 00155 00156 snprintf(username, 1024, "%.*s", NAD_CDATA_L(nad, elem), NAD_CDATA(nad, elem)); 00157 if(stringprep_xmpp_nodeprep(username, 1024) != 0) { 00158 log_debug(ZONE, "auth get username failed nodeprep, bouncing it"); 00159 sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_JID_MALFORMED), 0)); 00160 return; 00161 } 00162 00163 ar_mechs = c2s->ar_mechanisms; 00164 if (sess->s->ssf>0) 00165 ar_mechs = ar_mechs | c2s->ar_ssl_mechanisms; 00166 00167 /* no point going on if we have no mechanisms */ 00168 if(!(ar_mechs & (AR_MECH_TRAD_PLAIN | AR_MECH_TRAD_DIGEST))) { 00169 sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_FORBIDDEN), 0)); 00170 return; 00171 } 00172 00173 /* do we have the user? */ 00174 if((c2s->ar->user_exists)(c2s->ar, username, sess->host->realm) == 0) { 00175 sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_OLD_UNAUTH), 0)); 00176 return; 00177 } 00178 00179 /* extract the id */ 00180 attr = nad_find_attr(nad, 0, -1, "id", NULL); 00181 if(attr >= 0) 00182 snprintf(id, 128, "%.*s", NAD_AVAL_L(nad, attr), NAD_AVAL(nad, attr)); 00183 00184 nad_free(nad); 00185 00186 /* build a result packet */ 00187 nad = nad_new(); 00188 00189 ns = nad_add_namespace(nad, uri_CLIENT, NULL); 00190 00191 nad_append_elem(nad, ns, "iq", 0); 00192 nad_append_attr(nad, -1, "type", "result"); 00193 00194 if(attr >= 0) 00195 nad_append_attr(nad, -1, "id", id); 00196 00197 ns = nad_add_namespace(nad, uri_AUTH, NULL); 00198 nad_append_elem(nad, ns, "query", 1); 00199 00200 nad_append_elem(nad, ns, "username", 2); 00201 nad_append_cdata(nad, username, strlen(username), 3); 00202 00203 nad_append_elem(nad, ns, "resource", 2); 00204 00205 /* fill out the packet with available auth mechanisms */ 00206 if(ar_mechs & AR_MECH_TRAD_PLAIN && (c2s->ar->get_password != NULL || c2s->ar->check_password != NULL)) 00207 nad_append_elem(nad, ns, "password", 2); 00208 00209 if(ar_mechs & AR_MECH_TRAD_DIGEST && c2s->ar->get_password != NULL) 00210 nad_append_elem(nad, ns, "digest", 2); 00211 00212 /* give it back to the client */ 00213 sx_nad_write(sess->s, nad); 00214 00215 return; 00216 } 00217 00219 static void _authreg_auth_set(c2s_t c2s, sess_t sess, nad_t nad) { 00220 int ns, elem, attr, authd = 0; 00221 char username[1024], resource[1024], str[1024], hash[280]; 00222 int ar_mechs; 00223 00224 /* can't auth if they're active */ 00225 if(sess->active) { 00226 sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_NOT_ALLOWED), 0)); 00227 return; 00228 } 00229 00230 ns = nad_find_scoped_namespace(nad, uri_AUTH, NULL); 00231 00232 /* sort out the username */ 00233 elem = nad_find_elem(nad, 1, ns, "username", 1); 00234 if(elem < 0) 00235 { 00236 log_debug(ZONE, "auth set with no username, bouncing it"); 00237 00238 sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_BAD_REQUEST), 0)); 00239 00240 return; 00241 } 00242 00243 snprintf(username, 1024, "%.*s", NAD_CDATA_L(nad, elem), NAD_CDATA(nad, elem)); 00244 if(stringprep_xmpp_nodeprep(username, 1024) != 0) { 00245 log_debug(ZONE, "auth set username failed nodeprep, bouncing it"); 00246 sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_JID_MALFORMED), 0)); 00247 return; 00248 } 00249 00250 /* make sure we have the resource */ 00251 elem = nad_find_elem(nad, 1, ns, "resource", 1); 00252 if(elem < 0) 00253 { 00254 log_debug(ZONE, "auth set with no resource, bouncing it"); 00255 00256 sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_BAD_REQUEST), 0)); 00257 00258 return; 00259 } 00260 00261 snprintf(resource, 1024, "%.*s", NAD_CDATA_L(nad, elem), NAD_CDATA(nad, elem)); 00262 if(stringprep_xmpp_resourceprep(resource, 1024) != 0) { 00263 log_debug(ZONE, "auth set resource failed resourceprep, bouncing it"); 00264 sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_JID_MALFORMED), 0)); 00265 return; 00266 } 00267 00268 ar_mechs = c2s->ar_mechanisms; 00269 if (sess->s->ssf > 0) 00270 ar_mechs = ar_mechs | c2s->ar_ssl_mechanisms; 00271 00272 /* no point going on if we have no mechanisms */ 00273 if(!(ar_mechs & (AR_MECH_TRAD_PLAIN | AR_MECH_TRAD_DIGEST))) { 00274 sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_FORBIDDEN), 0)); 00275 return; 00276 } 00277 00278 /* do we have the user? */ 00279 if((c2s->ar->user_exists)(c2s->ar, username, sess->host->realm) == 0) { 00280 sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_OLD_UNAUTH), 0)); 00281 return; 00282 } 00283 00284 /* digest auth */ 00285 if(!authd && ar_mechs & AR_MECH_TRAD_DIGEST && c2s->ar->get_password != NULL) 00286 { 00287 elem = nad_find_elem(nad, 1, ns, "digest", 1); 00288 if(elem >= 0) 00289 { 00290 if((c2s->ar->get_password)(c2s->ar, username, sess->host->realm, str) == 0) 00291 { 00292 snprintf(hash, 280, "%s%s", sess->s->id, str); 00293 shahash_r(hash, hash); 00294 00295 if(strlen(hash) == NAD_CDATA_L(nad, elem) && strncmp(hash, NAD_CDATA(nad, elem), NAD_CDATA_L(nad, elem)) == 0) 00296 { 00297 log_debug(ZONE, "digest auth succeeded"); 00298 authd = 1; 00299 _authreg_auth_log(c2s, sess, "traditional.digest", username, resource, TRUE); 00300 } 00301 } 00302 } 00303 } 00304 00305 /* plaintext auth (compare) */ 00306 if(!authd && ar_mechs & AR_MECH_TRAD_PLAIN && c2s->ar->get_password != NULL) 00307 { 00308 elem = nad_find_elem(nad, 1, ns, "password", 1); 00309 if(elem >= 0) 00310 { 00311 if((c2s->ar->get_password)(c2s->ar, username, sess->host->realm, str) == 0 && strlen(str) == NAD_CDATA_L(nad, elem) && strncmp(str, NAD_CDATA(nad, elem), NAD_CDATA_L(nad, elem)) == 0) 00312 { 00313 log_debug(ZONE, "plaintext auth (compare) succeeded"); 00314 authd = 1; 00315 _authreg_auth_log(c2s, sess, "traditional.plain(compare)", username, resource, TRUE); 00316 } 00317 } 00318 } 00319 00320 /* plaintext auth (check) */ 00321 if(!authd && ar_mechs & AR_MECH_TRAD_PLAIN && c2s->ar->check_password != NULL) 00322 { 00323 elem = nad_find_elem(nad, 1, ns, "password", 1); 00324 if(elem >= 0) 00325 { 00326 snprintf(str, 1024, "%.*s", NAD_CDATA_L(nad, elem), NAD_CDATA(nad, elem)); 00327 if((c2s->ar->check_password)(c2s->ar, username, sess->host->realm, str) == 0) 00328 { 00329 log_debug(ZONE, "plaintext auth (check) succeded"); 00330 authd = 1; 00331 _authreg_auth_log(c2s, sess, "traditional.plain", username, resource, TRUE); 00332 } 00333 } 00334 } 00335 00336 /* now, are they authenticated? */ 00337 if(authd) 00338 { 00339 /* create new bound jid holder */ 00340 if(sess->resources == NULL) { 00341 sess->resources = (bres_t) calloc(1, sizeof(struct bres_st)); 00342 } 00343 00344 /* our local id */ 00345 sprintf(sess->resources->c2s_id, "%d", sess->s->tag); 00346 00347 /* the full user jid for this session */ 00348 sess->resources->jid = jid_new(sess->s->req_to, -1); 00349 jid_reset_components(sess->resources->jid, username, sess->resources->jid->domain, resource); 00350 00351 log_write(sess->c2s->log, LOG_NOTICE, "[%d] requesting session: jid=%s", sess->s->tag, jid_full(sess->resources->jid)); 00352 00353 /* build a result packet, we'll send this back to the client after we have a session for them */ 00354 sess->result = nad_new(); 00355 00356 ns = nad_add_namespace(sess->result, uri_CLIENT, NULL); 00357 00358 nad_append_elem(sess->result, ns, "iq", 0); 00359 nad_set_attr(sess->result, 0, -1, "type", "result", 6); 00360 00361 attr = nad_find_attr(nad, 0, -1, "id", NULL); 00362 if(attr >= 0) 00363 nad_set_attr(sess->result, 0, -1, "id", NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr)); 00364 00365 /* start a session with the sm */ 00366 sm_start(sess, sess->resources); 00367 00368 /* finished with the nad */ 00369 nad_free(nad); 00370 00371 return; 00372 } 00373 00374 _authreg_auth_log(c2s, sess, "traditional", username, resource, FALSE); 00375 00376 /* auth failed, so error */ 00377 sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_OLD_UNAUTH), 0)); 00378 00379 return; 00380 } 00381 00383 static void _authreg_register_get(c2s_t c2s, sess_t sess, nad_t nad) { 00384 int attr, ns; 00385 char id[128]; 00386 00387 /* registrations can happen if reg is enabled and we can create users and set passwords */ 00388 if(sess->active || !(c2s->ar->set_password != NULL && c2s->ar->create_user != NULL && (sess->host->ar_register_enable || sess->host->ar_register_oob))) { 00389 sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_NOT_ALLOWED), 0)); 00390 return; 00391 } 00392 00393 /* extract the id */ 00394 attr = nad_find_attr(nad, 0, -1, "id", NULL); 00395 if(attr >= 0) 00396 snprintf(id, 128, "%.*s", NAD_AVAL_L(nad, attr), NAD_AVAL(nad, attr)); 00397 00398 nad_free(nad); 00399 00400 /* build a result packet */ 00401 nad = nad_new(); 00402 00403 ns = nad_add_namespace(nad, uri_CLIENT, NULL); 00404 00405 nad_append_elem(nad, ns, "iq", 0); 00406 nad_append_attr(nad, -1, "type", "result"); 00407 00408 if(attr >= 0) 00409 nad_append_attr(nad, -1, "id", id); 00410 00411 ns = nad_add_namespace(nad, uri_REGISTER, NULL); 00412 nad_append_elem(nad, ns, "query", 1); 00413 00414 nad_append_elem(nad, ns, "instructions", 2); 00415 nad_append_cdata(nad, sess->host->ar_register_instructions, strlen(sess->host->ar_register_instructions), 3); 00416 00417 if(sess->host->ar_register_enable) { 00418 nad_append_elem(nad, ns, "username", 2); 00419 nad_append_elem(nad, ns, "password", 2); 00420 } 00421 00422 if(sess->host->ar_register_oob) { 00423 int ns = nad_add_namespace(nad, uri_OOB, NULL); 00424 nad_append_elem(nad, ns, "x", 2); 00425 nad_append_elem(nad, ns, "url", 3); 00426 nad_append_cdata(nad, sess->host->ar_register_oob, strlen(sess->host->ar_register_oob), 4); 00427 } 00428 00429 /* give it back to the client */ 00430 sx_nad_write(sess->s, nad); 00431 } 00432 00434 static void _authreg_register_set(c2s_t c2s, sess_t sess, nad_t nad) 00435 { 00436 int ns = 0, elem, attr; 00437 char username[1024], password[1024]; 00438 00439 /* if we're not configured for registration (or pw changes), or we can't set passwords, fail outright */ 00440 if(!(sess->host->ar_register_enable || sess->host->ar_register_password) || c2s->ar->set_password == NULL) { 00441 sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_NOT_ALLOWED), 0)); 00442 return; 00443 } 00444 00445 ns = nad_find_scoped_namespace(nad, uri_REGISTER, NULL); 00446 00447 /* removals */ 00448 if(sess->active && nad_find_elem(nad, 1, ns, "remove", 1) >= 0) { 00449 /* only if full reg is enabled */ 00450 if(!sess->host->ar_register_enable) { 00451 sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_NOT_ALLOWED), 0)); 00452 return; 00453 } 00454 00455 log_debug(ZONE, "user remove requested"); 00456 00457 /* make sure we can delete them */ 00458 if(c2s->ar->delete_user == NULL) { 00459 sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_NOT_ALLOWED), 0)); 00460 return; 00461 } 00462 00463 /* otherwise, delete them */ 00464 if((c2s->ar->delete_user)(c2s->ar, sess->resources->jid->node, sess->host->realm) != 0) { 00465 log_debug(ZONE, "user delete failed"); 00466 sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_INTERNAL_SERVER_ERROR), 0)); 00467 return; 00468 } 00469 00470 log_write(c2s->log, LOG_NOTICE, "[%d] deleted user: user=%s; realm=%s", sess->s->tag, sess->resources->jid->node, sess->host->realm); 00471 00472 log_write(c2s->log, LOG_NOTICE, "[%d] registration remove succeeded, requesting user deletion: jid=%s", sess->s->tag, jid_user(sess->resources->jid)); 00473 00474 /* make a result nad */ 00475 sess->result = nad_new(); 00476 00477 ns = nad_add_namespace(sess->result, uri_CLIENT, NULL); 00478 00479 nad_append_elem(sess->result, ns, "iq", 0); 00480 nad_set_attr(sess->result, 0, -1, "type", "result", 6); 00481 00482 /* extract the id */ 00483 attr = nad_find_attr(nad, 0, -1, "id", NULL); 00484 if(attr >= 0) 00485 nad_set_attr(sess->result, 0, -1, "id", NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr)); 00486 00487 nad_free(nad); 00488 00489 sx_nad_write(sess->s, sess->result); 00490 sess->result = NULL; 00491 00492 /* get the sm to delete them (it will force their sessions to end) */ 00493 sm_delete(sess, sess->resources); 00494 00495 return; 00496 } 00497 00498 /* username is required */ 00499 elem = nad_find_elem(nad, 1, ns, "username", 1); 00500 if(elem < 0) 00501 { 00502 log_debug(ZONE, "register set with no username, bouncing it"); 00503 sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_BAD_REQUEST), 0)); 00504 return; 00505 } 00506 00507 snprintf(username, 1024, "%.*s", NAD_CDATA_L(nad, elem), NAD_CDATA(nad, elem)); 00508 if(stringprep_xmpp_nodeprep(username, 1024) != 0) { 00509 log_debug(ZONE, "register set username failed nodeprep, bouncing it"); 00510 sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_JID_MALFORMED), 0)); 00511 return; 00512 } 00513 00514 elem = nad_find_elem(nad, 1, ns, "password", 1); 00515 if(elem < 0) 00516 { 00517 log_debug(ZONE, "register set with no password, bouncing it"); 00518 sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_BAD_REQUEST), 0)); 00519 return; 00520 } 00521 00522 /* if they're already auth'd, its a password change */ 00523 if(sess->active) 00524 { 00525 /* confirm that the username matches their auth id */ 00526 if(strcmp(username, sess->resources->jid->node) != 0) 00527 { 00528 log_debug(ZONE, "%s is trying to change password for %s, bouncing it", jid_full(sess->resources->jid), username); 00529 sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_OLD_UNAUTH), 0)); 00530 return; 00531 } 00532 } 00533 00534 /* can't go on if we're not doing full reg */ 00535 else if(!sess->host->ar_register_enable) { 00536 sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_NOT_ALLOWED), 0)); 00537 return; 00538 } 00539 00540 /* if they exist, bounce */ 00541 else if((c2s->ar->user_exists)(c2s->ar, username, sess->host->realm)) 00542 { 00543 log_debug(ZONE, "attempt to register %s, but they already exist", username); 00544 sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_CONFLICT), 0)); 00545 return; 00546 } 00547 00548 /* make sure we can create them */ 00549 else if(c2s->ar->create_user == NULL) 00550 { 00551 sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_NOT_ALLOWED), 0)); 00552 return; 00553 } 00554 00555 /* otherwise, create them */ 00556 else if((c2s->ar->create_user)(c2s->ar, username, sess->host->realm) != 0) 00557 { 00558 log_debug(ZONE, "user create failed"); 00559 sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_INTERNAL_SERVER_ERROR), 0)); 00560 return; 00561 } 00562 00563 else 00564 log_write(c2s->log, LOG_NOTICE, "[%d] created user: user=%s; realm=%s", sess->s->tag, username, sess->host->realm); 00565 00566 /* extract the password */ 00567 snprintf(password, 257, "%.*s", NAD_CDATA_L(nad, elem), NAD_CDATA(nad, elem)); 00568 00569 /* change it */ 00570 if((c2s->ar->set_password)(c2s->ar, username, sess->host->realm, password) != 0) 00571 { 00572 log_debug(ZONE, "password store failed"); 00573 sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_INTERNAL_SERVER_ERROR), 0)); 00574 return; 00575 } 00576 00577 log_debug(ZONE, "updated auth creds for %s", username); 00578 00579 /* make a result nad */ 00580 sess->result = nad_new(); 00581 00582 ns = nad_add_namespace(sess->result, uri_CLIENT, NULL); 00583 00584 nad_append_elem(sess->result, ns, "iq", 0); 00585 nad_set_attr(sess->result, 0, -1, "type", "result", 6); 00586 00587 /* extract the id */ 00588 attr = nad_find_attr(nad, 0, -1, "id", NULL); 00589 if(attr >= 0) 00590 nad_set_attr(sess->result, 0, -1, "id", NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr)); 00591 00592 /* if they're active, then this was just a password change, and we're done */ 00593 if(sess->active) { 00594 log_write(c2s->log, LOG_NOTICE, "[%d] password changed: jid=%s", sess->s->tag, jid_user(sess->resources->jid)); 00595 sx_nad_write(sess->s, sess->result); 00596 sess->result = NULL; 00597 return; 00598 } 00599 00600 /* create new bound jid holder */ 00601 if(sess->resources == NULL) { 00602 sess->resources = (bres_t) calloc(1, sizeof(struct bres_st)); 00603 } 00604 00605 /* our local id */ 00606 sprintf(sess->resources->c2s_id, "%d", sess->s->tag); 00607 00608 /* the user jid for this transaction */ 00609 sess->resources->jid = jid_new(sess->s->req_to, -1); 00610 jid_reset_components(sess->resources->jid, username, sess->resources->jid->domain, sess->resources->jid->resource); 00611 00612 log_write(c2s->log, LOG_NOTICE, "[%d] registration succeeded, requesting user creation: jid=%s", sess->s->tag, jid_user(sess->resources->jid)); 00613 00614 /* get the sm to create them */ 00615 sm_create(sess, sess->resources); 00616 00617 nad_free(nad); 00618 00619 return; 00620 } 00621 00626 int authreg_process(c2s_t c2s, sess_t sess, nad_t nad) { 00627 int ns, query, type, authreg = -1, getset = -1; 00628 00629 /* need iq */ 00630 if(NAD_ENAME_L(nad, 0) != 2 || strncmp("iq", NAD_ENAME(nad, 0), 2) != 0) 00631 return 1; 00632 00633 /* only want auth or register packets */ 00634 if((ns = nad_find_scoped_namespace(nad, uri_AUTH, NULL)) >= 0 && (query = nad_find_elem(nad, 0, ns, "query", 1)) >= 0) 00635 authreg = 0; 00636 else if((ns = nad_find_scoped_namespace(nad, uri_REGISTER, NULL)) >= 0 && (query = nad_find_elem(nad, 0, ns, "query", 1)) >= 0) 00637 authreg = 1; 00638 else 00639 return 1; 00640 00641 /* if its to someone else, pass it */ 00642 if(nad_find_attr(nad, 0, -1, "to", NULL) >= 0 && nad_find_attr(nad, 0, -1, "to", sess->s->req_to) < 0) 00643 return 1; 00644 00645 /* need a type */ 00646 if((type = nad_find_attr(nad, 0, -1, "type", NULL)) < 0 || NAD_AVAL_L(nad, type) != 3) 00647 { 00648 sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_BAD_REQUEST), 0)); 00649 return 0; 00650 } 00651 00652 /* get or set? */ 00653 if(strncmp("get", NAD_AVAL(nad, type), NAD_AVAL_L(nad, type)) == 0) 00654 getset = 0; 00655 else if(strncmp("set", NAD_AVAL(nad, type), NAD_AVAL_L(nad, type)) == 0) 00656 getset = 1; 00657 else 00658 { 00659 sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_BAD_REQUEST), 0)); 00660 return 0; 00661 } 00662 00663 /* hand to the correct handler */ 00664 if(authreg == 0) { 00665 /* can't do iq:auth after sasl auth */ 00666 if(sess->sasl_authd) { 00667 sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_NOT_ALLOWED), 0)); 00668 return 0; 00669 } 00670 00671 if(getset == 0) { 00672 log_debug(ZONE, "auth get"); 00673 _authreg_auth_get(c2s, sess, nad); 00674 } else if(getset == 1) { 00675 log_debug(ZONE, "auth set"); 00676 _authreg_auth_set(c2s, sess, nad); 00677 } 00678 } 00679 00680 if(authreg == 1) { 00681 if(getset == 0) { 00682 log_debug(ZONE, "register get"); 00683 _authreg_register_get(c2s, sess, nad); 00684 } else if(getset == 1) { 00685 log_debug(ZONE, "register set"); 00686 _authreg_register_set(c2s, sess, nad); 00687 } 00688 } 00689 00690 /* handled */ 00691 return 0; 00692 }