diff --git a/bin2c.cpp b/bin2c.cpp index 5f34fa4..d8614c4 100755 --- a/bin2c.cpp +++ b/bin2c.cpp @@ -10,6 +10,7 @@ #include #include #include +#include using namespace std; diff --git a/define.h b/define.h index 2bc804f..639e027 100755 --- a/define.h +++ b/define.h @@ -2,7 +2,7 @@ #define DEFINE_H #define APPNAME "Dirt" -#define APPVERSION "1.0.0 alpha 25" +#define APPVERSION "1.0.0 alpha 25 (extended)" #define APPAUTHOR "TmowhrekF" #define APPMAIL "tmowhrekf@filosoferna.se" #define APPURL "http://dirtirc.sf.net/" diff --git a/fish.cpp b/fish.cpp index 1d282d6..b597a27 100755 --- a/fish.cpp +++ b/fish.cpp @@ -10,8 +10,8 @@ using namespace std; union bf_data { struct { - unsigned long left; - unsigned long right; + unsigned int left; + unsigned int right; } lr; BF_LONG bf_long; }; diff --git a/misc.cpp b/misc.cpp index 6a42418..a954c58 100755 --- a/misc.cpp +++ b/misc.cpp @@ -142,7 +142,7 @@ void base64encode(string src, string &dest) string::size_type size = src.size(); src.resize(size + (3 - (size % 3)), 0); dest.erase(); - unsigned long data; + unsigned int data; unsigned char *p = (unsigned char *)src.data(); for (string::size_type i = 0; i < size; i += 3) { data = *p++ << 16; @@ -164,7 +164,7 @@ void base64decode(string src, string &dest) dest.erase(); if (src.find_first_not_of(base64 + "=") != string::npos) return; if (src.size() % 4 != 0) return; - unsigned long data = 0, val; + unsigned int data = 0, val; char *p = (char *)src.data(); for (string::size_type i = 0; i < src.size(); i += 4) { if ((val = base64.find(*p++)) != string::npos) data = val << 18; diff --git a/proxy.cpp b/proxy.cpp index 34140ae..67c45f9 100755 --- a/proxy.cpp +++ b/proxy.cpp @@ -12,6 +12,7 @@ extern "C" { } #include +#include using namespace std; @@ -70,23 +71,37 @@ void proxy::socks4_auth() { if (!received_headers) { const int bufsize = sizeof(socks4header) + 512; - char buf[bufsize]; + char buf[bufsize] = { 0 }; unsigned int num = user.peek(buf, bufsize); - if (num < sizeof(socks4header) + 1) return; - if (buf[num - 1] != '\x00') return; + + if (num < sizeof(socks4header) + 1) { + return; + } + + if (buf[num - 1] != '\x00') { + return; + } + socks4header header; user.get((char *)&header, sizeof(socks4header)); user.get(buf, bufsize - sizeof(socks4header)); string userid = buf; - if (header.vn != 4 || header.cd != 1) reject = true; + if (header.vn != 4 || header.cd != 1) { + reject = true; + } + in_addr inaddr; - inaddr.s_addr = *(unsigned long *)&header.ip; + inaddr.s_addr = *(unsigned int *)&header.ip; string ip = inet_ntoa(inaddr); int port = ntohs(header.port); - if (!good_irc_server(ip, port)) reject = true; + + if (!good_irc_server(ip, port)) + reject = true; + received_headers = true; if (reject) return; irc.bind("", 0); + irc.connect(ip, port); } else if (!sent_headers && !reject && irc.status() == net::connected) { socks4header header; @@ -149,7 +164,36 @@ void proxy::in(string &line) } } cmd = uppercase(pop_word_front(args)); - if (cmd == "PRIVMSG" || cmd == "NOTICE") { + + if(cmd == "332" || cmd == "TOPIC") { + string topic_command = line; + string target_user = ""; + + if(cmd == "332") + target_user = pop_word_front(args); + + string channel = pop_word_front(args); + string::size_type idx = args.find_first_of(":"); + if(idx != 0xffffffff) { + string topic = args.substr(idx + 1), topic_decoded; + string keyname; + + if(channel[0] == '#' || target[0] == '&') + keyname = channel; + else + keyname = source; + + key::decode(keyname, topic, topic_decoded); + + topic_command = prefix + " " + cmd + " " + target_user + " " + channel + " :" + topic_decoded; + if(topic_command[0] != ':') + topic_command.insert(0, ":"); + } + + user.putline(topic_command); + return; + } + else if (cmd == "PRIVMSG" || cmd == "NOTICE") { target = pop_word_front(args); if (target.empty()) return; if (args.substr(0, 1) == ":") args.erase(0, 1); @@ -249,6 +293,16 @@ void proxy::out(string &line) if (cmd == "PRIVMSG" || cmd == "NOTICE") { string target = pop_word_front(args); message(prefix, cmd, target, args); + } else if (cmd == "TOPIC") { + string topic_encoded; + string target = pop_word_front(args); + + if(args.substr(0, 1) == ":") + args = args.erase(0, 1); + + key::encode(target, args, topic_encoded); + string buf = "TOPIC " + target + " :" + topic_encoded; + irc.putline(buf); } else if (cmd == "DIRT") { string dirtcmd = pop_word_front(args); dirt(dirtcmd, args); diff --git a/proxy.h b/proxy.h index 4204f5f..66fb414 100755 --- a/proxy.h +++ b/proxy.h @@ -7,12 +7,15 @@ class proxy { public: +#pragma pack(push) +#pragma pack(1) struct socks4header { unsigned char vn; unsigned char cd; unsigned short port; - unsigned long ip; + unsigned int ip; }; +#pragma pack(pop) proxy(int proxymode, SOCKET userdes, std::string addr, int port); ~proxy(); bool check_status(); diff --git a/unix.cpp b/unix.cpp index 54aa999..f46711f 100755 --- a/unix.cpp +++ b/unix.cpp @@ -9,6 +9,8 @@ #include #include #include +#include +#include using namespace std; @@ -79,6 +81,8 @@ void interpret_cmdline(string cmdline, string unixname) cout << " -v, --version show version information" << endl; cout << " -b, --background start as a daemon (default)" << endl; cout << " -f, --foreground start as a normal user process" << endl; + cout << " -u , --user start as user X" << endl; + cout << " -g , --group start as group X" << endl; cout << " -q, --quit quit daemon" << endl; exit(0); } else if (s == "-v" || s == "--version") { @@ -94,6 +98,29 @@ void interpret_cmdline(string cmdline, string unixname) config.reset(); config.save(); exit(0); + } else if(s == "-u" || s == "--user") { + string arg; + passwd *pwd; + + arg = pop_word_front(cmdline); + if(arg.length() == 0) platform::error("Invalid argument to -u option."); + + pwd = getpwnam(arg.c_str()); + if(pwd == NULL) platform::error("Invalid username specified."); + + if(setuid(pwd->pw_uid) != 0) + platform::error("No permissions to change user."); + } else if(s == "-g" || s == "--group") { + string arg; + group *grp; + arg = pop_word_front(cmdline); + if(arg.length() == 0) platform::error("Invalid argument to -g option."); + + grp = getgrnam(arg.c_str()); + if(grp == NULL) platform::error("Invalid group specified."); + + if(setgid(grp->gr_gid) != 0) + platform::error("No permissions to change group."); } else { platform::error("Unrecognized option `" + s + "'\nTry `" + unixname + " --help' for more information."); } @@ -135,9 +162,9 @@ void set_umask() string homedir() { - const char *homedir; - homedir = getenv("HOME"); - if (homedir) return homedir; + //const char *homedir; + //homedir = getenv("HOME"); + //if (homedir) return homedir; struct passwd *pwd = getpwuid(getuid()); if (pwd) return pwd->pw_dir; return ""; @@ -186,19 +213,40 @@ void quit() exit(0); } +bool test() { + string data, orig; + + base64encode("antonone's test", data); + base64decode(data, orig); + + if(orig.compare("antonone's test")) { + cout << data << endl; + cout << orig << endl; + return false; + } else { + return true; + } +} + int main(int argc, char **args) { - set_umask(); - get_workdir(); - get_confdir(); - if (!set_rc_dir()) platform::error((string)"Could not change directory to ~/" + rc_dir); + if(! test()) { + cout << "Bad compilation! Tests failed.\n"; + return 1; + } + string s; int i; for (i = 0; i < argc - 1; i++) { if (i > 0) s += " "; s += args[i + 1]; } + interpret_cmdline(s, args[0]); + set_umask(); + get_workdir(); + get_confdir(); + if (!set_rc_dir()) platform::error((string)"Could not change directory to ~/" + rc_dir); pid_t pid = 0; ifstream pidfile(PIDFILE, ios::in); if (pidfile.good()) {