protect against spoofing in syndie with a per-jvm-instance nonce (which should prevent the spurious "are you being spoofed" things)

fixed the syndie previewing
This commit is contained in:
jrandom
2005-11-13 14:15:26 +00:00
committed by zzz
parent 16fd46db2b
commit ddd438de35
9 changed files with 157 additions and 38 deletions

View File

@ -749,6 +749,8 @@ public class BlogManager {
int split = line.indexOf('='); int split = line.indexOf('=');
int split2 = line.indexOf(':'); int split2 = line.indexOf(':');
if ( (split < 0) || ( (split2 > 0) && (split2 < split) ) ) split = split2; if ( (split < 0) || ( (split2 > 0) && (split2 < split) ) ) split = split2;
if ( (split < 0) && (split2 < 0) )
continue;
String key = line.substring(0,split).trim(); String key = line.substring(0,split).trim();
String val = line.substring(split+1).trim(); String val = line.substring(split+1).trim();
raw.append(key).append(": ").append(val).append('\n'); raw.append(key).append(": ").append(val).append('\n');

View File

@ -17,6 +17,7 @@ import net.i2p.util.Log;
public class ThreadedHTMLRenderer extends HTMLRenderer { public class ThreadedHTMLRenderer extends HTMLRenderer {
private Log _log; private Log _log;
private String _baseURI; private String _baseURI;
private boolean _inlineReply;
public ThreadedHTMLRenderer(I2PAppContext ctx) { public ThreadedHTMLRenderer(I2PAppContext ctx) {
super(ctx); super(ctx);
@ -118,8 +119,11 @@ public class ThreadedHTMLRenderer extends HTMLRenderer {
private static final boolean empty(String val) { return (val == null) || (val.trim().length() <= 0); } private static final boolean empty(String val) { return (val == null) || (val.trim().length() <= 0); }
/**
* @param replyHiddenFields HTML of hidden input fields necessary for the reply form to be honored
*/
public void render(User user, Writer out, Archive archive, BlogURI post, public void render(User user, Writer out, Archive archive, BlogURI post,
boolean inlineReply, ThreadIndex index, String baseURI, boolean inlineReply, ThreadIndex index, String baseURI, String replyHiddenFields,
String offset, String requestTags, String filteredAuthor) throws IOException { String offset, String requestTags, String filteredAuthor) throws IOException {
EntryContainer entry = archive.getEntry(post); EntryContainer entry = archive.getEntry(post);
if (entry == null) return; if (entry == null) return;
@ -131,6 +135,7 @@ public class ThreadedHTMLRenderer extends HTMLRenderer {
_archive = archive; _archive = archive;
_cutBody = false; _cutBody = false;
_showImages = true; _showImages = true;
_inlineReply = inlineReply;
_headers = new HashMap(); _headers = new HashMap();
_bodyBuffer = new StringBuffer(1024); _bodyBuffer = new StringBuffer(1024);
_postBodyBuffer = new StringBuffer(1024); _postBodyBuffer = new StringBuffer(1024);
@ -193,6 +198,30 @@ public class ThreadedHTMLRenderer extends HTMLRenderer {
out.write(getViewPostLink(baseURI, node, user, true, offset, requestTags, filteredAuthor)); out.write(getViewPostLink(baseURI, node, user, true, offset, requestTags, filteredAuthor));
out.write("\" title=\"Select a shareable link directly to this post\">permalink</a>\n"); out.write("\" title=\"Select a shareable link directly to this post\">permalink</a>\n");
if (!inlineReply) {
String refuseReply = (String)_headers.get(HEADER_REFUSE_REPLIES);
boolean allowReply = false;
if ( (refuseReply != null) && (Boolean.valueOf(refuseReply).booleanValue()) ) {
if (_entry == null )
allowReply = false;
else if ( (_user == null) || (_user.getBlog() == null) )
allowReply = false;
else if (_entry.getURI().getKeyHash().equals(_user.getBlog()))
allowReply = true;
else
allowReply = false;
} else {
allowReply = true;
}
if (allowReply && (_entry != null) ) {
out.write("<a href=\"post.jsp?");
out.write(PostServlet.PARAM_PARENT + '=' +
Base64.encode(_entry.getURI().getKeyHash().toBase64() + '/' + _entry.getURI().getEntryId()));
out.write("\" title=\"Reply to the current post\" >Reply</a><br />\n");
}
}
out.write("</td>\n</tr>\n"); out.write("</td>\n</tr>\n");
out.write("<!-- body meta end -->\n"); out.write("<!-- body meta end -->\n");
out.write("<!-- body post begin -->\n"); out.write("<!-- body post begin -->\n");
@ -229,6 +258,7 @@ public class ThreadedHTMLRenderer extends HTMLRenderer {
(refuseReplies == null) || (!Boolean.valueOf(refuseReplies).booleanValue()) ) { (refuseReplies == null) || (!Boolean.valueOf(refuseReplies).booleanValue()) ) {
out.write("<!-- body reply begin -->\n"); out.write("<!-- body reply begin -->\n");
out.write("<form action=\"post.jsp\" method=\"POST\" enctype=\"multipart/form-data\">\n"); out.write("<form action=\"post.jsp\" method=\"POST\" enctype=\"multipart/form-data\">\n");
out.write(replyHiddenFields);
out.write("<input type=\"hidden\" name=\"" + PostServlet.PARAM_PARENT + "\" value=\""); out.write("<input type=\"hidden\" name=\"" + PostServlet.PARAM_PARENT + "\" value=\"");
out.write(Base64.encode(post.toString())); out.write(Base64.encode(post.toString()));
out.write("\" />"); out.write("\" />");

View File

@ -96,6 +96,7 @@ public class AddressesServlet extends BaseServlet {
out.write("<form action=\"" + baseURI + "\" method=\"POST\">"); out.write("<form action=\"" + baseURI + "\" method=\"POST\">");
out.write("<input type=\"hidden\" name=\"" + PARAM_PROTO + "\" value=\"" + PROTO_BLOG + "\" />"); out.write("<input type=\"hidden\" name=\"" + PARAM_PROTO + "\" value=\"" + PROTO_BLOG + "\" />");
out.write("<input type=\"hidden\" name=\"" + PARAM_NET + "\" value=\"" + NET_SYNDIE + "\" />"); out.write("<input type=\"hidden\" name=\"" + PARAM_NET + "\" value=\"" + NET_SYNDIE + "\" />");
writeAuthActionFields(out);
out.write("<tr><td colspan=\"3\">"); out.write("<tr><td colspan=\"3\">");
out.write("<input type=\"checkbox\" name=\"" + PARAM_IS_PUBLIC + "\" value=\"true\" " + (pn.getIsPublic() ? " checked=\"true\" " : "") + " />\n"); out.write("<input type=\"checkbox\" name=\"" + PARAM_IS_PUBLIC + "\" value=\"true\" " + (pn.getIsPublic() ? " checked=\"true\" " : "") + " />\n");
out.write("Name: <input type=\"hidden\" name=\"" + PARAM_NAME + "\" value=\"" + pn.getName() + "\" />" + pn.getName() + " "); out.write("Name: <input type=\"hidden\" name=\"" + PARAM_NAME + "\" value=\"" + pn.getName() + "\" />" + pn.getName() + " ");
@ -120,6 +121,7 @@ public class AddressesServlet extends BaseServlet {
} }
out.write("<form action=\"" + baseURI + "\" method=\"POST\">"); out.write("<form action=\"" + baseURI + "\" method=\"POST\">");
writeAuthActionFields(out);
out.write("<input type=\"hidden\" name=\"" + PARAM_PROTO + "\" value=\"" + PROTO_BLOG + "\" />"); out.write("<input type=\"hidden\" name=\"" + PARAM_PROTO + "\" value=\"" + PROTO_BLOG + "\" />");
out.write("<input type=\"hidden\" name=\"" + PARAM_NET + "\" value=\"" + NET_SYNDIE + "\" />"); out.write("<input type=\"hidden\" name=\"" + PARAM_NET + "\" value=\"" + NET_SYNDIE + "\" />");
out.write("<tr><td colspan=\"3\">"); out.write("<tr><td colspan=\"3\">");
@ -156,6 +158,7 @@ public class AddressesServlet extends BaseServlet {
for (Iterator iter = names.iterator(); iter.hasNext(); ) { for (Iterator iter = names.iterator(); iter.hasNext(); ) {
PetName pn = db.getByName((String)iter.next()); PetName pn = db.getByName((String)iter.next());
out.write("<form action=\"" + baseURI + "\" method=\"POST\">"); out.write("<form action=\"" + baseURI + "\" method=\"POST\">");
writeAuthActionFields(out);
out.write("<input type=\"hidden\" name=\"" + PARAM_PROTO + "\" value=\"" + PROTO_ARCHIVE + "\" />"); out.write("<input type=\"hidden\" name=\"" + PARAM_PROTO + "\" value=\"" + PROTO_ARCHIVE + "\" />");
out.write("<input type=\"hidden\" name=\"" + PARAM_NET + "\" value=\"" + NET_SYNDIE + "\" />"); out.write("<input type=\"hidden\" name=\"" + PARAM_NET + "\" value=\"" + NET_SYNDIE + "\" />");
out.write("<tr><td colspan=\"3\">"); out.write("<tr><td colspan=\"3\">");
@ -177,6 +180,7 @@ public class AddressesServlet extends BaseServlet {
} }
out.write("<form action=\"" + baseURI + "\" method=\"POST\">"); out.write("<form action=\"" + baseURI + "\" method=\"POST\">");
writeAuthActionFields(out);
out.write("<input type=\"hidden\" name=\"" + PARAM_PROTO + "\" value=\"" + PROTO_ARCHIVE + "\" />"); out.write("<input type=\"hidden\" name=\"" + PARAM_PROTO + "\" value=\"" + PROTO_ARCHIVE + "\" />");
out.write("<input type=\"hidden\" name=\"" + PARAM_NET + "\" value=\"" + NET_SYNDIE + "\" />"); out.write("<input type=\"hidden\" name=\"" + PARAM_NET + "\" value=\"" + NET_SYNDIE + "\" />");
out.write("<tr><td colspan=\"3\">"); out.write("<tr><td colspan=\"3\">");
@ -208,6 +212,7 @@ public class AddressesServlet extends BaseServlet {
for (Iterator iter = names.iterator(); iter.hasNext(); ) { for (Iterator iter = names.iterator(); iter.hasNext(); ) {
PetName pn = db.getByName((String)iter.next()); PetName pn = db.getByName((String)iter.next());
out.write("<form action=\"" + baseURI + "\" method=\"POST\">"); out.write("<form action=\"" + baseURI + "\" method=\"POST\">");
writeAuthActionFields(out);
out.write("<input type=\"hidden\" name=\"" + PARAM_PROTO + "\" value=\"" + PROTO_I2PHEX + "\" />"); out.write("<input type=\"hidden\" name=\"" + PARAM_PROTO + "\" value=\"" + PROTO_I2PHEX + "\" />");
out.write("<input type=\"hidden\" name=\"" + PARAM_NET + "\" value=\"" + NET_I2P + "\" />"); out.write("<input type=\"hidden\" name=\"" + PARAM_NET + "\" value=\"" + NET_I2P + "\" />");
out.write("<tr><td colspan=\"3\">"); out.write("<tr><td colspan=\"3\">");
@ -222,6 +227,7 @@ public class AddressesServlet extends BaseServlet {
} }
out.write("<form action=\"" + baseURI + "\" method=\"POST\">"); out.write("<form action=\"" + baseURI + "\" method=\"POST\">");
writeAuthActionFields(out);
out.write("<input type=\"hidden\" name=\"" + PARAM_PROTO + "\" value=\"" + PROTO_I2PHEX + "\" />"); out.write("<input type=\"hidden\" name=\"" + PARAM_PROTO + "\" value=\"" + PROTO_I2PHEX + "\" />");
out.write("<input type=\"hidden\" name=\"" + PARAM_NET + "\" value=\"" + NET_I2P + "\" />"); out.write("<input type=\"hidden\" name=\"" + PARAM_NET + "\" value=\"" + NET_I2P + "\" />");
out.write("<tr><td colspan=\"3\">"); out.write("<tr><td colspan=\"3\">");
@ -248,6 +254,7 @@ public class AddressesServlet extends BaseServlet {
for (Iterator iter = names.iterator(); iter.hasNext(); ) { for (Iterator iter = names.iterator(); iter.hasNext(); ) {
PetName pn = db.getByName((String)iter.next()); PetName pn = db.getByName((String)iter.next());
out.write("<form action=\"" + baseURI + "\" method=\"POST\">"); out.write("<form action=\"" + baseURI + "\" method=\"POST\">");
writeAuthActionFields(out);
out.write("<input type=\"hidden\" name=\"" + PARAM_PROTO + "\" value=\"" + PROTO_EEPSITE + "\" />"); out.write("<input type=\"hidden\" name=\"" + PARAM_PROTO + "\" value=\"" + PROTO_EEPSITE + "\" />");
out.write("<input type=\"hidden\" name=\"" + PARAM_NET + "\" value=\"" + NET_I2P + "\" />"); out.write("<input type=\"hidden\" name=\"" + PARAM_NET + "\" value=\"" + NET_I2P + "\" />");
out.write("<tr><td colspan=\"3\">"); out.write("<tr><td colspan=\"3\">");
@ -262,6 +269,7 @@ public class AddressesServlet extends BaseServlet {
} }
out.write("<form action=\"" + baseURI + "\" method=\"POST\">"); out.write("<form action=\"" + baseURI + "\" method=\"POST\">");
writeAuthActionFields(out);
out.write("<input type=\"hidden\" name=\"" + PARAM_PROTO + "\" value=\"" + PROTO_EEPSITE + "\" />"); out.write("<input type=\"hidden\" name=\"" + PARAM_PROTO + "\" value=\"" + PROTO_EEPSITE + "\" />");
out.write("<input type=\"hidden\" name=\"" + PARAM_NET + "\" value=\"" + NET_I2P + "\" />"); out.write("<input type=\"hidden\" name=\"" + PARAM_NET + "\" value=\"" + NET_I2P + "\" />");
out.write("<tr><td colspan=\"3\">"); out.write("<tr><td colspan=\"3\">");
@ -288,6 +296,7 @@ public class AddressesServlet extends BaseServlet {
for (Iterator iter = names.iterator(); iter.hasNext(); ) { for (Iterator iter = names.iterator(); iter.hasNext(); ) {
PetName pn = db.getByName((String)iter.next()); PetName pn = db.getByName((String)iter.next());
out.write("<form action=\"" + baseURI + "\" method=\"POST\">"); out.write("<form action=\"" + baseURI + "\" method=\"POST\">");
writeAuthActionFields(out);
out.write("<tr><td colspan=\"3\">"); out.write("<tr><td colspan=\"3\">");
out.write("<input type=\"checkbox\" name=\"" + PARAM_IS_PUBLIC + "\" value=\"true\" " + (pn.getIsPublic() ? " checked=\"true\" " : "") + " />\n"); out.write("<input type=\"checkbox\" name=\"" + PARAM_IS_PUBLIC + "\" value=\"true\" " + (pn.getIsPublic() ? " checked=\"true\" " : "") + " />\n");
out.write("Network: <input type=\"text\" name=\"" + PARAM_NET + "\" value=\"" + pn.getNetwork() + "\" /> "); out.write("Network: <input type=\"text\" name=\"" + PARAM_NET + "\" value=\"" + pn.getNetwork() + "\" /> ");
@ -302,6 +311,7 @@ public class AddressesServlet extends BaseServlet {
} }
out.write("<form action=\"" + baseURI + "\" method=\"POST\">"); out.write("<form action=\"" + baseURI + "\" method=\"POST\">");
writeAuthActionFields(out);
out.write("<tr><td colspan=\"3\">"); out.write("<tr><td colspan=\"3\">");
out.write("<input type=\"checkbox\" name=\"" + PARAM_IS_PUBLIC + "\" value=\"true\" " + (newName.getIsPublic() ? " checked=\"true\" " : "") + " />\n"); out.write("<input type=\"checkbox\" name=\"" + PARAM_IS_PUBLIC + "\" value=\"true\" " + (newName.getIsPublic() ? " checked=\"true\" " : "") + " />\n");
@ -372,4 +382,6 @@ public class AddressesServlet extends BaseServlet {
return proto.equals(reqProto); return proto.equals(reqProto);
} }
} }
protected String getTitle() { return "Syndie :: Addressbook"; }
} }

View File

@ -31,6 +31,7 @@ public class AdminServlet extends BaseServlet {
private void displayForm(User user, HttpServletRequest req, PrintWriter out) throws IOException { private void displayForm(User user, HttpServletRequest req, PrintWriter out) throws IOException {
out.write("<form action=\"" + req.getRequestURI() + "\" method=\"POST\">\n"); out.write("<form action=\"" + req.getRequestURI() + "\" method=\"POST\">\n");
writeAuthActionFields(out);
out.write("<tr><td colspan=\"3\">"); out.write("<tr><td colspan=\"3\">");
out.write("<em class=\"b_adminField\">Single user?</em> <input type=\"checkbox\" class=\"b_adminField\" name=\"singleuser\" "); out.write("<em class=\"b_adminField\">Single user?</em> <input type=\"checkbox\" class=\"b_adminField\" name=\"singleuser\" ");
@ -71,4 +72,6 @@ public class AdminServlet extends BaseServlet {
out.write("</td></tr>\n"); out.write("</td></tr>\n");
out.write("</form>\n"); out.write("</form>\n");
} }
protected String getTitle() { return "Syndie :: Configuration"; }
} }

View File

@ -20,6 +20,53 @@ import net.i2p.syndie.sml.*;
* *
*/ */
public abstract class BaseServlet extends HttpServlet { public abstract class BaseServlet extends HttpServlet {
protected static final String PARAM_AUTH_ACTION = "syndie.auth";
private static long _authNonce;
public void init() throws ServletException {
super.init();
_authNonce = I2PAppContext.getGlobalContext().random().nextLong();
}
protected boolean authAction(HttpServletRequest req) {
return authAction(req.getParameter(PARAM_AUTH_ACTION));
}
protected boolean authAction(String auth) {
if (auth == null) {
return false;
} else {
try {
boolean rv = (Long.valueOf(auth).longValue() == _authNonce);
return rv;
} catch (NumberFormatException nfe) {
return false;
}
}
}
/**
* write out hidden fields for params that need to be tacked onto an http request that updates
* data, to prevent spoofing
*/
protected void writeAuthActionFields(Writer out) throws IOException {
out.write("<input type=\"hidden\" name=\"" + PARAM_AUTH_ACTION + "\" value=\"" + _authNonce + "\" />");
}
protected String getAuthActionFields() throws IOException {
return "<input type=\"hidden\" name=\"" + PARAM_AUTH_ACTION + "\" value=\"" + _authNonce + "\" />";
}
/**
* key=value& of params that need to be tacked onto an http request that updates data, to
* prevent spoofing
*/
protected String getAuthActionParams() { return PARAM_AUTH_ACTION + '=' + _authNonce + '&'; }
/**
* key=value& of params that need to be tacked onto an http request that updates data, to
* prevent spoofing
*/
protected void addAuthActionParams(StringBuffer buf) {
buf.append(PARAM_AUTH_ACTION).append('=').append(_authNonce).append('&');
}
public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8"); req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8"); resp.setCharacterEncoding("UTF-8");
@ -31,11 +78,14 @@ public abstract class BaseServlet extends HttpServlet {
String action = req.getParameter("action"); String action = req.getParameter("action");
boolean forceNewIndex = false; boolean forceNewIndex = false;
boolean authAction = authAction(req);
if (req.getParameter("regenerateIndex") != null) if (req.getParameter("regenerateIndex") != null)
forceNewIndex = true; forceNewIndex = true;
User oldUser = user; User oldUser = user;
user = handleRegister(user, req); if (authAction)
user = handleRegister(user, req);
if (oldUser != user) if (oldUser != user)
forceNewIndex = true; forceNewIndex = true;
@ -48,23 +98,25 @@ public abstract class BaseServlet extends HttpServlet {
user = BlogManager.instance().getDefaultUser(); user = BlogManager.instance().getDefaultUser();
} }
forceNewIndex = true; forceNewIndex = true;
} else if ("Login".equals(action)) { } else if (authAction && "Login".equals(action)) {
user = BlogManager.instance().login(login, pass); // ignore failures - user will just be unauthorized user = BlogManager.instance().login(login, pass); // ignore failures - user will just be unauthorized
if (!user.getAuthenticated()) if (!user.getAuthenticated())
user = BlogManager.instance().getDefaultUser(); user = BlogManager.instance().getDefaultUser();
forceNewIndex = true; forceNewIndex = true;
} else if ("Logout".equals(action)) { } else if (authAction && "Logout".equals(action)) {
user = BlogManager.instance().getDefaultUser(); user = BlogManager.instance().getDefaultUser();
forceNewIndex = true; forceNewIndex = true;
} }
req.getSession().setAttribute("user", user); req.getSession().setAttribute("user", user);
handleAdmin(user, req); if (authAction) {
handleAdmin(user, req);
forceNewIndex = handleAddressbook(user, req) || forceNewIndex; forceNewIndex = handleAddressbook(user, req) || forceNewIndex;
forceNewIndex = handleBookmarking(user, req) || forceNewIndex; forceNewIndex = handleBookmarking(user, req) || forceNewIndex;
handleUpdateProfile(user, req); handleUpdateProfile(user, req);
}
FilteredThreadIndex index = (FilteredThreadIndex)req.getSession().getAttribute("threadIndex"); FilteredThreadIndex index = (FilteredThreadIndex)req.getSession().getAttribute("threadIndex");
@ -677,6 +729,7 @@ public abstract class BaseServlet extends HttpServlet {
if (!empty(filteredAuthor)) if (!empty(filteredAuthor))
buf.append(ThreadedHTMLRenderer.PARAM_AUTHOR).append('=').append(filteredAuthor).append('&'); buf.append(ThreadedHTMLRenderer.PARAM_AUTHOR).append('=').append(filteredAuthor).append('&');
addAuthActionParams(buf);
return buf.toString(); return buf.toString();
} }
protected String getRemoveFromGroupLink(User user, String name, String group, String uri, String visible, protected String getRemoveFromGroupLink(User user, String name, String group, String uri, String visible,
@ -703,6 +756,7 @@ public abstract class BaseServlet extends HttpServlet {
if (!empty(filteredAuthor)) if (!empty(filteredAuthor))
buf.append(ThreadedHTMLRenderer.PARAM_AUTHOR).append('=').append(filteredAuthor).append('&'); buf.append(ThreadedHTMLRenderer.PARAM_AUTHOR).append('=').append(filteredAuthor).append('&');
addAuthActionParams(buf);
return buf.toString(); return buf.toString();
} }
protected String getViewPostLink(HttpServletRequest req, ThreadNode node, User user, boolean isPermalink) { protected String getViewPostLink(HttpServletRequest req, ThreadNode node, User user, boolean isPermalink) {

View File

@ -60,6 +60,13 @@ public class PostServlet extends BaseServlet {
} }
private void previewPostedData(User user, HttpServletRequest rawRequest, Archive archive, String contentType, PostBean post, PrintWriter out) throws IOException { private void previewPostedData(User user, HttpServletRequest rawRequest, Archive archive, String contentType, PostBean post, PrintWriter out) throws IOException {
MultiPartRequest req = new MultiPartRequest(rawRequest);
if (!authAction(req.getString(PARAM_AUTH_ACTION))) {
out.write("<tr><td colspan=\"3\"><span class=\"b_postMsgErro\">Invalid form submission... stale data?</span></td></tr>");
return;
}
// not confirmed but they posted stuff... gobble up what they give // not confirmed but they posted stuff... gobble up what they give
// and display it as a prview (then we show the confirm form // and display it as a prview (then we show the confirm form
@ -68,8 +75,6 @@ public class PostServlet extends BaseServlet {
post.reinitialize(); post.reinitialize();
post.setUser(user); post.setUser(user);
MultiPartRequest req = new MultiPartRequest(rawRequest);
boolean inNewThread = getInNewThread(req.getString(PARAM_IN_NEW_THREAD)); boolean inNewThread = getInNewThread(req.getString(PARAM_IN_NEW_THREAD));
boolean refuseReplies = getRefuseReplies(req.getString(PARAM_REFUSE_REPLIES)); boolean refuseReplies = getRefuseReplies(req.getString(PARAM_REFUSE_REPLIES));
@ -86,8 +91,8 @@ public class PostServlet extends BaseServlet {
if ( (replyTo != null) && (replyTo.trim().length() > 0) ) { if ( (replyTo != null) && (replyTo.trim().length() > 0) ) {
byte r[] = Base64.decode(replyTo); byte r[] = Base64.decode(replyTo);
if (r != null) { if (r != null) {
if (entryHeaders == null) entryHeaders = HTMLRenderer.HEADER_IN_REPLY_TO + ": " + new String(r, "UTF-8"); if (entryHeaders == null) entryHeaders = HTMLRenderer.HEADER_IN_REPLY_TO + ": entry://" + new String(r, "UTF-8");
else entryHeaders = entryHeaders + '\n' + HTMLRenderer.HEADER_IN_REPLY_TO + ": " + new String(r, "UTF-8"); else entryHeaders = entryHeaders + '\n' + HTMLRenderer.HEADER_IN_REPLY_TO + ": entry://" + new String(r, "UTF-8");
} else { } else {
replyTo = null; replyTo = null;
} }
@ -137,6 +142,7 @@ public class PostServlet extends BaseServlet {
post.renderPreview(out); post.renderPreview(out);
out.write("<hr /><span class=\"b_postConfirm\"><form action=\"" + getPostURI() + "\" method=\"POST\">\n"); out.write("<hr /><span class=\"b_postConfirm\"><form action=\"" + getPostURI() + "\" method=\"POST\">\n");
writeAuthActionFields(out);
out.write("Please confirm that the above is ok"); out.write("Please confirm that the above is ok");
if (BlogManager.instance().authorizeRemote(user)) { if (BlogManager.instance().authorizeRemote(user)) {
out.write(", and select what additional archives you want the post transmitted to."); out.write(", and select what additional archives you want the post transmitted to.");
@ -166,6 +172,10 @@ public class PostServlet extends BaseServlet {
} }
private void postEntry(User user, HttpServletRequest req, Archive archive, PostBean post, PrintWriter out) throws IOException { private void postEntry(User user, HttpServletRequest req, Archive archive, PostBean post, PrintWriter out) throws IOException {
if (!authAction(req)) {
out.write("<tr><td colspan=\"3\"><span class=\"b_postMsgErro\">Invalid form submission... stale data?</span></td></tr>");
return;
}
String remArchive = req.getParameter(PARAM_REMOTE_ARCHIVE); String remArchive = req.getParameter(PARAM_REMOTE_ARCHIVE);
post.setArchive(remArchive); post.setArchive(remArchive);
BlogURI uri = post.postEntry(); BlogURI uri = post.postEntry();
@ -185,6 +195,7 @@ public class PostServlet extends BaseServlet {
post.setUser(user); post.setUser(user);
out.write("<form action=\"" + getPostURI() + "\" method=\"POST\" enctype=\"multipart/form-data\">\n"); out.write("<form action=\"" + getPostURI() + "\" method=\"POST\" enctype=\"multipart/form-data\">\n");
writeAuthActionFields(out);
out.write("<tr><td colspan=\"3\">\n"); out.write("<tr><td colspan=\"3\">\n");
out.write("<span class=\"b_postField\">Post subject:</span> "); out.write("<span class=\"b_postField\">Post subject:</span> ");
out.write("<input type=\"text\" class=\"b_postSubject\" size=\"80\" name=\"" + PARAM_SUBJECT out.write("<input type=\"text\" class=\"b_postSubject\" size=\"80\" name=\"" + PARAM_SUBJECT
@ -203,7 +214,7 @@ public class PostServlet extends BaseServlet {
String parentURI = req.getParameter(PARAM_PARENT); String parentURI = req.getParameter(PARAM_PARENT);
if ( (parentURI != null) && (parentURI.trim().length() > 0) ) if ( (parentURI != null) && (parentURI.trim().length() > 0) )
out.write("<input type=\"hidden\" name=\"" + PARAM_PARENT + " value=\"" + parentURI + "\" />\n"); out.write("<input type=\"hidden\" name=\"" + PARAM_PARENT + "\" value=\"" + parentURI + "\" />\n");
out.write(" Tags: <input type=\"text\" size=\"10\" name=\"" + PARAM_TAGS + "\" value=\"" + getParam(req, PARAM_TAGS) + "\" />\n"); out.write(" Tags: <input type=\"text\" size=\"10\" name=\"" + PARAM_TAGS + "\" value=\"" + getParam(req, PARAM_TAGS) + "\" />\n");
@ -223,7 +234,8 @@ public class PostServlet extends BaseServlet {
if (parentURI != null) { if (parentURI != null) {
out.write("<hr /><span id=\"parentText\" class=\"b_postParent\">"); out.write("<hr /><span id=\"parentText\" class=\"b_postParent\">");
post.renderReplyPreview(out, DataHelper.getUTF8(Base64.decode(parentURI))); String decoded = DataHelper.getUTF8(Base64.decode(parentURI));
post.renderReplyPreview(out, "entry://" + decoded);
out.write("</span><hr/>\n"); out.write("</span><hr/>\n");
} }
@ -273,4 +285,5 @@ public class PostServlet extends BaseServlet {
+ "<span class=\"b_postField\">Attachment 2:</span> <input class=\"b_postField\" type=\"file\" name=\"entryfile2\" /><br />" + "<span class=\"b_postField\">Attachment 2:</span> <input class=\"b_postField\" type=\"file\" name=\"entryfile2\" /><br />"
+ "<span class=\"b_postField\">Attachment 3:</span> <input class=\"b_postField\" type=\"file\" name=\"entryfile3\" /><br />\n"; + "<span class=\"b_postField\">Attachment 3:</span> <input class=\"b_postField\" type=\"file\" name=\"entryfile3\" /><br />\n";
protected String getTitle() { return "Syndie :: Post new content"; }
} }

View File

@ -57,6 +57,7 @@ public class ProfileServlet extends BaseServlet {
out.write("<!-- " + info.toString() + "-->\n"); out.write("<!-- " + info.toString() + "-->\n");
out.write("<form action=\"" + baseURI + "\" method=\"POST\">\n"); out.write("<form action=\"" + baseURI + "\" method=\"POST\">\n");
writeAuthActionFields(out);
// now add the form to update // now add the form to update
out.write("<tr><td colspan=\"3\">Your profile</td></tr>\n"); out.write("<tr><td colspan=\"3\">Your profile</td></tr>\n");
out.write("<tr><td colspan=\"3\">Name: <input type=\"text\" name=\"" out.write("<tr><td colspan=\"3\">Name: <input type=\"text\" name=\""
@ -215,5 +216,7 @@ public class ProfileServlet extends BaseServlet {
} }
} }
protected String getTitle() { return "Syndie :: View profile"; }
private static final String INVALID_PROFILE = "<tr><td colspan=\"3\">The profile requested is invalid</td></tr>\n"; private static final String INVALID_PROFILE = "<tr><td colspan=\"3\">The profile requested is invalid</td></tr>\n";
} }

View File

@ -20,29 +20,30 @@ import net.i2p.syndie.sml.*;
* *
*/ */
public class SwitchServlet extends BaseServlet { public class SwitchServlet extends BaseServlet {
private final String FORM = "<form action=\"" + getControlTarget() + "\" method=\"POST\">\n" + protected String getTitle() { return "Syndie :: Login/Register"; }
"<tr><td colspan=\"3\"><b>Log in to an existing account</b></td></tr>\n" +
"<tr><td colspan=\"3\">Login: <input type=\"text\" name=\"login\" /></td></tr>\n" +
"<tr><td colspan=\"3\">Password: <input type=\"password\" name=\"password\" /></td></tr>\n" +
"<tr><td colspan=\"3\"><input type=\"submit\" name=\"action\" value=\"Login\" />\n" +
"<input type=\"submit\" name=\"action\" value=\"Cancel\" />\n" +
"<input type=\"submit\" name=\"action\" value=\"Logout\" /></td></tr>\n" +
"</form>\n" +
"<tr><td colspan=\"3\"><hr /></td></tr>\n" +
"<form action=\"" + ThreadedHTMLRenderer.buildProfileURL(null) + "\" method=\"POST\">\n" +
"<tr><td colspan=\"3\"><b>Register a new account</b></td></tr>\n" +
"<tr><td colspan=\"3\">Login: <input type=\"text\" name=\"login\" /> (only known locally)</td></tr>\n" +
"<tr><td colspan=\"3\">Password: <input type=\"password\" name=\"password\" /></td></tr>\n" +
"<tr><td colspan=\"3\">Public name: <input type=\"text\" name=\"accountName\" /></td></tr>\n" +
"<tr><td colspan=\"3\">Description: <input type=\"text\" name=\"description\" /></td></tr>\n" +
"<tr><td colspan=\"3\">Contact URL: <input type=\"text\" name=\"contactURL\" /></td></tr>\n" +
"<tr><td colspan=\"3\">Registration password: <input type=\"password\" name=\"registrationPass\" />" +
" (only necessary if the Syndie administrator requires it)</td></tr>\n" +
"<tr><td colspan=\"3\"><input type=\"submit\" name=\"action\" value=\"Register\" /></td></tr>\n" +
"</form>\n";
protected void renderServletDetails(User user, HttpServletRequest req, PrintWriter out, ThreadIndex index, protected void renderServletDetails(User user, HttpServletRequest req, PrintWriter out, ThreadIndex index,
int threadOffset, BlogURI visibleEntry, Archive archive) throws IOException { int threadOffset, BlogURI visibleEntry, Archive archive) throws IOException {
out.write(FORM); out.write("<form action=\"" + getControlTarget() + "\" method=\"POST\">\n");
writeAuthActionFields(out);
out.write("<tr><td colspan=\"3\"><b>Log in to an existing account</b></td></tr>\n" +
"<tr><td colspan=\"3\">Login: <input type=\"text\" name=\"login\" /></td></tr>\n" +
"<tr><td colspan=\"3\">Password: <input type=\"password\" name=\"password\" /></td></tr>\n" +
"<tr><td colspan=\"3\"><input type=\"submit\" name=\"action\" value=\"Login\" />\n" +
"<input type=\"submit\" name=\"action\" value=\"Cancel\" />\n" +
"<input type=\"submit\" name=\"action\" value=\"Logout\" /></td></tr>\n" +
"</form>\n" +
"<tr><td colspan=\"3\"><hr /></td></tr>\n" +
"<form action=\"" + ThreadedHTMLRenderer.buildProfileURL(null) + "\" method=\"POST\">\n" +
"<tr><td colspan=\"3\"><b>Register a new account</b></td></tr>\n" +
"<tr><td colspan=\"3\">Login: <input type=\"text\" name=\"login\" /> (only known locally)</td></tr>\n" +
"<tr><td colspan=\"3\">Password: <input type=\"password\" name=\"password\" /></td></tr>\n" +
"<tr><td colspan=\"3\">Public name: <input type=\"text\" name=\"accountName\" /></td></tr>\n" +
"<tr><td colspan=\"3\">Description: <input type=\"text\" name=\"description\" /></td></tr>\n" +
"<tr><td colspan=\"3\">Contact URL: <input type=\"text\" name=\"contactURL\" /></td></tr>\n" +
"<tr><td colspan=\"3\">Registration password: <input type=\"password\" name=\"registrationPass\" />" +
" (only necessary if the Syndie administrator requires it)</td></tr>\n" +
"<tr><td colspan=\"3\"><input type=\"submit\" name=\"action\" value=\"Register\" /></td></tr>\n" +
"</form>\n");
} }
} }

View File

@ -40,7 +40,7 @@ public class ViewThreadedServlet extends BaseServlet {
for (int i = 0; i < posts.size(); i++) { for (int i = 0; i < posts.size(); i++) {
BlogURI post = (BlogURI)posts.get(i); BlogURI post = (BlogURI)posts.get(i);
renderer.render(user, out, archive, post, posts.size() == 1, index, uri, off, tags, author); renderer.render(user, out, archive, post, posts.size() == 1, index, uri, getAuthActionFields(), off, tags, author);
} }
} }
@ -136,7 +136,7 @@ public class ViewThreadedServlet extends BaseServlet {
int written = 0; int written = 0;
for (int curRoot = threadOffset; curRoot < numThreads + threadOffset; curRoot++) { for (int curRoot = threadOffset; curRoot < numThreads + threadOffset; curRoot++) {
ThreadNode node = index.getRoot(curRoot); ThreadNode node = index.getRoot(curRoot);
out.write("<!-- thread begin node=" + node + " curRoot=" + curRoot + " threadOffset=" + threadOffset + " -->\n"); out.write("<!-- thread begin curRoot=" + curRoot + " threadOffset=" + threadOffset + " -->\n");
renderThread(user, out, index, archive, req, node, 0, visibleEntry, state); renderThread(user, out, index, archive, req, node, 0, visibleEntry, state);
out.write("<!-- thread end -->\n"); out.write("<!-- thread end -->\n");
written++; written++;
@ -302,4 +302,5 @@ public class ViewThreadedServlet extends BaseServlet {
return "&nbsp;"; return "&nbsp;";
} }
protected String getTitle() { return "Syndie :: View threads"; }
} }