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
prev 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).