/* * Zed Attack Proxy (ZAP) and its related class files. * * ZAP is an HTTP/HTTPS proxy for assessing web application security. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.zaproxy.zap.extension.httpsessions; import java.net.HttpCookie; import java.util.Collections; import java.util.HashMap; import java.util.Map; import org.apache.commons.httpclient.Cookie; /** * The Class HttpSession defines the data that is stored regarding an existing HTTP session on a * particular site. * <p> * The session can be invalidated and should only be used while it is valid. * </p> */ public class HttpSession { /** The name. */ private String name; /** Whether it is active. */ private boolean active; /** The session tokens' values for this session. */ private Map<String, Cookie> tokenValues; /** Whether this session is valid. */ private boolean valid; /** The number of http messages that matched this session. */ private int messagesMatched; private HttpSessionTokensSet tokenNames; /** * Instantiates a new http session. * * @param name the name * @param tokenNames the token names */ public HttpSession(String name, HttpSessionTokensSet tokenNames) { super(); this.name = name; this.active = false; this.valid = true; this.messagesMatched = 0; this.tokenValues = new HashMap<>(1); this.tokenNames=tokenNames; } public HttpSessionTokensSet getTokensNames() { return tokenNames; } /** * Gets the name. * * @return the name */ public String getName() { return name; } /** * Sets the name. * * @param name the new name */ public void setName(String name) { this.name = name; } /** * Checks if it is active. * * @return true, if is active */ public boolean isActive() { return active; } /** * Sets whether it is active. * * @param active the new active */ public void setActive(boolean active) { this.active = active; } /** * Sets a particular value for a session token. If the value is null, that token is deleted from * the session. * * @param tokenName the token name * @param value the new value of the token, or null, if the token has to be deleted */ public void setTokenValue(String tokenName, Cookie value) { if (value == null) { tokenValues.remove(tokenName); } else { tokenValues.put(tokenName, value); } } /** * Gets the token value. * * @param tokenName the token name * @return the token value */ public String getTokenValue(String tokenName) { Cookie ck = tokenValues.get(tokenName); if (ck != null) { return ck.getValue(); } return null; } /** * Checks if a particular cookie has the same value as one of the token values in the HTTP * session. If the {@literal cookie} parameter is null, the session matches the token if it does * not have a value for the corresponding token. * * @param tokenName the token name * @param cookie the cookie * @return true, if true */ public boolean matchesToken(String tokenName, HttpCookie cookie) { // Check if the cookie is null if (cookie == null) { return tokenValues.containsKey(tokenName) ? false : true; } // Check the value of the token from the cookie String tokenValue = getTokenValue(tokenName); if (tokenValue != null && tokenValue.equals(cookie.getValue())) { return true; } return false; } /** * Removes a given token. * * @param tokenName the token name */ public void removeToken(String tokenName) { tokenValues.remove(tokenName); } @Override public String toString() { return "HttpSession [name=" + name + ", active=" + active + ", tokenValues='" + getTokenValuesString() + "']"; } /** * Gets the token values string representation. * * @return the token values string */ public String getTokenValuesString() { if (tokenValues.isEmpty()) { return ""; } StringBuilder buf = new StringBuilder(); for (Map.Entry<String, Cookie> entry : tokenValues.entrySet()) { buf.append(entry.getKey()).append('=').append(entry.getValue().getValue()).append(';'); } buf.deleteCharAt(buf.length() - 1); return buf.toString(); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } HttpSession other = (HttpSession) obj; if (name == null) { if (other.name != null) { return false; } } else if (!name.equals(other.name)) { return false; } return true; } /** * Checks if the session is still valid. * * @return true, if is valid */ public boolean isValid() { return valid; } /** * Invalidates the session. */ public void invalidate() { this.valid = false; } /** * Gets the token values count. * * @return the token values count */ public int getTokenValuesCount() { return this.tokenValues.size(); } /** * Gets an unmodifiable view of the token values map. . Query operations on the returned map * "read through" to the specified map, and attempts to modify the returned map, whether direct * or via its collection views, result in an {@link UnsupportedOperationException}. * * @return the token values unmodifiable map */ public Map<String, Cookie> getTokenValuesUnmodifiableMap() { return Collections.unmodifiableMap(tokenValues); } /** * Gets the number of http messages that matched this session. * * @return the messages matched */ public int getMessagesMatched() { return messagesMatched; } /** * Sets the number of http messages that matched this session. * * @param messagesMatched the new messages matched count */ public void setMessagesMatched(int messagesMatched) { this.messagesMatched = messagesMatched; } }