jabberd2  2.3.6
authreg.c
Go to the documentation of this file.
1 /*
2  * jabberd - Jabber Open Source Server
3  * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney,
4  * Ryan Eatmon, Robert Norris
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA
19  */
20 
21 #include "c2s.h"
22 #include <stringprep.h>
23 #ifdef _WIN32
24  #include <windows.h>
25  #define LIBRARY_DIR "."
26 #else
27  #include <dlfcn.h>
28 #endif
29 
30 /* authreg module manager */
31 
32 typedef struct _authreg_error_st {
33  char *class;
34  char *name;
35  char *code;
36  char *uri;
38 
40 authreg_t authreg_init(c2s_t c2s, const char *name) {
41  char mod_fullpath[PATH_MAX];
42  const char *modules_path;
43  ar_module_init_fn init_fn = NULL;
44  authreg_t ar;
45  void *handle;
46 
47  /* return if already loaded */
48  ar = xhash_get(c2s->ar_modules, name);
49  if (ar) {
50  return ar->initialized ? ar : NULL;
51  }
52 
53  /* load authreg module */
54  modules_path = config_get_one(c2s->config, "authreg.path", 0);
55  if (modules_path != NULL)
56  log_write(c2s->log, LOG_NOTICE, "modules search path: %s", modules_path);
57  else
58  log_write(c2s->log, LOG_NOTICE, "modules search path undefined, using default: "LIBRARY_DIR);
59 
60  log_write(c2s->log, LOG_INFO, "loading '%s' authreg module", name);
61 #ifndef _WIN32
62  if (modules_path != NULL)
63  snprintf(mod_fullpath, PATH_MAX, "%s/authreg_%s.so", modules_path, name);
64  else
65  snprintf(mod_fullpath, PATH_MAX, "%s/authreg_%s.so", LIBRARY_DIR, name);
66  handle = dlopen(mod_fullpath, RTLD_LAZY);
67  if (handle != NULL)
68  init_fn = dlsym(handle, "ar_init");
69 #else
70  if (modules_path != NULL)
71  snprintf(mod_fullpath, PATH_MAX, "%s\\authreg_%s.dll", modules_path, name);
72  else
73  snprintf(mod_fullpath, PATH_MAX, "authreg_%s.dll", name);
74  handle = (void*) LoadLibrary(mod_fullpath);
75  if (handle != NULL)
76  init_fn = (ar_module_init_fn)GetProcAddress((HMODULE) handle, "ar_init");
77 #endif
78 
79  if (handle != NULL && init_fn != NULL) {
80  log_debug(ZONE, "preloaded module '%s' (not initialized yet)", name);
81  } else {
82 #ifndef _WIN32
83  log_write(c2s->log, LOG_ERR, "failed loading authreg module '%s' (%s)", name, dlerror());
84  if (handle != NULL)
85  dlclose(handle);
86 #else
87  log_write(c2s->log, LOG_ERR, "failed loading authreg module '%s' (errcode: %x)", name, GetLastError());
88  if (handle != NULL)
89  FreeLibrary((HMODULE) handle);
90 #endif
91  return NULL;
92  }
93 
94  /* make a new one */
95  ar = (authreg_t) pmalloco(xhash_pool(c2s->ar_modules), sizeof(struct authreg_st));
96  if(!ar) {
97  log_write(c2s->log, LOG_ERR, "cannot allocate memory for new authreg, aborting");
98  exit(1);
99  }
100 
101  ar->c2s = c2s;
102 
103  xhash_put(c2s->ar_modules, name, ar);
104 
105  /* call the initialiser */
106  if((init_fn)(ar) != 0)
107  {
108  log_write(c2s->log, LOG_ERR, "failed to initialize auth module '%s'", name);
109  authreg_free(ar);
110  return NULL;
111  }
112 
113  /* we need user_exists(), at the very least */
114  if(ar->user_exists == NULL)
115  {
116  log_write(c2s->log, LOG_ERR, "auth module '%s' has no check for user existence", name);
117  authreg_free(ar);
118  return NULL;
119  }
120 
121  /* its good */
122  ar->initialized = TRUE;
123  log_write(c2s->log, LOG_NOTICE, "initialized auth module '%s'", name);
124 
125  return ar;
126 }
127 
130  if (ar && ar->initialized) {
131  if(ar->free != NULL) (ar->free)(ar);
132  }
133 }
134 
136 inline static void _authreg_auth_log(c2s_t c2s, sess_t sess, const char *method, const char *username, const char *resource, int success) {
137  log_write(c2s->log, LOG_NOTICE, "[%d] %s authentication %s: %s@%s/%s %s:%d %s",
138  sess->s->tag, method, success ? "succeeded" : "failed",
139  username, sess->host->realm, resource,
140  sess->s->ip, sess->s->port, _sx_flags(sess->s)
141  );
142 }
143 
145 static void _authreg_auth_get(c2s_t c2s, sess_t sess, nad_t nad) {
146  int ns, elem, attr, err;
147  char username[1024], id[128];
148  int ar_mechs;
149 
150  /* can't auth if they're active */
151  if(sess->active) {
153  return;
154  }
155 
156  /* sort out the username */
157  ns = nad_find_scoped_namespace(nad, uri_AUTH, NULL);
158  elem = nad_find_elem(nad, 1, ns, "username", 1);
159  if(elem < 0)
160  {
161  log_debug(ZONE, "auth get with no username, bouncing it");
162 
164 
165  return;
166  }
167 
168  snprintf(username, 1024, "%.*s", NAD_CDATA_L(nad, elem), NAD_CDATA(nad, elem));
169  if(stringprep_xmpp_nodeprep(username, 1024) != 0) {
170  log_debug(ZONE, "auth get username failed nodeprep, bouncing it");
172  return;
173  }
174 
175  ar_mechs = c2s->ar_mechanisms;
176  if (sess->s->ssf>0)
177  ar_mechs = ar_mechs | c2s->ar_ssl_mechanisms;
178 
179  /* no point going on if we have no mechanisms */
182  return;
183  }
184 
185  /* do we have the user? */
186  if((sess->host->ar->user_exists)(sess->host->ar, sess, username, sess->host->realm) == 0) {
188  return;
189  }
190 
191  /* extract the id */
192  attr = nad_find_attr(nad, 0, -1, "id", NULL);
193  if(attr >= 0)
194  snprintf(id, 128, "%.*s", NAD_AVAL_L(nad, attr), NAD_AVAL(nad, attr));
195 
196  nad_free(nad);
197 
198  /* build a result packet */
199  nad = nad_new();
200 
201  ns = nad_add_namespace(nad, uri_CLIENT, NULL);
202 
203  nad_append_elem(nad, ns, "iq", 0);
204  nad_append_attr(nad, -1, "type", "result");
205 
206  if(attr >= 0)
207  nad_append_attr(nad, -1, "id", id);
208 
209  ns = nad_add_namespace(nad, uri_AUTH, NULL);
210  nad_append_elem(nad, ns, "query", 1);
211 
212  nad_append_elem(nad, ns, "username", 2);
213  nad_append_cdata(nad, username, strlen(username), 3);
214 
215  nad_append_elem(nad, ns, "resource", 2);
216 
217  /* fill out the packet with available auth mechanisms */
218  if(ar_mechs & AR_MECH_TRAD_PLAIN && (sess->host->ar->get_password != NULL || sess->host->ar->check_password != NULL))
219  nad_append_elem(nad, ns, "password", 2);
220 
221  if(ar_mechs & AR_MECH_TRAD_DIGEST && sess->host->ar->get_password != NULL)
222  nad_append_elem(nad, ns, "digest", 2);
223 
224  if (ar_mechs & AR_MECH_TRAD_CRAMMD5 && sess->host->ar->create_challenge != NULL) {
225  err = (sess->host->ar->create_challenge)(sess->host->ar, sess, (char *) username, sess->host->realm,
226  (char *) sess->auth_challenge, sizeof(sess->auth_challenge));
227  if (0 == err) { /* operation failed */
229  return;
230  }
231  else if (1 == err) { /* operation succeeded */
232  nad_append_elem(nad, ns, "crammd5", 2);
233  nad_append_attr(nad, -1, "challenge", sess->auth_challenge);
234  }
235  else ; /* auth method unsupported for user */
236  }
237 
238  /* give it back to the client */
239  sx_nad_write(sess->s, nad);
240 
241  return;
242 }
243 
245 static void _authreg_auth_set(c2s_t c2s, sess_t sess, nad_t nad) {
246  int ns, elem, attr, authd = 0;
247  char username[1024], resource[1024], str[1024], hash[280];
248  int ar_mechs;
249 
250  /* can't auth if they're active */
251  if(sess->active) {
253  return;
254  }
255 
256  ns = nad_find_scoped_namespace(nad, uri_AUTH, NULL);
257 
258  /* sort out the username */
259  elem = nad_find_elem(nad, 1, ns, "username", 1);
260  if(elem < 0)
261  {
262  log_debug(ZONE, "auth set with no username, bouncing it");
263 
265 
266  return;
267  }
268 
269  snprintf(username, 1024, "%.*s", NAD_CDATA_L(nad, elem), NAD_CDATA(nad, elem));
270  if(stringprep_xmpp_nodeprep(username, 1024) != 0) {
271  log_debug(ZONE, "auth set username failed nodeprep, bouncing it");
273  return;
274  }
275 
276  /* make sure we have the resource */
277  elem = nad_find_elem(nad, 1, ns, "resource", 1);
278  if(elem < 0)
279  {
280  log_debug(ZONE, "auth set with no resource, bouncing it");
281 
283 
284  return;
285  }
286 
287  snprintf(resource, 1024, "%.*s", NAD_CDATA_L(nad, elem), NAD_CDATA(nad, elem));
288  if(stringprep_xmpp_resourceprep(resource, 1024) != 0) {
289  log_debug(ZONE, "auth set resource failed resourceprep, bouncing it");
291  return;
292  }
293 
294  ar_mechs = c2s->ar_mechanisms;
295  if (sess->s->ssf > 0)
296  ar_mechs = ar_mechs | c2s->ar_ssl_mechanisms;
297 
298  /* no point going on if we have no mechanisms */
301  return;
302  }
303 
304  /* do we have the user? */
305  if((sess->host->ar->user_exists)(sess->host->ar, sess, username, sess->host->realm) == 0) {
307  return;
308  }
309 
310  /* handle CRAM-MD5 response */
311  if(!authd && ar_mechs & AR_MECH_TRAD_CRAMMD5 && sess->host->ar->check_response != NULL)
312  {
313  elem = nad_find_elem(nad, 1, ns, "crammd5", 1);
314  if(elem >= 0)
315  {
316  snprintf(str, 1024, "%.*s", NAD_CDATA_L(nad, elem), NAD_CDATA(nad, elem));
317  if((sess->host->ar->check_response)(sess->host->ar, sess, username, sess->host->realm, sess->auth_challenge, str) == 0)
318  {
319  log_debug(ZONE, "crammd5 auth (check) succeded");
320  authd = 1;
321  _authreg_auth_log(c2s, sess, "traditional.cram-md5", username, resource, TRUE);
322  } else {
323  _authreg_auth_log(c2s, sess, "traditional.cram-md5", username, resource, FALSE);
324  }
325  }
326  }
327 
328  /* digest auth */
329  if(!authd && ar_mechs & AR_MECH_TRAD_DIGEST && sess->host->ar->get_password != NULL)
330  {
331  elem = nad_find_elem(nad, 1, ns, "digest", 1);
332  if(elem >= 0)
333  {
334  if((sess->host->ar->get_password)(sess->host->ar, sess, username, sess->host->realm, str) == 0)
335  {
336  snprintf(hash, 280, "%s%s", sess->s->id, str);
337  shahash_r(hash, hash);
338 
339  if(strlen(hash) == NAD_CDATA_L(nad, elem) && strncmp(hash, NAD_CDATA(nad, elem), NAD_CDATA_L(nad, elem)) == 0)
340  {
341  log_debug(ZONE, "digest auth succeeded");
342  authd = 1;
343  _authreg_auth_log(c2s, sess, "traditional.digest", username, resource, TRUE);
344  } else {
345  _authreg_auth_log(c2s, sess, "traditional.digest", username, resource, FALSE);
346  }
347  }
348  }
349  }
350 
351  /* plaintext auth (compare) */
352  if(!authd && ar_mechs & AR_MECH_TRAD_PLAIN && sess->host->ar->get_password != NULL)
353  {
354  elem = nad_find_elem(nad, 1, ns, "password", 1);
355  if(elem >= 0)
356  {
357  if((sess->host->ar->get_password)(sess->host->ar, sess, username, sess->host->realm, str) == 0 &&
358  strlen(str) == NAD_CDATA_L(nad, elem) && strncmp(str, NAD_CDATA(nad, elem), NAD_CDATA_L(nad, elem)) == 0)
359  {
360  log_debug(ZONE, "plaintext auth (compare) succeeded");
361  authd = 1;
362  _authreg_auth_log(c2s, sess, "traditional.plain(compare)", username, resource, TRUE);
363  } else {
364  _authreg_auth_log(c2s, sess, "traditional.plain(compare)", username, resource, FALSE);
365  }
366  }
367  }
368 
369  /* plaintext auth (check) */
370  if(!authd && ar_mechs & AR_MECH_TRAD_PLAIN && sess->host->ar->check_password != NULL)
371  {
372  elem = nad_find_elem(nad, 1, ns, "password", 1);
373  if(elem >= 0)
374  {
375  snprintf(str, 1024, "%.*s", NAD_CDATA_L(nad, elem), NAD_CDATA(nad, elem));
376  if((sess->host->ar->check_password)(sess->host->ar, sess, username, sess->host->realm, str) == 0)
377  {
378  log_debug(ZONE, "plaintext auth (check) succeded");
379  authd = 1;
380  _authreg_auth_log(c2s, sess, "traditional.plain", username, resource, TRUE);
381  } else {
382  _authreg_auth_log(c2s, sess, "traditional.plain", username, resource, FALSE);
383  }
384  }
385  }
386 
387  /* now, are they authenticated? */
388  if(authd)
389  {
390  /* create new bound jid holder */
391  if(sess->resources == NULL) {
392  sess->resources = (bres_t) calloc(1, sizeof(struct bres_st));
393  }
394 
395  /* our local id */
396  sprintf(sess->resources->c2s_id, "%d", sess->s->tag);
397 
398  /* the full user jid for this session */
399  sess->resources->jid = jid_new(sess->s->req_to, -1);
400  jid_reset_components(sess->resources->jid, username, sess->resources->jid->domain, resource);
401 
402  log_write(sess->c2s->log, LOG_NOTICE, "[%d] requesting session: jid=%s", sess->s->tag, jid_full(sess->resources->jid));
403 
404  /* build a result packet, we'll send this back to the client after we have a session for them */
405  sess->result = nad_new();
406 
407  ns = nad_add_namespace(sess->result, uri_CLIENT, NULL);
408 
409  nad_append_elem(sess->result, ns, "iq", 0);
410  nad_set_attr(sess->result, 0, -1, "type", "result", 6);
411 
412  attr = nad_find_attr(nad, 0, -1, "id", NULL);
413  if(attr >= 0)
414  nad_set_attr(sess->result, 0, -1, "id", NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr));
415 
416  /* start a session with the sm */
417  sm_start(sess, sess->resources);
418 
419  /* finished with the nad */
420  nad_free(nad);
421 
422  return;
423  }
424 
425  _authreg_auth_log(c2s, sess, "traditional", username, resource, FALSE);
426 
427  /* auth failed, so error */
429 
430  return;
431 }
432 
434 static void _authreg_register_get(c2s_t c2s, sess_t sess, nad_t nad) {
435  int attr, ns;
436  char id[128];
437 
438  /* registrations can happen if reg is enabled and we can create users and set passwords */
439  if(sess->active || !(sess->host->ar->set_password != NULL && sess->host->ar->create_user != NULL &&
440  (sess->host->ar_register_enable || sess->host->ar_register_oob))) {
441 
443  return;
444  }
445 
446  /* extract the id */
447  attr = nad_find_attr(nad, 0, -1, "id", NULL);
448  if(attr >= 0)
449  snprintf(id, 128, "%.*s", NAD_AVAL_L(nad, attr), NAD_AVAL(nad, attr));
450 
451  nad_free(nad);
452 
453  /* build a result packet */
454  nad = nad_new();
455 
456  ns = nad_add_namespace(nad, uri_CLIENT, NULL);
457 
458  nad_append_elem(nad, ns, "iq", 0);
459  nad_append_attr(nad, -1, "type", "result");
460 
461  if(attr >= 0)
462  nad_append_attr(nad, -1, "id", id);
463 
464  ns = nad_add_namespace(nad, uri_REGISTER, NULL);
465  nad_append_elem(nad, ns, "query", 1);
466 
467  nad_append_elem(nad, ns, "instructions", 2);
469 
470  if(sess->host->ar_register_enable) {
471  nad_append_elem(nad, ns, "username", 2);
472  nad_append_elem(nad, ns, "password", 2);
473  }
474 
475  if(sess->host->ar_register_oob) {
476  int ns = nad_add_namespace(nad, uri_OOB, NULL);
477  nad_append_elem(nad, ns, "x", 2);
478  nad_append_elem(nad, ns, "url", 3);
479  nad_append_cdata(nad, sess->host->ar_register_oob, strlen(sess->host->ar_register_oob), 4);
480  }
481 
482  /* give it back to the client */
483  sx_nad_write(sess->s, nad);
484 }
485 
487 static void _authreg_register_set(c2s_t c2s, sess_t sess, nad_t nad)
488 {
489  int ns = 0, elem, attr;
490  char username[1024], password[1024];
491 
492  /* if we're not configured for registration (or pw changes), or we can't set passwords, fail outright */
493  if(!(sess->host->ar_register_enable || sess->host->ar_register_password) || sess->host->ar->set_password == NULL) {
495  return;
496  }
497 
498  ns = nad_find_scoped_namespace(nad, uri_REGISTER, NULL);
499 
500  /* removals */
501  if(sess->active && nad_find_elem(nad, 1, ns, "remove", 1) >= 0) {
502  /* only if full reg is enabled */
503  if(!sess->host->ar_register_enable) {
505  return;
506  }
507 
508  log_debug(ZONE, "user remove requested");
509 
510  /* make sure we can delete them */
511  if(sess->host->ar->delete_user == NULL) {
513  return;
514  }
515 
516  /* otherwise, delete them */
517  if((sess->host->ar->delete_user)(sess->host->ar, sess, sess->resources->jid->node, sess->host->realm) != 0) {
518  log_debug(ZONE, "user delete failed");
520  return;
521  }
522 
523  log_write(c2s->log, LOG_NOTICE, "[%d] deleted user: user=%s; realm=%s", sess->s->tag, sess->resources->jid->node, sess->host->realm);
524 
525  log_write(c2s->log, LOG_NOTICE, "[%d] registration remove succeeded, requesting user deletion: jid=%s", sess->s->tag, jid_user(sess->resources->jid));
526 
527  /* make a result nad */
528  sess->result = nad_new();
529 
530  ns = nad_add_namespace(sess->result, uri_CLIENT, NULL);
531 
532  nad_append_elem(sess->result, ns, "iq", 0);
533  nad_set_attr(sess->result, 0, -1, "type", "result", 6);
534 
535  /* extract the id */
536  attr = nad_find_attr(nad, 0, -1, "id", NULL);
537  if(attr >= 0)
538  nad_set_attr(sess->result, 0, -1, "id", NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr));
539 
540  nad_free(nad);
541 
542  sx_nad_write(sess->s, sess->result);
543  sess->result = NULL;
544 
545  /* get the sm to delete them (it will force their sessions to end) */
546  sm_delete(sess, sess->resources);
547 
548  return;
549  }
550 
551  /* username is required */
552  elem = nad_find_elem(nad, 1, ns, "username", 1);
553  if(elem < 0)
554  {
555  log_debug(ZONE, "register set with no username, bouncing it");
557  return;
558  }
559 
560  snprintf(username, 1024, "%.*s", NAD_CDATA_L(nad, elem), NAD_CDATA(nad, elem));
561  if(stringprep_xmpp_nodeprep(username, 1024) != 0) {
562  log_debug(ZONE, "register set username failed nodeprep, bouncing it");
564  return;
565  }
566 
567  elem = nad_find_elem(nad, 1, ns, "password", 1);
568  if(elem < 0)
569  {
570  log_debug(ZONE, "register set with no password, bouncing it");
572  return;
573  }
574 
575  /* if they're already auth'd, its a password change */
576  if(sess->active)
577  {
578  /* confirm that the username matches their auth id */
579  if(strcmp(username, sess->resources->jid->node) != 0)
580  {
581  log_debug(ZONE, "%s is trying to change password for %s, bouncing it", jid_full(sess->resources->jid), username);
583  return;
584  }
585  }
586 
587  /* can't go on if we're not doing full reg */
588  else if(!sess->host->ar_register_enable) {
590  return;
591  }
592 
593  /* if they exist, bounce */
594  else if((sess->host->ar->user_exists)(sess->host->ar, sess, username, sess->host->realm))
595  {
596  log_debug(ZONE, "attempt to register %s, but they already exist", username);
598  return;
599  }
600 
601  /* make sure we can create them */
602  else if(sess->host->ar->create_user == NULL)
603  {
605  return;
606  }
607 
608  /* otherwise, create them */
609  else if((sess->host->ar->create_user)(sess->host->ar, sess, username, sess->host->realm) != 0)
610  {
611  log_debug(ZONE, "user create failed");
613  return;
614  }
615 
616  else
617  log_write(c2s->log, LOG_NOTICE, "[%d] created user: user=%s; realm=%s", sess->s->tag, username, sess->host->realm);
618 
619  /* extract the password */
620  snprintf(password, 257, "%.*s", NAD_CDATA_L(nad, elem), NAD_CDATA(nad, elem));
621 
622  /* change it */
623  if((sess->host->ar->set_password)(sess->host->ar, sess, username, sess->host->realm, password) != 0)
624  {
625  log_debug(ZONE, "password store failed");
627  return;
628  }
629 
630  log_debug(ZONE, "updated auth creds for %s", username);
631 
632  /* make a result nad */
633  sess->result = nad_new();
634 
635  ns = nad_add_namespace(sess->result, uri_CLIENT, NULL);
636 
637  nad_append_elem(sess->result, ns, "iq", 0);
638  nad_set_attr(sess->result, 0, -1, "type", "result", 6);
639 
640  /* extract the id */
641  attr = nad_find_attr(nad, 0, -1, "id", NULL);
642  if(attr >= 0)
643  nad_set_attr(sess->result, 0, -1, "id", NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr));
644 
645  /* if they're active, then this was just a password change, and we're done */
646  if(sess->active) {
647  log_write(c2s->log, LOG_NOTICE, "[%d] password changed: jid=%s", sess->s->tag, jid_user(sess->resources->jid));
648  sx_nad_write(sess->s, sess->result);
649  sess->result = NULL;
650  return;
651  }
652 
653  /* create new bound jid holder */
654  if(sess->resources == NULL) {
655  sess->resources = (bres_t) calloc(1, sizeof(struct bres_st));
656  }
657 
658  /* our local id */
659  sprintf(sess->resources->c2s_id, "%d", sess->s->tag);
660 
661  /* the user jid for this transaction */
662  sess->resources->jid = jid_new(sess->s->req_to, -1);
663  jid_reset_components(sess->resources->jid, username, sess->resources->jid->domain, sess->resources->jid->resource);
664 
665  log_write(c2s->log, LOG_NOTICE, "[%d] registration succeeded, requesting user creation: jid=%s", sess->s->tag, jid_user(sess->resources->jid));
666 
667  /* get the sm to create them */
668  sm_create(sess, sess->resources);
669 
670  nad_free(nad);
671 
672  return;
673 }
674 
680  int ns, query, type, authreg = -1, getset = -1;
681 
682  /* need iq */
683  if(NAD_ENAME_L(nad, 0) != 2 || strncmp("iq", NAD_ENAME(nad, 0), 2) != 0)
684  return 1;
685 
686  /* only want auth or register packets */
687  if((ns = nad_find_scoped_namespace(nad, uri_AUTH, NULL)) >= 0 && (query = nad_find_elem(nad, 0, ns, "query", 1)) >= 0)
688  authreg = 0;
689  else if((ns = nad_find_scoped_namespace(nad, uri_REGISTER, NULL)) >= 0 && (query = nad_find_elem(nad, 0, ns, "query", 1)) >= 0)
690  authreg = 1;
691  else
692  return 1;
693 
694  /* if its to someone else, pass it */
695  if(nad_find_attr(nad, 0, -1, "to", NULL) >= 0 && nad_find_attr(nad, 0, -1, "to", sess->s->req_to) < 0)
696  return 1;
697 
698  /* need a type */
699  if((type = nad_find_attr(nad, 0, -1, "type", NULL)) < 0 || NAD_AVAL_L(nad, type) != 3)
700  {
702  return 0;
703  }
704 
705  /* get or set? */
706  if(strncmp("get", NAD_AVAL(nad, type), NAD_AVAL_L(nad, type)) == 0)
707  getset = 0;
708  else if(strncmp("set", NAD_AVAL(nad, type), NAD_AVAL_L(nad, type)) == 0)
709  getset = 1;
710  else
711  {
713  return 0;
714  }
715 
716  /* hand to the correct handler */
717  if(authreg == 0) {
718  /* can't do iq:auth after sasl auth */
719  if(sess->sasl_authd) {
721  return 0;
722  }
723 
724  if(getset == 0) {
725  log_debug(ZONE, "auth get");
726  _authreg_auth_get(c2s, sess, nad);
727  } else if(getset == 1) {
728  log_debug(ZONE, "auth set");
729  _authreg_auth_set(c2s, sess, nad);
730  }
731  }
732 
733  if(authreg == 1) {
734  if(getset == 0) {
735  log_debug(ZONE, "register get");
736  _authreg_register_get(c2s, sess, nad);
737  } else if(getset == 1) {
738  log_debug(ZONE, "register set");
739  _authreg_register_set(c2s, sess, nad);
740  }
741  }
742 
743  /* handled */
744  return 0;
745 }
int(* check_password)(authreg_t ar, sess_t sess, const char *username, const char *realm, char password[257])
check the given password against the stored password, 0 if equal, !0 if not equal (password auth) ...
Definition: c2s.h:351
const char * ip
Definition: sx.h:262
C2S_API void sm_create(sess_t sess, bres_t res)
Definition: sm.c:76
struct bres_st * bres_t
Definition: c2s.h:54
bres_t resources
Definition: c2s.h:103
Definition: nad.h:93
nad_t nad_new(void)
create a new nad
Definition: nad.c:125
int nad_append_attr(nad_t nad, int ns, const char *name, const char *val)
attach new attr to the last elem
Definition: nad.c:729
config_t config
config
Definition: c2s.h:193
#define NAD_CDATA_L(N, E)
Definition: nad.h:186
#define sx_nad_write(s, nad)
Definition: sx.h:167
xht ar_modules
loaded auth/reg modules
Definition: c2s.h:269
#define stanza_err_JID_MALFORMED
Definition: util.h:374
int ar_register_enable
registration
Definition: c2s.h:151
c2s_t c2s
Definition: c2s.h:338
const char * jid_user(jid_t jid)
expand and return the user
Definition: jid.c:339
const char * req_to
Definition: sx.h:282
const char * jid_full(jid_t jid)
expand and return the full
Definition: jid.c:347
jid_t jid_new(const char *id, int len)
make a new jid
Definition: jid.c:81
int(* get_password)(authreg_t ar, sess_t sess, const char *username, const char *realm, char password[257])
return this users cleartext password in the array (digest auth, password auth)
Definition: c2s.h:348
#define uri_AUTH
Definition: uri.h:61
int(* create_challenge)(authreg_t ar, sess_t sess, const char *username, const char *realm, char *challenge, int maxlen)
Apple extensions for challenge/response authentication methods.
Definition: c2s.h:372
int nad_find_elem(nad_t nad, int elem, int ns, const char *name, int depth)
locate the next elem at a given depth with an optional matching name
Definition: nad.c:204
void nad_append_cdata(nad_t nad, const char *cdata, int len, int depth)
append new cdata to the last elem
Definition: nad.c:737
int(* user_exists)(authreg_t ar, sess_t sess, const char *username, const char *realm)
returns 1 if the user exists, 0 if not
Definition: c2s.h:345
static void _authreg_auth_log(c2s_t c2s, sess_t sess, const char *method, const char *username, const char *resource, int success)
auth logger
Definition: authreg.c:136
void log_write(log_t log, int level, const char *msgfmt,...)
Definition: log.c:104
int(* ar_module_init_fn)(authreg_t)
type for the module init function
Definition: c2s.h:383
#define AR_MECH_TRAD_DIGEST
Definition: c2s.h:121
static void _authreg_auth_set(c2s_t c2s, sess_t sess, nad_t nad)
auth set handler
Definition: authreg.c:245
void shahash_r(const char *str, char hashbuf[41])
convenience (originally by Thomas Muldowney)
Definition: str.c:358
int tag
Definition: sx.h:258
list of resources bound to session
Definition: c2s.h:59
int nad_add_namespace(nad_t nad, const char *uri, const char *prefix)
bring a new namespace into scope
Definition: nad.c:762
nad_t result
Definition: c2s.h:108
int ar_mechanisms
allowed mechanisms
Definition: c2s.h:272
#define stanza_err_CONFLICT
Definition: util.h:368
#define stanza_err_FORBIDDEN
Definition: util.h:370
#define NAD_ENAME(N, E)
Definition: nad.h:183
int initialized
Definition: c2s.h:339
char * resource
Definition: jid.h:46
struct _authreg_error_st * authreg_error_t
int nad_append_elem(nad_t nad, int ns, const char *name, int depth)
create a new elem on the list
Definition: nad.c:695
void nad_free(nad_t nad)
free that nad
Definition: nad.c:178
int(* set_password)(authreg_t ar, sess_t sess, const char *username, const char *realm, char password[257])
store this password (register)
Definition: c2s.h:354
#define AR_MECH_TRAD_CRAMMD5
Definition: c2s.h:122
jid_t jid
full bound jid
Definition: c2s.h:61
#define AR_MECH_TRAD_PLAIN
Definition: c2s.h:120
sx_t s
Definition: c2s.h:86
#define PATH_MAX
Definition: util.h:69
void nad_set_attr(nad_t nad, int elem, int ns, const char *name, const char *val, int vallen)
create, update, or zap any matching attr on this elem
Definition: nad.c:403
int authreg_process(c2s_t c2s, sess_t sess, nad_t nad)
processor for iq:auth and iq:register packets return 0 if handled, 1 if not handled ...
Definition: authreg.c:679
jid_t jid_reset_components(jid_t jid, const char *node, const char *domain, const char *resource)
build a jid from components
Definition: jid.c:281
const char * ar_register_instructions
Definition: c2s.h:152
void * pmalloco(pool_t p, int size)
easy safety utility (for creating blank mem for structs, etc)
Definition: pool.c:183
#define NAD_ENAME_L(N, E)
Definition: nad.h:184
const char * realm
our realm (SASL)
Definition: c2s.h:126
void xhash_put(xht h, const char *key, void *val)
Definition: xhash.c:163
int ar_register_password
Definition: c2s.h:154
authreg_t ar
Definition: c2s.h:148
#define stanza_err_BAD_REQUEST
Definition: util.h:367
char * domain
Definition: jid.h:45
host_t host
host this session belongs to
Definition: c2s.h:89
nad_t stanza_tofrom(nad_t nad, int elem)
flip the to and from attributes on this elem
Definition: stanza.c:78
#define uri_REGISTER
Definition: uri.h:62
#define NAD_AVAL_L(N, A)
Definition: nad.h:190
struct authreg_st * authreg_t
Definition: c2s.h:56
#define log_debug(...)
Definition: log.h:65
#define stanza_err_NOT_ALLOWED
Definition: util.h:376
char c2s_id[44]
session id for this jid for us and them
Definition: c2s.h:63
nad_t stanza_error(nad_t nad, int elem, int err)
error the packet
Definition: stanza.c:52
#define uri_CLIENT
Definition: uri.h:35
#define NAD_AVAL(N, A)
Definition: nad.h:189
Definition: c2s.h:157
C2S_API void sm_start(sess_t sess, bres_t res)
Definition: sm.c:66
static void _authreg_register_get(c2s_t c2s, sess_t sess, nad_t nad)
register get handler
Definition: authreg.c:434
There is one instance of this struct per user who is logged in to this c2s instance.
Definition: c2s.h:74
int ssf
Definition: sx.h:340
static void _authreg_register_set(c2s_t c2s, sess_t sess, nad_t nad)
register set handler
Definition: authreg.c:487
int(* create_user)(authreg_t ar, sess_t sess, const char *username, const char *realm)
make or break the user (register / register remove)
Definition: c2s.h:357
pool_t xhash_pool(xht h)
get our pool
Definition: xhash.c:305
#define NAD_CDATA(N, E)
Definition: nad.h:185
char auth_challenge[65]
Apple: session challenge for challenge-response authentication.
Definition: c2s.h:113
void * xhash_get(xht h, const char *key)
Definition: xhash.c:184
void authreg_free(authreg_t ar)
shutdown the authreg system
Definition: authreg.c:129
int port
Definition: sx.h:266
#define ZONE
Definition: mio_impl.h:76
const char * config_get_one(config_t c, const char *key, int num)
get config value n for this key
Definition: config.c:277
const char * ar_register_oob
Definition: c2s.h:153
#define uri_OOB
Definition: uri.h:56
int nad_find_attr(nad_t nad, int elem, int ns, const char *name, const char *val)
get a matching attr on this elem, both name and optional val
Definition: nad.c:235
c2s_t c2s
Definition: c2s.h:75
static void _authreg_auth_get(c2s_t c2s, sess_t sess, nad_t nad)
auth get handler
Definition: authreg.c:145
#define stanza_err_OLD_UNAUTH
Definition: util.h:388
log_t log
logging
Definition: c2s.h:196
int(* check_response)(authreg_t ar, sess_t sess, const char *username, const char *realm, const char *challenge, const char *response)
Definition: c2s.h:373
authreg_t authreg_init(c2s_t c2s, const char *name)
get a handle for the named module
Definition: authreg.c:40
int ar_ssl_mechanisms
Definition: c2s.h:273
const char * id
Definition: sx.h:292
#define stanza_err_INTERNAL_SERVER_ERROR
Definition: util.h:372
int sasl_authd
Definition: c2s.h:110
int active
Definition: c2s.h:105
char * node
Definition: jid.h:44
void(* free)(authreg_t ar)
called prior to authreg shutdown
Definition: c2s.h:364
C2S_API void sm_delete(sess_t sess, bres_t res)
Definition: sm.c:82
int(* delete_user)(authreg_t ar, sess_t sess, const char *username, const char *realm)
Definition: c2s.h:358
int nad_find_scoped_namespace(nad_t nad, const char *uri, const char *prefix)
find a namespace in scope
Definition: nad.c:290
char * _sx_flags(sx_t s)
show sx flags as string - for logging
Definition: sx.c:349