Gtk interface for simple-netaid.
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

/*
* 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");
}
};
}