1 package com.atlassian.seraph.cookie;
2
3 import com.atlassian.seraph.config.SecurityConfigFactory;
4 import com.atlassian.seraph.util.CookieUtils;
5 import com.atlassian.seraph.util.EncryptionUtils;
6 import org.apache.log4j.Logger;
7
8 import java.net.URLEncoder;
9 import java.net.URLDecoder;
10 import java.io.UnsupportedEncodingException;
11
12
13
14
15 public class EncryptedCookieEncoder implements CookieEncoder
16 {
17 private static final Logger LOG = Logger.getLogger(EncryptedCookieEncoder.class);
18
19 private static final String URL_ENCODING = "UTF-8";
20
21 private static final String SEPARATOR = "^^^";
22
23 private final EncryptionUtils encryptionUtils;
24
25 public EncryptedCookieEncoder()
26 {
27 this(SecurityConfigFactory.getInstance().getCookieEncoding());
28 }
29
30 protected EncryptedCookieEncoder(String password)
31 {
32 if (password == null || password.length() == 0)
33 {
34 throw new IllegalArgumentException("The password must be specified");
35 }
36 encryptionUtils = new EncryptionUtils();
37 encryptionUtils.setPassword(password);
38 }
39
40 public String encodePasswordCookie(String username, String password, String encoding)
41 {
42 StringBuffer sb = new StringBuffer();
43 sb.append(username).append(SEPARATOR).append(password);
44 return escapeInvalidCookieCharacters(encryptionUtils.encrypt(sb.toString()));
45 }
46
47 public String[] decodePasswordCookie(String cookieVal, String encoding)
48 {
49 final String[] result = new String[2];
50 try
51 {
52 final String text = encryptionUtils.decrypt(unescapeInvalidCookieCharacters(cookieVal));
53 int pos = text.indexOf(SEPARATOR);
54 if (pos < 0)
55 {
56 LOG.info("Successfully decrypted password cookie, but decrypted value '" + text + "' is invalid because separator ('" +
57 SEPARATOR + "') was not found. Returning null.");
58 return null;
59 }
60 result[0] = text.substring(0, pos);
61 result[1] = text.substring(pos + SEPARATOR.length());
62 }
63 catch (RuntimeException ex)
64 {
65 LOG.info("Password cookie could not be decrypted, trying old insecure method of decoding it");
66 return CookieUtils.decodePasswordCookie(cookieVal, encoding);
67 }
68 return result;
69 }
70
71
72
73
74
75
76
77
78 private static String escapeInvalidCookieCharacters(final String s)
79 {
80 try
81 {
82 return URLEncoder.encode(s, URL_ENCODING);
83 }
84 catch (UnsupportedEncodingException e)
85 {
86 LOG.fatal("UTF-8 encoding unsupported !!?!! How is that possible?", e);
87 throw new RuntimeException(e);
88 }
89 }
90
91
92
93
94
95
96
97
98 private static String unescapeInvalidCookieCharacters(final String s)
99 {
100 try
101 {
102 return URLDecoder.decode(s, URL_ENCODING);
103 }
104 catch (UnsupportedEncodingException e)
105 {
106 LOG.fatal("UTF-8 encoding unsupported !!?!! How is that possible?", e);
107 throw new RuntimeException(e);
108 }
109 }
110 }