1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package davmail;
20
21 import davmail.caldav.CaldavServer;
22 import davmail.exception.DavMailException;
23 import davmail.exchange.ExchangeSessionFactory;
24 import davmail.exchange.auth.ExchangeAuthenticator;
25 import davmail.exchange.auth.KerberosCheck;
26 import davmail.http.HttpClientAdapter;
27 import davmail.http.request.GetRequest;
28 import davmail.http.SelfSignedCertificateGenerator;
29 import davmail.imap.ImapServer;
30 import davmail.ldap.LdapServer;
31 import davmail.pop.PopServer;
32 import davmail.smtp.SmtpServer;
33 import davmail.ui.tray.DavGatewayTray;
34 import org.apache.log4j.Logger;
35
36 import java.awt.*;
37 import java.io.IOException;
38 import java.lang.reflect.InvocationTargetException;
39 import java.util.ArrayList;
40
41
42
43
44 public final class DavGateway {
45 private static final Logger LOGGER = Logger.getLogger(DavGateway.class);
46 private static final String HTTP_DAVMAIL_SOURCEFORGE_NET_VERSION_TXT = "https://davmail.sourceforge.net/version.txt";
47
48 private static final Object LOCK = new Object();
49 private static boolean shutdown = false;
50
51 private DavGateway() {
52 }
53
54 private static final ArrayList<AbstractServer> SERVER_LIST = new ArrayList<>();
55
56
57
58
59
60
61 public static void main(String[] args) {
62 boolean noTray = false;
63 boolean tray = false;
64 boolean server = false;
65 boolean token = false;
66 boolean kerberos = false;
67 boolean generateCert = false;
68
69
70 String configFilePath = Settings.getConfigFilePath();
71 for (int i = 0; i < args.length; i++) {
72 String arg = args[i];
73 if (arg.startsWith("-")) {
74 switch (arg) {
75 case "-notray":
76 noTray = true;
77 break;
78 case "-tray":
79 tray = true;
80 break;
81 case "-server":
82 server = true;
83 break;
84 case "-token":
85 token = true;
86 break;
87 case "-kerberos":
88 kerberos = true;
89 break;
90 case "-generateCert":
91 generateCert = true;
92 break;
93 default:
94 LOGGER.warn("Unknown option: " + arg);
95 }
96 } else {
97 configFilePath = arg;
98 }
99 }
100
101 Settings.setConfigFilePath(configFilePath);
102 Settings.load();
103
104
105 if (tray) {
106 Settings.setProperty("davmail.enableTray", "true");
107 }
108 if (noTray) {
109 Settings.setProperty("davmail.enableTray", "false");
110 }
111
112 if (generateCert) {
113 SelfSignedCertificateGenerator.generate(configFilePath);
114 System.exit(0);
115 } else if (token) {
116 try {
117 ExchangeAuthenticator authenticator = (ExchangeAuthenticator) Class.forName("davmail.exchange.auth.O365InteractiveAuthenticator")
118 .getDeclaredConstructor().newInstance();
119 authenticator.setUsername("");
120 authenticator.authenticate();
121 System.out.println(authenticator.getToken().getRefreshToken());
122 } catch (IOException | ClassNotFoundException | NoSuchMethodException | InstantiationException |
123 IllegalAccessException | InvocationTargetException e) {
124 System.err.println(e + " " + e.getMessage());
125 }
126
127 System.exit(0);
128 } else if (kerberos) {
129 KerberosCheck kerberosCheck = new KerberosCheck();
130 if (kerberosCheck.checkKerberosAuthentication()) {
131 System.out.println("Kerberos authentication successful");
132 } else {
133 System.out.println("Kerberos authentication failed");
134 }
135 System.exit(0);
136 } else {
137
138 if (GraphicsEnvironment.isHeadless()) {
139
140 LOGGER.debug("Headless mode, do not create GUI");
141 server = true;
142 }
143 if (server) {
144 Settings.setProperty("davmail.server", "true");
145 Settings.updateLoggingConfig();
146 }
147
148
149 if (Settings.getBooleanProperty("davmail.server")) {
150 LOGGER.debug("Start DavMail headless " + Settings.getProperty("davmail.mode") + " " + Settings.getProperty("davmail.authentication"));
151 } else {
152 LOGGER.debug("Start DavMail with GUI " + Settings.getProperty("davmail.mode") + " " + Settings.getProperty("davmail.authentication"));
153 DavGatewayTray.init();
154 }
155
156 start();
157
158
159 if (Settings.getBooleanProperty("davmail.server")) {
160 Runtime.getRuntime().addShutdownHook(new Thread("Shutdown") {
161 @Override
162 public void run() {
163 shutdown = true;
164 DavGatewayTray.debug(new BundleMessage("LOG_GATEWAY_INTERRUPTED"));
165 DavGateway.stop();
166 synchronized (LOCK) {
167 LOCK.notifyAll();
168 }
169 }
170 });
171
172 synchronized (LOCK) {
173 try {
174 while (!shutdown) {
175 LOCK.wait();
176 }
177 } catch (InterruptedException e) {
178 DavGatewayTray.debug(new BundleMessage("LOG_GATEWAY_INTERRUPTED"));
179 Thread.currentThread().interrupt();
180 }
181 }
182
183 }
184 }
185 }
186
187
188
189
190 public static void start() {
191 SERVER_LIST.clear();
192
193 int smtpPort = Settings.getIntProperty("davmail.smtpPort");
194 if (smtpPort != 0) {
195 SERVER_LIST.add(new SmtpServer(smtpPort));
196 }
197 int popPort = Settings.getIntProperty("davmail.popPort");
198 if (popPort != 0) {
199 SERVER_LIST.add(new PopServer(popPort));
200 }
201 int imapPort = Settings.getIntProperty("davmail.imapPort");
202 if (imapPort != 0) {
203 SERVER_LIST.add(new ImapServer(imapPort));
204 }
205 int caldavPort = Settings.getIntProperty("davmail.caldavPort");
206 if (caldavPort != 0) {
207 SERVER_LIST.add(new CaldavServer(caldavPort));
208 }
209 int ldapPort = Settings.getIntProperty("davmail.ldapPort");
210 if (ldapPort != 0) {
211 SERVER_LIST.add(new LdapServer(ldapPort));
212 }
213
214 BundleMessage.BundleMessageList messages = new BundleMessage.BundleMessageList();
215 BundleMessage.BundleMessageList errorMessages = new BundleMessage.BundleMessageList();
216 for (AbstractServer server : SERVER_LIST) {
217 try {
218 server.bind();
219 server.start();
220 messages.add(new BundleMessage("LOG_PROTOCOL_PORT", server.getProtocolName(), server.getPort()));
221 } catch (DavMailException e) {
222 errorMessages.add(e.getBundleMessage());
223 }
224 }
225
226 final String currentVersion = getCurrentVersion();
227 boolean showStartupBanner = Settings.getBooleanProperty("davmail.showStartupBanner", true);
228 if (showStartupBanner) {
229 DavGatewayTray.info(new BundleMessage("LOG_DAVMAIL_GATEWAY_LISTENING", currentVersion, messages));
230 }
231 if (!errorMessages.isEmpty()) {
232 DavGatewayTray.error(new BundleMessage("LOG_MESSAGE", errorMessages));
233 if (Settings.getBooleanProperty("davmail.exitOnBindFailed", false)) {
234 System.exit(1);
235 }
236 }
237
238
239 new Thread("CheckRelease") {
240 @Override
241 public void run() {
242 String releasedVersion = getReleasedVersion();
243 if (!currentVersion.isEmpty() && releasedVersion != null && currentVersion.compareTo(releasedVersion) < 0) {
244 DavGatewayTray.info(new BundleMessage("LOG_NEW_VERSION_AVAILABLE", releasedVersion));
245 }
246
247 }
248 }.start();
249
250 }
251
252
253
254
255 public static void stop() {
256 DavGateway.stopServers();
257
258 ExchangeSessionFactory.shutdown();
259 DavGatewayTray.info(new BundleMessage("LOG_GATEWAY_STOP"));
260 DavGatewayTray.dispose();
261 }
262
263
264
265
266 public static void restart() {
267 DavGateway.stopServers();
268
269 ExchangeSessionFactory.shutdown();
270 DavGateway.start();
271 }
272
273 private static void stopServers() {
274 for (AbstractServer server : SERVER_LIST) {
275 server.close();
276 try {
277 server.join();
278 } catch (InterruptedException e) {
279 DavGatewayTray.warn(new BundleMessage("LOG_EXCEPTION_WAITING_SERVER_THREAD_DIE"), e);
280 Thread.currentThread().interrupt();
281 }
282 }
283 }
284
285
286
287
288
289
290 public static String getCurrentVersion() {
291 Package davmailPackage = DavGateway.class.getPackage();
292 String currentVersion = davmailPackage.getImplementationVersion();
293 if (currentVersion == null) {
294 currentVersion = "";
295 }
296 return currentVersion;
297 }
298
299
300
301
302
303
304 public static String getReleasedVersion() {
305 String version = null;
306 if (!Settings.getBooleanProperty("davmail.disableUpdateCheck")) {
307 try (HttpClientAdapter httpClientAdapter = new HttpClientAdapter(HTTP_DAVMAIL_SOURCEFORGE_NET_VERSION_TXT)) {
308 GetRequest getRequest = new GetRequest(HTTP_DAVMAIL_SOURCEFORGE_NET_VERSION_TXT);
309 getRequest.setHeader("User-Agent", "curl/8.21.0");
310 getRequest = httpClientAdapter.executeFollowRedirect(getRequest);
311 version = getRequest.getResponseBodyAsString();
312 LOGGER.debug("DavMail released version: " + version);
313 } catch (IOException e) {
314 DavGatewayTray.debug(new BundleMessage("LOG_UNABLE_TO_GET_RELEASED_VERSION"));
315 }
316 }
317 return version;
318 }
319 }