/** * This file is part of git-as-svn. It is subject to the license terms * in the LICENSE file found in the top-level directory of this distribution * and at http://www.gnu.org/licenses/gpl-2.0.html. No part of git-as-svn, * including this file, may be copied, modified, propagated, or distributed * except according to the terms contained in the LICENSE file. */ package svnserver.auth; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.internal.util.SVNBase64; import svnserver.parser.SvnServerParser; import svnserver.parser.SvnServerWriter; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; /** * @author Marat Radchenko <marat@slonopotamus.org> */ public final class PlainAuthenticator implements Authenticator, PasswordChecker { @NotNull private final PasswordChecker passwordChecker; public PlainAuthenticator(@NotNull PasswordChecker passwordChecker) { this.passwordChecker = passwordChecker; } @NotNull @Override public String getMethodName() { return "PLAIN"; } @Nullable @Override public User authenticate(@NotNull SvnServerParser parser, @NotNull SvnServerWriter writer, @NotNull String token) throws IOException, SVNException { final String[] credentials = new String(fromBase64(token), StandardCharsets.US_ASCII).split("\u0000"); if (credentials.length < 3) return null; final String username = credentials[1]; final String password = credentials[2]; return check(username, password); } @Nullable @Override public User check(@NotNull String userName, @NotNull String password) throws SVNException, IOException { return passwordChecker.check(userName, password); } /** * Taken from {@link org.tmatesoft.svn.core.internal.io.svn.sasl.SVNSaslAuthenticator#fromBase64(String)}. */ private static byte[] fromBase64(@Nullable String src) { if (src == null) { return new byte[0]; } ByteArrayOutputStream bos = new ByteArrayOutputStream(); for (int i = 0; i < src.length(); i++) { char ch = src.charAt(i); if (!Character.isWhitespace(ch) && ch != '\n' && ch != '\r') { bos.write((byte) ch & 0xFF); } } byte[] cbytes = new byte[src.length()]; src = new String(bos.toByteArray(), StandardCharsets.US_ASCII); int clength = SVNBase64.base64ToByteArray(new StringBuffer(src), cbytes); byte[] result = new byte[clength]; // strip trailing -1s. for (int i = clength - 1; i >= 0; i--) { if (i == -1) { clength--; } } System.arraycopy(cbytes, 0, result, 0, clength); return result; } }