Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

fish.cpp znc-git-recent

By: knarzling on Jun 7th, 2012  |  syntax: C++  |  size: 17.62 KB  |  views: 949  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. #include "znc/main.h"
  2. #include "znc/User.h"
  3. #include "znc/Nick.h"
  4. #include "znc/Modules.h"
  5. #include "znc/Chan.h"
  6. #include "znc/IRCNetwork.h"
  7.  
  8. #include <string.h>
  9. using std::pair;
  10. using std::map;
  11.  
  12. #include <netinet/in.h>
  13.  
  14. #include <openssl/opensslv.h>
  15. #include <openssl/blowfish.h>
  16.  
  17. #define REQUIRESSL      1
  18.  
  19. #if (OPENSSL_VERSION_NUMBER < 0x0090800f)
  20. #error "We require openssl >= 0.9.8"
  21. #endif
  22.  
  23. /*
  24.     Public Base64 conversion tables
  25. */
  26. unsigned char B64ABC[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  27. unsigned char b64buf[256];
  28.  
  29.  
  30. /*
  31.     void initb64();
  32.     Initializes the base64->base16 conversion tab.
  33.     Call this function once when your program starts.
  34.     and always after your B64 table has been changed.
  35. */
  36. void initb64(){
  37.     unsigned int i;
  38.     for (i=0; i<256; i++) b64buf[i]=0x00;
  39.     for (i=0; i<64; i++) b64buf[(B64ABC[i])]=i;
  40. }
  41.  
  42. /*
  43.    int b64toh(lpBase64String, lpDestinationBuffer);
  44.    Converts base64 string b to hexnumber d.
  45.    Returns size of hexnumber in bytes.
  46. */
  47. int b64toh(char *b, char *d){
  48.     int i,k,l;
  49.  
  50.     l=strlen(b);
  51.     if (l<2) return 0;
  52.     for (i=l-1;i>-1;i--){
  53.         if (b64buf[(unsigned char)(b[i])]==0) l--;
  54.         else break;
  55.     }
  56.  
  57.     if (l<2) return 0;
  58.     i=0, k=0;
  59.     while (1) {
  60.         i++;
  61.         if (k+1<l) d[i-1]=((b64buf[(unsigned char)(b[k])])<<2);
  62.         else break;
  63.         k++;
  64.         if (k<l) d[i-1]|=((b64buf[(unsigned char)(b[k])])>>4);
  65.         else break;
  66.         i++;
  67.         if (k+1<l) d[i-1]=((b64buf[(unsigned char)(b[k])])<<4);
  68.         else break;
  69.         k++;
  70.         if (k<l) d[i-1]|=((b64buf[(unsigned char)(b[k])])>>2);
  71.         else break;
  72.         i++;
  73.         if (k+1<l) d[i-1]=((b64buf[(unsigned char)(b[k])])<<6);
  74.         else break;
  75.         k++;
  76.         if (k<l) d[i-1]|=(b64buf[(unsigned char)(b[k])]);
  77.         else break;
  78.         k++;
  79.     }
  80.     return i-1;
  81. }
  82.  
  83. /*
  84.    int htob64(lpHexNumber, lpDestinationBuffer);
  85.    Converts hexnumber h (with length l bytes) to base64 string d.
  86.    Returns length of base64 string.
  87. */
  88. int htob64(char *h, char *d, unsigned int l){
  89.     unsigned int i,j,k;
  90.     unsigned char m,t;
  91.  
  92.     if (!l) return 0;
  93.     l<<=3;                              // no. bits
  94.     m=0x80;
  95.     for (i=0,j=0,k=0,t=0; i<l; i++){
  96.         if (h[(i>>3)]&m) t|=1;
  97.         j++;
  98.         if (!(m>>=1)) m=0x80;
  99.         if (!(j%6)) {
  100.             d[k]=B64ABC[t];
  101.             t&=0;
  102.             k++;
  103.         }
  104.         t<<=1;
  105.     }
  106.     m=5-(j%6);
  107.     t<<=m;
  108.     if (m) {
  109.         d[k]=B64ABC[t];
  110.         k++;
  111.     }
  112.     d[k]&=0;
  113.     return strlen(d);
  114. }
  115.  
  116. unsigned char B64[]="./0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  117.  
  118. const char *prime1080="FBE1022E23D213E8ACFA9AE8B9DFADA3EA6B7AC7A7B7E95AB5EB2DF858921FEADE95E6AC7BE7DE6ADBAB8A783E7AF7A7FA6A2B7BEB1E72EAE2B72F9FA2BFB2A2EFBEFAC868BADB3E828FA8BADFADA3E4CC1BE7E8AFE85E9698A783EB68FA07A77AB6AD7BEB618ACF9CA2897EB28A6189EFA07AB99A8A7FA9AE299EFA7BA66DEAFEFBEFBF0B7D8B";
  119.  
  120. int base64dec(char c)
  121. {
  122.     int i;
  123.  
  124.     for (i = 0; i < 64; i++)
  125.         if (B64[i] == c) return i;
  126.  
  127.     return 0;
  128. }
  129.  
  130. char *encrypts(char *key,char *str) {
  131.   char *result;
  132.   unsigned int length;
  133.   unsigned int left,right;
  134.   char *s,*d;
  135.   unsigned char *p;
  136.   BF_KEY bfkey;
  137.   int i;
  138.  
  139.   if(key==NULL||str==NULL) return NULL;
  140.  
  141.   length=strlen(str);
  142.   BF_set_key(&bfkey, strlen(key), (const unsigned char *)key);
  143.  
  144.   s=(char *)malloc(length+9);
  145.  
  146.   strncpy(s,str,length);
  147.   memset(s+length,0,9);
  148.  
  149.   result=(char *)malloc(((length%8==0) ? length/8*12 : 12+length/8*12)+1);
  150.  
  151.   p=(unsigned char *)s;
  152.   d=result;
  153.  
  154.   while(*p) {
  155.     BF_ecb_encrypt((const unsigned char *)p, (unsigned char *)p, &bfkey, BF_ENCRYPT);
  156.     left = ((*p++) << 24);
  157.     left += ((*p++) << 16);
  158.     left += ((*p++) << 8);
  159.     left += (*p++);
  160.     right = ((*p++) << 24);
  161.     right += ((*p++) << 16);
  162.     right += ((*p++) << 8);
  163.     right += (*p++);
  164.     for (i = 0; i < 6; i++) {
  165.         *d++=B64[right & 0x3f];
  166.         right = (right >> 6);
  167.     }
  168.  
  169.     for (i = 0; i < 6; i++) {
  170.         *d++=B64[left & 0x3f];
  171.         left = (left >> 6);
  172.     }
  173.   }
  174.   *d = '\0';
  175.  
  176.   memset(s,0,length+9);
  177.   free(s);
  178.   return result;
  179. }
  180.  
  181. char *decrypts(char *key, char *str) {
  182.   char *result;
  183.   unsigned int length;
  184.   unsigned int left,right;
  185.   int i;
  186.   char *d;
  187.   unsigned char *c;
  188.   BF_KEY bfkey;
  189.  
  190.   if(key==NULL||str==NULL) return NULL;
  191.  
  192.   length=strlen(str);
  193.   BF_set_key(&bfkey,strlen(key),(const unsigned char *)key);
  194.  
  195.   result=(char *)malloc((length/12*8)+1);
  196.   c=(unsigned char *)result;
  197.   d=str;
  198.   while(*d) {
  199.     right=0;
  200.     left=0;
  201.     for (i = 0; i < 6; i++) right |= (base64dec(*d++)) << (i * 6);
  202.         for (i = 0; i < 6; i++) left |= (base64dec(*d++)) << (i * 6);
  203.     right=htonl(right);
  204.     left=htonl(left);
  205.     memcpy(c,&left,4);
  206.     memcpy(c+4,&right,4);
  207.     BF_ecb_encrypt(c,c,&bfkey,BF_DECRYPT);
  208.     c+=8;
  209.   }
  210.   *c='\0';
  211.   return result;
  212. }
  213.  
  214. class CKeyExchangeTimer : public CTimer {
  215. public:
  216.         CKeyExchangeTimer(CModule* pModule)
  217.                     : CTimer(pModule, 5, 0, "KeyExchangeTimer", "Key exchange timer removes stale exchanges") {}
  218.  
  219. protected:
  220.         virtual void RunJob();
  221. };
  222.  
  223. class CFishMod : public CModule {
  224. public:
  225.         MODCONSTRUCTOR(CFishMod) {}
  226.         virtual ~CFishMod() {
  227.         }
  228.  
  229.         virtual EModRet OnPrivNotice(CNick& Nick, CString& sMessage) {
  230.                 CString command = sMessage.Token(0);
  231.                 CString sOtherPub_Key = sMessage.Token(1);
  232.  
  233.                 if (command.CaseCmp("DH1080_INIT") == 0 && !sOtherPub_Key.empty()) {
  234.                     CString sPriv_Key;
  235.                     CString sPub_Key;
  236.                     CString sSecretKey;
  237.  
  238.                     DH1080_gen(sPriv_Key, sPub_Key);
  239.                     if (!DH1080_comp(sPriv_Key, sOtherPub_Key, sSecretKey)) {
  240.                         PutModule("Error in DH1080 with " + Nick.GetNick() + ": " + sSecretKey);
  241.                         return CONTINUE;
  242.                     }
  243.                     PutModule("Received DH1080 public key from " + Nick.GetNick() + ", sending mine...");
  244.                     PutIRC("NOTICE " + Nick.GetNick() + " :DH1080_FINISH " + sPub_Key);
  245.                     SetNV(Nick.GetNick().AsLower(), sSecretKey);
  246.                     PutModule("Key for " + Nick.GetNick() + " successfully set.");
  247.                     return HALT;
  248.                 } else if (command.CaseCmp("DH1080_FINISH") == 0 && !sOtherPub_Key.empty()) {
  249.                     CString sPriv_Key;
  250.                     CString sSecretKey;
  251.  
  252.                     map<CString, pair<time_t, CString> >::iterator it = m_msKeyExchange.find(Nick.GetNick().AsLower());
  253.                     if (it == m_msKeyExchange.end()) {
  254.                         PutModule("Received unexpected DH1080_FINISH from " + Nick.GetNick() + ".");
  255.                     } else {
  256.                         sPriv_Key = it->second.second;
  257.                         if (DH1080_comp(sPriv_Key, sOtherPub_Key, sSecretKey)) {
  258.                                 SetNV(Nick.GetNick().AsLower(), sSecretKey);
  259.                                 PutModule("Key for " + Nick.GetNick() + " successfully set.");
  260.                                 m_msKeyExchange.erase(Nick.GetNick().AsLower());
  261.                         }
  262.                     }
  263.                     return HALT;
  264.                 } else {
  265.                         FilterIncoming(Nick.GetNick(), Nick, sMessage);
  266.                 }
  267.  
  268.                 return CONTINUE;
  269.         }
  270.  
  271.         virtual EModRet OnUserMsg(CString& sTarget, CString& sMessage) {
  272.                 MCString::iterator it = FindNV(sTarget.AsLower());
  273.  
  274.                 if (it != EndNV()) {
  275.                         CChan* pChan = m_pNetwork->FindChan(sTarget);
  276.                         if ((pChan) && (pChan->AutoClearChanBuffer())) {
  277.                                 pChan->AddBuffer(":" + m_pNetwork->GetIRCNick().GetNickMask() + " PRIVMSG " + sTarget + " :" + sMessage);
  278.                         }
  279.                         char * cMsg = encrypts((char *)it->second.c_str(), (char *)sMessage.c_str());
  280.  
  281.                         CString sMsg = "+OK " + CString(cMsg);
  282.                         PutIRC("PRIVMSG " + sTarget + " :" + sMsg);
  283.                         m_pNetwork->PutUser(":" + m_pNetwork->GetIRCNick().GetNickMask() + " PRIVMSG " + sTarget + " :" + sMessage, NULL, m_pClient);
  284.  
  285.                         free(cMsg);
  286.                         return HALTCORE;
  287.                 }
  288.  
  289.                 return CONTINUE;
  290.         }
  291.  
  292.         virtual EModRet OnUserAction(CString& sTarget, CString& sMessage) {
  293.                 MCString::iterator it = FindNV(sTarget.AsLower());
  294.  
  295.                 if (it != EndNV()) {
  296.                         CChan* pChan = m_pNetwork->FindChan(sTarget);
  297.                         if ((pChan) && (pChan->AutoClearChanBuffer())) {
  298.                                 pChan->AddBuffer(":" + m_pNetwork->GetIRCNick().GetNickMask() + " PRIVMSG " + sTarget + " :\001ACTION " + sMessage + "\001");
  299.                         }
  300.                         char * cMsg = encrypts((char *)it->second.c_str(), (char *)sMessage.c_str());
  301.  
  302.                         CString sMsg = "+OK " + CString(cMsg);
  303.                         PutIRC("PRIVMSG " + sTarget + " :\001ACTION " + sMsg + "\001");
  304.                         m_pNetwork->PutUser(":" + m_pNetwork->GetIRCNick().GetNickMask() + " PRIVMSG " + sTarget + " :\001ACTION " + sMessage + "\001", NULL, m_pClient);
  305.  
  306.                         free(cMsg);
  307.                         return HALTCORE;
  308.                 }
  309.  
  310.                 return CONTINUE;
  311.         }
  312.  
  313.         virtual EModRet OnUserNotice(CString& sTarget, CString& sMessage) {
  314.                 MCString::iterator it = FindNV(sTarget.AsLower());
  315.  
  316.                 if (it != EndNV()) {
  317.                         CChan* pChan = m_pNetwork->FindChan(sTarget);
  318.                         if ((pChan) && (pChan->AutoClearChanBuffer())) {
  319.                                 pChan->AddBuffer(":" + m_pNetwork->GetIRCNick().GetNickMask() + " NOTICE " + sTarget + " :" + sMessage);
  320.                         }
  321.                         char * cMsg = encrypts((char *)it->second.c_str(), (char *)sMessage.c_str());
  322.  
  323.                         CString sMsg = "+OK " + CString(cMsg);
  324.                         PutIRC("NOTICE " + sTarget + " :" + sMsg);
  325.                         m_pNetwork->PutUser(":" + m_pNetwork->GetIRCNick().GetNickMask() + " NOTICE " + sTarget + " :" + sMessage, NULL, m_pClient);
  326.  
  327.                         free(cMsg);
  328.                         return HALTCORE;
  329.                 }
  330.  
  331.                 return CONTINUE;
  332.  
  333.         }
  334.  
  335.         virtual EModRet OnUserTopic(CString& sChannel, CString& sTopic) {
  336.                 if (!sTopic.empty()) {
  337.                         MCString::iterator it = FindNV(sChannel.AsLower());
  338.                         if (it != EndNV()) {
  339.                                 char * cTopic = encrypts((char *)it->second.c_str(), (char *)sTopic.c_str());
  340.                                 sTopic = "+OK " + CString(cTopic);
  341.                                 free(cTopic);
  342.                         }
  343.                 }
  344.  
  345.                 return CONTINUE;
  346.         }
  347.  
  348.         virtual EModRet OnPrivMsg(CNick& Nick, CString& sMessage) {
  349.                 FilterIncoming(Nick.GetNick(), Nick, sMessage);
  350.                 return CONTINUE;
  351.         }
  352.  
  353.         virtual EModRet OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage) {
  354.                 FilterIncoming(Channel.GetName(), Nick, sMessage);
  355.                 return CONTINUE;
  356.         }
  357.  
  358.         virtual EModRet OnPrivAction(CNick& Nick, CString& sMessage) {
  359.                 FilterIncoming(Nick.GetNick(), Nick, sMessage);
  360.                 return CONTINUE;
  361.         }
  362.  
  363.         virtual EModRet OnChanAction(CNick& Nick, CChan& Channel, CString& sMessage) {
  364.                 FilterIncoming(Channel.GetName(), Nick, sMessage);
  365.                 return CONTINUE;
  366.         }
  367.        
  368.         virtual EModRet OnTopic(CNick& Nick, CChan& Channel, CString& sTopic) {
  369.                 FilterIncoming(Channel.GetName(), Nick, sTopic);
  370.                 return CONTINUE;
  371.         }
  372.  
  373.         virtual EModRet OnRaw(CString& sLine) {
  374.                 if (sLine.WildCmp(":* 332 *") && sLine.Token(1) == "332") {
  375.                         CChan* pChan = m_pNetwork->FindChan(sLine.Token(3));
  376.                         if (pChan) {
  377.                                 CNick Nick(sLine.Token(2));
  378.                                 CString sTopic = sLine.Token(4, true);
  379.                                 sTopic.LeftChomp();
  380.                                 FilterIncoming(pChan->GetName(), Nick, sTopic);
  381.                                 sLine = sLine.Token(0) + " " + sLine.Token(1) + " " + sLine.Token(2) + " " + pChan->GetName() + " :" + sTopic;
  382.                         }
  383.                 }
  384.                 return CONTINUE;
  385.         }
  386.  
  387.         void FilterIncoming(const CString& sTarget, CNick& Nick, CString& sMessage) {
  388.                 if (sMessage.Left(4) == "+OK " || sMessage.Left(5) == "mcps ") {
  389.                         MCString::iterator it = FindNV(sTarget.AsLower());
  390.  
  391.                         if (it != EndNV()) {
  392.                                 if (sMessage.Left(4) == "+OK ") {
  393.                                     sMessage.LeftChomp(4);
  394.                                 } else if (sMessage.Left(5) == "mcps ") {
  395.                                     sMessage.LeftChomp(5);
  396.                                 }
  397.  
  398.                                 unsigned int msg_len = strlen(sMessage.c_str());
  399.  
  400.                                 if ((strspn(sMessage.c_str(), (char *)B64) != msg_len) || msg_len < 12) {
  401.                                         return;
  402.                                 }
  403.  
  404.                                 unsigned int mark_broken_block = 0;
  405.  
  406.                                 if (msg_len != (msg_len/12)*12) {
  407.                                         msg_len = msg_len - (msg_len/12)*12;
  408.                                         sMessage.RightChomp(msg_len);
  409.                                         mark_broken_block = 1;
  410.                                 }
  411.  
  412.                                 char *cMsg = decrypts((char *)it->second.c_str(), (char *)sMessage.c_str());
  413.                                 sMessage = CString(cMsg);
  414.  
  415.                                 if (mark_broken_block) {
  416.                                         sMessage += "  \002&\002";
  417.                                 }
  418.  
  419.                                 free(cMsg);
  420.                         }
  421.                 }
  422.         }
  423.  
  424.         virtual void OnModCommand(const CString& sCommand) {
  425.                 CString sCmd = sCommand.Token(0);
  426.  
  427.                 if (sCmd.CaseCmp("DELKEY") == 0) {
  428.                         CString sTarget = sCommand.Token(1);
  429.  
  430.                         if (!sTarget.empty()) {
  431.                                 if (DelNV(sTarget.AsLower())) {
  432.                                         PutModule("Target [" + sTarget + "] deleted");
  433.                                 } else {
  434.                                         PutModule("Target [" + sTarget + "] not found");
  435.                                 }
  436.                         } else {
  437.                                 PutModule("Usage DelKey <#chan|Nick>");
  438.                         }
  439.                 } else if (sCmd.CaseCmp("SETKEY") == 0) {
  440.                         CString sTarget = sCommand.Token(1);
  441.                         CString sKey = sCommand.Token(2, true);
  442.  
  443.                         if (!sKey.empty()) {
  444.                                 SetNV(sTarget.AsLower(), sKey);
  445.                                 PutModule("Set encryption key for [" + sTarget + "] to [" + sKey + "]");
  446.                         } else {
  447.                                 PutModule("Usage: SetKey <#chan|Nick> <Key>");
  448.                         }
  449.                 } else if (sCmd.CaseCmp("SHOWKEY") == 0) {
  450.                         CString sTarget = sCommand.Token(1);
  451.  
  452.                         if (!sTarget.empty()) {
  453.                                 MCString::iterator it = FindNV(sTarget.AsLower());
  454.  
  455.                                 if (it != EndNV()) {
  456.                                         PutModule("Target key is " + it->second);
  457.                                 } else {
  458.                                         PutModule("Target not found.");
  459.                                 }
  460.                         } else {
  461.                                 PutModule("Usage ShowKey <#chan|Nick>");
  462.                         }
  463.                 } else if (sCmd.CaseCmp("LISTKEYS") == 0) {
  464.                         if (BeginNV() == EndNV()) {
  465.                                 PutModule("You have no encryption keys set.");
  466.                         } else {
  467.                                 CTable Table;
  468.                                 Table.AddColumn("Target");
  469.                                 Table.AddColumn("Key");
  470.  
  471.                                 for (MCString::iterator it = BeginNV(); it != EndNV(); it++) {
  472.                                         Table.AddRow();
  473.                                         Table.SetCell("Target", it->first);
  474.                                         Table.SetCell("Key", it->second);
  475.                                 }
  476.  
  477.                                 if (Table.size()) {
  478.                                         unsigned int uTableIdx = 0;
  479.                                         CString sLine;
  480.  
  481.                                         while (Table.GetLine(uTableIdx++, sLine)) {
  482.                                                 PutModule(sLine);
  483.                                         }
  484.                                 }
  485.                         }
  486.                 } else if (sCmd.CaseCmp("KEYX") == 0) {
  487.                         CString sTarget = sCommand.Token(1);
  488.  
  489.                         if (sTarget.empty()) {
  490.                             PutModule("You did not specify a target for the key exchange.");
  491.                         } else {
  492.                             map<CString, pair<time_t, CString> >::iterator it = m_msKeyExchange.find(sTarget.AsLower());
  493.                             if (it != m_msKeyExchange.end()) {
  494.                                 PutModule("Keyexchange with " + sTarget + " already in progress.");
  495.                             } else {
  496.                                 CString sPriv_Key;
  497.                                 CString sPub_Key;
  498.  
  499.                                 DH1080_gen(sPriv_Key, sPub_Key);
  500.                                 m_msKeyExchange.insert(make_pair(sTarget.AsLower(), make_pair(time(NULL), sPriv_Key)));
  501.                                 PutIRC("NOTICE " + sTarget + " :DH1080_INIT " + sPub_Key);
  502.                                 PutModule("Sent my DH1080 public key to " + sTarget + ", waiting for reply ...");
  503.                                 if (FindTimer("KeyExchangeTimer") == NULL) {
  504.                                     AddTimer(new CKeyExchangeTimer(this));
  505.                                 }
  506.                             }
  507.                         }
  508.                 } else if (sCmd.CaseCmp("HELP") == 0) {
  509.                         PutModule("Try: SetKey <target> <key>, DelKey <target>, ShowKey <target>, ListKeys, KeyX <target>");
  510.                 } else {
  511.                         PutModule("Unknown command, try 'Help'");
  512.                 }
  513.         }
  514.  
  515.         void DelStaleKeyExchanges(time_t iTime) {
  516.                 for (map<CString, pair<time_t, CString> >::const_iterator it = m_msKeyExchange.begin(); it != m_msKeyExchange.end(); it++) {
  517.                     if (iTime - 5 >= it->second.first) {
  518.                         PutModule("Keyexchange with " + it->first + " did expire before completition.");
  519.                         m_msKeyExchange.erase(it->first);
  520.                     }
  521.                 }
  522.                 if (m_msKeyExchange.size() <= 0) {
  523.                     RemTimer("KeyExchangeTimer");
  524.                 }
  525.         }
  526.  
  527. private:
  528.  
  529.         void DH1080_gen(CString& sPriv_Key, CString& sPub_Key) {
  530.                 sPriv_Key = "";
  531.                 sPub_Key = "";
  532.  
  533.                 unsigned char raw_buf[200];
  534.                 unsigned long len;
  535.                 unsigned char *a, *b;
  536.  
  537.                 DH *dh;
  538.                 BIGNUM *b_prime=NULL;
  539.                 BIGNUM *b_generator=NULL;
  540.  
  541.                 initb64();
  542.  
  543.                 dh=DH_new();
  544.  
  545.                 if (!BN_hex2bn(&b_prime, prime1080)) {
  546.                     return;
  547.                 }
  548.  
  549.                 if (!BN_dec2bn(&b_generator, "2")) {
  550.                     return;
  551.                 }
  552.  
  553.                 dh->p=b_prime;
  554.                 dh->g=b_generator;
  555.  
  556.                 if (!DH_generate_key(dh)) {
  557.                     return;
  558.                 }
  559.  
  560.                 len = BN_num_bytes(dh->priv_key);
  561.                 a = (unsigned char *)malloc(len);
  562.                 BN_bn2bin(dh->priv_key,a);
  563.  
  564.                 memset(raw_buf, 0, 200);
  565.                 htob64((char *)a, (char *)raw_buf, len);
  566.                 sPriv_Key = CString((char *)raw_buf);
  567.                 len=BN_num_bytes(dh->pub_key);
  568.                 b = (unsigned char *)malloc(len);
  569.                 BN_bn2bin(dh->pub_key,b);
  570.                 memset(raw_buf, 0, 200);
  571.                 htob64((char *)b, (char *)raw_buf, len);
  572.                 sPub_Key = CString((char *)raw_buf);
  573.                 DH_free(dh);
  574.                 free(a);
  575.                 free(b);
  576.         }
  577.  
  578.  
  579.         bool DH1080_comp(CString& sPriv_Key, CString& sOtherPub_Key, CString& sSecret_Key) {
  580.                 int len;
  581.                 unsigned char SHA256digest[32];
  582.                 char *key;
  583.                 BIGNUM *b_prime=NULL;
  584.                 BIGNUM *b_myPrivkey=NULL;
  585.                 BIGNUM *b_HisPubkey=NULL;
  586.                 BIGNUM *b_generator=NULL;
  587.                 DH *dh;
  588.                 CString sSHA256digest;
  589.                 unsigned char raw_buf[200];
  590.  
  591.                 if (!BN_hex2bn(&b_prime, prime1080)) {
  592.                     return false;
  593.                 }
  594.  
  595.                 if (!BN_dec2bn(&b_generator, "2")) {
  596.                     return false;
  597.                 }
  598.  
  599.                 dh=DH_new();
  600.                 dh->p=b_prime;
  601.                 dh->g=b_generator;
  602.  
  603.                 memset(raw_buf, 0, 200);
  604.                 len = b64toh((char *)sPriv_Key.c_str(), (char *)raw_buf);
  605.                 b_myPrivkey=BN_bin2bn(raw_buf, len, NULL);
  606.                 dh->priv_key=b_myPrivkey;
  607.  
  608.                 memset(raw_buf, 0, 200);
  609.                 len = b64toh((char *)sOtherPub_Key.c_str(), (char *)raw_buf);
  610.  
  611.                 b_HisPubkey=BN_bin2bn(raw_buf, len, NULL);
  612.  
  613.                 key=(char *)malloc(DH_size(dh));
  614.                 memset(key, 0, DH_size(dh));
  615.                 len=DH_compute_key((unsigned char *)key, b_HisPubkey, dh);
  616.                 if (len == -1) {
  617.                         // Bad pub key
  618.                         unsigned long err = ERR_get_error();
  619.                         DEBUG("** DH Error:" << ERR_error_string(err,NULL));
  620.                         DH_free(dh);
  621.                         BN_clear_free(b_HisPubkey);
  622.                         free(key);
  623.  
  624.                         sSecret_Key = CString(ERR_error_string(err,NULL)).Token(4,true,":");
  625.                         return false;
  626.                 }
  627.  
  628.                 SHA256_CTX c;
  629.                 SHA256_Init(&c);
  630.                 memset(SHA256digest, 0, 32);
  631.                 SHA256_Update(&c, key, len);
  632.                 SHA256_Final(SHA256digest, &c);
  633.                 memset(raw_buf, 0, 200);
  634.                 len = htob64((char *)SHA256digest, (char *)raw_buf, 32);
  635.                 sSecret_Key = "";
  636.                 sSecret_Key.append((char *)raw_buf, len);
  637.  
  638.                 DH_free(dh);
  639.                 BN_clear_free(b_HisPubkey);
  640.                 free(key);
  641.                 return true;
  642.         }
  643.  
  644.         map<CString, pair<time_t, CString> >    m_msKeyExchange;
  645.  
  646. };
  647.  
  648. void CKeyExchangeTimer::RunJob() {
  649.                 CFishMod *p = (CFishMod *)m_pModule;
  650.                 p->DelStaleKeyExchanges(time(NULL));
  651. }
  652.  
  653. MODULEDEFS(CFishMod, "FiSH encryption for channel/private messages")