Просмотр исходного кода

Recover from panics within API calls
* Defense in depth against malicious input.
* Standard panic behavior very undesirable since it
terminates all client sessions.
* Covers both SSH and web API request mechanisms, with
consistent logging.

Rod Hynes 9 лет назад
Родитель
Сommit
67103fc646
2 измененных файлов с 44 добавлено и 8 удалено
  1. 24 0
      psiphon/server/api.go
  2. 20 8
      psiphon/server/webServer.go

+ 24 - 0
psiphon/server/api.go

@@ -25,6 +25,7 @@ import (
 	"fmt"
 	"net"
 	"regexp"
+	"runtime/debug"
 	"strconv"
 	"strings"
 	"unicode"
@@ -71,6 +72,29 @@ func sshAPIRequestHandler(
 			fmt.Errorf("invalid payload for request name: %s: %s", name, err))
 	}
 
+	return dispatchAPIRequestHandler(support, geoIPData, name, params)
+}
+
+// dispatchAPIRequestHandler is the common dispatch point for both
+// web and SSH API requests.
+func dispatchAPIRequestHandler(
+	support *SupportServices,
+	geoIPData GeoIPData,
+	name string,
+	params requestJSONObject) (response []byte, reterr error) {
+
+	// Recover from and log any unexpected panics causes by user input
+	// handling bugs. User inputs shuld be properly validated; this
+	// mechanism is only a last resort to prevent the process from
+	// terminating in the case of a bug.
+	defer func() {
+		if e := recover(); e != nil {
+			reterr = common.ContextError(
+				fmt.Errorf(
+					"request handler panic: %s: %s", e, debug.Stack()))
+		}
+	}()
+
 	switch name {
 	case common.PSIPHON_API_HANDSHAKE_REQUEST_NAME:
 		return handshakeAPIRequestHandler(support, geoIPData, params)

+ 20 - 8
psiphon/server/webServer.go

@@ -225,8 +225,11 @@ func (webServer *webServer) handshakeHandler(w http.ResponseWriter, r *http.Requ
 
 	var responsePayload []byte
 	if err == nil {
-		responsePayload, err = handshakeAPIRequestHandler(
-			webServer.support, webServer.lookupGeoIPData(params), params)
+		responsePayload, err = dispatchAPIRequestHandler(
+			webServer.support,
+			webServer.lookupGeoIPData(params),
+			common.PSIPHON_API_HANDSHAKE_REQUEST_NAME,
+			params)
 	}
 
 	if err != nil {
@@ -251,8 +254,11 @@ func (webServer *webServer) connectedHandler(w http.ResponseWriter, r *http.Requ
 
 	var responsePayload []byte
 	if err == nil {
-		responsePayload, err = connectedAPIRequestHandler(
-			webServer.support, webServer.lookupGeoIPData(params), params)
+		responsePayload, err = dispatchAPIRequestHandler(
+			webServer.support,
+			webServer.lookupGeoIPData(params),
+			common.PSIPHON_API_CONNECTED_REQUEST_NAME,
+			params)
 	}
 
 	if err != nil {
@@ -270,8 +276,11 @@ func (webServer *webServer) statusHandler(w http.ResponseWriter, r *http.Request
 	params, err := convertHTTPRequestToAPIRequest(w, r, "statusData")
 
 	if err == nil {
-		_, err = statusAPIRequestHandler(
-			webServer.support, webServer.lookupGeoIPData(params), params)
+		_, err = dispatchAPIRequestHandler(
+			webServer.support,
+			webServer.lookupGeoIPData(params),
+			common.PSIPHON_API_STATUS_REQUEST_NAME,
+			params)
 	}
 
 	if err != nil {
@@ -289,8 +298,11 @@ func (webServer *webServer) clientVerificationHandler(w http.ResponseWriter, r *
 
 	var responsePayload []byte
 	if err == nil {
-		responsePayload, err = clientVerificationAPIRequestHandler(
-			webServer.support, webServer.lookupGeoIPData(params), params)
+		responsePayload, err = dispatchAPIRequestHandler(
+			webServer.support,
+			webServer.lookupGeoIPData(params),
+			common.PSIPHON_API_CLIENT_VERIFICATION_REQUEST_NAME,
+			params)
 	}
 
 	if err != nil {