summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKatolaZ <katolaz@freaknet.org>2017-07-08 07:47:51 +0100
committerKatolaZ <katolaz@freaknet.org>2017-07-08 07:47:51 +0100
commita6a9f827dee9c98c70aee5bd51f7f7d16f3b8368 (patch)
tree4cd40d5d8f2bcec09479b2d9f1cfc18c5b81e87d
parent363384c445c2b74593cb7b6b153f3cf2463ccd48 (diff)
Fixed form parsing and template escaping
-rw-r--r--binnit.go79
-rw-r--r--templ.go34
2 files changed, 53 insertions, 60 deletions
diff --git a/binnit.go b/binnit.go
index 8ab6d12..4f3786d 100644
--- a/binnit.go
+++ b/binnit.go
@@ -9,51 +9,46 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
- * You should have received a copy of the GNU Affero General Public
+ * You should have received a copy of the GNU Affero General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/>.
*
* (c) Vincenzo "KatolaZ" Nicosia 2017 -- <katolaz@freaknet.org>
- *
- *
- * This file is part of "binnit", a minimal no-fuss pastebin-like
+ *
+ *
+ * This file is part of "binnit", a minimal no-fuss pastebin-like
* server written in golang
*
*/
-
package main
import (
+ "binnit/paste"
+ "flag"
"fmt"
+ "html"
+ "io"
"log"
"net/http"
"os"
"path/filepath"
"time"
- "io"
- "binnit/paste"
- "flag"
)
-
var conf_file = flag.String("c", "./binnit.cfg", "Configuration file for binnit")
-
-
var p_conf = Config{
server_name: "localhost",
- bind_addr: "0.0.0.0",
- bind_port: "8000",
- paste_dir: "./pastes",
- templ_dir: "./tmpl",
- max_size: 4096,
- log_file: "./binnit.log",
+ bind_addr: "0.0.0.0",
+ bind_port: "8000",
+ paste_dir: "./pastes",
+ templ_dir: "./tmpl",
+ max_size: 4096,
+ log_file: "./binnit.log",
}
-
-
-func min (a, b int) int {
+func min(a, b int) int {
if a > b {
return b
@@ -71,16 +66,20 @@ func handle_get_paste(w http.ResponseWriter, r *http.Request) {
paste_name = p_conf.paste_dir + "/" + orig_name
orig_IP := r.RemoteAddr
-
+
log.Printf("Received GET from %s for '%s'\n", orig_IP, orig_name)
// The default is to serve index.html
if (orig_name == "/") || (orig_name == "/index.html") {
- http.ServeFile(w, r, p_conf.templ_dir + "/index.html")
+ http.ServeFile(w, r, p_conf.templ_dir+"/index.html")
} else {
// otherwise, if the requested paste exists, we serve it...
title, date, content, err := paste.Retrieve(paste_name)
+
+ title = html.EscapeString(title)
+ date = html.EscapeString(date)
+ content = html.EscapeString(content)
if err == nil {
s, err := prepare_paste_page(title, date, content, p_conf.templ_dir)
@@ -101,34 +100,37 @@ func handle_get_paste(w http.ResponseWriter, r *http.Request) {
func handle_put_paste(w http.ResponseWriter, r *http.Request) {
-
- if err := r.ParseForm(); err != nil {
+ err1 := r.ParseForm()
+ err2 := r.ParseMultipartForm(int64(2 * p_conf.max_size))
+
+ if err1 != nil && err2 != nil {
// Invalid POST -- let's serve the default file
- http.ServeFile(w, r, p_conf.templ_dir + "/index.html")
+ http.ServeFile(w, r, p_conf.templ_dir+"/index.html")
} else {
req_body := r.PostForm
orig_IP := r.RemoteAddr
log.Printf("Received new POST from %s\n", orig_IP)
-
+
// get title, body, and time
title := req_body.Get("title")
date := time.Now().String()
content := req_body.Get("paste")
-
+
content = content[0:min(len(content), int(p_conf.max_size))]
ID, err := paste.Store(title, date, content, p_conf.paste_dir)
-
+
+ log.Printf(" title: %s\npaste: %s\n", title, content)
log.Printf(" ID: %s; err: %s\n", ID, err)
- if err == nil {
+ if err == nil {
hostname := p_conf.server_name
if show := req_body.Get("show"); show != "1" {
- fmt.Fprintf(w, "http://%s/%s", hostname, ID)
+ fmt.Fprintf(w, "http://%s/%s\n", hostname, ID)
return
- } else{
+ } else {
fmt.Fprintf(w, "<html><body>Link: <a href='http://%s/%s'>http://%s/%s</a></body></html>",
hostname, ID, hostname, ID)
return
@@ -139,7 +141,6 @@ func handle_put_paste(w http.ResponseWriter, r *http.Request) {
}
}
-
func req_handler(w http.ResponseWriter, r *http.Request) {
switch r.Method {
@@ -152,23 +153,19 @@ func req_handler(w http.ResponseWriter, r *http.Request) {
}
}
-
-
func main() {
-
flag.Parse()
parse_config(*conf_file, &p_conf)
-
- f, err := os.OpenFile(p_conf.log_file, os.O_APPEND | os.O_CREATE | os.O_RDWR, 0600)
+
+ f, err := os.OpenFile(p_conf.log_file, os.O_APPEND|os.O_CREATE|os.O_RDWR, 0600)
if err != nil {
fmt.Fprintf(os.Stderr, "Error opening log_file: %s. Exiting\n", p_conf.log_file)
os.Exit(1)
}
defer f.Close()
-
log.SetOutput(io.Writer(f))
log.SetPrefix("[binnit]: ")
log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds)
@@ -176,13 +173,13 @@ func main() {
log.Println("Binnit version 0.1 -- Starting ")
log.Printf(" + Config file: %s\n", *conf_file)
log.Printf(" + Serving pastes on: %s\n", p_conf.server_name)
- log.Printf(" + listening on: %s:%s\n", p_conf.bind_addr, p_conf.bind_port )
+ log.Printf(" + listening on: %s:%s\n", p_conf.bind_addr, p_conf.bind_port)
log.Printf(" + paste_dir: %s\n", p_conf.paste_dir)
log.Printf(" + templ_dir: %s\n", p_conf.templ_dir)
log.Printf(" + max_size: %d\n", p_conf.max_size)
// FIXME: create paste_dir if it does not exist
-
+
http.HandleFunc("/", req_handler)
- log.Fatal(http.ListenAndServe(p_conf.bind_addr + ":" + p_conf.bind_port, nil))
+ log.Fatal(http.ListenAndServe(p_conf.bind_addr+":"+p_conf.bind_port, nil))
}
diff --git a/templ.go b/templ.go
index 0151c71..d5ea3d4 100644
--- a/templ.go
+++ b/templ.go
@@ -9,19 +9,18 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
- * You should have received a copy of the GNU Affero General Public
+ * You should have received a copy of the GNU Affero General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/>.
*
* (c) Vincenzo "KatolaZ" Nicosia 2017 -- <katolaz@freaknet.org>
- *
- *
- * This file is part of "binnit", a minimal no-fuss pastebin-like
+ *
+ *
+ * This file is part of "binnit", a minimal no-fuss pastebin-like
* server written in golang
*
*/
-
/*
*
* minimal Templating support for binnit
@@ -35,29 +34,28 @@ import (
"io/ioutil"
"os"
"regexp"
- "strings"
"strconv"
+ "strings"
)
-func format_rows(content string) (string) {
+func format_rows(content string) string {
var ret string
lines := strings.Split(content, "\n")
ret += "<table class='content'>"
-
+
for l_num, l := range lines {
ret += "<tr>\n"
- ret += "<td class='lineno'><pre>"+ strconv.Itoa(l_num+1) + "</pre></td>"
- ret += "<td class='line'><pre>"+ l +"</pre></td>"
+ ret += "<td class='lineno'><pre>" + strconv.Itoa(l_num+1) + "</pre></td>"
+ ret += "<td class='line'><pre>" + l + "</pre></td>"
ret += "</tr>"
}
ret += "</table>"
return ret
}
-
func prepare_paste_page(title, date, content, templ_dir string) (string, error) {
s := ""
@@ -83,28 +81,26 @@ func prepare_paste_page(title, date, content, templ_dir string) (string, error)
f_templ, err := os.Open(templ_file)
defer f_templ.Close()
-
if cont, err := ioutil.ReadFile(templ_file); err == nil {
tmpl := string(cont)
- // ...and replace {{CONTENT}} with the paste itself!
re, _ := regexp.Compile("{{TITLE}}")
- tmpl = string(re.ReplaceAll([]byte(tmpl), []byte(title)))
+ tmpl = string(re.ReplaceAllLiteralString(tmpl, title))
re, _ = regexp.Compile("{{DATE}}")
- tmpl = string(re.ReplaceAll([]byte(tmpl), []byte(date)))
+ tmpl = string(re.ReplaceAllLiteralString(tmpl, date))
re, _ = regexp.Compile("{{CONTENT}}")
- tmpl = string(re.ReplaceAll([]byte(tmpl), []byte(format_rows(content))))
+ tmpl = string(re.ReplaceAllLiteralString(tmpl, format_rows(content)))
re, _ = regexp.Compile("{{RAW_CONTENT}}")
- tmpl = string(re.ReplaceAll([]byte(tmpl), []byte(content)))
+ tmpl = string(re.ReplaceAllLiteralString(tmpl, content))
s += tmpl
-
+
} else {
return "", errors.New("Error opening template file")
}
-
+
// insert footer
foot_file := templ_dir + "/footer.html"
f_foot, err := os.Open(foot_file)