Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Autoconnect improvements and system trigger #412

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/agent/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
19 changes: 19 additions & 0 deletions lib/agent/providers/network/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions lib/agent/providers/network/linux.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
124 changes: 124 additions & 0 deletions lib/agent/triggers/auto-connect/bin/linux_auth.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#!/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 autoconnect feature (this is no mandatory for prey to work) (y/n)" answer </dev/tty
case ${answer:0:1} in
y|Y )
authorized=true
;;
n|N )
# Leave everything as it was
authorized=false
cp "$file.old" $file
rm "$file.old"
exit
;;
* )
askAutorization
;;
esac
}

processLine() {
if [[ $line == *"Identity"* ]]; then ready[0]=1; setIdentity $line
elif [[ $line == *"ResultAny"* ]]; then ready[1]=1; setResults $line
elif [[ $line == *"ResultActive"* ]]; then ready[2]=1; setResults $line
else echo $line >> $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
}

grant_permissions () {
# 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 "[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
if [[ $1 == "--grant" ]] || [[ $1 == "-g" ]]; then
grant_permissions
elif [[ $1 == "--restore" ]] || [[ $1 == "-r" ]]; then
restore_permissions
else
echo 'Invalid argument'
exit
fi
fi
87 changes: 57 additions & 30 deletions lib/agent/triggers/auto-connect/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,85 +4,112 @@ 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,
was_disconnected = false;
running = 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
reconnect_time = 1000 * 60 * 2; // Two minutes
wait_normal_reconnection();
}

var check_err = function(err) {
logger.info(err);
if (err.message.includes('Already connected')) {
logger.info(err.message + ". Autoconnect disengaged for now :)")
var check_err = (err) => {
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 = function() {
var wait_normal_reconnection = () => {
running = true;

if (connected) return stop_waiting();
logger.info("Device disconnected! Waiting for reconnection...");
reconnect.enable_wifi(function() {
timer = setTimeout(function() {
logger.info("Nothing happened, let's try connecting to the nearest access points...");
reconnect.get_open_ap_list(function(err, list) {
if (err) return check_err(err);
reconnect.try_connecting_to(list, function(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 = function() {
var stop_waiting = () => {
running = false;
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', () => {
connected = true;
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;
}
connected = ap;
reconnect.connected(ap);
reconnect.is_connected_to(ap);
})
stop_waiting();
});

hooks.on('disconnected', function() {
hooks.on('disconnected', () => {
reconnect.is_connected(false);
was_disconnected = true;
connected = false;
if (config.get('auto_connect') && os_name != 'linux') {
reconnect.connected(null);
if (config.get('auto_connect') && !sleeping) {
wait_normal_reconnection();
}
});

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();
cb(null, emitter);
}

exports.stop = function() {
exports.stop = () => {
hooks.remove('connected');
hooks.remove('disconnected');
hooks.remove('sleeping');

if (emitter) {
emitter.removeAllListeners();
Expand Down
Loading