java/eJabberd-auth/src/cz/frantovo/ejabberd/auth/EJabberdAuth.java
changeset 26 5d23fa316c1c
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/java/eJabberd-auth/src/cz/frantovo/ejabberd/auth/EJabberdAuth.java	Mon Mar 10 12:20:26 2014 +0100
     1.3 @@ -0,0 +1,209 @@
     1.4 +/**
     1.5 + * SQL-DK
     1.6 + * Copyright © 2014 František Kučera (frantovo.cz)
     1.7 + *
     1.8 + * This program is free software: you can redistribute it and/or modify
     1.9 + * it under the terms of the GNU General Public License as published by
    1.10 + * the Free Software Foundation, either version 3 of the License, or
    1.11 + * (at your option) any later version.
    1.12 + *
    1.13 + * This program is distributed in the hope that it will be useful,
    1.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    1.16 + * GNU General Public License for more details.
    1.17 + *
    1.18 + * You should have received a copy of the GNU General Public License
    1.19 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
    1.20 + */
    1.21 +package cz.frantovo.ejabberd.auth;
    1.22 +
    1.23 +import java.io.DataInputStream;
    1.24 +import java.io.DataOutputStream;
    1.25 +import java.io.FileInputStream;
    1.26 +import java.io.FileOutputStream;
    1.27 +import java.io.IOException;
    1.28 +import java.io.InputStream;
    1.29 +import java.io.OutputStream;
    1.30 +import java.io.PrintStream;
    1.31 +import java.sql.Connection;
    1.32 +import java.sql.DriverManager;
    1.33 +import java.sql.PreparedStatement;
    1.34 +import java.sql.ResultSet;
    1.35 +import java.sql.SQLException;
    1.36 +import java.util.Properties;
    1.37 +
    1.38 +/**
    1.39 + *
    1.40 + * @author Ing. František Kučera (frantovo.cz)
    1.41 + */
    1.42 +public class EJabberdAuth {
    1.43 +
    1.44 +	public static final String NASTAVENÍ_DB_URL = "db.url";
    1.45 +	public static final String NASTAVENÍ_DB_JMÉNO = "db.jmeno";
    1.46 +	public static final String NASTAVENÍ_DB_HESLO = "db.heslo";
    1.47 +	public static final String NASTAVENÍ_DOMÉNA = "domena";
    1.48 +	public static final String NASTAVENÍ_LOG = "log";
    1.49 +	public static final String VÝCHOZÍ_LOG = "/tmp/eJabberd-auth.log";
    1.50 +	private static final int ANO = 1;
    1.51 +	private static final int NE = 0;
    1.52 +	private final DataInputStream in;
    1.53 +	private final DataOutputStream out;
    1.54 +	private final PrintStream err;
    1.55 +	private final String našeDoména;
    1.56 +	private final String dbUrl;
    1.57 +	private final String dbJméno;
    1.58 +	private final String dbHeslo;
    1.59 +
    1.60 +	public static void main(String[] args) throws IOException, ChybaZápisuVýsledku, ChybaČteníVstupu {
    1.61 +
    1.62 +		try (FileInputStream nastaveníFis = new FileInputStream(args[0])) {
    1.63 +
    1.64 +			Properties nastavení = new Properties();
    1.65 +			nastavení.load(nastaveníFis);
    1.66 +
    1.67 +			try (FileOutputStream err = new FileOutputStream(nastavení.getProperty(NASTAVENÍ_LOG, VÝCHOZÍ_LOG))) {
    1.68 +				EJabberdAuth a = new EJabberdAuth(System.in, System.out, err, nastavení);
    1.69 +				a.start();
    1.70 +			}
    1.71 +		}
    1.72 +	}
    1.73 +
    1.74 +	public EJabberdAuth(InputStream in, OutputStream out, OutputStream err, Properties nastavení) {
    1.75 +		this.in = new DataInputStream(in);
    1.76 +		this.out = new DataOutputStream(out);
    1.77 +		this.err = new PrintStream(err);
    1.78 +
    1.79 +		this.našeDoména = nastavení.getProperty(NASTAVENÍ_DOMÉNA);
    1.80 +		this.dbUrl = nastavení.getProperty(NASTAVENÍ_DB_URL);
    1.81 +		this.dbJméno = nastavení.getProperty(NASTAVENÍ_DB_JMÉNO);
    1.82 +		this.dbHeslo = nastavení.getProperty(NASTAVENÍ_DB_HESLO);
    1.83 +	}
    1.84 +
    1.85 +	public void start() throws ChybaZápisuVýsledku, ChybaČteníVstupu {
    1.86 +		while (true) {
    1.87 +			String text = načtiText();
    1.88 +			zpracuj(text);
    1.89 +		}
    1.90 +	}
    1.91 +
    1.92 +	private Connection getDB() throws SQLException {
    1.93 +		return DriverManager.getConnection(dbUrl, dbJméno, dbHeslo);
    1.94 +	}
    1.95 +
    1.96 +	private String načtiText() throws ChybaČteníVstupu {
    1.97 +		try {
    1.98 +			short délka = in.readShort();
    1.99 +			byte[] bajty = new byte[délka];
   1.100 +			in.read(bajty);
   1.101 +			return new String(bajty);
   1.102 +		} catch (Exception e) {
   1.103 +			throw new ChybaČteníVstupu(e);
   1.104 +		}
   1.105 +	}
   1.106 +
   1.107 +	private void zpracuj(String text) throws ChybaZápisuVýsledku {
   1.108 +
   1.109 +		String[] prvky = text.split(":");
   1.110 +
   1.111 +		final String operace;
   1.112 +		final String uživatel;
   1.113 +		final String doména;
   1.114 +		final String heslo;
   1.115 +
   1.116 +		if (prvky.length < 3) {
   1.117 +			zapišVýsledek(NE);
   1.118 +			err.println("Chybný počet parametrů: " + prvky.length);
   1.119 +		} else {
   1.120 +			operace = prvky[0];
   1.121 +			uživatel = prvky[1];
   1.122 +			doména = prvky[2];
   1.123 +			heslo = (prvky.length > 3) ? prvky[3] : null;
   1.124 +
   1.125 +			err.println(operace + ":" + uživatel + ":" + doména + (heslo == null ? "" : ":*"));
   1.126 +
   1.127 +			switch (operace) {
   1.128 +				case "auth":
   1.129 +					ověřHeslo(uživatel, doména, heslo);
   1.130 +					break;
   1.131 +				case "isuser":
   1.132 +					ověřExistenci(uživatel, doména);
   1.133 +					break;
   1.134 +				case "setpass":
   1.135 +				case "tryregister":
   1.136 +				case "removeuser":
   1.137 +				case "removeuser3":
   1.138 +				default:
   1.139 +					zapišVýsledek(NE);
   1.140 +			}
   1.141 +		}
   1.142 +	}
   1.143 +
   1.144 +	private void zapišVýsledek(int výsledek) throws ChybaZápisuVýsledku {
   1.145 +		try {
   1.146 +			err.println("výsledek: " + výsledek);
   1.147 +
   1.148 +			out.writeShort(2);
   1.149 +			out.writeShort(výsledek);
   1.150 +			out.flush();
   1.151 +		} catch (Exception e) {
   1.152 +			throw new ChybaZápisuVýsledku(e);
   1.153 +		}
   1.154 +	}
   1.155 +
   1.156 +	private void ověřHeslo(String uživatel, String doména, String heslo) throws ChybaZápisuVýsledku {
   1.157 +		if (ověřDoménu(doména)) {
   1.158 +
   1.159 +			try (Connection db = getDB()) {
   1.160 +				try (PreparedStatement ps = db.prepareStatement("SELECT over_heslo(?,?)")) {
   1.161 +					int i = 1;
   1.162 +					ps.setString(i++, uživatel);
   1.163 +					ps.setString(i++, heslo);
   1.164 +					try (ResultSet rs = ps.executeQuery()) {
   1.165 +						rs.next();
   1.166 +						int výsledek = rs.getBoolean(1) ? ANO : NE;
   1.167 +						zapišVýsledek(výsledek);
   1.168 +					}
   1.169 +				}
   1.170 +			} catch (SQLException e) {
   1.171 +				logujSQLException(e);
   1.172 +				zapišVýsledek(NE);
   1.173 +			}
   1.174 +
   1.175 +		} else {
   1.176 +			zapišVýsledek(NE);
   1.177 +		}
   1.178 +	}
   1.179 +
   1.180 +	private void ověřExistenci(String uživatel, String doména) throws ChybaZápisuVýsledku {
   1.181 +		if (ověřDoménu(doména)) {
   1.182 +
   1.183 +			try (Connection db = getDB()) {
   1.184 +				try (PreparedStatement ps = db.prepareStatement("SELECT over_existenci_uzivatele(?)")) {
   1.185 +					int i = 1;
   1.186 +					ps.setString(i++, uživatel);
   1.187 +					try (ResultSet rs = ps.executeQuery()) {
   1.188 +						rs.next();
   1.189 +						int výsledek = rs.getBoolean(1) ? ANO : NE;
   1.190 +						zapišVýsledek(výsledek);
   1.191 +					}
   1.192 +				}
   1.193 +			} catch (SQLException e) {
   1.194 +				logujSQLException(e);
   1.195 +				zapišVýsledek(NE);
   1.196 +			}
   1.197 +
   1.198 +		} else {
   1.199 +			zapišVýsledek(NE);
   1.200 +		}
   1.201 +	}
   1.202 +
   1.203 +	private boolean ověřDoménu(String doména) {
   1.204 +		return našeDoména.equalsIgnoreCase(doména);
   1.205 +	}
   1.206 +
   1.207 +	private void logujSQLException(SQLException e) {
   1.208 +		err.println("-- SQLException:");
   1.209 +		e.printStackTrace(err);
   1.210 +		err.println("-- SQLException");
   1.211 +	}
   1.212 +}