Use lstinline to display inline code instead of texttt

This commit is contained in:
Kristóf Tóth 2018-12-02 16:44:31 +01:00
parent fab9861d0d
commit ce8cad2ac4
6 changed files with 76 additions and 79 deletions

View File

@ -16,7 +16,7 @@ content using TFW.
The purpose of this chapter is to further detail the built-in components
provided by the framework.
As previously mentioned, these components are implemented as event handlers
running in the \texttt{solvable} Docker container and frontend
running in the \code{solvable} Docker container and frontend
components written in Angular.
For instance the built-in code editor requires a frontend component and an event
handler to function properly, while the frontend component responsible for
@ -36,14 +36,14 @@ For example, to inject a command into the terminal one would use a message like
}
}
\end{lstlisting}
Notice the \texttt{\textbackslash{}n} at the end of the command.
Notice the \code{\n} at the end of the command.
By including a newline character, we are also capable of executing commands in the
user's terminal.
Were this newline omitted, the command would only be written to the terminal
(but not automatically executed) for users to inspect and potentially execute themselves.
Some components emit or broadcast messages on specific events, for instance the
\texttt{FSMManagingEventHandler} broadcasts the following message on state transitions:
\code{FSMManagingEventHandler} broadcasts the following message on state transitions:
\begin{lstlisting}[captionpos=b,caption={An FSM Update message}]
{
"key": "fsm_update",
@ -97,7 +97,7 @@ The timing of pauses and messages is based on the \emph{WPM} --- or Words Per Mi
set by developers according to their specific use cases.
This creates an experience similar to chatting with someone in real time, as the time
it takes for each message to be displayed is depending on the lenght of the previous message.
This illusion is made possible through appropriate \texttt{setTimeout()} calls in
This illusion is made possible through appropriate \code{setTimeout()} calls in
TypeScript and some elementary math to calculate the proper delays in milliseconds based on
message lengths:
@ -110,7 +110,7 @@ message lengths:
This is the code editor integrated into the frontend of the framework.
It allows users to select, display and edit files.
Developers can configure which directory on the file system of the \texttt{solvable}
Developers can configure which directory on the file system of the \code{solvable}
container should the editor list files from.
The editor features the ``Deploy'' button referred to earlier in this paper, which is
capable of restarting processes that might execute a file visible in the editor.
@ -136,11 +136,11 @@ to display, that file is automatially displayed on a new tab in the IDE.
This allows for really interesting demo opportunities.
Lets say I create a file using the terminal on the frontend by executing the
command \texttt{touch file.txt}. A new tab on the editor automatically
command \code{touch file.txt}. A new tab on the editor automatically
appears. If I select it I can confirm that I have successfully created an
empty file.
After this let's run a \texttt{while} cycle in the command line which
peroadically appends some text to \texttt{file.txt}:
After this let's run a \code{while} cycle in the command line which
peroadically appends some text to \code{file.txt}:
\begin{lstlisting}[captionpos=b,caption={Bash While Cycle Writing to a File Periodically},
language=bash]
while true
@ -183,9 +183,9 @@ terminal emulator to do so.
This component has a tiny server process which is managed by a TFW event handler.
This small server is responsible for spawning bash sessions and
unix pseudoterminals (or \texttt{pty}s) in the \texttt{solvable} Docker
unix pseudoterminals (or \code{pty}s) in the \code{solvable} Docker
container.
It is also responsible for connecting the master end of the \texttt{pty} to the
It is also responsible for connecting the master end of the \code{pty} to the
emulator running in your browser and the slave end to the bash session it has
spawned.
This way users are able to work in the shell displayed on the frontend just like
@ -212,21 +212,21 @@ monitoring solution such as Sysdig%
\footnote{\href{https://sysdig.comq}{https://sysdig.com}}.
I deemed most simiar systems a huge overkill to implement this functionality, and their
memory footprints are not something we could afford here.
Another way would be to use \texttt{pam\_tty\_audit.so} in the PAM%
Another way would be to use \code{pam_tty_audit.so} in the PAM%
\footnote{Linux Pluggable Authentication Modules:
\href{http://man7.org/linux/man-pages/man3/pam.3.html}
{http://man7.org/linux/man-pages/man3/pam.3.html}}
configurations responsible for logins, as this allows for various TTY auditing functions,
but I have found an ever simpler approach to the problem in the end.
By using the inotify system built into TFW, I can set up the user's environment in
such a way, that I can enforce and determine the location of the bash \texttt{HISTFILE}%
such a way, that I can enforce and determine the location of the bash \code{HISTFILE}%
\footnote{This environment variable contains the path to the file bash writes command
history to}
of the user.
This way I can monitor changes made to this file and read the commands executed
by the user from it.
It is important to keep in mind that the user is able to ``sabotage'' this method%
\footnote{By unsetting the \texttt{HISTFILE} envvar for example},
\footnote{By unsetting the \code{HISTFILE} envvar for example},
but that should not be an issue as this is not a feature that is intended to be
used in competitive environments (and if the users of a tutorial intentionally
break the system under themselves, well, good for them).
@ -248,7 +248,7 @@ experience similar to working in an IDE on your laptop.
\section{Process Management}\label{processmanagement}
The framework includes an event handler capable of managing processes running inside
the \texttt{solvable} Docker container.
the \code{solvable} Docker container.
It's capabilities include starting, stopping and restarting processes.
It is also capable of emitting the standard out or standard error logs of processes
(by broadcasting TFW messages).
@ -273,17 +273,17 @@ a complex system could come with.
I'll briefly explain such a bug, which I've found to be immersely exciting.
During the initial development of this feature all processes inside the
\texttt{solvable} Docker container were writing their logs to files
\code{solvable} Docker container were writing their logs to files
in the FHS%
\footnote{The File Hierarchy Standard is a standard maintained by the Linux foundation,
defining a common directory structure for compliant systems. See
\href{https://wiki.linuxfoundation.org/lsb/fhs}{https://wiki.linuxfoundation.org/lsb/fhs}}
location \texttt{/tmp/}.
location \code{/tmp/}.
All logs coming from the container itself were also logged to this location.
This had caused an infinite recursion: when a process would write to \texttt{/tmp/}
This had caused an infinite recursion: when a process would write to \code{/tmp/}
inotify would invoke a process that would also log to that location causing the kernel to
emit more inotify events, which in turn would cause more and more new proesses to spawn
and write to \texttt{/tmp/}, causing the whole procedure to repeat again and again.
and write to \code{/tmp/}, causing the whole procedure to repeat again and again.
This continued until my machine would start to run out of memory and stat swapping
pages to disk%
\footnote{When a modern operating system runs out of physical RAM, it is going to swap
@ -296,7 +296,7 @@ fascinating phenomenon, but those were \emph{very} fun hours.
\section{FSM Management}
I have already mentioned the event handler called \texttt{FSMManagingEventHandler},
I have already mentioned the event handler called \code{FSMManagingEventHandler},
which is responsible for managing the framework FSM.
For completeness I chose to include it on this chapter as well.
The API it exposes through TFW messages allows client code to attempt stepping the

View File

@ -4,14 +4,14 @@
It is important to understand that the Tutorial Framework is currently implemented as
two Docker images:
\begin{itemize}
\item the \texttt{solvable} image is responsible for running the framework and the client
\item the \code{solvable} image is responsible for running the framework and the client
code depending on it
\item the \texttt{controller} image is responsible for solution checking (to figure out
\item the \code{controller} image is responsible for solution checking (to figure out
whether the user completed the tutorial or not)
\end{itemize}
During most of this capter I am going to be discussing the \texttt{solvable} Docker image,
with the exception of section~\ref{solutioncheck}, where I will dive into how the
\texttt{controller} image is implemented.
During most of this capter I am going to be discussing the \code{solvable} Docker image,
with the exception of Section~\ref{solutioncheck}, where I will dive into how the
\code{controller} image is implemented.
The most important feature of the framework is it's messaging system.
Basically what we need is a system where processes running inside a Docker container
@ -51,7 +51,7 @@ of your website (and as such requiring to go over the whole TCP handshake and th
HTTP request-response on each update).
This has been superseded by WebSockets around 2011, which provide a full-duplex
communication channel over TCP between your browser and the server.
This is done by initiation a protocol handshake using the \texttt{Connection: Upgrade}
This is done by initiation a protocol handshake using the \code{Connection: Upgrade}
HTTP header, which establishes a premanent socket connection between the browser
and the server.
This allows for communication with lower overhead and latency facilitating efficient
@ -85,7 +85,7 @@ A few examples of top contenders and reasons for not using them in the end:
\item The handling of raw TCP sockets would involve lot's of boilerplate logic that
already have quality implementations in messaging libraries: i.e.\ making sure that
all bytes are sent or received both require checking the return values of the
libc \texttt{send()} and \texttt{recv()} system calls, while ZMQ takes care of this
libc \code{send()} and \code{recv()} system calls, while ZMQ takes care of this
extra logic involved and even provides higher level messaging patterns such as
subscribe-publish, which would need to be implemented on top of raw sockets again.
\item Using something like gRPC\footnote{\href{https://grpc.io}{https://grpc.io}}
@ -113,10 +113,10 @@ Architecturally TFW consists of four main components:
\item \textbf{TFW (proxy) server}: responsible for message routing/proxying
between the frontend and event handlers
\item \textbf{TFW FSM}: a finite state machine responsible for tracking user progress,
that is implemented as an event handler called \texttt{FSMManagingEventHandler}
that is implemented as an event handler called \code{FSMManagingEventHandler}
\end{itemize}
Note that it is important to keep in mind that as I've mentioned previously,
the TFW Server and event handlers reside in the \texttt{solvable} Docker container.
the TFW Server and event handlers reside in the \code{solvable} Docker container.
They all run in separate processes and only communicate using ZeroMQ sockets.
In the following sections I am going to explain each of the main components in
@ -147,17 +147,17 @@ Let's inspect further what a valid TFW message might look like:
}
\end{lstlisting}
All valid messages \emph{must} include a \texttt{key} field as this is used by the
All valid messages \emph{must} include a \code{key} field as this is used by the
framework for addressing: event handlers and frontend components subscribe to one
or more \texttt{key}s and only receive messages with \texttt{key}s they have
or more \code{key}s and only receive messages with \code{key}s they have
subscribed to.
It is possible to send a message with an empty key, however these messages will not
be forwarded by the TFW server (but will reach it, so in case the target of a message
is the TFW server exclusively, an empty \texttt{key} can may used).
is the TFW server exclusively, an empty \code{key} can may used).
The rest of the fields are optional, but most messages will carry something
in their \texttt{data} field.
The purpose \texttt{trigger} and \texttt{signature} fields will be detailed
in their \code{data} field.
The purpose \code{trigger} and \code{signature} fields will be detailed
at a later point in this paper.
\subsection{Networking Details}
@ -171,8 +171,8 @@ the frontend via WebSockets.
The TFW server is also capable of ``reflecting'' messages back to the side they were
received on (to faciliate event handler to event handler for instance), or broadcast
messages to all components.
This is possible by embedding a whole TFW message in the \texttt{data} field of
an outer wrapper message with a special \texttt{key} that signals to the TFW server that
This is possible by embedding a whole TFW message in the \code{data} field of
an outer wrapper message with a special \code{key} that signals to the TFW server that
this message requires special attention.
An example of this would be:
\begin{lstlisting}[captionpos=b,caption={Broadcasting and mirroring TFW messages}]
@ -187,12 +187,12 @@ An example of this would be:
}
}
\end{lstlisting}
Any invalid messages (not valid JSON or no \texttt{key} field present) are ignored
Any invalid messages (not valid JSON or no \code{key} field present) are ignored
by the TFW server.
\subsection{Event Handlers}
Event handlers are processes running in the \texttt{solvable} Docker container
Event handlers are processes running in the \code{solvable} Docker container
that subscribe to specific message types using ZeroMQ sockets.
As discussed earlier, using ZeroMQ allows developers to implement event handlers
in a wide variety of programming languages.
@ -253,7 +253,7 @@ This code editor is essentially a Monaco editor%
{https://microsoft.github.io/monaco-editor/}}
instance integrated into Angular and upgraded with the capability to
exchanges messages with an event handler to save, read and edit files
that reside in the writeable file system of the \texttt{solvable}
that reside in the writeable file system of the \code{solvable}
Docker container.
All of the built-ins come with full API documentation explaining what they do
@ -337,7 +337,7 @@ state transitions, or onentering and exiting a state.
It is \emph{very} important to be aware of these callbacks, as much of the
actual tutorial logic is often going to be implemented in these.
Architecturally a built-in event handler called \texttt{FSMManagingEventHandler}
Architecturally a built-in event handler called \code{FSMManagingEventHandler}
is capable of managing the FSM defined by clients.
The responsibilities of said event handler include:
\begin{itemize}
@ -347,16 +347,16 @@ The responsibilities of said event handler include:
such as successful transitions
\end{itemize}
The \texttt{trigger} field of a message can be used to step the framework FSM
The \code{trigger} field of a message can be used to step the framework FSM
if all preconditions are met.
The way this works is if the TFW server encounters a message with a
\texttt{trigger} defined, it notifies the event handler managing
\code{trigger} defined, it notifies the event handler managing
the state machine.
Since messages can come from unauthenticated sources, it is possible to
enforce the authentication of privileged messages, such as messages containing a \texttt{trigger}.
enforce the authentication of privileged messages, such as messages containing a \code{trigger}.
The framework allows trusted code to access a cryptographic key on the file system, which
can be used to digitally sign messages (this is what the \texttt{signature} message
can be used to digitally sign messages (this is what the \code{signature} message
field is designed for).
In this case the TFW server will only forward privileged messages that
have a valid signature.
@ -364,9 +364,9 @@ have a valid signature.
\subsection{Solution checking}\label{solutioncheck}
Traditionally most challenges on the Avatao platform implement a Docker image called
\texttt{controller}, which is responsible for detecting the successful
\code{controller}, which is responsible for detecting the successful
solution of a challenge.
When using the Tutorial Framework a pre-implemented \texttt{controller}
When using the Tutorial Framework a pre-implemented \code{controller}
image is available, which listens to messages emitted by the
framework FSM, and detects if the final state defined by developers is reached.
This means that if content creators implement a proper FSM, the solution checking

View File

@ -105,7 +105,7 @@ After I got this working I was looking into writing hacky bash scripts to automa
required to complete the challenge in order to make it easier for me to record the solution,
as I have often found myself recording over and over again for a demo without any mistakes.
During the time I was playing around with this idea, researching possible solutions have led me
to a hidden gem of a project on GitHub called \texttt{demo-magic}%
to a hidden gem of a project on GitHub called \code{demo-magic}%
\footnote{\href{https://github.com/paxtonhare/demo-magic}{https://github.com/paxtonhare/demo-magic}},
which is esentially a bash script that simulates someone typing into a terminal and executing
commands.
@ -118,7 +118,7 @@ Soon after recording demo videos was not even necessary anymore, as I have start
the solution script with the challenge code itself, making it toggleable using build-time
variables.
Should the solution script be enabled, the challenge would automatically start%
\footnote{I did this by injecting the solution script into the user's \texttt{.bashrc} file}
\footnote{I did this by injecting the solution script into the user's \code{.bashrc} file}
completing itself in the terminal integrated into it's frontend, often even explaining the
commands executed during the solution process.

View File

@ -2,7 +2,7 @@
In this section I am going to dive into further detail on how client code is supposed
to use the framework, some of the design decisions behind this and how everything is
is integrated into the \texttt{solvable} Docker image.
is integrated into the \code{solvable} Docker image.
To use the framework one has to do several things to get started.
The main points include:
@ -25,7 +25,7 @@ framework.
This repository is a really simple client codebase that is suitable for
developing TFW itself as well (a good place to host tests for the framework).
It also provides an ``industry standard'' \texttt{hack} directory
It also provides an ``industry standard'' \code{hack} directory
containing bash scripts that make the development of tutorials and TFW itself very convenient.
These scripts span from bootstrapping a complete development environment in one command,
to building and running challenges based on the framework.
@ -54,7 +54,7 @@ understanding of how the framework interacts with client code.
\end{lstlisting}
\subsection{Avatao Configuration File}
The \texttt{config.yml} file is an Avatao challenge configuration file,
The \code{config.yml} file is an Avatao challenge configuration file,
which is used describe what kind of Docker containers implement a challenge,
what ports do they expose talking what protocols, define the name of the
excercise, it's difficulity, and so on.
@ -63,12 +63,12 @@ The Tutorial Framework does not use this file, this is only required to run
the exercise in production, so it is mostly out of scope for this thesis.
\subsection{Controller Image}
It was previously mentioned that the \texttt{controller} Docker image is responsible
It was previously mentioned that the \code{controller} Docker image is responsible
for the solution checking of challenges (whether the user has completed the exercise or not).
Currently this image is maintained in the test-tutorial-framework repository.
It is a really simple Python server which functions as a TFW event handler as well.
It subscribes to the FSM update messages
broadcasted by the \texttt{FSMManagingEventHandler}, we've previously discussed,
broadcasted by the \code{FSMManagingEventHandler}, we've previously discussed,
this way it is capable of keeping track of the state of the tutorial,
which allows it to detect if the final state of the FSM is reached.
@ -80,7 +80,7 @@ Currently the Tutorial Framework is maintained in three git repositories:
\item[test-tutorial-framework] An example tutorial built using baseimage and frontend
\end{description}
Every tutorial based on the framework must use the TFW baseimage as the parent of
it's own \texttt{solvable} image, using the \texttt{FROM}%
it's own \code{solvable} image, using the \code{FROM}%
\footnote{\href{https://docs.docker.com/engine/reference/builder/\#from}
{https://docs.docker.com/engine/reference/builder/\#from}}
Dockerfile command.
@ -88,7 +88,7 @@ Being an example project of the framework this is the case with
test-tutorial-framework as well.
\section{Details of the Solvable Image}
Let us dive into greater detail on how the \texttt{solvable} Docker image of the
Let us dive into greater detail on how the \code{solvable} Docker image of the
test-tutorial-framework operates.
The directory structure is as follows:
\begin{lstlisting}
@ -102,9 +102,9 @@ solvable/
I am going to discuss these one by one.
\subsection{Dockerfile}
Since this is a Docker image it must define a \texttt{Dockerfile}.
Since this is a Docker image it must define a \code{Dockerfile}.
This image always uses the baseimage of the framework as a parent image.
Besides this developers can use this as a regular \texttt{Dockerfile} to work with as
Besides this developers can use this as a regular \code{Dockerfile} to work with as
they see fit to implement their tutorial.
\subsection{Frontend}
@ -124,7 +124,7 @@ very hard and impractial to do in practice.
Supervisor is a process control system designed to be able to work with
processes on UNIX-like operating systems.
When a tutorial built on TFW is started, the framework starts supervisor with
PID\footnote{Process ID, on UNIX-like systems the \texttt{init} program is the first
PID\footnote{Process ID, on UNIX-like systems the \code{init} program is the first
process started} 1, which in turn starts all the programs defined
in this directory using supervisor configuration files.
For example, a developer would use a file similar to this to run a webserver
@ -141,7 +141,7 @@ can be managed by the framewok using API messages.
\subsection{Nginx}
For simplicity, exercises based on the framework only expose a single port from the
\texttt{solvable} container.
\code{solvable} container.
This port is required to serve the frontend of the framework.
If this is the case, how do we run additional web applications to showcase vulnerabilies
on during the tutorial?
@ -167,7 +167,7 @@ What this means is that they are going to be serverd from a ``subdirectory'' of
for example ``/register'' will be served under ``/yoururl/register''.
This means that all links in the final HTML must refer to the proxied urls, e.g.\
``/yoururl/register'' and server side redirects must point to the correct hrefs as well.
Idiomatically this is usually implemented by supplying a \texttt{BASEURL}
Idiomatically this is usually implemented by supplying a \code{BASEURL}
to the application through an environment variable, so that it is able to set
itself up correctly.
@ -175,7 +175,7 @@ itself up correctly.
Behind the curtains, the Tutorial Framework uses some Dockerfile trickery to
faciliate the copying of supervisor and nginx configuration files to their correct
locations.
Normally when one uses the \texttt{COPY}%
Normally when one uses the \code{COPY}%
\footnote{\href{https://docs.docker.com/engine/reference/builder/\#copy}
{https://docs.docker.com/engine/reference/builder/\#copy}}
command to create a layer%
@ -188,23 +188,23 @@ these configuration files that will be written by content developers do not even
exist.
How could we copy files into an image layer that will be created in the future?
It is possible to use a command called \texttt{ONBUILD}%
It is possible to use a command called \code{ONBUILD}%
\footnote{\href{https://docs.docker.com/engine/reference/builder/\#onbuild}
{https://docs.docker.com/engine/reference/builder/\#onbuild}}
in the Dockerfile of a baseimage to delay another command
to the point in time when other images will use the baseimage
as a parent with the \texttt{FROM} command. This makes it possible to execute
as a parent with the \code{FROM} command. This makes it possible to execute
commands in the build context of the descendant image.
This is great, because the config files we need \emph{will} exist in the build
context of the \texttt{solvable} image of test-tutorial-framework.
In practice this looks something like this in the baseimage \texttt{Dockerfile}:
context of the \code{solvable} image of test-tutorial-framework.
In practice this looks something like this in the baseimage \code{Dockerfile}:
\begin{lstlisting}
ONBUILD COPY ${BUILD_CONTEXT}/nginx/ ${TFW_NGINX_COMPONENTS}
ONBUILD COPY ${BUILD_CONTEXT}/supervisor/ ${TFW_SUPERVISORD_COMPONENTS}
\end{lstlisting}
\subsection{Source Directory}
The \texttt{src} directory usually holds tutorial-specific code, such as
The \code{src} directory usually holds tutorial-specific code, such as
the implementations of event handlers, the framework FSM, additional web applications
served by the exercise and generally anything that won't fit in the other,
framework-specific directories.
@ -227,11 +227,11 @@ It is possible to use this format to define a state machine like so:
caption={A Finite State Machine implemented in YAML},
captionpos=b
]{listings/test_fsm.yml}
This state machine has 2 states, state 0 and 1.
It defines a single transition between them.
On entering state 1 the FSM will write a message to the frontend messaging component
by invoking TFW library code in Python.
The transition can only occour if the file \texttt{allow\_step\_1} exists.
This state machine has two states, state \code{0} and \code{1}.
It defines a single transition between them, \code{step_1}.
On entering state \code{1} the FSM will write a message to the frontend messaging component
by invoking TFW library code using Python.
The transition can only occour if the file \code{allow_step_1} exists.
YAML based state machine implementations also allow the usage of the Jinja2%
\footnote{\href{http://jinja.pocoo.org/docs/2.10/}{http://jinja.pocoo.org/docs/2.10/}}
@ -258,11 +258,11 @@ Python as well, it is going to be easier to interface with library code.
\section{Configuring Components}
The configuration of built-ins is generally done in two different ways.
For the frontend (Angular) side, developers can edit a \texttt{config.ts} file,
For the frontend (Angular) side, developers can edit a \code{config.ts} file,
which is full of key-value pairs of configurable frontend functionality.
These pairs are generally pretty self-documenting:
\lstinputlisting[
caption={Example of the frontend \texttt{config.ts} file (stripped down to save space)},
caption={Example of the frontend \code{config.ts} file (stripped down to save space)},
captionpos=b
]{listings/config.ts}
Configuring built-in event handlers is possible by editing the Python file they are
@ -283,7 +283,7 @@ This script is distributed as a bash one-liner command, like so:
\begin{lstlisting}[language=bash]
bash -c "$(curl -fsSL https://git.io/vxBfj)"
\end{lstlisting}
This command downloads a script using \texttt{curl}, then executes the downloaded
This command downloads a script using \code{curl}, then executes the downloaded
script in bash.
In the open source community it is quite common to distribute installers this way%
\footnote{A good example of this is oh-my-zsh
@ -318,9 +318,9 @@ The bootstrap script clones the three TFW repositories and does several steps
to create a working environment:
\begin{itemize}
\item It builds the newest version of the TFW baseimage locally
\item It pins the version tag in \texttt{solvable/Dockerfile},
\item It pins the version tag in \code{solvable/Dockerfile},
so that this newly-built version will be used by the tutorial
\item It places the latest frontend in \texttt{solvable/frontend} with
\item It places the latest frontend in \code{solvable/frontend} with
depencendies installed
\end{itemize}
It is important to note that this script \emph{does not} install anything system-wide,

View File

@ -15,10 +15,6 @@
}
\RequirePackage[bottom,hang,flushmargin]{footmisc}
\definecolor{andigray}{RGB}{237,237,237}
\sethlcolor{andigray}
\newcommand{\code}[1]{\hl{\mbox{#1}}}
\newtheorem*{note}{Note}
\newcommand{\pic}[3][width=\textwidth]

View File

@ -20,6 +20,7 @@
aboveskip=15pt,
belowskip=15pt,
}
\newcommand{\code}{\lstinline}
\setmainfont{Constantia}
\setmonofont{DejaVu Sans Mono}