From 1246937bd048a44bad5e88cb86958dfa19fb115d Mon Sep 17 00:00:00 2001 From: javo Date: Tue, 18 Dec 2018 16:00:47 -0300 Subject: [PATCH 1/7] Autoconnect improvements and system trigger --- lib/agent/index.js | 2 +- lib/agent/providers/network/index.js | 19 +++ lib/agent/triggers/auto-connect/index.js | 36 +++-- lib/agent/triggers/auto-connect/linux.js | 37 +++-- lib/agent/triggers/auto-connect/mac.js | 38 ++--- lib/agent/triggers/auto-connect/reconnect.js | 117 +++++++++----- lib/agent/triggers/auto-connect/windows.js | 35 +++-- lib/agent/triggers/system/index.js | 96 ++++++++++++ test/lib/agent/triggers/auto-connect.js | 154 +++++++++++++++---- 9 files changed, 389 insertions(+), 145 deletions(-) create mode 100644 lib/agent/triggers/system/index.js diff --git a/lib/agent/index.js b/lib/agent/index.js index 810aab333..460769f8f 100644 --- a/lib/agent/index.js +++ b/lib/agent/index.js @@ -25,7 +25,7 @@ var config = common.config, helpers = common.helpers, exceptions = common.exceptions, plugins = common.plugins, - watch_list = ['connection', 'control-zones', 'hostname', 'location', 'network', 'power'], + watch_list = ['auto-connect','connection', 'control-zones', 'hostname', 'location', 'network', 'power', 'system'], running = false, started_at = null, running_as = null; diff --git a/lib/agent/providers/network/index.js b/lib/agent/providers/network/index.js index 0058a61d6..2d998cb59 100644 --- a/lib/agent/providers/network/index.js +++ b/lib/agent/providers/network/index.js @@ -169,6 +169,25 @@ exp.get_open_access_points_list = function(callback) { }; +exp.get_categorized_access_points_list = function(callback) { + + exp.get_access_points_list(function(err, list) { + if (err || !list) + return callback(err || new Error('No access points detected.')); + + var open_aps = list.filter(function(ap) { + return ap.security == false || ap.security == null; + }); + + var secured_aps = list.filter(function(ap) { + return ap.security; + }); + + callback(null, [open_aps, secured_aps]); + }); + +}; + exp.get_connection_status = function(cb) { var proxy = config.get('try_proxy'), protocol = config.get('control-panel').protocol, diff --git a/lib/agent/triggers/auto-connect/index.js b/lib/agent/triggers/auto-connect/index.js index ab0bb8f06..73999df16 100644 --- a/lib/agent/triggers/auto-connect/index.js +++ b/lib/agent/triggers/auto-connect/index.js @@ -11,18 +11,19 @@ var join = require('path').join, var emitter, reconnect_time = 30000, - was_disconnected = false; + sleeping = false, + was_disconnected = false, timer = null; var connected = false; -var restart_reconnection = function() { +var restart_reconnection = () => { stop_waiting(); reconnect_time = 1000 * 60 * 3; // Three minutes wait_normal_reconnection(); } -var check_err = function(err) { +var check_err = (err) => { logger.info(err); if (err.message.includes('Already connected')) { logger.info(err.message + ". Autoconnect disengaged for now :)") @@ -31,14 +32,14 @@ var check_err = function(err) { else restart_reconnection(); } -var wait_normal_reconnection = function() { +var wait_normal_reconnection = () => { logger.info("Device disconnected! Waiting for reconnection..."); - reconnect.enable_wifi(function() { - timer = setTimeout(function() { + reconnect.enable_wifi(() => { + timer = setTimeout(() => { logger.info("Nothing happened, let's try connecting to the nearest access points..."); - reconnect.get_open_ap_list(function(err, list) { + reconnect.get_open_ap_list((err, list) => { if (err) return check_err(err); - reconnect.try_connecting_to(list, function(err, stdout) { + reconnect.try_connecting_to(list, (err, stdout) => { if (err) return check_err(err); return wait_normal_reconnection(); }); @@ -47,16 +48,16 @@ var wait_normal_reconnection = function() { }) } -var stop_waiting = function() { +var stop_waiting = () => { if (timer) { clearTimeout(timer); timer = null; } } -exports.start = function(opts, cb) { - hooks.on('connected', function() { - network.get_active_access_point(function(err, ap) { +exports.start = (opts, cb) => { + hooks.on('connected', () => { + network.get_active_access_point((err, ap) => { if (was_disconnected) { logger.info("Connection achieved! " + (ap ? ap.ssid || "" : "")); was_disconnected = false; @@ -67,20 +68,25 @@ exports.start = function(opts, cb) { stop_waiting(); }); - hooks.on('disconnected', function() { + hooks.on('disconnected', () => { was_disconnected = true; connected = false; - if (config.get('auto_connect') && os_name != 'linux') { + if (config.get('auto_connect') && !sleeping && os_name != 'linux') { reconnect.connected(null); wait_normal_reconnection(); } }); + hooks.on('sleeping', (value) => { + if (value) sleeping = true; + else sleeping = false; + }) + emitter = new Emitter(); cb(null, emitter); } -exports.stop = function() { +exports.stop = () => { hooks.remove('connected'); hooks.remove('disconnected'); diff --git a/lib/agent/triggers/auto-connect/linux.js b/lib/agent/triggers/auto-connect/linux.js index 99b04a737..3280cb9bf 100644 --- a/lib/agent/triggers/auto-connect/linux.js +++ b/lib/agent/triggers/auto-connect/linux.js @@ -1,59 +1,58 @@ -var join = require('path').join, - exec = require('child_process').exec; +var exec = require('child_process').exec; network = require('./../../providers/network/linux'); var net_interface = null; -var get_interface = function(cb) { - network.get_first_wireless_interface(function(err, data) { +var get_interface = (cb) => { + network.get_first_wireless_interface((err, data) => { net_interface = data; }); } -exports.enable_wifi = function(cb) { - var turn_on_wifi = function() { +exports.enable_wifi = (cb) => { + var turn_on_wifi = () => { var cmd = 'nmcli networking on; nmcli radio wifi on'; - exec(cmd, function(err, data) { + exec(cmd, (err, data) => { return cb(); }) } net_interface ? turn_on_wifi() : get_interface(turn_on_wifi); } -exports.get_existing_profiles = function(cb) { - var get_profiles = function() { +exports.get_existing_profiles = (cb) => { + var get_profiles = () => { var cmd = 'ls /etc/NetworkManager/system-connections' - exec(cmd, function(err, stdout) { + exec(cmd, (err, stdout) => { cb(null, stdout.split("\n").slice(0, -1)); }) } net_interface ? get_profiles() : get_interface(get_profiles); } -exports.create_profile = function(ssid, cb) { - var create = function() { +exports.create_profile = (ssid, cb) => { + var create = () => { var cmd = `nmcli connection add type wifi ifname ${net_interface} con-name "${ssid}" ssid "${ssid}"`; - exec(cmd, function(err, out) { + exec(cmd, (err, out) => { return cb && cb(err); }) } net_interface ? create() : get_interface(create); } -exports.delete_profile = function(ssid, cb) { - var discard = function() { +exports.delete_profile = (ssid, cb) => { + var discard = () => { var cmd = `nmcli connection delete "${ssid}"`; - exec('nmcli connection delete ' + '"' + ssid + '"', function(err, out) { + exec('nmcli connection delete ' + '"' + ssid + '"', (err, out) => { return cb && cb(err); }) } net_interface ? discard() : get_interface(discard); } -exports.connect_to_ap = function(ssid, cb) { - var connect = function() { +exports.connect_to_ap = (ssid, cb) => { + var connect = () => { var cmd = `nmcli connection up "${ssid}"`; - exec(cmd, function(err, out) { + exec(cmd, (err, out) => { return cb(err, out); }); } diff --git a/lib/agent/triggers/auto-connect/mac.js b/lib/agent/triggers/auto-connect/mac.js index 240cc1f32..4bb0eddf3 100644 --- a/lib/agent/triggers/auto-connect/mac.js +++ b/lib/agent/triggers/auto-connect/mac.js @@ -1,13 +1,12 @@ -var join = require('path').join, - exec = require('child_process').exec, +var exec = require('child_process').exec, system = require('./../../../system'), run_as_user = system.run_as_logged_user; var net_interface = null; -var get_interface = function(cb) { +var get_interface = (cb) => { var cmd = 'networksetup -listallhardwareports | awk "/Hardware Port: Wi-Fi/,/Ethernet/" | awk "NR==2" | cut -d " " -f 2'; - exec(cmd, function(err, data) { + exec(cmd, (err, data) => { if (err) return cb(err); net_interface = data.split("\n").slice(0, -1); @@ -15,50 +14,51 @@ var get_interface = function(cb) { }) } -exports.enable_wifi = function(cb) { - var turn_on_wifi = function() { +exports.enable_wifi = (cb) => { + console.log("ENABLE WIFI!!") + var turn_on_wifi = () => { var cmd = `networksetup -setairportpower ${net_interface} on`; - exec(cmd, function(err, data) { + exec(cmd, (err, data) => { return cb(); }) } net_interface ? turn_on_wifi() : get_interface(turn_on_wifi); } -exports.get_existing_profiles = function(cb) { - var get_profiles = function() { +exports.get_existing_profiles = (cb) => { + var get_profiles = () => { var cmd = `networksetup -listpreferredwirelessnetworks ${net_interface} | awk 'NR>1' | awk '{$1=$1;print}'` - exec(cmd, function(err, stdout) { + exec(cmd, (err, stdout) => { cb(null, stdout.split("\n").slice(0, -1)); }) } net_interface ? get_profiles() : get_interface(get_profiles); } -exports.create_profile = function(ssid, cb) { - var create = function() { +exports.create_profile = (ssid, cb) => { + var create = () => { var cmd = `networksetup -addpreferredwirelessnetworkatindex ${net_interface} "${ssid}" 0 open`; - run_as_user(cmd, [], function(err) { + run_as_user(cmd, [], (err) => { return cb && cb(err); }) } net_interface ? create() : get_interface(create); } -exports.delete_profile = function(ssid, cb) { - var discard = function() { +exports.delete_profile = (ssid, cb) => { + var discard = () => { var cmd = `networksetup -removepreferredwirelessnetwork ${net_interface} "${ssid}"`; - run_as_user(cmd, [], function(err) { + run_as_user(cmd, [], (err) => { return cb && cb(err); }) } net_interface ? discard() : get_interface(discard); } -exports.connect_to_ap = function(ssid, cb) { // revisar cb si va - var connect = function() { +exports.connect_to_ap = (ssid, cb) => { // revisar cb si va + var connect = () => { var cmd = `networksetup -setairportnetwork ${net_interface} "${ssid}"`; - run_as_user(cmd, [], function(err, out) { + run_as_user(cmd, [], (err, out) => { return cb(err, out); }); } diff --git a/lib/agent/triggers/auto-connect/reconnect.js b/lib/agent/triggers/auto-connect/reconnect.js index f3be85d92..8ae9f135f 100644 --- a/lib/agent/triggers/auto-connect/reconnect.js +++ b/lib/agent/triggers/auto-connect/reconnect.js @@ -6,25 +6,26 @@ var async = require('async'), logger = common.logger.prefix('auto-connect'); var previous = null, + previous_secured_wifi = [], connected_to = false; exports.attempted_wifi = {}, exports.time_between = 20000; exports.init_profiles = []; -var get_existing_profiles = function(cb) { - os_functions.get_existing_profiles(function(err, data) { +var get_existing_profiles = (cb) => { + os_functions.get_existing_profiles((err, data) => { return cb(null, data); }); } -var delete_profile = function(ssid, cb) { - get_existing_profiles(function(err, current_profiles) { +var delete_profile = (ssid, cb) => { + get_existing_profiles((err, current_profiles) => { // Check if the profile isn't original and exists in the current list also if the device is connected to that ap if (!ssid || exports.init_profiles.indexOf(ssid) != -1 || current_profiles.indexOf(ssid) == -1 || connected_to.ssid == ssid) { return cb(new Error("Nothing to delete " + ssid)); } - os_functions.delete_profile(ssid, function(err) { + os_functions.delete_profile(ssid, (err) => { if (!err) { logger.debug("Profile " + ssid + " succesfuly deleted"); previous = null; @@ -34,20 +35,20 @@ var delete_profile = function(ssid, cb) { }) } -var create_profile = function(ssid, cb) { - get_existing_profiles(function(err, current_profiles) { +var create_profile = (ssid, cb) => { + get_existing_profiles((err, current_profiles) => { if (current_profiles.indexOf(ssid) != -1) return cb(new Error("Profile " + ssid + " already exists")); - os_functions.create_profile(ssid, function(err) { + os_functions.create_profile(ssid, (err) => { if (!err) logger.debug("Profile " + ssid + " succesfuly created"); cb(null); }); }) } -var connect_to_access_point = function(ap, cb) { - var connect = function() { +var connect_to_access_point = (ap, cb) => { + var connect = () => { logger.info("Trying to connect to: " + ap.ssid); previous = ap.ssid; os_functions.connect_to_ap(ap.ssid, cb); @@ -57,7 +58,7 @@ var connect_to_access_point = function(ap, cb) { if (connected_to) { delete exports.attempted_wifi[connected_to.mac_address]; if (previous != connected_to.ssid) { - delete_profile(previous, function(err) { + delete_profile(previous, (err) => { if (err) logger.debug(err.message) }); } @@ -66,22 +67,22 @@ var connect_to_access_point = function(ap, cb) { exports.attempted_wifi[ap.mac_address] ? exports.attempted_wifi[ap.mac_address]++ : exports.attempted_wifi[ap.mac_address] = 1; - delete_profile(previous, function(err) { + delete_profile(previous, (err) => { if (err) logger.debug(err.message) - create_profile(ap.ssid, function(err) { + create_profile(ap.ssid, (err) => { if (err) logger.debug(err.message) connect(); }) }) } -exports.try_connecting_to = function(list, cb) { +exports.try_connecting_to = (list, cb) => { var array = []; - list.forEach(function(ap) { + list.forEach((ap) => { array.push( - function(callback) { - setTimeout(function() { - connect_to_access_point(ap, function(err) { + (callback) => { + setTimeout(() => { + connect_to_access_point(ap, (err) => { if (err && err.message.includes('Already connected')) return callback(err); callback(); }) @@ -90,15 +91,15 @@ exports.try_connecting_to = function(list, cb) { ) }) - array.push(function(callback) { - setTimeout(function() { + array.push((callback) => { + setTimeout(() => { callback(new Error("Connection attempted with all the open access points, retrying in 3 minutes...")); }, exports.time_between) }) - async.series(array, function(err) { + async.series(array, (err) => { if (err.message.includes("Connection attempted with all the open access points")) { - delete_profile(previous, function(err) { + delete_profile(previous, (err) => { if (err) logger.info(err.message); }); } @@ -109,43 +110,77 @@ exports.try_connecting_to = function(list, cb) { }); } -exports.get_open_ap_list = function(cb) { +exports.get_ap_lists = (cb) => { previuos = null; if (connected_to) return cb(new Error("Already connected to: " + connected_to.ssid)); + var proceed_with_open_aps = (open, current_profiles) => { + if (!open || open.length == 0) return cb(new Error('No open access points found. Retrying in 10')) + + var final_list = []; + + // Filter the 3 times attempted access points + open.forEach((ap) => { + if (!(ap.mac_address in exports.attempted_wifi) || exports.attempted_wifi[ap.mac_address] < 3) { + // Put open ap at the beginning of the list if the device was previously connected to it + current_profiles.indexOf(ap.ssid) > -1 ? final_list.unshift(ap) : final_list.push(ap); + } else { + logger.debug("3 attempts reached for: " + ap.ssid); + } + }) + + cb(null, final_list); + } + // Make sure Wi-Fi is on - os_functions.enable_wifi(function() { - // Scan the open access points - providers.get('open_access_points_list', function(err, list) { - if (err || !list || list.length == 0) { + os_functions.enable_wifi(() => { + // Scan the open and secured access points + providers.get('categorized_access_points_list', (err, list) => { + if (err || !list) { return cb(new Error('No open access points found. Retrying in 10')) } - var final_list = []; - - // Filter the 3 times attempted access points - list.forEach(function(ap) { - if (!(ap.mac_address in exports.attempted_wifi) || exports.attempted_wifi[ap.mac_address] < 3) { - final_list.push(ap); - } else { - logger.debug("3 attempts reached for: " + ap.ssid); - } - }) - cb(null, final_list); + var open = list[0], + secured = list[1]; + + exports.get_existing_profiles((err, current_profiles) => { + if (err || !secured || secured.length == 0) return proceed_with_open_aps(open, current_profiles); + + // Check if the device previously connected to at least one of the secured ap's + var known_secured_wifi = []; + secured.forEach((ap) => { + current_profiles.forEach((ssid) => { + if (ssid.trim() == ap.ssid.trim()) + known_secured_wifi.push(ap.ssid); + }) + }) + + var new_secured_wifi = known_secured_wifi.filter(x => previous_secured_wifi.indexOf(x) == -1) + previous_secured_wifi = previous_secured_wifi.concat(new_secured_wifi); + + if (new_secured_wifi.length > 0) + return cb(new Error('There is a secured known network, waiting for the device to autoconnect')) + + console.log("OPEN", open) + + proceed_with_open_aps(open, current_profiles); + + }); }) }) } -exports.connected = function(ap) { +exports.connected = (ap) => { + previous_secured_wifi = []; connected_to = false; if (ap) connected_to = ap; } -exports.enable_wifi = function(cb) { +exports.enable_wifi = (cb) => { os_functions.enable_wifi(cb); } -get_existing_profiles(function(err, profiles) { +get_existing_profiles((err, profiles) => { exports.init_profiles = profiles; }) diff --git a/lib/agent/triggers/auto-connect/windows.js b/lib/agent/triggers/auto-connect/windows.js index 8e4749cab..c1fb1840b 100644 --- a/lib/agent/triggers/auto-connect/windows.js +++ b/lib/agent/triggers/auto-connect/windows.js @@ -38,7 +38,7 @@ var profile_json = { } } -var generate_xml = function(ssid, cb) { +var generate_xml = (ssid, cb) => { var profile = profile_json; profile.WLANProfile.name = [ssid]; profile.WLANProfile.SSIDConfig[0].SSID[0].hex = [Buffer.from(ssid, 'utf8').toString('hex').toUpperCase()]; @@ -47,30 +47,31 @@ var generate_xml = function(ssid, cb) { var builder = new xml2js.Builder(), xml = builder.buildObject(profile); - fs.writeFile(join(tmpdir, `PreyWiFi-${ssid}.xml`), xml, function(err) { + fs.writeFile(join(tmpdir, `PreyWiFi-${ssid}.xml`), xml, (err) => { return cb && cb(err); }) } -exports.enable_wifi = function(cb) { - exec(wifion, function(err) { +exports.enable_wifi = (cb) => { + exec(wifion, (err) => { return cb(); }); } -var delete_xml = function(ssid, cb) { +var delete_xml = (ssid, cb) => { var file = join(tmpdir, `PreyWiFi-${ssid}.xml`); - fs.unlink(file, function(err) { + fs.unlink(file, (err) => { return cb && cb(err); }) } -exports.get_existing_profiles = function(cb) { - exec('netsh wlan show profiles', function(err, data) { +exports.get_existing_profiles = (cb) => { + exec('netsh wlan show profiles', (err, data) => { var lines = data.toString().split('\n'); var profiles = []; - lines.forEach(function(line) { + lines.forEach((line) => { + if (line.includes('All User Profile :')) { var profile = line.split(': ').pop(); profiles.push(profile.trim()); @@ -81,27 +82,27 @@ exports.get_existing_profiles = function(cb) { }) } -exports.create_profile = function(ssid, cb) { +exports.create_profile = (ssid, cb) => { var file = join(tmpdir, `PreyWiFi-${ssid}.xml`); - generate_xml(ssid, function(err) { + generate_xml(ssid, (err) => { if (err) return cb(err); - exec(`netsh wlan add profile filename="${file}" user=all`, function(err, stdout) { + exec(`netsh wlan add profile filename="${file}" user=all`, (err, stdout) => { return cb && cb(err); }) }) } -exports.delete_profile = function(ssid, cb) { - delete_xml(ssid, function(err) { - exec(`netsh wlan delete profile "${ssid}"`, function(err, stdout) { +exports.delete_profile = (ssid, cb) => { + delete_xml(ssid, (err) => { + exec(`netsh wlan delete profile "${ssid}"`, (err, stdout) => { return cb && cb(err); }) }); } -exports.connect_to_ap = function(ssid, cb) { // revisar cb si va - exec(`netsh wlan connect name="${ssid}"`, function(err, out) { +exports.connect_to_ap = (ssid, cb) => { // revisar cb si va + exec(`netsh wlan connect name="${ssid}"`, (err, out) => { return cb(err, out); }); } \ No newline at end of file diff --git a/lib/agent/triggers/system/index.js b/lib/agent/triggers/system/index.js new file mode 100644 index 000000000..e80158a13 --- /dev/null +++ b/lib/agent/triggers/system/index.js @@ -0,0 +1,96 @@ +"use strict" + +var triggers = require('os-triggers'), + join = require('path').join, + base_path = join(__dirname, '..', '..'), + hooks = require(join(base_path, 'hooks')), + exec = require('child_process').exec, + os_name = process.platform.replace('win32', 'windows').replace('darwin', 'mac'), + is_mac = os_name == 'mac', + Emitter = require('events').EventEmitter; + +var emitter, + previous = null, + checking = false; + +var common = require('./../../common'), + logger = common.logger.prefix('system'); + +var get_current_state = (cb) => { + if (is_mac) { + let cmd = `pmset -g log|grep -e " Sleep " -e " Wake "|tail -n 1 |awk '{print $4}'`; + exec(cmd, (err, state) => { + if (err) return cb(err); + + state = state.trim(); + let current = false; + + if (state == "Sleep") + current = true; + + return cb(null, current); + }); + + } else return cb(new Error('No info available')); +} + +var check_and_emit = (info) => { + if (checking) return; + checking = true; + + var done = (err, current) => { + if (err) logger.warn("ERROR!", err.message) + + if (previous != current) + hooks.trigger('sleeping', current); + + previous = current; + checking = false; + } + + if (info) { + let current = (info == 'true'); + return done(null, current); + } + + get_current_state((err, current) => { + if (err) return done(err); + return done(null, current); + }) +}; + +exports.start = function(opts, cb){ + + triggers.watch('system', { respawn: true }) + .catch(error => { return cb(error); }) + .then((system) => { + + // For mac and linux + system.on('state_changed', (info) => { + check_and_emit(info); + }); + + // For windows + system.on('suspended', (info) => { + check_and_emit('true'); + }); + system.on('unsuspended', (info) => { + check_and_emit(info); + }); + system.on('resumed', (info) => { + check_and_emit('false'); + }); + + emitter = new Emitter(); + cb(null, emitter); + }); +}; + +exports.stop = () => { + triggers.unwatch('system'); + if (emitter) { + emitter.removeAllListeners(); + emitter = null; + } +}; + diff --git a/test/lib/agent/triggers/auto-connect.js b/test/lib/agent/triggers/auto-connect.js index 54d7d268b..1ecb45f02 100644 --- a/test/lib/agent/triggers/auto-connect.js +++ b/test/lib/agent/triggers/auto-connect.js @@ -11,12 +11,12 @@ var ap_list = [ { ssid: 'Prey-Guest', signal_strength: -51, channel: 1, security: false }, - { ssid: 'Unsecured Wifi', + { ssid: 'Unsecured Wifi', mac_address: 'ab:cd:ef:gh:ij:kl', signal_strength: -66, channel: 1, security: false }, - { ssid: 'Secured wifi', + { ssid: 'Secured wifi', mac_address: '12:34:56:78:ab:cd', signal_strength: -66, channel: 1, @@ -75,6 +75,16 @@ describe('auto connect', function() { enable_wifi.restore(); }) + describe('get existing profiles', function() { + it('not callsback error', function(done) { + reconnect.get_existing_profiles(function(err, profiles) { + should.not.exist(err); + profiles.should.be.an.Array; + done(); + }) + }) + }) + describe('get open ap list', function() { describe('on empty list', function() { @@ -89,7 +99,7 @@ describe('auto connect', function() { }) it('callback an error', function(done) { - reconnect.get_open_ap_list(function(err, list) { + reconnect.get_ap_lists(function(err, list) { should.exist(err); err.message.should.containEql('No open access points found'); done(); @@ -111,49 +121,127 @@ describe('auto connect', function() { }) }) - it('not callback error', function(done) { - reconnect.get_open_ap_list(function(err, list) { - should.not.exist(err); - should.exist(list) - done(); + describe('when in the secured list there a profile in the current list', () => { + before(() => { + profiles_stub = sinon.stub(reconnect, 'get_existing_profiles', function(cb) { + cb(null, ['Pery', 'Secured wifi']); + }) }) - }) - it('returns a list only of open access points', function(done) { - reconnect.get_open_ap_list(function(err, list) { - list.length.should.be.equal(2); - list[0].ssid.should.be.equal('Prey-Guest'); - list[0].security.should.be.equal(false); - list[1].ssid.should.be.equal('Unsecured Wifi'); - list[1].security.should.be.equal(false); - done(); + after(() => { + profiles_stub.restore(); }) + + describe('the first time', () => { + it('waits for the autoconnection to the secured wifi', (done) => { + reconnect.get_ap_lists(function(err, list) { + should.not.exist(list); + should.exist(err); + err.message.should.containEql('There is a secured known network'); + done(); + }) + }) + }) + + describe('the second time', () => { + it('waits for the autoconnection to the secured wifi', (done) => { + reconnect.get_ap_lists(function(err, list) { + should.exist(list); + should.not.exist(err); + done(); + }) + }) + }) + + describe('the third time', () => { + before(() => { + ap_list_stub.restore(); + profiles_stub.restore(); + + var ap_list2 = ap_list + ap_list2.push({ + ssid: 'holi', + mac_address: '12:34:56:78:ab:cd', + signal_strength: -66, + channel: 1, + security: 'WP2' + }) + + ap_list_stub = sinon.stub(network, 'get_access_points_list', function(cb) { + cb(null, ap_list2); + }) + + profiles_stub = sinon.stub(reconnect, 'get_existing_profiles', function(cb) { + cb(null, ['Pery', 'Secured wifi', 'holi']); + }) + }) + + after(() => { + profiles_stub.restore(); + ap_list_stub.restore(); + }) + + it('waits for the autoconnection to the secured wifi', (done) => { + reconnect.get_ap_lists(function(err, list) { + should.not.exist(list); + should.exist(err); + err.message.should.containEql('There is a secured known network'); + done(); + }) + }) + }) + }) - describe('when an access has been attempted 3 times', function() { - before(function() { - reconnect.attempted_wifi = {'ab:cd:ef:gh:ij:kl': 3} + describe('when in the secured list there a profile in the current list', () => { + before(() => { + profiles_stub = sinon.stub(reconnect, 'get_existing_profiles', function(cb) { + cb(null, []); + }) + ap_list_stub = sinon.stub(network, 'get_access_points_list', function(cb) { + cb(null, ap_list); + }) }) - it('shouldnt return that ap in the final list', function(done) { - reconnect.get_open_ap_list(function(err, list) { + after(() => { + profiles_stub.restore(); + ap_list_stub.restore(); + }) + + it('not callback error', function(done) { + reconnect.get_ap_lists(function(err, list) { should.not.exist(err); - should.exist(list); - list.length.should.be.equal(1); + should.exist(list) + done(); + }) + }) + + it('returns a list only of open access points', function(done) { + reconnect.get_ap_lists(function(err, list) { + list.length.should.be.equal(2); list[0].ssid.should.be.equal('Prey-Guest'); + list[0].security.should.be.equal(false); + list[1].ssid.should.be.equal('Unsecured Wifi'); + list[1].security.should.be.equal(false); done(); }) }) - }) - }) - }) - describe('get existing profiles', function() { - it('not callsback error', function(done) { - reconnect.get_existing_profiles(function(err, profiles) { - should.not.exist(err); - profiles.should.be.an.Array; - done(); + describe('when an open access has been attempted 3 times', function() { + before(function() { + reconnect.attempted_wifi = {'ab:cd:ef:gh:ij:kl': 3} + }) + + it('shouldnt return that ap in the final list', function(done) { + reconnect.get_ap_lists(function(err, list) { + should.not.exist(err); + should.exist(list); + list.length.should.be.equal(1); + list[0].ssid.should.be.equal('Prey-Guest'); + done(); + }) + }) + }) }) }) }) From 712866726161ffb138921e19dd9df9db62f10e1d Mon Sep 17 00:00:00 2001 From: javo Date: Fri, 21 Dec 2018 17:09:55 -0300 Subject: [PATCH 2/7] Linux fixes --- lib/agent/providers/network/linux.js | 2 ++ lib/agent/triggers/auto-connect/index.js | 4 ++-- lib/agent/triggers/auto-connect/linux.js | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/agent/providers/network/linux.js b/lib/agent/providers/network/linux.js index f468b2be6..6b4e8972d 100644 --- a/lib/agent/providers/network/linux.js +++ b/lib/agent/providers/network/linux.js @@ -129,3 +129,5 @@ exports.parse_access_points_list = function(output) { }).filter(function(el) { return !!el }) }; + +exports.get_first_wireless_interface = get_first_wireless_interface; \ No newline at end of file diff --git a/lib/agent/triggers/auto-connect/index.js b/lib/agent/triggers/auto-connect/index.js index 73999df16..79703c4a4 100644 --- a/lib/agent/triggers/auto-connect/index.js +++ b/lib/agent/triggers/auto-connect/index.js @@ -37,7 +37,7 @@ var wait_normal_reconnection = () => { reconnect.enable_wifi(() => { timer = setTimeout(() => { logger.info("Nothing happened, let's try connecting to the nearest access points..."); - reconnect.get_open_ap_list((err, list) => { + reconnect.get_ap_lists((err, list) => { if (err) return check_err(err); reconnect.try_connecting_to(list, (err, stdout) => { if (err) return check_err(err); @@ -71,7 +71,7 @@ exports.start = (opts, cb) => { hooks.on('disconnected', () => { was_disconnected = true; connected = false; - if (config.get('auto_connect') && !sleeping && os_name != 'linux') { + if (config.get('auto_connect') && !sleeping) { reconnect.connected(null); wait_normal_reconnection(); } diff --git a/lib/agent/triggers/auto-connect/linux.js b/lib/agent/triggers/auto-connect/linux.js index 3280cb9bf..5077cbad4 100644 --- a/lib/agent/triggers/auto-connect/linux.js +++ b/lib/agent/triggers/auto-connect/linux.js @@ -11,7 +11,7 @@ var get_interface = (cb) => { exports.enable_wifi = (cb) => { var turn_on_wifi = () => { - var cmd = 'nmcli networking on; nmcli radio wifi on'; + var cmd = 'nmcli networking off; nmcli networking on; nmcli radio wifi on'; exec(cmd, (err, data) => { return cb(); }) @@ -42,7 +42,7 @@ exports.create_profile = (ssid, cb) => { exports.delete_profile = (ssid, cb) => { var discard = () => { var cmd = `nmcli connection delete "${ssid}"`; - exec('nmcli connection delete ' + '"' + ssid + '"', (err, out) => { + exec(cmd, (err, out) => { return cb && cb(err); }) } From 8e0cd9bd84ea87c49313f79e265303ba743029b0 Mon Sep 17 00:00:00 2001 From: javo Date: Thu, 27 Dec 2018 16:16:03 -0300 Subject: [PATCH 3/7] Refactot autoconnect logic and add linux auth --- .../triggers/auto-connect/bin/linux_auth.sh | 95 +++++++++++++ lib/agent/triggers/auto-connect/index.js | 39 +++-- lib/agent/triggers/auto-connect/linux.js | 26 +++- lib/agent/triggers/auto-connect/mac.js | 35 +++-- lib/agent/triggers/auto-connect/reconnect.js | 134 +++++++++++------- test/lib/agent/triggers/auto-connect.js | 84 +++-------- 6 files changed, 265 insertions(+), 148 deletions(-) create mode 100644 lib/agent/triggers/auto-connect/bin/linux_auth.sh diff --git a/lib/agent/triggers/auto-connect/bin/linux_auth.sh b/lib/agent/triggers/auto-connect/bin/linux_auth.sh new file mode 100644 index 000000000..4de89d74d --- /dev/null +++ b/lib/agent/triggers/auto-connect/bin/linux_auth.sh @@ -0,0 +1,95 @@ +#!/bin/bash + +if [ "$EUID" -ne 0 ] + then echo 'Please run as root' + exit +fi + +file="/var/lib/polkit-1/localauthority/50-local.d/10-network-manager.pkla" + +askAutorization () { + read -p "Prey needs autorization to modify network parameters for the autoconnection feature (y/n)" answer > $file; fi +} + +setResults() { + key=`cut -d "=" -f 1 <<< "$1"` + value=`cut -d "=" -f 2 <<< "$1"` + + if [[ "$value" != "yes" ]]; then + if [ $authorized == false ]; then askAutorization; fi + + if [ $key == "ResultAny" ]; then ready[1]=2; else ready[2]=2; fi + value="yes" + fi + + echo $key=$value >> $file; +} + +setIdentity() { + key=`cut -d "=" -f 1 <<< "$1"` + value=`cut -d "=" -f 2 <<< "$1"` + + if [[ $value != *":prey"* ]] && [[ $value != *":*"* ]]; then + if [ $authorized == false ]; then askAutorization; fi + ready[0]=2 + value="$value;unix-user:prey" + fi + + echo $key=$value >> $file; +} + +check () { + # Covered all fields and nothing changed + if [ ${ready[0]} == 1 ] && [ ${ready[1]} == 1 ] && [ ${ready[2]} == 1 ]; then + rm "$file.old" + exit + fi + + # if any of the fields wasn't in the original file + if [ ${ready[0]} == 0 ]; then setIdentity "Identity" "unix-user:prey"; fi + if [ ${ready[1]} == 0 ]; then setResults "ResultAny" "yes"; fi + if [ ${ready[2]} == 0 ]; then setResults "ResultActive" "yes"; fi +} + +# Verify if the files exists +if [ -f $file ]; then + authorized=false + ready=(0 0 0) + + # Back up information and clear original file + cp $file "$file.old" + > $file + + while read -r line; do + processLine $line + done < "$file.old" + + check + exit +else + # Create the file + su -c `printf "[Give Permissions to Prey user]\nIdentity=unix-user:prey\nAction=org.freedesktop.NetworkManager.*\nResultAny=yes\nResultInactive=no\nResultActive=yes\n" > ${file}` + exit +fi \ No newline at end of file diff --git a/lib/agent/triggers/auto-connect/index.js b/lib/agent/triggers/auto-connect/index.js index 79703c4a4..bfb4a9422 100644 --- a/lib/agent/triggers/auto-connect/index.js +++ b/lib/agent/triggers/auto-connect/index.js @@ -4,13 +4,13 @@ var join = require('path').join, network = require(join(base_path,'providers', 'network')), reconnect = require('./reconnect'), common = require('./../../common'), - os_name = process.platform.replace('darwin', 'mac').replace('win32', 'windows'), config = common.config, logger = common.logger.prefix('auto-connect'), Emitter = require('events').EventEmitter; var emitter, - reconnect_time = 30000, + reconnect_time = 10000, + running = false, sleeping = false, was_disconnected = false, timer = null; @@ -19,22 +19,31 @@ var connected = false; var restart_reconnection = () => { stop_waiting(); - reconnect_time = 1000 * 60 * 3; // Three minutes + reconnect_time = 1000 * 60 * 1; // Three minutes wait_normal_reconnection(); } var check_err = (err) => { - logger.info(err); - if (err.message.includes('Already connected')) { - logger.info(err.message + ". Autoconnect disengaged for now :)") + logger.debug(err); + if (err.message.includes('Already connected') || + err.message.includes('Device on sleeping state') || + err.message.includes('Unable to get wifi interface')) { + + logger.info(err.message + ". Autoconnect disengaged for now") stop_waiting(); } else restart_reconnection(); } var wait_normal_reconnection = () => { + running = true; + + if (connected) return stop_waiting(); logger.info("Device disconnected! Waiting for reconnection..."); - reconnect.enable_wifi(() => { + + // Make sure Wi-Fi is on + reconnect.enable_wifi((err) => { + if (err) return check_err(err); timer = setTimeout(() => { logger.info("Nothing happened, let's try connecting to the nearest access points..."); reconnect.get_ap_lists((err, list) => { @@ -49,6 +58,7 @@ var wait_normal_reconnection = () => { } var stop_waiting = () => { + running = false; if (timer) { clearTimeout(timer); timer = null; @@ -57,22 +67,23 @@ var stop_waiting = () => { exports.start = (opts, cb) => { hooks.on('connected', () => { + connected = true; + reconnect.is_connected(true); network.get_active_access_point((err, ap) => { if (was_disconnected) { logger.info("Connection achieved! " + (ap ? ap.ssid || "" : "")); was_disconnected = false; } - connected = ap; - reconnect.connected(ap); + reconnect.is_connected_to(ap); }) stop_waiting(); }); hooks.on('disconnected', () => { + reconnect.is_connected(false); was_disconnected = true; connected = false; if (config.get('auto_connect') && !sleeping) { - reconnect.connected(null); wait_normal_reconnection(); } }); @@ -80,6 +91,13 @@ exports.start = (opts, cb) => { hooks.on('sleeping', (value) => { if (value) sleeping = true; else sleeping = false; + + reconnect.is_sleeping(value); + + // if just woke up and it's disconnected, start reconnection + if (!sleeping && !connected && !running) { + wait_normal_reconnection(); + } }) emitter = new Emitter(); @@ -89,6 +107,7 @@ exports.start = (opts, cb) => { exports.stop = () => { hooks.remove('connected'); hooks.remove('disconnected'); + hooks.remove('sleeping'); if (emitter) { emitter.removeAllListeners(); diff --git a/lib/agent/triggers/auto-connect/linux.js b/lib/agent/triggers/auto-connect/linux.js index 5077cbad4..a4c9f39e2 100644 --- a/lib/agent/triggers/auto-connect/linux.js +++ b/lib/agent/triggers/auto-connect/linux.js @@ -1,16 +1,22 @@ var exec = require('child_process').exec; network = require('./../../providers/network/linux'); -var net_interface = null; +var net_interface = null, + interface_err = 'Unable to get wifi interface'; var get_interface = (cb) => { network.get_first_wireless_interface((err, data) => { + if (err) return cb(err); + net_interface = data; + return cb(null); }); } exports.enable_wifi = (cb) => { - var turn_on_wifi = () => { + var turn_on_wifi = (err) => { + if (err || !net_interface) return cb(new Error(interface_err)); + var cmd = 'nmcli networking off; nmcli networking on; nmcli radio wifi on'; exec(cmd, (err, data) => { return cb(); @@ -20,7 +26,9 @@ exports.enable_wifi = (cb) => { } exports.get_existing_profiles = (cb) => { - var get_profiles = () => { + var get_profiles = (err) => { + if (err || !net_interface) return cb(new Error(interface_err)); + var cmd = 'ls /etc/NetworkManager/system-connections' exec(cmd, (err, stdout) => { cb(null, stdout.split("\n").slice(0, -1)); @@ -30,7 +38,9 @@ exports.get_existing_profiles = (cb) => { } exports.create_profile = (ssid, cb) => { - var create = () => { + var create = (err) => { + if (err || !net_interface) return cb(new Error(interface_err)); + var cmd = `nmcli connection add type wifi ifname ${net_interface} con-name "${ssid}" ssid "${ssid}"`; exec(cmd, (err, out) => { return cb && cb(err); @@ -40,7 +50,9 @@ exports.create_profile = (ssid, cb) => { } exports.delete_profile = (ssid, cb) => { - var discard = () => { + var discard = (err) => { + if (err || !net_interface) return cb(new Error(interface_err)); + var cmd = `nmcli connection delete "${ssid}"`; exec(cmd, (err, out) => { return cb && cb(err); @@ -50,7 +62,9 @@ exports.delete_profile = (ssid, cb) => { } exports.connect_to_ap = (ssid, cb) => { - var connect = () => { + var connect = (err) => { + if (err || !net_interface) return cb(new Error(interface_err)); + var cmd = `nmcli connection up "${ssid}"`; exec(cmd, (err, out) => { return cb(err, out); diff --git a/lib/agent/triggers/auto-connect/mac.js b/lib/agent/triggers/auto-connect/mac.js index 4bb0eddf3..5ef4c3a98 100644 --- a/lib/agent/triggers/auto-connect/mac.js +++ b/lib/agent/triggers/auto-connect/mac.js @@ -2,7 +2,8 @@ var exec = require('child_process').exec, system = require('./../../../system'), run_as_user = system.run_as_logged_user; -var net_interface = null; +var net_interface = null, + interface_err = 'Unable to get wifi interface'; var get_interface = (cb) => { var cmd = 'networksetup -listallhardwareports | awk "/Hardware Port: Wi-Fi/,/Ethernet/" | awk "NR==2" | cut -d " " -f 2'; @@ -10,24 +11,28 @@ var get_interface = (cb) => { if (err) return cb(err); net_interface = data.split("\n").slice(0, -1); - return cb(null, net_interface); + return cb(null); }) } exports.enable_wifi = (cb) => { - console.log("ENABLE WIFI!!") - var turn_on_wifi = () => { - var cmd = `networksetup -setairportpower ${net_interface} on`; - exec(cmd, (err, data) => { - return cb(); + var turn_on_wifi = (err) => { + if (err || !net_interface) return cb(new Error(interface_err)); + + var cmd = `networksetup -setairportpower ${net_interface} off; networksetup -setairportpower ${net_interface} on`; + exec(cmd, (err) => { + return cb(null); }) } net_interface ? turn_on_wifi() : get_interface(turn_on_wifi); } exports.get_existing_profiles = (cb) => { - var get_profiles = () => { - var cmd = `networksetup -listpreferredwirelessnetworks ${net_interface} | awk 'NR>1' | awk '{$1=$1;print}'` + var get_profiles = (err) => { + if (err || !net_interface) return cb(new Error(interface_err)); + + // var cmd = `networksetup -listpreferredwirelessnetworks ${net_interface} | awk 'NR>1' | awk '{$1=$1;print}'` + var cmd = `networksetup -listpreferredwirelessnetworks ${net_interface} | awk 'NR>1' | awk -F '\t' '{print $2}'` exec(cmd, (err, stdout) => { cb(null, stdout.split("\n").slice(0, -1)); }) @@ -36,7 +41,9 @@ exports.get_existing_profiles = (cb) => { } exports.create_profile = (ssid, cb) => { - var create = () => { + var create = (err) => { + if (err || !net_interface) return cb(new Error(interface_err)); + var cmd = `networksetup -addpreferredwirelessnetworkatindex ${net_interface} "${ssid}" 0 open`; run_as_user(cmd, [], (err) => { return cb && cb(err); @@ -46,7 +53,9 @@ exports.create_profile = (ssid, cb) => { } exports.delete_profile = (ssid, cb) => { - var discard = () => { + var discard = (err) => { + if (err || !net_interface) return cb(new Error(interface_err)); + var cmd = `networksetup -removepreferredwirelessnetwork ${net_interface} "${ssid}"`; run_as_user(cmd, [], (err) => { return cb && cb(err); @@ -56,7 +65,9 @@ exports.delete_profile = (ssid, cb) => { } exports.connect_to_ap = (ssid, cb) => { // revisar cb si va - var connect = () => { + var connect = (err) => { + if (err || !net_interface) return cb(new Error(interface_err)); + var cmd = `networksetup -setairportnetwork ${net_interface} "${ssid}"`; run_as_user(cmd, [], (err, out) => { return cb(err, out); diff --git a/lib/agent/triggers/auto-connect/reconnect.js b/lib/agent/triggers/auto-connect/reconnect.js index 8ae9f135f..b60b6c523 100644 --- a/lib/agent/triggers/auto-connect/reconnect.js +++ b/lib/agent/triggers/auto-connect/reconnect.js @@ -6,13 +6,22 @@ var async = require('async'), logger = common.logger.prefix('auto-connect'); var previous = null, - previous_secured_wifi = [], + sleeping = false, + connected = true, connected_to = false; exports.attempted_wifi = {}, exports.time_between = 20000; exports.init_profiles = []; +var validate_procedure = () => { + var error = null; + if (connected) error = new Error("Already connected" + (connected_to ? " to: " + connected_to.ssid : "")); + if (sleeping) error = new Error("Device on sleeping state, stopping autoconnect"); + + return error; +} + var get_existing_profiles = (cb) => { os_functions.get_existing_profiles((err, data) => { return cb(null, data); @@ -22,12 +31,12 @@ var get_existing_profiles = (cb) => { var delete_profile = (ssid, cb) => { get_existing_profiles((err, current_profiles) => { // Check if the profile isn't original and exists in the current list also if the device is connected to that ap - if (!ssid || exports.init_profiles.indexOf(ssid) != -1 || current_profiles.indexOf(ssid) == -1 || connected_to.ssid == ssid) { + if (!ssid || exports.init_profiles.indexOf(ssid) != -1 || current_profiles.indexOf(ssid) == -1 || (connected_to && connected_to.ssid == ssid)) return cb(new Error("Nothing to delete " + ssid)); - } + os_functions.delete_profile(ssid, (err) => { if (!err) { - logger.debug("Profile " + ssid + " succesfuly deleted"); + logger.debug("Profile " + ssid + " successfully deleted"); previous = null; } return cb && cb(err); @@ -41,7 +50,7 @@ var create_profile = (ssid, cb) => { return cb(new Error("Profile " + ssid + " already exists")); os_functions.create_profile(ssid, (err) => { - if (!err) logger.debug("Profile " + ssid + " succesfuly created"); + if (!err) logger.debug("Profile " + ssid + " successfully created"); cb(null); }); }) @@ -54,24 +63,22 @@ var connect_to_access_point = (ap, cb) => { os_functions.connect_to_ap(ap.ssid, cb); } - // Before attempt to connect it checks if it's already connected - if (connected_to) { - delete exports.attempted_wifi[connected_to.mac_address]; - if (previous != connected_to.ssid) { - delete_profile(previous, (err) => { - if (err) logger.debug(err.message) - }); - } - return cb(new Error("Already connected to: " + connected_to.ssid)) + if (err = validate_procedure()) return cb(err); + + if (ap.security) { + delete_profile(previous, (err) => { + if (err) logger.debug(err.message); + return connect(); + }) } - exports.attempted_wifi[ap.mac_address] ? exports.attempted_wifi[ap.mac_address]++ : exports.attempted_wifi[ap.mac_address] = 1; + exports.attempted_wifi[ap.ssid] ? exports.attempted_wifi[ap.ssid]++ : exports.attempted_wifi[ap.ssid] = 1; delete_profile(previous, (err) => { - if (err) logger.debug(err.message) + if (err) logger.debug(err.message); create_profile(ap.ssid, (err) => { - if (err) logger.debug(err.message) - connect(); + if (err) logger.debug(err.message); + else connect(); }) }) } @@ -112,16 +119,27 @@ exports.try_connecting_to = (list, cb) => { exports.get_ap_lists = (cb) => { previuos = null; - if (connected_to) return cb(new Error("Already connected to: " + connected_to.ssid)); - var proceed_with_open_aps = (open, current_profiles) => { + if (err = validate_procedure()) return cb(err); + + var filter_wifi_list = (list) => { + var filtered_list = []; + + if (list.length == 0) return filtered_list; + filtered_list = list.filter((obj, pos, arr) => { + return list.map(mapObj => mapObj.ssid).indexOf(obj.ssid) === pos; + }); + return filtered_list; + } + + var proceed_with_open_aps = (open, secured, current_profiles) => { if (!open || open.length == 0) return cb(new Error('No open access points found. Retrying in 10')) var final_list = []; // Filter the 3 times attempted access points open.forEach((ap) => { - if (!(ap.mac_address in exports.attempted_wifi) || exports.attempted_wifi[ap.mac_address] < 3) { + if (!(ap.ssid in exports.attempted_wifi) || exports.attempted_wifi[ap.ssid] < 3) { // Put open ap at the beginning of the list if the device was previously connected to it current_profiles.indexOf(ap.ssid) > -1 ? final_list.unshift(ap) : final_list.push(ap); } else { @@ -129,51 +147,63 @@ exports.get_ap_lists = (cb) => { } }) + secured.forEach((ap) => { + final_list.unshift(ap); + }) + cb(null, final_list); } - // Make sure Wi-Fi is on - os_functions.enable_wifi(() => { - // Scan the open and secured access points - providers.get('categorized_access_points_list', (err, list) => { - if (err || !list) { - return cb(new Error('No open access points found. Retrying in 10')) - } + providers.get('categorized_access_points_list', (err, list) => { + if (err || !list) { + return cb(new Error('No open access points found. Retrying in 10')) + } - var open = list[0], - secured = list[1]; + var open = list[0], + secured = list[1]; - exports.get_existing_profiles((err, current_profiles) => { - if (err || !secured || secured.length == 0) return proceed_with_open_aps(open, current_profiles); + exports.get_existing_profiles((err, current_profiles) => { + if (err || !secured || secured.length == 0) return proceed_with_open_aps(open, [], current_profiles); - // Check if the device previously connected to at least one of the secured ap's - var known_secured_wifi = []; - secured.forEach((ap) => { - current_profiles.forEach((ssid) => { - if (ssid.trim() == ap.ssid.trim()) - known_secured_wifi.push(ap.ssid); - }) + // Check if the device previously connected to at least one of the secured ap's + var known_secured_wifi = []; + secured.forEach((ap) => { + current_profiles.forEach((ssid) => { + if (ssid.trim() == ap.ssid.trim()) + known_secured_wifi.push(ap); }) + }) - var new_secured_wifi = known_secured_wifi.filter(x => previous_secured_wifi.indexOf(x) == -1) - previous_secured_wifi = previous_secured_wifi.concat(new_secured_wifi); + secured = filter_wifi_list(known_secured_wifi); + open = filter_wifi_list(open); - if (new_secured_wifi.length > 0) - return cb(new Error('There is a secured known network, waiting for the device to autoconnect')) + proceed_with_open_aps(open, secured, current_profiles); - console.log("OPEN", open) + }); + }) +} - proceed_with_open_aps(open, current_profiles); +exports.is_connected = (value) => { + if (value) connected = true; + else { + connected = false; + connected_to = null; + } +} - }); - }) - }) +exports.is_sleeping = (value) => { + if (value) sleeping = true; + else sleeping = false; } -exports.connected = (ap) => { - previous_secured_wifi = []; - connected_to = false; - if (ap) connected_to = ap; +exports.is_connected_to = (ap) => { + connected_to = ap; + delete exports.attempted_wifi[connected_to.ssid]; + if (previous != connected_to.ssid) { + delete_profile(previous, (err) => { + if (err) logger.debug(err.message) + }); + } } exports.enable_wifi = (cb) => { diff --git a/test/lib/agent/triggers/auto-connect.js b/test/lib/agent/triggers/auto-connect.js index 1ecb45f02..0ca566604 100644 --- a/test/lib/agent/triggers/auto-connect.js +++ b/test/lib/agent/triggers/auto-connect.js @@ -89,6 +89,7 @@ describe('auto connect', function() { describe('on empty list', function() { before(function() { + reconnect.is_connected(false); ap_list_stub = sinon.stub(network, 'get_access_points_list', function(cb) { cb(null, close_ap_list); }) @@ -132,65 +133,15 @@ describe('auto connect', function() { profiles_stub.restore(); }) - describe('the first time', () => { - it('waits for the autoconnection to the secured wifi', (done) => { - reconnect.get_ap_lists(function(err, list) { - should.not.exist(list); - should.exist(err); - err.message.should.containEql('There is a secured known network'); - done(); - }) - }) - }) - - describe('the second time', () => { - it('waits for the autoconnection to the secured wifi', (done) => { - reconnect.get_ap_lists(function(err, list) { - should.exist(list); - should.not.exist(err); - done(); - }) - }) - }) - - describe('the third time', () => { - before(() => { - ap_list_stub.restore(); - profiles_stub.restore(); - - var ap_list2 = ap_list - ap_list2.push({ - ssid: 'holi', - mac_address: '12:34:56:78:ab:cd', - signal_strength: -66, - channel: 1, - security: 'WP2' - }) - - ap_list_stub = sinon.stub(network, 'get_access_points_list', function(cb) { - cb(null, ap_list2); - }) - - profiles_stub = sinon.stub(reconnect, 'get_existing_profiles', function(cb) { - cb(null, ['Pery', 'Secured wifi', 'holi']); - }) - }) - - after(() => { - profiles_stub.restore(); - ap_list_stub.restore(); - }) - - it('waits for the autoconnection to the secured wifi', (done) => { - reconnect.get_ap_lists(function(err, list) { - should.not.exist(list); - should.exist(err); - err.message.should.containEql('There is a secured known network'); - done(); - }) + it('gonna try to connect to the secured wifi first', (done) => { + reconnect.get_ap_lists(function(err, list) { + should.not.exist(err); + should.exist(list); + list[0].ssid.should.be.equal('Secured wifi'); + list[1].ssid.should.be.equal('Prey-Guest'); + done(); }) }) - }) describe('when in the secured list there a profile in the current list', () => { @@ -198,14 +149,10 @@ describe('auto connect', function() { profiles_stub = sinon.stub(reconnect, 'get_existing_profiles', function(cb) { cb(null, []); }) - ap_list_stub = sinon.stub(network, 'get_access_points_list', function(cb) { - cb(null, ap_list); - }) }) after(() => { profiles_stub.restore(); - ap_list_stub.restore(); }) it('not callback error', function(done) { @@ -229,7 +176,7 @@ describe('auto connect', function() { describe('when an open access has been attempted 3 times', function() { before(function() { - reconnect.attempted_wifi = {'ab:cd:ef:gh:ij:kl': 3} + reconnect.attempted_wifi = { 'Unsecured Wifi': 3 } }) it('shouldnt return that ap in the final list', function(done) { @@ -362,7 +309,7 @@ describe('auto connect', function() { it('will add the ap to the attempts list', function(done) { reconnect.connect_to_access_point(open_ap_list[0], function() { Object.keys(reconnect.attempted_wifi).length.should.be.equal(1); - reconnect.attempted_wifi[open_ap_list[0].mac_address].should.be.equal(1); + reconnect.attempted_wifi[open_ap_list[0].ssid].should.be.equal(1); done(); }) }) @@ -370,7 +317,7 @@ describe('auto connect', function() { it('will increment the attempt number for that ap', function(done) { reconnect.connect_to_access_point(open_ap_list[0], function() { Object.keys(reconnect.attempted_wifi).length.should.be.equal(1); - reconnect.attempted_wifi[open_ap_list[0].mac_address].should.be.equal(2); + reconnect.attempted_wifi[open_ap_list[0].ssid].should.be.equal(2); done(); }) }) @@ -385,8 +332,8 @@ describe('auto connect', function() { it('should keep saved the previous ap attempts', function(done) { reconnect.connect_to_access_point(ap_list[1], function() { Object.keys(reconnect.attempted_wifi).length.should.be.equal(2); - reconnect.attempted_wifi[open_ap_list[0].mac_address].should.be.equal(2); - reconnect.attempted_wifi[ap_list[1].mac_address].should.be.equal(1); + reconnect.attempted_wifi[open_ap_list[0].ssid].should.be.equal(2); + reconnect.attempted_wifi[ap_list[1].ssid].should.be.equal(1); done(); }) }) @@ -419,8 +366,9 @@ describe('auto connect', function() { describe('when device connects', function() { before(function() { - reconnect.attempted_wifi = {'oa:oa:oa:oa:oa:oa': 1}; - reconnect.connected({ ssid: 'Pery', mac_address: 'oa:oa:oa:oa:oa:oa', signal_strength: -51, channel: 1,security: 'WP2' }); + reconnect.attempted_wifi = {'Pery': 1}; + reconnect.is_connected(true); + reconnect.is_connected_to({ ssid: 'Pery', mac_address: 'oa:oa:oa:oa:oa:oa', signal_strength: -51, channel: 1,security: 'WP2' }); }) after(function() { From aa41baf0a13cc2cf079b1aba22030394a37170fd Mon Sep 17 00:00:00 2001 From: javo Date: Fri, 11 Jan 2019 16:26:55 -0300 Subject: [PATCH 4/7] Modify previous network logic --- lib/agent/triggers/auto-connect/mac.js | 1 - lib/agent/triggers/auto-connect/reconnect.js | 32 ++++++++++++-------- test/lib/agent/triggers/auto-connect.js | 21 ++++++------- 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/lib/agent/triggers/auto-connect/mac.js b/lib/agent/triggers/auto-connect/mac.js index 5ef4c3a98..f54e6e72e 100644 --- a/lib/agent/triggers/auto-connect/mac.js +++ b/lib/agent/triggers/auto-connect/mac.js @@ -31,7 +31,6 @@ exports.get_existing_profiles = (cb) => { var get_profiles = (err) => { if (err || !net_interface) return cb(new Error(interface_err)); - // var cmd = `networksetup -listpreferredwirelessnetworks ${net_interface} | awk 'NR>1' | awk '{$1=$1;print}'` var cmd = `networksetup -listpreferredwirelessnetworks ${net_interface} | awk 'NR>1' | awk -F '\t' '{print $2}'` exec(cmd, (err, stdout) => { cb(null, stdout.split("\n").slice(0, -1)); diff --git a/lib/agent/triggers/auto-connect/reconnect.js b/lib/agent/triggers/auto-connect/reconnect.js index b60b6c523..85332b545 100644 --- a/lib/agent/triggers/auto-connect/reconnect.js +++ b/lib/agent/triggers/auto-connect/reconnect.js @@ -28,15 +28,20 @@ var get_existing_profiles = (cb) => { }); } -var delete_profile = (ssid, cb) => { +var delete_profile = (ap, cb) => { get_existing_profiles((err, current_profiles) => { + if (!ap || !ap.ssid) return cb(new Error("Nothing to delete")); + // Check if the profile isn't original and exists in the current list also if the device is connected to that ap - if (!ssid || exports.init_profiles.indexOf(ssid) != -1 || current_profiles.indexOf(ssid) == -1 || (connected_to && connected_to.ssid == ssid)) - return cb(new Error("Nothing to delete " + ssid)); + if (exports.init_profiles.indexOf(ap.ssid) != -1 + || current_profiles.indexOf(ap.ssid) == -1 + || (connected_to && connected_to.ssid == ap.ssid) + || ap.security) + return cb(new Error("Nothing to delete " + ap.ssid)); - os_functions.delete_profile(ssid, (err) => { + os_functions.delete_profile(ap.ssid, (err) => { if (!err) { - logger.debug("Profile " + ssid + " successfully deleted"); + logger.debug("Profile " + ap.ssid + " successfully deleted"); previous = null; } return cb && cb(err); @@ -44,13 +49,13 @@ var delete_profile = (ssid, cb) => { }) } -var create_profile = (ssid, cb) => { +var create_profile = (ap, cb) => { get_existing_profiles((err, current_profiles) => { - if (current_profiles.indexOf(ssid) != -1) - return cb(new Error("Profile " + ssid + " already exists")); + if (current_profiles.indexOf(ap.ssid) != -1) + return cb(new Error("Profile " + ap.ssid + " already exists")); - os_functions.create_profile(ssid, (err) => { - if (!err) logger.debug("Profile " + ssid + " successfully created"); + os_functions.create_profile(ap.ssid, (err) => { + if (!err) logger.debug("Profile " + ap.ssid + " successfully created"); cb(null); }); }) @@ -59,7 +64,7 @@ var create_profile = (ssid, cb) => { var connect_to_access_point = (ap, cb) => { var connect = () => { logger.info("Trying to connect to: " + ap.ssid); - previous = ap.ssid; + previous = ap; os_functions.connect_to_ap(ap.ssid, cb); } @@ -76,7 +81,7 @@ var connect_to_access_point = (ap, cb) => { delete_profile(previous, (err) => { if (err) logger.debug(err.message); - create_profile(ap.ssid, (err) => { + create_profile(ap, (err) => { if (err) logger.debug(err.message); else connect(); }) @@ -199,7 +204,8 @@ exports.is_sleeping = (value) => { exports.is_connected_to = (ap) => { connected_to = ap; delete exports.attempted_wifi[connected_to.ssid]; - if (previous != connected_to.ssid) { + + if (previous && previous.ssid && previous.ssid != connected_to.ssid) { delete_profile(previous, (err) => { if (err) logger.debug(err.message) }); diff --git a/test/lib/agent/triggers/auto-connect.js b/test/lib/agent/triggers/auto-connect.js index 0ca566604..786542b22 100644 --- a/test/lib/agent/triggers/auto-connect.js +++ b/test/lib/agent/triggers/auto-connect.js @@ -197,19 +197,19 @@ describe('auto connect', function() { before(function(done) { reconnect.init_profiles = []; - reconnect.delete_profile('Prey-test', function() { + reconnect.delete_profile(open_ap_list[0], function() { done(); }) }) after(function(done) { - reconnect.delete_profile('Prey-test', function(err) { + reconnect.delete_profile(open_ap_list[0], function(err) { done(); }) }) it('not callsback error', function(done) { - reconnect.create_profile('Prey-test', function(err) { + reconnect.create_profile(open_ap_list[0], function(err) { should.not.exist(err); done(); }) @@ -224,7 +224,7 @@ describe('auto connect', function() { }) it('returns errors when profile already exists', function(done){ - reconnect.create_profile('Prey-test', function(err) { + reconnect.create_profile(open_ap_list[0], function(err) { should.exist(err); err.message.should.containEql('already exists'); done(); @@ -236,7 +236,7 @@ describe('auto connect', function() { describe('when profile does not exists', function() { it('callbacks an error', function(done) { - reconnect.delete_profile('Prey-test', function(err) { + reconnect.delete_profile(open_ap_list[0], function(err) { should.exist(err); err.message.should.containEql('Nothing to delete'); done(); @@ -246,13 +246,13 @@ describe('auto connect', function() { describe('when profile exists', function() { before(function(done) { - reconnect.create_profile('Prey-test', function() { + reconnect.create_profile(open_ap_list[0], function() { done(); }) }) it('not callsback an error', function(done) { - reconnect.delete_profile('Prey-test', function(err) { + reconnect.delete_profile(open_ap_list[0], function(err) { should.not.exist(err); done(); }) @@ -293,7 +293,6 @@ describe('auto connect', function() { describe('when theres an attempt to connect to an ap', function() { before(function() { reconnect.attempted_wifi = {}; - var ssid = 'Prey-test'; ap_list_stub = sinon.stub(os_functions, 'connect_to_ap', function(ssid, cb) { cb(null, 'not connected!'); }) @@ -301,7 +300,7 @@ describe('auto connect', function() { after(function(done) { ap_list_stub.restore(); - reconnect.delete_profile('Prey-test', function() { + reconnect.delete_profile(open_ap_list[0], function() { done(); }) }) @@ -324,7 +323,7 @@ describe('auto connect', function() { describe('when tryes to connect to another ap', function() { after(function(done) { - reconnect.delete_profile('Unsecured Wifi', function() { + reconnect.delete_profile(ap_list[1], function() { done(); }) }) @@ -366,7 +365,7 @@ describe('auto connect', function() { describe('when device connects', function() { before(function() { - reconnect.attempted_wifi = {'Pery': 1}; + reconnect.attempted_wifi = { 'Pery': 1 }; reconnect.is_connected(true); reconnect.is_connected_to({ ssid: 'Pery', mac_address: 'oa:oa:oa:oa:oa:oa', signal_strength: -51, channel: 1,security: 'WP2' }); }) From 0b199119ef017dc08c01382772fd8fec69c9a932 Mon Sep 17 00:00:00 2001 From: javo Date: Mon, 14 Jan 2019 17:16:16 -0300 Subject: [PATCH 5/7] Known wifi networks fix and linux auth improvements --- lib/agent/index.js | 2 +- .../triggers/auto-connect/bin/linux_auth.sh | 57 ++++++++++++++----- lib/agent/triggers/auto-connect/index.js | 4 +- lib/agent/triggers/auto-connect/reconnect.js | 16 +++--- lib/agent/triggers/system/index.js | 4 +- 5 files changed, 57 insertions(+), 26 deletions(-) diff --git a/lib/agent/index.js b/lib/agent/index.js index 460769f8f..e4733b786 100644 --- a/lib/agent/index.js +++ b/lib/agent/index.js @@ -25,7 +25,7 @@ var config = common.config, helpers = common.helpers, exceptions = common.exceptions, plugins = common.plugins, - watch_list = ['auto-connect','connection', 'control-zones', 'hostname', 'location', 'network', 'power', 'system'], + watch_list = ['connection', 'control-zones', 'hostname', 'location', 'network', 'power', 'system'], running = false, started_at = null, running_as = null; diff --git a/lib/agent/triggers/auto-connect/bin/linux_auth.sh b/lib/agent/triggers/auto-connect/bin/linux_auth.sh index 4de89d74d..8b3715798 100644 --- a/lib/agent/triggers/auto-connect/bin/linux_auth.sh +++ b/lib/agent/triggers/auto-connect/bin/linux_auth.sh @@ -8,7 +8,7 @@ fi file="/var/lib/polkit-1/localauthority/50-local.d/10-network-manager.pkla" askAutorization () { - read -p "Prey needs autorization to modify network parameters for the autoconnection feature (y/n)" answer $file + # Back up information and clear original file + cp $file "$file.old" + > $file - while read -r line; do - processLine $line - done < "$file.old" + while read -r line; do + processLine $line + done < "$file.old" - check + check + exit + else + # Create the file + su -c `printf "[Grant network permissions to Prey user]\nIdentity=unix-user:prey\nAction=org.freedesktop.NetworkManager.*\nResultAny=yes\nResultInactive=no\nResultActive=yes\n" > ${file}` + exit + fi +} + +restore_permissions () { + if [ -f $file ] && [ -f "$file.old" ]; then + cp "$file.old" $file + rm "$file.old" + exit + elif [ -f $file ]; then + rm $file + exit + else + exit + fi +} + +if [ -z "$1" ]; then + echo 'Grant (--grant) or Restore (--restore) arguments necessary' exit else - # Create the file - su -c `printf "[Give Permissions to Prey user]\nIdentity=unix-user:prey\nAction=org.freedesktop.NetworkManager.*\nResultAny=yes\nResultInactive=no\nResultActive=yes\n" > ${file}` - exit + if [[ $1 == "--grant" ]] || [[ $1 == "-g" ]]; then + grant_permissions + elif [[ $1 == "--restore" ]] || [[ $1 == "-r" ]]; then + restore_permissions + else + echo 'Invalid argument' + exit + fi fi \ No newline at end of file diff --git a/lib/agent/triggers/auto-connect/index.js b/lib/agent/triggers/auto-connect/index.js index bfb4a9422..0702d0967 100644 --- a/lib/agent/triggers/auto-connect/index.js +++ b/lib/agent/triggers/auto-connect/index.js @@ -9,7 +9,7 @@ var join = require('path').join, Emitter = require('events').EventEmitter; var emitter, - reconnect_time = 10000, + reconnect_time = 30000, running = false, sleeping = false, was_disconnected = false, @@ -19,7 +19,7 @@ var connected = false; var restart_reconnection = () => { stop_waiting(); - reconnect_time = 1000 * 60 * 1; // Three minutes + reconnect_time = 1000 * 60 * 3; // Three minutes wait_normal_reconnection(); } diff --git a/lib/agent/triggers/auto-connect/reconnect.js b/lib/agent/triggers/auto-connect/reconnect.js index 85332b545..c6f55a60e 100644 --- a/lib/agent/triggers/auto-connect/reconnect.js +++ b/lib/agent/triggers/auto-connect/reconnect.js @@ -75,17 +75,17 @@ var connect_to_access_point = (ap, cb) => { if (err) logger.debug(err.message); return connect(); }) - } - - exports.attempted_wifi[ap.ssid] ? exports.attempted_wifi[ap.ssid]++ : exports.attempted_wifi[ap.ssid] = 1; + } else { + exports.attempted_wifi[ap.ssid] ? exports.attempted_wifi[ap.ssid]++ : exports.attempted_wifi[ap.ssid] = 1; - delete_profile(previous, (err) => { - if (err) logger.debug(err.message); - create_profile(ap, (err) => { + delete_profile(previous, (err) => { if (err) logger.debug(err.message); - else connect(); + create_profile(ap, (err) => { + if (err) logger.debug(err.message); + else connect(); + }) }) - }) + } } exports.try_connecting_to = (list, cb) => { diff --git a/lib/agent/triggers/system/index.js b/lib/agent/triggers/system/index.js index e80158a13..c271c1d71 100644 --- a/lib/agent/triggers/system/index.js +++ b/lib/agent/triggers/system/index.js @@ -41,8 +41,10 @@ var check_and_emit = (info) => { var done = (err, current) => { if (err) logger.warn("ERROR!", err.message) - if (previous != current) + if (previous != current) { + logger.info("SLEEPING!!! " + current) hooks.trigger('sleeping', current); + } previous = current; checking = false; From 9c2b26e17430939930c117bfbfa42ab03de002f6 Mon Sep 17 00:00:00 2001 From: javo Date: Mon, 4 Feb 2019 15:58:34 -0300 Subject: [PATCH 6/7] Turn on wifi when its disabled and bugs fixes --- lib/agent/index.js | 2 +- lib/agent/triggers/auto-connect/index.js | 30 ++++++++++++---------- lib/agent/triggers/auto-connect/linux.js | 20 +++++++++++++-- lib/agent/triggers/auto-connect/mac.js | 15 +++++++++-- lib/agent/triggers/auto-connect/windows.js | 4 +++ 5 files changed, 52 insertions(+), 19 deletions(-) diff --git a/lib/agent/index.js b/lib/agent/index.js index e4733b786..2f4c24e17 100644 --- a/lib/agent/index.js +++ b/lib/agent/index.js @@ -25,7 +25,7 @@ var config = common.config, helpers = common.helpers, exceptions = common.exceptions, plugins = common.plugins, - watch_list = ['connection', 'control-zones', 'hostname', 'location', 'network', 'power', 'system'], + watch_list = ['auto-connect', 'connection', 'control-zones', 'hostname', 'location', 'network', 'power', 'system'], running = false, started_at = null, running_as = null; diff --git a/lib/agent/triggers/auto-connect/index.js b/lib/agent/triggers/auto-connect/index.js index 0702d0967..d9ada6693 100644 --- a/lib/agent/triggers/auto-connect/index.js +++ b/lib/agent/triggers/auto-connect/index.js @@ -19,7 +19,7 @@ var connected = false; var restart_reconnection = () => { stop_waiting(); - reconnect_time = 1000 * 60 * 3; // Three minutes + reconnect_time = 1000 * 60 * 2; // Two minutes wait_normal_reconnection(); } @@ -41,20 +41,22 @@ var wait_normal_reconnection = () => { if (connected) return stop_waiting(); logger.info("Device disconnected! Waiting for reconnection..."); - // Make sure Wi-Fi is on - reconnect.enable_wifi((err) => { - if (err) return check_err(err); - timer = setTimeout(() => { - logger.info("Nothing happened, let's try connecting to the nearest access points..."); - reconnect.get_ap_lists((err, list) => { - if (err) return check_err(err); - reconnect.try_connecting_to(list, (err, stdout) => { + setTimeout(() => { + // Make sure Wi-Fi is on + reconnect.enable_wifi((err) => { + if (err) return check_err(err); + timer = setTimeout(() => { + logger.info("Nothing happened, let's try connecting to the nearest access points..."); + reconnect.get_ap_lists((err, list) => { if (err) return check_err(err); - return wait_normal_reconnection(); + reconnect.try_connecting_to(list, (err, stdout) => { + if (err) return check_err(err); + return wait_normal_reconnection(); + }); }); - }); - }, reconnect_time) - }) + }, reconnect_time) + }) + }, 10000); } var stop_waiting = () => { @@ -71,7 +73,7 @@ exports.start = (opts, cb) => { reconnect.is_connected(true); network.get_active_access_point((err, ap) => { if (was_disconnected) { - logger.info("Connection achieved! " + (ap ? ap.ssid || "" : "")); + logger.info("Connection achieved! " + ((ap && ap.ssid) ? (ap.ssid || "") : "")); was_disconnected = false; } reconnect.is_connected_to(ap); diff --git a/lib/agent/triggers/auto-connect/linux.js b/lib/agent/triggers/auto-connect/linux.js index a4c9f39e2..5f73e133c 100644 --- a/lib/agent/triggers/auto-connect/linux.js +++ b/lib/agent/triggers/auto-connect/linux.js @@ -13,8 +13,24 @@ var get_interface = (cb) => { }); } +exports.is_wifi_on = (cb) => { + var check_wifi_status = (err) => { + if (err || !net_interface) return cb(new Error(interface_err)); + + var cmd = `LC_ALL=C nmcli networking` + exec(cmd, (err, stdout) => { + let status = stdout.trim(), + enabled = status == 'enabled' ? true : false; + + if (!enabled) return exports.enable_wifi(cb); + return cb(); + }) + } + net_interface ? check_wifi_status() : get_interface(check_wifi_status); +} + exports.enable_wifi = (cb) => { - var turn_on_wifi = (err) => { + var restart_wifi = (err) => { if (err || !net_interface) return cb(new Error(interface_err)); var cmd = 'nmcli networking off; nmcli networking on; nmcli radio wifi on'; @@ -22,7 +38,7 @@ exports.enable_wifi = (cb) => { return cb(); }) } - net_interface ? turn_on_wifi() : get_interface(turn_on_wifi); + net_interface ? restart_wifi() : get_interface(restart_wifi); } exports.get_existing_profiles = (cb) => { diff --git a/lib/agent/triggers/auto-connect/mac.js b/lib/agent/triggers/auto-connect/mac.js index f54e6e72e..e986665ba 100644 --- a/lib/agent/triggers/auto-connect/mac.js +++ b/lib/agent/triggers/auto-connect/mac.js @@ -15,8 +15,19 @@ var get_interface = (cb) => { }) } +exports.is_wifi_on = (cb) => { + var cmd = `networksetup -getairportpower ${net_interface}` + exec(cmd, (err, stdout) => { + var status = stdout.split('Wi-Fi Power (en0): ').pop().trim(), + enabled = status == 'On' ? true : false; + + if (!enabled) return exports.enable_wifi(cb); + return cb(); + }) +} + exports.enable_wifi = (cb) => { - var turn_on_wifi = (err) => { + var restart_wifi = (err) => { if (err || !net_interface) return cb(new Error(interface_err)); var cmd = `networksetup -setairportpower ${net_interface} off; networksetup -setairportpower ${net_interface} on`; @@ -24,7 +35,7 @@ exports.enable_wifi = (cb) => { return cb(null); }) } - net_interface ? turn_on_wifi() : get_interface(turn_on_wifi); + net_interface ? restart_wifi() : get_interface(restart_wifi); } exports.get_existing_profiles = (cb) => { diff --git a/lib/agent/triggers/auto-connect/windows.js b/lib/agent/triggers/auto-connect/windows.js index c1fb1840b..5d3ac47d6 100644 --- a/lib/agent/triggers/auto-connect/windows.js +++ b/lib/agent/triggers/auto-connect/windows.js @@ -52,6 +52,10 @@ var generate_xml = (ssid, cb) => { }) } +exports.is_wifi_on = (cb) => { + return exports.enable_wifi(cb); +} + exports.enable_wifi = (cb) => { exec(wifion, (err) => { return cb(); From 7035ca9d7ca8dde1179a1ab6ad8c9473c98ea401 Mon Sep 17 00:00:00 2001 From: javo Date: Mon, 4 Feb 2019 15:59:16 -0300 Subject: [PATCH 7/7] Reconnect enable wifi --- lib/agent/triggers/auto-connect/reconnect.js | 52 +++++++++++--------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/lib/agent/triggers/auto-connect/reconnect.js b/lib/agent/triggers/auto-connect/reconnect.js index c6f55a60e..7b2d43fd7 100644 --- a/lib/agent/triggers/auto-connect/reconnect.js +++ b/lib/agent/triggers/auto-connect/reconnect.js @@ -11,7 +11,7 @@ var previous = null, connected_to = false; exports.attempted_wifi = {}, -exports.time_between = 20000; +exports.time_between = 25000; exports.init_profiles = []; var validate_procedure = () => { @@ -82,7 +82,7 @@ var connect_to_access_point = (ap, cb) => { if (err) logger.debug(err.message); create_profile(ap, (err) => { if (err) logger.debug(err.message); - else connect(); + return connect(); }) }) } @@ -94,9 +94,11 @@ exports.try_connecting_to = (list, cb) => { array.push( (callback) => { setTimeout(() => { - connect_to_access_point(ap, (err) => { - if (err && err.message.includes('Already connected')) return callback(err); - callback(); + os_functions.is_wifi_on(() => { + connect_to_access_point(ap, (err) => { + if (err && err.message.includes('Already connected')) return callback(err); + callback(); + }) }) }, exports.time_between) } @@ -159,32 +161,34 @@ exports.get_ap_lists = (cb) => { cb(null, final_list); } - providers.get('categorized_access_points_list', (err, list) => { - if (err || !list) { - return cb(new Error('No open access points found. Retrying in 10')) - } + os_functions.is_wifi_on(() => { + providers.get('categorized_access_points_list', (err, list) => { + if (err || !list) { + return cb(new Error('No open access points found. Retrying in 10')) + } - var open = list[0], - secured = list[1]; + var open = list[0], + secured = list[1]; - exports.get_existing_profiles((err, current_profiles) => { - if (err || !secured || secured.length == 0) return proceed_with_open_aps(open, [], current_profiles); + exports.get_existing_profiles((err, current_profiles) => { + if (err || !secured || secured.length == 0) return proceed_with_open_aps(open, [], current_profiles); - // Check if the device previously connected to at least one of the secured ap's - var known_secured_wifi = []; - secured.forEach((ap) => { - current_profiles.forEach((ssid) => { - if (ssid.trim() == ap.ssid.trim()) - known_secured_wifi.push(ap); + // Check if the device previously connected to at least one of the secured ap's + var known_secured_wifi = []; + secured.forEach((ap) => { + current_profiles.forEach((ssid) => { + if (ssid.trim() == ap.ssid.trim()) + known_secured_wifi.push(ap); + }) }) - }) - secured = filter_wifi_list(known_secured_wifi); - open = filter_wifi_list(open); + secured = filter_wifi_list(known_secured_wifi); + open = filter_wifi_list(open); - proceed_with_open_aps(open, secured, current_profiles); + proceed_with_open_aps(open, secured, current_profiles); - }); + }); + }) }) }