virtual EModRet OnLoginAttempt(CSmartPtr<CAuthBase> Auth) { CString const user(Auth->GetUsername()); CString const pass(Auth->GetPassword()); CUser* pUser(CZNC::Get().FindUser(user)); sasl_conn_t *sasl_conn(0); if (!pUser) { // @todo Will want to do some sort of && !m_bAllowCreate in the future Auth->RefuseLogin("Invalid User - Halting SASL Authentication"); return HALT; } CString const key(CString(user + ":" + pass).MD5()); if (m_Cache.HasItem(key)) { Auth->AcceptLogin(*pUser); DEBUG("+++ Found in cache"); } else if (sasl_server_new("znc", NULL, NULL, NULL, NULL, cbs, 0, &sasl_conn) == SASL_OK && sasl_checkpass(sasl_conn, user.c_str(), user.size(), pass.c_str(), pass.size()) == SASL_OK) { Auth->AcceptLogin(*pUser); m_Cache.AddItem(key); DEBUG("+++ Successful SASL password check"); } else { Auth->RefuseLogin("SASL Authentication failed"); DEBUG("--- FAILED SASL password check"); } sasl_dispose(&sasl_conn); return HALT; }
static int chk_sasl( const struct berval *sc, const struct berval * passwd, const struct berval * cred, const char **text ) { unsigned int i; int rtn; void *ctx, *sconn = NULL; for( i=0; i<cred->bv_len; i++) { if(cred->bv_val[i] == '\0') { return LUTIL_PASSWD_ERR; /* NUL character in password */ } } if( cred->bv_val[i] != '\0' ) { return LUTIL_PASSWD_ERR; /* cred must behave like a string */ } for( i=0; i<passwd->bv_len; i++) { if(passwd->bv_val[i] == '\0') { return LUTIL_PASSWD_ERR; /* NUL character in password */ } } if( passwd->bv_val[i] != '\0' ) { return LUTIL_PASSWD_ERR; /* passwd must behave like a string */ } rtn = LUTIL_PASSWD_ERR; ctx = ldap_pvt_thread_pool_context(); ldap_pvt_thread_pool_getkey( ctx, (void *)slap_sasl_bind, &sconn, NULL ); if( sconn != NULL ) { int sc; sc = sasl_checkpass( sconn, passwd->bv_val, passwd->bv_len, cred->bv_val, cred->bv_len ); rtn = ( sc != SASL_OK ) ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK; } return rtn; }
virtual EModRet OnLoginAttempt(CSmartPtr<CAuthBase> Auth) { const CString& sUsername = Auth->GetUsername(); const CString& sPassword = Auth->GetPassword(); CUser *pUser(CZNC::Get().FindUser(sUsername)); sasl_conn_t *sasl_conn(NULL); bool bSuccess = false; if (!pUser && !CreateUser()) { return CONTINUE; } const CString sCacheKey(CString(sUsername + ":" + sPassword).MD5()); if (m_Cache.HasItem(sCacheKey)) { bSuccess = true; DEBUG("saslauth: Found [" + sUsername + "] in cache"); } else if (sasl_server_new("znc", NULL, NULL, NULL, NULL, m_cbs, 0, &sasl_conn) == SASL_OK && sasl_checkpass(sasl_conn, sUsername.c_str(), sUsername.size(), sPassword.c_str(), sPassword.size()) == SASL_OK) { m_Cache.AddItem(sCacheKey); DEBUG("saslauth: Successful SASL authentication [" + sUsername + "]"); bSuccess = true; } sasl_dispose(&sasl_conn); if (bSuccess) { if (!pUser) { CString sErr; pUser = new CUser(sUsername); if (ShouldCloneUser()) { CUser *pBaseUser = CZNC::Get().FindUser(CloneUser()); if (!pBaseUser) { DEBUG("saslauth: Clone User [" << CloneUser() << "] User not found"); delete pUser; pUser = NULL; } if (pUser && !pUser->Clone(*pBaseUser, sErr)) { DEBUG("saslauth: Clone User [" << CloneUser() << "] failed: " << sErr); delete pUser; pUser = NULL; } } if (pUser) { // "::" is an invalid MD5 hash, so user won't be able to login by usual method pUser->SetPass("::", CUser::HASH_MD5, "::"); } if (pUser && !CZNC::Get().AddUser(pUser, sErr)) { DEBUG("saslauth: Add user [" << sUsername << "] failed: " << sErr); delete pUser; pUser = NULL; } } if (pUser) { Auth->AcceptLogin(*pUser); return HALT; } } return CONTINUE; }
int main(int argc, char **argv) { const char *user, *realm, *passwd, *service, *mechs, **globals, *err; int c, ret; sasl_callback_t callbacks[] = { {SASL_CB_GETOPT, my_getopt, NULL}, {SASL_CB_LIST_END}, }; sasl_conn_t *connection; char hostname[512]; char fulluser[512]; /* XXX: may overflow */ user = realm = passwd = service = ""; strcpy(hostname, "localhost"); gethostname(hostname, sizeof(hostname)); while ((c = getopt(argc, argv, "u:r:p:s:h:12v")) != -1) { switch (c) { case 'u': user = optarg; break; case 'r': realm = optarg; break; case 'p': passwd = optarg; break; case 's': service = optarg; break; case 'h': strncpy(hostname, optarg, sizeof(hostname) - 1); hostname[sizeof(hostname) - 1] = '\0'; break; case '1': main_requested_sasl_version = 1; break; case '2': main_requested_sasl_version = 2; break; case 'v': main_verbose++; break; default: printf("Usage: %s [-v] [-1] [-2] " "[-h hostname] " "[-u user] " "[-r realm] " "[-p password] " "[-s service] " "\n", argv[0]); return 2; break; } } if ((strlen(user) == 0) || (strlen(passwd) == 0)) { printf("Usage: %s [-v] [-1] [-2] " "[-h hostname] " "[-u user] " "[-r realm] " "[-p password] " "[-s service] " "\n", argv[0]); return 2; } if (realm && (strlen(realm) > 0)) { sprintf(fulluser, "%s@%s", user, realm); } else { sprintf(fulluser, "%s", user); } ret = sasl_server_init(callbacks, strlen(service) ? service : "sasl-checkpass"); if (ret != SASL_OK) { fprintf(stderr, "Error in sasl_server_init(): %s\n", sasl_errstring(ret, NULL, NULL)); } connection = NULL; ret = sasl_server_new(strlen(service) ? service : "sasl-checkpass", hostname, NULL, #ifdef SASL2 NULL, NULL, #endif callbacks, 0, &connection); if (ret != SASL_OK) { fprintf(stderr, "Error in sasl_server_new(): %s\n", sasl_errstring(ret, NULL, NULL)); } err = NULL; ret = sasl_checkpass(connection, fulluser, strlen(fulluser), passwd, strlen(passwd) #ifndef SASL2 , &err #endif ); switch (ret) { case SASL_OK: printf("OK\n"); break; default: printf("NO: %d", ret); switch (ret) { case SASL_FAIL: err = "generic failure"; break; case SASL_BADAUTH: err = "authentication failure"; break; default: err = NULL; break; } if (err) { printf(" (%s)", err); } printf("\n"); break; } return ret; }
int main(int argc, char *argv[]) { char line[8192]; char *username, *password; #if SASL_VERSION_MAJOR < 2 const char *errstr; #endif int rc; sasl_conn_t *conn = NULL; /* make standard output line buffered */ setvbuf(stdout, NULL, _IOLBF, 0); rc = sasl_server_init( NULL, APP_NAME_SASL ); if ( rc != SASL_OK ) { fprintf( stderr, "error %d %s\n", rc, sasl_errstring(rc, NULL, NULL )); fprintf( stdout, "ERR\n" ); return 1; } #if SASL_VERSION_MAJOR < 2 rc = sasl_server_new( APP_NAME_SASL, NULL, NULL, NULL, 0, &conn ); #else rc = sasl_server_new( APP_NAME_SASL, NULL, NULL, NULL, NULL, NULL, 0, &conn ); #endif if ( rc != SASL_OK ) { fprintf( stderr, "error %d %s\n", rc, sasl_errstring(rc, NULL, NULL )); fprintf( stdout, "ERR\n" ); return 1; } while ( fgets( line, sizeof( line ), stdin )) { username = &line[0]; password = strchr( line, '\n' ); if ( !password) { fprintf( stderr, "authenticator: Unexpected input '%s'\n", line ); fprintf( stdout, "ERR\n" ); continue; } *password = '******'; password = strchr ( line, ' ' ); if ( !password) { fprintf( stderr, "authenticator: Unexpected input '%s'\n", line ); fprintf( stdout, "ERR\n" ); continue; } *password++ = '\0'; rfc1738_unescape(username); rfc1738_unescape(password); #if SASL_VERSION_MAJOR < 2 rc = sasl_checkpass(conn, username, strlen(username), password, strlen(password), &errstr); #else rc = sasl_checkpass(conn, username, strlen(username), password, strlen(password)); #endif if ( rc != SASL_OK ) { #if SASL_VERSION_MAJOR < 2 if ( errstr ) { fprintf( stderr, "errstr %s\n", errstr ); } if ( rc != SASL_BADAUTH ) { fprintf( stderr, "error %d %s\n", rc, sasl_errstring(rc, NULL, NULL )); } #endif fprintf( stdout, "ERR\n" ); } else { fprintf( stdout, "OK\n" ); } } sasl_dispose( &conn ); sasl_done(); return 0; }