Omaha #4492 Security for FaxSender.

Change-Id: I3db4a4175708764019d5a7d6befa4f02bfb49ed2

Former-commit-id: 22b1113b171200cdc3f57980019a0d7056b067d8
This commit is contained in:
Roger Ferrel 2015-06-04 15:48:13 -05:00
parent 98e1b91e00
commit 623c498d79
6 changed files with 407 additions and 9 deletions

View file

@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Text Plug-in
Bundle-SymbolicName: com.raytheon.uf.edex.plugin.text
Bundle-Version: 1.14.0.qualifier
Bundle-Version: 1.15.0.qualifier
Bundle-Vendor: RAYTHEON
Require-Bundle: org.apache.commons.lang,
com.raytheon.edex.common,
@ -18,7 +18,8 @@ Export-Package: com.raytheon.uf.edex.plugin.text,
com.raytheon.uf.edex.plugin.text.dao,
com.raytheon.uf.edex.plugin.text.db,
com.raytheon.uf.edex.plugin.text.dbsrv,
com.raytheon.uf.edex.plugin.text.dbsrv.impl
com.raytheon.uf.edex.plugin.text.dbsrv.impl,
com.raytheon.uf.edex.plugin.text.security
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Import-Package: com.raytheon.edex.uengine.runners,
com.raytheon.uf.common.dataplugin.text,

View file

@ -25,6 +25,7 @@ import java.io.FileWriter;
import java.io.IOException;
import com.raytheon.uf.common.util.RunProcess;
import com.raytheon.uf.edex.plugin.text.security.EnvPathWhiteList;
/**
* Sends FAX to number using LDAD system
@ -39,6 +40,7 @@ import com.raytheon.uf.common.util.RunProcess;
* Sep 19, 2011 10955 rferrel Use RunProcess
* Jan 10, 2012 4550 mgamazaychikov Fixed the sshCommand
* May 20, 2014 2536 bclement moved from edex.textdb to edex.plugin.text
* Jun 03, 2015 4492 rferrel Use {@link EnvPathWhiteList} for security check.
*
* </pre>
*
@ -49,6 +51,14 @@ import com.raytheon.uf.common.util.RunProcess;
public class FaxSender {
private static final String getDate = "date -u +%Y%m%d%H%M%S";
private static final String ENV_ERROR_FMT = "Unable to valiate environment variable %s.";
private static final String FXA_DATA = "FXA_DATA";
private static final String LDAD_EXTERNAL_PUBLIC = "LDAD_EXTERNAL_PUBLIC";
private static final String LDAD_EXTERNAL_HOME = "LDAD_EXTERNAL_HOME";
// Utility class constructor.
private FaxSender() {
}
@ -66,8 +76,15 @@ public class FaxSender {
retval = "Error reading date from system." + error;
return retval;
}
String date = p.getStdout().trim();
String fxadata = System.getenv("FXA_DATA");
EnvPathWhiteList manager = new EnvPathWhiteList();
String fxadata = manager.getenv(FXA_DATA);
if (fxadata == null) {
retval = String.format(ENV_ERROR_FMT, FXA_DATA);
return retval;
}
// Make fax data directory.
String faxDir = fxadata + "/workFiles/fax/";
// Make fax data file name.
@ -77,7 +94,11 @@ public class FaxSender {
String faxScriptFilename = fxadata + "/workFiles/fax/" + faxTitle
+ date + ".msg";
// Make ldad fax data file name.
String ldadExternalPublic = System.getenv("LDAD_EXTERNAL_PUBLIC");
String ldadExternalPublic = manager.getenv(LDAD_EXTERNAL_PUBLIC);
if (ldadExternalPublic == null) {
retval = String.format(ENV_ERROR_FMT, LDAD_EXTERNAL_PUBLIC);
return retval;
}
String ldadDataFilename = ldadExternalPublic + "/fax/" + faxTitle
+ date + ".data";
// Make ldad fax script file name.
@ -153,16 +174,21 @@ public class FaxSender {
// Execute faxSender.csh on ldad fax script file (system exec)
StringBuilder sshCommand = new StringBuilder();
/*
* DR4550 - the sshCommand should be:
* ssh -n ls1 -l ldad $LDAD_EXTERNAL_HOME/bin/faxSender.csh filename
* DR4550 - the sshCommand should be: ssh -n ls1 -l ldad
* $LDAD_EXTERNAL_HOME/bin/faxSender.csh filename
*/
String ldadHome = manager.getenv(LDAD_EXTERNAL_HOME);
if (ldadHome == null) {
retval = String.format(ENV_ERROR_FMT, LDAD_EXTERNAL_HOME);
return retval;
}
sshCommand.append("ssh -n ls1 -l ldad ");
sshCommand.append(System.getenv("LDAD_EXTERNAL_HOME"));
sshCommand.append(ldadHome);
sshCommand.append("/bin/faxSender.csh ");
sshCommand.append(ldadScriptFilename);
// DR#10955
RunProcess sshCommandExec = RunProcess.getRunProcess().exec(
sshCommand.toString());
sshCommand.toString());
error = sshCommandExec.getStderr().trim();
if (error.length() != 0) {
// Send back an appropriate error string.
@ -172,5 +198,4 @@ public class FaxSender {
// Return
return retval;
}
}

View file

@ -0,0 +1,198 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.edex.plugin.text.security;
import java.io.File;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.xml.bind.JAXB;
import com.raytheon.uf.common.localization.IPathManager;
import com.raytheon.uf.common.localization.PathManagerFactory;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
/**
* This manages a list of directory paths associated with an environment
* variable. The value associated with an environment variable must result in a
* absolute file name that starts with one of the path names in the list.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 3, 2015 4492 rferrel Initial creation
*
* </pre>
*
* @author rferrel
* @version 1.0
*/
public class EnvPathWhiteList {
private final IUFStatusHandler statusHandler = UFStatus
.getHandler(EnvPathWhiteList.class);
private final static String CONFIG_FILE = "environment/EnvWrapCfg.xml";
/**
* White list paths associated with an environment name.
*/
private final Map<String, List<Path>> pathMap = new HashMap<>();
public EnvPathWhiteList() {
init();
}
/**
*
* @param filename
* - A common static file name.
*/
private void init() {
EnvironmentWrapCfg envWrapCfg = null;
try {
IPathManager pm = PathManagerFactory.getPathManager();
File path = pm.getStaticFile(CONFIG_FILE);
envWrapCfg = JAXB.unmarshal(path, EnvironmentWrapCfg.class);
} catch (Exception e) {
statusHandler.handle(Priority.ERROR,
"Unable to parse the localized environment path configuration file: "
+ CONFIG_FILE + ".", e);
return;
}
// Perform Sanity Checks on configuration.
StringBuilder message = new StringBuilder();
Iterator<EnvironmentCfg> iter = envWrapCfg.getEnv().iterator();
while (iter.hasNext()) {
EnvironmentCfg envCfg = iter.next();
String name = envCfg.getName();
List<String> pathList = envCfg.getWhitePaths();
if (pathList != null) {
Iterator<String> pathIter = pathList.iterator();
while (pathIter.hasNext()) {
String pathSting = pathIter.next();
Path path = null;
try {
path = Paths.get(pathSting).normalize();
} catch (InvalidPathException ex) {
path = null;
}
if ((path == null) || !path.isAbsolute()) {
message.append(name).append(" removing invalid path: ")
.append(pathSting).append("\n");
pathIter.remove();
} else {
List<Path> paths = pathMap.get(name);
if (paths == null) {
paths = new ArrayList<Path>(pathList.size());
pathMap.put(name, paths);
}
paths.add(path);
}
}
}
if ((pathList == null) || pathList.isEmpty()) {
message.append(name).append(" has no valid Paths.\n");
iter.remove();
}
}
if (message.length() > 0) {
statusHandler.error(message.toString());
}
}
/**
* Obtain environment variable.
*
* @param name
* - variable to obtain
*
* @return value - null when not defined or fails validation
*/
public String getenv(String name) {
return getenv(name, null);
}
/**
* Obtain environment variable when not defined use default value.
*
* @param name
* @param defaultValue
* @return value - null when not defined and default value is null or fails
* validation
*/
public String getenv(String name, String defaultValue) {
String value = System.getenv(name);
if (value == null) {
if (defaultValue == null) {
return null;
}
value = defaultValue;
}
if (!validate(name, value)) {
statusHandler.error("The environment variable " + name
+ " is an invalid value: " + value);
return null;
}
return value;
}
/**
* Validate the value for the environment variable.
*
* @param name
* @param value
* @return true when value starts with a white list path
*/
private boolean validate(String name, String value) {
List<Path> paths = pathMap.get(name);
if (paths != null) {
Path valPath = null;
try {
valPath = Paths.get(value).normalize();
} catch (InvalidPathException ex) {
return false;
}
if (valPath != null) {
for (Path path : paths) {
if (valPath.startsWith(path)) {
return true;
}
}
}
}
return false;
}
}

View file

@ -0,0 +1,68 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.edex.plugin.text.security;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
/**
* The white list paths associated with an environment name.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 03, 2015 4492 rferrel Initial creation
*
* </pre>
*
* @author rferrel
* @version 1.0
*/
@XmlAccessorType(XmlAccessType.NONE)
public class EnvironmentCfg {
@XmlAttribute(required = true)
private String name;
@XmlElement(name = "path")
private List<String> whitePaths;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<String> getWhitePaths() {
return whitePaths;
}
public void setWhitePaths(List<String> whitePaths) {
this.whitePaths = whitePaths;
}
}

View file

@ -0,0 +1,58 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.edex.plugin.text.security;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
/**
* A list of environment configurations with white list dirctory information.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 03, 2015 4492 rferrel Initial creation
*
* </pre>
*
* @author rferrel
* @version 1.0
*/
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
public class EnvironmentWrapCfg {
@XmlElement(name = "environment")
private List<EnvironmentCfg> env;
public List<EnvironmentCfg> getEnv() {
return env;
}
public void setEnv(List<EnvironmentCfg> env) {
this.env = env;
}
}

View file

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
This_software_was_developed_and_/_or_modified_by_Raytheon_Company,
pursuant_to_Contract_DG133W-05-CQ-1067_with_the_US_Government.
U.S._EXPORT_CONTROLLED_TECHNICAL_DATA
This_software_product_contains_export-restricted_data_whose
export/transfer/disclosure_is_restricted_by_U.S._law._Dissemination
to_non-U.S._persons_whether_in_the_United_States_or_abroad_requires
an_export_license_or_other_authorization.
Contractor_Name:________Raytheon_Company
Contractor_Address:_____6825_Pine_Street,_Suite_340
________________________Mail_Stop_B8
________________________Omaha,_NE_68106
________________________402.291.0100
See_the_AWIPS_II_Master_Rights_File_("Master_Rights_File.pdf")_for
further_licensing_information.
-->
<!--
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ============ ========== =========== ==========================
* Jun 03, 2013 4492 rferrel Initial creation
*
* @author rferrel
* @version 1.0
-->
<!--
The <environmentWrapCfg> contains a list made up of a single tag <environment>.
<environment> - This contains one or more <Path> tags and the required attribute
name which must be the same as the associated environment variable name.
<path> - An absolute directory path name.
The value for a given name environment variable must start with the value of one of its paths.
-->
<environmentWrapCfg>
<environment name='FXA_DATA'>
<path>/awips2/edex/data/fxa</path>
</environment>
<environment name='LDAD_EXTERNAL_PUBLIC'>
<path>/data/ldad/public</path>
</environment>
<environment name='LDAD_EXTERNAL_HOME'>
<path>/ldad</path>
</environment>
</environmentWrapCfg>