Skip to content

Commit

Permalink
JDBC-417 Add connection property authPlugins for auth plugin selection
Browse files Browse the repository at this point in the history
- Move authentication plugins to separate packages to separate API from implementation
- Add service loader support for auth plugin providers
  • Loading branch information
mrotteveel committed Jun 24, 2018
1 parent 9981dbc commit ac24636
Show file tree
Hide file tree
Showing 42 changed files with 894 additions and 258 deletions.
10 changes: 9 additions & 1 deletion src/documentation/faq.md
Expand Up @@ -506,6 +506,12 @@ setting `AuthServer` does not include the `Legacy_Auth` plugin.
Enable `Legacy_Auth` (in `firebird.conf`) by adding this value to the property
`AuthServer`, for example: `AuthServer = Srp, Legacy_Auth`.

With Jaybird 4 and higher this can also mean that none of the default
authentication plugins or those specified using connection property
`authPlugins`, are listed in the `AuthServer` setting. Either revise the
Firebird configuration, or explicitly configure connection property `authPlugins`
with authentication plugins that are configured in Firebird.

You also need to make sure your user is created with the legacy user manager,
see [Jaybird Wiki - Jaybird and Firebird 3](https://github.com/FirebirdSQL/jaybird/wiki/Jaybird-and-Firebird-3)
for details.
Expand Down Expand Up @@ -661,4 +667,6 @@ you will need to add the module `javax.xml.bind.api` to your module:
<module name="javax.xml.bind.api"/> <!-- Add this -->
</dependencies>
</module>
```
```

Alternatively, use Jaybird for Java 8 (or higher).
101 changes: 87 additions & 14 deletions src/documentation/release_notes.md
Expand Up @@ -338,11 +338,11 @@ value from a connection property. Be aware that a static value response for
database encryption is not very secure as it can easily lead to replay attacks
or unintended key exposure.

Future versions of Jaybird (likely 4, maybe 5) will introduce plugin support for
Future versions of Jaybird (likely 5, maybe 4) will introduce plugin support for
database encryption plugins that require a more complex callback.

The static response value of the encryption callback can be set through the
`dbCryptConfig` connection property. Data sources and `ServiceManager`
`dbCryptConfig` connection property. `DataSource` and `ServiceManager`
implementations have an equivalent property with the same name. This
property can be set as follows:

Expand Down Expand Up @@ -394,35 +394,108 @@ Other warnings and limitations
Authentication plugin improvements
----------------------------------

Jaybird 4 has added support for the new `SrpNNN` (with NNN is 224, 256, 384 and
512) authentication plugins added in Firebird 4 (backported to Firebird 3.0.4).
Jaybird 4 has added support for the new `SrpNNN` (with NNN is 224, 256, 384
and 512) authentication plugins added in Firebird 4 (backported to Firebird
3.0.4).

The original `Srp` plugin used SHA-1, the new Srp-variants use SHA-224, SHA-256,
The original `Srp` plugin uses SHA-1, the new Srp-variants use SHA-224, SHA-256,
SHA-384 and SHA-512 respectively[^srpHash].

[^srpHash]: Internally `SrpNNN` continues to uses SHA-1, only the client-proof
applies the SHA-NNN hash. See also [CORE-5788](http://tracker.firebirdsql.org/browse/CORE-5788)).

Be aware, support for these plugins depends on support of these hash algorithms
in the JVM. For example, SHA-224 is not supported in Oracle Java 7.
in the JVM. For example, SHA-224 is not supported in Oracle Java 7 by default
and maybe require additional JCE libraries.

### Default authentication plugins ###

_TODO_: Remove Legacy_Auth from default?

The default plugins applied by Jaybird are now - in order - `Srp256`, `Srp` and
`Legacy_Auth`.
`Legacy_Auth`. This applies only for the pure Java protocol. The native
implementation will use its own default or the value configured through its
`firebird.conf`.

When connecting to Firebird 3 versions earlier than 3.0.4, or if `Srp256` has
been removed from the `AuthServer` setting in Firebird, this might result in a
slower authentication because more roundtrips to the server are needed because
the attempt to use `Srp256` fails, and authentication then
continues with `Srp`.
been removed from the `AuthServer` setting in Firebird, this might result in
slower authentication because more roundtrips to the server are needed. After
the attempt to use `Srp256` fails, authentication continues with `Srp`.

To avoid this, consider explicitly configuring the authentication plugins to
use, see [Configure authentication plugins] for details.

Firebird 2.5 and earlier are not affected.
Firebird 2.5 and earlier are not affected and will always use legacy
authentication.

### Configure authentication plugins ###

_Still TODO_

Jaybird 4 introduces the connection property `authPlugins` (alias
`auth_plugin_list`) to specify the authentication plugins to try when
connecting. The value of this property is a comma-separated[^authPluginSeparator]
list with the plugin names.

[^authPluginSeparator]: The `authPlugins` values can be separated by comma,
space, tab, or semi-colon. The semi-colon should not be used in a JDBC URL as
there the semi-colon is a separator between connection properties.

Unknown or unsupported plugins will be logged and skipped. When no known plugins
are specified, Jaybird will throw an exception with:

- For pure Java

_Cannot authenticate. No known authentication plugins, requested plugins: \[&lt;plugin-names&gt;] \[SQLState:28000, ISC error code:337248287]_

- For native

_Error occurred during login, please check server firebird.log for details \[SQLState:08006, ISC error code:335545106]_

The `authPlugins` property only affects connecting to Firebird 3 or later. It
will be ignored when connecting to Firebird 2.5 or earlier. The setting will
also be ignored for native connections when using a fbclient library of
version 2.5 or earlier.

Examples:

- JDBC URL to connect using `Srp256`-only:

jdbc:firebirdsql://localhost/employee?authPlugins=Srp256

- JDBC URL to try `Legacy_Auth` before `Srp512` (this order is unsafe!)

jdbc:firebirdsql://localhost/employee?authPlugins=Legacy_Auth,Srp512
The property is also supported by the data sources, service managers and event
manager.

### External authentication plugin support (experimental) ###

If you develop your own Firebird authentication plugin (or use a third-party
authentication plugin), it is possible - for pure Java only - to add your own
authentication plugin by implementing the interfaces

- `org.firebirdsql.gds.ng.wire.auth.AuthenticationPluginSpi`
- `org.firebirdsql.gds.ng.wire.auth.AuthenticationPlugin`

The SPI implementation needs to listed in `META-INF/services/org.firebirdsql.gds.ng.wire.auth.AuthenticationPluginSpi`
in your jar.

This support is experimental and comes with a number of caveats:

- We haven't tested this extensively (except for loading Jaybird's own
plugins internally)
- The authentication plugin (and provider) interfaces should be considered
unstable; they may change with point-releases (although we will try to avoid
that)
- For now it will be necessary for the jar containing the authentication
plugin to be loaded by the same class loader as Jaybird itself

If you implement a custom authentication plugin and run into problems, contact
us on the Firebird-Java mailing list.

If you use a native connection, check the Firebird documentation how to add
third-party authentication plugins to fbclient.

Firebird 4 DECFLOAT support
---------------------------

Expand Down
Expand Up @@ -22,10 +22,12 @@
import org.firebirdsql.gds.ParameterTagMapping;
import org.firebirdsql.gds.ng.AbstractConnection;
import org.firebirdsql.gds.ng.AbstractParameterConverter;
import org.firebirdsql.gds.ng.WireCrypt;
import org.firebirdsql.gds.ng.IAttachProperties;
import org.firebirdsql.gds.ng.WireCrypt;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

/**
* Implementation of {@link org.firebirdsql.gds.ng.ParameterConverter} for JNA.
Expand All @@ -47,10 +49,31 @@ protected void populateAuthenticationProperties(final AbstractConnection connect
pb.addArgument(tagMapping.getPasswordTag(), props.getPassword());
}

Map<String, String> configMap = new HashMap<>();

if (props.getWireCrypt() != WireCrypt.DEFAULT) {
// Need to do this differently when having to add multiple configs
String configString = "WireCrypt = " + props.getWireCrypt();
configMap.put("WireCrypt", props.getWireCrypt().name());
}

String authPlugins = props.getAuthPlugins();
if (authPlugins != null && !authPlugins.isEmpty()) {
configMap.put("AuthClient", authPlugins);
}

if (!configMap.isEmpty()) {
String configString = buildConfigString(configMap);
pb.addArgument(tagMapping.getConfigTag(), configString);
}
}

private String buildConfigString(Map<String, String> configMap) {
StringBuilder builder = new StringBuilder();
for (Map.Entry<String, String> configEntry : configMap.entrySet()) {
builder.append(configEntry.getKey())
.append('=')
.append(configEntry.getValue())
.append('\n');
}
return builder.toString();
}
}
15 changes: 15 additions & 0 deletions src/main/org/firebirdsql/ds/FBAbstractCommonDataSource.java
Expand Up @@ -533,6 +533,21 @@ public void setDbCryptConfig(String dbCryptConfig) {
connectionProperties.setDbCryptConfig(dbCryptConfig);
}
}

@Override
public String getAuthPlugins() {
synchronized (lock) {
return connectionProperties.getAuthPlugins();
}
}

@Override
public void setAuthPlugins(String authPlugins) {
synchronized (lock) {
checkNotStarted();
connectionProperties.setAuthPlugins(authPlugins);
}
}

/**
* Method that allows setting non-standard property in the form "key=value"
Expand Down
12 changes: 11 additions & 1 deletion src/main/org/firebirdsql/ds/FBSimpleDataSource.java
Expand Up @@ -402,7 +402,17 @@ public String getDbCryptConfig() {
public void setDbCryptConfig(String dbCryptConfig) {
mcf.setDbCryptConfig(dbCryptConfig);
}


@Override
public String getAuthPlugins() {
return mcf.getAuthPlugins();
}

@Override
public void setAuthPlugins(String authPlugins) {
mcf.setAuthPlugins(authPlugins);
}

/*
* INTERFACES IMPLEMENTATION
*/
Expand Down

0 comments on commit ac24636

Please sign in to comment.