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()) { diff --git a/fish.h b/fish.h index 39d0fdf..1a6feb4 100755 --- a/fish.h +++ b/fish.h @@ -3,6 +3,7 @@ #include #include +using namespace std; namespace fish { void init(); diff --git a/key.cpp b/key.cpp index eeb11e9..5d98d82 100755 --- a/key.cpp +++ b/key.cpp @@ -1,13 +1,14 @@ -#include "key.h" -#include "misc.h" -#include "fish.h" -#include "define.h" #include #include #include #include #include +#include "key.h" +#include "misc.h" +#include "fish.h" +#include "define.h" + using namespace std; algomap_t algomap; @@ -193,13 +194,81 @@ int key::encode(const string &search, const string &in, string &out) return kiter->encode(in, out); } +string get_nick_from_privlog_line(const string& in) { + string::size_type start, stop; + + start = in.find("("); + stop = in.find("!"); + + if(start == string::npos || stop == string::npos) + return ""; + + string newnick = in.substr(start + 1, stop - start - 1); + return newnick; +} + +string get_prefix_from_privlog_line(const string& in) { + string::size_type start; + + start = in.find(")"); + + if(start == string::npos) + return ""; + + return in.substr(0, start + 2); +} + +string get_msg_from_privlog_line(const string& in) { + string::size_type start; + + start = in.find(")"); + + if(start == string::npos) + return ""; + + return in.substr(start + 2); +} + int key::decode(const string &search, const string &in, string &out) { - if (!find(search)) { + bool psybnc_hack = false; + + string to_search = search; + string to_in = in; + string to_out = out; + string to_prefix; + + if(search == "-psyBNC") + psybnc_hack = true; + + if(psybnc_hack) { + string nick = get_nick_from_privlog_line(in); + + if(nick.size() == 0) + psybnc_hack = false; + else { + to_search = nick; + } + } + + if (!find(to_search)) { out = in; + return bad_target; } - return kiter->decode(in, out); + + if(psybnc_hack) { + to_prefix = get_prefix_from_privlog_line(in); + to_in = get_msg_from_privlog_line(in); + } + + int ret = kiter->decode(to_in, to_out); + out = to_out; + + if(psybnc_hack) + out = to_prefix + out; + + return ret; } bool key::addalias(const string &search, const string &alias) diff --git a/key.h b/key.h index 75a1d16..6436b8d 100755 --- a/key.h +++ b/key.h @@ -5,6 +5,7 @@ #include #include #include +using namespace std; typedef std::map algomap_t; typedef std::list keylist_t; diff --git a/misc.cpp b/misc.cpp index a954c58..d702b7f 100755 --- a/misc.cpp +++ b/misc.cpp @@ -84,7 +84,7 @@ string gettok(const string &s, const string delim, const int index) return empty; } -string lowercase(string s) +string lowercase(std::string s) { string::size_type i; for (i = 0; i < s.size(); i++) s[i] = (char)tolower(s[i]); diff --git a/misc.h b/misc.h index 21b712e..a679ce1 100755 --- a/misc.h +++ b/misc.h @@ -4,6 +4,8 @@ #include #include +using namespace std; + extern std::string base64; std::string itos(int i, const int base = 10); diff --git a/unix.mak b/unix.mak index 726e608..270a188 100755 --- a/unix.mak +++ b/unix.mak @@ -4,11 +4,19 @@ CC = gcc CXX = g++ +CPPFLAGS = -D DIRT_UNIX + +# release CFLAGS = -pipe -O3 -Wall -pedantic -Wno-long-long -std=c99 CXXFLAGS = -pipe -O3 -Wall -pedantic -Wno-long-long -CPPFLAGS = -D DIRT_UNIX LDFLAGS = -s +# debug +#CFLAGS = -pipe -g3 -O0 -Wall -pedantic -Wno-long-long -std=c99 +#CXXFLAGS = -pipe -g3 -O0 -Wall -pedantic -Wno-long-long +#LDFLAGS = + + MAKEDEPEND = $(CXX) -MM $(CPPFLAGS) -o $*.d $< DIRT = dirt