java/eJabberd-auth/src/cz/frantovo/ejabberd/auth/EJabberdAuth.java
author František Kučera <franta-hg@frantovo.cz>
Mon, 10 Mar 2014 12:20:26 +0100
changeset 26 5d23fa316c1c
permissions -rw-r--r--
eJabberd-auth: ověřování uživatelů proti SQL databázi
franta-hg@26
     1
/**
franta-hg@26
     2
 * SQL-DK
franta-hg@26
     3
 * Copyright © 2014 František Kučera (frantovo.cz)
franta-hg@26
     4
 *
franta-hg@26
     5
 * This program is free software: you can redistribute it and/or modify
franta-hg@26
     6
 * it under the terms of the GNU General Public License as published by
franta-hg@26
     7
 * the Free Software Foundation, either version 3 of the License, or
franta-hg@26
     8
 * (at your option) any later version.
franta-hg@26
     9
 *
franta-hg@26
    10
 * This program is distributed in the hope that it will be useful,
franta-hg@26
    11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
franta-hg@26
    12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
franta-hg@26
    13
 * GNU General Public License for more details.
franta-hg@26
    14
 *
franta-hg@26
    15
 * You should have received a copy of the GNU General Public License
franta-hg@26
    16
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
franta-hg@26
    17
 */
franta-hg@26
    18
package cz.frantovo.ejabberd.auth;
franta-hg@26
    19
franta-hg@26
    20
import java.io.DataInputStream;
franta-hg@26
    21
import java.io.DataOutputStream;
franta-hg@26
    22
import java.io.FileInputStream;
franta-hg@26
    23
import java.io.FileOutputStream;
franta-hg@26
    24
import java.io.IOException;
franta-hg@26
    25
import java.io.InputStream;
franta-hg@26
    26
import java.io.OutputStream;
franta-hg@26
    27
import java.io.PrintStream;
franta-hg@26
    28
import java.sql.Connection;
franta-hg@26
    29
import java.sql.DriverManager;
franta-hg@26
    30
import java.sql.PreparedStatement;
franta-hg@26
    31
import java.sql.ResultSet;
franta-hg@26
    32
import java.sql.SQLException;
franta-hg@26
    33
import java.util.Properties;
franta-hg@26
    34
franta-hg@26
    35
/**
franta-hg@26
    36
 *
franta-hg@26
    37
 * @author Ing. František Kučera (frantovo.cz)
franta-hg@26
    38
 */
franta-hg@26
    39
public class EJabberdAuth {
franta-hg@26
    40
franta-hg@26
    41
	public static final String NASTAVENÍ_DB_URL = "db.url";
franta-hg@26
    42
	public static final String NASTAVENÍ_DB_JMÉNO = "db.jmeno";
franta-hg@26
    43
	public static final String NASTAVENÍ_DB_HESLO = "db.heslo";
franta-hg@26
    44
	public static final String NASTAVENÍ_DOMÉNA = "domena";
franta-hg@26
    45
	public static final String NASTAVENÍ_LOG = "log";
franta-hg@26
    46
	public static final String VÝCHOZÍ_LOG = "/tmp/eJabberd-auth.log";
franta-hg@26
    47
	private static final int ANO = 1;
franta-hg@26
    48
	private static final int NE = 0;
franta-hg@26
    49
	private final DataInputStream in;
franta-hg@26
    50
	private final DataOutputStream out;
franta-hg@26
    51
	private final PrintStream err;
franta-hg@26
    52
	private final String našeDoména;
franta-hg@26
    53
	private final String dbUrl;
franta-hg@26
    54
	private final String dbJméno;
franta-hg@26
    55
	private final String dbHeslo;
franta-hg@26
    56
franta-hg@26
    57
	public static void main(String[] args) throws IOException, ChybaZápisuVýsledku, ChybaČteníVstupu {
franta-hg@26
    58
franta-hg@26
    59
		try (FileInputStream nastaveníFis = new FileInputStream(args[0])) {
franta-hg@26
    60
franta-hg@26
    61
			Properties nastavení = new Properties();
franta-hg@26
    62
			nastavení.load(nastaveníFis);
franta-hg@26
    63
franta-hg@26
    64
			try (FileOutputStream err = new FileOutputStream(nastavení.getProperty(NASTAVENÍ_LOG, VÝCHOZÍ_LOG))) {
franta-hg@26
    65
				EJabberdAuth a = new EJabberdAuth(System.in, System.out, err, nastavení);
franta-hg@26
    66
				a.start();
franta-hg@26
    67
			}
franta-hg@26
    68
		}
franta-hg@26
    69
	}
franta-hg@26
    70
franta-hg@26
    71
	public EJabberdAuth(InputStream in, OutputStream out, OutputStream err, Properties nastavení) {
franta-hg@26
    72
		this.in = new DataInputStream(in);
franta-hg@26
    73
		this.out = new DataOutputStream(out);
franta-hg@26
    74
		this.err = new PrintStream(err);
franta-hg@26
    75
franta-hg@26
    76
		this.našeDoména = nastavení.getProperty(NASTAVENÍ_DOMÉNA);
franta-hg@26
    77
		this.dbUrl = nastavení.getProperty(NASTAVENÍ_DB_URL);
franta-hg@26
    78
		this.dbJméno = nastavení.getProperty(NASTAVENÍ_DB_JMÉNO);
franta-hg@26
    79
		this.dbHeslo = nastavení.getProperty(NASTAVENÍ_DB_HESLO);
franta-hg@26
    80
	}
franta-hg@26
    81
franta-hg@26
    82
	public void start() throws ChybaZápisuVýsledku, ChybaČteníVstupu {
franta-hg@26
    83
		while (true) {
franta-hg@26
    84
			String text = načtiText();
franta-hg@26
    85
			zpracuj(text);
franta-hg@26
    86
		}
franta-hg@26
    87
	}
franta-hg@26
    88
franta-hg@26
    89
	private Connection getDB() throws SQLException {
franta-hg@26
    90
		return DriverManager.getConnection(dbUrl, dbJméno, dbHeslo);
franta-hg@26
    91
	}
franta-hg@26
    92
franta-hg@26
    93
	private String načtiText() throws ChybaČteníVstupu {
franta-hg@26
    94
		try {
franta-hg@26
    95
			short délka = in.readShort();
franta-hg@26
    96
			byte[] bajty = new byte[délka];
franta-hg@26
    97
			in.read(bajty);
franta-hg@26
    98
			return new String(bajty);
franta-hg@26
    99
		} catch (Exception e) {
franta-hg@26
   100
			throw new ChybaČteníVstupu(e);
franta-hg@26
   101
		}
franta-hg@26
   102
	}
franta-hg@26
   103
franta-hg@26
   104
	private void zpracuj(String text) throws ChybaZápisuVýsledku {
franta-hg@26
   105
franta-hg@26
   106
		String[] prvky = text.split(":");
franta-hg@26
   107
franta-hg@26
   108
		final String operace;
franta-hg@26
   109
		final String uživatel;
franta-hg@26
   110
		final String doména;
franta-hg@26
   111
		final String heslo;
franta-hg@26
   112
franta-hg@26
   113
		if (prvky.length < 3) {
franta-hg@26
   114
			zapišVýsledek(NE);
franta-hg@26
   115
			err.println("Chybný počet parametrů: " + prvky.length);
franta-hg@26
   116
		} else {
franta-hg@26
   117
			operace = prvky[0];
franta-hg@26
   118
			uživatel = prvky[1];
franta-hg@26
   119
			doména = prvky[2];
franta-hg@26
   120
			heslo = (prvky.length > 3) ? prvky[3] : null;
franta-hg@26
   121
franta-hg@26
   122
			err.println(operace + ":" + uživatel + ":" + doména + (heslo == null ? "" : ":*"));
franta-hg@26
   123
franta-hg@26
   124
			switch (operace) {
franta-hg@26
   125
				case "auth":
franta-hg@26
   126
					ověřHeslo(uživatel, doména, heslo);
franta-hg@26
   127
					break;
franta-hg@26
   128
				case "isuser":
franta-hg@26
   129
					ověřExistenci(uživatel, doména);
franta-hg@26
   130
					break;
franta-hg@26
   131
				case "setpass":
franta-hg@26
   132
				case "tryregister":
franta-hg@26
   133
				case "removeuser":
franta-hg@26
   134
				case "removeuser3":
franta-hg@26
   135
				default:
franta-hg@26
   136
					zapišVýsledek(NE);
franta-hg@26
   137
			}
franta-hg@26
   138
		}
franta-hg@26
   139
	}
franta-hg@26
   140
franta-hg@26
   141
	private void zapišVýsledek(int výsledek) throws ChybaZápisuVýsledku {
franta-hg@26
   142
		try {
franta-hg@26
   143
			err.println("výsledek: " + výsledek);
franta-hg@26
   144
franta-hg@26
   145
			out.writeShort(2);
franta-hg@26
   146
			out.writeShort(výsledek);
franta-hg@26
   147
			out.flush();
franta-hg@26
   148
		} catch (Exception e) {
franta-hg@26
   149
			throw new ChybaZápisuVýsledku(e);
franta-hg@26
   150
		}
franta-hg@26
   151
	}
franta-hg@26
   152
franta-hg@26
   153
	private void ověřHeslo(String uživatel, String doména, String heslo) throws ChybaZápisuVýsledku {
franta-hg@26
   154
		if (ověřDoménu(doména)) {
franta-hg@26
   155
franta-hg@26
   156
			try (Connection db = getDB()) {
franta-hg@26
   157
				try (PreparedStatement ps = db.prepareStatement("SELECT over_heslo(?,?)")) {
franta-hg@26
   158
					int i = 1;
franta-hg@26
   159
					ps.setString(i++, uživatel);
franta-hg@26
   160
					ps.setString(i++, heslo);
franta-hg@26
   161
					try (ResultSet rs = ps.executeQuery()) {
franta-hg@26
   162
						rs.next();
franta-hg@26
   163
						int výsledek = rs.getBoolean(1) ? ANO : NE;
franta-hg@26
   164
						zapišVýsledek(výsledek);
franta-hg@26
   165
					}
franta-hg@26
   166
				}
franta-hg@26
   167
			} catch (SQLException e) {
franta-hg@26
   168
				logujSQLException(e);
franta-hg@26
   169
				zapišVýsledek(NE);
franta-hg@26
   170
			}
franta-hg@26
   171
franta-hg@26
   172
		} else {
franta-hg@26
   173
			zapišVýsledek(NE);
franta-hg@26
   174
		}
franta-hg@26
   175
	}
franta-hg@26
   176
franta-hg@26
   177
	private void ověřExistenci(String uživatel, String doména) throws ChybaZápisuVýsledku {
franta-hg@26
   178
		if (ověřDoménu(doména)) {
franta-hg@26
   179
franta-hg@26
   180
			try (Connection db = getDB()) {
franta-hg@26
   181
				try (PreparedStatement ps = db.prepareStatement("SELECT over_existenci_uzivatele(?)")) {
franta-hg@26
   182
					int i = 1;
franta-hg@26
   183
					ps.setString(i++, uživatel);
franta-hg@26
   184
					try (ResultSet rs = ps.executeQuery()) {
franta-hg@26
   185
						rs.next();
franta-hg@26
   186
						int výsledek = rs.getBoolean(1) ? ANO : NE;
franta-hg@26
   187
						zapišVýsledek(výsledek);
franta-hg@26
   188
					}
franta-hg@26
   189
				}
franta-hg@26
   190
			} catch (SQLException e) {
franta-hg@26
   191
				logujSQLException(e);
franta-hg@26
   192
				zapišVýsledek(NE);
franta-hg@26
   193
			}
franta-hg@26
   194
franta-hg@26
   195
		} else {
franta-hg@26
   196
			zapišVýsledek(NE);
franta-hg@26
   197
		}
franta-hg@26
   198
	}
franta-hg@26
   199
franta-hg@26
   200
	private boolean ověřDoménu(String doména) {
franta-hg@26
   201
		return našeDoména.equalsIgnoreCase(doména);
franta-hg@26
   202
	}
franta-hg@26
   203
franta-hg@26
   204
	private void logujSQLException(SQLException e) {
franta-hg@26
   205
		err.println("-- SQLException:");
franta-hg@26
   206
		e.printStackTrace(err);
franta-hg@26
   207
		err.println("-- SQLException");
franta-hg@26
   208
	}
franta-hg@26
   209
}