jabberd2  2.3.1
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  /* load authreg module */
48  modules_path = config_get_one(c2s->config, "authreg.path", 0);
49  if (modules_path != NULL)
50  log_write(c2s->log, LOG_NOTICE, "modules search path: %s", modules_path);
51  else
52  log_write(c2s->log, LOG_NOTICE, "modules search path undefined, using default: "LIBRARY_DIR);
53 
54  log_write(c2s->log, LOG_INFO, "loading '%s' authreg module", name);
55 #ifndef _WIN32
56  if (modules_path != NULL)
57  snprintf(mod_fullpath, PATH_MAX, "%s/authreg_%s.so", modules_path, name);
58  else
59  snprintf(mod_fullpath, PATH_MAX, "%s/authreg_%s.so", LIBRARY_DIR, name);
60  handle = dlopen(mod_fullpath, RTLD_LAZY);
61  if (handle != NULL)
62  init_fn = dlsym(handle, "ar_init");
63 #else
64  if (modules_path != NULL)
65  snprintf(mod_fullpath, PATH_MAX, "%s\\authreg_%s.dll", modules_path, name);
66  else
67  snprintf(mod_fullpath, PATH_MAX, "authreg_%s.dll", name);
68  handle = (void*) LoadLibrary(mod_fullpath);
69  if (handle != NULL)
70  init_fn = (ar_module_init_fn)GetProcAddress((HMODULE) handle, "ar_init");
71 #endif
72 
73  if (handle != NULL && init_fn != NULL) {
74  log_debug(ZONE, "preloaded module '%s' (not initialized yet)", name);
75  } else {
76 #ifndef _WIN32
77  log_write(c2s->log, LOG_ERR, "failed loading authreg module '%s' (%s)", name, dlerror());
78  if (handle != NULL)
79  dlclose(handle);
80 #else
81  log_write(c2s->log, LOG_ERR, "failed loading authreg module '%s' (errcode: %x)", name, GetLastError());
82  if (handle != NULL)
83  FreeLibrary((HMODULE) handle);
84 #endif
85  return NULL;
86  }
87 
88  /* make a new one */
89  ar = (authreg_t) calloc(1, sizeof(struct authreg_st));
90 
91  ar->c2s = c2s;
92 
93  /* call the initialiser */
94  if((init_fn)(ar) != 0)
95  {
96  log_write(c2s->log, LOG_ERR, "failed to initialize auth module '%s'", name);
97  authreg_free(ar);
98  return NULL;
99  }
100 
101  /* we need user_exists(), at the very least */
102  if(ar->user_exists == NULL)
103  {
104  log_write(c2s->log, LOG_ERR, "auth module '%s' has no check for user existence", name);
105  authreg_free(ar);
106  return NULL;
107  }
108 
109  /* its good */
110  log_write(c2s->log, LOG_NOTICE, "initialized auth module '%s'", name);
111 
112  return ar;
113 }
114 
117  if (ar) {
118  if(ar->free != NULL) (ar->free)(ar);
119  free(ar);
120  }
121 }
122 
124 inline static void _authreg_auth_log(c2s_t c2s, sess_t sess, const char *method, const char *username, const char *resource, int success) {
125  log_write(c2s->log, LOG_NOTICE, "[%d] %s authentication %s: %s@%s/%s %s:%d%s%s",
126  sess->s->tag, method, success ? "succeeded" : "failed",
127  username, sess->host->realm, resource,
128  sess->s->ip, sess->s->port,
129  sess->s->ssf ? " TLS" : "", sess->s->compressed ? " ZLIB" : ""
130  );
131 }
132 
134 static void _authreg_auth_get(c2s_t c2s, sess_t sess, nad_t nad) {
135  int ns, elem, attr, err;
136  char username[1024], id[128];
137  int ar_mechs;
138 
139  /* can't auth if they're active */
140  if(sess->active) {
142  return;
143  }
144 
145  /* sort out the username */
146  ns = nad_find_scoped_namespace(nad, uri_AUTH, NULL);
147  elem = nad_find_elem(nad, 1, ns, "username", 1);
148  if(elem < 0)
149  {
150  log_debug(ZONE, "auth get with no username, bouncing it");
151 
153 
154  return;
155  }
156 
157  snprintf(username, 1024, "%.*s", NAD_CDATA_L(nad, elem), NAD_CDATA(nad, elem));
158  if(stringprep_xmpp_nodeprep(username, 1024) != 0) {
159  log_debug(ZONE, "auth get username failed nodeprep, bouncing it");
161  return;
162  }
163 
164  ar_mechs = c2s->ar_mechanisms;
165  if (sess->s->ssf>0)
166  ar_mechs = ar_mechs | c2s->ar_ssl_mechanisms;
167 
168  /* no point going on if we have no mechanisms */
171  return;
172  }
173 
174  /* do we have the user? */
175  if((c2s->ar->user_exists)(c2s->ar, username, sess->host->realm) == 0) {
177  return;
178  }
179 
180  /* extract the id */
181  attr = nad_find_attr(nad, 0, -1, "id", NULL);
182  if(attr >= 0)
183  snprintf(id, 128, "%.*s", NAD_AVAL_L(nad, attr), NAD_AVAL(nad, attr));
184 
185  nad_free(nad);
186 
187  /* build a result packet */
188  nad = nad_new();
189 
190  ns = nad_add_namespace(nad, uri_CLIENT, NULL);
191 
192  nad_append_elem(nad, ns, "iq", 0);
193  nad_append_attr(nad, -1, "type", "result");
194 
195  if(attr >= 0)
196  nad_append_attr(nad, -1, "id", id);
197 
198  ns = nad_add_namespace(nad, uri_AUTH, NULL);
199  nad_append_elem(nad, ns, "query", 1);
200 
201  nad_append_elem(nad, ns, "username", 2);
202  nad_append_cdata(nad, username, strlen(username), 3);
203 
204  nad_append_elem(nad, ns, "resource", 2);
205 
206  /* fill out the packet with available auth mechanisms */
207  if(ar_mechs & AR_MECH_TRAD_PLAIN && (c2s->ar->get_password != NULL || c2s->ar->check_password != NULL))
208  nad_append_elem(nad, ns, "password", 2);
209 
210  if(ar_mechs & AR_MECH_TRAD_DIGEST && c2s->ar->get_password != NULL)
211  nad_append_elem(nad, ns, "digest", 2);
212 
213  if (ar_mechs & AR_MECH_TRAD_CRAMMD5 && c2s->ar->create_challenge != NULL) {
214  err = (c2s->ar->create_challenge)(c2s->ar, (char *) username, (char *) sess->auth_challenge, sizeof(sess->auth_challenge));
215  if (0 == err) { /* operation failed */
217  return;
218  }
219  else if (1 == err) { /* operation succeeded */
220  nad_append_elem(nad, ns, "crammd5", 2);
221  nad_append_attr(nad, -1, "challenge", sess->auth_challenge);
222  }
223  else ; /* auth method unsupported for user */
224  }
225 
226  /* give it back to the client */
227  sx_nad_write(sess->s, nad);
228 
229  return;
230 }
231 
233 static void _authreg_auth_set(c2s_t c2s, sess_t sess, nad_t nad) {
234  int ns, elem, attr, authd = 0;
235  char username[1024], resource[1024], str[1024], hash[280];
236  int ar_mechs;
237 
238  /* can't auth if they're active */
239  if(sess->active) {
241  return;
242  }
243 
244  ns = nad_find_scoped_namespace(nad, uri_AUTH, NULL);
245 
246  /* sort out the username */
247  elem = nad_find_elem(nad, 1, ns, "username", 1);
248  if(elem < 0)
249  {
250  log_debug(ZONE, "auth set with no username, bouncing it");
251 
253 
254  return;
255  }
256 
257  snprintf(username, 1024, "%.*s", NAD_CDATA_L(nad, elem), NAD_CDATA(nad, elem));
258  if(stringprep_xmpp_nodeprep(username, 1024) != 0) {
259  log_debug(ZONE, "auth set username failed nodeprep, bouncing it");
261  return;
262  }
263 
264  /* make sure we have the resource */
265  elem = nad_find_elem(nad, 1, ns, "resource", 1);
266  if(elem < 0)
267  {
268  log_debug(ZONE, "auth set with no resource, bouncing it");
269 
271 
272  return;
273  }
274 
275  snprintf(resource, 1024, "%.*s", NAD_CDATA_L(nad, elem), NAD_CDATA(nad, elem));
276  if(stringprep_xmpp_resourceprep(resource, 1024) != 0) {
277  log_debug(ZONE, "auth set resource failed resourceprep, bouncing it");
279  return;
280  }
281 
282  ar_mechs = c2s->ar_mechanisms;
283  if (sess->s->ssf > 0)
284  ar_mechs = ar_mechs | c2s->ar_ssl_mechanisms;
285 
286  /* no point going on if we have no mechanisms */
289  return;
290  }
291 
292  /* do we have the user? */
293  if((c2s->ar->user_exists)(c2s->ar, username, sess->host->realm) == 0) {
295  return;
296  }
297 
298  /* handle CRAM-MD5 response */
299  if(!authd && ar_mechs & AR_MECH_TRAD_CRAMMD5 && c2s->ar->check_response != NULL)
300  {
301  elem = nad_find_elem(nad, 1, ns, "crammd5", 1);
302  if(elem >= 0)
303  {
304  snprintf(str, 1024, "%.*s", NAD_CDATA_L(nad, elem), NAD_CDATA(nad, elem));
305  if((c2s->ar->check_response)(c2s->ar, username, sess->host->realm, sess->auth_challenge, str) == 0)
306  {
307  log_debug(ZONE, "crammd5 auth (check) succeded");
308  authd = 1;
309  _authreg_auth_log(c2s, sess, "traditional.cram-md5", username, resource, TRUE);
310  } else {
311  _authreg_auth_log(c2s, sess, "traditional.cram-md5", username, resource, FALSE);
312  }
313  }
314  }
315 
316  /* digest auth */
317  if(!authd && ar_mechs & AR_MECH_TRAD_DIGEST && c2s->ar->get_password != NULL)
318  {
319  elem = nad_find_elem(nad, 1, ns, "digest", 1);
320  if(elem >= 0)
321  {
322  if((c2s->ar->get_password)(c2s->ar, username, sess->host->realm, str) == 0)
323  {
324  snprintf(hash, 280, "%s%s", sess->s->id, str);
325  shahash_r(hash, hash);
326 
327  if(strlen(hash) == NAD_CDATA_L(nad, elem) && strncmp(hash, NAD_CDATA(nad, elem), NAD_CDATA_L(nad, elem)) == 0)
328  {
329  log_debug(ZONE, "digest auth succeeded");
330  authd = 1;
331  _authreg_auth_log(c2s, sess, "traditional.digest", username, resource, TRUE);
332  } else {
333  _authreg_auth_log(c2s, sess, "traditional.digest", username, resource, FALSE);
334  }
335  }
336  }
337  }
338 
339  /* plaintext auth (compare) */
340  if(!authd && ar_mechs & AR_MECH_TRAD_PLAIN && c2s->ar->get_password != NULL)
341  {
342  elem = nad_find_elem(nad, 1, ns, "password", 1);
343  if(elem >= 0)
344  {
345  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)
346  {
347  log_debug(ZONE, "plaintext auth (compare) succeeded");
348  authd = 1;
349  _authreg_auth_log(c2s, sess, "traditional.plain(compare)", username, resource, TRUE);
350  } else {
351  _authreg_auth_log(c2s, sess, "traditional.plain(compare)", username, resource, FALSE);
352  }
353  }
354  }
355 
356  /* plaintext auth (check) */
357  if(!authd && ar_mechs & AR_MECH_TRAD_PLAIN && c2s->ar->check_password != NULL)
358  {
359  elem = nad_find_elem(nad, 1, ns, "password", 1);
360  if(elem >= 0)
361  {
362  snprintf(str, 1024, "%.*s", NAD_CDATA_L(nad, elem), NAD_CDATA(nad, elem));
363  if((c2s->ar->check_password)(c2s->ar, username, sess->host->realm, str) == 0)
364  {
365  log_debug(ZONE, "plaintext auth (check) succeded");
366  authd = 1;
367  _authreg_auth_log(c2s, sess, "traditional.plain", username, resource, TRUE);
368  } else {
369  _authreg_auth_log(c2s, sess, "traditional.plain", username, resource, FALSE);
370  }
371  }
372  }
373 
374  /* now, are they authenticated? */
375  if(authd)
376  {
377  /* create new bound jid holder */
378  if(sess->resources == NULL) {
379  sess->resources = (bres_t) calloc(1, sizeof(struct bres_st));
380  }
381 
382  /* our local id */
383  sprintf(sess->resources->c2s_id, "%d", sess->s->tag);
384 
385  /* the full user jid for this session */
386  sess->resources->jid = jid_new(sess->s->req_to, -1);
387  jid_reset_components(sess->resources->jid, username, sess->resources->jid->domain, resource);
388 
389  log_write(sess->c2s->log, LOG_NOTICE, "[%d] requesting session: jid=%s", sess->s->tag, jid_full(sess->resources->jid));
390 
391  /* build a result packet, we'll send this back to the client after we have a session for them */
392  sess->result = nad_new();
393 
394  ns = nad_add_namespace(sess->result, uri_CLIENT, NULL);
395 
396  nad_append_elem(sess->result, ns, "iq", 0);
397  nad_set_attr(sess->result, 0, -1, "type", "result", 6);
398 
399  attr = nad_find_attr(nad, 0, -1, "id", NULL);
400  if(attr >= 0)
401  nad_set_attr(sess->result, 0, -1, "id", NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr));
402 
403  /* start a session with the sm */
404  sm_start(sess, sess->resources);
405 
406  /* finished with the nad */
407  nad_free(nad);
408 
409  return;
410  }
411 
412  _authreg_auth_log(c2s, sess, "traditional", username, resource, FALSE);
413 
414  /* auth failed, so error */
416 
417  return;
418 }
419 
421 static void _authreg_register_get(c2s_t c2s, sess_t sess, nad_t nad) {
422  int attr, ns;
423  char id[128];
424 
425  /* registrations can happen if reg is enabled and we can create users and set passwords */
426  if(sess->active || !(c2s->ar->set_password != NULL && c2s->ar->create_user != NULL && (sess->host->ar_register_enable || sess->host->ar_register_oob))) {
428  return;
429  }
430 
431  /* extract the id */
432  attr = nad_find_attr(nad, 0, -1, "id", NULL);
433  if(attr >= 0)
434  snprintf(id, 128, "%.*s", NAD_AVAL_L(nad, attr), NAD_AVAL(nad, attr));
435 
436  nad_free(nad);
437 
438  /* build a result packet */
439  nad = nad_new();
440 
441  ns = nad_add_namespace(nad, uri_CLIENT, NULL);
442 
443  nad_append_elem(nad, ns, "iq", 0);
444  nad_append_attr(nad, -1, "type", "result");
445 
446  if(attr >= 0)
447  nad_append_attr(nad, -1, "id", id);
448 
449  ns = nad_add_namespace(nad, uri_REGISTER, NULL);
450  nad_append_elem(nad, ns, "query", 1);
451 
452  nad_append_elem(nad, ns, "instructions", 2);
454 
455  if(sess->host->ar_register_enable) {
456  nad_append_elem(nad, ns, "username", 2);
457  nad_append_elem(nad, ns, "password", 2);
458  }
459 
460  if(sess->host->ar_register_oob) {
461  int ns = nad_add_namespace(nad, uri_OOB, NULL);
462  nad_append_elem(nad, ns, "x", 2);
463  nad_append_elem(nad, ns, "url", 3);
464  nad_append_cdata(nad, sess->host->ar_register_oob, strlen(sess->host->ar_register_oob), 4);
465  }
466 
467  /* give it back to the client */
468  sx_nad_write(sess->s, nad);
469 }
470 
472 static void _authreg_register_set(c2s_t c2s, sess_t sess, nad_t nad)
473 {
474  int ns = 0, elem, attr;
475  char username[1024], password[1024];
476 
477  /* if we're not configured for registration (or pw changes), or we can't set passwords, fail outright */
478  if(!(sess->host->ar_register_enable || sess->host->ar_register_password) || c2s->ar->set_password == NULL) {
480  return;
481  }
482 
483  ns = nad_find_scoped_namespace(nad, uri_REGISTER, NULL);
484 
485  /* removals */
486  if(sess->active && nad_find_elem(nad, 1, ns, "remove", 1) >= 0) {
487  /* only if full reg is enabled */
488  if(!sess->host->ar_register_enable) {
490  return;
491  }
492 
493  log_debug(ZONE, "user remove requested");
494 
495  /* make sure we can delete them */
496  if(c2s->ar->delete_user == NULL) {
498  return;
499  }
500 
501  /* otherwise, delete them */
502  if((c2s->ar->delete_user)(c2s->ar, sess->resources->jid->node, sess->host->realm) != 0) {
503  log_debug(ZONE, "user delete failed");
505  return;
506  }
507 
508  log_write(c2s->log, LOG_NOTICE, "[%d] deleted user: user=%s; realm=%s", sess->s->tag, sess->resources->jid->node, sess->host->realm);
509 
510  log_write(c2s->log, LOG_NOTICE, "[%d] registration remove succeeded, requesting user deletion: jid=%s", sess->s->tag, jid_user(sess->resources->jid));
511 
512  /* make a result nad */
513  sess->result = nad_new();
514 
515  ns = nad_add_namespace(sess->result, uri_CLIENT, NULL);
516 
517  nad_append_elem(sess->result, ns, "iq", 0);
518  nad_set_attr(sess->result, 0, -1, "type", "result", 6);
519 
520  /* extract the id */
521  attr = nad_find_attr(nad, 0, -1, "id", NULL);
522  if(attr >= 0)
523  nad_set_attr(sess->result, 0, -1, "id", NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr));
524 
525  nad_free(nad);
526 
527  sx_nad_write(sess->s, sess->result);
528  sess->result = NULL;
529 
530  /* get the sm to delete them (it will force their sessions to end) */
531  sm_delete(sess, sess->resources);
532 
533  return;
534  }
535 
536  /* username is required */
537  elem = nad_find_elem(nad, 1, ns, "username", 1);
538  if(elem < 0)
539  {
540  log_debug(ZONE, "register set with no username, bouncing it");
542  return;
543  }
544 
545  snprintf(username, 1024, "%.*s", NAD_CDATA_L(nad, elem), NAD_CDATA(nad, elem));
546  if(stringprep_xmpp_nodeprep(username, 1024) != 0) {
547  log_debug(ZONE, "register set username failed nodeprep, bouncing it");
549  return;
550  }
551 
552  elem = nad_find_elem(nad, 1, ns, "password", 1);
553  if(elem < 0)
554  {
555  log_debug(ZONE, "register set with no password, bouncing it");
557  return;
558  }
559 
560  /* if they're already auth'd, its a password change */
561  if(sess->active)
562  {
563  /* confirm that the username matches their auth id */
564  if(strcmp(username, sess->resources->jid->node) != 0)
565  {
566  log_debug(ZONE, "%s is trying to change password for %s, bouncing it", jid_full(sess->resources->jid), username);
568  return;
569  }
570  }
571 
572  /* can't go on if we're not doing full reg */
573  else if(!sess->host->ar_register_enable) {
575  return;
576  }
577 
578  /* if they exist, bounce */
579  else if((c2s->ar->user_exists)(c2s->ar, username, sess->host->realm))
580  {
581  log_debug(ZONE, "attempt to register %s, but they already exist", username);
583  return;
584  }
585 
586  /* make sure we can create them */
587  else if(c2s->ar->create_user == NULL)
588  {
590  return;
591  }
592 
593  /* otherwise, create them */
594  else if((c2s->ar->create_user)(c2s->ar, username, sess->host->realm) != 0)
595  {
596  log_debug(ZONE, "user create failed");
598  return;
599  }
600 
601  else
602  log_write(c2s->log, LOG_NOTICE, "[%d] created user: user=%s; realm=%s", sess->s->tag, username, sess->host->realm);
603 
604  /* extract the password */
605  snprintf(password, 257, "%.*s", NAD_CDATA_L(nad, elem), NAD_CDATA(nad, elem));
606 
607  /* change it */
608  if((c2s->ar->set_password)(c2s->ar, username, sess->host->realm, password) != 0)
609  {
610  log_debug(ZONE, "password store failed");
612  return;
613  }
614 
615  log_debug(ZONE, "updated auth creds for %s", username);
616 
617  /* make a result nad */
618  sess->result = nad_new();
619 
620  ns = nad_add_namespace(sess->result, uri_CLIENT, NULL);
621 
622  nad_append_elem(sess->result, ns, "iq", 0);
623  nad_set_attr(sess->result, 0, -1, "type", "result", 6);
624 
625  /* extract the id */
626  attr = nad_find_attr(nad, 0, -1, "id", NULL);
627  if(attr >= 0)
628  nad_set_attr(sess->result, 0, -1, "id", NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr));
629 
630  /* if they're active, then this was just a password change, and we're done */
631  if(sess->active) {
632  log_write(c2s->log, LOG_NOTICE, "[%d] password changed: jid=%s", sess->s->tag, jid_user(sess->resources->jid));
633  sx_nad_write(sess->s, sess->result);
634  sess->result = NULL;
635  return;
636  }
637 
638  /* create new bound jid holder */
639  if(sess->resources == NULL) {
640  sess->resources = (bres_t) calloc(1, sizeof(struct bres_st));
641  }
642 
643  /* our local id */
644  sprintf(sess->resources->c2s_id, "%d", sess->s->tag);
645 
646  /* the user jid for this transaction */
647  sess->resources->jid = jid_new(sess->s->req_to, -1);
648  jid_reset_components(sess->resources->jid, username, sess->resources->jid->domain, sess->resources->jid->resource);
649 
650  log_write(c2s->log, LOG_NOTICE, "[%d] registration succeeded, requesting user creation: jid=%s", sess->s->tag, jid_user(sess->resources->jid));
651 
652  /* get the sm to create them */
653  sm_create(sess, sess->resources);
654 
655  nad_free(nad);
656 
657  return;
658 }
659 
664 int authreg_process(c2s_t c2s, sess_t sess, nad_t nad) {
665  int ns, query, type, authreg = -1, getset = -1;
666 
667  /* need iq */
668  if(NAD_ENAME_L(nad, 0) != 2 || strncmp("iq", NAD_ENAME(nad, 0), 2) != 0)
669  return 1;
670 
671  /* only want auth or register packets */
672  if((ns = nad_find_scoped_namespace(nad, uri_AUTH, NULL)) >= 0 && (query = nad_find_elem(nad, 0, ns, "query", 1)) >= 0)
673  authreg = 0;
674  else if((ns = nad_find_scoped_namespace(nad, uri_REGISTER, NULL)) >= 0 && (query = nad_find_elem(nad, 0, ns, "query", 1)) >= 0)
675  authreg = 1;
676  else
677  return 1;
678 
679  /* if its to someone else, pass it */
680  if(nad_find_attr(nad, 0, -1, "to", NULL) >= 0 && nad_find_attr(nad, 0, -1, "to", sess->s->req_to) < 0)
681  return 1;
682 
683  /* need a type */
684  if((type = nad_find_attr(nad, 0, -1, "type", NULL)) < 0 || NAD_AVAL_L(nad, type) != 3)
685  {
687  return 0;
688  }
689 
690  /* get or set? */
691  if(strncmp("get", NAD_AVAL(nad, type), NAD_AVAL_L(nad, type)) == 0)
692  getset = 0;
693  else if(strncmp("set", NAD_AVAL(nad, type), NAD_AVAL_L(nad, type)) == 0)
694  getset = 1;
695  else
696  {
698  return 0;
699  }
700 
701  /* hand to the correct handler */
702  if(authreg == 0) {
703  /* can't do iq:auth after sasl auth */
704  if(sess->sasl_authd) {
706  return 0;
707  }
708 
709  if(getset == 0) {
710  log_debug(ZONE, "auth get");
711  _authreg_auth_get(c2s, sess, nad);
712  } else if(getset == 1) {
713  log_debug(ZONE, "auth set");
714  _authreg_auth_set(c2s, sess, nad);
715  }
716  }
717 
718  if(authreg == 1) {
719  if(getset == 0) {
720  log_debug(ZONE, "register get");
721  _authreg_register_get(c2s, sess, nad);
722  } else if(getset == 1) {
723  log_debug(ZONE, "register set");
724  _authreg_register_set(c2s, sess, nad);
725  }
726  }
727 
728  /* handled */
729  return 0;
730 }
const char * ip
Definition: sx.h:260
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(* check_response)(authreg_t ar, const char *username, const char *realm, const char *challenge, const char *response)
Definition: c2s.h:349
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:701
int(* delete_user)(authreg_t ar, const char *username, const char *realm)
Definition: c2s.h:338
config_t config
config
Definition: c2s.h:183
#define NAD_CDATA_L(N, E)
Definition: nad.h:186
#define sx_nad_write(s, nad)
Definition: sx.h:166
#define stanza_err_JID_MALFORMED
Definition: util.h:374
int ar_register_enable
registration
Definition: c2s.h:141
c2s_t c2s
Definition: c2s.h:319
const char * jid_user(jid_t jid)
expand and return the user
Definition: jid.c:339
const char * req_to
Definition: sx.h:280
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
#define uri_AUTH
Definition: uri.h:60
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
int(* check_password)(authreg_t ar, 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:331
void nad_append_cdata(nad_t nad, const char *cdata, int len, int depth)
append new cdata to the last elem
Definition: nad.c:709
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:124
void log_write(log_t log, int level, const char *msgfmt,...)
Definition: log.c:104
#define AR_MECH_TRAD_DIGEST
Definition: c2s.h:118
static void _authreg_auth_set(c2s_t c2s, sess_t sess, nad_t nad)
auth set handler
Definition: authreg.c:233
void shahash_r(const char *str, char hashbuf[41])
convenience (originally by Thomas Muldowney)
Definition: str.c:358
int tag
Definition: sx.h:256
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:734
nad_t result
Definition: c2s.h:108
int ar_mechanisms
allowed mechanisms
Definition: c2s.h:253
#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
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:667
void nad_free(nad_t nad)
free that nad
Definition: nad.c:178
#define AR_MECH_TRAD_CRAMMD5
Definition: c2s.h:119
jid_t jid
full bound jid
Definition: c2s.h:61
authreg_t ar
Definition: c2s.h:250
#define AR_MECH_TRAD_PLAIN
Definition: c2s.h:117
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:375
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:664
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:142
int(* user_exists)(authreg_t ar, const char *username, const char *realm)
returns 1 if the user exists, 0 if not
Definition: c2s.h:325
#define NAD_ENAME_L(N, E)
Definition: nad.h:184
const char * realm
our realm (SASL)
Definition: c2s.h:123
int ar_register_password
Definition: c2s.h:144
int compressed
Definition: sx.h:340
#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
int(* create_user)(authreg_t ar, const char *username, const char *realm)
make or break the user (register / register remove)
Definition: c2s.h:337
#define uri_REGISTER
Definition: uri.h:61
#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:148
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:421
int(* ar_module_init_fn)(authreg_t)
type for the module init function
Definition: c2s.h:359
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:337
static void _authreg_register_set(c2s_t c2s, sess_t sess, nad_t nad)
register set handler
Definition: authreg.c:472
int(* create_challenge)(authreg_t ar, const char *username, const char *challenge, int maxlen)
Apple extensions for challenge/response authentication methods.
Definition: c2s.h:348
void(* free)(authreg_t ar)
Definition: c2s.h:340
#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 authreg_free(authreg_t ar)
shutdown the authreg system
Definition: authreg.c:116
int port
Definition: sx.h:264
#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:143
#define uri_OOB
Definition: uri.h:55
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:134
#define stanza_err_OLD_UNAUTH
Definition: util.h:388
log_t log
logging
Definition: c2s.h:186
int(* get_password)(authreg_t ar, const char *username, const char *realm, char password[257])
return this users cleartext password in the array (digest auth, password auth)
Definition: c2s.h:328
authreg_t authreg_init(c2s_t c2s, const char *name)
get a handle for the named module
Definition: authreg.c:40
int(* set_password)(authreg_t ar, const char *username, const char *realm, char password[257])
store this password (register)
Definition: c2s.h:334
int ar_ssl_mechanisms
Definition: c2s.h:254
const char * id
Definition: sx.h:290
#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
C2S_API void sm_delete(sess_t sess, bres_t res)
Definition: sm.c:82
int nad_find_scoped_namespace(nad_t nad, const char *uri, const char *prefix)
find a namespace in scope
Definition: nad.c:290