mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 17:59:46 +02:00
GT-2658 - more finishing touches
docs, exception handling, direct config file parsing instead of system property.
This commit is contained in:
parent
0ae460952e
commit
58f93ea0e7
11 changed files with 95 additions and 47 deletions
|
@ -0,0 +1 @@
|
|||
This directory is for additional JAVA libraries (*.jar) that you want to make available to GhidraServer.
|
|
@ -0,0 +1,4 @@
|
|||
This directory is for additional native system libraries that you want to make available to GhidraServer.
|
||||
|
||||
Place the system library in either a win64, linux64, or osx64 subdirectory, depending on the type of the
|
||||
system library.
|
|
@ -140,7 +140,8 @@ public class GhidraServer extends UnicastRemoteObject implements GhidraServerHan
|
|||
GhidraServer(File rootDir, AuthMode authMode, String loginDomain,
|
||||
boolean allowUserToSpecifyName, boolean altSSHLoginAllowed,
|
||||
int defaultPasswordExpirationDays, boolean allowAnonymousAccess,
|
||||
boolean autoProvisionAuthedUsers) throws IOException, CertificateException {
|
||||
boolean autoProvisionAuthedUsers, File jaasConfigFile)
|
||||
throws IOException, CertificateException {
|
||||
|
||||
super(ServerPortFactory.getRMISSLPort(), clientSocketFactory, serverSocketFactory);
|
||||
|
||||
|
@ -179,7 +180,8 @@ public class GhidraServer extends UnicastRemoteObject implements GhidraServerHan
|
|||
}
|
||||
break;
|
||||
case JAAS_LOGIN:
|
||||
authModule = new JAASAuthenticationModule("auth", allowUserToSpecifyName);
|
||||
authModule =
|
||||
new JAASAuthenticationModule("auth", allowUserToSpecifyName, jaasConfigFile);
|
||||
break;
|
||||
case KRB5_AD_LOGIN:
|
||||
if (loginDomain == null || loginDomain.isBlank()) {
|
||||
|
@ -329,9 +331,15 @@ public class GhidraServer extends UnicastRemoteObject implements GhidraServerHan
|
|||
}
|
||||
}
|
||||
else {
|
||||
throw new FailedLoginException(
|
||||
RepositoryManager.log(null, null,
|
||||
"User successfully authenticated, but does not exist in Ghidra user list: " +
|
||||
username);
|
||||
username,
|
||||
null);
|
||||
// Throw LoginException instead of FailedLoginException to prevent
|
||||
// the user from being asked to retry the login, which might
|
||||
// lead them to try older/different passwords and get their system
|
||||
// account locked.
|
||||
throw new LoginException("Unknown user: " + username);
|
||||
}
|
||||
}
|
||||
RepositoryManager.log(null, null, "User '" + username + "' authenticated",
|
||||
|
@ -341,7 +349,11 @@ public class GhidraServer extends UnicastRemoteObject implements GhidraServerHan
|
|||
catch (LoginException e) {
|
||||
RepositoryManager.log(null, null, "Login failed (" + e.getMessage() + ")",
|
||||
username);
|
||||
throw e;
|
||||
// Create new exceptions so we don't leak config info to the client.
|
||||
if (e instanceof FailedLoginException) {
|
||||
throw new FailedLoginException("User authentication failed");
|
||||
}
|
||||
throw new LoginException("User login system failure");
|
||||
}
|
||||
if (authModule instanceof PasswordFileAuthenticationModule) {
|
||||
supportPasswordChange = true;
|
||||
|
@ -671,21 +683,19 @@ public class GhidraServer extends UnicastRemoteObject implements GhidraServerHan
|
|||
serverRoot = new File(installRoot.getFile(false), rootPath);
|
||||
}
|
||||
|
||||
File jaasConfigFile = null;
|
||||
if (authMode == JAAS_LOGIN) {
|
||||
if (jaasConfigFileStr == null) {
|
||||
displayUsage("JAAS config file argument (-jaas <configfile>) not specified");
|
||||
System.exit(-1);
|
||||
}
|
||||
File jaasConfigFile = getServerCfgFile(jaasConfigFileStr);
|
||||
if (!jaasConfigFile.exists() || !jaasConfigFile.isFile()) {
|
||||
jaasConfigFile = getServerCfgFile(jaasConfigFileStr);
|
||||
if (!jaasConfigFile.isFile()) {
|
||||
displayUsage(
|
||||
"JAAS config file (-jaas <configfile>) does not exist or is not file: " +
|
||||
jaasConfigFile.getAbsolutePath());
|
||||
System.exit(-1);
|
||||
}
|
||||
// NOTE: there is a leading '=' char to force this path to be the one-and-only config file
|
||||
System.setProperty("java.security.auth.login.config",
|
||||
"=" + jaasConfigFile.getAbsolutePath());
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -788,7 +798,7 @@ public class GhidraServer extends UnicastRemoteObject implements GhidraServerHan
|
|||
|
||||
GhidraServer svr = new GhidraServer(serverRoot, authMode, loginDomain,
|
||||
nameCallbackAllowed, altSSHLoginAllowed, defaultPasswordExpiration,
|
||||
allowAnonymousAccess, autoProvision);
|
||||
allowAnonymousAccess, autoProvision, jaasConfigFile);
|
||||
|
||||
log.info("Registering Ghidra Server...");
|
||||
|
||||
|
|
|
@ -27,17 +27,16 @@ Command line parameters:
|
|||
|
||||
-jaas <config_file> : specifies the path to the JAAS config file (when using -a4), relative
|
||||
to the ghidra/server directory (if not absolute).
|
||||
See jaas/jaas.conf for examples and suggestions.
|
||||
See jaas.conf for examples and suggestions.
|
||||
It is the system administrator's responsibility to craft their own
|
||||
JAAS configuration directive when using the -a4 mode.
|
||||
|
||||
-u : enable users to be prompted for user ID (does not apply to -a2 PKI mode)
|
||||
|
||||
-autoProvision : enable the auto-creation of Ghidra users when the authenticator module
|
||||
(ie. OS or other authentication method specified by JAAS) authenticates
|
||||
a new unknown user.
|
||||
Users deleted in the OS or other source system will need to be
|
||||
deleted manually from the Ghidra system.
|
||||
-autoProvision : enable the auto-creation of new Ghidra Server
|
||||
users when they successfully authenticate to the server (-a1 and -a4 modes only).
|
||||
Users removed from the authentication provider (e.g., Active Directory) will need to be
|
||||
deleted manually from the Ghidra Server using svrAdmin command.
|
||||
|
||||
-anonymous : enables anonymous repository access (see svrREADME.html for details)
|
||||
|
||||
|
|
|
@ -15,7 +15,11 @@
|
|||
*/
|
||||
package ghidra.server.security;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.URIParameter;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.security.auth.Subject;
|
||||
|
@ -42,6 +46,7 @@ public class JAASAuthenticationModule implements AuthenticationModule {
|
|||
|
||||
private boolean allowUserToSpecifyName;
|
||||
private String loginContextName;
|
||||
private File jaasConfigFile;
|
||||
|
||||
/**
|
||||
* Creates a new {@link JAASAuthenticationModule} instance.
|
||||
|
@ -50,18 +55,42 @@ public class JAASAuthenticationModule implements AuthenticationModule {
|
|||
* @param allowUserToSpecifyName flag, if true will include a {@link NameCallback} in the
|
||||
* {@link #getAuthenticationCallbacks()} list, which allows the user to specify a different
|
||||
* name than their {@link GhidraPrincipal}.
|
||||
* @throws IllegalArgumentException if the loginContextName is not present in the JAAS configuration
|
||||
* @param jaasConfigFile JAAS config file
|
||||
* @throws IllegalArgumentException if the loginContextName is not present in the JAAS configuration or
|
||||
* if the JAAS config file does not exist
|
||||
*/
|
||||
public JAASAuthenticationModule(String loginContextName, boolean allowUserToSpecifyName)
|
||||
throws IllegalArgumentException {
|
||||
public JAASAuthenticationModule(String loginContextName, boolean allowUserToSpecifyName,
|
||||
File jaasConfigFile) throws IllegalArgumentException {
|
||||
|
||||
this.loginContextName = loginContextName;
|
||||
this.allowUserToSpecifyName = allowUserToSpecifyName;
|
||||
this.jaasConfigFile = jaasConfigFile;
|
||||
|
||||
Configuration cfg = Configuration.getConfiguration();
|
||||
AppConfigurationEntry[] authEntry = cfg.getAppConfigurationEntry(loginContextName);
|
||||
if (authEntry == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Missing '" + loginContextName + "' entry in JAAS config file");
|
||||
if (jaasConfigFile == null) {
|
||||
throw new IllegalArgumentException("JAAS config file not specified");
|
||||
}
|
||||
if (!jaasConfigFile.exists() || !jaasConfigFile.isFile()) {
|
||||
throw new IllegalArgumentException("JAAS config file does not exist or is not file: " +
|
||||
jaasConfigFile.getAbsolutePath());
|
||||
}
|
||||
// force early check for valid config file
|
||||
getJAASConfig();
|
||||
}
|
||||
|
||||
private Configuration getJAASConfig() {
|
||||
try {
|
||||
URI jaasConfigFileUri = jaasConfigFile.toURI();
|
||||
Configuration cfg =
|
||||
Configuration.getInstance("JavaLoginConfig", new URIParameter(jaasConfigFileUri));
|
||||
AppConfigurationEntry[] authEntry = cfg.getAppConfigurationEntry(loginContextName);
|
||||
if (authEntry == null) {
|
||||
throw new IllegalArgumentException("Missing '" + loginContextName +
|
||||
"' entry in JAAS config file: " + jaasConfigFile);
|
||||
}
|
||||
return cfg;
|
||||
}
|
||||
catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException("JAAS config error", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -70,14 +99,20 @@ public class JAASAuthenticationModule implements AuthenticationModule {
|
|||
throws LoginException {
|
||||
GhidraPrincipal principal = GhidraPrincipal.getGhidraPrincipal(subject);
|
||||
AtomicReference<String> loginName = new AtomicReference<>();
|
||||
LoginContext loginCtx = new LoginContext(loginContextName, loginModuleCallbacks -> {
|
||||
loginName.set(copyCallbackValues(callbacks, loginModuleCallbacks, principal));
|
||||
});
|
||||
|
||||
try {
|
||||
Configuration jaasCfg = getJAASConfig();
|
||||
LoginContext loginCtx =
|
||||
new LoginContext(loginContextName, null, loginModuleCallbacks -> {
|
||||
loginName.set(copyCallbackValues(callbacks, loginModuleCallbacks, principal));
|
||||
}, jaasCfg);
|
||||
|
||||
// this is where the callback is triggered
|
||||
loginCtx.login();
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
throw new LoginException("JAAS configuration error: " + e.getMessage());
|
||||
}
|
||||
catch (LoginException e) {
|
||||
// Convert plain LoginExceptions to FailedLoginExceptions to enable
|
||||
// the client to retry the login if desired.
|
||||
|
|
|
@ -55,7 +55,7 @@ public class GhidraServerAWTTest extends AbstractGenericTest {
|
|||
// directly instantiate to avoid GhidraServer.main which may
|
||||
// invoke System.exit
|
||||
GhidraServer server = new GhidraServer(myTmpDir, GhidraServer.AuthMode.NO_AUTH_LOGIN,
|
||||
null, true, true, -1, true, false);
|
||||
null, true, true, -1, true, false, null);
|
||||
|
||||
// exercise server elements, including a repository and buffer file
|
||||
RepositoryManager mgr = (RepositoryManager) getInstanceField("mgr", server);
|
||||
|
|
|
@ -40,8 +40,8 @@ example_ad_ldap_auth {
|
|||
// JPAM is not included in the Ghidra distro. See http://jpam.sourceforge.net/.
|
||||
//
|
||||
// Additionally:
|
||||
// the libjpam.so native library needs to be copied to your <ghidra>/server/os/[linux|linux64] directory.
|
||||
// the JPAM-x.y.jar java library needs to be copied to your <ghidra>/server/lib directory.
|
||||
// the libjpam.so native library needs to be copied to your Ghidra/Features/GhidraServer/os/linux64 directory.
|
||||
// the JPAM-x.y.jar java library needs to be copied to your Ghidra/Features/GhidraServer/lib directory.
|
||||
|
||||
example_jpam_auth {
|
||||
net.sf.jpam.jaas.JpamLoginModule REQUIRED
|
||||
|
@ -62,7 +62,7 @@ example_external_auth {
|
|||
ghidra.server.security.loginmodule.ExternalProgramLoginModule REQUIRED
|
||||
|
||||
// Path to the external program. An absolute path is preferable.
|
||||
PROGRAM="server/jaas/jaas_external_program.example.sh"
|
||||
PROGRAM="server/jaas_external_program.example.sh"
|
||||
|
||||
// Time to wait for external program to finish before killing it, in milliseconds.
|
||||
TIMEOUT="1000"
|
|
@ -132,17 +132,16 @@ ghidra.repositories.dir=./repositories
|
|||
#
|
||||
# -jaas <config_file> : specifies the path to the JAAS config file (when using -a4), relative
|
||||
# to the ghidra/server directory (if not absolute).
|
||||
# See jaas/jaas.conf for examples and suggestions.
|
||||
# See jaas.conf for examples and suggestions.
|
||||
# It is the system administrator's responsibility to craft their own
|
||||
# JAAS configuration directive when using the -a4 mode.
|
||||
#
|
||||
# -u : enable users to be prompted for user ID (does not apply to -a2 PKI mode)
|
||||
#
|
||||
# -autoProvision : enable the auto-creation of Ghidra users when the authenticator module
|
||||
# (ie. OS or other authentication method specified by JAAS) authenticates
|
||||
# a new unknown user.
|
||||
# Users deleted in the OS or other source system will need to be
|
||||
# deleted manually from the Ghidra system.
|
||||
# -autoProvision : enable the auto-creation of new Ghidra Server
|
||||
# users when they successfully authenticate to the server (-a1 and -a4 modes only).
|
||||
# Users removed from the authentication provider (e.g., Active Directory) will need to be
|
||||
# deleted manually from the Ghidra Server using svrAdmin command.
|
||||
#
|
||||
# -anonymous : enables anonymous repository access (see svrREADME.html for details)
|
||||
#
|
||||
|
|
|
@ -259,7 +259,7 @@ The Ghidra Server has been designed to support many possible user authenticatio
|
|||
<LI><u>JAAS - Java Authentication and Authorization Service (<typewriter>-a4</typewriter>)</u> -
|
||||
user authentication is delegated to the JAAS subsystem. The -jaas <config_file> argument
|
||||
is required to specify the JAAS config file. There is an example config file in the GhidraServer
|
||||
directory called jaas/jaas.conf.
|
||||
directory called jaas.conf.
|
||||
<p>
|
||||
JAAS is architected similar to Linux/Unix PAM, where a named authentication configuration is possibly
|
||||
composed of several different modules. Ghidra's support of JAAS only handles single simple
|
||||
|
@ -280,7 +280,7 @@ The Ghidra Server has been designed to support many possible user authenticatio
|
|||
of successful authentication.
|
||||
<p>
|
||||
There is an example (and non-useful) implementation of an external authenticator in the GhidraServer
|
||||
directory called jaas/jaas_external_program.example.sh.
|
||||
directory called jaas_external_program.example.sh.
|
||||
<p>
|
||||
This login module strives to be compatible with Apache's mod_authnz_external API, and you should
|
||||
be able to use any mod_authnz_external authenticator with Ghidra.
|
||||
|
@ -367,17 +367,17 @@ public key files may be made without restarting the Ghidra Server.
|
|||
<LI><typewriter>-jaas <config_file></typewriter><br>Specifies the path to the JAAS
|
||||
config file (when using -a4), relative to the ghidra/server directory (if not absolute).
|
||||
<p>
|
||||
See jaas/jaas.conf for examples and suggestions. It is the system administrator's
|
||||
See jaas.conf for examples and suggestions. It is the system administrator's
|
||||
responsibility to craft their own JAAS configuration directive when using the -a4 mode.</LI>
|
||||
<br>
|
||||
<LI><typewriter>-u</typewriter><br>Allows the server login user ID to be specified at time of
|
||||
login for <typewriter>-a0</typewriter> authentication mode. Without this option, the users
|
||||
client-side login ID will be assumed.</LI>
|
||||
<br>
|
||||
<LI><typewriter>-autoProvision</typewriter><br>Enable the auto-creation of Ghidra users when
|
||||
the authenticator module (ie. OS or other authentication method specified by JAAS) authenticates
|
||||
a new unknown user. Users deleted in the OS or other source system will need to be deleted
|
||||
manually from the Ghidra system.</LI>
|
||||
<LI><typewriter>-autoProvision</typewriter><br>Enable the auto-creation of new Ghidra Server
|
||||
users when they successfully authenticate to the server (-a1 and -a4 modes only).
|
||||
Users removed from the authentication provider (e.g., Active Directory) will need to be
|
||||
deleted manually from the Ghidra Server using svrAdmin command.</LI>
|
||||
<br>
|
||||
<LI><typewriter>-anonymous</typewriter><br>Enable anonymous access support for Ghidra Server
|
||||
and its repositories. Only those repositories which specifically enable anonymous access will be
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
##VERSION: 2.0
|
||||
##MODULE IP: Copyright Distribution Permitted
|
||||
Common/server/jaas/jaas.conf||GHIDRA||||END|
|
||||
Common/server/jaas/jaas_external_program.example.sh||GHIDRA||||END|
|
||||
Common/server/jaas.conf||GHIDRA||||END|
|
||||
Common/server/jaas_external_program.example.sh||GHIDRA||||END|
|
||||
Common/server/server.conf||GHIDRA||||END|
|
||||
Common/server/svrREADME.html||GHIDRA||||END|
|
||||
Common/support/analyzeHeadlessREADME.html||GHIDRA||||END|
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue