func defaultIcap(w icap.ResponseWriter, req *icap.Request) { local_debug := false if strings.Contains(req.URL.RawQuery, "debug=1") { local_debug = true } h := w.Header() h.Set("ISTag", ISTag) h.Set("Service", "Shadower default ICAP service") if *debug || local_debug { fmt.Fprintln(os.Stderr, "Printing the full ICAP request") fmt.Fprintln(os.Stderr, req) fmt.Fprintln(os.Stderr, req.Request) } switch req.Method { case "OPTIONS": h.Set("Methods", "REQMOD, RESPMOD") h.Set("Options-TTL", "1800") h.Set("Allow", "204") h.Set("Preview", "0") h.Set("Transfer-Preview", "*") h.Set("Max-Connections", *maxConnections) h.Set("This-Server", "Default ICAP url which bypass all requests adaptation") h.Set("X-Include", "X-Client-IP, X-Authenticated-Groups, X-Authenticated-User, X-Subscriber-Id, X-Server-IP") w.WriteHeader(200, nil, false) case "REQMOD": if *debug || local_debug { fmt.Fprintln(os.Stderr, "Default REQMOD, you should use the apropriate ICAP service URL") } w.WriteHeader(204, nil, false) case "RESPMOD": if *debug || local_debug { fmt.Fprintln(os.Stderr, "Default RESPMOD, you should use the apropriate ICAP service URL") } w.WriteHeader(204, nil, false) default: w.WriteHeader(405, nil, false) if *debug || local_debug { fmt.Fprintln(os.Stderr, "Invalid request method") } } }
func toGolang(w icap.ResponseWriter, req *icap.Request) { h := w.Header() h.Set("ISTag", ISTag) h.Set("Service", "Golang redirector") switch req.Method { case "OPTIONS": h.Set("Methods", "REQMOD") h.Set("Allow", "204") h.Set("Preview", "0") h.Set("Transfer-Preview", "*") w.WriteHeader(200, nil, false) case "REQMOD": switch req.Request.Host { case "gateway": // Run a fake HTTP server called gateway. icap.ServeLocally(w, req) case "java.com", "www.java.com": // Redirect the user to a more interesting language. req.Request.Host = "golang.org" req.Request.URL.Host = "golang.org" w.WriteHeader(200, req.Request, false) // TODO: copy the body (if any) from the original request. default: // Return the request unmodified. w.WriteHeader(204, nil, false) } case "ERRDUMMY": w.WriteHeader(400, nil, false) fmt.Println("Malformed request") default: w.WriteHeader(405, nil, false) fmt.Println("Invalid request method") } }
func toShadowD(w icap.ResponseWriter, req *icap.Request) { local_debug := false if strings.Contains(req.URL.RawQuery, "debug=1") { local_debug = true } h := w.Header() h.Set("ISTag", ISTag) h.Set("Service", "Shadower ICAP to WAF Connector") if *debug { fmt.Fprintln(os.Stderr, "Printing the full ICAP request") fmt.Fprintln(os.Stderr, req) fmt.Fprintln(os.Stderr, req.Request) fmt.Fprintln(os.Stderr, req.Response) } switch req.Method { case "OPTIONS": h.Set("Methods", "REQMOD") h.Set("Options-TTL", "1800") h.Set("Allow", "204, 206") h.Set("Preview", "0") h.Set("Transfer-Preview", "*") h.Set("Max-Connections", *maxConnections) h.Set("X-Include", "X-Client-Ip, X-Authenticated-Groups, X-Authenticated-User, X-Subscriber-Id") w.WriteHeader(200, nil, false) case "REQMOD": modified := false nullBody := false allow206 := false allow204 := false xclientip := false if _, allow204Exists := req.Header["Allow"]; allow204Exists { if strings.Contains(req.Header["Allow"][0], "204") { allow204 = true } } if _, allow206Exists := req.Header["Allow"]; allow206Exists { if strings.Contains(req.Header["Allow"][0], "206") { allow206 = true } } if _, xclientipExists := req.Header["X-Client-Ip"]; xclientipExists { if len(req.Header["X-Client-Ip"][0]) > 1 { xclientip = true } } if _, encapsulationExists := req.Header["Encapsulated"]; encapsulationExists { if strings.Contains(req.Header["Encapsulated"][0], "null-body=") { nullBody = true } } if *debug || local_debug { for k, v := range req.Header { fmt.Fprintln(os.Stderr, "The ICAP headers:") fmt.Fprintln(os.Stderr, "key size:", len(req.Header[k])) fmt.Fprintln(os.Stderr, "key:", k, "value:", v) } } _, _, _, _ = nullBody, allow206, modified, allow204 if xclientip { req.Request.RemoteAddr = req.Header["X-Client-Ip"][0] } if wrongMethod(req) { if *debug { fmt.Println("This request has a", req.Request.Method, "method which is not being analyzed") } w.WriteHeader(204, nil, false) return } if *debug || local_debug { for k, v := range req.Request.Header { fmt.Fprintln(os.Stderr, "key:", k, "value:", v) } } // Send the request to ShadowD // If an attack(5,6) was declared then send a custom 500 page // If OK then send a 204 back var resStatus = 1 shodowdres, err := shadowServer.SendToShadowd(req.Request) newmap := make(map[string]interface{}) err = json.Unmarshal([]byte(shodowdres), &newmap) if err != nil { panic(err) } switch int(newmap["status"].(float64)) { case shadowd.STATUS_OK: if *debug || local_debug { fmt.Println("Request reported, OK") } w.WriteHeader(204, nil, false) return case shadowd.STATUS_BAD_REQUEST: resStatus = 400 case shadowd.STATUS_BAD_SIGNATURE: resStatus = 503 case shadowd.STATUS_BAD_JSON: resStatus = 504 case shadowd.STATUS_ATTACK: resStatus = 505 case shadowd.STATUS_CRITICAL_ATTACK: resStatus = 506 default: resStatus = 500 } resp := new(http.Response) resp.Status = "Internal Server Error" resp.StatusCode = resStatus resp.Proto = req.Request.Proto resp.ProtoMajor = req.Request.ProtoMajor resp.ProtoMinor = req.Request.ProtoMinor resp.Request = req.Request myHeaderMap := make(map[string][]string) resp.Header = myHeaderMap resp.Header.Set("X-Ngtech-Proxy", "Shadower") resp.Header.Set("X-Shadower", strconv.Itoa(resStatus)) resp.Header.Set("Content-Type", "text/html") resp.Header.Set("Content-Length", strconv.Itoa(len(internalerrorpage))) w.WriteHeader(200, resp, true) io.WriteString(w, internalerrorpage) return if *debug { fmt.Println("end of the line 204 response!.. Shouldn't happen.") } w.WriteHeader(204, nil, false) return case "RESPMOD": w.WriteHeader(204, nil, false) return default: w.WriteHeader(405, nil, false) if *debug || local_debug { fmt.Fprintln(os.Stderr, "Invalid request method") } } }