SaslMechanism.java

 1package eu.siacs.conversations.crypto.sasl;
 2
 3import com.google.common.base.Strings;
 4
 5import java.security.SecureRandom;
 6
 7import eu.siacs.conversations.entities.Account;
 8import eu.siacs.conversations.xml.Element;
 9import eu.siacs.conversations.xml.Namespace;
10import eu.siacs.conversations.xml.TagWriter;
11
12public abstract class SaslMechanism {
13
14    final protected TagWriter tagWriter;
15    final protected Account account;
16    final protected SecureRandom rng;
17
18    protected enum State {
19        INITIAL,
20        AUTH_TEXT_SENT,
21        RESPONSE_SENT,
22        VALID_SERVER_RESPONSE,
23    }
24
25    public static class AuthenticationException extends Exception {
26        public AuthenticationException(final String message) {
27            super(message);
28        }
29
30        public AuthenticationException(final Exception inner) {
31            super(inner);
32        }
33
34        public AuthenticationException(final String message, final Exception exception) {
35            super(message, exception);
36        }
37    }
38
39    public static class InvalidStateException extends AuthenticationException {
40        public InvalidStateException(final String message) {
41            super(message);
42        }
43
44        public InvalidStateException(final State state) {
45            this("Invalid state: " + state.toString());
46        }
47    }
48
49    public SaslMechanism(final TagWriter tagWriter, final Account account, final SecureRandom rng) {
50        this.tagWriter = tagWriter;
51        this.account = account;
52        this.rng = rng;
53    }
54
55    /**
56     * The priority is used to pin the authentication mechanism. If authentication fails, it MAY be retried with another
57     * mechanism of the same priority, but MUST NOT be tried with a mechanism of lower priority (to prevent downgrade
58     * attacks).
59     *
60     * @return An arbitrary int representing the priority
61     */
62    public abstract int getPriority();
63
64    public abstract String getMechanism();
65
66    public String getClientFirstMessage() {
67        return "";
68    }
69
70    public String getResponse(final String challenge) throws AuthenticationException {
71        return "";
72    }
73
74    public enum Version {
75        SASL, SASL_2;
76
77        public static Version of(final Element element) {
78            switch ( Strings.nullToEmpty(element.getNamespace())) {
79                case Namespace.SASL:
80                    return SASL;
81                case Namespace.SASL_2:
82                    return SASL_2;
83                default:
84                    throw new IllegalArgumentException("Unrecognized SASL namespace");
85            }
86        }
87    }
88}