9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
From: ori@eigenstate.org
To: 9fans@9fans.net, 9front@9front.org
Subject: Re: [9fans] OAuth2 in factotum
Date: Sun, 22 Aug 2021 16:36:17 -0400	[thread overview]
Message-ID: <7BD08FA33BDEF31677ABBA911CD6A3FE@eigenstate.org> (raw)
In-Reply-To: <FEF7A1A8AA43660462E5C685BBCF3230@eigenstate.org>

[-- Attachment #1: Type: text/plain, Size: 4372 bytes --]

Quoth ori@eigenstate.org:
> Quoth Demetrius Iatrakis <demetrius.iatrakis@gmail.com>:
> > This is a preview of OAuth2 support in factotum, as part of this year's GSoC:
> > https://github.com/Mitsos101/plan9front/pull/1
> > 
> > Installation, on 9front:
> > 
> > git/clone https://github.com/Mitsos101/plan9front plan9front-oauth
> > cd plan9front-oauth
> > git/branch oauth
> > bind sys/include /sys/include
> > @{cd sys/src/libauth && mk install}
> > @{cd sys/src/cmd/auth && mk install}
> > @{cd sys/src/cmd/webfs && mk install}
> > 
> > This will replace your factotum.
> > 
> > Usage:
> > 
> > You need to obtain OAuth credentials from your issuer first. See, for
> > example, Google's guide:
> > https://developers.google.com/identity/protocols/oauth2.
> > 
> > % echo 'key proto=oauth issuer=https://accounts.google.com scope=email
> > client_id=1234 !client_secret=5678' > /mnt/factotum/ctl
> > % auth/oauth 'client_id=1234'
> > go to https://google.com/device
> > your code is ABCD-EFGH
> > <after user consent is provided, the access token is printed>
> > 
> > auth_oauth is also available in libauth. Webfs uses it to implement
> > the preoauth command.
> > 
> > Bugs:
> > 
> > This code is specific to 9front, as libjson is required and Plan 9's
> > webfs doesn't support preoauth.
> > 
> > factotum uses the needkey RPC to display the verification URL and code
> > to the user. This means that, for now, the needkey file must not be
> > open so that fgui doesn't intercept it.
> > 
> > The module imports lots of code to support HTTP/1.0 so that the
> > refresh token doesn't leave factotum's address space.
> > 
> > Only the device and refresh flows are supported. There is an
> > implementation of the authorization code flow (tested on macOS) here:
> > https://github.com/Mitsos101/plan9port/pull/1. However, it is not
> > included in the module as there is no good browser to plumb the URL
> > to.
> > 
> > Refresh tokens are not saved to persistent storage when factotum
> > exits. The user must provide consent every time factotum is restarted.
> > 
> 
> And, now that we have something working, I wrote
> some code to use it. I wrote a patch to add oauth
> support to upas/fs -- see attached:
> 
> To use the patch, I followed this kind of clunky
> process:
> 
> 	https://developers.google.com/identity/protocols/oauth2
> 
> I went to the 'credentials' section on the sidebar
> and I created a key for a 'desktop application'; Then
> I went to the 'oauth consent screen' and added my work
> email account as a 'test user'.
> 
> I grabbed the keys, and on my unix box, went to
> the patched oauth:
> 
> 	% cd $HOME/src/plan9port/src/cmd/oauth
> 
> and generated a key using the full, browser based
> auth flow:
> 
> 	% python httpd.py
> 	% ./oauth https://accounts.google.com https://mail.google.com/ $clientkey $clientsecret
> 	key proto=oauth issuer=https://accounts.google.com client_id=72...
> 
> then edited the resulting output to include the appropriate
> attributes, adding the attributes in >>...<< for upas/fs:
> 
> 	key proto=oauth
> 		>>service=imap server=imap.gmail.com user=ori@pingthings.io<<
> 		issuer=https://accounts.google.com client_id=<id> 
> 		token_type=Bearer exptime=1629662303 scope=...
> 
> and then added that to factotum:
> 
> 	echo key=... >/mnt/factotum/ctl
> 
> With that, upas/fs just worked with my work email:
> 
> 	upas/fs -f /imaps/imap.gmail.com/ori@pingthings.io
> 
> 
> Bugs: there are way too many steps. Unfortunately, the most
> annoying one is generating and adding an oauth client key/secret,
> and short of shipping a pregenerated one (is that a good idea?),
> I don't think there's a solution.
> 
> Beyond that, 2 small bits of polish which I think we
> can do:
> 
> 	- Adding a '-t' flag to oauth (the way auth/rsa does)
> 	  to add type information to auth/oauth login would
> 	  make it more convenient to use: the output could
> 	  be stored directly rather than needing editing.
> 	- Adding a script that allows spawning a browser and
> 	  http listener on unix (or redirecting thigns through
> 	  to plan 9) would make it easier to drive the auth
> 	  process from plan 9.
> 
> Thanks for doing this work, Demetrius!

Oops, realized that I'd left this line in the patch:

+	imap->flags |= Fdebug;

you'll really want to delete that, or you end up with
a *TON* of debug spew.

Updated patch attached.

[-- Attachment #2: Type: text/plain, Size: 2470 bytes --]

diff bcfee7b54757eb64cade34e476cf0dba672832f6 uncommitted
--- a/sys/src/cmd/upas/fs/imap.c
+++ b/sys/src/cmd/upas/fs/imap.c
@@ -24,6 +24,7 @@
        Cnolog  = 1<<0,
        Ccram   = 1<<1,
        Cntlm   = 1<<2,
+       Coauth  = 1<<3,
 
        /* flags */
        Fssl    = 1<<0,
@@ -151,7 +152,7 @@
 static void
 imap4cmd(Imap *imap, char *fmt, ...)
 {
-       char buf[256], *p;
+       char buf[1024], *p;
        va_list va;
 
        va_start(va, fmt);
@@ -430,6 +431,8 @@
                                imap->cap |= Ccram;
                        if(strcmp(p, "ntlm") == 0)
                                imap->cap |= Cntlm;
+                       if(strcmp(p, "xoauth2") == 0)
+                               imap->cap |= Coauth;
                }else if(strcmp(t[i], "logindisabled") == 0)
                        imap->cap |= Cnolog;
        }
@@ -733,6 +736,38 @@
 }
 
 static char*
+imap4oauth(Imap *imap)
+{
+       char *s, *auth, *enc;
+       int n;
+       OAuth *oa;
+
+       if(imap->user == nil)
+               return "user required for oauth";
+       oa = auth_getoauth(auth_getkey, "proto=oauth service=imap server=%q user=%q", imap->host, imap->user);
+       if(oa == nil)
+               return "cannot find IMAP oauth token";
+
+       imap->tag = 1;
+       if((auth = smprint("user=%s\x01auth=Bearer %s\x01\x01", imap->user, oa->access_token)) == nil)
+               sysfatal("smprint: %r");
+       if((enc = smprint("%[", auth) == nil)
+               sysfatal("smprint: %r");
+       imap4cmd(imap, "authenticate xoauth2 %s", enc);
+       free(auth);
+       free(enc);
+       free(oa);
+       s = imap4resp(imap);
+       if(isokay(s))
+               return nil;
+       imap4cmd(imap, "");
+       s = imap4resp(imap);
+       if(isokay(s))
+               return nil;
+       return s;
+}
+
+static char*
 imap4passwd(Imap *imap)
 {
        char *s;
@@ -762,6 +797,8 @@
                e = imap4cram(imap);
        else if(imap->cap & Cntlm)
                e = imap4ntlm(imap);
+       else if(imap->cap & Coauth)
+               e = imap4oauth(imap);
        else
                e = imap4passwd(imap);
        if(e)
------------------------------------------
9fans: 9fans
Permalink: https://9fans.topicbox.com/groups/9fans/T6899bf3f0654295d-Mbcaea13458be56f2909ea6c3
Delivery options: https://9fans.topicbox.com/groups/9fans/subscription

      parent reply	other threads:[~2021-08-22 20:36 UTC|newest]

Thread overview: 62+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-08-16 11:15 Demetrius Iatrakis
2021-08-17  3:48 ` Lucio De Re
2021-08-17  7:47   ` Keith Gibbs
2021-08-18  3:55     ` Lucio De Re
2021-08-18  7:02       ` [9fans] Software philosophy Skip Tavakkolian
2021-08-18  7:19         ` hiro
2021-08-18 10:15           ` Lucio De Re
2021-08-18  9:46         ` Keith Gibbs
2021-08-18 10:13         ` vic.thacker
2021-08-18 11:34           ` Keith Gibbs
2021-08-18 11:47             ` Lucio De Re
2021-08-18 23:44             ` hiro
2021-08-19  4:34               ` Lucio De Re
2021-08-19 10:44                 ` Keith Gibbs
2021-08-19 18:53                 ` Git & Conventional Browsers (Was Re: [9fans] Software philosophy) unobe
2021-08-19 19:00                   ` ori
2021-08-18 11:34           ` [9fans] Software philosophy Lucio De Re
2021-08-18 11:28         ` Lucio De Re
2021-08-18 12:02           ` Keith Gibbs
2021-08-18 19:33             ` leimy2k via 9fans
2021-08-18 20:09               ` David du Colombier
2021-08-18 22:00                 ` Eli Cohen
2021-08-19  7:08                   ` Keith Gibbs
2021-08-19  7:59                     ` sirjofri
2021-08-19  9:27                       ` Lucio De Re
2021-08-19  9:45                         ` hiro
2021-08-19  9:51                         ` hiro
2021-08-19 10:10                           ` sirjofri
2021-08-19 10:38                         ` Keith Gibbs
2021-08-19 11:45                           ` hiro
2021-08-19 12:43                             ` Eli Cohen
2021-08-19 19:58                               ` Aram Hăvărneanu
2021-08-19 10:56                         ` kvik
2021-08-19 11:33                           ` sirjofri
2021-08-19 20:44                           ` ori
2021-08-19  9:29                       ` hiro
2021-08-19  9:44                         ` sirjofri
2021-08-19  9:19                     ` hiro
2021-08-22  2:46                   ` kokamoto
2021-08-22  3:16                     ` Eli Cohen
2021-08-22  7:07                       ` [9fans] Drawterm GPU (was: Software philosophy) sirjofri
2021-08-22 10:04                         ` Frank D. Engel, Jr.
2021-08-22 11:49                           ` sirjofri
2021-08-22 12:24                             ` Chris McGee
2021-08-18  9:18       ` [9fans] OAuth2 in factotum Keith Gibbs
2021-08-18 12:10         ` Ethan Gardener
2021-08-18 15:23         ` Stuart Morrow
2021-08-18 16:58           ` Stuart Morrow
2021-08-18 17:06             ` Sigrid Solveig Haflínudóttir
2021-08-17 15:25   ` ori
2021-08-18  3:59     ` Lucio De Re
2021-08-18  4:20       ` ori
2021-08-18  4:42         ` Eli Cohen
2021-08-18  5:06         ` Lucio De Re
2021-08-17  4:13 ` ori
2021-08-17  5:43   ` Lucio De Re
2021-08-19  3:52 ` Kurt H Maier
2021-08-19  5:38 ` ori
2021-08-22 20:16 ` ori
2021-08-22 20:32   ` Demetrius Iatrakis
2021-08-22 20:38     ` ori
2021-08-22 20:36   ` ori [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7BD08FA33BDEF31677ABBA911CD6A3FE@eigenstate.org \
    --to=ori@eigenstate.org \
    --cc=9fans@9fans.net \
    --cc=9front@9front.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).