Skip to content

Commit 1aed58e

Browse files
authored
Merge pull request #49 from markterrill/patch-8
RPC Auth walkthrough
2 parents 8af0c9d + a58efa9 commit 1aed58e

File tree

1 file changed

+45
-0
lines changed

1 file changed

+45
-0
lines changed

mongoose-os/userguide/rpc.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,3 +139,48 @@ at IP address 192.168.1.4 using `mos` tool in a command line mode:
139139
31
140140
]</code></pre>
141141
142+
### RPC Authentication via mos cli
143+
144+
If you have enabled RPC authentication (ie auth_domain / auth_file / acl_file), then the easiest way to authenticate is via the rpc-creds argument to the mos tool:
145+
<pre class="command-line language-bash" data-user="chris" data-host="localhost" data-output="2-100"><code>mos --port ws://192.168.1.4/rpc [email protected] call I2C.Scan
146+
</code></pre>
147+
Where myusercreds.txt is your file containing simple auth formatted user:pass, ie ```johncitizen:plaintextpassword```
148+
149+
### RPC Authentication via code
150+
151+
Mongoose OS RPC authentication is quite basic, and is vulnerable to replay attacks as the TC field is not incremented. However it enforces basic authentication that is not plaintext, and the intention is you're communicating via a secure TLS channel like MQTT or HTTPS.
152+
153+
There are theoretically two ways to provide htdigest authentication, you can send a RPC command without auth and the system will reply with an error that contains a system generated nonce for you to use as input to your authentication reply. OR you can simply provide authentication with your original request, and since that works and is less traffic let's focus on that.
154+
155+
This is what a correctly formatted authenticated request looks like:
156+
```
157+
{"src":"mos","id":1602514363591,"method":"Config.Get","auth":{"realm":"myproduct","username":"serialUser",
158+
"nonce":1611048949,"cnonce":313273957,"response":"66e9cdd290e93ef623b1f415f10e62a7"}
159+
```
160+
161+
There is good documentation on HTDIGEST auth here: https://en.wikipedia.org/wiki/Digest_access_authentication
162+
163+
The short version of how it applies to the Mongoose implementation is:
164+
```
165+
let id = Date.now();
166+
let cmd = {"src":"rpc","id":id,"method":"Config.Get","params":{}};
167+
let cnonce = new Date().getTime();
168+
let nonce = nonce; // we're creating the request, otherwise take this from the error response
169+
let digestURI = {method = "dummy_method", path = "dummy_uri"}; //yes, this is hardcoded in MGOS
170+
171+
// Combine everything
172+
let HA1 = md5(user + ":" + realm + ":" + pass); // supply your credentials
173+
let HA2 = md5(digestURI.method + ":" + digestURI.path);
174+
let combined = HA1 + ":" + nonce + ":" + nc + ":" + cnonce + ":" + "auth" + ":" + HA2;
175+
let response = md5(combined);
176+
177+
// Add it to the command
178+
cmd['auth'] = {"realm": realm, "username": user, "nonce": nonce, "cnonce": cnonce, "response": response};
179+
180+
let textToSendToDevice = JSON.stringify(cmd); // transform from JSON to text
181+
ws.send(textToSendToDevice); // using a websocket instance
182+
183+
```
184+
Note: Advise using websockets as it skips CORS cross site issues you'd otherwise bump into in the browser
185+
186+

0 commit comments

Comments
 (0)