Exemple #1
0
        public void Test20SecurityHandlers()
        {
            string userJWT = "eyJ0eXAiOiJqd3QiLCJhbGciOiJlZDI1NTE5In0.e" +
                             "yJqdGkiOiJFU1VQS1NSNFhGR0pLN0FHUk5ZRjc0STVQNTZHMkFGWER" +
                             "YQ01CUUdHSklKUEVNUVhMSDJBIiwiaWF0IjoxNTQ0MjE3NzU3LCJpc" +
                             "3MiOiJBQ1pTV0JKNFNZSUxLN1FWREVMTzY0VlgzRUZXQjZDWENQTUV" +
                             "CVUtBMzZNSkpRUlBYR0VFUTJXSiIsInN1YiI6IlVBSDQyVUc2UFY1N" +
                             "TJQNVNXTFdUQlAzSDNTNUJIQVZDTzJJRUtFWFVBTkpYUjc1SjYzUlE" +
                             "1V002IiwidHlwZSI6InVzZXIiLCJuYXRzIjp7InB1YiI6e30sInN1Y" +
                             "iI6e319fQ.kCR9Erm9zzux4G6M-V2bp7wKMKgnSNqMBACX05nwePRW" +
                             "Qa37aO_yObbhcJWFGYjo1Ix-oepOkoyVLxOJeuD8Bw";

            string userSeed = "SUAIBDPBAUTWCWBKIO6XHQNINK5FWJW4OHLXC3HQ" +
                              "2KFE4PEJUA44CNHTC4";

            using (utils.CreateServerWithConfig("operator.conf"))
            {
                EventHandler <UserJWTEventArgs> jwtEh = (sender, args) =>
                {
                    //just return a jwt
                    args.JWT = userJWT;
                };

                EventHandler <UserSignatureEventArgs> sigEh = (sender, args) =>
                {
                    // generate a nats key pair from a private key.
                    // NEVER EVER handle a real private key/seed like this.
                    var kp = Nkeys.FromSeed(userSeed);
                    args.SignedNonce = kp.Sign(args.ServerNonce);
                };
                Options opts = ConnectionFactory.GetDefaultOptions();
                opts.SetUserCredentialHandlers(jwtEh, sigEh);
                new ConnectionFactory().CreateConnection(opts).Close();
            }
        }
Exemple #2
0
        public void TestNKEYCreateOperatorSeed()
        {
            string op = Nkeys.CreateOperatorSeed();

            Assert.NotEmpty(op);
            Assert.NotNull(Nkeys.FromSeed(op));
            string pk = Nkeys.PublicKeyFromSeed(op);

            Assert.Equal('O', pk[0]);
        }
Exemple #3
0
        public void TestNKEYCreateAccountSeed()
        {
            string acc = Nkeys.CreateAccountSeed();

            Assert.NotEmpty(acc);
            Assert.NotNull(Nkeys.FromSeed(acc));
            string pk = Nkeys.PublicKeyFromSeed(acc);

            Assert.Equal('A', pk[0]);
        }
Exemple #4
0
        public void TestNKEYCreateUserSeed()
        {
            string user = Nkeys.CreateUserSeed();

            Assert.NotEmpty(user);
            Assert.NotNull(Nkeys.FromSeed(user));
            string pk = Nkeys.PublicKeyFromSeed(user);

            Assert.Equal('U', pk[0]);
        }
Exemple #5
0
        public void TestNKEYCreateOperatorSeed()
        {
            string op = Nkeys.CreateOperatorSeed();

            Assert.NotEmpty(op);
            Assert.False(op.EndsWith("=", StringComparison.Ordinal));
            Assert.NotNull(Nkeys.FromSeed(op));
            string pk = Nkeys.PublicKeyFromSeed(op);

            Assert.Equal('O', pk[0]);
        }
Exemple #6
0
        public void TestNKEYCreateAccountSeed()
        {
            string acc = Nkeys.CreateAccountSeed();

            Assert.NotEmpty(acc);
            Assert.False(acc.EndsWith("=", StringComparison.Ordinal));
            Assert.NotNull(Nkeys.FromSeed(acc));
            string pk = Nkeys.PublicKeyFromSeed(acc);

            Assert.Equal('A', pk[0]);
        }
Exemple #7
0
        public void TestNKEYCreateUserSeed()
        {
            string user = Nkeys.CreateUserSeed();

            Assert.NotEmpty(user);
            Assert.False(user.EndsWith("=", StringComparison.Ordinal));
            Assert.NotNull(Nkeys.FromSeed(user));
            string pk = Nkeys.PublicKeyFromSeed(user);

            Assert.Equal('U', pk[0]);
        }
Exemple #8
0
        public void TestNKEYEncodeDecode()
        {
            byte[] a = new Byte[32];
            byte[] b = Nkeys.DecodeSeed(Nkeys.Encode(20 << 3, true, a));
            Assert.Equal(a, b);

            Random rnd = new Random();

            rnd.NextBytes(a);
            b = Nkeys.DecodeSeed(Nkeys.Encode(20 << 3, true, a));
            Assert.Equal(a, b);
        }
Exemple #9
0
        public void TestNKEYPublicKeyFromSeed()
        {
            // using nsc generated seeds for testing
            string pk = Nkeys.PublicKeyFromSeed("SOAELH6NJCEK4HST5644G4HK7TOAFZGRRJHNM4EUKUY7PPNDLIKO5IH4JM");

            Assert.Equal("ODPWIBQJVIQ42462QAFI2RKJC4RZHCQSIVPRDDHWFCJAP52NRZK6Z2YC", pk);

            pk = Nkeys.PublicKeyFromSeed("SAANWFZ3JINNPERWT3ALE45U7GYT2ZDW6GJUIVPDKUF6GKAX6AISZJMAS4");
            Assert.Equal("AATEJXG7UX4HFJ6ZPRTP22P6OYZER36YYD3GVBOVW7QHLU32P4QFFTZJ", pk);

            pk = Nkeys.PublicKeyFromSeed("SUAGDLNBWI2SGHDRYBHD63NH5FGZSVJUW2J7GAJZXWANQFLDW6G5SXZESU");
            Assert.Equal("UBICBTHDKQRB4LIYA6BMIJ7EA2G7YS7FIWMMVKZJE6M3HS5IVCOLKDY2", pk);
        }
Exemple #10
0
        public void TestExpiredJwt()
        {
            var expiredUserJwt
                = "eyJ0eXAiOiJqd3QiLCJhbGciOiJlZDI1NTE5In0.eyJleHAiOjE1NDg5NzkyMDAs" +
                  "Imp0aSI6IlhURFdZUVc3QldDNzJSR0RaVzNWMlNGQUxFRklCWlRKRkZLWDRTVEpa" +
                  "TVZYWFFBSk01WVEiLCJpYXQiOjE1NzM1NDMyNjYsImlzcyI6IkFBNTVENUw1S0sz" +
                  "WElJNklLSDc0Vk5CUDNTVjNKWUxVQlRKTkxTVEM2NjJKTDZWN0FPWk9GT0NIIiwi" +
                  "bmFtZSI6IlRlc3RVc2VyIiwibmJmIjoxNTQ2MzAwODAwLCJzdWIiOiJVRDZPVUNS" +
                  "T1VEQTZBTTdZMjMySTRLTFVGWU40TTNPWUxJWFhVU0FNTzVQT1RVMkpaVjNVNzY3" +
                  "SiIsInR5cGUiOiJ1c2VyIiwibmF0cyI6eyJwdWIiOnt9LCJzdWIiOnt9fX0.n81V" +
                  "bNLwtYMRYfUDbLgnn0MzFL3imxlEk0PQSzOxQpB_nBkVKvRUtbnd22iS8S9i_HRO" +
                  "FJXfk26xEoOhYtCACg";

            var userSeed = "SUAIBDPBAUTWCWBKIO6XHQNINK5FWJW4OHLXC3HQ2KFE4PEJUA44CNHTC4A";

            using (NATSServer.CreateWithConfig(Context.Server1.Port, "operator.conf"))
            {
                EventHandler <UserJWTEventArgs>       jwtEh = (sender, args) => args.JWT = expiredUserJwt;
                EventHandler <UserSignatureEventArgs> sigEh = (sender, args) =>
                {
                    // generate a nats key pair from a private key.
                    // NEVER EVER handle a real private key/seed like this.
                    var kp = Nkeys.FromSeed(userSeed);
                    args.SignedNonce = kp.Sign(args.ServerNonce);
                };
                var opts = Context.GetTestOptionsWithDefaultTimeout(Context.Server1.Port);
                opts.SetUserCredentialHandlers(jwtEh, sigEh);

                var ex = Assert.Throws <NATSConnectionException>(() =>
                {
                    using (Context.ConnectionFactory.CreateConnection(opts)){ }
                });

                Assert.Equal("'Authorization Violation'", ex.Message, StringComparer.OrdinalIgnoreCase);
            }
        }
Exemple #11
0
        public override async Task <AwsIamAuthReply> AwsIamAuth(AwsIamAuthRequest request,
                                                                ServerCallContext context)
        {
            if (_config.AwsIamMapping == null)
            {
                throw new Exception("missing AWS IAM configuration -- AWS IAM mapping is unsupported");
            }

            var nowUtc     = DateTime.UtcNow;
            var amzDateMin = nowUtc.AddMinutes(-5);
            var amzDateMax = nowUtc.AddMinutes(5);
            var amzDate    = DateTime.ParseExact(request.StsAmzIso8601Date,
                                                 AwsIamConstants.ISO8601DateTimeFormat, null).ToUniversalTime();

            if (amzDate < amzDateMin || amzDate > amzDateMax)
            {
                throw new Exception("AMZ Date outside of valid range");
            }

            using var httpBody = new StringContent(
                      AwsIamConstants.AwsIamRequestContent,
                      AwsIamConstants.AwsIamRequestContentEncoding,
                      AwsIamConstants.AwsIamRequestContentMediaType);

            using var httpRequ = new HttpRequestMessage(
                      AwsIamConstants.AwsIamRequestHttpMethod,
                      AwsIamConstants.AwsIamRequestEndpoint)
                  {
                      Content = httpBody,
                  };

            foreach (var h in request.StsAdditionalHeaders)
            {
                httpRequ.Headers.Add(h.Key, h.Value.Values);
            }
            if (!httpRequ.Headers.TryAddWithoutValidation("Authorization", request.StsAuthorization))
            {
                throw new Exception("could not add AWSv4 Authorization header");
            }

            using var http     = new HttpClient();
            using var httpResp = await http.SendAsync(httpRequ);

            httpResp.EnsureSuccessStatusCode();

            using var httpRespStream = await httpResp.Content.ReadAsStreamAsync();

            var httpRespResult = AwsStsGetCallerIdentityResponse.ParseXml(httpRespStream);

            var identityArn = httpRespResult?.GetCallerIdentityResult?.Arn;

            if (string.IsNullOrEmpty(identityArn))
            {
                throw new Exception("could not authenticate or resolve IAM Identity ARN");
            }

            var userMap = _config.AwsIamMapping.Users.FirstOrDefault(u => u.Arn == identityArn ||
                                                                     (u.Arn.EndsWith("*") &&
                                                                      identityArn.StartsWith(u.Arn.Substring(0, u.Arn.Length - 1))));

            if (userMap == null)
            {
                throw new Exception("user has no mapping");
            }

            ByteString sig = ByteString.Empty;

            if (!(request.Nonce?.IsEmpty ?? true))
            {
                var nonce = request.Nonce.ToByteArray();
                var nkeys = Nkeys.FromSeed(userMap.NKey);
                sig = ByteString.CopyFrom(nkeys.Sign(nonce));
            }

            return(new AwsIamAuthReply
            {
                Jwt = userMap.JWT,
                NonceSigned = sig,
                IdentityArn = httpRespResult.GetCallerIdentityResult?.Arn,
            });
        }
        public override async Task <KerberosAuthReply> KerberosAuth(KerberosAuthRequest request,
                                                                    ServerCallContext context)
        {
            if (_config.KerberosMapping == null)
            {
                throw new Exception("missing Kerberos configuration -- Kerberos mapping is unsupported");
            }

            if (request.ServiceToken?.IsEmpty ?? true)
            {
                throw new Exception("invalid or missing Kerberos authentication token");
            }

            var tokenBytes = request.ServiceToken.ToByteArray();
            var kKey       = new KerberosKey(
                _config.KerberosMapping.Password,
                principalName: new PrincipalName(
                    PrincipalNameType.NT_PRINCIPAL,
                    _config.KerberosMapping.Realm,
                    new[] { _config.KerberosMapping.Spn }
                    ),
                saltType: SaltType.ActiveDirectoryUser);

            var kValidator = new KerberosValidator(kKey);
            var auth       = new KerberosAuthenticator(kValidator);

            var claims = await auth.Authenticate(tokenBytes);

            if (claims == null)
            {
                throw new Exception("could not resolve identity");
            }
            if (string.IsNullOrEmpty(claims.Name))
            {
                throw new Exception("identity name is unresolved");
            }

            var userMap = _config.KerberosMapping.Users.FirstOrDefault(u => u.Name == claims.Name);

            if (userMap == null)
            {
                throw new Exception("user has no mapping");
            }

            ByteString sig = ByteString.Empty;

            if (!(request.Nonce?.IsEmpty ?? true))
            {
                var nonce = request.Nonce.ToByteArray();
                var nkeys = Nkeys.FromSeed(userMap.NKey);
                sig = ByteString.CopyFrom(nkeys.Sign(nonce));
            }

            _logger.LogInformation("Reploy:");
            var reply = new KerberosAuthReply
            {
                Jwt          = userMap.JWT,
                NonceSigned  = sig,
                IdentityName = claims.Name,
            };

            _logger.LogInformation(JsonSerializer.Serialize(reply));
            return(reply);
        }