tunnelconstructor.cpp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. #include "tunnelconstructor.h"
  2. #include "notepad.h"
  3. #include "randomstringgenerator.h"
  4. #include <algorithm>
  5. TunnelConstructor::TunnelConstructor()
  6. {
  7. lengthVariance_.inbound = 0;
  8. lengthVariance_.outbound = 0;
  9. }
  10. bool TunnelConstructor::setName(std::string name)
  11. {
  12. if (name.length() > 30)
  13. {
  14. name.erase(30);
  15. }
  16. const bool valid = std::all_of(name.begin(), name.end(), [](unsigned char c) {
  17. return std::isalnum(c) || c == '-' || c == '_' || c == '.';
  18. });
  19. if (!valid)
  20. {
  21. errorString_ = Notepad::SetterError::name(lang_);
  22. return false;
  23. }
  24. name_ = name;
  25. return true;
  26. }
  27. bool TunnelConstructor::setTunnelType(TunnelType type)
  28. {
  29. tunnelType_ = type;
  30. return true;
  31. }
  32. bool TunnelConstructor::setLength(int8_t inbound, int8_t outbound)
  33. {
  34. if (inbound < 0 or inbound > 8)
  35. {
  36. errorString_ = Notepad::SetterError::length(lang_);
  37. return false;
  38. }
  39. if (outbound < 0 or outbound > 8)
  40. {
  41. errorString_ = Notepad::SetterError::length(lang_);
  42. return false;
  43. }
  44. length_.inbound = inbound;
  45. length_.outbound = outbound;
  46. return true;
  47. }
  48. bool TunnelConstructor::setLengthVariance(int8_t inbound, int8_t outbound)
  49. {
  50. if (inbound > 3 or inbound < -3)
  51. {
  52. errorString_ = Notepad::SetterError::variance(lang_);
  53. return false;
  54. }
  55. if (outbound > 3 or outbound < -3)
  56. {
  57. errorString_ = Notepad::SetterError::variance(lang_);
  58. return false;
  59. }
  60. lengthVariance_.inbound = inbound;
  61. lengthVariance_.outbound = outbound;
  62. return true;
  63. }
  64. bool TunnelConstructor::setQuantity(int8_t inbound, int8_t outbound)
  65. {
  66. if (inbound > 16 or inbound < 1)
  67. {
  68. errorString_ = Notepad::SetterError::quantity(lang_);
  69. return false;
  70. }
  71. if (outbound > 16 or outbound < 1)
  72. {
  73. errorString_ = Notepad::SetterError::quantity(lang_);
  74. return false;
  75. }
  76. quantity_.inbound = inbound;
  77. quantity_.outbound = outbound;
  78. return true;
  79. }
  80. bool TunnelConstructor::setBlindedLeaseSet(bool isBlinded)
  81. {
  82. blinded_ = isBlinded;
  83. return true;
  84. }
  85. bool TunnelConstructor::setTransient(bool isTransient)
  86. {
  87. transient_ = isTransient;
  88. return true;
  89. }
  90. bool TunnelConstructor::setKeepAlive(int8_t interval)
  91. {
  92. if (interval < 0)
  93. {
  94. interval = 0;
  95. }
  96. keepAliveInterval_ = interval;
  97. return true;
  98. }
  99. bool TunnelConstructor::setComments(bool enabled)
  100. {
  101. comments_ = enabled;
  102. return true;
  103. }
  104. std::u8string TunnelConstructor::generate() const
  105. {
  106. std::u8string config;
  107. config += u8"[" + std::u8string{ name_.begin(), name_.end() } + u8"]\n";
  108. if (comments_)
  109. config += Notepad::ConfigComment::type(lang_, tunnelType_);
  110. const auto typeString = tunnelTypeToString(tunnelType_);
  111. config += u8"type = " + std::u8string{ typeString.begin(), typeString.end() } + u8"\n";
  112. if (isClientType(tunnelType_))
  113. {
  114. if (comments_)
  115. config += Notepad::ConfigComment::clientAddress(lang_);
  116. config += u8"address = LOCAL_INTERFACE_ADDRESS\n";
  117. if (comments_)
  118. config += Notepad::ConfigComment::clientPort(lang_);
  119. config += u8"port = LOCAL_INTERFACE_PORT\n";
  120. if (comments_)
  121. config += Notepad::ConfigComment::clientDestination(lang_);
  122. config += u8"destination = I2P_SERVER_ADDRESS\n";
  123. if (comments_)
  124. config += Notepad::ConfigComment::clientDestinationPort(lang_);
  125. config += u8"destinationport = I2P_SERVER_PORT\n";
  126. }
  127. else
  128. {
  129. if (comments_)
  130. config += Notepad::ConfigComment::serverAddress(lang_);
  131. config += u8"address = LOCAL_INTERFACE_ADDRESS\n";
  132. if (comments_)
  133. config += Notepad::ConfigComment::serverHost(lang_);
  134. config += u8"host = IP_ADDRESS_OF_APPLICATION\n";
  135. if (comments_)
  136. config += Notepad::ConfigComment::serverPort(lang_);
  137. config += u8"port = APPLICATION_PORT\n";
  138. if (comments_)
  139. config += Notepad::ConfigComment::serverInport(lang_);
  140. config += u8"inport = I2P_SERVER_PORT\n";
  141. }
  142. if (comments_)
  143. config += Notepad::ConfigComment::inbound(lang_);
  144. if (comments_)
  145. config += Notepad::ConfigComment::length(lang_);
  146. config += u8"inbound.length = " + std::u8string( reinterpret_cast<const char8_t*>(std::to_string(length_.inbound).c_str()) ) + u8"\n";
  147. if (comments_)
  148. config += Notepad::ConfigComment::quantity(lang_);
  149. config += u8"inbound.quantity = " + std::u8string( reinterpret_cast<const char8_t*>(std::to_string(quantity_.inbound).c_str()) ) + u8"\n";
  150. if (comments_)
  151. config += Notepad::ConfigComment::variance(lang_);
  152. config += u8"inbound.lengthVariance = " + std::u8string( reinterpret_cast<const char8_t*>(std::to_string(lengthVariance_.inbound).c_str()) ) + u8"\n";
  153. if (comments_)
  154. config += Notepad::ConfigComment::outbound(lang_);
  155. if (comments_)
  156. config += Notepad::ConfigComment::length(lang_);
  157. config += u8"outbound.length = " + std::u8string( reinterpret_cast<const char8_t*>(std::to_string(length_.outbound).c_str()) ) + u8"\n";
  158. if (comments_)
  159. config += Notepad::ConfigComment::quantity(lang_);
  160. config += u8"outbound.quantity = " + std::u8string( reinterpret_cast<const char8_t*>(std::to_string(quantity_.outbound).c_str()) ) + u8"\n";
  161. if (comments_)
  162. config += Notepad::ConfigComment::variance(lang_);
  163. config += u8"outbound.lengthVariance = " + std::u8string( reinterpret_cast<const char8_t*>(std::to_string(lengthVariance_.outbound).c_str()) ) + u8"\n";
  164. if (isClientType(tunnelType_))
  165. {
  166. if (keepAliveInterval_)
  167. {
  168. if (comments_)
  169. config += Notepad::ConfigComment::clientKeepAlive(lang_);
  170. config += u8"keepaliveinterval = " + std::u8string( reinterpret_cast<const char8_t*>(std::to_string(keepAliveInterval_).c_str()) ) + u8"\n";
  171. }
  172. }
  173. else if (blinded_) // blinded server
  174. {
  175. if (comments_)
  176. config += Notepad::ConfigComment::serverBlinded(lang_);
  177. config += u8"signaturetype = 11\n"
  178. "i2cp.leaseSetType = 5\n";
  179. }
  180. if (transient_)
  181. {
  182. if (comments_)
  183. config += Notepad::ConfigComment::keysTransient(lang_);
  184. config += u8"keys = transient-" + RandomStringGenerator::getU8string(5) + u8"\n";
  185. }
  186. else
  187. {
  188. std::string name(name_);
  189. std::transform(name.begin(), name.end(), name.begin(),
  190. [](unsigned char c) { return std::tolower(c); });
  191. if (comments_)
  192. config += Notepad::ConfigComment::keys(lang_);
  193. config += u8"keys = " + std::u8string( reinterpret_cast<const char8_t*>(name.c_str()) ) + u8"-" + RandomStringGenerator::getU8string(5) + u8".dat\n";
  194. }
  195. if (comments_)
  196. config += Notepad::ConfigComment::footer(lang_, blinded_);
  197. return config;
  198. }
  199. std::string TunnelConstructor::tunnelTypeToString(TunnelType type)
  200. {
  201. switch(type)
  202. {
  203. case TunnelType::TcpClient: {
  204. return "client";
  205. }
  206. case TunnelType::TcpServer: {
  207. return "server";
  208. }
  209. case TunnelType::UdpClient: {
  210. return "udpclient";
  211. }
  212. case TunnelType::UdpServer: {
  213. return "udpserver";
  214. }
  215. case TunnelType::HttpServer: {
  216. return "http";
  217. }
  218. case TunnelType::IrcServer: {
  219. return "irc";
  220. }
  221. case TunnelType::SocksProxy: {
  222. return "socks";
  223. }
  224. case TunnelType::HttpProxy: {
  225. return "httpproxy";
  226. }
  227. }
  228. return "undefined(bug)";
  229. }
  230. TunnelType TunnelConstructor::stringToTunnelType(const std::string &type)
  231. {
  232. if (type == "client")
  233. {
  234. return TunnelType::TcpClient;
  235. }
  236. else if (type == "server")
  237. {
  238. return TunnelType::TcpServer;
  239. }
  240. else if (type == "udpclient")
  241. {
  242. return TunnelType::UdpClient;
  243. }
  244. else if (type == "udpserver")
  245. {
  246. return TunnelType::UdpServer;
  247. }
  248. else if (type == "http")
  249. {
  250. return TunnelType::HttpServer;
  251. }
  252. else if (type == "irc")
  253. {
  254. return TunnelType::IrcServer;
  255. }
  256. else if (type == "socks")
  257. {
  258. return TunnelType::SocksProxy;
  259. }
  260. else if (type == "httpproxy")
  261. {
  262. return TunnelType::HttpProxy;
  263. }
  264. return TunnelType::TcpClient;
  265. }
  266. bool TunnelConstructor::isClientType(TunnelType type)
  267. {
  268. switch(type)
  269. {
  270. case TunnelType::TcpClient: {
  271. return true;
  272. }
  273. case TunnelType::UdpClient: {
  274. return true;
  275. }
  276. default : {
  277. return false;
  278. }
  279. }
  280. }