|
|
@@ -108,6 +108,46 @@ func dispatchAPIRequestHandler(
|
|
|
}
|
|
|
}()
|
|
|
|
|
|
+ // Before invoking the handlers, enforce some preconditions:
|
|
|
+ //
|
|
|
+ // - A handshake request must preceed any other requests.
|
|
|
+ // - When the handshake results in a traffic rules state where
|
|
|
+ // the client is immediately exhausted, no requests
|
|
|
+ // may succeed. This case ensures that blocked clients do
|
|
|
+ // not log "connected", etc.
|
|
|
+ //
|
|
|
+ // Note that sshClient.setHandshakeState enforces that only a
|
|
|
+ // single handshake is made; enforcing that there ensures no
|
|
|
+ // race condition even if concurrent requests are in flight.
|
|
|
+
|
|
|
+ if name != protocol.PSIPHON_API_HANDSHAKE_REQUEST_NAME {
|
|
|
+
|
|
|
+ // TODO: same session-ID-lookup TODO in handshakeAPIRequestHandler
|
|
|
+ // applies here.
|
|
|
+
|
|
|
+ sessionID, err := getStringRequestParam(params, "client_session_id")
|
|
|
+ if err == nil {
|
|
|
+ // Note: follows/duplicates baseRequestParams validation
|
|
|
+ if !isHexDigits(support, sessionID) {
|
|
|
+ err = errors.New("invalid param: client_session_id")
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if err != nil {
|
|
|
+ return nil, common.ContextError(err)
|
|
|
+ }
|
|
|
+
|
|
|
+ completed, exhausted, err := support.TunnelServer.GetClientHandshaked(sessionID)
|
|
|
+ if err != nil {
|
|
|
+ return nil, common.ContextError(err)
|
|
|
+ }
|
|
|
+ if !completed {
|
|
|
+ return nil, common.ContextError(errors.New("handshake not completed"))
|
|
|
+ }
|
|
|
+ if exhausted {
|
|
|
+ return nil, common.ContextError(errors.New("exhausted after handshake"))
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
switch name {
|
|
|
case protocol.PSIPHON_API_HANDSHAKE_REQUEST_NAME:
|
|
|
return handshakeAPIRequestHandler(support, apiProtocol, geoIPData, params)
|
|
|
@@ -147,8 +187,6 @@ func handshakeAPIRequestHandler(
|
|
|
params,
|
|
|
baseRequestParams))
|
|
|
|
|
|
- // Note: ignoring param format errors as params have been validated
|
|
|
-
|
|
|
sessionID, _ := getStringRequestParam(params, "client_session_id")
|
|
|
sponsorID, _ := getStringRequestParam(params, "sponsor_id")
|
|
|
clientVersion, _ := getStringRequestParam(params, "client_version")
|
|
|
@@ -509,7 +547,7 @@ const (
|
|
|
// is specified, in which case an array of string is expected.
|
|
|
var baseRequestParams = []requestParamSpec{
|
|
|
requestParamSpec{"server_secret", isServerSecret, requestParamNotLogged},
|
|
|
- requestParamSpec{"client_session_id", isHexDigits, requestParamOptional | requestParamNotLogged},
|
|
|
+ requestParamSpec{"client_session_id", isHexDigits, requestParamNotLogged},
|
|
|
requestParamSpec{"propagation_channel_id", isHexDigits, 0},
|
|
|
requestParamSpec{"sponsor_id", isHexDigits, 0},
|
|
|
requestParamSpec{"client_version", isIntString, 0},
|