flowchart LR
A(Python) --> B[fname.py file]
B --> C[python fname.py]
C --> D{hello world}
E(C) --> F[fname.c file]
F --> G[gcc fname.c -o ename]
G --> H[./ename]
H --> I{hello world}
C89/99
Week 0x0.3
Announcements
- Welcome to Computing Security
- Action Items:
- Enigma assignment
Homework
- The first homework, “Enigma”, is ready after this class.
- Due Monday, 14 Jul at midnight AOE
- The infamous CS1 hw, now in a good language!
- Mostly just get the toolchain working.
Today
- Reintroduce the technologies
podmanvimgccgit
What is Podman?
- Definition:
- Platform to develop, ship, and run applications in isolated containers.
- Benefits:
- Portability, consistency across environments.
- Editorializing:
- Probably all code should be written in a container now that they exist.
In practice:
- Windows only
- Run
wsl --install -d ubuntucommand once - Run
wslto… enter wsl. - Run
sudo apt updateonce - Run
sudo apt upgradeonce - Run
sudo apt install podman - Use
podmancommands within WSL
- Run
In practice:
- Mac only
- Use podman desktop installer
- Before using containers, run
podman machine start- If it didn’t work, may need to
podman machine init
- This may create a large file on your device
podman-machine-default-arm64.raw
In practice:
- Podman works well without hacks on Linux
- In fairness, the goal is have access to Linux anyways.
- “Linux” search term shows ~100 jobs in Portland area
- vs. 300:Python, 200:SQL, 100:Tableau, 200:R but the first is HVAC?
- “HVAC/R Service Technician”
Podman
- Podman solves the problem of writing code on one computer and running it another.
- Simply specify a Podman image
- a description of a imaginary computer
- Podman will pretend to be that computer
- We can run code “inside” Podman
- Code in the container can’t tell it’s running inside Podman
Inside:
Images
- Something we
podman run -itis an image- It is a template that corresponds to many possible pretend computers
- I think of them like object oriented class
- They define something that could be
Containers
- Each time we run said command, we have a different container
- They have different file systems
- Things we install don’t persist to future
runinstances. - I think of them like objects of a class
- Like ‘1’ instead of ‘integer’
- They are actually existing, running code.
Reuse
- On Enigma, probably:
- You opened a container.
- You wrote some code in vim.
- You compiled the code.
- You ran the executable.
- The executable deorbited a space station. /s
- You closed the container and went to touch grass.
Attach
- After touching grass, you
- Came back to your PC
- Had no graceful way to continue working on the code you wrote.
- We solve this with attachment and detachment.
Servers
- One of the most common ways to use containers is web dev.
- They are easier to think of as:
- A program, which
- Hosts a webpage, which
- Happens to need to run somewhere
- That somewhere is a command line
- Inside a pretend computer (container).
Sample
- Docker maintains a sample container.
- Podman is busy being free and open source.
- Try this:
- You can probably find it at this link:
Breakdown
| Command | Explanation |
|---|---|
podman |
do something with containers |
run |
run a new container |
-d |
detach - we’ll cover this next |
-p |
This is port forward… |
8080:80 |
80 is where websites usually live |
| 8080 is where we went (:8080) | |
docker/... |
Name of an image |
Ports
- Ports aren’t the point, but
- We should demystify.
- Change
8080:80to8083:80
- Change the link as well.
Two pages
- Wait a minute…
- There’s a webpage at 8080
- There’s a webpage at 8083
- They’re both from the same image.
- They were started in the same command line (maybe)
- That is two containers running concurrently.
- Enter
-d
- Enter
Detach
- When we run an image with the
-dflag, it:- Created and ran as any other container, but
- Runs “in the background”
- Control does not change to container
- It runs only its start command
- It’s just like a remote web server.
Detach Dev
- A perhaps nicer way to write code is
- Create and detach a container
- Leave it running or whatever
- Use other
podmancommands to:- Pop into the container and e.g.
vim - Transfer files in or out
- Pause and restart to save resources.
- Pop into the container and e.g.
ps
- When fiddling about with containers…
- It’s good to know who they are (names)
- And what they do (command)
- We can use
podman ps
- We see two servers (nginx) running
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7d6af09131b5 docker.io/docker/welcome-to-docker:latest nginx -g daemon o... 2 minutes ago Up 2 minutes 0.0.0.0:8080->80/tcp, 80/tcp confident_darwin
2e1b9f844dcd docker.io/docker/welcome-to-docker:latest nginx -g daemon o... 2 minutes ago Up 2 minutes 0.0.0.0:8083->80/tcp, 80/tcp adoring_shamirps -a
- You may also have many containers
podman ps -ato see old containers.
- I had many such containers!
- 4 GB worth, to be exact
- Clean them all up with prune
- System = containers, images, everything
exec -it
- If there’s a detached container running
- We can execute commands in that container.
- You only have to specify enough of the name or id to be unique.
- A server at 8080 beginning with id 7…
- This returns hello, directly, without switching into the container.
/bin/sh
- So far, I haven’t found a container without
/bin/sh - The Linux command line, more or less
bash>sh, but sometimes onlyshavailable
- Get an interactive command prompt via
- This is roughly the same as
run -it- But on an existing container, not a base image
NOTE
- In this example, a webserver is kept running.
- By default, containers can stop running.
- If a container isn’t under
podman ps:- Find it with
podman ps -a - Start it with
podman startby name
- Find it with
- Restarts the last container with
vim:
vim
- I’ve adopted a strong preference for just using
vim- When I exit
vim, I implicitly exit the container. - Feels better than typing
exit, to me
- When I exit
- So if we create an image with vim, we can
- And go from there.
Today
- Reintroduce the technologies
- ✓
podman vimgccgit
- ✓
IDEs
- At some point in time, code started being written in IDEs.
- Integrated design environments.
- To me, the first one was Eclipse (for Java)
- That time was shortly before the 2008 financial crises
- Don’t put in the course evals I blame Eclipse for the Great Recession
Why Vim fr tho?
- It is a command at command line
- It can be installed in containers
Containerfile
- Here’s the “Containerfile” I’m using today:
Ubuntu
- I use Ubuntu
- It’s a bit annoying Alpine requires separately grabbing libc to print
apt
- Ubuntu uses
aptto manage packages, likegccandvim - Images are notorious for having out-of-date package listings
- This tells Ubuntu to look for the latest & greatest
&&
- We use && to update and install at once
- We use
apt installto… installgccfromapt
- This avoids a container updating, going to sleep, and packages falling out of date.
- Apparently that actually happens on cloud, somehow
-y
- We list whatever other packages we need and also…
-yas by defaultaptasks us if we’re sure
- Without
-y,aptwill wait for us to type- We often use podman in scripts or commands where it gets stuck, so use
-y
- We often use podman in scripts or commands where it gets stuck, so use
Usage
- I usually enter a container via
- Or often with a filename
- From there I do a few things…
First window
- It looks like this:
Insert mode
- Press
ito enter “insert mode”
Write some code
- Type every letter perfectly on the first try.
:term
- Open the
vimterminal emulator- Press ESC
- Type
:term - Press ENTER
- We’ll go step by step
Press ESC
- Looks like this (mostly INSERT is gone)
Type “:term”
- The colon
:is meaningful invim
Press ENTER
- All kinds of colors could happen here too:
Use terminal
- Let’s compile with
gcc
Write file
- We didn’t save samp.c, we will:
- Use CTRL+
wto change “window” - We will use any
vimmovement key, likejjmoves down one “thing”- usually line, now a window
- We will use ESC +
:wto write the file - Then return to terminal CTRL+
w+k
- Use CTRL+
That was a lot
- Should look like this
Breathe
- You are now all-powerful
- You are not beholden to any operating system
- Can work on cloud or anywhere with
podman - If MS charges 10000 USD for VS Code tomorrow?
- You are non-impacted
- Everytime you do this you get faster
Verify Compilation
- Use
lsto list files, look for a.out
Run Executable
- Use
./prefix to usea.outas an executable
Segfault
- In “samp.c” to fix off-by-one error, test
Today
- ✓ Introduce the course
- ✓ The C Programming Language
- ✓ Cryptography + Cryptocurrency
- Introduce the technologies
- ✓
podman - ✓
vim gccgit
- ✓
GCC
- Developed for the C language to make an open source operating system in 1987.
- Mainly around today for the C language to make an open source operating system (Linux)
- (The C language was invented to write an operating system).
pythonis written in GCC C
Great freeware
- Many legendary programs created using GCC:
- HTTPD & NGINX, which serve a majority of webtraffic
- Every major Linux and FreeBSD distribution
- Major browsers like Firefox and Chromium
- Firefox is on
clangnow but that’s new
- Firefox is on
- GNU Bash and Coreutils, like
cat,ls,rm - Bitcoin Core
Compilation
- Like
pythonorpodmanorvim, GCC is a command -gcc gcctakes at least one argument: a filename, usually of a C file- GCC takes this C file and makes an executable
- a program, sort of
- Executables run as command with
./prefix- This differs from
pythonwhich runs a script without creating a corresponding program.
- This differs from
.py vs .c
- You only have to compile once to have the executable forever.
- Most programs are executables, not scripts.
Options
gcchas many options-ospecifies the name of the output file-stdspecifies the C version (there’s a few)-Wall -Wextra -Werror -Wpedanticset warnings - I use all 4-wstop all warnings.-O2to compile more slowly to make faster code
C89/99
- I prefer to write C89/99 compliant code
- Later code is a bit too unclear for me
- C89/99 have everything I need in a systems language
- Most latter features I’d just switch to Python anyways
- It tends to be easier to write compilers for C89 as well…
Podracing
- Quickly pop back into our container.
- Bookmark this page, save the text in a script, etc.
- Pop open
:termand run
- My code runs fine. Let’s break it.
C++ //
- Many C++ features have been adopted by C
- Perhaps the most famous is C++ comments.
std=c89
- My
vimwindow was tiny and I didn’t want to resize it - I opened a new terminal and tested
gcc samp.c --std=c89
user@DESKTOP-THMS2PJ:~/crypto/c89_99$ podman exec -it -l gcc samp.c --std=c89
samp.c: In function 'main':
samp.c:5:9: error: C++ style comments are not allowed in ISO C90
5 | // This is a C++ style comment
| ^
samp.c:5:9: note: (this will be reported only once per input file)
user@DESKTOP-THMS2PJ:~/crypto/c89_99$ podman exec -it -l gcc samp.c-Wall etc
- The other flags help “keep you honest”
- If we wanted shortcuts, we’d use Python
- We want to be percise [sic]
- Try it:
Whoops
- You don’t want to find these problems latter.
samp.c: In function 'main':
samp.c:5:9: error: C++ style comments are not allowed in ISO C90
5 | // This is a C++ style comment
| ^
samp.c:5:9: note: (this will be reported only once per input file)
samp.c:3:14: error: unused parameter 'argc' [-Werror=unused-parameter]
3 | int main(int argc, char **argv) {
| ~~~~^~~~
samp.c:3:27: error: unused parameter 'argv' [-Werror=unused-parameter]
3 | int main(int argc, char **argv) {
| ~~~~~~~^~~~
cc1: all warnings being treated as errors- Python needs
-Wallfor intro programming classes!
Benefits of C89
- In C89, we must declare all variables at the beginning of functions.
- Every “confused” Enigma I saw had massive variable name proliferation
- Python lets you do this.
- I argue this is Python preventing you from learning to program
- The C89 language standard will protect you from writing bad code.
Expectation
Reality
- These flags prevent unused variables
- These flags require variable declaration early.
- We have to think, plan etc.
Example
- Variable declared, not used.
int main(int argc, char **argv) {
int i;
/* if (argc < 1) {
return 1;
} */
for (i = 0 ; argv[1][i]; i++) {
argv[1][i] = cipher(argv[1][i], i);
}
printf("%s\n", argv[1]);
return 0;
}- We can segmentation fault from an out-of-bounds error on argv.
Example
- Variable declaration in function
int main(int argc, char **argv) {
int i;
for (i = 0 ; argv[1][i]; i++) {
argv[1][i] = cipher(argv[1][i], i);
int i++;
}
printf("%s\n", argv[1]);
return 0;
}- Prevents ill-formed variable changes.
- Like .js
constconvention
- Like .js
Example
-Werror=char-subscripts
int main(int argc, char **argv) {
char i;
for (i = 0 ; argv[1][i]; i++) {
argv[1][i] = cipher(argv[1][i], i);
}
printf("%s\n", argv[1]);
return 0;
}- Ensures we can read strings of 255+ chars.
Example
- Not technically wrong.
int main(int argc, char **argv) {
char i;
if (argc < 1) {
return 1;
}
char *input_string = argv[1];
for (i = 0 ; argv[1][i]; i++) {
argv[1][i] = cipher(argv[1][i], i);
}
printf("%s\n", argv[1]);
return 0;
}- But why?
Example
- Actually wrong - output_string has no size.
int main(int argc, char **argv) {
char i;
if (argc < 1) {
return 1;
}
char *output_string;
for (i = 0 ; argv[1][i]; i++) {
output_string[i] = cipher(argv[1][i], i);
}
printf("%s\n", argv[1]);
return 0;
}- C89 catches this, others don’t.
Takeaway
- As a second (or latter language)
- Learn C by turning on compiler flags and writing code.
- As a first language, use this little trick called “learn Python instead”
- With practice, the correspondences will become obvious.
- At that time, you will understand computing.
Practice to Perform
- My take: learn C89 in class
- Cultivate a disciplined coding practice
- Work on older devices
- Understand old code
- Understand how computers work
- Learn modern C via Stack Overflow
- Understand how to code in practice
Today
- Reintroduce the technologies
- ✓
podman - ✓
vim - ✓
gcc git
- ✓
Git
- Git was invented… to store the C language source code for an open source operating system (Linux)
- It is de facto the only way in the universe to store code other than “on my HDD/SSD”
-
It is also a very good way to
- Store Containerfiles
- Steadily build a codebase
As a command
- Git corresponds, like the others, to a command:
git- It is common now to use other techniques, but the command remains extremely stable
- Quoth GitHub, the first and greatest of the collaboration tools:
If you want a lot of control and flexibility, you can use the command line.
Henceforth
- This week: Macros homework
- This code will be used in the final project
- Just like all the rest of the code we write this term
- Store it on one big ole GitHub repo
Fun fact
- Despite Big Command Line lobbying to get us to use
git - There is no graceful way to set repositories to private at commandline
- There’s a tactic doing API calls through the GitHub CLI
- What are we even doing, open a browser
- In 2024, browsers are decisively more secure than the commandline
Private
- I recommend:
- Pop in browser
- Make a private github repo, like “crypto”
- Add me as a collaborator
- Name it “crypto”
- Probably use a folder per week for hws
- Maybe also labs, or just keep those local
GitHub x Podman
- Over time, we’ll try to operationalize code better and better
- Eventually, I plan to ask for a container in “ghcr”
- GitHub Container Registry
- In the meantime, I’d just keep a Containerfile at top level in your “crypto” repo.
Today
- Reintroduce the technologies
- ✓
podman - ✓
vim - ✓
gcc - ✓
git
- ✓
Stinger
root@262ad65a08ba:/# vim build.sh
root@262ad65a08ba:/# ./build.sh
bash: ./build.sh: Permission denied
root@262ad65a08ba:/# chmod 777 build.sh
root@262ad65a08ba:/# ./build.sh
samp.c: In function 'main':
samp.c:5:9: error: C++ style comments are not allowed in ISO C90
5 | // This is a C++ style comment
| ^
samp.c:5:9: note: (this will be reported only once per input file)
samp.c:3:14: error: unused parameter 'argc' [-Werror=unused-parameter]
3 | int main(int argc, char **argv) {
| ~~~~^~~~
samp.c:3:27: error: unused parameter 'argv' [-Werror=unused-parameter]
3 | int main(int argc, char **argv) {
| ~~~~~~~^~~~
cc1: all warnings being treated as errors
root@262ad65a08ba:/# cat build.sh
#!/bin/sh
gcc samp.c --std=c89 -Wall -Wextra -Werror -Wpedantic -O2 -o samp
root@262ad65a08ba:/#