]> WPIA git - gigi.git/blob - src/org/cacert/gigi/pages/main/Signup.java
Enforce Output of CSRF token.
[gigi.git] / src / org / cacert / gigi / pages / main / Signup.java
1 package org.cacert.gigi.pages.main;
2
3 import java.io.IOException;
4 import java.io.InputStreamReader;
5 import java.io.PrintWriter;
6 import java.io.UnsupportedEncodingException;
7 import java.sql.PreparedStatement;
8 import java.sql.ResultSet;
9 import java.sql.SQLException;
10 import java.sql.Date;
11 import java.util.HashMap;
12 import java.util.Map;
13
14 import javax.servlet.http.HttpServletRequest;
15
16 import org.cacert.gigi.Language;
17 import org.cacert.gigi.User;
18 import org.cacert.gigi.database.DatabaseConnection;
19 import org.cacert.gigi.email.EmailProvider;
20 import org.cacert.gigi.output.DateSelector;
21 import org.cacert.gigi.output.Form;
22 import org.cacert.gigi.output.Template;
23 import org.cacert.gigi.pages.Page;
24 import org.cacert.gigi.util.HTMLEncoder;
25 import org.cacert.gigi.util.Notary;
26 import org.cacert.gigi.util.PasswordStrengthChecker;
27 import org.cacert.gigi.util.RandomToken;
28 import org.cacert.gigi.util.ServerConstants;
29
30 public class Signup extends Form {
31         User buildup = new User();
32         Template t;
33         boolean general = true, country = true, regional = true, radius = true;
34         public Signup() {
35                 try {
36                         t = new Template(new InputStreamReader(
37                                         Signup.class.getResourceAsStream("Signup.templ"), "UTF-8"));
38                 } catch (UnsupportedEncodingException e) {
39                         e.printStackTrace();
40                 }
41                 buildup.setFname("");
42                 buildup.setMname("");
43                 buildup.setLname("");
44                 buildup.setSuffix("");
45                 buildup.setEmail("");
46                 buildup.setDob(new Date(0));
47         }
48         DateSelector myDoB = new DateSelector("day", "month", "year");
49
50         @Override
51         public void outputContent(PrintWriter out, Language l,
52                         Map<String, Object> outerVars) {
53                 HashMap<String, Object> vars = new HashMap<String, Object>();
54                 vars.put("fname", HTMLEncoder.encodeHTML(buildup.getFname()));
55                 vars.put("mname", HTMLEncoder.encodeHTML(buildup.getMname()));
56                 vars.put("lname", HTMLEncoder.encodeHTML(buildup.getLname()));
57                 vars.put("suffix", HTMLEncoder.encodeHTML(buildup.getSuffix()));
58                 vars.put("dob", myDoB);
59                 vars.put("email", HTMLEncoder.encodeHTML(buildup.getEmail()));
60                 vars.put("general", general ? " checked=\"checked\"" : "");
61                 vars.put("country", country ? " checked=\"checked\"" : "");
62                 vars.put("regional", regional ? " checked=\"checked\"" : "");
63                 vars.put("radius", radius ? " checked=\"checked\"" : "");
64                 vars.put(
65                                 "helpOnNames",
66                                 String.format(
67                                                 l.getTranslation("Help on Names %sin the wiki%s"),
68                                                 "<a href=\"//wiki.cacert.org/FAQ/HowToEnterNamesInJoinForm\" target=\"_blank\">",
69                                                 "</a>"));
70                 t.output(out, l, vars);
71         }
72         private void update(HttpServletRequest r) {
73                 if (r.getParameter("fname") != null) {
74                         buildup.setFname(r.getParameter("fname"));
75                 }
76                 if (r.getParameter("lname") != null) {
77                         buildup.setLname(r.getParameter("lname"));
78                 }
79                 if (r.getParameter("mname") != null) {
80                         buildup.setMname(r.getParameter("mname"));
81                 }
82                 if (r.getParameter("suffix") != null) {
83                         buildup.setSuffix(r.getParameter("suffix"));
84                 }
85                 if (r.getParameter("email") != null) {
86                         buildup.setEmail(r.getParameter("email"));
87                 }
88                 general = "1".equals(r.getParameter("general"));
89                 country = "1".equals(r.getParameter("country"));
90                 regional = "1".equals(r.getParameter("regional"));
91                 radius = "1".equals(r.getParameter("radius"));
92                 myDoB.update(r);
93         }
94
95         @Override
96         public synchronized boolean submit(PrintWriter out, HttpServletRequest req) {
97                 update(req);
98                 boolean failed = false;
99                 out.println("<div class='formError'>");
100                 if (buildup.getFname().equals("") || buildup.getLname().equals("")) {
101                         outputError(out, req, "First and/or last names were blank.");
102                         failed = true;
103                 }
104                 if (!myDoB.isValid()) {
105                         outputError(out, req, "Invalid date of birth");
106                         failed = true;
107                 }
108                 if (!"1".equals(req.getParameter("cca_agree"))) {
109                         outputError(out, req,
110                                         "You have to agree to the CAcert Community agreement.");
111                         failed = true;
112                 }
113                 if (buildup.getEmail().equals("")) {
114                         outputError(out, req, "Email Address was blank");
115                         failed = true;
116                 }
117                 String pw1 = req.getParameter("pword1");
118                 String pw2 = req.getParameter("pword2");
119                 if (pw1 == null || pw1.equals("")) {
120                         outputError(out, req, "Pass Phrases were blank");
121                         failed = true;
122                 } else if (!pw1.equals(pw2)) {
123                         outputError(out, req, "Pass Phrases don't match");
124                         failed = true;
125                 }
126                 int pwpoints = PasswordStrengthChecker.checkpw(pw1, buildup);
127                 if (pwpoints < 3) {
128                         outputError(
129                                         out,
130                                         req,
131                                         "The Pass Phrase you submitted failed to contain enough"
132                                                         + " differing characters and/or contained words from"
133                                                         + " your name and/or email address.");
134                         failed = true;
135                 }
136                 if (failed) {
137                         out.println("</div>");
138                         return false;
139                 }
140                 try {
141                         PreparedStatement q1 = DatabaseConnection.getInstance().prepare(
142                                         "select * from `email` where `email`=? and `deleted`=0");
143                         PreparedStatement q2 = DatabaseConnection.getInstance().prepare(
144                                         "select * from `users` where `email`=? and `deleted`=0");
145                         q1.setString(1, buildup.getEmail());
146                         q2.setString(1, buildup.getEmail());
147                         ResultSet r1 = q1.executeQuery();
148                         ResultSet r2 = q2.executeQuery();
149                         if (r1.next() || r2.next()) {
150                                 outputError(out, req,
151                                                 "This email address is currently valid in the system.");
152                                 failed = true;
153                         }
154                         r1.close();
155                         r2.close();
156                         PreparedStatement q3 = DatabaseConnection
157                                         .getInstance()
158                                         .prepare(
159                                                         "select `domain` from `baddomains` where `domain`=RIGHT(?, LENGTH(`domain`))");
160                         q3.setString(1, buildup.getEmail());
161
162                         ResultSet r3 = q3.executeQuery();
163                         if (r3.next()) {
164                                 String domain = r3.getString(1);
165                                 out.print("<div>");
166                                 out.print(String.format(
167                                                 Page.translate(req,
168                                                                 "We don't allow signups from people using email addresses from %s"),
169                                                 domain));
170                                 out.println("</div>");
171                                 failed = true;
172                         }
173                         r3.close();
174                 } catch (SQLException e) {
175                         e.printStackTrace();
176                         failed = true;
177                 }
178                 String mailResult = EmailProvider.FAIL;
179                 try {
180                         mailResult = EmailProvider.getInstance().checkEmailServer(0,
181                                         buildup.getEmail());
182                 } catch (IOException e) {
183                 }
184                 if (!mailResult.equals(EmailProvider.OK)) {
185                         if (mailResult.startsWith("4")) {
186                                 outputError(
187                                                 out,
188                                                 req,
189                                                 "The mail server responsible for your domain indicated"
190                                                                 + " a temporary failure. This may be due to anti-SPAM measures, such"
191                                                                 + " as greylisting. Please try again in a few minutes.");
192                         } else {
193                                 outputError(
194                                                 out,
195                                                 req,
196                                                 "Email Address given was invalid, or a test connection"
197                                                                 + " couldn't be made to your server, or the server"
198                                                                 + " rejected the email address as invalid");
199                         }
200                         if (mailResult.equals(EmailProvider.FAIL)) {
201                                 outputError(out, req,
202                                                 "Failed to make a connection to the mail server");
203                         } else {
204                                 out.print("<div>");
205                                 out.print(mailResult);
206                                 out.println("</div>");
207                         }
208                         failed = true;
209                 }
210
211                 out.println("</div>");
212                 if (failed) {
213                         return false;
214                 }
215                 try {
216                         run(req, pw1);
217                 } catch (SQLException e) {
218                         e.printStackTrace();
219                 }
220                 return true;
221         }
222
223         private void run(HttpServletRequest req, String password)
224                         throws SQLException {
225                 try {
226                         DatabaseConnection.getInstance().beginTransaction();
227                         String hash = RandomToken.generateToken(16);
228
229                         buildup.setDob(myDoB.getDate());
230                         buildup.insert(password);
231                         int memid = buildup.getId();
232                         PreparedStatement ps = DatabaseConnection.getInstance().prepare(
233                                         "insert into `email` set `email`=?,"
234                                                         + " `hash`=?, `created`=NOW(),`memid`=?");
235                         ps.setString(1, buildup.getEmail());
236                         ps.setString(2, hash);
237                         ps.setInt(3, memid);
238                         ps.execute();
239                         int emailid = DatabaseConnection.lastInsertId(ps);
240                         ps = DatabaseConnection
241                                         .getInstance()
242                                         .prepare(
243                                                         "insert into `alerts` set `memid`=?,"
244                                                                         + " `general`=?, `country`=?, `regional`=?, `radius`=?");
245                         ps.setInt(1, memid);
246                         ps.setString(2, general ? "1" : "0");
247                         ps.setString(3, country ? "1" : "0");
248                         ps.setString(4, regional ? "1" : "0");
249                         ps.setString(5, radius ? "1" : "0");
250                         ps.execute();
251                         Notary.writeUserAgreement(memid, "CCA", "account creation", "",
252                                         true, 0);
253
254                         StringBuffer body = new StringBuffer();
255                         body.append(Page
256                                         .translate(
257                                                         req,
258                                                         "Thanks for signing up with CAcert.org, below is the link you need to open to verify your account. Once your account is verified you will be able to start issuing certificates till your hearts' content!"));
259                         body.append("\n\nhttps://");
260                         body.append(ServerConstants.getWwwHostNamePort());
261                         body.append("/verify?type=email&id=");
262                         body.append(emailid);
263                         body.append("&hash=");
264                         body.append(hash);
265                         body.append("\n\n");
266                         body.append(Page.translate(req, "Best regards"));
267                         body.append("\n");
268                         body.append(Page.translate(req, "CAcert.org Support!"));
269                         try {
270                                 EmailProvider.getInstance().sendmail(buildup.getEmail(),
271                                                 "[CAcert.org] " + Page.translate(req, "Mail Probe"),
272                                                 body.toString(), "support@cacert.org", null, null,
273                                                 null, null, false);
274                         } catch (IOException e) {
275                                 e.printStackTrace();
276                         }
277                         DatabaseConnection.getInstance().commitTransaction();
278                 } finally {
279                         DatabaseConnection.getInstance().quitTransaction();
280                 }
281
282         }
283 }