From 1e5274e030e49a660dd10046f6ac4ceeda88c3b1 Mon Sep 17 00:00:00 2001 From: Nathan Fisher Date: Mon, 5 Jun 2023 00:32:30 -0400 Subject: [PATCH 1/5] Add tinylog entry --- Makefile | 2 +- content/tinylog.gmi | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index f4bfe82..51617db 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ build: zond build upload: build - scp -r public/* nathan@hitchhiker-linux.org:/srv/gemini + rsync -rP public/* nathan@hitchhiker-linux.org:/srv/gemini publish: echo "$(submit_url)" | eval openssl s_client -connect warmedal.se:1965 -crlf \ diff --git a/content/tinylog.gmi b/content/tinylog.gmi index 0a3e989..972f56d 100644 --- a/content/tinylog.gmi +++ b/content/tinylog.gmi @@ -1,19 +1,22 @@ Meta( - title: "JeanG3nie's Tinylog", + title: "JeanG3nie\'s Tinylog", summary: None, published: Some(Time( year: 2023, month: 6, - day: 3, - hour: 14, - minute: 58, - second: 11, + day: 5, + hour: 4, + minute: 25, + second: 55, )), tags: [ "tinylog", ], ) --- +## 2023-06-05 04:25 UTC +Rust 1.70 came out this past week. One of the highlights of this release was the stabilization of the OnceCell and OnceLock types. OnceLock in particular is a big deal because it has the potential to replace the `lazy-static` and `once-cell` crates, for those times when you want to have a lazily evaluated static data structure. + +I just finished a short while ago changing Zond to use the new interface and so far so good. It's nice and simple, with good documentation. ## 2023-06-03 14:58 UTC First tinylog post! - From 08297352d0cba7f4b1de5da7d21b07d3033020c5 Mon Sep 17 00:00:00 2001 From: Nathan Fisher Date: Tue, 6 Jun 2023 15:19:01 -0400 Subject: [PATCH 2/5] New post about Dory progress --- .../dory_progress_and_misfin_thoughts.gmi | 69 +++++++++++++++++++ content/tinylog.gmi | 14 ++-- 2 files changed, 79 insertions(+), 4 deletions(-) create mode 100644 content/gemlog/dory_progress_and_misfin_thoughts.gmi diff --git a/content/gemlog/dory_progress_and_misfin_thoughts.gmi b/content/gemlog/dory_progress_and_misfin_thoughts.gmi new file mode 100644 index 0000000..6f26e5b --- /dev/null +++ b/content/gemlog/dory_progress_and_misfin_thoughts.gmi @@ -0,0 +1,69 @@ +Meta( + title: "Dory progress and Misfin thoughts", + summary: Some("Dory successfully sends to the reference server, and I wax poetic about the protocol"), + published: Some(Time( + year: 2023, + month: 6, + day: 6, + hour: 19, + minute: 15, + second: 3, + )), + tags: [ + "misfin", + "email", + "identity", + "rust", + "rustls", + ], +) +--- +I guess I'd call this a milestone achieved. I've successfully sent a couple of Misfin messages to the reference server with a small binary that uses Dory under the hood. Getting there was a little more difficult than I expected, as these things often go. + +=> https://codeberg.org/jeang3nie/sendmsg The sendmsg repository + +### Rustls is a bitch to work with +As it pertains to Gemini (and now Misfin) we're really testing some corner cases in tls library support. Not only are we using Tofu, which is not well supported, but we're also using client certificates to provide identity verification. Rustls puts both of those things well outside the happy path. They're still possible, but you're not going to get any hand holding to wade through the documentation and roll your own certificate verifier. I also discovered a definite bug around client certs, but thankfully there was a workaround. +``` +use rustls::Certificate; +// Here 'c' is assumed to be a `Vec` of the raw der-encoded bytes +// +// This fails with CertificateError::MessageTooShort +let cert = Certificate::read_bytes(&c)?; +// But we can just construct the struct manually and use it, proving that +// the certificate is valid +let cert = Certificate(c); +``` +### Wherein the compiler being pedantic in one way leads me to question my own intelligence +I also ran into a bit of a compiler related issue, that caused me to make a boneheaded mistake. In Rust, you can use enums that map to integer values just like in C. But you can also give an enum member associated data, in which case it's effectively a tagged union. I'm doing that with Misfin status codes in Dory, where there is one 'Status' enum and serveral other enums which represent individual cases for each main status. +``` +pub enum status { + Success = 20, + Redirect(Redirect) = 20, + .. other variants .. +} + +pub enum Redirect ... +``` +The issue was in converting back to u8 from a `Status`. The compiler didn't like `Status::Success as u8` due to the fact that this doesn't work for the other enum members. Using `as u8` does work for a simple enum, just not for one where any of the members have associated data. But what the compiler did accept in my `impl From for u8` was a call to `Into`. +``` +Impl From for u8 { + fn from(value: Status) -> u8 { + match value { + Status::Success => value.into(), + ... +``` +Of course the `Into` trait is provided by reversing the `From` trait, so what I was doing was calling infinite recursion and causing a stack overflow. Yikes, that was stupid. It's also an annoying reminder that while Rust is very good, footguns still exist. This is technically a logic error, not a memory safety error, so the compiler was just like "hey dude, your funeral". + +## Some thoughts on the protocol itself +The further I get into this the more I think it's a good idea. Consider the idea of identity as a baseline. The fact that Email made it so laughably easy to send a message with a spoofed sender address, and in fact the sending address never even had to be a real mailbox, has been one of the major causes of the ridiculous spam problem that has plagued the protocol since the masses got connected. Well in Misfin we're sending a client certificate every time. As long as the servers are actually validating those identities in some way, and that can even be Tofu, then a whole lot of the identity issue is moot. Nobody can spoof your identity unless they have your certificate and key. That means that your ID is your client certificate, and your IP address when sending can change as often as you want because it's just not even looked at in terms of identity. Suddenly the possibility exists that you can send messages from any device and still be recognized as you, while nobody can spoof your identity. If you go that step further and have your client cert signed by the server cert, and use a CA verified server certificate, then the client certificate is pretty much a bulletprooof identity. + +This all occurred to me when I was thinking about how to design Dory in such a way that it would be useful for a single person service and also be able to scale to a server that handled multiple domains, each with multiple users. You still need a way for a client to connect and read their mail, which could be done in a variety of ways, but there's no issue with open relays because the client can just send outgoing messages itself, the way that email was originally supposed to work (you know, when every Unix box was expected to have a `sendmail` binary) but without a lot of the problems that open relays created. That's not to say that if Google ever set up a Misfin service they wouldn't block traffic from whole blocks of IP's, but they wouldn't actually be able to justify why they were doing it the way that they can with Email. + +I'm coming around to some of the other decisions as well. I like that there are no attachments. I think it's better form to just send someone a link to a file somewhere than to actually push that file to their machine. I'm not 100% sold on the message size limit, but in use it's likely not going to be a big issue. Even the little extensions to Gemtext, which are where I was originally most uncomfortable, are well reasoned. + +I've given some thought into how a hypothetical public mail service would look with Misfin. I think one could easily just serve up a person's mailbox over gemini and have them log in using the same client certificate that they use to send messages. Their client could also just send outgoing mail by compiling in the library code to do so and send it directly from whatever machine they're using, even from a phone over a 5g connection (insert whatever number of g's are appropriate for when you're reading this). The remote server which holds your mail could of course allow sending a message that you uploaded via Gemini or Titan, with your certificate, so that you could have in essence a webmail type of service that you use via your favorite Gemini browser. Or one could go all out and do the same with a Web interface, and provide a richer editor experience (although I wouldn't want to write that or use it because I like simple tools). + +For that matter, a fully featured SmallWeb browser could implement the sending portion of Misfin, requiring only access to a receiving server, either on your own home network or in Geminispace somewhere. + +All of these things do come with a small price of course. Anyone using Misfin mail would have to get used to handling their client cert with care. Some might argue that adds a barrier to entry, but considering how crazy most public services are for two factor auth and how they only ever seem to implement it using smartphones, Misfin might actually have an edge for those who don't have a smartphone, but could easily carry around a pendrive with their certificate on it. But we all know how passwords have worked out over time, so I can easily see a bunch of people having a folder on their desktop named "Certificate"... \ No newline at end of file diff --git a/content/tinylog.gmi b/content/tinylog.gmi index bc64544..7377da4 100644 --- a/content/tinylog.gmi +++ b/content/tinylog.gmi @@ -4,10 +4,10 @@ Meta( published: Some(Time( year: 2023, month: 6, - day: 5, - hour: 4, - minute: 25, - second: 55, + day: 6, + hour: 18, + minute: 12, + second: 41, )), tags: [ "tinylog", @@ -18,6 +18,12 @@ Some shorter thoughts and updates that might not warrant a full gemlog entry. I' => .. Home +## 2023-06-06 18:12 UTC +The `sendmsg` binary (using Dory as it's backend) is now able to send Misfin mail to the reference server. This required more debugging skill than it should have due to some issues with both rustls and a compiler issue. Might be good for a full post? Anyway, link to the repository below. + +=>https://codeberg.org/jeang3nie/sendmsg +## 2023-06-05 14:55 UTC +Began a proof of concept binary project to test out sending Misfin mail using Dory. I should be able to commence testing for interop in the next couple of days. Watch this space for progress reports. ## 2023-06-05 04:25 UTC Rust 1.70 came out this past week. One of the highlights of this release was the stabilization of the OnceCell and OnceLock types. OnceLock in particular is a big deal because it has the potential to replace the `lazy-static` and `once-cell` crates, for those times when you want to have a lazily evaluated static data structure. From f0bf2184d78ea0f8fadc724915cecda248b723fa Mon Sep 17 00:00:00 2001 From: Nathan Fisher Date: Wed, 7 Jun 2023 16:37:07 -0400 Subject: [PATCH 3/5] Add new blog post and tinylog entries --- content/gemlog/dory_progress_and_misfin_thoughts.gmi | 4 ++-- content/tinylog.gmi | 10 ++++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/content/gemlog/dory_progress_and_misfin_thoughts.gmi b/content/gemlog/dory_progress_and_misfin_thoughts.gmi index 6f26e5b..f93ae48 100644 --- a/content/gemlog/dory_progress_and_misfin_thoughts.gmi +++ b/content/gemlog/dory_progress_and_misfin_thoughts.gmi @@ -39,7 +39,7 @@ I also ran into a bit of a compiler related issue, that caused me to make a bone ``` pub enum status { Success = 20, - Redirect(Redirect) = 20, + Redirect(Redirect) = 30, .. other variants .. } @@ -66,4 +66,4 @@ I've given some thought into how a hypothetical public mail service would look w For that matter, a fully featured SmallWeb browser could implement the sending portion of Misfin, requiring only access to a receiving server, either on your own home network or in Geminispace somewhere. -All of these things do come with a small price of course. Anyone using Misfin mail would have to get used to handling their client cert with care. Some might argue that adds a barrier to entry, but considering how crazy most public services are for two factor auth and how they only ever seem to implement it using smartphones, Misfin might actually have an edge for those who don't have a smartphone, but could easily carry around a pendrive with their certificate on it. But we all know how passwords have worked out over time, so I can easily see a bunch of people having a folder on their desktop named "Certificate"... \ No newline at end of file +All of these things do come with a small price of course. Anyone using Misfin mail would have to get used to handling their client cert with care. Some might argue that adds a barrier to entry, but considering how crazy most public services are for two factor auth and how they only ever seem to implement it using smartphones, Misfin might actually have an edge for those who don't have a smartphone, but could easily carry around a pendrive with their certificate on it. But we all know how passwords have worked out over time, so I can easily see a bunch of people having a folder on their desktop named "Certificate"... diff --git a/content/tinylog.gmi b/content/tinylog.gmi index 7377da4..372890b 100644 --- a/content/tinylog.gmi +++ b/content/tinylog.gmi @@ -4,10 +4,10 @@ Meta( published: Some(Time( year: 2023, month: 6, - day: 6, - hour: 18, - minute: 12, - second: 41, + day: 7, + hour: 20, + minute: 36, + second: 36, )), tags: [ "tinylog", @@ -18,6 +18,8 @@ Some shorter thoughts and updates that might not warrant a full gemlog entry. I' => .. Home +## 2023-06-07 20:36 UTC +Today, after finishing a blog post, I wrote a parser to convert a `&str` to the `Message` struct in Dory. I also added a lot more test coverage, which revealed a few issues to fix. ## 2023-06-06 18:12 UTC The `sendmsg` binary (using Dory as it's backend) is now able to send Misfin mail to the reference server. This required more debugging skill than it should have due to some issues with both rustls and a compiler issue. Might be good for a full post? Anyway, link to the repository below. From 76f191696d1b6a838cefcb113fd051d2f9e4ed82 Mon Sep 17 00:00:00 2001 From: Nathan Fisher Date: Thu, 8 Jun 2023 10:18:07 -0400 Subject: [PATCH 4/5] New post about sourcehut --- .../gemlog/sourcehut_looks_really_good.gmi | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 content/gemlog/sourcehut_looks_really_good.gmi diff --git a/content/gemlog/sourcehut_looks_really_good.gmi b/content/gemlog/sourcehut_looks_really_good.gmi new file mode 100644 index 0000000..388c0f7 --- /dev/null +++ b/content/gemlog/sourcehut_looks_really_good.gmi @@ -0,0 +1,27 @@ +Meta( + title: "Sourcehut looks really good", + summary: Some("I host pretty much everything I\'m working on at Codeberg, but I wonder if I should be on Sourcehut instead based on it\'s features?"), + published: Some(Time( + year: 2023, + month: 6, + day: 8, + hour: 14, + minute: 15, + second: 42, + )), + tags: [ + "git", + "forges", + "email", + ], +) +--- +I've talked about software forges previously on this gemlog. I host pretty much everything I write on Codeberg and I've been overall happy with it, but I find myself more and more thinking sourcehut might have been a better choice. + +I'm definitely oldschool when it comes to computers. My first box was a Tandy TRaSh80, which is to say my earliest computer experience was with a DOS interpretor on an 8-bit POS. I still prefer command line interfaces a lot of the time, even when a gui is really full featured. Codeberg runs Forgejo, a light fork of Gitea. Gitea has obviously been designed from the ground up to be as much like GitHub and GitLab as possible, which makes it immediately comfy for younger devs. In contrast, Sourcehut gives you a really minimal web interface that can fairly be described as "spartan" or even "ugly". But what it does give you, and I like this a lot, is a more traditional way of working that is centered around the command line and email rather than the web browser. + +GitHub has a lot of it's own abstractions over top of git, and those ways of working have largely replaced the traditional way of working with git for a lot of developers. Those abstractions have also been directly copied into both GitLab and Gitea, further perpetuating their adoption. Add to that the hand holding that VScode provides for git operations and I think it's fair to say that an entire generation of developers have zero idea how to actually use git on the command line. + +Now, I was already aware that sourcehut handles patches via `git send-email` instead of the `pull request` push a button in the browser model. But I recently had cause to open a ticket on a project hosted on sr.ht, and discovered that this also works by sending an email. Bonus, you can send patches and open tickets via email, all without having an account on the site. Even bigger bonus, I sent the email from mutt because why yes I am that much of a nerd. And of course it worked and the ticket appeared on the project's page almost immediately. + +I'm sure that this way of working isn't for everybody, but I think that the type of people inhabiting Gemini are probably a little more likely to appreciate this workflow over what has become the "normal" developer workflow in recent years. From b92108489f400778fc62034fb7f9b94d4dd68a62 Mon Sep 17 00:00:00 2001 From: Nathan Fisher Date: Mon, 12 Jun 2023 12:21:03 -0400 Subject: [PATCH 5/5] Commit tinylog entries --- content/tinylog.gmi | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/content/tinylog.gmi b/content/tinylog.gmi index 372890b..64e08fe 100644 --- a/content/tinylog.gmi +++ b/content/tinylog.gmi @@ -4,10 +4,10 @@ Meta( published: Some(Time( year: 2023, month: 6, - day: 7, - hour: 20, - minute: 36, - second: 36, + day: 10, + hour: 13, + minute: 55, + second: 59, )), tags: [ "tinylog", @@ -18,6 +18,8 @@ Some shorter thoughts and updates that might not warrant a full gemlog entry. I' => .. Home +## 2023-06-10 13:55 UTC +The latest Dory commits center around an iso-8601 time implementation, which is the format that `timestamp` lines are supposed to use in messages. The spec is of course a little ambiguous, and iso8601 allows dates in one of three formats, with the further distinction that there is both a `basic` formatting and an `extended` formatting, where the difference is the appearance of separators between the fields. I've decided for expediency to only implement `calendar` style dates, which is the traditional yyyy-mm--dd format that we're all used to seeing. ## 2023-06-07 20:36 UTC Today, after finishing a blog post, I wrote a parser to convert a `&str` to the `Message` struct in Dory. I also added a lot more test coverage, which revealed a few issues to fix. ## 2023-06-06 18:12 UTC