• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Waffle / waffle / 6516

11 Mar 2026 12:15AM UTC coverage: 46.217%. Remained the same
6516

push

github

web-flow
Update dependency org.eclipse.jdt:ecj to v3.45.0

276 of 734 branches covered (37.6%)

Branch coverage included in aggregate %.

1019 of 2068 relevant lines covered (49.27%)

1.0 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

18.18
/Source/JNA/waffle-jna/src/main/java/waffle/servlet/spi/NegotiateSecurityFilterProvider.java
1
/*
2
 * SPDX-License-Identifier: MIT
3
 * See LICENSE file for details.
4
 *
5
 * Copyright 2010-2026 The Waffle Project Contributors: https://github.com/Waffle/waffle/graphs/contributors
6
 */
7
package waffle.servlet.spi;
8

9
import java.io.IOException;
10
import java.security.InvalidParameterException;
11
import java.util.ArrayList;
12
import java.util.Base64;
13
import java.util.List;
14

15
import javax.servlet.http.HttpServletRequest;
16
import javax.servlet.http.HttpServletResponse;
17

18
import org.slf4j.Logger;
19
import org.slf4j.LoggerFactory;
20

21
import waffle.util.AuthorizationHeader;
22
import waffle.util.NtlmServletRequest;
23
import waffle.windows.auth.IWindowsAuthProvider;
24
import waffle.windows.auth.IWindowsIdentity;
25
import waffle.windows.auth.IWindowsSecurityContext;
26

27
/**
28
 * A negotiate security filter provider.
29
 */
30
public class NegotiateSecurityFilterProvider implements SecurityFilterProvider {
31

32
    /** The Constant LOGGER. */
33
    private static final Logger LOGGER = LoggerFactory.getLogger(NegotiateSecurityFilterProvider.class);
2✔
34

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

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

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

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

47
    /** The protocols. */
48
    private List<String> protocolsList = new ArrayList<>();
2✔
49

50
    /** The auth. */
51
    private final IWindowsAuthProvider auth;
52

53
    /**
54
     * Instantiates a new negotiate security filter provider.
55
     *
56
     * @param newAuthProvider
57
     *            the new auth provider
58
     */
59
    public NegotiateSecurityFilterProvider(final IWindowsAuthProvider newAuthProvider) {
2✔
60
        this.auth = newAuthProvider;
2✔
61
        this.protocolsList.add(NegotiateSecurityFilterProvider.NEGOTIATE);
2✔
62
        this.protocolsList.add(NegotiateSecurityFilterProvider.NTLM);
2✔
63
    }
2✔
64

65
    /**
66
     * Gets the protocols.
67
     *
68
     * @return the protocols
69
     */
70
    public List<String> getProtocols() {
71
        return this.protocolsList;
×
72
    }
73

74
    /**
75
     * Sets the protocols.
76
     *
77
     * @param values
78
     *            the new protocols
79
     */
80
    public void setProtocols(final List<String> values) {
81
        this.protocolsList = values;
×
82
    }
×
83

84
    @Override
85
    public void sendUnauthorized(final HttpServletResponse response) {
86
        for (final String protocol : this.protocolsList) {
×
87
            response.addHeader(NegotiateSecurityFilterProvider.WWW_AUTHENTICATE, protocol);
×
88
        }
×
89
    }
×
90

91
    @Override
92
    public boolean isPrincipalException(final HttpServletRequest request) {
93
        final AuthorizationHeader authorizationHeader = new AuthorizationHeader(request);
×
94
        final boolean ntlmPost = authorizationHeader.isNtlmType1PostAuthorizationHeader();
×
95
        NegotiateSecurityFilterProvider.LOGGER.debug("authorization: {}, ntlm post: {}", authorizationHeader,
×
96
                Boolean.valueOf(ntlmPost));
×
97
        return ntlmPost;
×
98
    }
99

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

104
        final AuthorizationHeader authorizationHeader = new AuthorizationHeader(request);
×
105
        final boolean ntlmPost = authorizationHeader.isNtlmType1PostAuthorizationHeader();
×
106

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

113
        if (ntlmPost) {
×
114
            // type 2 NTLM authentication message received
115
            this.auth.resetSecurityToken(connectionId);
×
116
        }
117

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

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

130
        NegotiateSecurityFilterProvider.LOGGER.debug("continue required: {}",
×
131
                Boolean.valueOf(securityContext.isContinue()));
×
132
        if (securityContext.isContinue()) {
×
133
            response.setHeader("Connection", "keep-alive");
×
134
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
×
135
            response.flushBuffer();
×
136
            return null;
×
137
        }
138

139
        final IWindowsIdentity identity = securityContext.getIdentity();
×
140
        securityContext.dispose();
×
141
        return identity;
×
142
    }
143

144
    @Override
145
    public boolean isSecurityPackageSupported(final String securityPackage) {
146
        for (final String protocol : this.protocolsList) {
2✔
147
            if (protocol.equalsIgnoreCase(securityPackage)) {
2✔
148
                return true;
2✔
149
            }
150
        }
2✔
151
        return false;
2✔
152
    }
153

154
    @Override
155
    public void initParameter(final String parameterName, final String parameterValue) {
156
        if (NegotiateSecurityFilterProvider.PROTOCOLS.equals(parameterName)) {
×
157
            this.protocolsList = new ArrayList<>();
×
158
            final String[] protocolNames = parameterValue.split("\\s+", -1);
×
159
            for (String protocolName : protocolNames) {
×
160
                protocolName = protocolName.trim();
×
161
                if (protocolName.length() > 0) {
×
162
                    NegotiateSecurityFilterProvider.LOGGER.debug("init protocol: {}", protocolName);
×
163
                    if (NegotiateSecurityFilterProvider.NEGOTIATE.equals(protocolName)
×
164
                            || NegotiateSecurityFilterProvider.NTLM.equals(protocolName)) {
×
165
                        this.protocolsList.add(protocolName);
×
166
                    } else {
167
                        NegotiateSecurityFilterProvider.LOGGER.error("unsupported protocol: {}", protocolName);
×
168
                        throw new RuntimeException("Unsupported protocol: " + protocolName);
×
169
                    }
170
                }
171
            }
172
        } else {
×
173
            throw new InvalidParameterException(parameterName);
×
174
        }
175
    }
×
176
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc