/*
* CredentialManager.java
*
* Created on 04 January 2006, 08:25
*
* To change this template, choose Tools | Options and locate the template under
* the Source Creation and Management node. Right-click the template and choose
* Open. You can then make changes to the template in the Source Editor.
*/
package org.owasp.webscarab.plugin;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import org.owasp.webscarab.httpclient.Authenticator;
import org.owasp.webscarab.model.HttpUrl;
import org.owasp.webscarab.model.Preferences;
import org.owasp.webscarab.util.Encoding;
/**
*
* @author rdawes
*/
public class CredentialManager implements Authenticator {
// contains Maps per host, indexed by Realm
private Map<String, Map<String, BasicCredential>> _basicCredentials = new TreeMap<String, Map<String, BasicCredential>>();
private Map<String, DomainCredential> _domainCredentials = new TreeMap<String, DomainCredential>();
private CredentialManagerUI _ui = null;
/** Creates a new instance of CredentialManager */
public CredentialManager() {
}
public void setUI(CredentialManagerUI ui) {
_ui = ui;
}
public synchronized String getCredentials(HttpUrl url, String[] challenges) {
String creds = getPreferredCredentials(url.getHost(), challenges);
if (creds != null) return creds;
boolean prompt = Boolean.valueOf(Preferences.getPreference("WebScarab.promptForCredentials", "false")).booleanValue();
if (prompt && _ui != null && challenges != null && challenges.length > 0) {
boolean ask = false;
for (int i=0; i<challenges.length; i++)
if (challenges[i].startsWith("Basic") || challenges[i].startsWith("NTLM") || challenges[i].startsWith("Negotiate"))
ask = true;
if (ask)
_ui.requestCredentials(url.getHost(), challenges);
}
return getPreferredCredentials(url.getHost(), challenges);
}
public synchronized String getProxyCredentials(String hostname, String[] challenges) {
String creds = getPreferredCredentials(hostname, challenges);
if (creds != null) return creds;
boolean prompt = Boolean.valueOf(Preferences.getPreference("WebScarab.promptForCredentials", "false")).booleanValue();
if (prompt && _ui != null && challenges != null && challenges.length > 0) {
boolean ask = false;
for (int i=0; i<challenges.length; i++)
if (challenges[i].startsWith("Basic") || challenges[i].startsWith("NTLM") || challenges[i].startsWith("Negotiate"))
ask = true;
if (ask)
_ui.requestCredentials(hostname, challenges);
}
return getPreferredCredentials(hostname, challenges);
}
public void addBasicCredentials(BasicCredential cred) {
if ((cred.getUsername() == null || cred.getUsername().equals("")) && (cred.getPassword() == null || cred.getPassword().equals(""))) return;
Map<String, BasicCredential> realms = _basicCredentials.get(cred.getHost());
if (realms == null) {
realms = new TreeMap<String, BasicCredential>();
_basicCredentials.put(cred.getHost(), realms);
}
realms.put(cred.getRealm(), cred);
}
public void addDomainCredentials(DomainCredential cred) {
if ((cred.getUsername() == null || cred.getUsername().equals("")) && (cred.getPassword() == null || cred.getPassword().equals(""))) return;
_domainCredentials.put(cred.getHost(), cred);
}
public int getBasicCredentialCount() {
return getAllBasicCredentials().length;
}
public BasicCredential getBasicCredentialAt(int index) {
return getAllBasicCredentials()[index];
}
public void deleteBasicCredentialAt(int index) {
int i = -1;
Iterator<String> hosts = _basicCredentials.keySet().iterator();
while (hosts.hasNext()) {
Map<String, BasicCredential> realms = _basicCredentials.get(hosts.next());
Iterator<String> realm = realms.keySet().iterator();
while (realm.hasNext()) {
String key = realm.next();
i++;
if (i == index)
realms.remove(key);
}
}
}
public int getDomainCredentialCount() {
return _domainCredentials.entrySet().size();
}
public DomainCredential getDomainCredentialAt(int index) {
List<DomainCredential> all = new ArrayList<DomainCredential>();
Iterator<String> hosts = _domainCredentials.keySet().iterator();
while (hosts.hasNext())
all.add(_domainCredentials.get(hosts.next()));
return (DomainCredential) all.toArray(new DomainCredential[0])[index];
}
public void deleteDomainCredentialAt(int index) {
int i = -1;
Iterator<String> hosts = _domainCredentials.keySet().iterator();
while (hosts.hasNext()) {
String key = hosts.next();
i++;
if (i == index)
_domainCredentials.remove(key);
}
}
private BasicCredential[] getAllBasicCredentials() {
List<BasicCredential> all = new ArrayList<BasicCredential>();
Iterator<String> hosts = _basicCredentials.keySet().iterator();
while (hosts.hasNext()) {
Map<String, BasicCredential> realms = _basicCredentials.get(hosts.next());
Iterator<String> realm = realms.keySet().iterator();
while (realm.hasNext())
all.add(realms.get(realm.next()));
}
return (BasicCredential[]) all.toArray(new BasicCredential[0]);
}
private String getPreferredCredentials(String host, String[] challenges) {
// we don't do pre-emptive auth at all
if (challenges == null || challenges.length == 0)
return null;
for (int i=0; i<challenges.length; i++) {
if (challenges[i].startsWith("Basic")) {
String creds = getBasicCredentials(host, challenges[i]);
if (creds != null) return "Basic " + creds;
}
}
for (int i=0; i<challenges.length; i++) {
if (challenges[i].startsWith("NTLM")) {
String creds = getDomainCredentials(host);
if (creds != null) return "NTLM " + creds;
}
}
for (int i=0; i<challenges.length; i++) {
if (challenges[i].startsWith("Negotiate")) {
String creds = getDomainCredentials(host);
if (creds != null) return "Negotiate " + creds;
}
}
return null;
}
private String getBasicCredentials(String host, String challenge) {
String realm = challenge.substring("Basic Realm=\"".length(), challenge.length()-1);
Map<String, BasicCredential> realms = _basicCredentials.get(host);
if (realms == null) return null;
BasicCredential cred = realms.get(realm);
if (cred == null) return null;
String encoded = cred.getUsername() + ":" + cred.getPassword();
return Encoding.base64encode(encoded.getBytes(), false);
}
private String getDomainCredentials(String host) {
DomainCredential cred = _domainCredentials.get(host);
if (cred == null) return null;
String encoded = cred.getDomain() + "\\" + cred.getUsername() + ":" + cred.getPassword();
return Encoding.base64encode(encoded.getBytes(), false);
}
}