updating with fix for desktop/laptop use
[mnenc] / libmnenc / mnenc.cpp
1 #include <iostream>
2 #include <fstream>
3 #include <string>
4 #include <cstdio>
5 #include <cstdlib>
6 #include <ctime>
7 #include <sys/stat.h>
8 #include <sys/types.h>
9
10 #include "mnenc.hpp"
11
12 using namespace std;
13
14 mnenc::mnenc() { //Constructor
15         make_folder();
16         get_imei(); //see get_imei below
17         imei += imei; //imei now have 30 digits
18         imei += imei; //imei now have 60 digits
19         imei += imei; //imei now have 120 digits
20         imei += imei; //imei now have 240 digits, should now be longer than any password
21 }
22
23 void mnenc::encrypt(string str) { //Run xor against imei
24         for(int i=0; i < (signed) str.size(); i++)      {
25                 str[i] = str[i] ^ imei[i];
26         }
27         enc = str;
28 }
29  
30 void mnenc::decrypt(string str) { //Same as above only the other way around
31         for(int i = 0; i < (signed) enc.size(); i++)    {
32                 str[i] = imei[i] ^ str[i];
33         }
34         dec = str;
35 }
36
37 bool mnenc::to_file(string filename) { //Save to file
38         bool worked = false;
39         ofstream keyfile;
40         keyfile.open(filename.c_str());
41         if(keyfile.is_open()) {
42                 keyfile << enc;
43                 keyfile.close();
44                 worked = true;
45         }
46         return worked;
47 }
48
49 bool mnenc::from_file(string filename) { //Read password file
50         bool worked = false;
51         ifstream keyfile(filename.c_str());
52         string encryptedpw = "";
53         string line = "";
54         if (keyfile.is_open()) {
55                 while (! keyfile.eof() ) {
56                         getline (keyfile,line);
57                         encryptedpw += line;
58                 }
59                 keyfile.close();
60                 worked = true;
61         }
62         enc = encryptedpw;
63         decrypt(enc); // Automatically decrypt password on read
64         return worked;
65 }
66
67 string mnenc::genkey() { 
68         string key = "";
69         srand(time(NULL));
70         for(int i = 0; i < 15; i++) {
71                 key += (rand() % 10);  //generate a random number between 0 and 9
72         }
73         string filename = make_path() + ".keyfile"; //This is where the key goes 
74         ofstream os;
75         os.open(filename.c_str());
76         if(os.is_open()) {
77                 os << key;
78                 os.close();
79         }
80         return key;
81 }
82 void mnenc::get_imei() {
83         /* TODO 
84          * Implement this in c++ since it is realy realy ugly to shell out like this...
85          */
86           
87         string username = getenv("USER"); //Get username
88         string filename = make_path() + ".keyfile"; //This is where the key goes if we generate it
89         string cmd = "dbus-send --system --print-reply --type=method_call --dest=com.nokia.phone.SIM /com/nokia/phone/SIM/security Phone.Sim.Security.get_imei | grep string | sed -e 's/^.*\\\"\\([0-9]\\)/\\1/' -e 's/\\\"//'"; //Command used when shelling out to get imei
90         
91         FILE *fp; //a file pointer
92         char buffer[1024]; //Some tmp storage
93         fp = popen(cmd.c_str(), "r"); //Open a pipe whith the command
94         while ( fgets(buffer, 1024, fp) != NULL ) //Read the result
95                 imei.append(buffer); //Add the result to our attribute
96         pclose(fp); //Close the pipe
97
98     if(!is_imei(imei)) { //If we could not get imei
99                 ifstream keyfile(filename.c_str()); //open the keyfile
100                 string k = "";
101                 string line = "";
102                 if (keyfile.is_open()) { //if it worked
103                         while (! keyfile.eof() ) { //Get the key from there
104                                 getline (keyfile,line);
105                                 k += line;
106                         }
107                         keyfile.close(); //Close the file
108                         imei = k; //And save result
109                 } else { //If that didnt work 
110                         imei = genkey(); //generate a new key and save that to teh keyfile
111                 }
112                 
113         }
114 }
115
116 bool mnenc::user_from_file(string filename) { //Read userfile (Added by hexagon 2010-01-17)
117         bool worked = false;
118         ifstream userfile(filename.c_str());
119         string buf = "";
120         string line = "";
121         if (userfile.is_open()) {
122                 while (! userfile.eof() ) {
123                         getline (userfile,line);
124                         buf += line;
125                 }
126                 userfile.close();
127                 worked = true;
128         }
129         user = buf;
130         return worked;
131 }
132
133 bool mnenc::user_to_file(string filename) { //Save username to file (Added by hexagon 2010-01-17)
134         bool worked = false;
135         ofstream userfile;
136         userfile.open(filename.c_str());
137         if(userfile.is_open()) {
138                 userfile << user;
139                 userfile.close();
140                 worked = true;
141         }
142         return worked;
143 }
144
145 void mnenc::set_user(string usr) { // Sets username (Added by hexagon 2010-01-17)
146     user = usr.c_str();
147 }
148
149 string mnenc::get_user() { // Gets username (Added by hexagon 2010-01-17)
150     return user;
151 }
152
153 void mnenc::make_folder() { //Create home directory
154         string dirname = make_path(); 
155         int ret = chdir(dirname.c_str());
156         if(ret != 0) {
157                 mkdir(dirname.c_str(), 0755);
158         }
159 }
160
161 bool mnenc::is_int(char c) { //See if a char is an int
162         return (c == '0' || c == '1' || c == '2' || c == '3' || c == '4' || c == '5' || c == '6' || c == '7' || c == '8' || c == '9');
163 }
164
165 bool mnenc::is_imei(string str) { //See if a string is made up of 15 ints
166         bool proper_length = false; //Is it 15 chars?
167         bool is_ints = true; //Is it only ints?
168         if(str.length() == 15) { //Check length
169                 proper_length = true;
170         } else {
171                 return false; //Exit early if it fails length test
172         }
173         for(int i = 0; i < (signed) str.length(); i++) { //Check if they are all ints
174                 if(!is_int(str[i])) {
175                         is_ints = false;
176                 }
177         }
178         if(proper_length && is_ints) { //Return true if it passes the tests
179                 return true;
180         } else {
181                 return false; //And false if it doesnt
182         }
183 }
184
185 string mnenc::make_path() { //Create path to qtify home
186         string username = getenv("USER"); //Get username
187         string path = "/home/" + username + "/.qtify/"; //This is home directory of qtify
188         return path;
189 }