From 58cd5e3beada346f84dcd49b7ab9e122cc98a3df Mon Sep 17 00:00:00 2001 From: Ylian Saint-Hilaire Date: Wed, 20 Jul 2022 00:10:09 -0700 Subject: [PATCH] LDAP improvements (#4276) --- agents/hashagents.json | 132 +++++++++++++++----------------- views/default-mobile.handlebars | 2 +- views/default.handlebars | 3 +- webserver.js | 82 ++++++++++++-------- 4 files changed, 115 insertions(+), 104 deletions(-) diff --git a/agents/hashagents.json b/agents/hashagents.json index 14f83a82..318242bd 100644 --- a/agents/hashagents.json +++ b/agents/hashagents.json @@ -1,134 +1,128 @@ { "3": { "filename": "MeshService.exe", - "hash": "C0E5DB22DE5DED510C48141D7CFE4807F98B8205D680F5FC8A5D15950F17A1465E0953B7BFA7FAEED72019E765E1C8E1", - "size": 3680256, - "mtime": "2022-04-04T17:13:59Z" + "hash": "B23D7FE5B2378D1AD208F3B31642DF40BBE2705317C4620329D9FC67CB8B36FD8C97440A9C5E37E6C8FE8121D45DE626", + "size": 3789824, + "mtime": "2022-07-19T22:51:13Z" }, "4": { "filename": "MeshService64.exe", - "hash": "47A927806EDB6DFAC2C79467719FADA0F3625010D551C6D0EA6EA7DB99F088C088E70F562416FC1809B014913CFEA7E0", - "size": 3293184, - "mtime": "2022-03-25T19:04:18Z" + "hash": "2B08CC44D4C13185B84B7AC8BFF0AAA7B7A4C70BC61D195E9FC01BE7C054C622B9A5A2C2CB82FA02BC8CFFE62FC0ECF2", + "size": 3419648, + "mtime": "2022-07-19T22:50:43Z" }, "5": { "filename": "meshagent_x86", - "hash": "E984791A6FB96E06191AEA1D7B3066AB8B2170DC7B8A64D7C9A605CDC79B463541D994587E85E3FD4644359329344734", - "size": 3650016, - "mtime": "2022-04-04T17:22:17Z" + "hash": "259AD0C46A8C9C7D4C661580EAA2C089A30B27D6A540D78E7D19E3119F75191A268BC7A7F544C43D76936DA9900E6FB0", + "size": 3666464, + "mtime": "2022-07-19T23:10:37Z" }, "6": { "filename": "meshagent_x86-64", - "hash": "F6A48178D7BCE798CDF36AC8F49D9650674E38E266DB396A84657EE8FD81BF85FA998456245F2AFE4A20FDD08CD73D2E", - "size": 3724624, - "mtime": "2022-04-04T17:22:25Z" + "hash": "A72427913C9CE24B2E19518933C14D5E9FA9F5B02D4CACF2CD6BF0A8B13776659BBCE4CA006ED6463B65816628609C11", + "size": 3741136, + "mtime": "2022-07-19T23:10:45Z" }, "7": { "filename": "meshagent_mips", - "hash": "2D913C118114219CF127D9415174645A3F11464A4B13D07A702AFC2A836381C52C4A2854403215DAFF4582C058E8B824", - "size": 4522304, - "mtime": "2022-04-04T17:22:32Z" + "hash": "4DD7EA95238FCC527E1399515D1CDC43EF9873D3581066F03A8906A38D75B63A3BB492B338A4342E4043C90C5C5313C8", + "size": 4543564, + "mtime": "2022-07-19T23:10:53Z" }, "9": { "filename": "meshagent_arm", - "hash": "AD1C9D2A1E468AEB26FD6443581C3CE3F5F8D0A3779BA0EA5BA06C20B5094B095B5F0D0F104B2F26053877E5D005FBAB", - "size": 3132180, - "mtime": "2022-04-04T17:22:41Z" + "hash": "B7DA684D1425A24D9234711115893B330DD5F13A906B41DE84B2A226D0E9B95FB2C03AB2DE1F7738018257CCC21C08C8", + "size": 3148064, + "mtime": "2022-07-19T23:11:02Z" }, "13": { "filename": "meshagent_pogo", - "hash": "F9E19D72922732BC4C9F84F90CAB380E6A3851B8137A69AB648E1B145BA4F257B5C2C47BBE36CBE62E364328854DD844", - "size": 3140884, - "mtime": "2022-04-04T17:22:51Z" + "hash": "45415D3F6F31861F010B4C1538ABFF99EE9C6DB01EEB46E08D56F5FDE6134370D0BF41EB0961C0E95AC0828F03E48057", + "size": 3156272, + "mtime": "2022-07-19T23:11:11Z" }, "15": { "filename": "meshagent_poky", - "hash": "DFBF910AC01FE7D8BD2E6649908E0BBE0C553C12ACADB4C73C32BC65BCDCCDF336C39BA47A08C6659F9CB8E475C3677F", - "size": 3776024, - "mtime": "2022-04-04T17:23:00Z" + "hash": "AA61B7452257FDA5D9B60D12205852256BED392AD604B2A4183D423E31217610B1AC45C267EB3D906EBA759257963126", + "size": 3792504, + "mtime": "2022-07-19T23:11:21Z" }, "16": { "filename": "meshagent_osx-x86-64", - "hash": "77A87BCAE3534061CE15060C4F8971074B7AEBC88957CC9FF50BF8F6B234E3AFAE48DCB9A44681A24393F20191BB3DA1", - "size": 4391904, - "mtime": "2022-03-25T23:51:40Z" + "hash": "CE573066BCE2C37AC4F50D5C5FBE246EF1540D8E0F7431CE78BF1D5988803AFDF1307E59E6F6DF32AC52F4030E2CA5A8", + "size": 4687168, + "mtime": "2022-07-19T06:25:24Z" }, "18": { "filename": "meshagent_poky64", - "hash": "0DDF6A2CABC3B1D40CBE9CA4A6EB2103308F228D5332F64E3C9B01A54BC968B0120D2A50B71111D70682435A07577ABD", - "size": 3478872, - "mtime": "2022-04-04T17:23:11Z" + "hash": "A679356D5010A2ED8BB9C6875B11792BE88E3159EC472C691B6A518AE2BCB8DDB27D5D4D4ED59DB8CAA6651A8EFF5131", + "size": 3495416, + "mtime": "2022-07-19T23:11:32Z" }, "19": { "filename": "meshagent_x86_nokvm", - "hash": "2AFC43684BD2A2601FAA32BF86F35EAEB29CDD00ABE3BEB3446448EC44E3151E459909569044681C507FE11A82139914", - "size": 3365188, - "mtime": "2022-04-04T17:23:19Z" + "hash": "BF3CD00DC7AF8031E23A91FD137BD38792D99FF31FE9F2500BA21234DF2F41F5950BF99C5BB57C8C03BE15548AD1F413", + "size": 3381636, + "mtime": "2022-07-19T23:11:39Z" }, "20": { "filename": "meshagent_x86-64_nokvm", - "hash": "1B198D624FA99E4D6B52AD139A19259B491FA233A2783F5E4C46955A6AD37DDF5053D7F022C95C8F04684CCADFD2CC3D", - "size": 3425584, - "mtime": "2022-04-04T17:23:27Z" + "hash": "3AAD8F890EF129F5F0521B6FA96B72E9D6FF7166A75182C6D931DF3EC6A8B7EC4B789415733FE36F54A21F09CD2B1673", + "size": 3442096, + "mtime": "2022-07-19T23:11:47Z" }, "24": { "filename": "meshagent_arm-linaro", - "hash": "2F5D211E983A738ABE31A6EAF4B73629FD937D34D5BD8380A420BAB7108040CA2320EADA8F02CFEF763A3C1D0EA8F1A2", - "size": 2194704, - "mtime": "2022-04-04T17:23:39Z" + "hash": "1324A6EE63FC6317CF455B34A4D0C5CEE1FFA166BB4CD0D985F372BE3854D9930888E76AD50D169005F606914C2390C5", + "size": 2207060, + "mtime": "2022-07-19T23:12:00Z" }, "25": { "filename": "meshagent_armhf", - "hash": "37F717A44CDA07F88D51A5FF9FD220FEA7F61307BD3A418CC8D9E45D9B9EDB1CB069A9398318E0DF2042C4D204657F7D", - "size": 3166784, - "mtime": "2022-03-25T23:37:14Z" - }, - "27": { - "filename": "meshagent_armhf2", - "hash": "0AE840520D3B677B9767EA097F3AA5A1E24212529E688200F43935DB1541AB9FB441EC2C7BA8002D45299B04695FD037", - "size": 2837724, - "mtime": "2021-08-30T21:10:03Z" + "hash": "614CC92DC41FCA4F2BC95020778C5B4B967DBF244E091AB84ABEFAB18E4775EF6ED0F97EB8181CB2FC776B30724EB179", + "size": 3180252, + "mtime": "2022-07-19T05:55:00Z" }, "28": { "filename": "meshagent_mips24kc", - "hash": "636B02BD3DD7DED0BB79FAF1B991F7DB89FF23DC1373D3F5E3EA76897B4BF44E8F00A57A3B6C87EBECA8142D9AD5B7B9", - "size": 4163768, - "mtime": "2022-03-25T23:38:44Z" + "hash": "8AC9BB2A9365C992C40DE0AB654AE5E8A88295C64827325162C7EF218E0EDAA0122983998850902CA3EB31D79BE7E377", + "size": 4180968, + "mtime": "2022-07-19T05:56:10Z" }, "29": { "filename": "meshagent_osx-arm-64", - "hash": "D1D8CDAF59105E4E8A753CCC9032F1653AE4DB973765E3E009CA9F352BA7B3C8E487B4F34BB9A0C4A629C29DE55FFF69", - "size": 3911880, - "mtime": "2022-03-25T23:51:40Z" + "hash": "030935BA1A455F5E18E081C539D2461902DA1D5EE8390C690EDEB203B3C2586AC1BA37F0A0AB8A0A534B21DCBB26C04E", + "size": 3945560, + "mtime": "2022-07-19T06:25:24Z" }, "30": { "filename": "meshagent_freebsd_x86-64", - "hash": "4EA888AAD34D104E7FD898E4F331A9A65EB2EB85C7181DADF1E2A5C04B8F22B91B46AEBDC512D714D11D04B4C2B1EA3E", - "size": 4657032, - "mtime": "2022-03-25T23:51:56Z" + "hash": "6934C785992896EAA5B7DE0604326C7937A9788F2987DBF52C38CE928BA30524F2DD0CF8767A0147B1F8DA5ED1349030", + "size": 4671416, + "mtime": "2022-07-19T06:23:50Z" }, "32": { "filename": "meshagent_aarch64", - "hash": "27B50D0696EA3156BA91CBE0EFC2775217A2DCB1BC7AB0B079DCDE52E7D2B3E2A2647FDC6F74087C4D8D748FD90F59AD", - "size": 3227888, - "mtime": "2022-03-25T23:34:50Z" + "hash": "2BCEDB1042642D9B970F7B2532B700C4D3EA02F934CC6167E89E819C245A502043BDEBF64B4A2D75E0437F56AF1FFC17", + "size": 3248496, + "mtime": "2022-07-19T05:53:38Z" }, "40": { "filename": "meshagent_mipsel24kc", - "hash": "31F3377C4703CFFDD6905FC0EFC96C4BB328474CE62BECB2E79860C5841CA9019EFC6945974847D03797EE49529DDDE0", - "size": 4160072, - "mtime": "2022-03-25T23:40:12Z" + "hash": "15A135796664E2C6BA485A67246E0A5D8E9949FABB8F89DCF9C1C0D1701326DF356FD4003B54B3478B0400A798D7FA79", + "size": 4177256, + "mtime": "2022-07-19T05:57:12Z" }, "41": { "filename": "meshagent_aarch64-cortex-a53", - "hash": "E6D65EB2F8013E4DB811E2E73150C063EB41DF8C9D8321D1F2CA2FAEEA7DBA203032AD4E95A467A0D8FD836E18EE3D0D", - "size": 3059896, - "mtime": "2022-03-25T23:41:28Z" + "hash": "CA2034354732DF86F5D8E66B84E44F8DDB217E4059CBF473F85DD9E1A5B6583B7587053BF192FFCE301BD0F93E40DB9D", + "size": 3076424, + "mtime": "2022-07-19T05:58:08Z" }, "10005": { "filename": "meshagent_osx-universal-64", - "hash": "5AB5C0580E9B7B0689C20FD01561997D7B17CA5E14C747E981888C74B8CCECEE827E141ECF6CBD76C5040051C09DE840", - "size": 8335560, - "mtime": "2022-03-25T23:51:40Z" + "hash": "0092732E6602AF83DB316BF1924D6DA609534C50287B87A4E044E7595756890AEF19186A9C4618753C37EE114A035B75", + "size": 8664152, + "mtime": "2022-07-19T06:25:24Z" } } diff --git a/views/default-mobile.handlebars b/views/default-mobile.handlebars index 0bf905c2..c653ec6a 100644 --- a/views/default-mobile.handlebars +++ b/views/default-mobile.handlebars @@ -1303,7 +1303,7 @@ if (t != null) { desktopsettings = JSON.parse(t); } applyDesktopSettings(); - attemptWebRTC = false; // For now, default WebRTC off unless we set it in the URL. + //attemptWebRTC = false; // For now, default WebRTC off unless we set it in the URL. if (args.webrtc != null) { attemptWebRTC = (args.webrtc == 1); } // Session Refresh Timer diff --git a/views/default.handlebars b/views/default.handlebars index e7ae6e73..c6266029 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -1555,7 +1555,7 @@ if (!args.locale) { var x = getstore('loctag', 0); if ((x != null) && (x != '*')) { args.locale = x; } } debugmode = args.debug; - attemptWebRTC = false; // For now, default WebRTC off unless we set it in the URL. + //attemptWebRTC = false; // For now, default WebRTC off unless we set it in the URL. if (args.webrtc != null) { attemptWebRTC = (args.webrtc == 1); } QV('p13AutoConnect', debugmode); // Files @@ -14029,6 +14029,7 @@ 151: "Started Web-VNC session \"{0}\".", // Not in use yet 152: "No longer a relay for \"{0}\".", 153: "Is a relay for \"{0}\".", + 154: "Account changed to sync with LDAP data." }; var eventsShortMessageId = { diff --git a/webserver.js b/webserver.js index 0c37032a..30731f5c 100644 --- a/webserver.js +++ b/webserver.js @@ -452,11 +452,6 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF // Work on getting the userid for this LDAP user var shortname = null; - if ('[object Array]' == Object.prototype.toString.call(email)) { - // mail may be multivalued in ldap in which case, answer would be an array. Use the 1st one. - email = email[0]; - } - if (email) { email = email.toLowerCase(); } // it seems some code otherwhere also lowercase the emailaddress. be compatible. var username = xxuser['displayName']; if (domain.ldapusername) { username = xxuser[domain.ldapusername]; } if (domain.ldapuserbinarykey) { @@ -476,28 +471,31 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF if (username == null) { username = shortname; } var userid = 'user/' + domain.id + '/' + shortname; - // Work on getting the email address for this LDAP user + // Get the email address for this LDAP user var email = null; if (domain.ldapuseremail) { email = xxuser[domain.ldapuseremail]; } else if (xxuser.mail) { email = xxuser.mail; } // Use given feild name or default if ('[object Array]' == Object.prototype.toString.call(email)) { email = email[0]; } // Mail may be multivalued in LDAP in which case, answer is an array. Use the 1st value. if (email) { email = email.toLowerCase(); } // it seems some code elsewhere also lowercase the emailaddress, so let's be consistant. - // Work on getting the real name for this LDAP user + // Get the real name for this LDAP user var realname = null; if (domain.ldapuserrealname) { realname = xxuser[domain.ldapuserrealname]; } + else { if (typeof xxuser['name'] == 'string') { realname = xxuser['name']; } } - // Work on getting the phone number for this LDAP user + // Get the phone number for this LDAP user var phonenumber = null; if (domain.ldapuserphonenumber) { phonenumber = xxuser[domain.ldapuserphonenumber]; } + else { if (typeof xxuser['telephoneNumber'] == 'string') { phonenumber = xxuser['telephoneNumber']; } } // Work on getting the image of this LDAP user - /* - var userimage = null; - if (domain.ldapuserimage && xxuser[domain.ldapuserimage]) { - console.log('IMAGE', Buffer.from(xxuser[domain.ldapuserimage], 'utf8')); - userimage = 'data:image/jpeg;base64,' + Buffer.from(xxuser[domain.ldapuserimage], 'binary').toString('base64'); + // TODO: We need to get the image from LDAP as a buffer: https://github.com/ldapjs/node-ldapjs/issues/137 + var userimage = null, userImageBuffer = null; + if (domain.ldapuserimage && xxuser[domain.ldapuserimage]) { try { userImageBuffer = Buffer.from(xxuser[domain.ldapuserimage], 'binary'); } catch (ex) { } } + if (xxuser['thumbnailPhoto']) { try { userImageBuffer = Buffer.from(xxuser['thumbnailPhoto'], 'binary'); } catch (ex) { } } + if (userImageBuffer != null) { + if ((userImageBuffer[0] == 0xFF) && (userImageBuffer[1] == 0xD8) && (userImageBuffer[2] == 0xFF) && (userImageBuffer[3] == 0xE0)) { userimage = 'data:image/jpeg;base64,' + userImageBuffer.toString('base64'); } + if ((userImageBuffer[0] == 0x89) && (userImageBuffer[1] == 0x50) && (userImageBuffer[2] == 0x4E) && (userImageBuffer[3] == 0x47)) { userimage = 'data:image/png;base64,' + userImageBuffer.toString('base64'); } } - */ // Display user information extracted from LDAP data /* @@ -505,7 +503,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF console.log('email', email); console.log('realname', realname); console.log('phonenumber', phonenumber); - console.log('userimage', userimage); + console.log('userimage', userimage != null); */ // If there is a testing userid, use that @@ -514,6 +512,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF userid = 'user/' + domain.id + '/' + shortname; } + // Save the user image + if (userimage != null) { parent.db.Set({ _id: 'im' + userid, image: userimage }); } else { db.Remove('im' + userid); } + // Check if the user already exists var user = obj.users[userid]; if (user == null) { @@ -549,6 +550,15 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF } } + // Check the user real name + if (realname) { user.realname = realname; } + + // Check the user phone number + if (phonenumber) { user.phone = phonenumber; } + + // Indicate that this user has a image + if (userimage != null) { user.flags = 1; } + obj.users[user._id] = user; obj.db.SetUser(user); var event = { etype: 'user', userid: user._id, username: user.name, account: obj.CloneSafeUser(user), action: 'accountcreate', msgid: 128, msgArgs: [user.name], msg: 'Account created, name is ' + user.name, domain: domain.id }; @@ -556,32 +566,41 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF obj.parent.DispatchEvent(['*', 'server-users'], obj, event); return fn(null, user._id); } else { + var userChanged = false; + // This is an existing user // If the display username has changes, update it. - if (user.name != username) { - user.name = username; - obj.db.SetUser(user); - var event = { etype: 'user', userid: user._id, username: user.name, account: obj.CloneSafeUser(user), action: 'accountchange', msgid: 127, msgArgs: [user.name], msg: 'Changed account display name to ' + user.name, domain: domain.id }; - if (obj.db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user. Another event will come. - parent.DispatchEvent(['*', 'server-users', user._id], obj, event); - } + if (user.name != username) { user.name = username; userChanged = true; } + // Check if user email has changed - var emailreason = null; if (user.email && !email) { // email unset in ldap => unset delete user.email; delete user.emailVerified; - emailreason = 'Unset email (no more email in LDAP)' + userChanged = true; } else if (user.email != email) { // update email user['email'] = email; user['emailVerified'] = true; - emailreason = 'Set account email to ' + email + '. Sync with LDAP.'; + userChanged = true; } - if (emailreason) { + + // Check the user real name + if (realname != user.realname) { user.realname = realname; userChanged = true; } + + // Check the user phone number + if (phonenumber != user.phone) { user.phone = phonenumber; userChanged = true; } + + // Check the user image flag + if ((userimage != null) && ((user.flags == null) || ((user.flags & 1) == 0))) { if (user.flags == null) { user.flags = 1; } else { user.flags += 1; } userChanged = true; } + if ((userimage == null) && (user.flags != null) && ((user.flags & 1) != 0)) { if (user.flags == 1) { delete user.flags; } else { user.flags -= 1; } userChanged = true; } + + // If the user changed, save the changes to the database here + if (userChanged) { obj.db.SetUser(user); - var event = { etype: 'user', userid: user._id, username: user.name, account: obj.CloneSafeUser(user), action: 'accountchange', msg: emailreason, domain: domain.id }; + var event = { etype: 'user', userid: user._id, username: user.name, account: obj.CloneSafeUser(user), action: 'accountchange', msgid: 154, msg: 'Account changed to sync with LDAP data.', domain: domain.id }; if (obj.db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user. Another event will come. parent.DispatchEvent(['*', 'server-users', user._id], obj, event); } + // If user is locker out, block here. if ((user.siteadmin) && (user.siteadmin != 0xFFFFFFFF) && (user.siteadmin & 32) != 0) { fn('locked'); return; } return fn(null, user._id); @@ -594,10 +613,10 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF if (xxuser == null) { fn(new Error('invalid password')); return; } else { ldapHandler.ldapShortName = name.toLowerCase(); if (typeof xxuser == 'string') { - // This test LDAP user points to a JSON file we user information, load it. + // The test LDAP user points to a JSON file where the user information is, load it. ldapHandler(null, require(xxuser)); } else { - // THe user information is in the config.json, use it. + // The test user information is in the config.json, use it. ldapHandler(null, xxuser); } } @@ -606,10 +625,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF var LdapAuth = require('ldapauth-fork'); var ldap = new LdapAuth(domain.ldapoptions); ldapHandler.ldapobj = ldap; - ldap.on('error', function (err) { - try { ldap.close(); } catch (ex) { console.log(ex); } // Close the LDAP object - console.log('ldap error: ', err); - }); + ldap.on('error', function (err) { try { ldap.close(); } catch (ex) { console.log(ex); } console.log('ldap error: ', err); }); // Close the LDAP object ldap.authenticate(name, pass, ldapHandler); } } else {