From 3c09af9cc854c716d9f772d1c8c1e568cacc92b9 Mon Sep 17 00:00:00 2001
From: Ian Kelling <ian@iankelling.org>
Date: Thu, 25 Aug 2016 22:26:34 -0700
Subject: [PATCH] use cgi dir for better security

---
 _site/{comment.rb => cgi/comment} | 26 +++++++++++++++-----------
 b.rb                              |  9 +++++----
 build.rb                          |  4 +++-
 setup.sh                          | 11 +++++++++--
 4 files changed, 32 insertions(+), 18 deletions(-)
 rename _site/{comment.rb => cgi/comment} (92%)

diff --git a/_site/comment.rb b/_site/cgi/comment
similarity index 92%
rename from _site/comment.rb
rename to _site/cgi/comment
index 14f1152..b1e8796 100755
--- a/_site/comment.rb
+++ b/_site/cgi/comment
@@ -27,9 +27,12 @@ require 'fileutils'
 require 'time'
 require 'sqlite3'
 
-require_relative '../b'
+Dir.chdir(File.join(File.dirname(__FILE__), '..'))
+
+require '../b'
 include B
 
+
 # constanty things
 DEBUG = true
 CAPTCHA = -> {
@@ -77,11 +80,11 @@ EOF
 def do_captcha
   captcha_q = CAPTCHA.sample[0]
   puts "Content-type: text/html\n\n"
-  puts skel('comment.rb', "#{DN}/captcha", <<EOF, ' / <a href="/blog.html">blog</a> / comment-captcha')
+  puts skel("#{DN}/captcha", <<EOF, header: ' / <a href="/blog.html">blog</a> / captcha')
 <p>Hello friend. I haven't read a post from #{IP}, and I only remember for a few months, so:</p>
 <p>#{captcha_q}</p>
 
-<form action="/comment.rb" method="post">
+<form action="/cgi/comment" method="post">
   <input class="misc" type="text" name="url">
   <input name="goto" type="hidden" value="#{GOTO}">
   <input name="question" type="hidden" value="#{captcha_q}">
@@ -106,7 +109,6 @@ def fail(msg)
 end
 
 def redir
-  File.write('/tmp/x', GOTO)
   puts 'Status: 302 Found'
   puts "Location: #{GOTO}#comment-section\n\n"
   exit(0)
@@ -126,18 +128,18 @@ if cgi.has_key?('goto')
   GOTO = cgi['goto']
 else
   GOTO = '/'
-  fail['redir to /']
+  fail('redir to /')
 end
 
 if (cgi.has_key?('url') && cgi['url'] != "") || ! cgi.has_key?('comment')
-  fail["comment not in form or url in form. cgi.params: #{cgi.params}"]
+  fail("comment not in form or url in form. cgi.params: #{cgi.params}")
 end
 
 COMMENT_TXT = cgi["comment"]
 
 
 if COMMENT_TXT.length > 1000 or GOTO.length > 150
-  fail['length of comment or goto is too great']
+  fail('length of comment or goto is too great')
 end
 
 
@@ -154,12 +156,12 @@ end
   found = false
   Dir.foreach('blog') do |entry|
     next if ['.','..'].any? { |f| f == entry }
-    if GOTO == 'blog/' + entry
+    if GOTO == '/blog/' + entry
       found = true
       break
     end
   end
-  fail['goto entry not found'] unless found
+  fail('goto entry not found') unless found
 }[]
 ######### end error checking & arg parsing ########
 
@@ -194,18 +196,20 @@ SQL
 
 unless state
   older_date = NOW - DAY*2
-  last_moderated = $db.execute(<<-SQL, [older_date])[-1][0]
+  last_moderated = $db.execute(<<-SQL, [older_date])[-1]
   select date from c
   where ip = '#{IP}' and (
     state = 'moderated' or
     (date < ? and (state = 'timed' or state = 'known')))
 SQL
-  last_good = $db.execute(<<-SQL, [older_date])[-1][0]
+  last_moderated = last_moderated[0] if last_moderated
+  last_good = $db.execute(<<-SQL, [older_date])[-1]
   select date from c
   where ip = '#{IP}' and (
     state = 'picked' or
     (date < ? and (state = 'timed' or state = 'known')))
 SQL
+  last_good = last_good[0] if last_good
   if last_moderated && last_good
     if last_good > last_moderated
       state = 'known'
diff --git a/b.rb b/b.rb
index 511ac8d..2a612a6 100644
--- a/b.rb
+++ b/b.rb
@@ -49,6 +49,7 @@ module B # blog module
   end
 
   def fwrite(output_path, string)
+    output_path = File.join('./', output_path)
     FileUtils.mkdir_p(File.dirname(output_path))
     File.write(output_path, string)
   end
@@ -161,11 +162,11 @@ EOF
     b = File.basename(file,'.md')
     # date is in the format: YYYY-MM-DD-
     date = Time.parse(b[0..DATE_LEN])
-    rel_path = "blog/#{b[(DATE_LEN + 1)..-1]}.html"
+    rel_path = "/blog/#{b[(DATE_LEN + 1)..-1]}.html"
     comments = $db.execute <<-SQL, [WAIT_DATE]
       select comment, date from c
       where page = '#{rel_path}' and (
-       state = 'picked' or state = 'known'
+       state = 'picked' or state = 'known' or state = 'timed'
        or (state = 'waiting' and date < ?))
 SQL
     # get earliest comment. earlier ones stored in git will also be
@@ -221,7 +222,7 @@ EOF
         comment_html("Note: there #{text} pending approval.", NOW)
     end
     com_section = <<-EOF
-      <form class="comment" action="/comment.rb" method="post">
+      <form class="comment" action="/cgi/comment" method="post">
         <input class="misc" type="text" name="url">
         <input name="goto" type="hidden" value="#{rel_path}">
         <textarea rows="10" name="comment" placeholder="markdown" maxlength="1000"></textarea>
@@ -270,7 +271,7 @@ EOF
           footer: footer_extra,
           comments: com_section,
           description: description)
-    url="#{DURL}/#{rel_path}"
+    url="#{DURL}#{rel_path}"
 
 
     # following from https://creativecommons.org/choose,
diff --git a/build.rb b/build.rb
index 4a6c268..4025eef 100755
--- a/build.rb
+++ b/build.rb
@@ -84,6 +84,8 @@ stdpage('blog', <<EOF)
 </ul>
 EOF
 
-stdpage('resume', md_to_html(File.read('../resume.md')))
+if File.exists? ('../resume.md')
+  stdpage('resume', md_to_html(File.read('../resume.md')))
+end
 
 stdpage('favorite-stuff', File.read('../favorite-stuff.html'))
diff --git a/setup.sh b/setup.sh
index 3230bba..66953c5 100755
--- a/setup.sh
+++ b/setup.sh
@@ -20,7 +20,8 @@
 set -eE -o pipefail
 trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR
 
-cd "${BASH_SOURCE%/*}"
+script_dir=$(readlink -f "${BASH_SOURCE%/*}")
+cd "$script_dir"
 
 domain=${1:-iankelling.org} # use argument for testing site
 gitroot=/a/bin/githtml
@@ -91,6 +92,11 @@ apache-site - $domain <<EOF
   AddHandler cgi-script .py
 </Directory>
 
+<Directory "/var/www/$domain/html/cgi">
+  Options +ExecCGI
+  SetHandler cgi-script
+</Directory>
+
 # redirect some old paths when I was using jekyll.
 Redirect permanent /10-14-2014/On2-vote-results.html /blog/on2-vote-results.html
 Redirect permanent /09-29-2014/say-On2.html /blog/say-on2.html
@@ -178,4 +184,5 @@ gitweb_descriptions() {
 
 gitweb_descriptions
 
-./build.rb
+$script_dir/build.rb
+s lnf -T $script_dir/_site /var/www/$domain/html
-- 
2.30.2