From a6a9f827dee9c98c70aee5bd51f7f7d16f3b8368 Mon Sep 17 00:00:00 2001 From: KatolaZ Date: Sat, 8 Jul 2017 07:47:51 +0100 Subject: Fixed form parsing and template escaping --- binnit.go | 79 ++++++++++++++++++++++++++++++--------------------------------- templ.go | 34 ++++++++++++--------------- 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 * . * * (c) Vincenzo "KatolaZ" Nicosia 2017 -- - * - * - * 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, "Link: http://%s/%s", 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 * . * * (c) Vincenzo "KatolaZ" Nicosia 2017 -- - * - * - * 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 += "" - + for l_num, l := range lines { ret += "\n" - ret += "" - ret += "" + ret += "" + ret += "" ret += "" } ret += "
"+ strconv.Itoa(l_num+1) + "
"+ l +"
" + strconv.Itoa(l_num+1) + "
" + l + "
" 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) -- cgit v1.2.3