CPD Results

The following document contains the results of PMD's CPD 6.55.0.

Duplications

File Project Line
waffle/servlet/NegotiateSecurityFilter.java waffle-jna-jakarta 63
waffle/servlet/NegotiateSecurityFilter.java waffle-jna 62
public class NegotiateSecurityFilter implements Filter {

    /** The Constant LOGGER. */
    private static final Logger LOGGER = LoggerFactory.getLogger(NegotiateSecurityFilter.class);

    /** The Constant PRINCIPALSESSIONKEY. */
    private static final String PRINCIPALSESSIONKEY = NegotiateSecurityFilter.class.getName() + ".PRINCIPAL";

    /** The windows flag. */
    private static Boolean windows;

    /** The principal format. */
    private PrincipalFormat principalFormat = PrincipalFormat.FQN;

    /** The role format. */
    private PrincipalFormat roleFormat = PrincipalFormat.FQN;

    /** The providers. */
    private SecurityFilterProviderCollection providers;

    /** The auth. */
    private IWindowsAuthProvider auth;

    /** The exclusion filter. */
    private String[] excludePatterns;

    /** The allow guest login. */
    private boolean allowGuestLogin = true;

    /** The impersonate. */
    private boolean impersonate;

    /** The exclusion bearer authorization. */
    private boolean excludeBearerAuthorization;

    /** The exclusions cors pre flight. */
    private boolean excludeCorsPreflight;

    /** The disable SSO. */
    private boolean disableSSO;

    /**
     * Instantiates a new negotiate security filter.
     */
    public NegotiateSecurityFilter() {
        NegotiateSecurityFilter.LOGGER.debug("[waffle.servlet.NegotiateSecurityFilter] loaded");
    }

    @Override
    public void destroy() {
        NegotiateSecurityFilter.LOGGER.info("[waffle.servlet.NegotiateSecurityFilter] stopped");
    }

    @Override
    public void doFilter(final ServletRequest sreq, final ServletResponse sres, final FilterChain chain)
            throws IOException, ServletException {

        final HttpServletRequest request = (HttpServletRequest) sreq;
        final HttpServletResponse response = (HttpServletResponse) sres;

        NegotiateSecurityFilter.LOGGER.debug("{} {}, contentlength: {}", request.getMethod(), request.getRequestURI(),
                Integer.valueOf(request.getContentLength()));

        // If we are not in a windows environment, resume filter chain
        if (!NegotiateSecurityFilter.isWindows()) {
            NegotiateSecurityFilter.LOGGER.debug("Running in a non windows environment, SSO skipped");
            chain.doFilter(request, response);
            return;
        }

        // If sso is disabled, resume filter chain
        if (this.disableSSO) {
            NegotiateSecurityFilter.LOGGER.debug("SSO is disabled, resuming filter chain");
            chain.doFilter(request, response);
            return;
        }

        // If excluded URL, resume the filter chain
        if (request.getRequestURL() != null && this.excludePatterns != null) {
            final String url = request.getRequestURL().toString();
            for (final String pattern : this.excludePatterns) {
                if (url.matches(pattern)) {
                    NegotiateSecurityFilter.LOGGER.info("Pattern :{} excluded URL:{}", url, pattern);
                    chain.doFilter(sreq, sres);
                    return;
                }
            }
        }

        // If exclude cores pre-flight and is pre flight, resume the filter chain
        if (this.excludeCorsPreflight && CorsPreFlightCheck.isPreflight(request)) {
            NegotiateSecurityFilter.LOGGER.debug("[waffle.servlet.NegotiateSecurityFilter] CORS preflight");
            chain.doFilter(sreq, sres);
            return;
        }

        final AuthorizationHeader authorizationHeader = new AuthorizationHeader(request);

        // If exclude bearer authorization and is bearer authorization, result the filter chain
        if (this.excludeBearerAuthorization && authorizationHeader.isBearerAuthorizationHeader()) {
            NegotiateSecurityFilter.LOGGER.debug("[waffle.servlet.NegotiateSecurityFilter] Authorization: Bearer");
            chain.doFilter(sreq, sres);
            return;
        }

        if (this.doFilterPrincipal(request, response, chain)) {
            // previously authenticated user
            return;
        }

        // authenticate user
        if (!authorizationHeader.isNull()) {

            // log the user in using the token
            IWindowsIdentity windowsIdentity;
            try {
                windowsIdentity = this.providers.doFilter(request, response);
                if (windowsIdentity == null) {
                    return;
                }
            } catch (final IOException e) {
                NegotiateSecurityFilter.LOGGER.warn("error logging in user: {}", e.getMessage());
                NegotiateSecurityFilter.LOGGER.trace("", e);
                this.sendUnauthorized(response, true);
                return;
            }

            IWindowsImpersonationContext ctx = null;
            try {
                if (!this.allowGuestLogin && windowsIdentity.isGuest()) {
                    NegotiateSecurityFilter.LOGGER.warn("guest login disabled: {}", windowsIdentity.getFqn());
                    this.sendUnauthorized(response, true);
                    return;
                }

                NegotiateSecurityFilter.LOGGER.debug("logged in user: {} ({})", windowsIdentity.getFqn(),
                        windowsIdentity.getSidString());

                final HttpSession session = request.getSession(true);
                if (session == null) {
                    throw new ServletException("Expected HttpSession");
                }

                Subject subject = (Subject) session.getAttribute("javax.security.auth.subject");
                if (subject == null) {
                    subject = new Subject();
                }

                WindowsPrincipal windowsPrincipal;
                if (this.impersonate) {
                    windowsPrincipal = new AutoDisposableWindowsPrincipal(windowsIdentity, this.principalFormat,
                            this.roleFormat);
                } else {
                    windowsPrincipal = new WindowsPrincipal(windowsIdentity, this.principalFormat, this.roleFormat);
                }

                NegotiateSecurityFilter.LOGGER.debug("roles: {}", windowsPrincipal.getRolesString());
                subject.getPrincipals().add(windowsPrincipal);
                request.getSession(false).setAttribute("javax.security.auth.subject", subject);

                NegotiateSecurityFilter.LOGGER.info("successfully logged in user: {}", windowsIdentity.getFqn());

                request.getSession(false).setAttribute(NegotiateSecurityFilter.PRINCIPALSESSIONKEY, windowsPrincipal);

                final NegotiateRequestWrapper requestWrapper = new NegotiateRequestWrapper(request, windowsPrincipal);

                if (this.impersonate) {
                    NegotiateSecurityFilter.LOGGER.debug("impersonating user");
                    ctx = windowsIdentity.impersonate();
                }

                chain.doFilter(requestWrapper, response);
            } finally {
                if (this.impersonate && ctx != null) {
                    NegotiateSecurityFilter.LOGGER.debug("terminating impersonation");
                    ctx.revertToSelf();
                } else {
                    windowsIdentity.dispose();
                }
            }

            return;
        }

        NegotiateSecurityFilter.LOGGER.debug("authorization required");
        this.sendUnauthorized(response, false);
    }

    /**
     * Filter for a previously logged on user.
     *
     * @param request
     *            HTTP request.
     * @param response
     *            HTTP response.
     * @param chain
     *            Filter chain.
     *
     * @return True if a user already authenticated.
     *
     * @throws IOException
     *             Signals that an I/O exception has occurred.
     * @throws ServletException
     *             the servlet exception
     */
    private boolean doFilterPrincipal(final HttpServletRequest request, final HttpServletResponse response,
            final FilterChain chain) throws IOException, ServletException {
        Principal principal = request.getUserPrincipal();
        if (principal == null) {
            final HttpSession session = request.getSession(false);
            if (session != null) {
                principal = (Principal) session.getAttribute(NegotiateSecurityFilter.PRINCIPALSESSIONKEY);
            }
        }

        if (principal == null) {
            // no principal in this request
            return false;
        }

        if (this.providers.isPrincipalException(request)) {
            // the providers signal to authenticate despite an existing principal, eg. NTLM post
            return false;
        }

        // user already authenticated
        if (principal instanceof WindowsPrincipal) {
            NegotiateSecurityFilter.LOGGER.debug("previously authenticated Windows user: {}", principal.getName());
            final WindowsPrincipal windowsPrincipal = (WindowsPrincipal) principal;

            if (this.impersonate && windowsPrincipal.getIdentity() == null) {
                // This can happen when the session has been serialized then de-serialized
                // and because the IWindowsIdentity field is transient. In this case re-ask an
                // authentication to get a new identity.
                return false;
            }

            final NegotiateRequestWrapper requestWrapper = new NegotiateRequestWrapper(request, windowsPrincipal);

            IWindowsImpersonationContext ctx = null;
            if (this.impersonate) {
                NegotiateSecurityFilter.LOGGER.debug("re-impersonating user");
                ctx = windowsPrincipal.getIdentity().impersonate();
            }
            try {
                chain.doFilter(requestWrapper, response);
            } finally {
                if (this.impersonate && ctx != null) {
                    NegotiateSecurityFilter.LOGGER.debug("terminating impersonation");
                    ctx.revertToSelf();
                }
            }
        } else {
            NegotiateSecurityFilter.LOGGER.debug("previously authenticated user: {}", principal.getName());
            chain.doFilter(request, response);
        }
        return true;
    }

    @Override
    public void init(final FilterConfig filterConfig) throws ServletException {
        final Map<String, String> implParameters = new HashMap<>();

        NegotiateSecurityFilter.LOGGER.debug("[waffle.servlet.NegotiateSecurityFilter] starting");

        String authProvider = null;
        String[] providerNames = null;
        if (filterConfig != null) {
            final List<String> parameterNames = Collections.list(filterConfig.getInitParameterNames());
            NegotiateSecurityFilter.LOGGER.debug("[waffle.servlet.NegotiateSecurityFilter] processing filterConfig");
            for (String parameterName : parameterNames) {
                final String parameterValue = filterConfig.getInitParameter(parameterName);
                NegotiateSecurityFilter.LOGGER.debug("Init Param: '{}={}'", parameterName, parameterValue);
                switch (parameterName) {
                    case "principalFormat":
                        this.principalFormat = PrincipalFormat.valueOf(parameterValue.toUpperCase(Locale.ENGLISH));
                        break;
                    case "roleFormat":
                        this.roleFormat = PrincipalFormat.valueOf(parameterValue.toUpperCase(Locale.ENGLISH));
                        break;
                    case "allowGuestLogin":
                        this.allowGuestLogin = Boolean.parseBoolean(parameterValue);
                        break;
                    case "impersonate":
                        this.impersonate = Boolean.parseBoolean(parameterValue);
                        break;
                    case "securityFilterProviders":
                        providerNames = parameterValue.split("\\s+", -1);
                        break;
                    case "authProvider":
                        authProvider = parameterValue;
                        break;
                    case "excludePatterns":
                        this.excludePatterns = parameterValue.split("\\s+", -1);
                        break;
                    case "excludeCorsPreflight":
                        this.excludeCorsPreflight = Boolean.parseBoolean(parameterValue);
                        break;
                    case "excludeBearerAuthorization":
                        this.excludeBearerAuthorization = Boolean.parseBoolean(parameterValue);
                        break;
                    case "disableSSO":
                        this.disableSSO = Boolean.parseBoolean(parameterValue);
                        break;
                    default:
                        implParameters.put(parameterName, parameterValue);
                        break;
                }
            }
        }

        NegotiateSecurityFilter.LOGGER.debug("[waffle.servlet.NegotiateSecurityFilter] authProvider");
        if (authProvider != null) {
            try {
                this.auth = (IWindowsAuthProvider) Class.forName(authProvider).getConstructor().newInstance();
            } catch (final ClassNotFoundException | IllegalArgumentException | SecurityException
                    | InstantiationException | IllegalAccessException | InvocationTargetException
                    | NoSuchMethodException e) {
                throw new ServletException(e);
            }
        }

        if (this.auth == null) {
            this.auth = new WindowsAuthProviderImpl();
        }

        if (providerNames != null) {
            this.providers = new SecurityFilterProviderCollection(providerNames, this.auth);
        }

        // create default providers if none specified
        if (this.providers == null) {
            NegotiateSecurityFilter.LOGGER.debug("initializing default security filter providers");
            this.providers = new SecurityFilterProviderCollection(this.auth);
        }

        // apply provider implementation parameters
        NegotiateSecurityFilter.LOGGER.debug("[waffle.servlet.NegotiateSecurityFilter] load provider parameters");
        for (final Map.Entry<String, String> implParameter : implParameters.entrySet()) {
            final String[] classAndParameter = implParameter.getKey().split("/", 2);
            if (classAndParameter.length == 2) {
                try {

                    NegotiateSecurityFilter.LOGGER.debug("setting {}, {}={}", classAndParameter[0],
                            classAndParameter[1], implParameter.getValue());

                    final SecurityFilterProvider provider = this.providers.getByClassName(classAndParameter[0]);
                    provider.initParameter(classAndParameter[1], implParameter.getValue());

                } catch (final ClassNotFoundException e) {
                    NegotiateSecurityFilter.LOGGER.error("invalid class: {} in {}", classAndParameter[0],
                            implParameter.getKey());
                    throw new ServletException(e);
                } catch (final Exception e) {
                    NegotiateSecurityFilter.LOGGER.error("Error setting {} in {}", classAndParameter[0],
                            classAndParameter[1]);
                    throw new ServletException(e);
                }
            } else {
                NegotiateSecurityFilter.LOGGER.error("Invalid parameter: {}", implParameter.getKey());
                throw new ServletException("Invalid parameter: " + implParameter.getKey());
            }
        }

        NegotiateSecurityFilter.LOGGER.info("[waffle.servlet.NegotiateSecurityFilter] started");
    }

    /**
     * Set the principal format.
     *
     * @param format
     *            Principal format.
     */
    public void setPrincipalFormat(final String format) {
        this.principalFormat = PrincipalFormat.valueOf(format.toUpperCase(Locale.ENGLISH));
        NegotiateSecurityFilter.LOGGER.info("principal format: {}", this.principalFormat);
    }

    /**
     * Principal format.
     *
     * @return Principal format.
     */
    public PrincipalFormat getPrincipalFormat() {
        return this.principalFormat;
    }

    /**
     * Set the principal format.
     *
     * @param format
     *            Role format.
     */
    public void setRoleFormat(final String format) {
        this.roleFormat = PrincipalFormat.valueOf(format.toUpperCase(Locale.ENGLISH));
        NegotiateSecurityFilter.LOGGER.info("role format: {}", this.roleFormat);
    }

    /**
     * Principal format.
     *
     * @return Role format.
     */
    public PrincipalFormat getRoleFormat() {
        return this.roleFormat;
    }

    /**
     * Send a 401 Unauthorized along with protocol authentication headers.
     *
     * @param response
     *            HTTP Response
     * @param close
     *            Close connection.
     */
    private void sendUnauthorized(final HttpServletResponse response, final boolean close) {
        try {
            this.providers.sendUnauthorized(response);
            if (close) {
                response.setHeader("Connection", "close");
            } else {
                response.setHeader("Connection", "keep-alive");
            }
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
            response.flushBuffer();
        } catch (final IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Windows auth provider.
     *
     * @return IWindowsAuthProvider.
     */
    public IWindowsAuthProvider getAuth() {
        return this.auth;
    }

    /**
     * Set Windows auth provider.
     *
     * @param provider
     *            Class implements IWindowsAuthProvider.
     */
    public void setAuth(final IWindowsAuthProvider provider) {
        this.auth = provider;
    }

    /**
     * True if guest login is allowed.
     *
     * @return True if guest login is allowed, false otherwise.
     */
    public boolean isAllowGuestLogin() {
        return this.allowGuestLogin;
    }

    /**
     * Enable/Disable impersonation.
     *
     * @param value
     *            true to enable impersonation, false otherwise
     */
    public void setImpersonate(final boolean value) {
        this.impersonate = value;
    }

    /**
     * Checks if is impersonate.
     *
     * @return true if impersonation is enabled, false otherwise
     */
    public boolean isImpersonate() {
        return this.impersonate;
    }

    /**
     * Security filter providers.
     *
     * @return A collection of security filter providers.
     */
    public SecurityFilterProviderCollection getProviders() {
        return this.providers;
    }

    private static boolean isWindows() {
        if (NegotiateSecurityFilter.windows == null) {
            NegotiateSecurityFilter.windows = System.getProperty("os.name").toLowerCase(Locale.ENGLISH).contains("win");
        }
        return NegotiateSecurityFilter.windows.booleanValue();
    }

}
File Project Line
waffle/apache/MixedAuthenticator.java waffle-tomcat10 52
waffle/apache/MixedAuthenticator.java waffle-tomcat85 52
waffle/apache/MixedAuthenticator.java waffle-tomcat9 52
public class MixedAuthenticator extends WaffleAuthenticatorBase {

    /**
     * Instantiates a new mixed authenticator.
     */
    public MixedAuthenticator() {
        super();
        this.log = LoggerFactory.getLogger(MixedAuthenticator.class);
        this.info = "waffle.apache.MixedAuthenticator/1.0";
        this.log.debug("[waffle.apache.MixedAuthenticator] loaded");
    }

    @Override
    public synchronized void startInternal() throws LifecycleException {
        this.log.info("[waffle.apache.MixedAuthenticator] started");
        super.startInternal();
    }

    @Override
    public synchronized void stopInternal() throws LifecycleException {
        super.stopInternal();
        this.log.info("[waffle.apache.MixedAuthenticator] stopped");
    }

    @Override
    public boolean authenticate(final Request request, final HttpServletResponse response) {

        // realm: fail if no realm is configured
        if (this.context == null || this.context.getRealm() == null) {
            this.log.warn("missing context/realm");
            this.sendError(response, HttpServletResponse.SC_SERVICE_UNAVAILABLE);
            return false;
        }

        this.log.debug("{} {}, contentlength: {}", request.getMethod(), request.getRequestURI(),
                Integer.valueOf(request.getContentLength()));

        final boolean negotiateCheck = request.getParameter("j_negotiate_check") != null;
        this.log.debug("negotiateCheck: {}", Boolean.valueOf(negotiateCheck));
        final boolean securityCheck = request.getParameter("j_security_check") != null;
        this.log.debug("securityCheck: {}", Boolean.valueOf(securityCheck));

        final Principal principal = request.getUserPrincipal();

        final AuthorizationHeader authorizationHeader = new AuthorizationHeader(request);
        final boolean ntlmPost = authorizationHeader.isNtlmType1PostAuthorizationHeader();
        this.log.debug("authorization: {}, ntlm post: {}", authorizationHeader, Boolean.valueOf(ntlmPost));

        final LoginConfig loginConfig = this.context.getLoginConfig();

        if (principal != null && !ntlmPost) {
            this.log.debug("previously authenticated user: {}", principal.getName());
            return true;
        } else if (negotiateCheck) {
            if (!authorizationHeader.isNull()) {
                boolean negotiateResult = this.negotiate(request, response, authorizationHeader);
                if (!negotiateResult) {
                    this.redirectTo(request, response, loginConfig.getErrorPage());
                }
                return negotiateResult;
            }
            this.log.debug("authorization required");
            this.sendUnauthorized(response);
            return false;
        } else if (securityCheck) {
            final boolean postResult = this.post(request, response);
            if (!postResult) {
                this.redirectTo(request, response, loginConfig.getErrorPage());
            }
            return postResult;
        } else {
            this.redirectTo(request, response, loginConfig.getLoginPage());
            return false;
        }
    }

    /**
     * Negotiate.
     *
     * @param request
     *            the request
     * @param response
     *            the response
     * @param authorizationHeader
     *            the authorization header
     *
     * @return true, if successful
     */
    private boolean negotiate(final Request request, final HttpServletResponse response,
            final AuthorizationHeader authorizationHeader) {

        final String securityPackage = authorizationHeader.getSecurityPackage();
        // maintain a connection-based session for NTLM tokens
        final String connectionId = NtlmServletRequest.getConnectionId(request);

        this.log.debug("security package: {}, connection id: {}", securityPackage, connectionId);

        final boolean ntlmPost = authorizationHeader.isNtlmType1PostAuthorizationHeader();

        if (ntlmPost) {
            // type 1 NTLM authentication message received
            this.auth.resetSecurityToken(connectionId);
        }

        final byte[] tokenBuffer = authorizationHeader.getTokenBytes();
        this.log.debug("token buffer: {} byte(s)", Integer.valueOf(tokenBuffer.length));

        // log the user in using the token
        IWindowsSecurityContext securityContext;
        try {
            securityContext = this.auth.acceptSecurityToken(connectionId, tokenBuffer, securityPackage);
        } catch (final Win32Exception e) {
            this.log.warn("error logging in user: {}", e.getMessage());
            this.log.trace("", e);
            this.sendUnauthorized(response);
            return false;
        }
        this.log.debug("continue required: {}", Boolean.valueOf(securityContext.isContinue()));

        final byte[] continueTokenBytes = securityContext.getToken();
        if (continueTokenBytes != null && continueTokenBytes.length > 0) {
            final String continueToken = Base64.getEncoder().encodeToString(continueTokenBytes);
            this.log.debug("continue token: {}", continueToken);
            response.addHeader("WWW-Authenticate", securityPackage + " " + continueToken);
        }

        try {
            if (securityContext.isContinue() || ntlmPost) {
                response.setHeader("Connection", "keep-alive");
                response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
                response.flushBuffer();
                return false;
            }
        } catch (final IOException e) {
            this.log.warn("error logging in user: {}", e.getMessage());
            this.log.trace("", e);
            this.sendUnauthorized(response);
            return false;
        }

        // create and register the user principal with the session
        final IWindowsIdentity windowsIdentity = securityContext.getIdentity();

        // disable guest login
        if (!this.allowGuestLogin && windowsIdentity.isGuest()) {
            this.log.warn("guest login disabled: {}", windowsIdentity.getFqn());
            this.sendUnauthorized(response);
            return false;
        }

        try {

            this.log.debug("logged in user: {} ({})", windowsIdentity.getFqn(), windowsIdentity.getSidString());

            final GenericPrincipal genericPrincipal = this.createPrincipal(windowsIdentity);

            if (this.log.isDebugEnabled()) {
                this.log.debug("roles: {}", String.join(", ", genericPrincipal.getRoles()));
            }

            // create a session associated with this request if there's none
            final HttpSession session = request.getSession(true);
            this.log.debug("session id: {}", session == null ? "null" : session.getId());

            this.register(request, response, genericPrincipal, securityPackage, genericPrincipal.getName(), null);
            this.log.info("successfully logged in user: {}", genericPrincipal.getName());

        } finally {
            windowsIdentity.dispose();
        }

        return true;
    }

    /**
     * Post.
     *
     * @param request
     *            the request
     * @param response
     *            the response
     *
     * @return true, if successful
     */
    private boolean post(final Request request, final HttpServletResponse response) {

        final String username = request.getParameter("j_username");
        final String password = request.getParameter("j_password");

        this.log.debug("logging in: {}", username);

        IWindowsIdentity windowsIdentity;
        try {
            windowsIdentity = this.auth.logonUser(username, password);
        } catch (final Exception e) {
            this.log.error(e.getMessage());
            this.log.trace("", e);
            return false;
        }

        // disable guest login
        if (!this.allowGuestLogin && windowsIdentity.isGuest()) {
            this.log.warn("guest login disabled: {}", windowsIdentity.getFqn());
            return false;
        }

        try {
            this.log.debug("successfully logged in {} ({})", username, windowsIdentity.getSidString());

            final GenericPrincipal genericPrincipal = this.createPrincipal(windowsIdentity);

            if (this.log.isDebugEnabled()) {
                this.log.debug("roles: {}", String.join(", ", genericPrincipal.getRoles()));
            }

            // create a session associated with this request if there's none
            final HttpSession session = request.getSession(true);
            this.log.debug("session id: {}", session == null ? "null" : session.getId());

            this.register(request, response, genericPrincipal, "FORM", genericPrincipal.getName(), null);
            this.log.info("successfully logged in user: {}", genericPrincipal.getName());
        } finally {
            windowsIdentity.dispose();
        }

        return true;
    }

    /**
     * Redirect to.
     *
     * @param request
     *            the request
     * @param response
     *            the response
     * @param url
     *            the url
     */
    private void redirectTo(final Request request, final HttpServletResponse response, final String url) {
        try {
            this.log.debug("redirecting to: {}", url);
            final ServletContext servletContext = this.context.getServletContext();
            final RequestDispatcher disp = servletContext.getRequestDispatcher(url);
            disp.forward(request.getRequest(), response);
        } catch (final IOException | ServletException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * XXX The 'doAuthenticate' is intended to replace 'authenticate' for needs like ours. In order to support old and
     * new at this time, we will continue to have both for time being.
     */
    @Override
    protected boolean doAuthenticate(final Request request, final HttpServletResponse response) throws IOException {
        return this.authenticate(request, response);
    }

}
File Project Line
waffle/util/WaffleInfo.java waffle-jna-jakarta 96
waffle/util/WaffleInfo.java waffle-jna 96
public class WaffleInfo {

    /** The Constant LOGGER. */
    private static final Logger LOGGER = LoggerFactory.getLogger(WaffleInfo.class);

    /**
     * Get a Document with basic system information.
     * <p>
     * This uses the builtin jakarta.xml package even though the API is quite verbose
     *
     * @return Document with waffle info.
     *
     * @throws ParserConfigurationException
     *             when getting new document builder.
     */
    public Document getWaffleInfo() throws ParserConfigurationException {
        final DocumentBuilderFactory df = DocumentBuilderFactory.newInstance();
        df.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
        df.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
        df.setExpandEntityReferences(false);

        final Document doc = df.newDocumentBuilder().newDocument();

        // create the root element and add it to the document
        final Element root = doc.createElement("waffle");

        // Add Version Information as attributes
        String version = WaffleInfo.class.getPackage().getImplementationVersion();
        if (version != null) {
            root.setAttribute("version", version);
        }
        version = Platform.class.getPackage().getImplementationVersion();
        if (version != null) {
            root.setAttribute("jna", version);
        }
        version = WindowUtils.class.getPackage().getImplementationVersion();
        if (version != null) {
            root.setAttribute("jna-platform", version);
        }

        doc.appendChild(root);
        root.appendChild(this.getAuthProviderInfo(doc));

        return doc;
    }

    /**
     * Gets the auth provider info.
     *
     * @param doc
     *            the doc
     *
     * @return the auth provider info
     */
    protected Element getAuthProviderInfo(final Document doc) {
        final IWindowsAuthProvider auth = new WindowsAuthProviderImpl();

        final Element node = doc.createElement("auth");
        node.setAttribute("class", auth.getClass().getName());

        // Current User
        Element child = doc.createElement("currentUser");
        node.appendChild(child);

        final String currentUsername = WindowsAccountImpl.getCurrentUsername();
        this.addAccountInfo(doc, child, new WindowsAccountImpl(currentUsername));

        // Computer
        child = doc.createElement("computer");
        node.appendChild(child);

        final IWindowsComputer c = auth.getCurrentComputer();
        Element value = doc.createElement("computerName");
        value.setTextContent(c.getComputerName());
        child.appendChild(value);

        value = doc.createElement("memberOf");
        value.setTextContent(c.getMemberOf());
        child.appendChild(value);

        value = doc.createElement("joinStatus");
        value.setTextContent(c.getJoinStatus());
        child.appendChild(value);

        value = doc.createElement("groups");
        Element g;
        for (final String s : c.getGroups()) {
            g = doc.createElement("group");
            g.setTextContent(s);
            value.appendChild(g);
        }
        child.appendChild(value);

        // Only Show Domains if we are in a Domain
        if (Netapi32Util.getJoinStatus() == LMJoin.NETSETUP_JOIN_STATUS.NetSetupDomainName) {
            child = doc.createElement("domains");
            node.appendChild(child);

            Element d;
            for (final IWindowsDomain domain : auth.getDomains()) {
                d = doc.createElement("domain");
                node.appendChild(d);

                value = doc.createElement("FQN");
                value.setTextContent(domain.getFqn());
                child.appendChild(value);

                value = doc.createElement("TrustTypeString");
                value.setTextContent(domain.getTrustTypeString());
                child.appendChild(value);

                value = doc.createElement("TrustDirectionString");
                value.setTextContent(domain.getTrustDirectionString());
                child.appendChild(value);
            }
        }
        return node;
    }

    /**
     * Adds the account info.
     *
     * @param doc
     *            the doc
     * @param node
     *            the node
     * @param account
     *            the account
     */
    protected void addAccountInfo(final Document doc, final Element node, final IWindowsAccount account) {
        Element value = doc.createElement("Name");
        value.setTextContent(account.getName());
        node.appendChild(value);

        value = doc.createElement("FQN");
        value.setTextContent(account.getFqn());
        node.appendChild(value);

        value = doc.createElement("Domain");
        value.setTextContent(account.getDomain());
        node.appendChild(value);

        value = doc.createElement("SID");
        value.setTextContent(account.getSidString());
        node.appendChild(value);
    }

    /**
     * Gets the lookup info.
     *
     * @param doc
     *            the doc
     * @param lookup
     *            the lookup
     *
     * @return the lookup info
     */
    public Element getLookupInfo(final Document doc, final String lookup) {
        final IWindowsAuthProvider auth = new WindowsAuthProviderImpl();
        final Element node = doc.createElement("lookup");
        node.setAttribute("name", lookup);
        try {
            this.addAccountInfo(doc, node, auth.lookupAccount(lookup));
        } catch (final Win32Exception e) {
            node.appendChild(WaffleInfo.getException(doc, e));
        }
        return node;
    }

    /**
     * Gets the exception.
     *
     * @param doc
     *            the doc
     * @param t
     *            the t
     *
     * @return the exception
     */
    public static Element getException(final Document doc, final Exception t) {
        final Element node = doc.createElement("exception");
        node.setAttribute("class", t.getClass().getName());

        Element value = doc.createElement("message");
        if (t.getMessage() != null) {
            value.setTextContent(t.getMessage());
            node.appendChild(value);
        }

        value = doc.createElement("trace");
        value.setTextContent(Arrays.toString(t.getStackTrace()));
        node.appendChild(value);
        return node;
    }

    /**
     * To pretty xml.
     *
     * @param doc
     *            the doc
     *
     * @return the string
     *
     * @throws TransformerException
     *             the transformer exception
     */
    public static String toPrettyXML(final Document doc) throws TransformerException {
        // set up a transformer
        final TransformerFactory transfac = TransformerFactory.newInstance();
        transfac.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
        transfac.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");

        final Transformer trans = transfac.newTransformer();
        trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
        trans.setOutputProperty(OutputKeys.INDENT, "yes");

        // create string from xml tree
        final StringWriter sw = new StringWriter();
        final StreamResult result = new StreamResult(sw);
        final DOMSource source = new DOMSource(doc);
        trans.transform(source, result);
        return sw.toString();
    }

    /**
     * Print system information.
     *
     * @param args
     *            variable arguments to pass to main. Valid values are "-show" and "-lookup".
     */
    public static void main(final String[] args) {
        boolean show = false;
        final List<String> lookup = new ArrayList<>();
        if (args != null) {
            String arg;
            for (int i = 0; i < args.length; i++) {
                arg = args[i];
                if (null != arg) {
                    switch (arg) {
                        case "-show":
                            show = true;
                            break;
                        case "-lookup":
                            lookup.add(args[++i]);
                            break;
                        default:
                            WaffleInfo.LOGGER.error("Unknown Argument: {}", arg);
                            throw new RuntimeException("Unknown Argument: " + arg);
                    }
                }
            }
        }

        final WaffleInfo helper = new WaffleInfo();
        try {
            final Document info = helper.getWaffleInfo();
            for (final String name : lookup) {
                info.getDocumentElement().appendChild(helper.getLookupInfo(info, name));
            }

            final String xml = WaffleInfo.toPrettyXML(info);
            final File f;
            if (show) {
                f = Files.createTempFile("waffle-info-", ".xml").toFile();
                Files.write(f.toPath(), xml.getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND);
                Desktop.getDesktop().open(f);
            } else {
                WaffleInfo.LOGGER.info(xml);
            }
        } catch (final IOException | TransformerException | ParserConfigurationException e) {
            WaffleInfo.LOGGER.error(e.getMessage());
            WaffleInfo.LOGGER.trace("", e);
        }
    }
}
File Project Line
waffle/windows/auth/impl/WindowsAuthProviderImpl.java waffle-jna-jakarta 57
waffle/windows/auth/impl/WindowsAuthProviderImpl.java waffle-jna 57
public class WindowsAuthProviderImpl implements IWindowsAuthProvider {

    /** The Continue Context Timeout. */
    public static final int CONTINUE_CONTEXT_TIMEOUT = 30;

    /**
     * The Class ContinueContext.
     */
    private static class ContinueContext {
        /** The continue handle. */
        CtxtHandle continueHandle;

        /** The server credential. */
        IWindowsCredentialsHandle serverCredential;

        /**
         * Instantiates a new continue context.
         *
         * @param handle
         *            the handle
         * @param windowsCredential
         *            the windows credential
         */
        public ContinueContext(final CtxtHandle handle, final IWindowsCredentialsHandle windowsCredential) {
            this.continueHandle = handle;
            this.serverCredential = windowsCredential;
        }
    }

    /** The continue contexts. */
    private final Cache<String, ContinueContext> continueContexts;

    /**
     * Instantiates a new windows auth provider impl.
     */
    public WindowsAuthProviderImpl() {
        this(WindowsAuthProviderImpl.CONTINUE_CONTEXT_TIMEOUT);
    }

    /**
     * A Windows authentication provider.
     *
     * @param continueContextsTimeout
     *            Timeout for security contexts in seconds.
     */
    public WindowsAuthProviderImpl(final int continueContextsTimeout) {
        this.continueContexts = Cache.newCache(continueContextsTimeout);
    }

    @Override
    public IWindowsSecurityContext acceptSecurityToken(final String connectionId, final byte[] token,
            final String securityPackage) {

        if (token == null || token.length == 0) {
            this.resetSecurityToken(connectionId);
            throw new Win32Exception(WinError.SEC_E_INVALID_TOKEN);
        }

        CtxtHandle continueHandle = null;
        IWindowsCredentialsHandle serverCredential;
        ContinueContext continueContext = this.continueContexts.get(connectionId);
        if (continueContext != null) {
            continueHandle = continueContext.continueHandle;
            serverCredential = continueContext.serverCredential;
        } else {
            serverCredential = new WindowsCredentialsHandleImpl(null, Sspi.SECPKG_CRED_INBOUND, securityPackage);
            serverCredential.initialize();
        }

        WindowsSecurityContextImpl sc;

        int rc;
        int tokenSize = Sspi.MAX_TOKEN_SIZE;

        do {
            final ManagedSecBufferDesc pbServerToken = new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, tokenSize);
            final ManagedSecBufferDesc pbClientToken = new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, token);
            final IntByReference pfClientContextAttr = new IntByReference();

            final CtxtHandle phNewServerContext = new CtxtHandle();
            rc = Secur32.INSTANCE.AcceptSecurityContext(serverCredential.getHandle(), continueHandle, pbClientToken,
                    Sspi.ISC_REQ_CONNECTION, Sspi.SECURITY_NATIVE_DREP, phNewServerContext, pbServerToken,
                    pfClientContextAttr, null);

            sc = new WindowsSecurityContextImpl();
            sc.setCredentialsHandle(serverCredential);
            sc.setSecurityPackage(securityPackage);
            sc.setSecurityContext(phNewServerContext);

            switch (rc) {
                case WinError.SEC_E_BUFFER_TOO_SMALL:
                    tokenSize += Sspi.MAX_TOKEN_SIZE;
                    sc.dispose();
                    WindowsSecurityContextImpl.dispose(continueHandle);
                    break;
                case WinError.SEC_E_OK:
                    // the security context received from the client was accepted
                    this.resetSecurityToken(connectionId);
                    // if an output token was generated by the function, it must be sent to the client process
                    if (pbServerToken.pBuffers != null && pbServerToken.cBuffers == 1
                            && pbServerToken.getBuffer(0).cbBuffer > 0) {
                        sc.setToken(pbServerToken.getBuffer(0).getBytes() == null ? new byte[0]
                                : pbServerToken.getBuffer(0).getBytes().clone());
                    }
                    sc.setContinue(false);
                    break;
                case WinError.SEC_I_CONTINUE_NEEDED:
                    // the server must send the output token to the client and wait for a returned token
                    continueContext = new ContinueContext(phNewServerContext, serverCredential);
                    this.continueContexts.put(connectionId, continueContext);
                    sc.setToken(pbServerToken.getBuffer(0).getBytes() == null ? new byte[0]
                            : pbServerToken.getBuffer(0).getBytes().clone());
                    sc.setContinue(true);
                    break;
                default:
                    sc.dispose();
                    WindowsSecurityContextImpl.dispose(continueHandle);
                    this.resetSecurityToken(connectionId);
                    throw new Win32Exception(rc);
            }
        } while (rc == WinError.SEC_E_BUFFER_TOO_SMALL);

        return sc;
    }

    @Override
    public IWindowsComputer getCurrentComputer() {
        try {
            return new WindowsComputerImpl(InetAddress.getLocalHost().getHostName());
        } catch (final UnknownHostException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public IWindowsDomain[] getDomains() {
        final List<IWindowsDomain> domains = new ArrayList<>();
        final DomainTrust[] trusts = Netapi32Util.getDomainTrusts();
        for (final DomainTrust trust : trusts) {
            domains.add(new WindowsDomainImpl(trust));
        }
        return domains.toArray(new IWindowsDomain[0]);
    }

    @Override
    public IWindowsIdentity logonDomainUser(final String username, final String domain, final String password) {
        return this.logonDomainUserEx(username, domain, password, WinBase.LOGON32_LOGON_NETWORK,
                WinBase.LOGON32_PROVIDER_DEFAULT);
    }

    @Override
    public IWindowsIdentity logonDomainUserEx(final String username, final String domain, final String password,
            final int logonType, final int logonProvider) {
        final HANDLEByReference phUser = new HANDLEByReference();
        if (!Advapi32.INSTANCE.LogonUser(username, domain, password, logonType, logonProvider, phUser)) {
            throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
        }
        return new WindowsIdentityImpl(phUser.getValue());
    }

    @Override
    public IWindowsIdentity logonUser(final String username, final String password) {
        // username@domain UPN format is natively supported by the
        // Windows LogonUser API process domain\\username format
        final String[] userNameDomain = username.split("\\\\", 2);
        if (userNameDomain.length == 2) {
            return this.logonDomainUser(userNameDomain[1], userNameDomain[0], password);
        }
        return this.logonDomainUser(username, null, password);
    }

    @Override
    public IWindowsAccount lookupAccount(final String username) {
        return new WindowsAccountImpl(username);
    }

    @Override
    public void resetSecurityToken(final String connectionId) {
        this.continueContexts.remove(connectionId);
    }

    /**
     * Number of elements in the continue contexts map.
     *
     * @return Number of elements in the hash map.
     */
    public int getContinueContextsSize() {
        return this.continueContexts.size();
    }
}
File Project Line
waffle/spring/NegotiateSecurityFilter.java waffle-spring-security5 54
waffle/spring/NegotiateSecurityFilter.java waffle-spring-security6 54
public class NegotiateSecurityFilter extends GenericFilterBean {

    /** The Constant LOGGER. */
    private static final Logger LOGGER = LoggerFactory.getLogger(NegotiateSecurityFilter.class);

    /** The provider. */
    private SecurityFilterProviderCollection provider;

    /** The principal format. */
    private PrincipalFormat principalFormat = PrincipalFormat.FQN;

    /** The role format. */
    private PrincipalFormat roleFormat = PrincipalFormat.FQN;

    /** The allow guest login. */
    private boolean allowGuestLogin = true;

    /** The impersonate. */
    private boolean impersonate;

    /** The granted authority factory. */
    private GrantedAuthorityFactory grantedAuthorityFactory = WindowsAuthenticationToken.DEFAULT_GRANTED_AUTHORITY_FACTORY;

    /** The default granted authority. */
    private GrantedAuthority defaultGrantedAuthority = WindowsAuthenticationToken.DEFAULT_GRANTED_AUTHORITY;

    /**
     * Instantiates a new negotiate security filter.
     */
    public NegotiateSecurityFilter() {
        super();
        NegotiateSecurityFilter.LOGGER.debug("[waffle.spring.NegotiateSecurityFilter] loaded");
    }

    @Override
    public void doFilter(final ServletRequest req, final ServletResponse res, final FilterChain chain)
            throws IOException, ServletException {

        final HttpServletRequest request = (HttpServletRequest) req;
        final HttpServletResponse response = (HttpServletResponse) res;

        NegotiateSecurityFilter.LOGGER.debug("{} {}, contentlength: {}", request.getMethod(), request.getRequestURI(),
                Integer.valueOf(request.getContentLength()));

        final AuthorizationHeader authorizationHeader = new AuthorizationHeader(request);

        // authenticate user
        if (!authorizationHeader.isNull()
                && this.provider.isSecurityPackageSupported(authorizationHeader.getSecurityPackage())) {

            // log the user in using the token
            IWindowsIdentity windowsIdentity;

            try {
                windowsIdentity = this.provider.doFilter(request, response);
                if (windowsIdentity == null) {
                    return;
                }
            } catch (final IOException e) {
                NegotiateSecurityFilter.LOGGER.warn("error logging in user: {}", e.getMessage());
                NegotiateSecurityFilter.LOGGER.trace("", e);
                this.sendUnauthorized(response, true);
                return;
            }

            IWindowsImpersonationContext ctx = null;
            try {
                if (!this.allowGuestLogin && windowsIdentity.isGuest()) {
                    NegotiateSecurityFilter.LOGGER.warn("guest login disabled: {}", windowsIdentity.getFqn());
                    this.sendUnauthorized(response, true);
                    return;
                }

                NegotiateSecurityFilter.LOGGER.debug("logged in user: {} ({})", windowsIdentity.getFqn(),
                        windowsIdentity.getSidString());

                final WindowsPrincipal principal = this.impersonate
                        ? new AutoDisposableWindowsPrincipal(windowsIdentity, this.principalFormat, this.roleFormat)
                        : new WindowsPrincipal(windowsIdentity, this.principalFormat, this.roleFormat);

                NegotiateSecurityFilter.LOGGER.debug("roles: {}", principal.getRolesString());

                final Authentication authentication = new WindowsAuthenticationToken(principal,
                        this.grantedAuthorityFactory, this.defaultGrantedAuthority);

                if (!this.setAuthentication(request, response, authentication)) {
                    return;
                }

                NegotiateSecurityFilter.LOGGER.info("successfully logged in user: {}", windowsIdentity.getFqn());

                if (this.impersonate) {
                    NegotiateSecurityFilter.LOGGER.debug("impersonating user");
                    ctx = windowsIdentity.impersonate();
                }

                chain.doFilter(request, response);
            } finally {
                if (this.impersonate && ctx != null) {
                    NegotiateSecurityFilter.LOGGER.debug("terminating impersonation");
                    ctx.revertToSelf();
                } else {
                    windowsIdentity.dispose();
                }
            }
        } else {
            chain.doFilter(request, response);
        }
    }

    /**
     * Invoked when authentication towards ad was succesful to populate securitycontext Override to add service provider
     * authorization checks.
     *
     * @param request
     *            the request
     * @param response
     *            the response
     * @param authentication
     *            the authentication
     *
     * @return true, if successful
     */
    protected boolean setAuthentication(final HttpServletRequest request, final HttpServletResponse response,
            final Authentication authentication) {
        SecurityContextHolder.getContext().setAuthentication(authentication);
        return true;
    }

    @Override
    public void afterPropertiesSet() throws ServletException {
        super.afterPropertiesSet();

        if (this.provider == null) {
            throw new ServletException("Missing NegotiateSecurityFilter.Provider");
        }
    }

    /**
     * Send a 401 Unauthorized along with protocol authentication headers.
     *
     * @param response
     *            HTTP Response
     * @param close
     *            Close connection.
     */
    protected void sendUnauthorized(final HttpServletResponse response, final boolean close) {
        try {
            this.provider.sendUnauthorized(response);
            if (close) {
                response.setHeader("Connection", "close");
            } else {
                response.setHeader("Connection", "keep-alive");
            }
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
            response.flushBuffer();
        } catch (final IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Gets the principal format.
     *
     * @return the principal format
     */
    public PrincipalFormat getPrincipalFormat() {
        return this.principalFormat;
    }

    /**
     * Sets the principal format enum.
     *
     * @param value
     *            the new principal format enum
     */
    public void setPrincipalFormatEnum(final PrincipalFormat value) {
        this.principalFormat = value;
    }

    /**
     * Sets the principal format.
     *
     * @param value
     *            the new principal format
     */
    public void setPrincipalFormat(final String value) {
        this.setPrincipalFormatEnum(PrincipalFormat.valueOf(value.toUpperCase(Locale.ENGLISH)));
    }

    /**
     * Gets the role format.
     *
     * @return the role format
     */
    public PrincipalFormat getRoleFormat() {
        return this.roleFormat;
    }

    /**
     * Sets the role format enum.
     *
     * @param value
     *            the new role format enum
     */
    public void setRoleFormatEnum(final PrincipalFormat value) {
        this.roleFormat = value;
    }

    /**
     * Sets the role format.
     *
     * @param value
     *            the new role format
     */
    public void setRoleFormat(final String value) {
        this.setRoleFormatEnum(PrincipalFormat.valueOf(value.toUpperCase(Locale.ENGLISH)));
    }

    /**
     * Checks if is allow guest login.
     *
     * @return true, if is allow guest login
     */
    public boolean isAllowGuestLogin() {
        return this.allowGuestLogin;
    }

    /**
     * Sets the allow guest login.
     *
     * @param value
     *            the new allow guest login
     */
    public void setAllowGuestLogin(final boolean value) {
        this.allowGuestLogin = value;
    }

    /**
     * Enable/Disable impersonation.
     *
     * @param value
     *            true to enable impersonation, false otherwise
     */
    public void setImpersonate(final boolean value) {
        this.impersonate = value;
    }

    /**
     * Checks if is impersonate.
     *
     * @return true if impersonation is enabled, false otherwise
     */
    public boolean isImpersonate() {
        return this.impersonate;
    }

    /**
     * Gets the provider.
     *
     * @return the provider
     */
    public SecurityFilterProviderCollection getProvider() {
        return this.provider;
    }

    /**
     * Sets the provider.
     *
     * @param value
     *            the new provider
     */
    public void setProvider(final SecurityFilterProviderCollection value) {
        this.provider = value;
    }

    /**
     * Gets the granted authority factory.
     *
     * @return the granted authority factory
     */
    public GrantedAuthorityFactory getGrantedAuthorityFactory() {
        return this.grantedAuthorityFactory;
    }

    /**
     * Sets the granted authority factory.
     *
     * @param value
     *            the new granted authority factory
     */
    public void setGrantedAuthorityFactory(final GrantedAuthorityFactory value) {
        this.grantedAuthorityFactory = value;
    }

    /**
     * Gets the default granted authority.
     *
     * @return the default granted authority
     */
    public GrantedAuthority getDefaultGrantedAuthority() {
        return this.defaultGrantedAuthority;
    }

    /**
     * Sets the default granted authority.
     *
     * @param value
     *            the new default granted authority
     */
    public void setDefaultGrantedAuthority(final GrantedAuthority value) {
        this.defaultGrantedAuthority = value;
    }
}
File Project Line
waffle/apache/NegotiateAuthenticator.java waffle-tomcat10 48
waffle/apache/NegotiateAuthenticator.java waffle-tomcat85 48
waffle/apache/NegotiateAuthenticator.java waffle-tomcat9 48
public class NegotiateAuthenticator extends WaffleAuthenticatorBase {

    /**
     * Instantiates a new negotiate authenticator.
     */
    public NegotiateAuthenticator() {
        super();
        this.log = LoggerFactory.getLogger(NegotiateAuthenticator.class);
        this.info = "waffle.apache.NegotiateAuthenticator/1.0";
        this.log.debug("[waffle.apache.NegotiateAuthenticator] loaded");
    }

    @Override
    public synchronized void startInternal() throws LifecycleException {
        this.log.info("[waffle.apache.NegotiateAuthenticator] started");
        super.startInternal();
    }

    @Override
    public synchronized void stopInternal() throws LifecycleException {
        super.stopInternal();
        this.log.info("[waffle.apache.NegotiateAuthenticator] stopped");
    }

    @Override
    public boolean authenticate(final Request request, final HttpServletResponse response) {

        Principal principal = request.getUserPrincipal();
        final AuthorizationHeader authorizationHeader = new AuthorizationHeader(request);
        final boolean ntlmPost = authorizationHeader.isNtlmType1PostAuthorizationHeader();

        this.log.debug("{} {}, contentlength: {}", request.getMethod(), request.getRequestURI(),
                Integer.valueOf(request.getContentLength()));
        this.log.debug("authorization: {}, ntlm post: {}", authorizationHeader, Boolean.valueOf(ntlmPost));

        if (principal != null && !ntlmPost) {
            // user already authenticated
            this.log.debug("previously authenticated user: {}", principal.getName());
            return true;
        }

        // authenticate user
        if (!authorizationHeader.isNull()) {

            final String securityPackage = authorizationHeader.getSecurityPackage();
            // maintain a connection-based session for NTLM tokens
            final String connectionId = NtlmServletRequest.getConnectionId(request);

            this.log.debug("security package: {}, connection id: {}", securityPackage, connectionId);

            if (ntlmPost) {
                // type 1 NTLM authentication message received
                this.auth.resetSecurityToken(connectionId);
            }

            final byte[] tokenBuffer = authorizationHeader.getTokenBytes();
            this.log.debug("token buffer: {} byte(s)", Integer.valueOf(tokenBuffer.length));

            // log the user in using the token
            IWindowsSecurityContext securityContext;
            try {
                securityContext = this.auth.acceptSecurityToken(connectionId, tokenBuffer, securityPackage);
            } catch (final Win32Exception e) {
                this.log.warn("error logging in user: {}", e.getMessage());
                this.log.trace("", e);
                this.sendUnauthorized(response);
                return false;
            }
            this.log.debug("continue required: {}", Boolean.valueOf(securityContext.isContinue()));

            final byte[] continueTokenBytes = securityContext.getToken();
            if (continueTokenBytes != null && continueTokenBytes.length > 0) {
                final String continueToken = Base64.getEncoder().encodeToString(continueTokenBytes);
                this.log.debug("continue token: {}", continueToken);
                response.addHeader("WWW-Authenticate", securityPackage + " " + continueToken);
            }

            try {
                if (securityContext.isContinue()) {
                    response.setHeader("Connection", "keep-alive");
                    response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
                    response.flushBuffer();
                    return false;
                }
            } catch (final IOException e) {
                this.log.warn("error logging in user: {}", e.getMessage());
                this.log.trace("", e);
                this.sendUnauthorized(response);
                return false;
            }

            // realm: fail if no realm is configured
            if (this.context == null || this.context.getRealm() == null) {
                this.log.warn("missing context/realm");
                this.sendError(response, HttpServletResponse.SC_SERVICE_UNAVAILABLE);
                return false;
            }

            // create and register the user principal with the session
            final IWindowsIdentity windowsIdentity = securityContext.getIdentity();

            // disable guest login
            if (!this.allowGuestLogin && windowsIdentity.isGuest()) {
                this.log.warn("guest login disabled: {}", windowsIdentity.getFqn());
                this.sendUnauthorized(response);
                return false;
            }

            try {
                this.log.debug("logged in user: {} ({})", windowsIdentity.getFqn(), windowsIdentity.getSidString());

                final GenericPrincipal genericPrincipal = this.createPrincipal(windowsIdentity);

                if (this.log.isDebugEnabled()) {
                    this.log.debug("roles: {}", String.join(", ", genericPrincipal.getRoles()));
                }

                principal = genericPrincipal;

                // create a session associated with this request if there's none
                final HttpSession session = request.getSession(true);
                this.log.debug("session id: {}", session == null ? "null" : session.getId());

                // register the authenticated principal
                this.register(request, response, principal, securityPackage, principal.getName(), null);
                this.log.info("successfully logged in user: {}", principal.getName());

            } finally {
                windowsIdentity.dispose();
                securityContext.dispose();
            }

            return true;
        }

        this.log.debug("authorization required");
        this.sendUnauthorized(response);
        return false;
    }

    /**
     * XXX The 'doAuthenticate' is intended to replace 'authenticate' for needs like ours. In order to support old and
     * new at this time, we will continue to have both for time being.
     */
    @Override
    protected boolean doAuthenticate(final Request request, final HttpServletResponse response) throws IOException {
        return this.authenticate(request, response);
    }

}
File Project Line
waffle/apache/WaffleAuthenticatorBase.java waffle-tomcat10 50
waffle/apache/WaffleAuthenticatorBase.java waffle-tomcat85 50
waffle/apache/WaffleAuthenticatorBase.java waffle-tomcat9 50
abstract class WaffleAuthenticatorBase extends AuthenticatorBase {

    /** The Constant SUPPORTED_PROTOCOLS. */
    private static final Set<String> SUPPORTED_PROTOCOLS = new LinkedHashSet<>(Arrays.asList("Negotiate", "NTLM"));

    /** The info. */
    protected String info;

    /** The log. */
    protected Logger log;

    /** The principal format. */
    protected PrincipalFormat principalFormat = PrincipalFormat.FQN;

    /** The role format. */
    protected PrincipalFormat roleFormat = PrincipalFormat.FQN;

    /** The allow guest login. */
    protected boolean allowGuestLogin = true;

    /** The protocols. */
    protected Set<String> protocols = WaffleAuthenticatorBase.SUPPORTED_PROTOCOLS;

    /** The auth continueContextsTimeout configuration. */
    protected int continueContextsTimeout = WindowsAuthProviderImpl.CONTINUE_CONTEXT_TIMEOUT;

    /** The auth. */
    protected IWindowsAuthProvider auth;

    /**
     * Gets the continue context time out configuration.
     *
     * @return the continue contexts timeout
     */
    public int getContinueContextsTimeout() {
        return this.continueContextsTimeout;
    }

    /**
     * Sets the continue context time out configuration.
     *
     * @param continueContextsTimeout
     *            the new continue contexts timeout
     */
    public void setContinueContextsTimeout(final int continueContextsTimeout) {
        this.continueContextsTimeout = continueContextsTimeout;
    }

    /**
     * Windows authentication provider.
     *
     * @return IWindowsAuthProvider.
     */
    public IWindowsAuthProvider getAuth() {
        return this.auth;
    }

    /**
     * Set Windows auth provider.
     *
     * @param provider
     *            Class implements IWindowsAuthProvider.
     */
    public void setAuth(final IWindowsAuthProvider provider) {
        this.auth = provider;
    }

    /**
     * Gets the info.
     *
     * @return the info
     */
    public String getInfo() {
        return this.info;
    }

    /**
     * Set the principal format.
     *
     * @param format
     *            Principal format.
     */
    public void setPrincipalFormat(final String format) {
        this.principalFormat = PrincipalFormat.valueOf(format.toUpperCase(Locale.ENGLISH));
        this.log.debug("principal format: {}", this.principalFormat);
    }

    /**
     * Principal format.
     *
     * @return Principal format.
     */
    public PrincipalFormat getPrincipalFormat() {
        return this.principalFormat;
    }

    /**
     * Set the principal format.
     *
     * @param format
     *            Role format.
     */
    public void setRoleFormat(final String format) {
        this.roleFormat = PrincipalFormat.valueOf(format.toUpperCase(Locale.ENGLISH));
        this.log.debug("role format: {}", this.roleFormat);
    }

    /**
     * Principal format.
     *
     * @return Role format.
     */
    public PrincipalFormat getRoleFormat() {
        return this.roleFormat;
    }

    /**
     * True if Guest login permitted.
     *
     * @return True if Guest login permitted, false otherwise.
     */
    public boolean isAllowGuestLogin() {
        return this.allowGuestLogin;
    }

    /**
     * Set whether Guest login is permitted. Default is true, if the Guest account is enabled, an invalid
     * username/password results in a Guest login.
     *
     * @param value
     *            True or false.
     */
    public void setAllowGuestLogin(final boolean value) {
        this.allowGuestLogin = value;
    }

    /**
     * Set the authentication protocols. Default is "Negotiate, NTLM".
     *
     * @param value
     *            Authentication protocols
     */
    public void setProtocols(final String value) {
        this.protocols = new LinkedHashSet<>();
        final String[] protocolNames = value.split(",", -1);
        for (String protocolName : protocolNames) {
            protocolName = protocolName.trim();
            if (!protocolName.isEmpty()) {
                this.log.debug("init protocol: {}", protocolName);
                if (WaffleAuthenticatorBase.SUPPORTED_PROTOCOLS.contains(protocolName)) {
                    this.protocols.add(protocolName);
                } else {
                    this.log.error("unsupported protocol: {}", protocolName);
                    throw new RuntimeException("Unsupported protocol: " + protocolName);
                }
            }
        }
    }

    /**
     * Send a 401 Unauthorized along with protocol authentication headers.
     *
     * @param response
     *            HTTP Response
     */
    protected void sendUnauthorized(final HttpServletResponse response) {
        try {
            for (final String protocol : this.protocols) {
                response.addHeader("WWW-Authenticate", protocol);
            }
            response.setHeader("Connection", "close");
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
            response.flushBuffer();
        } catch (final IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Send an error code.
     *
     * @param response
     *            HTTP Response
     * @param code
     *            Error Code
     */
    protected void sendError(final HttpServletResponse response, final int code) {
        try {
            response.sendError(code);
        } catch (final IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    protected String getAuthMethod() {
        return null;
    }

    @Override
    protected Principal doLogin(final Request request, final String username, final String password)
            throws ServletException {
        this.log.debug("logging in: {}", username);
        IWindowsIdentity windowsIdentity;
        try {
            windowsIdentity = this.auth.logonUser(username, password);
        } catch (final Exception e) {
            this.log.error(e.getMessage());
            this.log.trace("", e);
            return super.doLogin(request, username, password);
        }
        // disable guest login
        if (!this.allowGuestLogin && windowsIdentity.isGuest()) {
            this.log.warn("guest login disabled: {}", windowsIdentity.getFqn());
            return super.doLogin(request, username, password);
        }
        try {
            this.log.debug("successfully logged in {} ({})", username, windowsIdentity.getSidString());
            final GenericPrincipal genericPrincipal = this.createPrincipal(windowsIdentity);
            if (this.log.isDebugEnabled()) {
                this.log.debug("roles: {}", String.join(", ", genericPrincipal.getRoles()));
            }
            return genericPrincipal;
        } finally {
            windowsIdentity.dispose();
        }
    }

    /**
     * This method will create an instance of a IWindowsIdentity based GenericPrincipal. It is used for creating custom
     * implementation within subclasses.
     *
     * @param windowsIdentity
     *            the windows identity to initialize the principal
     *
     * @return the Generic Principal
     */
    protected GenericPrincipal createPrincipal(final IWindowsIdentity windowsIdentity) {
        return new GenericWindowsPrincipal(windowsIdentity, this.principalFormat, this.roleFormat);
    }

    /**
     * Hook to the start and to set up the dependencies.
     *
     * @throws LifecycleException
     *             the lifecycle exception
     */
    @Override
    public synchronized void startInternal() throws LifecycleException {
        this.log.debug("Creating a windows authentication provider with continueContextsTimeout property set to: {}",
                this.continueContextsTimeout);
        this.auth = new WindowsAuthProviderImpl(this.continueContextsTimeout);
        super.startInternal();
    }

}
File Project Line
waffle/servlet/WindowsPrincipal.java waffle-jna-jakarta 41
waffle/servlet/WindowsPrincipal.java waffle-jna 41
public class WindowsPrincipal implements Principal, Serializable {

    /** The Constant serialVersionUID. */
    private static final long serialVersionUID = 1L;

    /** The fqn. */
    private final String fqn;

    /** The sid. */
    private final byte[] sid;

    /** The sid string. */
    private final String sidString;

    /** The roles. */
    private final List<String> roles;

    /** The identity. */
    private transient IWindowsIdentity identity;

    /** The groups. */
    private final Map<String, WindowsAccount> groups;

    /**
     * A windows principal.
     *
     * @param windowsIdentity
     *            Windows identity.
     */
    public WindowsPrincipal(final IWindowsIdentity windowsIdentity) {
        this(windowsIdentity, PrincipalFormat.FQN, PrincipalFormat.FQN);
    }

    /**
     * A windows principal.
     *
     * @param windowsIdentity
     *            Windows identity.
     * @param principalFormat
     *            Principal format.
     * @param roleFormat
     *            Role format.
     */
    public WindowsPrincipal(final IWindowsIdentity windowsIdentity, final PrincipalFormat principalFormat,
            final PrincipalFormat roleFormat) {
        this.identity = windowsIdentity;
        this.fqn = windowsIdentity.getFqn();
        this.sid = windowsIdentity.getSid();
        this.sidString = windowsIdentity.getSidString();
        this.groups = WindowsPrincipal.getGroups(windowsIdentity.getGroups());
        this.roles = WindowsPrincipal.getRoles(windowsIdentity, principalFormat, roleFormat);
    }

    /**
     * Gets the roles.
     *
     * @param windowsIdentity
     *            the windows identity
     * @param principalFormat
     *            the principal format
     * @param roleFormat
     *            the role format
     *
     * @return the roles
     */
    private static List<String> getRoles(final IWindowsIdentity windowsIdentity, final PrincipalFormat principalFormat,
            final PrincipalFormat roleFormat) {
        final List<String> roles = new ArrayList<>();
        roles.addAll(WindowsPrincipal.getPrincipalNames(windowsIdentity, principalFormat));
        for (final IWindowsAccount group : windowsIdentity.getGroups()) {
            roles.addAll(WindowsPrincipal.getRoleNames(group, roleFormat));
        }
        return roles;
    }

    /**
     * Gets the groups.
     *
     * @param groups
     *            the groups
     *
     * @return the groups
     */
    private static Map<String, WindowsAccount> getGroups(final IWindowsAccount[] groups) {
        final Map<String, WindowsAccount> groupMap = new HashMap<>();
        for (final IWindowsAccount group : groups) {
            groupMap.put(group.getFqn(), new WindowsAccount(group));
        }
        return groupMap;
    }

    /**
     * Byte representation of the SID.
     *
     * @return Array of bytes.
     */
    public byte[] getSid() {
        return this.sid.clone();
    }

    /**
     * String representation of the SID.
     *
     * @return String.
     */
    public String getSidString() {
        return this.sidString;
    }

    /**
     * Windows groups that the user is a member of.
     *
     * @return A map of group names to groups.
     */
    public Map<String, WindowsAccount> getGroups() {
        return this.groups;
    }

    /**
     * Returns a list of role principal objects.
     *
     * @param group
     *            Windows group.
     * @param principalFormat
     *            Principal format.
     *
     * @return List of role principal objects.
     */
    private static List<String> getRoleNames(final IWindowsAccount group, final PrincipalFormat principalFormat) {
        final List<String> principals = new ArrayList<>();
        switch (principalFormat) {
            case FQN:
                principals.add(group.getFqn());
                break;
            case SID:
                principals.add(group.getSidString());
                break;
            case BOTH:
                principals.add(group.getFqn());
                principals.add(group.getSidString());
                break;
            case NONE:
            default:
                break;
        }
        return principals;
    }

    /**
     * Returns a list of user principal objects.
     *
     * @param windowsIdentity
     *            Windows identity.
     * @param principalFormat
     *            Principal format.
     *
     * @return A list of user principal objects.
     */
    private static List<String> getPrincipalNames(final IWindowsIdentity windowsIdentity,
            final PrincipalFormat principalFormat) {
        final List<String> principals = new ArrayList<>();
        switch (principalFormat) {
            case FQN:
                principals.add(windowsIdentity.getFqn());
                break;
            case SID:
                principals.add(windowsIdentity.getSidString());
                break;
            case BOTH:
                principals.add(windowsIdentity.getFqn());
                principals.add(windowsIdentity.getSidString());
                break;
            case NONE:
            default:
                break;
        }
        return principals;
    }

    /**
     * Get an array of roles as a string.
     *
     * @return Role1, Role2, ...
     */
    public String getRolesString() {
        return String.join(", ", this.roles);
    }

    /**
     * Checks whether the principal has a given role.
     *
     * @param role
     *            Role name.
     *
     * @return True if the principal has a role, false otherwise.
     */
    public boolean hasRole(final String role) {
        return this.roles.contains(role);
    }

    /**
     * Fully qualified name.
     *
     * @return String.
     */
    @Override
    public String getName() {
        return this.fqn;
    }

    /**
     * Underlying identity.
     *
     * @return String.
     */
    public IWindowsIdentity getIdentity() {
        return this.identity;
    }

    @Override
    public String toString() {
        return this.getName();
    }

    @Override
    public boolean equals(final Object o) {
        if (this == o) {
            return true;
        }

        if (o instanceof WindowsPrincipal) {
            return this.getName().equals(((WindowsPrincipal) o).getName());
        }

        return false;
    }

    @Override
    public int hashCode() {
        return this.getName().hashCode();
    }

}
File Project Line
waffle/servlet/spi/NegotiateSecurityFilterProvider.java waffle-jna-jakarta 47
waffle/servlet/spi/NegotiateSecurityFilterProvider.java waffle-jna 47
public class NegotiateSecurityFilterProvider implements SecurityFilterProvider {

    /** The Constant LOGGER. */
    private static final Logger LOGGER = LoggerFactory.getLogger(NegotiateSecurityFilterProvider.class);

    /** The Constant WWW_AUTHENTICATE. */
    private static final String WWW_AUTHENTICATE = "WWW-Authenticate";

    /** The Constant PROTOCOLS. */
    private static final String PROTOCOLS = "protocols";

    /** The Constant NEGOTIATE. */
    private static final String NEGOTIATE = "Negotiate";

    /** The Constant NTLM. */
    private static final String NTLM = "NTLM";

    /** The protocols. */
    private List<String> protocolsList = new ArrayList<>();

    /** The auth. */
    private final IWindowsAuthProvider auth;

    /**
     * Instantiates a new negotiate security filter provider.
     *
     * @param newAuthProvider
     *            the new auth provider
     */
    public NegotiateSecurityFilterProvider(final IWindowsAuthProvider newAuthProvider) {
        this.auth = newAuthProvider;
        this.protocolsList.add(NegotiateSecurityFilterProvider.NEGOTIATE);
        this.protocolsList.add(NegotiateSecurityFilterProvider.NTLM);
    }

    /**
     * Gets the protocols.
     *
     * @return the protocols
     */
    public List<String> getProtocols() {
        return this.protocolsList;
    }

    /**
     * Sets the protocols.
     *
     * @param values
     *            the new protocols
     */
    public void setProtocols(final List<String> values) {
        this.protocolsList = values;
    }

    @Override
    public void sendUnauthorized(final HttpServletResponse response) {
        for (final String protocol : this.protocolsList) {
            response.addHeader(NegotiateSecurityFilterProvider.WWW_AUTHENTICATE, protocol);
        }
    }

    @Override
    public boolean isPrincipalException(final HttpServletRequest request) {
        final AuthorizationHeader authorizationHeader = new AuthorizationHeader(request);
        final boolean ntlmPost = authorizationHeader.isNtlmType1PostAuthorizationHeader();
        NegotiateSecurityFilterProvider.LOGGER.debug("authorization: {}, ntlm post: {}", authorizationHeader,
                Boolean.valueOf(ntlmPost));
        return ntlmPost;
    }

    @Override
    public IWindowsIdentity doFilter(final HttpServletRequest request, final HttpServletResponse response)
            throws IOException {

        final AuthorizationHeader authorizationHeader = new AuthorizationHeader(request);
        final boolean ntlmPost = authorizationHeader.isNtlmType1PostAuthorizationHeader();

        // maintain a connection-based session for NTLM tokens
        final String connectionId = NtlmServletRequest.getConnectionId(request);
        final String securityPackage = authorizationHeader.getSecurityPackage();
        NegotiateSecurityFilterProvider.LOGGER.debug("security package: {}, connection id: {}", securityPackage,
                connectionId);

        if (ntlmPost) {
            // type 2 NTLM authentication message received
            this.auth.resetSecurityToken(connectionId);
        }

        final byte[] tokenBuffer = authorizationHeader.getTokenBytes();
        NegotiateSecurityFilterProvider.LOGGER.debug("token buffer: {} byte(s)", Integer.valueOf(tokenBuffer.length));
        final IWindowsSecurityContext securityContext = this.auth.acceptSecurityToken(connectionId, tokenBuffer,
                securityPackage);

        final byte[] continueTokenBytes = securityContext.getToken();
        if (continueTokenBytes != null && continueTokenBytes.length > 0) {
            final String continueToken = Base64.getEncoder().encodeToString(continueTokenBytes);
            NegotiateSecurityFilterProvider.LOGGER.debug("continue token: {}", continueToken);
            response.addHeader(NegotiateSecurityFilterProvider.WWW_AUTHENTICATE, securityPackage + " " + continueToken);
        }

        NegotiateSecurityFilterProvider.LOGGER.debug("continue required: {}",
                Boolean.valueOf(securityContext.isContinue()));
        if (securityContext.isContinue()) {
            response.setHeader("Connection", "keep-alive");
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.flushBuffer();
            return null;
        }

        final IWindowsIdentity identity = securityContext.getIdentity();
        securityContext.dispose();
        return identity;
    }

    @Override
    public boolean isSecurityPackageSupported(final String securityPackage) {
        for (final String protocol : this.protocolsList) {
            if (protocol.equalsIgnoreCase(securityPackage)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public void initParameter(final String parameterName, final String parameterValue) {
        if (NegotiateSecurityFilterProvider.PROTOCOLS.equals(parameterName)) {
            this.protocolsList = new ArrayList<>();
            final String[] protocolNames = parameterValue.split("\\s+", -1);
            for (String protocolName : protocolNames) {
                protocolName = protocolName.trim();
                if (protocolName.length() > 0) {
                    NegotiateSecurityFilterProvider.LOGGER.debug("init protocol: {}", protocolName);
                    if (NegotiateSecurityFilterProvider.NEGOTIATE.equals(protocolName)
                            || NegotiateSecurityFilterProvider.NTLM.equals(protocolName)) {
                        this.protocolsList.add(protocolName);
                    } else {
                        NegotiateSecurityFilterProvider.LOGGER.error("unsupported protocol: {}", protocolName);
                        throw new RuntimeException("Unsupported protocol: " + protocolName);
                    }
                }
            }
        } else {
            throw new InvalidParameterException(parameterName);
        }
    }
}
File Project Line
waffle/windows/auth/impl/WindowsSecurityContextImpl.java waffle-jna-jakarta 44
waffle/windows/auth/impl/WindowsSecurityContextImpl.java waffle-jna 44
public class WindowsSecurityContextImpl implements IWindowsSecurityContext {

    /** The principal name. */
    private String principalName;

    /** The security package. */
    private String securityPackage;

    /** The token. */
    private ManagedSecBufferDesc token;

    /** The ctx. */
    private CtxtHandle ctx;

    /** The credentials. */
    private IWindowsCredentialsHandle credentials;

    /** The continue flag. */
    private boolean continueFlag;

    @Override
    public IWindowsImpersonationContext impersonate() {
        return new WindowsSecurityContextImpersonationContextImpl(this.ctx);
    }

    @Override
    public IWindowsIdentity getIdentity() {
        final HANDLEByReference phContextToken = new HANDLEByReference();
        final int rc = Secur32.INSTANCE.QuerySecurityContextToken(this.ctx, phContextToken);
        if (WinError.SEC_E_OK != rc) {
            throw new Win32Exception(rc);
        }
        return new WindowsIdentityImpl(phContextToken.getValue());
    }

    @Override
    public String getSecurityPackage() {
        return this.securityPackage;
    }

    @Override
    public byte[] getToken() {
        return this.token == null || this.token.getBuffer(0).getBytes() == null ? null
                : this.token.getBuffer(0).getBytes().clone();
    }

    /**
     * Get the current Windows security context for a given SSPI package.
     *
     * @param securityPackage
     *            SSPI package.
     * @param targetName
     *            The target of the context. The string contents are security-package specific.
     *
     * @return Windows security context.
     */
    public static IWindowsSecurityContext getCurrent(final String securityPackage, final String targetName) {
        IWindowsCredentialsHandle credentialsHandle = WindowsCredentialsHandleImpl.getCurrent(securityPackage);
        credentialsHandle.initialize();
        try {
            final WindowsSecurityContextImpl ctx = new WindowsSecurityContextImpl();
            ctx.setPrincipalName(WindowsAccountImpl.getCurrentUsername());
            ctx.setCredentialsHandle(credentialsHandle);
            ctx.setSecurityPackage(securityPackage);
            ctx.initialize(null, null, targetName);

            // Starting from here ctx 'owns' the credentials handle, so let's null out the
            // variable. This will prevent the finally block below from disposing it right away.
            credentialsHandle = null;

            return ctx;
        } finally {
            if (credentialsHandle != null) {
                credentialsHandle.dispose();
            }
        }
    }

    @Override
    public void initialize(final CtxtHandle continueCtx, final SecBufferDesc continueToken, final String targetName) {
        final IntByReference attr = new IntByReference();
        this.ctx = new CtxtHandle();
        int tokenSize = Sspi.MAX_TOKEN_SIZE;
        int rc;
        do {
            this.token = new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, tokenSize);
            rc = Secur32.INSTANCE.InitializeSecurityContext(this.credentials.getHandle(), continueCtx, targetName,
                    Sspi.ISC_REQ_CONNECTION, 0, Sspi.SECURITY_NATIVE_DREP, continueToken, 0, this.ctx, this.token, attr,
                    null);
            switch (rc) {
                case WinError.SEC_E_INSUFFICIENT_MEMORY:
                case WinError.SEC_E_BUFFER_TOO_SMALL:
                    tokenSize += Sspi.MAX_TOKEN_SIZE;
                    break;
                case WinError.SEC_I_CONTINUE_NEEDED:
                    this.continueFlag = true;
                    break;
                case WinError.SEC_E_OK:
                    this.continueFlag = false;
                    break;
                default:
                    throw new Win32Exception(rc);
            }
        } while (rc == WinError.SEC_E_INSUFFICIENT_MEMORY || rc == WinError.SEC_E_BUFFER_TOO_SMALL);
    }

    @Override
    public void dispose() {
        WindowsSecurityContextImpl.dispose(this.ctx);

        if (this.credentials != null) {
            this.credentials.dispose();
        }
    }

    /**
     * Dispose a security context.
     *
     * @param ctx
     *            Security context.
     *
     * @return True if a context was disposed.
     */
    public static boolean dispose(final CtxtHandle ctx) {
        if (ctx != null && !ctx.isNull()) {
            final int rc = Secur32.INSTANCE.DeleteSecurityContext(ctx);
            if (WinError.SEC_E_OK != rc) {
                throw new Win32Exception(rc);
            }
            return true;
        }
        return false;
    }

    @Override
    public String getPrincipalName() {
        return this.principalName;
    }

    /**
     * Sets the principal name.
     *
     * @param value
     *            the new principal name
     */
    public void setPrincipalName(final String value) {
        this.principalName = value;
    }

    @Override
    public CtxtHandle getHandle() {
        return this.ctx;
    }

    /**
     * Sets the credentials handle.
     *
     * @param handle
     *            the new credentials handle
     */
    public void setCredentialsHandle(final IWindowsCredentialsHandle handle) {
        this.credentials = handle;
    }

    /**
     * Sets the token.
     *
     * @param bytes
     *            the new token
     */
    public void setToken(final byte[] bytes) {
        this.token = new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, bytes);
    }

    /**
     * Sets the security package.
     *
     * @param value
     *            the new security package
     */
    public void setSecurityPackage(final String value) {
        this.securityPackage = value;
    }

    /**
     * Sets the security context.
     *
     * @param phNewServerContext
     *            the new security context
     */
    public void setSecurityContext(final CtxtHandle phNewServerContext) {
        this.ctx = phNewServerContext;
    }

    @Override
    public boolean isContinue() {
        return this.continueFlag;
    }

    /**
     * Sets the continue.
     *
     * @param b
     *            the new continue
     */
    public void setContinue(final boolean b) {
        this.continueFlag = b;
    }

}
File Project Line
waffle/mock/http/SimpleHttpRequest.java waffle-tests-jakarta 41
waffle/mock/http/SimpleHttpRequest.java waffle-tests 41
public class SimpleHttpRequest extends HttpServletRequestWrapper {

    /** The remote port s. */
    private static int remotePortS = 0;

    /** The request uri. */
    private String requestURI;

    /** The query string. */
    private String queryString;

    /** The remote user. */
    private String remoteUser;

    /** The method. */
    private String method = "GET";

    /** The remote host. */
    private String remoteHost;

    /** The remote addr. */
    private String remoteAddr;

    /** The remote port. */
    private int remotePort = -1;

    /** The headers. */
    private final Map<String, String> headers = new HashMap<>();

    /** The parameters. */
    private final Map<String, String> parameters = new HashMap<>();

    /** The content. */
    private byte[] content;

    /** The session. */
    private HttpSession session = new SimpleHttpSession();

    /** The principal. */
    private Principal principal;

    /**
     * Instantiates a new simple http request.
     */
    public SimpleHttpRequest() {
        super(Mockito.mock(HttpServletRequest.class));
        this.remotePort = SimpleHttpRequest.nextRemotePort();
    }

    /**
     * Next remote port.
     *
     * @return the int
     */
    public static synchronized int nextRemotePort() {
        return ++SimpleHttpRequest.remotePortS;
    }

    /**
     * Reset remote port.
     */
    public static synchronized void resetRemotePort() {
        SimpleHttpRequest.remotePortS = 0;
    }

    /**
     * Adds the header.
     *
     * @param headerName
     *            the header name
     * @param headerValue
     *            the header value
     */
    public void addHeader(final String headerName, final String headerValue) {
        this.headers.put(headerName, headerValue);
    }

    @Override
    public String getHeader(final String headerName) {
        return this.headers.get(headerName);
    }

    @Override
    public Enumeration<String> getHeaderNames() {
        return Collections.enumeration(this.headers.keySet());
    }

    @Override
    public String getMethod() {
        return this.method;
    }

    @Override
    public int getContentLength() {
        return this.content == null ? -1 : this.content.length;
    }

    @Override
    public int getRemotePort() {
        return this.remotePort;
    }

    /**
     * Sets the method.
     *
     * @param methodName
     *            the new method
     */
    public void setMethod(final String methodName) {
        this.method = methodName;
    }

    /**
     * Sets the content length.
     *
     * @param length
     *            the new content length
     */
    public void setContentLength(final int length) {
        this.content = new byte[length];
    }

    /**
     * Sets the remote user.
     *
     * @param username
     *            the new remote user
     */
    public void setRemoteUser(final String username) {
        this.remoteUser = username;
    }

    @Override
    public String getRemoteUser() {
        return this.remoteUser;
    }

    @Override
    public HttpSession getSession() {
        return this.session;
    }

    @Override
    public HttpSession getSession(final boolean create) {
        if (this.session == null && create) {
            this.session = new SimpleHttpSession();
        }
        return this.session;
    }

    @Override
    public String getQueryString() {
        return this.queryString;
    }

    /**
     * Sets the query string.
     *
     * @param query
     *            the new query string
     */
    public void setQueryString(final String query) {
        this.queryString = query;
        if (this.queryString != null) {
            for (final String eachParameter : this.queryString.split("[&]", -1)) {
                final String[] pair = eachParameter.split("=", -1);
                final String value = pair.length == 2 ? pair[1] : "";
                this.addParameter(pair[0], value);
            }
        }
    }

    /**
     * Sets the request uri.
     *
     * @param uri
     *            the new request uri
     */
    public void setRequestURI(final String uri) {
        this.requestURI = uri;
    }

    @Override
    public String getRequestURI() {
        return this.requestURI;
    }

    @Override
    public String getParameter(final String parameterName) {
        return this.parameters.get(parameterName);
    }

    /**
     * Adds the parameter.
     *
     * @param parameterName
     *            the parameter name
     * @param parameterValue
     *            the parameter value
     */
    public void addParameter(final String parameterName, final String parameterValue) {
        this.parameters.put(parameterName, parameterValue);
    }

    @Override
    public String getRemoteHost() {
        return this.remoteHost;
    }

    /**
     * Sets the remote host.
     *
     * @param value
     *            the new remote host
     */
    public void setRemoteHost(final String value) {
        this.remoteHost = value;
    }

    @Override
    public String getRemoteAddr() {
        return this.remoteAddr;
    }

    /**
     * Sets the remote addr.
     *
     * @param value
     *            the new remote addr
     */
    public void setRemoteAddr(final String value) {
        this.remoteAddr = value;
    }

    @Override
    public Principal getUserPrincipal() {
        return this.principal;
    }

    /**
     * Sets the user principal.
     *
     * @param value
     *            the new user principal
     */
    public void setUserPrincipal(final Principal value) {
        this.principal = value;
    }
}
File Project Line
waffle/spring/DelegatingNegotiateSecurityFilter.java waffle-spring-security5 77
waffle/spring/DelegatingNegotiateSecurityFilter.java waffle-spring-security6 77
public class DelegatingNegotiateSecurityFilter extends NegotiateSecurityFilter {

    /** The Constant LOGGER. */
    private static final Logger LOGGER = LoggerFactory.getLogger(DelegatingNegotiateSecurityFilter.class);

    /** The authentication manager. */
    private AuthenticationManager authenticationManager;

    /** The authentication success handler. */
    private AuthenticationSuccessHandler authenticationSuccessHandler;

    /** The authentication failure handler. */
    private AuthenticationFailureHandler authenticationFailureHandler;

    /** The access denied handler. */
    private AccessDeniedHandler accessDeniedHandler;

    /**
     * Instantiates a new delegating negotiate security filter.
     */
    public DelegatingNegotiateSecurityFilter() {
        super();
        DelegatingNegotiateSecurityFilter.LOGGER.debug("[waffle.spring.NegotiateSecurityFilter] loaded");
    }

    /**
     * Gets the access denied handler.
     *
     * @return the accessDeniedHandler
     */
    public AccessDeniedHandler getAccessDeniedHandler() {
        return this.accessDeniedHandler;
    }

    /**
     * Sets the access denied handler.
     *
     * @param value
     *            the accessDeniedHandler to set
     */
    public void setAccessDeniedHandler(final AccessDeniedHandler value) {
        this.accessDeniedHandler = value;
    }

    /**
     * Gets the authentication failure handler.
     *
     * @return the authenticationFailureHandler
     */
    public AuthenticationFailureHandler getAuthenticationFailureHandler() {
        return this.authenticationFailureHandler;
    }

    /**
     * Sets the authentication failure handler.
     *
     * @param value
     *            the authenticationFailureHandler to set
     */
    public void setAuthenticationFailureHandler(final AuthenticationFailureHandler value) {
        this.authenticationFailureHandler = value;
    }

    @Override
    protected boolean setAuthentication(final HttpServletRequest request, final HttpServletResponse response,
            final Authentication authentication) {
        try {
            Authentication delegateAuthentication = authentication;
            if (this.authenticationManager != null) {
                DelegatingNegotiateSecurityFilter.LOGGER.debug("Delegating to custom authenticationmanager");
                delegateAuthentication = this.authenticationManager.authenticate(authentication);
            }
            SecurityContextHolder.getContext().setAuthentication(delegateAuthentication);
            if (this.authenticationSuccessHandler != null) {
                try {
                    this.authenticationSuccessHandler.onAuthenticationSuccess(request, response,
                            delegateAuthentication);
                } catch (final IOException | ServletException e) {
                    DelegatingNegotiateSecurityFilter.LOGGER.warn("Error calling authenticationSuccessHandler: {}",
                            e.getMessage());
                    DelegatingNegotiateSecurityFilter.LOGGER.trace("", e);
                    return false;
                }
            }
        } catch (final AuthenticationException e) {
            DelegatingNegotiateSecurityFilter.LOGGER
                    .warn("Error authenticating user in custom authenticationmanager: {}", e.getMessage());
            this.sendAuthenticationFailed(request, response, e);
            return false;
        } catch (final AccessDeniedException e) {
            DelegatingNegotiateSecurityFilter.LOGGER.warn("Error authorizing user in custom authenticationmanager: {}",
                    e.getMessage());
            this.sendAccessDenied(request, response, e);
            return false;
        }
        return true;
    }

    @Override
    public void afterPropertiesSet() throws ServletException {
        super.afterPropertiesSet();

        if (this.getProvider() == null) {
            throw new ServletException("Missing NegotiateSecurityFilter.Provider");
        }
    }

    /**
     * Forward to authenticationFailureHandler.
     *
     * @param request
     *            the request
     * @param response
     *            HTTP Response
     * @param ae
     *            the ae
     */
    private void sendAuthenticationFailed(final HttpServletRequest request, final HttpServletResponse response,
            final AuthenticationException ae) {
        if (this.authenticationFailureHandler != null) {
            try {
                this.authenticationFailureHandler.onAuthenticationFailure(request, response, ae);
                return;
            } catch (final IOException e) {
                DelegatingNegotiateSecurityFilter.LOGGER.warn("IOException invoking authenticationFailureHandler: {}",
                        e.getMessage());
                DelegatingNegotiateSecurityFilter.LOGGER.trace("", e);
            } catch (final ServletException e) {
                DelegatingNegotiateSecurityFilter.LOGGER
                        .warn("ServletException invoking authenticationFailureHandler: {}", e.getMessage());
                DelegatingNegotiateSecurityFilter.LOGGER.trace("", e);
            }
        }
        super.sendUnauthorized(response, true);
    }

    /**
     * Forward to accessDeniedHandler.
     *
     * @param request
     *            the request
     * @param response
     *            HTTP Response
     * @param ae
     *            the ae
     */
    private void sendAccessDenied(final HttpServletRequest request, final HttpServletResponse response,
            final AccessDeniedException ae) {
        if (this.accessDeniedHandler != null) {
            try {
                this.accessDeniedHandler.handle(request, response, ae);
                return;
            } catch (final IOException e) {
                DelegatingNegotiateSecurityFilter.LOGGER.warn("IOException invoking accessDeniedHandler: {}",
                        e.getMessage());
                DelegatingNegotiateSecurityFilter.LOGGER.trace("", e);
            } catch (final ServletException e) {
                DelegatingNegotiateSecurityFilter.LOGGER.warn("ServletException invoking accessDeniedHandler: {}",
                        e.getMessage());
                DelegatingNegotiateSecurityFilter.LOGGER.trace("", e);
            }
        }
        // fallback
        this.sendUnauthorized(response, true);
    }

    /**
     * Gets the authentication success handler.
     *
     * @return the authenticationSuccessHandler
     */
    public AuthenticationSuccessHandler getAuthenticationSuccessHandler() {
        return this.authenticationSuccessHandler;
    }

    /**
     * Sets the authentication success handler.
     *
     * @param value
     *            the authenticationSuccessHandler to set
     */
    public void setAuthenticationSuccessHandler(final AuthenticationSuccessHandler value) {
        this.authenticationSuccessHandler = value;
    }

    /**
     * Gets the authentication manager.
     *
     * @return the authenticationManager
     */
    public AuthenticationManager getAuthenticationManager() {
        return this.authenticationManager;
    }

    /**
     * Sets the authentication manager.
     *
     * @param value
     *            the authenticationManager to set
     */
    public void setAuthenticationManager(final AuthenticationManager value) {
        this.authenticationManager = value;
    }

}
File Project Line
waffle/mock/http/SimpleHttpResponse.java waffle-tests-jakarta 48
waffle/mock/http/SimpleHttpResponse.java waffle-tests 48
public class SimpleHttpResponse extends HttpServletResponseWrapper {

    /** The Constant LOGGER. */
    private static final Logger LOGGER = LoggerFactory.getLogger(SimpleHttpResponse.class);

    /** The status. */
    private int status = 500;

    /** The headers. */
    private final Map<String, List<String>> headers = new HashMap<>();

    /** The bytes. */
    final ByteArrayOutputStream bytes = new ByteArrayOutputStream();

    /** The out. */
    private final ServletOutputStream out = new ServletOutputStream() {
        @Override
        public void write(final int b) throws IOException {
            SimpleHttpResponse.this.bytes.write(b);
        }

        @Override
        public boolean isReady() {
            return false;
        }

        @Override
        public void setWriteListener(final WriteListener writeListener) {
            // Not used
        }
    };

    /** The writer. */
    private final PrintWriter writer = new PrintWriter(new OutputStreamWriter(this.bytes, StandardCharsets.UTF_8),
            true);

    /**
     * Instantiates a new simple http response.
     */
    public SimpleHttpResponse() {
        super(Mockito.mock(HttpServletResponse.class));
    }

    /**
     * Gets the status.
     *
     * @return the status
     */
    @Override
    public int getStatus() {
        return this.status;
    }

    @Override
    public void addHeader(final String headerName, final String headerValue) {
        List<String> current = this.headers.get(headerName);
        if (current == null) {
            current = new ArrayList<>();
        }
        current.add(headerValue);
        this.headers.put(headerName, current);
    }

    @Override
    public void setHeader(final String headerName, final String headerValue) {
        List<String> current = this.headers.get(headerName);
        if (current == null) {
            current = new ArrayList<>();
        } else {
            current.clear();
        }
        current.add(headerValue);
        this.headers.put(headerName, current);
    }

    @Override
    public void setStatus(final int value) {
        this.status = value;
    }

    /**
     * Gets the status string.
     *
     * @return the status string
     */
    public String getStatusString() {
        if (this.status == 401) {
            return "Unauthorized";
        }
        return "Unknown";
    }

    @Override
    public void flushBuffer() {
        SimpleHttpResponse.LOGGER.info("{}: {}", Integer.valueOf(this.status), this.getStatusString());
        for (final Map.Entry<String, List<String>> header : this.headers.entrySet()) {
            for (final String headerValue : header.getValue()) {
                SimpleHttpResponse.LOGGER.info("{}: {}", header, headerValue);
            }
        }
    }

    /**
     * Use this for testing the number of headers.
     *
     * @return int header name size.
     */
    public int getHeaderNamesSize() {
        return this.headers.size();
    }

    /**
     * Gets the header values.
     *
     * @param headerName
     *            the header name
     *
     * @return the header values
     */
    public String[] getHeaderValues(final String headerName) {
        final List<String> headerValues = this.headers.get(headerName);
        return headerValues == null ? null : headerValues.toArray(new String[0]);
    }

    /**
     * Gets the header.
     *
     * @param headerName
     *            the header name
     *
     * @return the header
     */
    @Override
    public String getHeader(final String headerName) {
        final List<String> headerValues = this.headers.get(headerName);
        return headerValues == null ? null : String.join(", ", headerValues);
    }

    @Override
    public void sendError(final int rc, final String message) {
        this.status = rc;
    }

    @Override
    public void sendError(final int rc) {
        this.status = rc;
    }

    @Override
    public PrintWriter getWriter() {
        return this.writer;
    }

    @Override
    public ServletOutputStream getOutputStream() throws IOException {
        return this.out;
    }

    /**
     * Gets the output text.
     *
     * @return the output text
     */
    public String getOutputText() {
        this.writer.flush();
        return this.bytes.toString(StandardCharsets.UTF_8);
    }
}
File Project Line
waffle/jaas/WindowsLoginModule.java waffle-jna-jakarta 58
waffle/jaas/WindowsLoginModule.java waffle-jna 58
public class WindowsLoginModule implements LoginModule {

    /** The Constant LOGGER. */
    private static final Logger LOGGER = LoggerFactory.getLogger(WindowsLoginModule.class);

    /** The username. */
    private String username;

    /** The debug. */
    private boolean debug;

    /** The subject. */
    private Subject subject;

    /** The callback handler. */
    private CallbackHandler callbackHandler;

    /** The auth. */
    private IWindowsAuthProvider auth = new WindowsAuthProviderImpl();

    /** The principals. */
    private Set<Principal> principals;

    /** The principal format. */
    private PrincipalFormat principalFormat = PrincipalFormat.FQN;

    /** The role format. */
    private PrincipalFormat roleFormat = PrincipalFormat.FQN;

    /** The allow guest login. */
    private boolean allowGuestLogin = true;

    @Override
    public void initialize(final Subject initSubject, final CallbackHandler initCallbackHandler,
            final Map<String, ?> initSharedState, final Map<String, ?> initOptions) {

        this.subject = initSubject;
        this.callbackHandler = initCallbackHandler;

        for (final Map.Entry<String, ?> option : initOptions.entrySet()) {
            if ("debug".equalsIgnoreCase(option.getKey())) {
                this.debug = Boolean.parseBoolean((String) option.getValue());
            } else if ("principalFormat".equalsIgnoreCase(option.getKey())) {
                this.principalFormat = PrincipalFormat
                        .valueOf(((String) option.getValue()).toUpperCase(Locale.ENGLISH));
            } else if ("roleFormat".equalsIgnoreCase(option.getKey())) {
                this.roleFormat = PrincipalFormat.valueOf(((String) option.getValue()).toUpperCase(Locale.ENGLISH));
            }
        }
    }

    /**
     * Use Windows SSPI to authenticate a username with a password.
     *
     * @return true, if successful
     *
     * @throws LoginException
     *             the login exception
     */
    @Override
    public boolean login() throws LoginException {
        if (this.callbackHandler == null) {
            throw new LoginException("Missing callback to gather information from the user.");
        }

        final NameCallback usernameCallback = new NameCallback("user name: ");
        final PasswordCallback passwordCallback = new PasswordCallback("password: ", false);

        final Callback[] callbacks = new Callback[2];
        callbacks[0] = usernameCallback;
        callbacks[1] = passwordCallback;

        final String userName;
        final String password;

        try {
            this.callbackHandler.handle(callbacks);
            userName = usernameCallback.getName();
            password = passwordCallback.getPassword() == null ? "" : new String(passwordCallback.getPassword());
            passwordCallback.clearPassword();
        } catch (final IOException e) {
            WindowsLoginModule.LOGGER.trace("", e);
            throw new LoginException(e.toString());
        } catch (final UnsupportedCallbackException e) {
            WindowsLoginModule.LOGGER.trace("", e);
            throw new LoginException("Callback {} not available to gather authentication information from the user."
                    .replace("{}", e.getCallback().getClass().getName()));
        }

        IWindowsIdentity windowsIdentity;
        try {
            windowsIdentity = this.auth.logonUser(userName, password);
        } catch (final Exception e) {
            WindowsLoginModule.LOGGER.trace("", e);
            throw new LoginException(e.getMessage());
        }

        try {
            // disable guest login
            if (!this.allowGuestLogin && windowsIdentity.isGuest()) {
                WindowsLoginModule.LOGGER.debug("guest login disabled: {}", windowsIdentity.getFqn());
                throw new LoginException("Guest login disabled");
            }

            this.principals = new LinkedHashSet<>();
            // add the main user principal to the subject principals
            this.principals.addAll(WindowsLoginModule.getUserPrincipals(windowsIdentity, this.principalFormat));
            if (this.roleFormat != PrincipalFormat.NONE) {
File Project Line
waffle/jaas/WindowsLoginModule.java waffle-jna-jakarta 177
waffle/jaas/WindowsLoginModule.java waffle-jna 170
}

            this.username = windowsIdentity.getFqn();
            WindowsLoginModule.LOGGER.debug("successfully logged in {} ({})", this.username,
                    windowsIdentity.getSidString());
        } finally {
            windowsIdentity.dispose();
        }

        return true;
    }

    /**
     * Abort a login process.
     *
     * @return true, if successful
     *
     * @throws LoginException
     *             the login exception
     */
    @Override
    public boolean abort() throws LoginException {
        return this.logout();
    }

    /**
     * Commit principals to the subject.
     *
     * @return true, if successful
     *
     * @throws LoginException
     *             the login exception
     */
    @Override
    public boolean commit() throws LoginException {
        if (this.principals == null) {
            return false;
        }

        if (this.subject.isReadOnly()) {
            throw new LoginException("Subject cannot be read-only.");
        }

        final Set<Principal> principalsSet = this.subject.getPrincipals();
        principalsSet.addAll(this.principals);

        WindowsLoginModule.LOGGER.debug("committing {} principals",
                Integer.valueOf(this.subject.getPrincipals().size()));
        if (this.debug) {
            for (final Principal principal : principalsSet) {
                WindowsLoginModule.LOGGER.debug(" principal: {}", principal.getName());
            }
        }

        return true;
    }

    /**
     * Logout a user.
     *
     * @return true, if successful
     *
     * @throws LoginException
     *             the login exception
     */
    @Override
    public boolean logout() throws LoginException {
        if (this.subject.isReadOnly()) {
            throw new LoginException("Subject cannot be read-only.");
        }

        this.subject.getPrincipals().clear();

        if (this.username != null) {
            WindowsLoginModule.LOGGER.debug("logging out {}", this.username);
        }

        return true;
    }

    /**
     * True if Debug is enabled.
     *
     * @return True or false.
     */
    public boolean isDebug() {
        return this.debug;
    }

    /**
     * Windows auth provider.
     *
     * @return IWindowsAuthProvider.
     */
    public IWindowsAuthProvider getAuth() {
        return this.auth;
    }

    /**
     * Set Windows auth provider.
     *
     * @param provider
     *            Class implements IWindowsAuthProvider.
     */
    public void setAuth(final IWindowsAuthProvider provider) {
        this.auth = provider;
    }

    /**
     * Returns a list of user principal objects.
     *
     * @param windowsIdentity
     *            Windows identity.
     * @param principalFormat
     *            Principal format.
     *
     * @return A list of user principal objects.
     */
    private static List<Principal> getUserPrincipals(final IWindowsIdentity windowsIdentity,
            final PrincipalFormat principalFormat) {

        final List<Principal> principalsList = new ArrayList<>();
        switch (principalFormat) {
            case FQN:
                principalsList.add(new UserPrincipal(windowsIdentity.getFqn()));
                break;
            case SID:
                principalsList.add(new UserPrincipal(windowsIdentity.getSidString()));
                break;
            case BOTH:
                principalsList.add(new UserPrincipal(windowsIdentity.getFqn()));
                principalsList.add(new UserPrincipal(windowsIdentity.getSidString()));
                break;
            case NONE:
            default:
                break;
        }
        return principalsList;
    }

    /**
     * Returns a list of role principal objects.
     *
     * @param group
     *            Windows group.
     * @param principalFormat
     *            Principal format.
     *
     * @return List of role principal objects.
     */
    private static List<Principal> getRolePrincipals(final IWindowsAccount group,
            final PrincipalFormat principalFormat) {

        final List<Principal> principalsList = new ArrayList<>();
        switch (principalFormat) {
            case FQN:
                principalsList.add(new RolePrincipal(group.getFqn()));
                break;
            case SID:
                principalsList.add(new RolePrincipal(group.getSidString()));
                break;
            case BOTH:
                principalsList.add(new RolePrincipal(group.getFqn()));
                principalsList.add(new RolePrincipal(group.getSidString()));
                break;
            case NONE:
                break;
            default:
                break;
        }
        return principalsList;
    }

    /**
     * True if Guest login permitted.
     *
     * @return True if Guest login permitted, false otherwise.
     */
    public boolean isAllowGuestLogin() {
        return this.allowGuestLogin;
    }

    /**
     * Set whether Guest login is permitted. Default is true, if the Guest account is enabled, an invalid
     * username/password results in a Guest login.
     *
     * @param value
     *            True or false.
     */
    public void setAllowGuestLogin(final boolean value) {
        this.allowGuestLogin = value;
    }
}
File Project Line
waffle/servlet/WaffleInfoServlet.java waffle-jna-jakarta 54
waffle/servlet/WaffleInfoServlet.java waffle-jna 53
public class WaffleInfoServlet extends HttpServlet {

    /** The Constant serialVersionUID. */
    private static final long serialVersionUID = 1L;

    /** The Constant Logger. */
    private static final Logger logger = LoggerFactory.getLogger(WaffleInfoServlet.class);

    @Override
    public void doGet(final HttpServletRequest request, final HttpServletResponse response) {
        this.getWaffleInfoResponse(request, response);
    }

    @Override
    public void doPost(final HttpServletRequest request, final HttpServletResponse response) {
        this.getWaffleInfoResponse(request, response);
    }

    /**
     * Gets the waffle info response.
     *
     * @param request
     *            the request
     * @param response
     *            the response
     */
    public void getWaffleInfoResponse(final HttpServletRequest request, final HttpServletResponse response) {
        final WaffleInfo info = new WaffleInfo();
        try {
            final Document doc = info.getWaffleInfo();
            final Element root = doc.getDocumentElement();

            // Add the Request Information Here
            final Element http = this.getRequestInfo(doc, request);
            root.insertBefore(http, root.getFirstChild());

            // Lookup Accounts By Name
            final String[] lookup = request.getParameterValues("lookup");
            if (lookup != null) {
                for (final String name : lookup) {
                    root.appendChild(info.getLookupInfo(doc, name));
                }
            }

            // Write the XML Response
            final TransformerFactory transfac = TransformerFactory.newInstance();
            transfac.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
            transfac.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");

            final Transformer trans = transfac.newTransformer();
            trans.setOutputProperty(OutputKeys.INDENT, "yes");

            final StreamResult result = new StreamResult(response.getWriter());
            final DOMSource source = new DOMSource(doc);
            trans.transform(source, result);
            response.setContentType("application/xml");
        } catch (final ParserConfigurationException | TransformerException | IOException e) {
            WaffleInfoServlet.logger.error("", e);
            throw new RuntimeException("See logs for underlying error condition");
        }
    }

    /**
     * Gets the request info.
     *
     * @param doc
     *            the doc
     * @param request
     *            the request
     *
     * @return the request info
     */
    private Element getRequestInfo(final Document doc, final HttpServletRequest request) {
        final Element node = doc.createElement("request");

        Element value = doc.createElement("AuthType");
        value.setTextContent(request.getAuthType());
        node.appendChild(value);

        final Principal p = request.getUserPrincipal();
        if (p != null) {
            final Element child = doc.createElement("principal");
            child.setAttribute("class", p.getClass().getName());

            value = doc.createElement("name");
            value.setTextContent(p.getName());
            child.appendChild(value);

            value = doc.createElement("string");
            value.setTextContent(p.toString());
            child.appendChild(value);

            node.appendChild(child);
        }

        final List<String> headers = Collections.list(request.getHeaderNames());
        if (!headers.isEmpty()) {
            final Element child = doc.createElement("headers");
            for (String header : headers) {
                value = doc.createElement(header);
                value.setTextContent(request.getHeader(header));
                child.appendChild(value);
            }
            node.appendChild(child);
        }
        return node;
    }

}
File Project Line
waffle/spring/boot/WaffleAutoConfiguration.java waffle-spring-boot-autoconfigure2 52
waffle/spring/boot/WaffleAutoConfiguration.java waffle-spring-boot-autoconfigure3 52
@Configuration
@EnableConfigurationProperties(WaffleProperties.class)
public class WaffleAutoConfiguration {

    /** The properties. */
    private final WaffleProperties properties;

    /**
     * Instantiates a new waffle auto configuration.
     *
     * @param properties
     *            the properties
     */
    public WaffleAutoConfiguration(final WaffleProperties properties) {
        this.properties = properties;
    }

    /**
     * The {@link WindowsAuthProviderImpl} instance.
     *
     * @return the windows auth provider impl
     */
    @Bean
    @ConditionalOnMissingBean
    public WindowsAuthProviderImpl waffleWindowsAuthProvider() {
        return new WindowsAuthProviderImpl();
    }

    /**
     * The default {@link GrantedAuthority} that is applied to all users. Default can be overridden by defining a bean
     * of type {@link GrantedAuthority} with name "defaultGrantedAuthority".
     *
     * @return the granted authority
     */
    @Bean
    @ConditionalOnMissingBean(name = "defaultGrantedAuthority")
    public GrantedAuthority defaultGrantedAuthority() {
        return WindowsAuthenticationToken.DEFAULT_GRANTED_AUTHORITY;
    }

    /**
     * The default {@link GrantedAuthorityFactory} that is used. Default can be overridden by defining a bean of type
     * {@link GrantedAuthorityFactory}.
     *
     * @return the granted authority factory
     */
    @Bean
    @ConditionalOnMissingBean
    public GrantedAuthorityFactory grantedAuthorityFactory() {
        return WindowsAuthenticationToken.DEFAULT_GRANTED_AUTHORITY_FACTORY;
    }

    /**
     * The {@link WindowsAuthenticationProvider} that can be used by Spring Security by an {@link AuthenticationManager}
     * to provide authentication.
     *
     * @param waffleWindowsAuthProvider
     *            the waffle windows auth provider
     * @param defaultGrantedAuthority
     *            the default granted authority
     * @param grantedAuthorityFactory
     *            the granted authority factory
     *
     * @return the windows authentication provider
     */
    @Bean
    @ConditionalOnMissingBean
    public WindowsAuthenticationProvider waffleSpringAuthenticationProvider(
            final WindowsAuthProviderImpl waffleWindowsAuthProvider,
            @Qualifier("defaultGrantedAuthority") final GrantedAuthority defaultGrantedAuthority,
            final GrantedAuthorityFactory grantedAuthorityFactory) {
        final WindowsAuthenticationProvider bean = new WindowsAuthenticationProvider();
        bean.setAuthProvider(waffleWindowsAuthProvider);
        bean.setPrincipalFormat(this.properties.getPrincipalFormat());
        bean.setRoleFormat(this.properties.getRoleFormat());
        bean.setAllowGuestLogin(this.properties.isAllowGuestLogin());
        bean.setDefaultGrantedAuthority(defaultGrantedAuthority);
        bean.setGrantedAuthorityFactory(grantedAuthorityFactory);
        return bean;
    }

    /**
     * The {@link NegotiateSecurityFilterProvider} that provides single-sign-on authentication using Negotiate with the
     * configured protocols. Instantiated only when sso is enabled.
     *
     * @param windowsAuthProvider
     *            the windows auth provider
     *
     * @return the negotiate security filter provider
     */
    @Bean
    @ConditionalOnProperty("waffle.sso.enabled")
    @ConditionalOnMissingBean
    public NegotiateSecurityFilterProvider negotiateSecurityFilterProvider(
            final WindowsAuthProviderImpl windowsAuthProvider) {
        final NegotiateSecurityFilterProvider bean = new NegotiateSecurityFilterProvider(windowsAuthProvider);
        bean.setProtocols(this.properties.getSso().getProtocols());
        return bean;
    }

    /**
     * The {@link BasicSecurityFilterProvider} that provides Basic authentication fall back when using single-sign-on
     * with unsupported browser. Instantiated only when sso is enabled.
     *
     * @param windowsAuthProvider
     *            the windows auth provider
     *
     * @return the basic security filter provider
     */
    @Bean
    @ConditionalOnProperty("waffle.sso.enabled")
    @ConditionalOnMissingBean
    public BasicSecurityFilterProvider basicSecurityFilterProvider(final WindowsAuthProviderImpl windowsAuthProvider) {
        return new BasicSecurityFilterProvider(windowsAuthProvider);
    }

    /**
     * The {@link SecurityFilterProviderCollection} that includes {@link NegotiateSecurityFilterProvider} and/or
     * {@link BasicSecurityFilterProvider} depending on configuration. Instantiated only when sso is enabled.
     *
     * @param negotiateProvider
     *            the negotiate provider
     * @param basicProvider
     *            the basic provider
     *
     * @return the security filter provider collection
     */
    @Bean
    @ConditionalOnProperty("waffle.sso.enabled")
    @ConditionalOnMissingBean
    public SecurityFilterProviderCollection waffleSecurityFilterProviderCollection(
            final NegotiateSecurityFilterProvider negotiateProvider, final BasicSecurityFilterProvider basicProvider) {
        SecurityFilterProvider[] providers;
        if (this.properties.getSso().isBasicEnabled()) {
            providers = new SecurityFilterProvider[] { negotiateProvider, basicProvider };
        } else {
            providers = new SecurityFilterProvider[] { negotiateProvider };
        }
        return new SecurityFilterProviderCollection(providers);
    }

    /**
     * The {@link NegotiateSecurityFilterEntryPoint} for use by the Spring Security {@link AuthenticationManager} when
     * using single-sign-on. Instantiated only when sso is enabled.
     *
     * @param providers
     *            the providers
     *
     * @return the negotiate security filter entry point
     */
    @Bean
    @ConditionalOnProperty("waffle.sso.enabled")
    @ConditionalOnMissingBean
    public NegotiateSecurityFilterEntryPoint negotiateSecurityFilterEntryPoint(
            final SecurityFilterProviderCollection providers) {
        final NegotiateSecurityFilterEntryPoint bean = new NegotiateSecurityFilterEntryPoint();
        bean.setProvider(providers);
        return bean;
    }

    /**
     * The {@link NegotiateSecurityFilter} to be used by Spring Security {@link AuthenticationManager} when using
     * single-sign-on. Instantiated only when sso is enabled.
     *
     * @param providers
     *            the providers
     * @param defaultGrantedAuthority
     *            the default granted authority
     * @param grantedAuthorityFactory
     *            the granted authority factory
     *
     * @return the negotiate security filter
     */
    @Bean
    @ConditionalOnProperty("waffle.sso.enabled")
    @ConditionalOnMissingBean
    public NegotiateSecurityFilter waffleNegotiateSecurityFilter(final SecurityFilterProviderCollection providers,
            @Qualifier("defaultGrantedAuthority") final GrantedAuthority defaultGrantedAuthority,
            final GrantedAuthorityFactory grantedAuthorityFactory) {
        final NegotiateSecurityFilter bean = new NegotiateSecurityFilter();
        bean.setProvider(providers);
        bean.setPrincipalFormat(this.properties.getPrincipalFormat());
        bean.setRoleFormat(this.properties.getRoleFormat());
        bean.setAllowGuestLogin(this.properties.isAllowGuestLogin());
        bean.setImpersonate(this.properties.getSso().isImpersonate());
        bean.setDefaultGrantedAuthority(defaultGrantedAuthority);
        bean.setGrantedAuthorityFactory(grantedAuthorityFactory);
        return bean;
    }

    /**
     * When using Spring Boot, {@link Filter}s are automatically registered. In this case, the filter must be manually
     * configured within an {@link AuthenticationManager} and so we must prevent Spring Boot from registering it a
     * second time.
     *
     * @param filter
     *            The filter that we will be disabling from auto registration.
     *
     * @return the filter registration bean
     */
    @Bean
    @ConditionalOnProperty("waffle.sso.enabled")
    public FilterRegistrationBean<NegotiateSecurityFilter> waffleNegotiateSecurityFilterRegistrationBean(
            final NegotiateSecurityFilter filter) {
        final FilterRegistrationBean<NegotiateSecurityFilter> bean = new FilterRegistrationBean<>(filter);
        bean.setEnabled(false);
        return bean;
    }

}
File Project Line
waffle/spring/WindowsAuthenticationProvider.java waffle-spring-security5 46
waffle/spring/WindowsAuthenticationProvider.java waffle-spring-security6 46
public class WindowsAuthenticationProvider implements AuthenticationProvider {

    /** The Constant LOGGER. */
    private static final Logger LOGGER = LoggerFactory.getLogger(WindowsAuthenticationProvider.class);

    /** The principal format. */
    private PrincipalFormat principalFormat = PrincipalFormat.FQN;

    /** The role format. */
    private PrincipalFormat roleFormat = PrincipalFormat.FQN;

    /** The allow guest login. */
    private boolean allowGuestLogin = true;

    /** The auth provider. */
    private IWindowsAuthProvider authProvider;

    /** The granted authority factory. */
    private GrantedAuthorityFactory grantedAuthorityFactory = WindowsAuthenticationToken.DEFAULT_GRANTED_AUTHORITY_FACTORY;

    /** The default granted authority. */
    private GrantedAuthority defaultGrantedAuthority = WindowsAuthenticationToken.DEFAULT_GRANTED_AUTHORITY;

    /**
     * Instantiates a new windows authentication provider.
     */
    public WindowsAuthenticationProvider() {
        WindowsAuthenticationProvider.LOGGER.debug("[waffle.spring.WindowsAuthenticationProvider] loaded");
    }

    @Override
    public Authentication authenticate(final Authentication authentication) {
        final UsernamePasswordAuthenticationToken auth = (UsernamePasswordAuthenticationToken) authentication;
        IWindowsIdentity windowsIdentity;
        try {
            windowsIdentity = this.authProvider.logonUser(auth.getName(), auth.getCredentials().toString());
        } catch (final Win32Exception e) {
            throw new AuthenticationServiceException(e.getMessage(), e);
        }
        WindowsAuthenticationProvider.LOGGER.debug("logged in user: {} ({})", windowsIdentity.getFqn(),
                windowsIdentity.getSidString());

        if (!this.allowGuestLogin && windowsIdentity.isGuest()) {
            WindowsAuthenticationProvider.LOGGER.warn("guest login disabled: {}", windowsIdentity.getFqn());
            throw new GuestLoginDisabledAuthenticationException(windowsIdentity.getFqn());
        }

        final WindowsPrincipal windowsPrincipal = new WindowsPrincipal(windowsIdentity, this.principalFormat,
                this.roleFormat);
        WindowsAuthenticationProvider.LOGGER.debug("roles: {}", windowsPrincipal.getRolesString());

        final WindowsAuthenticationToken token = new WindowsAuthenticationToken(windowsPrincipal,
                this.grantedAuthorityFactory, this.defaultGrantedAuthority);

        WindowsAuthenticationProvider.LOGGER.info("successfully logged in user: {}", windowsIdentity.getFqn());
        return token;
    }

    /**
     * Supports.
     *
     * @param authentication
     *            the authentication
     *
     * @return true, if successful
     */
    @Override
    public boolean supports(final Class<? extends Object> authentication) {
        return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
    }

    /**
     * Gets the principal format.
     *
     * @return the principal format
     */
    public PrincipalFormat getPrincipalFormat() {
        return this.principalFormat;
    }

    /**
     * Sets the principal format enum.
     *
     * @param value
     *            the new principal format enum
     */
    public void setPrincipalFormatEnum(final PrincipalFormat value) {
        this.principalFormat = value;
    }

    /**
     * Sets the principal format.
     *
     * @param value
     *            the new principal format
     */
    public void setPrincipalFormat(final String value) {
        this.setPrincipalFormatEnum(PrincipalFormat.valueOf(value.toUpperCase(Locale.ENGLISH)));
    }

    /**
     * Gets the role format.
     *
     * @return the role format
     */
    public PrincipalFormat getRoleFormat() {
        return this.roleFormat;
    }

    /**
     * Sets the role format enum.
     *
     * @param value
     *            the new role format enum
     */
    public void setRoleFormatEnum(final PrincipalFormat value) {
        this.roleFormat = value;
    }

    /**
     * Sets the role format.
     *
     * @param value
     *            the new role format
     */
    public void setRoleFormat(final String value) {
        this.setRoleFormatEnum(PrincipalFormat.valueOf(value.toUpperCase(Locale.ENGLISH)));
    }

    /**
     * Checks if is allow guest login.
     *
     * @return true, if is allow guest login
     */
    public boolean isAllowGuestLogin() {
        return this.allowGuestLogin;
    }

    /**
     * Sets the allow guest login.
     *
     * @param value
     *            the new allow guest login
     */
    public void setAllowGuestLogin(final boolean value) {
        this.allowGuestLogin = value;
    }

    /**
     * Gets the auth provider.
     *
     * @return the auth provider
     */
    public IWindowsAuthProvider getAuthProvider() {
        return this.authProvider;
    }

    /**
     * Sets the auth provider.
     *
     * @param value
     *            the new auth provider
     */
    public void setAuthProvider(final IWindowsAuthProvider value) {
        this.authProvider = value;
    }

    /**
     * Gets the granted authority factory.
     *
     * @return the granted authority factory
     */
    public GrantedAuthorityFactory getGrantedAuthorityFactory() {
        return this.grantedAuthorityFactory;
    }

    /**
     * Sets the granted authority factory.
     *
     * @param value
     *            the new granted authority factory
     */
    public void setGrantedAuthorityFactory(final GrantedAuthorityFactory value) {
        this.grantedAuthorityFactory = value;
    }

    /**
     * Gets the default granted authority.
     *
     * @return the default granted authority
     */
    public GrantedAuthority getDefaultGrantedAuthority() {
        return this.defaultGrantedAuthority;
    }

    /**
     * Sets the default granted authority.
     *
     * @param value
     *            the new default granted authority
     */
    public void setDefaultGrantedAuthority(final GrantedAuthority value) {
        this.defaultGrantedAuthority = value;
    }
}
File Project Line
waffle/apache/GenericWindowsPrincipal.java waffle-tomcat85 41
waffle/apache/GenericWindowsPrincipal.java waffle-tomcat9 41
public class GenericWindowsPrincipal extends GenericPrincipal {

    /** The Constant serialVersionUID. */
    private static final long serialVersionUID = 1L;

    /** The sid. */
    private final byte[] sid;

    /** The sid string. */
    private final String sidString;

    /** The groups. */
    private final Map<String, WindowsAccount> groups;

    /**
     * A windows principal.
     *
     * @param windowsIdentity
     *            Windows identity.
     * @param principalFormat
     *            Principal format.
     * @param roleFormat
     *            Role format.
     */
    public GenericWindowsPrincipal(final IWindowsIdentity windowsIdentity, final PrincipalFormat principalFormat,
            final PrincipalFormat roleFormat) {
        super(windowsIdentity.getFqn(), "",
                GenericWindowsPrincipal.getRoles(windowsIdentity, principalFormat, roleFormat));
        this.sid = windowsIdentity.getSid();
        this.sidString = windowsIdentity.getSidString();
        this.groups = GenericWindowsPrincipal.getGroups(windowsIdentity.getGroups());
    }

    /**
     * Gets the roles.
     *
     * @param windowsIdentity
     *            the windows identity
     * @param principalFormat
     *            the principal format
     * @param roleFormat
     *            the role format
     *
     * @return the roles
     */
    private static List<String> getRoles(final IWindowsIdentity windowsIdentity, final PrincipalFormat principalFormat,
            final PrincipalFormat roleFormat) {
        final List<String> roles = new ArrayList<>();
        roles.addAll(GenericWindowsPrincipal.getPrincipalNames(windowsIdentity, principalFormat));
        for (final IWindowsAccount group : windowsIdentity.getGroups()) {
            roles.addAll(GenericWindowsPrincipal.getRoleNames(group, roleFormat));
        }
        return roles;
    }

    /**
     * Gets the groups.
     *
     * @param groups
     *            the groups
     *
     * @return the groups
     */
    private static Map<String, WindowsAccount> getGroups(final IWindowsAccount[] groups) {
        final Map<String, WindowsAccount> groupMap = new HashMap<>();
        for (final IWindowsAccount group : groups) {
            groupMap.put(group.getFqn(), new WindowsAccount(group));
        }
        return groupMap;
    }

    /**
     * Byte representation of the SID.
     *
     * @return Array of bytes.
     */
    public byte[] getSid() {
        return this.sid.clone();
    }

    /**
     * String representation of the SID.
     *
     * @return String.
     */
    public String getSidString() {
        return this.sidString;
    }

    /**
     * Windows groups that the user is a member of.
     *
     * @return A map of group names to groups.
     */
    public Map<String, WindowsAccount> getGroups() {
        return this.groups;
    }

    /**
     * Returns a list of role principal objects.
     *
     * @param group
     *            Windows group.
     * @param principalFormat
     *            Principal format.
     *
     * @return List of role principal objects.
     */
    private static List<String> getRoleNames(final IWindowsAccount group, final PrincipalFormat principalFormat) {
        final List<String> principals = new ArrayList<>();
        switch (principalFormat) {
            case FQN:
                principals.add(group.getFqn());
                break;
            case SID:
                principals.add(group.getSidString());
                break;
            case BOTH:
                principals.add(group.getFqn());
                principals.add(group.getSidString());
                break;
            case NONE:
            default:
                break;
        }
        return principals;
    }

    /**
     * Returns a list of user principal objects.
     *
     * @param windowsIdentity
     *            Windows identity.
     * @param principalFormat
     *            Principal format.
     *
     * @return A list of user principal objects.
     */
    private static List<String> getPrincipalNames(final IWindowsIdentity windowsIdentity,
            final PrincipalFormat principalFormat) {
        final List<String> principals = new ArrayList<>();
        switch (principalFormat) {
            case FQN:
                principals.add(windowsIdentity.getFqn());
                break;
            case SID:
                principals.add(windowsIdentity.getSidString());
                break;
            case BOTH:
                principals.add(windowsIdentity.getFqn());
                principals.add(windowsIdentity.getSidString());
                break;
            case NONE:
            default:
                break;
        }
        return principals;
    }

    /**
     * Get an array of roles as a string.
     *
     * @return Role1, Role2, ...
     */
    public String getRolesString() {
        return String.join(", ", this.getRoles());
    }

}
File Project Line
waffle/util/AuthorizationHeader.java waffle-jna-jakarta 37
waffle/util/AuthorizationHeader.java waffle-jna 37
public class AuthorizationHeader {

    /** The logger. */
    private static final Logger LOGGER = LoggerFactory.getLogger(AuthorizationHeader.class);

    /** The request. */
    private final HttpServletRequest request;

    /**
     * Instantiates a new authorization header.
     *
     * @param httpServletRequest
     *            the http servlet request
     */
    public AuthorizationHeader(final HttpServletRequest httpServletRequest) {
        this.request = httpServletRequest;
    }

    /**
     * Gets the header.
     *
     * @return the header
     */
    public String getHeader() {
        return this.request.getHeader("Authorization");
    }

    /**
     * Checks if is null.
     *
     * @return true, if is null
     */
    public boolean isNull() {
        return this.getHeader() == null || this.getHeader().length() == 0;
    }

    /**
     * Returns a supported security package string.
     *
     * <pre>
     * Authorization: NTLM the_token
     * Authorization: Negotiate the_token
     * Authorization: Bearer the_token
     * </pre>
     *
     * @return AuthenticationScheme as SecurityPackage e.g. Negotiate, NTLM, Bearer.
     */
    public String getSecurityPackage() {
        final String header = this.getHeader();

        if (header == null) {
            throw new RuntimeException("Missing Authorization: header");
        }

        final int space = header.indexOf(' ');
        if (space > 0) {
            return header.substring(0, space);
        }

        throw new RuntimeException("Invalid Authorization header: " + header);
    }

    @Override
    public String toString() {
        return this.isNull() ? "<none>" : this.getHeader();
    }

    /**
     * Gets the token.
     *
     * @return the token
     */
    public String getToken() {
        return this.getHeader().substring(this.getSecurityPackage().length() + 1);
    }

    /**
     * Gets the token bytes.
     *
     * @return the token bytes
     */
    public byte[] getTokenBytes() {
        try {
            return Base64.getDecoder().decode(this.getToken());
        } catch (final IllegalArgumentException e) {
            AuthorizationHeader.LOGGER.debug("", e);
            throw new RuntimeException("Invalid authorization header.");
        }
    }

    /**
     * Checks if is ntlm type1 message.
     *
     * @return true, if is ntlm type1 message
     */
    public boolean isNtlmType1Message() {
        if (this.isNull()) {
            return false;
        }

        final byte[] tokenBytes = this.getTokenBytes();
        if (!NtlmMessage.isNtlmMessage(tokenBytes)) {
            return false;
        }

        return 1 == NtlmMessage.getMessageType(tokenBytes);
    }

    /**
     * Checks if is SP nego message.
     *
     * @return true, if is SP nego message that contains NegTokenInit
     */
    public boolean isSPNegTokenInitMessage() {

        if (this.isNull()) {
            return false;
        }

        final byte[] tokenBytes = this.getTokenBytes();
        return SPNegoMessage.isNegTokenInit(tokenBytes);
    }

    /**
     * When using NTLM authentication and the browser is making a POST request, it preemptively sends a Type 2
     * authentication message (without the POSTed data). The server responds with a 401, and the browser sends a Type 3
     * request with the POSTed data. This is to avoid the situation where user's credentials might be potentially
     * invalid, and all this data is being POSTed across the wire.
     *
     * @return True if request is an NTLM POST, PUT, or DELETE with an Authorization header and no data.
     */
    public boolean isNtlmType1PostAuthorizationHeader() {
        if (!"POST".equals(this.request.getMethod()) && !"PUT".equals(this.request.getMethod())
                && !"DELETE".equals(this.request.getMethod())) {
            return false;
        }

        if (this.request.getContentLength() != 0) {
            return false;
        }

        return this.isNtlmType1Message() || this.isSPNegTokenInitMessage();
    }

    /**
     * Is Bearer Authorization Header will return true if 'BEARER' exists.
     *
     * @return True if header contains 'BEARER' header.
     */
    public boolean isBearerAuthorizationHeader() {
        if (this.isNull()) {
            return false;
        }

        return this.getSecurityPackage().toUpperCase(Locale.ENGLISH).equalsIgnoreCase("BEARER");
    }
}
File Project Line
waffle/apache/GenericWindowsPrincipal.java waffle-tomcat10 67
waffle/apache/GenericWindowsPrincipal.java waffle-tomcat85 67
waffle/apache/GenericWindowsPrincipal.java waffle-tomcat9 67
super(windowsIdentity.getFqn(), GenericWindowsPrincipal.getRoles(windowsIdentity, principalFormat, roleFormat));
        this.sid = windowsIdentity.getSid();
        this.sidString = windowsIdentity.getSidString();
        this.groups = GenericWindowsPrincipal.getGroups(windowsIdentity.getGroups());
    }

    /**
     * Gets the roles.
     *
     * @param windowsIdentity
     *            the windows identity
     * @param principalFormat
     *            the principal format
     * @param roleFormat
     *            the role format
     *
     * @return the roles
     */
    private static List<String> getRoles(final IWindowsIdentity windowsIdentity, final PrincipalFormat principalFormat,
            final PrincipalFormat roleFormat) {
        final List<String> roles = new ArrayList<>();
        roles.addAll(GenericWindowsPrincipal.getPrincipalNames(windowsIdentity, principalFormat));
        for (final IWindowsAccount group : windowsIdentity.getGroups()) {
            roles.addAll(GenericWindowsPrincipal.getRoleNames(group, roleFormat));
        }
        return roles;
    }

    /**
     * Gets the groups.
     *
     * @param groups
     *            the groups
     *
     * @return the groups
     */
    private static Map<String, WindowsAccount> getGroups(final IWindowsAccount[] groups) {
        final Map<String, WindowsAccount> groupMap = new HashMap<>();
        for (final IWindowsAccount group : groups) {
            groupMap.put(group.getFqn(), new WindowsAccount(group));
        }
        return groupMap;
    }

    /**
     * Byte representation of the SID.
     *
     * @return Array of bytes.
     */
    public byte[] getSid() {
        return this.sid.clone();
    }

    /**
     * String representation of the SID.
     *
     * @return String.
     */
    public String getSidString() {
        return this.sidString;
    }

    /**
     * Windows groups that the user is a member of.
     *
     * @return A map of group names to groups.
     */
    public Map<String, WindowsAccount> getGroups() {
        return this.groups;
    }

    /**
     * Returns a list of role principal objects.
     *
     * @param group
     *            Windows group.
     * @param principalFormat
     *            Principal format.
     *
     * @return List of role principal objects.
     */
    private static List<String> getRoleNames(final IWindowsAccount group, final PrincipalFormat principalFormat) {
        final List<String> principals = new ArrayList<>();
        switch (principalFormat) {
            case FQN:
                principals.add(group.getFqn());
                break;
            case SID:
                principals.add(group.getSidString());
                break;
            case BOTH:
                principals.add(group.getFqn());
                principals.add(group.getSidString());
                break;
            case NONE:
            default:
                break;
        }
        return principals;
    }

    /**
     * Returns a list of user principal objects.
     *
     * @param windowsIdentity
     *            Windows identity.
     * @param principalFormat
     *            Principal format.
     *
     * @return A list of user principal objects.
     */
    private static List<String> getPrincipalNames(final IWindowsIdentity windowsIdentity,
            final PrincipalFormat principalFormat) {
        final List<String> principals = new ArrayList<>();
        switch (principalFormat) {
            case FQN:
                principals.add(windowsIdentity.getFqn());
                break;
            case SID:
                principals.add(windowsIdentity.getSidString());
                break;
            case BOTH:
                principals.add(windowsIdentity.getFqn());
                principals.add(windowsIdentity.getSidString());
                break;
            case NONE:
            default:
                break;
        }
        return principals;
    }

    /**
     * Get an array of roles as a string.
     *
     * @return Role1, Role2, ...
     */
    public String getRolesString() {
        return String.join(", ", this.getRoles());
    }

}
File Project Line
waffle/windows/auth/impl/WindowsIdentityImpl.java waffle-jna-jakarta 42
waffle/windows/auth/impl/WindowsIdentityImpl.java waffle-jna 42
public class WindowsIdentityImpl implements IWindowsIdentity {

    /** The windows identity. */
    private final HANDLE windowsIdentity;

    /** The user groups. */
    private Account[] userGroups;

    /** The windows account. */
    private Account windowsAccount;

    /**
     * Instantiates a new windows identity impl.
     *
     * @param newWindowsIdentity
     *            the new windows identity
     */
    public WindowsIdentityImpl(final HANDLE newWindowsIdentity) {
        this.windowsIdentity = newWindowsIdentity;
    }

    /**
     * Gets the windows account.
     *
     * @return the windows account
     */
    private Account getWindowsAccount() {
        if (this.windowsAccount == null) {
            this.windowsAccount = Advapi32Util.getTokenAccount(this.windowsIdentity);
        }
        return this.windowsAccount;
    }

    /**
     * Gets the user groups.
     *
     * @return the user groups
     */
    private Account[] getUserGroups() {
        if (this.userGroups == null) {
            this.userGroups = Advapi32Util.getTokenGroups(this.windowsIdentity);
        }
        return this.userGroups.clone();
    }

    @Override
    public String getFqn() {
        return this.getWindowsAccount().fqn;
    }

    @Override
    public IWindowsAccount[] getGroups() {

        final Account[] groups = this.getUserGroups();

        final List<IWindowsAccount> result = new ArrayList<>(groups.length);
        for (final Account userGroup : groups) {
            final WindowsAccountImpl account = new WindowsAccountImpl(userGroup);
            result.add(account);
        }

        return result.toArray(new IWindowsAccount[0]);
    }

    @Override
    public byte[] getSid() {
        return this.getWindowsAccount().sid;
    }

    @Override
    public String getSidString() {
        return this.getWindowsAccount().sidString;
    }

    @Override
    public void dispose() {
        if (this.windowsIdentity != null) {
            Kernel32.INSTANCE.CloseHandle(this.windowsIdentity);
        }
    }

    @Override
    public IWindowsImpersonationContext impersonate() {
        return new WindowsIdentityImpersonationContextImpl(this.windowsIdentity);
    }

    @Override
    public boolean isGuest() {
        for (final Account userGroup : this.getUserGroups()) {
            if (Advapi32Util.isWellKnownSid(userGroup.sid, WELL_KNOWN_SID_TYPE.WinBuiltinGuestsSid)) {
                return true;
            }
            if (Advapi32Util.isWellKnownSid(userGroup.sid, WELL_KNOWN_SID_TYPE.WinAccountDomainGuestsSid)) {
                return true;
            }
            if (Advapi32Util.isWellKnownSid(userGroup.sid, WELL_KNOWN_SID_TYPE.WinAccountGuestSid)) {
                return true;
            }
        }
        return Advapi32Util.isWellKnownSid(this.getSid(), WELL_KNOWN_SID_TYPE.WinAnonymousSid);
    }
}
File Project Line
waffle/servlet/spi/SecurityFilterProviderCollection.java waffle-jna-jakarta 89
waffle/servlet/spi/SecurityFilterProviderCollection.java waffle-jna 90
throw new RuntimeException(e);
            } catch (final SecurityException | NoSuchMethodException | IllegalArgumentException | InstantiationException
                    | IllegalAccessException | InvocationTargetException e) {
                SecurityFilterProviderCollection.LOGGER.error("error loading '{}': {}", providerName, e.getMessage());
                SecurityFilterProviderCollection.LOGGER.trace("", e);
            }
        }
    }

    /**
     * Instantiates a new security filter provider collection.
     *
     * @param auth
     *            the auth
     */
    public SecurityFilterProviderCollection(final IWindowsAuthProvider auth) {
        this.providers.add(new NegotiateSecurityFilterProvider(auth));
        this.providers.add(new BasicSecurityFilterProvider(auth));
    }

    /**
     * Tests whether a specific security package is supported by any of the underlying providers.
     *
     * @param securityPackage
     *            Security package.
     *
     * @return True if the security package is supported, false otherwise.
     */
    public boolean isSecurityPackageSupported(final String securityPackage) {
        return this.get(securityPackage) != null;
    }

    /**
     * Gets the.
     *
     * @param securityPackage
     *            the security package
     *
     * @return the security filter provider
     */
    private SecurityFilterProvider get(final String securityPackage) {
        for (final SecurityFilterProvider provider : this.providers) {
            if (provider.isSecurityPackageSupported(securityPackage)) {
                return provider;
            }
        }
        return null;
    }

    /**
     * Filter.
     *
     * @param request
     *            Http Request
     * @param response
     *            Http Response
     *
     * @return Windows Identity or NULL.
     *
     * @throws IOException
     *             on doFilter.
     */
    public IWindowsIdentity doFilter(final HttpServletRequest request, final HttpServletResponse response)
            throws IOException {
        final AuthorizationHeader authorizationHeader = new AuthorizationHeader(request);
        final SecurityFilterProvider provider = this.get(authorizationHeader.getSecurityPackage());
        if (provider == null) {
            throw new RuntimeException("Unsupported security package: " + authorizationHeader.getSecurityPackage());
        }
        try {
            return provider.doFilter(request, response);
        } catch (final Win32Exception e) {
            throw new IOException(e);
        }
    }

    /**
     * Returns true if authentication still needs to happen despite an existing principal.
     *
     * @param request
     *            Http Request
     *
     * @return True if authentication is required.
     */
    public boolean isPrincipalException(final HttpServletRequest request) {
        for (final SecurityFilterProvider provider : this.providers) {
            if (provider.isPrincipalException(request)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Send authorization headers.
     *
     * @param response
     *            Http Response
     */
    public void sendUnauthorized(final HttpServletResponse response) {
        for (final SecurityFilterProvider provider : this.providers) {
            provider.sendUnauthorized(response);
        }
    }

    /**
     * Number of providers.
     *
     * @return Number of providers.
     */
    public int size() {
        return this.providers.size();
    }

    /**
     * Get a security provider by class name.
     *
     * @param name
     *            Class name.
     *
     * @return A security provider instance.
     *
     * @throws ClassNotFoundException
     *             when class not found.
     */
    public SecurityFilterProvider getByClassName(final String name) throws ClassNotFoundException {
        for (final SecurityFilterProvider provider : this.providers) {
            if (provider.getClass().getName().equals(name)) {
                return provider;
            }
        }
        throw new ClassNotFoundException(name);
    }
}
File Project Line
waffle/servlet/WindowsPrincipal.java waffle-jna-jakarta 111
waffle/servlet/WindowsPrincipal.java waffle-jna 111
waffle/apache/GenericWindowsPrincipal.java waffle-tomcat10 90
waffle/apache/GenericWindowsPrincipal.java waffle-tomcat85 91
waffle/apache/GenericWindowsPrincipal.java waffle-tomcat9 91
roles.addAll(WindowsPrincipal.getRoleNames(group, roleFormat));
        }
        return roles;
    }

    /**
     * Gets the groups.
     *
     * @param groups
     *            the groups
     *
     * @return the groups
     */
    private static Map<String, WindowsAccount> getGroups(final IWindowsAccount[] groups) {
        final Map<String, WindowsAccount> groupMap = new HashMap<>();
        for (final IWindowsAccount group : groups) {
            groupMap.put(group.getFqn(), new WindowsAccount(group));
        }
        return groupMap;
    }

    /**
     * Byte representation of the SID.
     *
     * @return Array of bytes.
     */
    public byte[] getSid() {
        return this.sid.clone();
    }

    /**
     * String representation of the SID.
     *
     * @return String.
     */
    public String getSidString() {
        return this.sidString;
    }

    /**
     * Windows groups that the user is a member of.
     *
     * @return A map of group names to groups.
     */
    public Map<String, WindowsAccount> getGroups() {
        return this.groups;
    }

    /**
     * Returns a list of role principal objects.
     *
     * @param group
     *            Windows group.
     * @param principalFormat
     *            Principal format.
     *
     * @return List of role principal objects.
     */
    private static List<String> getRoleNames(final IWindowsAccount group, final PrincipalFormat principalFormat) {
        final List<String> principals = new ArrayList<>();
        switch (principalFormat) {
            case FQN:
                principals.add(group.getFqn());
                break;
            case SID:
                principals.add(group.getSidString());
                break;
            case BOTH:
                principals.add(group.getFqn());
                principals.add(group.getSidString());
                break;
            case NONE:
            default:
                break;
        }
        return principals;
    }

    /**
     * Returns a list of user principal objects.
     *
     * @param windowsIdentity
     *            Windows identity.
     * @param principalFormat
     *            Principal format.
     *
     * @return A list of user principal objects.
     */
    private static List<String> getPrincipalNames(final IWindowsIdentity windowsIdentity,
            final PrincipalFormat principalFormat) {
        final List<String> principals = new ArrayList<>();
        switch (principalFormat) {
            case FQN:
                principals.add(windowsIdentity.getFqn());
                break;
            case SID:
                principals.add(windowsIdentity.getSidString());
                break;
            case BOTH:
                principals.add(windowsIdentity.getFqn());
                principals.add(windowsIdentity.getSidString());
                break;
            case NONE:
            default:
                break;
        }
        return principals;
    }

    /**
     * Get an array of roles as a string.
     *
     * @return Role1, Role2, ...
     */
    public String getRolesString() {
        return String.join(", ", this.roles);
File Project Line
waffle/mock/MockWindowsAuthProvider.java waffle-tests-jakarta 43
waffle/mock/MockWindowsAuthProvider.java waffle-tests 43
public class MockWindowsAuthProvider implements IWindowsAuthProvider {

    /** The Constant GUEST. */
    private static final String GUEST = "Guest";

    /** The groups. */
    private final List<String> groups = new ArrayList<>();

    /**
     * Instantiates a new mock windows auth provider.
     */
    public MockWindowsAuthProvider() {
        this.groups.add("Users");
        this.groups.add("Everyone");
    }

    /**
     * Adds the group.
     *
     * @param name
     *            the name
     */
    public void addGroup(final String name) {
        this.groups.add(name);
    }

    @Override
    public IWindowsSecurityContext acceptSecurityToken(final String connectionId, final byte[] token,
            final String securityPackage) {
        return new MockWindowsSecurityContext(new String(token, StandardCharsets.UTF_8));
    }

    @Override
    public IWindowsComputer getCurrentComputer() {
        return null;
    }

    @Override
    public IWindowsDomain[] getDomains() {
        return new IWindowsDomain[0];
    }

    @Override
    public IWindowsIdentity logonDomainUser(final String username, final String domain, final String password) {
        return null;
    }

    @Override
    public IWindowsIdentity logonDomainUserEx(final String username, final String domain, final String password,
            final int logonType, final int logonProvider) {
        return null;
    }

    /**
     * Will login the current user with any password. Will logon a "Guest" user as guest.
     *
     * @param username
     *            the username
     * @param password
     *            the password
     *
     * @return the i windows identity
     */
    @Override
    public IWindowsIdentity logonUser(final String username, final String password) {
        final String currentUsername = Secur32Util.getUserNameEx(EXTENDED_NAME_FORMAT.NameSamCompatible);
        if (username.equals(currentUsername)) {
            return new MockWindowsIdentity(currentUsername, this.groups);
        } else if (username.equals(MockWindowsAuthProvider.GUEST)) {
            return new MockWindowsIdentity(MockWindowsAuthProvider.GUEST, this.groups);
        } else {
            throw new RuntimeException("Mock error: " + username);
        }
    }

    @Override
    public IWindowsAccount lookupAccount(final String username) {
        return null;
    }

    @Override
    public void resetSecurityToken(final String connectionId) {
        // Do Nothing
    }

}
File Project Line
waffle/util/SPNegoMessage.java waffle-jna-jakarta 31
waffle/util/SPNegoMessage.java waffle-jna 31
public final class SPNegoMessage {

    // Check for NegTokenInit. It has always a special oid ("spnegoOid"),
    // which makes it rather easy to detect.
    /** The Constant SPENGO_OID. */
    private static final byte[] SPENGO_OID = { 0x06, 0x06, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x02 };

    // Check if this message is SPNEGO authentication token. There
    // are two token types, NegTokenInit and NegTokenArg.
    // For details and specification, see
    // https://msdn.microsoft.com/en-us/library/ms995330.aspx

    /**
     * Checks if is neg token init.
     *
     * @param message
     *            the message
     *
     * @return true, if is neg token init
     */
    public static boolean isNegTokenInit(final byte[] message) {

        // Message should always contains at least some kind of
        // id byte and length. If it is too short, it
        // cannot be a SPNEGO message.
        if (message == null || message.length < 2) {
            return false;
        }

        // First byte should always be 0x60 (Application Constructed Object)
        if (message[0] != 0x60) {
            return false;
        }

        // Next byte(s) contain token length, figure out
        // how many bytes are used for length data
        int lenBytes = 1;
        if ((message[1] & 0x80) != 0) {
            lenBytes = 1 + (message[1] & 0x7f);
        }

        if (message.length < SPNegoMessage.SPENGO_OID.length + 1 + lenBytes) {
            return false;
        }

        // Now check for SPNEGO OID, which should start just after length data.
        for (int i = 0; i < SPNegoMessage.SPENGO_OID.length; i++) {
            if (SPNegoMessage.SPENGO_OID[i] != message[i + 1 + lenBytes]) {
                return false;
            }
        }

        return true;
    }

    // Check for NegTokenArg. It doesn't have oid similar to NegTokenInit.
    // Instead id has one-byte id (0xa1). Obviously this is not
    // a great way to detect the message, so we check encoded
    // message length against number of received message bytes.
    /**
     * Checks if is neg token arg.
     *
     * @param message
     *            the message
     *
     * @return true, if is neg token arg
     */
    public static boolean isNegTokenArg(final byte[] message) {

        // Message should always contains at least some kind of
        // id byte and length. If it is too short, it
        // cannot be a SPNEGO message.
        if (message == null || message.length < 2) {
            return false;
        }

        // Check if this is NegTokenArg packet, it's id is 0xa1
        if ((message[0] & 0xff) != 0xa1) {
            return false;
        }

        int lenBytes;
        int len;

        // Get length of message for additional check.
        if ((message[1] & 0x80) == 0) {
            len = message[1];
        } else {
            lenBytes = message[1] & 0x7f;
            len = 0;
            final int i = 2;
            while (lenBytes > 0) {
                len = len << 8;
                len |= message[i] & 0xff;
                --lenBytes;
            }
        }

        return len + 2 == message.length;
    }

    /**
     * Instantiates a new SP nego message.
     */
    private SPNegoMessage() {
        // Prevent Instantiation of object
    }
}
File Project Line
waffle/spring/boot/WaffleProperties.java waffle-spring-boot-autoconfigure2 36
waffle/spring/boot/WaffleProperties.java waffle-spring-boot-autoconfigure3 36
@ConfigurationProperties(prefix = "waffle")
public class WaffleProperties {

    /** The principal format can be any of the options specified by {@link PrincipalFormat}. */
    private String principalFormat = "fqn";

    /** The principal format can be any of the options specified by {@link PrincipalFormat}. */
    private String roleFormat = "fqn";

    /** Enable or disable guest login. */
    private boolean allowGuestLogin = false;

    /** Configuration properties for single-sign-on. */
    private SingleSignOnProperties sso;

    /**
     * Gets the principal format.
     *
     * @return the principal format
     */
    public String getPrincipalFormat() {
        return this.principalFormat;
    }

    /**
     * Sets the principal format.
     *
     * @param principalFormat
     *            the new principal format
     */
    public void setPrincipalFormat(final String principalFormat) {
        this.principalFormat = principalFormat;
    }

    /**
     * Gets the role format.
     *
     * @return the role format
     */
    public String getRoleFormat() {
        return this.roleFormat;
    }

    /**
     * Sets the role format.
     *
     * @param roleFormat
     *            the new role format
     */
    public void setRoleFormat(final String roleFormat) {
        this.roleFormat = roleFormat;
    }

    /**
     * Checks if is allow guest login.
     *
     * @return true, if is allow guest login
     */
    public boolean isAllowGuestLogin() {
        return this.allowGuestLogin;
    }

    /**
     * Sets the allow guest login.
     *
     * @param allowGuestLogin
     *            the new allow guest login
     */
    public void setAllowGuestLogin(final boolean allowGuestLogin) {
        this.allowGuestLogin = allowGuestLogin;
    }

    /**
     * Gets the sso.
     *
     * @return the sso
     */
    public SingleSignOnProperties getSso() {
        return this.sso;
    }

    /**
     * Sets the sso.
     *
     * @param sso
     *            the new sso
     */
    public void setSso(final SingleSignOnProperties sso) {
        this.sso = sso;
    }

    /**
     * The Class SingleSignOnProperties.
     */
    public static class SingleSignOnProperties {

        /** Enable or disable single-sign-on using Negotiate protocol. */
        private boolean enabled = false;

        /** Enable fall back to Basic protocol for unsupported browsers. */
        private boolean basicEnabled = false;

        /** List of protocols to support: Can be Negotiate, NTLM. */
        private List<String> protocols = Arrays.asList("Negotiate", "NTLM");

        /** Enable WAFFLE impersonate option. */
        private boolean impersonate = false;

        /**
         * Checks if is enabled.
         *
         * @return true, if is enabled
         */
        public boolean isEnabled() {
            return this.enabled;
        }

        /**
         * Sets the enabled.
         *
         * @param enabled
         *            the new enabled
         */
        public void setEnabled(final boolean enabled) {
            this.enabled = enabled;
        }

        /**
         * Checks if is basic enabled.
         *
         * @return true, if is basic enabled
         */
        public boolean isBasicEnabled() {
            return this.basicEnabled;
        }

        /**
         * Sets the basic enabled.
         *
         * @param basicEnabled
         *            the new basic enabled
         */
        public void setBasicEnabled(final boolean basicEnabled) {
            this.basicEnabled = basicEnabled;
        }

        /**
         * Gets the protocols.
         *
         * @return the protocols
         */
        public List<String> getProtocols() {
            return this.protocols;
        }

        /**
         * Sets the protocols.
         *
         * @param protocols
         *            the new protocols
         */
        public void setProtocols(final List<String> protocols) {
            this.protocols = protocols;
        }

        /**
         * Checks if is impersonate.
         *
         * @return true, if is impersonate
         */
        public boolean isImpersonate() {
            return this.impersonate;
        }

        /**
         * Sets the impersonate.
         *
         * @param impersonate
         *            the new impersonate
         */
        public void setImpersonate(final boolean impersonate) {
            this.impersonate = impersonate;
        }

    }
}
File Project Line
waffle/servlet/spi/BasicSecurityFilterProvider.java waffle-jna-jakarta 43
waffle/servlet/spi/BasicSecurityFilterProvider.java waffle-jna 43
public class BasicSecurityFilterProvider implements SecurityFilterProvider {

    /** The Constant LOGGER. */
    private static final Logger LOGGER = LoggerFactory.getLogger(BasicSecurityFilterProvider.class);

    /** The realm. */
    private String realm = "BasicSecurityFilterProvider";

    /** The auth. */
    private final IWindowsAuthProvider auth;

    /**
     * Instantiates a new basic security filter provider.
     *
     * @param newAuthProvider
     *            the new auth provider
     */
    public BasicSecurityFilterProvider(final IWindowsAuthProvider newAuthProvider) {
        this.auth = newAuthProvider;
    }

    @Override
    public IWindowsIdentity doFilter(final HttpServletRequest request, final HttpServletResponse response)
            throws IOException {

        final AuthorizationHeader authorizationHeader = new AuthorizationHeader(request);
        final String usernamePassword = new String(authorizationHeader.getTokenBytes(), StandardCharsets.UTF_8);
        final String[] usernamePasswordArray = usernamePassword.split(":", 2);
        if (usernamePasswordArray.length != 2) {
            throw new RuntimeException("Invalid username:password in Authorization header.");
        }
        BasicSecurityFilterProvider.LOGGER.debug("logging in user: {}", usernamePasswordArray[0]);
        return this.auth.logonUser(usernamePasswordArray[0], usernamePasswordArray[1]);
    }

    @Override
    public boolean isPrincipalException(final HttpServletRequest request) {
        return false;
    }

    @Override
    public boolean isSecurityPackageSupported(final String securityPackage) {
        return "Basic".equalsIgnoreCase(securityPackage);
    }

    @Override
    public void sendUnauthorized(final HttpServletResponse response) {
        response.addHeader("WWW-Authenticate", "Basic realm=\"" + this.realm + "\"");
    }

    /**
     * Protection space.
     *
     * @return Name of the protection space.
     */
    public String getRealm() {
        return this.realm;
    }

    /**
     * Set the protection space.
     *
     * @param value
     *            Protection space name.
     */
    public void setRealm(final String value) {
        this.realm = value;
    }

    /**
     * Init configuration parameters.
     *
     * @param parameterName
     *            the parameter name
     * @param parameterValue
     *            the parameter value
     */
    @Override
    public void initParameter(final String parameterName, final String parameterValue) {
        if ("realm".equals(parameterName)) {
            this.setRealm(parameterValue);
        } else {
            throw new InvalidParameterException(parameterName);
        }
    }
}
File Project Line
waffle/spring/WindowsAuthenticationToken.java waffle-spring-security5 39
waffle/spring/WindowsAuthenticationToken.java waffle-spring-security6 39
public class WindowsAuthenticationToken implements Authentication {

    /** The Constant serialVersionUID. */
    private static final long serialVersionUID = 1L;

    /**
     * The {@link GrantedAuthorityFactory} that is used by default if a custom one is not specified. This default
     * {@link GrantedAuthorityFactory} is a {@link FqnGrantedAuthorityFactory} with prefix {@code "ROLE_"} and will
     * convert the fqn to uppercase
     */
    public static final GrantedAuthorityFactory DEFAULT_GRANTED_AUTHORITY_FACTORY = new FqnGrantedAuthorityFactory(
            "ROLE_", true);

    /**
     * The {@link GrantedAuthority} that will be added to every WindowsAuthenticationToken, unless another (or null) is
     * specified.
     */
    public static final GrantedAuthority DEFAULT_GRANTED_AUTHORITY = new SimpleGrantedAuthority("ROLE_USER");

    /** The principal. */
    private final WindowsPrincipal principal;

    /** The authorities. */
    private final Collection<GrantedAuthority> authorities;

    /**
     * Convenience constructor that calls
     * {@link #WindowsAuthenticationToken(WindowsPrincipal, GrantedAuthorityFactory, GrantedAuthority)} with:
     * <ul>
     * <li>the given identity,</li>
     * <li>the {@link #DEFAULT_GRANTED_AUTHORITY_FACTORY}</li>
     * <li>the {@link #DEFAULT_GRANTED_AUTHORITY}</li>
     * </ul>
     * .
     *
     * @param identity
     *            the identity
     */
    public WindowsAuthenticationToken(final WindowsPrincipal identity) {
        this(identity, WindowsAuthenticationToken.DEFAULT_GRANTED_AUTHORITY_FACTORY,
                WindowsAuthenticationToken.DEFAULT_GRANTED_AUTHORITY);
    }

    /**
     * Instantiates a new windows authentication token.
     *
     * @param identity
     *            The {@link WindowsPrincipal} for which this token exists.
     * @param grantedAuthorityFactory
     *            used to construct {@link GrantedAuthority}s for each of the groups to which the
     *            {@link WindowsPrincipal} belongs
     * @param defaultGrantedAuthority
     *            if not null, this {@link GrantedAuthority} will always be added to the granted authorities list
     */
    public WindowsAuthenticationToken(final WindowsPrincipal identity,
            final GrantedAuthorityFactory grantedAuthorityFactory, final GrantedAuthority defaultGrantedAuthority) {

        this.principal = identity;
        this.authorities = new ArrayList<>();
        if (defaultGrantedAuthority != null) {
            this.authorities.add(defaultGrantedAuthority);
        }
        for (final WindowsAccount group : this.principal.getGroups().values()) {
            this.authorities.add(grantedAuthorityFactory.createGrantedAuthority(group));
        }
    }

    @Override
    public Collection<GrantedAuthority> getAuthorities() {
        return this.authorities;
    }

    @Override
    public Object getCredentials() {
        return null;
    }

    @Override
    public Object getDetails() {
        return null;
    }

    @Override
    public Object getPrincipal() {
        return this.principal;
    }

    @Override
    public boolean isAuthenticated() {
        return this.principal != null;
    }

    @Override
    public void setAuthenticated(final boolean authenticated) {
        throw new IllegalArgumentException();
    }

    @Override
    public String getName() {
        return this.principal.getName();
    }

}
File Project Line
waffle/windows/auth/impl/WindowsDomainImpl.java waffle-jna-jakarta 33
waffle/windows/auth/impl/WindowsDomainImpl.java waffle-jna 33
public class WindowsDomainImpl implements IWindowsDomain {

    /**
     * The Enum TrustDirection.
     */
    private enum TrustDirection {

        /** The inbound. */
        INBOUND,
        /** The outbound. */
        OUTBOUND,
        /** The bidirectional. */
        BIDIRECTIONAL
    }

    /**
     * The Enum TrustType.
     */
    private enum TrustType {

        /** The tree root. */
        TREE_ROOT,
        /** The parent child. */
        PARENT_CHILD,
        /** The cross link. */
        CROSS_LINK,
        /** The external. */
        EXTERNAL,
        /** The forest. */
        FOREST,
        /** The kerberos. */
        KERBEROS,
        /** The unknown. */
        UNKNOWN
    }

    /** The fqn. */
    private String fqn;

    /** The trust direction. */
    private TrustDirection trustDirection = TrustDirection.BIDIRECTIONAL;

    /** The trust type. */
    private TrustType trustType = TrustType.UNKNOWN;

    /**
     * Instantiates a new windows domain impl.
     *
     * @param newFqn
     *            the new fqn
     */
    public WindowsDomainImpl(final String newFqn) {
        this.fqn = newFqn;
    }

    /**
     * Instantiates a new windows domain impl.
     *
     * @param trust
     *            the trust
     */
    public WindowsDomainImpl(final DomainTrust trust) {
        // fqn
        this.fqn = trust.DnsDomainName;
        if (this.fqn == null || this.fqn.length() == 0) {
            this.fqn = trust.NetbiosDomainName;
        }
        // trust direction
        if (trust.isInbound() && trust.isOutbound()) {
            this.trustDirection = TrustDirection.BIDIRECTIONAL;
        } else if (trust.isOutbound()) {
            this.trustDirection = TrustDirection.OUTBOUND;
        } else if (trust.isInbound()) {
            this.trustDirection = TrustDirection.INBOUND;
        }
        // trust type
        if (trust.isInForest()) {
            this.trustType = TrustType.FOREST;
        } else if (trust.isRoot()) {
            this.trustType = TrustType.TREE_ROOT;
        }
    }

    @Override
    public String getFqn() {
        return this.fqn;
    }

    @Override
    public String getTrustDirectionString() {
        return this.trustDirection.toString();
    }

    @Override
    public String getTrustTypeString() {
        return this.trustType.toString();
    }

}
File Project Line
waffle/windows/auth/impl/WindowsCredentialsHandleImpl.java waffle-jna-jakarta 39
waffle/windows/auth/impl/WindowsCredentialsHandleImpl.java waffle-jna 39
public class WindowsCredentialsHandleImpl implements IWindowsCredentialsHandle {

    /** The principal name. */
    private final String principalName;

    /** The credentials type. */
    private final int credentialsType;

    /** The security package. */
    private final String securityPackage;

    /** The handle. */
    private CredHandle handle;

    /**
     * A new Windows credentials handle.
     *
     * @param newPrincipalName
     *            Principal name.
     * @param newCredentialsType
     *            Credentials type.
     * @param newSecurityPackage
     *            Security package.
     */
    public WindowsCredentialsHandleImpl(final String newPrincipalName, final int newCredentialsType,
            final String newSecurityPackage) {
        this.principalName = newPrincipalName;
        this.credentialsType = newCredentialsType;
        this.securityPackage = newSecurityPackage;
    }

    /**
     * Returns the current credentials handle.
     *
     * @param securityPackage
     *            Security package, eg. "Negotiate".
     *
     * @return A windows credentials handle
     */
    public static IWindowsCredentialsHandle getCurrent(final String securityPackage) {
        final IWindowsCredentialsHandle handle = new WindowsCredentialsHandleImpl(null, Sspi.SECPKG_CRED_OUTBOUND,
                securityPackage);
        handle.initialize();
        return handle;
    }

    /**
     * Initialize a new credentials handle.
     */
    @Override
    public void initialize() {
        this.handle = new CredHandle();
        final TimeStamp clientLifetime = new TimeStamp();
        final int rc = Secur32.INSTANCE.AcquireCredentialsHandle(this.principalName, this.securityPackage,
                this.credentialsType, null, null, null, null, this.handle, clientLifetime);
        if (WinError.SEC_E_OK != rc) {
            throw new Win32Exception(rc);
        }
    }

    /**
     * Dispose of the credentials handle.
     */
    @Override
    public void dispose() {
        if (this.handle != null && !this.handle.isNull()) {
            final int rc = Secur32.INSTANCE.FreeCredentialsHandle(this.handle);
            if (WinError.SEC_E_OK != rc) {
                throw new Win32Exception(rc);
            }
        }
    }

    /**
     * Get CredHandle.
     *
     * @return the handle
     */
    @Override
    public CredHandle getHandle() {
        return this.handle;
    }
}
File Project Line
waffle/servlet/CorsAwareNegotiateSecurityFilter.java waffle-jna-jakarta 45
waffle/servlet/CorsAwareNegotiateSecurityFilter.java waffle-jna 45
public class CorsAwareNegotiateSecurityFilter extends NegotiateSecurityFilter implements Filter {

    /** The Constant LOGGER. */
    private static final Logger LOGGER = LoggerFactory.getLogger(CorsAwareNegotiateSecurityFilter.class);

    /**
     * Instantiates a new negotiate security filter.
     */
    public CorsAwareNegotiateSecurityFilter() {
        CorsAwareNegotiateSecurityFilter.LOGGER.info("[waffle.servlet.CorsAwareNegotiateSecurityFilter] loaded");
    }

    @Override
    public void init(final FilterConfig filterConfig) throws ServletException {
        CorsAwareNegotiateSecurityFilter.LOGGER.info("[waffle.servlet.CorsAwareNegotiateSecurityFilter] Starting");
        super.init(filterConfig);
        CorsAwareNegotiateSecurityFilter.LOGGER.info("[waffle.servlet.CorsAwareNegotiateSecurityFilter] Started");
    }

    @Override
    public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
            throws IOException, ServletException {

        CorsAwareNegotiateSecurityFilter.LOGGER.info("[waffle.servlet.CorsAwareNegotiateSecurityFilter] Filtering");

        final HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        final AuthorizationHeader authorizationHeader = new AuthorizationHeader(httpServletRequest);

        if (CorsPreFlightCheck.isPreflight(httpServletRequest)) {
            CorsAwareNegotiateSecurityFilter.LOGGER.info(
                    "[waffle.servlet.CorsAwareNegotiateSecurityFilter] Request is CORS preflight; continue filter chain");
            chain.doFilter(request, response);
        } else if (authorizationHeader.isBearerAuthorizationHeader()) {
            CorsAwareNegotiateSecurityFilter.LOGGER
                    .info("[waffle.servlet.CorsAwareNegotiateSecurityFilter] Request is Bearer, continue filter chain");
            chain.doFilter(request, response);
        } else {
            CorsAwareNegotiateSecurityFilter.LOGGER
                    .info("[waffle.servlet.CorsAwareNegotiateSecurityFilter] Request is Not CORS preflight");

            super.doFilter(request, response, chain);

            CorsAwareNegotiateSecurityFilter.LOGGER
                    .info("[waffle.servlet.CorsAwareNegotiateSecurityFilter] Authentication Completed");
        }
    }

    @Override
    public void destroy() {
        super.destroy();
        CorsAwareNegotiateSecurityFilter.LOGGER.info("[waffle.servlet.CorsAwareNegotiateSecurityFilter] unloaded");
    }

}
File Project Line
waffle/util/CorsPreFlightCheck.java waffle-jna-jakarta 38
waffle/util/CorsPreFlightCheck.java waffle-jna 38
public final class CorsPreFlightCheck {

    /** The logger. */
    private static final Logger LOGGER = LoggerFactory.getLogger(CorsPreFlightCheck.class);

    /** The Constant preflightAttributeValue. */
    private static final String PRE_FLIGHT_ATTRIBUTE_VALUE = "PRE_FLIGHT";

    /** The Constant CORS_PRE_FLIGHT_HEADERS. */
    private static final List<String> CORS_PRE_FLIGHT_HEADERS = new ArrayList<>(
            Arrays.asList("Access-Control-Request-Method", "Access-Control-Request-Headers", "Origin"));

    /**
     * Prevent Instantiation.
     */
    private CorsPreFlightCheck() {
        // Do Nothing
    }

    /**
     * Checks if is preflight.
     *
     * @param request
     *            the request
     *
     * @return true, if is preflight
     */
    public static boolean isPreflight(final HttpServletRequest request) {

        final String corsRequestType = (String) request.getAttribute("cors.request.type");

        CorsPreFlightCheck.LOGGER
                .debug("[waffle.util.CorsPreflightCheck] Request is CORS preflight; continue filter chain");

        // Method MUST be an OPTIONS Method to be a preflight Request
        final String method = request.getMethod();
        if (method == null || !method.equalsIgnoreCase("OPTIONS")) {
            return false;
        }

        CorsPreFlightCheck.LOGGER.debug("[waffle.util.CorsPreflightCheck] check for PRE_FLIGHT Attribute");

        /**
         * Support Apache CorsFilter which would already add the Attribute cors.request.type with a value "PRE_FLIGHT"
         **/
        if (corsRequestType != null
                && corsRequestType.equalsIgnoreCase(CorsPreFlightCheck.PRE_FLIGHT_ATTRIBUTE_VALUE)) {
            return true;
        } else {
            /*
             * it is OPTIONS and it is not an CorsFilter PRE_FLIGHT request make sure that the request contains all of
             * the CORS preflight Headers
             */
            CorsPreFlightCheck.LOGGER.debug("[waffle.util.CorsPreflightCheck] check headers");

            for (final String header : CorsPreFlightCheck.CORS_PRE_FLIGHT_HEADERS) {
                final String headerValue = request.getHeader(header);
                CorsPreFlightCheck.LOGGER.debug("[waffle.util.CorsPreflightCheck] {}", header);

                if (headerValue == null) {
                    /* one of the CORS pre-flight headers is missing */
                    return false;
                }
            }
            CorsPreFlightCheck.LOGGER.debug("[waffle.util.CorsPreflightCheck] is preflight");

            return true;
        }
    }
}
File Project Line
waffle/windows/auth/impl/WindowsComputerImpl.java waffle-jna-jakarta 38
waffle/windows/auth/impl/WindowsComputerImpl.java waffle-jna 38
public class WindowsComputerImpl implements IWindowsComputer {

    /** The computer name. */
    private final String computerName;

    /** The domain name. */
    private final String domainName;

    /**
     * Instantiates a new windows computer impl.
     *
     * @param newComputerName
     *            the new computer name
     */
    public WindowsComputerImpl(final String newComputerName) {
        this.computerName = newComputerName;
        this.domainName = Netapi32Util.getDomainName(newComputerName);
    }

    @Override
    public String getComputerName() {
        return this.computerName;
    }

    @Override
    public String[] getGroups() {
        final List<String> groupNames = new ArrayList<>();
        final LocalGroup[] groups = Netapi32Util.getLocalGroups(this.computerName);
        for (final LocalGroup group : groups) {
            groupNames.add(group.name);
        }
        return groupNames.toArray(new String[0]);
    }

    @Override
    public String getJoinStatus() {
        final int joinStatus = Netapi32Util.getJoinStatus(this.computerName);
        switch (joinStatus) {
            case LMJoin.NETSETUP_JOIN_STATUS.NetSetupDomainName:
                return "NetSetupDomainName";
            case LMJoin.NETSETUP_JOIN_STATUS.NetSetupUnjoined:
                return "NetSetupUnjoined";
            case LMJoin.NETSETUP_JOIN_STATUS.NetSetupWorkgroupName:
                return "NetSetupWorkgroupName";
            case LMJoin.NETSETUP_JOIN_STATUS.NetSetupUnknownStatus:
                return "NetSetupUnknownStatus";
            default:
                throw new RuntimeException("Unsupported join status: " + joinStatus);
        }
    }

    @Override
    public String getMemberOf() {
        return this.domainName;
    }

}
File Project Line
waffle/windows/auth/WindowsAccount.java waffle-jna-jakarta 31
waffle/windows/auth/WindowsAccount.java waffle-jna 31
public class WindowsAccount implements Serializable {

    /** The Constant serialVersionUID. */
    private static final long serialVersionUID = 1L;

    /** The sid string. */
    private final String sidString;

    /** The fqn. */
    private final String fqn;

    /** The name. */
    private final String name;

    /** The domain. */
    private final String domain;

    /**
     * Instantiates a new windows account.
     *
     * @param account
     *            the account
     */
    public WindowsAccount(final IWindowsAccount account) {
        this.sidString = account.getSidString();
        this.fqn = account.getFqn();
        this.name = account.getName();
        this.domain = account.getDomain();
    }

    /**
     * Gets the sid string.
     *
     * @return the sid string
     */
    public String getSidString() {
        return this.sidString;
    }

    /**
     * Gets the fqn.
     *
     * @return the fqn
     */
    public String getFqn() {
        return this.fqn;
    }

    /**
     * Gets the name.
     *
     * @return the name
     */
    public String getName() {
        return this.name;
    }

    /**
     * Gets the domain.
     *
     * @return the domain
     */
    public String getDomain() {
        return this.domain;
    }

    @Override
    public boolean equals(final Object o) {

        if (this == o) {
            return true;
        }

        if (!(o instanceof WindowsAccount)) {
            return false;
        }

        return ((WindowsAccount) o).getSidString().equals(this.getSidString());
    }

    @Override
    public int hashCode() {
        return this.getSidString().hashCode();
    }
}
File Project Line
waffle/mock/MockWindowsIdentity.java waffle-tests-jakarta 36
waffle/mock/MockWindowsIdentity.java waffle-tests 36
public class MockWindowsIdentity implements IWindowsIdentity {

    /** The fqn. */
    private final String fqn;

    /** The groups. */
    private final List<String> groups;

    /**
     * Instantiates a new mock windows identity.
     *
     * @param newFqn
     *            the new fqn
     * @param newGroups
     *            the new groups
     */
    public MockWindowsIdentity(final String newFqn, final List<String> newGroups) {
        this.fqn = newFqn;
        this.groups = newGroups;
    }

    @Override
    public String getFqn() {
        return this.fqn;
    }

    @Override
    public IWindowsAccount[] getGroups() {
        final List<MockWindowsAccount> groupsList = new ArrayList<>();
        for (final String group : this.groups) {
            groupsList.add(new MockWindowsAccount(group));
        }
        return groupsList.toArray(new IWindowsAccount[0]);
    }

    @Override
    public byte[] getSid() {
        return new byte[0];
    }

    @Override
    public String getSidString() {
        return "S-" + this.fqn.hashCode();
    }

    @Override
    public void dispose() {
        // Do Nothing
    }

    @Override
    public boolean isGuest() {
        return "Guest".equals(this.fqn);
    }

    @Override
    public IWindowsImpersonationContext impersonate() {
        return new MockWindowsImpersonationContext();
    }

}
File Project Line
waffle/apache/MixedAuthenticator.java waffle-tomcat10 149
waffle/apache/NegotiateAuthenticator.java waffle-tomcat10 96
waffle/apache/MixedAuthenticator.java waffle-tomcat85 149
waffle/apache/NegotiateAuthenticator.java waffle-tomcat85 96
waffle/apache/MixedAuthenticator.java waffle-tomcat9 149
waffle/apache/NegotiateAuthenticator.java waffle-tomcat9 96
final boolean ntlmPost = authorizationHeader.isNtlmType1PostAuthorizationHeader();

        if (ntlmPost) {
            // type 1 NTLM authentication message received
            this.auth.resetSecurityToken(connectionId);
        }

        final byte[] tokenBuffer = authorizationHeader.getTokenBytes();
        this.log.debug("token buffer: {} byte(s)", Integer.valueOf(tokenBuffer.length));

        // log the user in using the token
        IWindowsSecurityContext securityContext;
        try {
            securityContext = this.auth.acceptSecurityToken(connectionId, tokenBuffer, securityPackage);
        } catch (final Win32Exception e) {
            this.log.warn("error logging in user: {}", e.getMessage());
            this.log.trace("", e);
            this.sendUnauthorized(response);
            return false;
        }
        this.log.debug("continue required: {}", Boolean.valueOf(securityContext.isContinue()));

        final byte[] continueTokenBytes = securityContext.getToken();
        if (continueTokenBytes != null && continueTokenBytes.length > 0) {
            final String continueToken = Base64.getEncoder().encodeToString(continueTokenBytes);
            this.log.debug("continue token: {}", continueToken);
            response.addHeader("WWW-Authenticate", securityPackage + " " + continueToken);
        }

        try {
            if (securityContext.isContinue() || ntlmPost) {
File Project Line
waffle/mock/MockWindowsSecurityContext.java waffle-tests-jakarta 39
waffle/mock/MockWindowsSecurityContext.java waffle-tests 39
public class MockWindowsSecurityContext implements IWindowsSecurityContext {

    /** The identity. */
    private final IWindowsIdentity identity;

    /**
     * Instantiates a new mock windows security context.
     *
     * @param username
     *            the username
     */
    public MockWindowsSecurityContext(final String username) {
        final List<String> groups = new ArrayList<>();
        groups.add("Users");
        groups.add("Everyone");
        this.identity = new MockWindowsIdentity(username, groups);
    }

    @Override
    public void dispose() {
        // Do Nothing
    }

    @Override
    public boolean isContinue() {
        return false;
    }

    @Override
    public CtxtHandle getHandle() {
        return new CtxtHandle();
    }

    @Override
    public IWindowsIdentity getIdentity() {
        return this.identity;
    }

    @Override
    public String getPrincipalName() {
        return this.identity.getFqn();
    }

    @Override
    public String getSecurityPackage() {
        return "Mock";
    }

    @Override
    public byte[] getToken() {
        return new byte[0];
    }

    @Override
    public IWindowsImpersonationContext impersonate() {
        return new MockWindowsImpersonationContext();
    }

    /**
     * Initialize.
     */
    public void initialize() {
        // Do Nothing
    }

    @Override
    public void initialize(final CtxtHandle continueCtx, final SecBufferDesc continueToken,
            final String targetPrincipalName) {
        // Do Nothing
    }

}
File Project Line
waffle/servlet/spi/SecurityFilterProviderCollection.java waffle-jna-jakarta 47
waffle/servlet/spi/SecurityFilterProviderCollection.java waffle-jna 47
public class SecurityFilterProviderCollection {

    /** The Constant LOGGER. */
    private static final Logger LOGGER = LoggerFactory.getLogger(SecurityFilterProviderCollection.class);

    /** The providers. */
    private final List<SecurityFilterProvider> providers = new ArrayList<>();

    /**
     * Instantiates a new security filter provider collection.
     *
     * @param providerArray
     *            the provider array
     */
    public SecurityFilterProviderCollection(final SecurityFilterProvider[] providerArray) {
        for (final SecurityFilterProvider provider : providerArray) {
            SecurityFilterProviderCollection.LOGGER.info("using '{}'", provider.getClass().getName());
            this.providers.add(provider);
        }
    }

    /**
     * Instantiates a new security filter provider collection.
     *
     * @param providerNames
     *            the provider names
     * @param auth
     *            the auth
     */
    @SuppressWarnings("unchecked")
    public SecurityFilterProviderCollection(final String[] providerNames, final IWindowsAuthProvider auth) {
        Class<SecurityFilterProvider> providerClass;
        Constructor<SecurityFilterProvider> providerConstructor;
        for (String providerName : providerNames) {
            providerName = providerName.trim();
            SecurityFilterProviderCollection.LOGGER.info("loading '{}'", providerName);
            try {
                providerClass = (Class<SecurityFilterProvider>) Class.forName(providerName);
                providerConstructor = providerClass.getConstructor(IWindowsAuthProvider.class);
                final SecurityFilterProvider provider = providerConstructor.newInstance(auth);
                this.providers.add(provider);
            } catch (final ClassNotFoundException e) {
File Project Line
waffle/mock/MockWindowsAccount.java waffle-tests-jakarta 31
waffle/mock/MockWindowsAccount.java waffle-tests 31
public class MockWindowsAccount implements IWindowsAccount {

    /** The Constant TEST_USER_NAME. */
    public static final String TEST_USER_NAME = "WaffleTestUser";

    /** The Constant TEST_PASSWORD. */
    public static final String TEST_PASSWORD = "!WAFFLEP$$Wrd0";

    /** The fqn. */
    private final String fqn;

    /** The name. */
    private String name;

    /** The domain. */
    private String domain;

    /** The sid. */
    private final String sid;

    /**
     * Instantiates a new mock windows account.
     *
     * @param newFqn
     *            the new fqn
     */
    public MockWindowsAccount(final String newFqn) {
        this(newFqn, "S-" + newFqn.hashCode());
    }

    /**
     * Instantiates a new mock windows account.
     *
     * @param newFqn
     *            the new fqn
     * @param newSid
     *            the new sid
     */
    public MockWindowsAccount(final String newFqn, final String newSid) {
        this.fqn = newFqn;
        this.sid = newSid;
        final String[] userNameDomain = newFqn.split("\\\\", 2);
        if (userNameDomain.length == 2) {
            this.name = userNameDomain[1];
            this.domain = userNameDomain[0];
        } else {
            this.name = newFqn;
        }
    }

    @Override
    public String getDomain() {
        return this.domain;
    }

    @Override
    public String getFqn() {
        return this.fqn;
    }

    @Override
    public String getName() {
        return this.name;
    }

    @Override
    public String getSidString() {
        return this.sid;
    }

}
File Project Line
waffle/mock/http/SimpleFilterConfig.java waffle-tests-jakarta 39
waffle/mock/http/SimpleFilterConfig.java waffle-tests 39
public class SimpleFilterConfig implements FilterConfig {

    /** The filter name. */
    private String filterName = "Simple Filter";

    /** The parameters. */
    private final Map<String, String> parameters = new TreeMap<>();

    @Override
    public String getFilterName() {
        return this.filterName;
    }

    /**
     * Sets the filter name.
     *
     * @param value
     *            the new filter name
     */
    public void setFilterName(final String value) {
        this.filterName = value;
    }

    @Override
    public String getInitParameter(final String s) {
        return this.parameters.get(s);
    }

    @Override
    public Enumeration<String> getInitParameterNames() {
        final List<String> keys = new ArrayList<>();
        keys.addAll(this.parameters.keySet());
        return Collections.enumeration(keys);
    }

    @Override
    public ServletContext getServletContext() {
        return null;
    }

    /**
     * Sets the parameter.
     *
     * @param parameterName
     *            the parameter name
     * @param parameterValue
     *            the parameter value
     */
    public void setParameter(final String parameterName, final String parameterValue) {
        this.parameters.put(parameterName, parameterValue);
    }
}
File Project Line
waffle/util/cache/CaffeineCache.java waffle-jna-jakarta 42
waffle/util/cache/CaffeineCache.java waffle-jna 42
public class CaffeineCache<K, V> implements Cache<K, V> {

    /** The cache store. */
    private final com.github.benmanes.caffeine.cache.Cache<K, V> cache;

    /**
     * Instantiate new caffeine cache with timeout.
     *
     * @param timeout
     *            Specified timeout in seconds for cache.
     */
    public CaffeineCache(@NonNegative final long timeout) {
        cache = Caffeine.newBuilder().expireAfterWrite(Duration.ofSeconds(timeout)).build();
    }

    @Override
    public V get(K key) {
        return cache.asMap().get(key);
    }

    @Override
    public void put(K key, V value) {
        cache.put(key, value);
    }

    @Override
    public void remove(K key) {
        cache.asMap().remove(key);
    }

    @Override
    public int size() {
        return cache.asMap().size();
    }
}
File Project Line
waffle/windows/auth/impl/WindowsAccountImpl.java waffle-jna-jakarta 36
waffle/windows/auth/impl/WindowsAccountImpl.java waffle-jna 36
public class WindowsAccountImpl implements IWindowsAccount {

    /** The account. */
    private final Account account;

    /**
     * Windows Account.
     *
     * @param newAccount
     *            Account.
     */
    public WindowsAccountImpl(final Account newAccount) {
        this.account = newAccount;
    }

    /**
     * Windows Account.
     *
     * @param userName
     *            Fully qualified username.
     */
    public WindowsAccountImpl(final String userName) {
        this(userName, null);
    }

    /**
     * Windows Account.
     *
     * @param accountName
     *            Username, without a domain or machine.
     * @param systemName
     *            Machine name.
     */
    public WindowsAccountImpl(final String accountName, final String systemName) {
        this(Advapi32Util.getAccountByName(systemName, accountName));
    }

    /**
     * Get the SAM-compatible username of the currently logged-on user.
     *
     * @return String.
     */
    public static String getCurrentUsername() {
        return Secur32Util.getUserNameEx(EXTENDED_NAME_FORMAT.NameSamCompatible);
    }

    /**
     * Account domain.
     *
     * @return String.
     */
    @Override
    public String getDomain() {
        return this.account.domain;
    }

    @Override
    public String getFqn() {
        return this.account.fqn;
    }

    /**
     * Account name.
     *
     * @return String.
     */
    @Override
    public String getName() {
        return this.account.name;
    }

    @Override
    public String getSidString() {
        return this.account.sidString;
    }

}
File Project Line
waffle/spring/NegotiateSecurityFilterEntryPoint.java waffle-spring-security5 42
waffle/spring/NegotiateSecurityFilterEntryPoint.java waffle-spring-security6 42
public class NegotiateSecurityFilterEntryPoint implements AuthenticationEntryPoint {

    /** The Constant LOGGER. */
    private static final Logger LOGGER = LoggerFactory.getLogger(NegotiateSecurityFilterEntryPoint.class);

    /** The provider. */
    private SecurityFilterProviderCollection provider;

    /**
     * Instantiates a new negotiate security filter entry point.
     */
    public NegotiateSecurityFilterEntryPoint() {
        NegotiateSecurityFilterEntryPoint.LOGGER.debug("[waffle.spring.NegotiateEntryPoint] loaded");
    }

    @Override
    public void commence(final HttpServletRequest request, final HttpServletResponse response,
            final AuthenticationException ex) throws IOException, ServletException {

        NegotiateSecurityFilterEntryPoint.LOGGER.debug("[waffle.spring.NegotiateEntryPoint] commence");

        if (this.provider == null) {
            throw new ServletException("Missing NegotiateEntryPoint.Provider");
        }

        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        response.setHeader("Connection", "keep-alive");
        this.provider.sendUnauthorized(response);
        response.flushBuffer();
    }

    /**
     * Gets the provider.
     *
     * @return the provider
     */
    public SecurityFilterProviderCollection getProvider() {
        return this.provider;
    }

    /**
     * Sets the provider.
     *
     * @param value
     *            the new provider
     */
    public void setProvider(final SecurityFilterProviderCollection value) {
        this.provider = value;
    }
}
File Project Line
waffle/spring/NegotiateSecurityFilter.java waffle-spring-security5 213
waffle/spring/WindowsAuthenticationProvider.java waffle-spring-security5 115
waffle/spring/NegotiateSecurityFilter.java waffle-spring-security6 213
waffle/spring/WindowsAuthenticationProvider.java waffle-spring-security6 115
}

    /**
     * Gets the principal format.
     *
     * @return the principal format
     */
    public PrincipalFormat getPrincipalFormat() {
        return this.principalFormat;
    }

    /**
     * Sets the principal format enum.
     *
     * @param value
     *            the new principal format enum
     */
    public void setPrincipalFormatEnum(final PrincipalFormat value) {
        this.principalFormat = value;
    }

    /**
     * Sets the principal format.
     *
     * @param value
     *            the new principal format
     */
    public void setPrincipalFormat(final String value) {
        this.setPrincipalFormatEnum(PrincipalFormat.valueOf(value.toUpperCase(Locale.ENGLISH)));
    }

    /**
     * Gets the role format.
     *
     * @return the role format
     */
    public PrincipalFormat getRoleFormat() {
        return this.roleFormat;
    }

    /**
     * Sets the role format enum.
     *
     * @param value
     *            the new role format enum
     */
    public void setRoleFormatEnum(final PrincipalFormat value) {
        this.roleFormat = value;
    }

    /**
     * Sets the role format.
     *
     * @param value
     *            the new role format
     */
    public void setRoleFormat(final String value) {
        this.setRoleFormatEnum(PrincipalFormat.valueOf(value.toUpperCase(Locale.ENGLISH)));
    }

    /**
     * Checks if is allow guest login.
     *
     * @return true, if is allow guest login
     */
    public boolean isAllowGuestLogin() {
        return this.allowGuestLogin;
    }

    /**
     * Sets the allow guest login.
     *
     * @param value
     *            the new allow guest login
     */
    public void setAllowGuestLogin(final boolean value) {
        this.allowGuestLogin = value;
    }

    /**
     * Enable/Disable impersonation.
     *
     * @param value
     *            true to enable impersonation, false otherwise
     */
    public void setImpersonate(final boolean value) {
File Project Line
waffle/util/NtlmMessage.java waffle-jna-jakarta 29
waffle/util/NtlmMessage.java waffle-jna 29
public final class NtlmMessage {

    // NTLM messages start with 0x4e544c4d53535000, NTLMSSP signature
    /** The Constant NTLM_SSP_SIGNATURE. */
    private static final byte[] NTLM_SSP_SIGNATURE = { 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00 };

    /**
     * Checks if is ntlm message.
     *
     * @param message
     *            the message
     *
     * @return true, if is ntlm message
     */
    public static boolean isNtlmMessage(final byte[] message) {
        if (message == null || message.length < NtlmMessage.NTLM_SSP_SIGNATURE.length) {
            return false;
        }

        for (int i = 0; i < NtlmMessage.NTLM_SSP_SIGNATURE.length; i++) {
            if (NtlmMessage.NTLM_SSP_SIGNATURE[i] != message[i]) {
                return false;
            }
        }

        return true;
    }

    /**
     * Get NTLM message type.
     *
     * @param message
     *            Assuming a valid NTLM message.
     *
     * @return Message type.
     */
    public static int getMessageType(final byte[] message) {
        return message[NtlmMessage.NTLM_SSP_SIGNATURE.length];
    }

    /**
     * Instantiates a new ntlm message.
     */
    private NtlmMessage() {
        // Prevent Instantiation of object
    }
}
File Project Line
waffle/servlet/NegotiateSecurityFilter.java waffle-jna-jakarta 179
waffle/servlet/NegotiateSecurityFilter.java waffle-jna 178
waffle/spring/NegotiateSecurityFilter.java waffle-spring-security5 108
waffle/spring/NegotiateSecurityFilter.java waffle-spring-security6 108
windowsIdentity = this.providers.doFilter(request, response);
                if (windowsIdentity == null) {
                    return;
                }
            } catch (final IOException e) {
                NegotiateSecurityFilter.LOGGER.warn("error logging in user: {}", e.getMessage());
                NegotiateSecurityFilter.LOGGER.trace("", e);
                this.sendUnauthorized(response, true);
                return;
            }

            IWindowsImpersonationContext ctx = null;
            try {
                if (!this.allowGuestLogin && windowsIdentity.isGuest()) {
                    NegotiateSecurityFilter.LOGGER.warn("guest login disabled: {}", windowsIdentity.getFqn());
                    this.sendUnauthorized(response, true);
                    return;
                }

                NegotiateSecurityFilter.LOGGER.debug("logged in user: {} ({})", windowsIdentity.getFqn(),
                        windowsIdentity.getSidString());

                final HttpSession session = request.getSession(true);
File Project Line
waffle/jaas/RolePrincipal.java waffle-jna-jakarta 32
waffle/jaas/RolePrincipal.java waffle-jna 32
public class RolePrincipal implements Principal, Serializable {

    /** The Constant serialVersionUID. */
    private static final long serialVersionUID = 1L;

    /** The fqn. */
    private final String fqn;

    /**
     * A windows principal.
     *
     * @param newFqn
     *            Fully qualified name.
     */
    public RolePrincipal(final String newFqn) {
        this.fqn = newFqn;
    }

    /**
     * Role name (Windows Group).
     *
     * @return the name
     */
    @Override
    public String getName() {
        return this.fqn;
    }

    /**
     * Role Principal Equals for FQN.
     *
     * @param o
     *            Object used for Equality Check.
     *
     * @return true, if successful
     */
    @Override
    public boolean equals(final Object o) {

        if (this == o) {
            return true;
        }

        if (o instanceof RolePrincipal) {
            return this.getName().equals(((RolePrincipal) o).getName());
        }

        return false;
    }

    /**
     * Role Principal HashCode for FQN.
     *
     * @return the int
     */
    @Override
    public int hashCode() {
        return this.getName().hashCode();
    }

}
File Project Line
waffle/jaas/UserPrincipal.java waffle-jna-jakarta 32
waffle/jaas/UserPrincipal.java waffle-jna 32
public class UserPrincipal implements Principal, Serializable {

    /** The Constant serialVersionUID. */
    private static final long serialVersionUID = 1L;

    /** The fqn. */
    private final String fqn;

    /**
     * A user principal.
     *
     * @param newFqn
     *            Fully qualified username.
     */
    public UserPrincipal(final String newFqn) {
        this.fqn = newFqn;
    }

    /**
     * Fully qualified username.
     *
     * @return the name
     */
    @Override
    public String getName() {
        return this.fqn;
    }

    @Override
    public boolean equals(final Object o) {

        if (this == o) {
            return true;
        }

        if (o instanceof UserPrincipal) {
            return this.getName().equals(((UserPrincipal) o).getName());
        }

        return false;
    }

    @Override
    public int hashCode() {
        return this.getName().hashCode();
    }
}
File Project Line
waffle/apache/MixedAuthenticator.java waffle-tomcat10 188
waffle/apache/NegotiateAuthenticator.java waffle-tomcat10 142
waffle/apache/MixedAuthenticator.java waffle-tomcat85 188
waffle/apache/NegotiateAuthenticator.java waffle-tomcat85 142
waffle/apache/MixedAuthenticator.java waffle-tomcat9 188
waffle/apache/NegotiateAuthenticator.java waffle-tomcat9 142
this.sendUnauthorized(response);
            return false;
        }

        // create and register the user principal with the session
        final IWindowsIdentity windowsIdentity = securityContext.getIdentity();

        // disable guest login
        if (!this.allowGuestLogin && windowsIdentity.isGuest()) {
            this.log.warn("guest login disabled: {}", windowsIdentity.getFqn());
            this.sendUnauthorized(response);
            return false;
        }

        try {

            this.log.debug("logged in user: {} ({})", windowsIdentity.getFqn(), windowsIdentity.getSidString());

            final GenericPrincipal genericPrincipal = this.createPrincipal(windowsIdentity);

            if (this.log.isDebugEnabled()) {
                this.log.debug("roles: {}", String.join(", ", genericPrincipal.getRoles()));
            }
File Project Line
waffle/mock/http/SimpleHttpSession.java waffle-tests-jakarta 36
waffle/mock/http/SimpleHttpSession.java waffle-tests 39
public class SimpleHttpSession implements HttpSession {

    /** The attributes. */
    private final Map<String, Object> attributes = new HashMap<>();

    @Override
    public Object getAttribute(final String attributeName) {
        return this.attributes.get(attributeName);
    }

    @Override
    public Enumeration<String> getAttributeNames() {
        return null;
    }

    @Override
    public long getCreationTime() {
        return 0;
    }

    @Override
    public String getId() {
        return null;
    }

    @Override
    public long getLastAccessedTime() {
        return 0;
    }

    @Override
    public int getMaxInactiveInterval() {
        return 0;
    }

    @Override
    public ServletContext getServletContext() {
        return null;
    }

    @Override
File Project Line
waffle/util/cache/Cache.java waffle-jna-jakarta 42
waffle/util/cache/Cache.java waffle-jna 42
public interface Cache<K, V> {

    /**
     * Creates a new cache with the specified timeout.
     * <p>
     * The cache implementation is obtained using {@link ServiceLoader}. To create your own implementation, implement
     * {@link CacheSupplier} and register it using the {@code /META-INF/services/waffle.util.cache.CacheSupplier} file
     * on your classpath.
     *
     * @param timeout
     *            timeout in seconds
     * @param <K>
     *            the type of keys maintained by this cache
     * @param <V>
     *            the type of mapped values
     *
     * @return a new cache
     *
     * @throws NoSuchElementException
     *             if no cache can be instantiated, use {@link Exception#getSuppressed()} to obtain details.
     */
    static <K, V> Cache<K, V> newCache(int timeout) throws NoSuchElementException {
        final NoSuchElementException exception = new NoSuchElementException();
        for (CacheSupplier cacheSupplier : ServiceLoader.load(CacheSupplier.class)) {
            try {
                return cacheSupplier.newCache(timeout);
            } catch (Exception e) {
                exception.addSuppressed(e);
            }
        }
        throw exception;
    }

    /**
     * Fetches the key from the cache
     *
     * @param key
     *            the key
     *
     * @return the corresponding value
     *
     * @see java.util.Map#get
     */
    V get(K key);

    /**
     * Stores a binding for the key and the value in the cache
     *
     * @param key
     *            the key
     * @param value
     *            the value
     *
     * @see java.util.Map#put
     */
    void put(K key, V value);

    /**
     * Removes the binding for the key from the cache
     *
     * @param key
     *            the key
     *
     * @see java.util.Map#remove(Object)
     */
    void remove(K key);

    /**
     * Returns the number of bindings in this cache
     *
     * @return the size
     *
     * @see java.util.Map#size
     */
    int size();
}