Only in cyrus-sasl-2.1.22: autom4te.cache diff -ur cyrus-sasl-2.1.22~/config.h.in cyrus-sasl-2.1.22/config.h.in --- cyrus-sasl-2.1.22~/config.h.in Thu May 18 15:38:02 2006 +++ cyrus-sasl-2.1.22/config.h.in Mon Dec 17 14:07:18 2007 @@ -416,6 +416,9 @@ /* use the doors IPC API for saslauthd? */ #undef USE_DOORS +/* Use KCRAP support */ +#undef USE_KCRAP + /* Version number of package */ #undef VERSION Only in cyrus-sasl-2.1.22: config.h.in~ diff -ur cyrus-sasl-2.1.22~/configure.in cyrus-sasl-2.1.22/configure.in --- cyrus-sasl-2.1.22~/configure.in Thu May 18 15:06:13 2006 +++ cyrus-sasl-2.1.22/configure.in Mon Dec 17 14:06:10 2007 @@ -608,6 +608,33 @@ AC_MSG_RESULT(disabled) fi +dnl KCRAP +AC_ARG_ENABLE(kcrap, [ --enable-kcrap enable experimental NTLM through KCRAP authentication [[auto]] ], + kcrap=$enableval, + kcrap=auto) + +if test "$kcrap" != auto; then + AC_CHECK_HEADER(kcrap.h,[ + AC_CHECK_LIB(kcrap, kcrap_try, [ + kcrap=yes + ], [ kcrap=no ]) + ], [ kcrap=no ]) +fi + +AC_MSG_CHECKING(KCRAP) +if test "$kcrap" != no; then + AC_MSG_RESULT(enabled) + if test "$ntlm" = no; then + AC_MSG_ERROR(Must enable NTLM for KCRAP) + fi + NTLM_LIBS="$NTLM_LIBS -lkcrap" + AC_SUBST(NTLM_LIBS) + AC_DEFINE(USE_KCRAP,[],[Use KCRAP support]) +else + AC_MSG_RESULT(disabled) +fi + + dnl PASSDSS AC_ARG_ENABLE(passdss, [ --enable-passdss enable PASSDSS authentication (experimental) [[no]] ], passdss=$enableval, diff -ur cyrus-sasl-2.1.22~/plugins/ntlm.c cyrus-sasl-2.1.22/plugins/ntlm.c --- cyrus-sasl-2.1.22~/plugins/ntlm.c Thu Jul 7 12:10:14 2005 +++ cyrus-sasl-2.1.22/plugins/ntlm.c Mon Dec 17 14:46:36 2007 @@ -91,6 +92,10 @@ DES_ecb_encrypt((i),(o),&(k),(e)) #endif /* OpenSSL 0.9.7+ w/o old DES support */ +#ifdef USE_KCRAP +# include +#endif + #include #define MD5_H /* suppress internal MD5 */ #include @@ -464,6 +469,8 @@ /***************************** Server Section *****************************/ +struct kcrap_context; + typedef struct server_context { int state; @@ -476,6 +483,7 @@ /* socket to remote authentication host */ SOCKET sock; + struct kcrap_context *kcrap; } server_context_t; @@ -1364,6 +1372,10 @@ server_context_t *text; const char *serv; unsigned int len; +#ifdef USE_KCRAP + const char *keytab_file; + unsigned int ktlen; +#endif SOCKET sock = (SOCKET) -1; sparams->utils->getopt(sparams->utils->getopt_context, @@ -1385,6 +1397,17 @@ text->state = 1; text->sock = sock; + +#ifdef USE_KCRAP + sparams->utils->getopt(sparams->utils->getopt_context, + "KCRAP", "keytab_file", &keytab_file, &ktlen); + text->kcrap = kcrap_init(keytab_file, NULL); + if (text->kcrap == NULL) { + sparams->utils->log(NULL, SASL_LOG_WARN, "Cannot initialize KCRAP: %s", kcrap_errmsg()); + } +#else + text->kcrap = NULL; +#endif *conn_context = text; @@ -1514,7 +1537,68 @@ if (domain) sparams->utils->log(NULL, SASL_LOG_DEBUG, "client domain: %s", domain); - if (text->sock == -1) { +#ifdef USE_KCRAP +# define KCRAP_SDATA(VAR,VAL) (VAR).data = (VAL), (VAR).length = strlen((VAR).data) + if (text->kcrap && nt_resp) { + struct kcrap_auth_req_data req; + static const unsigned char zeros[16] = { 0, }; + int auth_status; + + bzero(&req, sizeof(req)); + if (nt_resp_len > NTLM_RESP_LENGTH) { + /* NTLM V2 */ + KCRAP_SDATA(req.chal_type, "NTLM2"); + req.principal.length = authid_len; + req.principal.data = authid; + req.alt_username.length = domain_len; + req.alt_username.data = domain; + req.server_challenge.length = NTLM_NONCE_LENGTH; + req.server_challenge.data = text->nonce; + req.client_challenge.length = nt_resp_len - MD5_DIGEST_LENGTH; + req.client_challenge.data = nt_resp + MD5_DIGEST_LENGTH; + req.response.length = MD5_DIGEST_LENGTH; + req.response.data = nt_resp; + } else if (lm_resp && memcmp(lm_resp+8, zeros, 16) == 0 && + memcmp(lm_resp, zeros, 8) != 0) { + KCRAP_SDATA(req.chal_type, "NTLM2S"); + req.principal.length = authid_len; + req.principal.data = authid; + req.server_challenge.length = NTLM_NONCE_LENGTH; + req.server_challenge.data = text->nonce; + req.client_challenge.length = 8; + req.client_challenge.data = lm_resp; + req.response.length = nt_resp_len; + req.response.data = nt_resp; + } else { + /* NTLM V1 */ + KCRAP_SDATA(req.chal_type, "NTLM"); + req.principal.length = authid_len; + req.principal.data = authid; + req.server_challenge.length = NTLM_NONCE_LENGTH; + req.server_challenge.data = text->nonce; + req.response.length = nt_resp_len; + req.response.data = nt_resp; + } + result = kcrap_try(text->kcrap, &req, &auth_status); + if (result != 0) { + sparams->utils->log(NULL, SASL_LOG_WARN, "NTLM: KCRAP error: %s\n", kcrap_errmsg()); + SETERROR(sparams->utils, "internal error authenticating with KCRAP"); + result = SASL_FAIL; + goto cleanup; + } else if (auth_status == 0) { + SETERROR(sparams->utils, "incorrect NTLM response"); + result = SASL_BADAUTH; + goto cleanup; + } else { + sparams->utils->log(NULL, SASL_LOG_WARN, "NTLM: KCRAP ok\n"); + + result = sparams->canon_user(sparams->utils->conn, authid, authid_len, + SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams); + if (result != SASL_OK) goto cleanup; + } + } else +#endif + if (text->sock == -1) { /* verify the response internally */ sasl_secret_t *password = NULL; @@ -1697,6 +1781,9 @@ if (text->out_buf) utils->free(text->out_buf); if (text->sock != -1) closesocket(text->sock); +#ifdef USE_KCRAP + if (text->kcrap) kcrap_free(text->kcrap); +#endif utils->free(text); }