Chris
Chris

Reputation: 934

Python in C# UnboundNameException

I am using a XCCDF to TSV parser, written in python, and when I call the file I get an UnboundNameException was unhandled and I'm not sure why. The code runs fine from the terminal just not when called in C#.

The Stacktrace is below, if that is useful:

IronPython.Runtime.UnboundNameException was unhandled
  HResult=-2146233088
  Message=global name 'xccdf' is not defined
  Source=IronPython
  StackTrace:
       at IronPython.Compiler.PythonGlobal.GetCachedValue(Boolean lightThrow)
       at IronPython.Compiler.PythonGlobal.get_CurrentValue()
       at IronPython.Compiler.PythonGlobalInstruction.Run(InterpretedFrame frame)
       at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)
       at Microsoft.Scripting.Interpreter.LightLambda.Run1[T0,TRet](T0 arg0)
       at IronPython.Compiler.RuntimeScriptCode.InvokeTarget(Scope scope)
       at IronPython.Compiler.RuntimeScriptCode.Run()
       at Microsoft.Scripting.Hosting.ScriptSource.Execute()
       at Microsoft.Scripting.Hosting.ScriptEngine.Execute(String expression)
       at TestReportCreator_Beta_v3.Program.Main(String[] args) in  g:\TestReportCreator_Beta_v2\TestReportCreator_Beta_v2\Program.cs:line 122
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.Runtime.Hosting.ManifestRunner.Run(Boolean checkAptModel)
       at System.Runtime.Hosting.ManifestRunner.ExecuteAsAssembly()
       at System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext, String[] activationCustomData)
       at System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext)
       at System.Activator.CreateInstance(ActivationContext activationContext)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssemblyDebugInZone()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()

InnerException:'

C# code:

string profile = Console.ReadLine();

IDictionary<string, object> options = new Dictionary<string, object>();
options["Argument"] = new[] { filePath, profile };
var pyEngine = Python.CreateEngine(options);
string script = "xccdf-xml2tsv.py";

pyEngine.Execute(script);

The Python Code I'm using:

#!/usr/bin/env python

### 
# (C) 2010 Adam Crosby
# Licensed under:
#  http://creativecommons.org/licenses/by-nc-sa/3.0/
##
import csv
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
import xml.etree.ElementTree as ET
xmlns = "http://checklists.nist.gov/xccdf/1.1"

if len(sys.argv) != 2:
    print "  XCCDF-xml2tsv converts XCCDF XML documents (such as DISA STIGs)"
    print "    into easier to use Tab-Separated documents."
    print "  Please run as '%s' <filename> and redirect output as needed." % sys.argv[0]
    print "  Files should open easily in Excel."
    print "  E.g.:\n\t %s U_Perimeter_Router_v8R2_manual.xccdf.xml > output.tsv" % sys.argv[0]
    sys.exit(0)
try:
    xml = ET.parse(sys.argv[0])
except Exception,e:
    print "Error, unable to parse XML document.  Are you sure that's XCCDF?"
    sys.exit(-1)

benchmark = xml.getroot()
check_list = []
profile_name = sys.argv[1]
profiles = benchmark.findall("{%s}Profile" % xmlns)
for profile in profiles:
    if profile.get("id") == profile_name:
        #<select idref="V-761" selected="true"/>
        selects = profile.findall("{%s}select" % xmlns)
        for select_tag in selects:
            if select_tag.get("selected") == "true":
                check_list.append(select_tag.get('idref'))

groups = benchmark.findall("{%s}Group" % xmlns)

print "ID\tVersion\tRule Title\tTitle\tSeverity\tIA Controls"

csvfile = open('tmp.csv', 'wb')
output = csv.writer(csvfile, dialect='excel')

for group in groups:
    group_id = group.get("id")
    if group_id in check_list:
        title = group.find("{%s}title" % xmlns).text
        severity = group.find("{%s}Rule" % xmlns).get("severity")
        version = group.find("{%s}Rule/{%s}version" % (xmlns, xmlns)).text
        rule_title = group.find("{%s}Rule/{%s}title" % (xmlns, xmlns)).text
        desctag = "{%s}Rule/{%s}description" % (xmlns, xmlns)
        fixtext = group.find("{%s}Rule/{%s}fixtext" % (xmlns, xmlns)).text
        check = group.find("{%s}Rule/{%s}check" % (xmlns, xmlns)).text
        descriptiontext = group.find(desctag).text
        encodedDesc = descriptiontext.replace("&gt;", ">").replace("&lt;", "<").replace("&", "&amp;")
        innerXML = "<desc>%s</desc>" % format(encodedDesc)
        xml = ET.XML(innerXML)
        iacontrols = xml.find("IAControls").text
        vulndisc = xml.find("VulnDiscussion").text

        output.writerow( (group_id.replace('\n', '##').replace('V-',''), version.replace('\n', '##'), rule_title.replace('\n', '##'), title.replace('\n', '##'), severity.replace('\n', '##'), check, fixtext) )

Upvotes: 1

Views: 1569

Answers (1)

Chris
Chris

Reputation: 934

Didn't have the syntax for setting the scope right.

IDictionary<string, object> options = new Dictionary<string, object>();
options["Arguments"] = new[] { filePath, profile };

var pyEngine = Python.CreateEngine(options);
var pyScope = pyEngine.CreateScope();
string script = "xccdf-xml2tsv.py";
pyScope.SetVariable(profile, options);

pyEngine.ExecuteFile(script, pyScope);

Upvotes: 1

Related Questions