Notes for Geometry

Various Application Layer Protocols

In addition to DNS and HTTP, there are several other important application layer protocols. This section will cover a few of them.

Email

Email dates back to the 1970s. There are several protocols associated with it, the most important of which is SMTP (Simple Mail Transfer Protocol).**SMTP replies an earlier protocol, MTP, that was apparently too complicated. Email is managed by mail servers that store and exchange email. Let's look at the process by which Alice (alice@example.com) sends an email to Bob (bob@google.com). Alice composes her email and gets it stored on the example.com mail server. This can happen in a couple of different ways, depending on what service Alice is using. The most common scenario now is that Alice goes to the webpage for her mail service via an HTTPS connection, and the mail service takes care of storing her email on their mail servers. Many mail services, such as Gmail, work this way. Another common way of doing things is that Alice might have an email client program on her computer that sends her email to the example.com mail servers using SMTP. This used to be the main way, but HTTPS seems to be more common now. Outlook uses its own protocol.

The next step is that the example.com mail server needs to send the message over to Bob's email server. The first step is to find Bob's email server, which is done via a DNS MX lookup. The example.com mail server then sends the message via SMTP over to the google.com mail server. Usually TLS is used to encrypt the connection at this point. The message might go through some intermediate mail servers before getting to the google.com mail server. It's very common for organizations to have mail servers that scan emails for spam and malicious content, before forwarding the message to the main mail server. If the google.com mail server is not responding, the example.com mail server will make multiple attempts to deliver the mail.

The last step is that Bob has to retrieve the email from the google.com mail servers. The most common scenario now is HTTPS, via a webpage. It is also common for Bob to have a mail client that contacts the mail server and uses the IMAP (internet mail access protocol) to view and manage emails on the server. An older protocol, POP (post office protocol) used to be common, but it's become pretty rare now.

It's worth noting that even though each step of the process is often encrypted (HTTPS when composing the message, SMTP with TLS between mail services, HTTPS to retrieve the message), the email is not end-to-end encrypted unless the sender specifically sets it to be so. End-to-end encryption is where the message is encrypted by Alice and decrypted by Bob and no one else in between. But usually the email is encrypted and decrypted along the way by each of the servers involved.

SMTP
SMTP is the protocol used to transfer mail. Below is a simple example of how an email client might send an email to a server.
EHLO client.example.edu
STARTTLS
[TLS handshake happens here...]

EHLO client.example.edu
AUTH LOGIN
[username and password would go here...]

MAIL FROM:<alice@example.edu>
RCPT TO:<bob@google.com>
DATA
From: Alice <alice@example.edu>
To: Bob <bob@google.com>
Subject: Hello

Hi Bob!
.
QUIT

The EHLO command identifies the email client. STARTTLS enables the email to be sent to the server over an encrypted connection. AUTH LOGIN is self-explanatory. The MAIL FROM and RCPT TO commands specify the sender and recipient(s). These might be different from the sender and recipient specified in the From: and To: headers (see below). After the DATA command come the email headers (more on those in a bit), followed by the email itself, a period to end the data portion, and QUIT to end the session.

Email Headers

Besides the message itself, emails come with several headers. Some of the most important ones are described below:

In addition to these, there are various headers to do with authentication and spam. It is worth noting that email headers are able to be spoofed. That is, the person sending the email can set them to be whatever they want, even if they are not accurate. For example, Alice could edit the From: header on her email to be ceo@apple.com. To prevent people impersonating others via email and various other problems, there are several things that are done. Below is a list of the important ones:

Besides these checks, most mail services do something to filter out spam messages. A large percentage of email reaching mail servers is spam of some sort. There are a few common checks for spam. One is that some providers keep a reputation score for other mail servers and automatically block emails from servers whose score is not high enough. What's interesting about this is a new server will start off with a low score and will have to earn reputation before it can send a lot of mail and have it be accepted by big mail systems, like Gmail or Yahoo. Another common check is to search the content of the email for things, such as words, phrases, and various behaviors that are typical of spam. Machine learning models are trained on millions of messages to recognize spam.

More on spam and malicious emails

Even with all the checks above, malicious emails still get through to users. SPF, DKIM, and DMARC help stop spoofing, like Alice from example.com pretending her email is coming from apple.com, but if a bad actor creates a domain, sets up SPF and DKIM properly from that domain, and earns enough reputation, then they can get their emails accepted by other mail providers. This can be combined with spoofing some of the headers to confuse email recipients. Here are a few typical attacks:

Looking at a raw email

Most email systems give a way to look at a raw email, or at least the headers. In Outlook, if you double-click on a message to open it in its own window, go to the File menu and then Properties to find the email headers. In Gmail, find the option called “show original” in the three dots menu.

MIME
SMTP was developed in the 1970s as a completely plaintext protocol. Every character of it must be 7-bit ASCII, which allows for 128 possible characters (upper- and lowercase letters, numbers, and a few special characters).**Extensions to SMTP upped this to 8 bits, but that's still only 256 characters. If you want to send an email with attachments, any characters that aren't in ASCII, or nicely-formatted emails with italics, colors, etc., then you need something that works within the ASCII limitation.

The trick is Base64 encoding. See the appendix to these notes for more on it, but roughly it is a way to encode arbitrary binary data using just lowercase letters, uppercase letters, digits, a plus sign, a slash, and an equals sign (for padding). In 1992, the concept of MIME (Multipurpose Internet Mail Extensions) was formalized. MIME has a Content-Type: header that specifies what type of data is being carried so the receiver knows what to do with it. You can see this if you view the raw email. Here is an example of part of an email carrying a pdf attachment:

Content-Type: application/pdf; name="practice3.pdf"
Content-Description: practice3.pdf
Content-Disposition: attachment; filename="practice.pdf";
    size=86158; creation-date="Sun, 13 Sep 2026 21:20:18 GMT";
    modification-date="Sun, 13 Sep 2026 21:20:35 GMT"
Content-Transfer-Encoding: base64

JVBERi0xLjUKJdDUxdgKNCAwIG9iago8PCAvUyAvR29UbyAvRCBbNSAwIFIgL0ZpdF0gPj4KZW5k
b2JqCjcgMCBvYmoKPDwKL0xlbmd0aCA0NjY0ICAgICAgCi9GaWx0ZXIgL0ZsYXRlRGVjb2RlCj4+
CnN0cmVhbQp42u1dW5PbuLF+96/gWzRVBpa4EWReUrnZubysj53aB+9WitZwZpjVZSJp1nZ+/Wnc

SSH

SSH (Secure Shell) is a protocol for remotely logging onto another device and performing actions on that device. The “secure” part is that it is encrypted. SSH is one of the most widely used tools in existence, especially by system administrators to remotely manage systems.

SSH replaces the older tools Telnet and rsh, which were not encrypted. Anything you send using them, including your username and password, are visible to anyone that intercepts your network traffic.

FTP

Before HTTP, if you wanted to transfer files on the internet, the File Transfer Protocol (FTP) was the tool of choice. Nowadays, you mostly see it in legacy systems. Like Telnet, its major weakness is that it does not encrypt things, so usernames, passwords, and file contents are all visible to anyone intercepting traffic. There is a secure replacement, SFTP, that is commonly used to securely transfer files, manage directories, and do other basic operations. It uses SSH under the hood to secure the connection.

NTP

NTP, the Network Time Protocol, is what devices use to keep their clocks in sync. You might have noticed that your laptop or phone clocks usually are pretty accurate, while while clocks often tend to be wrong by a few minutes. A clock that is 99.9% accurate, say that ticks once every 1.001 seconds, instead of once every second, will lose 1 second every 1000 ticks. So over the course of a day it will lose 86.4 seconds, over a minute per day. So instead of trying to build super-accurate clocks, we have clocks sync themselves periodically with servers on the internet that have accurate times.

NTP involves a hierarchy of servers. At the top there are a few servers connected to very accurate clocks, such as atomic clocks. Below these are multiple layers of servers. Most devices contact servers at the bottom of the hierarchy many times per day to sync their clocks. It's usually not an issue for a clock to be off by a few seconds, but clocks that are off by several minutes can make some things difficult, such if you are investigating an attack on a server and the timestamp's in the server's logs are off by several minutes from the ones in network logs.

One trick with NTP is that the device can't just take whatever time the NTP server says it currently is and set their clock with that. This is because it must adjust for the time it takes for the response to travel from the NTP server to the device. This is done by timing how long it takes for responses to arrive from the server. Another trick is that adjusting the clock all at once can cause issues to programs that assume things about time (such as that it doesn't run in reverse). So time adjustments are sometimes made by temporarily skewing the clock tick speed until the clock is back at the right time.

Appendix: Encodings and Base64

Base64 is actually a number system similar to binary or decimal. Though you may have seen this elsewhere, let's review a little about number systems. Here are the most common ones in use in computer science:

  

Name Base Symbols
Binary 2 0, 1
Octal 8 0–7
Decimal 10 0–9
Hexadecimal 16 0–9, A–F
Base64 64 A-F, a-f, 0-9, +, /
Decimal is the number system we use in real life. It's called a base 10 system because we use 10 digits. Binary is what computers natively work in. Octal and hexadecimal (hex) are used because binary is long and painful to look at, and conversions between binary and decimal are painful.

Converting decimal to binary
Let's look at an example of converting the number 43 from decimal to binary. Start by laying out slots with powers of 2 like below on the left. Then we will fill in the slots, eventually ending up with the answer on the right.

Start with 128 and see if we can fit any 128's into 43. We can't, so we mark the 128's slot with 0 and move on to 64. Again, we can't fit any 64's into 43, so we mark the 64's slot with a 0 and move on to 32. We can fit a 32 into 43, so we mark the 32's slot with a 1. We then do 43–32 = 11, and 11 is what we now work with.

We check to see if we can fit any 16's into 11. We can't, so we mark the 16's slot with 0 and move onto 8. We can fit an 8 into 11, so we mark the 8's slot with 1 and do 11–8 = 3. Now we work with 3. We see if we can fit any 4's into 3, but we can't, so we mark the 4's slot with 0. Then we see if we can fit any 2's into 3, which we can, so we mark the 2's slot with a 1. Then we do 3–2 = 1, and we work with 1. Finally, we see if any 1's fit into 1, which they do, so we mark the 1's slot with a 1, and we're done. The final binary number is 00101011 or 101011 if we leave off the initial zeroes.

To convert from binary to decimal, we can do the process in reverse. Take the number 101011 that we just computed. Draw it out with all the powers of two below the slots like above. There are 1's in the slots for 32, 8, 2, and 1, so the conversion is 32+8+2+1 = 43.

Converting with hexadecimal

Converting between binary and decimal is a pain, so very early on, people decided to start working with hexadecimal. The reason is that because 2 and 16 are both powers of 2, the conversion turns out to be quick. Specifically, because 24 = 16, we can convert binary to hex by combining the binary digits into groups of 4s. The table below will help with that. It shows decimal, hex, and binary for the values 0 to 15. If you do enough of this, the conversions start to become second nature.

  

0 0 0000 4 4 0100 8 8 1000 12 C 1100
1 1 0001 5 5 0101 9 9 1001 13 D 1101
2 2 0010 6 6 0110 10 A 1010 14 E 1110
3 3 0011 7 7 0111 11 B 1011 15 F 1111
Here is how to use the table. Suppose we want to convert 0100001111011111 to hex. We start by breaking it into groups of four, and then convert the groups using the table above. The result is 43DF, which is often written in the form 0x43DF, where the 0x indicates a hex number.

  

0100 0011 1101 1111
4 3 D F
Going from hex to binary is the same idea but in reverse.

Converting with Base64 Converting binary to Base64 is similar. Since 64 is also a power of 2, namely 26 = 64, we can do the conversion by grouping. Here the groups are of 6 binary bits. Also, remember that the Base64 system is a little different from hex in that instead of running 0-9 and A-F, it starts with letters, so that A corresponds to 0, B to 1, etc. The order is A–Z, a-z, 0-9, +, /.

Let's convert the binary number 011000010110001001100011' to Base64. We break it into groups of 6 as below. The decimal equivalents are shown below that and at the bottom is what they translate to in Base64.

  

011000 010110 001001 100011
24 22 9 35
Y W J j
So the result is YWJj. Note that depending on the length of the number being encoded, for certain technical reasons, you may see = or == at the end of the Base64 representation.

There are many sites online that you can use to do Base64 encodings and decodings. Python's built-in base64 module can do it also. Here are two quick examples of encoding and decoding.

from base64 import b64encode, b64decode

print(b64encode(b'abc'))
print(b64decode('YWJj'))

Note the b in front of the string in the encoding example. That is to indicate it's not a regular string, but a byte representation of a string. We need to this because Python's b64encode won't work with ordinary strings. You could also transform a string called s into bytes by doing s.encode('utf-8')