Subject: [Captive-portals] Comments on draft-donnelly-capport-detection-01

From: Dave Dolson <[email-masked]>
Date: Tue, 21 Mar 2017 19:20:56 +0000

Mark and Margaret,
Thanks for putting this together. I have some questions and comments.

I suspect there are a number of nits in the syntax, but first I'd like to discuss some high-level questions.

1.       Regarding $toplevel, is this intended to be used as the body for both request and response? I suspect no, this is the body of the response and the body of the POST has not been defined. For example, how is the MD5 sum of the t&c to be presented?

2.       I see a role for performing GET, once the session has been established.

3.       Do you see any opposition to including various hrefs for satisfying requirements in the browser?

I think working through some examples would be useful. This differs from your proposal, but I was thinking:

-------
GET from the DHCP-provided URL:
GET http://<server>/capport (Accept: application/json)
200 OK
{
   "create_href": "http://<server>/capport/sessions",
   "browse_href": "http://portal.example.com/"
}

----
Posting to the create_href:
POST http://<server>/capport/sessions (Accept: application/json)
{ "identity": "<USERNAME>"}
200 OK
{ " id": { "uuid": "<session_uuid>",
           "href": "http://<server>/capport/sessions/<session_uuid>" },
  "identity": "<USERNAME>",
  "state": { "permitted": false },
  "requirements": [
    {"view_page": "http://portal.example.com/welcome/terms_and_conditions.html?session=<session_uuid>"},
    {"provide_credentials": "http://<server>/capport/sessions/<session_uuid>/credentials"}]
}

-------
The session now exists, and GET works:
GET http://<server>/capport/sessions/<session_uuid> (Accept: application/json)
200 OK
{ " id": { "uuid": "<session_uuid>",
           "href": "http://<server>/capport/sessions/<session_uuid>" },
  "identity": "<USERNAME>",
  "state": { "permitted": false },
  "requirements": [
    {"view_page": "http://portal.example.com/welcome/terms_and_conditions.html?session=<session_uuid>"},
    {"provide_credentials": "http://<server>/capport/sessions/<session_uuid>/credentials"}]
}

------
Or GET for browser:
GET http://<server>/capport/sessions/<session_uuid> (Accept: text/html)
200 OK
<html> Human readable page of above information </html>

----------
After visiting the view_page URL and clicking OK, the internet works, and the info is available for query:
GET http://<server>/capport/sessions/<session_uuid> (Accept: application/json)
200 OK
{ " id": { "uuid": "<session_uuid>",
           "href": "http://<server>/capport/sessions/<session_uuid>" },
  "identity": "<USERNAME>",
  "token": "<TOKEN>",
  "state": { "permitted": true, "expires": "2017-02-25T19:00:00-06:00", "bytes_remaining": 10000000 },
  "requirements": []
}

----
When the session expires, ICMP alert occurs, the client GETs again (note different value for view_page):
GET http://<server>/capport/sessions/<session_uuid> (Accept: application/json)
200 OK
{ " id": { "uuid": "<session_uuid>",
           "href": "http://<server>/capport/sessions/<session_uuid>" },
  "identity": "<USERNAME>",
  "state": { "permitted": false, "expires": "2017-02-25T19:00:00-06:00", "bytes_remaining": 0 },
  "requirements": [
    {"view_page": "http://portal.example.com/welcome/renew.html?session=<session_uuid>"},
    {"provide_credentials": "http://<server>/capport/sessions/<session_uuid>/credentials"}]
}

The client can fulfil requirements again.

----
When the client wants to explicitly leave the network, delete the href for the session:
DELETE http://<server>/capport/sessions/<session_uuid>
200 OK

The USERNAME could be DHCP option-12 value or MAC address or ?  I don't think it is too important for security, but useful for diagnostics.
I did not delve into how the TOKEN would be used with provide_credentials. But the idea is that it could be shared (e.g., with devices lacking displays.)

Does this make sense?

-Dave

---

From: Vincent van Dam <[email-masked]>
Date: Sat, 25 Mar 2017 11:30:47 +0000

To research the API a bit more, I implemented a proof-of-concept captive portal that implements this API, and specifically the API with the suggestions of Dave in the previous mail. You can find the poc here: https://github.com/joyrex2001/capport-detection

In general, I think the implementation of the API at the user-equipment side should have very little business logic. As everything that we decide to have implemeted there, needs to be replicated in every ‘user equipment’ platform.

In my opinion, the user-equipment should be able to detect if his traffic was blocked by the captive portal (the icmp message), validate if this icmp is authentic, and then has to take action. The action being, either at least inform or start some interactive journey.

In the inform case, I think specifically devices without input or screens fit in. The inform could be some text which explains what happened and what the user can do to resolve (this could be anything, dial some callcenter, do some magic at some kind of vending machine, or text something to some shortcode, etc..).

The other action, start the interactive journey, I think this is our typical captive portal as we see it nowadays. I also think that solving this is a browser component (webbrowser, webview, …) is a good fit to make sure that the captive portal provider has enough freedom to implement whatever their marketing department figured was the best way to provide access (being passcodes, accepting t&cs, watching videos, or something we didn’t think of yet).

With this in mind, I like the suggestions Dave did on this document. The user-equipment can do a simple rest call to the API. It can detect (confirm) it didn’t have access yet, and the response contains a list of requirements that should be met to get access. The requirements are currently only urls, and I think this should also contain a ‘inform’ message as well (for the inform case). I think the validation of the icmp message is not yet covered in the API either.

When I was implementing the proof of concept, there was a bit of struggling with the requirements. The semantics (view_url, provide_credentials) didn’t add value at my end, as the captive portal provider (developer). I had more desire for an id that would uniquely identify that requirement. If the ‘view_url’,’provide_credentials’ where id’s instead, I could have better implement the code where I had to delete the requirement when it was met. From the captive-portal-developer perspective, I was just providing a list of url’s I thought the user should visit. On these pages, the use had to do something, and if he had done that successfully, I would remove that requirement from the list.

Regards,

Vincent van Dam

ps. sorry for hijacking this thread; note the questions/feedback Dave gave in his mail were not discussed yet.

________________________________
Van: Captive-portals [[email-masked]] namens Dave Dolson [[email-masked]]
Verzonden: dinsdag 21 maart 2017 20:20
Aan: [email-masked]
CC: [email-masked]
Onderwerp: [Captive-portals] Comments on draft-donnelly-capport-detection-01

Mark and Margaret,

I suspect there are a number of nits in the syntax, but first I’d like to discuss some high-level questions.

-------

----

-------

------
Or GET for browser:

----------

----

----

The USERNAME could be DHCP option-12 value or MAC address or ?  I don’t think it is too important for security, but useful for diagnostics.
I did not delve into how the TOKEN would be used with provide_credentials. But the idea is that it could be shared (e.g., with devices lacking displays.)

Does this make sense?

-Dave