Explorar o código

Initial Commit

Thomas Flucke %!s(int64=6) %!d(string=hai) anos
achega
8f36f69fa4
Modificáronse 50 ficheiros con 3879 adicións e 0 borrados
  1. 10 0
      .gitignore
  2. 5 0
      data/file2datetime.sh
  3. 8 0
      data/getData.sh
  4. 13 0
      data/match-flows.sh
  5. 63 0
      irb/informed-concent-1.md
  6. 63 0
      irb/informed-concent-2.md
  7. 49 0
      irb/informed-concent.md
  8. 137 0
      irb/research-methods.md
  9. 82 0
      irb/testing-instructions.md
  10. 40 0
      notes/cassh.md
  11. 211 0
      notes/notes.md
  12. 21 0
      src/common/Makefile
  13. 52 0
      src/common/timecap.c
  14. 21 0
      src/common/timecap.h
  15. 1 0
      src/flow-seperator
  16. 19 0
      src/packet-matcher/Makefile
  17. 271 0
      src/packet-matcher/getPackets.c
  18. 150 0
      src/packet-matcher/linkedList.c
  19. 40 0
      src/packet-matcher/linkedList.h
  20. BIN=BIN
      src/packet-matcher/packet-matcher
  21. 1 0
      systems/mitm/home/keylog/.ssh/authorized_keys
  22. 8 0
      systems/mitm/home/keylog/bin/keylog.sh
  23. 8 0
      systems/mitm/openvpn/easy-rsa/build-ca
  24. 11 0
      systems/mitm/openvpn/easy-rsa/build-dh
  25. 7 0
      systems/mitm/openvpn/easy-rsa/build-inter
  26. 7 0
      systems/mitm/openvpn/easy-rsa/build-key
  27. 7 0
      systems/mitm/openvpn/easy-rsa/build-key-pass
  28. 8 0
      systems/mitm/openvpn/easy-rsa/build-key-pkcs12
  29. 10 0
      systems/mitm/openvpn/easy-rsa/build-key-server
  30. 7 0
      systems/mitm/openvpn/easy-rsa/build-req
  31. 7 0
      systems/mitm/openvpn/easy-rsa/build-req-pass
  32. 16 0
      systems/mitm/openvpn/easy-rsa/clean-all
  33. 39 0
      systems/mitm/openvpn/easy-rsa/inherit-inter
  34. 13 0
      systems/mitm/openvpn/easy-rsa/list-crl
  35. 268 0
      systems/mitm/openvpn/easy-rsa/openssl-0.9.6.cnf
  36. 293 0
      systems/mitm/openvpn/easy-rsa/openssl-0.9.8.cnf
  37. 288 0
      systems/mitm/openvpn/easy-rsa/openssl-1.0.0.cnf
  38. 288 0
      systems/mitm/openvpn/easy-rsa/openssl.cnf
  39. 399 0
      systems/mitm/openvpn/easy-rsa/pkitool
  40. 43 0
      systems/mitm/openvpn/easy-rsa/revoke-full
  41. 7 0
      systems/mitm/openvpn/easy-rsa/sign-req
  42. 80 0
      systems/mitm/openvpn/easy-rsa/vars
  43. 26 0
      systems/mitm/openvpn/easy-rsa/whichopensslcnf
  44. 321 0
      systems/mitm/openvpn/thesis.conf
  45. 58 0
      systems/mitm/openvpn/update-resolv-conf
  46. 209 0
      systems/mitm/usr/local/bin/packetTap.sh
  47. 127 0
      systems/victim/etc/openvpn/client.conf
  48. 1 0
      systems/victim/keylog_rsa.pub
  49. 24 0
      systems/victim/usr/local/bin/routing-rest.sh
  50. 42 0
      systems/victim/usr/local/bin/ssh

+ 10 - 0
.gitignore

@@ -0,0 +1,10 @@
+data/*/
+[a-zA-z0-9\-_]*_rsa
+*~
+*.key
+*.crt
+*.pem
+*.o
+*.a
+*.so
+*.pdf

+ 5 - 0
data/file2datetime.sh

@@ -0,0 +1,5 @@
+#!/bin/sh
+
+grep -o '[0-9]*\.log' |
+    xargs -i basename {} .log |
+    sed 's/.\{12\}/&:/;s/.\{10\}/&:/;s/.\{8\}/& /;s/.\{6\}/&-/;s/.\{4\}/&-/'

+ 8 - 0
data/getData.sh

@@ -0,0 +1,8 @@
+#!/bin/sh
+
+readonly SERVER="tf2.csc.calpoly.io"
+readonly DIR=$(dirname $0)
+
+mkdir -p $DIR/keylogs $DIR/packets
+scp -ri ~/.ssh/keylog_rsa keylog@$SERVER:~/data/* $DIR/keylogs/
+scp -ri ~/.ssh/keylog_rsa keylog@$SERVER:/var/log/tcpdump/*.pcap $DIR/packets

+ 13 - 0
data/match-flows.sh

@@ -0,0 +1,13 @@
+#!/bin/sh
+
+readonly BASE_DIR="$(dirname $0)"
+readonly MATCHER="$BASE_DIR/../packet-matcher/packet-matcher"
+
+for k in "$BASE_DIR"/keylogs/*/*.log; do
+    outdir="$BASE_DIR/timings/$(basename $(dirname $k))"
+    outfile="$outdir/$(basename $k)"
+    mkdir -p "$outdir" > /dev/null
+    if ! "$MATCHER" "$k" flows/*.pcap > "$outfile"; then
+        rm "$outfile"
+    fi
+done

+ 63 - 0
irb/informed-concent-1.md

@@ -0,0 +1,63 @@
+# INFORMED CONSENT TO PARTICIPATE IN A RESEARCH PROJECT
+## “Investigating SSH Information Leaks (Dataset 1)”
+This form asks for your agreement to participate in a research project for
+SecureShell.  Your participation involves using the SecureShell program over a
+monitored network to type sentences and run commands from the attached document. 
+
+These tasks are expected to take approximately 30 minutes. If you stop early
+your data may not be used. There are no risks anticipated with your
+participation. Those in the cybersecurity, system administration and software
+development industries may benefit from your participation. If you are
+interested in participating, please review the following information:
+
+The purpose of the study is to examine if the pattern of network traffic
+from SecureShell is unique to a user such that an outside party can identify
+them. Additionally, this study will examine if the timing of publicly visible
+network traffic can be used to identify keystrokes.  Potential benefits
+associated with the study include improvements in secure internet
+communications.
+
+If you agree to participate, you will be asked to complete the attached set of
+instructions.  This research involves finding vulnerabilities in the
+SecureShell protocol and as such anything you type in the SecureShell
+application as part of this study will be recorded for validation purposes.
+You are advised to not type any passwords or otherwise sensitive information
+into a terminal being used as part of this study.
+
+Please be aware that you are not required to participate in this research,
+refusal to participate will not involve any penalty or loss of benefits to
+which you are otherwise entitled, and you may discontinue your participation
+at any time. Your participation or refusal will not contribute or impact your
+grade in any of your classes.  The focus of this study is on the behavior of
+the SecureShell system and thus your responses to prompts and inputs to the
+terminal are only incidentally involved in the study.  There are no risks
+anticipated with your participation in this study, as your data will be
+maintained confidentially.
+
+This research is being conducted by Dr. Bruce DeBruhl and graduate student Thomas
+Flucke in the Department of Computer Science and Software Engineering at Cal Poly,
+San Luis Obispo. If you have questions regarding this study or would like to be
+informed of the results when the study is completed, please contact Dr. DeBruhl at
+bdebruhl@calpoly.edu.  If you have concerns regarding the manner in which the
+study is conducted, you may contact Dr. Michael Black, Chair of the Cal Poly
+Institutional Review Board, at (805) 756-2894, mblack@calpoly.edu, or Ms. Debbie
+Hart, Compliance Officer, at (805) 756-1508, dahart@calpoly.edu.
+
+If you agree to voluntarily participate in this research project as described,
+please indicate your agreement by performing one or more tasks from above when
+the researcher tells you. Please keep a copy of this form for your reference, 
+and thank you for your participation in this research.
+
+
+<div style="float: left;">
+Name:<br />
+<br />
+<br />
+_________________________________________________________
+</div>
+<div style="float: left; margin-left: 2em;">
+Date:<br />
+<br />
+<br />
+_____________________
+</div>

+ 63 - 0
irb/informed-concent-2.md

@@ -0,0 +1,63 @@
+# INFORMED CONSENT TO PARTICIPATE IN A RESEARCH PROJECT
+## “Investigating SSH Information Leaks (Dataset 2)”
+This form asks for your agreement to participate in a research project for
+SecureShell.  Your participation involves completing your class work using
+the SecureShell program over a monitored network from a virtual machine. 
+
+The experiment is not expected to hinder your ability to complete your
+assignments and will not require more than a negligible amount of time to
+participate beyond that you would normally take to do your class work.  If you
+stop early your data may not be used. There are no risks anticipated with your
+participation. Those in the cybersecurity, system administration and software
+development industries may benefit from your participation. If you are interested
+in participating, please review the following information:
+
+The purpose of the study is to examine if the pattern of network traffic
+from SecureShell is unique to a user such that an outside party can identify
+them. Additionally, this study will examine if the timing of publicly visible
+network traffic can be used to identify keystrokes.  Potential benefits
+associated with the study include improvements in secure internet
+communications.
+
+If you agree to participate, you will be asked to use the provided virtual
+machine to complete your classwork.  This research involves finding
+vulnerabilities in the SecureShell protocol and as such anything you type
+in the SecureShell application as part of this study will be recorded for
+validation purposes.  You are advised to not type any passwords or otherwise
+sensitive information into a terminal being used as part of this study.
+
+Please be aware that you are not required to participate in this research,
+refusal to participate will not involve any penalty or loss of benefits to
+which you are otherwise entitled, and you may discontinue your participation
+at any time. Your participation or refusal will not contribute or impact your
+grade in any of your classes.  The focus of this study is on the behavior of
+the SecureShell system and thus your inputs to the terminal are only
+incidentally involved in the study.  There are no risks anticipated with your
+participation in this study, as your data will be maintained confidentially.
+
+This research is being conducted by Dr. Bruce DeBruhl and graduate student Thomas
+Flucke in the Department of Computer Science and Software Engineering at Cal Poly, San Luis Obispo. If you have questions regarding this study or would like to be
+informed of the results when the study is completed, please contact Dr. DeBruhl
+at bdebruhl@calpoly.edu.  If you have concerns regarding the manner in which the
+study is conducted, you may contact Dr. Michael Black, Chair of the Cal Poly
+Institutional Review Board, at (805) 756-2894, mblack@calpoly.edu, or Ms. Debbie
+Hart, Compliance Officer, at (805) 756-1508, dahart@calpoly.edu.
+
+If you agree to voluntarily participate in this research project as described,
+please indicate your agreement by performing one or more tasks from above when
+the researcher tells you. Please keep a copy of this form for your reference, 
+and thank you for your participation in this research.
+
+
+<div style="float: left;">
+Name:<br />
+<br />
+<br />
+_________________________________________________________
+</div>
+<div style="float: left; margin-left: 2em;">
+Date:<br />
+<br />
+<br />
+_____________________
+</div>

+ 49 - 0
irb/informed-concent.md

@@ -0,0 +1,49 @@
+# INFORMED CONSENT TO PARTICIPATE IN A RESEARCH PROJECT
+## “Investigating SSH Information Leaks (Dataset 1)”
+This form asks for your agreement to participate in a research project for
+SecureShell.  Your participation involves using the SecureShell program over a
+monitored network to type sentences run commands from the attached document. 
+
+These tasks are expected to take approximately 30 minutes. If you stop early
+your data may not be used. There are no risks anticipated with your
+participation. Those in the cybersecurity, system administration and software
+development industries may benefit from your participation. If you are
+interested in participating, please review the following information:
+
+The purpose of the study is to examine if the pattern of network traffic
+from SecureShell is unique to a user such that an outside party can identify
+them. Additionally, this study will examine if the timing of publicly visible
+network traffic can be used to identify keystrokes.  Potential benefits
+associated with the study include improvements in secure internet
+communications.
+
+If you agree to participate, you will be asked to complete the attached set of
+instructions.  This research involves finding vulnerabilities in the
+SecureShell protocol and as such anything you type in the SecureShell
+application as part of this study will be recorded for validation purposes.
+You are advised to not type any passwords or otherwise sensitive information
+into a terminal being used as part of this study.
+
+Please be aware that you are not required to participate in this research,
+refusal to participate will not involve any penalty or loss of benefits to
+which you are otherwise entitled, and you may discontinue your participation
+at any time. Your participation or refusal will not contribute or impact your
+grade in any of your classes.  The focus of this study is on the behavior of
+the SecureShell system and thus your responses to prompts and inputs to the
+terminal are only incidentally involved in the study.  There are no risks
+anticipated with your participation in this study, as your data will be
+maintained confidentially.
+
+This research is being conducted by Dr. Bruce DeBruhl in the Department of
+Computer Science and Software Engineering at Cal Poly, San Luis Obispo. If you
+have questions regarding this study or would like to be informed of the results
+when the study is completed, please contact Dr. DeBruhl at bdebruhl@calpoly.edu.
+If you have concerns regarding the manner in which the study is conducted, you
+may contact Dr. Michael Black, Chair of the Cal Poly Institutional Review Board,
+at (805) 756-2894, mblack@calpoly.edu, or Ms. Debbie Hart, Compliance Officer,
+at (805) 756-1508, dahart@calpoly.edu.
+
+If you agree to voluntarily participate in this research project as described,
+please indicate your agreement by performing one or more tasks from above when
+the researcher tells you. Please keep a copy of this form for your reference, 
+and thank you for your participation in this research.

+ 137 - 0
irb/research-methods.md

@@ -0,0 +1,137 @@
+# Investigating SSH Information Leaks
+## Primary Investigator
+Thomas Flucke
+
+Department of Computer Science and Software Engineering, College of Engineering
+
+## Faculty Advisor
+Bruce DeBruhl
+
+Department of Computer Science and Software Engineering, College of Engineering
+
+## Statement of Purpose, benefits, and hypotheses
+In this experiment, I plan to explore possible data leaks in the common secure
+communications
+program SecureShell (SSH).  This program is commonly used in industry and within
+Cal Poly as a means of creating secure connections between a user and a remote
+computer.  I hypothesize that the current implementation is flawed in such a way
+that I can use publicly visible patterns in encrypted internet traffic to discover
+information such as who is using the program and the content of the encrypted
+data.  I will test this hypothesis with an experiment which involves having
+participants type into the SecureShell program.  The participants would be
+volunteers among students in the computer science department.  The risk to
+volunteers is minimal and the potential discovery is significant.  The data will
+be collected in an environment isolated from their personal computer.  Data will
+be anonymized to not contain any personal identifiable information.
+
+## Methods
+### Subjects and Subject Characteristics
+Volunteers will be gathered from systems classes in the Cal Poly C.S. department.
+These classes will be upper-division classes related to systems and security
+programming.  All of the classes will have Systems Programming (CPE 357) as a
+prerequisite or be the Systems Programming class.
+
+### Investigators
+Thomas Flucke, Student, California Polytechnic State University, College of
+Engineering, Department of Computer Science and Software Engineering
+
+### Materials and Procedures
+#### Materials
+A "router" which records encrypted traffic and forwards it to it's destination.
+The router will be configured to only accept connections involved in this study
+and will only store encrypted information.
+
+A virtual machine with a key logger installed and configured to send traffic
+through the "router".  The virtual machine isolates monitors used in this study
+from materials unrelated to this work.
+
+### Procedure
+#### Dataset 1
+##### Before the Experiment
+Volunteer will be provided consent form 1 and an explanation of the experiment and
+how the information they provide will be used.
+
+##### During the Experiment
+Volunteers will respond to a series of prompts with complete English sentences.
+Prompts will not ask for any personally identifiable information.  This will
+provide a baseline of data for network traffic patterns of normal English typing.
+Then the experimenter will ask the volunteer to copy an English paragraph into the
+terminal.  This will provide a more structured dataset which eliminates
+variations between respondents.  Because this instruction is more strict than
+the prior instruction, the typing patterns may be skewed, altering data generated
+by typing and thus both are necessary. The volunteer will enter their responses
+into a monitored terminal with a SecureShell connection to the computer science
+department's servers over the internet.  The router will observe public network
+traffic of the connection and record the data.
+
+Then the volunteer will be asked to perform a few basic tasks over the
+SecureShell connection.  This will provide data for the traffic generated by
+normal usage of SecureShell.  Afterwards volunteers will execute a series of basic
+Unix commands over the SecureShell connection.  This is important to provide a
+similar structured baseline for comparison as with the English paragraph, but in
+the context of Unix commands rather than English.  Again both the volunteers'
+inputs and network traffic will be monitored and recorded.
+
+In total, responding to the prompts should not take more than 30 minutes.  The
+test can be paused if the volunteer requests a break.
+
+An investigator will be present for the entire test to give directions and
+clarifications.
+
+Volunteers will be permitted to make adjustments to the chair, table, or other
+surroundings in order to make themselves more comfortable.
+
+The volunteer's data will be marked with a one-way-encrypted hash of their Cal Poly
+username.  This allows the data to be uniquely identified without risk of
+connecting the data to a particular volunteer or exposing the volunteer's
+participation in this study.
+
+#### Dataset 2
+##### Before the Experiment
+Volunteers will be provided consent form 2 and an explanation of the experiment and
+how the information they provide will be used.
+
+Volunteers will be provided a virtual computer described above and informed that
+any information entered into the computer will be recorded.  The volunteer will be
+discouraged from using the virtual machine for purposes unrelated to the study.
+The Volunteer will be informed that their usage of SecureShell is not the subject
+of study.
+
+If a volunteer does use the virtual machine for any purpose not related to the
+study, the extraneous data generated will be filtered from the dataset.  If the
+data cannot be filtered, the volunteer's contributions will be discarded.
+
+Volunteers will also be informed that their participation or refusal in the study
+does not impact their grade and will not hinder their ability to complete their
+classwork.
+
+##### During the Experiment
+Volunteers will perform their normal class work using the virtual machine as the
+terminal to the school server.  Once on the school server, the volunteer will
+complete their class work as they otherwise would.  This data will provide an
+organic dataset which represents real world use cases of SecureShell.
+
+The additional time to complete the tasks while participating in this study is
+negligible.
+
+An investigator will be present for the entire test to give directions and
+clarifications.
+
+The volunteer's data will be marked with a one-way-encrypted hash of their Cal Poly
+username.  This allows the data to be uniquely identified without risk of
+connecting the data to a particular volunteer or exposing the volunteer's
+participation in this study.
+
+### Study Location
+The participants of the study will perform their work on Cal Poly campus.
+Dataset 1 will be gathered with the participants physically in the Cal Poly
+computer Science building 14.  Dataset 2 will be collected in the volunteer's
+usual classroom setting.  Additionally, data will be recorded on a router hosted
+on Amazon Web Services (AWS) on the internet.
+
+### Informed Consent Form
+All participants will be asked for informed consent before participating.
+Participants in both datasets will be asked to sign both informed consent forms.
+
+### Debriefing Statement for Projects Involving Deception and Incomplete Disclosure
+No deception or incomplete disclosure will be involved in this project.

+ 82 - 0
irb/testing-instructions.md

@@ -0,0 +1,82 @@
+## Instructions for Participants (Dataset 1)
+### Protocol:
+
+1. Provide the informed consent form and describe the nature of the study.
+2. Provide the Loose-Instructed English prompts
+3. Provide the Strict-Instructed English prompts
+4. Provide the Loose-Instructed Unix Shell prompts
+5. Provide the Strict-Instructed Unix Shell prompts
+6. Tag data with sha256 hash of Cal Poly username
+
+#### Loose-Instructed English Language
+Please answer the following prompts with a complete, English sentence.
+
+1. Describe a T.V. show character.
+2. What is the weather outside today?
+3. Describe the inside of a restaurant.
+4. Who is the current president of the United States?
+5. Describe to an extra terrestrial how to use a microwave oven.
+6. Describe the time without using a clock.
+7. What is the name of a sport team and what sport do they play?
+8. Choose an animal and give a brief description of it.
+
+#### Strict-Instructed English Language
+Write the following paragraph:
+
+>It was the best of times, it was the worst of times, it was the age of wisdom,
+>it was the age of foolishness, it was the epoch of belief, it was the epoch of
+>incredulity, it was the season of Light, it was the season of Darkness, it was
+>the spring of hope, it was the winter of despair, we had everything before us,
+>we had nothing before us, we were all going direct to Heaven, we were all
+>going direct the other way--in short, the period was so far like the present
+>period, that some of its noisiest authorities insisted on its being received,
+>for good or for evil, in the superlative degree of comparison only.
+
+#### Loose-Instructed Shell
+Perform the following tasks over an SSH session
+
+1. Create a directory named 'foo'
+2. Create an empty file in foo named 'bar'
+3. Write a C program in foo which prints "Hello World" to the terminal
+4. Compile the program to an executable named, "greet"
+5. Run greet
+6. Run greet and redirect the output to a file in foo
+7. Check that the output from greet and foo/bar are different
+8. Delete foo/bar
+9. Print your current directory
+10. Make a subdirectory of foo named bar/biz/boo
+11. Change your current directory to boo
+12. Write "Hello World" to a file
+13. Compare that file with the output of greet
+14. Print the contents of the foo directory
+15. Change your current directory to foo
+
+#### Strict-Instructed Shell
+Enter the following commands over an SSH session
+
+1. `mkdir testsess1`
+2. `whoami`
+3. `touch testsess1/file.txt`
+4. `echo Hello World > testsess1/file.txt`
+5. `cp --verbose testsess1/file.txt testsess1/copy.txt`
+6. `diff -q testsess1/file.txt testsess1/copy.txt`
+7. `basename testsess1/copy.txt`
+8. `egrep -i wo testsess1/copy.txt`
+9. `cat > source.c`
+
+    ```
+    int main() {
+      int a = 7;
+      int b = 2;
+      return a - b;
+    }
+    ```
+10. `gcc -g source.c`
+11. `./a.out`
+12. `echo $?`
+13. `mv a.out testprog`
+14. `zip -j out.zip testsess1 source.c`
+15. `which vim`
+16. `wc --help`
+17. `wc -c source.c`
+18. `quit`

+ 40 - 0
notes/cassh.md

@@ -0,0 +1,40 @@
+# Context Aware Secure Shell Notes
+## Types of interactivity
+Define C := {All characters}
+Define P := {All programs}
+
+Define interactive key set (IKS) such that IKS: P -> C as
+IKS(p) := {c \in C : c has semantic meaning to the user interface of p}
+
+Define non-interactive programs (NIPs) as {p \in P : IKS(p) == \empty}
+Define arbitrarily-interactive programs (AIPs) as {p \in P : IKS(p) == C}
+Define limited-interactive programs (LIPs) as {p \in P : IKS(p) \subset C}
+Define newline-interactive programs (NLIPs) as {p \in P : IKS(p) == {'\n'}}
+
+Majority of programs are NIPs.
+Because NIPs do not react to user input, they are not vulnerable to this attack.
+
+By default, stdin is newline buffered.  Therefore a program must request to read
+more frequently than newlines are entered.  If a program only reads as frequently
+as newlines are entered, no key other than newline can have semantic meaning
+because it won't be read independently of the newline.  Thus in order for any key
+other than newline to have semantic meaning to the user interface, the program
+must make a system call to request it.  Thus, by default, all programs can be
+treated as NLIPs.
+
+NIPs can be treated as NLIPs because their IKS is a subset of NLIPs' IKS.  No
+additional information is leaked because no input sent has semantic meaning.
+
+strace proves that a program can detect system calls of its child processes.  Thus
+SecureShell can detect the system calls of it's child processes.
+
+If a child process of SecureShell wants an IKS that is not a subset of that of
+NLIPs, it must make a system call.  SecureShell can detect that system call and
+thus recognize programs which are not NLIPs.
+
+If the program is not an NLIP, SecureShell can shift modes to treat it as an AIP
+until the process finishes.
+
+Possible: Can I see what keys the program is requesting?
+
+Thus I can limit sending keystrokes to exclusively when the program needs it.

+ 211 - 0
notes/notes.md

@@ -0,0 +1,211 @@
+# Thesis Journal
+## Quarter 1 (Spring 19)
+### 2019-04-15
+* Background research
+  * "Timing analysis of keystrokes and timing attacks on ssh" - Song et al.
+    * Basically the exact same attack applied to passwords.  Very useful.
+  * Found several papers using acoustics to determine keystrokes
+* Found useful wireshark filter for ssh keystrokes (tcp.dstport == 22 and tcp.flags.push == 1)
+* Wrote proposal
+### 2019-04-16
+* Submitted thesis proposal to DeBruhl
+* Discussed logistics of testing
+* Began arrangements with Mammen on using 357 students.
+  * Still need to submit paperwork
+  * Need to talk to Nico about O.S.
+### 2019-04-18
+* Researched NLP and Hidden Markov Chains
+### 2019-04-19
+* Requested VirtualBox be installed on CSL machines
+* Acquired V.M. for router
+  * Decided to use a V.M. on AWS to get realistic network variance/latency
+  * Plan: Set up as router
+    * Concern: If I make it a proxy router, may be abused.  See if I can transparently route or limit to only my subject's VMs.
+      * Concern: If I transparently route, BGP may break my MitM.  Might not be an issue if I only care about the upstream.
+  * Plan: Open necessary ports
+* Researched methods of tracking/tagging SSH connections
+  * Surprisingly difficult to track origin machine - Mostly due to University Wi-Fi NAT
+  * Nothing in the packet meta-data uniquely and consistently identifies a victim
+  * SSH man page describes session variables which may be useful
+    * SSH_CONNECTION contains the victim port from the remote host perspective
+      * I can use the timestamp + src port to link a connection to an ID
+      * Tried printing SSH_CONNECTION to local file on connection init (failed)
+      * Tried printing SSH_CONNECTION to remote file on init (I don't have access to remote file)
+      * Started working with ncat to send ID + time + port to router
+        * I can then join on time + port to assign each SSH flow to an ID
+        * ncat unencrypted by default, privacy concern + potential abuse
+        * Unix servers uninstalled ncat, not viable
+      * Plan: write a basic web server, TLS encrypt, limit to only accept Unix server connections, use CURL to send ID
+        * Concern: Unix server IPs may not be static.  Unlikely but possible.
+* Found several simple keyloggers
+  * Plan: Find one which can monitor one process at a time.  Must also include timestamps 
+### 2019-04-20
+* Realized using V.M. as router and be on the internet doesn't work because I can't force it to be the default gateway
+  * Try making router impersonate Unix VM's by forwarding connection and add routing rule to victim VM
+    * How do I tell the difference between a legitimate SSH connection or one to be forwarded?
+      * Use a different port for real SSH connections?
+      * Might be easier to just use VPNs and hook on new connections
+### 2019-04-21
+* Gathered preliminary data on Unix commands
+  * Used my ubuntu VM sans emacs which I installed afterwards
+  * 1828 commands installed by default, most of them length 8 (normal-ish distribution around it)
+    * A lot of these seem like administrative commands
+  * 315 non-privileged commands, most of them at length 7
+### 2019-04-22
+* Began IRB paperwork
+* Began writing prompts for students
+### 2019-04-23
+* Plan: Talk to Lupo/Pentoja about Fall Quarter
+* Spoke with Debbie Hart
+  * Mention that I have no influence over grading status
+  * Mention whether or not there is difference in ability to complete homework
+  * Ensure students don't feel pressured to participate
+  * Possibly two consent forms
+  * Responses are not used, only information generated by the system
+  * If any part of analysis uses plain responses, submit and IRB
+* Submitted IRB paperwork
+### 2019-04-24
+* Wrote keylogger script for SSH
+  * Concern: No way to no trace the password entered into SSH.  Might have to 
+  instruct students on RSA keys.
+* Wrote up Context-Aware SSH docs
+### 2019-04-27
+* Extensively tested key logger
+### 2019-04-29
+* IRB approved
+  * Submitted revised consent form
+* Talked to Tedd about getting VirtualBox on lab machines
+* Tested OpenVPN
+  * Measured added latency (8.8.8.8 reference point): ~12.5ms
+* Wrote tcpdump filter for only traffic SSHing into another system
+  * Considered: Fixing to only unix server
+    * I don't know if the IPs will change and it's still potentially valid data
+  * Considered: Filtering for only PSH packets (all keystrokes are PSH)
+    * I might need the extra information later so I'll hold on to it.
+* Tested pairing network packets to keystrokes
+  * Difference between key and packet observation: ~11.8ms
+  * First SYN packet is within 100ms of SSH starting in log
+### 2019-04-30
+* Discussed thesis progress with DeBruhl
+  * Password entry is questionable
+    * Maybe write script that generates secureshell key if asked for password?
+    * Might have to just filter it out
+  * Decided port mapping might be unnecessary
+* Ethan (357 student) expressed interest in project
+  * DeBruhl offered to do 400 in Fall
+* Set up CRON to automatically run packet tap on reboot + app armor permissions
+* Server suddenly cannot connect to Unix1
+  * Forgot to save IPTables rule
+### 2019-05-01
+* Started writing script to automatically pair keylog files to packet flows
+  * Got to the point where it could match the start of a file to a TCP SYN
+### 2019-05-02
+* Finished and tested script
+  * Was able to match all packets with 50ms time difference
+### 2019-05-03
+* Tested multiple keylog files.
+* Discovered that different keylogs have different delays.
+  * Delay within one log file fairly consistent
+### 2019-05-06
+* Created scripts which copy keylog file to router VM.
+### 2019-05-07
+* Changes in delay attributable to AWS server instances changing
+* Tested two SSH sessions at same time
+  * Found uses fd 5 instead of 4 - Not sure why
+* Found issue with VM routing
+  * Apparently, upon reboot it adds tun0 without a VPN being turned on.
+    Then tries to route all traffic through inactive device
+    * --No idea why.--
+    * Found old configuration.  systemctl task was trying to open VPN separately.
+* Set up VPN to automatically enable when VM boots
+* Plan: Separate out each flow into a separate pcap
+### 2019-05-08
+* Worked on separating each TCP flow into a separate pcap
+  * Apparently editcap can't do this on it's own so I'm writing my own utility for this
+### 2019-05-09
+* Deployed VM to Unix machines upstairs
+  * Apparently most people don't have enough space to house VM's
+    * Might just have to make VM's smaller
+    * Tested stripping down unneeded packages, didn't do much.
+      * Might just have to use headless-ubuntu
+* Tested running Dataset 1 with Griffian
+  * Issues with DNS resolution on VPN
+  * Packets did not seem to capture --(may have just not flushed yet)--
+    * Packets confirmed not captured.
+  * Total time ~20 (gave longer than expected answers)
+* Set up Lubuntu VM (~1/2 the size)
+### 2019-05-10
+* Fixed issues with VirtualBox version differences (CSL was running 6, I was running 5)
+* Gathered data from Lucy
+* Wrote script to automatically filter the packets before sending them to server.
+### 2019-05-13
+* Got VM's working on CSL computers - Had to install to /tmp for space reasons
+* Tested client configuration with 3 people simultaneously
+  * Sequentially each of us had the connection break
+    * Each after ~15 minutes, each re-established the connection before the next disconnect occurred
+* Added prompt to script to give students a chance to review/approve data before submitting
+### 2019-05-14
+* Discussed progress with DeBruhl
+* Worked on the disconnect problem
+  * --Seems like it happens after every 15 minutes almost exactly--
+  * Can't seem to make it happen at all now.
+* Gather data from a few students:
+  * One had a disconnect but no noticeable issues
+  * Another had a complete disconnect at the very end
+    * Testing was completely finish and I was able to manually upload the data
+    * Captured log of what happened
+      * OpenVPN seems to be detecting itself as a replay attack after network goes down
+        * Solution: Set up NTP server (virtual machine system clock is way off)
+        * Solution: Use TCP
+### 2019-05-15
+* Talked with Nico about testing O.S./S.S. sections
+* Found bug that caused network to disconnect
+  * Network goes down -> link device removed -> route to VPN through device removed -> VPN taffic has no route
+    * It takes 2 minutes for OpenVPN to detect the network is broken
+      * Once OpenVPN tries to renegotiate, fixing the connection causes errors.  Have to full restart OpenVPN
+    * Can fix within first two minutes by adding the route back
+### 2019-05-16
+* Gathered more data from 357 students
+  * Data velocity very slow
+    * Option: Bigger test - Might dissuade more people
+    * Option: Skip to dataset 2
+    * Option: More classes
+    * Option: Reduce dataset requirements
+### 2019-05-17
+* Asked for volunteers from O.S.
+* Met with 357 students from Griffian's section/Elie
+### 2019-05-18
+* Checked that pcaps, log files, and consent forms line up
+  * Because of Timezone offsets, some logs on day boundary
+### 2019-07-20
+* Finished refactoring packet matcher to work with flow-seperated pcaps.
+* Began looking over data
+  * Seems like a lot of files have incomplete data - may have to rerecord all of it.
+### 2019-07-27
+* Looked into issues with files
+  * At least one file seems like it has all the correct data and timestamps, but poor matches
+  * Seems packet-matcher has issues
+    * Fixed.  Seems like it was a problem with my keylog pattern matching.  FD is not reliable.
+  * Some files still fail
+    * Time stamps are way off.  Some data has timestamps way after my last recorded flow
+      * Possibilities:
+        * Problem with flow separator did not split off a file for these flows (best case)
+        * Unix Lab sysclock are wrong (Unlikely but recoverable case)
+        * Problem with recording system did not capture data (worst case)
+      * Investigation:
+        * See if I have a syn-packet for one of my problem flows
+          * No Syn packet found.  Nothing close.  Looking at server to see if I have data at the source.
+          * No packets recorder after 2019-05-21.
+            * I have several flows from 2019-05-23 that were missed.
+            * Other flows are from way earlier.  May be a different problem.
+          * Some packet captures empty.  Seems data capture system needs serious work.
+### 2019-08-11
+* Emailed Ethan
+* Emailed DeBruhl
+* Bought Amazon gift cards
+* Looked for patterns in missing data
+  * None found
+  * May be a failure in data collection or in data parsing
+    * On the server nothing from day 23.  3 keylogs from that day.
+    * Maybe it has to do with the connection dropping randomly?
+    

+ 21 - 0
src/common/Makefile

@@ -0,0 +1,21 @@
+TARGETS=libtimecap.a
+CC=gcc
+AR=ar
+CCFLAGS=-Wall -g
+ARFLAGS=rcs
+
+ODIR=obj
+
+default: $(TARGETS)
+
+libtimecap.a: $(ODIR)/timecap.o
+	$(AR) $(ARFLAGS) $<
+
+$(ODIR)/timecap.o: timecap.c timecap.h $(ODIR)
+	$(CC) -c $(CCFLAGS) $< -o $@
+
+$(ODIR):
+	mkdir $(ODIR)
+
+clean:
+	rm -f $(TARGETS) $(ODIR)/*.o *~

+ 52 - 0
src/common/timecap.c

@@ -0,0 +1,52 @@
+#include"timecap.h"
+#include<stdlib.h>
+
+TimeCap* new_timecap(char* filename, char* errBuf) {
+  struct pcap_pkthdr* header;
+  const u_char* buf;
+  TimeCap* cap = malloc(sizeof(TimeCap));
+  if (cap == NULL) {
+    perror("malloc");
+    exit(1);
+  }
+  cap->pcap = pcap_open_offline(filename, errBuf);
+  if (cap->pcap == NULL) {
+    free(cap);
+    return NULL;
+  }
+  if (pcap_next_ex(cap->pcap, &header, &buf) == -1) {
+    sprintf(errBuf, NO_PACKET_ERR, filename, pcap_geterr(cap->pcap));
+    pcap_close(cap->pcap);
+    free(cap);
+    return NULL;
+  }
+  cap->time = header->ts;
+  pcap_close(cap->pcap);
+  cap->pcap = pcap_open_offline(filename, errBuf);
+  if (cap->pcap == NULL) {
+    free(cap);
+    return NULL;
+  }
+  cap->name = filename;
+  return cap;
+}
+
+int cmp_timecap(const void* a, const void* b) {
+  struct timeval* ta = &((TimeCap*) a)->time;
+  struct timeval* tb = &((TimeCap*) b)->time;
+  if (timercmp(ta, tb, >)) {
+    return 1;
+  }
+  else if (timercmp(ta, tb, <)) {
+    return -1;
+  }
+  else {
+    return 0;
+  }
+}
+
+void delete_timecap(void* val) {
+  TimeCap* cap = val;
+  pcap_close(cap->pcap);
+  free(cap);
+}

+ 21 - 0
src/common/timecap.h

@@ -0,0 +1,21 @@
+#ifndef TIMECAP_H
+#define TIMECAP_H
+
+#include<pcap/pcap.h>
+#include <sys/time.h>
+
+#define NO_PACKET_ERR "Failed to read any packets from file, \"%s\".\n\t%s"
+
+typedef struct {
+  struct timeval time;
+  pcap_t* pcap;
+  char* name;
+} TimeCap;
+
+TimeCap* new_timecap(char* filename, char* errBuf);
+
+int cmp_timecap(const void* a, const void* b);
+
+void delete_timecap(void* val);
+
+#endif

+ 1 - 0
src/flow-seperator

@@ -0,0 +1 @@
+Subproject commit bf3e141e14302f281bf317b3200125629ade87fe

+ 19 - 0
src/packet-matcher/Makefile

@@ -0,0 +1,19 @@
+TARGET=packet-matcher
+CC=gcc
+LIBS=../common
+CCFLAGS=-Wall -g -I$(LIBS)
+LDFLAGS=-lpcap -lm -ltimecap -L$(LIBS)
+
+ODIR=obj
+
+SOURCES = $(wildcard *.c)
+OBJECTS = $(patsubst %.c, $(ODIR)/%.o, $(SOURCES))
+HEADERS = $(wildcard *.h)
+
+default: $(TARGET)
+
+$(TARGET): $(SOURCES)
+	$(CC) $(CCFLAGS) $^ $(LDFLAGS) -o $@ -D"PROG_NAME=\"$@\""
+
+clean:
+	rm -f $(TARGET) $(ODIR)/*.o *~

+ 271 - 0
src/packet-matcher/getPackets.c

@@ -0,0 +1,271 @@
+#include<stdio.h>
+#include<stdlib.h>
+#include<string.h>
+#include<pcap/pcap.h>
+#include<stdbool.h>
+#include<inttypes.h>
+#include<netinet/ether.h>
+#include<arpa/inet.h>
+#include"linkedList.h"
+#include"timecap.h"
+
+#ifndef PROG_NAME
+#define PROG_NAME "a.out"
+#endif
+
+#define FLAG_SHORT_HELP "-h"
+#define FLAG_LONG_HELP  "--help"
+
+#define FLAG_SHORT_DIFF "-d"
+#define FLAG_LONG_DIFF  "--diff"
+
+#define FILTER_KEY_PKT "tcp[13] & 8 == 8 and len == 102 and dst port 22"
+
+/* Format of keylog lines in log file.
+ * 4 = the fd SSH reads user input from (don't know why it isn't 0 but it isn't)
+ * 16384 = How many bytes SSH reads as a time
+ * The last %c is there to check that the entire string matched correctly.
+ * This does not read the entire line.  Call read_line after using this.
+ */
+#define KEYLOG_FORMAT "%lf read(%*d, \"%m[^\"]\", 16384) %c"
+
+#define S_TO_NS 1000000000
+#define S_TO_US 1000000
+
+#define DEFAULT_SYN_E {3, 0}
+
+typedef struct {
+  FILE* keylog;
+  char* keylogName;
+  struct timeval keylogStart;
+  List* timecaps;
+  struct timeval synEpsiolon;
+} Args;
+
+typedef struct
+{
+  /* Ethernet Header */
+  struct ether_addr destMac;
+  struct ether_addr srcMac;
+  uint16_t type;
+  /* IP Header */
+  uint8_t version_ihl;
+  uint8_t dscp_ecn;
+  uint16_t total_length;
+  uint16_t id;
+  uint16_t flags_offset;
+  uint8_t ttl;
+  uint8_t proto;
+  uint8_t udpChecksum[2];
+  struct in_addr srcIP;
+  struct in_addr destIP;
+  /* TCP Header */
+  uint16_t srcPort;
+  uint16_t destPort;
+  uint32_t seqNum;
+  uint32_t ackNum;
+  uint8_t offset_ns;
+  uint8_t flags;
+  uint16_t windowSize;
+  uint8_t tcpChecksum[2];
+  uint16_t urgPtr;
+}__attribute__((packed)) Packet;
+
+typedef struct {
+  struct timeval time;
+  struct timeval packetTime;
+  char* input;
+  uint16_t packetId;
+} Keystroke;
+
+void check_error(int cond, char* str) {
+  if (cond) {
+    perror(str);
+    exit(1);
+  }
+}
+
+void check_error_pcap(int cond, pcap_t* pcap, char* str) {
+  if (cond) {
+    pcap_perror(pcap, str);
+    exit(1);
+  }
+}
+
+void print_usage(int exitCode) {
+  printf("Usage: %s [options] keylog pcap [pcap ...]\n"
+         "Pair a keylog to a SSH TCP stream.\n\n"
+         "Options:\n"
+         "%-20s Show this help message and exit\n"
+         "%-20s The allowable difference in time (in seconds) between keylog \n"
+         "%-20s start and flow start\n",
+         PROG_NAME,
+         "  "FLAG_SHORT_HELP", "FLAG_LONG_HELP,
+         "  "FLAG_SHORT_DIFF", "FLAG_LONG_DIFF, "");
+  exit(exitCode);
+}
+
+struct timeval double_to_timeval(double in) {
+  struct timeval time;
+  time.tv_sec = in;
+  time.tv_usec = (in - time.tv_sec) * S_TO_US;
+  return time;
+}
+
+void parse_flag(char** argv, Args* res, size_t* i) {
+  double d;
+  char* arg = argv[*i];
+  if (strcmp(arg, FLAG_SHORT_HELP) == 0 || strcmp(arg, FLAG_LONG_HELP) == 0) {
+    print_usage(0);
+  }
+  else if (strcmp(arg, FLAG_SHORT_DIFF) == 0 || strcmp(arg, FLAG_LONG_DIFF) == 0) {
+    if (sscanf(argv[++*i], " %lf", &d) == 1 && d > 0) {
+      res->synEpsiolon = double_to_timeval(d);
+    }
+    else {
+      print_usage(1);
+    }
+  }
+}
+
+/* Assumes each pcap has at least one packet and each pcap doesn't overlap.
+ */
+static void add_timecap(List* pcaps, char* filename) {
+  char* errBuf  = alloca(PCAP_ERRBUF_SIZE + strlen(filename) +
+                         sizeof(NO_PACKET_ERR));
+  TimeCap* cap = new_timecap(filename, errBuf);
+  if (cap == NULL) {
+    fprintf(stderr, "%s: %s\n", filename, errBuf);
+  }
+  else {
+    list_add_head(pcaps, cap);
+  }
+}
+
+static void read_line(FILE* keylog) {
+  int c;
+  while ((c = fgetc(keylog)) != '\n' && c != EOF) {
+    continue;
+  }
+}
+
+static struct timeval get_keylog_start(FILE* keylog) {
+  double seconds;
+  if (fscanf(keylog, " %lf", &seconds) != 1) {
+    fprintf(stderr, "Failed to read timestame from keylog file.\n");
+    exit(1);
+  }
+  read_line(keylog);
+  return double_to_timeval(seconds);
+}
+
+static Args get_args(int argc, char** argv) {
+  Args res = {NULL, NULL, {0, 0}, new_list(NULL), DEFAULT_SYN_E};
+  size_t i = 1;
+  while (argv[i]) {
+    if (argv[i][0] == '-') {
+      parse_flag(argv, &res, &i);
+    }
+    else if (res.keylog) {
+      add_timecap(res.timecaps, argv[i]);
+    }
+    else {
+      res.keylog = fopen(argv[i], "r");
+      res.keylogName = argv[i];
+      check_error(res.keylog == NULL, argv[i]);
+      res.keylogStart = get_keylog_start(res.keylog);
+    }
+    ++i;
+  }
+  if (res.keylog == NULL || res.timecaps == NULL) {
+    print_usage(1);
+  }
+  return res;
+}
+
+void timeval_subtract(struct timeval *result, struct timeval *x, struct timeval *y)
+{
+  *result = *x;
+  if (result->tv_usec < y->tv_usec) {
+    result->tv_sec -= 1;
+    result->tv_usec += 1*S_TO_US;
+  }
+  result->tv_sec -= y->tv_sec;
+  result->tv_usec -= y->tv_usec;
+  result->tv_sec = abs(result->tv_sec);
+  result->tv_usec = abs(result->tv_usec);
+}
+
+int is_match(void* tc, void* a) {
+  struct timeval diff;
+  TimeCap* cap = (TimeCap*) tc;
+  Args* args = (Args*) a;
+  timeval_subtract(&diff, &args->keylogStart, &cap->time);
+  return timercmp(&diff, &args->synEpsiolon, <);
+}
+
+void print_time(struct timeval ts) {
+  printf("%lu.%06lu", ts.tv_sec, ts.tv_usec);
+}
+
+Keystroke get_next_key(FILE* keylog) {
+  Keystroke res = {{0, 0}, {0, 0}, NULL, 0};
+  double time = 0.0;
+  int i;
+  char boundry;
+  do {
+    free(res.input);
+    res.input = NULL;
+    i = fscanf(keylog, KEYLOG_FORMAT, &time, &res.input, &boundry);
+    read_line(keylog);
+  } while (i != -1 && i != 3);
+  res.time = double_to_timeval(time);
+  return res;
+}
+
+void print_keystroke(Keystroke key) {
+    print_time(key.time);
+    printf(" '%s' ", key.input);
+    print_time(key.packetTime);
+    printf(" %hu\n", key.packetId);
+}
+
+void match_packets_to_keys(TimeCap* cap, FILE* keylog) {
+  struct bpf_program filter;
+  struct pcap_pkthdr header;
+  Keystroke key;
+  Packet* data;
+  int err = pcap_compile(cap->pcap, &filter, FILTER_KEY_PKT, true,
+                         PCAP_NETMASK_UNKNOWN);
+  check_error_pcap(err == -1, cap->pcap, NULL);
+  pcap_setfilter(cap->pcap, &filter);
+  while ((data = (Packet*) pcap_next(cap->pcap, &header)) != NULL) {
+    key = get_next_key(keylog);
+    key.packetTime = header.ts;
+    key.packetId = data->id;
+    print_keystroke(key);
+    free(key.input);
+  }  
+  pcap_freecode(&filter);
+}
+
+void cleanup(Args args) {
+  delete_list(args.timecaps, delete_timecap);
+  fclose(args.keylog);
+}
+
+int main(int argc, char** argv) {
+  Args args = get_args(argc, argv);
+  TimeCap* cap = (TimeCap*) list_find(args.timecaps, &args, is_match);
+  int exitStatus = 0;
+  if (cap != NULL) {
+    match_packets_to_keys(cap, args.keylog);
+  }
+  else {
+    fprintf(stderr, "Failed to find matching flow file for %s.\n",
+            args.keylogName);
+    exitStatus = 1;
+  }
+  cleanup(args);
+  return exitStatus;
+}

+ 150 - 0
src/packet-matcher/linkedList.c

@@ -0,0 +1,150 @@
+#include"linkedList.h"
+#include<stdlib.h>
+#include<errno.h>
+
+List* new_list(int (*cmp)(const void*, const void*)) {
+  List* res = calloc(1, sizeof(List));
+  if (!res) {
+    return NULL;
+  }
+  res->cmp = cmp;
+  return res;
+}
+
+void delete_list(List* list, void (*del)(void*)) {
+  Node* n = list->head;
+  Node* tmp;
+  while (n != NULL) {
+    tmp = n->next;
+    if (del) {
+      del(n->value);
+    }
+    free(n);
+    n = tmp;
+  }
+  free(list);
+}
+
+void* list_get(List* list, size_t index) {
+  Node* elm;
+  if (index == list->size) {
+    return list->tail->value;
+  }
+  else if (index == 0) {
+    return list->head->value;
+  }
+  elm = list->head->next;
+  while (--index > 0) {
+    elm = elm->next;
+  }
+  return elm->value;
+}
+
+int list_add_head(List* list, void* val) {
+  Node* n = calloc(1, sizeof(Node));
+  if (!n) {
+    return -1;
+  }
+  n->value = val;
+  n->next = list->head;
+  list->head = n;
+  ++list->size;
+  if (list->tail == NULL) {
+    list->tail = n;
+  }
+  return 0;
+}
+
+int list_add_tail(List* list, void* val) {
+  Node* n = calloc(1, sizeof(Node));
+  if (!n) {
+    return -1;
+  }
+  n->value = val;
+  if (list->tail == NULL) {
+    list->head = list->tail =  n;
+  }
+  else {
+    list->tail = list->tail->next = n;
+  }
+  ++list->size;
+  return 0;
+}
+
+int list_add_index(List* list, void* val, size_t index) {
+  Node* elm;
+  Node* prev;
+  Node* n;
+  if (index == list->size) {
+    return list_add_tail(list, val);
+  }
+  else if (index == 0) {
+    return list_add_head(list, val);
+  }
+  else if ((n = calloc(1, sizeof(Node))) == NULL) {
+    return -1;
+  }
+  n->value = val;
+  ++list->size;
+  prev = list->head;
+  elm = prev->next;
+  while (--index > 0) {
+    prev = elm;
+    elm = elm->next;
+  }
+  n->next = elm;
+  prev->next = n;
+  return 0;
+}
+
+int list_contains(List* list, void* val) {
+  Node* elm = list->head;
+  if (list->cmp == NULL) {
+    errno = ENOSYS;
+    return -1;
+  }
+  while (elm && list->cmp(val, elm->value)) {
+    elm = elm->next;
+  }
+  return elm != NULL;
+}
+
+void* list_remove_head(List* list) {
+  Node* tmp = list->head;
+  void* v = tmp->value;
+  list->head = tmp->next;
+  if (tmp == list->tail) {
+    list->tail = NULL;
+  }
+  free(tmp);
+  --list->size;
+  return v;
+}
+
+void* list_remove(List* list, size_t index) {
+  Node* prev = list->head;
+  Node* elm = prev->next;
+  void* v;
+  if (index == 0) {
+    return list_remove_head(list);
+  }
+  while (--index > 0) {
+    prev = elm;
+    elm = prev->next;
+  }
+  v = elm->value;
+  if ((prev->next = elm->next) == NULL) {
+    list->tail = prev;
+  }
+  free(elm);
+  --list->size;
+  return v;
+}
+
+void* list_find(List* list, void* token, int (*fn)(void*, void*)) {
+  Node* elm = list->head;
+  while (elm && !fn(elm->value, token)) {
+    elm = elm->next;
+  }
+  return elm == NULL? NULL : elm->value;
+}

+ 40 - 0
src/packet-matcher/linkedList.h

@@ -0,0 +1,40 @@
+#ifndef LINKEDLIST_H
+#define LINKEDLIST_H
+
+#include<stddef.h>
+
+typedef struct node
+{
+  struct node* next;
+  void* value;
+} Node;
+
+typedef struct
+{
+  Node* head;
+  Node* tail;
+  int (*cmp)(const void*, const void*);
+  size_t size;
+} List;
+
+List* new_list(int (*cmp)(const void*, const void*));
+
+void delete_list(List* list, void (*del)(void*));
+
+void* list_get(List* list, size_t index);
+
+int list_add_head(List* list, void* val);
+
+int list_add_tail(List* list, void* val);
+
+int list_add_index(List* list, void* val, size_t index);
+
+int list_contains(List* list, void* val);
+
+void* list_remove_head(List* list);
+
+void* list_remove(List* list, size_t index);
+
+void* list_find(List* list, void* token, int (*fn)(void*, void*));
+
+#endif

BIN=BIN
src/packet-matcher/packet-matcher


+ 1 - 0
systems/mitm/home/keylog/.ssh/authorized_keys

@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC3fTpbTAMJlGk+nUdCIN+DXzgfXJWhYCgkkAynP0u6AS7a8n7uXfGOKPipavkP+DFMi0GtRFsUtQLfCeTjVGFCn7JB9D8+QpbgxRoyhPE3CT9q4gDyrdU7kMmdQqSH8TezZ8DjNDm28XvKvwGCOQHFeWhhLWsqVdbidx8O4LCjKOLZ3cB3lIGqbeRkz9/ggRhLkoMDOawzkKmtu98dwtN5/ai0D3Jtefd9+W4yqQboFTZW6yoq23Td2HHZ7EdJfQst0DunLozjCkKfr3QLORntN3CwZ+OxIORQJ8uzMrc2h9kXEnWIMuMny3cECbWj1VKUx8RfywwBYfkpgZuQd6aX

+ 8 - 0
systems/mitm/home/keylog/bin/keylog.sh

@@ -0,0 +1,8 @@
+#!/bin/sh
+
+if [ $# -eq 3 -a "$1" = "scp" ]; then
+    mkdir ~/data/"$3/" 2> /dev/null
+    scp -q -t ~/data/"$3/"
+else
+    echo "Invalid number of arguements." 1>&2
+fi

+ 8 - 0
systems/mitm/openvpn/easy-rsa/build-ca

@@ -0,0 +1,8 @@
+#!/bin/sh
+
+#
+# Build a root certificate
+#
+
+export EASY_RSA="${EASY_RSA:-.}"
+"$EASY_RSA/pkitool" --interact --initca $*

+ 11 - 0
systems/mitm/openvpn/easy-rsa/build-dh

@@ -0,0 +1,11 @@
+#!/bin/sh
+
+# Build Diffie-Hellman parameters for the server side
+# of an SSL/TLS connection.
+
+if [ -d $KEY_DIR ] && [ $KEY_SIZE ]; then
+    $OPENSSL dhparam -out ${KEY_DIR}/dh${KEY_SIZE}.pem ${KEY_SIZE}
+else
+    echo 'Please source the vars script first (i.e. "source ./vars")'
+    echo 'Make sure you have edited it to reflect your configuration.'
+fi

+ 7 - 0
systems/mitm/openvpn/easy-rsa/build-inter

@@ -0,0 +1,7 @@
+#!/bin/sh
+
+# Make an intermediate CA certificate/private key pair using a locally generated
+# root certificate.
+
+export EASY_RSA="${EASY_RSA:-.}"
+"$EASY_RSA/pkitool" --interact --inter $*

+ 7 - 0
systems/mitm/openvpn/easy-rsa/build-key

@@ -0,0 +1,7 @@
+#!/bin/sh
+
+# Make a certificate/private key pair using a locally generated
+# root certificate.
+
+export EASY_RSA="${EASY_RSA:-.}"
+"$EASY_RSA/pkitool" --interact $*

+ 7 - 0
systems/mitm/openvpn/easy-rsa/build-key-pass

@@ -0,0 +1,7 @@
+#!/bin/sh
+
+# Similar to build-key, but protect the private key
+# with a password.
+
+export EASY_RSA="${EASY_RSA:-.}"
+"$EASY_RSA/pkitool" --interact --pass $*

+ 8 - 0
systems/mitm/openvpn/easy-rsa/build-key-pkcs12

@@ -0,0 +1,8 @@
+#!/bin/sh
+
+# Make a certificate/private key pair using a locally generated
+# root certificate and convert it to a PKCS #12 file including the
+# the CA certificate as well.
+
+export EASY_RSA="${EASY_RSA:-.}"
+"$EASY_RSA/pkitool" --interact --pkcs12 $*

+ 10 - 0
systems/mitm/openvpn/easy-rsa/build-key-server

@@ -0,0 +1,10 @@
+#!/bin/sh
+
+# Make a certificate/private key pair using a locally generated
+# root certificate.
+#
+# Explicitly set nsCertType to server using the "server"
+# extension in the openssl.cnf file.
+
+export EASY_RSA="${EASY_RSA:-.}"
+"$EASY_RSA/pkitool" --interact --server $*

+ 7 - 0
systems/mitm/openvpn/easy-rsa/build-req

@@ -0,0 +1,7 @@
+#!/bin/sh
+
+# Build a certificate signing request and private key.  Use this
+# when your root certificate and key is not available locally.
+
+export EASY_RSA="${EASY_RSA:-.}"
+"$EASY_RSA/pkitool" --interact --csr $*

+ 7 - 0
systems/mitm/openvpn/easy-rsa/build-req-pass

@@ -0,0 +1,7 @@
+#!/bin/sh
+
+# Like build-req, but protect your private key
+# with a password.
+
+export EASY_RSA="${EASY_RSA:-.}"
+"$EASY_RSA/pkitool" --interact --csr --pass $*

+ 16 - 0
systems/mitm/openvpn/easy-rsa/clean-all

@@ -0,0 +1,16 @@
+#!/bin/sh
+
+# Initialize the $KEY_DIR directory.
+# Note that this script does a
+# rm -rf on $KEY_DIR so be careful!
+
+if [ "$KEY_DIR" ]; then
+    rm -rf "$KEY_DIR"
+    mkdir "$KEY_DIR" && \
+        chmod go-rwx "$KEY_DIR" && \
+        touch "$KEY_DIR/index.txt" && \
+        echo 01 >"$KEY_DIR/serial"
+else
+    echo 'Please source the vars script first (i.e. "source ./vars")'
+    echo 'Make sure you have edited it to reflect your configuration.'
+fi

+ 39 - 0
systems/mitm/openvpn/easy-rsa/inherit-inter

@@ -0,0 +1,39 @@
+#!/bin/sh
+
+# Build a new PKI which is rooted on an intermediate certificate generated
+# by ./build-inter or ./pkitool --inter from a parent PKI.  The new PKI should
+# have independent vars settings, and must use a different KEY_DIR directory
+# from the parent.  This tool can be used to generate arbitrary depth
+# certificate chains.
+#
+# To build an intermediate CA, follow the same steps for a regular PKI but
+# replace ./build-key or ./pkitool --initca with this script.
+
+# The EXPORT_CA file will contain the CA certificate chain and should be
+# referenced by the OpenVPN "ca" directive in config files.  The ca.crt file
+# will only contain the local intermediate CA -- it's needed by the easy-rsa
+# scripts but not by OpenVPN directly.
+EXPORT_CA="export-ca.crt"
+
+if [ $# -ne 2 ]; then
+    echo "usage: $0 <parent-key-dir> <common-name>"
+    echo "parent-key-dir: the KEY_DIR directory of the parent PKI"
+    echo "common-name: the common name of the intermediate certificate in the parent PKI"
+    exit 1;
+fi
+
+if [ "$KEY_DIR" ]; then
+    cp "$1/$2.crt" "$KEY_DIR/ca.crt"
+    cp "$1/$2.key" "$KEY_DIR/ca.key"
+
+    if [ -e "$1/$EXPORT_CA" ]; then
+        PARENT_CA="$1/$EXPORT_CA"
+    else
+        PARENT_CA="$1/ca.crt"
+    fi
+    cp "$PARENT_CA" "$KEY_DIR/$EXPORT_CA"
+    cat "$KEY_DIR/ca.crt" >> "$KEY_DIR/$EXPORT_CA"
+else
+    echo 'Please source the vars script first (i.e. "source ./vars")'
+    echo 'Make sure you have edited it to reflect your configuration.'
+fi

+ 13 - 0
systems/mitm/openvpn/easy-rsa/list-crl

@@ -0,0 +1,13 @@
+#!/bin/sh
+
+# list revoked certificates
+
+CRL="${1:-crl.pem}"
+
+if [ "$KEY_DIR" ]; then
+    cd "$KEY_DIR" && \
+        $OPENSSL crl -text -noout -in "$CRL"
+else
+    echo 'Please source the vars script first (i.e. "source ./vars")'
+    echo 'Make sure you have edited it to reflect your configuration.'
+fi

+ 268 - 0
systems/mitm/openvpn/easy-rsa/openssl-0.9.6.cnf

@@ -0,0 +1,268 @@
+# For use with easy-rsa version 2.0
+
+#
+# OpenSSL example configuration file.
+# This is mostly being used for generation of certificate requests.
+#
+
+# This definition stops the following lines choking if HOME isn't
+# defined.
+HOME			= .
+RANDFILE		= $ENV::HOME/.rnd
+
+# Extra OBJECT IDENTIFIER info:
+#oid_file		= $ENV::HOME/.oid
+oid_section		= new_oids
+
+# To use this configuration file with the "-extfile" option of the
+# "openssl x509" utility, name here the section containing the
+# X.509v3 extensions to use:
+# extensions		= 
+# (Alternatively, use a configuration file that has only
+# X.509v3 extensions in its main [= default] section.)
+
+[ new_oids ]
+
+# We can add new OIDs in here for use by 'ca' and 'req'.
+# Add a simple OID like this:
+# testoid1=1.2.3.4
+# Or use config file substitution like this:
+# testoid2=${testoid1}.5.6
+
+####################################################################
+[ ca ]
+default_ca	= CA_default		# The default ca section
+
+####################################################################
+[ CA_default ]
+
+dir		= $ENV::KEY_DIR		# Where everything is kept
+certs		= $dir			# Where the issued certs are kept
+crl_dir		= $dir			# Where the issued crl are kept
+database	= $dir/index.txt	# database index file.
+new_certs_dir	= $dir			# default place for new certs.
+
+certificate	= $dir/ca.crt	 	# The CA certificate
+serial		= $dir/serial 		# The current serial number
+crl		= $dir/crl.pem 		# The current CRL
+private_key	= $dir/ca.key	 	# The private key
+RANDFILE	= $dir/.rand		# private random number file
+
+x509_extensions	= usr_cert		# The extentions to add to the cert
+
+# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
+# so this is commented out by default to leave a V1 CRL.
+# crl_extensions	= crl_ext
+
+default_days	= 3650			# how long to certify for
+default_crl_days= 30			# how long before next CRL
+default_md	= sha256		# which md to use.
+preserve	= no			# keep passed DN ordering
+
+# A few difference way of specifying how similar the request should look
+# For type CA, the listed attributes must be the same, and the optional
+# and supplied fields are just that :-)
+policy		= policy_anything
+
+# For the CA policy
+[ policy_match ]
+countryName		= match
+stateOrProvinceName	= match
+organizationName	= match
+organizationalUnitName	= optional
+commonName		= supplied
+emailAddress		= optional
+
+# For the 'anything' policy
+# At this point in time, you must list all acceptable 'object'
+# types.
+[ policy_anything ]
+countryName		= optional
+stateOrProvinceName	= optional
+localityName		= optional
+organizationName	= optional
+organizationalUnitName	= optional
+commonName		= supplied
+emailAddress		= optional
+
+####################################################################
+[ req ]
+default_bits		= $ENV::KEY_SIZE
+default_keyfile 	= privkey.pem
+default_md		= sha256
+distinguished_name	= req_distinguished_name
+attributes		= req_attributes
+x509_extensions	= v3_ca	# The extentions to add to the self signed cert
+
+# Passwords for private keys if not present they will be prompted for
+# input_password = secret
+# output_password = secret
+
+# This sets a mask for permitted string types. There are several options. 
+# default: PrintableString, T61String, BMPString.
+# pkix	 : PrintableString, BMPString.
+# utf8only: only UTF8Strings.
+# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
+# MASK:XXXX a literal mask value.
+# WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings
+# so use this option with caution!
+string_mask = nombstr
+
+# req_extensions = v3_req # The extensions to add to a certificate request
+
+[ req_distinguished_name ]
+countryName			= Country Name (2 letter code)
+countryName_default		= $ENV::KEY_COUNTRY
+countryName_min			= 2
+countryName_max			= 2
+
+stateOrProvinceName		= State or Province Name (full name)
+stateOrProvinceName_default	= $ENV::KEY_PROVINCE
+
+localityName			= Locality Name (eg, city)
+localityName_default		= $ENV::KEY_CITY
+
+0.organizationName		= Organization Name (eg, company)
+0.organizationName_default	= $ENV::KEY_ORG
+
+# we can do this but it is not needed normally :-)
+#1.organizationName		= Second Organization Name (eg, company)
+#1.organizationName_default	= World Wide Web Pty Ltd
+
+organizationalUnitName		= Organizational Unit Name (eg, section)
+#organizationalUnitName_default	=
+
+commonName			= Common Name (eg, your name or your server\'s hostname)
+commonName_max			= 64
+
+emailAddress			= Email Address
+emailAddress_default		= $ENV::KEY_EMAIL
+emailAddress_max		= 40
+
+# JY -- added for batch mode
+organizationalUnitName_default = $ENV::KEY_OU
+commonName_default = $ENV::KEY_CN
+
+# SET-ex3			= SET extension number 3
+
+[ req_attributes ]
+challengePassword		= A challenge password
+challengePassword_min		= 4
+challengePassword_max		= 20
+
+unstructuredName		= An optional company name
+
+[ usr_cert ]
+
+# These extensions are added when 'ca' signs a request.
+
+# This goes against PKIX guidelines but some CAs do it and some software
+# requires this to avoid interpreting an end user certificate as a CA.
+
+basicConstraints=CA:FALSE
+
+# Here are some examples of the usage of nsCertType. If it is omitted
+# the certificate can be used for anything *except* object signing.
+
+# This is OK for an SSL server.
+# nsCertType			= server
+
+# For an object signing certificate this would be used.
+# nsCertType = objsign
+
+# For normal client use this is typical
+# nsCertType = client, email
+
+# and for everything including object signing:
+# nsCertType = client, email, objsign
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# This will be displayed in Netscape's comment listbox.
+nsComment			= "Easy-RSA Generated Certificate"
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer:always
+extendedKeyUsage=clientAuth
+keyUsage = digitalSignature
+
+# This stuff is for subjectAltName and issuerAltname.
+# Import the email address.
+# subjectAltName=email:copy
+subjectAltName=$ENV::KEY_ALTNAMES
+
+# Copy subject details
+# issuerAltName=issuer:copy
+
+#nsCaRevocationUrl		= http://www.domain.dom/ca-crl.pem
+#nsBaseUrl
+#nsRevocationUrl
+#nsRenewalUrl
+#nsCaPolicyUrl
+#nsSslServerName
+
+[ server ]
+
+# JY ADDED -- Make a cert with nsCertType set to "server"
+basicConstraints=CA:FALSE
+nsCertType			= server
+nsComment			= "Easy-RSA Generated Server Certificate"
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer:always
+extendedKeyUsage=serverAuth
+keyUsage = digitalSignature, keyEncipherment
+subjectAltName=$ENV::KEY_ALTNAMES
+
+[ v3_req ]
+
+# Extensions to add to a certificate request
+
+basicConstraints = CA:FALSE
+keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+[ v3_ca ]
+
+
+# Extensions for a typical CA
+
+
+# PKIX recommendation.
+
+subjectKeyIdentifier=hash
+
+authorityKeyIdentifier=keyid:always,issuer:always
+
+# This is what PKIX recommends but some broken software chokes on critical
+# extensions.
+#basicConstraints = critical,CA:true
+# So we do this instead.
+basicConstraints = CA:true
+
+# Key usage: this is typical for a CA certificate. However since it will
+# prevent it being used as an test self-signed certificate it is best
+# left out by default.
+# keyUsage = cRLSign, keyCertSign
+
+# Some might want this also
+# nsCertType = sslCA, emailCA
+
+# Include email address in subject alt name: another PKIX recommendation
+# subjectAltName=email:copy
+# Copy issuer details
+# issuerAltName=issuer:copy
+
+# DER hex encoding of an extension: beware experts only!
+# obj=DER:02:03
+# Where 'obj' is a standard or added object
+# You can even override a supported extension:
+# basicConstraints= critical, DER:30:03:01:01:FF
+
+[ crl_ext ]
+
+# CRL extensions.
+# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
+
+# issuerAltName=issuer:copy
+authorityKeyIdentifier=keyid:always,issuer:always

+ 293 - 0
systems/mitm/openvpn/easy-rsa/openssl-0.9.8.cnf

@@ -0,0 +1,293 @@
+# For use with easy-rsa version 2.0
+
+#
+# OpenSSL example configuration file.
+# This is mostly being used for generation of certificate requests.
+#
+
+# This definition stops the following lines choking if HOME isn't
+# defined.
+HOME			= .
+RANDFILE		= $ENV::HOME/.rnd
+openssl_conf		= openssl_init
+
+[ openssl_init ]
+# Extra OBJECT IDENTIFIER info:
+#oid_file		= $ENV::HOME/.oid
+oid_section		= new_oids
+engines                 = engine_section
+
+# To use this configuration file with the "-extfile" option of the
+# "openssl x509" utility, name here the section containing the
+# X.509v3 extensions to use:
+# extensions		=
+# (Alternatively, use a configuration file that has only
+# X.509v3 extensions in its main [= default] section.)
+
+[ new_oids ]
+
+# We can add new OIDs in here for use by 'ca' and 'req'.
+# Add a simple OID like this:
+# testoid1=1.2.3.4
+# Or use config file substitution like this:
+# testoid2=${testoid1}.5.6
+
+####################################################################
+[ ca ]
+default_ca	= CA_default		# The default ca section
+
+####################################################################
+[ CA_default ]
+
+dir		= $ENV::KEY_DIR		# Where everything is kept
+certs		= $dir			# Where the issued certs are kept
+crl_dir		= $dir			# Where the issued crl are kept
+database	= $dir/index.txt	# database index file.
+new_certs_dir	= $dir			# default place for new certs.
+
+certificate	= $dir/ca.crt	 	# The CA certificate
+serial		= $dir/serial 		# The current serial number
+crl		= $dir/crl.pem 		# The current CRL
+private_key	= $dir/ca.key	 	# The private key
+RANDFILE	= $dir/.rand		# private random number file
+
+x509_extensions	= usr_cert		# The extentions to add to the cert
+
+# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
+# so this is commented out by default to leave a V1 CRL.
+# crl_extensions	= crl_ext
+
+default_days	= 3650			# how long to certify for
+default_crl_days= 30			# how long before next CRL
+default_md	= sha256		# which md to use.
+preserve	= no			# keep passed DN ordering
+
+# A few difference way of specifying how similar the request should look
+# For type CA, the listed attributes must be the same, and the optional
+# and supplied fields are just that :-)
+policy		= policy_anything
+
+# For the CA policy
+[ policy_match ]
+countryName		= match
+stateOrProvinceName	= match
+organizationName	= match
+organizationalUnitName	= optional
+commonName		= supplied
+name			= optional
+emailAddress		= optional
+
+# For the 'anything' policy
+# At this point in time, you must list all acceptable 'object'
+# types.
+[ policy_anything ]
+countryName		= optional
+stateOrProvinceName	= optional
+localityName		= optional
+organizationName	= optional
+organizationalUnitName	= optional
+commonName		= supplied
+name			= optional
+emailAddress		= optional
+
+####################################################################
+[ req ]
+default_bits		= $ENV::KEY_SIZE
+default_keyfile 	= privkey.pem
+default_md		= sha256
+distinguished_name	= req_distinguished_name
+attributes		= req_attributes
+x509_extensions	= v3_ca	# The extentions to add to the self signed cert
+
+# Passwords for private keys if not present they will be prompted for
+# input_password = secret
+# output_password = secret
+
+# This sets a mask for permitted string types. There are several options.
+# default: PrintableString, T61String, BMPString.
+# pkix	 : PrintableString, BMPString.
+# utf8only: only UTF8Strings.
+# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
+# MASK:XXXX a literal mask value.
+# WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings
+# so use this option with caution!
+string_mask = nombstr
+
+# req_extensions = v3_req # The extensions to add to a certificate request
+
+[ req_distinguished_name ]
+countryName			= Country Name (2 letter code)
+countryName_default		= $ENV::KEY_COUNTRY
+countryName_min			= 2
+countryName_max			= 2
+
+stateOrProvinceName		= State or Province Name (full name)
+stateOrProvinceName_default	= $ENV::KEY_PROVINCE
+
+localityName			= Locality Name (eg, city)
+localityName_default		= $ENV::KEY_CITY
+
+0.organizationName		= Organization Name (eg, company)
+0.organizationName_default	= $ENV::KEY_ORG
+
+# we can do this but it is not needed normally :-)
+#1.organizationName		= Second Organization Name (eg, company)
+#1.organizationName_default	= World Wide Web Pty Ltd
+
+organizationalUnitName		= Organizational Unit Name (eg, section)
+#organizationalUnitName_default	=
+
+commonName			= Common Name (eg, your name or your server\'s hostname)
+commonName_max			= 64
+
+name				= Name
+name_max			= 64
+
+emailAddress			= Email Address
+emailAddress_default		= $ENV::KEY_EMAIL
+emailAddress_max		= 40
+
+# JY -- added for batch mode
+organizationalUnitName_default = $ENV::KEY_OU
+commonName_default = $ENV::KEY_CN
+name_default = $ENV::KEY_NAME
+
+# SET-ex3			= SET extension number 3
+
+[ req_attributes ]
+challengePassword		= A challenge password
+challengePassword_min		= 4
+challengePassword_max		= 20
+
+unstructuredName		= An optional company name
+
+[ usr_cert ]
+
+# These extensions are added when 'ca' signs a request.
+
+# This goes against PKIX guidelines but some CAs do it and some software
+# requires this to avoid interpreting an end user certificate as a CA.
+
+basicConstraints=CA:FALSE
+
+# Here are some examples of the usage of nsCertType. If it is omitted
+# the certificate can be used for anything *except* object signing.
+
+# This is OK for an SSL server.
+# nsCertType			= server
+
+# For an object signing certificate this would be used.
+# nsCertType = objsign
+
+# For normal client use this is typical
+# nsCertType = client, email
+
+# and for everything including object signing:
+# nsCertType = client, email, objsign
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# This will be displayed in Netscape's comment listbox.
+nsComment			= "Easy-RSA Generated Certificate"
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer:always
+extendedKeyUsage=clientAuth
+keyUsage = digitalSignature
+
+# This stuff is for subjectAltName and issuerAltname.
+# Import the email address.
+# subjectAltName=email:copy
+subjectAltName=$ENV::KEY_ALTNAMES
+
+# Copy subject details
+# issuerAltName=issuer:copy
+
+#nsCaRevocationUrl		= http://www.domain.dom/ca-crl.pem
+#nsBaseUrl
+#nsRevocationUrl
+#nsRenewalUrl
+#nsCaPolicyUrl
+#nsSslServerName
+
+[ server ]
+
+# JY ADDED -- Make a cert with nsCertType set to "server"
+basicConstraints=CA:FALSE
+nsCertType			= server
+nsComment			= "Easy-RSA Generated Server Certificate"
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer:always
+extendedKeyUsage=serverAuth
+keyUsage = digitalSignature, keyEncipherment
+subjectAltName=$ENV::KEY_ALTNAMES
+
+[ v3_req ]
+
+# Extensions to add to a certificate request
+
+basicConstraints = CA:FALSE
+keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+[ v3_ca ]
+
+
+# Extensions for a typical CA
+
+
+# PKIX recommendation.
+
+subjectKeyIdentifier=hash
+
+authorityKeyIdentifier=keyid:always,issuer:always
+
+# This is what PKIX recommends but some broken software chokes on critical
+# extensions.
+#basicConstraints = critical,CA:true
+# So we do this instead.
+basicConstraints = CA:true
+
+# Key usage: this is typical for a CA certificate. However since it will
+# prevent it being used as an test self-signed certificate it is best
+# left out by default.
+# keyUsage = cRLSign, keyCertSign
+
+# Some might want this also
+# nsCertType = sslCA, emailCA
+
+# Include email address in subject alt name: another PKIX recommendation
+# subjectAltName=email:copy
+# Copy issuer details
+# issuerAltName=issuer:copy
+
+# DER hex encoding of an extension: beware experts only!
+# obj=DER:02:03
+# Where 'obj' is a standard or added object
+# You can even override a supported extension:
+# basicConstraints= critical, DER:30:03:01:01:FF
+
+[ crl_ext ]
+
+# CRL extensions.
+# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
+
+# issuerAltName=issuer:copy
+authorityKeyIdentifier=keyid:always,issuer:always
+
+[ engine_section ]
+#
+# If you are using PKCS#11
+# Install engine_pkcs11 of opensc (www.opensc.org)
+# And uncomment the following
+# verify that dynamic_path points to the correct location
+#
+#pkcs11 = pkcs11_section
+
+[ pkcs11_section ]
+engine_id = pkcs11
+dynamic_path = /usr/lib/engines/engine_pkcs11.so
+MODULE_PATH = $ENV::PKCS11_MODULE_PATH
+PIN = $ENV::PKCS11_PIN
+init = 0

+ 288 - 0
systems/mitm/openvpn/easy-rsa/openssl-1.0.0.cnf

@@ -0,0 +1,288 @@
+# For use with easy-rsa version 2.0 and OpenSSL 1.0.0*
+
+# This definition stops the following lines choking if HOME isn't
+# defined.
+HOME			= .
+RANDFILE		= $ENV::HOME/.rnd
+openssl_conf		= openssl_init
+
+[ openssl_init ]
+# Extra OBJECT IDENTIFIER info:
+#oid_file		= $ENV::HOME/.oid
+oid_section		= new_oids
+engines			= engine_section
+
+# To use this configuration file with the "-extfile" option of the
+# "openssl x509" utility, name here the section containing the
+# X.509v3 extensions to use:
+# extensions		=
+# (Alternatively, use a configuration file that has only
+# X.509v3 extensions in its main [= default] section.)
+
+[ new_oids ]
+
+# We can add new OIDs in here for use by 'ca' and 'req'.
+# Add a simple OID like this:
+# testoid1=1.2.3.4
+# Or use config file substitution like this:
+# testoid2=${testoid1}.5.6
+
+####################################################################
+[ ca ]
+default_ca	= CA_default		# The default ca section
+
+####################################################################
+[ CA_default ]
+
+dir		= $ENV::KEY_DIR		# Where everything is kept
+certs		= $dir			# Where the issued certs are kept
+crl_dir		= $dir			# Where the issued crl are kept
+database	= $dir/index.txt	# database index file.
+new_certs_dir	= $dir			# default place for new certs.
+
+certificate	= $dir/ca.crt	 	# The CA certificate
+serial		= $dir/serial 		# The current serial number
+crl		= $dir/crl.pem 		# The current CRL
+private_key	= $dir/ca.key		# The private key
+RANDFILE	= $dir/.rand		# private random number file
+
+x509_extensions	= usr_cert		# The extentions to add to the cert
+
+# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
+# so this is commented out by default to leave a V1 CRL.
+# crl_extensions	= crl_ext
+
+default_days	= 3650			# how long to certify for
+default_crl_days= 30			# how long before next CRL
+default_md	= sha256		# use public key default MD
+preserve	= no			# keep passed DN ordering
+
+# A few difference way of specifying how similar the request should look
+# For type CA, the listed attributes must be the same, and the optional
+# and supplied fields are just that :-)
+policy		= policy_anything
+
+# For the CA policy
+[ policy_match ]
+countryName		= match
+stateOrProvinceName	= match
+organizationName	= match
+organizationalUnitName	= optional
+commonName		= supplied
+name			= optional
+emailAddress		= optional
+
+# For the 'anything' policy
+# At this point in time, you must list all acceptable 'object'
+# types.
+[ policy_anything ]
+countryName		= optional
+stateOrProvinceName	= optional
+localityName		= optional
+organizationName	= optional
+organizationalUnitName	= optional
+commonName		= supplied
+name			= optional
+emailAddress		= optional
+
+####################################################################
+[ req ]
+default_bits		= $ENV::KEY_SIZE
+default_keyfile 	= privkey.pem
+default_md		= sha256
+distinguished_name	= req_distinguished_name
+attributes		= req_attributes
+x509_extensions	= v3_ca	# The extentions to add to the self signed cert
+
+# Passwords for private keys if not present they will be prompted for
+# input_password = secret
+# output_password = secret
+
+# This sets a mask for permitted string types. There are several options.
+# default: PrintableString, T61String, BMPString.
+# pkix	 : PrintableString, BMPString (PKIX recommendation after 2004).
+# utf8only: only UTF8Strings (PKIX recommendation after 2004).
+# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
+# MASK:XXXX a literal mask value.
+string_mask = nombstr
+
+# req_extensions = v3_req # The extensions to add to a certificate request
+
+[ req_distinguished_name ]
+countryName			= Country Name (2 letter code)
+countryName_default		= $ENV::KEY_COUNTRY
+countryName_min			= 2
+countryName_max			= 2
+
+stateOrProvinceName		= State or Province Name (full name)
+stateOrProvinceName_default	= $ENV::KEY_PROVINCE
+
+localityName			= Locality Name (eg, city)
+localityName_default		= $ENV::KEY_CITY
+
+0.organizationName		= Organization Name (eg, company)
+0.organizationName_default	= $ENV::KEY_ORG
+
+# we can do this but it is not needed normally :-)
+#1.organizationName		= Second Organization Name (eg, company)
+#1.organizationName_default	= World Wide Web Pty Ltd
+
+organizationalUnitName		= Organizational Unit Name (eg, section)
+#organizationalUnitName_default	=
+
+commonName			= Common Name (eg, your name or your server\'s hostname)
+commonName_max			= 64
+
+name				= Name
+name_max			= 64
+
+emailAddress			= Email Address
+emailAddress_default		= $ENV::KEY_EMAIL
+emailAddress_max		= 40
+
+# JY -- added for batch mode
+organizationalUnitName_default = $ENV::KEY_OU
+commonName_default = $ENV::KEY_CN
+name_default = $ENV::KEY_NAME
+
+
+# SET-ex3			= SET extension number 3
+
+[ req_attributes ]
+challengePassword		= A challenge password
+challengePassword_min		= 4
+challengePassword_max		= 20
+
+unstructuredName		= An optional company name
+
+[ usr_cert ]
+
+# These extensions are added when 'ca' signs a request.
+
+# This goes against PKIX guidelines but some CAs do it and some software
+# requires this to avoid interpreting an end user certificate as a CA.
+
+basicConstraints=CA:FALSE
+
+# Here are some examples of the usage of nsCertType. If it is omitted
+# the certificate can be used for anything *except* object signing.
+
+# This is OK for an SSL server.
+# nsCertType			= server
+
+# For an object signing certificate this would be used.
+# nsCertType = objsign
+
+# For normal client use this is typical
+# nsCertType = client, email
+
+# and for everything including object signing:
+# nsCertType = client, email, objsign
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# This will be displayed in Netscape's comment listbox.
+nsComment			= "Easy-RSA Generated Certificate"
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer:always
+extendedKeyUsage=clientAuth
+keyUsage = digitalSignature
+
+
+# This stuff is for subjectAltName and issuerAltname.
+# Import the email address.
+# subjectAltName=email:copy
+subjectAltName=$ENV::KEY_ALTNAMES
+
+# Copy subject details
+# issuerAltName=issuer:copy
+
+#nsCaRevocationUrl		= http://www.domain.dom/ca-crl.pem
+#nsBaseUrl
+#nsRevocationUrl
+#nsRenewalUrl
+#nsCaPolicyUrl
+#nsSslServerName
+
+[ server ]
+
+# JY ADDED -- Make a cert with nsCertType set to "server"
+basicConstraints=CA:FALSE
+nsCertType                     = server
+nsComment                      = "Easy-RSA Generated Server Certificate"
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer:always
+extendedKeyUsage=serverAuth
+keyUsage = digitalSignature, keyEncipherment
+subjectAltName=$ENV::KEY_ALTNAMES
+
+[ v3_req ]
+
+# Extensions to add to a certificate request
+
+basicConstraints = CA:FALSE
+keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+[ v3_ca ]
+
+
+# Extensions for a typical CA
+
+
+# PKIX recommendation.
+
+subjectKeyIdentifier=hash
+
+authorityKeyIdentifier=keyid:always,issuer:always
+
+# This is what PKIX recommends but some broken software chokes on critical
+# extensions.
+#basicConstraints = critical,CA:true
+# So we do this instead.
+basicConstraints = CA:true
+
+# Key usage: this is typical for a CA certificate. However since it will
+# prevent it being used as an test self-signed certificate it is best
+# left out by default.
+# keyUsage = cRLSign, keyCertSign
+
+# Some might want this also
+# nsCertType = sslCA, emailCA
+
+# Include email address in subject alt name: another PKIX recommendation
+# subjectAltName=email:copy
+# Copy issuer details
+# issuerAltName=issuer:copy
+
+# DER hex encoding of an extension: beware experts only!
+# obj=DER:02:03
+# Where 'obj' is a standard or added object
+# You can even override a supported extension:
+# basicConstraints= critical, DER:30:03:01:01:FF
+
+[ crl_ext ]
+
+# CRL extensions.
+# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
+
+# issuerAltName=issuer:copy
+authorityKeyIdentifier=keyid:always,issuer:always
+
+[ engine_section ]
+#
+# If you are using PKCS#11
+# Install engine_pkcs11 of opensc (www.opensc.org)
+# And uncomment the following
+# verify that dynamic_path points to the correct location
+#
+#pkcs11 = pkcs11_section
+
+[ pkcs11_section ]
+engine_id = pkcs11
+dynamic_path = /usr/lib/engines/engine_pkcs11.so
+MODULE_PATH = $ENV::PKCS11_MODULE_PATH
+PIN = $ENV::PKCS11_PIN
+init = 0

+ 288 - 0
systems/mitm/openvpn/easy-rsa/openssl.cnf

@@ -0,0 +1,288 @@
+# For use with easy-rsa version 2.0 and OpenSSL 1.0.0*
+
+# This definition stops the following lines choking if HOME isn't
+# defined.
+HOME			= .
+RANDFILE		= $ENV::HOME/.rnd
+openssl_conf		= openssl_init
+
+[ openssl_init ]
+# Extra OBJECT IDENTIFIER info:
+#oid_file		= $ENV::HOME/.oid
+oid_section		= new_oids
+engines			= engine_section
+
+# To use this configuration file with the "-extfile" option of the
+# "openssl x509" utility, name here the section containing the
+# X.509v3 extensions to use:
+# extensions		=
+# (Alternatively, use a configuration file that has only
+# X.509v3 extensions in its main [= default] section.)
+
+[ new_oids ]
+
+# We can add new OIDs in here for use by 'ca' and 'req'.
+# Add a simple OID like this:
+# testoid1=1.2.3.4
+# Or use config file substitution like this:
+# testoid2=${testoid1}.5.6
+
+####################################################################
+[ ca ]
+default_ca	= CA_default		# The default ca section
+
+####################################################################
+[ CA_default ]
+
+dir		= $ENV::KEY_DIR		# Where everything is kept
+certs		= $dir			# Where the issued certs are kept
+crl_dir		= $dir			# Where the issued crl are kept
+database	= $dir/index.txt	# database index file.
+new_certs_dir	= $dir			# default place for new certs.
+
+certificate	= $dir/ca.crt	 	# The CA certificate
+serial		= $dir/serial 		# The current serial number
+crl		= $dir/crl.pem 		# The current CRL
+private_key	= $dir/ca.key		# The private key
+RANDFILE	= $dir/.rand		# private random number file
+
+x509_extensions	= usr_cert		# The extentions to add to the cert
+
+# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
+# so this is commented out by default to leave a V1 CRL.
+# crl_extensions	= crl_ext
+
+default_days	= 3650			# how long to certify for
+default_crl_days= 30			# how long before next CRL
+default_md	= sha256		# use public key default MD
+preserve	= no			# keep passed DN ordering
+
+# A few difference way of specifying how similar the request should look
+# For type CA, the listed attributes must be the same, and the optional
+# and supplied fields are just that :-)
+policy		= policy_anything
+
+# For the CA policy
+[ policy_match ]
+countryName		= match
+stateOrProvinceName	= match
+organizationName	= match
+organizationalUnitName	= optional
+commonName		= supplied
+name			= optional
+emailAddress		= optional
+
+# For the 'anything' policy
+# At this point in time, you must list all acceptable 'object'
+# types.
+[ policy_anything ]
+countryName		= optional
+stateOrProvinceName	= optional
+localityName		= optional
+organizationName	= optional
+organizationalUnitName	= optional
+commonName		= supplied
+name			= optional
+emailAddress		= optional
+
+####################################################################
+[ req ]
+default_bits		= $ENV::KEY_SIZE
+default_keyfile 	= privkey.pem
+default_md		= sha256
+distinguished_name	= req_distinguished_name
+attributes		= req_attributes
+x509_extensions	= v3_ca	# The extentions to add to the self signed cert
+
+# Passwords for private keys if not present they will be prompted for
+# input_password = secret
+# output_password = secret
+
+# This sets a mask for permitted string types. There are several options.
+# default: PrintableString, T61String, BMPString.
+# pkix	 : PrintableString, BMPString (PKIX recommendation after 2004).
+# utf8only: only UTF8Strings (PKIX recommendation after 2004).
+# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
+# MASK:XXXX a literal mask value.
+string_mask = nombstr
+
+# req_extensions = v3_req # The extensions to add to a certificate request
+
+[ req_distinguished_name ]
+countryName			= Country Name (2 letter code)
+countryName_default		= $ENV::KEY_COUNTRY
+countryName_min			= 2
+countryName_max			= 2
+
+stateOrProvinceName		= State or Province Name (full name)
+stateOrProvinceName_default	= $ENV::KEY_PROVINCE
+
+localityName			= Locality Name (eg, city)
+localityName_default		= $ENV::KEY_CITY
+
+0.organizationName		= Organization Name (eg, company)
+0.organizationName_default	= $ENV::KEY_ORG
+
+# we can do this but it is not needed normally :-)
+#1.organizationName		= Second Organization Name (eg, company)
+#1.organizationName_default	= World Wide Web Pty Ltd
+
+organizationalUnitName		= Organizational Unit Name (eg, section)
+#organizationalUnitName_default	=
+
+commonName			= Common Name (eg, your name or your server\'s hostname)
+commonName_max			= 64
+
+name				= Name
+name_max			= 64
+
+emailAddress			= Email Address
+emailAddress_default		= $ENV::KEY_EMAIL
+emailAddress_max		= 40
+
+# JY -- added for batch mode
+organizationalUnitName_default = $ENV::KEY_OU
+commonName_default = $ENV::KEY_CN
+name_default = $ENV::KEY_NAME
+
+
+# SET-ex3			= SET extension number 3
+
+[ req_attributes ]
+challengePassword		= A challenge password
+challengePassword_min		= 4
+challengePassword_max		= 20
+
+unstructuredName		= An optional company name
+
+[ usr_cert ]
+
+# These extensions are added when 'ca' signs a request.
+
+# This goes against PKIX guidelines but some CAs do it and some software
+# requires this to avoid interpreting an end user certificate as a CA.
+
+basicConstraints=CA:FALSE
+
+# Here are some examples of the usage of nsCertType. If it is omitted
+# the certificate can be used for anything *except* object signing.
+
+# This is OK for an SSL server.
+# nsCertType			= server
+
+# For an object signing certificate this would be used.
+# nsCertType = objsign
+
+# For normal client use this is typical
+# nsCertType = client, email
+
+# and for everything including object signing:
+# nsCertType = client, email, objsign
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# This will be displayed in Netscape's comment listbox.
+nsComment			= "Easy-RSA Generated Certificate"
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer:always
+extendedKeyUsage=clientAuth
+keyUsage = digitalSignature
+
+
+# This stuff is for subjectAltName and issuerAltname.
+# Import the email address.
+# subjectAltName=email:copy
+subjectAltName=$ENV::KEY_ALTNAMES
+
+# Copy subject details
+# issuerAltName=issuer:copy
+
+#nsCaRevocationUrl		= http://www.domain.dom/ca-crl.pem
+#nsBaseUrl
+#nsRevocationUrl
+#nsRenewalUrl
+#nsCaPolicyUrl
+#nsSslServerName
+
+[ server ]
+
+# JY ADDED -- Make a cert with nsCertType set to "server"
+basicConstraints=CA:FALSE
+nsCertType                     = server
+nsComment                      = "Easy-RSA Generated Server Certificate"
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer:always
+extendedKeyUsage=serverAuth
+keyUsage = digitalSignature, keyEncipherment
+subjectAltName=$ENV::KEY_ALTNAMES
+
+[ v3_req ]
+
+# Extensions to add to a certificate request
+
+basicConstraints = CA:FALSE
+keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+[ v3_ca ]
+
+
+# Extensions for a typical CA
+
+
+# PKIX recommendation.
+
+subjectKeyIdentifier=hash
+
+authorityKeyIdentifier=keyid:always,issuer:always
+
+# This is what PKIX recommends but some broken software chokes on critical
+# extensions.
+#basicConstraints = critical,CA:true
+# So we do this instead.
+basicConstraints = CA:true
+
+# Key usage: this is typical for a CA certificate. However since it will
+# prevent it being used as an test self-signed certificate it is best
+# left out by default.
+# keyUsage = cRLSign, keyCertSign
+
+# Some might want this also
+# nsCertType = sslCA, emailCA
+
+# Include email address in subject alt name: another PKIX recommendation
+# subjectAltName=email:copy
+# Copy issuer details
+# issuerAltName=issuer:copy
+
+# DER hex encoding of an extension: beware experts only!
+# obj=DER:02:03
+# Where 'obj' is a standard or added object
+# You can even override a supported extension:
+# basicConstraints= critical, DER:30:03:01:01:FF
+
+[ crl_ext ]
+
+# CRL extensions.
+# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
+
+# issuerAltName=issuer:copy
+authorityKeyIdentifier=keyid:always,issuer:always
+
+[ engine_section ]
+#
+# If you are using PKCS#11
+# Install engine_pkcs11 of opensc (www.opensc.org)
+# And uncomment the following
+# verify that dynamic_path points to the correct location
+#
+#pkcs11 = pkcs11_section
+
+[ pkcs11_section ]
+engine_id = pkcs11
+dynamic_path = /usr/lib/engines/engine_pkcs11.so
+MODULE_PATH = $ENV::PKCS11_MODULE_PATH
+PIN = $ENV::PKCS11_PIN
+init = 0

+ 399 - 0
systems/mitm/openvpn/easy-rsa/pkitool

@@ -0,0 +1,399 @@
+#!/bin/sh
+
+#  OpenVPN -- An application to securely tunnel IP networks
+#             over a single TCP/UDP port, with support for SSL/TLS-based
+#             session authentication and key exchange,
+#             packet encryption, packet authentication, and
+#             packet compression.
+#
+#  Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
+#
+#  This program is free software; you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License version 2
+#  as published by the Free Software Foundation.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program (see the file COPYING included with this
+#  distribution); if not, write to the Free Software Foundation, Inc.,
+#  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+# pkitool is a front-end for the openssl tool.
+
+# Calling scripts can set the certificate organizational
+# unit with the KEY_OU environmental variable.
+
+# Calling scripts can also set the KEY_NAME environmental
+# variable to set the "name" X509 subject field.
+
+PROGNAME=pkitool
+VERSION=2.0
+DEBUG=0
+
+die()
+{
+    local m="$1"
+
+    echo "$m" >&2
+    exit 1
+}
+
+need_vars()
+{
+    cat <<EOM
+  Please edit the vars script to reflect your configuration,
+  then source it with "source ./vars".
+  Next, to start with a fresh PKI configuration and to delete any
+  previous certificates and keys, run "./clean-all".
+  Finally, you can run this tool ($PROGNAME) to build certificates/keys.
+EOM
+}
+
+usage()
+{
+    cat <<EOM
+$PROGNAME $VERSION
+Usage: $PROGNAME [options...] [common-name]
+
+Options:
+  --batch    : batch mode (default)
+  --keysize  : Set keysize
+      size   : size (default=1024)
+  --interact : interactive mode
+  --server   : build server cert
+  --initca   : build root CA
+  --inter    : build intermediate CA
+  --pass     : encrypt private key with password
+  --csr      : only generate a CSR, do not sign
+  --sign     : sign an existing CSR
+  --pkcs12   : generate a combined PKCS#12 file
+  --pkcs11   : generate certificate on PKCS#11 token
+      lib    : PKCS#11 library
+      slot   : PKCS#11 slot
+      id     : PKCS#11 object id (hex string)
+      label  : PKCS#11 object label
+
+Standalone options:
+  --pkcs11-slots   : list PKCS#11 slots
+      lib    : PKCS#11 library
+  --pkcs11-objects : list PKCS#11 token objects
+      lib    : PKCS#11 library
+      slot   : PKCS#11 slot
+  --pkcs11-init    : initialize PKCS#11 token DANGEROUS!!!
+      lib    : PKCS#11 library
+      slot   : PKCS#11 slot
+      label  : PKCS#11 token label
+
+Notes:
+EOM
+    need_vars
+    cat <<EOM
+  In order to use PKCS#11 interface you must have opensc-0.10.0 or higher.
+
+Generated files and corresponding OpenVPN directives:
+(Files will be placed in the \$KEY_DIR directory, defined in ./vars)
+  ca.crt     -> root certificate (--ca)
+  ca.key     -> root key, keep secure (not directly used by OpenVPN)
+  .crt files -> client/server certificates (--cert)
+  .key files -> private keys, keep secure (--key)
+  .csr files -> certificate signing request (not directly used by OpenVPN)
+  dh1024.pem or dh2048.pem -> Diffie Hellman parameters (--dh)
+
+Examples:
+  $PROGNAME --initca          -> Build root certificate
+  $PROGNAME --initca --pass   -> Build root certificate with password-protected key
+  $PROGNAME --server server1  -> Build "server1" certificate/key
+  $PROGNAME client1           -> Build "client1" certificate/key
+  $PROGNAME --pass client2    -> Build password-protected "client2" certificate/key
+  $PROGNAME --pkcs12 client3  -> Build "client3" certificate/key in PKCS#12 format
+  $PROGNAME --csr client4     -> Build "client4" CSR to be signed by another CA
+  $PROGNAME --sign client4    -> Sign "client4" CSR
+  $PROGNAME --inter interca   -> Build an intermediate key-signing certificate/key
+                               Also see ./inherit-inter script.
+  $PROGNAME --pkcs11 /usr/lib/pkcs11/lib1 0 010203 "client5 id" client5
+                              -> Build "client5" certificate/key in PKCS#11 token
+
+Typical usage for initial PKI setup.  Build myserver, client1, and client2 cert/keys.
+Protect client2 key with a password.  Build DH parms.  Generated files in ./keys :
+  [edit vars with your site-specific info]
+  source ./vars
+  ./clean-all
+  ./build-dh     -> takes a long time, consider backgrounding
+  ./$PROGNAME --initca
+  ./$PROGNAME --server myserver
+  ./$PROGNAME client1
+  ./$PROGNAME --pass client2
+
+Typical usage for adding client cert to existing PKI:
+  source ./vars
+  ./$PROGNAME client-new
+EOM
+}
+
+# Set tool defaults
+[ -n "$OPENSSL" ] || export OPENSSL="openssl"
+[ -n "$PKCS11TOOL" ] || export PKCS11TOOL="pkcs11-tool"
+[ -n "$GREP" ] || export GREP="grep"
+
+# Set defaults
+DO_REQ="1"
+REQ_EXT=""
+DO_CA="1"
+CA_EXT=""
+DO_P12="0"
+DO_P11="0"
+DO_ROOT="0"
+NODES_REQ="-nodes"
+NODES_P12=""
+BATCH="-batch"
+CA="ca"
+# must be set or errors of openssl.cnf
+PKCS11_MODULE_PATH="dummy"
+PKCS11_PIN="dummy"
+
+# Process options
+while [ $# -gt 0 ]; do
+    case "$1" in
+        --keysize  ) KEY_SIZE=$2
+                     shift;;
+        --server   ) REQ_EXT="$REQ_EXT -extensions server"
+                     CA_EXT="$CA_EXT -extensions server" ;;
+        --batch    ) BATCH="-batch" ;;
+        --interact ) BATCH="" ;;
+        --inter    ) CA_EXT="$CA_EXT -extensions v3_ca" ;;
+        --initca   ) DO_ROOT="1" ;;
+        --pass     ) NODES_REQ="" ;;
+        --csr      ) DO_CA="0" ;;
+        --sign     ) DO_REQ="0" ;;
+        --pkcs12   ) DO_P12="1" ;;
+        --pkcs11   ) DO_P11="1"
+                     PKCS11_MODULE_PATH="$2"
+                     PKCS11_SLOT="$3"
+                     PKCS11_ID="$4"
+                     PKCS11_LABEL="$5"
+                     shift 4;;
+
+        # standalone
+        --pkcs11-init)
+                     PKCS11_MODULE_PATH="$2"
+                     PKCS11_SLOT="$3"
+                     PKCS11_LABEL="$4"
+                     if [ -z "$PKCS11_LABEL" ]; then
+                       die "Please specify library name, slot and label"
+                     fi
+                     $PKCS11TOOL --module "$PKCS11_MODULE_PATH" --init-token --slot "$PKCS11_SLOT" \
+                             --label "$PKCS11_LABEL" &&
+                        $PKCS11TOOL --module "$PKCS11_MODULE_PATH" --init-pin --slot "$PKCS11_SLOT"
+                     exit $?;;
+        --pkcs11-slots)
+                     PKCS11_MODULE_PATH="$2"
+                     if [ -z "$PKCS11_MODULE_PATH" ]; then
+                       die "Please specify library name"
+                     fi
+                     $PKCS11TOOL --module "$PKCS11_MODULE_PATH" --list-slots
+                     exit 0;;
+        --pkcs11-objects)
+                     PKCS11_MODULE_PATH="$2"
+                     PKCS11_SLOT="$3"
+                     if [ -z "$PKCS11_SLOT" ]; then
+                       die "Please specify library name and slot"
+                     fi
+                     $PKCS11TOOL --module "$PKCS11_MODULE_PATH" --list-objects --login --slot "$PKCS11_SLOT"
+                     exit 0;;
+
+        --help|--usage)
+                    usage
+                    exit ;;
+        --version)
+                    echo "$PROGNAME $VERSION"
+                    exit ;;
+        # errors
+        --*        ) die "$PROGNAME: unknown option: $1" ;;
+        *          ) break ;;
+    esac
+    shift
+done
+
+if ! [ -z "$BATCH" ]; then
+        if $OPENSSL version | grep 0.9.6 > /dev/null; then
+                die "Batch mode is unsupported in openssl<0.9.7"
+        fi
+fi
+
+if [ $DO_P12 -eq 1 -a $DO_P11 -eq 1 ]; then
+        die "PKCS#11 and PKCS#12 cannot be specified together"
+fi
+
+if [ $DO_P11 -eq 1 ]; then
+        if ! grep "^pkcs11.*=" "$KEY_CONFIG" > /dev/null; then
+                die "Please edit $KEY_CONFIG and setup PKCS#11 engine"
+        fi
+fi
+
+# If we are generating pkcs12, only encrypt the final step
+if [ $DO_P12 -eq 1 ]; then
+    NODES_P12="$NODES_REQ"
+    NODES_REQ="-nodes"
+fi
+
+if [ $DO_P11 -eq 1 ]; then
+    if [ -z "$PKCS11_LABEL" ]; then
+        die "PKCS#11 arguments incomplete"
+    fi
+fi
+
+# If undefined, set default key expiration intervals
+if [ -z "$KEY_EXPIRE" ]; then
+    KEY_EXPIRE=3650
+fi
+if [ -z "$CA_EXPIRE" ]; then
+    CA_EXPIRE=3650
+fi
+
+# Set organizational unit to empty string if undefined
+if [ -z "$KEY_OU" ]; then
+    KEY_OU=""
+fi
+
+# Set X509 Name string to empty string if undefined
+if [ -z "$KEY_NAME" ]; then
+    KEY_NAME=""
+fi
+
+# Set KEY_CN, FN
+if [ $DO_ROOT -eq 1 ]; then
+    if [ -z "$KEY_CN" ]; then
+        if [ "$1" ]; then
+            KEY_CN="$1"
+	    KEY_ALTNAMES="DNS:${KEY_CN}"
+        elif [ "$KEY_ORG" ]; then
+            KEY_CN="$KEY_ORG CA"
+	    KEY_ALTNAMES="$KEY_CN"
+        fi
+    fi
+    if [ $BATCH ] && [ "$KEY_CN" ]; then
+        echo "Using CA Common Name:" "$KEY_CN"
+	KEY_ALTNAMES="$KEY_CN"
+    fi
+    FN="$KEY_CN"
+elif [ $BATCH ] && [ "$KEY_CN" ]; then
+    echo "Using Common Name:" "$KEY_CN"
+    KEY_ALTNAMES="$KEY_CN"
+    FN="$KEY_CN"
+    if [ "$1" ]; then
+        FN="$1"
+    fi
+else
+    KEY_CN="$1"
+    KEY_ALTNAMES="DNS:$1"
+    shift
+    while [ "x$1" != "x" ]
+    do
+        KEY_ALTNAMES="${KEY_ALTNAMES},DNS:$1"
+        shift
+    done
+    FN="$KEY_CN"
+fi
+
+export CA_EXPIRE KEY_EXPIRE KEY_OU KEY_NAME KEY_CN PKCS11_MODULE_PATH PKCS11_PIN KEY_ALTNAMES
+
+# Show parameters (debugging)
+if [ $DEBUG -eq 1 ]; then
+    echo DO_REQ $DO_REQ
+    echo REQ_EXT $REQ_EXT
+    echo DO_CA $DO_CA
+    echo CA_EXT $CA_EXT
+    echo NODES_REQ $NODES_REQ
+    echo NODES_P12 $NODES_P12
+    echo DO_P12 $DO_P12
+    echo KEY_CN $KEY_CN
+    echo KEY_ALTNAMES $KEY_ALTNAMES
+    echo BATCH $BATCH
+    echo DO_ROOT $DO_ROOT
+    echo KEY_EXPIRE $KEY_EXPIRE
+    echo CA_EXPIRE $CA_EXPIRE
+    echo KEY_OU $KEY_OU
+    echo KEY_NAME $KEY_NAME
+    echo DO_P11 $DO_P11
+    echo PKCS11_MODULE_PATH $PKCS11_MODULE_PATH
+    echo PKCS11_SLOT $PKCS11_SLOT
+    echo PKCS11_ID $PKCS11_ID
+    echo PKCS11_LABEL $PKCS11_LABEL
+fi
+
+# Make sure ./vars was sourced beforehand
+if [ -d "$KEY_DIR" ] && [ "$KEY_CONFIG" ]; then
+    cd "$KEY_DIR"
+
+    # Make sure $KEY_CONFIG points to the correct version
+    # of openssl.cnf
+    if $GREP -i 'easy-rsa version 2\.[0-9]' "$KEY_CONFIG" >/dev/null; then
+        :
+    else
+        echo "$PROGNAME: KEY_CONFIG (set by the ./vars script) is pointing to the wrong"
+        echo "version of openssl.cnf: $KEY_CONFIG"
+        echo "The correct version should have a comment that says: easy-rsa version 2.x";
+        exit 1;
+    fi
+
+    # Build root CA
+    if [ $DO_ROOT -eq 1 ]; then
+        $OPENSSL req $BATCH -days $CA_EXPIRE $NODES_REQ -new -newkey rsa:$KEY_SIZE \
+            -x509 -keyout "$CA.key" -out "$CA.crt" -config "$KEY_CONFIG" && \
+            chmod 0600 "$CA.key"
+    else
+        # Make sure CA key/cert is available
+        if [ $DO_CA -eq 1 ] || [ $DO_P12 -eq 1 ]; then
+            if [ ! -r "$CA.crt" ] || [ ! -r "$CA.key" ]; then
+                echo "$PROGNAME: Need a readable $CA.crt and $CA.key in $KEY_DIR"
+                echo "Try $PROGNAME --initca to build a root certificate/key."
+                exit 1
+            fi
+        fi
+
+        # Generate key for PKCS#11 token
+        PKCS11_ARGS=
+        if [ $DO_P11 -eq 1 ]; then
+                stty -echo
+                echo -n "User PIN: "
+                read -r PKCS11_PIN
+                stty echo
+                export PKCS11_PIN
+
+                echo "Generating key pair on PKCS#11 token..."
+                $PKCS11TOOL --module "$PKCS11_MODULE_PATH" --keypairgen \
+                        --login --pin "$PKCS11_PIN" \
+                        --key-type rsa:1024 \
+                        --slot "$PKCS11_SLOT" --id "$PKCS11_ID" --label "$PKCS11_LABEL" || exit 1
+                PKCS11_ARGS="-engine pkcs11 -keyform engine -key $PKCS11_SLOT:$PKCS11_ID"
+        fi
+
+        # Build cert/key
+        ( [ $DO_REQ -eq 0 ] || $OPENSSL req $BATCH $NODES_REQ -new -newkey rsa:$KEY_SIZE \
+                -keyout "$FN.key" -out "$FN.csr" $REQ_EXT -config "$KEY_CONFIG" $PKCS11_ARGS ) && \
+            ( [ $DO_CA -eq 0 ]  || $OPENSSL ca $BATCH -days $KEY_EXPIRE -out "$FN.crt" \
+                -in "$FN.csr" $CA_EXT -config "$KEY_CONFIG" ) && \
+            ( [ $DO_P12 -eq 0 ] || $OPENSSL pkcs12 -export -inkey "$FN.key" \
+                -in "$FN.crt" -certfile "$CA.crt" -out "$FN.p12" $NODES_P12 ) && \
+            ( [ $DO_CA -eq 0 -o $DO_P11 -eq 1 ]  || chmod 0600 "$FN.key" ) && \
+            ( [ $DO_P12 -eq 0 ] || chmod 0600 "$FN.p12" )
+
+        # Load certificate into PKCS#11 token
+        if [ $DO_P11 -eq 1 ]; then
+                $OPENSSL x509 -in "$FN.crt" -inform PEM -out "$FN.crt.der" -outform DER && \
+                  $PKCS11TOOL --module "$PKCS11_MODULE_PATH" --write-object "$FN.crt.der" --type cert \
+                        --login --pin "$PKCS11_PIN" \
+                        --slot "$PKCS11_SLOT" --id "$PKCS11_ID" --label "$PKCS11_LABEL"
+                [ -e "$FN.crt.der" ]; rm "$FN.crt.der"
+        fi
+
+    fi
+
+# Need definitions
+else
+    need_vars
+fi

+ 43 - 0
systems/mitm/openvpn/easy-rsa/revoke-full

@@ -0,0 +1,43 @@
+#!/bin/sh
+
+# revoke a certificate, regenerate CRL,
+# and verify revocation
+
+CRL="crl.pem"
+RT="revoke-test.pem"
+
+if [ $# -ne 1 ]; then
+    echo "usage: revoke-full <cert-name-base>";
+    exit 1
+fi
+
+if [ "$KEY_DIR" ]; then
+    cd "$KEY_DIR"
+    rm -f "$RT"
+
+    # set defaults
+    export KEY_CN=""
+    export KEY_OU=""
+    export KEY_NAME=""
+
+	# required due to hack in openssl.cnf that supports Subject Alternative Names
+    export KEY_ALTNAMES=""
+
+    # revoke key and generate a new CRL
+    $OPENSSL ca -revoke "$1.crt" -config "$KEY_CONFIG"
+
+    # generate a new CRL -- try to be compatible with
+    # intermediate PKIs
+    $OPENSSL ca -gencrl -out "$CRL" -config "$KEY_CONFIG"
+    if [ -e export-ca.crt ]; then
+        cat export-ca.crt "$CRL" >"$RT"
+    else
+        cat ca.crt "$CRL" >"$RT"
+    fi
+
+    # verify the revocation
+    $OPENSSL verify -CAfile "$RT" -crl_check "$1.crt"
+else
+    echo 'Please source the vars script first (i.e. "source ./vars")'
+    echo 'Make sure you have edited it to reflect your configuration.'
+fi

+ 7 - 0
systems/mitm/openvpn/easy-rsa/sign-req

@@ -0,0 +1,7 @@
+#!/bin/sh
+
+# Sign a certificate signing request (a .csr file)
+# with a local root certificate and key.
+
+export EASY_RSA="${EASY_RSA:-.}"
+"$EASY_RSA/pkitool" --interact --sign $*

+ 80 - 0
systems/mitm/openvpn/easy-rsa/vars

@@ -0,0 +1,80 @@
+# easy-rsa parameter settings
+
+# NOTE: If you installed from an RPM,
+# don't edit this file in place in
+# /usr/share/openvpn/easy-rsa --
+# instead, you should copy the whole
+# easy-rsa directory to another location
+# (such as /etc/openvpn) so that your
+# edits will not be wiped out by a future
+# OpenVPN package upgrade.
+
+# This variable should point to
+# the top level of the easy-rsa
+# tree.
+export EASY_RSA="`pwd`"
+
+#
+# This variable should point to
+# the requested executables
+#
+export OPENSSL="openssl"
+export PKCS11TOOL="pkcs11-tool"
+export GREP="grep"
+
+
+# This variable should point to
+# the openssl.cnf file included
+# with easy-rsa.
+export KEY_CONFIG=`$EASY_RSA/whichopensslcnf $EASY_RSA`
+
+# Edit this variable to point to
+# your soon-to-be-created key
+# directory.
+#
+# WARNING: clean-all will do
+# a rm -rf on this directory
+# so make sure you define
+# it correctly!
+export KEY_DIR="$EASY_RSA/keys"
+
+# Issue rm -rf warning
+echo NOTE: If you run ./clean-all, I will be doing a rm -rf on $KEY_DIR
+
+# PKCS11 fixes
+export PKCS11_MODULE_PATH="dummy"
+export PKCS11_PIN="dummy"
+
+# Increase this to 2048 if you
+# are paranoid.  This will slow
+# down TLS negotiation performance
+# as well as the one-time DH parms
+# generation process.
+export KEY_SIZE=2048
+
+# In how many days should the root CA key expire?
+export CA_EXPIRE=3650
+
+# In how many days should certificates expire?
+export KEY_EXPIRE=3650
+
+# These are the default values for fields
+# which will be placed in the certificate.
+# Don't leave any of these fields blank.
+export KEY_COUNTRY="US"
+export KEY_PROVINCE="CA"
+export KEY_CITY="San Luis Obispo"
+export KEY_ORG="Cal Poly"
+export KEY_EMAIL="tflucke@calpoly.edu"
+export KEY_OU="Computer Science Department"
+
+# X509 Subject Field
+export KEY_NAME="ThesisVPN"
+
+# PKCS11 Smart Card
+# export PKCS11_MODULE_PATH="/usr/lib/changeme.so"
+# export PKCS11_PIN=1234
+
+# If you'd like to sign all keys with the same Common Name, uncomment the KEY_CN export below
+# You will also need to make sure your OpenVPN server config has the duplicate-cn option set
+# export KEY_CN="CommonName"

+ 26 - 0
systems/mitm/openvpn/easy-rsa/whichopensslcnf

@@ -0,0 +1,26 @@
+#!/bin/sh
+
+cnf="$1/openssl.cnf"
+
+if [ "$OPENSSL" ]; then
+    if $OPENSSL version | grep -E "0\.9\.6[[:alnum:]]?" > /dev/null; then
+        cnf="$1/openssl-0.9.6.cnf"
+    elif $OPENSSL version | grep -E "0\.9\.8[[:alnum:]]?" > /dev/null; then
+        cnf="$1/openssl-0.9.8.cnf"
+    elif $OPENSSL version | grep -E "1\.0\.[[:digit:]][[:alnum:]]?" > /dev/null; then
+        cnf="$1/openssl-1.0.0.cnf"
+    else
+        cnf="$1/openssl.cnf"
+    fi
+fi
+
+echo $cnf
+
+if [ ! -r $cnf ]; then
+    echo "**************************************************************" >&2
+    echo "  No $cnf file could be found" >&2
+    echo "  Further invocations will fail" >&2
+    echo "**************************************************************" >&2
+fi
+
+exit 0

+ 321 - 0
systems/mitm/openvpn/thesis.conf

@@ -0,0 +1,321 @@
+#################################################
+# Sample OpenVPN 2.0 config file for            #
+# multi-client server.                          #
+#                                               #
+# This file is for the server side              #
+# of a many-clients <-> one-server              #
+# OpenVPN configuration.                        #
+#                                               #
+# OpenVPN also supports                         #
+# single-machine <-> single-machine             #
+# configurations (See the Examples page         #
+# on the web site for more info).               #
+#                                               #
+# This config should work on Windows            #
+# or Linux/BSD systems.  Remember on            #
+# Windows to quote pathnames and use            #
+# double backslashes, e.g.:                     #
+# "C:\\Program Files\\OpenVPN\\config\\foo.key" #
+#                                               #
+# Comments are preceded with '#' or ';'         #
+#################################################
+
+# Which local IP address should OpenVPN
+# listen on? (optional)
+;local a.b.c.d
+
+# Which TCP/UDP port should OpenVPN listen on?
+# If you want to run multiple OpenVPN instances
+# on the same machine, use a different port
+# number for each one.  You will need to
+# open up this port on your firewall.
+port 1194
+
+# TCP or UDP server?
+;proto tcp
+proto udp
+
+# "dev tun" will create a routed IP tunnel,
+# "dev tap" will create an ethernet tunnel.
+# Use "dev tap0" if you are ethernet bridging
+# and have precreated a tap0 virtual interface
+# and bridged it with your ethernet interface.
+# If you want to control access policies
+# over the VPN, you must create firewall
+# rules for the the TUN/TAP interface.
+# On non-Windows systems, you can give
+# an explicit unit number, such as tun0.
+# On Windows, use "dev-node" for this.
+# On most systems, the VPN will not function
+# unless you partially or fully disable
+# the firewall for the TUN/TAP interface.
+;dev tap
+dev tun
+
+# Windows needs the TAP-Win32 adapter name
+# from the Network Connections panel if you
+# have more than one.  On XP SP2 or higher,
+# you may need to selectively disable the
+# Windows firewall for the TAP adapter.
+# Non-Windows systems usually don't need this.
+;dev-node MyTap
+
+# SSL/TLS root certificate (ca), certificate
+# (cert), and private key (key).  Each client
+# and the server must have their own cert and
+# key file.  The server and all clients will
+# use the same ca file.
+#
+# See the "easy-rsa" directory for a series
+# of scripts for generating RSA certificates
+# and private keys.  Remember to use
+# a unique Common Name for the server
+# and each of the client certificates.
+#
+# Any X509 key management system can be used.
+# OpenVPN can also use a PKCS #12 formatted key file
+# (see "pkcs12" directive in man page).
+ca ca.crt
+cert ThesisVPN.crt
+key ThesisVPN.key  # This file should be kept secret
+
+# Diffie hellman parameters.
+# Generate your own with:
+#   openssl dhparam -out dh2048.pem 2048
+dh dh2048.pem
+
+# Network topology
+# Should be subnet (addressing via IP)
+# unless Windows clients v2.0.9 and lower have to
+# be supported (then net30, i.e. a /30 per client)
+# Defaults to net30 (not recommended)
+topology subnet
+
+# Configure server mode and supply a VPN subnet
+# for OpenVPN to draw client addresses from.
+# The server will take 10.8.0.1 for itself,
+# the rest will be made available to clients.
+# Each client will be able to reach the server
+# on 10.8.0.1. Comment this line out if you are
+# ethernet bridging. See the man page for more info.
+server 10.8.0.0 255.255.255.0
+
+# Maintain a record of client <-> virtual IP address
+# associations in this file.  If OpenVPN goes down or
+# is restarted, reconnecting clients can be assigned
+# the same virtual IP address from the pool that was
+# previously assigned.
+ifconfig-pool-persist /var/log/openvpn/ipp.txt
+
+# Configure server mode for ethernet bridging.
+# You must first use your OS's bridging capability
+# to bridge the TAP interface with the ethernet
+# NIC interface.  Then you must manually set the
+# IP/netmask on the bridge interface, here we
+# assume 10.8.0.4/255.255.255.0.  Finally we
+# must set aside an IP range in this subnet
+# (start=10.8.0.50 end=10.8.0.100) to allocate
+# to connecting clients.  Leave this line commented
+# out unless you are ethernet bridging.
+;server-bridge 10.8.0.4 255.255.255.0 10.8.0.50 10.8.0.100
+
+# Configure server mode for ethernet bridging
+# using a DHCP-proxy, where clients talk
+# to the OpenVPN server-side DHCP server
+# to receive their IP address allocation
+# and DNS server addresses.  You must first use
+# your OS's bridging capability to bridge the TAP
+# interface with the ethernet NIC interface.
+# Note: this mode only works on clients (such as
+# Windows), where the client-side TAP adapter is
+# bound to a DHCP client.
+;server-bridge
+
+# Push routes to the client to allow it
+# to reach other private subnets behind
+# the server.  Remember that these
+# private subnets will also need
+# to know to route the OpenVPN client
+# address pool (10.8.0.0/255.255.255.0)
+# back to the OpenVPN server.
+;push "route 192.168.10.0 255.255.255.0"
+;push "route 192.168.20.0 255.255.255.0"
+
+# To assign specific IP addresses to specific
+# clients or if a connecting client has a private
+# subnet behind it that should also have VPN access,
+# use the subdirectory "ccd" for client-specific
+# configuration files (see man page for more info).
+
+# EXAMPLE: Suppose the client
+# having the certificate common name "Thelonious"
+# also has a small subnet behind his connecting
+# machine, such as 192.168.40.128/255.255.255.248.
+# First, uncomment out these lines:
+;client-config-dir ccd
+;route 192.168.40.128 255.255.255.248
+# Then create a file ccd/Thelonious with this line:
+#   iroute 192.168.40.128 255.255.255.248
+# This will allow Thelonious' private subnet to
+# access the VPN.  This example will only work
+# if you are routing, not bridging, i.e. you are
+# using "dev tun" and "server" directives.
+
+# EXAMPLE: Suppose you want to give
+# Thelonious a fixed VPN IP address of 10.9.0.1.
+# First uncomment out these lines:
+;client-config-dir ccd
+;route 10.9.0.0 255.255.255.252
+# Then add this line to ccd/Thelonious:
+#   ifconfig-push 10.9.0.1 10.9.0.2
+
+# Suppose that you want to enable different
+# firewall access policies for different groups
+# of clients.  There are two methods:
+# (1) Run multiple OpenVPN daemons, one for each
+#     group, and firewall the TUN/TAP interface
+#     for each group/daemon appropriately.
+# (2) (Advanced) Create a script to dynamically
+#     modify the firewall in response to access
+#     from different clients.  See man
+#     page for more info on learn-address script.
+;learn-address ./script
+
+# If enabled, this directive will configure
+# all clients to redirect their default
+# network gateway through the VPN, causing
+# all IP traffic such as web browsing and
+# and DNS lookups to go through the VPN
+# (The OpenVPN server machine may need to NAT
+# or bridge the TUN/TAP interface to the internet
+# in order for this to work properly).
+push "redirect-gateway def1 bypass-dhcp"
+
+# Certain Windows-specific network settings
+# can be pushed to clients, such as DNS
+# or WINS server addresses.  CAVEAT:
+# http://openvpn.net/faq.html#dhcpcaveats
+# The addresses below refer to the public
+# DNS servers provided by opendns.com.
+;push "dhcp-option DNS 208.67.222.222"
+;push "dhcp-option DNS 208.67.220.220"
+
+# Uncomment this directive to allow different
+# clients to be able to "see" each other.
+# By default, clients will only see the server.
+# To force clients to only see the server, you
+# will also need to appropriately firewall the
+# server's TUN/TAP interface.
+;client-to-client
+
+# Uncomment this directive if multiple clients
+# might connect with the same certificate/key
+# files or common names.  This is recommended
+# only for testing purposes.  For production use,
+# each client should have its own certificate/key
+# pair.
+#
+# IF YOU HAVE NOT GENERATED INDIVIDUAL
+# CERTIFICATE/KEY PAIRS FOR EACH CLIENT,
+# EACH HAVING ITS OWN UNIQUE "COMMON NAME",
+# UNCOMMENT THIS LINE OUT.
+duplicate-cn
+
+# The keepalive directive causes ping-like
+# messages to be sent back and forth over
+# the link so that each side knows when
+# the other side has gone down.
+# Ping every 10 seconds, assume that remote
+# peer is down if no ping received during
+# a 120 second time period.
+keepalive 10 120
+
+# For extra security beyond that provided
+# by SSL/TLS, create an "HMAC firewall"
+# to help block DoS attacks and UDP port flooding.
+#
+# Generate with:
+#   openvpn --genkey --secret ta.key
+#
+# The server and each client must have
+# a copy of this key.
+# The second parameter should be '0'
+# on the server and '1' on the clients.
+;tls-auth ta.key 0 # This file is secret
+
+# Select a cryptographic cipher.
+# This config item must be copied to
+# the client config file as well.
+# Note that v2.4 client/server will automatically
+# negotiate AES-256-GCM in TLS mode.
+# See also the ncp-cipher option in the manpage
+;cipher AES-256-CBC
+# Disables all encryption/authentification
+# We don't actually want to add extra protections,
+# we just want to reroute the packets.
+# Disabling encryption reduces overhead/variables.
+auth none
+cipher none
+
+# Enable compression on the VPN link and push the
+# option to the client (v2.4+ only, for earlier
+# versions see below)
+;compress lz4-v2
+;push "compress lz4-v2"
+
+# For compression compatible with older clients use comp-lzo
+# If you enable it here, you must also
+# enable it in the client config file.
+;comp-lzo
+
+# The maximum number of concurrently connected
+# clients we want to allow.
+;max-clients 100
+
+# It's a good idea to reduce the OpenVPN
+# daemon's privileges after initialization.
+#
+# You can uncomment this out on
+# non-Windows systems.
+user nobody
+group nogroup
+
+# The persist options will try to avoid
+# accessing certain resources on restart
+# that may no longer be accessible because
+# of the privilege downgrade.
+persist-key
+persist-tun
+
+# Output a short status file showing
+# current connections, truncated
+# and rewritten every minute.
+status /var/log/openvpn/openvpn-status.log
+
+# By default, log messages will go to the syslog (or
+# on Windows, if running as a service, they will go to
+# the "\Program Files\OpenVPN\log" directory).
+# Use log or log-append to override this default.
+# "log" will truncate the log file on OpenVPN startup,
+# while "log-append" will append to it.  Use one
+# or the other (but not both).
+;log         /var/log/openvpn/openvpn.log
+;log-append  /var/log/openvpn/openvpn.log
+
+# Set the appropriate level of log
+# file verbosity.
+#
+# 0 is silent, except for fatal errors
+# 4 is reasonable for general usage
+# 5 and 6 can help to debug connection problems
+# 9 is extremely verbose
+verb 3
+
+# Silence repeating messages.  At most 20
+# sequential messages of the same message
+# category will be output to the log.
+;mute 20
+
+# Notify the client that when the server restarts so it
+# can automatically reconnect.
+explicit-exit-notify 1

+ 58 - 0
systems/mitm/openvpn/update-resolv-conf

@@ -0,0 +1,58 @@
+#!/bin/bash
+# 
+# Parses DHCP options from openvpn to update resolv.conf
+# To use set as 'up' and 'down' script in your openvpn *.conf:
+# up /etc/openvpn/update-resolv-conf
+# down /etc/openvpn/update-resolv-conf
+#
+# Used snippets of resolvconf script by Thomas Hood and Chris Hanson.
+# Licensed under the GNU GPL.  See /usr/share/common-licenses/GPL. 
+# 
+# Example envs set from openvpn:
+#
+#     foreign_option_1='dhcp-option DNS 193.43.27.132'
+#     foreign_option_2='dhcp-option DNS 193.43.27.133'
+#     foreign_option_3='dhcp-option DOMAIN be.bnc.ch'
+#
+
+[ -x /sbin/resolvconf ] || exit 0
+[ "$script_type" ] || exit 0
+[ "$dev" ] || exit 0
+
+split_into_parts()
+{
+	part1="$1"
+	part2="$2"
+	part3="$3"
+}
+
+case "$script_type" in
+  up)
+	NMSRVRS=""
+	SRCHS=""
+	for optionvarname in ${!foreign_option_*} ; do
+		option="${!optionvarname}"
+		echo "$option"
+		split_into_parts $option
+		if [ "$part1" = "dhcp-option" ] ; then
+			if [ "$part2" = "DNS" ] ; then
+				NMSRVRS="${NMSRVRS:+$NMSRVRS }$part3"
+			elif [ "$part2" = "DOMAIN" ] ; then
+				SRCHS="${SRCHS:+$SRCHS }$part3"
+			fi
+		fi
+	done
+	R=""
+	[ "$SRCHS" ] && R="search $SRCHS
+"
+	for NS in $NMSRVRS ; do
+        	R="${R}nameserver $NS
+"
+	done
+	echo -n "$R" | /sbin/resolvconf -a "${dev}.openvpn"
+	;;
+  down)
+	/sbin/resolvconf -d "${dev}.openvpn"
+	;;
+esac
+

+ 209 - 0
systems/mitm/usr/local/bin/packetTap.sh

@@ -0,0 +1,209 @@
+#!/bin/bash
+
+shopt -s extglob
+
+# settings
+readonly LOGDIR='/var/log/tcpdump'
+
+# Name or location of main log file.  If not a path, will be saved to LOGDIR
+MAINLOGFILE='main.log'
+## File is reduced when this size is reached.
+readonly MAINLOGFILEMAXSIZE=$(( 20 * 1024 * 1024 )) ## bytes
+## This is the extra space given when file is reduced.
+readonly MAINLOGFILEALLOWANCE=$(( 1 * 1024 * 1024 )) ## bytes
+## Recommended: >= 300
+readonly MAINLOGCHECKINTERVALS=300 ## seconds
+
+# Location of tcpdump
+readonly TCPDUMP='/usr/sbin/tcpdump'
+## customize arguments here e.g. (-C 1 "another with spaces")
+readonly MY_IP=$(host `hostname` | cut -d' ' -f4)
+# Arguments for tcpdump
+readonly TCPDUMPARGS=("(src $MY_IP and dst port 22) or
+		       (dst $MY_IP and src port 22)")
+# Capture log prefix
+readonly TCPDUMPCAPTUREFILEPREFIX='thesis-capture-'
+# Capture log suffix
+readonly TCPDUMPCAPTUREFILESUFFIX=''
+# Frequency to check that tcpdump is running
+readonly TCPDUMPCHECKINTERVALS=60 ## seconds
+# Frequency to try and re-run tcpdump if it failed
+readonly TCPDUMPTRYTIMEOUT=20 ## seconds
+
+# How long to keep log files around
+readonly OLD=14 ## days
+# How large of a block to copy at a time
+readonly DDBLOCKSIZE=512 ## bytes
+# Location for temporary files
+readonly TEMPDIR='/var/tmp'
+
+# other variables
+CURRENTDATE=''
+QUIT=false
+TCPDUMPPID=0
+
+# functions
+# Print to log file
+function log {
+    echo "[$(date '+%F %T')] $1" >> "$MAINLOGFILE"
+    echo "$1"
+}
+
+# Check if tcpdump process is running
+# Returns 1 if not found
+function checktcpdump {
+    [[ $TCPDUMPPID -ne 0 ]] && [[ -e /proc/$TCPDUMPPID ]] &&
+	kill -s 0 "$TCPDUMPPID" 2>/dev/null
+}
+
+# Creates a new log file for tcpdump and forks a new process
+# Returns 1 on error
+function starttcpdump {
+    log "Starting tcpdump..."
+    CURRENTDATE=$(date +%F)
+    local BASENAME="${TCPDUMPCAPTUREFILEPREFIX}${CURRENTDATE}${TCPDUMPCAPTUREFILESUFFIX}"
+    local -a EXISTINGFILES
+    # Generate a list of all files matching pattern and put into array
+    {
+	if [[ BASH_VERSINFO -ge 4 ]]; then
+	    readarray -t EXISTINGFILES
+	else
+	    EXISTINGFILES=()
+	    local -i I=0
+	    while read LINE; do
+		EXISTINGFILES[I++]=$LINE
+	    done
+	fi
+    } < <(compgen -G "$LOGDIR/${BASENAME}.+([[:digit:]]).pcap*([[:digit:]])")
+    # Finds the lowest log file number higher than all existing files
+    local NEXT_SESSION=0
+    if [[ ${#EXISTINGFILES[@]} -gt 0 ]]; then
+	local SESSION_NUMBER
+	for FILE in "${EXISTINGFILES[@]}"; do
+	    SESSION_NUMBER=${FILE%.pcap*}
+	    SESSION_NUMBER=${SESSION_NUMBER##*.}
+	    # If session_number is a gigit and >= next_session, then
+	    # next_session = session_number + 1
+	    [[ $SESSION_NUMBER == +([[:digit:]]) &&
+		   SESSION_NUMBER -ge NEXT_SESSION ]] &&
+		NEXT_SESSION=$(( SESSION_NUMBER + 1 ))
+	done
+    fi
+    # Forks tcpdump and checks that it succeeded
+    local OUTPUTFILE=$LOGDIR/${BASENAME}.$NEXT_SESSION.pcap
+    "$TCPDUMP" "${TCPDUMPARGS[@]}" -w "$OUTPUTFILE" &
+    if [[ $? -ne 0 ]]; then
+	TCPDUMPPID=0
+	return 1
+    fi
+    TCPDUMPPID=$!
+    disown "$TCPDUMPPID"
+    checktcpdump
+}
+
+# Try to start tcpdump.  If $QUIT, then exit after a failed attempt
+# otherwise try again
+function starttcpdumploop {
+    until starttcpdump; do
+	log "Error: Failed to start tcpdump.  Waiting for $TCPDUMPTRYTIMEOUT seconds before next attempt..."
+	read -t $TCPDUMPTRYTIMEOUT
+	[[ $QUIT = true ]] && {
+	    log "Ending tcpdump manager script."
+	    exit
+	}
+    done
+}
+
+# Kill the current tcpdump process and set QUIT to true
+function stoptcpdump {
+    log "Stopping tcpdump..."
+    kill "$TCPDUMPPID"
+    # If tcpdump is still running, sigkill it
+    checktcpdump && kill -s 9 "$TCPDUMPPID"
+    TCPDUMPPID=0
+    QUIT=true
+}
+
+# Stop tcpdump and start it again
+function restarttcpdump {
+    local TMPQUIT=$QUIT
+    log "Restarting tcpdump..."
+    checktcpdump && stoptcpdump
+    QUIT=$TMPQUIT
+    starttcpdumploop
+}
+
+# Sets QUIT to true
+function catchsignals {
+    log "Caught a signal."
+    QUIT=true
+}
+
+function main {
+    local CAPTUREFILEPATTERN FILE NEWDATE SIZE TEMPFILE
+    local -i I
+    # Initializes variables and starts tcpdump child
+    CAPTUREFILEPATTERN="${TCPDUMPCAPTUREFILEPREFIX}[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]${TCPDUMPCAPTUREFILESUFFIX}.pcap*"
+    [[ $MAINLOGFILE != */* ]] && MAINLOGFILE=$LOGDIR/$MAINLOGFILE
+    log "Starting tcpdump manager script..."
+    [[ $MAINLOGFILEMAXSIZE == +([[:digit:]]) && MAINLOGFILEMAXSIZE -gt DDBLOCKSIZE ]] || {
+	echo "MAINLOGFILEMAXSIZE is not valid."
+	return 1
+    }
+    [[ $MAINLOGFILEALLOWANCE == +([[:digit:]]) && MAINLOGFILEALLOWANCE -gt DDBLOCKSIZE && MAINLOGFILEALLOWANCE -lt MAINLOGFILEMAXSIZE ]] || {
+	echo "MAINLOGFILEALLOWANCE is not valid."
+	return 1
+    }
+    trap catchsignals SIGQUIT SIGINT SIGKILL SIGTERM
+    mkdir -p "$LOGDIR"
+    starttcpdumploop
+    # 
+    for (( I = 1;; I = (I + 1) % 10000 )); do
+	# Wait 1 second
+	## we have to separate this from the next statement
+	## to ensure proper handling of signals
+	read -t 1
+	# If QUIT, exit loop
+	[[ $QUIT = true ]] && break
+	#  Handle daily file rotations
+	if (( (I % TCPDUMPCHECKINTERVALS) == 0 )); then
+	    NEWDATE=$(exec date +%F)
+	    if [[ ! $NEWDATE = "$CURRENTDATE" ]]; then
+		log "A new day has come."
+		# Delete files older than $OLD
+		if read FILE; then
+		    log "Deleting $OLD-days old files..."
+		    while
+			log "Deleting $FILE..."
+			rm -f "$FILE"
+			read FILE
+		    do
+			continue
+		    done
+		fi < <(exec find "$LOGDIR" -name "$CAPTUREFILEPATTERN" -daystart -ctime "+$OLD")   # or -mtime?
+		# Delete empty files
+		find "$LOGDIR" -size 0 -delete
+		restarttcpdump
+	    fi
+	fi
+	# Truncates main log from front if it exceeds maximum
+	if (( (I % MAINLOGCHECKINTERVALS) == 0 )); then
+	    SIZE=$(exec stat --printf=%s "$MAINLOGFILE")
+	    if [[ $SIZE == +([[:digit:]]) && SIZE -gt MAINLOGFILEMAXSIZE ]]; then
+		log "Reducing log data in $MAINLOGFILE..."
+		TEMPFILE=$TEMPDIR/tcpdump-$RANDOM.tmp
+		SKIP=$(( (SIZE - (MAINLOGFILEMAXSIZE - MAINLOGFILEALLOWANCE)) /
+			 DDBLOCKSIZE ))
+		dd "bs=$DDBLOCKSIZE" "skip=$SKIP" "if=$MAINLOGFILE" "of=$TEMPFILE"
+		## better than mv
+		cat "$TEMPFILE" > "$MAINLOGFILE"; rm -f "$TEMPFILE"
+	    fi
+	fi
+    done
+    # Stop tcpdump
+    checktcpdump && stoptcpdump
+    log "Ending tcpdump manager script."
+}
+
+# start
+main

+ 127 - 0
systems/victim/etc/openvpn/client.conf

@@ -0,0 +1,127 @@
+##############################################
+# Sample client-side OpenVPN 2.0 config file #
+# for connecting to multi-client server.     #
+#                                            #
+# This configuration can be used by multiple #
+# clients, however each client should have   #
+# its own cert and key files.                #
+#                                            #
+# On Windows, you might want to rename this  #
+# file so it has a .ovpn extension           #
+##############################################
+
+# Specify that we are a client and that we
+# will be pulling certain config file directives
+# from the server.
+client
+
+# Use the same setting as you are using on
+# the server.
+# On most systems, the VPN will not function
+# unless you partially or fully disable
+# the firewall for the TUN/TAP interface.
+;dev tap
+dev tun
+
+# Windows needs the TAP-Win32 adapter name
+# from the Network Connections panel
+# if you have more than one.  On XP SP2,
+# you may need to disable the firewall
+# for the TAP adapter.
+;dev-node MyTap
+
+# Are we connecting to a TCP or
+# UDP server?  Use the same setting as
+# on the server.
+;proto tcp
+proto udp
+
+# The hostname/IP and port of the server.
+# You can have multiple remote entries
+# to load balance between the servers.
+remote tf2.csc.calpoly.io 1194
+;remote my-server-2 1194
+
+# Choose a random host from the remote
+# list for load-balancing.  Otherwise
+# try hosts in the order specified.
+;remote-random
+
+# Keep trying indefinitely to resolve the
+# host name of the OpenVPN server.  Very useful
+# on machines which are not permanently connected
+# to the internet such as laptops.
+resolv-retry infinite
+
+# Most clients don't need to bind to
+# a specific local port number.
+nobind
+
+# Downgrade privileges after initialization (non-Windows only)
+user nobody
+group nogroup
+
+# Try to preserve some state across restarts.
+persist-key
+persist-tun
+
+# If you are connecting through an
+# HTTP proxy to reach the actual OpenVPN
+# server, put the proxy server/IP and
+# port number here.  See the man page
+# if your proxy server requires
+# authentication.
+;http-proxy-retry # retry on connection failures
+;http-proxy [proxy server] [proxy port #]
+
+# Wireless networks often produce a lot
+# of duplicate packets.  Set this flag
+# to silence duplicate packet warnings.
+;mute-replay-warnings
+
+# SSL/TLS parms.
+# See the server config file for more
+# description.  It's best to use
+# a separate .crt/.key file pair
+# for each client.  A single ca
+# file can be used for all clients.
+ca ca.crt
+cert client1.crt
+key client1.key
+
+script-security 1
+
+# Verify server certificate by checking that the
+# certicate has the correct key usage set.
+# This is an important precaution to protect against
+# a potential attack discussed here:
+#  http://openvpn.net/howto.html#mitm
+#
+# To use this feature, you will need to generate
+# your server certificates with the keyUsage set to
+#   digitalSignature, keyEncipherment
+# and the extendedKeyUsage to
+#   serverAuth
+# EasyRSA can do this for you.
+remote-cert-tls server
+
+# If a tls-auth key is used on the server
+# then every client must also have the key.
+;tls-auth ta.key 1
+
+# Select a cryptographic cipher.
+# If the cipher option is used on the server
+# then you must also specify it here.
+cipher none
+auth none
+
+# Enable compression on the VPN link.
+# Don't enable this unless it is also
+# enabled in the server config file.
+;comp-lzo
+
+# Set log file verbosity.
+verb 3
+
+# Silence repeating messages
+;mute 20

+ 1 - 0
systems/victim/keylog_rsa.pub

@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDJfrZrLhccxPUrFjPsevT4NgkpyydSXwxcooP9TeulU3MrOtbES3hfMJwxTPQdsb/1tYN6FL0XBVp6Q5GZLBxep5GwSLmpF3DMvmK8TmQBEnq1KcaGjek4vw6hxP2e+kjIytWbFUZXj2yrBFGfd3kfGroMuC2SUb/ySYJSrJES9EsW7jpcCknTkqoYb/QAprcXD1lEIzHkwZeh5xcVURrBkc9Z2LpvgCmvXnKtNXMld1twhQc/Ezx7JvOkFzpg9e6sSyLzPcx+ZhACM9VCJbe5C5VV0DKs9qGt1WhVVcnZY76opz5Y6sQX8+/bJNHalNTrTPkt1Ufdf+KSJUx9356b subject@Thesis-VM

+ 24 - 0
systems/victim/usr/local/bin/routing-rest.sh

@@ -0,0 +1,24 @@
+#!/bin/sh
+
+# Sometimes the connection does down and we lose our route to
+# the VPN.  Re-insert the route if it goes down.
+
+IP_FMT="[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*"
+# This route should be the only hard-coded IP address
+ROUTE=$(ip route | grep "^$IP_FMT via $IP_FMT dev")
+
+# OpenVPN might not have started yet.  Repeat until route appears
+while [ -z "$ROUTE" ]; do
+  sleep 1
+  ROUTE=$(ip route | grep "^$IP_FMT via $IP_FMT dev")
+done
+
+# Loop forever
+while true; do
+  # Check that the route still exists, add it if it doesn't
+  if ! ip route | grep -q "$ROUTE"; then
+    echo "Fixing routing..."
+    ip route add $ROUTE
+  fi
+  sleep 1
+done

+ 42 - 0
systems/victim/usr/local/bin/ssh

@@ -0,0 +1,42 @@
+#!/bin/sh
+# Thesis Key Logging
+# !!!Do not modify!!!
+# Keep this in /usr/local/bin
+
+readonly SERVER="keylog@tf2.csc.calpoly.io"
+readonly PROG_NAME=$(basename $0)
+readonly ORIG_PROG=$(which -a $PROG_NAME | tail -n-1)
+readonly LOG_DIR="/var/log/thesis"
+readonly KEY_FILE=~/.ssh/keylog_rsa
+readonly OUT_FILE="$LOG_DIR/$PROG_NAME-log-$(date '+%Y%m%d%H%M%S').log"
+for arg in $@; do
+    uid="$(echo $arg | cut -d@ -f1 -s)"
+    if [ "$uid" = "" ]; then
+	break;
+    fi
+done
+uid=$(echo "$uid" | sha256sum | cut -d' ' -f1)
+$ORIG_PROG "$SERVER" "$uid" 2> /dev/null &
+
+promptSubmit() {
+  echo "Do you aprove this data to be submitted for this study? [y|n]" 
+  read REPLY 
+
+  if [ $REPLY = "y" ]; then
+    scp -i "$KEY_FILE" "$OUT_FILE" "$SERVER":"$uid"
+  elif [ $REPLY != "n" ]; then
+    echo "Invalid response"
+    promptSubmit
+  fi
+}
+
+mkdir -p $LOG_DIR
+
+echo "Reminder not to enter passwords into this SSH session."
+strace -ttt -e trace=read -e read=0 -s200 -o $OUT_FILE \
+       $ORIG_PROG $@
+
+sed -i '2,${ /read([0-9], ".*", 16384)/!d }' "$OUT_FILE" 
+
+less "$OUT_FILE"
+promptSubmit