From 8fbce6373cf57f6522f3d4d42114e6e6b886dd2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wojciech=20Przytu=C5=82a?= Date: Fri, 12 Sep 2025 19:58:40 +0200 Subject: [PATCH] codewide: remove DataStax-specific functionalities Those are not going to be supported by the driver. --- README.md | 3 +- docs/source/api-docs/toc.yml | 2 +- docs/source/features/graph-support/index.md | 296 ------------- docs/source/features/index.md | 2 - docs/source/features/metrics/index.md | 4 +- docs/source/features/opentelemetry/index.md | 2 +- docs/source/index.md | 3 +- docs/source/upgrade-guide/index.md | 5 +- .../DataStax/Auth/SspiClientTests.cs | 39 -- .../DataStax/Cloud/CloudIntegrationTests.cs | 405 ------------------ .../SharedCloudClusterTest.cs | 139 ------ src/Cassandra.Tests/ApiTests.cs | 3 - src/Cassandra.Tests/BuilderTests.cs | 126 ------ .../Cloud/CloudConfigurationParserTests.cs | 172 -------- .../Cloud/CloudMetadataServiceTests.cs | 35 -- .../CustomCaCertificateValidatorTests.cs | 100 ----- .../DataStax/Cloud/certs/customdomain.crt | 30 -- .../DataStax/Cloud/certs/example.crt | 29 -- .../DataStax/Cloud/certs/localhostcsharp.crt | 19 - .../DataStax/Cloud/certs/rootcacsharp.crt | 19 - .../DataStax/Cloud/certs/rootcacsharp.key | 28 -- .../DataStax/Search/DateRangeBoundTests.cs | 76 ---- .../Search/DateRangeSerializerTests.cs | 53 --- .../DataStax/Search/DateRangeTests.cs | 147 ------- src/Cassandra/Builder.cs | 120 ------ src/Cassandra/DataStax/Auth/.editorconfig | 4 - .../DataStax/Auth/GssapiClientFactory.cs | 26 -- src/Cassandra/DataStax/Auth/IGssapiClient.cs | 26 -- .../Auth/Sspi/Buffers/SecureBuffer.cs | 99 ----- .../Auth/Sspi/Buffers/SecureBufferAdapter.cs | 243 ----------- .../Auth/Sspi/Buffers/SecureBufferDataRep.cs | 44 -- .../Auth/Sspi/Buffers/SecureBufferDesc.cs | 58 --- .../Auth/Sspi/Buffers/SecureBufferType.cs | 82 ---- .../DataStax/Auth/Sspi/ByteWriter.cs | 100 ----- .../Auth/Sspi/Contexts/ClientContext.cs | 202 --------- .../DataStax/Auth/Sspi/Contexts/Context.cs | 296 ------------- .../Auth/Sspi/Contexts/ContextAttrib.cs | 158 ------- .../Sspi/Contexts/ContextNativeMethods.cs | 403 ----------------- .../Auth/Sspi/Contexts/ContextQueries.cs | 51 --- .../Auth/Sspi/Contexts/ContextQueryAttrib.cs | 59 --- .../Auth/Sspi/Contexts/SafeContextHandle.cs | 47 -- .../Auth/Sspi/Credentials/ClientCredential.cs | 42 -- .../Auth/Sspi/Credentials/Credential.cs | 227 ---------- .../Credentials/CredentialNativeMethods.cs | 72 ---- .../Sspi/Credentials/CredentialQueryAttrib.cs | 38 -- .../Auth/Sspi/Credentials/CredentialUse.cs | 51 --- .../Sspi/Credentials/CurrentCredential.cs | 90 ---- .../Auth/Sspi/Credentials/QueryNameSupport.cs | 43 -- .../Sspi/Credentials/SafeCredentialHandle.cs | 52 --- .../Auth/Sspi/Credentials/ServerCredential.cs | 43 -- src/Cassandra/DataStax/Auth/Sspi/EnumMgr.cs | 87 ---- .../DataStax/Auth/Sspi/NativeMethods.cs | 48 --- .../DataStax/Auth/Sspi/PackageNames.cs | 48 --- .../DataStax/Auth/Sspi/PackageSupport.cs | 147 ------- .../DataStax/Auth/Sspi/SecPkgInfo.cs | 188 -------- .../DataStax/Auth/Sspi/SecurityStatus.cs | 191 --------- .../DataStax/Auth/Sspi/SspiException.cs | 115 ----- .../DataStax/Auth/Sspi/SspiHandle.cs | 101 ----- src/Cassandra/DataStax/Auth/Sspi/TimeStamp.cs | 69 --- src/Cassandra/DataStax/Auth/SspiClient.cs | 120 ------ .../DataStax/Cloud/CloudConfiguration.cs | 68 --- .../Cloud/CloudConfigurationParser.cs | 66 --- .../DataStax/Cloud/CloudMetadataResult.cs | 31 -- .../DataStax/Cloud/CloudMetadataService.cs | 217 ---------- .../DataStax/Cloud/CloudSniOptionsProvider.cs | 132 ------ src/Cassandra/DataStax/Cloud/ContactInfo.cs | 39 -- .../Cloud/CustomCACertificateValidator.cs | 251 ----------- .../DataStax/Cloud/ICertificateValidator.cs | 29 -- .../Cloud/ICloudConfigurationParser.cs | 33 -- .../DataStax/Cloud/ICloudMetadataService.cs | 34 -- .../Cloud/ISecureConnectionBundleParser.cs | 31 -- .../DataStax/Cloud/SecureConnectionBundle.cs | 70 --- .../Cloud/SecureConnectionBundleParser.cs | 119 ----- src/Cassandra/DataStax/Search/DateRange.cs | 203 --------- .../DataStax/Search/DateRangeBound.cs | 336 --------------- .../DataStax/Search/DateRangePrecision.cs | 59 --- src/Cassandra/GraphProtocol.cs | 39 -- src/Cassandra/GraphProtocolExtensions.cs | 44 -- .../SecureConnectionBundleException.cs | 31 -- .../Serialization/GenericSerializer.cs | 2 - .../Search/DateRangeSerializer.cs | 146 ------- 81 files changed, 7 insertions(+), 7500 deletions(-) delete mode 100644 docs/source/features/graph-support/index.md delete mode 100644 src/Cassandra.IntegrationTests/DataStax/Auth/SspiClientTests.cs delete mode 100644 src/Cassandra.IntegrationTests/DataStax/Cloud/CloudIntegrationTests.cs delete mode 100644 src/Cassandra.IntegrationTests/SharedCloudClusterTest.cs delete mode 100644 src/Cassandra.Tests/DataStax/Cloud/CloudConfigurationParserTests.cs delete mode 100644 src/Cassandra.Tests/DataStax/Cloud/CloudMetadataServiceTests.cs delete mode 100644 src/Cassandra.Tests/DataStax/Cloud/CustomCaCertificateValidatorTests.cs delete mode 100644 src/Cassandra.Tests/DataStax/Cloud/certs/customdomain.crt delete mode 100644 src/Cassandra.Tests/DataStax/Cloud/certs/example.crt delete mode 100644 src/Cassandra.Tests/DataStax/Cloud/certs/localhostcsharp.crt delete mode 100644 src/Cassandra.Tests/DataStax/Cloud/certs/rootcacsharp.crt delete mode 100644 src/Cassandra.Tests/DataStax/Cloud/certs/rootcacsharp.key delete mode 100644 src/Cassandra.Tests/DataStax/Search/DateRangeBoundTests.cs delete mode 100644 src/Cassandra.Tests/DataStax/Search/DateRangeSerializerTests.cs delete mode 100644 src/Cassandra.Tests/DataStax/Search/DateRangeTests.cs delete mode 100644 src/Cassandra/DataStax/Auth/.editorconfig delete mode 100644 src/Cassandra/DataStax/Auth/GssapiClientFactory.cs delete mode 100644 src/Cassandra/DataStax/Auth/IGssapiClient.cs delete mode 100644 src/Cassandra/DataStax/Auth/Sspi/Buffers/SecureBuffer.cs delete mode 100644 src/Cassandra/DataStax/Auth/Sspi/Buffers/SecureBufferAdapter.cs delete mode 100644 src/Cassandra/DataStax/Auth/Sspi/Buffers/SecureBufferDataRep.cs delete mode 100644 src/Cassandra/DataStax/Auth/Sspi/Buffers/SecureBufferDesc.cs delete mode 100644 src/Cassandra/DataStax/Auth/Sspi/Buffers/SecureBufferType.cs delete mode 100644 src/Cassandra/DataStax/Auth/Sspi/ByteWriter.cs delete mode 100644 src/Cassandra/DataStax/Auth/Sspi/Contexts/ClientContext.cs delete mode 100644 src/Cassandra/DataStax/Auth/Sspi/Contexts/Context.cs delete mode 100644 src/Cassandra/DataStax/Auth/Sspi/Contexts/ContextAttrib.cs delete mode 100644 src/Cassandra/DataStax/Auth/Sspi/Contexts/ContextNativeMethods.cs delete mode 100644 src/Cassandra/DataStax/Auth/Sspi/Contexts/ContextQueries.cs delete mode 100644 src/Cassandra/DataStax/Auth/Sspi/Contexts/ContextQueryAttrib.cs delete mode 100644 src/Cassandra/DataStax/Auth/Sspi/Contexts/SafeContextHandle.cs delete mode 100644 src/Cassandra/DataStax/Auth/Sspi/Credentials/ClientCredential.cs delete mode 100644 src/Cassandra/DataStax/Auth/Sspi/Credentials/Credential.cs delete mode 100644 src/Cassandra/DataStax/Auth/Sspi/Credentials/CredentialNativeMethods.cs delete mode 100644 src/Cassandra/DataStax/Auth/Sspi/Credentials/CredentialQueryAttrib.cs delete mode 100644 src/Cassandra/DataStax/Auth/Sspi/Credentials/CredentialUse.cs delete mode 100644 src/Cassandra/DataStax/Auth/Sspi/Credentials/CurrentCredential.cs delete mode 100644 src/Cassandra/DataStax/Auth/Sspi/Credentials/QueryNameSupport.cs delete mode 100644 src/Cassandra/DataStax/Auth/Sspi/Credentials/SafeCredentialHandle.cs delete mode 100644 src/Cassandra/DataStax/Auth/Sspi/Credentials/ServerCredential.cs delete mode 100644 src/Cassandra/DataStax/Auth/Sspi/EnumMgr.cs delete mode 100644 src/Cassandra/DataStax/Auth/Sspi/NativeMethods.cs delete mode 100644 src/Cassandra/DataStax/Auth/Sspi/PackageNames.cs delete mode 100644 src/Cassandra/DataStax/Auth/Sspi/PackageSupport.cs delete mode 100644 src/Cassandra/DataStax/Auth/Sspi/SecPkgInfo.cs delete mode 100644 src/Cassandra/DataStax/Auth/Sspi/SecurityStatus.cs delete mode 100644 src/Cassandra/DataStax/Auth/Sspi/SspiException.cs delete mode 100644 src/Cassandra/DataStax/Auth/Sspi/SspiHandle.cs delete mode 100644 src/Cassandra/DataStax/Auth/Sspi/TimeStamp.cs delete mode 100644 src/Cassandra/DataStax/Auth/SspiClient.cs delete mode 100644 src/Cassandra/DataStax/Cloud/CloudConfiguration.cs delete mode 100644 src/Cassandra/DataStax/Cloud/CloudConfigurationParser.cs delete mode 100644 src/Cassandra/DataStax/Cloud/CloudMetadataResult.cs delete mode 100644 src/Cassandra/DataStax/Cloud/CloudMetadataService.cs delete mode 100644 src/Cassandra/DataStax/Cloud/CloudSniOptionsProvider.cs delete mode 100644 src/Cassandra/DataStax/Cloud/ContactInfo.cs delete mode 100644 src/Cassandra/DataStax/Cloud/CustomCACertificateValidator.cs delete mode 100644 src/Cassandra/DataStax/Cloud/ICertificateValidator.cs delete mode 100644 src/Cassandra/DataStax/Cloud/ICloudConfigurationParser.cs delete mode 100644 src/Cassandra/DataStax/Cloud/ICloudMetadataService.cs delete mode 100644 src/Cassandra/DataStax/Cloud/ISecureConnectionBundleParser.cs delete mode 100644 src/Cassandra/DataStax/Cloud/SecureConnectionBundle.cs delete mode 100644 src/Cassandra/DataStax/Cloud/SecureConnectionBundleParser.cs delete mode 100644 src/Cassandra/DataStax/Search/DateRange.cs delete mode 100644 src/Cassandra/DataStax/Search/DateRangeBound.cs delete mode 100644 src/Cassandra/DataStax/Search/DateRangePrecision.cs delete mode 100644 src/Cassandra/GraphProtocol.cs delete mode 100644 src/Cassandra/GraphProtocolExtensions.cs delete mode 100644 src/Cassandra/SecureConnectionBundleException.cs delete mode 100644 src/Cassandra/Serialization/Search/DateRangeSerializer.cs diff --git a/README.md b/README.md index e4ad9e77c..8f209d194 100644 --- a/README.md +++ b/README.md @@ -223,7 +223,6 @@ To configure a provider, pass it when initializing the cluster: ```csharp using Cassandra; -using Cassandra.DataStax.Auth; ``` ```csharp @@ -255,7 +254,7 @@ Here is a list of platforms and .NET targets that Datastax uses when testing thi Mono `6.12.0` is also used to run `net462` tests on `Ubuntu 18.04` but Datastax can't guarantee that the driver fully supports Mono in a production environment. Datastax recommends the modern cross platform .NET platform instead. -Note: DataStax products do not support big-endian systems. +Note: Big-endian systems are not supported. ## Building and running the tests diff --git a/docs/source/api-docs/toc.yml b/docs/source/api-docs/toc.yml index 8c4b5d7a4..a84248c1f 100644 --- a/docs/source/api-docs/toc.yml +++ b/docs/source/api-docs/toc.yml @@ -1,2 +1,2 @@ -- name: DataStax C# Driver for Apache Cassandra API Documentation +- name: ScyllaDB C# Driver API Documentation href: api/ \ No newline at end of file diff --git a/docs/source/features/graph-support/index.md b/docs/source/features/graph-support/index.md deleted file mode 100644 index c5df20123..000000000 --- a/docs/source/features/graph-support/index.md +++ /dev/null @@ -1,296 +0,0 @@ -# Graph support - -The driver provides support for DataStax Graph. The `ISession` interface has dedicated methods to execute graph queries with the [Gremlin] graph traversal language. - -*This manual only covers driver usage; for more information about server-side configuration and data modeling, refer to the [DSE developer guide].* - -```csharp -using Cassandra.DataStax.Graph; -``` - -```csharp -session.ExecuteGraph("system.createGraph('demo').ifNotExist().build()"); - -GraphStatement s1 = new SimpleGraphStatement("g.addV(label, 'test_vertex')").SetGraphName("demo"); -session.ExecuteGraph(s1); - -GraphStatement s2 = new SimpleGraphStatement("g.V()").SetGraphName("demo"); -GraphResultSet rs = session.ExecuteGraph(s2); -``` - -`GraphResultSet` is a sequence of `GraphNode` elements. Each item can be converted to the expected type. - -```csharp -IVertex vertex = rs.First().To(); -Console.WriteLine(vertex.Label); -``` - -Additionally, you can apply the conversion to all the sequence by using `GraphResultSet.To()` method: - -```csharp -foreach (IVertex vertex in rs.To()) -{ - Console.WriteLine(vertex.Label); -} -``` - -## DataStax Graph and the Core Engine (DSE 6.8+) - -Graphs that use the core engine (default in DSE 6.8+) only support GraphSON3. The driver automatically switches the default GraphSON version if it detects the core engine. - -However, this graph engine detection is based on the metadata. In some scenarios **you might experience some server errors where the message mentions that the GraphSON version is incompatible.** This happens when the graph has been newly created and is not yet in the metadata. It also happens when you don't provide the graph name. - -If you are running into these errors you can set the GraphSON version explicitly: - -```csharp -// with the legacy configuration method -var cluster = - Cluster.Builder() - .AddContactPoint("127.0.0.1") - .WithGraphOptions( - new GraphOptions().SetGraphProtocolVersion(GraphProtocol.GraphSON3)) - .Build(); - -// with execution profiles -var cluster = - Cluster.Builder() - .AddContactPoint("127.0.0.1") - .WithExecutionProfiles(opt => opt - .WithProfile("default", profile => profile - .WithGraphOptions( - new GraphOptions().SetGraphProtocolVersion(GraphProtocol.GraphSON3)))) - .Build(); -``` - -## Query Execution APIs - -There are 2 APIs that you can use to execute graph queries: - -- A `fluent`, builder-like API; -- A Gremlin traversal **string** execution API. - -With the Gremlin traversal **string** execution API, you pass a Gremlin traversal directly in a plain C# string via `SimpleGraphStatement` objects. Every example on this page uses this API. - -To use the `fluent` API you must add an additional dependency to your application: the [DataStax C# Graph Extension]. This extension pulls in the `Gremlin.Net` nuget package which is the Apache Tinkerpop GLV (Gremlin Language Variant) for the .NET platform. - -For examples and more information on the `fluent` API, please take a look at the documentation for the [DataStax C# Graph Extension]. - -If your application just uses the Gremlin traversal string execution API, then it is not necessary to install any other packages besides the core driver, i.e., `CassandraCSharpDriver`. - -## Graph options - -You can set default graph options when initializing the cluster. They will be used for all graph statements. For example, to avoid repeating `SetGraphName("demo")` on each statement: - -```csharp -// with the legacy configuration method -ICluster cluster = Cluster.Builder() - .AddContactPoint("127.0.0.1") - .WithGraphOptions(new GraphOptions().SetName("demo")) - .Build(); - -// with execution profiles -ICluster cluster = Cluster.Builder() - .AddContactPoint("127.0.0.1") - .WithExecutionProfiles(opt => opt - .WithProfile("default", profile => profile - .WithGraphOptions(new GraphOptions().SetName("demo")))) - .Build(); -``` - -For more information on execution profiles, see [this page of the manual](../execution-profiles/index). - -If an option is set manually on a `GraphStatement`, it always takes precedence; otherwise the default option is used. This might be a problem if a default graph name is set, but you explicitly want to execute a statement targeting `system`, for which no graph name must be set. In that situation, use `GraphStatement.SetSystemQuery()`: - -```csharp -GraphStatement s = - new SimpleGraphStatement("system.createGraph('demo').ifNotExist().build()").SetSystemQuery(); - -session.ExecuteGraph(s); -``` - -## Asynchronous query execution - -Graph statements can also be executed without blocking the calling thread using `ExecuteGraphAsync()` method. - -```csharp -GraphResultSet rs = await session.ExecuteGraphAsync(new SimpleGraphStatement("g.V()")); -``` - -## Handling results - -Graph queries return a `GraphResultSet`, which is a sequence of `GraphNode` elements: - -```csharp -GraphResultSet rs = session.ExecuteGraph(new SimpleGraphStatement("g.V()")); - -// Iterating as IGraphNode -foreach (IGraphNode r in rs) -{ - Console.WriteLine(r); -} -``` - -`IGraphNode` represents a response item returned by the server. Each item can be converted to the expected type: - -```csharp -GraphResultSet rs = session.ExecuteGraph(new SimpleGraphStatement("g.V()")); -IVertex vertex = rs.First().To(); -Console.WriteLine(vertex.Label); -``` - -Additionally, you can apply the conversion to all the sequence by using `GraphResultSet.To()` method: - -```csharp -foreach (IVertex vertex in rs.To()) -{ - Console.WriteLine(vertex.Label); -} -``` - -With Datastax Graph Core Engine (DSE 6.8+), you are often required to use the `elementMap()` step to obtain vertices with their properties and in this case `To()` won't work because the returned objects are not of the type `Vertex`. For this specific case, there is an `ElementMap` C# class that can be easier to manipulate than the default `Dictionary` that is used when deserializing results from `elementMap()` queries. - -```csharp -foreach (ElementMap elementMap in rs.To()) -{ - Console.WriteLine(elementMap.Label); -} -``` - -`GraphNode` provides [implicit conversion operators][implicit] to `string`, `int`, `long` and others in order to improve code readability, allowing the following C# syntax: - -```csharp -var rs = session.ExecuteGraph(new SimpleGraphStatement("g.V().has('name', 'marko').values('location')")); -foreach (string location in rs) -{ - Console.WriteLine(location); -} -``` - -`GraphNode` inherits from [`DynamicObject`][dynamic], allowing you to consume it using the `dynamic` keyword and/or as a dictionary. - -```csharp -dynamic r = session.ExecuteGraph(new SimpleGraphStatement("g.V()")).First(); -``` - -You can get the GraphNode properties using the `GetProperty()` method from the element: - -```csharp -var vertex = session.ExecuteGraph(new SimpleGraphStatement("g.V()")).First().To(); -// Assuming that vertex with properties: name:string, and age:int -Console.WriteLine(vertex.GetProperty("name").Value.ToString()); -Console.WriteLine(vertex.GetProperty("age").Value.ToInt32()); -``` - -## Parameters - -Graph query parameters are always named. Parameter bindings are passed as an anonymous type or as a `IDictionary` alongside the query: - -```csharp -session.ExecuteGraph("g.addV(label, vertexLabel)", new { vertexLabel = "test_vertex_2" }); -``` - -Note that, unlike in CQL, Gremlin placeholders are not prefixed with ":". - -## Graph types - -The DataStax C# driver supports a wide variety of TinkerPop types and [DSE types](../datatypes/index). - -For example: - -```csharp -var traversal = new SimpleGraphStatement( - "g.addV('sample').property('uid', uid).property('ip_address', address)", - new { uid = Guid.NewGuid(), address = IPAddress.Parse("127.0.0.1") }); - -session.ExecuteGraph(traversal); -``` - -The same types are also supported for traversal execution results: - -```csharp -var rs = session.ExecuteGraph("g.V().hasLabel('sample').values('ip_address')"); -foreach (IPAddress ip in rs.To()) -{ - Console.WriteLine(ip.ToString()); -} -``` - -### User-defined types - -User-defined types (UDTs) in DataStax Graph are supported with the C# driver. - -In order to use them you need to map them to .NET types in the same way as you would use UDTs in standard CQL workloads with Apache Cassandra. You can find documentation on how to map UDTs to .NET types in [the UDT section of the driver manual](../udts/index). - -Reading UDT values in traversal results does not require a UDT mapping as UDTs can be deserialized to `IDictionary` but a UDT mapping is required if you need to provide a UDT value as a parameter. - -### Without a UDT mapping - -Here's an example of reading UDT values and their properties without a UDT mapping: - -```csharp -var firstResult = session.ExecuteGraph(new SimpleGraphStatement( - "g.V().hasLabel('users_contacts').has('id', 305).properties('contacts')")).ToArray()[0]; - -// the 'contacts' vertex property is a list where 'contact' is a UDT -var firstContact = firstElement.To().Value.To>>().First(); - -// 'emails' is a property of 'contact' and its type is list -var firstContactEmails = firstContact["emails"].To>(); -``` - -The example doesn't contain a vertex insertion with parameters because that requires a UDT mapping (see the next example). - -Attempting to provide a `IDictionary` value as a UDT parameter will result in a type mismatch server error. - -## With a UDT mapping - -This example contains two traversals: - -- One that inserts a vertex with a UDT value as parameter for its property; -- One that selects all vertices with that label and retrieves the UDT property. - -```csharp -class Contact -{ - public string FirstName { get; set; } - public string LastName { get; set; } - public IEnumerable Emails { get; set; } -} -``` - -```csharp -session.UserDefinedTypes.Define( - UdtMap.For(udtName: "contact", keyspace: "demo") - .Map(c => c.FirstName, "first_name") - .Map(c => c.LastName, "last_name") - .Map(c => c.Emails, "emails")); - -var john = new Contact -{ - FirstName = "John", LastName "Williams", Emails = new [] { "john@email.com" } -}; - -// the 'contacts' property is a list where 'contact' is a UDT -session.ExecuteGraph(new SimpleGraphStatement( - "g.addV('users_contacts').property('id', 123).property('contacts', contacts)", - new { contacts = new List { john }}); - -var firstResult = session.ExecuteGraph(new SimpleGraphStatement( - "g.V().hasLabel('users_contacts').has('id', 305).properties('contacts')")).ToArray()[0]; - -var firstContact = firstElement.To().Value.To>().First(); - -// 'Emails' is a property of the 'Contact' class and its type is IEnumerable -var firstContactEmails = firstContact.Emails; -``` - -## Prepared statements - -Prepared graph statements are not supported by DSE Graph. - -[modern-graph]: http://tinkerpop.apache.org/docs/3.1.1-incubating/reference/#_the_graph_structure -[dynamic]: https://msdn.microsoft.com/en-us/library/dd264736.aspx -[implicit]: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/implicit -[DSE developer guide]: https://docs.datastax.com/en/dse/6.8/dse-dev/datastax_enterprise/graph/graphTOC.html -[Gremlin]: https://docs.datastax.com/en/dse/6.8/dse-dev/datastax_enterprise/graph/dseGraphAbout.html#WhatisGremlin? -[DataStax C# Graph Extension]: https://docs.datastax.com/en/developer/csharp-dse-graph/latest/ \ No newline at end of file diff --git a/docs/source/features/index.md b/docs/source/features/index.md index 8a310e76e..de3b267b1 100644 --- a/docs/source/features/index.md +++ b/docs/source/features/index.md @@ -17,7 +17,6 @@ The ScyllaDB C# Driver for Scylla is a feature-rich and highly tunable C# client - [CQL data types to C# types](datatypes/index) - [Execution Profiles](execution-profiles/index) - [Cluster and schema metadata](metadata/index) -- [Graph support](graph-support/index) - [Metrics](metrics/index) - [App.Metrics Provider](metrics/app-metrics/index) - [List of metrics](metrics/metrics-list/index) @@ -48,7 +47,6 @@ connection-heartbeat/index connection-pooling/index datatypes/index execution-profiles/index -graph-support/index metadata/index metrics/index native-protocol/index diff --git a/docs/source/features/metrics/index.md b/docs/source/features/metrics/index.md index 15dd5c183..05139d71e 100644 --- a/docs/source/features/metrics/index.md +++ b/docs/source/features/metrics/index.md @@ -2,7 +2,7 @@ The driver exposes measurements of its internal behavior through an API composed by abstractions. The client application must provide an implementation of these abstractions (`IDriverMetricsProvider`) in order to enable metrics. -DataStax offers an [Extension package] based on the [App.Metrics] library. Application developers can use [App.Metrics] to export metrics to a monitoring tool. +An [Extension package] is offered that is based on the [App.Metrics] library. Application developers can use [App.Metrics] to export metrics to a monitoring tool. ## Structure @@ -55,7 +55,7 @@ builder.WithMetrics(provider, new DriverMetricsOptions() `DriverMetricsOptions.SetBucketPrefix` can be used to specify a custom prefix to be added to the bucket name of every metric. See the [previous section](#structure) for information about his. -The `provider` parameter must be an implementation of `IDriverMetricsProvider`. As was mentioned previouly, DataStax offers an [App.Metrics based implementation on a separate extension nuget package]. +The `provider` parameter must be an implementation of `IDriverMetricsProvider`. As was mentioned previouly, an [App.Metrics based implementation on a separate extension nuget package] is offered. ## Exporting metrics diff --git a/docs/source/features/opentelemetry/index.md b/docs/source/features/opentelemetry/index.md index 1503b3bfe..185809503 100644 --- a/docs/source/features/opentelemetry/index.md +++ b/docs/source/features/opentelemetry/index.md @@ -21,7 +21,7 @@ using var tracerProvider = Sdk.CreateTracerProviderBuilder() ... ``` -__You can also find an [example in the driver's Github repository](https://github.com/scylladb/csharp-driver/tree/master/examples/OpenTelemetry/DistributedTracing) of how to implement distributed tracing with OpenTelemetry and the DataStax C# driver in an ASP.NET Core project.__ +__You can also find an [example in the driver's Github repository](https://github.com/scylladb/csharp-driver/tree/master/examples/OpenTelemetry/DistributedTracing) of how to implement distributed tracing with OpenTelemetry and the ScyllaDB C# driver in an ASP.NET Core project.__ ### Attributes diff --git a/docs/source/index.md b/docs/source/index.md index ddc2549fd..c229c0187 100644 --- a/docs/source/index.md +++ b/docs/source/index.md @@ -221,7 +221,6 @@ To configure a provider, pass it when initializing the cluster: ```csharp using Cassandra; -using Cassandra.DataStax.Auth; ``` ```csharp @@ -253,7 +252,7 @@ Here is a list of platforms and .NET targets that Datastax uses when testing thi Mono `6.12.0` is also used to run `net462` tests on `Ubuntu 18.04` but Datastax can't guarantee that the driver fully supports Mono in a production environment. Datastax recommends the modern cross platform .NET platform instead. -Note: DataStax products do not support big-endian systems. +Note: Big-endian systems are not supported. ## Building and running the tests diff --git a/docs/source/upgrade-guide/index.md b/docs/source/upgrade-guide/index.md index 68a43e6d4..dbd6d510e 100644 --- a/docs/source/upgrade-guide/index.md +++ b/docs/source/upgrade-guide/index.md @@ -1,8 +1,6 @@ # Upgrade Guide -The purpose of this guide is to detail the changes made by the successive versions of the DataStax C# Driver that are relevant to for an upgrade from prior versions. - -If you have any question or comment, you can [post it on the mailing list][mailing-list]. +The purpose of this guide is to detail the changes made by the successive versions of the ScyllaDB C# Driver that are relevant to for an upgrade from prior versions. ## Our policy regarding API changes and release versioning @@ -280,7 +278,6 @@ only an initial amount of rows will be fetched (according to the page size), the "on-demand" as you iterate through it. -[mailing-list]: https://groups.google.com/a/lists.datastax.com/forum/#!forum/csharp-driver-user [context]: https://msdn.microsoft.com/en-us/library/system.data.objects.objectcontext(v=vs.110).aspx [entitynuget]: https://www.nuget.org/packages/CassandraEntityContext/ [enum-tolist]: https://msdn.microsoft.com/en-us/library/bb342261(v=vs.110).aspx \ No newline at end of file diff --git a/src/Cassandra.IntegrationTests/DataStax/Auth/SspiClientTests.cs b/src/Cassandra.IntegrationTests/DataStax/Auth/SspiClientTests.cs deleted file mode 100644 index d5ffe6f3c..000000000 --- a/src/Cassandra.IntegrationTests/DataStax/Auth/SspiClientTests.cs +++ /dev/null @@ -1,39 +0,0 @@ -// -// Copyright (C) DataStax Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using Cassandra.Tests; -using NUnit.Framework; - -namespace Cassandra.IntegrationTests.DataStax.Auth -{ - [Category(TestCategory.Kerberos)] - public class SspiClientTests : BaseIntegrationTest - { - [Explicit( - "It can only run when the host running the test is authenticated against the KDC")] - [Test] - public void Test_First_Step() - { - // var sspi = new SspiClient(); - // //For the server principal: "dse/cassandra1.datastax.com@DATASTAX.COM" - // //the expected Uri is: "dse/cassandra1.datastax.com" - // //sspi.Init("dse", "172.16.56.1"); - // //sspi.Init("host", "jorge-win.datastaxrealm.com"); - // sspi.Init("krbtgt", "DATASTAXREALM.COM"); - // sspi.EvaluateChallenge(null); - } - } -} diff --git a/src/Cassandra.IntegrationTests/DataStax/Cloud/CloudIntegrationTests.cs b/src/Cassandra.IntegrationTests/DataStax/Cloud/CloudIntegrationTests.cs deleted file mode 100644 index 4ab5ac56c..000000000 --- a/src/Cassandra.IntegrationTests/DataStax/Cloud/CloudIntegrationTests.cs +++ /dev/null @@ -1,405 +0,0 @@ -// -// Copyright (C) DataStax Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net; -#if NETCOREAPP -using System.Net.Http; -#endif -using System.Threading; -using System.Threading.Tasks; -using Cassandra.Data.Linq; -using Cassandra.DataStax.Cloud; -using Cassandra.IntegrationTests.Mapping.Structures; -using Cassandra.IntegrationTests.Policies.Util; -using Cassandra.IntegrationTests.TestAttributes; -using Cassandra.IntegrationTests.TestBase; -using Cassandra.IntegrationTests.TestClusterManagement; -using Cassandra.Mapping; -using Cassandra.Tests; -using Cassandra.Tests.TestAttributes; -using NUnit.Framework; - -namespace Cassandra.IntegrationTests.DataStax.Cloud -{ - [SniEnabledOnly] - [CloudSupported(Supported = true)] - [TestFixture, Category(TestCategory.Short), Category(TestCategory.Cloud), Category(TestCategory.RealClusterLong)] - public class CloudIntegrationTests : SharedCloudClusterTest - { - [Test] - public void Should_ThrowNoHostAvailable_When_MetadataServiceIsUnreachable() - { - var ex = Assert.ThrowsAsync( - () => CreateSessionAsync( - "creds-v1-unreachable.zip", - retries: 1, - act: - b => b - .WithSocketOptions(new SocketOptions().SetReadTimeoutMillis(5000).SetConnectTimeoutMillis(10000)) - .WithQueryTimeout(5000))); - Assert.IsTrue(ex.Message.Contains("https://192.0.2.255:30443/metadata"), ex.Message); - Assert.IsTrue(ex.Message.Contains("There was an error fetching the metadata information"), ex.Message); - Assert.IsTrue(ex.Message.Contains("Please make sure your cluster is not parked or terminated."), ex.Message); - } - - [Test] - public async Task Should_ContinueQuerying_When_ANodeGoesDown() - { - var session = await CreateSessionAsync(act: builder => - builder.WithPoolingOptions( - new PoolingOptions().SetHeartBeatInterval(50)) - .WithReconnectionPolicy(new ConstantReconnectionPolicy(40)) - .WithQueryOptions(new QueryOptions().SetDefaultIdempotence(true))).ConfigureAwait(false); - - Assert.IsTrue(session.Cluster.AllHosts().All(h => h.IsUp)); - var restarted = true; - var t = Task.Run(async () => - { - TestCluster.Stop(1); - await Task.Delay(2000).ConfigureAwait(false); - TestCluster.Start(1, "--jvm_arg \"-Ddse.product_type=DATASTAX_APOLLO\""); - await Task.Delay(500).ConfigureAwait(false); - try - { - TestHelper.RetryAssert( - () => - { - var dict = Session.Cluster.Metadata.TokenToReplicasMap.GetByKeyspace("system_distributed"); - Assert.AreEqual(3, dict.First().Value.Count); - Assert.AreEqual(3, Session.Cluster.AllHosts().Count); - Assert.IsTrue(Session.Cluster.AllHosts().All(h => h.IsUp)); - }, - 20, - 500); - } - finally - { - Volatile.Write(ref restarted, true); - } - }); - - var t2 = Task.Run(async () => - { - while (true) - { - if (Volatile.Read(ref restarted)) - { - return; - } - - var tasks = new List(); - long counter = 0; - foreach (var _ in Enumerable.Range(0, 32)) - { - tasks.Add(Task.Run(async () => - { - while (true) - { - var c = Interlocked.Increment(ref counter); - if (c > 1000) - { - return; - } - - try - { - await session.ExecuteAsync(new SimpleStatement("SELECT key FROM system.local WHERE key='local'")).ConfigureAwait(false); - } - catch (QueryTimeoutException) { } - } - })); - } - - await Task.WhenAll(tasks).ConfigureAwait(false); - } - }); - await Task.WhenAll(t, t2).ConfigureAwait(false); - } - - [Test] - public void Should_ThrowException_When_BundleDoesNotExist() - { - var ex = Assert.Throws( - () => ClusterBuilder() - .WithCloudSecureConnectionBundle("does-not-exist.zip") - .WithCredentials("user1", "user1").Build()); - } - - [Test] - public void Should_FailFast_When_ConfigJsonDoesNotHaveCredentialsAndUserDoesNotProvideCredentials() - { - var ex = Assert.Throws(() => CreateTemporaryCluster("creds-v1-wo-creds.zip", withCredentials: false)); - Assert.AreEqual( - ex.Message, - "No credentials were provided. When using the secure connection bundle, " + - "your cluster's credentials must be provided via the Builder.WithCredentials() method."); - } - - [Test] - public void Should_SetAuthProvider() - { - Assert.IsNotNull(Session.Cluster.Configuration.AuthProvider.GetType()); - Assert.AreEqual(typeof(PlainTextAuthProvider), Session.Cluster.Configuration.AuthProvider.GetType()); - var provider = (PlainTextAuthProvider)Session.Cluster.Configuration.AuthProvider; - Assert.AreEqual("user1", provider.Username); - } - - [Test] - public async Task Should_MatchSystemLocalInformationOfEachNode() - { - const int port = 9042; - var session = await CreateSessionAsync(act: b => b.WithLoadBalancingPolicy(new RoundRobinPolicy())).ConfigureAwait(false); - var queriedHosts = new HashSet(); - foreach (var i in Enumerable.Range(0, 3)) - { - var rs = await session.ExecuteAsync(new SimpleStatement("SELECT * FROM system.local WHERE key='local'")).ConfigureAwait(false); - var row = rs.First(); - var host = session.Cluster.GetHost(new IPEndPoint(rs.Info.QueriedHost.Address, rs.Info.QueriedHost.Port)); - Assert.IsNotNull(host); - queriedHosts.Add(rs.Info.QueriedHost.Address); - Assert.AreEqual(host.HostId, row.GetValue("host_id")); - Assert.AreEqual(host.Address, new IPEndPoint(row.GetValue("rpc_address"), port)); - } - - Assert.AreEqual(3, queriedHosts.Count); - } - - [Test] - public async Task Should_HaveTwoRows_When_QueryingSystemPeers() - { - var rs = await Session.ExecuteAsync(new SimpleStatement("select * from system.peers")).ConfigureAwait(false); - var allRs = rs.ToList(); - Assert.AreEqual(2, allRs.Count); - } - - [Test] - public void TokenAware_Prepared_Composite_NoHops() - { - // Setup - var policyTestTools = new PolicyTestTools(); - - // Test - policyTestTools.CreateSchema(Session, 1, forceSchemaAgreement: true); - policyTestTools.TableName = TestUtils.GetUniqueTableName(); - Session.Execute($"CREATE TABLE {policyTestTools.TableName} (k1 text, k2 int, i int, PRIMARY KEY ((k1, k2)))"); - Thread.Sleep(1000); - TestHelper.RetryAssert(() => - { - Assert.True(Session.Cluster.Metadata.CheckSchemaAgreementAsync().Result); - }, 500, 150); - var ps = Session.Prepare($"INSERT INTO {policyTestTools.TableName} (k1, k2, i) VALUES (?, ?, ?)"); - var traces = new List(); - for (var i = 0; i < 10; i++) - { - var statement = ps.Bind(i.ToString(), i, i).EnableTracing(); - //Routing key is calculated by the driver - Assert.NotNull(statement.RoutingKey); - var rs = Session.Execute(statement); - traces.Add(rs.Info.QueryTrace); - } - //Check that there weren't any hops - foreach (var t in traces) - { - //The coordinator must be the only one executing the query - Assert.True(t.Events.All(e => e.Source.ToString() == t.Coordinator.ToString()), "There were trace events from another host for coordinator " + t.Coordinator); - } - } - - [Test] - public void TokenAware_TargetWrongPartition_HopsOccur() - { - // Setup - var policyTestTools = new PolicyTestTools { TableName = TestUtils.GetUniqueTableName() }; - - policyTestTools.CreateSchema(Session, 1, forceSchemaAgreement: true); - var traces = new List(); - for (var i = 1; i < 10; i++) - { - //The partition key is wrongly calculated - var statement = new SimpleStatement(string.Format("INSERT INTO " + policyTestTools.TableName + " (k, i) VALUES ({0}, {0})", i)) - .SetRoutingKey(new RoutingKey() { RawRoutingKey = new byte[] { 0, 0, 0, 0 } }) - .EnableTracing(); - var rs = Session.Execute(statement); - traces.Add(rs.Info.QueryTrace); - } - //Check that there were hops - var hopsPerQuery = traces.Select(t => t.Events.Any(e => e.Source.ToString() == t.Coordinator.ToString())); - Assert.True(hopsPerQuery.Any(v => v)); - } - - [Test] - public void TokenAware_NoKey_HopsOccurAndAllNodesAreChosenAsCoordinators() - { - // Setup - var policyTestTools = new PolicyTestTools { TableName = TestUtils.GetUniqueTableName() }; - - policyTestTools.CreateSchema(Session, 1, forceSchemaAgreement: true); - var traces = new List(); - for (var i = 1; i < 10; i++) - { - //The partition key is wrongly calculated - var statement = new SimpleStatement(string.Format("INSERT INTO " + policyTestTools.TableName + " (k, i) VALUES ({0}, {0})", i)) - .EnableTracing(); - var rs = Session.Execute(statement); - traces.Add(rs.Info.QueryTrace); - } - //Check that there were hops - var hopsPerQuery = traces.Select(t => t.Events.Any(e => e.Source.ToString() == t.Coordinator.ToString())); - Assert.True(hopsPerQuery.Any(v => v)); - var tracesPerCoordinator = traces.GroupBy(t => t.Coordinator).ToDictionary(t => t.Key, t => t.Count()); - Assert.AreEqual(3, tracesPerCoordinator.Count); - Assert.IsTrue(tracesPerCoordinator.All(kvp => kvp.Value == 3)); - } - - [Test] - public void Should_ThrowSslException_When_ClientCertIsNotProvided() - { - var ex = Assert.ThrowsAsync(() => CreateSessionAsync("creds-v1-wo-cert.zip", retries: 1)); - AssertIsSslError(ex); - } - - [Test] - public void Should_ThrowSslException_When_CaMismatch() - { - var ex = Assert.ThrowsAsync(() => CreateSessionAsync("creds-v1-invalid-ca.zip", retries: 1)); - AssertCaMismatchSslError(ex); - } - - [Test] - public void Should_ParseBundleCorrectly_When_BundlePathIsProvided() - { - var scb = new SecureConnectionBundleParser() - .ParseBundle( - Path.Combine( - ((CloudCluster)TestCluster).SniHomeDirectory, - "certs", - "bundles", - "creds-v1.zip")); - - Assert.IsNotNull(scb.CaCert); - Assert.IsNotNull(scb.ClientCert); - Assert.IsFalse(string.IsNullOrWhiteSpace(scb.Config.CertificatePassword)); - Assert.IsTrue(scb.ClientCert.HasPrivateKey); - Assert.AreEqual(30443, scb.Config.Port); - Assert.AreEqual("localhost", scb.Config.Host); - } - - [Test] - public async Task Should_UseCorrectConsistencyLevelDefaults_When_Dbaas() - { - var session = await CreateSessionAsync(act: b => b - .WithExecutionProfiles(opt => opt - .WithProfile("default", profile => - profile.WithConsistencyLevel(ConsistencyLevel.Any)) - .WithProfile("profile", profile => - profile.WithSerialConsistencyLevel(ConsistencyLevel.LocalSerial)) - .WithDerivedProfile("derived", "profile", profile => - profile.WithConsistencyLevel(ConsistencyLevel.LocalQuorum)))).ConfigureAwait(false); - Assert.AreEqual(ConsistencyLevel.LocalQuorum, Cluster.Configuration.DefaultRequestOptions.ConsistencyLevel); - Assert.AreEqual(ConsistencyLevel.LocalQuorum, Cluster.Configuration.QueryOptions.GetConsistencyLevel()); - Assert.AreEqual(ConsistencyLevel.Serial, Cluster.Configuration.DefaultRequestOptions.SerialConsistencyLevel); - Assert.AreEqual(ConsistencyLevel.Serial, Cluster.Configuration.QueryOptions.GetSerialConsistencyLevel()); - - var ks = TestUtils.GetUniqueKeyspaceName().ToLower(); - const string createKeyspaceQuery = "CREATE KEYSPACE {0} WITH replication = {{ 'class' : '{1}', {2} }}"; - session.Execute(string.Format(createKeyspaceQuery, ks, "SimpleStrategy", "'replication_factor' : 3")); - TestHelper.RetryAssert( - () => Assert.IsTrue(session.Cluster.Metadata.CheckSchemaAgreementAsync().Result), - 1000, 60); - var table = new Table(session, MappingConfiguration.Global, "author", ks); - TestHelper.RetryAssert(() => - { - try - { - table.CreateIfNotExists(); - RowSet rs = null; - Assert.Throws(() => { rs = session.Execute($"INSERT INTO {ks}.author(authorid) VALUES ('auth')"); }); - - Assert.Throws(() => - { - rs = session.Execute($"INSERT INTO {ks}.author(authorid) VALUES ('auth')", "profile"); - }); - - rs = session.Execute($"INSERT INTO {ks}.author(authorid) VALUES ('auth')", "derived"); - Assert.AreEqual(ConsistencyLevel.LocalQuorum, rs.Info.AchievedConsistency); - - rs = session.Execute($"INSERT INTO {ks}.author(authorid) VALUES ('auth') IF NOT EXISTS", "derived"); - Assert.IsTrue(string.Compare(rs.First()["[applied]"].ToString(), "false", StringComparison.OrdinalIgnoreCase) == 0); - - rs = session.Execute($"SELECT authorid FROM {ks}.author WHERE authorid = 'auth'", "derived"); - var row = rs.First(); - Assert.AreEqual(ConsistencyLevel.LocalQuorum, rs.Info.AchievedConsistency); - Assert.AreEqual("auth", row["authorid"].ToString()); - } - catch (QueryTimeoutException) { } - }, 1000, 10); - } - - private void AssertCaMismatchSslError(NoHostAvailableException ex) - { -#if NETCOREAPP - var ex2 = ex.InnerException; - Assert.IsTrue(ex2 is HttpRequestException, ex2.ToString()); - var ex3 = ex2.InnerException; - Assert.IsTrue(ex2 is HttpRequestException, ex2.ToString()); - Assert.IsTrue(ex2.Message.Contains("The SSL connection could not be established"), ex2.Message); -#elif NETFRAMEWORK - if (TestHelper.IsMono) - { - var ex2 = ex.InnerException; - Assert.IsTrue(ex2 is WebException, ex2.ToString()); - Assert.IsTrue(ex2.Message.Contains("Authentication failed"), ex2.Message); - Assert.IsTrue(ex2.Message.Contains("TrustFailure"), ex2.Message); - } - else - { - var ex2 = ex.InnerException; - Assert.IsTrue(ex2 is WebException, ex2.ToString()); - Assert.IsTrue(ex2.Message.Contains("Could not establish trust relationship for the SSL/TLS secure channel"), ex2.Message); - } -#endif - } - - private void AssertIsSslError(NoHostAvailableException ex) - { -#if NETFRAMEWORK - if (TestHelper.IsMono) - { - var ex2 = ex.InnerException; - Assert.IsTrue(ex2 is WebException, ex2.ToString()); - Assert.IsTrue(ex2.Message.Contains("Authentication failed"), ex2.Message); - Assert.IsTrue(ex2.Message.Contains("SecureChannelFailure"), ex2.Message); - } - else - { - var ex2 = ex.InnerException; - Assert.IsTrue(ex2 is WebException, ex2.ToString()); - Assert.IsTrue(ex2.Message.Contains("Could not create SSL/TLS secure channel."), ex2.Message); - } -#else - var ex2 = ex.InnerException; - Assert.IsTrue(ex2 is HttpRequestException, ex2.ToString()); - - // SocketsHttpHandler - Assert.IsTrue(ex2.Message.Contains("The SSL connection could not be established"), ex2.Message); -#endif - } - } -} \ No newline at end of file diff --git a/src/Cassandra.IntegrationTests/SharedCloudClusterTest.cs b/src/Cassandra.IntegrationTests/SharedCloudClusterTest.cs deleted file mode 100644 index 466044180..000000000 --- a/src/Cassandra.IntegrationTests/SharedCloudClusterTest.cs +++ /dev/null @@ -1,139 +0,0 @@ -// -// Copyright (C) DataStax Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using System.IO; -using System.Threading.Tasks; -using Cassandra.IntegrationTests.TestClusterManagement; - -namespace Cassandra.IntegrationTests -{ - public abstract class SharedCloudClusterTest : SharedClusterTest - { - private const int MaxRetries = 10; - - private readonly bool _sniCertValidation; - private readonly bool _clientCert; - protected override string[] SetupQueries => base.SetupQueries; - - protected new ICluster Cluster => _cluster; - - private ICluster _cluster; - - protected SharedCloudClusterTest( - bool createSession = true, bool sniCertValidation = true, bool clientCert = true) : - base(3, createSession) - { - _sniCertValidation = sniCertValidation; - _clientCert = clientCert; - } - - public override void OneTimeSetUp() - { - base.OneTimeSetUp(); - } - - public override void OneTimeTearDown() - { - base.OneTimeTearDown(); - TestCloudClusterManager.TryRemove(); - } - - protected override void CreateCommonSession() - { - Exception last = null; - for (var i = 0; i < SharedCloudClusterTest.MaxRetries; i++) - { - try - { - _cluster = CreateCluster(); - SetBaseSession(Cluster.Connect()); - return; - } - catch (Exception ex) - { - last = ex; - Task.Delay(1000).GetAwaiter().GetResult(); - if (Cluster != null) - { - Cluster.Dispose(); - _cluster = null; - } - } - } - throw last; - } - - private ICluster CreateCluster(string creds = "creds-v1.zip", Action act = null, bool withCredentials = true) - { - var builder = ClusterBuilder() - .WithSocketOptions(new SocketOptions().SetReadTimeoutMillis(22000).SetConnectTimeoutMillis(60000)) - .WithQueryTimeout(60000); - act?.Invoke(builder); - builder = builder - .WithCloudSecureConnectionBundle( - Path.Combine(((CloudCluster)TestCluster).SniHomeDirectory, "certs", "bundles", creds)) - .WithPoolingOptions( - new PoolingOptions().SetHeartBeatInterval(200)) - .WithReconnectionPolicy(new ConstantReconnectionPolicy(100)); - - if (withCredentials) - { - builder = builder.WithCredentials("user1", "user1"); - } - - return builder.Build(); - } - - protected ICluster CreateTemporaryCluster(string creds = "creds-v1.zip", Action act = null, bool withCredentials = true) - { - var cluster = CreateCluster(creds, act, withCredentials); - ClusterInstances.Add(cluster); - return cluster; - } - - protected async Task CreateSessionAsync( - string creds = "creds-v1.zip", int retries = SharedCloudClusterTest.MaxRetries, Action act = null) - { - Exception last = null; - ICluster cluster = null; - for (var i = 0; i < SharedCloudClusterTest.MaxRetries; i++) - { - try - { - cluster = CreateTemporaryCluster(creds, act); - return await cluster.ConnectAsync().ConfigureAwait(false); - } - catch (Exception ex) - { - last = ex; - Task.Delay(1000).GetAwaiter().GetResult(); - if (cluster != null) - { - cluster.Dispose(); - cluster = null; - } - } - } - throw last; - } - - protected override ITestCluster CreateNew(int nodeLength, TestClusterOptions options, bool startCluster) - { - return TestCloudClusterManager.CreateNew(_sniCertValidation); - } - } -} diff --git a/src/Cassandra.Tests/ApiTests.cs b/src/Cassandra.Tests/ApiTests.cs index 4d2b55dcc..9e72678e4 100644 --- a/src/Cassandra.Tests/ApiTests.cs +++ b/src/Cassandra.Tests/ApiTests.cs @@ -17,7 +17,6 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; -using Cassandra.DataStax.Auth; using NUnit.Framework; namespace Cassandra.Tests @@ -47,8 +46,6 @@ public void Cassandra_Exported_Namespaces() "Cassandra.Connections", "Cassandra.Data", "Cassandra.Data.Linq", - "Cassandra.DataStax.Auth.Sspi", - "Cassandra.DataStax.Search", "Cassandra.Mapping", "Cassandra.Mapping.Attributes", "Cassandra.Mapping.TypeConversion", diff --git a/src/Cassandra.Tests/BuilderTests.cs b/src/Cassandra.Tests/BuilderTests.cs index 84d654a1b..46936c142 100644 --- a/src/Cassandra.Tests/BuilderTests.cs +++ b/src/Cassandra.Tests/BuilderTests.cs @@ -268,132 +268,6 @@ public void Should_ReturnDefaultMaxSchemaAgreementWaitSeconds_When_NotProvidedTo Assert.AreEqual(expected, config.ProtocolOptions.MaxSchemaAgreementWaitSeconds); } - [Test] - public void Should_ThrowException_When_ContactPointAndBundleAreProvided() - { - const string exceptionMsg = "Contact points can not be set when a secure connection bundle is provided."; - var builder = Cluster.Builder() - .AddContactPoint("192.168.1.10") - .WithCloudSecureConnectionBundle("bundle"); - - var ex = Assert.Throws(() => builder.Build()); - Assert.AreEqual(exceptionMsg, ex.Message); - - builder = Cluster.Builder() - .AddContactPoint(IPAddress.Parse("192.168.1.10")) - .WithCloudSecureConnectionBundle("bundle"); - - ex = Assert.Throws(() => builder.Build()); - Assert.AreEqual(exceptionMsg, ex.Message); - - builder = Cluster.Builder() - .AddContactPoint(new IPEndPoint(IPAddress.Parse("192.168.1.10"), 9042)) - .WithCloudSecureConnectionBundle("bundle"); - - ex = Assert.Throws(() => builder.Build()); - Assert.AreEqual(exceptionMsg, ex.Message); - - builder = Cluster.Builder() - .AddContactPoints(new IPEndPoint(IPAddress.Parse("192.168.1.10"), 9042)) - .WithCloudSecureConnectionBundle("bundle"); - - ex = Assert.Throws(() => builder.Build()); - Assert.AreEqual(exceptionMsg, ex.Message); - - builder = Cluster.Builder() - .AddContactPoint(IPAddress.Parse("192.168.1.10")) - .WithCloudSecureConnectionBundle("bundle"); - - ex = Assert.Throws(() => builder.Build()); - Assert.AreEqual(exceptionMsg, ex.Message); - - builder = Cluster.Builder() - .WithCloudSecureConnectionBundle("bundle") - .AddContactPoint(IPAddress.Parse("192.168.1.10")); - - ex = Assert.Throws(() => builder.Build()); - Assert.AreEqual(exceptionMsg, ex.Message); - } - - [Test] - public void Should_ThrowException_When_SslOptionsAndBundleAreProvided() - { - const string exceptionMsg = "SSL options can not be set when a secure connection bundle is provided."; - var builder = Cluster.Builder() - .WithSSL() - .WithCloudSecureConnectionBundle("bundle"); - - var ex = Assert.Throws(() => builder.Build()); - Assert.AreEqual(exceptionMsg, ex.Message); - - builder = Cluster.Builder() - .WithSSL() - .WithCloudSecureConnectionBundle("bundle"); - - ex = Assert.Throws(() => builder.Build()); - Assert.AreEqual(exceptionMsg, ex.Message); - - builder = Cluster.Builder() - .WithSSL() - .WithCloudSecureConnectionBundle("bundle"); - - ex = Assert.Throws(() => builder.Build()); - Assert.AreEqual(exceptionMsg, ex.Message); - - builder = Cluster.Builder() - .WithSSL() - .WithCloudSecureConnectionBundle("bundle"); - - ex = Assert.Throws(() => builder.Build()); - Assert.AreEqual(exceptionMsg, ex.Message); - - builder = Cluster.Builder() - .WithSSL() - .WithCloudSecureConnectionBundle("bundle"); - - ex = Assert.Throws(() => builder.Build()); - Assert.AreEqual(exceptionMsg, ex.Message); - - builder = Cluster.Builder() - .WithCloudSecureConnectionBundle("bundle") - .WithSSL(); - - ex = Assert.Throws(() => builder.Build()); - Assert.AreEqual(exceptionMsg, ex.Message); - } - - [Test] - public void Should_ThrowException_When_CredentialsAreNotProvidedWithBundle() - { - const string exceptionMsg = "No credentials were provided. When using the secure connection bundle"; - var builder = Cluster.Builder() - .WithCloudSecureConnectionBundle("bundle"); - - var ex = Assert.Throws(() => builder.Build()); - Assert.IsTrue(ex.Message.Contains(exceptionMsg), ex.Message); - } - - [Test] - public void Should_ThrowException_When_SslOptionsAndContactPointAndBundleAreProvided() - { - const string exceptionMsg = "SSL options can not be set when a secure connection bundle is provided."; - var builder = Cluster.Builder() - .AddContactPoints("127.0.0.1") - .WithSSL() - .WithCloudSecureConnectionBundle("bundle"); - - var ex = Assert.Throws(() => builder.Build()); - Assert.AreEqual(exceptionMsg, ex.Message); - - builder = Cluster.Builder() - .WithSSL() - .AddContactPoints("127.0.0.1") - .WithCloudSecureConnectionBundle("bundle"); - - ex = Assert.Throws(() => builder.Build()); - Assert.AreEqual(exceptionMsg, ex.Message); - } - [Test] public void Should_Build_A_Cluster_With_Default_Graph_Options() { diff --git a/src/Cassandra.Tests/DataStax/Cloud/CloudConfigurationParserTests.cs b/src/Cassandra.Tests/DataStax/Cloud/CloudConfigurationParserTests.cs deleted file mode 100644 index 60adcccbc..000000000 --- a/src/Cassandra.Tests/DataStax/Cloud/CloudConfigurationParserTests.cs +++ /dev/null @@ -1,172 +0,0 @@ -// -// Copyright (C) DataStax Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using System.IO; -using System.Text; -using Cassandra.DataStax.Cloud; -using NUnit.Framework; - -namespace Cassandra.Tests.DataStax.Cloud -{ - [TestFixture] - public class CloudConfigurationParserTests - { - [Test] - public void Should_ParseCorrectly_When_AllPropertiesAreThereAndMore() - { - var randomString = Guid.NewGuid().ToString().Replace("-", ""); - var randomString2 = Guid.NewGuid().ToString().Replace("-", ""); - var randomString3 = Guid.NewGuid().ToString().Replace("-", ""); - var randomString4 = Guid.NewGuid().ToString().Replace("-", ""); - var randomString5 = Guid.NewGuid().ToString().Replace("-", ""); - var a = -"{" + - $"\"username\": \"{randomString}\"," + - $"\"password\": \"{randomString2}\"," + - "\"host\": \"ea20d9d5-f69e-46ad-8eb1-f32f33a7472e.us-east-1.dse.datastax.com\"," + - "\"port\": 30443," + - $"\"keyspace\": \"{randomString3}\"," + - "\"localDC\": \"aws-us-east-1\"," + - "\"caCertLocation\": \"./ca.crt\"," + - "\"keyLocation\": \"./key\"," + - "\"certLocation\": \"./cert\"," + - "\"keyStoreLocation\": \"./identity.jks\"," + - $"\"keyStorePassword\": \"{randomString4}\"," + - "\"trustStoreLocation\": \"./trustStore.jks\"," + - $"\"trustStorePassword\": \"{randomString5}\"," + - "\"csvLocation\": \"./data\"" + -"}"; - var stream = new MemoryStream(Encoding.Default.GetBytes(a)); - var target = new CloudConfigurationParser(); - - var config = target.ParseConfig(stream); - - Assert.AreEqual(30443, config.Port); - Assert.AreEqual("ea20d9d5-f69e-46ad-8eb1-f32f33a7472e.us-east-1.dse.datastax.com", config.Host); - } - - [Test] - public void Should_ParseCorrectly_When_OnlyRequiredPropertiesAreThere() - { - var a = -@"{ - ""host"": ""ea20d9d5-f69e-46ad-8eb1-f32f33a7472e.us-east-1.dse.datastax.com"", - ""port"": 30443, - ""localDC"": ""aws-us-east-1"" -}"; - var stream = new MemoryStream(Encoding.Default.GetBytes(a)); - var target = new CloudConfigurationParser(); - - var config = target.ParseConfig(stream); - - Assert.AreEqual(30443, config.Port); - Assert.AreEqual("ea20d9d5-f69e-46ad-8eb1-f32f33a7472e.us-east-1.dse.datastax.com", config.Host); - } - - [Test] - public void Should_ParseCorrectly_When_AllPropertiesAreThere() - { - var randomString = Guid.NewGuid().ToString().Replace("-", ""); - var randomString2 = Guid.NewGuid().ToString().Replace("-", ""); - var randomString3 = Guid.NewGuid().ToString().Replace("-", ""); - var a = -@"{" + - $"\"username\": \"{randomString}\"," + - $"\"password\": \"{randomString2}\"," + - "\"host\": \"ea20d9d5-f69e-46ad-8eb1-f32f33a7472e.us-east-1.dse.datastax.com\"," + - "\"port\": 30443," + - $"\"keyspace\": \"{randomString3}\"," + - "\"localDC\": \"aws-us-east-1\"" + -"}"; - var stream = new MemoryStream(Encoding.Default.GetBytes(a)); - var target = new CloudConfigurationParser(); - - var config = target.ParseConfig(stream); - - Assert.AreEqual(30443, config.Port); - Assert.AreEqual("ea20d9d5-f69e-46ad-8eb1-f32f33a7472e.us-east-1.dse.datastax.com", config.Host); - } - - [Test] - public void Should_ThrowException_When_HostIsNotThere() - { - var randomString = Guid.NewGuid().ToString().Replace("-", ""); - var randomString2 = Guid.NewGuid().ToString().Replace("-", ""); - var randomString3 = Guid.NewGuid().ToString().Replace("-", ""); - var a = -"{" + - $"\"username\": \"{randomString}\"," + - $"\"password\": \"{randomString2}\"," + - "\"port\": 30443," + - $"\"keyspace\": \"{randomString3}\"," + - "\"localDC\": \"aws-us-east-1\"" + -"}"; - var stream = new MemoryStream(Encoding.Default.GetBytes(a)); - var target = new CloudConfigurationParser(); - - var ex = Assert.Throws(() => target.ParseConfig(stream)); - - Assert.IsTrue(ex.Message.Contains("Could not parse the \"host\""), ex.Message); - } - - [Test] - public void Should_ThrowException_When_PortIsNotThere() - { - var randomString = Guid.NewGuid().ToString().Replace("-", ""); - var randomString2 = Guid.NewGuid().ToString().Replace("-", ""); - var randomString3 = Guid.NewGuid().ToString().Replace("-", ""); - var a = -"{" + - $"\"username\": \"{randomString}\"," + - $"\"password\": \"{randomString2}\"," + - "\"host\": \"ea20d9d5-f69e-46ad-8eb1-f32f33a7472e.us-east-1.dse.datastax.com\"," + - $"\"keyspace\": \"{randomString3}\"," + - "\"localDC\": \"aws-us-east-1\"" + -"}"; - var stream = new MemoryStream(Encoding.Default.GetBytes(a)); - var target = new CloudConfigurationParser(); - - var ex = Assert.Throws(() => target.ParseConfig(stream)); - - Assert.IsTrue(ex.Message.Contains("Could not parse the \"port\""), ex.Message); - } - - [Test] - public void Should_ThrowException_When_ConfigIsEmpty() - { - var a = @""; - var stream = new MemoryStream(Encoding.Default.GetBytes(a)); - var target = new CloudConfigurationParser(); - - var ex = Assert.Throws(() => target.ParseConfig(stream)); - - Assert.IsTrue(ex.Message.Contains("Config file is empty"), ex.Message); - } - - [Test] - public void Should_ThrowException_When_ConfigDoesntHaveAnyRelevantProperty() - { - var a = @"{""keyStoreLocation"": ""./identity.jks""}"; - var stream = new MemoryStream(Encoding.Default.GetBytes(a)); - var target = new CloudConfigurationParser(); - - var ex = Assert.Throws(() => target.ParseConfig(stream)); - - Assert.IsTrue(ex.Message.Contains("Could not parse"), ex.Message); - } - } -} \ No newline at end of file diff --git a/src/Cassandra.Tests/DataStax/Cloud/CloudMetadataServiceTests.cs b/src/Cassandra.Tests/DataStax/Cloud/CloudMetadataServiceTests.cs deleted file mode 100644 index ff6e02756..000000000 --- a/src/Cassandra.Tests/DataStax/Cloud/CloudMetadataServiceTests.cs +++ /dev/null @@ -1,35 +0,0 @@ -// -// Copyright (C) DataStax Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using Cassandra.DataStax.Cloud; -using Cassandra.Tests.TestAttributes; -using NUnit.Framework; - -namespace Cassandra.Tests.DataStax.Cloud -{ - [TestFixture] - public class CloudMetadataServiceTests - { - [Test] - [CloudSupported(Supported = false)] - public void Should_ThrowNotSupported_When_NetCore20() - { - Assert.Throws(() => - new CloudMetadataService().GetClusterMetadataAsync(null, null, null).GetAwaiter().GetResult()); - } - } -} \ No newline at end of file diff --git a/src/Cassandra.Tests/DataStax/Cloud/CustomCaCertificateValidatorTests.cs b/src/Cassandra.Tests/DataStax/Cloud/CustomCaCertificateValidatorTests.cs deleted file mode 100644 index ea7c384ae..000000000 --- a/src/Cassandra.Tests/DataStax/Cloud/CustomCaCertificateValidatorTests.cs +++ /dev/null @@ -1,100 +0,0 @@ -// -// Copyright (C) DataStax Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using System.Net.Security; -using System.Security.Cryptography.X509Certificates; - -using Cassandra.DataStax.Cloud; - -using NUnit.Framework; - -namespace Cassandra.Tests.DataStax.Cloud -{ - [TestFixture] - public class CustomCaCertificateValidatorTests - { - /// - /// Positive test validator with custom domain in SAN - /// - [Test] - public void TestCertificateWithCustomDomainInSan_WithNormalDomain() - { - // customdomain.crt - var customDomainRawData = - "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZHakNDQkFLZ0F3SUJBZ0lVZlZ5T2trQjVVY0g0dzh0c1NNQ1FadCtWZldjd0RRWUpLb1pJaHZjTkFRRUwKQlFBd2dZVXhDekFKQmdOVkJBWVRBbFZUTVE0d0RBWURWUVFJREFWVGRHRjBaVEVOTUFzR0ExVUVCd3dFUTJsMAplVEVRTUE0R0ExVUVDZ3dIUTI5dGNHRnVlVEVMTUFrR0ExVUVDd3dDUWxVeEZqQVVCZ05WQkFNTURTb3VaWGhoCmJYQnNaUzVqYjIweElEQWVCZ2txaGtpRzl3MEJDUUVXRVdGa2JXbHVRR1Y0WVcxd2JHVXVZMjl0TUNBWERUSXoKTVRFd056RTFORE15TlZvWUR6TXdNak13TXpFd01UVTBNekkxV2pDQmhURUxNQWtHQTFVRUJoTUNWVk14RGpBTQpCZ05WQkFnTUJWTjBZWFJsTVEwd0N3WURWUVFIREFSRGFYUjVNUkF3RGdZRFZRUUtEQWREYjIxd1lXNTVNUXN3CkNRWURWUVFMREFKQ1ZURVdNQlFHQTFVRUF3d05LaTVsZUdGdGNHeGxMbU52YlRFZ01CNEdDU3FHU0liM0RRRUoKQVJZUllXUnRhVzVBWlhoaGJYQnNaUzVqYjIwd2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUJEd0F3Z2dFSwpBb0lCQVFDeSs4eGx3WW8rQ1IrZVFUSEZuVURTOGlSLzAyaGM3dlhCUUk2RGkyZ3dVR3pKVzUzUVR4N3MvYkI3Ck84YTVRZEI5RVBPVjREclFZZFZidFMwMFpwRmlhWWJxU1NQeko2bUdsWFFQVjBiWFduWXJGL3NvN295dUpmOVcKdzlGcWxoa1VPd1NUamNxWUNuT3hrSDBHRWx3YzZxUTRTTmFFRVJNcW13K0orb0R2dTljeHlGT1pFb3hPNUhjbQpVU2FEcTNXUkkwVXY0Ky9nQlZNVlVFNVVscVRpQlBUNG9vUDhxTkxheTUrSFRYQTlwRmdzMTlmSTJxdjlkSDlKCmZNcExkc2txMERNemZoZHgrbkdLSDBiVlc5MHdqWWJGbGkwcWVPRWFWNTA2Q012K3A4WlhyWUlWdXIreGZSamQKMUkyN05yVldiTVdMSUFPQ0d3UllwM010T3RmekFnTUJBQUdqZ2dGOE1JSUJlREFkQmdOVkhRNEVGZ1FVdHJNdgpIb1g2c2h2NUo4Ni9jeTNDRmdPVzluUXdnY1VHQTFVZEl3U0J2VENCdW9BVXRyTXZIb1g2c2h2NUo4Ni9jeTNDCkZnT1c5blNoZ1l1a2dZZ3dnWVV4Q3pBSkJnTlZCQVlUQWxWVE1RNHdEQVlEVlFRSURBVlRkR0YwWlRFTk1Bc0cKQTFVRUJ3d0VRMmwwZVRFUU1BNEdBMVVFQ2d3SFEyOXRjR0Z1ZVRFTE1Ba0dBMVVFQ3d3Q1FsVXhGakFVQmdOVgpCQU1NRFNvdVpYaGhiWEJzWlM1amIyMHhJREFlQmdrcWhraUc5dzBCQ1FFV0VXRmtiV2x1UUdWNFlXMXdiR1V1ClkyOXRnaFI5WEk2U1FIbFJ3ZmpEeTJ4SXdKQm0zNVY5WnpBTUJnTlZIUk1FQlRBREFRSC9NQXNHQTFVZER3UUUKQXdJQy9EQTVCZ05WSFJFRU1qQXdnZ3RsZUdGdGNHeGxMbU52YllJTktpNWxlR0Z0Y0d4bExtTnZiWUlTS2k1agpkWE4wYjIxa2IyMWhhVzR1WTI5dE1Ea0dBMVVkRWdReU1EQ0NDMlY0WVcxd2JHVXVZMjl0Z2cwcUxtVjRZVzF3CmJHVXVZMjl0Z2hJcUxtTjFjM1J2YldSdmJXRnBiaTVqYjIwd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFDQkQKYXVManJpRDNoRERmY3FMTUR4MVorT1l3U2UzaGdicXRadGFYUnVEZGlxeFE5dDY5dkxPWGY1WFA5dGxxODZxSQpXWHBtWEpRQ2VodDFnU00rL3lpNW1iQnZxaVl3SUJtblJNeUFIK3A1dzAyU0NxRk92ZTBmYm56VWdMVTBvWWliClFBbXdJdm9oRXJvZ1V6RG05Q01sS1lrdmdjSDhnZGVqbXJBdlNuZGVyMWVjU2ZmendYelFLUjBMSzNjQjQzbUEKK2RJK01Wa3FSbmFxeDdnZVZCaEhLblZVcklnMWQ5UVYwUFM5N0ZSSjkyd2VPY2xiTzl0MkpmOHE3Kzl3S3kybgpUVUtmem5DVkUyNjhOUUNISDhQd0NPUGljYU9IdFBlbWhhN0YrMUcwU1YrNjk1ZFFTOXQ1VE1EUi9JeEk3emFKCnFCRTNEMnVBVGlFaGE5bHFVazA9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K"; - var cert = new X509Certificate2(Convert.FromBase64String(customDomainRawData)); - var chain = new X509Chain(); - chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; - chain.Build(cert); - Assert.AreEqual("*.example.com", cert.GetNameInfo(X509NameType.SimpleName, false)); - Assert.True(new CustomCaCertificateValidator(cert, "test123.example.com").Validate(cert, chain, SslPolicyErrors.RemoteCertificateChainErrors | SslPolicyErrors.RemoteCertificateNameMismatch)); - } - - /// - /// Positive test validator with custom domain in SAN - /// - [Test] - public void TestCertificateWithCustomDomainInSan_WithCustomDomain() - { - // customdomain.crt - var customDomainRawData = - "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZHakNDQkFLZ0F3SUJBZ0lVZlZ5T2trQjVVY0g0dzh0c1NNQ1FadCtWZldjd0RRWUpLb1pJaHZjTkFRRUwKQlFBd2dZVXhDekFKQmdOVkJBWVRBbFZUTVE0d0RBWURWUVFJREFWVGRHRjBaVEVOTUFzR0ExVUVCd3dFUTJsMAplVEVRTUE0R0ExVUVDZ3dIUTI5dGNHRnVlVEVMTUFrR0ExVUVDd3dDUWxVeEZqQVVCZ05WQkFNTURTb3VaWGhoCmJYQnNaUzVqYjIweElEQWVCZ2txaGtpRzl3MEJDUUVXRVdGa2JXbHVRR1Y0WVcxd2JHVXVZMjl0TUNBWERUSXoKTVRFd056RTFORE15TlZvWUR6TXdNak13TXpFd01UVTBNekkxV2pDQmhURUxNQWtHQTFVRUJoTUNWVk14RGpBTQpCZ05WQkFnTUJWTjBZWFJsTVEwd0N3WURWUVFIREFSRGFYUjVNUkF3RGdZRFZRUUtEQWREYjIxd1lXNTVNUXN3CkNRWURWUVFMREFKQ1ZURVdNQlFHQTFVRUF3d05LaTVsZUdGdGNHeGxMbU52YlRFZ01CNEdDU3FHU0liM0RRRUoKQVJZUllXUnRhVzVBWlhoaGJYQnNaUzVqYjIwd2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUJEd0F3Z2dFSwpBb0lCQVFDeSs4eGx3WW8rQ1IrZVFUSEZuVURTOGlSLzAyaGM3dlhCUUk2RGkyZ3dVR3pKVzUzUVR4N3MvYkI3Ck84YTVRZEI5RVBPVjREclFZZFZidFMwMFpwRmlhWWJxU1NQeko2bUdsWFFQVjBiWFduWXJGL3NvN295dUpmOVcKdzlGcWxoa1VPd1NUamNxWUNuT3hrSDBHRWx3YzZxUTRTTmFFRVJNcW13K0orb0R2dTljeHlGT1pFb3hPNUhjbQpVU2FEcTNXUkkwVXY0Ky9nQlZNVlVFNVVscVRpQlBUNG9vUDhxTkxheTUrSFRYQTlwRmdzMTlmSTJxdjlkSDlKCmZNcExkc2txMERNemZoZHgrbkdLSDBiVlc5MHdqWWJGbGkwcWVPRWFWNTA2Q012K3A4WlhyWUlWdXIreGZSamQKMUkyN05yVldiTVdMSUFPQ0d3UllwM010T3RmekFnTUJBQUdqZ2dGOE1JSUJlREFkQmdOVkhRNEVGZ1FVdHJNdgpIb1g2c2h2NUo4Ni9jeTNDRmdPVzluUXdnY1VHQTFVZEl3U0J2VENCdW9BVXRyTXZIb1g2c2h2NUo4Ni9jeTNDCkZnT1c5blNoZ1l1a2dZZ3dnWVV4Q3pBSkJnTlZCQVlUQWxWVE1RNHdEQVlEVlFRSURBVlRkR0YwWlRFTk1Bc0cKQTFVRUJ3d0VRMmwwZVRFUU1BNEdBMVVFQ2d3SFEyOXRjR0Z1ZVRFTE1Ba0dBMVVFQ3d3Q1FsVXhGakFVQmdOVgpCQU1NRFNvdVpYaGhiWEJzWlM1amIyMHhJREFlQmdrcWhraUc5dzBCQ1FFV0VXRmtiV2x1UUdWNFlXMXdiR1V1ClkyOXRnaFI5WEk2U1FIbFJ3ZmpEeTJ4SXdKQm0zNVY5WnpBTUJnTlZIUk1FQlRBREFRSC9NQXNHQTFVZER3UUUKQXdJQy9EQTVCZ05WSFJFRU1qQXdnZ3RsZUdGdGNHeGxMbU52YllJTktpNWxlR0Z0Y0d4bExtTnZiWUlTS2k1agpkWE4wYjIxa2IyMWhhVzR1WTI5dE1Ea0dBMVVkRWdReU1EQ0NDMlY0WVcxd2JHVXVZMjl0Z2cwcUxtVjRZVzF3CmJHVXVZMjl0Z2hJcUxtTjFjM1J2YldSdmJXRnBiaTVqYjIwd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFDQkQKYXVManJpRDNoRERmY3FMTUR4MVorT1l3U2UzaGdicXRadGFYUnVEZGlxeFE5dDY5dkxPWGY1WFA5dGxxODZxSQpXWHBtWEpRQ2VodDFnU00rL3lpNW1iQnZxaVl3SUJtblJNeUFIK3A1dzAyU0NxRk92ZTBmYm56VWdMVTBvWWliClFBbXdJdm9oRXJvZ1V6RG05Q01sS1lrdmdjSDhnZGVqbXJBdlNuZGVyMWVjU2ZmendYelFLUjBMSzNjQjQzbUEKK2RJK01Wa3FSbmFxeDdnZVZCaEhLblZVcklnMWQ5UVYwUFM5N0ZSSjkyd2VPY2xiTzl0MkpmOHE3Kzl3S3kybgpUVUtmem5DVkUyNjhOUUNISDhQd0NPUGljYU9IdFBlbWhhN0YrMUcwU1YrNjk1ZFFTOXQ1VE1EUi9JeEk3emFKCnFCRTNEMnVBVGlFaGE5bHFVazA9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K"; - var cert = new X509Certificate2(Convert.FromBase64String(customDomainRawData)); - var chain = new X509Chain(); - chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; - chain.Build(cert); - Assert.AreEqual("*.example.com", cert.GetNameInfo(X509NameType.SimpleName, false)); - Assert.True(new CustomCaCertificateValidator(cert, "test123.customdomain.com").Validate(cert, chain, SslPolicyErrors.RemoteCertificateChainErrors | SslPolicyErrors.RemoteCertificateNameMismatch)); - } - - /// - /// Positive test validator without custom domain in SAN - /// - [Test] - public void TestCertificateWithoutCustomDomainInSan_WithNormalDomain() - { - // example.crt - var rawData = - "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUU4akNDQTlxZ0F3SUJBZ0lVWHBMT2UrVHpJY0x4SUFHNjVwWjAzbHFpMzFBd0RRWUpLb1pJaHZjTkFRRUwKQlFBd2dZVXhDekFKQmdOVkJBWVRBbFZUTVE0d0RBWURWUVFJREFWVGRHRjBaVEVOTUFzR0ExVUVCd3dFUTJsMAplVEVRTUE0R0ExVUVDZ3dIUTI5dGNHRnVlVEVMTUFrR0ExVUVDd3dDUWxVeEZqQVVCZ05WQkFNTURTb3VaWGhoCmJYQnNaUzVqYjIweElEQWVCZ2txaGtpRzl3MEJDUUVXRVdGa2JXbHVRR1Y0WVcxd2JHVXVZMjl0TUNBWERUSXoKTVRFd056RTFORE0wTjFvWUR6TXdNak13TXpFd01UVTBNelEzV2pDQmhURUxNQWtHQTFVRUJoTUNWVk14RGpBTQpCZ05WQkFnTUJWTjBZWFJsTVEwd0N3WURWUVFIREFSRGFYUjVNUkF3RGdZRFZRUUtEQWREYjIxd1lXNTVNUXN3CkNRWURWUVFMREFKQ1ZURVdNQlFHQTFVRUF3d05LaTVsZUdGdGNHeGxMbU52YlRFZ01CNEdDU3FHU0liM0RRRUoKQVJZUllXUnRhVzVBWlhoaGJYQnNaUzVqYjIwd2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUJEd0F3Z2dFSwpBb0lCQVFDeSs4eGx3WW8rQ1IrZVFUSEZuVURTOGlSLzAyaGM3dlhCUUk2RGkyZ3dVR3pKVzUzUVR4N3MvYkI3Ck84YTVRZEI5RVBPVjREclFZZFZidFMwMFpwRmlhWWJxU1NQeko2bUdsWFFQVjBiWFduWXJGL3NvN295dUpmOVcKdzlGcWxoa1VPd1NUamNxWUNuT3hrSDBHRWx3YzZxUTRTTmFFRVJNcW13K0orb0R2dTljeHlGT1pFb3hPNUhjbQpVU2FEcTNXUkkwVXY0Ky9nQlZNVlVFNVVscVRpQlBUNG9vUDhxTkxheTUrSFRYQTlwRmdzMTlmSTJxdjlkSDlKCmZNcExkc2txMERNemZoZHgrbkdLSDBiVlc5MHdqWWJGbGkwcWVPRWFWNTA2Q012K3A4WlhyWUlWdXIreGZSamQKMUkyN05yVldiTVdMSUFPQ0d3UllwM010T3RmekFnTUJBQUdqZ2dGVU1JSUJVREFkQmdOVkhRNEVGZ1FVdHJNdgpIb1g2c2h2NUo4Ni9jeTNDRmdPVzluUXdnY1VHQTFVZEl3U0J2VENCdW9BVXRyTXZIb1g2c2h2NUo4Ni9jeTNDCkZnT1c5blNoZ1l1a2dZZ3dnWVV4Q3pBSkJnTlZCQVlUQWxWVE1RNHdEQVlEVlFRSURBVlRkR0YwWlRFTk1Bc0cKQTFVRUJ3d0VRMmwwZVRFUU1BNEdBMVVFQ2d3SFEyOXRjR0Z1ZVRFTE1Ba0dBMVVFQ3d3Q1FsVXhGakFVQmdOVgpCQU1NRFNvdVpYaGhiWEJzWlM1amIyMHhJREFlQmdrcWhraUc5dzBCQ1FFV0VXRmtiV2x1UUdWNFlXMXdiR1V1ClkyOXRnaFJla3M1NzVQTWh3dkVnQWJybWxuVGVXcUxmVURBTUJnTlZIUk1FQlRBREFRSC9NQXNHQTFVZER3UUUKQXdJQy9EQWxCZ05WSFJFRUhqQWNnZ3RsZUdGdGNHeGxMbU52YllJTktpNWxlR0Z0Y0d4bExtTnZiVEFsQmdOVgpIUklFSGpBY2dndGxlR0Z0Y0d4bExtTnZiWUlOS2k1bGVHRnRjR3hsTG1OdmJUQU5CZ2txaGtpRzl3MEJBUXNGCkFBT0NBUUVBQzVGelZSM0VNODAxRWhBR2dLK2Q2OEpRYkpjZEJyMXloWHVDVUJLYnlYZHRTM1RGTStOdGNGZ3YKUDI0dXFuU05wSjB3SDRwQTdma0IwR0I2dUwvQmNZbHo0S1lTcEJHTWhoZEFyRnJ3S3hsb2tOVGx5RUJma0ovdwpDWWpkZGpzYkFvdUxsc3J6Nzl0VE93aVM3TEJQN1p6NHdqYWdIdkFncmpQTEVwcnhrVkhaNE1nSjVJY0RhdFhtCm5jdTk4NWhvT2VMWmpRRG9OVVpmWWwwdUJoNHNmYnY0OC9WdEJtSjAxVjVEbkVweEJWNUhuRjRIeW9ZTjZ6Y3kKNGZBU2E3ZzU1VTBReGY3T0JBT0NmVGFQbjR5ci9HK3ZDSTN3VWQzU2NzOW9laSttanNpNGJOcW1yR2dGZm5yMApvcWtNQzFtVXNtMEJQVmYveUdRSUpNZmRGSlRNS2c9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg=="; - - var cert = new X509Certificate2(Convert.FromBase64String(rawData)); - var chain = new X509Chain(); - chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; - chain.Build(cert); - Assert.AreEqual("*.example.com", cert.GetNameInfo(X509NameType.SimpleName, false)); - Assert.True(new CustomCaCertificateValidator(cert, "test123.example.com").Validate(cert, chain, SslPolicyErrors.RemoteCertificateChainErrors | SslPolicyErrors.RemoteCertificateNameMismatch)); - } - - /// - /// Negative test validator without custom domain in SAN - /// - [Test] - public void TestCertificateWithoutCustomDomainInSan_WithCustomDomain() - { - // example.crt - var rawData = - "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUU4akNDQTlxZ0F3SUJBZ0lVWHBMT2UrVHpJY0x4SUFHNjVwWjAzbHFpMzFBd0RRWUpLb1pJaHZjTkFRRUwKQlFBd2dZVXhDekFKQmdOVkJBWVRBbFZUTVE0d0RBWURWUVFJREFWVGRHRjBaVEVOTUFzR0ExVUVCd3dFUTJsMAplVEVRTUE0R0ExVUVDZ3dIUTI5dGNHRnVlVEVMTUFrR0ExVUVDd3dDUWxVeEZqQVVCZ05WQkFNTURTb3VaWGhoCmJYQnNaUzVqYjIweElEQWVCZ2txaGtpRzl3MEJDUUVXRVdGa2JXbHVRR1Y0WVcxd2JHVXVZMjl0TUNBWERUSXoKTVRFd056RTFORE0wTjFvWUR6TXdNak13TXpFd01UVTBNelEzV2pDQmhURUxNQWtHQTFVRUJoTUNWVk14RGpBTQpCZ05WQkFnTUJWTjBZWFJsTVEwd0N3WURWUVFIREFSRGFYUjVNUkF3RGdZRFZRUUtEQWREYjIxd1lXNTVNUXN3CkNRWURWUVFMREFKQ1ZURVdNQlFHQTFVRUF3d05LaTVsZUdGdGNHeGxMbU52YlRFZ01CNEdDU3FHU0liM0RRRUoKQVJZUllXUnRhVzVBWlhoaGJYQnNaUzVqYjIwd2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUJEd0F3Z2dFSwpBb0lCQVFDeSs4eGx3WW8rQ1IrZVFUSEZuVURTOGlSLzAyaGM3dlhCUUk2RGkyZ3dVR3pKVzUzUVR4N3MvYkI3Ck84YTVRZEI5RVBPVjREclFZZFZidFMwMFpwRmlhWWJxU1NQeko2bUdsWFFQVjBiWFduWXJGL3NvN295dUpmOVcKdzlGcWxoa1VPd1NUamNxWUNuT3hrSDBHRWx3YzZxUTRTTmFFRVJNcW13K0orb0R2dTljeHlGT1pFb3hPNUhjbQpVU2FEcTNXUkkwVXY0Ky9nQlZNVlVFNVVscVRpQlBUNG9vUDhxTkxheTUrSFRYQTlwRmdzMTlmSTJxdjlkSDlKCmZNcExkc2txMERNemZoZHgrbkdLSDBiVlc5MHdqWWJGbGkwcWVPRWFWNTA2Q012K3A4WlhyWUlWdXIreGZSamQKMUkyN05yVldiTVdMSUFPQ0d3UllwM010T3RmekFnTUJBQUdqZ2dGVU1JSUJVREFkQmdOVkhRNEVGZ1FVdHJNdgpIb1g2c2h2NUo4Ni9jeTNDRmdPVzluUXdnY1VHQTFVZEl3U0J2VENCdW9BVXRyTXZIb1g2c2h2NUo4Ni9jeTNDCkZnT1c5blNoZ1l1a2dZZ3dnWVV4Q3pBSkJnTlZCQVlUQWxWVE1RNHdEQVlEVlFRSURBVlRkR0YwWlRFTk1Bc0cKQTFVRUJ3d0VRMmwwZVRFUU1BNEdBMVVFQ2d3SFEyOXRjR0Z1ZVRFTE1Ba0dBMVVFQ3d3Q1FsVXhGakFVQmdOVgpCQU1NRFNvdVpYaGhiWEJzWlM1amIyMHhJREFlQmdrcWhraUc5dzBCQ1FFV0VXRmtiV2x1UUdWNFlXMXdiR1V1ClkyOXRnaFJla3M1NzVQTWh3dkVnQWJybWxuVGVXcUxmVURBTUJnTlZIUk1FQlRBREFRSC9NQXNHQTFVZER3UUUKQXdJQy9EQWxCZ05WSFJFRUhqQWNnZ3RsZUdGdGNHeGxMbU52YllJTktpNWxlR0Z0Y0d4bExtTnZiVEFsQmdOVgpIUklFSGpBY2dndGxlR0Z0Y0d4bExtTnZiWUlOS2k1bGVHRnRjR3hsTG1OdmJUQU5CZ2txaGtpRzl3MEJBUXNGCkFBT0NBUUVBQzVGelZSM0VNODAxRWhBR2dLK2Q2OEpRYkpjZEJyMXloWHVDVUJLYnlYZHRTM1RGTStOdGNGZ3YKUDI0dXFuU05wSjB3SDRwQTdma0IwR0I2dUwvQmNZbHo0S1lTcEJHTWhoZEFyRnJ3S3hsb2tOVGx5RUJma0ovdwpDWWpkZGpzYkFvdUxsc3J6Nzl0VE93aVM3TEJQN1p6NHdqYWdIdkFncmpQTEVwcnhrVkhaNE1nSjVJY0RhdFhtCm5jdTk4NWhvT2VMWmpRRG9OVVpmWWwwdUJoNHNmYnY0OC9WdEJtSjAxVjVEbkVweEJWNUhuRjRIeW9ZTjZ6Y3kKNGZBU2E3ZzU1VTBReGY3T0JBT0NmVGFQbjR5ci9HK3ZDSTN3VWQzU2NzOW9laSttanNpNGJOcW1yR2dGZm5yMApvcWtNQzFtVXNtMEJQVmYveUdRSUpNZmRGSlRNS2c9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg=="; - - var cert = new X509Certificate2(Convert.FromBase64String(rawData)); - var chain = new X509Chain(); - chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; - chain.Build(cert); - Assert.AreEqual("*.example.com", cert.GetNameInfo(X509NameType.SimpleName, false)); - Assert.False(new CustomCaCertificateValidator(cert, "test123.customdomain.com").Validate(cert, chain, SslPolicyErrors.RemoteCertificateChainErrors | SslPolicyErrors.RemoteCertificateNameMismatch)); - } - } -} \ No newline at end of file diff --git a/src/Cassandra.Tests/DataStax/Cloud/certs/customdomain.crt b/src/Cassandra.Tests/DataStax/Cloud/certs/customdomain.crt deleted file mode 100644 index 52b42b5b6..000000000 --- a/src/Cassandra.Tests/DataStax/Cloud/certs/customdomain.crt +++ /dev/null @@ -1,30 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFGjCCBAKgAwIBAgIUfVyOkkB5UcH4w8tsSMCQZt+VfWcwDQYJKoZIhvcNAQEL -BQAwgYUxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVTdGF0ZTENMAsGA1UEBwwEQ2l0 -eTEQMA4GA1UECgwHQ29tcGFueTELMAkGA1UECwwCQlUxFjAUBgNVBAMMDSouZXhh -bXBsZS5jb20xIDAeBgkqhkiG9w0BCQEWEWFkbWluQGV4YW1wbGUuY29tMCAXDTIz -MTEwNzE1NDMyNVoYDzMwMjMwMzEwMTU0MzI1WjCBhTELMAkGA1UEBhMCVVMxDjAM -BgNVBAgMBVN0YXRlMQ0wCwYDVQQHDARDaXR5MRAwDgYDVQQKDAdDb21wYW55MQsw -CQYDVQQLDAJCVTEWMBQGA1UEAwwNKi5leGFtcGxlLmNvbTEgMB4GCSqGSIb3DQEJ -ARYRYWRtaW5AZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK -AoIBAQCy+8xlwYo+CR+eQTHFnUDS8iR/02hc7vXBQI6Di2gwUGzJW53QTx7s/bB7 -O8a5QdB9EPOV4DrQYdVbtS00ZpFiaYbqSSPzJ6mGlXQPV0bXWnYrF/so7oyuJf9W -w9FqlhkUOwSTjcqYCnOxkH0GElwc6qQ4SNaEERMqmw+J+oDvu9cxyFOZEoxO5Hcm -USaDq3WRI0Uv4+/gBVMVUE5UlqTiBPT4ooP8qNLay5+HTXA9pFgs19fI2qv9dH9J -fMpLdskq0DMzfhdx+nGKH0bVW90wjYbFli0qeOEaV506CMv+p8ZXrYIVur+xfRjd -1I27NrVWbMWLIAOCGwRYp3MtOtfzAgMBAAGjggF8MIIBeDAdBgNVHQ4EFgQUtrMv -HoX6shv5J86/cy3CFgOW9nQwgcUGA1UdIwSBvTCBuoAUtrMvHoX6shv5J86/cy3C -FgOW9nShgYukgYgwgYUxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVTdGF0ZTENMAsG -A1UEBwwEQ2l0eTEQMA4GA1UECgwHQ29tcGFueTELMAkGA1UECwwCQlUxFjAUBgNV -BAMMDSouZXhhbXBsZS5jb20xIDAeBgkqhkiG9w0BCQEWEWFkbWluQGV4YW1wbGUu -Y29tghR9XI6SQHlRwfjDy2xIwJBm35V9ZzAMBgNVHRMEBTADAQH/MAsGA1UdDwQE -AwIC/DA5BgNVHREEMjAwggtleGFtcGxlLmNvbYINKi5leGFtcGxlLmNvbYISKi5j -dXN0b21kb21haW4uY29tMDkGA1UdEgQyMDCCC2V4YW1wbGUuY29tgg0qLmV4YW1w -bGUuY29tghIqLmN1c3RvbWRvbWFpbi5jb20wDQYJKoZIhvcNAQELBQADggEBACBD -auLjriD3hDDfcqLMDx1Z+OYwSe3hgbqtZtaXRuDdiqxQ9t69vLOXf5XP9tlq86qI -WXpmXJQCeht1gSM+/yi5mbBvqiYwIBmnRMyAH+p5w02SCqFOve0fbnzUgLU0oYib -QAmwIvohErogUzDm9CMlKYkvgcH8gdejmrAvSnder1ecSffzwXzQKR0LK3cB43mA -+dI+MVkqRnaqx7geVBhHKnVUrIg1d9QV0PS97FRJ92weOclbO9t2Jf8q7+9wKy2n -TUKfznCVE268NQCHH8PwCOPicaOHtPemha7F+1G0SV+695dQS9t5TMDR/IxI7zaJ -qBE3D2uATiEha9lqUk0= ------END CERTIFICATE----- diff --git a/src/Cassandra.Tests/DataStax/Cloud/certs/example.crt b/src/Cassandra.Tests/DataStax/Cloud/certs/example.crt deleted file mode 100644 index 84a33391f..000000000 --- a/src/Cassandra.Tests/DataStax/Cloud/certs/example.crt +++ /dev/null @@ -1,29 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIE8jCCA9qgAwIBAgIUXpLOe+TzIcLxIAG65pZ03lqi31AwDQYJKoZIhvcNAQEL -BQAwgYUxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVTdGF0ZTENMAsGA1UEBwwEQ2l0 -eTEQMA4GA1UECgwHQ29tcGFueTELMAkGA1UECwwCQlUxFjAUBgNVBAMMDSouZXhh -bXBsZS5jb20xIDAeBgkqhkiG9w0BCQEWEWFkbWluQGV4YW1wbGUuY29tMCAXDTIz -MTEwNzE1NDM0N1oYDzMwMjMwMzEwMTU0MzQ3WjCBhTELMAkGA1UEBhMCVVMxDjAM -BgNVBAgMBVN0YXRlMQ0wCwYDVQQHDARDaXR5MRAwDgYDVQQKDAdDb21wYW55MQsw -CQYDVQQLDAJCVTEWMBQGA1UEAwwNKi5leGFtcGxlLmNvbTEgMB4GCSqGSIb3DQEJ -ARYRYWRtaW5AZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK -AoIBAQCy+8xlwYo+CR+eQTHFnUDS8iR/02hc7vXBQI6Di2gwUGzJW53QTx7s/bB7 -O8a5QdB9EPOV4DrQYdVbtS00ZpFiaYbqSSPzJ6mGlXQPV0bXWnYrF/so7oyuJf9W -w9FqlhkUOwSTjcqYCnOxkH0GElwc6qQ4SNaEERMqmw+J+oDvu9cxyFOZEoxO5Hcm -USaDq3WRI0Uv4+/gBVMVUE5UlqTiBPT4ooP8qNLay5+HTXA9pFgs19fI2qv9dH9J -fMpLdskq0DMzfhdx+nGKH0bVW90wjYbFli0qeOEaV506CMv+p8ZXrYIVur+xfRjd -1I27NrVWbMWLIAOCGwRYp3MtOtfzAgMBAAGjggFUMIIBUDAdBgNVHQ4EFgQUtrMv -HoX6shv5J86/cy3CFgOW9nQwgcUGA1UdIwSBvTCBuoAUtrMvHoX6shv5J86/cy3C -FgOW9nShgYukgYgwgYUxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVTdGF0ZTENMAsG -A1UEBwwEQ2l0eTEQMA4GA1UECgwHQ29tcGFueTELMAkGA1UECwwCQlUxFjAUBgNV -BAMMDSouZXhhbXBsZS5jb20xIDAeBgkqhkiG9w0BCQEWEWFkbWluQGV4YW1wbGUu -Y29tghReks575PMhwvEgAbrmlnTeWqLfUDAMBgNVHRMEBTADAQH/MAsGA1UdDwQE -AwIC/DAlBgNVHREEHjAcggtleGFtcGxlLmNvbYINKi5leGFtcGxlLmNvbTAlBgNV -HRIEHjAcggtleGFtcGxlLmNvbYINKi5leGFtcGxlLmNvbTANBgkqhkiG9w0BAQsF -AAOCAQEAC5FzVR3EM801EhAGgK+d68JQbJcdBr1yhXuCUBKbyXdtS3TFM+NtcFgv -P24uqnSNpJ0wH4pA7fkB0GB6uL/BcYlz4KYSpBGMhhdArFrwKxlokNTlyEBfkJ/w -CYjddjsbAouLlsrz79tTOwiS7LBP7Zz4wjagHvAgrjPLEprxkVHZ4MgJ5IcDatXm -ncu985hoOeLZjQDoNUZfYl0uBh4sfbv48/VtBmJ01V5DnEpxBV5HnF4HyoYN6zcy -4fASa7g55U0Qxf7OBAOCfTaPn4yr/G+vCI3wUd3Scs9oei+mjsi4bNqmrGgFfnr0 -oqkMC1mUsm0BPVf/yGQIJMfdFJTMKg== ------END CERTIFICATE----- diff --git a/src/Cassandra.Tests/DataStax/Cloud/certs/localhostcsharp.crt b/src/Cassandra.Tests/DataStax/Cloud/certs/localhostcsharp.crt deleted file mode 100644 index 79356e76e..000000000 --- a/src/Cassandra.Tests/DataStax/Cloud/certs/localhostcsharp.crt +++ /dev/null @@ -1,19 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDAjCCAeoCCQCfB4leiC4dizANBgkqhkiG9w0BAQsFADBAMQswCQYDVQQGEwJV -UzERMA8GA1UECgwIRGF0YVN0YXgxDjAMBgNVBAsMBUNsb3VkMQ4wDAYDVQQDDAVD -bG91ZDAgFw0yMjA1MzAxMjQzNTNaGA8zMDIxMDkzMDEyNDM1M1owRDELMAkGA1UE -BhMCVVMxETAPBgNVBAoTCERhdGFTdGF4MQ4wDAYDVQQLEwVDbG91ZDESMBAGA1UE -AxMJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAofwO -R5nBAoOihlzx+M+wzxBw868u9/qqfUrFR2qyrHPXfCcJmxeAWTNT1yemg2wjYIFf -VhSef9vMIiPmhuywvGTdTYBpWle3JFV7z7ooRXoWxHl04RS5V7CJzJMo4GMEfXjh -/er5Y65Obnv7ghb7B34Hy45sdS2YjOFIYTQsex008H2zCJehOrt9aYZQNTJufOA3 -/6rQhoaeXc+/CugJQid8D2FRoPCf3SlBY3xqYnhI4bfAboQ2jbbH6+sb9XD1lu5B -+0Miy4g0/M2A045fibrcAP/DoXZzRvGyIifaNyDymB6DEhmPSMRCYEgiZQe2jdET -IED2I96rAf8iopvdmwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQA3ew1XehoV0zAd -6JBnKQs2GdV9yXUEEXDA473LIgNIYakTJVmVSTgPRSDmmKG926U0QH3DKpn+lL3q -t8WR23x0G2Ryqmhby11eQqdYFkG3H8lU1UHe37/27CoDxO4rzMPSIwBVESwi5llz -sQGYv6+WgeAWPzQc9B9UyPV2zqRn+BA3Nt0OJrNtmTpRlDNWSchgUaWPBuxQVMd6 -68C9vG36OabrEd0fjGIQeZbRcpqOAUDlJLiF7HIDSCd4Z41LN3zMvc1NxL7Z+P7a -ncSdSr9dGKH9toFn2vNMwBNeh/nnWspQwwcJo9bOif3fyyF9fXXatN5q3gIqHUwO -UyE+YuR1 ------END CERTIFICATE----- diff --git a/src/Cassandra.Tests/DataStax/Cloud/certs/rootcacsharp.crt b/src/Cassandra.Tests/DataStax/Cloud/certs/rootcacsharp.crt deleted file mode 100644 index 057e41ccc..000000000 --- a/src/Cassandra.Tests/DataStax/Cloud/certs/rootcacsharp.crt +++ /dev/null @@ -1,19 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIC/jCCAeYCCQCMI4yE3ByZzTANBgkqhkiG9w0BAQsFADBAMQswCQYDVQQGEwJV -UzERMA8GA1UECgwIRGF0YVN0YXgxDjAMBgNVBAsMBUNsb3VkMQ4wDAYDVQQDDAVD -bG91ZDAgFw0yMjA1MzAxMjM2MDhaGA8zMDIxMDkzMDEyMzYwOFowQDELMAkGA1UE -BhMCVVMxETAPBgNVBAoMCERhdGFTdGF4MQ4wDAYDVQQLDAVDbG91ZDEOMAwGA1UE -AwwFQ2xvdWQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaYN5ArnU9 -9od9qwO35ZFPptZBsJlsoBAiyoEuXJBlQpvyoxv6rAWbBZ2LiXAofFVw5cY8qNSq -e3G+cZbsRm1nOXsISFuXzHFIaIYa3f/NnR3snRDmneL0KyaQR9Vqo0+yWDT2aeek -H3k4WkRRk0Fm9HHQiJMaSuM9X/gBxrQ7b2LA8Tc3acLZ+nf1tjRkMY7HC6rzMokG -tBhB7yq/Wm31NVMnqY6Rva9jAWYHqmXYvd8on2dlL9sW12lTT4wxBJuU5z37yl8W -VNcDdcyaubsAKCSspfj+wjU/FD/M3eGX4GYAYCv7Pm+M/cL4mp04mGwDjHU8MQKo -R/uBdQnYQ7iXAgMBAAEwDQYJKoZIhvcNAQELBQADggEBALXo/MTQEXcooCwSIW3h -/zhZHSkRJ5Jf2wjcM9ONlDiR5+MMSjXTUS0qzjiadSoK9YxgV7PrTzc1dtqSsN7W -YP4s4TosmdsETSvepEqQJIKDvrTRZL9OWhKoPUE7w72UVuXpDZXr+i3MCzwSNsdl -71WlzUqrjpbBJFgSmqffd6bnUq1YXJSz+s/JJuxJik4ejLiHm8w1hHrE/adoaKLm -5zV1hzOOv4wEgI47Vso1LXzt3BdNyuU2vOGTxZl0kA5mEREL1GrtLJ/knuJAzify -QJ2ueSbLMVZupl7/81nHoy7ySZ+3X3UTRGP73Mac9q7o+FIy5v3IZ/sI3ADic85u -Xeo= ------END CERTIFICATE----- diff --git a/src/Cassandra.Tests/DataStax/Cloud/certs/rootcacsharp.key b/src/Cassandra.Tests/DataStax/Cloud/certs/rootcacsharp.key deleted file mode 100644 index 0a047b7cc..000000000 --- a/src/Cassandra.Tests/DataStax/Cloud/certs/rootcacsharp.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDaYN5ArnU99od9 -qwO35ZFPptZBsJlsoBAiyoEuXJBlQpvyoxv6rAWbBZ2LiXAofFVw5cY8qNSqe3G+ -cZbsRm1nOXsISFuXzHFIaIYa3f/NnR3snRDmneL0KyaQR9Vqo0+yWDT2aeekH3k4 -WkRRk0Fm9HHQiJMaSuM9X/gBxrQ7b2LA8Tc3acLZ+nf1tjRkMY7HC6rzMokGtBhB -7yq/Wm31NVMnqY6Rva9jAWYHqmXYvd8on2dlL9sW12lTT4wxBJuU5z37yl8WVNcD -dcyaubsAKCSspfj+wjU/FD/M3eGX4GYAYCv7Pm+M/cL4mp04mGwDjHU8MQKoR/uB -dQnYQ7iXAgMBAAECggEBAIdyt8e0raGeLJHEpczFRij6WUBrUe4vJXL+2bswzJsS -AnovsyX61os9o2ct+vQRkkkxK5DqQuXvJTCzcaHhWPBClc4gWzc/JjB8LFmzwnr8 -7deZ4Ca6XU+HCCdLdtLqsn7y+P6x12xT3TMXwfI6/MDn80Qdwef39RRXVxN69MU7 -fsK4cE2e964CT+9EHbpCcTXWkWKCfcq3B8mbA/YIjX5Cl+ve9Jtt0MSsJlY71lkb -Vjm+ALfdK7sSoxlliyZqY+dUCZ+QXHq1f5nbfvxhzsRb4IV46591erCi1pSoKKX/ -2S39LFneDJE0cRZTI0QpKshGL6Upzc0ovh2UcvwTcxECgYEA8swD4idLxKckubuB -RMl59Y4C8JonVC4yigxkjKnSveR3W0vGxZJw8Bl+afUV44PpcR3xHG5E71NOdW4g -UDMSGO0WmJusrP0Tk0xd3nHY3GlgOQJAHsMUfPS19RASa1u7MI7XkyhPjqRYYQm2 -hoHRW99hv48sVHq7Sic1B+fF8Y8CgYEA5kDr7X62IKD/FRIVQ6cVxE+Jn7uWJaD/ -i+ZvkjTDk6HGIqS0hlBEpz0v9eEg6LPnVXRc8oMzxtNYsp/cQdSPmePTyfZEx5lV -dA+yZdtVrJbtk3MrZUFLrK01kaKcLqWK4S4Bk27J+7K2IgY96sWwJuYYgm2llWPT -uWFWex5ktHkCgYBZJ4MRiz5uQrXgobKREK6A9Zmswd5JMgGK4YwWftGMuxT86DFg -ISrpb2MVA1L7TVfuGoGL4A3eF6gKxNqGuIofrweKGDfq+a8zempJoWJxZRxZMrNa -2GVwkOczyqgI1hFBfmI4fifgiAaP82IbuBWpd7hMAAXWK48UZps5gOkVjwKBgGgQ -p5DrV/1fRmqLhbjR53CWUikzayUOovDj8UEvP8WVtCssLbsWxDCh4u9KFMmXpdJl -iSzCR8Bw/QGeZroKC+0Nn0cEWwmrL4gJICQRAaPDgxTFVLOq0zzz++YajGQ4xZAI -bwXnaLqthsvR7mIRfw/VpvYsAE6Ik8SRTbjPf8xhAoGBAK81qteujYDunLOflzRa -ViLM13ZjpbvSHbuATKmVzH8hc9yJ98nPWRpo3X1nDKMB4GiyWmmbTOwame+TOWGx -YV6coUzbnThlvBqNHs9huEYdXeJulAsaAwSz80XXcOKiPbvW9e2HSB6bihhLdj85 -5j7S2QURQTTF7Q2S9/tzShO0 ------END PRIVATE KEY----- diff --git a/src/Cassandra.Tests/DataStax/Search/DateRangeBoundTests.cs b/src/Cassandra.Tests/DataStax/Search/DateRangeBoundTests.cs deleted file mode 100644 index 9fe9c8ced..000000000 --- a/src/Cassandra.Tests/DataStax/Search/DateRangeBoundTests.cs +++ /dev/null @@ -1,76 +0,0 @@ -// -// Copyright (C) DataStax Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using Cassandra.DataStax.Search; -using NUnit.Framework; - -namespace Cassandra.Tests.DataStax.Search -{ - public class DateRangeBoundTests : BaseUnitTest - { - [Test] - public void Parse_ToString_Test() - { - var arr = new[] - { - "2017-01-20T06:24:57.123Z", - "2017-01-20T06", - "2017", - "1234-07", - "1234-07-02T18:01", - "0001", - "*" - }; - foreach (var boundaryString in arr) - { - var value = DateRangeBound.Parse(boundaryString); - Assert.AreEqual(boundaryString, value.ToString()); - } - } - - [Test] - public void Constructor_Validates_Precision() - { - var values = new byte[] { 8, 9, 32, 128, 255 }; - foreach (var invalidPrecision in values) - { - Assert.Throws( - () => new DateRangeBound(DateTimeOffset.UtcNow, (DateRangePrecision)invalidPrecision)); - } - } - - [Test] - public void Constructor_Uses_Utc_Timestamp() - { - var d1 = new DateTimeOffset(1999, 12, 31, 23, 59, 59, TimeSpan.FromHours(3)); - Assert.AreEqual(new DateRangeBound(d1, DateRangePrecision.Millisecond).ToString(), "1999-12-31T20:59:59.000Z"); - } - - [Test] - public void Equality_Tests() - { - var d1 = new DateTimeOffset(1999, 12, 31, 23, 59, 59, TimeSpan.FromHours(0)); - var boundary1 = new DateRangeBound(d1, DateRangePrecision.Millisecond); - Assert.True(boundary1 == new DateRangeBound(d1, DateRangePrecision.Millisecond)); - Assert.True(boundary1.Equals(new DateRangeBound(d1, DateRangePrecision.Millisecond))); - Assert.False(boundary1 == new DateRangeBound(d1, DateRangePrecision.Second)); - Assert.True(boundary1 != new DateRangeBound(d1, DateRangePrecision.Second)); - Assert.False(boundary1.Equals(new DateRangeBound(d1, DateRangePrecision.Second))); - Assert.False(boundary1.Equals(null)); - } - } -} diff --git a/src/Cassandra.Tests/DataStax/Search/DateRangeSerializerTests.cs b/src/Cassandra.Tests/DataStax/Search/DateRangeSerializerTests.cs deleted file mode 100644 index a5a257f4b..000000000 --- a/src/Cassandra.Tests/DataStax/Search/DateRangeSerializerTests.cs +++ /dev/null @@ -1,53 +0,0 @@ -// -// Copyright (C) DataStax Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using System.Collections.Generic; -using System.Linq; -using Cassandra.Serialization.Search; -using NUnit.Framework; - -namespace Cassandra.Tests.DataStax.Search -{ - public class DateRangeSerializerTests : BaseUnitTest - { - [Test] - public void Serialize_Deserialize_Test() - { - var serializer = new DateRangeSerializer(); - foreach (var value in DateRangeTests.Values.Select(e => e.Item3)) - { - var serialized = serializer.Serialize(4, value); - // Use a buffer at a different index than 0 - var buffer = DateRangeSerializerTests.JoinBuffers(new[] { new byte[10], serialized }, serialized.Length + 10); - var deserialized = serializer.Deserialize(4, buffer, 10, serialized.Length, serializer.TypeInfo); - Assert.AreEqual(value, deserialized); - } - } - - private static byte[] JoinBuffers(IEnumerable buffers, int totalLength) - { - var result = new byte[totalLength]; - var offset = 0; - foreach (byte[] data in buffers) - { - Buffer.BlockCopy(data, 0, result, offset, data.Length); - offset += data.Length; - } - return result; - } - } -} diff --git a/src/Cassandra.Tests/DataStax/Search/DateRangeTests.cs b/src/Cassandra.Tests/DataStax/Search/DateRangeTests.cs deleted file mode 100644 index ba782b2b8..000000000 --- a/src/Cassandra.Tests/DataStax/Search/DateRangeTests.cs +++ /dev/null @@ -1,147 +0,0 @@ -// -// Copyright (C) DataStax Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using Cassandra.DataStax.Search; -using NUnit.Framework; -using Precision = Cassandra.DataStax.Search.DateRangePrecision; - -namespace Cassandra.Tests.DataStax.Search -{ - public class DateRangeTests : BaseUnitTest - { - internal static readonly Tuple[] Values = { - Tuple.Create("[2010 TO 2011-12]", (string)null, - DateRangeTests.GetRange(DateRangeTests.UtcDate(2010), Precision.Year, DateRangeTests.UtcDate(2011, 12, 31, 23, 59, 59, 999), Precision.Month)), - Tuple.Create("[* TO 2011-8]", "[* TO 2011-08]", - DateRangeTests.GetRange(null, null, DateRangeTests.UtcDate(2011, 8, 31, 23, 59, 59, 999), Precision.Month)), - Tuple.Create("[2015-01 TO *]", (string)null, - new DateRange(new DateRangeBound(DateRangeTests.UtcDate(2015), Precision.Month), DateRangeBound.Unbounded)), - Tuple.Create("[2017-01 TO 2017-02]", "[2017-01 TO 2017-02]", - DateRangeTests.GetRange(DateRangeTests.UtcDate(2017), Precision.Month, DateRangeTests.UtcDate(2017, 2, 28, 23, 59, 59, 999), Precision.Month)), - Tuple.Create("[2016-1 TO 2016-02]", "[2016-01 TO 2016-02]", - DateRangeTests.GetRange(DateRangeTests.UtcDate(2016), Precision.Month, DateRangeTests.UtcDate(2016, 2, 29, 23, 59, 59, 999), Precision.Month)), - Tuple.Create("2012-1-2", "2012-01-02", DateRangeTests.GetRange(DateRangeTests.UtcDate(2012, 1, 2), Precision.Day)), - Tuple.Create("2012-1-2T", "2012-01-02", DateRangeTests.GetRange(DateRangeTests.UtcDate(2012, 1, 2), Precision.Day)), - Tuple.Create("1-2-3T23:5:7", "0001-02-03T23:05:07", - DateRangeTests.GetRange(DateRangeTests.UtcDate(1, 2, 3, 23, 5, 7), Precision.Second)), - Tuple.Create("2015-01T03", "2015-01-01T03", DateRangeTests.GetRange(DateRangeTests.UtcDate(2015, 1, 1, 3), Precision.Hour)), - Tuple.Create("2015-04T03:02", "2015-04-01T03:02", - DateRangeTests.GetRange(DateRangeTests.UtcDate(2015, 4, 1, 3, 2), Precision.Minute)), - Tuple.Create("2015-04T03:02:01.081", "2015-04-01T03:02:01.081Z", - DateRangeTests.GetRange(DateRangeTests.UtcDate(2015, 4, 1, 3, 2, 1, 81), Precision.Millisecond)), - Tuple.Create("*", (string)null, new DateRange(DateRangeBound.Unbounded)), - Tuple.Create("[* TO *]", (string)null, new DateRange(DateRangeBound.Unbounded, DateRangeBound.Unbounded)), - Tuple.Create("0001-01-01", (string)null, new DateRange(new DateRangeBound(DateRangeTests.UtcDate(1), Precision.Day))), - - }; - - - [Test] - public void Parse_Values_Test() - { - foreach (var value in DateRangeTests.Values) - { - Assert.AreEqual(DateRange.Parse(value.Item1), value.Item3); - } - } - - [Test] - public void Parse_Should_Throw_For_Invalid_Values() - { - var invalidValues = new[] - { - "2015-01T03:02.001", - "2012-1-2T12:", - "2015-01T03.001", - "[2015-01 TO]", - "[ TO 2015-01]", - "[TO 2015-01]", - " 2015-01", - "2015-01T03:04.001" - }; - foreach (var value in invalidValues) - { - Assert.Throws(() => DateRange.Parse(value)); - } - } - - [Test] - public void ToString_Values_Test() - { - foreach (var value in DateRangeTests.Values) - { - Assert.AreEqual(value.Item3.ToString(), value.Item2 ?? value.Item1); - } - } - - [Test] - public void Constructor_Sets_UpperBound_To_Null_Test() - { - var lowerBound = new DateRangeBound(DateTimeOffset.UtcNow, DateRangePrecision.Second); - var value = new DateRange(lowerBound); - Assert.AreEqual(null, value.UpperBound); - Assert.AreEqual(lowerBound, value.LowerBound); - } - - [Test] - public void Compare_Should_Be_Based_By_Byte_Order() - { - var valuesToCompare = new[] - { - Tuple.Create("2001-01-01", 10), - Tuple.Create("2002-01-01", 20), - Tuple.Create("2002-01-02", 21), - Tuple.Create("[2000-01-01 TO 2000-01-01]", 30), - Tuple.Create("[* TO 2000-01-01]", 40), - Tuple.Create("[* TO 2001-01-01]", 41), - Tuple.Create("[* TO 2002-01-01]", 42), - Tuple.Create("[* TO *]", 50) - }; - foreach (var value in valuesToCompare) - { - foreach (var other in valuesToCompare) - { - Assert.AreEqual( - Math.Sign(value.Item2.CompareTo(other.Item2)), - Math.Sign(DateRange.Parse(value.Item1).CompareTo(DateRange.Parse(other.Item1))), - "Comparison failed for {0} vs {1}", value.Item1, other.Item1); - } - } - } - - private static DateTimeOffset UtcDate( - int year, int month = 1, int day = 1, int hour = 0, int minute = 0, int second = 0, int ms = 0) - { - return new DateTimeOffset(year, month, day, hour, minute, second, ms, TimeSpan.Zero); - } - - private static DateRange GetRange( - DateTimeOffset? d1, Precision? precision1, DateTimeOffset? d2 = null, Precision? precision2 = null) - { - var lowerBound = DateRangeBound.Unbounded; - if (d1 != null && precision1 != null) - { - lowerBound = new DateRangeBound(d1.Value, precision1.Value); - } - if (d2 == null || precision2 == null) - { - return new DateRange(lowerBound); - } - return new DateRange(lowerBound, new DateRangeBound(d2.Value, precision2.Value)); - } - } -} diff --git a/src/Cassandra/Builder.cs b/src/Cassandra/Builder.cs index 222c93269..77851eb6e 100644 --- a/src/Cassandra/Builder.cs +++ b/src/Cassandra/Builder.cs @@ -23,7 +23,6 @@ using System.Threading.Tasks; using Cassandra.Connections; using Cassandra.Connections.Control; -using Cassandra.DataStax.Cloud; using Cassandra.ExecutionProfiles; using Cassandra.Metrics; using Cassandra.Metrics.Abstractions; @@ -74,11 +73,6 @@ public class Builder : IInitializer private DriverMetricsOptions _metricsOptions; private MonitorReportingOptions _monitorReportingOptions = new MonitorReportingOptions(); private string _sessionName; - private string _bundlePath; - private bool _addedSsl; - private bool _addedContactPoints; - private bool _addedAuth; - private bool _addedLbp; private bool? _keepContactPointsUnresolved; private bool? _allowBetaProtocolVersions; @@ -155,11 +149,6 @@ public ICollection ContactPoints /// the configuration to use for the new cluster. public Configuration GetConfiguration() { - if (_bundlePath != null) - { - ConfigureCloudCluster(_bundlePath); - } - var typeSerializerDefinitions = _typeSerializerDefinitions ?? new TypeSerializerDefinitions(); var policies = GetPolicies(); SetLegacySettingsFromDefaultProfile(); @@ -510,7 +499,6 @@ private Builder AddMultipleContactPointsInternal(IEnumerable contactPoin throw new ArgumentNullException(nameof(contactPoints)); } - _addedContactPoints = true; _contactPoints.AddRange(contactPoints); return this; } @@ -522,7 +510,6 @@ private Builder AddSingleContactPointInternal(object contactPoint) throw new ArgumentNullException(nameof(contactPoint)); } - _addedContactPoints = true; _contactPoints.Add(contactPoint); return this; } @@ -573,7 +560,6 @@ public Builder WithBetaProtocolVersions() /// this Builder public Builder WithLoadBalancingPolicy(ILoadBalancingPolicy policy) { - _addedLbp = true; _loadBalancingPolicy = policy; return this; } @@ -680,7 +666,6 @@ public Builder WithConnectionString(string connectionString) /// this Builder public Builder WithCredentials(String username, String password) { - _addedAuth = true; _authInfoProvider = new SimpleAuthInfoProvider().Add("username", username).Add("password", password); _authProvider = new PlainTextAuthProvider(username, password); return this; @@ -697,7 +682,6 @@ public Builder WithCredentials(String username, String password) public Builder WithAuthProvider(IAuthProvider authProvider) { _authProvider = authProvider ?? throw new ArgumentNullException(nameof(authProvider)); - _addedAuth = true; return this; } @@ -770,7 +754,6 @@ public Builder WithPoolingOptions(PoolingOptions value) /// this builder public Builder WithSSL() { - _addedSsl = true; _sslOptions = new SSLOptions(); return this; } @@ -788,7 +771,6 @@ public Builder WithSSL() /// this builder public Builder WithSSL(SSLOptions sslOptions) { - _addedSsl = true; _sslOptions = sslOptions; return this; } @@ -1099,33 +1081,6 @@ public Builder WithSessionName(string sessionName) return this; } - /// - /// - /// Configures a Cluster using the Cloud Secure Connection Bundle. - /// Using this method will configure this builder with specific contact points, SSL options, credentials and load balancing policy. - /// When needed, you can specify custom settings by calling other builder methods. - /// - /// - /// In case you need to specify a different set of credentials from the one in the bundle, here is an example: /// - /// Cluster.Builder() - /// .WithCloudSecureConnectionBundle("/path/to/bundle.zip") - /// .WithCredentials("username", "password") - /// .Build(); - /// - /// - /// - /// will throw when an error occurs that is not related to - /// connectivity and when an error occurs while trying to obtain the cluster metadata from the remote endpoint. - /// - /// - /// Path of the secure connection bundle. - /// A preconfigured builder ready for use. - public Builder WithCloudSecureConnectionBundle(string bundlePath) - { - _bundlePath = bundlePath; - return this; - } - /// /// Configures options related to Monitor Reporting for the new cluster. /// By default, Monitor Reporting is enabled for server types and versions that support it. @@ -1169,80 +1124,5 @@ private Builder SetContactPoints(IEnumerable contactPoints) _contactPoints.Clear(); return AddMultipleContactPointsInternal(contactPoints); } - - private Builder ConfigureCloudCluster(string bundlePath) - { - if (_addedSsl) - { - throw new ArgumentException("SSL options can not be set when a secure connection bundle is provided."); - } - - if (_addedContactPoints) - { - throw new ArgumentException("Contact points can not be set when a secure connection bundle is provided."); - } - - if (!_addedAuth) - { - throw new ArgumentException( - "No credentials were provided. When using the secure connection bundle, " + - "your cluster's credentials must be provided via the Builder.WithCredentials() method."); - } - - SecureConnectionBundle bundle; - try - { - bundle = new SecureConnectionBundleParser().ParseBundle(bundlePath); - } - catch (Exception ex2) - { - throw new InvalidOperationException( - "Failed to load or parse the secure connection bundle. See inner exception for more details.", ex2); - } - - return ConfigureCloudCluster(bundle); - } - - private Builder ConfigureCloudCluster(SecureConnectionBundle bundle) - { - var certificateValidator = new CustomCaCertificateValidator(bundle.CaCert, bundle.Config.Host); - var sslOptions = new SSLOptions( - SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls, - false, - (sender, certificate, chain, errors) => certificateValidator.Validate(certificate, chain, errors)); - - if (bundle.ClientCert != null) - { - sslOptions = sslOptions.SetCertificateCollection(new X509Certificate2Collection(new[] { bundle.ClientCert })); - } - - var sniOptionsProvider = new CloudSniOptionsProvider(this.SocketOptions, sslOptions, bundle, new CloudMetadataService()); - var cloudMetadata = Task.Run(() => sniOptionsProvider.InitializeAsync()).GetAwaiter().GetResult(); - var sniEndPointResolver = new SniEndPointResolver(sniOptionsProvider, new DnsResolver()); - var builder = this.SetContactPoints(new List - { - new SniContactPoint(sniEndPointResolver) - }); - - builder = builder.WithEndPointResolver(sniEndPointResolver); - - if (!_addedLbp) - { - if (cloudMetadata.ContactInfo.LocalDc == null) - { - Builder.Logger.Warning("Not setting localDc property of DCAwareRoundRobinPolicy because the driver could not" + - "obtain it from the cluster metadata."); - builder = builder.WithLoadBalancingPolicy(new TokenAwarePolicy(new DCAwareRoundRobinPolicy())); - } - else - { - builder = builder.WithLoadBalancingPolicy(new TokenAwarePolicy(new DCAwareRoundRobinPolicy(cloudMetadata.ContactInfo.LocalDc))); - } - } - - builder = builder.WithSSL(sslOptions); - - return builder; - } } } \ No newline at end of file diff --git a/src/Cassandra/DataStax/Auth/.editorconfig b/src/Cassandra/DataStax/Auth/.editorconfig deleted file mode 100644 index 81fa929b9..000000000 --- a/src/Cassandra/DataStax/Auth/.editorconfig +++ /dev/null @@ -1,4 +0,0 @@ -[*.cs] - -# SA1636: File header copyright text should match -dotnet_diagnostic.SA1636.severity = silent \ No newline at end of file diff --git a/src/Cassandra/DataStax/Auth/GssapiClientFactory.cs b/src/Cassandra/DataStax/Auth/GssapiClientFactory.cs deleted file mode 100644 index 29d7e3156..000000000 --- a/src/Cassandra/DataStax/Auth/GssapiClientFactory.cs +++ /dev/null @@ -1,26 +0,0 @@ -// -// Copyright (C) DataStax Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -namespace Cassandra.DataStax.Auth -{ - internal static class GssapiClientFactory - { - internal static IGssapiClient CreateNew() - { - return new SspiClient(); - } - } -} \ No newline at end of file diff --git a/src/Cassandra/DataStax/Auth/IGssapiClient.cs b/src/Cassandra/DataStax/Auth/IGssapiClient.cs deleted file mode 100644 index f1d233a75..000000000 --- a/src/Cassandra/DataStax/Auth/IGssapiClient.cs +++ /dev/null @@ -1,26 +0,0 @@ -// -// Copyright (C) DataStax Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; - -namespace Cassandra.DataStax.Auth -{ - internal interface IGssapiClient : IDisposable - { - void Init(string service, string host); - byte[] EvaluateChallenge(byte[] challenge); - } -} diff --git a/src/Cassandra/DataStax/Auth/Sspi/Buffers/SecureBuffer.cs b/src/Cassandra/DataStax/Auth/Sspi/Buffers/SecureBuffer.cs deleted file mode 100644 index b9998e045..000000000 --- a/src/Cassandra/DataStax/Auth/Sspi/Buffers/SecureBuffer.cs +++ /dev/null @@ -1,99 +0,0 @@ -// -// Copyright (c) 2014, Kevin Thompson -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -using System; -using System.Runtime.InteropServices; - -namespace Cassandra.DataStax.Auth.Sspi.Buffers -{ - /// - /// Represents a native SecureBuffer structure, which is used for communicating - /// buffers to the native APIs. - /// - [StructLayout(LayoutKind.Sequential)] - internal struct SecureBufferInternal - { - /// - /// When provided to the native API, the total number of bytes available in the buffer. - /// On return from the native API, the number of bytes that were filled or used by the - /// native API. - /// - public int Count; - - /// - /// The type or purpose of the buffer. - /// - public BufferType Type; - - /// - /// An pointer to a pinned byte[] buffer. - /// - public IntPtr Buffer; - } - - /// - /// Stores buffers to provide tokens and data to the native SSPI APIs. - /// - /// The buffer is translated into a SecureBufferInternal for the actual call. - /// To keep the call setup code simple, and to centralize the buffer pinning code, - /// this class stores and returns buffers as regular byte arrays. The buffer - /// pinning support code in SecureBufferAdapter handles conversion to SecureBufferInternal - /// for pass to the managed api, as well as pinning relevant chunks of memory. - /// - /// Furthermore, the native API may not use the entire buffer, and so a mechanism - /// is needed to communicate the usage of the buffer separate from the length - /// of the buffer. - internal class SecureBuffer - { - /// - /// Initializes a new instance of the SecureBuffer class. - /// - /// The buffer to wrap. - /// The type or purpose of the buffer, for purposes of - /// invoking the native API. - public SecureBuffer(byte[] buffer, BufferType type) - { - this.Buffer = buffer; - this.Type = type; - this.Length = this.Buffer.Length; - } - - /// - /// The type or purposes of the API, for invoking the native API. - /// - public BufferType Type { get; set; } - - /// - /// The buffer to provide to the native API. - /// - public byte[] Buffer { get; set; } - - /// - /// The number of elements that were actually filled or used by the native API, - /// which may be less than the total length of the buffer. - /// - public int Length { get; internal set; } - } -} diff --git a/src/Cassandra/DataStax/Auth/Sspi/Buffers/SecureBufferAdapter.cs b/src/Cassandra/DataStax/Auth/Sspi/Buffers/SecureBufferAdapter.cs deleted file mode 100644 index ad6bd44bc..000000000 --- a/src/Cassandra/DataStax/Auth/Sspi/Buffers/SecureBufferAdapter.cs +++ /dev/null @@ -1,243 +0,0 @@ -// -// Copyright (c) 2014, Kevin Thompson -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -using System; -using System.Collections.Generic; -using System.Runtime.ConstrainedExecution; -using System.Runtime.InteropServices; - -namespace Cassandra.DataStax.Auth.Sspi.Buffers -{ - /// - /// Prepares SecureBuffers for providing them to native API calls. - /// - /// - /// The native APIs consume lists of buffers, with each buffer indicating its type or purpose. - /// - /// The buffers themselves are simple byte arrays, and the native APIs consume arrays of buffers. - /// - /// Since winapi calling convention, perhaps as an extension of C calling convention, does not - /// provide a standard convention means of communicating the length of any array, custom structures - /// must be created to carry the buffer length and usage. - /// - /// Not only does the API need to know how long each buffer is, and how long the array of buffers is, - /// it needs to communicate back how much of each buffer was filled; we may provide it a token buffer - /// that is 12288 bytes long, but it might only use 125 bytes of that, which we need a way of knowing. - /// - /// As a result of this, the API requires byte arrays to be carried in structs that are natively known as - /// SecureBuffers (known as SecureBufferInternal in this project), and then arrays of SecureBuffers are - /// carried in a SecureBufferDescriptor structure. - /// - /// As such, this class has to do a significant amount of marshaling work just to get the buffers back and - /// forth to the native APIs. - /// * We have to pin all buffers - /// * We have to pin the array of buffers - /// * We have to obtain IntPtr handles to each of the buffers and to the array of buffers. - /// * Since we provide EasyToUse SecureBuffer classes from the rest of the project, but we - /// provide SecureBufferInternal structures from the native API, we have to copy back values - /// from the SecureBufferInternal structs to our SecureBuffer class. - /// - /// To make this class easy to use, it accepts either one or many buffers as its constructor; and - /// implements IDisposable to know when to marshal values back from the unmanaged structures and to - /// release pinned handles. - /// - /// Additionally, in case the adapter is leaked without disposing, the adapter implements a Critical - /// Finalizer, to ensure that the GCHandles are released, else we will permanently pin handles. - /// - /// The typical flow is to take one or many buffers; create and fill the neccessary unmanaged structures; - /// pin memory; acquire the IntPtr handles; let the caller access the top-level IntPtr representing - /// the SecureBufferDescriptor, to provide to the native APIs; wait for the caller to invoke the native - /// API; wait for the caller to invoke our Dispose; marshal back any data from the native structures - /// (buffer write counts); release all GCHandles to unpin memory. - /// - /// The total descriptor structure is as follows: - /// |-- Descriptor handle - /// |-- Array of buffers - /// |-- Buffer 1 - /// |-- Buffer 2 - /// ... - /// |-- Buffer N. - /// - /// Each object in that structure must be pinned and passed as an IntPtr to the native APIs. - /// All this to pass what boils down to a List of byte arrays.. - /// - internal sealed class SecureBufferAdapter : CriticalFinalizerObject, IDisposable - { - /// - /// Whether the adapter has already been disposed. - /// - private bool disposed; - - /// - /// The list of mananged SecureBuffers the caller provided to us. - /// - private IList buffers; - - /// - /// The top level handle representing the entire descriptor. - /// - private GCHandle descriptorHandle; - - /// - /// The handle representing the array of buffers. - /// - private GCHandle bufferCarrierHandle; - - /// - /// The handles representing each actual buffer. - /// - private GCHandle[] bufferHandles; - - /// - /// The native buffer descriptor - /// - private SecureBufferDescInternal descriptor; - - /// - /// An array of the native buffers. - /// - private SecureBufferInternal[] bufferCarrier; - - /// - /// Initializes a SecureBufferAdapter to carry a single buffer to the native api. - /// - /// - public SecureBufferAdapter(SecureBuffer buffer) - : this(new[] { buffer }) - { - } - - /// - /// Initializes the SecureBufferAdapter to carry a list of buffers to the native api. - /// - /// - public SecureBufferAdapter(IList buffers) : base() - { - this.buffers = buffers; - - this.disposed = false; - - this.bufferHandles = new GCHandle[this.buffers.Count]; - this.bufferCarrier = new SecureBufferInternal[this.buffers.Count]; - - for (int i = 0; i < this.buffers.Count; i++) - { - this.bufferHandles[i] = GCHandle.Alloc(this.buffers[i].Buffer, GCHandleType.Pinned); - - this.bufferCarrier[i] = new SecureBufferInternal(); - this.bufferCarrier[i].Type = this.buffers[i].Type; - this.bufferCarrier[i].Count = this.buffers[i].Buffer.Length; - this.bufferCarrier[i].Buffer = bufferHandles[i].AddrOfPinnedObject(); - } - - this.bufferCarrierHandle = GCHandle.Alloc(bufferCarrier, GCHandleType.Pinned); - - this.descriptor = new SecureBufferDescInternal(); - this.descriptor.Version = SecureBufferDescInternal.ApiVersion; - this.descriptor.NumBuffers = this.buffers.Count; - this.descriptor.Buffers = bufferCarrierHandle.AddrOfPinnedObject(); - - this.descriptorHandle = GCHandle.Alloc(descriptor, GCHandleType.Pinned); - } - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - ~SecureBufferAdapter() - { - // We bend the typical Dispose pattern here. This finalizer runs in a Constrained Execution Region, - // and so we shouldn't call virtual methods. There's no need to extend this class, so we prevent it - // and mark the protected Dispose method as non-virtual. - Dispose(false); - } - - /// - /// Gets the top-level pointer to the secure buffer descriptor to pass to the native API. - /// - public IntPtr Handle - { - get - { - if (this.disposed) - { - throw new ObjectDisposedException("Cannot use SecureBufferListHandle after it has been disposed"); - } - - return this.descriptorHandle.AddrOfPinnedObject(); - } - } - - /// - /// Completes any buffer passing marshaling and releases all resources associated with the adapter. - /// - public void Dispose() - { - this.Dispose(true); - GC.SuppressFinalize(this); - } - - /// - /// Completes any buffer passing marshaling and releases all resources associated with the adapter. - /// This may be called by the finalizer, or by the regular Dispose method. In the case of the finalizer, - /// we've been leaked and there's no point in attempting to marshal back data from the native structures, - /// nor should we anyway since they may be gone. - /// - /// Whether Dispose is being called. - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - private void Dispose(bool disposing) - { - if (this.disposed == true) { return; } - - if (disposing) - { - // When this class is actually being used for its original purpose - to convey buffers - // back and forth to SSPI calls - we need to copy the potentially modified structure members - // back to our caller's buffer. - for (int i = 0; i < this.buffers.Count; i++) - { - this.buffers[i].Length = this.bufferCarrier[i].Count; - } - } - - for (int i = 0; i < this.bufferHandles.Length; i++) - { - if (this.bufferHandles[i].IsAllocated) - { - this.bufferHandles[i].Free(); - } - } - - if (this.bufferCarrierHandle.IsAllocated) - { - this.bufferCarrierHandle.Free(); - } - - if (this.descriptorHandle.IsAllocated) - { - this.descriptorHandle.Free(); - } - - this.disposed = true; - } - } -} diff --git a/src/Cassandra/DataStax/Auth/Sspi/Buffers/SecureBufferDataRep.cs b/src/Cassandra/DataStax/Auth/Sspi/Buffers/SecureBufferDataRep.cs deleted file mode 100644 index 88d1f36ae..000000000 --- a/src/Cassandra/DataStax/Auth/Sspi/Buffers/SecureBufferDataRep.cs +++ /dev/null @@ -1,44 +0,0 @@ -// -// Copyright (c) 2014, Kevin Thompson -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -namespace Cassandra.DataStax.Auth.Sspi.Buffers -{ - /// - /// Describes how a buffer's opaque internals should be stored, with regards to byte ordering. - /// - internal enum SecureBufferDataRep : int - { - /// - /// Buffers internals are to be stored in the machine native byte order, which will change depending on - /// what machine generated the buffer. - /// - Native = 0x10, - - /// - /// Buffers are stored in network byte ordering, that is, big endian format. - /// - Network = 0x00 - } -} diff --git a/src/Cassandra/DataStax/Auth/Sspi/Buffers/SecureBufferDesc.cs b/src/Cassandra/DataStax/Auth/Sspi/Buffers/SecureBufferDesc.cs deleted file mode 100644 index 38f7aa07a..000000000 --- a/src/Cassandra/DataStax/Auth/Sspi/Buffers/SecureBufferDesc.cs +++ /dev/null @@ -1,58 +0,0 @@ -// -// Copyright (c) 2014, Kevin Thompson -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -using System; -using System.Runtime.InteropServices; - -namespace Cassandra.DataStax.Auth.Sspi.Buffers -{ - /// - /// Represents the native layout of the secure buffer descriptor that is provided directly - /// to native API calls. - /// - [StructLayout(LayoutKind.Sequential)] - internal struct SecureBufferDescInternal - { - /// - /// The buffer structure version. - /// - public int Version; - - /// - /// The number of buffers represented by this descriptor. - /// - public int NumBuffers; - - /// - /// A pointer to a array of buffers, where each buffer is a byte[]. - /// - public IntPtr Buffers; - - /// - /// Indicates the buffer structure version supported by this structure. Always 0. - /// - public const int ApiVersion = 0; - } -} diff --git a/src/Cassandra/DataStax/Auth/Sspi/Buffers/SecureBufferType.cs b/src/Cassandra/DataStax/Auth/Sspi/Buffers/SecureBufferType.cs deleted file mode 100644 index e5d2f912a..000000000 --- a/src/Cassandra/DataStax/Auth/Sspi/Buffers/SecureBufferType.cs +++ /dev/null @@ -1,82 +0,0 @@ -// -// Copyright (c) 2014, Kevin Thompson -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -namespace Cassandra.DataStax.Auth.Sspi.Buffers -{ - /// - /// Describes the type and purpose of a secure buffer passed to the native API. - /// - internal enum BufferType : int - { - /// - /// The buffer is empty. - /// - Empty = 0x00, - - /// - /// The buffer contains message data. Message data can be plaintext or cipher text data. - /// - Data = 0x01, - - /// - /// The buffer contains opaque authentication token data. - /// - Token = 0x02, - - /// - /// The buffer contains parameters specific to the security package. - /// - Parameters = 0x03, - - /// - /// The buffer placeholder indicating that some data is missing. - /// - Missing = 0x04, - - /// - /// The buffer passed to an API call contained more data than was necessary for completing the action, - /// such as the case when a streaming-mode connection that does not preserve message bounders, such as TCP - /// is used as the transport. The extra data is returned back to the caller in a buffer of this type. - /// - Extra = 0x05, - - /// - /// The buffer contains a security data trailer, such as a message signature or marker, or framing data. - /// - Trailer = 0x06, - - /// - /// The buffer contains a security data header, such as a message signature, marker, or framing data. - /// - Header = 0x07, - - Padding = 0x09, - Stream = 0x0A, - ChannelBindings = 0x0E, - TargetHost = 0x10, - ReadOnlyFlag = unchecked((int)0x80000000), - ReadOnlyWithChecksum = 0x10000000 - } -} diff --git a/src/Cassandra/DataStax/Auth/Sspi/ByteWriter.cs b/src/Cassandra/DataStax/Auth/Sspi/ByteWriter.cs deleted file mode 100644 index 459a95878..000000000 --- a/src/Cassandra/DataStax/Auth/Sspi/ByteWriter.cs +++ /dev/null @@ -1,100 +0,0 @@ -// -// Copyright (c) 2014, Kevin Thompson -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -using System; - -namespace Cassandra.DataStax.Auth.Sspi -{ - /// - /// Reads and writes value types to byte arrays with explicit endianness. - /// - internal static class ByteWriter - { - // Big endian: Most significant byte at lowest address in memory. - - /// - /// Writes a 2-byte signed integer to the buffer in big-endian format. - /// - /// The value to write to the buffer. - /// The buffer to write to. - /// The index of the first byte to write to. - public static void WriteInt16_BE(Int16 value, byte[] buffer, int position) - { - buffer[position + 0] = (byte)(value >> 8); - buffer[position + 1] = (byte)(value); - } - - /// - /// Writes a 4-byte signed integer to the buffer in big-endian format. - /// - /// The value to write to the buffer. - /// The buffer to write to. - /// The index of the first byte to write to. - public static void WriteInt32_BE(Int32 value, byte[] buffer, int position) - { - buffer[position + 0] = (byte)(value >> 24); - buffer[position + 1] = (byte)(value >> 16); - buffer[position + 2] = (byte)(value >> 8); - buffer[position + 3] = (byte)(value); - - } - - /// - /// Reads a 2-byte signed integer that is stored in the buffer in big-endian format. - /// The returned value is in the native endianness. - /// - /// The buffer to read. - /// The index of the first byte to read. - /// - public static Int16 ReadInt16_BE(byte[] buffer, int position) - { - Int16 value; - - value = (Int16)(buffer[position + 0] << 8); - value += (Int16)(buffer[position + 1]); - - return value; - } - - /// - /// Reads a 4-byte signed integer that is stored in the buffer in big-endian format. - /// The returned value is in the native endianness. - /// - /// The buffer to read. - /// The index of the first byte to read. - /// - public static Int32 ReadInt32_BE(byte[] buffer, int position) - { - Int32 value; - - value = (Int32)(buffer[position + 0] << 24); - value |= (Int32)(buffer[position + 1] << 16); - value |= (Int32)(buffer[position + 2] << 8); - value |= (Int32)(buffer[position + 3]); - - return value; - } - } -} diff --git a/src/Cassandra/DataStax/Auth/Sspi/Contexts/ClientContext.cs b/src/Cassandra/DataStax/Auth/Sspi/Contexts/ClientContext.cs deleted file mode 100644 index 48f509973..000000000 --- a/src/Cassandra/DataStax/Auth/Sspi/Contexts/ClientContext.cs +++ /dev/null @@ -1,202 +0,0 @@ -// -// Copyright (c) 2014, Kevin Thompson -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -using System; -using Cassandra.DataStax.Auth.Sspi.Buffers; -using Cassandra.DataStax.Auth.Sspi.Credentials; - -namespace Cassandra.DataStax.Auth.Sspi.Contexts -{ - /// - /// Represents a client security context. Provides the means to establish a shared security context - /// with the server and to encrypt, decrypt, sign and verify messages to and from the server. - /// - /// - /// A client and server establish a shared security context by exchanging authentication tokens. Once - /// the shared context is established, the client and server can pass messages to each other, encrypted, - /// signed, etc, using the established parameters of the shared context. - /// - internal class ClientContext : Context - { - private ContextAttrib requestedAttribs; - private ContextAttrib finalAttribs; - private string serverPrinc; - - /// - /// Initializes a new instance of the ClientContext class. The context is not fully initialized and usable - /// until the authentication cycle has been completed. - /// - /// The security credential to authenticate as. - /// The principle name of the server to connect to, or null for any. - /// Requested attributes that describe the desired properties of the - /// context once it is established. If a context cannot be established that satisfies the indicated - /// properties, the context initialization is aborted. - public ClientContext(ClientCredential cred, string serverPrinc, ContextAttrib requestedAttribs) - : base(cred) - { - this.serverPrinc = serverPrinc; - this.requestedAttribs = requestedAttribs; - } - - /// - /// Performs and continues the authentication cycle. - /// - /// - /// This method is performed iteratively to start, continue, and end the authentication cycle with the - /// server. Each stage works by acquiring a token from one side, presenting it to the other side - /// which in turn may generate a new token. - /// - /// The cycle typically starts and ends with the client. On the first invocation on the client, - /// no server token exists, and null is provided in its place. The client returns its status, providing - /// its output token for the server. The server accepts the clients token as input and provides a - /// token as output to send back to the client. This cycle continues until the server and client - /// both indicate, typically, a SecurityStatus of 'OK'. - /// - /// The most recently received token from the server, or null if beginning - /// the authentication cycle. - /// The clients next authentication token in the authentication cycle. - /// A status message indicating the progression of the authentication cycle. - /// A status of 'OK' indicates that the cycle is complete, from the client's perspective. If the outToken - /// is not null, it must be sent to the server. - /// A status of 'Continue' indicates that the output token should be sent to the server and - /// a response should be anticipated. - public SecurityStatus Init(byte[] serverToken, out byte[] outToken) - { - TimeStamp rawExpiry = new TimeStamp(); - - SecurityStatus status; - - SecureBuffer outTokenBuffer; - SecureBufferAdapter outAdapter; - - SecureBuffer serverBuffer; - SecureBufferAdapter serverAdapter; - - if (this.Disposed) - { - throw new ObjectDisposedException("ClientContext"); - } - else if ((serverToken != null) && (this.ContextHandle.IsInvalid)) - { - throw new InvalidOperationException("Out-of-order usage detected - have a server token, but no previous client token had been created."); - } - else if ((serverToken == null) && (this.ContextHandle.IsInvalid == false)) - { - throw new InvalidOperationException("Must provide the server's response when continuing the init process."); - } - - // The security package tells us how big its biggest token will be. We'll allocate a buffer - // that size, and it'll tell us how much it used. - outTokenBuffer = new SecureBuffer( - new byte[this.Credential.PackageInfo.MaxTokenLength], - BufferType.Token - ); - - serverBuffer = null; - if (serverToken != null) - { - serverBuffer = new SecureBuffer(serverToken, BufferType.Token); - } - - // Some notes on handles and invoking InitializeSecurityContext - // - The first time around, the phContext parameter (the 'old' handle) is a null pointer to what - // would be an RawSspiHandle, to indicate this is the first time it's being called. - // The phNewContext is a pointer (reference) to an RawSspiHandle struct of where to write the - // new handle's values. - // - The next time you invoke ISC, it takes a pointer to the handle it gave you last time in phContext, - // and takes a pointer to where it should write the new handle's values in phNewContext. - // - After the first time, you can provide the same handle to both parameters. From MSDN: - // "On the second call, phNewContext can be the same as the handle specified in the phContext - // parameter." - // It will overwrite the handle you gave it with the new handle value. - // - All handle structures themselves are actually *two* pointer variables, eg, 64 bits on 32-bit - // Windows, 128 bits on 64-bit Windows. - // - So in the end, on a 64-bit machine, we're passing a 64-bit value (the pointer to the struct) that - // points to 128 bits of memory (the struct itself) for where to write the handle numbers. - using (outAdapter = new SecureBufferAdapter(outTokenBuffer)) - { - if (this.ContextHandle.IsInvalid) - { - status = ContextNativeMethods.InitializeSecurityContext_1( - ref this.Credential.Handle.rawHandle, - IntPtr.Zero, - this.serverPrinc, - this.requestedAttribs, - 0, - SecureBufferDataRep.Network, - IntPtr.Zero, - 0, - ref this.ContextHandle.rawHandle, - outAdapter.Handle, - ref this.finalAttribs, - ref rawExpiry - ); - } - else - { - using (serverAdapter = new SecureBufferAdapter(serverBuffer)) - { - status = ContextNativeMethods.InitializeSecurityContext_2( - ref this.Credential.Handle.rawHandle, - ref this.ContextHandle.rawHandle, - this.serverPrinc, - this.requestedAttribs, - 0, - SecureBufferDataRep.Network, - serverAdapter.Handle, - 0, - ref this.ContextHandle.rawHandle, - outAdapter.Handle, - ref this.finalAttribs, - ref rawExpiry - ); - } - } - } - - if (status.IsError() == false) - { - if (status == SecurityStatus.OK) - { - base.Initialize(rawExpiry.ToDateTime()); - } - - outToken = null; - - if (outTokenBuffer.Length != 0) - { - outToken = new byte[outTokenBuffer.Length]; - Array.Copy(outTokenBuffer.Buffer, outToken, outToken.Length); - } - } - else - { - throw new SspiException("Failed to invoke InitializeSecurityContext for a client", status); - } - - return status; - } - } -} diff --git a/src/Cassandra/DataStax/Auth/Sspi/Contexts/Context.cs b/src/Cassandra/DataStax/Auth/Sspi/Contexts/Context.cs deleted file mode 100644 index 9e7233630..000000000 --- a/src/Cassandra/DataStax/Auth/Sspi/Contexts/Context.cs +++ /dev/null @@ -1,296 +0,0 @@ -// -// Copyright (c) 2014, Kevin Thompson -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -using System; -using System.Runtime.CompilerServices; -using Cassandra.DataStax.Auth.Sspi.Buffers; -using Cassandra.DataStax.Auth.Sspi.Credentials; - -namespace Cassandra.DataStax.Auth.Sspi.Contexts -{ - /// - /// Represents a security context and provides common functionality required for all security - /// contexts. - /// - /// - /// This class is abstract and has a protected constructor and Initialize method. The exact - /// initialization implementation is provided by a subclasses, which may perform initialization - /// in a variety of manners. - /// - internal abstract class Context : IDisposable - { - /// - /// Produce a header or trailer but do not encrypt the message. See: KERB_WRAP_NO_ENCRYPT. - /// - private const uint WrapNoEncrypt = 0x80000001; - - /// - /// Performs basic initialization of a new instance of the Context class. - /// Initialization is not complete until the ContextHandle property has been set - /// and the Initialize method has been called. - /// - /// - protected Context(Credential cred) - { - this.Credential = cred; - - this.ContextHandle = new SafeContextHandle(); - - this.Disposed = false; - this.Initialized = false; - } - - /// - /// Whether or not the context is fully formed. - /// - public bool Initialized { get; private set; } - - /// - /// The credential being used by the context to authenticate itself to other actors. - /// - protected Credential Credential { get; private set; } - - /// - /// A reference to the security context's handle. - /// - public SafeContextHandle ContextHandle { get; private set; } - - /// - /// The UTC time when the context expires. - /// - public DateTime Expiry { get; private set; } - - /// - /// Whether the context has been disposed. - /// - public bool Disposed { get; private set; } - - /// - /// Marks the context as having completed the initialization process, ie, exchanging of authentication tokens. - /// - /// The date and time that the context will expire. - protected void Initialize(DateTime expiry) - { - this.Expiry = expiry; - this.Initialized = true; - } - - /// - /// Releases all resources associated with the context. - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// - /// Releases resources associated with the context. - /// - /// If true, release managed resources, else release only unmanaged resources. - protected virtual void Dispose(bool disposing) - { - if (this.Disposed) { return; } - - if (disposing) - { - this.ContextHandle.Dispose(); - } - - this.Disposed = true; - } - - /// - /// Encrypts the byte array using the context's session key. - /// - /// - /// The structure of the returned data is as follows: - /// - 2 bytes, an unsigned big-endian integer indicating the length of the trailer buffer size - /// - 4 bytes, an unsigned big-endian integer indicating the length of the message buffer size. - /// - 2 bytes, an unsigned big-endian integer indicating the length of the encryption padding buffer size. - /// - The trailer buffer - /// - The message buffer - /// - The padding buffer. - /// - /// The raw message to encrypt. - /// The packed and encrypted message. - public byte[] Encrypt(byte[] input) - { - // The message is encrypted in place in the buffer we provide to Win32 EncryptMessage - SecPkgContext_Sizes sizes; - - SecureBuffer trailerBuffer; - SecureBuffer dataBuffer; - SecureBuffer paddingBuffer; - SecureBufferAdapter adapter; - - SecurityStatus status = SecurityStatus.InvalidHandle; - CheckLifecycle(); - - sizes = QueryBufferSizes(); - - trailerBuffer = new SecureBuffer(new byte[sizes.SecurityTrailer], BufferType.Token); - dataBuffer = new SecureBuffer(new byte[input.Length], BufferType.Data); - paddingBuffer = new SecureBuffer(new byte[sizes.BlockSize], BufferType.Padding); - - Array.Copy(input, dataBuffer.Buffer, input.Length); - - using (adapter = new SecureBufferAdapter(new[] { trailerBuffer, dataBuffer, paddingBuffer })) - { - status = ContextNativeMethods.SafeEncryptMessage( - this.ContextHandle, - Context.WrapNoEncrypt, - adapter, - 0 - ); - } - - if (status != SecurityStatus.OK) - { - throw new SspiException("Failed to encrypt message", status); - } - - int position = 0; - - // Return 1 buffer with the 3 buffers joined - var result = new byte[trailerBuffer.Length + dataBuffer.Length + paddingBuffer.Length]; - - Array.Copy(trailerBuffer.Buffer, 0, result, position, trailerBuffer.Length); - position += trailerBuffer.Length; - - Array.Copy(dataBuffer.Buffer, 0, result, position, dataBuffer.Length); - position += dataBuffer.Length; - - Array.Copy(paddingBuffer.Buffer, 0, result, position, paddingBuffer.Length); - - return result; - } - - /// - /// Decrypts a previously encrypted message. - /// Assumes that the message only contains the "hash" integrity validation. - /// - /// - /// The expected format of the buffer is as follows (order is not important): - /// - The trailer buffer - /// - The message buffer - /// - /// The packed and encrypted data. - /// Null - /// Exception thrown when hash validation fails. - public byte[] Decrypt(byte[] input) - { - SecurityStatus status; - - CheckLifecycle(); - - var trailerLength = input.Length; - - var dataBuffer = new SecureBuffer(new byte[0], BufferType.Data); - var trailerBuffer = new SecureBuffer(new byte[trailerLength], BufferType.Stream); - - Array.Copy(input, 0, trailerBuffer.Buffer, 0, trailerBuffer.Length); - - using (var adapter = new SecureBufferAdapter(new[] { dataBuffer, trailerBuffer })) - { - status = ContextNativeMethods.SafeDecryptMessage( - this.ContextHandle, - 0, - adapter, - 0 - ); - } - - if (status != SecurityStatus.OK) - { - throw new SspiException("Failed to decrypt message", status); - } - - return null; - } - - /// - /// Queries the security package's expectations regarding message/token/signature/padding buffer sizes. - /// - /// - private SecPkgContext_Sizes QueryBufferSizes() - { - SecPkgContext_Sizes sizes = new SecPkgContext_Sizes(); - SecurityStatus status = SecurityStatus.InternalError; - bool gotRef = false; - - RuntimeHelpers.PrepareConstrainedRegions(); - try - { - this.ContextHandle.DangerousAddRef(ref gotRef); - } - catch (Exception) - { - if (gotRef) - { - this.ContextHandle.DangerousRelease(); - gotRef = false; - } - - throw; - } - finally - { - if (gotRef) - { - status = ContextNativeMethods.QueryContextAttributes_Sizes( - ref this.ContextHandle.rawHandle, - ContextQueryAttrib.Sizes, - ref sizes - ); - this.ContextHandle.DangerousRelease(); - } - } - - if (status != SecurityStatus.OK) - { - throw new SspiException("Failed to query context buffer size attributes", status); - } - - return sizes; - } - - /// - /// Verifies that the object's lifecycle (initialization / disposition) state is suitable for using the - /// object. - /// - private void CheckLifecycle() - { - if (this.Initialized == false) - { - throw new InvalidOperationException("The context is not yet fully formed."); - } - else if (this.Disposed) - { - throw new ObjectDisposedException("Context"); - } - } - } -} diff --git a/src/Cassandra/DataStax/Auth/Sspi/Contexts/ContextAttrib.cs b/src/Cassandra/DataStax/Auth/Sspi/Contexts/ContextAttrib.cs deleted file mode 100644 index 980ab0b56..000000000 --- a/src/Cassandra/DataStax/Auth/Sspi/Contexts/ContextAttrib.cs +++ /dev/null @@ -1,158 +0,0 @@ -// -// Copyright (c) 2014, Kevin Thompson -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -using System; - -namespace Cassandra.DataStax.Auth.Sspi.Contexts -{ - /// - /// Defines options for creating a security context via win32 InitializeSecurityContext - /// (used by clients) and AcceptSecurityContext (used by servers). - /// Required attribute flags are specified when creating the context. InitializeSecurityContext - /// and AcceptSecurityContext returns a value indicating what final attributes the created context - /// actually has. - /// - [Flags] - internal enum ContextAttrib : int - { - /// - /// No additional attributes are provided. - /// - Zero = 0, - - /// - /// The server can use the context to authenticate to other servers as the client. The - /// MutualAuth flag must be set for this flag to work. Valid for Kerberos. Ignore this flag for - /// constrained delegation. - /// - Delegate = 0x00000001, - - /// - /// The mutual authentication policy of the service will be satisfied. - /// *Caution* - This does not necessarily mean that mutual authentication is performed, only that - /// the authentication policy of the service is satisfied. To ensure that mutual authentication is - /// performed, query the context attributes after it is created. - /// - MutualAuth = 0x00000002, - - - /// - /// Detect replayed messages that have been encoded by using the EncryptMessage or MakeSignature - /// message support functionality. - /// - ReplayDetect = 0x00000004, - - /// - /// Detect messages received out of sequence when using the message support functionality. - /// This flag implies all of the conditions specified by the Integrity flag - out-of-order sequence - /// detection can only be trusted if the integrity of any underlying sequence detection mechanism - /// in transmitted data can be trusted. - /// - SequenceDetect = 0x00000008, - - // The context must protect data while in transit. - // Confidentiality is supported for NTLM with Microsoft - // Windows NT version 4.0, SP4 and later and with the - // Kerberos protocol in Microsoft Windows 2000 and later. - - /// - /// The context must protect data while in transit. Encrypt messages by using the EncryptMessage function. - /// - Confidentiality = 0x00000010, - - /// - /// A new session key must be negotiated. - /// This value is supported only by the Kerberos security package. - /// - UseSessionKey = 0x00000020, - - /// - /// The security package allocates output buffers for you. Buffers allocated by the security package have - /// to be released by the context memory management functions. - /// - AllocateMemory = 0x00000100, - - /// - /// The security context will not handle formatting messages. This value is the default for the Kerberos, - /// Negotiate, and NTLM security packages. - /// - Connection = 0x00000800, - - /// - /// When errors occur, the remote party will be notified. - /// - /// - /// A client specifies InitExtendedError in InitializeSecurityContext - /// and the server specifies AcceptExtendedError in AcceptSecurityContext. - /// - InitExtendedError = 0x00004000, - - /// - /// When errors occur, the remote party will be notified. - /// - /// - /// A client specifies InitExtendedError in InitializeSecurityContext - /// and the server specifies AcceptExtendedError in AcceptSecurityContext. - /// - AcceptExtendedError = 0x00008000, - - /// - /// Support a stream-oriented connection. Provided by clients. - /// - InitStream = 0x00008000, - - /// - /// Support a stream-oriented connection. Provided by servers. - /// - AcceptStream = 0x00010000, - - /// - /// Sign messages and verify signatures by using the EncryptMessage and MakeSignature functions. - /// Replayed and out-of-sequence messages will not be detected with the setting of this attribute. - /// Set ReplayDetect and SequenceDetect also if these behaviors are desired. - /// - InitIntegrity = 0x00010000, - - /// - /// Sign messages and verify signatures by using the EncryptMessage and MakeSignature functions. - /// Replayed and out-of-sequence messages will not be detected with the setting of this attribute. - /// Set ReplayDetect and SequenceDetect also if these behaviors are desired. - /// - AcceptIntegrity = 0x00020000, - - InitIdentify = 0x00020000, - AcceptIdentify = 0x00080000, - - /// - /// An Schannel provider connection is instructed to not authenticate the server automatically. - /// - InitManualCredValidation = 0x00080000, - - /// - /// An Schannel provider connection is instructed to not authenticate the client automatically. - /// - InitUseSuppliedCreds = 0x00000080, - } -} diff --git a/src/Cassandra/DataStax/Auth/Sspi/Contexts/ContextNativeMethods.cs b/src/Cassandra/DataStax/Auth/Sspi/Contexts/ContextNativeMethods.cs deleted file mode 100644 index 360231cf5..000000000 --- a/src/Cassandra/DataStax/Auth/Sspi/Contexts/ContextNativeMethods.cs +++ /dev/null @@ -1,403 +0,0 @@ -// -// Copyright (c) 2014, Kevin Thompson -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -using System; -using System.Runtime.CompilerServices; -using System.Runtime.ConstrainedExecution; -using System.Runtime.InteropServices; -using Cassandra.DataStax.Auth.Sspi.Buffers; - -namespace Cassandra.DataStax.Auth.Sspi.Contexts -{ - /// - /// Declares native methods calls for security context-related win32 functions. - /// - internal static class ContextNativeMethods - { - /* - SECURITY_STATUS SEC_Entry AcceptSecurityContext( - _In_opt_ PCredHandle phCredential, - _Inout_ PCtxtHandle phContext, - _In_opt_ PSecBufferDesc pInput, - _In_ ULONG fContextReq, - _In_ ULONG TargetDataRep, - _Inout_opt_ PCtxtHandle phNewContext, - _Inout_opt_ PSecBufferDesc pOutput, - _Out_ PULONG pfContextAttr, - _Out_opt_ PTimeStamp ptsTimeStamp - ); - - SECURITY_STATUS SEC_Entry InitializeSecurityContext( - _In_opt_ PCredHandle phCredential, // [in] handle to the credentials - _In_opt_ PCtxtHandle phContext, // [in/out] handle of partially formed context. Always NULL the first time through - _In_opt_ SEC_CHAR *pszTargetName, // [in] name of the target of the context. Not needed by NTLM - _In_ ULONG fContextReq, // [in] required context attributes - _In_ ULONG Reserved1, // [reserved] reserved; must be zero - _In_ ULONG TargetDataRep, // [in] data representation on the target - _In_opt_ PSecBufferDesc pInput, // [in/out] pointer to the input buffers. Always NULL the first time through - _In_ ULONG Reserved2, // [reserved] reserved; must be zero - _Inout_opt_ PCtxtHandle phNewContext, // [in/out] receives the new context handle (must be pre-allocated) - _Inout_opt_ PSecBufferDesc pOutput, // [out] pointer to the output buffers - _Out_ PULONG pfContextAttr, // [out] receives the context attributes - _Out_opt_ PTimeStamp ptsExpiry // [out] receives the life span of the security context - ); - */ - - [DllImport("Secur32.dll", EntryPoint = "AcceptSecurityContext", CharSet = CharSet.Unicode)] - internal static extern SecurityStatus AcceptSecurityContext_1( - ref RawSspiHandle credHandle, - IntPtr oldContextHandle, - IntPtr inputBuffer, - ContextAttrib requestedAttribs, - SecureBufferDataRep dataRep, - ref RawSspiHandle newContextHandle, - IntPtr outputBuffer, - ref ContextAttrib outputAttribs, - ref TimeStamp expiry - ); - - - [DllImport("Secur32.dll", EntryPoint = "AcceptSecurityContext", CharSet = CharSet.Unicode)] - internal static extern SecurityStatus AcceptSecurityContext_2( - ref RawSspiHandle credHandle, - ref RawSspiHandle oldContextHandle, - IntPtr inputBuffer, - ContextAttrib requestedAttribs, - SecureBufferDataRep dataRep, - ref RawSspiHandle newContextHandle, - IntPtr outputBuffer, - ref ContextAttrib outputAttribs, - ref TimeStamp expiry - ); - - - [DllImport("Secur32.dll", EntryPoint = "InitializeSecurityContext", CharSet = CharSet.Unicode)] - internal static extern SecurityStatus InitializeSecurityContext_1( - ref RawSspiHandle credentialHandle, - IntPtr zero, - string serverPrincipleName, - ContextAttrib requiredAttribs, - int reserved1, - SecureBufferDataRep dataRep, - IntPtr inputBuffer, - int reserved2, - ref RawSspiHandle newContextHandle, - IntPtr outputBuffer, - ref ContextAttrib contextAttribs, - ref TimeStamp expiry - ); - - - [DllImport("Secur32.dll", EntryPoint = "InitializeSecurityContext", CharSet = CharSet.Unicode)] - internal static extern SecurityStatus InitializeSecurityContext_2( - ref RawSspiHandle credentialHandle, - ref RawSspiHandle previousHandle, - string serverPrincipleName, - ContextAttrib requiredAttribs, - int reserved1, - SecureBufferDataRep dataRep, - IntPtr inputBuffer, - int reserved2, - ref RawSspiHandle newContextHandle, - IntPtr outputBuffer, - ref ContextAttrib contextAttribs, - ref TimeStamp expiry - ); - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - [DllImport("Secur32.dll", EntryPoint = "DeleteSecurityContext", CharSet = CharSet.Unicode)] - internal static extern SecurityStatus DeleteSecurityContext(ref RawSspiHandle contextHandle); - - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - [DllImport("Secur32.dll", EntryPoint = "EncryptMessage", CharSet = CharSet.Unicode)] - internal static extern SecurityStatus EncryptMessage( - ref RawSspiHandle contextHandle, - uint qualityOfProtection, - IntPtr bufferDescriptor, - int sequenceNumber - ); - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - [DllImport("Secur32.dll", EntryPoint = "DecryptMessage", CharSet = CharSet.Unicode)] - internal static extern SecurityStatus DecryptMessage( - ref RawSspiHandle contextHandle, - IntPtr bufferDescriptor, - int sequenceNumber, - int qualityOfProtection - ); - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - [DllImport("Secur32.dll", EntryPoint = "MakeSignature", CharSet = CharSet.Unicode)] - internal static extern SecurityStatus MakeSignature( - ref RawSspiHandle contextHandle, - int qualityOfProtection, - IntPtr bufferDescriptor, - int sequenceNumber - ); - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - [DllImport("Secur32.dll", EntryPoint = "VerifySignature", CharSet = CharSet.Unicode)] - internal static extern SecurityStatus VerifySignature( - ref RawSspiHandle contextHandle, - IntPtr bufferDescriptor, - int sequenceNumber, - int qualityOfProtection - ); - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - [DllImport("Secur32.dll", EntryPoint = "QueryContextAttributes", CharSet = CharSet.Unicode)] - internal static extern SecurityStatus QueryContextAttributes_Sizes( - ref RawSspiHandle contextHandle, - ContextQueryAttrib attrib, - ref SecPkgContext_Sizes sizes - ); - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - [DllImport("Secur32.dll", EntryPoint = "QueryContextAttributes", CharSet = CharSet.Unicode)] - internal static extern SecurityStatus QueryContextAttributes_String( - ref RawSspiHandle contextHandle, - ContextQueryAttrib attrib, - ref SecPkgContext_String names - ); - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - [DllImport("Secur32.dll", EntryPoint = "FreeContextBuffer", CharSet = CharSet.Unicode)] - internal static extern SecurityStatus FreeContextBuffer(IntPtr handle); - - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - [DllImport("Secur32.dll", EntryPoint = "ImpersonateSecurityContext", CharSet = CharSet.Unicode)] - internal static extern SecurityStatus ImpersonateSecurityContext(ref RawSspiHandle contextHandle); - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - [DllImport("Secur32.dll", EntryPoint = "RevertSecurityContext", CharSet = CharSet.Unicode)] - internal static extern SecurityStatus RevertSecurityContext(ref RawSspiHandle contextHandle); - - /// - /// Safely invokes the native EncryptMessage function, making sure that handle ref counting is - /// performed in a proper CER. - /// - /// - /// - /// - /// - /// - internal static SecurityStatus SafeEncryptMessage( - SafeContextHandle handle, - uint qualityOfProtection, - SecureBufferAdapter bufferAdapter, - int sequenceNumber) - { - SecurityStatus status = SecurityStatus.InternalError; - bool gotRef = false; - - RuntimeHelpers.PrepareConstrainedRegions(); - try - { - handle.DangerousAddRef(ref gotRef); - } - catch (Exception) - { - if (gotRef) - { - handle.DangerousRelease(); - gotRef = false; - } - - throw; - } - finally - { - if (gotRef) - { - status = ContextNativeMethods.EncryptMessage( - ref handle.rawHandle, - qualityOfProtection, - bufferAdapter.Handle, - sequenceNumber - ); - - handle.DangerousRelease(); - } - } - - return status; - } - - /// - /// Safely invokes the native DecryptMessage function, making sure that handle ref counting is - /// performed in a proper CER. - /// - /// - /// - /// - /// - /// - internal static SecurityStatus SafeDecryptMessage( - SafeContextHandle handle, - int qualityOfProtection, - SecureBufferAdapter bufferAdapter, - int sequenceNumber) - { - SecurityStatus status = SecurityStatus.InvalidHandle; - bool gotRef = false; - - RuntimeHelpers.PrepareConstrainedRegions(); - try - { - handle.DangerousAddRef(ref gotRef); - } - catch (Exception) - { - if (gotRef) - { - handle.DangerousRelease(); - gotRef = false; - } - - throw; - } - finally - { - if (gotRef) - { - status = ContextNativeMethods.DecryptMessage( - ref handle.rawHandle, - bufferAdapter.Handle, - sequenceNumber, - qualityOfProtection - ); - - handle.DangerousRelease(); - } - } - - return status; - } - - /// - /// Safely invokes the native MakeSignature function, making sure that handle ref counting is - /// performed in a proper CER. - /// - /// - /// - /// - /// - /// - internal static SecurityStatus SafeMakeSignature( - SafeContextHandle handle, - int qualityOfProtection, - SecureBufferAdapter adapter, - int sequenceNumber) - { - bool gotRef = false; - SecurityStatus status = SecurityStatus.InternalError; - - RuntimeHelpers.PrepareConstrainedRegions(); - try - { - handle.DangerousAddRef(ref gotRef); - } - catch (Exception) - { - if (gotRef) - { - handle.DangerousRelease(); - gotRef = false; - } - - throw; - } - finally - { - if (gotRef) - { - status = ContextNativeMethods.MakeSignature( - ref handle.rawHandle, - qualityOfProtection, - adapter.Handle, - sequenceNumber - ); - - handle.DangerousRelease(); - } - } - - return status; - } - - /// - /// Safely invokes the native VerifySignature function, making sure that handle ref counting is - /// performed in a proper CER. - /// - /// - /// - /// - /// - /// - internal static SecurityStatus SafeVerifySignature( - SafeContextHandle handle, - int qualityOfProtection, - SecureBufferAdapter adapter, - int sequenceNumber) - { - bool gotRef = false; - SecurityStatus status = SecurityStatus.InternalError; - - RuntimeHelpers.PrepareConstrainedRegions(); - try - { - handle.DangerousAddRef(ref gotRef); - } - catch (Exception) - { - if (gotRef) - { - handle.DangerousRelease(); - gotRef = false; - } - - throw; - } - finally - { - if (gotRef) - { - status = ContextNativeMethods.VerifySignature( - ref handle.rawHandle, - adapter.Handle, - sequenceNumber, - qualityOfProtection - ); - - handle.DangerousRelease(); - } - } - - return status; - } - } -} diff --git a/src/Cassandra/DataStax/Auth/Sspi/Contexts/ContextQueries.cs b/src/Cassandra/DataStax/Auth/Sspi/Contexts/ContextQueries.cs deleted file mode 100644 index 9fbb35caf..000000000 --- a/src/Cassandra/DataStax/Auth/Sspi/Contexts/ContextQueries.cs +++ /dev/null @@ -1,51 +0,0 @@ -// -// Copyright (c) 2014, Kevin Thompson -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -using System; -using System.Runtime.InteropServices; - -namespace Cassandra.DataStax.Auth.Sspi.Contexts -{ - /// - /// Stores the result of a context query for the context's buffer sizes. - /// - [StructLayout(LayoutKind.Sequential)] - internal struct SecPkgContext_Sizes - { - public int MaxToken; - public int MaxSignature; - public int BlockSize; - public int SecurityTrailer; - } - - /// - /// Stores the result of a context query for a string-valued context attribute. - /// - [StructLayout(LayoutKind.Sequential)] - internal struct SecPkgContext_String - { - public IntPtr StringResult; - } -} diff --git a/src/Cassandra/DataStax/Auth/Sspi/Contexts/ContextQueryAttrib.cs b/src/Cassandra/DataStax/Auth/Sspi/Contexts/ContextQueryAttrib.cs deleted file mode 100644 index f547fdcbe..000000000 --- a/src/Cassandra/DataStax/Auth/Sspi/Contexts/ContextQueryAttrib.cs +++ /dev/null @@ -1,59 +0,0 @@ -// -// Copyright (c) 2014, Kevin Thompson -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -namespace Cassandra.DataStax.Auth.Sspi.Contexts -{ - /// - /// Defines the types of queries that can be performed with QueryContextAttribute. - /// Each query has a different result buffer. - /// - internal enum ContextQueryAttrib : int - { - /// - /// Queries the buffer size parameters when performing message functions, such - /// as encryption, decryption, signing and signature validation. - /// - /// - /// Results for a query of this type are stored in a Win32 SecPkgContext_Sizes structure. - /// - Sizes = 0, - - /// - /// Queries the context for the name of the user assocated with a security context. - /// - /// - /// Results for a query of this type are stored in a Win32 SecPkgContext_Name structure. - /// - Names = 1, - - /// - /// Queries the name of the authenticating authority for the security context. - /// - /// - /// Results for a query of this type are stored in a Win32 SecPkgContext_Authority structure. - /// - Authority = 6, - } -} diff --git a/src/Cassandra/DataStax/Auth/Sspi/Contexts/SafeContextHandle.cs b/src/Cassandra/DataStax/Auth/Sspi/Contexts/SafeContextHandle.cs deleted file mode 100644 index 44ffd54d6..000000000 --- a/src/Cassandra/DataStax/Auth/Sspi/Contexts/SafeContextHandle.cs +++ /dev/null @@ -1,47 +0,0 @@ -// -// Copyright (c) 2014, Kevin Thompson -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -using System.Runtime.ConstrainedExecution; - -namespace Cassandra.DataStax.Auth.Sspi.Contexts -{ - /// - /// Captures an unmanaged security context handle. - /// - internal class SafeContextHandle : SafeSspiHandle - { - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - protected override bool ReleaseHandle() - { - SecurityStatus status = ContextNativeMethods.DeleteSecurityContext( - ref rawHandle - ); - - base.ReleaseHandle(); - - return status == SecurityStatus.OK; - } - } -} diff --git a/src/Cassandra/DataStax/Auth/Sspi/Credentials/ClientCredential.cs b/src/Cassandra/DataStax/Auth/Sspi/Credentials/ClientCredential.cs deleted file mode 100644 index bed40fa7e..000000000 --- a/src/Cassandra/DataStax/Auth/Sspi/Credentials/ClientCredential.cs +++ /dev/null @@ -1,42 +0,0 @@ -// -// Copyright (c) 2014, Kevin Thompson -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -namespace Cassandra.DataStax.Auth.Sspi.Credentials -{ - /// - /// Represents the credentials of the user running the current process, for use as an SSPI client. - /// - internal class ClientCredential : CurrentCredential - { - /// - /// Initializes a new instance of the ClientCredential class. - /// - /// The security package to acquire the credential handle from. - public ClientCredential(string package) - : base(package, CredentialUse.Outbound) - { - } - } -} diff --git a/src/Cassandra/DataStax/Auth/Sspi/Credentials/Credential.cs b/src/Cassandra/DataStax/Auth/Sspi/Credentials/Credential.cs deleted file mode 100644 index 3f5c90651..000000000 --- a/src/Cassandra/DataStax/Auth/Sspi/Credentials/Credential.cs +++ /dev/null @@ -1,227 +0,0 @@ -// -// Copyright (c) 2014, Kevin Thompson -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -using System; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -namespace Cassandra.DataStax.Auth.Sspi.Credentials -{ - /// - /// Provides access to the pre-existing credentials of a security principle. - /// - internal class Credential : IDisposable - { - /// - /// Whether the Credential has been disposed. - /// - private bool disposed; - - /// - /// The name of the security package that controls the credential. - /// - private string securityPackage; - - /// - /// A safe handle to the credential's handle. - /// - private SafeCredentialHandle safeCredHandle; - - /// - /// The UTC time the credentials expire. - /// - private DateTime expiry; - - /// - /// Initializes a new instance of the Credential class. - /// - /// The security package to acquire the credential from. - public Credential(string package) - { - this.disposed = false; - this.securityPackage = package; - - this.expiry = DateTime.MinValue; - - this.PackageInfo = PackageSupport.GetPackageCapabilities(this.SecurityPackage); - } - - /// - /// Gets metadata for the security package associated with the credential. - /// - public SecPkgInfo PackageInfo { get; private set; } - - /// - /// Gets the name of the security package that owns the credential. - /// - public string SecurityPackage - { - get - { - CheckLifecycle(); - - return this.securityPackage; - } - } - - /// - /// Returns the User Principle Name of the credential. Depending on the underlying security - /// package used by the credential, this may not be the same as the Down-Level Logon Name - /// for the user. - /// - public string PrincipleName - { - get - { - QueryNameAttribCarrier carrier; - SecurityStatus status; - string name = null; - bool gotRef = false; - - CheckLifecycle(); - - status = SecurityStatus.InternalError; - carrier = new QueryNameAttribCarrier(); - - RuntimeHelpers.PrepareConstrainedRegions(); - try - { - this.safeCredHandle.DangerousAddRef(ref gotRef); - } - catch (Exception) - { - if (gotRef == true) - { - this.safeCredHandle.DangerousRelease(); - gotRef = false; - } - throw; - } - finally - { - if (gotRef) - { - status = CredentialNativeMethods.QueryCredentialsAttribute_Name( - ref this.safeCredHandle.rawHandle, - CredentialQueryAttrib.Names, - ref carrier - ); - - this.safeCredHandle.DangerousRelease(); - - if (status == SecurityStatus.OK && carrier.Name != IntPtr.Zero) - { - try - { - name = Marshal.PtrToStringUni(carrier.Name); - } - finally - { - NativeMethods.FreeContextBuffer(carrier.Name); - } - } - } - } - - if (status.IsError()) - { - throw new SspiException("Failed to query credential name", status); - } - - return name; - } - } - - /// - /// Gets the UTC time the credentials expire. - /// - public DateTime Expiry - { - get - { - CheckLifecycle(); - - return this.expiry; - } - - protected set - { - CheckLifecycle(); - - this.expiry = value; - } - } - - /// - /// Gets a handle to the credential. - /// - public SafeCredentialHandle Handle - { - get - { - CheckLifecycle(); - - return this.safeCredHandle; - } - - protected set - { - CheckLifecycle(); - - this.safeCredHandle = value; - } - } - - /// - /// Releases all resources associated with the credential. - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposing) - { - if (this.disposed == false) - { - if (disposing) - { - this.safeCredHandle.Dispose(); - } - - this.disposed = true; - } - } - - private void CheckLifecycle() - { - if (this.disposed) - { - throw new ObjectDisposedException("Credential"); - } - } - } -} diff --git a/src/Cassandra/DataStax/Auth/Sspi/Credentials/CredentialNativeMethods.cs b/src/Cassandra/DataStax/Auth/Sspi/Credentials/CredentialNativeMethods.cs deleted file mode 100644 index a02af853d..000000000 --- a/src/Cassandra/DataStax/Auth/Sspi/Credentials/CredentialNativeMethods.cs +++ /dev/null @@ -1,72 +0,0 @@ -// -// Copyright (c) 2014, Kevin Thompson -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -using System; -using System.Runtime.ConstrainedExecution; -using System.Runtime.InteropServices; - -namespace Cassandra.DataStax.Auth.Sspi.Credentials -{ - internal static class CredentialNativeMethods - { - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - [DllImport("Secur32.dll", EntryPoint = "AcquireCredentialsHandle", CharSet = CharSet.Unicode)] - internal static extern SecurityStatus AcquireCredentialsHandle( - string principleName, - string packageName, - CredentialUse credentialUse, - IntPtr loginId, - IntPtr packageData, - IntPtr getKeyFunc, - IntPtr getKeyData, - ref RawSspiHandle credentialHandle, - ref TimeStamp expiry - ); - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - [DllImport("Secur32.dll", EntryPoint = "FreeCredentialsHandle", CharSet = CharSet.Unicode)] - internal static extern SecurityStatus FreeCredentialsHandle( - ref RawSspiHandle credentialHandle - ); - - - /// - /// The overload of the QueryCredentialsAttribute method that is used for querying the name attribute. - /// In this call, it takes a void* to a structure that contains a wide char pointer. The wide character - /// pointer is allocated by the SSPI api, and thus needs to be released by a call to FreeContextBuffer(). - /// - /// - /// - /// - /// - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - [DllImport("Secur32.dll", EntryPoint = "QueryCredentialsAttributes", CharSet = CharSet.Unicode)] - internal static extern SecurityStatus QueryCredentialsAttribute_Name( - ref RawSspiHandle credentialHandle, - CredentialQueryAttrib attributeName, - ref QueryNameAttribCarrier name - ); - } -} diff --git a/src/Cassandra/DataStax/Auth/Sspi/Credentials/CredentialQueryAttrib.cs b/src/Cassandra/DataStax/Auth/Sspi/Credentials/CredentialQueryAttrib.cs deleted file mode 100644 index 1e2cc2d49..000000000 --- a/src/Cassandra/DataStax/Auth/Sspi/Credentials/CredentialQueryAttrib.cs +++ /dev/null @@ -1,38 +0,0 @@ -// -// Copyright (c) 2014, Kevin Thompson -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -namespace Cassandra.DataStax.Auth.Sspi.Credentials -{ - /// - /// Identifies credential query types. - /// - internal enum CredentialQueryAttrib : uint - { - /// - /// Queries the credential's principle name. - /// - Names = 1, - } -} diff --git a/src/Cassandra/DataStax/Auth/Sspi/Credentials/CredentialUse.cs b/src/Cassandra/DataStax/Auth/Sspi/Credentials/CredentialUse.cs deleted file mode 100644 index 2bd824dbc..000000000 --- a/src/Cassandra/DataStax/Auth/Sspi/Credentials/CredentialUse.cs +++ /dev/null @@ -1,51 +0,0 @@ -// -// Copyright (c) 2014, Kevin Thompson -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -namespace Cassandra.DataStax.Auth.Sspi.Credentials -{ - /// - /// Indicates the manner in which a credential will be used for SSPI authentication. - /// - internal enum CredentialUse : uint - { - /// - /// The credentials will be used for establishing a security context with an inbound request, eg, - /// the credentials will be used by a server building a security context with a client. - /// - Inbound = 1, - - /// - /// The credentials will be used for establishing a security context as an outbound request, - /// eg, the credentials will be used by a client to build a security context with a server. - /// - Outbound = 2, - - /// - /// The credentials may be used to to either build a client's security context or a server's - /// security context. - /// - Both = 3, - } -} diff --git a/src/Cassandra/DataStax/Auth/Sspi/Credentials/CurrentCredential.cs b/src/Cassandra/DataStax/Auth/Sspi/Credentials/CurrentCredential.cs deleted file mode 100644 index a30aeb51e..000000000 --- a/src/Cassandra/DataStax/Auth/Sspi/Credentials/CurrentCredential.cs +++ /dev/null @@ -1,90 +0,0 @@ -// -// Copyright (c) 2014, Kevin Thompson -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -using System; -using System.Runtime.CompilerServices; - -namespace Cassandra.DataStax.Auth.Sspi.Credentials -{ - /// - /// Acquires a handle to the credentials of the user associated with the current process. - /// - internal class CurrentCredential : Credential - { - /// - /// Initializes a new instance of the CurrentCredential class. - /// - /// The security package to acquire the credential handle - /// from. - /// The manner in which the credentials will be used - Inbound typically - /// represents servers, outbound typically represent clients. - public CurrentCredential(string securityPackage, CredentialUse use) : - base(securityPackage) - { - Init(use); - } - - private void Init(CredentialUse use) - { - string packageName; - TimeStamp rawExpiry = new TimeStamp(); - SecurityStatus status = SecurityStatus.InternalError; - - // -- Package -- - // Copy off for the call, since this.SecurityPackage is a property. - packageName = this.SecurityPackage; - - this.Handle = new SafeCredentialHandle(); - - // The finally clause is the actual constrained region. The VM pre-allocates any stack space, - // performs any allocations it needs to prepare methods for execution, and postpones any - // instances of the 'uncatchable' exceptions (ThreadAbort, StackOverflow, OutOfMemory). - RuntimeHelpers.PrepareConstrainedRegions(); - try { } - finally - { - status = CredentialNativeMethods.AcquireCredentialsHandle( - null, - packageName, - use, - IntPtr.Zero, - IntPtr.Zero, - IntPtr.Zero, - IntPtr.Zero, - ref this.Handle.rawHandle, - ref rawExpiry - ); - } - - if (status != SecurityStatus.OK) - { - throw new SspiException("Failed to call AcquireCredentialHandle", status); - } - - this.Expiry = rawExpiry.ToDateTime(); - } - - } -} diff --git a/src/Cassandra/DataStax/Auth/Sspi/Credentials/QueryNameSupport.cs b/src/Cassandra/DataStax/Auth/Sspi/Credentials/QueryNameSupport.cs deleted file mode 100644 index fb55cec46..000000000 --- a/src/Cassandra/DataStax/Auth/Sspi/Credentials/QueryNameSupport.cs +++ /dev/null @@ -1,43 +0,0 @@ -// -// Copyright (c) 2014, Kevin Thompson -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -using System; -using System.Runtime.InteropServices; - -namespace Cassandra.DataStax.Auth.Sspi.Credentials -{ - /// - /// Stores the result from a query of a credential's principle name. - /// - [StructLayout(LayoutKind.Sequential)] - internal struct QueryNameAttribCarrier - { - /// - /// A pointer to a null-terminated ascii-encoded containing the principle name - /// associated with a credential - /// - public IntPtr Name; - } -} diff --git a/src/Cassandra/DataStax/Auth/Sspi/Credentials/SafeCredentialHandle.cs b/src/Cassandra/DataStax/Auth/Sspi/Credentials/SafeCredentialHandle.cs deleted file mode 100644 index 08f11ded9..000000000 --- a/src/Cassandra/DataStax/Auth/Sspi/Credentials/SafeCredentialHandle.cs +++ /dev/null @@ -1,52 +0,0 @@ -// -// Copyright (c) 2014, Kevin Thompson -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -using System.Runtime.ConstrainedExecution; - -namespace Cassandra.DataStax.Auth.Sspi.Credentials -{ - /// - /// Provides a managed handle to an SSPI credential. - /// - internal class SafeCredentialHandle : SafeSspiHandle - { - public SafeCredentialHandle() - : base() - { } - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - protected override bool ReleaseHandle() - { - SecurityStatus status = CredentialNativeMethods.FreeCredentialsHandle( - ref base.rawHandle - ); - - base.ReleaseHandle(); - - return status == SecurityStatus.OK; - } - } - -} diff --git a/src/Cassandra/DataStax/Auth/Sspi/Credentials/ServerCredential.cs b/src/Cassandra/DataStax/Auth/Sspi/Credentials/ServerCredential.cs deleted file mode 100644 index 8ecaf9277..000000000 --- a/src/Cassandra/DataStax/Auth/Sspi/Credentials/ServerCredential.cs +++ /dev/null @@ -1,43 +0,0 @@ -// -// Copyright (c) 2014, Kevin Thompson -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -namespace Cassandra.DataStax.Auth.Sspi.Credentials -{ - /// - /// Represents the credentials of the user running the current process, for use as an SSPI server. - /// - internal class ServerCredential : CurrentCredential - { - /// - /// Initializes a new instance of the ServerCredential class, acquiring credentials from - /// the current thread's security context. - /// - /// The name of the security package to obtain credentials from. - public ServerCredential(string package) - : base(package, CredentialUse.Inbound) - { - } - } -} diff --git a/src/Cassandra/DataStax/Auth/Sspi/EnumMgr.cs b/src/Cassandra/DataStax/Auth/Sspi/EnumMgr.cs deleted file mode 100644 index 27475769e..000000000 --- a/src/Cassandra/DataStax/Auth/Sspi/EnumMgr.cs +++ /dev/null @@ -1,87 +0,0 @@ -// -// Copyright (c) 2014, Kevin Thompson -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -using System; -using System.Reflection; - -namespace Cassandra.DataStax.Auth.Sspi -{ - [AttributeUsage(AttributeTargets.Field)] - internal class EnumStringAttribute : Attribute - { - public EnumStringAttribute(string text) - { - this.Text = text; - } - - public string Text { get; private set; } - } - - internal class EnumMgr - { - public static string ToText(Enum value) - { - FieldInfo field = value.GetType().GetField(value.ToString()); - - if (field == null) - { - return null; - } - - EnumStringAttribute[] attribs = (EnumStringAttribute[])field.GetCustomAttributes(typeof(EnumStringAttribute), false); - - if (attribs == null || attribs.Length == 0) - { - return null; - } - else - { - return attribs[0].Text; - } - } - - public static T FromText(string text) - { - FieldInfo[] fields = typeof(T).GetFields(); - - EnumStringAttribute[] attribs; - - foreach (FieldInfo field in fields) - { - attribs = (EnumStringAttribute[])field.GetCustomAttributes(typeof(EnumStringAttribute), false); - - foreach (EnumStringAttribute attrib in attribs) - { - if (attrib.Text == text) - { - return (T)field.GetValue(null); - } - } - } - - throw new ArgumentException("Could not find a matching enumeration value for the text '" + text + "'."); - } - } -} diff --git a/src/Cassandra/DataStax/Auth/Sspi/NativeMethods.cs b/src/Cassandra/DataStax/Auth/Sspi/NativeMethods.cs deleted file mode 100644 index 9ce593f29..000000000 --- a/src/Cassandra/DataStax/Auth/Sspi/NativeMethods.cs +++ /dev/null @@ -1,48 +0,0 @@ -// -// Copyright (c) 2014, Kevin Thompson -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -using System; -using System.Runtime.ConstrainedExecution; -using System.Runtime.InteropServices; - -namespace Cassandra.DataStax.Auth.Sspi -{ - internal static class NativeMethods - { - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - [DllImport("Secur32.dll", EntryPoint = "FreeContextBuffer", CharSet = CharSet.Unicode)] - internal static extern SecurityStatus FreeContextBuffer(IntPtr buffer); - - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - [DllImport("Secur32.dll", EntryPoint = "QuerySecurityPackageInfo", CharSet = CharSet.Unicode)] - internal static extern SecurityStatus QuerySecurityPackageInfo(string packageName, ref IntPtr pkgInfo); - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - [DllImport("Secur32.dll", EntryPoint = "EnumerateSecurityPackages", CharSet = CharSet.Unicode)] - internal static extern SecurityStatus EnumerateSecurityPackages(ref int numPackages, ref IntPtr pkgInfoArry); - - } -} diff --git a/src/Cassandra/DataStax/Auth/Sspi/PackageNames.cs b/src/Cassandra/DataStax/Auth/Sspi/PackageNames.cs deleted file mode 100644 index 97f6de8db..000000000 --- a/src/Cassandra/DataStax/Auth/Sspi/PackageNames.cs +++ /dev/null @@ -1,48 +0,0 @@ -// -// Copyright (c) 2014, Kevin Thompson -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -namespace Cassandra.DataStax.Auth.Sspi -{ - /// - /// Provides canonical names for security pacakges. - /// - internal static class PackageNames - { - /// - /// Indicates the Negotiate security package. - /// - public const string Negotiate = "Negotiate"; - - /// - /// Indicates the Kerberos security package. - /// - public const string Kerberos = "Kerberos"; - - /// - /// Indicates the NTLM security package. - /// - public const string Ntlm = "NTLM"; - } -} diff --git a/src/Cassandra/DataStax/Auth/Sspi/PackageSupport.cs b/src/Cassandra/DataStax/Auth/Sspi/PackageSupport.cs deleted file mode 100644 index 8aa9dfbe3..000000000 --- a/src/Cassandra/DataStax/Auth/Sspi/PackageSupport.cs +++ /dev/null @@ -1,147 +0,0 @@ -// -// Copyright (c) 2014, Kevin Thompson -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -using System; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -namespace Cassandra.DataStax.Auth.Sspi -{ - /// - /// Queries information about security packages. - /// - internal static class PackageSupport - { - /// - /// Returns the properties of the named package. - /// - /// The name of the package. - /// - public static SecPkgInfo GetPackageCapabilities(string packageName) - { - SecPkgInfo info; - SecurityStatus status = SecurityStatus.InternalError; - - IntPtr rawInfoPtr; - - rawInfoPtr = new IntPtr(); - info = new SecPkgInfo(); - - RuntimeHelpers.PrepareConstrainedRegions(); - try - { } - finally - { - status = NativeMethods.QuerySecurityPackageInfo(packageName, ref rawInfoPtr); - - if (rawInfoPtr != IntPtr.Zero) - { - try - { - if (status == SecurityStatus.OK) - { - // This performs allocations as it makes room for the strings contained in the SecPkgInfo class. - Marshal.PtrToStructure(rawInfoPtr, info); - } - } - finally - { - NativeMethods.FreeContextBuffer(rawInfoPtr); - } - } - } - - if (status != SecurityStatus.OK) - { - throw new SspiException("Failed to query security package provider details", status); - } - - return info; - } - - /// - /// Returns a list of all known security package providers and their properties. - /// - /// - public static SecPkgInfo[] EnumeratePackages() - { - SecurityStatus status = SecurityStatus.InternalError; - SecPkgInfo[] packages = null; - IntPtr pkgArrayPtr; - IntPtr pkgPtr; - int numPackages = 0; - int pkgSize = Marshal.SizeOf(typeof(SecPkgInfo)); - - pkgArrayPtr = new IntPtr(); - - RuntimeHelpers.PrepareConstrainedRegions(); - try { } - finally - { - status = NativeMethods.EnumerateSecurityPackages(ref numPackages, ref pkgArrayPtr); - - if (pkgArrayPtr != IntPtr.Zero) - { - try - { - if (status == SecurityStatus.OK) - { - // Bwooop Bwooop Alocation Alert - // 1) We allocate the array - // 2) We allocate the individual elements in the array (they're class objects). - // 3) We allocate the strings in the individual elements in the array when we - // call Marshal.PtrToStructure() - - packages = new SecPkgInfo[numPackages]; - - for (int i = 0; i < numPackages; i++) - { - packages[i] = new SecPkgInfo(); - } - - for (int i = 0; i < numPackages; i++) - { - pkgPtr = IntPtr.Add(pkgArrayPtr, i * pkgSize); - - Marshal.PtrToStructure(pkgPtr, packages[i]); - } - } - } - finally - { - NativeMethods.FreeContextBuffer(pkgArrayPtr); - } - } - } - - if (status != SecurityStatus.OK) - { - throw new SspiException("Failed to enumerate security package providers", status); - } - - return packages; - } - } -} diff --git a/src/Cassandra/DataStax/Auth/Sspi/SecPkgInfo.cs b/src/Cassandra/DataStax/Auth/Sspi/SecPkgInfo.cs deleted file mode 100644 index af4054d88..000000000 --- a/src/Cassandra/DataStax/Auth/Sspi/SecPkgInfo.cs +++ /dev/null @@ -1,188 +0,0 @@ -// -// Copyright (c) 2014, Kevin Thompson -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -using System; -using System.Runtime.InteropServices; - -namespace Cassandra.DataStax.Auth.Sspi -{ - /// - /// Stores information about a particular security package. - /// - [StructLayout(LayoutKind.Sequential)] - internal class SecPkgInfo - { - /// - /// The packages capabilities and options. - /// - public SecPkgCapability Capabilities; - - /// - /// The package's version number. - /// - public short Version; - - /// - /// The package's Id when used in RPC contexts. - /// - public short RpcId; - - /// - /// The maximum size, in bytes, of tokens generated by the package. - /// - public int MaxTokenLength; - - /// - /// The human-readable name of the package. - /// - [MarshalAs(UnmanagedType.LPWStr)] - public string Name; - - /// - /// A short description of the package. - /// - [MarshalAs(UnmanagedType.LPWStr)] - public string Comment; - } - - /// - /// Describes the capabilities of a security package. - /// - [Flags] - internal enum SecPkgCapability : uint - { - /// - /// Whether the package supports generating messages with integrity information. Required for MakeSignature and VerifySignature. - /// - Integrity = 0x1, - - /// - /// Whether the package supports generating encrypted messages. Required for EncryptMessage and DecryptMessage. - /// - Privacy = 0x2, - - /// - /// Whether the package uses any other buffer information than token buffers. - /// - TokenOnly = 0x4, - - /// - /// Whether the package supports datagram-style authentication. - /// - Datagram = 0x8, - - /// - /// Whether the package supports creating contexts with connection semantics - /// - Connection = 0x10, - - /// - /// Multiple legs are neccessary for authentication. - /// - MultiLeg = 0x20, - - /// - /// Server authentication is not supported. - /// - ClientOnly = 0x40, - - /// - /// Supports extended error handling facilities. - /// - ExtendedError = 0x80, - - /// - /// Supports client impersonation on the server. - /// - Impersonation = 0x100, - - /// - /// Understands Windows princple and target names. - /// - AcceptWin32Name = 0x200, - - /// - /// Supports stream semantics - /// - Stream = 0x400, - - /// - /// Package may be used by the Negiotiate meta-package. - /// - Negotiable = 0x800, - - /// - /// Compatible with GSS. - /// - GssCompatible = 0x1000, - - /// - /// Supports LsaLogonUser - /// - Logon = 0x2000, - - /// - /// Token buffers are in Ascii format. - /// - AsciiBuffers = 0x4000, - - /// - /// Supports separating large tokens into multiple buffers. - /// - Fragment = 0x8000, - - /// - /// Supports mutual authentication between a client and server. - /// - MutualAuth = 0x10000, - - /// - /// Supports credential delegation from the server to a third context. - /// - Delegation = 0x20000, - - /// - /// Supports calling EncryptMessage with the read-only-checksum flag, which protects data only - /// with a checksum and does not encrypt it. - /// - ReadOnlyChecksum = 0x40000, - - /// - /// Whether the package supports handling restricted tokens, which are tokens derived from existing tokens - /// that have had restrictions placed on them. - /// - RestrictedTokens = 0x80000, - - /// - /// Extends the negotiate package; only one such package may be registered at any time. - /// - ExtendsNego = 0x00100000, - - /// - /// This package is negotiated by the package of type ExtendsNego. - /// - Negotiable2 = 0x00200000, - } -} diff --git a/src/Cassandra/DataStax/Auth/Sspi/SecurityStatus.cs b/src/Cassandra/DataStax/Auth/Sspi/SecurityStatus.cs deleted file mode 100644 index 5bdf567a9..000000000 --- a/src/Cassandra/DataStax/Auth/Sspi/SecurityStatus.cs +++ /dev/null @@ -1,191 +0,0 @@ -// -// Copyright (c) 2014, Kevin Thompson -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -namespace Cassandra.DataStax.Auth.Sspi -{ - /* - // From winerror.h - #define SEC_E_OK ((HRESULT)0x00000000L) - #define SEC_E_INSUFFICIENT_MEMORY _HRESULT_TYPEDEF_(0x80090300L) - #define SEC_E_INVALID_HANDLE _HRESULT_TYPEDEF_(0x80090301L) - #define SEC_E_UNSUPPORTED_FUNCTION _HRESULT_TYPEDEF_(0x80090302L) - #define SEC_E_TARGET_UNKNOWN _HRESULT_TYPEDEF_(0x80090303L) - #define SEC_E_INTERNAL_ERROR _HRESULT_TYPEDEF_(0x80090304L) - #define SEC_E_SECPKG_NOT_FOUND _HRESULT_TYPEDEF_(0x80090305L) - #define SEC_E_NOT_OWNER _HRESULT_TYPEDEF_(0x80090306L) - #define SEC_E_UNKNOWN_CREDENTIALS _HRESULT_TYPEDEF_(0x8009030DL) - #define SEC_E_NO_CREDENTIALS _HRESULT_TYPEDEF_(0x8009030EL) - */ - - /// - /// Defines the results of invoking the SSPI api. - /// - internal enum SecurityStatus : uint - { - // --- Success / Informational --- - - /// - /// The request completed successfully - /// - [EnumString("No error")] - OK = 0x00000000, - - /// - /// The token returned by the context needs to be provided to the cooperating party - /// to continue construction of the context. - /// - [EnumString("Authentication cycle needs to continue")] - ContinueNeeded = 0x00090312, - - /// - /// Occurs after a client calls InitializeSecurityContext to indicate that the client - /// must call CompleteAuthToken. - /// - [EnumString("Authentication cycle needs to perform a 'complete'.")] - CompleteNeeded = 0x00090313, - - /// - /// Occurs after a client calls InitializeSecurityContext to indicate that the client - /// must call CompleteAuthToken and pass the result to the server. - /// - [EnumString("Authentication cycle needs to perform a 'complete' and then continue.")] - CompAndContinue = 0x00090314, - - /// - /// An attempt to use the context was performed after the context's expiration time elapsed. - /// - [EnumString("The security context was used after its expiration time passed.")] - ContextExpired = 0x00090317, - - [EnumString("The credentials supplied to the security context were not fully initialized.")] - CredentialsNeeded = 0x00090320, - - [EnumString("The context data must be re-negotiated with the peer")] - Renegotiate = 0x00090321, - - // Errors - [EnumString("Not enough memory.")] - OutOfMemory = 0x80090300, - - [EnumString("The handle provided to the API was invalid.")] - InvalidHandle = 0x80090301, - - [EnumString("The attempted operation is not supported")] - Unsupported = 0x80090302, - - [EnumString("The specified principle is not known in the authentication system.")] - TargetUnknown = 0x80090303, - - [EnumString("An internal error occurred")] - InternalError = 0x80090304, - - /// - /// No security provider package was found with the given name. - /// - [EnumString("The requested security package was not found.")] - PackageNotFound = 0x80090305, - - NotOwner = 0x80090306, - CannotInstall = 0x80090307, - - /// - /// A token was provided that contained incorrect or corrupted data. - /// - [EnumString("The provided authentication token is invalid or corrupted.")] - InvalidToken = 0x80090308, - - CannotPack = 0x80090309, - QopNotSupported = 0x8009030A, - - /// - /// Impersonation is not supported. - /// - [EnumString("Impersonation is not supported with the current security package.")] - NoImpersonation = 0x8009030B, - - [EnumString("The logon was denied, perhaps because the provided credentials were incorrect.")] - LogonDenied = 0x8009030C, - - - [EnumString("The credentials provided are not recognized by the selected security package.")] - UnknownCredentials = 0x8009030D, - - [EnumString("No credentials are available in the selected security package.")] - NoCredentials = 0x8009030E, - - [EnumString("A message that was provided to the Decrypt or VerifySignature functions was altered " + - "after it was created.")] - MessageAltered = 0x8009030F, - - [EnumString("A message was received out of the expected order.")] - OutOfSequence = 0x80090310, - - [EnumString("The current security package cannot contact an authenticating authority.")] - NoAuthenticatingAuthority = 0x80090311, - - /// - /// The buffer provided to an SSPI API call contained a message that was not complete. - /// - /// - /// This occurs regularly with SSPI contexts that exchange data using a streaming context, - /// where the data returned from the streaming communications channel, such as a TCP socket, - /// did not contain the complete message. - /// Similarly, a streaming channel may return too much data, in which case the API function - /// will indicate success, but will save off the extra, unrelated data in a buffer of - /// type 'extra'. - /// - IncompleteMessage = 0x80090318, - IncompleteCredentials = 0x80090320, - BufferNotEnough = 0x80090321, - WrongPrincipal = 0x80090322, - TimeSkew = 0x80090324, - UntrustedRoot = 0x80090325, - IllegalMessage = 0x80090326, - CertUnknown = 0x80090327, - CertExpired = 0x80090328, - AlgorithmMismatch = 0x80090331, - SecurityQosFailed = 0x80090332, - SmartcardLogonRequired = 0x8009033E, - UnsupportedPreauth = 0x80090343, - BadBinding = 0x80090346 - } - - /// - /// Provides extension methods for the SecurityStatus enumeration. - /// - internal static class SecurityStatusExtensions - { - /// - /// Returns whether or not the status represents an error. - /// - /// - /// True if the status represents an error condition. - public static bool IsError(this SecurityStatus status) - { - return (uint)status > 0x80000000u; - } - } - -} diff --git a/src/Cassandra/DataStax/Auth/Sspi/SspiException.cs b/src/Cassandra/DataStax/Auth/Sspi/SspiException.cs deleted file mode 100644 index 69f05cab9..000000000 --- a/src/Cassandra/DataStax/Auth/Sspi/SspiException.cs +++ /dev/null @@ -1,115 +0,0 @@ -// -// Copyright (c) 2014, Kevin Thompson -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -using System; -using System.Runtime.Serialization; - -namespace Cassandra.DataStax.Auth.Sspi -{ - /// - /// The exception that is thrown when a problem occurs hwen using the SSPI system. - /// -#if NET452 - [Serializable] -#endif - public class SspiException : Exception - { - private SecurityStatus errorCode; - private string message; - - /// - /// Initializes a new instance of the SSPIException class with the given message and status. - /// - /// A message explaining what part of the system failed. - /// The error code observed during the failure. - internal SspiException(string message, SecurityStatus errorCode) - { - this.message = message; - this.errorCode = errorCode; - } - - /// - /// Creates a new instance of . - /// - public SspiException(string message, int errorCode) : this(message, (SecurityStatus)errorCode) - { - - } - -#if NET452 - /// - /// Initializes a new instance of the SSPIException class from serialization data. - /// - /// - /// - protected SspiException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - this.message = info.GetString("messsage"); - this.errorCode = (SecurityStatus)info.GetUInt32("errorCode"); - } - - /// - /// Serializes the exception. - /// - /// - /// - public override void GetObjectData(SerializationInfo info, StreamingContext context) - { - base.GetObjectData(info, context); - - info.AddValue("message", this.message); - info.AddValue("errorCode", this.errorCode); - } -#endif - - /// - /// The error code that was observed during the SSPI call. - /// - public int ErrorCode - { - get - { - return (int)this.errorCode; - } - } - - /// - /// A human-readable message indicating the nature of the exception. - /// - public override string Message - { - get - { - return string.Format( - "{0}. Error Code = '0x{1:X}' - \"{2}\".", - this.message, - this.errorCode, - EnumMgr.ToText(this.errorCode) - ); - } - } - } -} diff --git a/src/Cassandra/DataStax/Auth/Sspi/SspiHandle.cs b/src/Cassandra/DataStax/Auth/Sspi/SspiHandle.cs deleted file mode 100644 index 04c077cb5..000000000 --- a/src/Cassandra/DataStax/Auth/Sspi/SspiHandle.cs +++ /dev/null @@ -1,101 +0,0 @@ -// -// Copyright (c) 2014, Kevin Thompson -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -using System; -using System.Runtime.ConstrainedExecution; -using System.Runtime.InteropServices; - -namespace Cassandra.DataStax.Auth.Sspi -{ - /// - /// Represents the raw structure for any handle created for the SSPI API, for example, credential - /// handles, context handles, and security package handles. Any SSPI handle is always the size - /// of two native pointers. - /// - /// - /// The documentation for SSPI handles can be found here: - /// http://msdn.microsoft.com/en-us/library/windows/desktop/aa380495(v=vs.85).aspx - /// - /// This class is not reference safe - if used directly, or referenced directly, it may be leaked, - /// or subject to finalizer races, or any of the hundred of things SafeHandles were designed to fix. - /// Do not directly use this class - use only though SafeHandle wrapper objects. Any reference needed - /// to this handle for performing work (InitializeSecurityContext, eg) should be performed a CER - /// that employs handle reference counting across the native API invocation. - /// - [StructLayout(LayoutKind.Sequential, Pack = 1)] - internal struct RawSspiHandle - { - private IntPtr lowPart; - private IntPtr highPart; - - /// - /// Returns whether or not the handle is set to the default, empty value. - /// - /// - public bool IsZero() - { - return this.lowPart == IntPtr.Zero && this.highPart == IntPtr.Zero; - } - - /// - /// Sets the handle to an invalid value. - /// - /// - /// This method is executed in a CER during handle release. - /// - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - public void SetInvalid() - { - this.lowPart = IntPtr.Zero; - this.highPart = IntPtr.Zero; - } - } - - /// - /// Safely encapsulates a raw handle used in the SSPI api. - /// - internal abstract class SafeSspiHandle : SafeHandle - { - internal RawSspiHandle rawHandle; - - protected SafeSspiHandle() - : base(IntPtr.Zero, true) - { - this.rawHandle = new RawSspiHandle(); - } - - public override bool IsInvalid - { - get { return IsClosed || this.rawHandle.IsZero(); } - } - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - protected override bool ReleaseHandle() - { - this.rawHandle.SetInvalid(); - return true; - } - } -} diff --git a/src/Cassandra/DataStax/Auth/Sspi/TimeStamp.cs b/src/Cassandra/DataStax/Auth/Sspi/TimeStamp.cs deleted file mode 100644 index 990609f8c..000000000 --- a/src/Cassandra/DataStax/Auth/Sspi/TimeStamp.cs +++ /dev/null @@ -1,69 +0,0 @@ -// -// Copyright (c) 2014, Kevin Thompson -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -using System; -using System.Runtime.InteropServices; - -namespace Cassandra.DataStax.Auth.Sspi -{ - /// - /// Represents a Windows API Timestamp structure, which stores time in units of 100 nanosecond - /// ticks, counting from January 1st, year 1601 at 00:00 UTC. Time is stored as a 64-bit value. - /// - [StructLayout(LayoutKind.Sequential)] - internal struct TimeStamp - { - public static readonly DateTime Epoch = new DateTime(1601, 1, 1, 0, 0, 0, DateTimeKind.Utc); - - /// - /// Stores the time value. Infinite times are often represented as values near, but not exactly - /// at the maximum signed 64-bit 2's complement value. - /// - private long time; - - /// - /// Converts the TimeStamp to an equivalant DateTime object. If the TimeStamp represents - /// a value larger than DateTime.MaxValue, then DateTime.MaxValue is returned. - /// - /// - public DateTime ToDateTime() - { - ulong test = (ulong)this.time + (ulong)(TimeStamp.Epoch.Ticks); - - // Sometimes the value returned is massive, eg, 0x7fffff154e84ffff, which is a value - // somewhere in the year 30848. This would overflow DateTime, since it peaks at 31-Dec-9999. - // It turns out that this value corresponds to a TimeStamp's maximum value, reduced by my local timezone - // http://stackoverflow.com/questions/24478056/ - if (test > (ulong)DateTime.MaxValue.Ticks) - { - return DateTime.MaxValue; - } - else - { - return DateTime.FromFileTimeUtc(this.time); - } - } - } -} diff --git a/src/Cassandra/DataStax/Auth/SspiClient.cs b/src/Cassandra/DataStax/Auth/SspiClient.cs deleted file mode 100644 index 253d2fa62..000000000 --- a/src/Cassandra/DataStax/Auth/SspiClient.cs +++ /dev/null @@ -1,120 +0,0 @@ -// -// Copyright (C) DataStax Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using System.Threading; - -using Cassandra.DataStax.Auth.Sspi; -using Cassandra.DataStax.Auth.Sspi.Contexts; -using Cassandra.DataStax.Auth.Sspi.Credentials; - -namespace Cassandra.DataStax.Auth -{ - /// - /// A Windows-only implementation. - /// - internal class SspiClient : IGssapiClient - { - private delegate byte[] TransitionHandler(byte[] challenge); - private const ContextAttrib ContextRequestAttributes = ContextAttrib.MutualAuth; - private static readonly byte[] EmptyBuffer = new byte[0]; - private readonly TransitionHandler[] _transitions; - private int _transitionIndex = -1; - private volatile ClientCredential _credentials; - private volatile ClientContext _context; - - public SspiClient() - { - _transitions = new TransitionHandler[] - { - FirstTransition, - SecondTransition, - ThirdTransition - }; - } - - public void Init(string service, string host) - { - if (!string.IsNullOrEmpty(service)) - { - //For the server principal: "dse/cassandra1.datastax.com@DATASTAX.COM" - //the expected Uri is: "dse/cassandra1.datastax.com" - service = service + "/" + host; - } - else - { - //Use string empty - service = ""; - } - //Acquire credentials - _credentials = new ClientCredential(PackageNames.Kerberos); - //Initialize security context - _context = new ClientContext(_credentials, service, SspiClient.ContextRequestAttributes); - } - - public byte[] EvaluateChallenge(byte[] challenge) - { - var index = Interlocked.Increment(ref _transitionIndex); - if (index > 2) - { - throw new InvalidOperationException("No additional transitions supported"); - } - //According to RFC 2222 7.2.1: Client can respond with no data - //Use empty buffer instead - return _transitions[index](challenge) ?? SspiClient.EmptyBuffer; - } - - private byte[] FirstTransition(byte[] challenge) - { - _context.Init(null, out byte[] resultToken); - return resultToken; - } - - private byte[] SecondTransition(byte[] challenge) - { - _context.Init(challenge, out byte[] resultToken); - return resultToken; - } - - private byte[] ThirdTransition(byte[] challenge) - { - _context.Decrypt(challenge); - - var plainResult = new byte[] - { - 0x1, // QOP - 0x0, - 0x0, - 0x0 - }; - return _context.Encrypt(plainResult); - } - - public void Dispose() - { - var context = _context; - if (context != null) - { - context.Dispose(); - } - var credentials = _credentials; - if (credentials != null) - { - credentials.Dispose(); - } - } - } -} \ No newline at end of file diff --git a/src/Cassandra/DataStax/Cloud/CloudConfiguration.cs b/src/Cassandra/DataStax/Cloud/CloudConfiguration.cs deleted file mode 100644 index b3889649c..000000000 --- a/src/Cassandra/DataStax/Cloud/CloudConfiguration.cs +++ /dev/null @@ -1,68 +0,0 @@ -// -// Copyright (C) DataStax Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using System.Collections.Generic; - -using Newtonsoft.Json; - -namespace Cassandra.DataStax.Cloud -{ - [JsonObject] - internal class CloudConfiguration : IEquatable - { - [JsonProperty("host")] - public string Host { get; private set; } - - [JsonProperty("port")] - public int Port { get; private set; } - - [JsonProperty("pfxCertPassword")] - public string CertificatePassword { get; private set; } - - public override bool Equals(object obj) - { - return Equals(obj as CloudConfiguration); - } - - public bool Equals(CloudConfiguration other) - { - return other != null && - Host == other.Host && - Port == other.Port && - CertificatePassword == other.CertificatePassword; - } - - public override int GetHashCode() - { - int hashCode = 1018287022; - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(Host); - hashCode = hashCode * -1521134295 + Port.GetHashCode(); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(CertificatePassword); - return hashCode; - } - - public static bool operator ==(CloudConfiguration left, CloudConfiguration right) - { - return EqualityComparer.Default.Equals(left, right); - } - - public static bool operator !=(CloudConfiguration left, CloudConfiguration right) - { - return !(left == right); - } - } -} \ No newline at end of file diff --git a/src/Cassandra/DataStax/Cloud/CloudConfigurationParser.cs b/src/Cassandra/DataStax/Cloud/CloudConfigurationParser.cs deleted file mode 100644 index 3f1950ae7..000000000 --- a/src/Cassandra/DataStax/Cloud/CloudConfigurationParser.cs +++ /dev/null @@ -1,66 +0,0 @@ -// -// Copyright (C) DataStax Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using System.IO; -using Newtonsoft.Json; - -namespace Cassandra.DataStax.Cloud -{ - /// - internal class CloudConfigurationParser : ICloudConfigurationParser - { - private static readonly Logger Logger = new Logger(typeof(CloudConfigurationParser)); - - /// - public CloudConfiguration ParseConfig(Stream stream) - { - CloudConfiguration cloudConfiguration; - using (var configStream = new StreamReader(stream)) - { - var json = configStream.ReadToEnd(); - cloudConfiguration = JsonConvert.DeserializeObject(json); - } - - ValidateConfiguration(cloudConfiguration); - - return cloudConfiguration; - } - - private void ValidateConfiguration(CloudConfiguration config) - { - if (config == null) - { - throw new ArgumentException("Config file is empty."); - } - - if (config.Port == 0) - { - throw new ArgumentException("Could not parse the \"port\" property from the config file."); - } - - if (string.IsNullOrWhiteSpace(config.Host)) - { - throw new ArgumentException("Could not parse the \"host\" property from the config file."); - } - - if (string.IsNullOrEmpty(config.CertificatePassword)) - { - CloudConfigurationParser.Logger.Warning("Could not parse the \"pfxCertPassword\" property from the config file."); - } - } - } -} \ No newline at end of file diff --git a/src/Cassandra/DataStax/Cloud/CloudMetadataResult.cs b/src/Cassandra/DataStax/Cloud/CloudMetadataResult.cs deleted file mode 100644 index 5cc8ab01f..000000000 --- a/src/Cassandra/DataStax/Cloud/CloudMetadataResult.cs +++ /dev/null @@ -1,31 +0,0 @@ -// -// Copyright (C) DataStax Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using Newtonsoft.Json; - -namespace Cassandra.DataStax.Cloud -{ - [JsonObject] - internal class CloudMetadataResult - { - [JsonProperty("region")] - public string Region { get; set; } - - [JsonRequired] - [JsonProperty("contact_info")] - public ContactInfo ContactInfo { get; set; } - } -} \ No newline at end of file diff --git a/src/Cassandra/DataStax/Cloud/CloudMetadataService.cs b/src/Cassandra/DataStax/Cloud/CloudMetadataService.cs deleted file mode 100644 index 610ebe899..000000000 --- a/src/Cassandra/DataStax/Cloud/CloudMetadataService.cs +++ /dev/null @@ -1,217 +0,0 @@ -// -// Copyright (C) DataStax Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using System.IO; -using System.Net; -using System.Security.Authentication; -using System.Threading.Tasks; -using Cassandra.Helpers; -using Newtonsoft.Json; -#if NETSTANDARD -using System.Net.Http; -using System.Net.Http.Headers; -#endif - -namespace Cassandra.DataStax.Cloud -{ - /// - internal class CloudMetadataService : ICloudMetadataService - { - /// - public Task GetClusterMetadataAsync( - string url, SocketOptions socketOptions, SSLOptions sslOptions) - { -#if NET452 - return GetWithWebRequestAsync(url, socketOptions, sslOptions); -#else - if (PlatformHelper.RuntimeSupportsCloudTlsSettings()) - { - return GetWithHttpClientAsync(url, socketOptions, sslOptions); - } - - throw new NotSupportedException("DataStax Astra support in .NET Core requires .NET Core 2.1 runtime or later. " + - "The HTTPS implementation of .NET Core 2.0 and below don't work when some TLS settings are set. " + - $"The runtime that is being used is: .NET Core {PlatformHelper.GetNetCoreVersion()}"); -#endif - } - -#if !NETSTANDARD - - private async Task GetWithWebRequestAsync( - string url, SocketOptions socketOptions, SSLOptions sslOptions) - { - ServicePointManager.SecurityProtocol |= ConvertSslProtocolEnum(sslOptions.SslProtocol); - var request = (HttpWebRequest)WebRequest.Create(url); - request.KeepAlive = false; - request.Timeout = socketOptions.ConnectTimeoutMillis; - request.Accept = "application/json"; - - request.ServerCertificateValidationCallback = sslOptions.RemoteCertValidationCallback; - - if (sslOptions.CertificateCollection.Count > 0) - { - request.ClientCertificates.AddRange(sslOptions.CertificateCollection); - } - - try - { - using (var response = (HttpWebResponse)await request.GetResponseAsync().ConfigureAwait(false)) - { - var responseString = await new StreamReader(response.GetResponseStream()).ReadToEndAsync().ConfigureAwait(false); - if ((int)response.StatusCode < 200 || (int)response.StatusCode >= 300) - { - throw GetServiceRequestException(false, url, null, (int)response.StatusCode); - } - - try - { - return JsonConvert.DeserializeObject(responseString); - } - catch (Exception ex) - { - throw GetServiceRequestException(true, url, ex, (int)response.StatusCode); - } - } - } - catch (NoHostAvailableException) - { - throw; - } - catch (Exception ex) - { - throw GetServiceRequestException(false, url, ex); - } - } - - private SecurityProtocolType ConvertSslProtocolEnum(SslProtocols protocol) - { - SecurityProtocolType securityProtocolType = 0; - if ((protocol & SslProtocols.Ssl3) != 0) - { - securityProtocolType |= SecurityProtocolType.Ssl3; - } - - if ((protocol & SslProtocols.Tls) != 0) - { - securityProtocolType |= SecurityProtocolType.Tls; - } - - if ((protocol & SslProtocols.Tls11) != 0) - { - securityProtocolType |= SecurityProtocolType.Tls11; - } - - if ((protocol & SslProtocols.Tls12) != 0) - { - securityProtocolType |= SecurityProtocolType.Tls12; - } - - return securityProtocolType; - } - -#endif - -#if NETSTANDARD - private async Task GetWithHttpClientAsync( - string url, SocketOptions socketOptions, SSLOptions sslOptions) - { - var handler = CreateHttpClientHandler(sslOptions); - return await GetWithHandlerAsync(url, handler, socketOptions).ConfigureAwait(false); - } - - private async Task GetWithHandlerAsync( - string url, HttpMessageHandler handler, SocketOptions socketOptions) - { - using (var httpClient = new HttpClient(handler)) - { - string body = null; - try - { - httpClient.Timeout = TimeSpan.FromMilliseconds(socketOptions.ConnectTimeoutMillis); - httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); - - var response = await httpClient.GetAsync(url).ConfigureAwait(false); - body = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - - if (!response.IsSuccessStatusCode) - { - throw GetServiceRequestException(false, url, null, (int) response.StatusCode); - } - - try - { - return JsonConvert.DeserializeObject(body); - } - catch (Exception ex2) - { - throw GetServiceRequestException(true, url, ex2, (int) response.StatusCode); - } - } - catch (NoHostAvailableException) - { - throw; - } - catch (Exception ex) - { - throw GetServiceRequestException(false, url, ex); - } - - } - } - - private HttpClientHandler CreateHttpClientHandler(SSLOptions sslOptions) - { - var httpClientHandler = new HttpClientHandler(); - httpClientHandler.SslProtocols = sslOptions.SslProtocol; - - httpClientHandler.CheckCertificateRevocationList = sslOptions.CheckCertificateRevocation; - httpClientHandler.ServerCertificateCustomValidationCallback = - (httpRequestMessage, cert, chain, errors) => - sslOptions.RemoteCertValidationCallback.Invoke(httpRequestMessage, cert, chain, errors); - - if (sslOptions.CertificateCollection.Count > 0) - { - httpClientHandler.ClientCertificateOptions = ClientCertificateOption.Manual; - httpClientHandler.ClientCertificates.AddRange(sslOptions.CertificateCollection); - } - - return httpClientHandler; - } -#endif - private Exception GetServiceRequestException(bool isParsingError, string url, Exception exception = null, int? statusCode = null) - { - var message = - isParsingError - ? $"There was an error while parsing the metadata service information from the Metadata Service ({url})." - : $"There was an error fetching the metadata information from the Cloud Metadata Service ({url}). " + - "Please make sure your cluster is not parked or terminated."; - - if (statusCode.HasValue) - { - message += $" It returned a {statusCode.Value} status code."; - } - - if (exception != null) - { - message += " See inner exception for more details."; - return new NoHostAvailableException(message, exception); - } - - return new NoHostAvailableException(message); - } - } -} \ No newline at end of file diff --git a/src/Cassandra/DataStax/Cloud/CloudSniOptionsProvider.cs b/src/Cassandra/DataStax/Cloud/CloudSniOptionsProvider.cs deleted file mode 100644 index 559649c4d..000000000 --- a/src/Cassandra/DataStax/Cloud/CloudSniOptionsProvider.cs +++ /dev/null @@ -1,132 +0,0 @@ -// -// Copyright (C) DataStax Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using System.Collections.Generic; -using System.Net; -using System.Threading.Tasks; - -using Cassandra.Connections; - -namespace Cassandra.DataStax.Cloud -{ - internal class CloudSniOptionsProvider : ISniOptionsProvider, IEquatable - { - private readonly SecureConnectionBundle _bundle; - private readonly SSLOptions _sslOptions; - private readonly SocketOptions _socketOptions; - private readonly ICloudMetadataService _cloudMetadataService; - private readonly SingleThreadedResolver _cloudMetadataResolver; - - private volatile CloudMetadataResult _cloudMetadataResult; - private volatile SniOptions _sniOptions; - - public CloudSniOptionsProvider( - SocketOptions socketOptions, - SSLOptions sslOptions, - SecureConnectionBundle bundle, - ICloudMetadataService cloudMetadataService) - { - _socketOptions = socketOptions ?? throw new ArgumentNullException(nameof(socketOptions)); - _sslOptions = sslOptions ?? throw new ArgumentNullException(nameof(sslOptions)); - _bundle = bundle ?? throw new ArgumentNullException(nameof(bundle)); - _cloudMetadataService = cloudMetadataService ?? throw new ArgumentNullException(nameof(cloudMetadataService)); - - _cloudMetadataResolver = new SingleThreadedResolver(); - } - - private async Task UnsafeRefreshSniOptions() - { - var cloudMetadata = await _cloudMetadataService.GetClusterMetadataAsync( - $"https://{_bundle.Config.Host}:{_bundle.Config.Port}/metadata", - _socketOptions, - _sslOptions).ConfigureAwait(false); - - var proxyAddress = cloudMetadata.ContactInfo.SniProxyAddress; - var separatorIndex = proxyAddress.IndexOf(':'); - - if (separatorIndex == -1) - { - throw new InvalidOperationException($"The SNI endpoint address should contain ip/name and port. Address received: {proxyAddress}"); - } - - if (cloudMetadata.ContactInfo.ContactPoints == null || cloudMetadata.ContactInfo.ContactPoints.Count == 0) - { - throw new InvalidOperationException("The metadata service returned 0 contact points."); - } - - var ipOrName = proxyAddress.Substring(0, separatorIndex); - var port = int.Parse(proxyAddress.Substring(separatorIndex + 1)); - var isIp = IPAddress.TryParse(ipOrName, out var addr); - var sniOptions = new SniOptions(addr, port, isIp ? null : ipOrName, new SortedSet(cloudMetadata.ContactInfo.ContactPoints)); - - _sniOptions = sniOptions; - _cloudMetadataResult = cloudMetadata; - } - - public async Task InitializeAsync() - { - await _cloudMetadataResolver.RefreshIfNeededAsync(() => true, UnsafeRefreshSniOptions).ConfigureAwait(false); - return _cloudMetadataResult; - } - - public async Task GetAsync(bool refresh) - { - if (refresh || !IsInitialized()) - { - await _cloudMetadataResolver.RefreshIfNeededAsync(() => true, UnsafeRefreshSniOptions).ConfigureAwait(false); - } - - return _sniOptions; - } - - public bool IsInitialized() - { - return _sniOptions != null && _cloudMetadataResult != null; - } - - public string GetStaticIdentifier() - { - return $"{_bundle.Config.Host}:{_bundle.Config.Port}"; - } - - public override bool Equals(object obj) - { - return Equals(obj as CloudSniOptionsProvider); - } - - public bool Equals(CloudSniOptionsProvider other) - { - return other != null && - EqualityComparer.Default.Equals(_bundle, other._bundle); - } - - public override int GetHashCode() - { - return -631637154 + EqualityComparer.Default.GetHashCode(_bundle); - } - - public static bool operator ==(CloudSniOptionsProvider left, CloudSniOptionsProvider right) - { - return EqualityComparer.Default.Equals(left, right); - } - - public static bool operator !=(CloudSniOptionsProvider left, CloudSniOptionsProvider right) - { - return !(left == right); - } - } -} \ No newline at end of file diff --git a/src/Cassandra/DataStax/Cloud/ContactInfo.cs b/src/Cassandra/DataStax/Cloud/ContactInfo.cs deleted file mode 100644 index dd1d8e422..000000000 --- a/src/Cassandra/DataStax/Cloud/ContactInfo.cs +++ /dev/null @@ -1,39 +0,0 @@ -// -// Copyright (C) DataStax Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace Cassandra.DataStax.Cloud -{ - [JsonObject] - internal class ContactInfo - { - [JsonProperty("type")] - public string Type { get; set; } - - [JsonProperty("local_dc")] - public string LocalDc { get; set; } - - [JsonRequired] - [JsonProperty("contact_points")] - public List ContactPoints { get; set; } - - [JsonRequired] - [JsonProperty("sni_proxy_address")] - public string SniProxyAddress { get; set; } - } -} \ No newline at end of file diff --git a/src/Cassandra/DataStax/Cloud/CustomCACertificateValidator.cs b/src/Cassandra/DataStax/Cloud/CustomCACertificateValidator.cs deleted file mode 100644 index 216196188..000000000 --- a/src/Cassandra/DataStax/Cloud/CustomCACertificateValidator.cs +++ /dev/null @@ -1,251 +0,0 @@ -// -// Copyright (C) DataStax Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net.Security; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; - -namespace Cassandra.DataStax.Cloud -{ - /// - /// Validates a certificate chain using a specific root CA. Also validates that the server certificate has a specific CN. - /// - internal class CustomCaCertificateValidator : ICertificateValidator - { - private const string SubjectAlternateNameOid = "2.5.29.17"; // Oid for the SAN extension - - private static readonly Logger Logger = new Logger(typeof(CustomCaCertificateValidator)); - - private static readonly string SanPlatformId; - private static readonly string SanSeparator; - - private readonly X509Certificate2 _trustedRootCertificateAuthority; - private readonly string _hostname; - - static CustomCaCertificateValidator() - { - // use a well known example SAN extension to extract the platform identifier (since it is affected by platform and locale/culture) - - const string wellKnownSanExtension = @"MBuCC2V4YW1wbGUuY29tggxmYWtlLXN1YmplY3Q="; - const string firstWellKnownDomainName = "example.com"; - const string secondWellKnownDomainName = "fake-subject"; - - var formattedExtString = new X509Extension(SubjectAlternateNameOid, Convert.FromBase64String(wellKnownSanExtension), true).Format(false); - - // Windows identifier is affected by locale/culture - // Example well known SAN extension has the following format: - // Windows: "DNS Name=example.com, DNS Name=fake-subject" - // Linux: "DNS:example.com, DNS:fake-subject" - // - // Parse it as the following: - // - // e.g. for Windows with EN culture: - // platform-id -> "DNS Name=" - // first-domain-name -> "example.com" - // second-domain-name -> "fake-subject" - // separator -> ", " - - // "example.com" - var firstDomainNameIndex = formattedExtString.IndexOf(firstWellKnownDomainName, StringComparison.Ordinal); - - // "fake-subject" - var secondDomainNameIndex = formattedExtString.IndexOf(secondWellKnownDomainName, StringComparison.Ordinal); - - // "DNS Name=" - SanPlatformId = formattedExtString.Substring(0, firstDomainNameIndex); - - // ", " - var separatorIndex = firstDomainNameIndex + firstWellKnownDomainName.Length; - var lengthUntilSeparator = firstDomainNameIndex + firstWellKnownDomainName.Length; - var separatorLength = secondDomainNameIndex - SanPlatformId.Length - lengthUntilSeparator; - SanSeparator = formattedExtString.Substring(separatorIndex, separatorLength); - } - - public CustomCaCertificateValidator(X509Certificate2 trustedRootCertificateAuthority, string hostname) - { - _trustedRootCertificateAuthority = - trustedRootCertificateAuthority ?? throw new ArgumentNullException(nameof(trustedRootCertificateAuthority)); - _hostname = hostname ?? throw new ArgumentNullException(nameof(hostname)); - } - - public bool Validate(X509Certificate cert, X509Chain chain, SslPolicyErrors errors) - { - if (errors == SslPolicyErrors.None) - { - return true; - } - - X509Certificate2 cert2 = null; - var valid = true; - - if ((errors & SslPolicyErrors.RemoteCertificateNotAvailable) != 0) - { - valid = false; - CustomCaCertificateValidator.Logger.Error("SSL validation failed due to SslPolicyErrors.RemoteCertificateNotAvailable."); - } - - // validate server certificate's CN against the provided hostname - if (valid && (errors & SslPolicyErrors.RemoteCertificateNameMismatch) != 0) - { - GetOrCreateCert2(ref cert2, cert); - var cn = cert2.GetNameInfo(X509NameType.SimpleName, false); - var subjectAlternativeNames = GetSubjectAlternativeNames(cert2).ToList(); - var names = new List { cn }.Concat(subjectAlternativeNames); - var validName = false; - - foreach (var name in names) - { - validName = ValidateName(name); - if (validName) - { - break; - } - } - - if (!validName) - { - CustomCaCertificateValidator.Logger.Error( - "Failed to validate the server certificate's CN. Expected {0} but found CN={1} and SANs={2}.", - _hostname, - cn ?? "null", string.Join(",", subjectAlternativeNames)); - } - - valid = validName; - } - if (valid && (errors & SslPolicyErrors.RemoteCertificateChainErrors) != 0) - { - var oldChain = chain; - chain = new X509Chain(); - chain.ChainPolicy.RevocationFlag = oldChain.ChainPolicy.RevocationFlag; - chain.ChainPolicy.VerificationFlags = oldChain.ChainPolicy.VerificationFlags; - chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; - if (oldChain.ChainElements.Count > 0) - { - var chainElements = new X509ChainElement[oldChain.ChainElements.Count]; - oldChain.ChainElements.CopyTo(chainElements, 0); - chain.ChainPolicy.ExtraStore.AddRange(chainElements - .Where(elem => elem.Certificate != null) - .Select(elem => elem.Certificate) - .ToArray()); - } - chain.ChainPolicy.ExtraStore.AddRange(oldChain.ChainPolicy.ExtraStore); - - // clone CA object because on Mono it gets reset for some reason after using it to build a new chain - var clonedCa = new X509Certificate2(_trustedRootCertificateAuthority); - chain.ChainPolicy.ExtraStore.Add(clonedCa); - - GetOrCreateCert2(ref cert2, cert); - if (!chain.Build(cert2)) - { - // verify if the chain is correct - foreach (var status in chain.ChainStatus) - { - if (status.Status == X509ChainStatusFlags.NoError || status.Status == X509ChainStatusFlags.UntrustedRoot) - { - //Acceptable Status - } - else - { - CustomCaCertificateValidator.Logger.Error( - "Certificate chain validation failed. Found chain status {0} ({1}).", status.Status, status.StatusInformation); - valid = false; - break; - } - } - - if (valid) - { - //Now that we have tested to see if the cert builds properly, we now will check if the thumbprint of the root ca matches our trusted one - var rootCertThumbprint = chain.ChainElements[chain.ChainElements.Count - 1].Certificate.Thumbprint; - if (rootCertThumbprint != _trustedRootCertificateAuthority.Thumbprint) - { - CustomCaCertificateValidator.Logger.Error( - "Root certificate thumbprint mismatch. Expected {0} but found {1}.", _trustedRootCertificateAuthority.Thumbprint, rootCertThumbprint); - valid = false; - } - } - - } - DisposeCert2(clonedCa); - } - - DisposeCert2(cert2); - return valid; - } - - private bool ValidateName(string name) - { - if (name == null || _hostname == null || !name.StartsWith("*.")) - { - if (name?.ToLowerInvariant() == _hostname?.ToLowerInvariant()) - { - return true; - } - } - else if (name.StartsWith("*.")) - { - name = name.Remove(0, 1); - if (_hostname.EndsWith(name, StringComparison.InvariantCultureIgnoreCase)) - { - return true; - } - } - - return false; - } - - /// - /// Check the static constructor inline comments for an explanation about this - /// - private IEnumerable GetSubjectAlternativeNames(X509Certificate2 cert) - { - var sanStrings = cert.Extensions - .Cast() - .Where(ext => ext.Oid.Value == SubjectAlternateNameOid) - .Select(ext => new AsnEncodedData(ext.Oid, ext.RawData).Format(false)).ToList(); - - var splitSanStrings = sanStrings.SelectMany(s => s.Split(new[] { SanSeparator }, StringSplitOptions.RemoveEmptyEntries)); - - // remove the platform identifier (i.e. "DNS Name=") from the strings to get the domain names - return splitSanStrings - .Where(s => s.StartsWith(SanPlatformId) && s.Length > SanPlatformId.Length) - .Select(s => s.Substring(SanPlatformId.Length)); - - } - - private void GetOrCreateCert2(ref X509Certificate2 cert2, X509Certificate cert) - { - if (cert2 != null) - { - return; - } - - cert2 = new X509Certificate2(cert); - } - - private void DisposeCert2(X509Certificate2 cert2) - { -#if NET452 - cert2?.Reset(); -#else - cert2?.Dispose(); -#endif - } - } -} \ No newline at end of file diff --git a/src/Cassandra/DataStax/Cloud/ICertificateValidator.cs b/src/Cassandra/DataStax/Cloud/ICertificateValidator.cs deleted file mode 100644 index ef1cddf5c..000000000 --- a/src/Cassandra/DataStax/Cloud/ICertificateValidator.cs +++ /dev/null @@ -1,29 +0,0 @@ -// -// Copyright (C) DataStax Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System.Net.Security; -using System.Security.Cryptography.X509Certificates; - -namespace Cassandra.DataStax.Cloud -{ - /// - /// Validates a certificate (and its chain). Used in server certificate callbacks with SslStream, HttpClient, etc. - /// - internal interface ICertificateValidator - { - bool Validate(X509Certificate cert, X509Chain chain, SslPolicyErrors errors); - } -} \ No newline at end of file diff --git a/src/Cassandra/DataStax/Cloud/ICloudConfigurationParser.cs b/src/Cassandra/DataStax/Cloud/ICloudConfigurationParser.cs deleted file mode 100644 index b8bcbdfe4..000000000 --- a/src/Cassandra/DataStax/Cloud/ICloudConfigurationParser.cs +++ /dev/null @@ -1,33 +0,0 @@ -// -// Copyright (C) DataStax Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System.IO; - -namespace Cassandra.DataStax.Cloud -{ - /// - /// Parses the configuration data from the secure connection bundle. - /// - internal interface ICloudConfigurationParser - { - /// - /// Parses config.json file from the secure connection bundle. - /// - /// Stream that contains the config.json data in text format - /// Configuration object mapped from config.json - CloudConfiguration ParseConfig(Stream stream); - } -} \ No newline at end of file diff --git a/src/Cassandra/DataStax/Cloud/ICloudMetadataService.cs b/src/Cassandra/DataStax/Cloud/ICloudMetadataService.cs deleted file mode 100644 index b036a5c0c..000000000 --- a/src/Cassandra/DataStax/Cloud/ICloudMetadataService.cs +++ /dev/null @@ -1,34 +0,0 @@ -// -// Copyright (C) DataStax Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System.Threading.Tasks; - -namespace Cassandra.DataStax.Cloud -{ - /// - /// Client to interact with the Cloud Metadata Service. - /// - internal interface ICloudMetadataService - { - /// - /// Retrieve the cloud cluster's metadata from the cloud metadata service. - /// - /// Metadata endpoint - /// Socket options to use for the HTTPS request (timeout). - /// SSL Options to use for the HTTPS request. - Task GetClusterMetadataAsync(string url, SocketOptions socketOptions, SSLOptions sslOptions); - } -} \ No newline at end of file diff --git a/src/Cassandra/DataStax/Cloud/ISecureConnectionBundleParser.cs b/src/Cassandra/DataStax/Cloud/ISecureConnectionBundleParser.cs deleted file mode 100644 index c311654f6..000000000 --- a/src/Cassandra/DataStax/Cloud/ISecureConnectionBundleParser.cs +++ /dev/null @@ -1,31 +0,0 @@ -// -// Copyright (C) DataStax Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -namespace Cassandra.DataStax.Cloud -{ - /// - /// Loads and parses the secure connection bundle. - /// - internal interface ISecureConnectionBundleParser - { - /// - /// Loads and parses the secure connection bundle (creds.zip) - /// - /// Path of the secure connection bundle file. - /// The configuration object built from the provided bundle. - SecureConnectionBundle ParseBundle(string path); - } -} \ No newline at end of file diff --git a/src/Cassandra/DataStax/Cloud/SecureConnectionBundle.cs b/src/Cassandra/DataStax/Cloud/SecureConnectionBundle.cs deleted file mode 100644 index 081df43e8..000000000 --- a/src/Cassandra/DataStax/Cloud/SecureConnectionBundle.cs +++ /dev/null @@ -1,70 +0,0 @@ -// -// Copyright (C) DataStax Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using System.Collections.Generic; -using System.Security.Cryptography.X509Certificates; - -namespace Cassandra.DataStax.Cloud -{ - internal class SecureConnectionBundle : IEquatable - { - public SecureConnectionBundle(X509Certificate2 caCert, X509Certificate2 clientCert, CloudConfiguration config) - { - CaCert = caCert; - ClientCert = clientCert; - Config = config; - } - - public X509Certificate2 CaCert { get; } - - public X509Certificate2 ClientCert { get; } - - public CloudConfiguration Config { get; } - - public override bool Equals(object obj) - { - return Equals(obj as SecureConnectionBundle); - } - - public bool Equals(SecureConnectionBundle other) - { - return other != null && - EqualityComparer.Default.Equals(CaCert, other.CaCert) && - EqualityComparer.Default.Equals(ClientCert, other.ClientCert) && - EqualityComparer.Default.Equals(Config, other.Config); - } - - public override int GetHashCode() - { - int hashCode = 899271478; - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(CaCert); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(ClientCert); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(Config); - return hashCode; - } - - public static bool operator ==(SecureConnectionBundle left, SecureConnectionBundle right) - { - return EqualityComparer.Default.Equals(left, right); - } - - public static bool operator !=(SecureConnectionBundle left, SecureConnectionBundle right) - { - return !(left == right); - } - } -} \ No newline at end of file diff --git a/src/Cassandra/DataStax/Cloud/SecureConnectionBundleParser.cs b/src/Cassandra/DataStax/Cloud/SecureConnectionBundleParser.cs deleted file mode 100644 index 156729d73..000000000 --- a/src/Cassandra/DataStax/Cloud/SecureConnectionBundleParser.cs +++ /dev/null @@ -1,119 +0,0 @@ -// -// Copyright (C) DataStax Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System.IO; -using System.IO.Compression; -using System.Linq; -using System.Security.Cryptography.X509Certificates; - -namespace Cassandra.DataStax.Cloud -{ - /// - internal class SecureConnectionBundleParser : ISecureConnectionBundleParser - { - private const string CaName = "ca.crt"; - private const string ConfigName = "config.json"; - private const string CertName = "cert.pfx"; - - private static readonly Logger Logger = new Logger(typeof(SecureConnectionBundleParser)); - - private readonly CloudConfigurationParser _configParser; - - public SecureConnectionBundleParser() - { - _configParser = new CloudConfigurationParser(); - } - - /// - public SecureConnectionBundle ParseBundle(string path) - { - var archive = ZipFile.OpenRead(path); - - var caCert = LoadCertificateAuthority(archive); - var config = ParseConfig(archive); - var clientCert = LoadClientCertificate(archive, config.CertificatePassword); - - return new SecureConnectionBundle(caCert, clientCert, config); - } - - private CloudConfiguration ParseConfig(ZipArchive archive) - { - var config = archive.Entries.FirstOrDefault(entry => entry.Name.Equals(SecureConnectionBundleParser.ConfigName)); - - if (config == null) - { - throw new SecureConnectionBundleException( - $"Could not get {SecureConnectionBundleParser.ConfigName} from the secure connection bundle."); - } - - return _configParser.ParseConfig(config.Open()); - } - - private X509Certificate2 LoadCertificateAuthority(ZipArchive archive) - { - var caEntry = archive.Entries.FirstOrDefault(entry => entry.Name.Equals(SecureConnectionBundleParser.CaName)); - if (caEntry == null) - { - throw new SecureConnectionBundleException( - $"Could not get {SecureConnectionBundleParser.CaName} from the secure connection bundle."); - } - - X509Certificate2 caCert; - using (var memoryStream = new MemoryStream()) - { - using (var caStream = caEntry.Open()) - { - caStream.CopyTo(memoryStream); - } - - caCert = new X509Certificate2(memoryStream.ToArray()); - } - - return caCert; - } - - private X509Certificate2 LoadClientCertificate(ZipArchive archive, string password) - { - var clientCertEntry = archive.Entries.FirstOrDefault(entry => entry.Name.Equals(SecureConnectionBundleParser.CertName)); - if (clientCertEntry == null) - { - SecureConnectionBundleParser.Logger.Warning( - $"Could not get {SecureConnectionBundleParser.CertName} from the secure connection bundle. " + - "The driver will attempt to connect without client authentication."); - return null; - } - - if (password == null) - { - SecureConnectionBundleParser.Logger.Warning( - "The certificate password that was obtained from the bundle is null. " + - "The driver will assume that the certificate is not password protected."); - } - - X509Certificate2 clientCert; - using (var memoryStream = new MemoryStream()) - { - using (var clientCertStream = clientCertEntry.Open()) - { - clientCertStream.CopyTo(memoryStream); - } - - clientCert = new X509Certificate2(memoryStream.ToArray(), password); - } - return clientCert; - } - } -} \ No newline at end of file diff --git a/src/Cassandra/DataStax/Search/DateRange.cs b/src/Cassandra/DataStax/Search/DateRange.cs deleted file mode 100644 index 09600ede1..000000000 --- a/src/Cassandra/DataStax/Search/DateRange.cs +++ /dev/null @@ -1,203 +0,0 @@ -// -// Copyright (C) DataStax Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Text.RegularExpressions; -using Cassandra.Serialization.Search; - -namespace Cassandra.DataStax.Search -{ - /// - /// Represents a range of dates, corresponding to the Apache Solr type - /// DateRangeField. - /// - /// A date range can have one or two bounds, namely lower bound and upper bound, to represent an interval of time. - /// Date range bounds are both inclusive. For example: - /// - ///
    - ///
  • [2015 TO 2016-10] represents from the first day of 2015 to the last day of October 2016
  • - ///
  • 2015 represents during the course of the year 2015.
  • - ///
  • [2017 TO *] represents any date greater or equals to the first day of the year 2017.
  • - ///
- /// - /// Note that this representation of DateRangeField does not support Dates outside of the range - /// supported by DateTimeOffset: from 1/1/0001 12:00:00 AM +00:00 to 12/31/9999 11:59:59 PM +00:00. - /// - ///
- /// DateRange instances are immutable and thread-safe. - public struct DateRange : IEquatable, IComparable - { - private static readonly Regex MultipleBoundariesRegex = new Regex( - @"^\[(.+?) TO (.+)]$", RegexOptions.Compiled); - - private static readonly DateRangeSerializer Serializer = new DateRangeSerializer(); - - /// - /// Gets the lower bound of this range (inclusive). - /// - public DateRangeBound LowerBound { get; private set; } - - /// - /// Gets the upper bound of this range (inclusive). - /// - public DateRangeBound? UpperBound { get; private set; } - - /// - /// Creates a new instance of using a lower bound and an upper bound. - /// Consider using to create instances more easily. - /// - /// - /// A value representing the range lower bound, composed by a - /// DateTimeOffset and a precision. Use for an open lower bound. - /// - /// - /// A value representing the range upper bound, composed by a - /// DateTimeOffset and a precision. Use for an open higher bound. - /// - public DateRange(DateRangeBound lowerBound, DateRangeBound upperBound) : this(lowerBound) - { - UpperBound = upperBound; - } - - /// - /// Creates a new instance of using a lower bound and an upper bound. - /// Consider using to create instances more easily. - /// - /// - /// A value representing the range lower bound, composed by a - /// DateTimeOffset and a precision. Use for an open lower bound. - /// - public DateRange(DateRangeBound lowerBound) : this() - { - LowerBound = lowerBound; - } - - /// - /// Returns the representation from a given string. - /// String representations of dates are always expressed in Coordinated Universal Time(UTC) - /// - /// - public static DateRange Parse(string value) - { - var match = DateRange.MultipleBoundariesRegex.Match(value); - if (!match.Success) - { - return new DateRange(DateRangeBound.Parse(value)); - } - return new DateRange( - DateRangeBound.Parse(match.Groups[1].Value), - DateRangeBound.ParseUpperBound(match.Groups[2].Value)); - } - - /// - public override int GetHashCode() - { - unchecked - { - var hash = 17; - hash = hash * 31 + LowerBound.GetHashCode(); - if (UpperBound != null) - { - hash = hash * 31 + UpperBound.GetHashCode(); - } - return hash; - } - } - - /// - public override bool Equals(object obj) - { - if (!(obj is DateRange)) - { - return false; - } - return Equals((DateRange)obj); - } - - /// - /// Returns true if the value of this DateRange instance and other are the same. - /// - public bool Equals(DateRange other) - { - return LowerBound.Equals(other.LowerBound) && - (UpperBound != null ? UpperBound.Equals(other.UpperBound) : (other.UpperBound == null)); - } - - /// - /// Compares the DateRange based to the bytes representation. - /// - public int CompareTo(DateRange other) - { - var buffer1 = DateRange.Serializer.Serialize((ushort)ProtocolVersion.MaxSupported, this); - var buffer2 = DateRange.Serializer.Serialize((ushort)ProtocolVersion.MaxSupported, other); - if (buffer1.Length == buffer2.Length) - { - // Use Array IStructuralComparable implementation - return ((IStructuralComparable)buffer1).CompareTo(buffer2, Comparer.Default); - } - var length = Math.Max(buffer1.Length, buffer2.Length); - // Different length comparison should return as soon as we find a difference starting from msb - for (var i = 0; i < length; i++) - { - byte b1 = 0; - byte b2 = 0; - if (buffer1.Length > i) - { - b1 = buffer1[i]; - } - if (buffer2.Length > i) - { - b2 = buffer2[i]; - } - if (b1 != b2) - { - return b1 - b2; - } - } - return 0; - } - - /// - /// Returns the string representation of the instance. - /// - public override string ToString() - { - if (UpperBound == null) - { - return LowerBound.ToString(); - } - return "[" + LowerBound + " TO " + UpperBound + "]"; - } - - /// - /// Compares value equality of 2 DateRange instances. - /// - public static bool operator ==(DateRange a, DateRange b) - { - return a.Equals(b); - } - - /// - /// Compares value inequality of 2 DateRange instances. - /// - public static bool operator !=(DateRange a, DateRange b) - { - return !(a == b); - } - } -} diff --git a/src/Cassandra/DataStax/Search/DateRangeBound.cs b/src/Cassandra/DataStax/Search/DateRangeBound.cs deleted file mode 100644 index b4eac1d64..000000000 --- a/src/Cassandra/DataStax/Search/DateRangeBound.cs +++ /dev/null @@ -1,336 +0,0 @@ -// -// Copyright (C) DataStax Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using System.Text.RegularExpressions; - -namespace Cassandra.DataStax.Search -{ - /// - /// Represents a date range boundary, composed by a Date and a precision. - /// - /// DateRangeBound instances are immutable and thread-safe. - public struct DateRangeBound : IEquatable - { - /// - /// Regex to parse dates in the following format YYYY-MM-DDThh:mm:ss.mssZ. - /// - private static readonly Regex TimestampRegex = new Regex( - // year mandatory 1 to 4 digits - @"^[-+]?(\d{1,4})" + - // two non-capturing groups representing the month and day (1 to 2 digits captured) - @"(?:-(\d{1,2}))?(?:-(\d{1,2}))?" + - // A non-capturing group for the time portion - @"(?:T(\d{1,2}?)?(?::(\d{1,2}))?(?::(\d{1,2})(?:\.(\d{1,3}))?)?)?Z?$", RegexOptions.Compiled); - - private static readonly string[] FormatByPrecision = - { - "{0:0000}", - "{0:0000}-{1:00}", - "{0:0000}-{1:00}-{2:00}", - "{0:0000}-{1:00}-{2:00}T{3:00}", - "{0:0000}-{1:00}-{2:00}T{3:00}:{4:00}", - "{0:0000}-{1:00}-{2:00}T{3:00}:{4:00}:{5:00}", - "{0:0000}-{1:00}-{2:00}T{3:00}:{4:00}:{5:00}.{6:000}Z" - }; - - /// - /// The unbounded instance. Unbounded bounds are syntactically - /// represented by a * (star) sign. - /// - public static readonly DateRangeBound Unbounded = new DateRangeBound(true); - - private const string UnboundedString = "*"; - - private readonly DateTimeOffset _timestamp; - private readonly DateRangePrecision _precision; - - /// - /// The timestamp portion of the boundary. - /// - public DateTimeOffset Timestamp - { - get { return _timestamp; } - } - - /// - /// The precision portion of the boundary. - /// - public DateRangePrecision Precision - { - get { return _precision; } - } - - /// - /// Creates a new instance of . - /// - public DateRangeBound(DateTimeOffset timestamp, DateRangePrecision precision) : - this(precision, timestamp.ToUniversalTime()) - { - } - - /// - /// Creates a new instance of using a UTC timestamp - /// - /// - /// - private DateRangeBound(DateRangePrecision precision, DateTimeOffset utcTimestamp) - { - if (precision < DateRangePrecision.Year || precision > DateRangePrecision.Millisecond) - { - throw new ArgumentOutOfRangeException("precision"); - } - if (utcTimestamp.Offset != TimeSpan.Zero) - { - throw new ArgumentException("Timestamp should be a UTC time", "utcTimestamp"); - } - _timestamp = utcTimestamp; - _precision = precision; - } - - /// - /// Private constructor only intended for creating the unbounded instance - /// - // ReSharper disable once UnusedParameter.Local - private DateRangeBound(bool asUnbounded) - { - // Workaround: we can not declare a parameter-less constructor on a struct - _timestamp = DateTimeOffset.MinValue; - _precision = (DateRangePrecision)byte.MaxValue; - } - - /// - /// Returns true if the value of this instance and other are the same. - /// - public bool Equals(DateRangeBound other) - { - return other.Precision == Precision && other.Timestamp == Timestamp; - } - - /// - public override bool Equals(object obj) - { - if (!(obj is DateRangeBound)) - { - return false; - } - return Equals((DateRangeBound)obj); - } - - /// - public override int GetHashCode() - { - unchecked - { - var hash = 17; - hash = hash * 31 + Timestamp.GetHashCode(); - hash = hash * 31 + Precision.GetHashCode(); - return hash; - } - } - - /// - /// Returns the string representation of the instance. - /// - public override string ToString() - { - if ((byte)_precision == byte.MaxValue) - { - return "*"; - } - return string.Format(DateRangeBound.FormatByPrecision[(int)Precision], - Timestamp.Year, Timestamp.Month, Timestamp.Day, - Timestamp.Hour, Timestamp.Minute, Timestamp.Second, Timestamp.Millisecond); - - } - - /// - /// Returns the representation of a given string. - /// String representations of dates are always expressed in Coordinated Universal Time(UTC) - /// - /// - public static DateRangeBound Parse(string boundaryString) - { - if (boundaryString == DateRangeBound.UnboundedString) - { - return DateRangeBound.Unbounded; - } - return DateRangeBound.ParseBuilder(boundaryString).Build(); - } - - internal static DateRangeBound ParseUpperBound(string boundaryString) - { - if (boundaryString == DateRangeBound.UnboundedString) - { - return DateRangeBound.Unbounded; - } - var builder = DateRangeBound.ParseBuilder(boundaryString); - return builder.BuildUpperBound(); - } - - private static Builder ParseBuilder(string boundaryString) - { - var match = DateRangeBound.TimestampRegex.Match(boundaryString); - if (!match.Success) - { - throw new FormatException("String provided is not a valid timestamp " + boundaryString); - } - if (match.Groups[7].Success && !match.Groups[5].Success) - { - // Due to a limitation in the regex, its possible to match dates like 2015T03:02.001, - // without the seconds portion but with the milliseconds specified. - throw new FormatException("String representation of the date contains the milliseconds " + - "portion but not the seconds: " + boundaryString); - } - if (boundaryString[0] == '-') - { - throw new ArgumentOutOfRangeException("boundaryString", - "Dates outside the DateTimeOffset range are not supported"); - } - var builder = new Builder(); - for (var i = 1; i < match.Groups.Count; i++) - { - builder.Set(i - 1, match.Groups[i].Value, boundaryString); - } - return builder; - } - - /// - /// Compares value equality of 2 DateRangeBound instances. - /// - public static bool operator ==(DateRangeBound a, DateRangeBound b) - { - return a.Equals(b); - } - - /// - /// Compares value inequality of 2 DateRangeBound instances. - /// - public static bool operator !=(DateRangeBound a, DateRangeBound b) - { - return !(a == b); - } - - private class Builder - { - private int _index; - private readonly int[] _values = new int[7]; - - public void Set(int index, string value, string stringDate) - { - if (string.IsNullOrEmpty(value)) - { - return; - } - if (index > 6) - { - throw new IndexOutOfRangeException(); - } - if (index > _index) - { - _index = index; - } - var numValue = int.Parse(value); - switch ((DateRangePrecision)index) - { - case DateRangePrecision.Month: - if (numValue < 1 || numValue > 12) - { - throw new ArgumentOutOfRangeException( - "Month portion is not valid for date: " + stringDate); - } - break; - case DateRangePrecision.Day: - if (numValue < 1 || numValue > 31) - { - throw new ArgumentOutOfRangeException( - "Day portion is not valid for date: " + stringDate); - } - break; - case DateRangePrecision.Hour: - if (numValue > 23) - { - throw new ArgumentOutOfRangeException( - "Hour portion is not valid for date: " + stringDate); - } - break; - case DateRangePrecision.Minute: - case DateRangePrecision.Second: - if (numValue > 59) - { - throw new ArgumentOutOfRangeException( - "Minute/second portion is not valid for date: " + stringDate); - } - break; - case DateRangePrecision.Millisecond: - if (numValue > 999) - { - throw new ArgumentOutOfRangeException( - "Millisecond portion is not valid for date: " + stringDate); - } - break; - } - _values[index] = numValue; - } - - private void Set(DateRangePrecision precision, int value) - { - _values[(int)precision] = value; - } - - public DateRangeBound Build() - { - var timestamp = new DateTimeOffset( - // year, month, day - _values[0], Math.Max(_values[1], 1), Math.Max(_values[2], 1), - // hour, minutes, second, millisecond - _values[3], _values[4], _values[5], _values[6], - TimeSpan.Zero); - return new DateRangeBound((DateRangePrecision)_index, timestamp); - } - - public DateRangeBound BuildUpperBound() - { - var precision = (DateRangePrecision)_index; - if (precision == DateRangePrecision.Year) - { - Set(DateRangePrecision.Month, 12); - } - if (precision <= DateRangePrecision.Month) - { - Set(DateRangePrecision.Day, DateTime.DaysInMonth(_values[0], Math.Max(_values[1], 1))); - } - if (precision <= DateRangePrecision.Day) - { - Set(DateRangePrecision.Hour, 23); - } - if (precision <= DateRangePrecision.Hour) - { - Set(DateRangePrecision.Minute, 59); - } - if (precision <= DateRangePrecision.Minute) - { - Set(DateRangePrecision.Second, 59); - } - if (precision <= DateRangePrecision.Second) - { - Set(DateRangePrecision.Millisecond, 999); - } - return Build(); - } - } - } -} diff --git a/src/Cassandra/DataStax/Search/DateRangePrecision.cs b/src/Cassandra/DataStax/Search/DateRangePrecision.cs deleted file mode 100644 index 6be80f8c7..000000000 --- a/src/Cassandra/DataStax/Search/DateRangePrecision.cs +++ /dev/null @@ -1,59 +0,0 @@ -// -// Copyright (C) DataStax Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -namespace Cassandra.DataStax.Search -{ - /// - /// Defines the possible values of date range precision. - /// - public enum DateRangePrecision : byte - { - /// - /// Year precision. Any timestamp precision beyond the year portion will be ignored. - /// - Year = 0, - - /// - /// Year precision. Any timestamp precision beyond the years portion will be ignored. - /// - Month = 1, - - /// - /// Day precision. Any timestamp precision beyond the days portion will be ignored. - /// - Day = 2, - - /// - /// Hour precision. Any timestamp precision beyond the hours portion will be ignored. - /// - Hour = 3, - - /// - /// Minute precision. Any timestamp precision beyond the minutes portion will be ignored. - /// - Minute = 4, - - /// - /// Second precision. Any timestamp precision beyond the seconds portion will be ignored. - /// - Second = 5, - - /// - /// Millisecond precision. - /// - Millisecond = 6 - } -} diff --git a/src/Cassandra/GraphProtocol.cs b/src/Cassandra/GraphProtocol.cs deleted file mode 100644 index fe64b8bca..000000000 --- a/src/Cassandra/GraphProtocol.cs +++ /dev/null @@ -1,39 +0,0 @@ -// -// Copyright (C) DataStax Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -namespace Cassandra -{ - /// - /// Specifies the different graph protocol versions that are supported by the driver - /// - public enum GraphProtocol - { - /// - /// GraphSON v1. - /// - GraphSON1 = 1, - - /// - /// GraphSON v2. - /// - GraphSON2 = 2, - - /// - /// GraphSON v3. - /// - GraphSON3 = 3 - } -} \ No newline at end of file diff --git a/src/Cassandra/GraphProtocolExtensions.cs b/src/Cassandra/GraphProtocolExtensions.cs deleted file mode 100644 index 57fce7183..000000000 --- a/src/Cassandra/GraphProtocolExtensions.cs +++ /dev/null @@ -1,44 +0,0 @@ -// -// Copyright (C) DataStax Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System.Collections.Generic; - -namespace Cassandra -{ - /// - /// Defines extension methods for graph protocol versions - /// - internal static class GraphProtocolExtensions - { - private static readonly IDictionary EnumToNameMap = - new Dictionary - { - { GraphProtocol.GraphSON1, "graphson-1.0" }, - { GraphProtocol.GraphSON2, "graphson-2.0" }, - { GraphProtocol.GraphSON3, "graphson-3.0" }, - }; - - public static string GetInternalRepresentation(this GraphProtocol? version) - { - return version == null ? "null" : version.Value.GetInternalRepresentation(); - } - - public static string GetInternalRepresentation(this GraphProtocol version) - { - return GraphProtocolExtensions.EnumToNameMap[version]; - } - } -} \ No newline at end of file diff --git a/src/Cassandra/SecureConnectionBundleException.cs b/src/Cassandra/SecureConnectionBundleException.cs deleted file mode 100644 index 35022dbc1..000000000 --- a/src/Cassandra/SecureConnectionBundleException.cs +++ /dev/null @@ -1,31 +0,0 @@ -// -// Copyright (C) DataStax Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; - -namespace Cassandra -{ - internal class SecureConnectionBundleException : Exception - { - public SecureConnectionBundleException(string message) : base(message) - { - } - - public SecureConnectionBundleException(string message, Exception innerException) : base(message, innerException) - { - } - } -} \ No newline at end of file diff --git a/src/Cassandra/Serialization/GenericSerializer.cs b/src/Cassandra/Serialization/GenericSerializer.cs index 526cd1cf2..bef28f3f8 100644 --- a/src/Cassandra/Serialization/GenericSerializer.cs +++ b/src/Cassandra/Serialization/GenericSerializer.cs @@ -19,7 +19,6 @@ using System.Linq; using System.Numerics; using System.Reflection; -using Cassandra.Serialization.Search; namespace Cassandra.Serialization { @@ -54,7 +53,6 @@ internal class GenericSerializer : IGenericSerializer private readonly IEnumerable _defaultCustomTypeSerializers = new ITypeSerializer[] { - new DateRangeSerializer(), new DurationSerializer(true), }; diff --git a/src/Cassandra/Serialization/Search/DateRangeSerializer.cs b/src/Cassandra/Serialization/Search/DateRangeSerializer.cs deleted file mode 100644 index 8ead5d183..000000000 --- a/src/Cassandra/Serialization/Search/DateRangeSerializer.cs +++ /dev/null @@ -1,146 +0,0 @@ -// -// Copyright (C) DataStax Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using Cassandra.DataStax.Search; - -namespace Cassandra.Serialization.Search -{ - internal class DateRangeSerializer : TypeSerializer - { - private readonly IColumnInfo _typeInfo = new CustomColumnInfo("org.apache.cassandra.db.marshal.DateRangeType"); - - /// - /// The byte length of the serialized DateRange with a single boundary: byte + long + byte - /// - private const int ByteLengthSingleBoundary = 10; - - /// - /// The byte length of the serialized DateRange with a 2 boundaries: byte + long + byte + long + byte - /// - private const int ByteLengthTwoBoundaries = 19; - - public override ColumnTypeCode CqlType - { - get { return ColumnTypeCode.Custom; } - } - - public override IColumnInfo TypeInfo - { - get { return _typeInfo; } - } - - public override DateRange Deserialize(ushort protocolVersion, byte[] buffer, int offset, int length, IColumnInfo typeInfo) - { - if (length == 0) - { - throw new ArgumentException("DateRange serialized value must have at least 1 byte"); - } - var type = (RangeType)buffer[offset++]; - switch (type) - { - case RangeType.SingleValue: - return new DateRange(ReadDateRangeBound(buffer, offset)); - case RangeType.ClosedRange: - return new DateRange(ReadDateRangeBound(buffer, offset), ReadDateRangeBound(buffer, offset + 9)); - case RangeType.OpenRangeHigh: - return new DateRange(ReadDateRangeBound(buffer, offset), DateRangeBound.Unbounded); - case RangeType.OpenRangeLow: - return new DateRange(DateRangeBound.Unbounded, ReadDateRangeBound(buffer, offset)); - case RangeType.OpenBoth: - return new DateRange(DateRangeBound.Unbounded, DateRangeBound.Unbounded); - case RangeType.OpenSingle: - return new DateRange(DateRangeBound.Unbounded); - } - throw new ArgumentException(string.Format("Range type {0} not supported", type)); - } - - private DateRangeBound ReadDateRangeBound(byte[] buffer, int offset) - { - var millis = EndianBitConverter.ToInt64(false, buffer, offset); - return new DateRangeBound(UnixStart.AddMilliseconds(millis), (DateRangePrecision)buffer[offset + 8]); - } - - public override byte[] Serialize(ushort protocolVersion, DateRange value) - { - // Serializes the value containing: - // [] - byte[] buffer; - if (value.LowerBound == DateRangeBound.Unbounded) - { - if (value.UpperBound == null) - { - return new[] { (byte)RangeType.OpenSingle }; - } - if (value.UpperBound == DateRangeBound.Unbounded) - { - return new[] { (byte)RangeType.OpenBoth }; - } - // byte + long + byte - buffer = new byte[10]; - buffer[0] = (byte)RangeType.OpenRangeLow; - WriteDateRangeBound(buffer, 1, value.UpperBound.Value); - return buffer; - } - if (value.UpperBound == null) - { - buffer = new byte[ByteLengthSingleBoundary]; - buffer[0] = (byte)RangeType.SingleValue; - WriteDateRangeBound(buffer, 1, value.LowerBound); - return buffer; - } - if (value.UpperBound == DateRangeBound.Unbounded) - { - buffer = new byte[ByteLengthSingleBoundary]; - buffer[0] = (byte)RangeType.OpenRangeHigh; - WriteDateRangeBound(buffer, 1, value.LowerBound); - return buffer; - } - var offset = 0; - buffer = new byte[ByteLengthTwoBoundaries]; - buffer[offset++] = (byte)RangeType.ClosedRange; - offset = WriteDateRangeBound(buffer, offset, value.LowerBound); - WriteDateRangeBound(buffer, offset, value.UpperBound.Value); - return buffer; - } - - private static int WriteDateRangeBound(byte[] buffer, int offset, DateRangeBound value) - { - var ticksDiff = value.Timestamp.Ticks - UnixStart.Ticks; - var millisecondsDiff = ticksDiff / (decimal)TimeSpan.TicksPerMillisecond; - var millis = Convert.ToInt64(Math.Floor(millisecondsDiff)); - EndianBitConverter.SetBytes(false, buffer, offset, millis); - buffer[offset + 8] = (byte)value.Precision; - return offset + 9; - } - - private enum RangeType : byte - { - // single value as in "2001-01-01" - SingleValue = 0, - // closed range as in "[2001-01-01 TO 2001-01-31]" - ClosedRange = 1, - // open range high as in "[2001-01-01 TO *]" - OpenRangeHigh = 2, - // - 0x03 - open range low as in "[* TO 2001-01-01]" - OpenRangeLow = 3, - // - 0x04 - both ranges open as in "[* TO *]" - OpenBoth = 4, - // - 0x05 - single open range as in "[*]" - OpenSingle = 5 - } - } -}