moving the shell functions into a jruby script

This commit is contained in:
Vincent Batts 2012-11-12 14:26:08 -05:00
parent de9f279ed4
commit 9f5054d2a3
3 changed files with 100 additions and 320 deletions

View file

@ -23,3 +23,26 @@ You can use either ant, or maven. I included the only two jar deps, for local
tools and ant builds. tools and ant builds.
But the unit tests are currently run with maven. But the unit tests are currently run with maven.
Tools
=====
The CLI class was done away with, so as not to ship in the jar, anything uneeded for
the library. It's been rewritten in jRuby (see http://jruby.org/ ).
The script ./tools/handy.rb, has plenty of functionality, and feel free to add more.
** Usage
$> jruby tools/handy.rb --help
Usage: handy [options]
--dot output the dot digraph of content listing (defaults to ./src/test/resources/contents.list
--contents FILE use FILE instead of ./src/test/resources/contents.list
--cert FILE read contents from certificate FILE
--test PATH validate PATH, instead of [/content/beta/rhel/server/5/5server/x86_64/sap/os/repomd.xml]
--print print the tree of contents
$> jruby ./tools/handy.rb --dot > contents.dot && dot -Tpng contents.dot -o contents.png && display contents.png
$> jruby ./tools/handy.rb --cert ./src/test/resources/test-certv3.pem
[/content/beta/rhel/server/5/5server/x86_64/sap/os/repomd.xml] true
[/foo/path, /foo/path/always/$releasever, /foo/path/never]

View file

@ -1,315 +0,0 @@
package com.hashbangbash.trie;
import java.util.List;
import java.util.ArrayList;
import java.io.InputStream;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import com.redhat.trie.HuffNode;
import com.redhat.trie.NodePair;
import com.redhat.trie.PathNode;
import com.redhat.trie.PathTree;
import com.redhat.trie.PayloadException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.security.cert.CertificateFactory;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.x509.extension.X509ExtensionUtil;
/*
* App
*
* This is just a simple class to handle command line interactions
*
*/
public class App {
/*
* PrettyPrint a PathNode tree
*/
public static void printTree(PathNode pn, int tab) {
StringBuffer nodeRep = new StringBuffer();
for (int i = 0; i <= tab; i++) {
nodeRep.append(" ");
}
nodeRep.append("Node [");
nodeRep.append(pn.getId());
nodeRep.append("]");
for (PathNode parent : pn.getParents()) {
nodeRep.append(" ^ [");
nodeRep.append(parent.getId());
nodeRep.append("]");
}
for (NodePair cp : pn.getChildren()) {
nodeRep.append(" v [");
nodeRep.append(cp.getName());
nodeRep.append(" {");
nodeRep.append(cp.getConnection().getId());
nodeRep.append("} ]");
}
System.out.println(nodeRep);
for (NodePair cp : pn.getChildren()) {
printTree(cp.getConnection(), tab + 1);
}
}
/*
* PrettyPrint a HuffNode tree
*/
public static void printTrie(HuffNode hn, int tab) {
StringBuffer nodeRep = new StringBuffer();
for (int i = 0; i <= tab; i++) {
nodeRep.append(" ");
}
nodeRep.append("Node [");
nodeRep.append(hn.getId());
nodeRep.append("]");
nodeRep.append(", Weight [");
nodeRep.append(hn.getWeight());
nodeRep.append("]");
nodeRep.append(", Value = [");
nodeRep.append(hn.getValue());
nodeRep.append("]");
System.out.println(nodeRep);
if (hn.getLeft() != null) {
printTrie(hn.getLeft(), tab + 1);
}
if (hn.getRight() != null) {
printTrie(hn.getRight(), tab + 1);
}
}
/*
* From the deflated payload, produce the content set lists
*
*
* FIXME - break this apart, so that the hydrated payload
* can be structure to more quickly search, and use less memory
*
* Rename it for tracking, and to be clear about what is happening
*/
public static List<String> hydrateContentPackage(byte[] compressedBlob) {
PathTree pt = new PathTree(compressedBlob);
return pt.toList();
}
public static ASN1Encodable objectFromOid(X509Certificate cert, String oid) {
if (cert == null) { return null; }
try {
for (String thisOid : cert.getNonCriticalExtensionOIDs()) {
if (thisOid.equals(oid)) {
return X509ExtensionUtil.fromExtensionValue(cert.getExtensionValue(oid));
}
}
} catch (IOException ex) { }
return null;
}
public static byte[] getBytesFromFile(File file) throws IOException {
InputStream is = new FileInputStream(file);
// Get the size of the file
long length = file.length();
// You cannot create an array using a long type.
// It needs to be an int type.
// Before converting to an int type, check
// to ensure that file is not larger than Integer.MAX_VALUE.
if (length > Integer.MAX_VALUE) {
// File is too large
}
// Create the byte array to hold the data
byte[] bytes = new byte[(int)length];
// Read in the bytes
int offset = 0;
int numRead = 0;
while (offset < bytes.length
&& (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
offset += numRead;
}
// Ensure all the bytes have been read in
if (offset < bytes.length) {
throw new IOException("Could not completely read file "+file.getName());
}
// Close the input stream and return bytes
is.close();
return bytes;
}
public static List<String> hydrateFromBytes(byte[] compressedBlob) {
return hydrateContentPackage(compressedBlob);
}
public static List<String> hydrateFromFile(String filename) {
try {
return hydrateFromBytes(getBytesFromFile(new File(filename)));
} catch (IOException ex) {
System.out.println(ex);
}
return null;
}
public static void byteArrayToFile(byte[] output, String filename) {
try {
FileOutputStream fos = new FileOutputStream(filename);
/*
* To write byte array to a file, use
* void write(byte[] bArray) method of Java FileOutputStream class.
*
* This method writes given byte array to a file.
*/
fos.write(output);
/*
* Close FileOutputStream using,
* void close() method of Java FileOutputStream class.
*
*/
fos.flush();
fos.close();
} catch(FileNotFoundException ex) {
System.out.println("FileNotFoundException : " + ex);
} catch(IOException ioe) {
System.out.println("IOException : " + ioe);
}
}
public static List<String> listFromFile(String filename) throws IOException, FileNotFoundException {
FileInputStream fis;
DataInputStream in;
BufferedReader br;
String content;
List<String> contentList;
try {
fis = new FileInputStream(filename);
} catch (FileNotFoundException ex) {
throw ex;
} catch (Throwable t) {
System.out.printf("ERROR: [%s] %s\n", filename, t);
return new ArrayList<String>();
}
in = new DataInputStream(fis);
br = new BufferedReader(new InputStreamReader(in));
contentList = new ArrayList<String>();
try {
while ((content = br.readLine()) != null) {
contentList.add(content);
}
} catch (IOException ex) {
throw ex;
}
return contentList;
}
public static void showTree(String filename) {
List<String> contentList;
try {
contentList = listFromFile(filename);
} catch (IOException ex) {
System.out.printf("ERROR: [%s] - %s\n", filename, ex);
return;
}
showTree(contentList);
}
public static void showTree(List<String> contentList) {
PathTree pt;
try {
pt = new PathTree(contentList);
printTree(pt.getRootPathNode(), 0);
} catch (PayloadException ex) {
System.out.println(ex);
}
}
public static ASN1Encodable objectFromCertOid(String certFilename, String oid) {
X509Certificate cert;
cert = certFromFile(certFilename);
return objectFromOid(cert,oid);
}
public static X509Certificate certFromFile(String certFilename) {
FileInputStream fis;
BufferedInputStream bis;
CertificateFactory cf;
X509Certificate cert;
try {
fis = new FileInputStream(certFilename);
} catch (FileNotFoundException ex) {
return null;
}
bis = new BufferedInputStream(fis);
try {
cf = CertificateFactory.getInstance("X.509");
} catch (CertificateException ex) {
return null;
}
try {
while (bis.available() > 0) {
cert = (X509Certificate) cf.generateCertificate(bis);
return cert;
}
} catch (IOException ex) {
} catch (CertificateException cex) {
}
return null;
}
public static void main(String[] args) {
for (String arg : args) {
//showTreeFromCSFIle(arg);
//showTreeFromCSFIle(arg);
DEROctetString dos;
List<String> contents;
dos = (DEROctetString)objectFromCertOid(arg, "1.3.6.1.4.1.2312.9.7");
//byteArrayToFile(dos.getOctets(), "herp.bin");
if ((contents = hydrateFromBytes(dos.getOctets())) == null) {
System.out.println("FAIL");
return;
}
for (String content : contents) {
System.out.println(content);
}
}
}
}

View file

@ -5,9 +5,19 @@ require 'java'
Dir[File.join(BASE_DIR,'lib/*jar')].each {|j| require j } Dir[File.join(BASE_DIR,'lib/*jar')].each {|j| require j }
Dir[File.join(BASE_DIR,'target/*jar')].each {|j| require j } Dir[File.join(BASE_DIR,'target/*jar')].each {|j| require j }
require 'openssl'
require 'stringio' require 'stringio'
require 'optparse' require 'optparse'
import java.io.BufferedInputStream
import java.io.FileInputStream
import java.security.cert.X509Certificate
import java.security.cert.CertificateFactory
import org.bouncycastle.asn1.DEROctetString
import org.bouncycastle.asn1.ASN1Encodable
import org.bouncycastle.x509.extension.X509ExtensionUtil
module Trie module Trie
include_package 'com.redhat.trie' include_package 'com.redhat.trie'
end end
@ -44,12 +54,31 @@ def write_children(io, node)
end end
end end
def get_end(node) # PrettyPrint a PathNode or HuffNode tree
return node if node.getChildren().length == 0 def printTree(node, tab)
nodeRep = " " * tab
nodeRep += "Node [#{node.getId}]"
nodeRep += ", Weight [#{node.getWeight}]" if node.respond_to? :getWeight
nodeRep += ", Value = [#{node.getValue}]" if node.respond_to? :getValue
node.getParents.each do |parent|
nodeRep += " ^ [#{parent.getId}]"
end if node.respond_to? :getParents
node.getChildren.each do |child| node.getChildren.each do |child|
return get_end(child.getConnection()) nodeRep += " v [#{child.getName} {#{child.getId}}]"
end if node.respond_to? :getChildren
puts nodeRep
node.getChildren.each do |child|
printTree(child.getConnection, tab+1)
end if node.respond_to? :getChildren
if node.respond_to?(:getLeft) and node.respond_to?(:getRight)
printTree(node.getLeft, tab+1) if node.getLeft != nil
printTree(node.getRight, tab+1) if node.getRight != nil
end end
end end
def parse_args(args) def parse_args(args)
options = { options = {
:content_list => './src/test/resources/contents.list', :content_list => './src/test/resources/contents.list',
@ -63,9 +92,15 @@ def parse_args(args)
opts.on('--contents FILE', "use FILE instead of #{options[:content_list]}") do |o| opts.on('--contents FILE', "use FILE instead of #{options[:content_list]}") do |o|
options[:content_list] = o options[:content_list] = o
end end
opts.on('--cert FILE', "read contents from certificate FILE") do |o|
options[:certificate] = o
end
opts.on('--test PATH', "validate PATH, instead of [#{options[:test_url]}]") do |o| opts.on('--test PATH', "validate PATH, instead of [#{options[:test_url]}]") do |o|
options[:test_url] = o options[:test_url] = o
end end
opts.on('--print', "print the tree of contents") do |o|
options[:printTree] = o
end
end end
opts.parse!(args) opts.parse!(args)
@ -73,6 +108,36 @@ def parse_args(args)
return options return options
end end
# ick, using java to do SSL
def object_from_oid(cert, oid)
return unless cert
cert.getNonCriticalExtensionOIDs.each do |o|
if o == oid
return X509ExtensionUtil.fromExtensionValue(cert.getExtensionValue(o))
end
end
return nil
end
# ick, using java to do SSL
def value_from_oid(filename, oid)
bis = BufferedInputStream.new(FileInputStream.new(filename))
cf = CertificateFactory.getInstance("X.509")
cert = cf.generateCertificate(bis) # this is an X509Certificate
object_from_oid(cert, oid)
end
# not working on jRuby. :-(
# https://github.com/jruby/jruby/issues/389
def value_from_oid_bunk(filename, oid)
cert = OpenSSL::X509::Certificate.new(File.read(filename))
ext = cert.extensions.detect {|ext| ext.oid == oid }
return if ext.nil?
return OpenSSL::ASN1.decode(OpenSSL::ASN1.decode(ext.to_der).value[1].value).value
end
def main(args) def main(args)
options = parse_args(args) options = parse_args(args)
@ -80,8 +145,15 @@ def main(args)
puts print_dot(pt(options[:content_list]).getRootPathNode()).read() if options[:dot] puts print_dot(pt(options[:content_list]).getRootPathNode()).read() if options[:dot]
#pn = pt.getRootPathNode if options[:printTree]
#Trie::Util.printTree(pn, 0) pn = pt.getRootPathNode
printTree(pn, 0)
end
if options[:certificate]
data = value_from_oid(options[:certificate], '1.3.6.1.4.1.2312.9.7')
pt = Trie::PathTree.new(data.getOctets)
puts pt.toList()
end
end end
main(ARGV) if $0 == __FILE__ main(ARGV) if $0 == __FILE__