💾 Archived View for gemi.dev › gemini-mailing-list › 000724.gmi captured on 2023-11-04 at 13:04:04. Gemini links have been rewritten to link to archived content
-=-=-=-=-=-=-
Good evening! (I know this is a long email - I'm excited to share some of what I've been experimenting with. Hopefully it's coherent.) I've been experimenting with a non-standard status code and I wanted to share some details. I am running this experiment to find a way for users to manage content using only a Gemini client and server. No ssh, rsync, vim, emacs, nano, or anything else. # High Level Concepts I see status code 10 as the server telling the client that the user can, "provide short input". I see status code 11 as the server telling the client that the user can, "provide short secured input". I've been using a status code of 12 for having the ondollo.com server tell the Mansfield client that the user can, "provide long input". The simplest conceptual adjustment is that there's no character limit on the input a client might provide in request/response input cycle involving a status code of 12. Status codes 10 and 11 have specified limits around 1k bytes (I'm fudging the details there). Status codes 10 and 11 also have the specified behavior of putting the user input into the URL as the value of the query component. So... the simple part is that there's no limit to the number of bytes sent from a client to a server in a request/response input cycle involving a status code of 12. To escape the 1k limits of the URL in responses to 10 and 11, my exploration of status code 12 places the user input in the body. This meant I had to change my server from only understanding how to process the single request line of standard requests to processing the request line *and* the body when it sees a response to a 12. So I needed to tell the difference between requests with a body and ones without. # Some of the Consequences of the Above Approach Since I then needed to be able to tell the difference between requests that didn't have a body and those that should, I modified the server to provide unique links to the client. These unique links use a UUIDv4 that is tracked on the server and expire after a day. These are, IMO, the geminispace equivalent of server side sessions. I say the geminispace equivalent since they do as little as possible and only for the purpose of getting simple content from the writer to the reader. (The current spec says as much and explains additional privacy benefits of this concept of server-side sessions.) Because the goal is to help users manage content (or resources) using only a Gemini client, internally the UUID is paired with the clients certificate fingerprint and originally requested resource. In practical details, the resource is the page the user is editing. So. If a client provides a certificate and a URL that contain the fingerprint and UUID (respectively) that the server is tracking, the server will accept the body of the request as the value of the originally requested resource. To make the impact of certificate fingerprints line up more with *all* of the content a user might want to manage, the user must create an account on the ondollo.com server first. This account creation process is very very simple. The only step is to visit this link [1]: => gemini://ondollo.com/internal/account/create The certificate used when visiting that url is the certificate required to be provided when managing content in that account, since it's the certificate that will be paired with the UUID and originally requested resource on any resource that provides edit or create links. (This concept is also explored a bit in the current spec, and mentioned that it could be thought of as analogous to the .authorized_keys file on an SSH server.) [1] - After creating an account you'll get a status code of 20 in response, with unique links as described above - if you use those links you'll get a status code of 12 containing the current value of the resource as the body of the response and letting you manage your content as this email describes (assuming your client supports sending requests with a body). # Concerns About Certificates in Geminispace This puts additional emphasis on the geminispace use of certificates. We feel we've lined up with the current spec quite well on this. If a client created content with a certificate and then lost the certificate, the content would no longer be accessible for writing. If an account were created with a certificate and then the user lost that certificate, the account would no longer be accessible. If a client allowed more than one certificate to be locked to ondollo.com, then the user could choose between more than one account anytime they visited. If a user chose a certificate that had never been registered with an ondollo.com account, the server would have no way of knowing that that user might already have an account under a different certificate. There is an additional concern about 'leaking' the certificate. If a certificate is used to create an account, it becomes a form of username/password. If that same certificate were presented to other servers as a user were browsing through geminispace, the other servers would have access to any resources in that account that had been limited to only those who can present the original certificate. (At least, I think that's true from my limited understanding of certificates. I'd *love* to be proven wrong on this.) IMO this means that Gemini Clients must allow and encourage users to 'lock' certificates to specific sites (urls? hostnames? domains?). (Here, again, the current gemini specification seems to agree and mentions this as a concern that client implementers should watch for and enable users to manage - by hostname+path, locking all urls with that pair as a prefix.) The Mansfield client was modified in two ways to support the above. The first was simple - allow a user to lock a certificate to a hostname. Then, every time the client navigated anywhere, it would check the lockfiles to see if the hostname it was about to open a connection to had already been locked to a cert. If it had been locked to a cert, that cert would be used for all communication with that hostname, including the initial connection. (We're still on the fence about locking to the hostname+path pair, but we lean on the side of considering it a 'good-thing' that we'll probably implement.) The second adjustment to support user privacy is that the Mansfield client, on start-up, generates an in-memory-only cert. This isn't secure memory, or memory that can not be flushed to disk, this is just a certificate that can't be reused after the client is shutdown. This is done so that if the user navigates to any hostname that is *not* locked to any other certificate, the in-memory cert created at startup will be used. This removes the possibility of leaking a locked cert. We think that a recommendation along the lines of generating an in-memory cert like this might improve the current gemini spec. # After-thoughts One additional point - the account name used when following this cert-based process is based on the subject-common-name element in the cert. To deal with collisions, the first few characters from the certificate fingerprint are combined with the above common-name. We plan to eventually add functionality that allows users to register a pseudonym that takes the place of that common-name+fingerprint-prefix pair and would be more human friendly. Ah... and another point... how does the server know when to stop reading the body of a request that pairs up with a 12? Well... there's a deadline on the connection. You'll want to get all your data across before then. We don't really like that that's all we have... we've thought about implementing something more, but other options currently feel just as arbitrary... some max byte size? Finally - thanks for reading all this. I need to stop typing... I've been typing this for the last hour and a half! :-D If a status code of 12 makes it in to the spec or not is fine with us. We'd love to see more servers and clients fight for the user. (Yes, I've been watching certain movies recently.) We believe creation of content should be as simple as consumption, and we're enjoying exploring this approach as an option. Thanks!
On Thu, Feb 18, 2021 at 08:30:05PM -0700, Mansfield <mansfield at ondollo.com> wrote a message of 291 lines which said: > If a certificate is used to create an account, it becomes a form of > username/password. Not really. A certificate is basically a public key plus some metadata (identity, signature, expiration date, etc). Certificates are typically public (with TLS 1.2, they are even sent in clear). It is the knowledge of the private key that allows client certificates to be used as an authentication tool.
Mansfield <mansfield at ondollo.com> wrote: > I've been experimenting with a non-standard status code and I wanted to > share some details. I am running this experiment to find a way for users to > manage content using only a Gemini client and server. No ssh, rsync, vim, > emacs, nano, or anything else. > A gemini client could implement an existing protocol, like rsync or sftp, to achieve the goal of not requiring any additional software to manage a capsule. The simplest conceptual adjustment is that there's no character limit on > the input a client might provide in request/response input cycle involving > a status code of 12. Status codes 10 and 11 have specified limits around 1k > bytes (I'm fudging the details there). Status codes 10 and 11 also have the > specified behavior of putting the user input into the URL as the value of > the query component. So... the simple part is that there's no limit to the > number of bytes sent from a client to a server in a request/response input > cycle involving a status code of 12. > So you are using status code 12 to signal the client to use a different kind of request. What happens when a client interpretes that as a status code 10? (As it should if it doesn't understand 12.) To escape the 1k limits of the URL in responses to 10 and 11, my > exploration of status code 12 places the user input in the body. This meant > I had to change my server from only understanding how to process the single > request line of standard requests to processing the request line *and* the > body when it sees a response to a 12. So I needed to tell the difference > between requests with a body and ones without. > Introducing a new kind of request into gemini would be a mistake, I think. We have seen proposals for side protocols on this list to fill this space but they didn't get popular. Since I then needed to be able to tell the difference between requests that > didn't have a body and those that should, I modified the server to provide > unique links to the client. These unique links use a UUIDv4 that is tracked > on the server and expire after a day. > Such links could also start with something like "gemini+edit://" so that only clients supporting this feature can access it. [1] - After creating an account you'll get a status code of 20 in response, > with unique links as described above - if you use those links you'll get a > status code of 12 containing the current value of the resource as the body > of the response and letting you manage your content as this email describes > (assuming your client supports sending requests with a body). > Ah, so the client only get status code 12 if it has an account. I missed that the first time I read through your e-mail. I also missed that it supports editing of existing text. Ah... and another point... how does the server know when to stop reading > the body of a request that pairs up with a 12? Well... there's a deadline > on the connection. You'll want to get all your data across before then. We > don't really like that that's all we have... we've thought about > implementing something more, but other options currently feel just as > arbitrary... some max byte size? > TLS close_notify from the client maybe? I think the simplicity of only having "<URL>CRLF" requests outweighs any benefits we get from this approach. -- Katarina >
On Fri, 19 Feb 2021 at 03:30, Mansfield <mansfield at ondollo.com> wrote: > > To escape the 1k limits of the URL in responses to 10 and 11, my exploration of status code 12 places the user input in the body. This meant I had to change my server from only understanding how to process the single request line of standard requests to processing the request line
Katarina Eriksson writes: > Mansfield <mansfield at ondollo.com> wrote: > > I've been experimenting with a non-standard status code and I > wanted to share some details. I am running this experiment to find > a way for users to manage content using only a Gemini client and > server. No ssh, rsync, vim, emacs, nano, or anything else. > > A gemini client could implement an existing protocol, like rsync or > sftp, to achieve the goal of not requiring any additional software to > manage a capsule. This is my recommendation. People come to Gemini with the experience of the web, where the line protocol is both a floor wax AND a dessert topping. But there's really no reason that things have to be done that way. IMO, if a client wants to provide editing and publishing capabilities (which is a good idea), it should use rsync over SSH, with public-key authentication. All of this can be baked into the client, so that the user never has to deal with it. -- Jason McBrayer | ?Strange is the night where black stars rise, jmcbray at carcosa.net | and strange moons circle through the skies, | but stranger still is lost Carcosa.? | ? Robert W. Chambers,The King in Yellow
---