forked from pquiring/javaforce
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPOP3.java
More file actions
268 lines (241 loc) · 6.69 KB
/
Copy pathPOP3.java
File metadata and controls
268 lines (241 loc) · 6.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
package javaforce;
import java.io.*;
import java.net.*;
import java.util.*;
/**
* POP3 client class.
*/
public class POP3 {
private Socket s;
private InputStream is;
private OutputStream os;
private BufferedReader br;
private String host;
public static boolean debug = false;
public static boolean debug_log = false;
public static int log;
/**
* Holds the response strings from the last executed command
*/
public String response;
public static final int PORT = 25; //default port
public static final int TLSPORT = 587; //default SSL port (explicit)
public static final int SSLPORT = 465; //default SSL port (implicit)
/** Connects to an insecure POP3 server.
* @param host = POP3 server
* @param port = port to connect (default = 25 or 587)
*/
public boolean connect(String host, int port) throws Exception {
s = new Socket(host, port);
is = s.getInputStream();
br = new BufferedReader(new InputStreamReader(is));
os = s.getOutputStream();
this.host = host;
getResponse();
if (response.startsWith("+OK")) {
return true;
}
disconnect(); //not valid POP3 site
return false;
}
/** Connects to a secure POP3 server.
* @param host = POP3 server
* @param port = port to connect (default = 465)
*/
public boolean connectSSL(String host, int port) throws Exception {
s = JF.connectSSL(s, KeyMgmt.getDefaultClient());
is = s.getInputStream();
br = new BufferedReader(new InputStreamReader(is));
os = s.getOutputStream();
this.host = host;
getResponse();
if (response.startsWith("+OK")) {
return true;
}
disconnect(); //not valid POP3 site
return false;
}
/** Disconnect from POP3 Server. */
public void disconnect() throws Exception {
if (s != null) {
s.close();
}
s = null;
is = null;
os = null;
br = null;
}
/** Set debug logging state. */
public static void setLogging(boolean state) {
debug_log = state;
}
public static void setLog(int id) {
log = id;
}
/** Sends HELO command. */
public boolean login() throws Exception {
cmd("HELO " + host);
getResponse();
if (!response.startsWith("+OK")) {
return false;
}
return true;
}
public static final String AUTH_LOGIN = "LOGIN"; //legacy
public static final String AUTH_APOP = "APOP";
/** Authenticates with POP3 Server using APOP.
* @param user = username
* @param pass = password
* @param type = AUTH_LOGIN or AUTH_APOP
*/
public boolean auth(String user, String pass, String type) throws Exception {
switch (type) {
case AUTH_LOGIN: return user_pass(user, pass);
case AUTH_APOP: return apop(user, pass);
default: JFLog.log(log, "POP3:Unknown auth type:" + type);
}
return false;
}
private boolean user_pass(String user, String pass) throws Exception {
cmd("USER " + user);
getResponse();
if (!response.startsWith("+OK")) {
return false;
}
cmd("PASS " + pass);
getResponse();
if (!response.startsWith("+OK")) {
return false;
}
return true;
}
private boolean apop(String user, String pass) throws Exception {
MD5 md5 = new MD5();
md5.add(pass);
String pass_md5 = md5.toString();
cmd("APOP " + user + " " + pass_md5);
getResponse();
if (!response.startsWith("+OK")) {
return false;
}
return true;
}
/** Authenticates with POP3 Server using AUTH_LOGIN type.
* @param user = username
* @param pass = password
*/
public boolean auth(String user, String pass) throws Exception {
return auth(user, pass, AUTH_LOGIN);
}
/** Send QUIT command. */
public void logout() throws Exception {
cmd("quit");
getResponse(); //should be "+OK" but ignored
}
/** Send any command to server. */
public void cmd(String cmd) throws Exception {
if ((s == null) || (s.isClosed())) {
throw new Exception("not connected");
}
if (debug_log || debug) {
if (cmd.startsWith("pass ")) {
JFLog.log(log, "pass ****");
} else {
JFLog.log(log, cmd);
}
}
cmd += "\r\n";
os.write(cmd.getBytes());
}
/** Secures connection using STARTTLS command. */
public void starttls() throws Exception {
cmd("STARTTLS");
getResponse();
if (!response.startsWith("+OK")) {
throw new Exception("STARTTLS failed!");
}
s = JF.connectSSL(s, KeyMgmt.getDefaultClient());
is = s.getInputStream();
os = s.getOutputStream();
}
public static class Message {
public int idx;
public long size;
}
private static final int bufsiz = 1500 - 20 - 20;
/** List messages available. */
public Message[] list() throws Exception {
cmd("LIST");
getResponse();
if (!response.startsWith("+OK")) {
throw new Exception("LIST failed!");
}
ArrayList<Message> list = new ArrayList<>();
while (true) {
String ln = br.readLine(); //# ###
if (ln.equals(".")) break;
String[] p = ln.split(" ", 2);
int idx = Integer.valueOf(p[0]);
int size = Integer.valueOf(p[1]);
Message msg = new Message();
msg.idx = idx;
msg.size = size;
list.add(msg);
}
return list.toArray(new Message[0]);
}
/** Get message */
public byte[] get(int idx) throws Exception {
cmd("RETR " + idx);
getResponse();
if (!response.startsWith("+OK")) {
throw new Exception("RETR failed!");
}
String[] p = response.split(" ", 3);
int length = Integer.valueOf(p[1]);
StringBuilder sb = new StringBuilder();
int total = 0;
while (total < length) {
String ln = br.readLine();
sb.append(ln);
total += ln.length();
sb.append("\r\n");
total += 2;
}
getResponse(); //"."
return sb.toString().getBytes();
}
/** Get message */
public void get(int idx, OutputStream os) throws Exception {
cmd("RETR " + idx);
getResponse();
if (!response.startsWith("+OK")) {
throw new Exception("RETR failed!");
}
String[] p = response.split(" ", 3);
int length = Integer.valueOf(p[1]);
int total = 0;
while (total < length) {
String ln = br.readLine();
os.write(ln.getBytes());
total += ln.length();
os.write("\r\n".getBytes());
total += 2;
}
getResponse(); //"."
}
/** Delete message on server. */
public boolean delete(int idx) throws Exception {
cmd("DELE " + idx);
getResponse();
if (!response.startsWith("+OK")) {
throw new Exception("DELE failed!");
}
return true;
}
private void getResponse() throws Exception {
if (debug) JFLog.log(log, "POP3:reading response...");
response = br.readLine();
if (debug) JFLog.log(log, "POP3:response=" + response);
}
}