Procházet zdrojové kódy

Merge pull request #194 from rod-hynes/master

end-to-end homepage test + bug fixes
Rod Hynes před 9 roky
rodič
revize
63e67b8648

+ 3 - 2
psiphon/server/api.go

@@ -495,11 +495,12 @@ func getJSONObjectRequestParam(params requestJSONObject, name string) (requestJS
 	if params[name] == nil {
 	if params[name] == nil {
 		return nil, psiphon.ContextError(fmt.Errorf("missing param: %s", name))
 		return nil, psiphon.ContextError(fmt.Errorf("missing param: %s", name))
 	}
 	}
-	value, ok := params[name].(requestJSONObject)
+	// TODO: can't use requestJSONObject type?
+	value, ok := params[name].(map[string]interface{})
 	if !ok {
 	if !ok {
 		return nil, psiphon.ContextError(fmt.Errorf("invalid param: %s", name))
 		return nil, psiphon.ContextError(fmt.Errorf("invalid param: %s", name))
 	}
 	}
-	return value, nil
+	return requestJSONObject(value), nil
 }
 }
 
 
 func getJSONObjectArrayRequestParam(params requestJSONObject, name string) ([]requestJSONObject, error) {
 func getJSONObjectArrayRequestParam(params requestJSONObject, name string) ([]requestJSONObject, error) {

+ 64 - 6
psiphon/server/server_test.go

@@ -106,9 +106,12 @@ func runServer(t *testing.T, runConfig *runServerConfig) {
 
 
 	// customize server config
 	// customize server config
 
 
+	psinetFilename, sponsorID, expectedHomepageURL := pavePsinetDatabaseFile(t)
+
 	var serverConfig interface{}
 	var serverConfig interface{}
 	json.Unmarshal(serverConfigJSON, &serverConfig)
 	json.Unmarshal(serverConfigJSON, &serverConfig)
 	serverConfig.(map[string]interface{})["GeoIPDatabaseFilename"] = ""
 	serverConfig.(map[string]interface{})["GeoIPDatabaseFilename"] = ""
+	serverConfig.(map[string]interface{})["PsinetDatabaseFilename"] = psinetFilename
 	serverConfig.(map[string]interface{})["TrafficRulesFilename"] = ""
 	serverConfig.(map[string]interface{})["TrafficRulesFilename"] = ""
 	serverConfigJSON, _ = json.Marshal(serverConfig)
 	serverConfigJSON, _ = json.Marshal(serverConfig)
 
 
@@ -155,13 +158,14 @@ func runServer(t *testing.T, runConfig *runServerConfig) {
 
 
 	// Note: calling LoadConfig ensures all *int config fields are initialized
 	// Note: calling LoadConfig ensures all *int config fields are initialized
 	clientConfigJSON := `
 	clientConfigJSON := `
-	{
-	"ClientVersion":                     "0",
-	"PropagationChannelId":              "0",
-	"SponsorId":                         "0"
-	}`
+    {
+        "ClientVersion" : "0",
+        "SponsorId" : "0",
+        "PropagationChannelId" : "0"
+    }`
 	clientConfig, _ := psiphon.LoadConfig([]byte(clientConfigJSON))
 	clientConfig, _ := psiphon.LoadConfig([]byte(clientConfigJSON))
 
 
+	clientConfig.SponsorId = sponsorID
 	clientConfig.ConnectionWorkerPoolSize = numTunnels
 	clientConfig.ConnectionWorkerPoolSize = numTunnels
 	clientConfig.TunnelPoolSize = numTunnels
 	clientConfig.TunnelPoolSize = numTunnels
 	clientConfig.DisableRemoteServerListFetcher = true
 	clientConfig.DisableRemoteServerListFetcher = true
@@ -181,6 +185,7 @@ func runServer(t *testing.T, runConfig *runServerConfig) {
 	}
 	}
 
 
 	tunnelsEstablished := make(chan struct{}, 1)
 	tunnelsEstablished := make(chan struct{}, 1)
+	homepageReceived := make(chan struct{}, 1)
 
 
 	psiphon.SetNoticeOutput(psiphon.NewNoticeReceiver(
 	psiphon.SetNoticeOutput(psiphon.NewNoticeReceiver(
 		func(notice []byte) {
 		func(notice []byte) {
@@ -201,6 +206,16 @@ func runServer(t *testing.T, runConfig *runServerConfig) {
 					default:
 					default:
 					}
 					}
 				}
 				}
+			case "Homepage":
+				homepageURL := payload["url"].(string)
+				if homepageURL != expectedHomepageURL {
+					// TODO: wrong goroutine for t.FatalNow()
+					t.Fatalf("unexpected homepage: %s", homepageURL)
+				}
+				select {
+				case homepageReceived <- *new(struct{}):
+				default:
+				}
 			}
 			}
 		}))
 		}))
 
 
@@ -229,7 +244,8 @@ func runServer(t *testing.T, runConfig *runServerConfig) {
 		}
 		}
 	}()
 	}()
 
 
-	// Test: tunnels must be established within 30 seconds
+	// Test: tunnels must be established, and correct homepage
+	// must be received, within 30 seconds
 
 
 	establishTimeout := time.NewTimer(30 * time.Second)
 	establishTimeout := time.NewTimer(30 * time.Second)
 	select {
 	select {
@@ -238,6 +254,12 @@ func runServer(t *testing.T, runConfig *runServerConfig) {
 		t.Fatalf("tunnel establish timeout exceeded")
 		t.Fatalf("tunnel establish timeout exceeded")
 	}
 	}
 
 
+	select {
+	case <-homepageReceived:
+	case <-establishTimeout.C:
+		t.Fatalf("homepage received timeout exceeded")
+	}
+
 	// Test: tunneled web site fetch
 	// Test: tunneled web site fetch
 
 
 	testUrl := "https://psiphon.ca"
 	testUrl := "https://psiphon.ca"
@@ -266,3 +288,39 @@ func runServer(t *testing.T, runConfig *runServerConfig) {
 	}
 	}
 	response.Body.Close()
 	response.Body.Close()
 }
 }
+
+func pavePsinetDatabaseFile(t *testing.T) (string, string, string) {
+
+	psinetFilename := "psinet.json"
+
+	sponsorID, _ := psiphon.MakeRandomStringHex(8)
+
+	fakeDomain, _ := psiphon.MakeRandomStringHex(4)
+	fakePath, _ := psiphon.MakeRandomStringHex(4)
+	expectedHomepageURL := fmt.Sprintf("https://%s.com/%s", fakeDomain, fakePath)
+
+	psinetJSONFormat := `
+    {
+        "sponsors": {
+            "%s": {
+                "home_pages": {
+                    "None": [
+                        {
+                            "region": null,
+                            "url": "%s"
+                        }
+                    ]
+                }
+            }
+        }
+    }
+	`
+	psinetJSON := fmt.Sprintf(psinetJSONFormat, sponsorID, expectedHomepageURL)
+
+	err := ioutil.WriteFile(psinetFilename, []byte(psinetJSON), 0600)
+	if err != nil {
+		t.Fatalf("error paving psinet database: %s", err)
+	}
+
+	return psinetFilename, sponsorID, expectedHomepageURL
+}

+ 10 - 1
psiphon/server/tunnelServer.go

@@ -566,7 +566,14 @@ func (sshClient *sshClient) passwordCallback(conn ssh.ConnMetadata, password []b
 }
 }
 
 
 func (sshClient *sshClient) authLogCallback(conn ssh.ConnMetadata, method string, err error) {
 func (sshClient *sshClient) authLogCallback(conn ssh.ConnMetadata, method string, err error) {
+
 	if err != nil {
 	if err != nil {
+
+		if method == "none" && err.Error() == "no auth passed yet" {
+			// In this case, the callback invocation is noise from auth negotiation
+			return
+		}
+
 		logFields := LogFields{"error": err, "method": method}
 		logFields := LogFields{"error": err, "method": method}
 		if sshClient.sshServer.support.Config.UseFail2Ban() {
 		if sshClient.sshServer.support.Config.UseFail2Ban() {
 			clientIPAddress := psiphon.IPAddressFromAddr(conn.RemoteAddr())
 			clientIPAddress := psiphon.IPAddressFromAddr(conn.RemoteAddr())
@@ -575,8 +582,10 @@ func (sshClient *sshClient) authLogCallback(conn ssh.ConnMetadata, method string
 					sshClient.sshServer.support.Config.Fail2BanFormat, clientIPAddress)
 					sshClient.sshServer.support.Config.Fail2BanFormat, clientIPAddress)
 			}
 			}
 		}
 		}
-		log.WithContextFields(LogFields{"error": err, "method": method}).Error("authentication failed")
+		log.WithContextFields(logFields).Error("authentication failed")
+
 	} else {
 	} else {
+
 		log.WithContextFields(LogFields{"error": err, "method": method}).Debug("authentication success")
 		log.WithContextFields(LogFields{"error": err, "method": method}).Debug("authentication success")
 	}
 	}
 }
 }

+ 4 - 2
psiphon/serverApi.go

@@ -345,7 +345,8 @@ func (serverContext *ServerContext) DoStatusRequest(tunnel *Tunnel) error {
 
 
 	if serverContext.psiphonHttpsClient == nil {
 	if serverContext.psiphonHttpsClient == nil {
 
 
-		params["statusData"] = json.RawMessage(statusPayload)
+		rawMessage := json.RawMessage(statusPayload)
+		params["statusData"] = &rawMessage
 
 
 		var request []byte
 		var request []byte
 		request, err = makeSSHAPIRequestPayload(params)
 		request, err = makeSSHAPIRequestPayload(params)
@@ -655,7 +656,8 @@ func (serverContext *ServerContext) DoClientVerificationRequest(
 
 
 	if serverContext.psiphonHttpsClient == nil {
 	if serverContext.psiphonHttpsClient == nil {
 
 
-		params["verificationData"] = json.RawMessage(verificationPayload)
+		rawMessage := json.RawMessage(verificationPayload)
+		params["verificationData"] = &rawMessage
 
 
 		request, err := makeSSHAPIRequestPayload(params)
 		request, err := makeSSHAPIRequestPayload(params)
 		if err != nil {
 		if err != nil {