2259 |
28 Feb 14 |
nicklas |
1 |
package net.sf.basedb.yubikey; |
2259 |
28 Feb 14 |
nicklas |
2 |
|
2259 |
28 Feb 14 |
nicklas |
3 |
import java.io.IOException; |
2259 |
28 Feb 14 |
nicklas |
4 |
|
2259 |
28 Feb 14 |
nicklas |
5 |
import javax.servlet.ServletException; |
2259 |
28 Feb 14 |
nicklas |
6 |
import javax.servlet.http.HttpServlet; |
2259 |
28 Feb 14 |
nicklas |
7 |
import javax.servlet.http.HttpServletRequest; |
2259 |
28 Feb 14 |
nicklas |
8 |
import javax.servlet.http.HttpServletResponse; |
2259 |
28 Feb 14 |
nicklas |
9 |
|
2259 |
28 Feb 14 |
nicklas |
10 |
import org.json.simple.JSONObject; |
2259 |
28 Feb 14 |
nicklas |
11 |
|
3991 |
10 Jun 16 |
nicklas |
12 |
import com.yubico.client.v2.ResponseStatus; |
3991 |
10 Jun 16 |
nicklas |
13 |
import com.yubico.client.v2.VerificationResponse; |
2259 |
28 Feb 14 |
nicklas |
14 |
import com.yubico.client.v2.YubicoClient; |
2259 |
28 Feb 14 |
nicklas |
15 |
|
2259 |
28 Feb 14 |
nicklas |
16 |
import net.sf.basedb.core.Application; |
2259 |
28 Feb 14 |
nicklas |
17 |
import net.sf.basedb.core.SessionControl; |
2259 |
28 Feb 14 |
nicklas |
18 |
import net.sf.basedb.util.error.ThrowableUtil; |
2259 |
28 Feb 14 |
nicklas |
19 |
|
2259 |
28 Feb 14 |
nicklas |
20 |
|
2259 |
28 Feb 14 |
nicklas |
21 |
/** |
2259 |
28 Feb 14 |
nicklas |
Servlet class for performing YubiKey-related tasks |
2259 |
28 Feb 14 |
nicklas |
for the web interface. |
2259 |
28 Feb 14 |
nicklas |
24 |
|
2259 |
28 Feb 14 |
nicklas |
@author nicklas |
2259 |
28 Feb 14 |
nicklas |
@since 1.0 |
2259 |
28 Feb 14 |
nicklas |
27 |
*/ |
2259 |
28 Feb 14 |
nicklas |
28 |
public class YubiKeyServlet |
2259 |
28 Feb 14 |
nicklas |
29 |
extends HttpServlet |
2259 |
28 Feb 14 |
nicklas |
30 |
{ |
2259 |
28 Feb 14 |
nicklas |
31 |
|
2259 |
28 Feb 14 |
nicklas |
32 |
|
2259 |
28 Feb 14 |
nicklas |
33 |
private static final long serialVersionUID = 5289634293839942481L; |
2259 |
28 Feb 14 |
nicklas |
34 |
|
2259 |
28 Feb 14 |
nicklas |
35 |
public YubiKeyServlet() |
2259 |
28 Feb 14 |
nicklas |
36 |
{} |
2259 |
28 Feb 14 |
nicklas |
37 |
|
2259 |
28 Feb 14 |
nicklas |
38 |
@Override |
2259 |
28 Feb 14 |
nicklas |
39 |
protected void doGet(HttpServletRequest req, HttpServletResponse resp) |
2259 |
28 Feb 14 |
nicklas |
40 |
throws ServletException, IOException |
2259 |
28 Feb 14 |
nicklas |
41 |
{ |
2259 |
28 Feb 14 |
nicklas |
42 |
|
2259 |
28 Feb 14 |
nicklas |
43 |
final String ID = req.getParameter("ID"); |
2259 |
28 Feb 14 |
nicklas |
44 |
final String cmd = req.getParameter("cmd"); |
2259 |
28 Feb 14 |
nicklas |
45 |
|
2259 |
28 Feb 14 |
nicklas |
46 |
resp.setContentType("application/json"); |
2259 |
28 Feb 14 |
nicklas |
47 |
resp.setCharacterEncoding("UTF-8"); |
2259 |
28 Feb 14 |
nicklas |
48 |
|
2259 |
28 Feb 14 |
nicklas |
49 |
JSONObject json = new JSONObject(); |
2259 |
28 Feb 14 |
nicklas |
50 |
json.put("status", "ok"); |
2259 |
28 Feb 14 |
nicklas |
51 |
|
2259 |
28 Feb 14 |
nicklas |
52 |
try |
2259 |
28 Feb 14 |
nicklas |
53 |
{ |
3990 |
10 Jun 16 |
nicklas |
54 |
final SessionControl sc = Application.getSessionControl(ID, "net.sf.basedb.clients.web", req.getRemoteAddr(), true); |
2259 |
28 Feb 14 |
nicklas |
55 |
|
2259 |
28 Feb 14 |
nicklas |
56 |
if ("Verify".equals(cmd)) |
2259 |
28 Feb 14 |
nicklas |
57 |
{ |
2259 |
28 Feb 14 |
nicklas |
// Verify a YubiKey one-time-password |
2259 |
28 Feb 14 |
nicklas |
59 |
String otp = req.getParameter("otp"); |
2259 |
28 Feb 14 |
nicklas |
60 |
|
2259 |
28 Feb 14 |
nicklas |
61 |
YubicoClient client = YubiKey.getYubicoClient(); |
3991 |
10 Jun 16 |
nicklas |
62 |
VerificationResponse response = client.verify(otp); |
2259 |
28 Feb 14 |
nicklas |
63 |
|
3991 |
10 Jun 16 |
nicklas |
64 |
ResponseStatus status = response.getStatus(); |
3991 |
10 Jun 16 |
nicklas |
65 |
if (!response.isOk()) |
2259 |
28 Feb 14 |
nicklas |
66 |
{ |
2259 |
28 Feb 14 |
nicklas |
67 |
String msg = "Invalid YubiKey"; |
3991 |
10 Jun 16 |
nicklas |
68 |
if (status == ResponseStatus.BAD_OTP) |
2259 |
28 Feb 14 |
nicklas |
69 |
{ |
2259 |
28 Feb 14 |
nicklas |
70 |
msg = "Invalid one-time-password format"; |
2259 |
28 Feb 14 |
nicklas |
71 |
} |
3991 |
10 Jun 16 |
nicklas |
72 |
else if (status == ResponseStatus.REPLAYED_OTP) |
2259 |
28 Feb 14 |
nicklas |
73 |
{ |
2259 |
28 Feb 14 |
nicklas |
74 |
msg = "One-time-password has already been used"; |
2259 |
28 Feb 14 |
nicklas |
75 |
} |
2259 |
28 Feb 14 |
nicklas |
76 |
throw new RuntimeException(msg + " (" + status + ")"); |
2259 |
28 Feb 14 |
nicklas |
77 |
} |
2259 |
28 Feb 14 |
nicklas |
78 |
|
2259 |
28 Feb 14 |
nicklas |
79 |
json.put("publicId", response.getPublicId()); |
2259 |
28 Feb 14 |
nicklas |
80 |
} |
2259 |
28 Feb 14 |
nicklas |
81 |
} |
2259 |
28 Feb 14 |
nicklas |
82 |
catch (Throwable t) |
2259 |
28 Feb 14 |
nicklas |
83 |
{ |
2259 |
28 Feb 14 |
nicklas |
84 |
t.printStackTrace(); |
2259 |
28 Feb 14 |
nicklas |
85 |
json.clear(); |
2259 |
28 Feb 14 |
nicklas |
86 |
json.put("status", "error"); |
2259 |
28 Feb 14 |
nicklas |
87 |
json.put("message", t.getMessage()); |
2259 |
28 Feb 14 |
nicklas |
88 |
json.put("stacktrace", ThrowableUtil.stackTraceToString(t)); |
2259 |
28 Feb 14 |
nicklas |
89 |
} |
2259 |
28 Feb 14 |
nicklas |
90 |
finally |
2259 |
28 Feb 14 |
nicklas |
91 |
{ |
2259 |
28 Feb 14 |
nicklas |
92 |
json.writeJSONString(resp.getWriter()); |
2259 |
28 Feb 14 |
nicklas |
93 |
} |
2259 |
28 Feb 14 |
nicklas |
94 |
} |
2259 |
28 Feb 14 |
nicklas |
95 |
|
2259 |
28 Feb 14 |
nicklas |
96 |
|
2259 |
28 Feb 14 |
nicklas |
97 |
|
2259 |
28 Feb 14 |
nicklas |
98 |
} |