]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.enterprise/src/org/argeo/ident/IdentClient.java
Merge remote-tracking branch 'origin/master' into v2.x
[lgpl/argeo-commons.git] / org.argeo.enterprise / src / org / argeo / ident / IdentClient.java
1 package org.argeo.ident;
2
3 import java.io.BufferedReader;
4 import java.io.IOException;
5 import java.io.InputStreamReader;
6 import java.io.OutputStream;
7 import java.net.ConnectException;
8 import java.net.Socket;
9 import java.nio.charset.StandardCharsets;
10 import java.nio.file.Files;
11 import java.nio.file.Path;
12 import java.nio.file.Paths;
13 import java.util.List;
14 import java.util.StringTokenizer;
15
16 /**
17 * A simple ident client, supporting authd OpenSSL encrypted username.
18 *
19 * @see RFC 1413 https://tools.ietf.org/html/rfc1413
20 */
21 public class IdentClient {
22 public final static int DEFAULT_IDENT_PORT = 113;
23 public final static String AUTHD_PASSPHRASE_PATH = "/etc/ident.key";
24 final static String NO_USER = "NO-USER";
25
26 private final String host;
27 private final int port;
28
29 private OpenSslDecryptor openSslDecryptor = new OpenSslDecryptor();
30 private String identPassphrase = null;
31
32 public IdentClient(String host) {
33 this(host, readPassphrase(AUTHD_PASSPHRASE_PATH), DEFAULT_IDENT_PORT);
34 }
35
36 public IdentClient(String host, Path passPhrasePath) {
37 this(host, readPassphrase(passPhrasePath), DEFAULT_IDENT_PORT);
38 }
39
40 public IdentClient(String host, String identPassphrase) {
41 this(host, identPassphrase, DEFAULT_IDENT_PORT);
42 }
43
44 public IdentClient(String host, String identPassphrase, int port) {
45 this.host = host;
46 this.identPassphrase = identPassphrase;
47 this.port = port;
48 }
49
50 /** @return the username or null if none */
51 public String getUsername(int serverPort, int clientPort) {
52 String answer;
53 try (Socket socket = new Socket(host, port)) {
54 String msg = clientPort + "," + serverPort + "\n";
55 OutputStream out = socket.getOutputStream();
56 out.write(msg.getBytes(StandardCharsets.US_ASCII));
57 out.flush();
58 BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
59 answer = reader.readLine();
60 } catch (ConnectException e) {
61 System.err.println(
62 "Ident client is configured but no ident server available on " + host + " (port " + port + ")");
63 return null;
64 } catch (Exception e) {
65 throw new RuntimeException("Cannot read from ident server on " + host + " (port " + port + ")", e);
66 }
67 StringTokenizer st = new StringTokenizer(answer, " :\n");
68 String username = null;
69 while (st.hasMoreTokens())
70 username = st.nextToken();
71
72 if (username.equals(NO_USER))
73 return null;
74
75 if (identPassphrase != null && username.startsWith("[")) {
76 String encrypted = username.substring(1, username.length() - 1);
77 username = openSslDecryptor.decryptAuthd(encrypted, identPassphrase).trim();
78 }
79 // System.out.println(username);
80 return username;
81 }
82
83 public void setOpenSslDecryptor(OpenSslDecryptor openSslDecryptor) {
84 this.openSslDecryptor = openSslDecryptor;
85 }
86
87 public static String readPassphrase(String filePath) {
88 return readPassphrase(Paths.get(filePath));
89 }
90
91 /** @return the first line of the file. */
92 public static String readPassphrase(Path path) {
93 if (!isPathAvailable(path))
94 return null;
95 List<String> lines;
96 try {
97 lines = Files.readAllLines(path);
98 } catch (IOException e) {
99 throw new IllegalStateException("Cannot read " + path, e);
100 }
101 if (lines.size() == 0)
102 return null;
103 String passphrase = lines.get(0);
104 return passphrase;
105 }
106
107 public static boolean isDefaultAuthdPassphraseFileAvailable() {
108 return isPathAvailable(Paths.get(AUTHD_PASSPHRASE_PATH));
109 }
110
111 public static boolean isPathAvailable(Path path) {
112 if (!Files.exists(path))
113 return false;
114 if (!Files.isReadable(path))
115 return false;
116 return true;
117 }
118
119 public static void main(String[] args) {
120 IdentClient identClient = new IdentClient("127.0.0.1", "changeit");
121 String username = identClient.getUsername(7070, 55958);
122 System.out.println(username);
123 }
124 }