-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.go
180 lines (147 loc) · 5.27 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
package main
import (
"flag"
"github.com/dchest/captcha"
"github.com/gorilla/csrf"
"github.com/gorilla/mux"
"log"
"math/rand"
"net"
"net/http"
"net/http/fcgi"
"os"
"time"
)
var (
mandrillApiUrl string
mandrillKey string
casgoDestination string
casgoAPIKey string
)
type C struct {
CaptchaId string
}
const (
// Default number of digits in captcha solution.
DefaultLen = 6
// The number of captchas created that triggers garbage collection used
// by default store.
CollectNum = 100
// Expiration time of captchas used by default store.
Expiration = 10 * time.Minute
)
const (
// Standard width and height of a captcha image.
StdWidth = 240
StdHeight = 80
)
func main() {
// We can set the CASGO_API_KEY environment variable, or it defaults to a new random one!
if os.Getenv("CASGO_API_KEY") == "" {
log.Println("Generating Random API Key...")
// The length of the API key can be modified here.
casgoAPIKey = GenerateAPIKey(20)
// Print new GenerateAPIKey
log.Println("CASGO_API_KEY:", getKey())
} else {
casgoAPIKey = os.Getenv("CASGO_API_KEY")
// Print selected CASGO_API_KEY
log.Println("CASGO_API_KEY:", getKey())
}
//
port := flag.String("port", "8080", "HTTP Port to listen on")
debug := flag.Bool("debug", false, "be verbose, dont switch to logfile")
insecure := flag.Bool("insecure", false, "accept insecure cookie transfer")
mailbox := flag.Bool("mailbox", false, "save messages to an local mbox file")
fastcgi := flag.Bool("fastcgi", false, "use fastcgi")
bind := flag.String("bind", "127.0.0.1", "default: 127.0.0.1")
flag.Parse()
mandrillApiUrl = "https://mandrillapp.com/api/1.0/"
mandrillKey = os.Getenv("MANDRILL_KEY")
if mandrillKey == "" {
log.Fatal("MANDRILL_KEY is Crucial. Type: export MANDRILL_KEY=123456789")
os.Exit(1)
}
casgoDestination = os.Getenv("CASGO_DESTINATION")
if casgoDestination == "" {
log.Fatal("CASGO_DESTINATION is Crucial. Type: export CASGO_DESTINATION=\"[email protected]\"")
os.Exit(1)
}
log.Printf("listening on https://127.0.0.1:%s", *port)
r := mux.NewRouter()
// Custom 404 redirect to /
r.NotFoundHandler = http.HandlerFunc(RedirectHomeHandler)
// Should be called BlankPageHandler
r.HandleFunc("/", HomeHandler)
// This is the meat, for behind a reverse proxy.
r.HandleFunc("/"+casgoAPIKey+"/form", ContactHandler)
r.HandleFunc("/"+casgoAPIKey+"/form/", ContactHandler)
// r.HandleFunc("/contact/", ContactHandler)
// Magic URL Generator for API endpoint
r.HandleFunc("/"+casgoAPIKey+"/send", EmailHandler)
//r.Methods("GET").PathPrefix("/captcha2").Handler(captcha.Server(captcha.StdWidth, captcha.StdHeight))
// Fun for 404s
r.HandleFunc("/{whatever}", LoveHandler)
r.Methods("GET").PathPrefix("/captcha/").Handler(captcha.Server(captcha.StdWidth, captcha.StdHeight))
//http.Handle("/captcha/", captcha.Server(captcha.StdWidth, captcha.StdHeight))
http.Handle("/", r)
//r.HandleFunc("/captcha/",captcha.Server(captcha.StdWidth, captcha.StdHeight))
// Switch to file log so we can ctrl+c and launch another instance :)
if *mailbox == true {
log.Println("mailbox mode: [sending mail to casgo.mbox]")
//CreateMailBox()
}
if *debug == false {
log.Println("quiet mode: [switching logs to casgo.log]")
OpenLogFile()
} else {
log.Println("debug on: [not using casgo.log]")
}
if *fastcgi == true {
log.Println("fastcgi [on]")
log.Println("secure [off]")
listener, err := net.Listen("tcp", *bind+":"+*port)
if err != nil {
log.Fatal("Could not bind: ", err)
}
log.Println("info: Listening on", *port)
// fcgi.Serve(listener, nil) // this works but without csrf..!
fcgi.Serve(listener, csrf.Protect([]byte("LI80PNK1xcT01jmQBsEyxyrNCrbyyFPjPU8CKnxwmCruxNijgnyb3hXXD3p1RBc0+LIRQUUbTtis6hc6LD4I/A=="), csrf.HttpOnly(true), csrf.Secure(false))(r))
//log.Fatal(fcgi.Serve( listener, csrf.Protect([]byte("LI80PNK1xcT01jmQBsEyxyrNCrbyyFPjPU8CKnxwmCruxNijgnyb3hXXD3p1RBc0+LIRQUUbTtis6hc6LD4I/A=="), csrf.HttpOnly(true), csrf.Secure(false))(r)))
} else if *insecure == true {
log.Println("info: Listening on", *port)
log.Println("secure [off]")
log.Fatal(http.ListenAndServe(":"+*port, csrf.Protect([]byte("LI80PNK1xcT01jmQBsEyxyrNCrbyyFPjPU8CKnxwmCruxNijgnyb3hXXD3p1RBc0+LIRQUUbTtis6hc6LD4I/A=="), csrf.HttpOnly(true), csrf.Secure(false))(r)))
} else {
log.Println("info: Listening on", *port)
// Change this CSRF auth token in production!
log.Println("secure [on]")
log.Fatal(http.ListenAndServe(":"+*port, csrf.Protect([]byte("LI80PNK1xcT01jmQBsEyxyrNCrbyyFPjPU8CKnxwmCruxNijgnyb3hXXD3p1RBc0+LIRQUUbTtis6hc6LD4I/A=="), csrf.HttpOnly(true), csrf.Secure(true))(r)))
}
}
// Key Generator
func init() {
rand.Seed(time.Now().UnixNano())
}
var runes = []rune("____ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890123456789012345678901234567890")
func GenerateAPIKey(n int) string {
b := make([]rune, n)
for i := range b {
b[i] = runes[rand.Intn(len(runes))]
}
return string(b)
}
// Which Key are we using again?
func getKey() string {
return casgoAPIKey
}
// This function opens a log file. "debug.log"
func OpenLogFile() {
f, err := os.OpenFile("./casgo.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0660)
if err != nil {
log.Fatal("error opening file: %v", err)
os.Exit(1)
}
log.SetOutput(f)
}
// This is the home page it is blank. "This server is broken"