Merge remote-tracking branch 'origin/GT-2740_ghidra1_svrAdmin' into patch

This commit is contained in:
ghidravore 2019-04-24 16:08:51 -04:00
commit 227be22a1f
6 changed files with 463 additions and 478 deletions

View File

@ -0,0 +1,389 @@
/* ###
* IP: GHIDRA
*
* 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.
*/
package ghidra.server;
import java.io.*;
import java.util.ArrayList;
import java.util.Properties;
import javax.security.auth.x500.X500Principal;
import generic.jar.ResourceFile;
import ghidra.GhidraApplicationLayout;
import ghidra.GhidraLaunchable;
import ghidra.framework.Application;
import ghidra.framework.ApplicationConfiguration;
import ghidra.util.Msg;
import ghidra.util.NamingUtilities;
public class ServerAdmin implements GhidraLaunchable {
private static final String CONFIG_FILE_PROPERTY = "UserAdmin.config";
// property name defined within the sever.conf file which specifies
// server repositories directory
private static final String SERVER_DIR_CONFIG_PROPERTY = "ghidra.repositories.dir";
private static final String INVOCATION_NAME_PROPERTY = "UserAdmin.invocation";
// Immediate commands
private static final String LIST_COMMAND = "-list";
private static final String USERS_COMMAND = "-users";
// Delayed commands
private static final String MIGRATE_COMMAND = "-migrate";
private static final String MIGRATE_ALL_COMMAND = "-migrate-all";
private boolean propertyUsed = false;
/**
* Main method for running the UserAdmin Application.
* The following properties may be set:
* <pre>
* UserAdmin.invocation - identifies the name of the application used when displaying usage text.
* UserAdmin.serverDir - identifies the server directory instead of passing on command line.
* </pre>
* @param args command line arguments
*/
@Override
public void launch(GhidraApplicationLayout layout, String[] args) {
// Perform static initializations if not already initialized
// Some tests invoke main method directly which have already initialized Application
if (!Application.isInitialized()) {
ApplicationConfiguration configuration = new ApplicationConfiguration();
configuration.setInitializeLogging(false);
Application.initializeApplication(layout, configuration);
}
File serverDir = null;
int ix = 0;
if (args.length != 0 && !args[0].startsWith("-")) {
serverDir = new File(args[ix++]);
}
else {
serverDir = getServerDirFromConfig();
}
if (serverDir == null || (args.length - ix) == 0) {
displayUsage("");
System.exit(-1);
return;
}
try {
serverDir = serverDir.getCanonicalFile();
}
catch (IOException e1) {
System.err.println("Failed to resolve server directory: " + serverDir);
System.exit(-1);
}
if (propertyUsed) {
System.out.println("Using server directory: " + serverDir);
}
File userFile = new File(serverDir, UserManager.USER_PASSWORD_FILE);
if (!serverDir.isDirectory() || !userFile.isFile()) {
System.err.println("Invalid Ghidra server directory!");
System.exit(-1);
}
File cmdDir = new File(serverDir, UserAdmin.ADMIN_CMD_DIR);
if (!cmdDir.isDirectory() || !cmdDir.canWrite()) {
System.err.println("Insufficient privilege or server not started!");
System.exit(-1);
}
// Process command line
boolean listRepositories = false;
boolean listUsers = false;
boolean migrationConfirmed = false;
boolean migrationAbort = false;
ArrayList<String> cmdList = new ArrayList<>();
int cmdLen = 1;
for (; ix < args.length; ix += cmdLen) {
boolean queueCmd = true;
if (UserAdmin.ADD_USER_COMMAND.equals(args[ix])) { // add user
cmdLen = 2;
validateSID(args, ix + 1);
}
else if (UserAdmin.REMOVE_USER_COMMAND.equals(args[ix])) { // remove user
cmdLen = 2;
validateSID(args, ix + 1);
}
else if (UserAdmin.RESET_USER_COMMAND.equals(args[ix])) { // reset user
cmdLen = 2;
validateSID(args, ix + 1);
}
else if (UserAdmin.SET_USER_DN_COMMAND.equals(args[ix])) { // set/add user with DN for PKI
cmdLen = 3;
validateSID(args, ix + 1);
validateDN(args, ix + 2);
}
else if (UserAdmin.SET_ADMIN_COMMAND.equals(args[ix])) { // set/add repository admin
cmdLen = 3;
validateSID(args, ix + 1);
validateRepName(args, ix + 2, serverDir);
}
else if (LIST_COMMAND.equals(args[ix])) { // list repositories
cmdLen = 1;
queueCmd = false;
listRepositories = true;
}
else if (USERS_COMMAND.equals(args[ix])) { // list users (also affects listRepositories)
cmdLen = 1;
queueCmd = false;
listUsers = true;
}
else if (MIGRATE_ALL_COMMAND.equals(args[ix])) { // list repositories
cmdLen = 1;
queueCmd = false;
if (!migrationConfirmed && !confirmMigration()) {
migrationAbort = true;
}
migrationConfirmed = true;
if (!migrationAbort) {
RepositoryManager.markAllRepositoriesForIndexMigration(serverDir);
}
}
else if (MIGRATE_COMMAND.equals(args[ix])) { // list repositories
cmdLen = 2;
queueCmd = false;
if (ix == (args.length - 1)) {
System.err.println("Missing " + MIGRATE_COMMAND + " repository name argument");
}
else {
String repositoryName = args[ix + 1];
if (!migrationConfirmed && !confirmMigration()) {
migrationAbort = true;
}
migrationConfirmed = true;
if (!migrationAbort) {
Repository.markRepositoryForIndexMigration(serverDir, repositoryName,
false);
}
}
}
else {
displayUsage("Invalid usage!");
System.exit(-1);
}
if (queueCmd) {
addCommand(cmdList, args, ix, cmdLen);
}
}
try {
UserAdmin.writeCommands(cmdList, cmdDir);
}
catch (IOException e) {
System.err.println("Failed to queue commands: " + e.toString());
System.exit(-1);
}
System.out.println(cmdList.size() + " command(s) queued.");
if (listUsers) {
UserManager.listUsers(serverDir);
}
if (listRepositories) {
RepositoryManager.listRepositories(serverDir, listUsers);
}
System.out.println();
}
/**
* @param serverDir
* @param args
* @param i
*/
private static void addCommand(ArrayList<String> cmdList, String[] args, int argOffset,
int argCnt) {
StringBuffer buf = new StringBuffer();
for (int i = 0; i < argCnt; i++) {
if (i > 0) {
buf.append(' ');
}
buf.append(args[argOffset + i]);
}
cmdList.add(buf.toString());
}
private static boolean confirmMigration() {
System.out.print("\nWARNING! Please confirm the requested migration of one or more\n" +
"Ghidra Server repositories. Once migrated to indexed storage,\n" +
"any attempt to use these server repositories with a Ghidra Server\n" +
"older than version 5.5 will corrupt the data storage.\n" +
"\nWould you like to continue? [y/n]: ");
try {
if ('y' == System.in.read()) {
System.out.println();
return true;
}
}
catch (IOException e) {
e.printStackTrace();
}
System.out.println("\nAll repository data migration(s) has been aborted.");
return false;
}
/**
* Validate properly formatted Distinguished Name
* Example: 'CN=Doe John, OU=X, OU=Y, OU=DoD, O=U.S. Government, C=US'
* @param args
* @param i argument index
*/
private void validateDN(String[] args, int i) {
if (args.length < (i + 1)) {
displayUsage("Invalid usage!");
System.exit(-1);
}
String dn = args[i];
try {
X500Principal x500User = new X500Principal(dn);
args[i] = "\"" + x500User.getName() + "\"";
}
catch (Exception e) {
Msg.error(UserAdmin.class, "Invalid DN: " + dn);
System.exit(-1);
}
}
/**
* Validate username/sid
* @param args
* @param i argument index
*/
private void validateSID(String[] args, int i) {
if (args.length < (i + 1)) {
displayUsage("Invalid usage!");
System.exit(-1);
}
String sid = args[i];
if (!NamingUtilities.isValidName(sid) || sid.indexOf(' ') >= 0) {
Msg.error(UserAdmin.class, "Invalid username/sid: " + sid);
System.exit(-1);
}
}
/**
* Validate username/sid
* @param args
* @param i argument index
*/
private void validateRepName(String[] args, int i, File rootDirFile) {
if (args.length < (i + 1)) {
displayUsage("Invalid usage!");
System.exit(-1);
}
String repName = args[i];
File f = new File(rootDirFile, NamingUtilities.mangle(repName));
if (!f.isDirectory()) {
Msg.error(UserAdmin.class, "Repository not found: " + repName);
System.exit(-1);
}
}
private File getServerDirFromConfig() {
String p = System.getProperty(CONFIG_FILE_PROPERTY);
if (p == null) {
return null;
}
propertyUsed = true;
File configFile = new File(p);
if (!configFile.exists()) {
System.out.println("Config file not found: " + configFile.getAbsolutePath());
}
Properties config = new Properties();
InputStream in = null;
try {
in = new FileInputStream(configFile);
config.load(in);
}
catch (IOException e) {
System.out.println("Failed to read " + configFile.getName() + ": " + e.getMessage());
}
finally {
if (in != null) {
try {
in.close();
}
catch (IOException e) {
// ignore
}
}
}
p = config.getProperty(SERVER_DIR_CONFIG_PROPERTY);
if (p == null) {
return null;
}
File dir = new File(p);
if (!dir.isAbsolute()) {
// Make relative repositories dir relative to installation root
ResourceFile installRoot = Application.getInstallationDirectory();
if (installRoot == null || installRoot.getFile(false) == null) {
System.out.println("Failed to resolve installation root directory!");
return null;
}
dir = new File(installRoot.getFile(false), p);
}
return dir;
}
/**
* Display an optional message followed by usage syntax.
* @param msg
*/
private void displayUsage(String msg) {
if (msg != null) {
System.err.println(msg);
}
String invocationName = System.getProperty(INVOCATION_NAME_PROPERTY);
System.err.println("Usage: " +
(invocationName != null ? invocationName : "java " + UserAdmin.class.getName()) +
(propertyUsed ? "" : " <serverPath>") + " [<command>] [<command>] ...");
System.err.println("\nSupported commands:");
System.err.println(" -add <sid>");
System.err.println(" Add a new user to the server identified by their sid identifier");
System.err.println(" -remove <sid>");
System.err.println(" Remove the specified user from the server's user list");
System.err.println(" -reset <sid>");
System.err.println(" Reset the specified user's server login password");
System.err.println(" -dn <sid> \"<dname>\"");
System.err.println(
" When PKI authentication is used, add the specified X500 Distinguished Name for a user");
System.err.println(" -admin <sid> \"<repository-name>\"");
System.err.println(
" Grant ADMIN privilege to the specified user with the specified repository");
System.err.println(" -list [-users]");
System.err.println(
" Output list of repositories to the console (user access list will be included with -users)");
System.err.println(" -users");
System.err.println(" Output list of users to console which have server access");
System.err.println(" -migrate \"<repository-name>\"");
System.err.println(
" Migrate the specified repository to the latest file system storage schema (see svrREADME.html)");
System.err.println(" -migrate-all");
System.err.println(
" Migrate the all repositories to the latest file system storage schema (see svrREADME.html)");
System.err.println();
}
}

View File

@ -23,15 +23,8 @@ import javax.security.auth.x500.X500Principal;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import generic.jar.ResourceFile;
import ghidra.framework.Application;
import ghidra.framework.ApplicationConfiguration;
import ghidra.framework.store.local.LocalFileSystem;
import ghidra.server.remote.GhidraServerApplicationLayout;
import ghidra.util.Msg;
import ghidra.util.NamingUtilities;
import ghidra.util.exception.DuplicateNameException;
import utility.application.ApplicationLayout;
/**
* <code>UserAdmin</code> is an Application for generating administrative
@ -41,32 +34,15 @@ import utility.application.ApplicationLayout;
public class UserAdmin {
static final Logger log = LogManager.getLogger(UserAdmin.class);
private static final String INVOCATION_NAME_PROPERTY = "UserAdmin.invocation";
private static final String CONFIG_FILE_PROPERTY = "UserAdmin.config";
// property name defined within the sever.conf file which specifies
// server repositories directory
private static final String SERVER_DIR_CONFIG_PROPERTY = "ghidra.repositories.dir";
private static boolean propertyUsed = false;
// Queued commands
private static final String ADD_USER_COMMAND = "-add";
private static final String REMOVE_USER_COMMAND = "-remove";
private static final String RESET_USER_COMMAND = "-reset";
private static final String SET_USER_DN_COMMAND = "-dn";
private static final String SET_ADMIN_COMMAND = "-admin";
static final String ADD_USER_COMMAND = "-add";
static final String REMOVE_USER_COMMAND = "-remove";
static final String RESET_USER_COMMAND = "-reset";
static final String SET_USER_DN_COMMAND = "-dn";
static final String SET_ADMIN_COMMAND = "-admin";
// Immediate commands
private static final String LIST_COMMAND = "-list";
private static final String USERS_COMMAND = "-users";
// Delayed commands
private static final String MIGRATE_COMMAND = "-migrate";
private static final String MIGRATE_ALL_COMMAND = "-migrate-all";
private static final String ADMIN_CMD_DIR = LocalFileSystem.HIDDEN_DIR_PREFIX + "admin";
private static final String COMMAND_FILE_EXT = ".cmd";
static final String ADMIN_CMD_DIR = LocalFileSystem.HIDDEN_DIR_PREFIX + "admin";
static final String COMMAND_FILE_EXT = ".cmd";
/**
* Command file filter
@ -264,7 +240,7 @@ public class UserAdmin {
* @param cmdDir command file directory
* @throws IOException
*/
private static void writeCommands(ArrayList<String> cmdList, File cmdDir) throws IOException {
static void writeCommands(ArrayList<String> cmdList, File cmdDir) throws IOException {
File cmdFile = File.createTempFile("adm", ".tmp", cmdDir);
String cmdFilename = cmdFile.getName();
cmdFilename = cmdFilename.substring(0, cmdFilename.length() - 4) + COMMAND_FILE_EXT;
@ -289,346 +265,4 @@ public class UserAdmin {
}
}
/**
* Validate properly formatted Distinguished Name
* Example: 'CN=Doe John, OU=X, OU=Y, OU=DoD, O=U.S. Government, C=US'
* @param args
* @param i argument index
*/
private static void validateDN(String[] args, int i) {
if (args.length < (i + 1)) {
displayUsage("Invalid usage!");
System.exit(-1);
}
String dn = args[i];
try {
X500Principal x500User = new X500Principal(dn);
args[i] = "\"" + x500User.getName() + "\"";
}
catch (Exception e) {
Msg.error(UserAdmin.class, "Invalid DN: " + dn);
System.exit(-1);
}
}
/**
* Validate username/sid
* @param args
* @param i argument index
*/
private static void validateSID(String[] args, int i) {
if (args.length < (i + 1)) {
displayUsage("Invalid usage!");
System.exit(-1);
}
String sid = args[i];
if (!NamingUtilities.isValidName(sid) || sid.indexOf(' ') >= 0) {
Msg.error(UserAdmin.class, "Invalid username/sid: " + sid);
System.exit(-1);
}
}
/**
* Validate username/sid
* @param args
* @param i argument index
*/
private static void validateRepName(String[] args, int i, File rootDirFile) {
if (args.length < (i + 1)) {
displayUsage("Invalid usage!");
System.exit(-1);
}
String repName = args[i];
File f = new File(rootDirFile, NamingUtilities.mangle(repName));
if (!f.isDirectory()) {
Msg.error(UserAdmin.class, "Repository not found: " + repName);
System.exit(-1);
}
}
/**
* @param serverDir
* @param args
* @param i
*/
private static void addCommand(ArrayList<String> cmdList, String[] args, int argOffset,
int argCnt) {
StringBuffer buf = new StringBuffer();
for (int i = 0; i < argCnt; i++) {
if (i > 0) {
buf.append(' ');
}
buf.append(args[argOffset + i]);
}
cmdList.add(buf.toString());
}
/**
* Display an optional message followed by usage syntax.
* @param msg
*/
private static void displayUsage(String msg) {
if (msg != null) {
System.err.println(msg);
}
String invocationName = System.getProperty(INVOCATION_NAME_PROPERTY);
System.err.println("Usage: " +
(invocationName != null ? invocationName : "java " + UserAdmin.class.getName()) +
(propertyUsed ? "" : " <serverPath>") + " [<command>] [<command>] ...");
System.err.println("\nSupported commands:");
System.err.println(" -add <sid>");
System.err.println(" Add a new user to the server identified by their sid identifier");
System.err.println(" -remove <sid>");
System.err.println(" Remove the specified user from the server's user list");
System.err.println(" -reset <sid>");
System.err.println(" Reset the specified user's server login password");
System.err.println(" -dn <sid> \"<dname>\"");
System.err.println(
" When PKI authentication is used, add the specified X500 Distinguished Name for a user");
System.err.println(" -admin <sid> \"<repository-name>\"");
System.err.println(
" Grant ADMIN privilege to the specified user with the specified repository");
System.err.println(" -list [-users]");
System.err.println(
" Output list of repositories to the console (user access list will be included with -users)");
System.err.println(" -users");
System.err.println(" Output list of users to console which have server access");
System.err.println(" -migrate \"<repository-name>\"");
System.err.println(
" Migrate the specified repository to the latest file system storage schema (see svrREADME.html)");
System.err.println(" -migrate-all");
System.err.println(
" Migrate the all repositories to the latest file system storage schema (see svrREADME.html)");
System.err.println();
}
private static File getServerDirFromConfig() {
String p = System.getProperty(CONFIG_FILE_PROPERTY);
if (p == null) {
return null;
}
propertyUsed = true;
File configFile = new File(p);
if (!configFile.exists()) {
System.out.println("Config file not found: " + configFile.getAbsolutePath());
}
Properties config = new Properties();
InputStream in = null;
try {
in = new FileInputStream(configFile);
config.load(in);
}
catch (IOException e) {
System.out.println("Failed to read " + configFile.getName() + ": " + e.getMessage());
}
finally {
if (in != null) {
try {
in.close();
}
catch (IOException e) {
// ignore
}
}
}
p = config.getProperty(SERVER_DIR_CONFIG_PROPERTY);
if (p == null) {
return null;
}
File dir = new File(p);
if (!dir.isAbsolute()) {
// Make relative repositories dir relative to installation root
ResourceFile installRoot = Application.getInstallationDirectory();
if (installRoot == null || installRoot.getFile(false) == null) {
System.out.println("Failed to resolve installation root directory!");
return null;
}
dir = new File(installRoot.getFile(false), p);
}
return dir;
}
/**
* Main method for running the UserAdmin Application.
* The following properties may be set:
* <pre>
* UserAdmin.invocation - identifies the name of the application used when displaying usage text.
* UserAdmin.serverDir - identifies the server directory instead of passing on command line.
* </pre>
* @param args command line arguments
*/
public static void main(String[] args) throws Exception {
// Perform static initializations if not already initialized
// Some tests invoke main method directly which have already initialized Application
if (!Application.isInitialized()) {
ApplicationLayout layout = new GhidraServerApplicationLayout();
ApplicationConfiguration configuration = new ApplicationConfiguration();
configuration.setInitializeLogging(false);
Application.initializeApplication(layout, configuration);
}
File serverDir = null;
int ix = 0;
if (args.length != 0 && !args[0].startsWith("-")) {
serverDir = new File(args[ix++]);
}
else {
serverDir = getServerDirFromConfig();
}
if (serverDir == null || (args.length - ix) == 0) {
displayUsage("");
System.exit(-1);
return;
}
try {
serverDir = serverDir.getCanonicalFile();
}
catch (IOException e1) {
System.err.println("Failed to resolve server directory: " + serverDir);
System.exit(-1);
}
if (propertyUsed) {
System.out.println("Using server directory: " + serverDir);
}
File userFile = new File(serverDir, UserManager.USER_PASSWORD_FILE);
if (!serverDir.isDirectory() || !userFile.isFile()) {
System.err.println("Invalid Ghidra server directory specified: " + serverDir);
System.exit(-1);
}
File cmdDir = new File(serverDir, ADMIN_CMD_DIR);
if (!cmdDir.exists()) {
System.err.println("Insufficient privilege or server not started.");
System.exit(-1);
}
if (!cmdDir.isDirectory()) {
System.err.println("Bad server directory: " + serverDir);
System.exit(-1);
}
// Process command line
boolean listRepositories = false;
boolean listUsers = false;
boolean migrationConfirmed = false;
boolean migrationAbort = false;
ArrayList<String> cmdList = new ArrayList<>();
int cmdLen = 1;
for (; ix < args.length; ix += cmdLen) {
boolean queueCmd = true;
if (ADD_USER_COMMAND.equals(args[ix])) { // add user
cmdLen = 2;
validateSID(args, ix + 1);
}
else if (REMOVE_USER_COMMAND.equals(args[ix])) { // remove user
cmdLen = 2;
validateSID(args, ix + 1);
}
else if (RESET_USER_COMMAND.equals(args[ix])) { // reset user
cmdLen = 2;
validateSID(args, ix + 1);
}
else if (SET_USER_DN_COMMAND.equals(args[ix])) { // set/add user with DN for PKI
cmdLen = 3;
validateSID(args, ix + 1);
validateDN(args, ix + 2);
}
else if (SET_ADMIN_COMMAND.equals(args[ix])) { // set/add repository admin
cmdLen = 3;
validateSID(args, ix + 1);
validateRepName(args, ix + 2, serverDir);
}
else if (LIST_COMMAND.equals(args[ix])) { // list repositories
cmdLen = 1;
queueCmd = false;
listRepositories = true;
}
else if (USERS_COMMAND.equals(args[ix])) { // list users (also affects listRepositories)
cmdLen = 1;
queueCmd = false;
listUsers = true;
}
else if (MIGRATE_ALL_COMMAND.equals(args[ix])) { // list repositories
cmdLen = 1;
queueCmd = false;
if (!migrationConfirmed && !confirmMigration()) {
migrationAbort = true;
}
migrationConfirmed = true;
if (!migrationAbort) {
RepositoryManager.markAllRepositoriesForIndexMigration(serverDir);
}
}
else if (MIGRATE_COMMAND.equals(args[ix])) { // list repositories
cmdLen = 2;
queueCmd = false;
if (ix == (args.length - 1)) {
System.err.println("Missing " + MIGRATE_COMMAND + " repository name argument");
}
else {
String repositoryName = args[ix + 1];
if (!migrationConfirmed && !confirmMigration()) {
migrationAbort = true;
}
migrationConfirmed = true;
if (!migrationAbort) {
Repository.markRepositoryForIndexMigration(serverDir, repositoryName,
false);
}
}
}
else {
displayUsage("Invalid usage!");
System.exit(-1);
}
if (queueCmd) {
addCommand(cmdList, args, ix, cmdLen);
}
}
try {
writeCommands(cmdList, cmdDir);
}
catch (IOException e) {
System.err.println("Failed to queue commands: " + e.toString());
System.exit(-1);
}
System.out.println(cmdList.size() + " command(s) queued.");
if (listUsers) {
UserManager.listUsers(serverDir);
}
if (listRepositories) {
RepositoryManager.listRepositories(serverDir, listUsers);
}
System.out.println();
}
private static boolean confirmMigration() {
System.out.print("\nWARNING! Please confirm the requested migration of one or more\n" +
"Ghidra Server repositories. Once migrated to indexed storage,\n" +
"any attempt to use these server repositories with a Ghidra Server\n" +
"older than version 5.5 will corrupt the data storage.\n" +
"\nWould you like to continue? [y/n]: ");
try {
if ('y' == System.in.read()) {
System.out.println();
return true;
}
}
catch (IOException e) {
e.printStackTrace();
}
System.out.println("\nAll repository data migration(s) has been aborted.");
return false;
}
}

View File

@ -532,12 +532,17 @@ public class UserManager {
readUserList(userFile, list, lookupMap);
System.out.println("\nRepository Server Users:");
for (String name : list.keySet()) {
System.out.println(" " + name);
if (list.isEmpty()) {
System.out.println(" <No users have been added>");
}
else {
for (String name : list.keySet()) {
System.out.println(" " + name);
}
}
}
catch (IOException e) {
System.out.println("Failed to read user file: " + e.getMessage());
System.out.println("\nFailed to read user file: " + e.getMessage());
}
}

View File

@ -1,30 +1,29 @@
#!/bin/bash
# ***********************************************************
# ** Arguments (each -argument option may be repeated):
# ** [-add <sid>] [-remove <sid>] [-reset <sid>] [-dn <sid> "<x500_distinguished_name>"]
# ** [-admin <sid> "<repository-name>"] [-list] [-migrate "<repository-name>"] [-migrate-all]
# ** [-add <sid>] [-dn <sid> "<x500_distinguished_name>"]
# ** [-remove <sid>]
# ** [-reset <sid>]
# ** [-admin <sid> "<repository-name>"]
# ** [-list] [-users]
# ** [-migrate "<repository-name>"] [-migrate-all]
# **
# ** add - add a new user to the server with the default password 'changeme'
# ** dn - set a user's distinguished name for PKI authentication
# ** remove - remove an existing user from the server
# ** reset - reset an existing user's password to 'changeme'
# ** dn - set a user's distinguished name for PKI authentication
# ** admin - set the specified existing user as an admin of the specified repository
# ** list - list all existing named repositories
# ** users - list all users or those associated with each listed repository
# ** migrate - migrate the specified named repository to an indexed data storage
# ** migrate-all - migrate all named repositories to index data storage
# ***********************************************************
UMASK=027
SUDO=sudo
# Preserve quoted arguments
ARGS=()
WHITESPACE="[[:space:]]"
for AA in "$@"; do
if [[ $AA =~ $WHITESPACE ]]; then
AA="\"$AA\""
fi
ARGS[${#ARGS[@]}]=$AA
done
# Maximum heap memory may be changed if default is inadequate. This will generally be up to 1/4 of
# the physical memory available to the OS. Uncomment MAXMEM setting if non-default value is needed.
MAXMEM=128M
# Resolve symbolic link if present and get the directory this script lives in.
# NOTE: "readlink -f" is best but works on Linux only, "readlink" will only work if your PWD
@ -34,49 +33,20 @@ SCRIPT_FILE="$(readlink -f "$0" 2>/dev/null || readlink "$0" 2>/dev/null || echo
SCRIPT_DIR="${SCRIPT_FILE%/*}"
if [ -d "${SCRIPT_DIR}/../Ghidra" ]; then
# Production Environment
CONFIG="${SCRIPT_DIR}/server.conf"
GHIDRA_DIR="${SCRIPT_DIR}/../Ghidra"
CPATH="${GHIDRA_DIR}/Features/GhidraServer/lib/GhidraServer.jar:${GHIDRA_DIR}/Framework/FileSystem/lib/FileSystem.jar:${GHIDRA_DIR}/Framework/DB/lib/DB.jar:${GHIDRA_DIR}/Framework/Generic/lib/Generic.jar:${GHIDRA_DIR}/Framework/Utility/lib/Utility.jar:${GHIDRA_DIR}/Framework/Generic/lib/log4j-core-2.8.1.jar:${GHIDRA_DIR}/Framework/Generic/lib/log4j-api-2.8.1.jar"
LS_CPATH="${GHIDRA_DIR}/../support/LaunchSupport.jar"
else
# Development Environment
CONFIG="${SCRIPT_DIR}/../../Common/server/server.conf"
GHIDRA_DIR="${SCRIPT_DIR}/../../.."
GHIDRA_BIN_REPO="${GHIDRA_DIR}/../../ghidra.bin"
CPATH="${GHIDRA_DIR}/Features/GhidraServer/bin/main:${GHIDRA_DIR}/Framework/FileSystem/bin/main:${GHIDRA_DIR}/Framework/DB/bin/main:${GHIDRA_DIR}/Framework/Generic/bin/main:${GHIDRA_DIR}/Framework/Utility/bin/main:${GHIDRA_BIN_REPO}/ExternalLibraries/libsForRuntime/log4j-core-2.8.1.jar:${GHIDRA_BIN_REPO}/ExternalLibraries/libsForRuntime/log4j-api-2.8.1.jar"
LS_CPATH="${GHIDRA_DIR}/../GhidraBuild/LaunchSupport/bin/main"
fi
# Make sure some kind of java is on the path. It's required to run the LaunchSupport program.
if ! [ -x "$(command -v java)" ] ; then
echo "Java runtime not found. Please refer to the Ghidra Installation Guide's Troubleshooting section."
exit 1
fi
# Get the java that will be used to launch GhidraServer
JAVA_HOME=$(java -cp "${LS_CPATH}" LaunchSupport "${GHIDRA_DIR}/.." -java_home)
if [ ! $? -eq 0 ]; then
echo "Failed to find a supported Java runtime. Please refer to the Ghidra Installation Guide's Troubleshooting section."
exit 1
fi
JAVA_CMD="${JAVA_HOME}/bin/java"
VMARGS="-DUserAdmin.invocation=$(basename "${SCRIPT_FILE}") -DUserAdmin.config=\"${CONFIG}\""
OLD_UMASK=$(umask)
umask $UMASK
# Identify server process owner if set within server.conf
OWNER="$(grep '^wrapper.app.account=' "${CONFIG}" | sed -e 's/^.*=\(.*\)\s*.*$/\1/')"
if [ -z "${OWNER}" -o "${OWNER}" = "$(whoami)" ]; then
eval "\"${JAVA_CMD}\" ${VMARGS} -cp \"${CPATH}\" ghidra.server.UserAdmin ${ARGS[@]}"
VMARGS="-DUserAdmin.invocation=$(basename "${SCRIPT_FILE}") -DUserAdmin.config=\"${CONFIG}\""
"${SCRIPT_DIR}"/../support/launch.sh fg svrAdmin "${MAXMEM}" "$VMARGS" ghidra.server.ServerAdmin "$@"
else
echo "Running svrAdmin with sudo as ${OWNER} ..."
eval "sudo -u "${OWNER}" \"${JAVA_CMD}\" ${VMARGS} -cp \"${CPATH}\" ghidra.server.UserAdmin ${ARGS[@]}"
echo "Running svrAdmin with $SUDO as ${OWNER} ..."
$SUDO -u $OWNER "$0" "${ARGS[@]}"
fi
umask $OLD_UMASK

View File

@ -1,22 +1,30 @@
@echo off
:: ***********************************************************
:: ** Arguments (each argument set may be repeated):
:: ** [-add <sid>] [-remove <sid>] [-reset <sid>] [-dn <sid> "<x500_distinguished_name>"]
:: ** [-admin <sid> "<repository-name>"] [-list] [-migrate "<repository-name>"] [-migrate-all]
:: ** Arguments (each -argument option may be repeated):
:: ** [-add <sid>] [-dn <sid> "<x500_distinguished_name>"]
:: ** [-remove <sid>]
:: ** [-reset <sid>]
:: ** [-admin <sid> "<repository-name>"]
:: ** [-list] [-users]
:: ** [-migrate "<repository-name>"] [-migrate-all]
:: **
:: ** add - add a new user to the server with the default password 'changeme'
:: ** dn - set a user's distinguished name for PKI authentication
:: ** remove - remove an existing user from the server
:: ** reset - reset an existing user's password to 'changeme'
:: ** dn - set a user's distinguished name for PKI authentication
:: ** admin - set the specified existing user as an admin of the specified repository
:: ** list - list all existing named repositories
:: ** users - list all users or those associated with each listed repository
:: ** migrate - migrate the specified named repository to an indexed data storage
:: ** migrate-all - migrate all named repositories to index data storage
:: ***********************************************************
setlocal
:: maximum heap memory may be change if inadequate
set MAXMEM=128M
:: Sets SCRIPT_DIR to the directory that contains this file
::
:: '% ~' dereferences the value in param 0
@ -24,51 +32,16 @@ setlocal
:: 'p' - path (without filename)
set SCRIPT_DIR=%~dp0
:: Uncomment and set the value below as necessary
:: set SCRIPT_DIR=<full Ghidra installation server directory path>
if not exist "%SCRIPT_DIR%" (
echo Unable to set the Ghidra server script directory.
echo.
echo To run Ghidra in this mode you must set the
echo value of SCRIPT_DIR in this file to be
echo the full path containing this batch file
goto :eof
)
:: Production Environment
set CONFIG=%SCRIPT_DIR%.\server.conf
set GHIDRA_DIR=%SCRIPT_DIR%..\Ghidra
set CPATH=%GHIDRA_DIR%\Features\GhidraServer\lib\GhidraServer.jar;%GHIDRA_DIR%\Framework\FileSystem\lib\FileSystem.jar;%GHIDRA_DIR%\Framework\DB\lib\DB.jar;%GHIDRA_DIR%\Framework\Generic\lib\Generic.jar;%GHIDRA_DIR%\Framework\Utility\lib\Utility.jar;%GHIDRA_DIR%\Framework\Generic\lib\log4j-core-2.8.1.jar;%GHIDRA_DIR%\Framework\Generic\lib\log4j-api-2.8.1.jar
set LS_CPATH=%GHIDRA_DIR%\..\support\LaunchSupport.jar
if exist "%GHIDRA_DIR%" goto continue
:: Development Environment - assumes suitable java in command path
:: Development Environment
set CONFIG=%SCRIPT_DIR%..\..\Common\server\server.conf
set GHIDRA_DIR=%SCRIPT_DIR%..\..\..
set GHIDRA_BIN_HOME=%GHIDRA_DIR%\..\..\ghidra.bin
set CPATH=%GHIDRA_DIR%\Features\GhidraServer\bin\main;%GHIDRA_DIR%\Framework\FileSystem\bin\main;%GHIDRA_DIR%\Framework\DB\bin\main;%GHIDRA_DIR%\Framework\Generic\bin\main;%GHIDRA_DIR%\Framework\Utility\bin\main;%GHIDRA_BIN_HOME%\ExternalLibraries\libsForRuntime\log4j-core-2.8.1.jar;%GHIDRA_BIN_HOME%\ExternalLibraries\libsForRuntime\log4j-api-2.8.1.jar
set LS_CPATH=%GHIDRA_DIR%\..\GhidraBuild\LaunchSupport\bin\main
:continue
:: Make sure some kind of java is on the path. It's required to run the LaunchSupport program.
java -version >nul 2>nul
if not %ERRORLEVEL% == 0 (
echo Java runtime not found. Please refer to the Ghidra Installation Guide's Troubleshooting section.
exit /B 1
)
set VMARGS=-DUserAdmin.invocation="%0" -DUserAdmin.config="%CONFIG%"
:: Get the java that will be used to launch GhidraServer
set JAVA_HOME=
for /f "delims=*" %%i in ('java -cp "%LS_CPATH%" LaunchSupport "%GHIDRA_DIR%\.." -java_home') do set JAVA_HOME=%%i
if "%JAVA_HOME%" == "" (
echo Failed to find a supported Java runtime. Please refer to the Ghidra Installation Guide's Troubleshooting section.
exit /B 1
)
set JAVA=%JAVA_HOME%\bin\java.exe
set VMARGS=-DUserAdmin.invocation="%0" -DUserAdmin.config="%CONFIG%" -Djava.net.preferIPv4Stack=true
"%JAVA%" %VMARGS% -cp "%CPATH%" ghidra.server.UserAdmin %*
call "%~dp0\..\support\launch.bat" fg svrAdmin "%MAXMEM%" "%VMARGS%" ghidra.server.ServerAdmin %*

View File

@ -10,31 +10,45 @@
@echo off
setlocal
if "%~1" == "" (
echo "Usage: createPdbXmlFiles.bat <path to .pdb file|path to directory of .pdb files>"
Exit /B 0
)
REM Get parent of current folder
for %%A in (%~dp0\.) do set ghidraPath=%%~dpA
set SCRIPT_DIR=%~dp0
set GHIDRA_DIR=%SCRIPT_DIR%..\Ghidra
set OS_DIR=os
REM Production Environment
if exist "%ghidraPath%Ghidra" goto continue
if exist "%GHIDRA_DIR%" goto continue
REM Development Environment
set ghidraPath="%ghidraPath%..\..\..\..\ghidra.bin\"
set GHIDRA_DIR=%SCRIPT_DIR%..\..\..
set OS_DIR=build\os
:continue
set arg1="%~1"
REM create absolute path
for /f %%i in ("%GHIDRA_DIR%") do set GHIDRA_DIR=%%~fi
REM Determine if 64-bit or 32-bit
if exist "%PROGRAMFILES(X86)%" (
set osType=win64
set OS_TYPE=win64
) else (
set osType=win32
set OS_TYPE=win32
)
set PDB_EXE=%GHIDRA_DIR%\Features\PDB\%OS_DIR%\%OS_TYPE%\pdb.exe
if not exist "%PDB_EXE%" (
echo "%PDB_EXE% not found"
Exit /B 1
)
if "%~1" == "" (
echo "Usage: createPdbXmlFiles.bat <path to .pdb file|path to directory of .pdb files>"
Exit /B 1
)
set arg1="%~1"
set /a count=0
REM Recursively traverse through the given directory
@ -50,7 +64,7 @@ for /f "tokens=* delims=" %%a in ('dir %arg1% /s /b') do (
setlocal enableDelayedExpansion
(
echo "Processing file: %%a"
START /B /WAIT "" "%ghidraPath%Ghidra\Features\PDB\os\%ostype%\pdb.exe" %%a > "%%a.xml"
START /B /WAIT "" "%PDB_EXE%" %%a > "%%a.xml"
REM Exit if executable returned non-zero error code (signifies that there is a problem).
if !errorlevel! neq 0 (
@ -63,7 +77,7 @@ for /f "tokens=* delims=" %%a in ('dir %arg1% /s /b') do (
echo Error detected. Exiting...
)
Exit /B 0
Exit /B 1
)
)