diff --git a/README.md b/README.md index b0d9230..0db885a 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ After command just hit enter (~3x). For more informations visit --> https://docs.gitlab.com/ee/ssh/ ## Cloning Repository ```bash -git clone git@git.kemt.fei.tuke.sk:mr171hg/DiplomaWork.git +git clone git@github.com:mr171hg/DiplomaProject.git ``` ## Add & Push new data ```bash diff --git a/WireGuard/USAGE/UsingWireGuardVPN.pdf b/WireGuard/USAGE/UsingWireGuardVPN.pdf new file mode 100644 index 0000000..1fc7944 Binary files /dev/null and b/WireGuard/USAGE/UsingWireGuardVPN.pdf differ diff --git a/WireGuard/USAGE/links.txt b/WireGuard/USAGE/links.txt index 14e4717..18bf372 100644 --- a/WireGuard/USAGE/links.txt +++ b/WireGuard/USAGE/links.txt @@ -1 +1,3 @@ -https://www.researchgate.net/publication/345641555_Using_WireGuard_VPN \ No newline at end of file +https://www.researchgate.net/publication/345641555_Using_WireGuard_VPN + +https://www.researchgate.net/publication/348734501_Using_WireGuard_VPN \ No newline at end of file diff --git a/adds/ubuntu command for shared folder.txt b/adds/ubuntu command for shared folder.txt new file mode 100644 index 0000000..60cfa4f --- /dev/null +++ b/adds/ubuntu command for shared folder.txt @@ -0,0 +1,2 @@ +ubuntu command for shared folder +sudo usermod -aG vboxsf $(whoami) \ No newline at end of file diff --git a/dsvpn-master/.clang-format b/dsvpn-master/.clang-format new file mode 100644 index 0000000..7ba97b1 --- /dev/null +++ b/dsvpn-master/.clang-format @@ -0,0 +1,94 @@ +--- +Language: Cpp +AccessModifierOffset: -4 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: true +AlignConsecutiveDeclarations: true +AlignEscapedNewlinesLeft: true +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Inline +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: true +AlwaysBreakTemplateDeclarations: true +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false +BreakBeforeBinaryOperators: None +BreakBeforeBraces: WebKit +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: true +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 100 +CommentPragmas: '^ IWYU pragma:' +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: false +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: true +ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + - Regex: '^(<|"(gtest|isl|json)/)' + Priority: 3 + - Regex: '.*' + Priority: 1 +IncludeIsMainRegex: '$' +IndentCaseLabels: false +IndentWidth: 4 +IndentWrappedFunctionNames: false +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: false +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: Inner +ObjCBlockIndentWidth: 4 +ObjCSpaceAfterProperty: true +ObjCSpaceBeforeProtocolList: true +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Right +ReflowComments: true +SortIncludes: true +SpaceAfterCStyleCast: true +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp11 +TabWidth: 8 +UseTab: Never +... + diff --git a/dsvpn-master/.github/workflows/c.yml b/dsvpn-master/.github/workflows/c.yml new file mode 100644 index 0000000..5b3743d --- /dev/null +++ b/dsvpn-master/.github/workflows/c.yml @@ -0,0 +1,15 @@ +name: CI + +on: [push] + +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, macOS-latest] + + steps: + - uses: actions/checkout@master + - name: make + run: make diff --git a/dsvpn-master/.github/workflows/codeql-analysis.yml b/dsvpn-master/.github/workflows/codeql-analysis.yml new file mode 100644 index 0000000..7cfcf77 --- /dev/null +++ b/dsvpn-master/.github/workflows/codeql-analysis.yml @@ -0,0 +1,51 @@ +name: "CodeQL scan" + +on: + push: + pull_request: + schedule: + - cron: '0 21 * * 6' + +jobs: + CodeQL-Build: + + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + with: + # We must fetch at least the immediate parents so that if this is + # a pull request then we can checkout the head. + fetch-depth: 2 + + # If this run was triggered by a pull request event, then checkout + # the head of the pull request instead of the merge commit. + - run: git checkout HEAD^2 + if: ${{ github.event_name == 'pull_request' }} + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + # Override language selection by uncommenting this and choosing your languages + # with: + # languages: go, javascript, csharp, python, cpp, java + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v1 + + # ℹ️ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 diff --git a/dsvpn-master/.gitignore b/dsvpn-master/.gitignore new file mode 100644 index 0000000..9c951fb --- /dev/null +++ b/dsvpn-master/.gitignore @@ -0,0 +1,42 @@ +*.a +*.app +*.cmd +*.d +*.dSYM/ +*.dll +*.dylib +*.elf +*.exe +*.exp +*.gch +*.hex +*.i*86 +*.idb +*.ilk +*.key +*.ko +*.la +*.lib +*.lo +*.map +*.mod* +*.o +*.obj +*.out +*.pch +*.pdb +*.so +*.so.* +*.su +*.x86_64 +*~ +.tmp_versions/ +.vscode +Mkfile.old +Module.symvers +dkms.conf +dsvpn +key +modules.order +zig-out +zig-cache diff --git a/dsvpn-master/.travis.yml b/dsvpn-master/.travis.yml new file mode 100644 index 0000000..7c5c7bc --- /dev/null +++ b/dsvpn-master/.travis.yml @@ -0,0 +1,24 @@ +language: c +sudo: false +dist: bionic + +os: + - linux + +compiler: + - gcc + - clang + +arch: + - arm64 + - amd64 + - s390x + - ppc64le + +matrix: + include: + - os: osx + arch: amd64 + compiler: clang + +script: make diff --git a/dsvpn-master/LICENSE b/dsvpn-master/LICENSE new file mode 100644 index 0000000..72b9282 --- /dev/null +++ b/dsvpn-master/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Frank Denis + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/dsvpn-master/Makefile b/dsvpn-master/Makefile new file mode 100644 index 0000000..04bc14c --- /dev/null +++ b/dsvpn-master/Makefile @@ -0,0 +1,33 @@ +CFLAGS_FILE?=.cflags +COMPILE_TEST_FILE?=.test.c +PREFIX?=/usr/local + +all: dsvpn + +dsvpn: $(CFLAGS_FILE) Makefile src/vpn.c src/charm.c src/os.c include/charm.h include/vpn.h include/os.h + $(CC) $$(cat "$(CFLAGS_FILE)") $(OPTFLAGS) -Iinclude -o $@ src/vpn.c src/charm.c src/os.c + strip $@ + +install: dsvpn + install -d $(PREFIX)/sbin + install -m 0755 dsvpn $(PREFIX)/sbin + +uninstall: + rm -f $(PREFIX)/sbin/dsvpn + +clean: + rm -f dsvpn *~ $(CFLAGS_FILE) $(COMPILE_TEST_FILE) + +$(CFLAGS_FILE): + @CFLAGS="$(CFLAGS)" + @if [ -z "$$CFLAGS" ]; then \ + if [ ! -r "$(CFLAGS_FILE)" ]; then \ + echo "int main(void) { return 0; }" > "$(COMPILE_TEST_FILE)"; \ + for flag in -march=native -mtune=native -Ofast -Wno-unused-command-line-argument; do \ + $(CC) $${CFLAGS} $${flag} "$(COMPILE_TEST_FILE)" >/dev/null 2>&1 && CFLAGS="$$CFLAGS $$flag"; \ + done; \ + rm -f a.out \ + CFLAGS="$${CFLAGS} -Wall -W -Wshadow -Wmissing-prototypes"; \ + fi \ + fi; \ + echo "$$CFLAGS" > "$(CFLAGS_FILE)" diff --git a/dsvpn-master/README.md b/dsvpn-master/README.md new file mode 100644 index 0000000..1419000 --- /dev/null +++ b/dsvpn-master/README.md @@ -0,0 +1,156 @@ +# ![DSVPN](https://raw.github.com/jedisct1/dsvpn/master/logo.png) + +[![GitHub CI status](https://github.com/jedisct1/dsvpn/workflows/CI/badge.svg)](https://github.com/jedisct1/dsvpn/actions) +[![Travis CI status](https://api.travis-ci.org/jedisct1/dsvpn.svg?branch=master)](https://travis-ci.org/jedisct1/dsvpn) +![CodeQL scan](https://github.com/jedisct1/dsvpn/workflows/CodeQL%20scan/badge.svg) + +DSVPN is a Dead Simple VPN, designed to address the most common use case for using a VPN: + +```text +[client device] ---- (untrusted/restricted network) ---- [vpn server] ---- [the Internet] +``` + +Features: + +* Runs on TCP. Works pretty much everywhere, including on public WiFi where only TCP/443 is open or reliable. +* Uses only modern cryptography, with formally verified implementations. +* Small and constant memory footprint. Doesn't perform any heap memory allocations. +* Small (~25 KB), with an equally small and readable code base. No external dependencies. +* Works out of the box. No lousy documentation to read. No configuration file. No post-configuration. Run a single-line command on the server, a similar one on the client and you're done. No firewall and routing rules to manually mess with. +* Works on Linux (kernel >= 3.17), macOS and OpenBSD, as well as DragonFly BSD, FreeBSD and NetBSD in client and point-to-point modes. Adding support for other operating systems is trivial. +* Doesn't leak between reconnects if the network doesn't change. Blocks IPv6 on the client to prevent IPv6 leaks. + +## Installation + +```sh +make +``` + +On Raspberry Pi 3 and 4, use the following command instead to enable NEON optimizations: + +```sh +env OPTFLAGS=-mfpu=neon make +``` + +Alternatively, if you have [zig](https://ziglang.org) installed, it can be used to compile DSVPN: + +```sh +zig build +``` + +On macOS, DSVPN can be installed using Homebrew: `brew install dsvpn`. + +## Secret key + +DSVPN uses a shared secret. Create it with the following command: + +```sh +dd if=/dev/urandom of=vpn.key count=1 bs=32 +``` + +And copy it on the server and the client. + +If required, keys can be exported and imported in printable form: + +```sh +base64 < vpn.key +echo 'HK940OkWcFqSmZXnCQ1w6jhQMZm0fZoEhQOOpzJ/l3w=' | base64 --decode > vpn.key +``` + +## Example usage on the server + +```sh +sudo ./dsvpn server vpn.key auto 1959 +``` + +Here, I use port `1959`. Everything else is set to the default values. If you want to use the default port (`443`), it doesn't even have to be specified, so the parameters can just be `server vpn.key` + +## Example usage on the client + +```sh +sudo ./dsvpn client vpn.key 34.216.127.34 1959 +``` + +This is a macOS client, connecting to the VPN server `34.216.127.34` on port `1959`. The port number is optional here as well. And the IP can be replaced by a host name. + +## That's it + +You are connected. Just hit `Ctrl`-`C` to disconnect. + +Evaggelos Balaskas wrote a great blog post walking through the whole procedure: [A Dead Simple VPN](https://balaskas.gr/blog/2019/07/20/a-dead-simple-vpn/). + +He also maintains [systemd service files for DSVPN](https://github.com/ebal/scripts/tree/master/dsvpn). Thank you Evaggelos! + +## A note on DNS + +If you were previously using a DNS resolver only accessible from the local network, it won't be accessible through the VPN. That might be the only thing you may have to change. Use a public resolver, a local resolver, or DNSCrypt. + +Or send a pull request implementing the required commands to change and revert the DNS settings, or redirect DNS queries to another resolver, for all supported operating systems. + +## Advanced configuration + +```text +dsvpn "server" + + |"auto" + |"auto" + |"auto" + |"auto" + "auto" + |"auto" + +dsvpn "client" + + + |"auto" + |"auto" + |"auto" + |"auto" + |"auto" +``` + +* `server`|`client`: use `server` on the server, and `client` on clients. +* ``: path to the file with the secret key (e.g. `vpn.key`). +* ``: on the client, it should be the IP address or the hostname of the server. On the server, it doesn't matter, so you can just use `auto`. +* ``: the TCP port to listen to/connect to for the VPN. Use 443 or anything else. `auto` will use `443`. +* ``: this is the name of the VPN interface. On Linux, you can set it to anything. Or macOS, it has to follow a more boring pattern. If you feel lazy, just use `auto` here. +* ``: local IP address of the tunnel. Use any private IP address that you don't use here. +* ``: remote IP address of the tunnel. See above. The local and remote tunnel IPs must the same on the client and on the server, just reversed. For some reason, I tend to pick `192.168.192.254` for the server, and `192.168.192.1` for the client. These values will be used if you put `auto` for the local and remote tunnel IPs. +* `` (server only): the external IP address of the server. Can be left to `"auto"`. +* `` (client only): the internal router IP address. The first line printed by `netstat -rn` will tell you (`gateway`). + +If all the remaining parameters of a command would be `auto`, they don't have to be specified. + +## Related projects + +* Robert Debock maintains [an Ansible role for DSVPN](https://github.com/robertdebock/ansible-role-dsvpn) +* [OpenMPTCProuter](http://www.openmptcprouter.com/) is an OpenWRT-based router OS that supports DSVPN +* Yecheng Fu maintains a [Docker image for DSVPN](https://github.com/cofyc/dsvpn-docker) + +## Why + +I needed a VPN that works in an environment where only TCP/80 and TCP/443 are open. + +WireGuard doesn't work over TCP. + +[GloryTun](https://github.com/angt/glorytun) is excellent, but requires post-configuration and the maintained branch uses UDP. + +I forgot about [VTUN-libsodium](https://github.com/jedisct1/vtun). But it would have been too much complexity and attack surface for a simple use case. + +OpenVPN is horribly difficult to set up. + +Sshuttle is very nice and I've been using it a lot in the past, but it's not a VPN. It doesn't tunnel non-TCP traffic. It also requires a full Python install, which I'd rather avoid on my router. + +Everything else I looked at was either too difficult to use, slow, bloated, didn't work on macOS, didn't work on small devices, was complicated to cross-compile due to dependencies, wasn't maintained, or didn't feel secure. + +TCP-over-TCP is not as bad as some documents describe. It works surprisingly well in practice, especially with modern congestion control algorithms (BBR). For traditional algorithms that rely on packet loss, DSVPN couples the inner and outer congestion controllers by lowering `TCP_NOTSENT_LOWAT` and dropping packets when congestion is detected at the outer layer. + +## Cryptography + +The cryptographic primitives used in DSVPN are available as a standalone project: [Charm](https://github.com/jedisct1/charm). + +## Guarantees, support, feature additions + +None. + +This is not intended to be a replacement for GloryTun or WireGuard. This is what I use, because it solves a problem I had. Extending it to solve different problems is not planned, but feel free to fork it and tailor it to your needs! diff --git a/dsvpn-master/build.zig b/dsvpn-master/build.zig new file mode 100644 index 0000000..f9fd3c1 --- /dev/null +++ b/dsvpn-master/build.zig @@ -0,0 +1,16 @@ +const std = @import("std"); +const builtin = @import("builtin"); + +pub fn build(b: *std.build.Builder) !void { + var target = b.standardTargetOptions(.{}); + + const dsvpn = b.addExecutable("dsvpn", null); + dsvpn.setTarget(target); + dsvpn.setBuildMode(.ReleaseSmall); + dsvpn.install(); + dsvpn.linkLibC(); + + dsvpn.addIncludeDir("include"); + dsvpn.defineCMacro("_GNU_SOURCE", "1"); + dsvpn.addCSourceFiles(&.{ "src/charm.c", "src/os.c", "src/vpn.c" }, &.{}); +} diff --git a/dsvpn-master/include/charm.h b/dsvpn-master/include/charm.h new file mode 100644 index 0000000..64f7d63 --- /dev/null +++ b/dsvpn-master/include/charm.h @@ -0,0 +1,30 @@ +/* +Organization: Technical University of Kosice (TUKE), +Department: Department of Electronics and Multimedia Telecommunications (DEMT/KEMT), +Faculties: Faculty of Electrical Engineering and Informatics (FEI), +Feld of study: Informatics, +Study program: Computer Networks, +School year: 4., Ing., 2021/2022 +Author of corrections: Marek Rohac -- MR, +Last Update: 20.02.2022 -- add description +*/ +#ifndef charm_H +#define charm_H 1 + +#include +#include + +void uc_state_init(uint32_t st[12], const unsigned char key[32], const unsigned char iv[16]); + +void uc_encrypt(uint32_t st[12], unsigned char *msg, size_t msg_len, unsigned char tag[16]); + +int uc_decrypt(uint32_t st[12], unsigned char *msg, size_t msg_len, + const unsigned char *expected_tag, size_t expected_tag_len); + +void uc_hash(uint32_t st[12], unsigned char h[32], const unsigned char *msg, size_t len); + +void uc_memzero(void *buf, size_t len); + +void uc_randombytes_buf(void *buf, size_t len); + +#endif diff --git a/dsvpn-master/include/os.h b/dsvpn-master/include/os.h new file mode 100644 index 0000000..fb58a8c --- /dev/null +++ b/dsvpn-master/include/os.h @@ -0,0 +1,47 @@ +/* +Organization: Technical University of Kosice (TUKE), +Department: Department of Electronics and Multimedia Telecommunications (DEMT/KEMT), +Faculties: Faculty of Electrical Engineering and Informatics (FEI), +Feld of study: Informatics, +Study program: Computer Networks, +School year: 4., Ing., 2021/2022 +Author of corrections: Marek Rohac -- MR, +Last Update: 20.02.2022 -- add description +*/ +#ifndef os_H +#define os_H 1 + +#include "vpn.h" + +ssize_t safe_read(const int fd, void *const buf_, size_t count, const int timeout); + +ssize_t safe_write(const int fd, const void *const buf_, size_t count, const int timeout); + +ssize_t safe_read_partial(const int fd, void *const buf_, const size_t max_count); + +ssize_t safe_write_partial(const int fd, void *const buf_, const size_t max_count); + +typedef struct Cmds { + const char *const *set; + const char *const *unset; +} Cmds; + +Cmds firewall_rules_cmds(int is_server); + +int shell_cmd(const char *substs[][2], const char *args_str, int silent); + +const char *get_default_gw_ip(void); + +const char *get_default_ext_if_name(void); + +int tcp_opts(int fd); + +int tun_create(char if_name[IFNAMSIZ], const char *wanted_name); + +int tun_set_mtu(const char *if_name, int mtu); + +ssize_t tun_read(int fd, void *data, size_t size); + +ssize_t tun_write(int fd, const void *data, size_t size); + +#endif diff --git a/dsvpn-master/include/vpn.h b/dsvpn-master/include/vpn.h new file mode 100644 index 0000000..a053f2b --- /dev/null +++ b/dsvpn-master/include/vpn.h @@ -0,0 +1,98 @@ +/* +Organization: Technical University of Kosice (TUKE), +Department: Department of Electronics and Multimedia Telecommunications (DEMT/KEMT), +Faculties: Faculty of Electrical Engineering and Informatics (FEI), +Feld of study: Informatics, +Study program: Computer Networks, +School year: 4., Ing., 2021/2022 +Author of corrections: Marek Rohac -- MR, +Last Update: 20.02.2022 -- add description +*/ + +#ifndef vpn_H +#define vpn_H 1 + +/*UNIX-like OS Dependent Libraries*/ +#include +#include +#include +#include +#include + +#include +#include +#include +/*End UNIX-like OS Dependent Libraries*/ + +/*%Standard C Libraries*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +/*End of Standard C Libraries*/ + +/*OS setup dependencies*/ +#ifdef __linux__ +#include +#endif + +#ifdef __APPLE__ +#include +#include +#include +#endif + +#define VERSION_STRING "0.1.4" + +#ifdef __NetBSD__ +#define DEFAULT_MTU 1500 +#else +#define DEFAULT_MTU 9000 +#endif +/*End of OS setup dependencies*/ + +/*Constants - system independent*/ +#define RECONNECT_ATTEMPTS 100 +#define TAG_LEN 6 +#define MAX_PACKET_LEN 65536 +#define TS_TOLERANCE 7200 +#define TIMEOUT (60 * 1000) +#define ACCEPT_TIMEOUT (10 * 1000) +#define OUTER_CONGESTION_CONTROL_ALG "bbr" +#define BUFFERBLOAT_CONTROL 1 +#define NOTSENT_LOWAT (128 * 1024) +#define DEFAULT_CLIENT_IP "192.168.192.1" +#define DEFAULT_SERVER_IP "192.168.192.254" +#define DEFAULT_PORT "443" + +/*Edianity check + setup*/ +#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \ + __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ && !defined(NATIVE_BIG_ENDIAN) +#define NATIVE_BIG_ENDIAN +#endif + +/*Big endian definition*/ +#ifdef NATIVE_BIG_ENDIAN +#define endian_swap16(x) __builtin_bswap16(x) +#define endian_swap32(x) __builtin_bswap32(x) +#define endian_swap64(x) __builtin_bswap64(x) +#else +#define endian_swap16(x) (x) +#define endian_swap32(x) (x) +#define endian_swap64(x) (x) +#endif + +//celociselny typ pre objekty, ktorych hodnota sa meni priradovacim operatorom +extern volatile sig_atomic_t exit_signal_received; +// atomova operacia -- vykonavanie nie je nikdy pozastavene, kym nie je ciastocne ukoncena operacia +//asi na spracovanie udajov zo sietovky ?? -- uvidime +#endif diff --git a/dsvpn-master/logo.png b/dsvpn-master/logo.png new file mode 100644 index 0000000..644e9a0 Binary files /dev/null and b/dsvpn-master/logo.png differ diff --git a/dsvpn-master/src/charm.c b/dsvpn-master/src/charm.c new file mode 100644 index 0000000..4ee7ca3 --- /dev/null +++ b/dsvpn-master/src/charm.c @@ -0,0 +1,337 @@ +#include +#include +#include +#ifdef __SSSE3__ +#include +#endif +#if defined(__ARM_NEON) || defined(__aarch64__) +#include +#endif +#ifdef __linux__ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include +#include +#endif + +#include "charm.h" + +#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \ + __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +#define NATIVE_BIG_ENDIAN +#endif +#ifndef NATIVE_BIG_ENDIAN +#ifndef NATIVE_LITTLE_ENDIAN +#define NATIVE_LITTLE_ENDIAN +#endif +#endif + +#ifndef XOODOO_ROUNDS +#define XOODOO_ROUNDS 12 +#endif + +static inline void mem_cpy(unsigned char *dst, const unsigned char *src, size_t n) +{ + size_t i; + for (i = 0; i < n; i++) { + dst[i] = src[i]; + } +} + +static const uint32_t RK[12] = { 0x058, 0x038, 0x3c0, 0x0d0, 0x120, 0x014, + 0x060, 0x02c, 0x380, 0x0f0, 0x1a0, 0x012 }; + +#ifdef __SSSE3__ +#define ROL32in128(x, b) _mm_or_si128(_mm_slli_epi32((x), (b)), _mm_srli_epi32((x), 32 - (b))) + +static void permute(uint32_t st[12]) +{ + const __m128i rhoEast2 = _mm_set_epi32(0x06050407, 0x02010003, 0x0e0d0c0f, 0x0a09080b); + __m128i a, b, c, p, e; + int r; + + a = _mm_loadu_si128((const __m128i *) (const void *) &st[0]); + b = _mm_loadu_si128((const __m128i *) (const void *) &st[4]); + c = _mm_loadu_si128((const __m128i *) (const void *) &st[8]); + for (r = 0; r < XOODOO_ROUNDS; r++) { + p = _mm_shuffle_epi32(_mm_xor_si128(_mm_xor_si128(a, b), c), 0x93); + e = ROL32in128(p, 5); + p = ROL32in128(p, 14); + e = _mm_xor_si128(e, p); + a = _mm_xor_si128(a, e); + b = _mm_xor_si128(b, e); + c = _mm_xor_si128(c, e); + b = _mm_shuffle_epi32(b, 0x93); + c = ROL32in128(c, 11); + a = _mm_xor_si128(a, _mm_set_epi32(0, 0, 0, RK[r])); + a = _mm_xor_si128(a, _mm_andnot_si128(b, c)); + b = _mm_xor_si128(b, _mm_andnot_si128(c, a)); + c = _mm_xor_si128(c, _mm_andnot_si128(a, b)); + b = ROL32in128(b, 1); + c = _mm_shuffle_epi8(c, rhoEast2); + } + _mm_storeu_si128((__m128i *) (void *) &st[0], a); + _mm_storeu_si128((__m128i *) (void *) &st[4], b); + _mm_storeu_si128((__m128i *) (void *) &st[8], c); +} +#elif defined(__ARM_NEON) || defined(__aarch64__) +#define ROL32in128(x, b) vsriq_n_u32(vshlq_n_u32((x), (b)), (x), 32 - (b)) + +static void permute(uint32_t st[12]) +{ + uint32x4_t a, b, c, d, e, f; + int r; + + a = vld1q_u32((const uint32_t *) (const void *) &st[0]); + b = vld1q_u32((const uint32_t *) (const void *) &st[4]); + c = vld1q_u32((const uint32_t *) (const void *) &st[8]); + for (r = 0; r < XOODOO_ROUNDS; r++) { + d = veorq_u32(veorq_u32(a, b), c); + d = vextq_u32(d, d, 3); + e = ROL32in128(d, 5); + f = ROL32in128(d, 14); + e = veorq_u32(e, f); + a = veorq_u32(a, e); + b = veorq_u32(b, e); + f = veorq_u32(c, e); + c = ROL32in128(f, 11); + b = vextq_u32(b, b, 3); + a = veorq_u32(a, vsetq_lane_u32(RK[r], vmovq_n_u32(0), 0)); + e = vbicq_u32(c, b); + d = vbicq_u32(a, c); + f = vbicq_u32(b, a); + a = veorq_u32(a, e); + d = veorq_u32(b, d); + c = veorq_u32(c, f); + f = vextq_u32(c, c, 2); + b = ROL32in128(d, 1); + c = ROL32in128(f, 8); + } + vst1q_u32((uint32_t *) (void *) &st[0], a); + vst1q_u32((uint32_t *) (void *) &st[4], b); + vst1q_u32((uint32_t *) (void *) &st[8], c); +} +#else +#define ROTR32(x, b) (uint32_t)(((x) >> (b)) | ((x) << (32 - (b)))) +#define SWAP32(s, u, v) \ + do { \ + t = (s)[u]; \ + (s)[u] = (s)[v], (s)[v] = t; \ + } while (0) + +static void permute(uint32_t st[12]) +{ + uint32_t e[4], a, b, c, t, r, i; + + for (r = 0; r < XOODOO_ROUNDS; r++) { + for (i = 0; i < 4; i++) { + e[i] = ROTR32(st[i] ^ st[i + 4] ^ st[i + 8], 18); + e[i] ^= ROTR32(e[i], 9); + } + for (i = 0; i < 12; i++) { + st[i] ^= e[(i - 1) & 3]; + } + SWAP32(st, 7, 4); + SWAP32(st, 7, 5); + SWAP32(st, 7, 6); + st[0] ^= RK[r]; + for (i = 0; i < 4; i++) { + a = st[i]; + b = st[i + 4]; + c = ROTR32(st[i + 8], 21); + st[i + 8] = ROTR32((b & ~a) ^ c, 24); + st[i + 4] = ROTR32((a & ~c) ^ b, 31); + st[i] ^= c & ~b; + } + SWAP32(st, 8, 10); + SWAP32(st, 9, 11); + } +} +#endif + +static inline void endian_swap_rate(uint32_t st[12]) +{ + (void) st; +#ifdef NATIVE_BIG_ENDIAN + size_t i; + for (i = 0; i < 4; i++) { + st[i] = __builtin_bswap32(st[i]); + } +#endif +} + +static inline void endian_swap_all(uint32_t st[12]) +{ + (void) st; +#ifdef NATIVE_BIG_ENDIAN + size_t i; + for (i = 0; i < 12; i++) { + st[i] = __builtin_bswap32(st[i]); + } +#endif +} + +static inline void xor128(void *out, const void *in) +{ +#ifdef __SSSE3__ + _mm_storeu_si128((__m128i *) out, + _mm_xor_si128(_mm_loadu_si128((const __m128i *) out), + _mm_loadu_si128((const __m128i *) in))); +#else + unsigned char * out_ = (unsigned char *) out; + const unsigned char *in_ = (const unsigned char *) in; + size_t i; + + for (i = 0; i < 16; i++) { + out_[i] ^= in_[i]; + } +#endif +} + +static inline int equals(const unsigned char a[16], const unsigned char b[16], size_t len) +{ + unsigned char d = 0; + size_t i; + + for (i = 0; i < len; i++) { + d |= a[i] ^ b[i]; + } + return 1 & ((d - 1) >> 8); +} + +static inline void squeeze_permute(uint32_t st[12], unsigned char dst[16]) +{ + endian_swap_rate(st); + memcpy(dst, st, 16); + endian_swap_rate(st); + permute(st); +} + +void uc_state_init(uint32_t st[12], const unsigned char key[32], const unsigned char iv[16]) +{ + memcpy(&st[0], iv, 16); + memcpy(&st[4], key, 32); + endian_swap_all(st); + permute(st); +} + +void uc_encrypt(uint32_t st[12], unsigned char *msg, size_t msg_len, unsigned char tag[16]) +{ + unsigned char squeezed[16]; + unsigned char padded[16 + 1]; + size_t off = 0; + size_t leftover; + + if (msg_len > 16) { + for (; off < msg_len - 16; off += 16) { + endian_swap_rate(st); + memcpy(squeezed, st, 16); + xor128(st, &msg[off]); + endian_swap_rate(st); + xor128(&msg[off], squeezed); + permute(st); + } + } + leftover = msg_len - off; + memset(padded, 0, 16); + mem_cpy(padded, &msg[off], leftover); + padded[leftover] = 0x80; + endian_swap_rate(st); + memcpy(squeezed, st, 16); + xor128(st, padded); + endian_swap_rate(st); + st[11] ^= (1UL << 24 | (uint32_t) leftover >> 4 << 25 | 1UL << 26); + xor128(padded, squeezed); + mem_cpy(&msg[off], padded, leftover); + permute(st); + squeeze_permute(st, tag); +} + +int uc_decrypt(uint32_t st[12], unsigned char *msg, size_t msg_len, + const unsigned char *expected_tag, size_t expected_tag_len) +{ + unsigned char tag[16]; + unsigned char squeezed[16]; + unsigned char padded[16 + 1]; + size_t off = 0; + size_t leftover; + + if (msg_len > 16) { + for (; off < msg_len - 16; off += 16) { + endian_swap_rate(st); + memcpy(squeezed, st, 16); + xor128(&msg[off], squeezed); + xor128(st, &msg[off]); + endian_swap_rate(st); + permute(st); + } + } + leftover = msg_len - off; + memset(padded, 0, 16); + mem_cpy(padded, &msg[off], leftover); + endian_swap_rate(st); + memset(squeezed, 0, 16); + mem_cpy(squeezed, (const unsigned char *) (const void *) st, leftover); + xor128(&padded, squeezed); + padded[leftover] = 0x80; + xor128(st, padded); + endian_swap_rate(st); + st[11] ^= (1UL << 24 | (uint32_t) leftover >> 4 << 25 | 1UL << 26); + mem_cpy(&msg[off], padded, leftover); + permute(st); + squeeze_permute(st, tag); + if (equals(expected_tag, tag, expected_tag_len) == 0) { + memset(msg, 0, msg_len); + return -1; + } + return 0; +} + +void uc_hash(uint32_t st[12], unsigned char h[32], const unsigned char *msg, size_t len) +{ + unsigned char padded[16 + 1]; + size_t off = 0; + size_t leftover; + + if (len > 16) { + for (; off < len - 16; off += 16) { + endian_swap_rate(st); + xor128(st, &msg[off]); + endian_swap_rate(st); + permute(st); + } + } + leftover = len - off; + memset(padded, 0, 16); + mem_cpy(padded, &msg[off], leftover); + padded[leftover] = 0x80; + endian_swap_rate(st); + xor128(st, padded); + endian_swap_rate(st); + st[11] ^= (1UL << 24 | (uint32_t) leftover >> 4 << 25); + permute(st); + squeeze_permute(st, &h[0]); + squeeze_permute(st, &h[16]); +} + +void uc_memzero(void *buf, size_t len) +{ + volatile unsigned char *volatile buf_ = (volatile unsigned char *volatile) buf; + size_t i = (size_t) 0U; + + while (i < len) { + buf_[i++] = 0U; + } +} + +void uc_randombytes_buf(void *buf, size_t len) +{ +#ifdef __linux__ + if ((size_t) syscall(SYS_getrandom, buf, (int) len, 0) != len) { + abort(); + } +#else + arc4random_buf(buf, len); +#endif +} diff --git a/dsvpn-master/src/gw.bat b/dsvpn-master/src/gw.bat new file mode 100644 index 0000000..3022790 --- /dev/null +++ b/dsvpn-master/src/gw.bat @@ -0,0 +1,10 @@ +@echo off +for /f "tokens=2,3 delims={,}" %%a in ('"WMIC NICConfig where IPEnabled="True" get DefaultIPGateway /value | find "I" "') do echo IPv4 %%~a IPV6 %%~b +pause + +@echo on +set "ip=" +for /f "tokens=1-2 delims=:" %%a in ('ipconfig^|find "Default"') do if not defined ip set ip=%%b +pause + +echo "check also https://superuser.com/questions/524822/awk-equivalent-functionality-on-windows" \ No newline at end of file diff --git a/dsvpn-master/src/os.c b/dsvpn-master/src/os.c new file mode 100644 index 0000000..41de48d --- /dev/null +++ b/dsvpn-master/src/os.c @@ -0,0 +1,537 @@ +#include "os.h" +#include "vpn.h" +// nacitavanie po znaku +ssize_t safe_read(const int fd, void *const buf_, size_t count, const int timeout) +{ + struct pollfd pfd; + unsigned char *buf = (unsigned char *) buf_; + ssize_t readnb = (ssize_t) -1; + + while (readnb != 0 && count > (ssize_t) 0) { + while ((readnb = read(fd, buf, count)) < (ssize_t) 0) { + if (errno == EAGAIN) { + pfd.fd = fd; + pfd.events = POLLIN; + if (poll(&pfd, (nfds_t) 1, timeout) <= 0) { //https://man7.org/linux/man-pages/man2/poll.2.html + return (ssize_t) -1; + } + } else if (errno != EINTR || exit_signal_received) { + return (ssize_t) -1; + } + } + count -= readnb; + buf += readnb; + } + return (ssize_t)(buf - (unsigned char *) buf_); +} + +ssize_t safe_write(const int fd, const void *const buf_, size_t count, const int timeout) +{ + struct pollfd pfd; + const char * buf = (const char *) buf_; + ssize_t written; + + while (count > (size_t) 0) { + while ((written = write(fd, buf, count)) < (ssize_t) 0) { + if (errno == EAGAIN) { + pfd.fd = fd; + pfd.events = POLLOUT; + if (poll(&pfd, (nfds_t) 1, timeout) <= 0) { + return (ssize_t) -1; + } + } else if (errno != EINTR || exit_signal_received) { + return (ssize_t) -1; + } + } + buf += written; + count -= written; + } + return (ssize_t)(buf - (const char *) buf_); +} + +ssize_t safe_read_partial(const int fd, void *const buf_, const size_t max_count) +{ + unsigned char *const buf = (unsigned char *) buf_; + ssize_t readnb; + + while ((readnb = read(fd, buf, max_count)) < (ssize_t) 0 && errno == EINTR && + !exit_signal_received) + ; + return readnb; +} + +ssize_t safe_write_partial(const int fd, void *const buf_, const size_t max_count) +{ + unsigned char *const buf = (unsigned char *) buf_; + ssize_t writenb; + + while ((writenb = write(fd, buf, max_count)) < (ssize_t) 0 && errno == EINTR && + !exit_signal_received) + ; + return writenb; +} + +#ifdef __linux__ +int tun_create(char if_name[IFNAMSIZ], const char *wanted_name) +{ + struct ifreq ifr; + int fd; + int err; + + fd = open("/dev/net/tun", O_RDWR); + if (fd == -1) { + fprintf(stderr, "tun module not present. See https://sk.tl/2RdReigK\n"); + return -1; + } + ifr.ifr_flags = IFF_TUN | IFF_NO_PI; + snprintf(ifr.ifr_name, IFNAMSIZ, "%s", wanted_name == NULL ? "" : wanted_name); + if (ioctl(fd, TUNSETIFF, &ifr) != 0) { + err = errno; + (void) close(fd); + errno = err; + return -1; + } + snprintf(if_name, IFNAMSIZ, "%s", ifr.ifr_name); + + return fd; +} +#elif defined(__APPLE__) +static int tun_create_by_id(char if_name[IFNAMSIZ], unsigned int id) +{ + struct ctl_info ci; + struct sockaddr_ctl sc; + int err; + int fd; + + if ((fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL)) == -1) { + return -1; + } + memset(&ci, 0, sizeof ci); + snprintf(ci.ctl_name, sizeof ci.ctl_name, "%s", UTUN_CONTROL_NAME); + if (ioctl(fd, CTLIOCGINFO, &ci)) { + err = errno; + (void) close(fd); + errno = err; + return -1; + } + memset(&sc, 0, sizeof sc); + sc = (struct sockaddr_ctl){ + .sc_id = ci.ctl_id, + .sc_len = sizeof sc, + .sc_family = AF_SYSTEM, + .ss_sysaddr = AF_SYS_CONTROL, + .sc_unit = id + 1, + }; + if (connect(fd, (struct sockaddr *) &sc, sizeof sc) != 0) { + err = errno; + (void) close(fd); + errno = err; + return -1; + } + snprintf(if_name, IFNAMSIZ, "utun%u", id); + + return fd; +} + +int tun_create(char if_name[IFNAMSIZ], const char *wanted_name) +{ + unsigned int id; + int fd; + + if (wanted_name == NULL || *wanted_name == 0) { + for (id = 0; id < 32; id++) { + if ((fd = tun_create_by_id(if_name, id)) != -1) { + return fd; + } + } + return -1; + } + if (sscanf(wanted_name, "utun%u", &id) != 1) { + errno = EINVAL; + return -1; + } + return tun_create_by_id(if_name, id); +} +#elif defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__) +int tun_create(char if_name[IFNAMSIZ], const char *wanted_name) +{ + char path[64]; + unsigned int id; + int fd; + + if (wanted_name == NULL || *wanted_name == 0) { + for (id = 0; id < 32; id++) { + snprintf(if_name, IFNAMSIZ, "tun%u", id); + snprintf(path, sizeof path, "/dev/%s", if_name); + if ((fd = open(path, O_RDWR)) != -1) { + return fd; + } + } + return -1; + } + snprintf(if_name, IFNAMSIZ, "%s", wanted_name); + snprintf(path, sizeof path, "/dev/%s", wanted_name); + + return open(path, O_RDWR); +} +#else +int tun_create(char if_name[IFNAMSIZ], const char *wanted_name) +{ + char path[64]; + + if (wanted_name == NULL) { + fprintf(stderr, + "The tunnel device name must be specified on that platform " + "(try 'tun0')\n"); + errno = EINVAL; + return -1; + } + snprintf(if_name, IFNAMSIZ, "%s", wanted_name); + snprintf(path, sizeof path, "/dev/%s", wanted_name); + + return open(path, O_RDWR); +} +#endif + +int tun_set_mtu(const char *if_name, int mtu) +{ + struct ifreq ifr; + int fd; + + if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { + return -1; + } + ifr.ifr_mtu = mtu; + snprintf(ifr.ifr_name, IFNAMSIZ, "%s", if_name); + if (ioctl(fd, SIOCSIFMTU, &ifr) != 0) { + close(fd); + return -1; + } + return close(fd); +} + +#if !defined(__APPLE__) && !defined(__OpenBSD__) +ssize_t tun_read(int fd, void *data, size_t size) +{ + return safe_read_partial(fd, data, size); +} + +ssize_t tun_write(int fd, const void *data, size_t size) +{ + return safe_write(fd, data, size, TIMEOUT); +} +#else +ssize_t tun_read(int fd, void *data, size_t size) +{ + ssize_t ret; + uint32_t family; + + struct iovec iov[2] = { + { + .iov_base = &family, + .iov_len = sizeof family, + }, + { + .iov_base = data, + .iov_len = size, + }, + }; + + ret = readv(fd, iov, 2); + if (ret <= (ssize_t) 0) { + return -1; + } + if (ret <= (ssize_t) sizeof family) { + return 0; + } + return ret - sizeof family; +} + +ssize_t tun_write(int fd, const void *data, size_t size) +{ + uint32_t family; + ssize_t ret; + + if (size < 20) { + return 0; + } + switch (*(const uint8_t *) data >> 4) { + case 4: + family = htonl(AF_INET); + break; + case 6: + family = htonl(AF_INET6); + break; + default: + errno = EINVAL; + return -1; + } + struct iovec iov[2] = { + { + .iov_base = &family, + .iov_len = sizeof family, + }, + { + .iov_base = (void *) data, + .iov_len = size, + }, + }; + ret = writev(fd, iov, 2); + if (ret <= (ssize_t) 0) { + return ret; + } + if (ret <= (ssize_t) sizeof family) { + return 0; + } + return ret - sizeof family; +} +#endif + +static char *read_from_shell_command(char *result, size_t sizeof_result, const char *command) +{ + FILE *fp; + char *pnt; + + if ((fp = popen(command, "r")) == NULL) { + return NULL; + } + if (fgets(result, (int) sizeof_result, fp) == NULL) { + pclose(fp); + fprintf(stderr, "Command [%s] failed]\n", command); + return NULL; + } + if ((pnt = strrchr(result, '\n')) != NULL) { + *pnt = 0; + } + (void) pclose(fp); + + return *result == 0 ? NULL : result; +} + +const char *get_default_gw_ip(void) +{ + static char gw[64]; +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || \ + defined(__DragonFly__) || defined(__NetBSD__) + return read_from_shell_command( + gw, sizeof gw, "route -n get default 2>/dev/null|awk '/gateway:/{print $2;exit}'"); +#elif defined(__linux__) + return read_from_shell_command(gw, sizeof gw, + "ip route show default 2>/dev/null|awk '/default/{print $3}'"); //gw.bat mame pre windows pripraveny bat len ho spustit a presmerovat vystup pripadne overit ci popen ide aj na win +#else + return NULL; +#endif +} + +const char *get_default_ext_if_name(void) +{ + static char if_name[64]; +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || \ + defined(__DragonFly__) || defined(__NetBSD__) + return read_from_shell_command(if_name, sizeof if_name, + "route -n get default 2>/dev/null|awk " + "'/interface:/{print $2;exit}'"); +#elif defined(__linux__) + return read_from_shell_command(if_name, sizeof if_name, + "ip route show default 2>/dev/null|awk '/default/{print $5}'"); //route print 0* --> a vybrat ip intf +#else //Get-NetConnectionProfile in PS + return NULL; +#endif +} + +int tcp_opts(int fd) +{ + int on = 1; + + (void) setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char *) &on, sizeof on); +#ifdef TCP_QUICKACK + (void) setsockopt(fd, IPPROTO_TCP, TCP_QUICKACK, (char *) &on, sizeof on); +#else + (void) setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *) &on, sizeof on); +#endif +#ifdef TCP_CONGESTION + (void) setsockopt(fd, IPPROTO_TCP, TCP_CONGESTION, OUTER_CONGESTION_CONTROL_ALG, + sizeof OUTER_CONGESTION_CONTROL_ALG - 1); +#endif +#if BUFFERBLOAT_CONTROL && defined(TCP_NOTSENT_LOWAT) + (void) setsockopt(fd, IPPROTO_TCP, TCP_NOTSENT_LOWAT, + (char *) (unsigned int[]){ NOTSENT_LOWAT }, sizeof(unsigned int)); +#endif +#ifdef TCP_USER_TIMEOUT + (void) setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, (char *) (unsigned int[]){ TIMEOUT }, + sizeof(unsigned int)); +#endif +#ifdef SO_MARK + (void) setsockopt(fd, SOL_SOCKET, SO_MARK, (char *) (unsigned int[]){ 42069U }, + sizeof(unsigned int)); +#endif + return 0; +} + +int shell_cmd(const char *substs[][2], const char *args_str, int silent) +{ + char * args[64]; + char cmdbuf[4096]; + pid_t child; + size_t args_i = 0, cmdbuf_i = 0, args_str_i, i; + int c, exit_status, is_space = 1; + + errno = ENOSPC; + for (args_str_i = 0; (c = args_str[args_str_i]) != 0; args_str_i++) { + if (isspace((unsigned char) c)) { + if (!is_space) { + if (cmdbuf_i >= sizeof cmdbuf) { + return -1; + } + cmdbuf[cmdbuf_i++] = 0; + } + is_space = 1; + continue; + } + if (is_space) { + if (args_i >= sizeof args / sizeof args[0]) { + return -1; + } + args[args_i++] = &cmdbuf[cmdbuf_i]; + } + is_space = 0; + for (i = 0; substs[i][0] != NULL; i++) { + size_t pat_len = strlen(substs[i][0]), sub_len; + if (!strncmp(substs[i][0], &args_str[args_str_i], pat_len)) { + sub_len = strlen(substs[i][1]); + if (sizeof cmdbuf - cmdbuf_i <= sub_len) { + return -1; + } + memcpy(&cmdbuf[cmdbuf_i], substs[i][1], sub_len); + args_str_i += pat_len - 1; + cmdbuf_i += sub_len; + break; + } + } + if (substs[i][0] == NULL) { + if (cmdbuf_i >= sizeof cmdbuf) { + return -1; + } + cmdbuf[cmdbuf_i++] = c; + } + } + if (!is_space) { + if (cmdbuf_i >= sizeof cmdbuf) { + return -1; + } + cmdbuf[cmdbuf_i++] = 0; + } + if (args_i >= sizeof args / sizeof args[0] || args_i == 0) { + return -1; + } + args[args_i] = NULL; + if ((child = fork()) == (pid_t) -1) { + return -1; + } else if (child == (pid_t) 0) { + if (silent) { + dup2(dup2(open("/dev/null", O_WRONLY), 2), 1); + } + execvp(args[0], args); + _exit(1); + } else if (waitpid(child, &exit_status, 0) == (pid_t) -1 || !WIFEXITED(exit_status)) { + return -1; + } + return 0; +} + +Cmds firewall_rules_cmds(int is_server) +{ + if (is_server) { +#ifdef __linux__ + static const char + *set_cmds[] = + { "sysctl net.ipv4.ip_forward=1", + "ip addr add $LOCAL_TUN_IP peer $REMOTE_TUN_IP dev $IF_NAME", + "ip -6 addr add $LOCAL_TUN_IP6 peer $REMOTE_TUN_IP6/96 dev $IF_NAME", + "ip link set dev $IF_NAME up", + "iptables -t raw -I PREROUTING ! -i $IF_NAME -d $LOCAL_TUN_IP -m addrtype ! " + "--src-type LOCAL -j DROP", + "iptables -t nat -A POSTROUTING -o $EXT_IF_NAME -s $REMOTE_TUN_IP -j MASQUERADE", + "iptables -t filter -A FORWARD -i $EXT_IF_NAME -o $IF_NAME -m state --state " + "RELATED,ESTABLISHED -j ACCEPT", + "iptables -t filter -A FORWARD -i $IF_NAME -o $EXT_IF_NAME -j ACCEPT", + NULL }, + *unset_cmds[] = { + "iptables -t nat -D POSTROUTING -o $EXT_IF_NAME -s $REMOTE_TUN_IP -j MASQUERADE", + "iptables -t filter -D FORWARD -i $EXT_IF_NAME -o $IF_NAME -m state --state " + "RELATED,ESTABLISHED -j ACCEPT", + "iptables -t filter -D FORWARD -i $IF_NAME -o $EXT_IF_NAME -j ACCEPT", + "iptables -t raw -D PREROUTING ! -i $IF_NAME -d $LOCAL_TUN_IP -m addrtype ! " + "--src-type LOCAL -j DROP", + NULL + }; +#elif defined(__APPLE__) || defined(__OpenBSD__) || defined(__FreeBSD__) || \ + defined(__DragonFly__) || defined(__NetBSD__) + static const char *set_cmds[] = + { "sysctl -w net.inet.ip.forwarding=1", + "ifconfig $IF_NAME $LOCAL_TUN_IP $REMOTE_TUN_IP up", + "ifconfig $IF_NAME inet6 $LOCAL_TUN_IP6 $REMOTE_TUN_IP6 prefixlen 128 up", NULL }, + *unset_cmds[] = { NULL, NULL }; +#else + static const char *const *set_cmds = NULL, *const *unset_cmds = NULL; +#endif + return (Cmds){ set_cmds, unset_cmds }; + } else { +#if defined(__APPLE__) || defined(__OpenBSD__) || defined(__FreeBSD__) || \ + defined(__DragonFly__) || defined(__NetBSD__) + static const char *set_cmds[] = + { "ifconfig $IF_NAME $LOCAL_TUN_IP $REMOTE_TUN_IP up", + "ifconfig $IF_NAME inet6 $LOCAL_TUN_IP6 $REMOTE_TUN_IP6 prefixlen 128 up", +#ifndef NO_DEFAULT_ROUTES + "route add $EXT_IP $EXT_GW_IP", + "route add 0/1 $REMOTE_TUN_IP", + "route add 128/1 $REMOTE_TUN_IP", + "route add -inet6 -blackhole 0000::/1 $REMOTE_TUN_IP6", + "route add -inet6 -blackhole 8000::/1 $REMOTE_TUN_IP6", +#endif + NULL }, + *unset_cmds[] = { +#ifndef NO_DEFAULT_ROUTES + "route delete $EXT_IP", + "route delete 0/1", + "route delete 128/1", + "route delete -inet6 0000::/1", + "route delete -inet6 8000::/1", +#endif + NULL + }; +#elif defined(__linux__) + static const char + *set_cmds[] = + { "sysctl net.ipv4.tcp_congestion_control=bbr", + "ip link set dev $IF_NAME up", + "iptables -t raw -I PREROUTING ! -i $IF_NAME -d $LOCAL_TUN_IP -m addrtype ! " + "--src-type LOCAL -j DROP", + "ip addr add $LOCAL_TUN_IP peer $REMOTE_TUN_IP dev $IF_NAME", + "ip -6 addr add $LOCAL_TUN_IP6 peer $REMOTE_TUN_IP6/96 dev $IF_NAME", +#ifndef NO_DEFAULT_ROUTES + "ip route add default dev $IF_NAME table 42069", + "ip -6 route add default dev $IF_NAME table 42069", + "ip rule add not fwmark 42069 table 42069", + "ip -6 rule add not fwmark 42069 table 42069", + "ip rule add table main suppress_prefixlength 0", + "ip -6 rule add table main suppress_prefixlength 0", +#endif + NULL }, + *unset_cmds[] = { +#ifndef NO_DEFAULT_ROUTES + "ip rule delete table 42069", + "ip -6 rule delete table 42069", + "ip rule delete table main suppress_prefixlength 0", + "ip -6 rule delete table main suppress_prefixlength 0", +#endif + "iptables -t raw -D PREROUTING ! -i $IF_NAME -d $LOCAL_TUN_IP -m addrtype ! " + "--src-type LOCAL -j DROP", + NULL + }; +#else + static const char *const *set_cmds = NULL, *const *unset_cmds = NULL; +#endif + return (Cmds){ set_cmds, unset_cmds }; + } +} diff --git a/dsvpn-master/src/vpn.c b/dsvpn-master/src/vpn.c new file mode 100644 index 0000000..c9ae711 --- /dev/null +++ b/dsvpn-master/src/vpn.c @@ -0,0 +1,640 @@ +#include "vpn.h" +#include "charm.h" +#include "os.h" + +static const int POLLFD_TUN = 0, POLLFD_LISTENER = 1, POLLFD_CLIENT = 2, POLLFD_COUNT = 3; + +typedef struct __attribute__((aligned(16))) Buf_ { +#if TAG_LEN < 16 - 2 + unsigned char _pad[16 - TAG_LEN - 2]; +#endif + unsigned char len[2]; + unsigned char tag[TAG_LEN]; + unsigned char data[MAX_PACKET_LEN]; + size_t pos; +} Buf; + +typedef struct Context_ { + const char * wanted_if_name; + const char * local_tun_ip; + const char * remote_tun_ip; + const char * local_tun_ip6; + const char * remote_tun_ip6; + const char * server_ip_or_name; + const char * server_port; + const char * ext_if_name; + const char * wanted_ext_gw_ip; + char client_ip[NI_MAXHOST]; + char ext_gw_ip[64]; + char server_ip[64]; + char if_name[IFNAMSIZ]; + int is_server; + int tun_fd; + int client_fd; + int listen_fd; + int congestion; + int firewall_rules_set; + Buf client_buf; + struct pollfd fds[3]; + uint32_t uc_kx_st[12]; + uint32_t uc_st[2][12]; +} Context; + +volatile sig_atomic_t exit_signal_received; + +static void signal_handler(int sig) +{ + signal(sig, SIG_DFL); + exit_signal_received = 1; +} + +static int firewall_rules(Context *context, int set, int silent) +{ + const char * substs[][2] = { { "$LOCAL_TUN_IP6", context->local_tun_ip6 }, + { "$REMOTE_TUN_IP6", context->remote_tun_ip6 }, + { "$LOCAL_TUN_IP", context->local_tun_ip }, + { "$REMOTE_TUN_IP", context->remote_tun_ip }, + { "$EXT_IP", context->server_ip }, + { "$EXT_PORT", context->server_port }, + { "$EXT_IF_NAME", context->ext_if_name }, + { "$EXT_GW_IP", context->ext_gw_ip }, + { "$IF_NAME", context->if_name }, + { NULL, NULL } }; + const char *const *cmds; + size_t i; + + if (context->firewall_rules_set == set) { + return 0; + } + if ((cmds = (set ? firewall_rules_cmds(context->is_server).set + : firewall_rules_cmds(context->is_server).unset)) == NULL) { + fprintf(stderr, + "Routing commands for that operating system have not been " + "added yet.\n"); + return 0; + } + for (i = 0; cmds[i] != NULL; i++) { + if (shell_cmd(substs, cmds[i], silent) != 0) { + fprintf(stderr, "Unable to run [%s]: [%s]\n", cmds[i], strerror(errno)); + return -1; + } + } + context->firewall_rules_set = set; + return 0; +} + +static int tcp_client(const char *address, const char *port) +{ + struct addrinfo hints, *res; + int eai; + int client_fd; + int err; + + printf("Connecting to %s:%s...\n", address, port); + memset(&hints, 0, sizeof hints); + hints.ai_flags = 0; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_addr = NULL; + if ((eai = getaddrinfo(address, port, &hints, &res)) != 0 || + (res->ai_family != AF_INET && res->ai_family != AF_INET6)) { + fprintf(stderr, "Unable to create the client socket: [%s]\n", gai_strerror(eai)); + errno = EINVAL; + return -1; + } + if ((client_fd = socket(res->ai_family, SOCK_STREAM, IPPROTO_TCP)) == -1 || + tcp_opts(client_fd) != 0 || + connect(client_fd, (const struct sockaddr *) res->ai_addr, res->ai_addrlen) != 0) { + freeaddrinfo(res); + err = errno; + (void) close(client_fd); + errno = err; + return -1; + } + freeaddrinfo(res); + return client_fd; +} + +static int tcp_listener(const char *address, const char *port) +{ + struct addrinfo hints, *res; + int eai, err; + int listen_fd; + int backlog = 1; + + memset(&hints, 0, sizeof hints); + hints.ai_flags = AI_PASSIVE; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_addr = NULL; +#if defined(__OpenBSD__) || defined(__DragonFly__) + if (address == NULL) { + hints.ai_family = AF_INET; + } +#endif +// zapise info o addrese do res deskriptora a nasledne sa ide vytvorit soket na zaklade informacii + if ((eai = getaddrinfo(address, port, &hints, &res)) != 0 || + (res->ai_family != AF_INET && res->ai_family != AF_INET6)) { + fprintf(stderr, "Unable to create the listening socket: [%s]\n", gai_strerror(eai)); + errno = EINVAL; + return -1; + } + //tcp_socket = socket(AF_INET, SOCK_STREAM, 0); --> nastavenie na tcp socket + //https://www.ibm.com/docs/pl/aix/7.1?topic=protocols-socket-types + if ((listen_fd = socket(res->ai_family, SOCK_STREAM, IPPROTO_TCP)) == -1 || + setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, (char *) (int[]){ 1 }, sizeof(int)) != 0) { + //^--povoli opätovné použitie lokálnych adries pre tento soket. Ak povolíte túto možnosť, v skutočnosti môžete mať dva sokety s rovnakým číslom internetového portu; + // ale systém vám nedovolí použiť dva identicky pomenované sokety spôsobom, ktorý by zmiatol internet. + // Dôvodom tejto možnosti je, že niektoré internetové protokoly vyššej úrovne vrátane FTP vyžadujú, aby ste stále používali rovnaké číslo portu. + err = errno; + (void) close(listen_fd); + freeaddrinfo(res); + errno = err; + return -1; + } +#if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) + (void) setsockopt(listen_fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *) (int[]){ 0 }, sizeof(int)); +#endif +#ifdef TCP_DEFER_ACCEPT + (void) setsockopt(listen_fd, SOL_TCP, TCP_DEFER_ACCEPT, + (char *) (int[]){ ACCEPT_TIMEOUT / 1000 }, sizeof(int)); +#endif + printf("Listening to %s:%s\n", address == NULL ? "*" : address, port); + if (bind(listen_fd, (struct sockaddr *) res->ai_addr, (socklen_t) res->ai_addrlen) != 0 || + listen(listen_fd, backlog) != 0) { + freeaddrinfo(res); + return -1; + } + freeaddrinfo(res); + + return listen_fd; +} + +static void client_disconnect(Context *context) +{ + if (context->client_fd == -1) { + return; + } + (void) close(context->client_fd); + context->client_fd = -1; + context->fds[POLLFD_CLIENT] = (struct pollfd){ .fd = -1, .events = 0 }; + memset(context->uc_st, 0, sizeof context->uc_st); +} + +static int server_key_exchange(Context *context, const int client_fd) +{ + uint32_t st[12]; + uint8_t pkt1[32 + 8 + 32], pkt2[32 + 32]; + uint8_t h[32]; + uint8_t k[32]; + uint8_t iv[16] = { 0 }; + uint64_t ts, now; + + memcpy(st, context->uc_kx_st, sizeof st); + errno = EACCES; + if (safe_read(client_fd, pkt1, sizeof pkt1, ACCEPT_TIMEOUT) != sizeof pkt1) { + return -1; + } + uc_hash(st, h, pkt1, 32 + 8); + if (memcmp(h, pkt1 + 32 + 8, 32) != 0) { + return -1; + } + memcpy(&ts, pkt1 + 32, 8); + ts = endian_swap64(ts); + now = time(NULL); + if ((ts > now && ts - now > TS_TOLERANCE) || (now > ts && now - ts > TS_TOLERANCE)) { + fprintf(stderr, + "Clock difference is too large: %" PRIu64 " (client) vs %" PRIu64 " (server)\n", ts, + now); + return -1; + } + uc_randombytes_buf(pkt2, 32); + uc_hash(st, pkt2 + 32, pkt2, 32); + if (safe_write_partial(client_fd, pkt2, sizeof pkt2) != sizeof pkt2) { + return -1; + } + uc_hash(st, k, NULL, 0); + iv[0] = context->is_server; + uc_state_init(context->uc_st[0], k, iv); + iv[0] ^= 1; + uc_state_init(context->uc_st[1], k, iv); + + return 0; +} + +static int tcp_accept(Context *context, int listen_fd) +{ + char client_ip[NI_MAXHOST] = { 0 }; + struct sockaddr_storage client_ss; + socklen_t client_ss_len = sizeof client_ss; + int client_fd; + int err; + + if ((client_fd = accept(listen_fd, (struct sockaddr *) &client_ss, &client_ss_len)) < 0) { + return -1; + } + if (client_ss_len <= (socklen_t) 0U) { + (void) close(client_fd); + errno = EINTR; + return -1; + } + if (tcp_opts(client_fd) != 0) { + err = errno; + (void) close(client_fd); + errno = err; + return -1; + } + getnameinfo((const struct sockaddr *) (const void *) &client_ss, client_ss_len, client_ip, + sizeof client_ip, NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV); + printf("Connection attempt from [%s]\n", client_ip); + context->congestion = 0; + fcntl(client_fd, F_SETFL, fcntl(client_fd, F_GETFL, 0) | O_NONBLOCK); + if (context->client_fd != -1 && + memcmp(context->client_ip, client_ip, sizeof context->client_ip) != 0) { + fprintf(stderr, "Closing: a session from [%s] is already active\n", context->client_ip); + (void) close(client_fd); + errno = EBUSY; + return -1; + } + if (server_key_exchange(context, client_fd) != 0) { + fprintf(stderr, "Authentication failed\n"); + (void) close(client_fd); + errno = EACCES; + return -1; + } + memcpy(context->client_ip, client_ip, sizeof context->client_ip); + return client_fd; +} + +static int client_key_exchange(Context *context) +{ + uint32_t st[12]; + uint8_t pkt1[32 + 8 + 32], pkt2[32 + 32]; + uint8_t h[32]; + uint8_t k[32]; + uint8_t iv[16] = { 0 }; + uint64_t now; + + memcpy(st, context->uc_kx_st, sizeof st); + uc_randombytes_buf(pkt1, 32); + now = endian_swap64(time(NULL)); + memcpy(pkt1 + 32, &now, 8); + uc_hash(st, pkt1 + 32 + 8, pkt1, 32 + 8); + if (safe_write(context->client_fd, pkt1, sizeof pkt1, TIMEOUT) != sizeof pkt1) { + return -1; + } + errno = EACCES; + if (safe_read(context->client_fd, pkt2, sizeof pkt2, TIMEOUT) != sizeof pkt2) { + return -1; + } + uc_hash(st, h, pkt2, 32); + if (memcmp(h, pkt2 + 32, 32) != 0) { + return -1; + } + uc_hash(st, k, NULL, 0); + iv[0] = context->is_server; + uc_state_init(context->uc_st[0], k, iv); + iv[0] ^= 1; + uc_state_init(context->uc_st[1], k, iv); + + return 0; +} + +static int client_connect(Context *context) +{ + const char *ext_gw_ip; + + context->client_buf.pos = 0; + memset(context->client_buf.data, 0, sizeof context->client_buf.data); + if (context->wanted_ext_gw_ip == NULL && (ext_gw_ip = get_default_gw_ip()) != NULL && + strcmp(ext_gw_ip, context->ext_gw_ip) != 0) { + printf("Gateway changed from [%s] to [%s]\n", context->ext_gw_ip, ext_gw_ip); + firewall_rules(context, 0, 0); + snprintf(context->ext_gw_ip, sizeof context->ext_gw_ip, "%s", ext_gw_ip); + firewall_rules(context, 1, 0); + } + memset(context->uc_st, 0, sizeof context->uc_st); + context->uc_st[context->is_server][0] ^= 1; + context->client_fd = tcp_client(context->server_ip, context->server_port); + if (context->client_fd == -1) { + perror("Client connection failed"); + return -1; + } + fcntl(context->client_fd, F_SETFL, fcntl(context->client_fd, F_GETFL, 0) | O_NONBLOCK); + context->congestion = 0; + if (client_key_exchange(context) != 0) { + fprintf(stderr, "Authentication failed\n"); + client_disconnect(context); + sleep(1); + return -1; + } + firewall_rules(context, 1, 0); + context->fds[POLLFD_CLIENT] = + (struct pollfd){ .fd = context->client_fd, .events = POLLIN, .revents = 0 }; + puts("Connected"); + + return 0; +} + +static int client_reconnect(Context *context) +{ + unsigned int i; + + client_disconnect(context); + if (context->is_server) { + return 0; + } + for (i = 0; exit_signal_received == 0 && i < RECONNECT_ATTEMPTS; i++) { + puts("Trying to reconnect"); + sleep(i > 3 ? 3 : i); + if (client_connect(context) == 0) { + return 0; + } + } + return -1; +} + +static int event_loop(Context *context) +{ + struct pollfd *const fds = context->fds; + Buf tun_buf; + Buf * client_buf = &context->client_buf; + ssize_t len; + int found_fds; + int new_client_fd; + + if (exit_signal_received != 0) { + return -2; + } + if ((found_fds = poll(fds, POLLFD_COUNT, 1500)) == -1) { + return errno == EINTR ? 0 : -1; + } + if (fds[POLLFD_LISTENER].revents & POLLIN) { + new_client_fd = tcp_accept(context, context->listen_fd); //prijatie noveho klienta + if (new_client_fd == -1) { + perror("Accepting a new client failed"); + return 0; + } + if (context->client_fd != -1) { //ukoncenie stareho klienta + (void) close(context->client_fd); + sleep(1); + } + context->client_fd = new_client_fd; + client_buf->pos = 0; + memset(client_buf->data, 0, sizeof client_buf->data); + puts("Session established"); + fds[POLLFD_CLIENT] = (struct pollfd){ .fd = context->client_fd, .events = POLLIN }; + } + if ((fds[POLLFD_TUN].revents & POLLERR) || (fds[POLLFD_TUN].revents & POLLHUP)) { + puts("HUP (tun)"); + return -1; + } + if (fds[POLLFD_TUN].revents & POLLIN) { + len = tun_read(context->tun_fd, tun_buf.data, sizeof tun_buf.data); + if (len <= 0) { + perror("tun_read"); + return -1; + } +#ifdef BUFFERBLOAT_CONTROL + if (context->congestion) { + context->congestion = 0; + return 0; + } +#endif + if (context->client_fd != -1) { + unsigned char tag_full[16]; + ssize_t writenb; + uint16_t binlen = endian_swap16((uint16_t) len); + + memcpy(tun_buf.len, &binlen, 2); + uc_encrypt(context->uc_st[0], tun_buf.data, len, tag_full); + memcpy(tun_buf.tag, tag_full, TAG_LEN); + writenb = safe_write_partial(context->client_fd, tun_buf.len, 2U + TAG_LEN + len); //zapis zasifrovanych dat z buffra do forwardingu clienta + if (writenb < (ssize_t) 0) { + context->congestion = 1; + writenb = (ssize_t) 0; + } + if (writenb != (ssize_t)(2U + TAG_LEN + len)) { + writenb = safe_write(context->client_fd, tun_buf.len + writenb, + 2U + TAG_LEN + len - writenb, TIMEOUT); + } + if (writenb < (ssize_t) 0) { + perror("Unable to write data to the TCP socket"); + return client_reconnect(context); + } + } + } + if ((fds[POLLFD_CLIENT].revents & POLLERR) || (fds[POLLFD_CLIENT].revents & POLLHUP)) { + puts("Client disconnected"); + return client_reconnect(context); + } + if (fds[POLLFD_CLIENT].revents & POLLIN) { + uint16_t binlen; + size_t len_with_header; + ssize_t readnb; + + if ((readnb = safe_read_partial(context->client_fd, client_buf->len + client_buf->pos, + 2 + TAG_LEN + MAX_PACKET_LEN - client_buf->pos)) <= 0) { + puts("Client disconnected"); + return client_reconnect(context); + } + client_buf->pos += readnb; + while (client_buf->pos >= 2 + TAG_LEN) { + memcpy(&binlen, client_buf->len, 2); + len = (ssize_t) endian_swap16(binlen); + if (client_buf->pos < (len_with_header = 2 + TAG_LEN + (size_t) len)) { + break; + } + if (uc_decrypt(context->uc_st[1], client_buf->data, len, client_buf->tag, TAG_LEN) != + 0) { + fprintf(stderr, "Corrupted stream\n"); + sleep(1); + return client_reconnect(context); + } + if (tun_write(context->tun_fd, client_buf->data, len) != len) { + perror("tun_write"); + } + if (2 + TAG_LEN + MAX_PACKET_LEN != len_with_header) { + unsigned char *rbuf = client_buf->len; + size_t remaining = client_buf->pos - len_with_header, i; + for (i = 0; i < remaining; i++) { + rbuf[i] = rbuf[len_with_header + i]; + } + } + client_buf->pos -= len_with_header; + } + } + return 0; +} + +static int doit(Context *context) +{ + context->client_fd = context->listen_fd = -1; + memset(context->fds, 0, sizeof *context->fds); + context->fds[POLLFD_TUN] = + (struct pollfd){ .fd = context->tun_fd, .events = POLLIN, .revents = 0 }; + if (context->is_server) { + //vytvorenie tcp soketu aj s postupom podla ibm + if ((context->listen_fd = tcp_listener(context->server_ip_or_name, context->server_port)) == + -1) { + perror("Unable to set up a TCP server"); + return -1; + } + context->fds[POLLFD_LISTENER] = (struct pollfd){ + .fd = context->listen_fd, + .events = POLLIN, + }; + } + if (!context->is_server && client_reconnect(context) != 0) { + fprintf(stderr, "Unable to connect to server: [%s]\n", strerror(errno)); + return -1; + } + while (event_loop(context) == 0) + ; + return 0; +} + +static int load_key_file(Context *context, const char *file) +{ + unsigned char key[32]; + int fd; + + if ((fd = open(file, O_RDONLY)) == -1) { + return -1; + } + if (safe_read(fd, key, sizeof key, -1) != sizeof key) { + (void) close(fd); + return -1; + } + uc_state_init(context->uc_kx_st, key, (const unsigned char *) "VPN Key Exchange"); + uc_memzero(key, sizeof key); + + return close(fd); +} + +__attribute__((noreturn)) static void usage(void) +{ + puts("DSVPN " VERSION_STRING + " usage:\n" + "\n" + "dsvpn\t\"server\"\n\t\n\t|\"auto\"\n\t|\"auto\"\n\t|\"auto\"\n\t|\"auto\"\n\t\"auto\"\n\t|\"auto\"" + "\n\n" + "dsvpn\t\"client\"\n\t\n\t\n\t|\"auto\"\n\t|\"auto\"\n\t|\"auto\"\n\t|\"auto\"\n\t|\"auto\"\n\n" + "Example:\n\n[server]\n\tdd if=/dev/urandom of=vpn.key count=1 bs=32\t# create key\n" + "\tbase64 < vpn.key\t\t# copy key as a string\n\tsudo ./dsvpn server vpn.key\t# listen on " + "443\n\n[client]\n\techo ohKD...W4= | base64 --decode > vpn.key\t# paste key\n" + "\tsudo ./dsvpn client vpn.key 34.216.127.34\n"); + exit(254); +} + +static void get_tun6_addresses(Context *context) +{ + static char local_tun_ip6[40], remote_tun_ip6[40]; + + snprintf(local_tun_ip6, sizeof local_tun_ip6, "64:ff9b::%s", context->local_tun_ip); + snprintf(remote_tun_ip6, sizeof remote_tun_ip6, "64:ff9b::%s", context->remote_tun_ip); + context->local_tun_ip6 = local_tun_ip6; + context->remote_tun_ip6 = remote_tun_ip6; +} + +static int resolve_ip(char *ip, size_t sizeof_ip, const char *ip_or_name) +{ + struct addrinfo hints, *res; + int eai; + + memset(&hints, 0, sizeof hints); + hints.ai_flags = 0; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_addr = NULL; + if ((eai = getaddrinfo(ip_or_name, NULL, &hints, &res)) != 0 || + (res->ai_family != AF_INET && res->ai_family != AF_INET6) || + (eai = getnameinfo(res->ai_addr, res->ai_addrlen, ip, (socklen_t) sizeof_ip, NULL, 0, + NI_NUMERICHOST | NI_NUMERICSERV)) != 0) { + fprintf(stderr, "Unable to resolve [%s]: [%s]\n", ip_or_name, gai_strerror(eai)); + return -1; + } + return 0; +} + +int main(int argc, char *argv[]) +{ + Context context; + const char *ext_gw_ip; + + if (argc < 3) { + usage(); + } + memset(&context, 0, sizeof context); + context.is_server = strcmp(argv[1], "server") == 0; //strcmp ak == tak vrati 0 + if (load_key_file(&context, argv[2]) != 0) { // nacitanie zdielaneho kluca + fprintf(stderr, "Unable to load the key file [%s]\n", argv[2]); + return 1; + } + context.server_ip_or_name = (argc <= 3 || strcmp(argv[3], "auto") == 0) ? NULL : argv[3]; + if (context.server_ip_or_name == NULL && !context.is_server) { + usage(); + } + context.server_port = (argc <= 4 || strcmp(argv[4], "auto") == 0) ? DEFAULT_PORT : argv[4]; + context.wanted_if_name = (argc <= 5 || strcmp(argv[5], "auto") == 0) ? NULL : argv[5]; + context.local_tun_ip = (argc <= 6 || strcmp(argv[6], "auto") == 0) + ? (context.is_server ? DEFAULT_SERVER_IP : DEFAULT_CLIENT_IP) + : argv[6]; + context.remote_tun_ip = (argc <= 7 || strcmp(argv[7], "auto") == 0) + ? (context.is_server ? DEFAULT_CLIENT_IP : DEFAULT_SERVER_IP) + : argv[7]; + context.wanted_ext_gw_ip = (argc <= 8 || strcmp(argv[8], "auto") == 0) ? NULL : argv[8]; + ext_gw_ip = context.wanted_ext_gw_ip ? context.wanted_ext_gw_ip : get_default_gw_ip(); + snprintf(context.ext_gw_ip, sizeof context.ext_gw_ip, "%s", ext_gw_ip == NULL ? "" : ext_gw_ip); //zapis gw do struktury + if (ext_gw_ip == NULL && !context.is_server) { //check of params + fprintf(stderr, "Unable to automatically determine the gateway IP\n"); + return 1; + } + if ((context.ext_if_name = get_default_ext_if_name()) == NULL && context.is_server) { + fprintf(stderr, "Unable to automatically determine the external interface\n"); + return 1; + } + get_tun6_addresses(&context); // priradenie ipv6 adries + context.tun_fd = tun_create(context.if_name, context.wanted_if_name); + if (context.tun_fd == -1) { + perror("tun device creation"); + return 1; + } + printf("Interface: [%s]\n", context.if_name); + if (tun_set_mtu(context.if_name, DEFAULT_MTU) != 0) { + perror("mtu"); + } +#ifdef __OpenBSD__ + pledge("stdio proc exec dns inet", NULL); +#endif + context.firewall_rules_set = -1; + if (context.server_ip_or_name != NULL && + resolve_ip(context.server_ip, sizeof context.server_ip, context.server_ip_or_name) != 0) { + firewall_rules(&context, 0, 1); + return 1; + } + if (context.is_server) { + if (firewall_rules(&context, 1, 0) != 0) { + return -1; + } +#ifdef __OpenBSD__ + printf("\nAdd the following rule to /etc/pf.conf:\npass out from %s nat-to egress\n\n", + context.remote_tun_ip); +#endif + } else { + firewall_rules(&context, 0, 1); + } + signal(SIGINT, signal_handler); + signal(SIGTERM, signal_handler); + if (doit(&context) != 0) { + return -1; + } + firewall_rules(&context, 0, 0); + puts("Done."); + + return 0; +} diff --git a/linu_networking.zip b/linu_networking.zip new file mode 100644 index 0000000..6f87857 Binary files /dev/null and b/linu_networking.zip differ diff --git a/templates/.gitignore b/templates/.gitignore new file mode 100644 index 0000000..07904fb --- /dev/null +++ b/templates/.gitignore @@ -0,0 +1,26 @@ +_minted* + +*.acn +*.acr +*.alg +*.aux +*.bbl +*.bcf +*.blg +*.fdb_latexmk +*.fls +*.glsdefs +*.ist +*.lof +*.log +*.lol +*.lot +*.out +*.run.xml +*.synctex.gz +*.toc +*.glg +*.glo +*.gls + + diff --git a/templates/README.md b/templates/README.md new file mode 100644 index 0000000..93aba9b --- /dev/null +++ b/templates/README.md @@ -0,0 +1,47 @@ +# About + +Šablóna bola prebraná od _KPI FEI TUKE_. + +Pozor! Kódovanie všetkých dokumentov je nastavené na _UTF-8_! Nezabudnite si preto nastaviť aj svoje prostredie, v ktorom budete záverečnú prácu písať tak, aby toto kódovanie používalo! + + + +## Compilation + +Dokument vytvoríte napísaním nasledovného príkazu z príkazového riadku: + +```bash +compile_template.bat +``` + +Spustením tohto príkazu dôjde k vytvoreniu výsledného dokumentu vo formáte _PDF_. + +Projekt si samozrejme môžete otvoriť v ktoromkoľvek _LaTeX_ editore alebo IDE, ako je napr. _TeX Studio_ + +## Source codes & programs + +Všetky zdrojové kódy a odladené programy sú dostupné v priečinku: + + appendixes --> BC_ZK + +Viac informácií je možné násť v tomto priečinku alebo v bakalárskej práci (Obsah Prílohy A). + +# Author +Organization: Technical University of Kosice (TUKE), + +Department: Department of Electronics and Multimedia Telecommunications (DEMT/KEMT), + +Faculties: Faculty of Electrical Engineering and Informatics (FEI), + +Feld of study: Informatics, + +Study program: Computer Networks, + +School year: 3., Bachelor study, 2020/2021, + +Author: Marek Rohac -- MR, + +Kontakt: marek.rohac@student.tuke.sk + marroh004@gmail.com + +ALL RIGHTS RESERVED. diff --git a/templates/acronyms.tex b/templates/acronyms.tex new file mode 100644 index 0000000..c7556f9 --- /dev/null +++ b/templates/acronyms.tex @@ -0,0 +1,49 @@ +% Acronyms +% ======== +% +% An acronym is a word formed from the initial letters in a phrase. +% +% Acronym Definition Exapmle: +% --------------------------- +% \newacronym{gcd}{GCD}{Greatest Common Divisor} +% \newacronym{dry}{DRY}{Don't Repeat Yourself} +% +% Usage: +% ------ +% You can use these three options: +% +% \acrlong{} +% Displays the phrase which the acronyms stands for. Put the label of the acronym inside the braces. In the example, \acrlong{gcd} prints Greatest Common Divisor. +% +% \acrshort{} +% Prints the acronym whose label is passed as parameter. For instance, \acrshort{gcd} renders as GCD. +% +% \acrfull{ } +% Prints both, the acronym and its definition. In the example the output of \acrfull{dry} is Don't Repeat Yourself (DRY). +% +% For more information see: +% ------------------------- +% * https://www.sharelatex.com/learn/Glossaries +% * https://en.wikibooks.org/wiki/LaTeX/Glossary +% + + +\newacronym{vpn}{VPN}{Virtual Private Network} +\newacronym{vm}{VM}{Virtual Machine} +\newacronym{vb}{VB}{Virtual Box} +\newacronym{lts}{LTS}{Long Term Support} +\newacronym{os}{OS}{Operating System} +\newacronym{tcp}{TCP}{Transmission Control Protocol} +\newacronym{oss}{OSS}{Operating System Server} +\newacronym{osc}{OSC}{Operating System Client} +\newacronym{ip}{IP}{Internet Protocol} +\newacronym{ftp}{FTP}{File Transfer Protocol} +\newacronym{tls}{TLS}{Transport Layer Security} +\newacronym{ssl}{SSL}{Secure Socket Layers} +\newacronym{gw}{GW}{GateWay} +\newacronym{fw}{FW}{FireWall} +\newacronym{pdv}{PDV}{Packet Delay Variation} +\newacronym{aes}{AES}{Advanced Encryption Standard} +\newacronym{fskd}{FSKD}{Full-State Keyed Duplex} +\newacronym{}{}{} + diff --git a/templates/appendixes/prilohaa.tex b/templates/appendixes/prilohaa.tex new file mode 100644 index 0000000..612203f --- /dev/null +++ b/templates/appendixes/prilohaa.tex @@ -0,0 +1,10 @@ +% !TEX root = ../thesis.tex + +\chapter{Obsah CD Média} + +Obsah tohto média je dostupný na gite: +\begin{itemize} + \item \url{https://github.com/mr171hg/DiplomaProject} +\end{itemize} + +Pouzite obrazy, zdrojove kody... \ No newline at end of file diff --git a/templates/appendixes/prilohy.tex b/templates/appendixes/prilohy.tex new file mode 100644 index 0000000..89cb937 --- /dev/null +++ b/templates/appendixes/prilohy.tex @@ -0,0 +1,9 @@ +% !TEX root = ../thesis.tex + +\chapter*{Zoznam príloh} +\addcontentsline{toc}{chapter}{Zoznam príloh} + +\begin{description} + \item[Príloha A] CD médium -- viď. obsah CD média +\end{description} + diff --git a/templates/chapters/analysis.tex b/templates/chapters/analysis.tex new file mode 100644 index 0000000..82d778c --- /dev/null +++ b/templates/chapters/analysis.tex @@ -0,0 +1,168 @@ +% !TEX root = ../thesis.tex + +\chapter{Virtual Private Network -- VPN}\label{1} +Virtuálna privátna sieť (ďalej \textbf{\acrshort{vpn}}) je jeden zo spôsobov prepojenia zariadení, tak že internetová komunikácia medzi nimi je privátna, resp. zabezpečená aj v prípade používania nezabezpečenej, verejnej siete. Bezpečnosť spojenia je docielená pomocou kryptografických protokolov v tuneli, ktorý VPN vytvára. +Táto technológia patrí aktuálne k najpoužívanejším spôsobom pripojenia sa medzi 2 rôznymi internetovými doménami. Najčastejší výskyt je možné sledovať v korporačnom prostredí, pričom cieľom je rozšírenie možností bezpečného pripojenia sa k firemnej sieti. Vzhľadom na firemné tajomstvá je nutné aby bolo takéto spojenie bezpečné a zamestnanci sa mohli pripojiť z rôznych miest. Vďaka uvedeným vlastnostiam je následne možná aj práca z~domu (z~ang. \textit{Home office}), ktorá môže byť benefitom pre obe strany. Ukážka použitia VPN je znázornená pomocou \ref{vpndemo}. +\begin{figure}[!ht] + \centering + \includegraphics[width=.9\textwidth]{figures/VPNdemo} + \caption{Ukážka typického VPN pripojenia} + \label{vpndemo} +\end{figure} + +\section{Rozdelenie VPN} +\cite{divvpn}, \cite{ciscovpn} + +\section{Protokol riadenia prenosu -- \acrshort{tcp}} +Protokol riadenia prenosu (z ang. \textit{Transmission Control Protocol}, ďalej \acrshort{tcp}) je komunikačný protokol orientovaný na nadviazanie a udržanie sieťového spojenia medzi zariadeniami. Môže byť použitý pri úlohe príjímateľa aj odosielateľa (z ang. \textit{full-duplex}). Úlohou je spoľahlivý prenos dát medzi komunikantmi. Odoslanie a príjem dát je v rovnakom poradí. Protokol zároveň obsahuje mechanizmy na kontrolu výskytu chýb. + +Na začiatku 21. storočia je 95\% paketov používaných na internete TCP. Bežné aplikácie používajúce TCP sú webové (HTTP/HTTPS protokoly), slúžiace na e-mailovú komunikáciu (SMTP/POP3/IMAP) a prenos súborov (z ang. \textit{File Transfer Protocol -- \acrshort{ftp}}). Minimálna dĺžka hlavičky TCP je 20 bajtov a maximálna dĺžka 60 bajtov. Po pridaní údajov TCP hlavičky k prenášaným dátam, vzniká tzv. \textit{segment}. TCP je použitý s internetovým protokolom (ďalej \acrshort{ip}) Z uvedeného dôvodu sa preto často stretávame s označením TCP/IP. Dôležité je však poznamenať, že sa jedná o jeden a ten istý TCP protokol. + +V súvislosti s TCP/IP sa používateľ môže stretnúť s modelom. Ten je zobrazený pomocou schémy \ref{tcpipprot}. V uvedenej schéme sú znázornené aj niektoré z protokolov, ktoré ja na jednotlivých vrstvách používajú. + +\begin{figure}[!ht] + \centering + \includegraphics[width=0.9\textwidth]{figures/tcpipprot} + \caption{Schéma TCP/IP modelu s niektorými protokolmi} + \label{tcpipprot} +\end{figure} + +V súčasnosti je možne TCP protokol implementovať softvérovo aj hardvérovo. Pri prvom z uvedených je problémom závislosť na OS a následne aj vysoká vyťaženosť procesora pri príprave a spracovaní dát. Pri hardvérovom riešení je výhodou optimalizácia a implementácia bez potreby dodatočnej úpravy OS. Hardvérové implementácie sa realizujú pomocou koprocesorov umiestnených vo vnútri procesora. Následkom toho môžeme dnes bežne pozorovať umiestnenie spomenutých zariadení na našich zariadeniach. + +Podrobnejšie informácie o TCP protokole je možné nájsť na \cite{tcp2}. V uvedenej publikácií sa nachádza opis TCP hlavičky, metódy nadviazania a ukončenia spojenia. Obdobne je spomenuté ako dochádza k prenosu dát pomocou sekvenčných čísel. Ak má používateľ nejasnosti v fungovaní TCP protokolu, odporúča sa danú publikáciu prečítať. + +\section{Kryptografické zabezpečenie protokolov} +TCP protokol sam o sebe nezabezpečí dáta, ku ktorým sa pridáva TCP hlavička. Dôsledkom toho vznikli viacere protokoly slúžiace na autentizované šifrovanie dát. Najznámejší je protokol zabezpečenia prenosu -- \acrshort{tls} a IPSec. +\subsection{Transport Layer Security -- TLS} +Zabezpečenie dát bolo prvotne vykonávané pomocou protokolu \textit{Secure Sockets Layer} -- \acrshort{ssl}. Tento spôsob používa certifikáty na odšifrovanie dát. SSL malo od svojho vytvorenia dlhý vývoj, ktorý smeroval až k doteraz najpoužívanejšiemu TLS vo verzii 1.3. Inými slovami, TLS protokol je nástupca SSL pričom obsahuje rôzne úpravy a vylepšenia najmä z hľadiska rýchlosti. Zároveň sa v dnešnej dobe neodporúča používanie SSL protokolu. Dôsledkom optimalizácií je, že klienta komunikujúci so serverom cez HTTPS protokol s TLS 1.3 je rýchlejší ako v prípade použitia nešifrovaného HTTP variantu. + +TLS pracuje niekde na pomedzi aplikačnej a transportnej vrstvy. Spôsob spracovania dát je zobrazený pomocou schémy \ref{ssl} s SSL operáciami, prebratej z \cite{biks}. +\begin{figure}[!ht] + \centering + \includegraphics[width=0.7\linewidth]{figures/ssl} + \caption{Prehľad operácií v SSL protokole} + \label{ssl} +\end{figure} + +Viac informácií o TLS protokole, jednotlivých verziách a optimalizáciách je možné nájsť na \cite{tls}. + +\subsection{Internet Protocol Security -- IPSec} +Ochrana medzi transportnou a sietovou vrstvou TCL/IP. +Nabudúce. \cite{biks} +\chapter{Kryptografia vo VPN}\label{krypto} +Cieľom kryptografických blokov je utajiť správu pri jej ceste z bodu A do B. Teda od odosielateľa (tvorcu) správy, až k jej príjimateľovi. Dôsledkom tohto úkonu dochádza k zabezpečeniu 3 hlavných úloh kryptografie: +\begin{itemize} + \item \textbf{Ochrana osobných údajov} (dôvernosť) -- z ang. \textit{Data Privacy}, + \item \textbf{Autenticita údajov} (prišla z miesta, kde sa uvádza) -- z ang. \textit{Data Authenticity}, + \item \textbf{Integrita údajov} (nebola upravovaná na ceste) -- z ang. \textit{Data Integrity}. +\end{itemize} + + Prvý z uvedených bodov je najčastejšie žiadaným a známym cieľom. Odosielateľ správy zašifruje jej obsah pomocou použitia niektorého z šifrovacích algoritmov, kryptografického kľúča a následne správu odošle. Na druhej strane, príjmateľ, musí použiť komplementárny dešifrovací algoritmus s prislúchajúcim kľúčom. Ktokoľvek kto sa dostane medzi týchto komunikantov, k takto preposielanej správe, z nej nedokáže obsahovo nič zistiť, v istom časovom období. + + Dôsledkom týchto faktov je jasné, že komunikanti musia mať jasne definovaný použitý algoritmus. Zároveň je nutné aby došlo k výmene kryptografických kľúčov, ktoré sú pri šifrovaní a dešifrovaní aplikované. Tým sa zabezpečí aj druhá úloha -- Autenticita dát, pretože potrebné informácie budú mať len komunikanti. + + V kryptografických blokoch sú taktiež aplikované algoritmy na overenie integrity správ. Ich úlohou je potvrdiť, že do obsahu správy nebolo, počas jej transportu medzi komunikantmi, nič pridané, resp. ubrané. + + V súčasnosti má používateľ možnosť vybrať si zo širokej ponuky kryptografických algoritmov. Medzi najznámejší patrí \acrshort{aes} \cite{aes}, ktorý je aktuálne používaný ako štandardný kryptografický algoritmus pri počítačovej komunikácií. Detailný opis jednotlivých blokov a postupov použitých v AES-e, je obsahom rôznych knižných vydaní. Pre čitateľa preto posúvam knihu \cite{levicky}, ktorá obsahuje okrem opisu AES-u aj doležité informácie, týkajúce sa kryptografických základov. + +V rámci tejto práce sme sa rozhodli opísať, v súčásnosti menej známe, algoritmy: +\begin{itemize} + \item XOODOO \cite{tkecak} + \item Gimli \cite{gimli} + \item Simpira384 \cite{simpira} +\end{itemize} +Uvedené permutácie sú použité ako kryptografické primitívum a pri následnej tvorbe ďalších kryptografickych blokov. + +\section{Kryptografický algoritmus XOODOO a variácie} +XOODOO je sada 384-bitových kryptografických permutácií parametrizovaných počtom kôl. Funkcia kola/rundy\footnote{z ang. \textit{round}} funguje na 12 slovách\footnote{z ang. \textit{words}} po 32 bitoch, vďaka čomu je efektívna aj na procesoroch nižšej triedy. Vytvoril ju tím Keccak, ktorý stojí za viacerými úspešnými kryptografickými algoritmami. Napríklad hashovacie funkcie z rodiny SHA-3 a iné -- \cite{kecsup}. XOODOO algoritmus vznikol po vytvorení tzv. Kravatte autentizačno-šifrovacieho algoritmu \cite{kravatte}, založené na Keccak-p permutácií \cite{keccakp}. Ten sa ukázal ako dostatočne rýchly na širokom spektre platforiem. Avšak nezapadá do kategórie tzv. ľahkej kryptografie \footnote{z ang. \textit{lightweight cryptography}}. + +Tím Keccak vypracoval nové riešenie. Ním bol port medzi ich prvotným Keccak-p dizajnom a Gimli-ho \cite{bernstein2017gimli} permutačným algoritmom. Vo výsledku autori zlúčili lepšie realizované prvky z oboch algoritmov do jedného celku. Primárny problém samotnej Gimli permutácie bol v slabom prejave zmeny výstupu po malých zmenách vo vstupnej správe. Táto vlastnosť sa v kryptografii označuje pomocou anglického pojmu, tzv. \textit{propagation proporties}\footnote{Cieľom je aby aj zmena jedného bitu na vstupe, ovplyvnila čo najviac bitov vo výstupe -- tzv. \textit{Lavínový efekt}.}. Novo-vzniknuté riešenie autori pomenovali XOODOO. Na základe rôznych variácií tohto kryptografického primitíva sa im následne podarilo vytvoriť sadu vysoko efektívnych kryptografických funkcií. +Medzi sady, ktorých jadro tvorí XOODOO, patrí Xoodyak a Xoofff. Xoofff pozostáva zo zlúčenia Farfalle konštrukcie \cite{farfalle} so XOODOO permutáciou. + +Xoodyak ma narozdiel od Xoofff duplexovú konštrukciu \cite{duplex}. Vo výsledku máme ľahko prenosnú, všestrannú, kryptografickú knižnicu. Je vhodná do výkonovo obmedzených prostredí. Môže sa použiť pre väčšinu kryptografických funkcií, ktoré používajú symetrický kľúč. Napríklad hashovanie, šifrovanie, výpočet MAC alebo autentizované šifrovanie. O kvalite riešenia napovedá aj fakt, že sada Xoodyak je jedným z 10 finalistov v oblasti ľahkej kryptografie NIST štandardizačného procesu. +V rámci tejto kapitoly opíšeme kryptografické primitívum XOODOO a následne balík Xoodyak. Informácie o téme boli čerpané z týchto zdrojov: \cite{tkecak}, \cite{xd}, \cite{xcb}, \cite{xoodoocb}, \cite{xdupdate},\cite{xdr1}. +\subsection{XOODOO permutácia} +XOODOO je rodina permutácií, ktorá je definovaná počtom rúnd. Má klasickú iteračnú štruktúru. Teda opakovateľne sa vola rundová funkcia s aktuálnym stavom. Pre pochopenie operácií je nutné pochopiť určité označenie použité v algoritme. + +Stav -- \textbf{state}, pozostáva z 3 rovnako veľkých horizontálnych rovín -- \textbf{planes}. Každá z týchto rovín obsahuje štyri paralelne 32-bitové pruhy -- \textbf{lanes}. Okrem tejto charakteristiky je možné opísať stav ako množinu 128 stĺpcov -- \textbf{columns}, pričom jeden stĺpec obsahuje 3 bity v každej rovine. Stav je teda tvorený zo stĺpcov usporiadaných v poli o rozmere 4x32. Posledná položka na opis stavu sú tzv. listy -- \textbf{sheets}. List sa skladá z 3 na sebe uložených pruhov. Uvedené pojmy sú znázornené pomocou schémy \ref{xoodooterm}, ktorá bola prebraná z \cite{xcb}. + +\begin{figure}[!h] + \centering + \includegraphics[width=1\textwidth]{figures/xoodooTerminology} + \caption{Grafické znázornenie terminológie v XOODOO} + \label{xoodooterm} +\end{figure} + +Roviny majú index $y$. $y=0$ zodpovedá spodnej rovine a vrchná rovina $y=2$. Bit je označený s indexom $z$ vrámci množiny pruhov. List ich označujeme pomocou indexu $x$. Takže pozícia pruhu v stave je definovaná pomocou dvoch súradníc $(x,y)$. Konkrétny bit je možné v stave následne reprezentovať pomocou trojice súradníc $(x,y,z)$. Pri učení stĺpca sú potrebné 2 súradnice $(x,z)$. Pred spustením samotného algoritmu musí používateľ vykonať mapovanie 384-bitovej správy voči horizontálnym rovinám. Tento úkon sa realizuje pomocou matematickej formuly \ref{index}. + +\begin{equation}\label{index} + i=z+32(x+4y) +\end{equation} + +Rundová funkcia pozostáva z 5 krokov: +\begin{enumerate} + \item a mixing layer $\theta$, + \item a plane shifting $\rho_{west}$, + \item the addition of round constants $\iota$, + \item a non-linear layer $\chi$, + \item an another plane shifting $\rho_{east}$. +\end{enumerate} +Celý algoritmus je znázornený pomocou schémy \ref{xoodooalgo}, ktorá je prebratá z \cite{xcb}. + + \begin{figure}[!h] + \centering + \includegraphics[width=1.1\textwidth]{figures/xoodooalgo} + \caption{} + \label{xoodooalgo} + \end{figure} + +\subsection{Xoodyak} +Xoodyak možno považovať za všestranný kryptografický nástroj. Je vhodný pre väčšinu operácií využívajúcich symetrický kľúč. Napríklad generovanie pseudonáhodných bitov, autentizáciu, šifrovanie a mnohé iné. Tím Keccak použil pri návrhu duplexnú konštrukciu. Konkrétne variant s plným stavom a využitím kľúča. Tento dizajn označujeme ako \acrfull{fskd}. Viac o tejto konštrukcii si čitateľ môže prečítať v \cite{duplex}. +Operačný režim, v ktorom Xoodyak pracuje sa nazýva Cyklista -- z ang. \textit{Cyclist}. Tento názov získal ako opozitum k pomenovaniu režimu Motorista, ktorý je možné nájsť v Keyak schéme \cite{keyak}. Narozdiel od uvedeného balíka Keyak, nie je Xoodyak limitovaný len na autentizované šifrovanie. Je jednoduchší hlavne kvôli tomu že neobsahuje paralelné varianty. + +\subsubsection{Režim Cyklista}\label{cyklista} +Režim Cyklista funguje na princípe kryptografických permutácií $f$, teda zmeny usporiadania bitov za pomoci tajného kľúča a matematických operácií. Parametrami sú veľkosti blokov $R_{hash}$, $R_{kin}$, $R_{kout}$ a veľkosť račety, resp. západky\footnote{z ang. \textit{the ratchet size}} \cite{ratchet} $\ell_{ratchet}$. Uvedený pojem sa v kryptografii používa vo forme obrazného pomenovania. Cieľom je poukázať na jednoduchý pohyb vpred, ale s ťažkým, resp. zložitejším pohybom naspäť. Dôležité je, že uvedený scenár je vyvolaný zámerným dizajnom. Šírka permutácie $b'$ je definovaná pomocou matematickej formuly \ref{index2}. Všetky uvedené parametre sú v bajtoch. Pre označenie prázdneho slova budeme používať $\epsilon$. +\begin{equation}\label{index2} + max(R_{hash}, R_{kin}, R_{kout}) + 2 \leq b' +\end{equation} + +Cyklista operuje v dvoch režimoch -- \textbf{hašovací a kľúčový}\footnote{z ang. \textit{hash and keyed mode}.}. +Inicializácia prebieha pomocou príkazu \lstinline|CYCLIST(K,id,counter)|. Ak sa parameter $K$ rovná prázdnemu slovu $\epsilon$, tak potom nastane spustenie v hašovacom režime. Aktuálne nie je do implementácie zakomponovaná možnosť zmeny režimu po inicializácií. Vývojári však túto vlastnosť nevylúčili pre prípadné aktualizácie balíka. + + +Dostupné funkcie závisia od režimu, v ktorom sa Cyklista spúšťa. Medzi ne patria \lstinline|ABSORB()| a \lstinline|SQUEEZE()|. Možno ich volať v oboch režimoch, zatiaľ čo funkcie \lstinline|ENCRYPT()|, \lstinline|DECRYPT()|, \lstinline|SQUEEZEKEY()| a \lstinline|RATCHET()| sú dostupné len pre kľúčový režim. Účel každej funkcie je nasledujúci: +\begin{itemize} + \item \lstinline|ABSORB(X)| absorbuje vstupný reťazec X, + \item C $\gets$ \lstinline|ENCRYPT(P)| zašifruje P do C a absorbuje P, + \item P $\gets$ \lstinline|DECRYPT(C)| dešifruje C do P a absorbuje P, + \item Y $\gets$ \lstinline|SQUEEZE($\ell$)| vytvára $\ell$-bajtový výstup, ktorý závisí od doteraz absorbovaných dát, + \item Y $\gets$ \lstinline|SQUEEZEKEY($\ell$)| funguje ako \lstinline|SQUEEZE($\ell$)|, ale používa sa za účelom generovania odvodeného kľúča, \\ell nefunguje v listings pckg + \item \lstinline|RATCHET()| transformuje stav na nevratný tak, aby sa zabezpečila dopredná bezpečnosť\footnote{z ang. \textit{Forward secrecy}} \cite{fsec}. +\end{itemize} + +Stav bude závisieť od postupnosti volaní funkcií a od jeho vstupných reťazcov. Presnejšie povedané, zámerom je, že akýkoľvek výstup závisí od postupnosti všetkých vstupných reťazcov a volaní, tak že akékoľvek dva nasledujúce výstupné reťazce budú výstupom rôznych domén. Napríklad volanie \lstinline|ABSORB(X)| znamená, že výstup bude závisieť od reťazca $X$. Na druhej strane \lstinline|ABSORB()| vo funkcii \lstinline|ENCRYPT(P)| vytvorí výstup závislý aj od $P$ z funkcie šifrovania. Okrem uvedených závislostí ovplyvňujú výstup aj iné dizajnové riešenia. Príkladom je minimalizácia pamäťovej stopy. Vo výsledku teda výstup závisí od počtu predchádzajúcich volaní funkcie \lstinline|SQUEEZE()| a predtým spracovaných textov pomocou funkcií \lstinline|ENCRYPT()| a \lstinline|DECRYPT()|. Viac informácií o režime je dostupných v kapitole 7.2, publikácie \cite{xcb}. + +\subsubsection{Definícia a bezpečnosť} +Xoodyak je definovaný pomocou operatívneho režimu Cyklista nasledovne: +\begin{equation} + CYCLIST[f,R_{hash},R_{kin},R_{kout},\ell_{ratchet}] +\end{equation} +Kde jednotlivé parametre majú veľkosti: +\begin{enumerate} + \item $f$ -- permutácia XOODOO so šírkou 48 bajtov (384 bitov), + \item $R_{hash}$ -- 16 bajtov, + \item $R_{kin}$ -- 44 bajtov, + \item $R_{kout}$ -- 24 bajtov, + \item $\ell_{ratchet}$ -- 16 bajtov. +\end{enumerate} +Takto definované parametre algoritmu dokážu poskytnúť 128-bitovú bezpečnosť v oboch režimoch Cyklistu. Samozrejmosťou je, že v prípade kľúčového režimu, musí byť veľkosť kľúča rovná alebo väčšia ako 128 bitov. Viac informácií o kryptografickej bezpečnosti algoritmov je možné nájsť v \cite{sec}. + +Viac informácií o bezpečnosti Xoodyak-a je možné nájsť v \cite{xcb, 7.3}, odkiaľ boli informácie čerpané. + +\subsection{Možnosti použitia Xoodyak algoritmu} +Obsahom tejto podkapitoly sú uvedené postupy ako a za akých okolností je daný balík možné použiť. +\subsubsection{Použitie hašovacieho režimu} +Xoodyak sa dá aplikovať ako hašovacia funkcia. +\subsubsection{Použitie kľúčového režimu} +\section{Kryptografický algoritmus Gimli} +\section{Kryptografický algoritmus Simpira384} diff --git a/templates/chapters/bibliography.bib b/templates/chapters/bibliography.bib new file mode 100644 index 0000000..d3980a7 --- /dev/null +++ b/templates/chapters/bibliography.bib @@ -0,0 +1,291 @@ +@article{divvpn, +author = {Sridevi, Sridevi and D H, Manjaiah}, +year = {2012}, +month = {06}, +pages = {93-96}, +title = {Technical Overview of Virtual Private Networks(VPNs)}, +volume = {2}, +journal = {International Journal of Scientific Research}, +doi = {10.15373/22778179/JULY2013/32}, +url={https://www.researchgate.net/publication/274929918_Technical_Overview_of_Virtual_Private_NetworksVPNs}, +note="[Online; Citované: 22.1.2022]" +} +@ARTICLE{vbox, + title={Oracle VM Virtual Box}, + publisher={Wikipedia}, + url={https://en.wikipedia.org/wiki/VirtualBox}, + note="[Online; Citované: 20.1.2022]" +} +@ARTICLE{sha2, + title={Secure Hash Algorithm 2 (SHA-2)}, + publisher={Wikipedia}, + url={https://en.wikipedia.org/wiki/SHA-2}, + note="[Online; Citované: 21.5.2021]" +} +@ARTICLE{base, + title={Base64}, + publisher={Wikipedia}, + url={https://en.wikipedia.org/wiki/Base64}, + note="[Online; Citované: 21.5.2021]" +} +@article{ciscovpn, +title={Virtual Private Networks Simplified}, +publisher={Cisco}, +url={https://www.cisco.com/c/dam/en_us/training-events/le21/le34/downloads/689/academy/2008/sessions/BRK-134T_VPNs_Simplified.pdf}, +note="[Online; Citované:26.1.2022]" +} +@article{vmkonfig, + title={Installing Windows 10 on Virtualbox 6.1.12 -- FULL PROCESS, 2020 -- video tutorial}, + author={MikeTheTech}, + year={2020}, + url={https://www.youtube.com/watch?v=gKQvaPejxpc&ab_channel=MikeTheTech}, + note="[Online; Citované: 17.5.2021]" +} +@article{vbguide, +title={VirtualBox Network Settings: Complete Guide}, +author={Michael Bose}, +publisher={Nakivo}, +year={2019}, +url={https://www.nakivo.com/blog/virtualbox-network-setting-guide/}, +note="[Online; Citované:26.1.2022]" +} +@article{vboracle, +title={6.2. Introduction to Networking Modes}, +author={Oracle}, +url={https://www.virtualbox.org/manual/ch06.html}, +note="[Online; Citované:26.1.2022]" +} +@article{tcp, +title={Transmission Control Protocol}, +author={Wikipedia}, +url={https://en.wikipedia.org/wiki/Transmission_Control_Protocol}, +note="[Online; Citované:26.1.2022]" +} +@article{cryptol, +title={Cryptol -- The Language of Cryptography}, +author={Cryptol}, +url={https://cryptol.net/index.html}, +note="[Online; Citované:6.2.2022]" +} +@misc{xoodoocb, + author = {Joan Daemen and + Seth Hoffert and + Michaël Peeters and + Gilles Van Assche and + Ronny Van Keer}, + title = {Xoodoo cookbook (2.revision)}, + howpublished = {Cryptology ePrint Archive, Report 2018/767}, + year = {2019}, + url = {https://eprint.iacr.org/2018/767.pdf}, + note = "[Online; Citované:6.2.2022]" +} +@article{xd, + title={The design of Xoodoo and Xoofff}, + author = {Joan Daemen, Seth Hoffert, Gilles Van Assche and Ronny Van Keer}, + volume={2018}, + url={https://tosc.iacr.org/index.php/ToSC/article/view/7359/6529}, + DOI={10.13154/tosc.v2018.i4.1-38}, + year={2018}, + note="[Online; Citované:6.2.2022]" +} + +@misc{xdupdate, + title={Xoodyak, an update}, + author={Daemen, Joan and Hoffert, Seth and Mella, Silvia and Peeters, Micha{\"e}l and Van Assche, Gilles and Van Keer, Ronny}, + year={2020}, + publisher={Publication to NIST Lightweight Cryptography Standardization Process (round~…}, + url={https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/round-2/status-update-sep2020/Xoodyak-update.pdf}, + note="[Online; Citované:6.2.2022]" +} +@misc{xdr1, + title={Xoodyak}, + author={Daemen, Joan and Hoffert, Seth and Mella, Silvia and Peeters, Micha{\"e}l and Van Assche, Gilles and Van Keer, Ronny}, + year={2020}, + publisher={Publication to NIST Lightweight Cryptography Standardization Process}, + url={https://csrc.nist.gov/CSRC/media/Projects/Lightweight-Cryptography/documents/round-1/spec-doc/Xoodyak-spec.pdf}, + note="[Online; Citované:6.2.2022]" +} +@misc{tkecak, + title={Xoodyak}, + author={Daemen, Joan and Hoffert, Seth and Mella, Silvia and Peeters, Micha{\"e}l and Van Assche, Gilles and Van Keer, Ronny}, + year={2020}, + publisher={Team Keccak}, + url={https://keccak.team/xoodyak.html}, + note="[Online; Citované:6.2.2022]" +} +@ARTICLE{tls, + title={Transport Layer Security}, + publisher={Wikipedia}, + url={https://en.wikipedia.org/wiki/Transport_Layer_Security#TLS_1.3}, + note="[Online; Citované: 21.5.2021]" +} +@article{biks, +title={Bezpečnosť v architektúre TCP/IP II (BIKS pr7)}, +author={Miloš Drutarovský}, +note="[Online; Citované:6.2.2022]" +} +@article{tcp2, +title={5. Prednáška - Transportná vrstva: Protokol TCP}, +author={Institute of Computer Science UPJS}, +url={https://siete.ics.upjs.sk/prednaska-5/}, +note="[Online; Citované:6.2.2022]" +} +@article{gimli, +title={Gimli 2019-03-29}, +author={Publication to NIST Lightweight Cryptography Standardization Process}, +url={https://csrc.nist.gov/CSRC/media/Projects/Lightweight-Cryptography/documents/round-1/spec-doc/gimli-spec.pdf}, +note="[Online; Citované:6.2.2022]" +} + +@article{simpira, +title={Simpira v2: A Family of Efficient Permutations Using the AES Round Function}, +author={Shay Gueron, Nicky Mouha}, +url={https://hal.inria.fr/hal-01403414/document}, +note="[Online; Citované:6.2.2022]" +} + +@article{make, +title={GNU Make Manual}, +author={GNU org.}, +url={https://www.gnu.org/software/make/manual/html_node/index.html}, +note="[Online; Citované:20.2.2022]" +} +@article{endianita, +title={Endianita}, +author={Wikipedia}, +url={https://sk.wikipedia.org/wiki/Endianita}, +note="[Online; Citované:20.2.2022]" +} +@article{poll, +title={Poll}, +author={man7org}, +url={https://man7.org/linux/man-pages/man2/poll.2.html}, +note="[Online; Citované:20.2.2022]" +} + +@article{ternary, +title={Ternary Operator in C Explained}, +author={freeCodeCamp.org}, +url={https://www.freecodecamp.org/news/c-ternary-operator/}, +note="[Online; Citované:20.2.2022]" +} +@ARTICLE{bufferbloat, + title={Bufferbloat}, + publisher={Wikipedia}, + url={https://en.wikipedia.org/wiki/Bufferbloat}, + note="[Online; Citované: 1.3.2021]" +} +@ARTICLE{aes, + title={Advanced Encryption Standard}, + publisher={Wikipedia}, + url={https://en.wikipedia.org/wiki/Advanced_Encryption_Standard}, + note="[Online; Citované: 8.5.2021]" +} +@book{levicky, + title={Kryptografia v informačnej bezpečnosti}, + author={Levický, Dušan}, + year={2005}, + publisher={Elfa} +} + +@misc{kravatte, + title={Kravatte}, + author={Daemen, Joan and Hoffert, Seth and Mella, Silvia and Peeters, Micha{\"e}l and Van Assche, Gilles and Van Keer, Ronny}, + year={2020}, + publisher={Team Keccak}, + url={https://keccak.team/kravatte.html}, + note="[Online; Citované:6.2.2022]" +} + +@misc{keccakp, + title={The Keccak-p Permutations}, + author={Daemen, Joan and Hoffert, Seth and Mella, Silvia and Peeters, Micha{\"e}l and Van Assche, Gilles and Van Keer, Ronny}, + year={2020}, + publisher={Team Keccak}, + url={https://keccak.team/keccakp.html}, + note="[Online; Citované:6.2.2022]" +} + +@misc{kecsup, + title={The Keccak-p Permutations}, + author={Daemen, Joan and Hoffert, Seth and Mella, Silvia and Peeters, Micha{\"e}l and Van Assche, Gilles and Van Keer, Ronny}, + year={2020}, + publisher={Team Keccak}, + url={https://keccak.team/specifications.html}, + note="[Online; Citované:6.2.2022]" +} +@inproceedings{bernstein2017gimli, + title={Gimli: a cross-platform permutation}, + author={Bernstein, Daniel J and K{\"o}lbl, Stefan and Lucks, Stefan and Massolino, Pedro Maat Costa and Mendel, Florian and Nawaz, Kashif and Schneider, Tobias and Schwabe, Peter and Standaert, Fran{\c{c}}ois-Xavier and Todo, Yosuke and others}, + booktitle={International Conference on Cryptographic Hardware and Embedded Systems}, + pages={299--320}, + year={2017}, + organization={Springer} +} +@misc{farfalle, + title={Farfalle: parallel permutation-based cryptography}, + author={Daemen, Joan and Hoffert, Seth and Mella, Silvia and Peeters, Micha{\"e}l and Van Assche, Gilles and Van Keer, Ronny}, + year={2020}, + publisher={Team Keccak}, + url={https://keccak.team/farfalle.html}, + note="[Online; Citované:6.2.2022]" +} +@misc{duplex, + title={The sponge and duplex constructions}, + author={Daemen, Joan and Hoffert, Seth and Mella, Silvia and Peeters, Micha{\"e}l and Van Assche, Gilles and Van Keer, Ronny}, + year={2020}, + publisher={Team Keccak}, + url={https://keccak.team/sponge_duplex.html}, + note="[Online; Citované:6.2.2022]" +} +@misc{xcb, + title={Xoodoo cookbook}, + author={Daemen, Joan and Hoffert, Seth and Mella, Silvia and Peeters, Micha{\"e}l and Van Assche, Gilles and Van Keer, Ronny}, + year={2020}, + publisher={Team Keccak}, + url={https://eprint.iacr.org/2018/767.pdf}, + note="[Online; Citované:6.2.2022]" +} +@InProceedings{duplex, +author="Daemen, Joan +and Mennink, Bart +and Van Assche, Gilles", +editor="Takagi, Tsuyoshi +and Peyrin, Thomas", +title="Full-State Keyed Duplex with Built-In Multi-user Support", +booktitle="Advances in Cryptology -- ASIACRYPT 2017", +year="2017", +publisher="Springer International Publishing", +address="Cham", +pages="606--637", +abstract="The keyed duplex construction was introduced by Bertoni et al. (SAC 2011) and recently generalized to full-state absorption by Mennink et al. (ASIACRYPT 2015). We present a generalization of the full-state keyed duplex that natively supports multiple instances by design, and perform a security analysis that improves over that of Mennink et al. in terms of a more modular security analysis and a stronger and more adaptive security bound. Via the introduction of an additional parameter to the analysis, our bound demonstrates a significant security improvement in case of nonce-respecting adversaries. Furthermore, by supporting multiple instances by design, instead of adapting the security model to it, we manage to derive a security bound that is largely independent of the number of instances.", +isbn="978-3-319-70697-9", +url={https://link.springer.com/chapter/10.1007/978-3-319-70697-9_21#citeas}, +note="[Online; Citované:6.2.2022]" +} +@misc{keyak, + title={The Keyak authenticated encryption scheme}, + author={Daemen, Joan and Hoffert, Seth and Mella, Silvia and Peeters, Micha{\"e}l and Van Assche, Gilles and Van Keer, Ronny}, + year={2020}, + publisher={Team Keccak}, + url={https://keccak.team/keyak.html}, + note="[Online; Citované:6.2.2022]" +} +@ARTICLE{ratchet, + title={What is a ratchet?}, + publisher={Cryptography StackExcchange}, + url={https://crypto.stackexchange.com/questions/39762/what-is-a-ratchet}, + note="[Online; Citované: 8.5.2021]" +} +@ARTICLE{fsec, + title={Forward secrecy}, + publisher={Wikipedia}, + url={https://en.wikipedia.org/wiki/Forward_secrecy}, + note="[Online; Citované: 8.5.2021]" +} +@ARTICLE{sec, + title={Security level}, + publisher={Wikipedia}, + url={https://en.wikipedia.org/wiki/Security_level}, + note="[Online; Citované: 8.5.2021]" +} diff --git a/templates/chapters/evaluation.tex b/templates/chapters/evaluation.tex new file mode 100644 index 0000000..d7ee128 --- /dev/null +++ b/templates/chapters/evaluation.tex @@ -0,0 +1,3 @@ +% !TEX root = ../thesis.tex +\chapter{Vyhodnotenie dosiahnutých výsledkov} +\blindtext \ No newline at end of file diff --git a/templates/chapters/introduction.tex b/templates/chapters/introduction.tex new file mode 100644 index 0000000..8ce167a --- /dev/null +++ b/templates/chapters/introduction.tex @@ -0,0 +1,12 @@ +% !TEX root = ../thesis.tex + +\chaptermark{Úvod} +\phantomsection +\addcontentsline{toc}{chapter}{Úvod} + +\chapter*{Úvod} +\blindtext +\acrshort{vpn} +\cite{book} + + diff --git a/templates/chapters/sheeesh.txt b/templates/chapters/sheeesh.txt new file mode 100644 index 0000000..a52e9d2 --- /dev/null +++ b/templates/chapters/sheeesh.txt @@ -0,0 +1,24 @@ +Dobrý deň, moje meno je Marek Rohač a predtým než začneme +by som rád predstavil členov nášho pracovného tímu. +Predstavenie členov. (dvihnut ruku) + +Témou nášho semestrálneho zadania bola Virtualizácia sieťových funkcií + v 5g sietach. + +Našou úlohou bola taktiež príprava 5 otázok. Jedná sa o otázky, +ktoré je možné vidieť na tomto slide. Teda + +Otázka 3. +Siete 5G sa budujú tak, aby využívali signály s rôznymi frekvenciami: +• Vysokopásmové (high-band): 24+GHz +• Strednopásmové (mid-band): 1 − 6GHz +• Nízkopásmové (low-band): < 1GHz + +Teda pre oblast kde je malý počet bts staníc by bolo najvhodnejšie +využiť frekvencie menšie ako 1 ghz, ktoré patria medzi nizko-pasmové. +Vo výsledku by sme mali pokrytie signalom aj v uvedených husto zastavaných prostrediach +avśak na úkor nižšia kapacita a nižšie prenosové rýchlosti. + +Ak by sme však potrebovali pokrytie s vyssou kapacitou a aj prenosovymi rychlostami +tak by sme museli zvoliť iné pásmo + diff --git a/templates/chapters/summary.tex b/templates/chapters/summary.tex new file mode 100644 index 0000000..748ac7d --- /dev/null +++ b/templates/chapters/summary.tex @@ -0,0 +1,15 @@ +% !TEX root = ../thesis.tex + +\chapter{Záver} +\label{summary} +Plán budúcej práce: +\begin{itemize} + \item Študium a opis kódu DSVPN + \item Štúdium a opis funkcionality XOODOO,gimli atd. + \item Implementacia inych kryptograf. blokov do DSVPN + \item vytvorenie kompatibility DSVPN na OS Windows +\end{itemize} + + +Vo výsledku by sme mali mať k dispozícií funkcnu VPN, upravenú o kompatibilitu s OS windowse aj s moznostou vyberu kryp. algoritmov. + diff --git a/templates/chapters/synthesis.tex b/templates/chapters/synthesis.tex new file mode 100644 index 0000000..28e0322 --- /dev/null +++ b/templates/chapters/synthesis.tex @@ -0,0 +1,535 @@ +% !TEX root = ../thesis.tex +\chapter{Prostredie virtuálnych strojov pomocou VirtualBox}\label{merania} +Pri testovaní funkcionality VPN sme použili virtualizačný nástroj (daľej \textbf{\acrshort{vm}}) Virtual Box (ďalej \textbf{\acrshort{vb})}, spoločnosti Oracle, vo verzii 6.1.30. \acrshort{vb} je voľne dostupný. Inštalácia je jednoduchá a rýchla. Viac informácii o nástroji je možné dohľadať v \cite{vbox}. + +Pre použitie je potrebné aby mal používateľ k dispozícií obraz operačného systému (ďalej \acrshort{os}). Tie nie je problém získať ani pre \acrshort{os} Windows a podobne, avšak pri našej práci sme zvolili využitie voľno dostupného \acrshort{os} -- \textbf{Linux Ubuntu} vo verziách 20.04.3(\acrshort{lts}\footnote{z ang. \acrlong{lts}})-- OSC a 21.10 -- OSS. Pri opise práce použijeme označenia OSS pre VPN server a OSC pre klienta. + +Pri jednoduchej inštalácií \acrshort{vm} sme použili konfiguráciu s 2048 MB RAM a 2 jadrami. (Minimálna inštalácia). V prípade potreby dávame do popredia návod na prípravu Windows \acrshort{os} v \acrshort{vm} -- \cite{vmkonfig}, avšak postup je triviálny. Po inštalácii sme OS aktualizovali pomocou príkazov: +\begin{lstlisting}[language=bash] + sudo apt-get update + sudo apt-get upgrade +\end{lstlisting} +Následne sme doinštalovali potrebné súčasti k \acrshort{vm} \acrshort{os} vo verzii ako je \acrshort{vb}, teda 6.1.30. Dôvodom bolo zväčšenie rozlíšenia a využívanie možnosti zdieľaného priečinka s \acrshort{os}, na ktorom daný \acrshort{vb} beží. Za účelom správneho fungovania priečinka bolo nutné v termináli použiť príkaz: +\begin{lstlisting}[language=bash] + sudo usermod -aG vboxsf $(whoami) +\end{lstlisting} +a následne reštartovať \acrshort{os}. + +Posledné úpravy prostredia sú spojené s jazykom C a balíčkom Make. Inštalácia je opäť jednoduchá. Použili sme príkazy: +\begin{lstlisting}[language=bash] + sudo apt install gcc + sudo apt install make +\end{lstlisting} +Uvedené úpravy boli vykonané na oboch \acrshort{os}. + +V prípade použitia \acrshort{os} Windows je postup inštalácie jazyka C a balička Make zložitejší. Používateľovi odporúčam použitie knižníc Winlibs, dostupne na \href{https://winlibs.com/}{webe}. Po stiahnutí balíčkov musí používateľ importovať uvedený balíček, resp. cestu k nemu, do premenných prostredia \acrshort{os} Windows. Jeden zo spôsobov je uvedený aj na Winlibs stránke. + +\section{Zmena sieťových adaptérov} +\acrshort{vb} ponúka rôzne možnosti nastavenia sieťových adaptérov. Aktuálne su dostupné tieto: +\begin{itemize} + \item{Not attached} + \item{Network Address Translation (ďalej NAT)} + \item{NAT Network} + \item{Bridge adapter} + \item{Internal} + \item{Host-Only} + \item{Generic driver} + \item{Cloud-Based} -- experimentálne +\end{itemize} + +Konektivita jednotlivých možností je znázornená pomocou obrázku \ref{vbmode}. Viac informácií o jednotlivých režimoch je dostupných na \cite{vboracle}. + +\begin{figure} + \centering + \includegraphics[width=.9\textwidth]{figures/vbmodes} + \caption{Konektivita jednotlivých sieťových adaptérov} + \label{vbmode} +\end{figure} +Vzhľadom k našim potrebám, teda obojsmerná komunikácia medzi 2 VM, sú pre nás relevantné režimy bridge a NAT network. Ako si môžeme všimnúť, NAT vyžaduje dodatočnú konfiguráciu portov v prípadoch kedy chceme aby nastala komunikácia medzi dvoma VM. Z tohto dôvodu je pre čo najjednoduchší prístup zvoliť práve režim bridge. Ten priradí VM vlastnú IP adresu, pomocou, ktorej stroj komunikuje. + +Viac o jednotlivých režimov je taktiež možné nájsť v \cite{vbguide}. Autor sa venuje postupu konfigurácie jednotlivých režimov spoločne s ich opisom. + +\chapter{DSVPN -- Dead Simple VPN}\label{dsvpn} +Dead Simple VPN je voľne dostupný\footnote{\href{https://github.com/jedisct1/dsvpn}{https://github.com/jedisct1/dsvpn}} program, napísaný v jazyku C. Určený je pre operačný systém Linux. Autorom je Frank Denis. DSVPN rieši najbežnejší prípad použitia VPN, teda pripojenie klienta k VPN serveru cez nezabezpečenú sieť. Následne sa klient dostane na internet prostredníctvom servera. Uvedenú skutočnosť je možne vidieť na schéme \ref{vpnsimple}. +\begin{figure} + \centering + \includegraphics[width=0.9\textwidth]{figures/vpnsimple} + \caption{Schéma jednoduchej VPN} + \label{vpnsimple} +\end{figure} + + +DSVPN používa protokol riadenia prenosu -- \acrshort{tcp}\footnote{z ang. \textit{Transmission Control Protocol}} \cite{tcp}. Medzi ďalšie pozitíva patrí: +\begin{itemize} + \item{Používa iba modernú kryptografiu s formálne overenými implementáciami,} + \item{Malá a konštantná pamäťová stopa. Nevykonáva žiadne dynamické alokovanie pamäte (z ang. \textit{heap memory}),} + \item{Malý (~25 KB) a čitateľný kód. Žiadne vonkajšie závislosti (z ang. \textit{Dependencies}),} + \item{Funguje po preklade GCC prekladačom. Bez dlhej dokumentácia, žiaden konfiguračný súbor, dodatočná konfigurácia. DSVPN je spustiteľná jednoriadkovým príkazom na serveri, obdobne na klientovi. Bez potreby konfigurácie brány firewall a pravidiel smerovania,} + \item{Funguje na Linuxe (kernel >= 3.17), macOS a OpenBSD, DragonFly BSD, FreeBSD a NetBSD v klientskych a point-to-point režimoch. Pridanie podpory pre iné operačné systémy je triviálne,} + \item{Nedochádza k úniku IP medzi pripojeniami, ak sa sieť nezmení. Blokuje IPv6 na klientovi, aby sa zabránilo úniku IPv6 adries.} +\end{itemize} + +V uvedenej VPN autor zakomponoval aj možnosť pokročilejších nastavení. Celkový súhrn vstupných parametrov pri štarte programu je takýto: +\begin{lstlisting}[language=bash] + ./dsvpn server + + |"auto" + |"auto" + |"auto" + |"auto" + "auto" + |"auto" + + ./dsvpn client + + + |"auto" + |"auto" + |"auto" + |"auto" + |"auto" + \end{lstlisting} +Väčšina parametrov je však prednastavených na automatické hodnoty. Príkladom je port 443, vytvorenie rozhrania tun0, prevziatie externej IP adresy zo siete a ďalšie. + +\section{Kryptografia použitá v DSVPN} +DSVPN používa v svojej implementácií malú sebestačnú kryptografickú knižnicu -- \textit{Charm}\footnote{\url{https://github.com/jedisct1/charm}}. Jej autorom je tvorca DSVPN. Implementácia umožňuje autentizované šifrovanie (z ang.\textit{authenticated encryption}) a hašovanie kľúčov (z ang. \textit{keyed hashing}). Správnosť implementácie algoritmu v knižnici programátor overil pomocou nástroja \textbf{Cryptol}\footnote{\url{https://cryptol.net/index.html}}. Uvedený nástroj slúži na zápis algoritmu do matematickej špecifikácií. Tým poskytne možnosť jednoduchšej a hlavne korektnej implementácie zvoleného kryptografického algoritmu. Zároveň je možné program využiť aj na verifikáciu vytvoreného riešenia. Obdobne sú v repozitári knižnice ponechané overovacie skripty pre jednoduché spustenie. + +Kryptografický algoritmus použitý v DSVPN je Xoodoo permutácia v duplex móde, pričom môže byť jednoducho nahradená napríklad Gimli-im\footnote{\url{https://github.com/jedisct1/gimli}} \cite{gimli} alebo Simpira384\footnote{\url{https://github.com/jedisct1/simpira384}} \cite{simpira}, ktorá je založené na AES-e . Uvedené algoritmy sú predmetom opisu kapitoly \ref{krypto}. Pri zmene musí používateľ zasiahnuť do zdrojového kódu v súbore \textbf{charm.c}, ktorého obsahom sú kryptografické primitíva. +\section{Experimentálne overenie VPN} +DSVPN sme prakticky overili pomocou dvojice virtuálnych strojov OSS a OSC, ktorých opis je obsahom \ref{merania}. Na zariadení OSS sme pomocou balička make a GCC prekladača vykonali inštaláciu DSVPN. Obdobný postup je aplikovaný aj vo VM OSC. Na OSS spúšťame VPN Server, ktorý nám poskytne IP adresu, prostredníctvom ktorej budeme komunikovať s vonkajším svetom. Na spustenie a vytvorenie spojenie vykonáme nasledujúce úkony: +\begin{enumerate} + \item Vygenerovanie zdieľaného kľúča:\begin{lstlisting}[language=bash] + dd if=/dev/urandom of=vpn.key count=1 bs=32 + \end{lstlisting} +-- zdieľaný kľúč, ktorý sme vygenerovali, sa nám uložil do súboru \textit{vpn.key}. Ten je potrebné vložiť do priečinka s programom \textit{dsvpn} v oboch zariadeniach -- OSS aj OSC. + \item OSS zariadenie: \begin{lstlisting}[language=bash] + sudo ./dsvpn server vpn.key auto + 2340 auto 10.8.0.254 10.8.0.2 + \end{lstlisting} +-- tento príkaz zabezpečí spustenie VPN servera na prostredí OSS s IP adresou, priradenou k vytvoren=emu tunelovaciemu rozhraniu s menom \textit{tun0}. Vytvorí sa pri spustení servera\footnote{Pomocou \lstinline|ip address show tun0| zistíme IPv4 adresu VPN servera.}. Príkazom ďalej definujeme portové číslo 2340, ktoré sa použije pri nastolení TCP spojenie medzi klientom a serverom. Poslednou konfiguráciou je priradenie IP adresy tunelov, ktoré bude využívať náš klient -- 10.8.0.254 a server -- 10.8.0.2. Používateľ má ešte možnosť nastaviť tzv. External IP. Tú by sme využili ak by sme spúšťali DSVPN na routri poskytovateľa internetu. + \item OSC zariadenie: \begin{lstlisting}[language=bash] + sudo ./dsvpn client vpn.key 192.168.88.62 + 2340 auto 10.8.0.2 10.8.0.254 + \end{lstlisting} +-- uvedený príkaz zabezpečí, že sa pripojíme na VPN Server, ktorý ma ip adresu \textit{192.168.88.62} s portom 2340. Následne vzniká TCP spojenie. Dôležité je si všimnúť poradie adries tunelov. Je opačné ako v prípade servera. + \item V prípade úspešnej konektivity sa operácia podarila a pre okolitý svet sme viditelný pomocou IP adresy, ktorú sme zvolili. +\end{enumerate} + +Na overenie správnosti funkcionality nám postačí jednoduchý sieťový príkaz \lstinline|traceroute|. Napríklad \lstinline|traceroute google.sk|\footnote{vo Windows CMD prostredí: \lstinline|tracert google.sk|}. Prvá z uvedených adries je práve tá, ktorú dané zariadenie používa. + +V našom prípade bolo nutné použiť lokálne adresy vzhľadom na to, že obe VM bežia na jednom hosťovskom počítači. Obidva zariadenia sú tým pádom pripojené k jednému internetovému poskytovateľovi, čo má za následok takmer rovnaké smerovanie k vzdialenej doméne. + +Proces zistenia IP adresy VPN servera, po spustení, a overenie funkčnosti je následne znázornené pomocou \ref{ipu21},\ref{ipu20}, \ref{vpntru20}. +V \ref{ipu21} sme žltou farbou znázornili IP adresu, na ktorej je VPN server dostupný. Oranžová farba znázorňuje IP adresy tunelu medzi serverom a klientom v tomto poradí. Následne v \ref{ipu20} môžeme vidieť to isté pre klienta. + \begin{figure} + \centering + \includegraphics[width=0.9\textwidth]{figures/ipu21} + \caption{Zistenie IP adries VPN Servera na VM OSS} + \label{ipu21} + \end{figure} + + +\begin{figure} + \centering + \includegraphics[width=0.9\textwidth]{figures/ipu20} + \caption{Zistenie IP adries VPN Klienta na VM OSC} + \label{ipu20} +\end{figure} +Nakoniec, v \ref{vpntru20} môžeme vidieť ako klient pri internetovej komunikácií používa namiesto svojej vlastnej, adresu poskytnutú VPN Serverom na zariadení OSS -- žltou zvýraznená IP. Červenou je zaškrnutá farba poskytovateľa internetu. + +\begin{figure} + \centering + \includegraphics[width=0.9\textwidth]{figures/vpntru20} + \caption{Overenie funkcionality DSVPN pomocou traceroute} + \label{vpntru20} +\end{figure} + \section{Analýza zdrojového kódu DSVPN} + Pri analýze sa zameriame výhradne na dôležité časti kódu DSVPN pre programovací jazyk C. Repozitár pozostáva z jedného make-file balíčka\cite{make}. 3 hlavičkových (.h) a k ním korešpondujúcimi zdrojovými kódmi (.c), s pomenovaním: + \begin{enumerate} + \item \textbf{charm.h} -- kryptografická knižnica so 6 funkciami, + \item \textbf{os.h} -- funkcie čítania a zápisu paketov, vytvorenia, aplikácie a zrušenia tunelu, + \item \textbf{vpn.h} -- deklarácia konštánt, endianity\cite{endianita} a niektorých závislostí OS. + \end{enumerate} + + V spomenutých hlavičkových súboroch sa nachádzajú deklarácie funkcií, ktoré VPN používa. Definície sú obsahom .c súborov, ako je v jazyku C zaužívaným zvykom. Obsahom tejto podkapitoly je analýza týchto kódov. + + \subsection{Súbor charm.h a charm.c} + Obsahom sú prevažne funkcie slúžiace pri behu kryptografického algoritmu XOODOO. Charm.h pozostáva z 6 funkcií. Ich implementácia nie je až tak rozsiahla. Zaberá celkovo 337 riadkov. Jednotlivú implementáciu každej funkcie postupne opíšeme. + + \begin{minipage}{\linewidth} + \begin{lstlisting}[frame=single, + numbers=left, + caption={Obsah charm.h}\label{charm.h}, + basicstyle=\ttfamily\small, keywordstyle=\color{black}\bfseries,] +void uc_state_init(uint32_t st[12], const unsigned char key[32], + const unsigned char iv[16]); +void uc_encrypt(uint32_t st[12], unsigned char *msg, + size_t msg_len, unsigned char tag[16]); +int uc_decrypt(uint32_t st[12], unsigned char *msg, + size_t msg_len, + const unsigned char *expected_tag, + size_t expected_tag_len); +void uc_hash(uint32_t st[12], unsigned char h[32], + const unsigned char *msg, size_t len); +void uc_memzero(void *buf, size_t len); +void uc_randombytes_buf(void *buf, size_t len); + \end{lstlisting} + \end{minipage}\\ + \subsection{Súbor os.h a os.c} + Obsahom su funkcie, ktorých úlohami sú čítanie alebo pridanie \acrshort{gw}, vytvorenie a nastavenie tunelu v danom OS. Následne je aplikovaná úprava firewall pravidiel, tak aby všetka komunikácia bola presmerovaná na VPN server. Úprava firewall pravidiel je závislá od role, pod ktorou je VPN spustená. Teda či sa jedná o server alebo klienta. + Celkovo je obsahom 12 funkcií, ktoré riešia uvedené úlohy. Detail je možné vidiet v \ref{os.h}. + + \begin{minipage}{\linewidth} + \begin{lstlisting}[frame=single, + numbers=left, + caption={Obsah ZK os.h}\label{os.h}, + basicstyle=\ttfamily\small, keywordstyle=\color{black}\bfseries,] + ssize_t safe_read(const int fd, void *const buf_, size_t count, + const int timeout); + ssize_t safe_write(const int fd, const void *const buf_, + size_t count, + const int timeout); + ssize_t safe_read_partial(const int fd, void *const buf_, + const size_t max_count); + ssize_t safe_write_partial(const int fd, void *const buf_, + const size_t max_count); + + typedef struct Cmds { + const char *const *set; + const char *const *unset; + } Cmds; + + Cmds firewall_rules_cmds(int is_server); + int shell_cmd(const char *substs[][2], const char *args_str, + int silent); + const char *get_default_gw_ip(void); + const char *get_default_ext_if_name(void); + int tcp_opts(int fd); + int tun_create(char if_name[IFNAMSIZ], const char *wanted_name); + int tun_set_mtu(const char *if_name, int mtu); + ssize_t tun_read(int fd, void *data, size_t size); + ssize_t tun_write(int fd, const void *data, size_t size); +\end{lstlisting} +\end{minipage}\\ + \subsection{Súbor vpn.h a vpn.c} + Hlavičkový súbor obsahuje prevažne definovanie niektorých parametrov potrebných na správnu funkcionalitu VPN, spoločne s korekciou pre niektoré OS. Viď. \ref{vpn.h}. Ostatné parametre, ktoré bolí opísané pri spustení su definované práve v tomto súbore (MTU,Porty,IP atď.). + + \begin{minipage}{\linewidth} + \begin{lstlisting}[frame=single, + numbers=left, + caption={Obsah ZK vpn.h}\label{vpn.h}, + basicstyle=\ttfamily\small, keywordstyle=\color{black}\bfseries,] + /*UNIX-like OS Dependent Libraries*/ + #include + #include + #include + #include + #include + #include + #include + #include + /*End UNIX-like OS Dependent Libraries*/ + /*OS setup dependencies*/ + #ifdef __linux__ + #include + #endif + + #ifdef __APPLE__ + #include + #include + #include + #endif + + #ifdef __NetBSD__ + #define DEFAULT_MTU 1500 + #else + #define DEFAULT_MTU 9000 + #endif + /*End of OS setup dependencies*/ + \end{lstlisting} +\end{minipage}\\ + +\subsubsection{Main() -- Beh programu} +Pred samotným opisom by som rád upozornil na jeden fakt. Autor DSVPN používa vo veľkej miere zápis pomocou tzv. ternárnych operátorov. Viac informácií o tejto problematike je možné nájsť v \cite{ternary}. + +Vpn.c je hlavným zdrojovým kódom DSVPN. V jeho vnútri nájdeme hlavnú, štartovaciu, funkciu main. Zároveň má prilinkované aj vyššie uvedené knižnice. Ako prvé dochádza k inicializácií premennej štruktúry \lstinline|Context|\ref{context}. + +\begin{minipage}{\linewidth} + \begin{lstlisting}[frame=single, + numbers=left, + caption={Štruktúra Context}\label{context}, + basicstyle=\ttfamily\small, keywordstyle=\color{black}\bfseries,] +typedef struct Context_ { + const char * wanted_if_name; + const char * local_tun_ip; + const char * remote_tun_ip; + const char * local_tun_ip6; + const char * remote_tun_ip6; + const char * server_ip_or_name; + const char * server_port; + const char * ext_if_name; + const char * wanted_ext_gw_ip; + char client_ip[NI_MAXHOST]; + char ext_gw_ip[64]; + char server_ip[64]; + char if_name[IFNAMSIZ]; + int is_server; + int tun_fd; + int client_fd; + int listen_fd; + int congestion; + int firewall_rules_set; + Buf client_buf; + struct pollfd fds[3]; + uint32_t uc_kx_st[12]; + uint32_t uc_st[2][12]; +} Context; + \end{lstlisting} +\end{minipage}\\ + + Následne dochádza k načítaniu kľúča pomocou pomocnej funkcie +\\ + \lstinline|load_key_file()|\ref{load}. Úlohou je prepočítanie zdieľaného kľúča, pričom sa používa funkcia z os.c -- \lstinline|safe_read()|. Realizuje sa znakové spočítanie, v ktorom je zakomponovaná funkcia \lstinline|poll()|\cite{poll}. V prípade zhody veľkosti, funkcia vracia 0. + + \begin{minipage}{\linewidth} + \begin{lstlisting}[frame=single, + numbers=left, + caption={Načítanie zdieľaného kľúča}\label{load}, + basicstyle=\ttfamily\small, keywordstyle=\color{black}\bfseries,] + static int load_key_file(Context *context, const char *file) + { + unsigned char key[32]; + int fd; + + if ((fd = open(file, O_RDONLY)) == -1) { + return -1; + } + if (safe_read(fd, key, sizeof key, -1) != sizeof key) { + (void) close(fd); + return -1; + } + uc_state_init(context->uc_kx_st, key, + (const unsigned char *) "VPN Key Exchange"); + uc_memzero(key, sizeof key); + + return close(fd); + } + \end{lstlisting} +\end{minipage}\\ + + Po preverení kľúča dochádza k priradeniu parametrov do štruktúry \lstinline|Context| na základe vstupu pri spustení DSVPN. V prípade že nedochádza k zmene GateWay (ďalej \acrshort{gw}) IP adresy, tak sa priradí pôvodná. Tá sa získa pomocou \\\lstinline|get_default_gw_ip()|, ktorá je deklarovaná v \ref{os.h}. Prostredníctvom shell príkazu \lstinline|ip route...| a \lstinline|read_from_shell_command()| funkcie, dochádza k extrakcii informácií priamo z príkazového riadka. Tento krok je teda závislý od \acrshort{os}, v ktorom používateľ pracuje. Nasleduje overenie návratových hodnôt z funkcií iba v prípade ak je DSVPN spustené ako Klient. + + Program v prípade servera pokračuje s \lstinline|get_default_ext_if_name()|. Obdobne ako v predchádzajúcom odstavci je realizácia funkcionality, vykonaná pomocou terminálu. Podstata spočíva v zistení mena rozhrania, ktoré bude presmerované na VPN server. + + Po nastavení parametrov sa dostávame k vytvoreniu tunelovacieho rozhrania. V tomto kroku autor používa funckiu \lstinline|tun_create|. Úloha je vysoko závislá od OS. Dôsledkom toho je možné vidieť vetvenie funkcionality vzhľadom k bežiacemu OS. Ako sa už spomínalo v úvode kapitoly. DSVPN poskytuje kompatibilitu pre 6 OS, medzi ktoré patrí Linux, FreeBSD, NetBSD, OpenBSD, MacOS, DragonFly. Následne na základe systému dochádza k vytváraniu tunelu s prednastaveným, resp. zvoleným menom. Program ďalej nastaví hodnotu MTU. + + Po príprave tunelu ešte repetitívne dochádza k overeniu. Tento krok vykonáva funkcia \lstinline|resolve_ip|. Tá ma v sebe vnorené 2 funkcie, ktoré su menným ekvivalentom aj vo Windows knižniciach. Jedná sa o funkcie \lstinline|getaddrinfo| a \lstinline|getnameinfo|. + + Posledným krokom súvisiacim s konfiguráciou prostredia je vytvorenie pravidla pre branu FireWall (ďalej \acrshort{fw}). Tento úkon realizuje \lstinline|firewall_rules()|. Tento proces je opäť systémovo závislý. Jeho realizácia je vykonaná pomocou globálne definovanej funkcie \lstinline|Cmds firewall_rules_cmds()|. Tá obsahuje súbor prednastavených príkazov. Ich úlohou je presmerovanie celej premávky cez novovzniknutý tunel. + + Posledným úkonom je samotný beh VPN. Ten spúšťa funkcia \lstinline|doit()|. + Doterajší beh je jednoducho znázornený pomocou flow diagramu \ref{fc1}. + +\begin{figure} + \centering + \includegraphics[width=0.5\textwidth]{figures/fc1} + \caption{Beh DSVPN} + \label{fc1} +\end{figure} + + Od tohto momentu sa presúvame k postupnému vnáraniu do procesu spojenia a spracovania dát. Vo vnútri \lstinline|doit()| dochádza k vetveniu programu. V prípade, že je DSVPN spustená ako server spustí sa funkcia \lstinline|tcp_listener()|. V opačnom prípade \lstinline|client_reconnect()|. Ulohami funkcií je nastolenie TCP spojenia medzi clientom a serverom. Listener vytvára socket pomocou systemovej funkcie \lstinline|bind()|, ktorý následne čaká na klienta. Smerník na socket je uložený do štruktúry Context. V tejto vetve sa v Context ešte nastaví smerovanie na tento socket. \lstinline|Client_reconnect()| podľa prednastaveného počtu pokusov o znovu nadviazanie spojenia sa pokúša pomocou \lstinline|client_connect()| o spojenie. Pred týmto úkonom samozrejme dochádza k overeniu či už nedošlo k nadviazaniu spojenia a o to sa stará \lstinline|client_disconnect()|. + + + + \lstinline|Client_connect()| slúži na pripojenie klienta k serveru. Vykonáva úpravu pravidiel v \acrshort{fw}. Následne sa pokúša o nadviazania spojenia pomocou funkcie \lstinline|tcp_client()|. Po tejto sérií úloh sa vraciame opäť do \lstinline|doit()|. Tu je vo \lstinline|while| cykle vykonávaná funkcia \lstinline|event_loop()|, v ktorej dochádza k použitiu kryptografickej knižnice charm. Jej obsahom je inicializácia premenných. viď. \ref{el}. Schéma \ref{fc2} znázorňuje opísané skutočnosti. + + \begin{minipage}{\linewidth} + \begin{lstlisting}[frame=single, + numbers=left, + caption={Premenné funkcie event loop}\label{el}, + basicstyle=\ttfamily\small, keywordstyle=\color{black}\bfseries,] + struct pollfd *const fds = context->fds; + Buf tun_buf; + Buf * client_buf = &context->client_buf; + ssize_t len; + int found_fds; + int new_client_fd; + \end{lstlisting} +\end{minipage}\\ + + + +\begin{figure} + \centering + \includegraphics[width=0.9\textwidth]{figures/fc2} + \caption{Funkcia Doit()} + \label{fc2} +\end{figure} + + \subsubsection{Funckia event\_loop()} + Event\_loop je 111 riadkov dlhá funkcia. Jej obsah môžeme rozdeliť na overovací a výkonový. Úlohou niekoľkých if-ou vo funkcii je preverovanie signálov, spätných hodnôt a podobných premenných, ktoré by signalizovali chybu alebo používateľov záujem o ukončenie relácie programu. + + Zaujímavé je taktiež predom definované makro \lstinline|BUFFERBLOAT_CONTROL|. Jeho úlohou je zamedzenie problému zvaného \textbf{Bufferbloat}. V skratke, je to nechcený jav, ktorý je zapríčinený nadmerným ukladaním paketov do vyrovnávacej pamäte, tzv. zahltenie. To ma za následok vysokú latenciu a tzv. Packet Delay Variation -- \acrshort{pdv} (Jitter), v paketovo-orientovaných sieťach. Viac o tejto problematike je možne si prečítať na \cite{bufferbloat}. + + Na druhej strane výkonové funkcie, ako hovorí ich názov. niečo vykonávajú. Do tejto kategórie sme zaradili funkcie: + \begin{itemize} + \item\lstinline|tcp_accept()| -- slúži na nastolenie nového TCP spojenia s klientom, + \item\lstinline|tun_read()| -- volá \lstinline|safe_read_partial| v prípade linuxového OS, + \item\lstinline|uc_encrypt()| -- kryptografické šifrovanie správy, + \item\lstinline|safe_write_partial()| -- používa štandardizovanú funkciu write vo while cykle, zapíše zašifrované dáta do buffera určeného pre odoslanie klientovi, vracia počet zapísaných dát, + \item\lstinline|safe_write()| -- používa sa v prípade ak došlo k zahlteniu paketmi, + \item\lstinline|client_reconnect()| -- slúži na obnovu spojenia v prípade chyby, + \item\lstinline|safe_read_partial()| -- obdobne ako pri write, používa read funkciu, + \item\lstinline|uc_decrypt()| -- kryptografické dešifrovanie správy, + \item\lstinline|tun_write()| -- volá \lstinline|safe_write| pri OS Linux. + \end{itemize} +Metóda použitá pri zápise zašifrovaných dát vo funkcii \lstinline|event_loop()| je znázornená v \ref{ed}. + + \begin{minipage}{\linewidth} + \begin{lstlisting}[frame=single, + numbers=left, + caption={Spôsob zápisu šifrovaných dát}\label{ed}, + basicstyle=\ttfamily\small, keywordstyle=\color{black}\bfseries,] + + writenb = safe_write_partial(context->client_fd, tun_buf.len, + 2U + TAG_LEN + len); + if (writenb < (ssize_t) 0) {// kontrola zahltenia -- bufferbloat + context->congestion = 1; + writenb = (ssize_t) 0; + } +// ak je iny objem ako maximum + if (writenb != (ssize_t)(2U + TAG_LEN + len)) { + writenb = safe_write(context->client_fd, tun_buf.len + writenb, + 2U + TAG_LEN + len - writenb, TIMEOUT); + } + \end{lstlisting} +\end{minipage}\\ + +\subsubsection{Šifrovanie a dešifrovanie} +Proces šifrovanie resp. dešifrovania správy nastáva na oboch stránách siete, teda pri klientovy aj serveri. \ref{SS} demonštruje šifrovanie implementované v funkcii \lstinline|uc_encrypt()|. Tento proces sme sa pokúsili opísať v grafe \ref{fc3}. + +\begin{figure} + \centering + \includegraphics[width=0.7\textwidth]{figures/fc3} + \caption{Funkcia uc\_encrypt} + \label{fc3} +\end{figure} + +\begin{minipage}{\linewidth} + \begin{lstlisting}[frame=single, + numbers=left, + caption={Šifrovanie správy}\label{SS}, + basicstyle=\ttfamily\small, keywordstyle=\color{black}\bfseries,] + +void uc_encrypt(uint32_t st[12], unsigned char *msg, + size_t msg_len, unsigned char tag[16]) +{ //spracovanie po 16 znakov + unsigned char squeezed[16]; + unsigned char padded[16 + 1]; + size_t off = 0; + size_t leftover; + + if (msg_len > 16) { + for (; off < msg_len - 16; off += 16) { + endian_swap_rate(st); + memcpy(squeezed, st, 16); + xor128(st, &msg[off]); + endian_swap_rate(st); + xor128(&msg[off], squeezed); + permute(st); + } + } + leftover = msg_len - off; + memset(padded, 0, 16); + mem_cpy(padded, &msg[off], leftover); + padded[leftover] = 0x80; + endian_swap_rate(st); + memcpy(squeezed, st, 16); + xor128(st, padded); + endian_swap_rate(st); + st[11] ^= (1UL << 24 | (uint32_t) leftover >> 4 << 25 + | 1UL << 26); + xor128(padded, squeezed); + mem_cpy(&msg[off], padded, leftover); + permute(st); + squeeze_permute(st, tag); +} + \end{lstlisting} +\end{minipage}\\ + +Ako je viditeľne v kóde dochádza k častému použitiu 2 funkcií. Nimi sú \lstinline|xor128()| a \lstinline|permute()|. Jedná sa o pomerne dôležité bloky pre správne fungovanie šifrovacieho algoritmu. Obsah prvej z uvedených je preto znázornený v \ref{xor}. + +\begin{minipage}{\linewidth} + \begin{lstlisting}[frame=single, + numbers=left, + caption={Funkcia xor128}\label{xor}, + basicstyle=\ttfamily\small, keywordstyle=\color{black}\bfseries,] +static inline void xor128(void *out, const void *in) +{ + #ifdef __SSSE3__ + _mm_storeu_si128((__m128i *) out, + _mm_xor_si128(_mm_loadu_si128((const __m128i *) out), + _mm_loadu_si128((const __m128i *) in))); + #else + unsigned char * out_ = (unsigned char *) out; + const unsigned char *in_ = (const unsigned char *) in; + size_t i; + + for (i = 0; i < 16; i++) { //xororvanie jednotlivych znakov + out_[i] ^= in_[i]; //v 16 bitovom bloku spravy + } + #endif +} + \end{lstlisting} +\end{minipage}\\ + +Na druhej strane \lstinline|permute()| je pomerne rozsiahla funkcia pričom jej obsah sa rozprestiera na 100 riadkoch. Funkcionalita závisí od procesorových inštrukcií. Avšak nás bude zaujímať softvérová implementácia, ktorá je aj použitá pri behu. Dôvodom je, že naše zariadenie nemá k dispozícií uvedené procesorové inštrukcie. Blok, ktorý je použitý pri volaní sa nachádza v \ref{permute}. + +\begin{minipage}{\linewidth} + \begin{lstlisting}[frame=single, + numbers=left, + caption={Funkcia Permute + makrá }\label{permute}, + basicstyle=\ttfamily\small, keywordstyle=\color{black}\bfseries,] +#define ROTR32(x, b) (uint32_t)(((x) >> (b)) | ((x) << (32 - (b)))) +#define SWAP32(s, u, v) \ +do { \ + t = (s)[u]; \ + (s)[u] = (s)[v], (s)[v] = t; \ +} while (0) + +static void permute(uint32_t st[12]) +{ + uint32_t e[4], a, b, c, t, r, i; + for (r = 0; r < XOODOO_ROUNDS; r++) { + for (i = 0; i < 4; i++) { + e[i] = ROTR32(st[i] ^ st[i + 4] ^ st[i + 8], 18); + e[i] ^= ROTR32(e[i], 9); + } + for (i = 0; i < 12; i++) { + st[i] ^= e[(i - 1) & 3]; + } + SWAP32(st, 7, 4); + SWAP32(st, 7, 5); + SWAP32(st, 7, 6); + st[0] ^= RK[r]; + for (i = 0; i < 4; i++) { + a = st[i]; + b = st[i + 4]; + c = ROTR32(st[i + 8], 21); + st[i + 8] = ROTR32((b & ~a) ^ c, 24); + st[i + 4] = ROTR32((a & ~c) ^ b, 31); + st[i] ^= c & ~b; + } + SWAP32(st, 8, 10); + SWAP32(st, 9, 11); + } +} + \end{lstlisting} +\end{minipage}\\ +\chapter{Populárne VPN}\label{zlozitejsia vpn} +V~súčasnosti je trend, využívanie VPN na súkromné účely. Dôvodov môže byť viacero. Napríklad prístup k lokálne blokovaným doménam, anonymita v internetovom prostredí, zabezpečenie pripojenia a iné. V tomto prípade vstupujú do popredia tzv. VPN poskytovatelia (z ang. \textit{VPN Providers}). Ktorý za poplatok poskytujú výhody pripojenia cez VPN k verejnej sieti. + +opis fungovania, demonštrácia v prostredi VB. +\section{OpenVPN} +\section{WireGuard} +\section{Porovnanie -- mohlo by sa, ak sa stihne a bude vediet} diff --git a/templates/compile_template.bat b/templates/compile_template.bat new file mode 100644 index 0000000..91f3cff --- /dev/null +++ b/templates/compile_template.bat @@ -0,0 +1,10 @@ +rem prikazy ktore korektne prelozia Sablonu 2 +rem KEMT FEI TUKE, M.D. 2021-02-21 +rem vysledkom je subor thesis.pdf + +pdflatex thesis.tex +biber thesis +makeindex -s thesis.ist -t thesis.glg -o thesis.gls thesis.glo +makeindex -s thesis.ist -t tthesis.alg -o thesis.acr thesis.acn +pdflatex thesis.tex +pdflatex thesis.tex diff --git a/templates/figures/VPNdemo.png b/templates/figures/VPNdemo.png new file mode 100644 index 0000000..2b4de6a Binary files /dev/null and b/templates/figures/VPNdemo.png differ diff --git a/templates/figures/fc1.pdf b/templates/figures/fc1.pdf new file mode 100644 index 0000000..888c9c5 Binary files /dev/null and b/templates/figures/fc1.pdf differ diff --git a/templates/figures/fc2.pdf b/templates/figures/fc2.pdf new file mode 100644 index 0000000..b7a49f2 Binary files /dev/null and b/templates/figures/fc2.pdf differ diff --git a/templates/figures/fc3.pdf b/templates/figures/fc3.pdf new file mode 100644 index 0000000..430f6ad Binary files /dev/null and b/templates/figures/fc3.pdf differ diff --git a/templates/figures/ipu20.png b/templates/figures/ipu20.png new file mode 100644 index 0000000..dedb640 Binary files /dev/null and b/templates/figures/ipu20.png differ diff --git a/templates/figures/ipu21.png b/templates/figures/ipu21.png new file mode 100644 index 0000000..40db6e7 Binary files /dev/null and b/templates/figures/ipu21.png differ diff --git a/templates/figures/ssl.png b/templates/figures/ssl.png new file mode 100644 index 0000000..d04dddc Binary files /dev/null and b/templates/figures/ssl.png differ diff --git a/templates/figures/tcpipprot.png b/templates/figures/tcpipprot.png new file mode 100644 index 0000000..a4d4f8d Binary files /dev/null and b/templates/figures/tcpipprot.png differ diff --git a/templates/figures/vbmodes.png b/templates/figures/vbmodes.png new file mode 100644 index 0000000..fe7bd73 Binary files /dev/null and b/templates/figures/vbmodes.png differ diff --git a/templates/figures/vpnsimple.jpg b/templates/figures/vpnsimple.jpg new file mode 100644 index 0000000..650d85e Binary files /dev/null and b/templates/figures/vpnsimple.jpg differ diff --git a/templates/figures/vpntru20.png b/templates/figures/vpntru20.png new file mode 100644 index 0000000..767534b Binary files /dev/null and b/templates/figures/vpntru20.png differ diff --git a/templates/figures/xoodooTerminology.png b/templates/figures/xoodooTerminology.png new file mode 100644 index 0000000..012b45c Binary files /dev/null and b/templates/figures/xoodooTerminology.png differ diff --git a/templates/figures/xoodooalgo.png b/templates/figures/xoodooalgo.png new file mode 100644 index 0000000..842866a Binary files /dev/null and b/templates/figures/xoodooalgo.png differ diff --git a/templates/glossary.tex b/templates/glossary.tex new file mode 100644 index 0000000..171c5e6 --- /dev/null +++ b/templates/glossary.tex @@ -0,0 +1,23 @@ +% Glossary +% ======== +% +% A glossary is a list of terms in a particular domain of knowledge with definitions for those terms. +% +% Glossary Definition Exapmle: +% -------- +% \newglossaryentry{class diagram} +% { +% name={Class Diagram}, +% description={is a type of static structure diagram that describes the structure of a system by showing the system's classes, their attributes, operations (or methods), and the relationships among objects} +% } +% +% Usage: +% ------ +% Because most of you will write thesis in Slovak, the best recommendation is to use \glslink command as follows: +% Na konceptuálnom \glslink{class diagram}{diagrame tried}, ktorý sa nachádza na obrázku ... +% +% For more information see: +% ------------------------- +% * https://www.sharelatex.com/learn/Glossaries +% * https://en.wikibooks.org/wiki/LaTeX/Glossary +% diff --git a/templates/kithesis.cls b/templates/kithesis.cls new file mode 100644 index 0000000..07cba4b --- /dev/null +++ b/templates/kithesis.cls @@ -0,0 +1,679 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% +%% KPI Thesis Class. +%% +%% Class for writing bachelor/master/phd thesis at Computer Science department +%% at Faculty of Electrical Engineering and Informatics and Technical University +%% of Košice. +%% +%% department homepage: http://kpi.fei.tuke.sk +%% project homepage: https://git.kpi.fei.tuke.sk/tuke/thesis.in.latex +%% +%%%%% +\NeedsTeXFormat{LaTeX2e} +\ProvidesClass{kithesis}[2021/03/23 KPI Thesis Class, v2021.2] + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% +%% Using report class as base. +%% +%%%%% +\PassOptionsToClass{a4paper,12pt,oneside}{report} +\LoadClass{report} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% +%% Additional packages, and their options. +%% +%%%%% + +\RequirePackage{pdfpages} + +% titlesec for modification of chapters and sections +\RequirePackage{titlesec} +\titleformat{\chapter} + {\huge}{\textbf\thechapter}{20pt}{\huge\textbf}[{\titlerule[0.8pt]}] + +% sets the document geometry +\RequirePackage[ + a4paper, + %width=150mm, + top=25mm, + bottom=25mm, + left=30mm, + right=25mm, + bindingoffset=6mm +]{geometry} + +\RequirePackage{graphicx} +\DeclareGraphicsExtensions{.pdf,.png,.jpg,.eps,.svg} + +\RequirePackage[utf8]{inputenc} +\RequirePackage[T1]{fontenc} + +\RequirePackage[ + figure, + table]{totalcount} + +%% Numeric citations and sorting by citation order +\RequirePackage{csquotes} +\RequirePackage[ + bibencoding=auto, + style=iso-numeric, % numeric citations according for ISO 690 + autolang=other, + sorting=none, % sort by order of citation + backend=biber % different backend +]{biblatex} + +% location of file with bibliography resources +\addbibresource{chapters/bibliography.bib} + +% slovak translation of bibliography +\DefineBibliographyStrings{slovak}{% + bibliography = {Literatúra} +} + +\RequirePackage[ + unicode, + %backref, + pdfusetitle, + %pdfusekeywords, + pdftoolbar=true, + pdfmenubar=true, + pdfwindowui=true, + bookmarksopenlevel={0}, + bookmarksnumbered, + bookmarksopen, + pdfhighlight={/P}, + colorlinks=false, % TODO draft vs publish ready? + %hidelinks, % disable color links completly + citecolor=magenta, + baseurl={https://kpi.fei.tuke.sk/} +]{hyperref} + +% PDF metadata based on macro values +\AtBeginDocument{ + \hypersetup{ + pdftitle = {\@title@en}, + pdfauthor = {\@author}, + pdfkeywords = {\@keywords@en}, + pdfsubject = {\@thesis} + } +} + +% popisky ku obrazkom a tabulkam +\RequirePackage[small]{caption} +\setlength{\captionmargin}{25pt} + +% TODO These commande probably have no effect, because are overriden by babel +\def\figurename{Obrázok} +\def\tabname{Tabuľka} +% \def\refname{Zoznam použitej literatúry} % TODO replaced by biblatex stuff, should be \bibname either + +%% Vlastná hlavička +\RequirePackage{fancyhdr} +\setlength{\headheight}{15pt} + +% nastavenie hlavičky pre hlavnú časť práce +\pagestyle{fancy} +\renewcommand{\chaptermark}[1]{ + \markboth{\ifnum\value{chapter}>0 \chaptername\ \thechapter.\ \fi #1}{} +} +\fancyhf{} +\rhead{\itshape \nouppercase{\leftmark}} +\rfoot{\thepage} + + +% štýl pre prvú stranu kapitoly (plain s číslom strany v päte zarovnaný vpravo) +\fancypagestyle{chapterpage}{ + \fancyhf{} + \renewcommand\headrulewidth{0pt} + \rfoot{\thepage} +} + + +% zmena štýlu prvej stránke kapitoly +\renewcommand\chapter{\if@openright\cleardoublepage\else\clearpage\fi + \thispagestyle{chapterpage}% + \global\@topnum\z@ + \@afterindentfalse + \secdef\@chapter\@schapter} + +\renewcommand{\headrulewidth}{0.7pt} + + +% slovnik terminov a skratiek +\RequirePackage[ + toc, + acronym, + nonumberlist, + noredefwarn +]{glossaries} +\loadglsentries{glossary} +\makeglossaries % prikaz na vytvorenie suboru .glo + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% +%% Variable definitions and default values: these variables should be defined by +%% the user (somewhere in the preamble). For example, to put the abstract into +%% the thesis, the thesis writer should type the following somewhere in the +%% preamble (before the `\begin{document}` or `\frontmatter` commands are +%% called): +%% +%% \abstract{This is my abstract.} +%% +%% See below (in the comments starting with 'DOCVAR: ') for a list of all +% variables +%% the thesis writer is expected to use. +%% +%%%%% + +\def\br{\\} + +% DOCVAR: thesisspec (The list of thesis specifications) +\newcommand{\@thesisspec}{ + \thispagestyle{empty} + \vspace*{\fill} + \begin{center} + \iflanguage{slovak}{ + Tu vložte zadávací list pomocou príkazu\\ + {\tt{\textbackslash{}thesisspec\{cesta/k/suboru/so/zadavacim.listom\}}}\\ + v preambule dokumentu. + + Kópiu zadávacieho listu skenujte čiernobielo (v odtieňoch sivej) na $200$ až $300$ DPI! + Nezabudnite do jednej práce vložiť originál zadávacieho listu! + }{ + Here insert the assignment statement using the command\\ + {\tt{\textbackslash{}thesisspec\{path/to/the/filw/with/assignment.statement\}}}\\ + in the preamble of the document. + + Copy of the assignment statement should be scanned black\&white (grayscale) using DPI from $200$ to $300$! + Don't forget to insert the original assignment statement into one of the theses copies. + } + \end{center} + \vspace*{\fill} + \newpage +} +\newcommand{\thesisspec}[1]{ + \renewcommand{\@thesisspec}{ + \includepdf[pages={-}]{#1} + } +} + + +% Command for author's name in the form of: [affil]{Name}{Surname}[affil] +% Second optional argument using https://texfaq.org/FAQ-twooptarg +\newcommand{\@author@prefix}{} +\newcommand{\@author@firstname}{} +\newcommand{\@author@lastname}{} +\newcommand{\@author@postfix}{} +\renewcommand\author[3][]{ + \renewcommand{\@author@prefix}{#1} + \renewcommand{\@author@firstname}{#2} + \renewcommand{\@author@lastname}{#3} + \authorpostfix +} +\newcommand\authorpostfix[1][]{ + \renewcommand{\@author@postfix}{#1} +} + + +% DOCVAR: college (The name of the thesis writer's college) +\newcommand{\@college@en}{Technical University of Košice} +\newcommand{\@college@sk}{Technická univerzita v Košiciach} +\newcommand{\@college}{\@college@en} +\newcommand{\college}[2]{ + \renewcommand{\@college@en}{#1} + \renewcommand{\@college@sk}{#2} +} + +\newcommand{\@college@city}{Košice} + +% DOCVAR: faculty (The name of the thesis writer's faculty) +\newcommand{\@faculty@en}{Faculty of Electrical Engineering and Informatics} +\newcommand{\@faculty@sk}{Fakulta elektrotechniky a informatiky} +\newcommand{\@faculty}{\@faculty@en} +\newcommand{\faculty}[2]{ + \renewcommand{\@faculty@en}{#1} + \renewcommand{\@faculty@sk}{#2} +} + + +% DOCVAR: department (name of the thesis writer's department) +\newcommand{\@department@en}{Department of Computers and Informatics} +\newcommand{\@department@sk}{Katedra počítačov a informatiky} +\newcommand{\@department}{\@department@en} +\newcommand{\department}[2]{ + \renewcommand{\@department@en}{#1} + \renewcommand{\@department@sk}{#2} +} + +% DOCVAR: department's shortcut +\newcommand{\@departmentacr@en}{DCI} +\newcommand{\@departmentacr@sk}{KPI} +\newcommand{\@departmentacr}{\@departmentacr@en} +\newcommand{\departmentacr}[2]{ + \renewcommand{\@departmentacr@en}{#1} + \renewcommand{\@departmentacr@sk}{#2} +} + + +% DOCVAR: supervisor (name of the thesis writer's supervisor) +\newcommand{\@supervisor}{} +\newcommand{\supervisor}[1]{\renewcommand{\@supervisor}{#1}} + +% DOCVAR: consultant (name of the thesis writer's consultant) +\newcommand{\@consultant}{} +\newcommand{\consultant}[1]{\renewcommand{\@consultant}{#1}} + +% DOCVAR: field of study +\newcommand{\@fieldofstudy}{9.2.1. Informatika} +\newcommand{\fieldofstudy}[1]{\renewcommand{\@fieldofstudy}{#1}} + +% DOCVAR: study programme +\newcommand{\@studyprogramme}{Informatika} +\newcommand{\studyprogramme}[1]{\renewcommand{\@studyprogramme}{#1}} + +% DOCVAR: thesis (type of the thesis) +\newcommand{\@thesis@en}{Bachelor thesis} +\newcommand{\@thesis@sk}{Bakalárska práca} +\newcommand{\@thesis}{\@thesis@en} +\newcommand{\thesis}[2]{ + \renewcommand{\@thesis@en}{#1} + \renewcommand{\@thesis@sk}{#2} +} + +% DOCVAR: declaration text +\newcommand{\@declaration@en}{I hereby declare that this thesis is my own work and effort. Where other sources of information have been used, they have been acknowledged.} +\newcommand{\@declaration@sk}{Vyhlasujem, že som záverečnú prácu vypracoval samostatne s~použitím uvedenej odbornej literatúry.} +\newcommand{\@declaration}{\@declaration@en} +\newcommand{\declaration}[1]{ + \renewcommand{\@declaration@en}{#1} + \renewcommand{\@declaration@sk}{#1} +} + +% DOCVAR: date (declaration date) +\newcommand{\@submissiondate}{} +\newcommand{\submissiondate}[3]{ + \newcommand{\@submissionday}{#1} + \newcommand{\@submissionmonth}{#2} + \newcommand{\@submissionyear}{#3} +} + +% DOCVAR: abstract of the thesis +\renewcommand{\abstract}[2]{% + \newcommand{\@abstract@en}{#1}% + \newcommand{\@abstract@sk}{#2}% +} +\newcommand{\@abstract}{\@abstract@en} + +% DOCVAR: thesis keywords +\newcommand{\keywords}[2]{% + \newcommand{\@keywords@en}{#1}% + \newcommand{\@keywords@sk}{#2}% +} +\newcommand{\@keywords}{\@keywords@en} + +% DOCVAR: thesis title +\renewcommand{\title}[2]{% + \newcommand{\@title@en}{#1}% + \newcommand{\@title@sk}{#2}% +} +\renewcommand{\@title}{\@title@en} + + +% DOCVAR: thesis (type of the thesis) +\newcommand{\@acknowledgment}{Na tomto mieste by som sa rád poďakoval svojmu vedúcemu záverečnej práce za pripomienky a~odbornú pomoc.} +\newcommand{\acknowledgment}[1]{\renewcommand{\@acknowledgment}{#1}} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% +%% Translations of strings used in the thesis +%% + +% Default empty declarations +\newcommand{\declarationname}{No Language Selected} +\newcommand{\signaturename}{No Language Selected} +\newcommand{\acknowledgementname}{No Language Selected} +\newcommand{\lstlistingname}{No Language Selected} +\newcommand{\studyprogrammename}{No Language Selected} +\newcommand{\fieldofstudyname}{No Language Selected} +\newcommand{\departmentname}{No Language Selected} +\newcommand{\supervisorname}{No Language Selected} +\newcommand{\consultantname}{No Language Selected} +\newcommand{\keywordsname}{No Language Selected} +\newcommand{\secondabstractname}{No Language Selected} +\newcommand{\secondkeywordsname}{No Language Selected} +\newcommand{\bibcitationname}{No Language Selected} +\newcommand{\supervisorcitationname}{No Language Selected} +\newcommand{\acrlistname}{No Language Selected} +\newcommand{\appendixlistname}{No Language Selected} + +\AtBeginDocument{ + \addto\captionsenglish{ + \renewcommand{\@title}{\@title@en} + \renewcommand{\@abstract}{\@abstract@en} + \renewcommand{\@keywords}{\@keywords@en} + \renewcommand{\@college}{\@college@en} + \renewcommand{\@department}{\@department@en} + \renewcommand{\@departmentacr}{\@departmentacr@en} + \renewcommand{\@faculty}{\@faculty@en} + \renewcommand{\@thesis}{\@thesis@en} + \renewcommand{\@declaration}{\@declaration@en} + \renewcommand{\declarationname}{Declaration} + \renewcommand{\signaturename}{Signature} + \renewcommand{\acknowledgementname}{Acknowledgement} + \renewcommand{\studyprogrammename}{Study Programme} + \renewcommand{\fieldofstudyname}{Field of Study} + \renewcommand{\departmentname}{Department} + \renewcommand{\supervisorname}{Supervisor} + \renewcommand{\consultantname}{Consultant} + \renewcommand{\abstractname}{Abstract in English} + \renewcommand{\keywordsname}{Keywords in English} + \renewcommand{\secondabstractname}{Abstract in Slovak} + \renewcommand{\secondkeywordsname}{Keywords in Slovak} + \renewcommand{\bibcitationname}{Bibliographic Citation} + \renewcommand{\supervisorcitationname}{Supervisor} + \renewcommand{\lstlistingname}{Listing} + \renewcommand{\acrlistname}{List of Abbreviations} + \renewcommand{\appendixlistname}{List of Appendixes} + } + \addto\captionsslovak{ + \renewcommand{\@title}{\@title@sk} + \renewcommand{\@abstract}{\@abstract@sk} + \renewcommand{\@keywords}{\@keywords@sk} + \renewcommand{\@college}{\@college@sk} + \renewcommand{\@department}{\@department@sk} + \renewcommand{\@departmentacr}{\@departmentacr@sk} + \renewcommand{\@faculty}{\@faculty@sk} + \renewcommand{\@thesis}{\@thesis@sk} + \renewcommand{\@declaration}{\@declaration@sk} + \renewcommand{\declarationname}{Čestné vyhlásenie} + \renewcommand{\signaturename}{Vlastnoručný podpis} + \renewcommand{\acknowledgementname}{Poďakovanie} + \renewcommand{\studyprogrammename}{Študijný program} + \renewcommand{\fieldofstudyname}{Študijný odbor} + \renewcommand{\departmentname}{Školiace pracovisko} + \renewcommand{\supervisorname}{Školiteľ} + \renewcommand{\consultantname}{Konzultant} + \renewcommand{\abstractname}{Abstrakt v SJ} + \renewcommand{\keywordsname}{Kľúčové slová v SJ} + \renewcommand{\secondabstractname}{Abstrakt v AJ} + \renewcommand{\secondkeywordsname}{Kľúčové slová v AJ} + \renewcommand{\bibcitationname}{Bibliografická citácia} + \renewcommand{\supervisorcitationname}{Vedúci práce} + \renewcommand{\lstlistingname}{Zdrojový kód} + \renewcommand{\acrlistname}{Zoznam skratiek} + \renewcommand{\appendixlistname}{Zoznam príloh} + \renewcommand{\appendixname}{Príloha} + } +} + +% right page number aligment from 2nd page in table of content +\fancypagestyle{plain}{% + \renewcommand{\footrulewidth}{0pt} +} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% +%% Front matter +%% +%% - outside and inside front cover +%% - title leaf +%% Do not include the date of make! +%% Institution + department. +%% Names of referees. (optional) +%% Degree. +%% Date of submission and defense. (optional) +%% Place and date of publication and publishers (and other info by them). +% +\newcommand{\frontmatter}{ + \pagenumbering{roman} + \frontpage + \titlepage + \abstractpage + + % thesis detail specification + \@thesisspec + + \declarationpage + \acknowledgmentpage + + \pagestyle{plain} + \tableofcontents + \newpage + + % show list of figures only if there are some + \iftotalfigures% + \listoffigures% + \newpage% + \fi + + + % show list of tables only if there are some + \iftotaltables% + \listoftables% + \newpage% + \fi + + \renewcommand\lstlistlistingname{Zoznam zdrojových kódov} + \lstlistoflistings{} + \newpage + + \printglossary[type=\acronymtype,title={\acrlistname}] + \newpage + + \pagestyle{fancy} + \pagenumbering{arabic} + \newpage +} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% +%% Front page component +%% +%%%%% +\newcommand{\frontpage}{ + + \thispagestyle{empty} + + \begin{center} + {\Large \textbf{\@college}} + + {\Large \textbf{\@faculty}} + + \vfill + + {\LARGE \textbf{\@title} \par} + + \bigskip + + {\large \textbf{\@thesis}} + \end{center} + + \vfill + + \begin{center} + {\Large \textbf{\@submissionyear}} \hfill {\Large \textbf{\@author@prefix~\@author@firstname~\@author@lastname~\@author@postfix}} + \end{center} + + \newpage +} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% +%% Abstract component +%% +%%%%% + +\newcommand{\abstractpage}{ + \def\br{} + + \thispagestyle{empty} + \noindent + \subsection*{\abstractname} + + \@abstract + + \subsection*{\keywordsname} + + \@keywords + + \iflanguage{slovak}{ + \subsection*{\secondabstractname} + + \begin{otherlanguage}{english} + \@abstract + \end{otherlanguage} + + \subsection*{\secondkeywordsname} + + \begin{otherlanguage}{english} + \@keywords + \end{otherlanguage} + }{ + \subsection*{\secondabstractname} + + \begin{otherlanguage}{slovak} + \@abstract + \end{otherlanguage} + + \subsection*{\secondkeywordsname} + + \begin{otherlanguage}{slovak} + \@keywords + \end{otherlanguage} + } + + \vfill + + \subsection*{\bibcitationname} + + \MakeUppercase\@author@lastname, \@author@firstname. {\itshape \@title}. \@college@city: \@college, \@faculty, \@submissionyear. \pageref{theend}s. \supervisorcitationname: \@supervisor + + \newpage + + \def\br{\\} +} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% +%% Declaration component +%% +%%%%% +\newcommand\declarationpage{ + \thispagestyle{empty} + + \vglue0pt + \vfill + \subsection*{\declarationname} + + \noindent\@declaration + + \bigskip + + \noindent \@college@city,~\@submissionday.\@submissionmonth.\@submissionyear \hfill + \begin{tabular}[t]{c} + \hbox to 50mm {\dotfill} \\ \textit{\small \signaturename} + \end{tabular} + \newpage +} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% +%% Declaration component +%% +%%%%% +\newcommand\acknowledgmentpage{% + \thispagestyle{empty}% + \vglue0pt\vfill% + + \subsection*{\acknowledgementname}% + + \@acknowledgment + + \newpage +} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% +%% Title page component +%% +%%%%% +\renewcommand{\titlepage}{ + \thispagestyle{empty} + + \begin{center} + {\Large \textbf{\@college}} + + {\Large \textbf{\@faculty}} + + \vfill + + {\LARGE \textbf{\@title} \par} + + \bigskip + + {\large \textbf{\@thesis}} + \end{center} + + \vfill + + \noindent + \begin{tabular}{@{}p{.26\textwidth}p{.7\textwidth}} + \studyprogrammename:& \@studyprogramme \\ + \fieldofstudyname:& \@fieldofstudy \\ + \departmentname:& \@department~(\@departmentacr) \\ + \supervisorname:& \@supervisor \\ + \consultantname:& \@consultant \\ + \end{tabular} + + \vspace{2\baselineskip} + + \begin{center} + \centering + {\Large \textbf{\@college@city{} \@submissionyear}} \hfill {\Large \textbf{\@author@prefix~\@author@firstname~\@author@lastname~\@author@postfix}} + \end{center} + + \newpage +} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% +%% Fonts +%% +%%%%% + +% Font for some math characters to work with TeX Gyre Pagella font + +\RequirePackage{textcomp} + +% Font used for thesis is TeX Gyre Pagella. +% Note: You might need to install it first. + +\RequirePackage{tgpagella} + +% Use TXTT as a typewriter font. It supports bold and matches Pagella in style. +\renewcommand*\ttdefault{txtt} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% +%% Line spacing and paragraph indentation +%% +%%%%% + +\linespread{1.3} +\setlength{\parindent}{1.5em} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newcommand{\blindtext}{Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Etiam lobortis facilisissem. Nullam nec mi et neque pharetra sollicitudin. Praesent imperdiet mi necante. Donec ullamcorper, felis non sodales commodo, lectus velit ultrices augue, a dignissim nibh lectus placerat pede. Vivamus nunc nunc, molestie ut, ultriciesvel, semper in, velit. Ut porttitor. Praesent in sapien. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Duis fringilla tristique neque. Sed interdum libero utmetus. Pellentesque placerat. Nam rutrum augue a leo. Morbi sed elit sit ametante lobortis sollicitudin. Praesent blandit blandit mauris. Praesent lectus tellus, aliquet aliquam, luctus a, egestas a, turpis. Mauris lacinia lorem sit amet ipsum. Nunc quis urna dictum turpis accumsan semper.} diff --git a/templates/kithesis.pdf b/templates/kithesis.pdf new file mode 100644 index 0000000..1a1ede9 Binary files /dev/null and b/templates/kithesis.pdf differ diff --git a/templates/kithesis.sty b/templates/kithesis.sty new file mode 100644 index 0000000..b7d3f21 --- /dev/null +++ b/templates/kithesis.sty @@ -0,0 +1,4 @@ +\NeedsTeXFormat{LaTeX2e} +%\@obsoletefile{article.cls}{article.sty} +\LoadClass{kithesis} +\endinput diff --git a/templates/kithesis.synctex(busy) b/templates/kithesis.synctex(busy) new file mode 100644 index 0000000..e69de29 diff --git a/templates/latexmkrc b/templates/latexmkrc new file mode 100644 index 0000000..3dec073 --- /dev/null +++ b/templates/latexmkrc @@ -0,0 +1,13 @@ +# Building glossaries. Copied from +# http://mirrors.ctan.org/support/latexmk/example_rcfiles/glossary_latexmkrc + +add_cus_dep( 'acn', 'acr', 0, 'makeglossaries' ); +add_cus_dep( 'glo', 'gls', 0, 'makeglossaries' ); +$clean_ext .= " acr acn alg glo gls glg"; +sub makeglossaries { + my ($base_name, $path) = fileparse( $_[0] ); + pushd $path; + my $return = system "makeglossaries", $base_name; + popd; + return $return; +} diff --git a/templates/thesis.pdf b/templates/thesis.pdf new file mode 100644 index 0000000..9679d37 Binary files /dev/null and b/templates/thesis.pdf differ diff --git a/templates/thesis.tex b/templates/thesis.tex new file mode 100644 index 0000000..f71a0d6 --- /dev/null +++ b/templates/thesis.tex @@ -0,0 +1,164 @@ +%% ----------------------------------------------------------------- +%% This file uses UTF-8 encoding +%% +%% For compilation use following command: +%% latexmk -pdf -pvc -bibtex thesis +%% +%% ----------------------------------------------------------------- +%% _ _ +%% _ __ _ __ ___ __ _ _ __ ___ | |__ | | ___ +%% | '_ \| '__/ _ \/ _` | '_ ` _ \| '_ \| |/ _ \ +%% | |_) | | | __/ (_| | | | | | | |_) | | __/ +%% | .__/|_| \___|\__,_|_| |_| |_|_.__/|_|\___| +%% |_| +%% +%% ----------------------------------------------------------------- +\documentclass{kithesis} + +% Additional packages +\usepackage[main=slovak,english]{babel} +\usepackage{listings} +\usepackage{amsmath} +\usepackage{multirow} +\usepackage{booktabs} +\usepackage{indentfirst} +\usepackage{dirtree} +\usepackage{hyperref} + % for source code +% Listings settings +% See for details: https://en.wikibooks.org/wiki/LaTeX/Source_Code_Listings +\lstset{ % nastavení + % Definice jazyka použitého ve výpisech + % language=[LaTeX]{TeX}, % LaTeX + % language={Matlab}, % Matlab + language={C}, % jazyk C + basicstyle=\ttfamily, % definice základního stylu písma + tabsize=2, % definice velikosti tabulátoru + mathescape=, + inputencoding=utf8, % pro soubory uložené v kódování UTF-8 + columns=fixed, %fixed nebo flexible, + fontadjust=true %licovani sloupcu + extendedchars=true, + literate=% definice symbolů s diakritikou + {á}{{\'a}}1 + {č}{{\v{c}}}1 + {ď}{{\v{d}}}1 + {é}{{\'e}}1 + {ě}{{\v{e}}}1 + {í}{{\'i}}1 + {ň}{{\v{n}}}1 + {ó}{{\'o}}1 + {ř}{{\v{r}}}1 + {š}{{\v{s}}}1 + {ť}{{\v{t}}}1 + {ú}{{\'u}}1 + {ů}{{\r{u}}}1 + {ý}{{\'y}}1 + {ž}{{\v{z}}}1 + {Á}{{\'A}}1 + {Č}{{\v{C}}}1 + {Ď}{{\v{D}}}1 + {É}{{\'E}}1 + {Ě}{{\v{E}}}1 + {Í}{{\'I}}1 + {Ň}{{\v{N}}}1 + {Ó}{{\'O}}1 + {Ř}{{\v{R}}}1 + {Š}{{\v{S}}}1 + {Ť}{{\v{T}}}1 + {Ú}{{\'U}}1 + {Ů}{{\r{U}}}1 + {Ý}{{\'Y}}1 + {Ž}{{\v{Z}}}1 +} +\def\lstlistingname{Zdrojový kód} + +% Variables +%zadanie z maisu +%\thesisspec{figures/meno.png} + +\title{Cryptography in VPN networks \br)}{Kryptografia vo VPN sieťach\br } + + +\author{Marek}{Rohač} +\supervisor{prof. Ing. Miloš Drutarovský, CSc.} %veduci prace +\consultant{} %konzultant +\college{Technical University of Košice}{Technická univerzita v Košiciach} %univerzita +\faculty{Faculty of Electrical Engineering and informatics}{Fakulta elektrotechniky a informatiky} %fakulta +\department{Department of electronies and multimedia telecommunications}{Katedra elektroniky a multimediálnych telekomunikácií} %katedra +\departmentacr{DEMT}{KEMT} % skratka katedry +\thesis{Master thesis}{Diplomová práca} %typ prace +\submissiondate{ 28}{ 5}{ 2023} +\fieldofstudy{Informatika} +\studyprogramme{Počítačové siete} +%\city{Košice} +\keywords{VPN}{VPN} +\declaration{Vyhlasujem, že som záverečnú prácu vypracoval samostatne s použitím uvedenej odbornej literatúry.} + +\abstract{english +}{slovak} + + +\acknowledgment{Na~tomto mieste by~som rád poďakoval svojmu vedúcemu práce \textit{prof. Ing. Milošovi Drutarovskému, CSc.} za jeho čas a odborné vedenie počas celého riešenia záverečnej práce.} + +% if you want to work only on selected chapters +%\includeonly{chapters/analyza} %,chapters/synteza} +% Load acronyms +\input{acronyms} + + + +%% ----------------------------------------------------------------- +%% _ _ +%% __| | ___ ___ _ _ _ __ ___ ___ _ __ | |_ +%% / _` |/ _ \ / __| | | | '_ ` _ \ / _ \ '_ \| __| +%% | (_| | (_) | (__| |_| | | | | | | __/ | | | |_ +%% \__,_|\___/ \___|\__,_|_| |_| |_|\___|_| |_|\__| +%% +%% ----------------------------------------------------------------- + +\begin{document} +%% Title page, abstract, declaration etc.: +\frontmatter{} + +%% List of code listings, if you are using package minted +%\renewcommand\lstlistlistingname{Zoznam zdrojových kódov} +%\lstlistoflistings{} + +\pagenumbering{arabic} + +%% Chapters +\include{chapters/introduction} +\include{chapters/analysis} +\include{chapters/synthesis} +\include{chapters/evaluation} +\include{chapters/summary} + +% good linebraking of bibtex url +\setcounter{biburllcpenalty}{7000} +\setcounter{biburlucpenalty}{8000} + +%% The bibliography +\printbibliography[heading=bibintoc] + +\label{theend} % the last page of the thesis + +% List of acronyms + +% Glossaries +%\printglossary + +%% Appendix +\include{appendixes/prilohy} +\appendix +\renewcommand\chaptername{Príloha} +\include{appendixes/prilohaa} + +% zivotopis autora +%\curriculumvitae\protect +%Táto časť\/ je nepovinná. Autor tu môže uviesť\/ svoje biografické +%údaje, údaje o~záujmoch, účasti na~projektoch, účasti na~súťažiach, +%získané ocenenia, zahraničné pobyty na~praxi, domácu prax, publikácie +%a~pod. + +\end{document}