mirror of https://github.com/M66B/FairEmail.git
104 lines
3.4 KiB
Java
104 lines
3.4 KiB
Java
package com.sun.mail.imap.protocol;
|
|
|
|
/*
|
|
This file is part of FairEmail.
|
|
|
|
FairEmail is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
FairEmail is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with FairEmail. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
Copyright 2018-2020 by Marcel Bokhorst (M66B)
|
|
*/
|
|
|
|
import android.util.Base64;
|
|
|
|
import com.sun.mail.iap.Argument;
|
|
import com.sun.mail.iap.ProtocolException;
|
|
import com.sun.mail.iap.Response;
|
|
import com.sun.mail.util.MailLogger;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.Properties;
|
|
|
|
import eu.faircode.email.Helper;
|
|
|
|
// https://github.com/javaee/javamail/blob/master/mail/src/main/java/com/sun/mail/imap/protocol/IMAPSaslAuthenticator.java
|
|
public class IMAPSaslAuthenticator implements SaslAuthenticator {
|
|
private IMAPProtocol pr;
|
|
private String name;
|
|
private Properties props;
|
|
private MailLogger logger;
|
|
private String host;
|
|
|
|
public IMAPSaslAuthenticator(
|
|
IMAPProtocol pr, String name, Properties props,
|
|
MailLogger logger, String host) {
|
|
this.pr = pr;
|
|
this.name = name;
|
|
this.props = props;
|
|
this.logger = logger;
|
|
this.host = host;
|
|
}
|
|
|
|
@Override
|
|
public boolean authenticate(
|
|
String[] mechs, final String realm,
|
|
final String authzid, final String u,
|
|
final String p) throws ProtocolException {
|
|
|
|
if (!pr.hasCapability("AUTH=CRAM-MD5"))
|
|
throw new UnsupportedOperationException();
|
|
|
|
List<Response> v = new ArrayList<>();
|
|
String tag = null;
|
|
Response r = null;
|
|
boolean done = false;
|
|
|
|
try {
|
|
Argument args = new Argument();
|
|
args.writeAtom("CRAM-MD5");
|
|
tag = pr.writeCommand("AUTHENTICATE", args);
|
|
} catch (Exception ex) {
|
|
r = Response.byeResponse(ex);
|
|
done = true;
|
|
}
|
|
|
|
while (!done) {
|
|
try {
|
|
r = pr.readResponse();
|
|
if (r.isContinuation()) {
|
|
byte[] nonce = Base64.decode(r.getRest(), Base64.NO_WRAP);
|
|
String hmac = Helper.HMAC("MD5", 64, p.getBytes(), nonce);
|
|
String hash = Base64.encodeToString((u + " " + hmac).getBytes(), Base64.NO_WRAP) + "\r\n";
|
|
pr.getIMAPOutputStream().write(hash.getBytes());
|
|
pr.getIMAPOutputStream().flush();
|
|
} else if (r.isTagged() && r.getTag().equals(tag))
|
|
done = true;
|
|
else if (r.isBYE())
|
|
done = true;
|
|
} catch (Exception ex) {
|
|
r = Response.byeResponse(ex);
|
|
done = true;
|
|
}
|
|
v.add(r);
|
|
}
|
|
|
|
Response[] responses = v.toArray(new Response[0]);
|
|
pr.handleCapabilityResponse(responses);
|
|
pr.notifyResponseHandlers(responses);
|
|
pr.handleLoginResult(r);
|
|
pr.setCapabilities(r);
|
|
return true;
|
|
}
|
|
}
|