You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
271 lines
6.2 KiB
271 lines
6.2 KiB
/*
|
|
* suid.cpp
|
|
* Copyright (C) Aitor Cuadrado Zubizarreta <aitor_czr@gnuinos.org>
|
|
*
|
|
* simple-netaid is free software: you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the
|
|
* Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* simple-netaid is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; witkkkhout even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
* See the GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
* See the COPYING file. *
|
|
*/
|
|
|
|
#include <gtkmm.h>
|
|
#include <iostream>
|
|
#include <vector>
|
|
#include <memory>
|
|
#include <net/if.h>
|
|
#include <sys/ioctl.h>
|
|
|
|
#include <dirent.h>
|
|
|
|
#include "gtk/cli.h"
|
|
#include "gtk/svr.h"
|
|
#include "gtk/pipe_file.h"
|
|
|
|
|
|
extern "C" {
|
|
|
|
#include <simple-netaid/sbuf.h>
|
|
void scan_active_wifis(const char*, struct sbuf*);
|
|
void interface_up(const char*);
|
|
void interface_down(const char*);
|
|
void ipaddr_flush(const char*);
|
|
void get_interface_status(const char*);
|
|
}
|
|
|
|
using namespace std;
|
|
|
|
string get_pid();
|
|
string get_file_descriptor(int);
|
|
void print_active_wifis(string);
|
|
void wireless_connection(string, string, string);
|
|
void kill_all_processes(vector<string>);
|
|
void wpa_supplicant(string, string, string);
|
|
void ifup(string);
|
|
void ifdown(string);
|
|
void delete_active_wifis_output();
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
if(argc>1) print_active_wifis(argv[1]);
|
|
else {
|
|
|
|
unique_ptr<Cli> cli( new Cli(get_file_descriptor(0)) );
|
|
|
|
printf("---> %s %s\n", cli->messages[0].c_str(), cli->messages[1].c_str());
|
|
|
|
switch(stoi(cli->messages[0])) {
|
|
|
|
case 0: wireless_connection(cli->messages[1], cli->messages[2], cli->messages[3]);
|
|
break;
|
|
|
|
case 1: interface_up(cli->messages[1].c_str());
|
|
break;
|
|
|
|
case 2: interface_down(cli->messages[1].c_str());
|
|
break;
|
|
|
|
case 3: delete_active_wifis_output();
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
string get_pid()
|
|
{
|
|
string pid;
|
|
unique_ptr<PipeFile> fp( new PipeFile() );
|
|
vector<string> output = fp->get_output("ps -A | grep simple-netaid");
|
|
|
|
if(output.size() == 1) {
|
|
istringstream iss(output[0]);
|
|
getline(iss, pid, ' ');
|
|
} else throw runtime_error("Unable to get the pid of simple-netaid.\n");
|
|
|
|
return(pid);
|
|
}
|
|
|
|
string get_file_descriptor(int i)
|
|
{
|
|
string str;
|
|
|
|
switch(i) {
|
|
|
|
case 0: str = "/tmp/snet_suid_args_" + get_pid() + ".socket";
|
|
break;
|
|
|
|
case 1: str = "/tmp/snet_active-wifis_" + get_pid() + ".socket";
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return(str);
|
|
}
|
|
|
|
void print_active_wifis(string wireless_device)
|
|
{
|
|
struct sbuf ifname, s;
|
|
sbuf_init(&ifname);
|
|
sbuf_init(&s);
|
|
sbuf_addstr(&ifname, wireless_device.c_str());
|
|
scan_active_wifis(wireless_device.c_str(), &s);
|
|
printf("%s\n", s.buf);
|
|
free(ifname.buf);
|
|
free(s.buf);
|
|
}
|
|
|
|
void kill_all_processes(vector<string> processes)
|
|
{
|
|
struct dirent *ent;
|
|
|
|
DIR *proc_dir = opendir("/proc");
|
|
while ((ent = readdir(proc_dir))) {
|
|
|
|
// Be sure it's a pid:
|
|
if ((*ent->d_name>'0') && (*ent->d_name<='9')) {
|
|
|
|
pid_t pid = atoi(ent->d_name);
|
|
|
|
char statFileName[128];
|
|
char *mypid = NULL;
|
|
|
|
if (asprintf(&mypid, "%jd", (intmax_t) pid) != -1) {
|
|
sprintf(statFileName, "/proc/%s/stat", mypid);
|
|
free(mypid);
|
|
|
|
int i=0;
|
|
FILE *fp;
|
|
|
|
try {
|
|
fp = fopen(statFileName, "r");
|
|
} catch( const exception& e ) {
|
|
i++; if (i>10) break;
|
|
};
|
|
|
|
if (!fp) {
|
|
cout << "Enable to open the "
|
|
<< string(statFileName)
|
|
<< " file."
|
|
<< endl;
|
|
} else {
|
|
|
|
char buffer[512];
|
|
fgets(buffer, 512, fp);
|
|
fclose(fp);
|
|
|
|
char* cstart=strchr(buffer, '(');
|
|
char* cend =strrchr(buffer, ')');
|
|
size_t namesize = (cend-cstart<33)?cend-cstart-1:32;
|
|
|
|
char name[512];
|
|
strncpy(name, cstart+1, namesize);
|
|
name[namesize]='\0';
|
|
if ( (cstart == NULL) || (cend == NULL) ) {
|
|
cout << "Enable to get the name of the process from "
|
|
<< string(statFileName)
|
|
<< endl;
|
|
} else {
|
|
for(unsigned int i=0; i<processes.size(); i++) {
|
|
if(!strcmp(processes[i].c_str(), name)) {
|
|
cout << " " << name;
|
|
if ((kill(pid, SIGTERM)) == 0) {
|
|
cout << " ----> SIGTERM" << endl;
|
|
}
|
|
else {
|
|
kill(pid, SIGKILL);
|
|
cout << " ----> SIGKILL" << endl;
|
|
}
|
|
}
|
|
} // for
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
} // while
|
|
|
|
closedir(proc_dir);
|
|
}
|
|
|
|
void wireless_connection(string ifname, string essid, string password)
|
|
{
|
|
vector<string> processes = { "dhclient", "udhcpc", "pump", "dhcp6c", "wpa_supplicant" };
|
|
kill_all_processes(processes);
|
|
ipaddr_flush( ifname.c_str() );
|
|
interface_down( ifname.c_str() );
|
|
ifdown( ifname.c_str() );
|
|
interface_up( ifname.c_str() );
|
|
wpa_supplicant( ifname, essid, password );
|
|
sleep(1); /* not sure if neccessary*/
|
|
ifup( ifname.c_str() );
|
|
}
|
|
|
|
void wpa_supplicant(string ifname, string essid, string password)
|
|
{
|
|
FILE *fp;
|
|
fp = fopen( "/tmp/wpa.conf", "w" );
|
|
if(!fp) {
|
|
cout << "Cannot open \"/tmp/wpa.conf\" config file file." << endl;
|
|
exit( EXIT_FAILURE );
|
|
}
|
|
|
|
if(!password.empty())
|
|
fprintf( fp, "network={\n\tssid=\"%s\"\n\tpsk=\"%s\"\n}", essid.c_str(), password.c_str() );
|
|
else fprintf( fp, "network={\n\tssid=\"%s\"\n\tkey_mgmt=NONE\n}", essid.c_str() );
|
|
|
|
fclose( fp );
|
|
|
|
string conf_filename = "/tmp/wpa.conf";
|
|
string cmd = "/sbin/wpa_supplicant -B -i " + ifname + " -c " + conf_filename;
|
|
system(cmd.c_str());
|
|
|
|
try {
|
|
remove(conf_filename.c_str());
|
|
}
|
|
catch( const exception& e ) {
|
|
throw runtime_error("Error deleting file.\n");
|
|
};
|
|
}
|
|
|
|
void ifup(string ifname)
|
|
{
|
|
string cmd = "/sbin/ifup " + ifname;
|
|
system(cmd.c_str());
|
|
}
|
|
|
|
void ifdown(string ifname)
|
|
{
|
|
string cmd = "/sbin/ifdown " + ifname;
|
|
system(cmd.c_str());
|
|
}
|
|
|
|
void delete_active_wifis_output()
|
|
{
|
|
string file=get_file_descriptor(1);
|
|
|
|
Glib::RefPtr<Gio::File> ref_path = Gio::File::create_for_path(file.c_str());
|
|
if(ref_path->query_exists()) {
|
|
try {
|
|
remove(file.c_str());
|
|
}
|
|
catch( const exception& e ) {
|
|
throw runtime_error("Error deleting active_wifis_output file descriptor.\n");
|
|
}
|
|
};
|
|
}
|
|
|