Index: Makefile.in
===================================================================
--- Makefile.in	(revisión: 650)
+++ Makefile.in	(copia de trabajo)
@@ -27,7 +27,7 @@
 
 prefix = @prefix@
 
-SUBDIRS = @mod_irc@ @mod_pubsub@ @mod_muc@ @eldap@ @web@ stringprep @tls@ @odbc@ @ejabberd_zlib@
+SUBDIRS = @mod_irc@ @mod_pubsub@ @mod_muc@ @eldap@ @web@ stringprep @tls@ @odbc@ @ejabberd_zlib@ @sasl@
 ERLSHLIBS = expat_erl.so
 SOURCES = $(wildcard *.erl)
 BEAMS = $(SOURCES:.erl=.beam)
Index: ejabberd.cfg.example
===================================================================
--- ejabberd.cfg.example	(revisión: 650)
+++ ejabberd.cfg.example	(copia de trabajo)
@@ -95,7 +95,10 @@
 %{auth_method, odbc}.
 %{odbc_server, "DSN=ejabberd;UID=ejabberd;PWD=ejabberd"}.
 
+% If you want to allow SASL authentication:
+{auth_method, [sasl]}.
 
+
 % Host name:
 {hosts, ["localhost"]}.
 
Index: configure.ac
===================================================================
--- configure.ac	(revisión: 650)
+++ configure.ac	(copia de trabajo)
@@ -16,6 +16,10 @@
 AM_WITH_EXPAT
 #locating zlib
 AM_WITH_ZLIB
+#locating zlib
+AM_WITH_ZLIB
+# for SASL
+AM_WITH_SASL
 
 # Checks for typedefs, structures, and compiler characteristics.
 AC_C_CONST
@@ -27,6 +31,7 @@
 AC_FUNC_MALLOC
 AC_HEADER_STDC
 
+AC_MOD_ENABLE(sasl, yes)
 AC_MOD_ENABLE(mod_pubsub, yes)
 AC_MOD_ENABLE(mod_irc, yes)
 AC_MOD_ENABLE(mod_muc, yes)
@@ -55,6 +60,7 @@
 AC_SUBST(db_type)
 
 AC_CONFIG_FILES([Makefile
+                 $make_sasl
                  $make_mod_irc
                  $make_mod_muc
                  $make_mod_pubsub
Index: sasl/ejabberd_auth_sasl.c
===================================================================
--- sasl/ejabberd_auth_sasl.c	(revisión: 0)
+++ sasl/ejabberd_auth_sasl.c	(revisión: 0)
@@ -0,0 +1,175 @@
+#include <stdio.h>
+#include <string.h>
+#include <ei.h>
+#include <erl_driver.h>
+#include <sasl/sasl.h>
+
+typedef struct
+{
+  ErlDrvPort port;
+  
+  /* The SASL context kept for the life of the connection */
+  sasl_conn_t *conn;
+
+} ejabberd_sasl_data;
+
+void sasl_start(ejabberd_sasl_data* data)
+{
+  int result;
+
+  /* Initialize SASL */
+  result=sasl_server_init(NULL,      /* Callbacks supported */
+    "TestServer");  /* Name of the application */
+
+  /* Make a new context for this connection */
+  result=sasl_server_new("ejabberd_auth_sasl", /* Registered name of service */
+    NULL, /* my fully qualified domain name; 
+          NULL says use gethostname() */
+          NULL, /* The user realm used for password
+                lookups; NULL means default to serverFQDN
+                Note: This does not affect Kerberos */
+                NULL, NULL, /* IP Address information strings */
+                NULL, /* Callbacks supported only for this connection */
+                0, /* security flags (security layers are enabled
+                   * using security properties, separately)*/
+                   &data->conn);
+}
+
+int login(ejabberd_sasl_data* data,const char* user,const char* pass)
+{
+  int result;
+  const char *out;
+
+  //printf("login %s %s\r\n",user,pass);
+
+  result=sasl_checkpass(data->conn,user,strlen(user),pass,strlen(pass));
+
+  //printf("%s\r\n",sasl_errstring(result,NULL,NULL));
+
+  if(result==SASL_OK)
+    return 1;
+
+  return 0;
+}
+
+int exist(ejabberd_sasl_data* data,const char* user)
+{
+  int result;
+  const char *out;
+
+  //printf("exist %s\r\n",user);
+
+  result=sasl_user_exists(data->conn,"ejabberd_auth_sasl",NULL,user);
+  
+  //printf("%s\r\n",sasl_errstring(result,NULL,NULL));
+
+  if(result!=SASL_NOUSER)
+    return 1;
+  
+  return 0;
+}
+
+void sasl_stop(ejabberd_sasl_data* data)
+{
+  int result;
+
+  sasl_dispose(&data->conn);
+  sasl_done();
+}
+
+#define DECODE_STRING(buffer, index, result)      \
+    {                                             \
+        int tmp = 0; int size = 0;                \
+        ei_get_type(buffer, index, &tmp, &size);  \
+        result = malloc(size + 1);                \
+        ei_decode_string(buffer, index, result);  \
+    }
+
+#define RETURN_INT(value) \
+    {                                             \
+        ErlDrvBinary* b = driver_alloc_binary(1); \
+        rlen = 1;                                 \
+        b->orig_bytes[0] = value;                 \
+        *rbuf = (char*)b;                         \
+        return rlen;                              \
+    }
+
+static ErlDrvData start( ErlDrvPort port, char* command )
+{
+  printf( "SASL-AUTH driver start\r\n" );
+
+  ejabberd_sasl_data *d = (ejabberd_sasl_data *)driver_alloc( sizeof( ejabberd_sasl_data ));
+  d->port = port;
+  set_port_control_flags( port, PORT_CONTROL_FLAG_BINARY );
+
+  sasl_start(d);
+           
+  return (ErlDrvData)d;
+};
+
+static void stop( ErlDrvData handle ) {
+  sasl_stop(handle);
+
+  driver_free( (char *)handle );
+
+  printf( "SASL-AUTH driver stop\r\n" );
+};
+
+static int er_login(ErlDrvData drv_data, char* buf)
+{
+  int iSize = 0;
+  int iIndex = 0;
+  int iResult = 0;
+  // Parse the version and tuple header
+  ei_decode_version( buf, &iIndex, &iSize );
+  ei_decode_tuple_header( buf, &iIndex, &iSize );
+  if ( iSize == 2 )
+  {
+    const char* user;
+    const char* pass;
+    // The first item in the tuple should be the username
+    DECODE_STRING( buf, &iIndex, user );
+    DECODE_STRING( buf, &iIndex, pass );
+    if(login(drv_data,user,pass))
+      return 1;
+  }else if(iSize==1)
+  {
+    const char* user;
+    DECODE_STRING( buf, &iIndex, user );
+    if(exist(drv_data,user))
+      return 1;
+  }else
+  {
+    ;// wrong args
+  }
+  return 0;
+};
+
+static int control( ErlDrvData drv_data, unsigned int command, char *buf, int len, char** rbuf, int rlen )
+{
+  int iResult;
+  iResult=er_login(drv_data, buf );
+  RETURN_INT( iResult );
+};
+
+static ErlDrvEntry entry =
+{
+  NULL,			/* F_PTR init, N/A */
+  start,		/* L_PTR start, called when port is opened */
+  stop,	        	/* F_PTR stop, called when port is closed */
+  NULL,			/* F_PTR output, called when erlang has sent */
+  NULL,			/* F_PTR ready_input, called when input descriptor ready */
+  NULL,			/* F_PTR ready_output, called when output descriptor ready */
+  "ejabberd_auth_sasl",  /* char *driver_name, the argument to open_port */
+  NULL,			/* F_PTR finish, called when unloaded */
+  NULL,			/* handle */
+  control,		/* F_PTR control, port_command callback */
+  NULL,			/* F_PTR timeout, reserved */
+  NULL			/* F_PTR outputv, reserved */
+};
+
+DRIVER_INIT(ejabberd_auth_sasl) /* must match name in driver_entry */
+{
+  return &entry;
+};
+
Index: sasl/ejabberd_auth_sasl.erl
===================================================================
--- sasl/ejabberd_auth_sasl.erl	(revisión: 0)
+++ sasl/ejabberd_auth_sasl.erl	(revisión: 0)
@@ -0,0 +1,70 @@
+-module(ejabberd_auth_sasl).
+-author('').
+
+-export([
+         start/1,
+         plain_password_required/0, 
+         set_password/3, 
+	 try_register/3,
+         remove_user/2,
+         remove_user/3, 
+         get_password/2,
+         get_password_s/2,
+         is_user_exists/2,
+         get_vh_registered_users/1,
+         check_password/3,
+	 check_password/5
+        ]).
+
+start( _Host ) ->
+  case erl_ddll:load_driver( ejabberd:get_so_path(), ejabberd_auth_sasl) of
+    ok -> ok;
+    {error, already_loaded} -> ok;
+    Error -> exit({error, could_not_load_driver, Error})
+  end.
+
+plain_password_required() ->
+  true.
+
+check_password( User, Server, Password ) ->
+  Port = open_port( { spawn, ejabberd_auth_sasl }, [ binary ] ),
+  Bin = term_to_binary( { User, Password }),
+  Res = port_control( Port, 0, Bin ),
+  case Res of
+    <<1>> -> true;
+    _ -> false
+  end.
+
+check_password( User, Server, Password,  _StreamID, _Digest ) ->
+  check_password( User, Server,  Password ).
+
+set_password( _User, _Server, _Password ) ->
+  { error, not_allowed }.
+
+try_register( _User, _Server, _Password ) ->
+  { error, not_allowed }.
+
+remove_user( _User, _Server ) ->
+  { error, not_allowed }.
+
+remove_user( _User, _Server, _Password ) ->
+  { error, not_allowed }.
+    
+get_vh_registered_users( _Server ) ->
+  [].
+    
+is_user_exists( _User, _Server ) ->
+  Port = open_port( { spawn, ejabberd_auth_sasl }, [ binary ] ),
+  Bin = term_to_binary( { _User }),
+  Res = port_control( Port, 0, Bin ),
+  case Res of
+    <<1>> -> true;
+    _ -> false
+  end.
+
+get_password( _User, _Server ) ->
+  false.
+
+get_password_s( _User, _Server ) ->
+  "".
+
Index: sasl/Makefile.in
===================================================================
--- sasl/Makefile.in	(revisión: 0)
+++ sasl/Makefile.in	(revisión: 0)
@@ -0,0 +1,35 @@
+# $Id: Makefile.in 285 2006-12-11 10:16:21Z $
+
+CC = @CC@
+CFLAGS = @CFLAGS@ @SASL_CFLAGS@ @ERLANG_CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@ @SASL_LIBS@ @ERLANG_LIBS@
+
+SUBDIRS = 
+
+ERLSHLIBS = ../ejabberd_auth_sasl.so
+
+OUTDIR = ..
+EFLAGS = -I .. -pz ..
+OBJS   = \
+	$(OUTDIR)/ejabberd_auth_sasl.beam
+
+all:    $(OBJS) $(ERLSHLIBS)
+
+$(OUTDIR)/%.beam:       %.erl
+	@ERLC@ -W $(EFLAGS) -o $(OUTDIR) $<
+
+$(ERLSHLIBS):	../%.so:	%.c
+	$(CC) -Wall $(CFLAGS) $(LDFLAGS) \
+	$(subst ../,,$(subst .so,.c,$@)) $(LIBS) \
+	-o $@ -fpic -shared
+
+clean:
+	rm -f $(OBJS) $(ERLSHLIBS)
+
+distclean: clean
+	rm -f Makefile
+
+TAGS:
+	etags *.erl[/quote]
Index: aclocal.m4
===================================================================
--- aclocal.m4	(revisión: 650)
+++ aclocal.m4	(copia de trabajo)
@@ -292,3 +292,36 @@
 fi
 ])
 dnl <openssl/>
+
+AC_DEFUN(AM_WITH_SASL,
+[ AC_ARG_WITH(sasl2, [ --with-sasl=PREFIX  prefix where SASL is installed ])
+unset SASL_LIBS;
+unset SASL_CFLAGS;
+
+if test x"$with_sasl" != x; then
+   SASL_CFLAGS="-I$with_sasl/include"
+   SASL_LIBS="-L$with_sasl/lib"
+fi
+
+AC_CHECK_LIB(sasl2, sasl_server_init,
+        [ SASL_LIBS="$SASL_LIBS -lsasl2" sasl_found=yes ],
+        [ sasl_found=no ],
+        "$SASL_LIBS")
+
+if test $sasl_found = no; then
+      AC_MSG_ERROR([Could not find sasl/sasl.h])
+fi
+
+if test $sasl_found = yes; then
+   sasl_save_CFLAGS="$CFLAGS"
+   CFLAGS="$SASL_CFLAGS $CFLAGS"
+   AC_CHECK_HEADERS(sasl/sasl.h, ,$sasl_found=no)
+   if test $sasl_found = no; then
+      AC_MSG_ERROR([Could not find sasl/sasl.h])
+   fi
+   CFLAGS=$sasl_save_CFLAGS
+
+   AC_SUBST(SASL_CFLAGS)
+   AC_SUBST(SASL_LIBS)
+fi
+])
