(t *testing.T)
| 1406 | } |
| 1407 | |
| 1408 | func TestTurnAuthFailure(t *testing.T) { |
| 1409 | if testing.Short() { |
| 1410 | t.SkipNow() |
| 1411 | return |
| 1412 | } |
| 1413 | |
| 1414 | const turnUDPPort = 3478 |
| 1415 | |
| 1416 | s := createSingleNodeServer(func(c *config.Config) { |
| 1417 | c.TURN.Enabled = true |
| 1418 | c.TURN.UDPPort = turnUDPPort |
| 1419 | }) |
| 1420 | go func() { |
| 1421 | if err := s.Start(); err != nil { |
| 1422 | logger.Errorw("server returned error", err) |
| 1423 | } |
| 1424 | }() |
| 1425 | defer s.Stop(true) |
| 1426 | |
| 1427 | waitForServerToStart(s) |
| 1428 | |
| 1429 | // build a known-good username/password pair so individual cases can mutate |
| 1430 | // only the part they are exercising. |
| 1431 | pID := livekit.ParticipantID("PA_authfail") |
| 1432 | authHandler := service.NewTURNAuthHandler(auth.NewSimpleKeyProvider(testApiKey, testApiSecret)) |
| 1433 | validUsername, validExpiry := authHandler.CreateUsername(testApiKey, pID, 300) |
| 1434 | validPassword, err := authHandler.CreatePassword(testApiKey, pID, validExpiry) |
| 1435 | require.NoError(t, err) |
| 1436 | |
| 1437 | // username encoded with an already-expired timestamp. |
| 1438 | expiredUsername, _ := authHandler.CreateUsername(testApiKey, pID, -10) |
| 1439 | |
| 1440 | // username encoded with an api key the server does not know about. |
| 1441 | unknownAPIKeyUsername, _ := authHandler.CreateUsername("unknown-api-key", pID, 300) |
| 1442 | |
| 1443 | // password whose hash was generated for an expiry that doesn't match the |
| 1444 | // one encoded in the username. The server reconstructs the password using |
| 1445 | // the username's expiry, so the integrity check fails. |
| 1446 | mismatchedExpiryPassword, err := authHandler.CreatePassword(testApiKey, pID, validExpiry+60) |
| 1447 | require.NoError(t, err) |
| 1448 | require.NotEqual(t, validPassword, mismatchedExpiryPassword) |
| 1449 | |
| 1450 | // username carrying expiry=0 must be rejected outright; constructed |
| 1451 | // directly because CreateUsername always stamps a real expiry. |
| 1452 | zeroExpiryUsername := base62.EncodeToString(fmt.Appendf(nil, "%s|%s|%d", testApiKey, pID, 0)) |
| 1453 | |
| 1454 | // username with only apiKey|pID (no expiry component) is the legacy |
| 1455 | // pre-expiry form and must be rejected. |
| 1456 | twoPartUsername := base62.EncodeToString(fmt.Appendf(nil, "%s|%s", testApiKey, pID)) |
| 1457 | |
| 1458 | testCases := []struct { |
| 1459 | name string |
| 1460 | username string |
| 1461 | password string |
| 1462 | }{ |
| 1463 | { |
| 1464 | name: "unparseable-username", |
| 1465 | username: "not-base62!!!", |
nothing calls this directly
no test coverage detected