Commit 52ed7ba1 authored by David Johnson's avatar David Johnson

Take a checkpoint of the motelogging stuff. Add some code for ssl

connections and parsing mig-generated packet specs.
parent 1151742a
import javax.net.ssl.*;
import java.io.*;
import java.security.cert.*;
import java.security.*;
import java.util.Arrays;
public class ElabTrustManager implements X509TrustManager {
private static final String CA_CERT = "/etc/emulab/client.pem";
private static final String CLIENT_CERT = "/etc/emulab/emulab.pem";
private byte[] digest;
public ElabTrustManager()
throws FileNotFoundException, CertificateException,
NoSuchAlgorithmException, CertificateEncodingException {
this(new File(CLIENT_CERT));
}
public ElabTrustManager(File certFile)
throws FileNotFoundException, CertificateException,
NoSuchAlgorithmException, CertificateEncodingException {
InputStream is = new FileInputStream(certFile);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate)cf.generateCertificate(is);
MessageDigest md = MessageDigest.getInstance("SHA");
this.digest = md.digest(cert.getEncoded());
}
public ElabTrustManager(String digest) {
this(hexToBytes(digest));
}
public ElabTrustManager(byte[] digest) {
this.digest = digest;
}
/**
* Radix for hexadecimal numbers.
*/
private static final int HEX_RADIX = 16;
/* from tim... */
/**
* Convert a hexadecimal encoded string into a byte array.
*
* TODO: Move elsewhere...
*
* @param str The hexadecimal encoded string to convert.
* @return The byte array that was encoded in the given string.
* @throws NumberFormatException If there was a problem while decoding the
* string.
*/
private static byte[] hexToBytes(String str)
throws NumberFormatException
{
byte retval[] = new byte[str.length() / 2];
int lpc;
for( lpc = 0; lpc < retval.length; lpc++ )
{
int lo, hi;
hi = Character.digit(str.charAt(lpc * 2), HEX_RADIX);
lo = Character.digit(str.charAt(lpc * 2 + 1), HEX_RADIX);
if( hi == -1 || lo == -1 )
throw new NumberFormatException(str);
retval[lpc] = (byte) ((hi << 4) | lo);
}
return retval;
}
public void checkClientTrusted(X509Certificate chain[], String authType) {
}
public void checkServerTrusted(X509Certificate chain[], String authType)
throws CertificateException {
try {
MessageDigest md = MessageDigest.getInstance("SHA");
byte certHash[];
/** we DO NOT try to auth the server, just check its consistency */
certHash = md.digest(chain[0].getEncoded());
if( !Arrays.equals(certHash, this.digest) ) {
System.out.println("bad certificate!");
throw new CertificateException(
"Certificate for "
+ chain[0].getSubjectDN()
+ " does not match finger print");
}
}
catch(NoSuchAlgorithmException e) {
throw new CertificateException(
"Unable to verify certificate because: " + e.getMessage());
}
}
// don't need this...
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public String toString() {
return "ElabTrustManager[digest="+this.digest+"]";
}
}
import java.util.*;
public class FieldInfo {
public static int TYPE_NONE = 0;
public static int TYPE_INT = 1;
public static int TYPE_UNSIGNED = 2;
public static int TYPE_FLOAT = 3;
public static int TYPE_DOUBLE = 4;
public static int TYPE_LONG_DOUBLE = 5;
public static int TYPE_STRUCT = 6;
public static int TYPE_UNION = 7;
public static int TYPE_UNKNOWN = 8;
public static String[] typeNames = {
"none",
"signed",
"unsigned",
"float",
"double",
"long double",
"struct",
"union",
"unknown",
};
String name;
String fullName;
FieldInfo parent;
Vector children;
int type;
int[] dim;
public FieldInfo() {
this.name = null;
this.fullName = null;
this.parent = null;
this.children = new Vector();
this.type = TYPE_NONE;
this.dim = null;
}
public static int getTypeForSpecString(String specType) {
if (specType.equals("U")) {
return FieldInfo.TYPE_UNSIGNED;
}
else if (specType.equals("I")) {
return FieldInfo.TYPE_INT;
}
else if (specType.equals("F")) {
return FieldInfo.TYPE_FLOAT;
}
else if (specType.equals("D")) {
return FieldInfo.TYPE_DOUBLE;
}
else if (specType.equals("LD")) {
return FieldInfo.TYPE_LONG_DOUBLE;
}
else if (specType.equals("AS")) {
return FieldInfo.TYPE_STRUCT;
}
else if (specType.equals("AU")) {
return FieldInfo.TYPE_UNION;
}
else {
return FieldInfo.TYPE_UNKNOWN;
}
}
public static String getTypeName(int type) {
if (type > TYPE_NONE && type < TYPE_UNKNOWN) {
return typeNames[type];
}
else {
return typeNames[TYPE_UNKNOWN];
}
}
public void addChild(FieldInfo child) {
children.add(child);
}
public Enumeration getChildren() {
return children.elements();
}
public String toString() {
String retval = "" + this.name + "("+ getTypeName(this.type) + ")";
if (isArray()) {
for (int i = 0; i < dim.length; ++i) {
retval += "[" + dim[i] + "]";
}
}
return retval;
}
public FieldInfo getParent() {
return this.parent;
}
public boolean isBasic() {
if (this.type == FieldInfo.TYPE_INT
|| this.type == FieldInfo.TYPE_UNSIGNED
|| this.type == FieldInfo.TYPE_FLOAT
|| this.type == FieldInfo.TYPE_DOUBLE
|| this.type == FieldInfo.TYPE_LONG_DOUBLE) {
return true;
}
else {
return false;
}
}
public boolean isStruct() {
if (this.type == FieldInfo.TYPE_STRUCT) {
return true;
}
else {
return false;
}
}
public boolean isUnion() {
if (this.type == FieldInfo.TYPE_UNION) {
return true;
}
else {
return false;
}
}
public boolean isArray() {
if (this.dim != null && this.dim.length > 0) {
return true;
}
else {
return false;
}
}
public void print(int depth) {
for (int i = 0; i < depth; ++i) {
System.out.print(" ");
}
System.out.println(this.toString());
for (Enumeration e = this.getChildren(); e.hasMoreElements(); ) {
FieldInfo fi = (FieldInfo)e.nextElement();
fi.print(depth+1);
}
}
}
This diff is collapsed.
import java.util.*;
import java.io.*;
import java.util.regex.*;
/**
*
* Parses spec files generated by ncc, the nesc parser. These specs are dumped
* out from mig separately from the generated msg stub file. We parse them
* so as to ascertain structure/array layout for each msg structure; this info
* allows more effective organization of database packet tables.
*
* if (type_complex(t))
* {
* printf("C");
* t = make_base_type(t);
* }
*
* Enums treated as ints for now
* if (type_integer(t))
* if (type_unsigned(t))
* printf("U");
* else
* printf("I");
*else if (type_float(t))
* printf("F");
*else if (type_double(t))
* printf("D");
*else if (type_long_double(t))
* printf("LD");
*else if (type_union(t))
* printf("AU");
*else if (type_struct(t))
* printf("AS");
*else if (type_pointer(t))
* printf("U");
*
*/
public class NCCSpecParser {
public static void main(String[] args) throws Exception {
SpecData sd = NCCSpecParser.parseSpecFile(new File(args[0]));
sd.getRoot().print(0);
}
protected NCCSpecParser() { }
private static void debug(int level,String msg) {
MoteLogger.globalDebug(level,"NCCSpecParser: " + msg);
}
private static void error(String msg) {
MoteLogger.globalError("NCCSpecParser: " + msg);
}
public static SpecData parseSpecFile(File specFile) throws Exception {
ArrayList lines = new ArrayList();
String specLines[] = null;
if (specFile.canRead()) {
// read it in...
BufferedReader br = null;
String line = null;
try {
int j = 0;
br = new BufferedReader(new FileReader(specFile));
while ((line = br.readLine()) != null) {
lines.add(j,line);
++j;
}
specLines = new String[lines.size()];
for (int i = 0; i < specLines.length; ++i) {
specLines[i] = (String)lines.get(i);
}
}
catch (Exception e) {
specLines = null;
error("problem reading file " + specFile);
e.printStackTrace();
}
}
else {
throw new Exception("could not read file " + specFile);
}
return parseSpec(specLines);
}
public static SpecData parseSpec(String[] lines) throws Exception {
FieldInfo root = new FieldInfo();
String specName = null;
int rootType = FieldInfo.TYPE_UNKNOWN;
Stack stack = new Stack();
FieldInfo currentElm = root;
for (int i = 0; i < lines.length; ++i) {
if (lines[i].equals("")) {
continue;
}
String[] s = lines[i].split("[ \t]+");
int firstNonEmptyIdx = -1;
if (s != null && s.length > 1) {
int idx = 0;
while (idx < s.length) {
if (!s[idx].equals("")) {
firstNonEmptyIdx = idx;
break;
}
++idx;
}
if (idx < s.length-1) {
String tmp[] = new String[s.length - firstNonEmptyIdx];
System.arraycopy(s,firstNonEmptyIdx,tmp,0,tmp.length);
s = tmp;
}
}
else {
continue;
}
// pretty basic here.... there's not a lot of possibilities:
if (s.length == 2) {
// probably we are closing an aggregate type:
if (s[1].equals("AX")) {
String fieldName = s[0];
if (!stack.empty()) {
String top = (String)stack.peek();
if (!top.equals(fieldName)) {
throw new Exception("end of aggregate field for " +
"field " + fieldName + " " +
"does not match expected " +
"field " + top + " at " +
"line " + (i+1));
}
else {
//debug(1,"finished complex type " + fieldName);
stack.pop();
// move back up an element:
currentElm = currentElm.getParent();
}
}
else {
throw new Exception("end of aggregate field for " +
"field " + fieldName + ", but " +
"no corresponding match at line " +
(i+1));
}
}
else {
throw new Exception("unrecognized spec, line " + (i+1));
}
}
else if (s.length == 4) {
if (s[0].equals("struct")) {
specName = s[1];
rootType = FieldInfo.TYPE_STRUCT;
}
else if (s[0].equals("union")) {
specName = s[1];
rootType = FieldInfo.TYPE_UNION;
}
else {
FieldInfo nF = new FieldInfo();
nF.parent = currentElm;
nF.fullName = s[0];
String bF[] = s[0].split("\\.");
if (bF != null && bF.length > 1) {
nF.name = bF[bF.length-1];
}
else {
nF.name = s[0];
}
String typeName = s[1];
// figure out what this field is:
String arrayIdxStr = "\\[(\\d)+\\]";
Pattern arrayIdx = Pattern.compile(arrayIdxStr);
String typeStr = "(U|I|F|D|LD|AU|AS)";
Pattern type = Pattern.compile(typeStr);
int lastBracketIdx = -1;
if ((lastBracketIdx = typeName.lastIndexOf("]")) != -1) {
Matcher m = arrayIdx.matcher(typeName);
// find the dimensions:
int[] dims = new int[256];
int j = 0;
while (m.find() && j < dims.length) {
dims[j] = Integer.parseInt(m.group(1));
++j;
}
if (j == dims.length) {
throw new Exception("more than 256 dimensions!");
}
nF.dim = new int[j];
System.arraycopy(dims,0,nF.dim,0,j);
}
else {
lastBracketIdx = 0;
}
// now get the type:
Matcher m = type.matcher(typeName.substring(lastBracketIdx,
typeName.length()));
if (m.find()) {
nF.type = FieldInfo.getTypeForSpecString(m.group(1));
if (nF.type == FieldInfo.TYPE_UNKNOWN) {
throw new Exception("unrecognized type " +
typeName + ", line " + (i+1));
}
}
else {
throw new Exception("unrecognized type " + typeName +
", line " + (i+1));
}
// see if we have a parent...
if (currentElm != null) {
currentElm.addChild(nF);
}
// see if we will have children for the new field:
if (nF.type == FieldInfo.TYPE_STRUCT
|| nF.type == FieldInfo.TYPE_UNION) {
stack.push(nF.fullName);
currentElm = nF;
}
}
}
else {
for (int k = 0; k < s.length; ++k) {
System.out.print("'" + s[k] + "' ");
}
System.out.println();
throw new Exception("unknown field format, line " + (i+1));
}
}
return new SpecData(specName,rootType,root);
}
}
......@@ -112,7 +112,7 @@ public final class PacketReader {
// read byte -- let the exception fly through to the caller
int b = (int)in.read();
debug(4,"read byte: "+b);
debug(5,"read byte: "+b);
if (b == ESCAPE_BYTE) {
isEscaped = true;
......
This diff is collapsed.
public class SpecData {
private FieldInfo root;
private String specName;
private int type;
public SpecData(String specName,int specType,FieldInfo root) {
this.root = root;
this.specName = specName;
this.type = specType;
}
public FieldInfo getRoot() {
return this.root;
}
public String getSpecName() {
return this.specName;
}
public int getType() {
return this.type;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment