Changeset 546
- Timestamp:
- 05/03/06 03:05:12 (3 years ago)
- Files:
-
- nepenthes/branches/nepenthes-experimental/modules/log-irc/IrcDialogue.cpp (modified) (11 diffs)
- nepenthes/branches/nepenthes-experimental/modules/log-irc/IrcDialogue.hpp (modified) (3 diffs)
- nepenthes/branches/nepenthes-experimental/modules/log-irc/log-irc.conf.dist (modified) (1 diff)
- nepenthes/branches/nepenthes-experimental/modules/log-irc/log-irc.cpp (modified) (3 diffs)
- nepenthes/branches/nepenthes-experimental/modules/log-irc/log-irc.hpp (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
nepenthes/branches/nepenthes-experimental/modules/log-irc/IrcDialogue.cpp
r543 r546 6 6 * 7 7 * Copyright (C) 2005 Paul Baecher & Markus Koetter 8 * Copyright (C) 2006 Georg Wicherski 8 9 * 9 10 * This program is free software; you can redistribute it and/or … … 62 63 63 64 64 65 66 /**67 * Dialogue::Dialogue(Socket *)68 * construktor for the IrcDialogue, creates a new IrcDialogue69 *70 * replies some crap to the socket71 *72 * @param socket the Socket the Dialogue has to use73 */74 65 IrcDialogue::IrcDialogue(Socket *socket, LogIrc * logirc) 75 66 { 76 67 m_Socket = socket; 77 m_DialogueName = "IrcDialogue";78 m_DialogueDescription = " eXample Dialogue";68 m_DialogueName = "IrcDialogue"; 69 m_DialogueDescription = "IRC logging client"; 79 70 80 71 m_ConsumeLevel = CL_ASSIGN; … … 85 76 if ( m_LogIrc->useTor() == true ) 86 77 { 87 socks4_header_t s4hHeader; 88 memset(&s4hHeader,0,sizeof(socks4_header_t)); 89 90 s4hHeader.ucVersion = 4; 91 s4hHeader.ucCommand = 1; // connect request 92 s4hHeader.usDestPort = htons(m_LogIrc->getIrcPort()); 93 s4hHeader.ulDestAddr = m_LogIrc->getIrcIP(); 94 95 m_Socket->doRespond((char *) &s4hHeader,8+ strlen(s4hHeader.szUser)+1 ); 96 } else 78 SocksHeader torHeader; 79 memset(&torHeader, 0, sizeof(torHeader)); 80 81 torHeader.version = 4; 82 torHeader.command = 1; // connect request 83 torHeader.destPort = htons(m_LogIrc->getIrcPort()); 84 torHeader.destAddress = m_LogIrc->getIrcIP(); 85 86 m_Socket->doRespond((char *) &torHeader,8+strlen(torHeader.user)+1); 87 } 88 else 97 89 { 98 90 m_State = IRCDIA_CONNECTED; … … 116 108 } 117 109 118 /**119 * Dialogue::incomingData(Message *)120 *121 * a small and ugly shell where we can use122 * "download protocol://localction:port/path/to/file123 * to trigger a download124 *125 * @param msg the Message the Socker received.126 *127 *128 * @return CL_ASSIGN129 */130 110 ConsumeLevel IrcDialogue::incomingData(Message *msg) 131 111 { 132 133 112 switch (m_State) 134 113 { 135 114 case IRCDIA_REQUEST_SEND: 136 if ( ((socks4_header_t *)msg->getMsg())->ucCommand == 90 )137 { 138 logInfo(" connected to ircd via tor\n");115 if( ((SocksHeader *) msg->getMsg())->command == 90 ) 116 { 117 logInfo("Connected to IRC server \"%s\" through TOR proxy \"%s\"\n", m_LogIrc->getIrcServer().c_str(), m_LogIrc->getTorServer().c_str()); 139 118 m_State = IRCDIA_CONNECTED; 140 119 … … 143 122 sendUser(); 144 123 145 } else 146 { 147 logWarn("tor did not accept our connection \n"); 124 } 125 else 126 { 127 logInfo("Relaying to IRC server \"%s\" denied by TOR proxy \"%s\"\n", m_LogIrc->getIrcServer().c_str(), m_LogIrc->getTorServer().c_str()); 148 128 return CL_DROP; 149 129 } 130 150 131 break; 132 151 133 case IRCDIA_CONNECTED: 152 { 153 m_Buffer->add(msg->getMsg(),msg->getSize()); 154 processBuffer(); 155 } 134 m_Buffer->add(msg->getMsg(),msg->getSize()); 135 processBuffer(); 136 156 137 break; 157 138 158 139 } 140 159 141 return CL_ASSIGN; 160 142 } 161 143 162 144 //! oxff: slightly faster and definitely better readable than old implementation 163 145 void IrcDialogue::processBuffer() 164 146 { 165 logPF(); 166 unsigned char *linestart = (unsigned char *)m_Buffer->getData(); 167 unsigned char *linestopp = (unsigned char *)m_Buffer->getData(); 168 169 uint32_t i=0; 170 while (i < m_Buffer->getSize()) 171 { 172 173 if ( linestopp[i] == '\n') 174 { 175 i++; 176 // printf("IRCLINE len %i \n'%.*s'\n",(int32_t)(linestopp+i-linestart),(int32_t)(linestopp+i-linestart),linestart); 177 string line((char *)m_Buffer->getData(),(int32_t)(linestopp+i - linestart)); 178 if (line[line.size()-1] == '\n') 147 uint32_t bufferLength = m_Buffer->getSize(); 148 uint32_t lineLength, processedLength; 149 const char * look, * lineStart; 150 151 if(bufferLength < 2) 152 return; 153 154 processedLength = 0; 155 look = (char *) m_Buffer->getData(); 156 157 lineStart = look; 158 lineLength = 1; 159 ++look; 160 161 for(uint32_t i = 0; i < bufferLength; ++i, ++look) 162 { 163 if(* look == '\n' && * (look - 1) == '\r') 164 { 165 // -1 cuts the already processed '\r' 166 processLine(lineStart, lineLength - 1); 167 168 // + 1 includes the trailing '\n' 169 processedLength += lineLength + 1; 170 lineLength = 0; 171 lineStart = look + 1; 172 } 173 else 174 ++lineLength; 175 } 176 177 m_Buffer->cut(processedLength); 178 } 179 180 //! oxff: again slightly faster and definitely better readable 181 //! oxff: now splits into IRC RFC elements, not words (leaving PRIVMSG lines) 182 void IrcDialogue::processLine(const char * line, uint32_t lineLength) 183 { 184 vector<string> lineElements; 185 186 { 187 const char * look = line; 188 string element; 189 190 if(* line == ':') 191 { 192 if(!--lineLength) 193 return; 194 195 ++look; 196 } 197 198 //! oxff: this is a pre-condition to the parsing loop 199 if(* look == ':') 200 { 201 logWarn("IRC Server \"%s\" sent line beginning with two colons\n", m_LogIrc->getIrcServer().c_str()); 202 return; 203 } 204 205 for(uint32_t i = 0; i < lineLength; ++i, ++look) 206 { 207 if(* look == ' ') 179 208 { 180 line[line.size()-1] = '\0'; 209 lineElements.push_back(element); 210 element.erase(); 181 211 } 182 if (line[line.size()-2] == '\r') 183 { 184 line[line.size()-2] = '\0'; 212 else if(* look == ':' && * (look - 1) == ' ') // look behind allowed due to pre-condition 213 { 214 element = string(look + 1, lineLength - i - 1); 215 lineElements.push_back(element); 216 element.erase(); 217 218 break; 185 219 } 186 printf("test '%s'\n",line.c_str()); 187 processLine(&line); 188 m_Buffer->cut(i); 189 i=0; 190 linestart = linestopp+i; 191 }else 192 { 193 i++; 194 } 195 } 196 } 197 198 void IrcDialogue::processLine(string *line) 199 { 200 vector<string> words; 201 202 uint32_t i=0; 203 bool haschar = false; 204 uint32_t wordstart=0; 205 uint32_t wordstopp=0; 206 207 while ( i<=line->size() ) 208 { 209 if ( ( ( (*line)[i] == ' ' || (*line)[i] == '\0') && haschar == true) ) 210 { 211 wordstopp = i; 212 string word = line->substr(wordstart,wordstopp-wordstart); 213 // logInfo("Word is %i %i '%s' \n",wordstart,wordstopp,word.c_str()); 214 words.push_back(word); 215 haschar = false; 216 } else 217 if ( isgraph((*line)[i]) && haschar == false ) 218 { 219 haschar = true; 220 wordstart = i; 221 } 222 i++; 223 } 224 225 /* 226 for (i=0;i<words.size();i++) 227 { 228 logSpam("word is '%s'\n",words[i].c_str()); 229 } 230 */ 231 232 if (words[0] == "PING" ) 233 { 234 string reply = "PONG "; 235 reply += words[1]; 236 reply += "\r\n"; 237 m_Socket->doRespond((char *)reply.c_str(),reply.size()); 238 239 }else 240 if ( words[1] == "376" || words[1] == "422" ) 241 { 242 string reply = "JOIN "; 243 reply += m_LogIrc->getIrcChannel(); 244 reply += " "; 245 reply += m_LogIrc->getIrcChannelPass(); 246 reply += "\r\n"; 247 m_Socket->doRespond((char *)reply.c_str(),reply.size()); 248 m_LogIrc->setDialogue(this); 249 }else 250 if (words[1] == "PONG" ) 251 { 220 else 221 element.push_back(* look); 222 } 223 224 if(element.size()) 225 lineElements.push_back(element); 226 } 227 228 if(lineElements.empty()) 229 return; 230 231 232 if(lineElements.size() >= 1 && lineElements[1] == "433") 233 sendNick(true); 234 if(lineElements[0] == "PING" && lineElements.size() == 2) 235 { 236 string reply = "PONG " + lineElements[1] + "\r\n"; 237 238 m_Socket->doRespond((char *) reply.data(), reply.size()); 239 } 240 else if(lineElements[0] == "PONG") 252 241 m_Pinged = false; 253 }else 254 if ( words[1] == "433" ) 255 { 256 sendNick(true); 257 }else 258 if ( words.size() >= 4 && words[1] == "PRIVMSG" && words[3] == ":!version") 259 { 260 char *reply; 261 asprintf(&reply,"PRIVMSG %s :Nepenthes Version %s - Compiled on %s %s with %s %s \n",words[2].c_str(),VERSION,__DATE__, __TIME__,MY_COMPILER,__VERSION__); 262 m_Socket->doRespond((char *)reply,strlen(reply)); 263 free(reply); 264 } 265 return; 266 267 } 268 269 /** 270 * Dialogue::outgoingData(Message *) 271 * as we are not interested in these socket actions 272 * we simply return CL_DROP to show the socket 273 * 274 * @param msg 275 * 276 * @return CL_DROP 277 */ 242 else if(lineElements.size() >= 2 && (lineElements[1] == "003" ||lineElements[1] == "004" || lineElements[1] == "005" || lineElements[1] == "376" || lineElements[1] == "422")) 243 loggedOn(); 244 else if(lineElements.size() >= 4 && (lineElements[1] == "PRIVMSG" || lineElements[1] == "NOTICE")) 245 processMessage(lineElements[0].c_str(), lineElements[2].c_str(), lineElements[3].c_str()); 246 } 247 248 void IrcDialogue::processMessage(const char * origin, const char * target, const char * message) 249 { 250 string responseMessage = string("PRIVMSG "); 251 252 logDebug("<%s.%s.%s> \"%s\"\n", m_LogIrc->getIrcServer().c_str(), target, origin, message); 253 254 if(m_NickName == target) 255 { 256 string originString = origin; 257 258 responseMessage += originString.substr(0, originString.find('!')); 259 } 260 else 261 responseMessage += target; 262 263 if(string(message) == "!version") 264 { 265 responseMessage += " :nepenthes v" VERSION " compiled on [" __DATE__ " " __TIME__ "] with " MY_COMPILER " " __VERSION__ "\r\n"; 266 m_Socket->doRespond((char *) responseMessage.data(), responseMessage.size()); 267 } 268 269 } 270 271 272 // TODO: add on-connect cmd to auth at nickserv 273 274 void IrcDialogue::loggedOn() 275 { 276 string joinCommand = "JOIN " + m_LogIrc->getIrcChannel() + " " + m_LogIrc->getIrcChannelPass() + "\r\n"; 277 m_Socket->doRespond((char *) joinCommand.data(), joinCommand.size()); 278 } 279 278 280 ConsumeLevel IrcDialogue::outgoingData(Message *msg) 279 281 { … … 281 283 } 282 284 283 /**284 * Dialogue::handleTimeout(Message *)285 * as we are not interested in these socket actions286 * we simply return CL_DROP to show the socket287 *288 * @param msg289 *290 * @return CL_DROP291 */292 285 ConsumeLevel IrcDialogue::handleTimeout(Message *msg) 293 286 { … … 295 288 { 296 289 m_Pinged = true; 297 string ping = "PING :12356789\r\n"; 298 m_Socket->doRespond((char *)ping.c_str(),ping.size()); 290 291 string ping = "PING :12356789\r\n"; 292 m_Socket->doRespond((char *) ping.data(), ping.size()); 293 299 294 return CL_ASSIGN; 300 }else 295 } 296 else 301 297 { 302 298 m_LogIrc->doRestart(); 303 299 return CL_DROP; 304 300 } 305 306 } 307 308 /** 309 * Dialogue::connectionLost(Message *) 310 * as we are not interested in these socket actions 311 * we simply return CL_DROP to show the socket 312 * 313 * @param msg 314 * 315 * @return CL_DROP 316 */ 301 } 302 317 303 ConsumeLevel IrcDialogue::connectionLost(Message *msg) 318 304 { 319 305 logPF(); 306 320 307 m_LogIrc->doRestart(); 321 308 return CL_DROP; 322 309 } 323 310 324 /**325 * Dialogue::connectionShutdown(Message *)326 * as we are not interested in these socket actions327 * we simply return CL_DROP to show the socket328 *329 * @param msg330 *331 * @return CL_DROP332 */333 311 ConsumeLevel IrcDialogue::connectionShutdown(Message *msg) 334 312 { 335 313 logPF(); 314 336 315 m_LogIrc->doRestart(); 337 316 return CL_DROP; 338 317 } 318 319 320 321 // TODO: format, translate 339 322 340 323 struct FlagMapping … … 343 326 char *m_ColorFlag; 344 327 }; 345 346 328 347 329 const struct FlagMapping colors[] = … … 370 352 371 353 372 373 void IrcDialogue::logIrc(uint32_t mask, const char *message) 354 // TODO: parse log tags from configuration 355 356 void IrcDialogue::logIrc(uint32_t mask, const char *message) 374 357 { 375 358 if ( … … 403 386 void IrcDialogue::sendNick(bool random) 404 387 { 405 if (random) 406 { 407 string nick = "NICK "; 408 nick += m_LogIrc->getIrcNick(); 409 nick += (char) ((int32_t)rand()%20 + 97); 410 nick += "\r\n"; 411 412 m_Socket->doRespond((char *)nick.c_str(),nick.size()); 413 }else 414 { 415 string nick = "NICK "; 416 nick += m_LogIrc->getIrcNick(); 417 nick += "\r\n"; 418 419 m_Socket->doRespond((char *)nick.c_str(),nick.size()); 420 } 388 m_NickName = m_LogIrc->getIrcNick(); 389 390 if(random) 391 { 392 m_NickName += "-"; 393 m_NickName += (char) ((int32_t)rand()%20 + 97); 394 m_NickName += (char) ((int32_t)rand()%20 + 97); 395 m_NickName += (char) ((int32_t)rand()%20 + 97); 396 } 397 398 string nickCommand = "NICK " + m_NickName + "\r\n"; 399 m_Socket->doRespond((char *) nickCommand.data(), nickCommand.size()); 421 400 } 422 401 423 402 void IrcDialogue::sendUser() 424 403 { 425 string user = "USER "; 426 user += m_LogIrc->getIrcIdent(); 427 user += " 0 0 :"; 428 user += m_LogIrc->getIrcUserInfo(); 429 user += "\r\n"; 430 431 m_Socket->doRespond((char *)user.c_str(),user.size()); 404 string user = "USER " + m_LogIrc->getIrcIdent() + " 0 0 :" + m_LogIrc->getIrcUserInfo() + "\r\n"; 405 m_Socket->doRespond((char *) user.data(), user.size()); 432 406 } 433 407 … … 436 410 if ( m_LogIrc->getIrcPass().size() > 0 ) 437 411 { 438 string pass = "PASS "; 439 pass += m_LogIrc->getIrcPass(); 440 pass += "\r\n"; 441 m_Socket->doRespond((char *)pass.c_str(),pass.size()); 442 } 443 } 444 412 string pass = "PASS " + m_LogIrc->getIrcPass() + pass + "\r\n"; 413 m_Socket->doRespond((char *) pass.data(), pass.size()); 414 } 415 } 416 nepenthes/branches/nepenthes-experimental/modules/log-irc/IrcDialogue.hpp
r378 r546 6 6 * 7 7 * Copyright (C) 2005 Paul Baecher & Markus Koetter 8 * Copyright (C) 2005 Georg Wicherski 8 9 * 9 10 * This program is free software; you can redistribute it and/or … … 38 39 using namespace std; 39 40 41 40 42 namespace nepenthes 41 43 { 42 typedef struct44 struct SocksHeader 43 45 { 44 unsigned char ucVersion;45 unsigned char ucCommand;46 uint16_t usDestPort;47 uint32_t ulDestAddr;48 char szUser[1024];46 unsigned char version; 47 unsigned char command; 48 uint16_t destPort; 49 uint32_t destAddress; 50 char user[1024]; 49 51 50 } socks4_header_t;52 }; 51 53 52 54 53 typedef enum55 enum IrcDialogueState 54 56 { 55 57 IRCDIA_REQUEST_SEND, 56 58 IRCDIA_CONNECTED, 57 } irc_dia_state;59 }; 58 60 59 61 class LogIrc; … … 65 67 IrcDialogue(Socket *socket, LogIrc * logirc); 66 68 ~IrcDialogue(); 67 ConsumeLevel incomingData(Message *msg); 68 ConsumeLevel outgoingData(Message *msg); 69 ConsumeLevel handleTimeout(Message *msg); 70 ConsumeLevel connectionLost(Message *msg); 71 ConsumeLevel connectionShutdown(Message *msg); 69 70 ConsumeLevel incomingData(Message * msg); 71 ConsumeLevel outgoingData(Message * msg); 72 ConsumeLevel handleTimeout(Message * msg); 73 ConsumeLevel connectionLost(Message * msg); 74 ConsumeLevel connectionShutdown(Message * msg); 72 75 73 void logIrc(uint32_t mask, const char *message);76 void logIrc(uint32_t mask, const char * message); 74 77 75 78 void sendNick(bool random); 76 79 void sendUser(); 77 80 void sendServerPass(); 81 78 82 protected: 79 80 83 void processBuffer(); 81 void processLine(string *line); 84 void processLine(const char * line, uint32_t lineLength); 85 86 void loggedOn(); 87 void processMessage(const char * origin, const char * target, const char * message); 88 82 89 bool m_Pinged; 90 83 91 LogIrc *m_LogIrc; 84 92 85 irc_dia_state m_State;93 IrcDialogueState m_State; 86 94 87 95 string m_NickName; nepenthes/branches/nepenthes-experimental/modules/log-irc/log-irc.conf.dist
r330 r546 21 21 nick "nep-noname"; 22 22 ident "nepenthes"; 23 userinfo "http://nepenthes. sf.net";23 userinfo "http://nepenthes.mwcollect.org/"; 24 24 usermodes "+i"; 25 25 }; nepenthes/branches/nepenthes-experimental/modules/log-irc/log-irc.cpp
r543 r546 6 6 * 7 7 * Copyright (C) 2005 Paul Baecher & Markus Koetter 8 * Copyright (C) 2005 Georg Wicherski 8 9 * 9 10 * This program is free software; you can redistribute it and/or … … 79 80 { 80 81 m_ModuleName = "log-irc"; 81 m_ModuleDescription = "log to irc using tor";82 m_ModuleDescription = "log to irc (optionally using tor)"; 82 83 m_ModuleRevision = "$Rev$"; 83 84 m_Nepenthes = nepenthes; … … 291 292 } 292 293 294 string LogIrc::getTorServer() 295 { 296 return m_TorServer; 297 } 298 299 string LogIrc::getIrcServer() 300 { 301 return m_IrcServer; 302 } 303 293 304 uint32_t LogIrc::getIrcIP() 294 305 { nepenthes/branches/nepenthes-experimental/modules/log-irc/log-irc.hpp
r378 r546 6 6 * 7 7 * Copyright (C) 2005 Paul Baecher & Markus Koetter 8 * Copyright (C) 2006 Georg Wicherski 8 9 * 9 10 * This program is free software; you can redistribute it and/or … … 58 59 public: 59 60 LogIrc(Nepenthes *); 60 // LogIrc(LogHandler *lm);61 61 ~LogIrc(); 62 62 Dialogue *createDialogue(Socket *socket); … … 64 64 bool Exit(); 65 65 66 bool dnsResolved(DNSResult *result);66 bool dnsResolved(DNSResult *result); 67 67 bool dnsFailure(DNSResult *result); 68 68 … … 84 84 string getIrcChannelPass(); 85 85 string getIrcUserModes(); 86 string getIrcPass(); //server password 86 string getIrcPass(); 87 88 string getTorServer(); 89 string getIrcServer(); 87 90 88 91
