This pull request fully implements and documents all of the registration token administrator API endpoints.
**NOTE:** There is a memory leak when listing all of the registration tokens. Debug this before merging.
~~Closes~~ Supersedes #37.
Closes#26.
This pull request is based off of #37, which addresses #26. This pull makes a number of improvements to the logic, organization, and behavior of the API endpoints.
Co-authored-by: hatkid <daichi93100@gmail.com>
Co-authored-by: LoaD Accumulator <lda@freetards.xyz>
Co-authored-by: LoaD Accumulator <lda@noreply.git.telodendria.io>
Co-authored-by: lda <lda@freetards.xyz>
Co-authored-by: Load Accumulator <lda@freetards.xyz>
Reviewed-on: #43
I will use them eventually when I implement all these functions.
I'm probably going to start CI work here soon, so I don't want warnings showing up in the logs unless they're important.
This pull request also requires the use of the external [Cytoplasm](/Telodendria/Cytoplasm) repository by removing the in-tree copy of Cytoplasm. The increased modularity requires a little more complex build process, but is overall better. Closes#19
The appropriate documentation has been updated. Closes#18
---
Please review the developer certificate of origin:
1. The contribution was created in whole or in part by me, and I have
the right to submit it under the open source licenses of the
Telodendria project; or
1. The contribution is based upon a previous work that, to the best of
my knowledge, is covered under an appropriate open source license and
I have the right under that license to submit that work with
modifications, whether created in whole or in part by me, under the
Telodendria project license; or
1. The contribution was provided directly to me by some other person
who certified (1), (2), or (3), and I have not modified it.
1. I understand and agree that this project and the contribution are
made public and that a record of the contribution—including all
personal information I submit with it—is maintained indefinitely
and may be redistributed consistent with this project or the open
source licenses involved.
- [x] I have read the Telodendria Project development certificate of
origin, and I certify that I have permission to submit this patch
under the conditions specified in it.
Reviewed-on: #38
The problem here is that some Matrix homeservers reject requests that don't
have a Content-Length. http was not sending a Content-Length because it was
reading from standard input. By reading from an actual file, we can actually
easily get the size of the file to send as the Content-Length.
This allows some additional operations to be performed inside the memory
hooks, although it's still a bad idea to allocate or free memory while
inside the hook.
This is a temporary fix; I'm not convinced it will work on all platforms,
so I will probably end up removing all of the memory boundary code
altogether.
This allows us to get rid of the hideous MATRIX_PATH_PART_EQUALS macro,
and prevents inconsistent usage of strcmp() (for example, !strcmp() vs
strcmp() == 0).
StrEquals() also has sensible behavior for dealing with NULL strings (it
doesn't just segfault like strcmp()).
This is a very early prototype. It works, but it is probably not efficient
or reliable. However, the documentation format it parses is stable, so I
will begin moving the documentation into the headers.
The OpenBSD linker is complaining about it. Even though every single
case strcpy() was used is safe, strncpy() provides a little bit of extra
security, and makes the linker happy.
This implementation is loosely inspired by the original paper on the
Mersenne Twister, and borrows code from a public-domain implementation of
it, adapting it to fit the style of Telodendria's code, and fixing a few
bugs regarding the size of the data type used.
Neither C nor POSIX provide a good, thread-safe pseudorandom number
generator. The OpenBSD linker started complaining about the use of
rand_r(), and no standard alternative presented itself as worthy of
consideration, so I finally decided it was time to roll my own PRNG.
This is accomplished by locking the entire database, and keeping it locked
until the last reference is unlocked. We get rid of per-reference locks,
because those are what cause race conditions.
Note that Db has the potential to deadlock when caching is being used,
and when caching isn't being used, an inconsistent state can occur. Future
changes to Db will fix both of these issues.
Apparently it can EAGAIN on non-blocking connections... I don't think
LibreSSL's TLS library does this, but something to keep in mind if it
doesn't work for somebody.
tls_read() and tls_write() may return TLS_WANT_POLLIN or TLS_WANT_POLLOUT
if data isn't ready to be read or written yet. We have to account for this
by converting it to EAGAIN, which is how a typical read() or write()
function should behave.
Also installed a SIGPIPE handler; we do not want to be terminated by
SIGPIPE, and it's safe to ignore this signal because it should be
handled thoroughly in the code.
This is useful for having a TLS and a non-TLS version port, like Synapse.
I verified that the multiple-servers does in fact work as intended,
although the TLS server part is broken; I must be doing something
incorrectly with LibreSSL in setting up the server.
This way, we can still set the debug level in the configuration, and not
see the log just absolutely flooded with memory allocations and whatnot.
This is helpful because I want debug messages to show up in development,
but not in production, but having all the memory logging makes it
almost impossible to pick anything else out of the log. I want the
feature available, just not on by default because it's useful in limited
circumstances.
The standard use case for this is going to be running a TLS and a non-TLS
HTTP server. I can't see a need for *more* than two, but it is theoretically
possible.
We shouldn't have to change anything with the database or anything; it
should suffice to simply spin up more HTTP servers, and they should
interact with each other the same way a single HTTP server with multiple
threads will.
This is the easiest and cleanest way to get logging into some of the
fundamental APIs, such as the database and TLS APIs. We don't want to
have to pass logging functions to those, but they can safely use the
global logging configuration.
Not only does this make us more POSIX, it actually makes things a lot
easier because TLS implementations will need to be able to access the
trusted certificates file, which most likely will not live in the
data directory.
Both do buffered reads and writes, but IoCopy() uses IoRead() and
IoWrite() directly, whereas StreamCopy() relies on StreamGetc() and
StreamPutc(), which manipulate the stream buffers.
If we haven't read any bytes yet, then we try a few times a few ms apart
to see if we get anything. If not, treat it as an EOF. Otherwise, read
bytes until we get an EOF or EAGAIN. EAGAIN after a consistent read of
bytes is treaded as an EOF immediately.
These functions previously operated on the assumption that fgetc() would
block; however it will not block on HttpServer streams because those are
non-blocking. They now check error conditions properly before failing
prematurely.
You might be asking why I would just write a simple curl replacement
when curl does the job just fine. Well, the most immediate reason is
to test the HttpClient API, but since Telodendria's goal is to not
be dependent on any third-party code if at all possible, it makes
sense to have a simple HTTP client to use not only for testing
Telodendria, but also for configuring it. When we move the
configuration to the database, we'll ship a script that uses this
tool to allow admins to easily submit API requests.
Do not be concerned that HttpClient does not support TLS yet. TLS
support is necessary for federation to work, so it is coming
eventually.
**Telodendria** is an open source Matrix homeserver implementation written from scratch in ANSI C and designed to be lightweight and simple, yet functional.
**Telodendria** is an extremely powerful, yet lightweight and portable
chat server designed to be easy to install and configure. Powered by
the [Matrix](https://matrix.org) protocol, Telodendria empowers
everyone to run their own chat server on ordinary hardware, including
old and embedded devices. Whether you want a simple chat server just
for you and your friends and family, or want to talk to users on other
Matrix homeservers but don't want to go through all the hastle of
hosting a complicated, high-maintenance homeserver or joining an
existing homeserver for privacy or other reasons, then Telodendria
might be for you.
**Important:** This project is not developed on GitHub, or even with Git. As such, GitHub Pull Requests are not accepted. But that doesn't mean we don't want your contribution! You're more than welcome to clone this repo and use Git to make changes to the project if you'd prefer it to CVS, but when it comes time to actually submit your changes to this project, use [git format-patch](https://git-scm.com/docs/git-format-patch) to generate patch files, then submit them to the official Matrix room: [#telodendria-patches:bancino.net](https://matrix.to/#/#telodendria-patches:bancino.net).
!!!! **Note:** Telodendria still in development. See **Status** below.
Please see the `README.txt` file for the actual project `README`, which simply details the repository structure a little bit. All of **Telodendria**'s user and developer documentation is available as `man` pages, or online.
## What is Matrix?
Matrix is an **open standard** for *interoperable*, *decentralized*,
*secure*, and *real-time* communication over the internet.
Matrix can be thought of as the successor to email, but it works
very similar to iMessage, Discord, or direct messaging on most
social media networks. The primary difference between Matrix and these
other services, however, is that Matrix doesn't depend on one central
authority, and is designed in such a way to respect your privacy.
Matrix has proven itself over the last few
years to be a reliable communication tool, and has only gotten more
user-friendly over the course of its development. Matrix is capable
enough that it can—and should—totally replace any other
means of digital communication, and it offers a much higher degree
of security, simplicity, and functionality.
Strictly speaking, Matrix itself is just the *protocol* by which
clients and servers communicate. In order to use Matrix, we need
implementations of both clients and servers. Telodendria is a server
implementation of the Matrix protocol.
## Why Telodendria?
- **Lightweight:** Written in the C programming language, Telodendria
is automatically lighter and faster than other self-hosted chat servers.
It has very few external dependencies and is as self-contained as
possible.
- **Fully-Featured:** Most lightweight chat solutions compromise on
features. Telodendria is built on the fully-featured Matrix protocol,
which provides a chat experience that most normal users are familiar
with.
- **Portable:** You can run Telodendria on just about everything,
including more traditional options like a personal home server or VPS,
but also more obscure platforms like Raspberry Pis or retro computers.
Telodendria can run on a broad number of operating systems, which means
that no matter which platform and OS you prefer, there is a good chance
you can add Telodendria without much difficulty. It is also extremely
easy to migrate a Telodendria instance between platforms; just copy the
data directory to a new device.
- **Simple:** Telodendria is designed to be a simple, no-frills
chat server. It is easy to install, easy to configure, and easy to
maintain.
- **Stable:** Other Matrix homeservers develop at the pace of the
Matrix specification itself, which is to say quite rapidly. Changes are
always being made, and a version shipped 6 months ago is already
incredibly outdated. Telodendria, on the other hand, aims to be stable.
It should *just work* for long periods of time between upgrades, and
you should never feel like Telodendria is going to change significantly
between upgrades.
- **Well-Documented:** Telodendria places as much emphasis on documentation as on code, which means you can be sure that the documentation will always remain up-to-date, accurate, and most importantly, reasonably exhaustive.