eduvpn-client 4.3.0__2-py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (951) hide show
  1. eduvpn/__init__.py +1 -0
  2. eduvpn/__main__.py +4 -0
  3. eduvpn/app.py +628 -0
  4. eduvpn/cli.py +720 -0
  5. eduvpn/config.py +68 -0
  6. eduvpn/connection.py +244 -0
  7. eduvpn/data/share/applications/org.eduvpn.client.desktop +10 -0
  8. eduvpn/data/share/applications/org.letsconnect-vpn.client.desktop +10 -0
  9. eduvpn/data/share/eduvpn/builder/mainwindow.ui +1811 -0
  10. eduvpn/data/share/eduvpn/country_codes.json +1001 -0
  11. eduvpn/data/share/eduvpn/eduvpn.png +0 -0
  12. eduvpn/data/share/eduvpn/images/app-icon-circle.svg +16 -0
  13. eduvpn/data/share/eduvpn/images/app-icon-circle@2x.png +0 -0
  14. eduvpn/data/share/eduvpn/images/app-icon-circle@3x.png +0 -0
  15. eduvpn/data/share/eduvpn/images/back.png +0 -0
  16. eduvpn/data/share/eduvpn/images/back@2x.png +0 -0
  17. eduvpn/data/share/eduvpn/images/back@3x.png +0 -0
  18. eduvpn/data/share/eduvpn/images/chevron-down.png +0 -0
  19. eduvpn/data/share/eduvpn/images/chevron-down@2x.png +0 -0
  20. eduvpn/data/share/eduvpn/images/chevron-down@3x.png +0 -0
  21. eduvpn/data/share/eduvpn/images/chevron-right-white.png +0 -0
  22. eduvpn/data/share/eduvpn/images/chevron-right-white@2x.png +0 -0
  23. eduvpn/data/share/eduvpn/images/chevron-right-white@3x.png +0 -0
  24. eduvpn/data/share/eduvpn/images/chevron-right.png +0 -0
  25. eduvpn/data/share/eduvpn/images/chevron-right@2x.png +0 -0
  26. eduvpn/data/share/eduvpn/images/chevron-right@3x.png +0 -0
  27. eduvpn/data/share/eduvpn/images/cross.png +0 -0
  28. eduvpn/data/share/eduvpn/images/cross@2x.png +0 -0
  29. eduvpn/data/share/eduvpn/images/cross@3x.png +0 -0
  30. eduvpn/data/share/eduvpn/images/desktop-connected.png +0 -0
  31. eduvpn/data/share/eduvpn/images/desktop-connected@2x.png +0 -0
  32. eduvpn/data/share/eduvpn/images/desktop-connected@3x.png +0 -0
  33. eduvpn/data/share/eduvpn/images/desktop-connecting.png +0 -0
  34. eduvpn/data/share/eduvpn/images/desktop-connecting@2x.png +0 -0
  35. eduvpn/data/share/eduvpn/images/desktop-connecting@3x.png +0 -0
  36. eduvpn/data/share/eduvpn/images/desktop-default.png +0 -0
  37. eduvpn/data/share/eduvpn/images/desktop-default@2x.png +0 -0
  38. eduvpn/data/share/eduvpn/images/desktop-default@3x.png +0 -0
  39. eduvpn/data/share/eduvpn/images/desktop-not-connected.png +0 -0
  40. eduvpn/data/share/eduvpn/images/desktop-not-connected@2x.png +0 -0
  41. eduvpn/data/share/eduvpn/images/desktop-not-connected@3x.png +0 -0
  42. eduvpn/data/share/eduvpn/images/earth-icon-dark.png +0 -0
  43. eduvpn/data/share/eduvpn/images/earth-icon-dark@2x.png +0 -0
  44. eduvpn/data/share/eduvpn/images/earth-icon-dark@3x.png +0 -0
  45. eduvpn/data/share/eduvpn/images/earth-icon.png +0 -0
  46. eduvpn/data/share/eduvpn/images/earth-icon@2x.png +0 -0
  47. eduvpn/data/share/eduvpn/images/earth-icon@3x.png +0 -0
  48. eduvpn/data/share/eduvpn/images/edu-vpn-logo-dark.png +0 -0
  49. eduvpn/data/share/eduvpn/images/edu-vpn-logo-dark@2x.png +0 -0
  50. eduvpn/data/share/eduvpn/images/edu-vpn-logo-dark@3x.png +0 -0
  51. eduvpn/data/share/eduvpn/images/edu-vpn-logo.png +0 -0
  52. eduvpn/data/share/eduvpn/images/edu-vpn-logo@2x.png +0 -0
  53. eduvpn/data/share/eduvpn/images/edu-vpn-logo@3x.png +0 -0
  54. eduvpn/data/share/eduvpn/images/flags/png/AD@1,5x.png +0 -0
  55. eduvpn/data/share/eduvpn/images/flags/png/AD@2x.png +0 -0
  56. eduvpn/data/share/eduvpn/images/flags/png/AD@3x.png +0 -0
  57. eduvpn/data/share/eduvpn/images/flags/png/AE@1,5x.png +0 -0
  58. eduvpn/data/share/eduvpn/images/flags/png/AE@2x.png +0 -0
  59. eduvpn/data/share/eduvpn/images/flags/png/AE@3x.png +0 -0
  60. eduvpn/data/share/eduvpn/images/flags/png/AF@1,5x.png +0 -0
  61. eduvpn/data/share/eduvpn/images/flags/png/AF@2x.png +0 -0
  62. eduvpn/data/share/eduvpn/images/flags/png/AF@3x.png +0 -0
  63. eduvpn/data/share/eduvpn/images/flags/png/AG@1,5x.png +0 -0
  64. eduvpn/data/share/eduvpn/images/flags/png/AG@2x.png +0 -0
  65. eduvpn/data/share/eduvpn/images/flags/png/AG@3x.png +0 -0
  66. eduvpn/data/share/eduvpn/images/flags/png/AI@1,5x.png +0 -0
  67. eduvpn/data/share/eduvpn/images/flags/png/AI@2x.png +0 -0
  68. eduvpn/data/share/eduvpn/images/flags/png/AI@3x.png +0 -0
  69. eduvpn/data/share/eduvpn/images/flags/png/AL@1,5x.png +0 -0
  70. eduvpn/data/share/eduvpn/images/flags/png/AL@2x.png +0 -0
  71. eduvpn/data/share/eduvpn/images/flags/png/AL@3x.png +0 -0
  72. eduvpn/data/share/eduvpn/images/flags/png/AM@1,5x.png +0 -0
  73. eduvpn/data/share/eduvpn/images/flags/png/AM@2x.png +0 -0
  74. eduvpn/data/share/eduvpn/images/flags/png/AM@3x.png +0 -0
  75. eduvpn/data/share/eduvpn/images/flags/png/AO@1,5x.png +0 -0
  76. eduvpn/data/share/eduvpn/images/flags/png/AO@2x.png +0 -0
  77. eduvpn/data/share/eduvpn/images/flags/png/AO@3x.png +0 -0
  78. eduvpn/data/share/eduvpn/images/flags/png/AQ@1,5x.png +0 -0
  79. eduvpn/data/share/eduvpn/images/flags/png/AQ@2x.png +0 -0
  80. eduvpn/data/share/eduvpn/images/flags/png/AQ@3x.png +0 -0
  81. eduvpn/data/share/eduvpn/images/flags/png/AR@1,5x.png +0 -0
  82. eduvpn/data/share/eduvpn/images/flags/png/AR@2x.png +0 -0
  83. eduvpn/data/share/eduvpn/images/flags/png/AR@3x.png +0 -0
  84. eduvpn/data/share/eduvpn/images/flags/png/AS@1,5x.png +0 -0
  85. eduvpn/data/share/eduvpn/images/flags/png/AS@2x.png +0 -0
  86. eduvpn/data/share/eduvpn/images/flags/png/AS@3x.png +0 -0
  87. eduvpn/data/share/eduvpn/images/flags/png/AT@1,5x.png +0 -0
  88. eduvpn/data/share/eduvpn/images/flags/png/AT@2x.png +0 -0
  89. eduvpn/data/share/eduvpn/images/flags/png/AT@3x.png +0 -0
  90. eduvpn/data/share/eduvpn/images/flags/png/AU@1,5x.png +0 -0
  91. eduvpn/data/share/eduvpn/images/flags/png/AU@2x.png +0 -0
  92. eduvpn/data/share/eduvpn/images/flags/png/AU@3x.png +0 -0
  93. eduvpn/data/share/eduvpn/images/flags/png/AW@1,5x.png +0 -0
  94. eduvpn/data/share/eduvpn/images/flags/png/AW@2x.png +0 -0
  95. eduvpn/data/share/eduvpn/images/flags/png/AW@3x.png +0 -0
  96. eduvpn/data/share/eduvpn/images/flags/png/AX@1,5x.png +0 -0
  97. eduvpn/data/share/eduvpn/images/flags/png/AX@2x.png +0 -0
  98. eduvpn/data/share/eduvpn/images/flags/png/AX@3x.png +0 -0
  99. eduvpn/data/share/eduvpn/images/flags/png/AZ@1,5x.png +0 -0
  100. eduvpn/data/share/eduvpn/images/flags/png/AZ@2x.png +0 -0
  101. eduvpn/data/share/eduvpn/images/flags/png/AZ@3x.png +0 -0
  102. eduvpn/data/share/eduvpn/images/flags/png/Artsakh@1,5x.png +0 -0
  103. eduvpn/data/share/eduvpn/images/flags/png/Artsakh@2x.png +0 -0
  104. eduvpn/data/share/eduvpn/images/flags/png/Artsakh@3x.png +0 -0
  105. eduvpn/data/share/eduvpn/images/flags/png/BA@1,5x.png +0 -0
  106. eduvpn/data/share/eduvpn/images/flags/png/BA@2x.png +0 -0
  107. eduvpn/data/share/eduvpn/images/flags/png/BA@3x.png +0 -0
  108. eduvpn/data/share/eduvpn/images/flags/png/BB@1,5x.png +0 -0
  109. eduvpn/data/share/eduvpn/images/flags/png/BB@2x.png +0 -0
  110. eduvpn/data/share/eduvpn/images/flags/png/BB@3x.png +0 -0
  111. eduvpn/data/share/eduvpn/images/flags/png/BD@1,5x.png +0 -0
  112. eduvpn/data/share/eduvpn/images/flags/png/BD@2x.png +0 -0
  113. eduvpn/data/share/eduvpn/images/flags/png/BD@3x.png +0 -0
  114. eduvpn/data/share/eduvpn/images/flags/png/BE@1,5x.png +0 -0
  115. eduvpn/data/share/eduvpn/images/flags/png/BE@2x.png +0 -0
  116. eduvpn/data/share/eduvpn/images/flags/png/BE@3x.png +0 -0
  117. eduvpn/data/share/eduvpn/images/flags/png/BF@1,5x.png +0 -0
  118. eduvpn/data/share/eduvpn/images/flags/png/BF@2x.png +0 -0
  119. eduvpn/data/share/eduvpn/images/flags/png/BF@3x.png +0 -0
  120. eduvpn/data/share/eduvpn/images/flags/png/BG@1,5x.png +0 -0
  121. eduvpn/data/share/eduvpn/images/flags/png/BG@2x.png +0 -0
  122. eduvpn/data/share/eduvpn/images/flags/png/BG@3x.png +0 -0
  123. eduvpn/data/share/eduvpn/images/flags/png/BH@1,5x.png +0 -0
  124. eduvpn/data/share/eduvpn/images/flags/png/BH@2x.png +0 -0
  125. eduvpn/data/share/eduvpn/images/flags/png/BH@3x.png +0 -0
  126. eduvpn/data/share/eduvpn/images/flags/png/BI@1,5x.png +0 -0
  127. eduvpn/data/share/eduvpn/images/flags/png/BI@2x.png +0 -0
  128. eduvpn/data/share/eduvpn/images/flags/png/BI@3x.png +0 -0
  129. eduvpn/data/share/eduvpn/images/flags/png/BJ@1,5x.png +0 -0
  130. eduvpn/data/share/eduvpn/images/flags/png/BJ@2x.png +0 -0
  131. eduvpn/data/share/eduvpn/images/flags/png/BJ@3x.png +0 -0
  132. eduvpn/data/share/eduvpn/images/flags/png/BM@1,5x.png +0 -0
  133. eduvpn/data/share/eduvpn/images/flags/png/BM@2x.png +0 -0
  134. eduvpn/data/share/eduvpn/images/flags/png/BM@3x.png +0 -0
  135. eduvpn/data/share/eduvpn/images/flags/png/BN@1,5x.png +0 -0
  136. eduvpn/data/share/eduvpn/images/flags/png/BN@2x.png +0 -0
  137. eduvpn/data/share/eduvpn/images/flags/png/BN@3x.png +0 -0
  138. eduvpn/data/share/eduvpn/images/flags/png/BO@1,5x.png +0 -0
  139. eduvpn/data/share/eduvpn/images/flags/png/BO@2x.png +0 -0
  140. eduvpn/data/share/eduvpn/images/flags/png/BO@3x.png +0 -0
  141. eduvpn/data/share/eduvpn/images/flags/png/BQ-BO@1,5x.png +0 -0
  142. eduvpn/data/share/eduvpn/images/flags/png/BQ-BO@2x.png +0 -0
  143. eduvpn/data/share/eduvpn/images/flags/png/BQ-BO@3x.png +0 -0
  144. eduvpn/data/share/eduvpn/images/flags/png/BQ-SA@1,5x.png +0 -0
  145. eduvpn/data/share/eduvpn/images/flags/png/BQ-SA@2x.png +0 -0
  146. eduvpn/data/share/eduvpn/images/flags/png/BQ-SA@3x.png +0 -0
  147. eduvpn/data/share/eduvpn/images/flags/png/BQ-SE@1,5x.png +0 -0
  148. eduvpn/data/share/eduvpn/images/flags/png/BQ-SE@2x.png +0 -0
  149. eduvpn/data/share/eduvpn/images/flags/png/BQ-SE@3x.png +0 -0
  150. eduvpn/data/share/eduvpn/images/flags/png/BR@1,5x.png +0 -0
  151. eduvpn/data/share/eduvpn/images/flags/png/BR@2x.png +0 -0
  152. eduvpn/data/share/eduvpn/images/flags/png/BR@3x.png +0 -0
  153. eduvpn/data/share/eduvpn/images/flags/png/BS@1,5x.png +0 -0
  154. eduvpn/data/share/eduvpn/images/flags/png/BS@2x.png +0 -0
  155. eduvpn/data/share/eduvpn/images/flags/png/BS@3x.png +0 -0
  156. eduvpn/data/share/eduvpn/images/flags/png/BT@1,5x.png +0 -0
  157. eduvpn/data/share/eduvpn/images/flags/png/BT@2x.png +0 -0
  158. eduvpn/data/share/eduvpn/images/flags/png/BT@3x.png +0 -0
  159. eduvpn/data/share/eduvpn/images/flags/png/BW@1,5x.png +0 -0
  160. eduvpn/data/share/eduvpn/images/flags/png/BW@2x.png +0 -0
  161. eduvpn/data/share/eduvpn/images/flags/png/BW@3x.png +0 -0
  162. eduvpn/data/share/eduvpn/images/flags/png/BY@1,5x.png +0 -0
  163. eduvpn/data/share/eduvpn/images/flags/png/BY@2x.png +0 -0
  164. eduvpn/data/share/eduvpn/images/flags/png/BY@3x.png +0 -0
  165. eduvpn/data/share/eduvpn/images/flags/png/BZ@1,5x.png +0 -0
  166. eduvpn/data/share/eduvpn/images/flags/png/BZ@2x.png +0 -0
  167. eduvpn/data/share/eduvpn/images/flags/png/BZ@3x.png +0 -0
  168. eduvpn/data/share/eduvpn/images/flags/png/CA-AB@1,5x.png +0 -0
  169. eduvpn/data/share/eduvpn/images/flags/png/CA-AB@2x.png +0 -0
  170. eduvpn/data/share/eduvpn/images/flags/png/CA-AB@3x.png +0 -0
  171. eduvpn/data/share/eduvpn/images/flags/png/CA-BC@1,5x.png +0 -0
  172. eduvpn/data/share/eduvpn/images/flags/png/CA-BC@2x.png +0 -0
  173. eduvpn/data/share/eduvpn/images/flags/png/CA-BC@3x.png +0 -0
  174. eduvpn/data/share/eduvpn/images/flags/png/CA-MB@1,5x.png +0 -0
  175. eduvpn/data/share/eduvpn/images/flags/png/CA-MB@2x.png +0 -0
  176. eduvpn/data/share/eduvpn/images/flags/png/CA-MB@3x.png +0 -0
  177. eduvpn/data/share/eduvpn/images/flags/png/CA-NB@1,5x.png +0 -0
  178. eduvpn/data/share/eduvpn/images/flags/png/CA-NB@2x.png +0 -0
  179. eduvpn/data/share/eduvpn/images/flags/png/CA-NB@3x.png +0 -0
  180. eduvpn/data/share/eduvpn/images/flags/png/CA-NL@1,5x.png +0 -0
  181. eduvpn/data/share/eduvpn/images/flags/png/CA-NL@2x.png +0 -0
  182. eduvpn/data/share/eduvpn/images/flags/png/CA-NL@3x.png +0 -0
  183. eduvpn/data/share/eduvpn/images/flags/png/CA-NS@1,5x.png +0 -0
  184. eduvpn/data/share/eduvpn/images/flags/png/CA-NS@2x.png +0 -0
  185. eduvpn/data/share/eduvpn/images/flags/png/CA-NS@3x.png +0 -0
  186. eduvpn/data/share/eduvpn/images/flags/png/CA-NT@1,5x.png +0 -0
  187. eduvpn/data/share/eduvpn/images/flags/png/CA-NT@2x.png +0 -0
  188. eduvpn/data/share/eduvpn/images/flags/png/CA-NT@3x.png +0 -0
  189. eduvpn/data/share/eduvpn/images/flags/png/CA-NU@1,5x.png +0 -0
  190. eduvpn/data/share/eduvpn/images/flags/png/CA-NU@2x.png +0 -0
  191. eduvpn/data/share/eduvpn/images/flags/png/CA-NU@3x.png +0 -0
  192. eduvpn/data/share/eduvpn/images/flags/png/CA-ON@1,5x.png +0 -0
  193. eduvpn/data/share/eduvpn/images/flags/png/CA-ON@2x.png +0 -0
  194. eduvpn/data/share/eduvpn/images/flags/png/CA-ON@3x.png +0 -0
  195. eduvpn/data/share/eduvpn/images/flags/png/CA-PE@1,5x.png +0 -0
  196. eduvpn/data/share/eduvpn/images/flags/png/CA-PE@2x.png +0 -0
  197. eduvpn/data/share/eduvpn/images/flags/png/CA-PE@3x.png +0 -0
  198. eduvpn/data/share/eduvpn/images/flags/png/CA-QC@1,5x.png +0 -0
  199. eduvpn/data/share/eduvpn/images/flags/png/CA-QC@2x.png +0 -0
  200. eduvpn/data/share/eduvpn/images/flags/png/CA-QC@3x.png +0 -0
  201. eduvpn/data/share/eduvpn/images/flags/png/CA-SK@1,5x.png +0 -0
  202. eduvpn/data/share/eduvpn/images/flags/png/CA-SK@2x.png +0 -0
  203. eduvpn/data/share/eduvpn/images/flags/png/CA-SK@3x.png +0 -0
  204. eduvpn/data/share/eduvpn/images/flags/png/CA-YT@1,5x.png +0 -0
  205. eduvpn/data/share/eduvpn/images/flags/png/CA-YT@2x.png +0 -0
  206. eduvpn/data/share/eduvpn/images/flags/png/CA-YT@3x.png +0 -0
  207. eduvpn/data/share/eduvpn/images/flags/png/CA@1,5x.png +0 -0
  208. eduvpn/data/share/eduvpn/images/flags/png/CA@2x.png +0 -0
  209. eduvpn/data/share/eduvpn/images/flags/png/CA@3x.png +0 -0
  210. eduvpn/data/share/eduvpn/images/flags/png/CC@1,5x.png +0 -0
  211. eduvpn/data/share/eduvpn/images/flags/png/CC@2x.png +0 -0
  212. eduvpn/data/share/eduvpn/images/flags/png/CC@3x.png +0 -0
  213. eduvpn/data/share/eduvpn/images/flags/png/CD@1,5x.png +0 -0
  214. eduvpn/data/share/eduvpn/images/flags/png/CD@2x.png +0 -0
  215. eduvpn/data/share/eduvpn/images/flags/png/CD@3x.png +0 -0
  216. eduvpn/data/share/eduvpn/images/flags/png/CF@1,5x.png +0 -0
  217. eduvpn/data/share/eduvpn/images/flags/png/CF@2x.png +0 -0
  218. eduvpn/data/share/eduvpn/images/flags/png/CF@3x.png +0 -0
  219. eduvpn/data/share/eduvpn/images/flags/png/CG@1,5x.png +0 -0
  220. eduvpn/data/share/eduvpn/images/flags/png/CG@2x.png +0 -0
  221. eduvpn/data/share/eduvpn/images/flags/png/CG@3x.png +0 -0
  222. eduvpn/data/share/eduvpn/images/flags/png/CH@1,5x.png +0 -0
  223. eduvpn/data/share/eduvpn/images/flags/png/CH@2x.png +0 -0
  224. eduvpn/data/share/eduvpn/images/flags/png/CH@3x.png +0 -0
  225. eduvpn/data/share/eduvpn/images/flags/png/CI@1,5x.png +0 -0
  226. eduvpn/data/share/eduvpn/images/flags/png/CI@2x.png +0 -0
  227. eduvpn/data/share/eduvpn/images/flags/png/CI@3x.png +0 -0
  228. eduvpn/data/share/eduvpn/images/flags/png/CK@1,5x.png +0 -0
  229. eduvpn/data/share/eduvpn/images/flags/png/CK@2x.png +0 -0
  230. eduvpn/data/share/eduvpn/images/flags/png/CK@3x.png +0 -0
  231. eduvpn/data/share/eduvpn/images/flags/png/CL@1,5x.png +0 -0
  232. eduvpn/data/share/eduvpn/images/flags/png/CL@2x.png +0 -0
  233. eduvpn/data/share/eduvpn/images/flags/png/CL@3x.png +0 -0
  234. eduvpn/data/share/eduvpn/images/flags/png/CM@1,5x.png +0 -0
  235. eduvpn/data/share/eduvpn/images/flags/png/CM@2x.png +0 -0
  236. eduvpn/data/share/eduvpn/images/flags/png/CM@3x.png +0 -0
  237. eduvpn/data/share/eduvpn/images/flags/png/CN@1,5x.png +0 -0
  238. eduvpn/data/share/eduvpn/images/flags/png/CN@2x.png +0 -0
  239. eduvpn/data/share/eduvpn/images/flags/png/CN@3x.png +0 -0
  240. eduvpn/data/share/eduvpn/images/flags/png/CO@1,5x.png +0 -0
  241. eduvpn/data/share/eduvpn/images/flags/png/CO@2x.png +0 -0
  242. eduvpn/data/share/eduvpn/images/flags/png/CO@3x.png +0 -0
  243. eduvpn/data/share/eduvpn/images/flags/png/CR@1,5x.png +0 -0
  244. eduvpn/data/share/eduvpn/images/flags/png/CR@2x.png +0 -0
  245. eduvpn/data/share/eduvpn/images/flags/png/CR@3x.png +0 -0
  246. eduvpn/data/share/eduvpn/images/flags/png/CU@1,5x.png +0 -0
  247. eduvpn/data/share/eduvpn/images/flags/png/CU@2x.png +0 -0
  248. eduvpn/data/share/eduvpn/images/flags/png/CU@3x.png +0 -0
  249. eduvpn/data/share/eduvpn/images/flags/png/CV@1,5x.png +0 -0
  250. eduvpn/data/share/eduvpn/images/flags/png/CV@2x.png +0 -0
  251. eduvpn/data/share/eduvpn/images/flags/png/CV@3x.png +0 -0
  252. eduvpn/data/share/eduvpn/images/flags/png/CW@1,5x.png +0 -0
  253. eduvpn/data/share/eduvpn/images/flags/png/CW@2x.png +0 -0
  254. eduvpn/data/share/eduvpn/images/flags/png/CW@3x.png +0 -0
  255. eduvpn/data/share/eduvpn/images/flags/png/CX@1,5x.png +0 -0
  256. eduvpn/data/share/eduvpn/images/flags/png/CX@2x.png +0 -0
  257. eduvpn/data/share/eduvpn/images/flags/png/CX@3x.png +0 -0
  258. eduvpn/data/share/eduvpn/images/flags/png/CY@1,5x.png +0 -0
  259. eduvpn/data/share/eduvpn/images/flags/png/CY@2x.png +0 -0
  260. eduvpn/data/share/eduvpn/images/flags/png/CY@3x.png +0 -0
  261. eduvpn/data/share/eduvpn/images/flags/png/CZ@1,5x.png +0 -0
  262. eduvpn/data/share/eduvpn/images/flags/png/CZ@2x.png +0 -0
  263. eduvpn/data/share/eduvpn/images/flags/png/CZ@3x.png +0 -0
  264. eduvpn/data/share/eduvpn/images/flags/png/Chechnya@1,5x.png +0 -0
  265. eduvpn/data/share/eduvpn/images/flags/png/Chechnya@2x.png +0 -0
  266. eduvpn/data/share/eduvpn/images/flags/png/Chechnya@3x.png +0 -0
  267. eduvpn/data/share/eduvpn/images/flags/png/DE@1,5x.png +0 -0
  268. eduvpn/data/share/eduvpn/images/flags/png/DE@2x.png +0 -0
  269. eduvpn/data/share/eduvpn/images/flags/png/DE@3x.png +0 -0
  270. eduvpn/data/share/eduvpn/images/flags/png/DJ@1,5x.png +0 -0
  271. eduvpn/data/share/eduvpn/images/flags/png/DJ@2x.png +0 -0
  272. eduvpn/data/share/eduvpn/images/flags/png/DJ@3x.png +0 -0
  273. eduvpn/data/share/eduvpn/images/flags/png/DK@1,5x.png +0 -0
  274. eduvpn/data/share/eduvpn/images/flags/png/DK@2x.png +0 -0
  275. eduvpn/data/share/eduvpn/images/flags/png/DK@3x.png +0 -0
  276. eduvpn/data/share/eduvpn/images/flags/png/DM@1,5x.png +0 -0
  277. eduvpn/data/share/eduvpn/images/flags/png/DM@2x.png +0 -0
  278. eduvpn/data/share/eduvpn/images/flags/png/DM@3x.png +0 -0
  279. eduvpn/data/share/eduvpn/images/flags/png/DO@1,5x.png +0 -0
  280. eduvpn/data/share/eduvpn/images/flags/png/DO@2x.png +0 -0
  281. eduvpn/data/share/eduvpn/images/flags/png/DO@3x.png +0 -0
  282. eduvpn/data/share/eduvpn/images/flags/png/DZ@1,5x.png +0 -0
  283. eduvpn/data/share/eduvpn/images/flags/png/DZ@2x.png +0 -0
  284. eduvpn/data/share/eduvpn/images/flags/png/DZ@3x.png +0 -0
  285. eduvpn/data/share/eduvpn/images/flags/png/EC@1,5x.png +0 -0
  286. eduvpn/data/share/eduvpn/images/flags/png/EC@2x.png +0 -0
  287. eduvpn/data/share/eduvpn/images/flags/png/EC@3x.png +0 -0
  288. eduvpn/data/share/eduvpn/images/flags/png/EE@1,5x.png +0 -0
  289. eduvpn/data/share/eduvpn/images/flags/png/EE@2x.png +0 -0
  290. eduvpn/data/share/eduvpn/images/flags/png/EE@3x.png +0 -0
  291. eduvpn/data/share/eduvpn/images/flags/png/EG@1,5x.png +0 -0
  292. eduvpn/data/share/eduvpn/images/flags/png/EG@2x.png +0 -0
  293. eduvpn/data/share/eduvpn/images/flags/png/EG@3x.png +0 -0
  294. eduvpn/data/share/eduvpn/images/flags/png/EH@1,5x.png +0 -0
  295. eduvpn/data/share/eduvpn/images/flags/png/EH@2x.png +0 -0
  296. eduvpn/data/share/eduvpn/images/flags/png/EH@3x.png +0 -0
  297. eduvpn/data/share/eduvpn/images/flags/png/ER@1,5x.png +0 -0
  298. eduvpn/data/share/eduvpn/images/flags/png/ER@2x.png +0 -0
  299. eduvpn/data/share/eduvpn/images/flags/png/ER@3x.png +0 -0
  300. eduvpn/data/share/eduvpn/images/flags/png/ES-CT@1,5x.png +0 -0
  301. eduvpn/data/share/eduvpn/images/flags/png/ES-CT@2x.png +0 -0
  302. eduvpn/data/share/eduvpn/images/flags/png/ES-CT@3x.png +0 -0
  303. eduvpn/data/share/eduvpn/images/flags/png/ES@1,5x.png +0 -0
  304. eduvpn/data/share/eduvpn/images/flags/png/ES@2x.png +0 -0
  305. eduvpn/data/share/eduvpn/images/flags/png/ES@3x.png +0 -0
  306. eduvpn/data/share/eduvpn/images/flags/png/ET@1,5x.png +0 -0
  307. eduvpn/data/share/eduvpn/images/flags/png/ET@2x.png +0 -0
  308. eduvpn/data/share/eduvpn/images/flags/png/ET@3x.png +0 -0
  309. eduvpn/data/share/eduvpn/images/flags/png/EU@1,5x.png +0 -0
  310. eduvpn/data/share/eduvpn/images/flags/png/EU@2x.png +0 -0
  311. eduvpn/data/share/eduvpn/images/flags/png/EU@3x.png +0 -0
  312. eduvpn/data/share/eduvpn/images/flags/png/England-Symbol@1,5x.png +0 -0
  313. eduvpn/data/share/eduvpn/images/flags/png/England-Symbol@2x.png +0 -0
  314. eduvpn/data/share/eduvpn/images/flags/png/England-Symbol@3x.png +0 -0
  315. eduvpn/data/share/eduvpn/images/flags/png/FI@1,5x.png +0 -0
  316. eduvpn/data/share/eduvpn/images/flags/png/FI@2x.png +0 -0
  317. eduvpn/data/share/eduvpn/images/flags/png/FI@3x.png +0 -0
  318. eduvpn/data/share/eduvpn/images/flags/png/FJ@1,5x.png +0 -0
  319. eduvpn/data/share/eduvpn/images/flags/png/FJ@2x.png +0 -0
  320. eduvpn/data/share/eduvpn/images/flags/png/FJ@3x.png +0 -0
  321. eduvpn/data/share/eduvpn/images/flags/png/FK@1,5x.png +0 -0
  322. eduvpn/data/share/eduvpn/images/flags/png/FK@2x.png +0 -0
  323. eduvpn/data/share/eduvpn/images/flags/png/FK@3x.png +0 -0
  324. eduvpn/data/share/eduvpn/images/flags/png/FM@1,5x.png +0 -0
  325. eduvpn/data/share/eduvpn/images/flags/png/FM@2x.png +0 -0
  326. eduvpn/data/share/eduvpn/images/flags/png/FM@3x.png +0 -0
  327. eduvpn/data/share/eduvpn/images/flags/png/FO@1,5x.png +0 -0
  328. eduvpn/data/share/eduvpn/images/flags/png/FO@2x.png +0 -0
  329. eduvpn/data/share/eduvpn/images/flags/png/FO@3x.png +0 -0
  330. eduvpn/data/share/eduvpn/images/flags/png/FR-MQ@1,5x.png +0 -0
  331. eduvpn/data/share/eduvpn/images/flags/png/FR-MQ@2x.png +0 -0
  332. eduvpn/data/share/eduvpn/images/flags/png/FR-MQ@3x.png +0 -0
  333. eduvpn/data/share/eduvpn/images/flags/png/FR-TF@1,5x.png +0 -0
  334. eduvpn/data/share/eduvpn/images/flags/png/FR-TF@2x.png +0 -0
  335. eduvpn/data/share/eduvpn/images/flags/png/FR-TF@3x.png +0 -0
  336. eduvpn/data/share/eduvpn/images/flags/png/FR-YT@1,5x.png +0 -0
  337. eduvpn/data/share/eduvpn/images/flags/png/FR-YT@2x.png +0 -0
  338. eduvpn/data/share/eduvpn/images/flags/png/FR-YT@3x.png +0 -0
  339. eduvpn/data/share/eduvpn/images/flags/png/FR@1,5x.png +0 -0
  340. eduvpn/data/share/eduvpn/images/flags/png/FR@2x.png +0 -0
  341. eduvpn/data/share/eduvpn/images/flags/png/FR@3x.png +0 -0
  342. eduvpn/data/share/eduvpn/images/flags/png/France-Symbol@1,5x.png +0 -0
  343. eduvpn/data/share/eduvpn/images/flags/png/France-Symbol@2x.png +0 -0
  344. eduvpn/data/share/eduvpn/images/flags/png/France-Symbol@3x.png +0 -0
  345. eduvpn/data/share/eduvpn/images/flags/png/GA@1,5x.png +0 -0
  346. eduvpn/data/share/eduvpn/images/flags/png/GA@2x.png +0 -0
  347. eduvpn/data/share/eduvpn/images/flags/png/GA@3x.png +0 -0
  348. eduvpn/data/share/eduvpn/images/flags/png/GB-ENG@1,5x.png +0 -0
  349. eduvpn/data/share/eduvpn/images/flags/png/GB-ENG@2x.png +0 -0
  350. eduvpn/data/share/eduvpn/images/flags/png/GB-ENG@3x.png +0 -0
  351. eduvpn/data/share/eduvpn/images/flags/png/GB-SCT@1,5x.png +0 -0
  352. eduvpn/data/share/eduvpn/images/flags/png/GB-SCT@2x.png +0 -0
  353. eduvpn/data/share/eduvpn/images/flags/png/GB-SCT@3x.png +0 -0
  354. eduvpn/data/share/eduvpn/images/flags/png/GB-Symbol@1,5x.png +0 -0
  355. eduvpn/data/share/eduvpn/images/flags/png/GB-Symbol@2x.png +0 -0
  356. eduvpn/data/share/eduvpn/images/flags/png/GB-Symbol@3x.png +0 -0
  357. eduvpn/data/share/eduvpn/images/flags/png/GB-WLS@1,5x.png +0 -0
  358. eduvpn/data/share/eduvpn/images/flags/png/GB-WLS@2x.png +0 -0
  359. eduvpn/data/share/eduvpn/images/flags/png/GB-WLS@3x.png +0 -0
  360. eduvpn/data/share/eduvpn/images/flags/png/GB@1,5x.png +0 -0
  361. eduvpn/data/share/eduvpn/images/flags/png/GB@2x.png +0 -0
  362. eduvpn/data/share/eduvpn/images/flags/png/GB@3x.png +0 -0
  363. eduvpn/data/share/eduvpn/images/flags/png/GD@1,5x.png +0 -0
  364. eduvpn/data/share/eduvpn/images/flags/png/GD@2x.png +0 -0
  365. eduvpn/data/share/eduvpn/images/flags/png/GD@3x.png +0 -0
  366. eduvpn/data/share/eduvpn/images/flags/png/GE-AB@1,5x.png +0 -0
  367. eduvpn/data/share/eduvpn/images/flags/png/GE-AB@2x.png +0 -0
  368. eduvpn/data/share/eduvpn/images/flags/png/GE-AB@3x.png +0 -0
  369. eduvpn/data/share/eduvpn/images/flags/png/GE@1,5x.png +0 -0
  370. eduvpn/data/share/eduvpn/images/flags/png/GE@2x.png +0 -0
  371. eduvpn/data/share/eduvpn/images/flags/png/GE@3x.png +0 -0
  372. eduvpn/data/share/eduvpn/images/flags/png/GG@1,5x.png +0 -0
  373. eduvpn/data/share/eduvpn/images/flags/png/GG@2x.png +0 -0
  374. eduvpn/data/share/eduvpn/images/flags/png/GG@3x.png +0 -0
  375. eduvpn/data/share/eduvpn/images/flags/png/GH@1,5x.png +0 -0
  376. eduvpn/data/share/eduvpn/images/flags/png/GH@2x.png +0 -0
  377. eduvpn/data/share/eduvpn/images/flags/png/GH@3x.png +0 -0
  378. eduvpn/data/share/eduvpn/images/flags/png/GI@1,5x.png +0 -0
  379. eduvpn/data/share/eduvpn/images/flags/png/GI@2x.png +0 -0
  380. eduvpn/data/share/eduvpn/images/flags/png/GI@3x.png +0 -0
  381. eduvpn/data/share/eduvpn/images/flags/png/GL@1,5x.png +0 -0
  382. eduvpn/data/share/eduvpn/images/flags/png/GL@2x.png +0 -0
  383. eduvpn/data/share/eduvpn/images/flags/png/GL@3x.png +0 -0
  384. eduvpn/data/share/eduvpn/images/flags/png/GM@1,5x.png +0 -0
  385. eduvpn/data/share/eduvpn/images/flags/png/GM@2x.png +0 -0
  386. eduvpn/data/share/eduvpn/images/flags/png/GM@3x.png +0 -0
  387. eduvpn/data/share/eduvpn/images/flags/png/GN@1,5x.png +0 -0
  388. eduvpn/data/share/eduvpn/images/flags/png/GN@2x.png +0 -0
  389. eduvpn/data/share/eduvpn/images/flags/png/GN@3x.png +0 -0
  390. eduvpn/data/share/eduvpn/images/flags/png/GQ@1,5x.png +0 -0
  391. eduvpn/data/share/eduvpn/images/flags/png/GQ@2x.png +0 -0
  392. eduvpn/data/share/eduvpn/images/flags/png/GQ@3x.png +0 -0
  393. eduvpn/data/share/eduvpn/images/flags/png/GR@1,5x.png +0 -0
  394. eduvpn/data/share/eduvpn/images/flags/png/GR@2x.png +0 -0
  395. eduvpn/data/share/eduvpn/images/flags/png/GR@3x.png +0 -0
  396. eduvpn/data/share/eduvpn/images/flags/png/GS@1,5x.png +0 -0
  397. eduvpn/data/share/eduvpn/images/flags/png/GS@2x.png +0 -0
  398. eduvpn/data/share/eduvpn/images/flags/png/GS@3x.png +0 -0
  399. eduvpn/data/share/eduvpn/images/flags/png/GT@1,5x.png +0 -0
  400. eduvpn/data/share/eduvpn/images/flags/png/GT@2x.png +0 -0
  401. eduvpn/data/share/eduvpn/images/flags/png/GT@3x.png +0 -0
  402. eduvpn/data/share/eduvpn/images/flags/png/GU@1,5x.png +0 -0
  403. eduvpn/data/share/eduvpn/images/flags/png/GU@2x.png +0 -0
  404. eduvpn/data/share/eduvpn/images/flags/png/GU@3x.png +0 -0
  405. eduvpn/data/share/eduvpn/images/flags/png/GW@1,5x.png +0 -0
  406. eduvpn/data/share/eduvpn/images/flags/png/GW@2x.png +0 -0
  407. eduvpn/data/share/eduvpn/images/flags/png/GW@3x.png +0 -0
  408. eduvpn/data/share/eduvpn/images/flags/png/GY@1,5x.png +0 -0
  409. eduvpn/data/share/eduvpn/images/flags/png/GY@2x.png +0 -0
  410. eduvpn/data/share/eduvpn/images/flags/png/GY@3x.png +0 -0
  411. eduvpn/data/share/eduvpn/images/flags/png/HK@1,5x.png +0 -0
  412. eduvpn/data/share/eduvpn/images/flags/png/HK@2x.png +0 -0
  413. eduvpn/data/share/eduvpn/images/flags/png/HK@3x.png +0 -0
  414. eduvpn/data/share/eduvpn/images/flags/png/HN@1,5x.png +0 -0
  415. eduvpn/data/share/eduvpn/images/flags/png/HN@2x.png +0 -0
  416. eduvpn/data/share/eduvpn/images/flags/png/HN@3x.png +0 -0
  417. eduvpn/data/share/eduvpn/images/flags/png/HR@1,5x.png +0 -0
  418. eduvpn/data/share/eduvpn/images/flags/png/HR@2x.png +0 -0
  419. eduvpn/data/share/eduvpn/images/flags/png/HR@3x.png +0 -0
  420. eduvpn/data/share/eduvpn/images/flags/png/HT@1,5x.png +0 -0
  421. eduvpn/data/share/eduvpn/images/flags/png/HT@2x.png +0 -0
  422. eduvpn/data/share/eduvpn/images/flags/png/HT@3x.png +0 -0
  423. eduvpn/data/share/eduvpn/images/flags/png/HU@1,5x.png +0 -0
  424. eduvpn/data/share/eduvpn/images/flags/png/HU@2x.png +0 -0
  425. eduvpn/data/share/eduvpn/images/flags/png/HU@3x.png +0 -0
  426. eduvpn/data/share/eduvpn/images/flags/png/ID@1,5x.png +0 -0
  427. eduvpn/data/share/eduvpn/images/flags/png/ID@2x.png +0 -0
  428. eduvpn/data/share/eduvpn/images/flags/png/ID@3x.png +0 -0
  429. eduvpn/data/share/eduvpn/images/flags/png/IE@1,5x.png +0 -0
  430. eduvpn/data/share/eduvpn/images/flags/png/IE@2x.png +0 -0
  431. eduvpn/data/share/eduvpn/images/flags/png/IE@3x.png +0 -0
  432. eduvpn/data/share/eduvpn/images/flags/png/IL@1,5x.png +0 -0
  433. eduvpn/data/share/eduvpn/images/flags/png/IL@2x.png +0 -0
  434. eduvpn/data/share/eduvpn/images/flags/png/IL@3x.png +0 -0
  435. eduvpn/data/share/eduvpn/images/flags/png/IM@1,5x.png +0 -0
  436. eduvpn/data/share/eduvpn/images/flags/png/IM@2x.png +0 -0
  437. eduvpn/data/share/eduvpn/images/flags/png/IM@3x.png +0 -0
  438. eduvpn/data/share/eduvpn/images/flags/png/IN@1,5x.png +0 -0
  439. eduvpn/data/share/eduvpn/images/flags/png/IN@2x.png +0 -0
  440. eduvpn/data/share/eduvpn/images/flags/png/IN@3x.png +0 -0
  441. eduvpn/data/share/eduvpn/images/flags/png/IO@1,5x.png +0 -0
  442. eduvpn/data/share/eduvpn/images/flags/png/IO@2x.png +0 -0
  443. eduvpn/data/share/eduvpn/images/flags/png/IO@3x.png +0 -0
  444. eduvpn/data/share/eduvpn/images/flags/png/IQ@1,5x.png +0 -0
  445. eduvpn/data/share/eduvpn/images/flags/png/IQ@2x.png +0 -0
  446. eduvpn/data/share/eduvpn/images/flags/png/IQ@3x.png +0 -0
  447. eduvpn/data/share/eduvpn/images/flags/png/IR@1,5x.png +0 -0
  448. eduvpn/data/share/eduvpn/images/flags/png/IR@2x.png +0 -0
  449. eduvpn/data/share/eduvpn/images/flags/png/IR@3x.png +0 -0
  450. eduvpn/data/share/eduvpn/images/flags/png/IS@1,5x.png +0 -0
  451. eduvpn/data/share/eduvpn/images/flags/png/IS@2x.png +0 -0
  452. eduvpn/data/share/eduvpn/images/flags/png/IS@3x.png +0 -0
  453. eduvpn/data/share/eduvpn/images/flags/png/IT@1,5x.png +0 -0
  454. eduvpn/data/share/eduvpn/images/flags/png/IT@2x.png +0 -0
  455. eduvpn/data/share/eduvpn/images/flags/png/IT@3x.png +0 -0
  456. eduvpn/data/share/eduvpn/images/flags/png/JE@1,5x.png +0 -0
  457. eduvpn/data/share/eduvpn/images/flags/png/JE@2x.png +0 -0
  458. eduvpn/data/share/eduvpn/images/flags/png/JE@3x.png +0 -0
  459. eduvpn/data/share/eduvpn/images/flags/png/JM@1,5x.png +0 -0
  460. eduvpn/data/share/eduvpn/images/flags/png/JM@2x.png +0 -0
  461. eduvpn/data/share/eduvpn/images/flags/png/JM@3x.png +0 -0
  462. eduvpn/data/share/eduvpn/images/flags/png/JO@1,5x.png +0 -0
  463. eduvpn/data/share/eduvpn/images/flags/png/JO@2x.png +0 -0
  464. eduvpn/data/share/eduvpn/images/flags/png/JO@3x.png +0 -0
  465. eduvpn/data/share/eduvpn/images/flags/png/JP@1,5x.png +0 -0
  466. eduvpn/data/share/eduvpn/images/flags/png/JP@2x.png +0 -0
  467. eduvpn/data/share/eduvpn/images/flags/png/JP@3x.png +0 -0
  468. eduvpn/data/share/eduvpn/images/flags/png/KE@1,5x.png +0 -0
  469. eduvpn/data/share/eduvpn/images/flags/png/KE@2x.png +0 -0
  470. eduvpn/data/share/eduvpn/images/flags/png/KE@3x.png +0 -0
  471. eduvpn/data/share/eduvpn/images/flags/png/KG@1,5x.png +0 -0
  472. eduvpn/data/share/eduvpn/images/flags/png/KG@2x.png +0 -0
  473. eduvpn/data/share/eduvpn/images/flags/png/KG@3x.png +0 -0
  474. eduvpn/data/share/eduvpn/images/flags/png/KH@1,5x.png +0 -0
  475. eduvpn/data/share/eduvpn/images/flags/png/KH@2x.png +0 -0
  476. eduvpn/data/share/eduvpn/images/flags/png/KH@3x.png +0 -0
  477. eduvpn/data/share/eduvpn/images/flags/png/KI@1,5x.png +0 -0
  478. eduvpn/data/share/eduvpn/images/flags/png/KI@2x.png +0 -0
  479. eduvpn/data/share/eduvpn/images/flags/png/KI@3x.png +0 -0
  480. eduvpn/data/share/eduvpn/images/flags/png/KM@1,5x.png +0 -0
  481. eduvpn/data/share/eduvpn/images/flags/png/KM@2x.png +0 -0
  482. eduvpn/data/share/eduvpn/images/flags/png/KM@3x.png +0 -0
  483. eduvpn/data/share/eduvpn/images/flags/png/KN@1,5x.png +0 -0
  484. eduvpn/data/share/eduvpn/images/flags/png/KN@2x.png +0 -0
  485. eduvpn/data/share/eduvpn/images/flags/png/KN@3x.png +0 -0
  486. eduvpn/data/share/eduvpn/images/flags/png/KP@1,5x.png +0 -0
  487. eduvpn/data/share/eduvpn/images/flags/png/KP@2x.png +0 -0
  488. eduvpn/data/share/eduvpn/images/flags/png/KP@3x.png +0 -0
  489. eduvpn/data/share/eduvpn/images/flags/png/KR@1,5x.png +0 -0
  490. eduvpn/data/share/eduvpn/images/flags/png/KR@2x.png +0 -0
  491. eduvpn/data/share/eduvpn/images/flags/png/KR@3x.png +0 -0
  492. eduvpn/data/share/eduvpn/images/flags/png/KW@1,5x.png +0 -0
  493. eduvpn/data/share/eduvpn/images/flags/png/KW@2x.png +0 -0
  494. eduvpn/data/share/eduvpn/images/flags/png/KW@3x.png +0 -0
  495. eduvpn/data/share/eduvpn/images/flags/png/KY@1,5x.png +0 -0
  496. eduvpn/data/share/eduvpn/images/flags/png/KY@2x.png +0 -0
  497. eduvpn/data/share/eduvpn/images/flags/png/KY@3x.png +0 -0
  498. eduvpn/data/share/eduvpn/images/flags/png/KZ@1,5x.png +0 -0
  499. eduvpn/data/share/eduvpn/images/flags/png/KZ@2x.png +0 -0
  500. eduvpn/data/share/eduvpn/images/flags/png/KZ@3x.png +0 -0
  501. eduvpn/data/share/eduvpn/images/flags/png/Kurdistan@1,5x.png +0 -0
  502. eduvpn/data/share/eduvpn/images/flags/png/Kurdistan@2x.png +0 -0
  503. eduvpn/data/share/eduvpn/images/flags/png/Kurdistan@3x.png +0 -0
  504. eduvpn/data/share/eduvpn/images/flags/png/LA@1,5x.png +0 -0
  505. eduvpn/data/share/eduvpn/images/flags/png/LA@2x.png +0 -0
  506. eduvpn/data/share/eduvpn/images/flags/png/LA@3x.png +0 -0
  507. eduvpn/data/share/eduvpn/images/flags/png/LB@1,5x.png +0 -0
  508. eduvpn/data/share/eduvpn/images/flags/png/LB@2x.png +0 -0
  509. eduvpn/data/share/eduvpn/images/flags/png/LB@3x.png +0 -0
  510. eduvpn/data/share/eduvpn/images/flags/png/LC@1,5x.png +0 -0
  511. eduvpn/data/share/eduvpn/images/flags/png/LC@2x.png +0 -0
  512. eduvpn/data/share/eduvpn/images/flags/png/LC@3x.png +0 -0
  513. eduvpn/data/share/eduvpn/images/flags/png/LI@1,5x.png +0 -0
  514. eduvpn/data/share/eduvpn/images/flags/png/LI@2x.png +0 -0
  515. eduvpn/data/share/eduvpn/images/flags/png/LI@3x.png +0 -0
  516. eduvpn/data/share/eduvpn/images/flags/png/LK@1,5x.png +0 -0
  517. eduvpn/data/share/eduvpn/images/flags/png/LK@2x.png +0 -0
  518. eduvpn/data/share/eduvpn/images/flags/png/LK@3x.png +0 -0
  519. eduvpn/data/share/eduvpn/images/flags/png/LR@1,5x.png +0 -0
  520. eduvpn/data/share/eduvpn/images/flags/png/LR@2x.png +0 -0
  521. eduvpn/data/share/eduvpn/images/flags/png/LR@3x.png +0 -0
  522. eduvpn/data/share/eduvpn/images/flags/png/LS@1,5x.png +0 -0
  523. eduvpn/data/share/eduvpn/images/flags/png/LS@2x.png +0 -0
  524. eduvpn/data/share/eduvpn/images/flags/png/LS@3x.png +0 -0
  525. eduvpn/data/share/eduvpn/images/flags/png/LT@1,5x.png +0 -0
  526. eduvpn/data/share/eduvpn/images/flags/png/LT@2x.png +0 -0
  527. eduvpn/data/share/eduvpn/images/flags/png/LT@3x.png +0 -0
  528. eduvpn/data/share/eduvpn/images/flags/png/LU@1,5x.png +0 -0
  529. eduvpn/data/share/eduvpn/images/flags/png/LU@2x.png +0 -0
  530. eduvpn/data/share/eduvpn/images/flags/png/LU@3x.png +0 -0
  531. eduvpn/data/share/eduvpn/images/flags/png/LV@1,5x.png +0 -0
  532. eduvpn/data/share/eduvpn/images/flags/png/LV@2x.png +0 -0
  533. eduvpn/data/share/eduvpn/images/flags/png/LV@3x.png +0 -0
  534. eduvpn/data/share/eduvpn/images/flags/png/LY@1,5x.png +0 -0
  535. eduvpn/data/share/eduvpn/images/flags/png/LY@2x.png +0 -0
  536. eduvpn/data/share/eduvpn/images/flags/png/LY@3x.png +0 -0
  537. eduvpn/data/share/eduvpn/images/flags/png/MA@1,5x.png +0 -0
  538. eduvpn/data/share/eduvpn/images/flags/png/MA@2x.png +0 -0
  539. eduvpn/data/share/eduvpn/images/flags/png/MA@3x.png +0 -0
  540. eduvpn/data/share/eduvpn/images/flags/png/MC@1,5x.png +0 -0
  541. eduvpn/data/share/eduvpn/images/flags/png/MC@2x.png +0 -0
  542. eduvpn/data/share/eduvpn/images/flags/png/MC@3x.png +0 -0
  543. eduvpn/data/share/eduvpn/images/flags/png/MD@1,5x.png +0 -0
  544. eduvpn/data/share/eduvpn/images/flags/png/MD@2x.png +0 -0
  545. eduvpn/data/share/eduvpn/images/flags/png/MD@3x.png +0 -0
  546. eduvpn/data/share/eduvpn/images/flags/png/ME@1,5x.png +0 -0
  547. eduvpn/data/share/eduvpn/images/flags/png/ME@2x.png +0 -0
  548. eduvpn/data/share/eduvpn/images/flags/png/ME@3x.png +0 -0
  549. eduvpn/data/share/eduvpn/images/flags/png/MG@1,5x.png +0 -0
  550. eduvpn/data/share/eduvpn/images/flags/png/MG@2x.png +0 -0
  551. eduvpn/data/share/eduvpn/images/flags/png/MG@3x.png +0 -0
  552. eduvpn/data/share/eduvpn/images/flags/png/MH@1,5x.png +0 -0
  553. eduvpn/data/share/eduvpn/images/flags/png/MH@2x.png +0 -0
  554. eduvpn/data/share/eduvpn/images/flags/png/MH@3x.png +0 -0
  555. eduvpn/data/share/eduvpn/images/flags/png/MK@1,5x.png +0 -0
  556. eduvpn/data/share/eduvpn/images/flags/png/MK@2x.png +0 -0
  557. eduvpn/data/share/eduvpn/images/flags/png/MK@3x.png +0 -0
  558. eduvpn/data/share/eduvpn/images/flags/png/ML@1,5x.png +0 -0
  559. eduvpn/data/share/eduvpn/images/flags/png/ML@2x.png +0 -0
  560. eduvpn/data/share/eduvpn/images/flags/png/ML@3x.png +0 -0
  561. eduvpn/data/share/eduvpn/images/flags/png/MM@1,5x.png +0 -0
  562. eduvpn/data/share/eduvpn/images/flags/png/MM@2x.png +0 -0
  563. eduvpn/data/share/eduvpn/images/flags/png/MM@3x.png +0 -0
  564. eduvpn/data/share/eduvpn/images/flags/png/MN@1,5x.png +0 -0
  565. eduvpn/data/share/eduvpn/images/flags/png/MN@2x.png +0 -0
  566. eduvpn/data/share/eduvpn/images/flags/png/MN@3x.png +0 -0
  567. eduvpn/data/share/eduvpn/images/flags/png/MO@1,5x.png +0 -0
  568. eduvpn/data/share/eduvpn/images/flags/png/MO@2x.png +0 -0
  569. eduvpn/data/share/eduvpn/images/flags/png/MO@3x.png +0 -0
  570. eduvpn/data/share/eduvpn/images/flags/png/MP@1,5x.png +0 -0
  571. eduvpn/data/share/eduvpn/images/flags/png/MP@2x.png +0 -0
  572. eduvpn/data/share/eduvpn/images/flags/png/MP@3x.png +0 -0
  573. eduvpn/data/share/eduvpn/images/flags/png/MR@1,5x.png +0 -0
  574. eduvpn/data/share/eduvpn/images/flags/png/MR@2x.png +0 -0
  575. eduvpn/data/share/eduvpn/images/flags/png/MR@3x.png +0 -0
  576. eduvpn/data/share/eduvpn/images/flags/png/MT@1,5x.png +0 -0
  577. eduvpn/data/share/eduvpn/images/flags/png/MT@2x.png +0 -0
  578. eduvpn/data/share/eduvpn/images/flags/png/MT@3x.png +0 -0
  579. eduvpn/data/share/eduvpn/images/flags/png/MU@1,5x.png +0 -0
  580. eduvpn/data/share/eduvpn/images/flags/png/MU@2x.png +0 -0
  581. eduvpn/data/share/eduvpn/images/flags/png/MU@3x.png +0 -0
  582. eduvpn/data/share/eduvpn/images/flags/png/MV@1,5x.png +0 -0
  583. eduvpn/data/share/eduvpn/images/flags/png/MV@2x.png +0 -0
  584. eduvpn/data/share/eduvpn/images/flags/png/MV@3x.png +0 -0
  585. eduvpn/data/share/eduvpn/images/flags/png/MW@1,5x.png +0 -0
  586. eduvpn/data/share/eduvpn/images/flags/png/MW@2x.png +0 -0
  587. eduvpn/data/share/eduvpn/images/flags/png/MW@3x.png +0 -0
  588. eduvpn/data/share/eduvpn/images/flags/png/MX@1,5x.png +0 -0
  589. eduvpn/data/share/eduvpn/images/flags/png/MX@2x.png +0 -0
  590. eduvpn/data/share/eduvpn/images/flags/png/MX@3x.png +0 -0
  591. eduvpn/data/share/eduvpn/images/flags/png/MY@1,5x.png +0 -0
  592. eduvpn/data/share/eduvpn/images/flags/png/MY@2x.png +0 -0
  593. eduvpn/data/share/eduvpn/images/flags/png/MY@3x.png +0 -0
  594. eduvpn/data/share/eduvpn/images/flags/png/MZ@1,5x.png +0 -0
  595. eduvpn/data/share/eduvpn/images/flags/png/MZ@2x.png +0 -0
  596. eduvpn/data/share/eduvpn/images/flags/png/MZ@3x.png +0 -0
  597. eduvpn/data/share/eduvpn/images/flags/png/NA@1,5x.png +0 -0
  598. eduvpn/data/share/eduvpn/images/flags/png/NA@2x.png +0 -0
  599. eduvpn/data/share/eduvpn/images/flags/png/NA@3x.png +0 -0
  600. eduvpn/data/share/eduvpn/images/flags/png/NC@1,5x.png +0 -0
  601. eduvpn/data/share/eduvpn/images/flags/png/NC@2x.png +0 -0
  602. eduvpn/data/share/eduvpn/images/flags/png/NC@3x.png +0 -0
  603. eduvpn/data/share/eduvpn/images/flags/png/NE@1,5x.png +0 -0
  604. eduvpn/data/share/eduvpn/images/flags/png/NE@2x.png +0 -0
  605. eduvpn/data/share/eduvpn/images/flags/png/NE@3x.png +0 -0
  606. eduvpn/data/share/eduvpn/images/flags/png/NF@1,5x.png +0 -0
  607. eduvpn/data/share/eduvpn/images/flags/png/NF@2x.png +0 -0
  608. eduvpn/data/share/eduvpn/images/flags/png/NF@3x.png +0 -0
  609. eduvpn/data/share/eduvpn/images/flags/png/NG@1,5x.png +0 -0
  610. eduvpn/data/share/eduvpn/images/flags/png/NG@2x.png +0 -0
  611. eduvpn/data/share/eduvpn/images/flags/png/NG@3x.png +0 -0
  612. eduvpn/data/share/eduvpn/images/flags/png/NI@1,5x.png +0 -0
  613. eduvpn/data/share/eduvpn/images/flags/png/NI@2x.png +0 -0
  614. eduvpn/data/share/eduvpn/images/flags/png/NI@3x.png +0 -0
  615. eduvpn/data/share/eduvpn/images/flags/png/NL@1,5x.png +0 -0
  616. eduvpn/data/share/eduvpn/images/flags/png/NL@2x.png +0 -0
  617. eduvpn/data/share/eduvpn/images/flags/png/NL@3x.png +0 -0
  618. eduvpn/data/share/eduvpn/images/flags/png/NO@1,5x.png +0 -0
  619. eduvpn/data/share/eduvpn/images/flags/png/NO@2x.png +0 -0
  620. eduvpn/data/share/eduvpn/images/flags/png/NO@3x.png +0 -0
  621. eduvpn/data/share/eduvpn/images/flags/png/NP@1,5x.png +0 -0
  622. eduvpn/data/share/eduvpn/images/flags/png/NP@2x.png +0 -0
  623. eduvpn/data/share/eduvpn/images/flags/png/NP@3x.png +0 -0
  624. eduvpn/data/share/eduvpn/images/flags/png/NR@1,5x.png +0 -0
  625. eduvpn/data/share/eduvpn/images/flags/png/NR@2x.png +0 -0
  626. eduvpn/data/share/eduvpn/images/flags/png/NR@3x.png +0 -0
  627. eduvpn/data/share/eduvpn/images/flags/png/NU@1,5x.png +0 -0
  628. eduvpn/data/share/eduvpn/images/flags/png/NU@2x.png +0 -0
  629. eduvpn/data/share/eduvpn/images/flags/png/NU@3x.png +0 -0
  630. eduvpn/data/share/eduvpn/images/flags/png/NZ@1,5x.png +0 -0
  631. eduvpn/data/share/eduvpn/images/flags/png/NZ@2x.png +0 -0
  632. eduvpn/data/share/eduvpn/images/flags/png/NZ@3x.png +0 -0
  633. eduvpn/data/share/eduvpn/images/flags/png/Netherlands Antilles@1,5x.png +0 -0
  634. eduvpn/data/share/eduvpn/images/flags/png/Netherlands Antilles@2x.png +0 -0
  635. eduvpn/data/share/eduvpn/images/flags/png/Netherlands Antilles@3x.png +0 -0
  636. eduvpn/data/share/eduvpn/images/flags/png/OM@1,5x.png +0 -0
  637. eduvpn/data/share/eduvpn/images/flags/png/OM@2x.png +0 -0
  638. eduvpn/data/share/eduvpn/images/flags/png/OM@3x.png +0 -0
  639. eduvpn/data/share/eduvpn/images/flags/png/Overlay@1,5x.png +0 -0
  640. eduvpn/data/share/eduvpn/images/flags/png/Overlay@2x.png +0 -0
  641. eduvpn/data/share/eduvpn/images/flags/png/Overlay@3x.png +0 -0
  642. eduvpn/data/share/eduvpn/images/flags/png/PA@1,5x.png +0 -0
  643. eduvpn/data/share/eduvpn/images/flags/png/PA@2x.png +0 -0
  644. eduvpn/data/share/eduvpn/images/flags/png/PA@3x.png +0 -0
  645. eduvpn/data/share/eduvpn/images/flags/png/PE@1,5x.png +0 -0
  646. eduvpn/data/share/eduvpn/images/flags/png/PE@2x.png +0 -0
  647. eduvpn/data/share/eduvpn/images/flags/png/PE@3x.png +0 -0
  648. eduvpn/data/share/eduvpn/images/flags/png/PF@1,5x.png +0 -0
  649. eduvpn/data/share/eduvpn/images/flags/png/PF@2x.png +0 -0
  650. eduvpn/data/share/eduvpn/images/flags/png/PF@3x.png +0 -0
  651. eduvpn/data/share/eduvpn/images/flags/png/PG@1,5x.png +0 -0
  652. eduvpn/data/share/eduvpn/images/flags/png/PG@2x.png +0 -0
  653. eduvpn/data/share/eduvpn/images/flags/png/PG@3x.png +0 -0
  654. eduvpn/data/share/eduvpn/images/flags/png/PH@1,5x.png +0 -0
  655. eduvpn/data/share/eduvpn/images/flags/png/PH@2x.png +0 -0
  656. eduvpn/data/share/eduvpn/images/flags/png/PH@3x.png +0 -0
  657. eduvpn/data/share/eduvpn/images/flags/png/PK@1,5x.png +0 -0
  658. eduvpn/data/share/eduvpn/images/flags/png/PK@2x.png +0 -0
  659. eduvpn/data/share/eduvpn/images/flags/png/PK@3x.png +0 -0
  660. eduvpn/data/share/eduvpn/images/flags/png/PL@1,5x.png +0 -0
  661. eduvpn/data/share/eduvpn/images/flags/png/PL@2x.png +0 -0
  662. eduvpn/data/share/eduvpn/images/flags/png/PL@3x.png +0 -0
  663. eduvpn/data/share/eduvpn/images/flags/png/PN@1,5x.png +0 -0
  664. eduvpn/data/share/eduvpn/images/flags/png/PN@2x.png +0 -0
  665. eduvpn/data/share/eduvpn/images/flags/png/PN@3x.png +0 -0
  666. eduvpn/data/share/eduvpn/images/flags/png/PR@1,5x.png +0 -0
  667. eduvpn/data/share/eduvpn/images/flags/png/PR@2x.png +0 -0
  668. eduvpn/data/share/eduvpn/images/flags/png/PR@3x.png +0 -0
  669. eduvpn/data/share/eduvpn/images/flags/png/PS@1,5x.png +0 -0
  670. eduvpn/data/share/eduvpn/images/flags/png/PS@2x.png +0 -0
  671. eduvpn/data/share/eduvpn/images/flags/png/PS@3x.png +0 -0
  672. eduvpn/data/share/eduvpn/images/flags/png/PT@1,5x.png +0 -0
  673. eduvpn/data/share/eduvpn/images/flags/png/PT@2x.png +0 -0
  674. eduvpn/data/share/eduvpn/images/flags/png/PT@3x.png +0 -0
  675. eduvpn/data/share/eduvpn/images/flags/png/PW@1,5x.png +0 -0
  676. eduvpn/data/share/eduvpn/images/flags/png/PW@2x.png +0 -0
  677. eduvpn/data/share/eduvpn/images/flags/png/PW@3x.png +0 -0
  678. eduvpn/data/share/eduvpn/images/flags/png/PY@1,5x.png +0 -0
  679. eduvpn/data/share/eduvpn/images/flags/png/PY@2x.png +0 -0
  680. eduvpn/data/share/eduvpn/images/flags/png/PY@3x.png +0 -0
  681. eduvpn/data/share/eduvpn/images/flags/png/QA@1,5x.png +0 -0
  682. eduvpn/data/share/eduvpn/images/flags/png/QA@2x.png +0 -0
  683. eduvpn/data/share/eduvpn/images/flags/png/QA@3x.png +0 -0
  684. eduvpn/data/share/eduvpn/images/flags/png/RE@1,5x.png +0 -0
  685. eduvpn/data/share/eduvpn/images/flags/png/RE@2x.png +0 -0
  686. eduvpn/data/share/eduvpn/images/flags/png/RE@3x.png +0 -0
  687. eduvpn/data/share/eduvpn/images/flags/png/RO@1,5x.png +0 -0
  688. eduvpn/data/share/eduvpn/images/flags/png/RO@2x.png +0 -0
  689. eduvpn/data/share/eduvpn/images/flags/png/RO@3x.png +0 -0
  690. eduvpn/data/share/eduvpn/images/flags/png/RS@1,5x.png +0 -0
  691. eduvpn/data/share/eduvpn/images/flags/png/RS@2x.png +0 -0
  692. eduvpn/data/share/eduvpn/images/flags/png/RS@3x.png +0 -0
  693. eduvpn/data/share/eduvpn/images/flags/png/RU@1,5x.png +0 -0
  694. eduvpn/data/share/eduvpn/images/flags/png/RU@2x.png +0 -0
  695. eduvpn/data/share/eduvpn/images/flags/png/RU@3x.png +0 -0
  696. eduvpn/data/share/eduvpn/images/flags/png/RW@1,5x.png +0 -0
  697. eduvpn/data/share/eduvpn/images/flags/png/RW@2x.png +0 -0
  698. eduvpn/data/share/eduvpn/images/flags/png/RW@3x.png +0 -0
  699. eduvpn/data/share/eduvpn/images/flags/png/Red Peak Flag (NZ)@1,5x.png +0 -0
  700. eduvpn/data/share/eduvpn/images/flags/png/Red Peak Flag (NZ)@2x.png +0 -0
  701. eduvpn/data/share/eduvpn/images/flags/png/Red Peak Flag (NZ)@3x.png +0 -0
  702. eduvpn/data/share/eduvpn/images/flags/png/SA@1,5x.png +0 -0
  703. eduvpn/data/share/eduvpn/images/flags/png/SA@2x.png +0 -0
  704. eduvpn/data/share/eduvpn/images/flags/png/SA@3x.png +0 -0
  705. eduvpn/data/share/eduvpn/images/flags/png/SB@1,5x.png +0 -0
  706. eduvpn/data/share/eduvpn/images/flags/png/SB@2x.png +0 -0
  707. eduvpn/data/share/eduvpn/images/flags/png/SB@3x.png +0 -0
  708. eduvpn/data/share/eduvpn/images/flags/png/SC@1,5x.png +0 -0
  709. eduvpn/data/share/eduvpn/images/flags/png/SC@2x.png +0 -0
  710. eduvpn/data/share/eduvpn/images/flags/png/SC@3x.png +0 -0
  711. eduvpn/data/share/eduvpn/images/flags/png/SD@1,5x.png +0 -0
  712. eduvpn/data/share/eduvpn/images/flags/png/SD@2x.png +0 -0
  713. eduvpn/data/share/eduvpn/images/flags/png/SD@3x.png +0 -0
  714. eduvpn/data/share/eduvpn/images/flags/png/SE@1,5x.png +0 -0
  715. eduvpn/data/share/eduvpn/images/flags/png/SE@2x.png +0 -0
  716. eduvpn/data/share/eduvpn/images/flags/png/SE@3x.png +0 -0
  717. eduvpn/data/share/eduvpn/images/flags/png/SG@1,5x.png +0 -0
  718. eduvpn/data/share/eduvpn/images/flags/png/SG@2x.png +0 -0
  719. eduvpn/data/share/eduvpn/images/flags/png/SG@3x.png +0 -0
  720. eduvpn/data/share/eduvpn/images/flags/png/SH-HL@1,5x.png +0 -0
  721. eduvpn/data/share/eduvpn/images/flags/png/SH-HL@2x.png +0 -0
  722. eduvpn/data/share/eduvpn/images/flags/png/SH-HL@3x.png +0 -0
  723. eduvpn/data/share/eduvpn/images/flags/png/SI@1,5x.png +0 -0
  724. eduvpn/data/share/eduvpn/images/flags/png/SI@2x.png +0 -0
  725. eduvpn/data/share/eduvpn/images/flags/png/SI@3x.png +0 -0
  726. eduvpn/data/share/eduvpn/images/flags/png/SK@1,5x.png +0 -0
  727. eduvpn/data/share/eduvpn/images/flags/png/SK@2x.png +0 -0
  728. eduvpn/data/share/eduvpn/images/flags/png/SK@3x.png +0 -0
  729. eduvpn/data/share/eduvpn/images/flags/png/SL@1,5x.png +0 -0
  730. eduvpn/data/share/eduvpn/images/flags/png/SL@2x.png +0 -0
  731. eduvpn/data/share/eduvpn/images/flags/png/SL@3x.png +0 -0
  732. eduvpn/data/share/eduvpn/images/flags/png/SM@1,5x.png +0 -0
  733. eduvpn/data/share/eduvpn/images/flags/png/SM@2x.png +0 -0
  734. eduvpn/data/share/eduvpn/images/flags/png/SM@3x.png +0 -0
  735. eduvpn/data/share/eduvpn/images/flags/png/SN@1,5x.png +0 -0
  736. eduvpn/data/share/eduvpn/images/flags/png/SN@2x.png +0 -0
  737. eduvpn/data/share/eduvpn/images/flags/png/SN@3x.png +0 -0
  738. eduvpn/data/share/eduvpn/images/flags/png/SO@1,5x.png +0 -0
  739. eduvpn/data/share/eduvpn/images/flags/png/SO@2x.png +0 -0
  740. eduvpn/data/share/eduvpn/images/flags/png/SO@3x.png +0 -0
  741. eduvpn/data/share/eduvpn/images/flags/png/SR@1,5x.png +0 -0
  742. eduvpn/data/share/eduvpn/images/flags/png/SR@2x.png +0 -0
  743. eduvpn/data/share/eduvpn/images/flags/png/SR@3x.png +0 -0
  744. eduvpn/data/share/eduvpn/images/flags/png/SS@1,5x.png +0 -0
  745. eduvpn/data/share/eduvpn/images/flags/png/SS@2x.png +0 -0
  746. eduvpn/data/share/eduvpn/images/flags/png/SS@3x.png +0 -0
  747. eduvpn/data/share/eduvpn/images/flags/png/ST@1,5x.png +0 -0
  748. eduvpn/data/share/eduvpn/images/flags/png/ST@2x.png +0 -0
  749. eduvpn/data/share/eduvpn/images/flags/png/ST@3x.png +0 -0
  750. eduvpn/data/share/eduvpn/images/flags/png/SV@1,5x.png +0 -0
  751. eduvpn/data/share/eduvpn/images/flags/png/SV@2x.png +0 -0
  752. eduvpn/data/share/eduvpn/images/flags/png/SV@3x.png +0 -0
  753. eduvpn/data/share/eduvpn/images/flags/png/SX@1,5x.png +0 -0
  754. eduvpn/data/share/eduvpn/images/flags/png/SX@2x.png +0 -0
  755. eduvpn/data/share/eduvpn/images/flags/png/SX@3x.png +0 -0
  756. eduvpn/data/share/eduvpn/images/flags/png/SY@1,5x.png +0 -0
  757. eduvpn/data/share/eduvpn/images/flags/png/SY@2x.png +0 -0
  758. eduvpn/data/share/eduvpn/images/flags/png/SY@3x.png +0 -0
  759. eduvpn/data/share/eduvpn/images/flags/png/SZ@1,5x.png +0 -0
  760. eduvpn/data/share/eduvpn/images/flags/png/SZ@2x.png +0 -0
  761. eduvpn/data/share/eduvpn/images/flags/png/SZ@3x.png +0 -0
  762. eduvpn/data/share/eduvpn/images/flags/png/Sealand@1,5x.png +0 -0
  763. eduvpn/data/share/eduvpn/images/flags/png/Sealand@2x.png +0 -0
  764. eduvpn/data/share/eduvpn/images/flags/png/Sealand@3x.png +0 -0
  765. eduvpn/data/share/eduvpn/images/flags/png/Serb Republic@1,5x.png +0 -0
  766. eduvpn/data/share/eduvpn/images/flags/png/Serb Republic@2x.png +0 -0
  767. eduvpn/data/share/eduvpn/images/flags/png/Serb Republic@3x.png +0 -0
  768. eduvpn/data/share/eduvpn/images/flags/png/South Ossetia@1,5x.png +0 -0
  769. eduvpn/data/share/eduvpn/images/flags/png/South Ossetia@2x.png +0 -0
  770. eduvpn/data/share/eduvpn/images/flags/png/South Ossetia@3x.png +0 -0
  771. eduvpn/data/share/eduvpn/images/flags/png/TC@1,5x.png +0 -0
  772. eduvpn/data/share/eduvpn/images/flags/png/TC@2x.png +0 -0
  773. eduvpn/data/share/eduvpn/images/flags/png/TC@3x.png +0 -0
  774. eduvpn/data/share/eduvpn/images/flags/png/TD@1,5x.png +0 -0
  775. eduvpn/data/share/eduvpn/images/flags/png/TD@2x.png +0 -0
  776. eduvpn/data/share/eduvpn/images/flags/png/TD@3x.png +0 -0
  777. eduvpn/data/share/eduvpn/images/flags/png/TG@1,5x.png +0 -0
  778. eduvpn/data/share/eduvpn/images/flags/png/TG@2x.png +0 -0
  779. eduvpn/data/share/eduvpn/images/flags/png/TG@3x.png +0 -0
  780. eduvpn/data/share/eduvpn/images/flags/png/TH@1,5x.png +0 -0
  781. eduvpn/data/share/eduvpn/images/flags/png/TH@2x.png +0 -0
  782. eduvpn/data/share/eduvpn/images/flags/png/TH@3x.png +0 -0
  783. eduvpn/data/share/eduvpn/images/flags/png/TJ@1,5x.png +0 -0
  784. eduvpn/data/share/eduvpn/images/flags/png/TJ@2x.png +0 -0
  785. eduvpn/data/share/eduvpn/images/flags/png/TJ@3x.png +0 -0
  786. eduvpn/data/share/eduvpn/images/flags/png/TK@1,5x.png +0 -0
  787. eduvpn/data/share/eduvpn/images/flags/png/TK@2x.png +0 -0
  788. eduvpn/data/share/eduvpn/images/flags/png/TK@3x.png +0 -0
  789. eduvpn/data/share/eduvpn/images/flags/png/TL@1,5x.png +0 -0
  790. eduvpn/data/share/eduvpn/images/flags/png/TL@2x.png +0 -0
  791. eduvpn/data/share/eduvpn/images/flags/png/TL@3x.png +0 -0
  792. eduvpn/data/share/eduvpn/images/flags/png/TM@1,5x.png +0 -0
  793. eduvpn/data/share/eduvpn/images/flags/png/TM@2x.png +0 -0
  794. eduvpn/data/share/eduvpn/images/flags/png/TM@3x.png +0 -0
  795. eduvpn/data/share/eduvpn/images/flags/png/TN@1,5x.png +0 -0
  796. eduvpn/data/share/eduvpn/images/flags/png/TN@2x.png +0 -0
  797. eduvpn/data/share/eduvpn/images/flags/png/TN@3x.png +0 -0
  798. eduvpn/data/share/eduvpn/images/flags/png/TO@1,5x.png +0 -0
  799. eduvpn/data/share/eduvpn/images/flags/png/TO@2x.png +0 -0
  800. eduvpn/data/share/eduvpn/images/flags/png/TO@3x.png +0 -0
  801. eduvpn/data/share/eduvpn/images/flags/png/TR@1,5x.png +0 -0
  802. eduvpn/data/share/eduvpn/images/flags/png/TR@2x.png +0 -0
  803. eduvpn/data/share/eduvpn/images/flags/png/TR@3x.png +0 -0
  804. eduvpn/data/share/eduvpn/images/flags/png/TT@1,5x.png +0 -0
  805. eduvpn/data/share/eduvpn/images/flags/png/TT@2x.png +0 -0
  806. eduvpn/data/share/eduvpn/images/flags/png/TT@3x.png +0 -0
  807. eduvpn/data/share/eduvpn/images/flags/png/TV@1,5x.png +0 -0
  808. eduvpn/data/share/eduvpn/images/flags/png/TV@2x.png +0 -0
  809. eduvpn/data/share/eduvpn/images/flags/png/TV@3x.png +0 -0
  810. eduvpn/data/share/eduvpn/images/flags/png/TW@1,5x.png +0 -0
  811. eduvpn/data/share/eduvpn/images/flags/png/TW@2x.png +0 -0
  812. eduvpn/data/share/eduvpn/images/flags/png/TW@3x.png +0 -0
  813. eduvpn/data/share/eduvpn/images/flags/png/TZ@1,5x.png +0 -0
  814. eduvpn/data/share/eduvpn/images/flags/png/TZ@2x.png +0 -0
  815. eduvpn/data/share/eduvpn/images/flags/png/TZ@3x.png +0 -0
  816. eduvpn/data/share/eduvpn/images/flags/png/Transnistria@1,5x.png +0 -0
  817. eduvpn/data/share/eduvpn/images/flags/png/Transnistria@2x.png +0 -0
  818. eduvpn/data/share/eduvpn/images/flags/png/Transnistria@3x.png +0 -0
  819. eduvpn/data/share/eduvpn/images/flags/png/Turkish Republic of Northern Cyprus@1,5x.png +0 -0
  820. eduvpn/data/share/eduvpn/images/flags/png/Turkish Republic of Northern Cyprus@2x.png +0 -0
  821. eduvpn/data/share/eduvpn/images/flags/png/Turkish Republic of Northern Cyprus@3x.png +0 -0
  822. eduvpn/data/share/eduvpn/images/flags/png/UA@1,5x.png +0 -0
  823. eduvpn/data/share/eduvpn/images/flags/png/UA@2x.png +0 -0
  824. eduvpn/data/share/eduvpn/images/flags/png/UA@3x.png +0 -0
  825. eduvpn/data/share/eduvpn/images/flags/png/UG@1,5x.png +0 -0
  826. eduvpn/data/share/eduvpn/images/flags/png/UG@2x.png +0 -0
  827. eduvpn/data/share/eduvpn/images/flags/png/UG@3x.png +0 -0
  828. eduvpn/data/share/eduvpn/images/flags/png/US@1,5x.png +0 -0
  829. eduvpn/data/share/eduvpn/images/flags/png/US@2x.png +0 -0
  830. eduvpn/data/share/eduvpn/images/flags/png/US@3x.png +0 -0
  831. eduvpn/data/share/eduvpn/images/flags/png/UY@1,5x.png +0 -0
  832. eduvpn/data/share/eduvpn/images/flags/png/UY@2x.png +0 -0
  833. eduvpn/data/share/eduvpn/images/flags/png/UY@3x.png +0 -0
  834. eduvpn/data/share/eduvpn/images/flags/png/UZ@1,5x.png +0 -0
  835. eduvpn/data/share/eduvpn/images/flags/png/UZ@2x.png +0 -0
  836. eduvpn/data/share/eduvpn/images/flags/png/UZ@3x.png +0 -0
  837. eduvpn/data/share/eduvpn/images/flags/png/VA@1,5x.png +0 -0
  838. eduvpn/data/share/eduvpn/images/flags/png/VA@2x.png +0 -0
  839. eduvpn/data/share/eduvpn/images/flags/png/VA@3x.png +0 -0
  840. eduvpn/data/share/eduvpn/images/flags/png/VC@1,5x.png +0 -0
  841. eduvpn/data/share/eduvpn/images/flags/png/VC@2x.png +0 -0
  842. eduvpn/data/share/eduvpn/images/flags/png/VC@3x.png +0 -0
  843. eduvpn/data/share/eduvpn/images/flags/png/VE@1,5x.png +0 -0
  844. eduvpn/data/share/eduvpn/images/flags/png/VE@2x.png +0 -0
  845. eduvpn/data/share/eduvpn/images/flags/png/VE@3x.png +0 -0
  846. eduvpn/data/share/eduvpn/images/flags/png/VG@1,5x.png +0 -0
  847. eduvpn/data/share/eduvpn/images/flags/png/VG@2x.png +0 -0
  848. eduvpn/data/share/eduvpn/images/flags/png/VG@3x.png +0 -0
  849. eduvpn/data/share/eduvpn/images/flags/png/VI@1,5x.png +0 -0
  850. eduvpn/data/share/eduvpn/images/flags/png/VI@2x.png +0 -0
  851. eduvpn/data/share/eduvpn/images/flags/png/VI@3x.png +0 -0
  852. eduvpn/data/share/eduvpn/images/flags/png/VN@1,5x.png +0 -0
  853. eduvpn/data/share/eduvpn/images/flags/png/VN@2x.png +0 -0
  854. eduvpn/data/share/eduvpn/images/flags/png/VN@3x.png +0 -0
  855. eduvpn/data/share/eduvpn/images/flags/png/VU@1,5x.png +0 -0
  856. eduvpn/data/share/eduvpn/images/flags/png/VU@2x.png +0 -0
  857. eduvpn/data/share/eduvpn/images/flags/png/VU@3x.png +0 -0
  858. eduvpn/data/share/eduvpn/images/flags/png/WS@1,5x.png +0 -0
  859. eduvpn/data/share/eduvpn/images/flags/png/WS@2x.png +0 -0
  860. eduvpn/data/share/eduvpn/images/flags/png/WS@3x.png +0 -0
  861. eduvpn/data/share/eduvpn/images/flags/png/XK@1,5x.png +0 -0
  862. eduvpn/data/share/eduvpn/images/flags/png/XK@2x.png +0 -0
  863. eduvpn/data/share/eduvpn/images/flags/png/XK@3x.png +0 -0
  864. eduvpn/data/share/eduvpn/images/flags/png/YE@1,5x.png +0 -0
  865. eduvpn/data/share/eduvpn/images/flags/png/YE@2x.png +0 -0
  866. eduvpn/data/share/eduvpn/images/flags/png/YE@3x.png +0 -0
  867. eduvpn/data/share/eduvpn/images/flags/png/ZA@1,5x.png +0 -0
  868. eduvpn/data/share/eduvpn/images/flags/png/ZA@2x.png +0 -0
  869. eduvpn/data/share/eduvpn/images/flags/png/ZA@3x.png +0 -0
  870. eduvpn/data/share/eduvpn/images/flags/png/ZM@1,5x.png +0 -0
  871. eduvpn/data/share/eduvpn/images/flags/png/ZM@2x.png +0 -0
  872. eduvpn/data/share/eduvpn/images/flags/png/ZM@3x.png +0 -0
  873. eduvpn/data/share/eduvpn/images/flags/png/ZW@1,5x.png +0 -0
  874. eduvpn/data/share/eduvpn/images/flags/png/ZW@2x.png +0 -0
  875. eduvpn/data/share/eduvpn/images/flags/png/ZW@3x.png +0 -0
  876. eduvpn/data/share/eduvpn/images/group.png +0 -0
  877. eduvpn/data/share/eduvpn/images/group@2x.png +0 -0
  878. eduvpn/data/share/eduvpn/images/group@3x.png +0 -0
  879. eduvpn/data/share/eduvpn/images/institute-icon-dark.png +0 -0
  880. eduvpn/data/share/eduvpn/images/institute-icon-dark@2x.png +0 -0
  881. eduvpn/data/share/eduvpn/images/institute-icon-dark@3x.png +0 -0
  882. eduvpn/data/share/eduvpn/images/institute-icon.png +0 -0
  883. eduvpn/data/share/eduvpn/images/institute-icon@2x.png +0 -0
  884. eduvpn/data/share/eduvpn/images/institute-icon@3x.png +0 -0
  885. eduvpn/data/share/eduvpn/images/institute.png +0 -0
  886. eduvpn/data/share/eduvpn/images/institute@2x.png +0 -0
  887. eduvpn/data/share/eduvpn/images/institute@3x.png +0 -0
  888. eduvpn/data/share/eduvpn/images/question-icon-dark.png +0 -0
  889. eduvpn/data/share/eduvpn/images/question-icon-dark@2x.png +0 -0
  890. eduvpn/data/share/eduvpn/images/question-icon-dark@3x.png +0 -0
  891. eduvpn/data/share/eduvpn/images/question-icon.png +0 -0
  892. eduvpn/data/share/eduvpn/images/question-icon@2x.png +0 -0
  893. eduvpn/data/share/eduvpn/images/question-icon@3x.png +0 -0
  894. eduvpn/data/share/eduvpn/images/server-icon-dark.png +0 -0
  895. eduvpn/data/share/eduvpn/images/server-icon-dark@2x.png +0 -0
  896. eduvpn/data/share/eduvpn/images/server-icon-dark@3x.png +0 -0
  897. eduvpn/data/share/eduvpn/images/server-icon.png +0 -0
  898. eduvpn/data/share/eduvpn/images/server-icon@2x.png +0 -0
  899. eduvpn/data/share/eduvpn/images/server-icon@3x.png +0 -0
  900. eduvpn/data/share/eduvpn/images/settings-dark.png +0 -0
  901. eduvpn/data/share/eduvpn/images/settings-dark@2x.png +0 -0
  902. eduvpn/data/share/eduvpn/images/settings-dark@3x.png +0 -0
  903. eduvpn/data/share/eduvpn/images/settings.png +0 -0
  904. eduvpn/data/share/eduvpn/images/settings@2x.png +0 -0
  905. eduvpn/data/share/eduvpn/images/settings@3x.png +0 -0
  906. eduvpn/data/share/icons/hicolor/128x128/apps/org.eduvpn.client.png +0 -0
  907. eduvpn/data/share/icons/hicolor/128x128/apps/org.letsconnect-vpn.client.png +0 -0
  908. eduvpn/data/share/icons/hicolor/256x256/apps/org.eduvpn.client.png +0 -0
  909. eduvpn/data/share/icons/hicolor/256x256/apps/org.letsconnect-vpn.client.png +0 -0
  910. eduvpn/data/share/icons/hicolor/48x48/apps/org.eduvpn.client.png +0 -0
  911. eduvpn/data/share/icons/hicolor/48x48/apps/org.letsconnect-vpn.client.png +0 -0
  912. eduvpn/data/share/icons/hicolor/512x512/apps/org.eduvpn.client.png +0 -0
  913. eduvpn/data/share/icons/hicolor/512x512/apps/org.letsconnect-vpn.client.png +0 -0
  914. eduvpn/data/share/letsconnect/images/app-icon-circle.svg +6 -0
  915. eduvpn/data/share/letsconnect/images/letsconnect.png +0 -0
  916. eduvpn/data/share/letsconnect/images/letsconnect@2x.png +0 -0
  917. eduvpn/data/share/letsconnect/images/letsconnect@3x.png +0 -0
  918. eduvpn/data/share/letsconnect/images/server-illustration.png +0 -0
  919. eduvpn/data/share/letsconnect/images/server-illustration@2x.png +0 -0
  920. eduvpn/data/share/letsconnect/images/server-illustration@3x.png +0 -0
  921. eduvpn/data/share/locale/Makefile +34 -0
  922. eduvpn/data/share/locale/de_DE/LC_MESSAGES/eduVPN.mo +0 -0
  923. eduvpn/data/share/locale/de_DE/LC_MESSAGES/eduVPN.po +228 -0
  924. eduvpn/data/share/locale/eduVPN.pot +226 -0
  925. eduvpn/data/share/locale/es_LA/LC_MESSAGES/eduVPN.mo +0 -0
  926. eduvpn/data/share/locale/es_LA/LC_MESSAGES/eduVPN.po +228 -0
  927. eduvpn/discovery.py +95 -0
  928. eduvpn/i18n.py +104 -0
  929. eduvpn/keyring.py +155 -0
  930. eduvpn/nm.py +916 -0
  931. eduvpn/notify.py +34 -0
  932. eduvpn/ovpn.py +99 -0
  933. eduvpn/server.py +313 -0
  934. eduvpn/settings.py +29 -0
  935. eduvpn/storage.py +71 -0
  936. eduvpn/ui/__init__.py +0 -0
  937. eduvpn/ui/__main__.py +56 -0
  938. eduvpn/ui/app.py +146 -0
  939. eduvpn/ui/search.py +197 -0
  940. eduvpn/ui/stats.py +106 -0
  941. eduvpn/ui/ui.py +1490 -0
  942. eduvpn/ui/utils.py +167 -0
  943. eduvpn/utils.py +253 -0
  944. eduvpn/variants.py +72 -0
  945. eduvpn_client-4.3.0.dist-info/LICENSE +674 -0
  946. eduvpn_client-4.3.0.dist-info/LICENSE.spdx +20 -0
  947. eduvpn_client-4.3.0.dist-info/METADATA +52 -0
  948. eduvpn_client-4.3.0.dist-info/RECORD +951 -0
  949. eduvpn_client-4.3.0.dist-info/WHEEL +5 -0
  950. eduvpn_client-4.3.0.dist-info/entry_points.txt +7 -0
  951. eduvpn_client-4.3.0.dist-info/top_level.txt +1 -0
eduvpn/__init__.py ADDED
@@ -0,0 +1 @@
1
+ __version__ = "4.3.0"
eduvpn/__main__.py ADDED
@@ -0,0 +1,4 @@
1
+ from eduvpn.cli import eduvpn
2
+
3
+ if __name__ == "__main__":
4
+ eduvpn()
eduvpn/app.py ADDED
@@ -0,0 +1,628 @@
1
+ import json
2
+ import logging
3
+ import os
4
+ import signal
5
+ import time
6
+ import webbrowser
7
+ from typing import Any, Callable, Iterator, Optional, TextIO
8
+
9
+ from eduvpn_common.main import EduVPN, ServerType, WrappedError
10
+ from eduvpn_common.state import State, StateType
11
+ from eduvpn_common.types import ProxyReady, ProxySetup, ReadRxBytes
12
+
13
+ from eduvpn import nm
14
+ from eduvpn.config import Configuration
15
+ from eduvpn.connection import Config, Connection, Protocol, parse_config, parse_expiry, parse_tokens
16
+ from eduvpn.keyring import DBusKeyring, InsecureFileKeyring, TokenKeyring
17
+ from eduvpn.server import ServerDatabase, parse_profiles, parse_required_transition
18
+ from eduvpn.utils import (
19
+ handle_exception,
20
+ model_transition,
21
+ run_in_background_thread,
22
+ run_in_glib_thread,
23
+ set_failovered,
24
+ set_online_detecting,
25
+ )
26
+ from eduvpn.variants import ApplicationVariant
27
+
28
+ logger = logging.getLogger(__name__)
29
+
30
+
31
+ class ApplicationModelTransitions:
32
+ def __init__(self, common: EduVPN, variant: ApplicationVariant) -> None:
33
+ self.common = common
34
+ self.common.register_class_callbacks(self)
35
+ self.server_db = ServerDatabase(common, variant.use_predefined_servers)
36
+
37
+ @model_transition(State.MAIN, StateType.ENTER)
38
+ def get_previous_servers(self, old_state: State, data):
39
+ logger.debug(f"Transition: MAIN, old state: {old_state}")
40
+ return self.server_db.configured
41
+
42
+ @model_transition(State.DEREGISTERED, StateType.ENTER)
43
+ def deregistered(self, old_state: State, data: str):
44
+ logger.debug(f"Transition: DEREGISTERED, old state: {old_state}")
45
+ return data
46
+
47
+ @model_transition(State.ADDING_SERVER, StateType.ENTER)
48
+ def adding_server(self, old_state: State, data: str):
49
+ logger.debug(f"Transition: ADDING_SERVER, old state: {old_state}")
50
+ return data
51
+
52
+ @model_transition(State.GETTING_CONFIG, StateType.ENTER)
53
+ def getting_config(self, old_state: State, data: str):
54
+ logger.debug(f"Transition: GETTING_CONFIG, old state: {old_state}")
55
+ return data
56
+
57
+ @model_transition(State.DISCONNECTED, StateType.ENTER)
58
+ def disconnected_server(self, old_state: State, data: str):
59
+ logger.debug(f"Transition: DISCONNECTED, old state: {old_state}")
60
+ return self.server_db.current
61
+
62
+ @model_transition(State.DISCONNECTING, StateType.ENTER)
63
+ def disconnecting(self, old_state: State, data):
64
+ logger.debug(f"Transition: DISCONNECTING, old state: {old_state}")
65
+ return self.server_db.current
66
+
67
+ @model_transition(State.ASK_PROFILE, StateType.ENTER)
68
+ def ask_profile(self, old_state: State, data: str):
69
+ logger.debug(f"Transition: ASK_PROFILE, old state: {old_state}")
70
+ cookie, profiles = parse_required_transition(data, get=parse_profiles)
71
+
72
+ def set_profile(prof):
73
+ self.common.cookie_reply(cookie, prof)
74
+
75
+ return (set_profile, profiles)
76
+
77
+ @model_transition(State.ASK_LOCATION, StateType.ENTER)
78
+ def ask_location(self, old_state: State, data):
79
+ cookie, locations = parse_required_transition(data)
80
+
81
+ def set_location(loc):
82
+ self.common.cookie_reply(cookie, loc)
83
+
84
+ return (set_location, locations)
85
+
86
+ @model_transition(State.OAUTH_STARTED, StateType.ENTER)
87
+ def start_oauth(self, old_state: State, url: str):
88
+ logger.debug(f"Transition: OAUTH_STARTED, old state: {old_state}")
89
+ self.open_browser(url)
90
+ return url
91
+
92
+ @model_transition(State.GOT_CONFIG, StateType.ENTER)
93
+ def parse_config(self, old_state: State, data):
94
+ logger.debug(f"Transition: GOT_CONFIG, old state: {old_state}")
95
+ return self.server_db.current
96
+
97
+ @run_in_background_thread("open-browser")
98
+ def open_browser(self, url):
99
+ logger.debug(f"Opening web browser with url: {url}")
100
+ webbrowser.open(url)
101
+ # Explicitly wait to not have zombie processes
102
+ # See https://bugs.python.org/issue5993
103
+ logger.debug("Running os.wait for browser")
104
+ try:
105
+ os.wait()
106
+ except ChildProcessError:
107
+ pass
108
+ logger.debug("Done waiting for browser")
109
+
110
+ @model_transition(State.CONNECTED, StateType.ENTER)
111
+ def parse_connected(self, old_state: State, data):
112
+ logger.debug(f"Transition: CONNECTED, old state: {old_state}")
113
+ server = self.server_db.current
114
+ expire_times = parse_expiry(self.common.get_expiry_times())
115
+ return (server, expire_times)
116
+
117
+ @model_transition(State.CONNECTING, StateType.ENTER)
118
+ def parse_connecting(self, old_state: State, data):
119
+ logger.debug(f"Transition: CONNECTING, old state: {old_state}")
120
+ return self.server_db.current
121
+
122
+
123
+ class ApplicationModel:
124
+ def __init__(
125
+ self,
126
+ common: EduVPN,
127
+ config,
128
+ variant: ApplicationVariant,
129
+ nm_manager,
130
+ ) -> None:
131
+ self.common = common
132
+ self.config = config
133
+ self._keyring: TokenKeyring | None = None
134
+ self.transitions = ApplicationModelTransitions(common, variant)
135
+ self.variant = variant
136
+ self.nm_manager = nm_manager
137
+ self._was_tcp = False
138
+ self._should_failover = False
139
+ self._peer_ips_proxy = None
140
+
141
+ @property
142
+ def keyring(self):
143
+ if self._keyring is not None:
144
+ return self._keyring
145
+ keyring = DBusKeyring(self.variant)
146
+ if not keyring.available:
147
+ logger.warning("Secure keyring not available, reverting to insecure file keyring!")
148
+ keyring = InsecureFileKeyring(self.variant)
149
+ self._keyring = keyring
150
+ return self._keyring
151
+
152
+ def register(self, debug: bool):
153
+ self.common.register(debug=debug)
154
+ self.common.set_token_handler(self.load_tokens, self.save_tokens)
155
+
156
+ def cancel(self):
157
+ # Cancel any eduvpn-common operation
158
+ self.common.cancel()
159
+
160
+ # Cancel any NetworkManager operation
161
+ self.nm_manager.cancel()
162
+
163
+ @property
164
+ def server_db(self):
165
+ return self.transitions.server_db
166
+
167
+ @property
168
+ def current_server(self):
169
+ return self.server_db.current
170
+
171
+ def get_failover_rx(self, filehandler: Optional[TextIO]) -> int:
172
+ rx_bytes = self.nm_manager.get_stats_bytes(filehandler)
173
+ if rx_bytes is None:
174
+ return -1
175
+ return rx_bytes
176
+
177
+ def should_failover(self):
178
+ if self._should_failover:
179
+ logger.debug("eduvpn-common reports we should failover")
180
+
181
+ if self._was_tcp:
182
+ logger.debug("TCP was not previously triggered, failover should not continue")
183
+ return False
184
+ return True
185
+
186
+ logger.debug("Failover should not continue")
187
+ return False
188
+
189
+ def reconnect_tcp(self, callback: Callable):
190
+ def on_reconnected(success: bool):
191
+ callback(success)
192
+
193
+ self.reconnect(on_reconnected, prefer_tcp=True)
194
+
195
+ @run_in_background_thread("start-failover")
196
+ def start_failover(self, callback: Callable):
197
+ try:
198
+ rx_bytes_file = self.nm_manager.open_stats_file("rx_bytes")
199
+ if rx_bytes_file is None:
200
+ logger.error("Failed to initialize failover, failed to open rx bytes file")
201
+ callback(False)
202
+ return
203
+ endpoint = self.nm_manager.failover_endpoint_ip
204
+ if endpoint is None:
205
+ logger.error("Failed to initialize failover, failed to get endpoint")
206
+ callback(False)
207
+ return
208
+ mtu = self.nm_manager.mtu
209
+ if mtu is None:
210
+ logger.debug("failed to get MTU for failover, setting MTU to 1000")
211
+ mtu = 1000
212
+ logger.debug(
213
+ f"starting failover with gateway {endpoint} and MTU {mtu} for protocol {self.nm_manager.protocol}"
214
+ )
215
+ failover_delay = float(os.getenv("EDUVPN_FAILOVER_DELAY", 1))
216
+ logger.debug(f"Sleeping for {failover_delay}s to begin failover")
217
+ time.sleep(failover_delay)
218
+ dropped = self.common.start_failover(
219
+ endpoint,
220
+ mtu,
221
+ ReadRxBytes(lambda: self.get_failover_rx(rx_bytes_file)),
222
+ )
223
+
224
+ if dropped:
225
+ logger.debug("Failover exited, connection is dropped")
226
+ callback(True)
227
+ else:
228
+ logger.debug("Failover exited, connection is NOT dropped")
229
+ callback(False)
230
+ except WrappedError as e:
231
+ logger.debug(f"Failed failover, error: {e}")
232
+ callback(False)
233
+
234
+ def change_secure_location(self, country_code: str):
235
+ server = self.server_db.secure_internet
236
+ if server.country_code == country_code:
237
+ return
238
+ self.common.set_secure_location(server.org_id, country_code)
239
+ self.common.set_state(State.MAIN)
240
+
241
+ def go_back(self):
242
+ self.cancel()
243
+ self.common.set_state(State.MAIN)
244
+
245
+ def add(self, server, callback=None):
246
+ self.common.add_server(server.category_id, server.identifier)
247
+ if callback:
248
+ callback(server)
249
+
250
+ def remove(self, server):
251
+ self.common.remove_server(server.category_id, server.identifier)
252
+ # Delete tokens from the keyring
253
+ self.clear_tokens(server.category_id, server.identifier)
254
+ self.common.set_state(State.MAIN)
255
+
256
+ def connect_get_config(self, server, prefer_tcp: bool = False) -> Config:
257
+ # We prefer TCP if the user has set it or UDP is determined to be blocked
258
+ config = self.common.get_config(server.category_id, server.identifier, prefer_tcp)
259
+ return parse_config(config)
260
+
261
+ def clear_tokens(self, server_type: int, server_id: str):
262
+ attributes = {
263
+ "server": server_id,
264
+ "category": str(ServerType(server_type)),
265
+ }
266
+ try:
267
+ cleared = self.keyring.clear(attributes)
268
+ if not cleared:
269
+ logger.debug("Tokens were not cleared")
270
+ except Exception as e:
271
+ logger.debug("Failed clearing tokens with exception")
272
+ logger.debug(e, exc_info=True)
273
+
274
+ def load_tokens(self, server_id: str, server_type: int) -> Optional[str]:
275
+ attributes = {"server": server_id, "category": str(ServerType(server_type))}
276
+ try:
277
+ tokens_json = self.keyring.load(attributes)
278
+ if tokens_json is None:
279
+ logger.debug("No tokens available")
280
+ return None
281
+ tokens = json.loads(tokens_json)
282
+ expires = tokens.get("expires_at", None)
283
+ if expires is None:
284
+ expires = tokens.get("expires", None)
285
+ if expires is None:
286
+ logger.warning("failed to parse expires")
287
+ return None
288
+ d = {
289
+ "access_token": tokens["access"],
290
+ "refresh_token": tokens["refresh"],
291
+ "expires_at": int(expires),
292
+ }
293
+ return json.dumps(d)
294
+ except Exception as e:
295
+ logger.debug("Failed loading tokens with exception:")
296
+ logger.debug(e, exc_info=True)
297
+ return None
298
+
299
+ def save_tokens(self, server_id: str, server_type: int, tokens: str):
300
+ tokens_parsed = parse_tokens(tokens)
301
+ if tokens is None or (tokens_parsed.access == "" and tokens_parsed.refresh == ""):
302
+ logger.warning("Got empty tokens, not saving them to the keyring")
303
+ return
304
+ tokens_dict = {}
305
+ tokens_dict["access"] = tokens_parsed.access
306
+ tokens_dict["refresh"] = tokens_parsed.refresh
307
+ tokens_dict["expires_at"] = str(tokens_parsed.expires)
308
+ attributes = {"server": server_id, "category": str(ServerType(server_type))}
309
+ label = f"{server_id} - OAuth Tokens"
310
+ try:
311
+ self.keyring.save(label, attributes, json.dumps(tokens_dict))
312
+ except Exception as e:
313
+ logger.error("Failed saving tokens with exception:")
314
+ logger.error(e, exc_info=True)
315
+
316
+ def on_proxy_setup(self, fd, peer_ips):
317
+ logger.debug(f"got proxy fd: {fd}, peer_ips: {peer_ips}")
318
+ self._peer_ips_proxy = json.loads(peer_ips)
319
+
320
+ @run_in_background_thread("start-proxy")
321
+ def start_proxy(self, proxy, callback):
322
+ try:
323
+ self.common.start_proxyguard(
324
+ proxy.listen,
325
+ proxy.source_port,
326
+ proxy.peer,
327
+ ProxySetup(self.on_proxy_setup),
328
+ ProxyReady(lambda: callback()),
329
+ )
330
+ except Exception as e:
331
+ handle_exception(self.common, e)
332
+
333
+ def connect(
334
+ self,
335
+ server,
336
+ callback: Optional[Callable] = None,
337
+ prefer_tcp: bool = False,
338
+ ) -> None:
339
+ # Variable to be used as a last resort or for debugging
340
+ # to override the prefer TCP setting
341
+ if os.environ.get("EDUVPN_PREFER_TCP", "0") == "1":
342
+ prefer_tcp = True
343
+ config = self.connect_get_config(server, prefer_tcp=prefer_tcp)
344
+ if not config:
345
+ logger.warning("no configuration available")
346
+ if callback:
347
+ callback(False)
348
+ return
349
+
350
+ self._was_tcp = prefer_tcp or config.protocol == Protocol.WIREGUARDTCP
351
+ self._should_failover = config.should_failover
352
+
353
+ def on_fail():
354
+ if self.common.in_state(State.CONNECTED):
355
+ self.common.set_state(State.DISCONNECTING)
356
+ self.common.set_state(State.DISCONNECTED)
357
+ if callback:
358
+ callback(False)
359
+
360
+ def on_success():
361
+ # failed to disconnected
362
+ if self.common.in_state(State.CONNECTING):
363
+ self.common.set_state(State.CONNECTED)
364
+ if callback:
365
+ callback(True)
366
+
367
+ def final_connected(dropped: bool, error: str = ""):
368
+ # failover reports not dropped, return to connected if we are still in connecting
369
+ if not dropped:
370
+ if self.common.in_state(State.CONNECTING):
371
+ on_success()
372
+ else:
373
+ on_fail()
374
+ return
375
+
376
+ # Connection is dropped!
377
+ def on_reconnected(success: bool):
378
+ if not success:
379
+ handle_exception(self.common, Exception("failed to reconnect with TCP"))
380
+ if success:
381
+ set_failovered(self.common)
382
+ # When an error happens we always set success now as the previous
383
+ # protocol might be connected to
384
+ # TODO: differentiate between disconnect and new connect errors
385
+ on_success()
386
+
387
+ # reconnect with TCP
388
+ self.reconnect_tcp(on_reconnected)
389
+
390
+ def on_connected(success: bool):
391
+ if success:
392
+ # failover should not continue
393
+ if not self.should_failover():
394
+ on_success()
395
+ else:
396
+ set_online_detecting(self.common)
397
+ # failover should start
398
+ self.start_failover(final_connected)
399
+ else:
400
+ on_fail()
401
+
402
+ def on_connect(success: bool):
403
+ if success:
404
+ self.nm_manager.activate_connection(on_connected)
405
+ else:
406
+ on_fail()
407
+
408
+ @run_in_glib_thread
409
+ def connect(config):
410
+ if not self.common.in_state(State.CONNECTING):
411
+ self.common.set_state(State.CONNECTING)
412
+ connection = Connection.parse(config)
413
+ connection.connect(
414
+ self.nm_manager,
415
+ config.default_gateway,
416
+ self.config.allow_wg_lan,
417
+ config.dns_search_domains,
418
+ config.proxy,
419
+ self._peer_ips_proxy,
420
+ on_connect,
421
+ )
422
+ self._peer_ips_proxy = None
423
+
424
+ if config.proxy:
425
+ self.start_proxy(config.proxy, lambda: connect(config))
426
+ else:
427
+ connect(config)
428
+
429
+ def reconnect(self, callback: Optional[Callable] = None, prefer_tcp: bool = False):
430
+ def on_disconnected(success: bool):
431
+ if success:
432
+ self.activate_connection(callback, prefer_tcp=prefer_tcp)
433
+
434
+ # Reconnect
435
+ self.deactivate_connection(on_disconnected)
436
+
437
+ # https://github.com/eduvpn/documentation/blob/v3/API.md#session-expiry
438
+ def renew_session(self, callback: Optional[Callable] = None):
439
+ was_connected = self.common.in_state(State.CONNECTED)
440
+
441
+ @run_in_background_thread("reconnect")
442
+ def reconnect(success: bool = True):
443
+ if not success:
444
+ if callback:
445
+ callback(False)
446
+ return
447
+ # Delete the OAuth access and refresh token
448
+ # Start the OAuth authorization flow
449
+ self.common.renew_session()
450
+ # Automatically reconnect to the server
451
+ self.activate_connection(callback)
452
+
453
+ if was_connected:
454
+ # Call /disconnect and reconnect with callback
455
+ self.deactivate_connection(reconnect)
456
+ else:
457
+ reconnect()
458
+
459
+ def disconnect(self, callback: Optional[Callable] = None) -> None:
460
+ self.nm_manager.deactivate_connection(callback)
461
+
462
+ def set_profile(self, profile: str, connect=False):
463
+ was_connected = self.common.in_state(State.CONNECTED)
464
+
465
+ def do_profile(success: bool = True):
466
+ if not success:
467
+ return
468
+ # Set the profile ID
469
+ self.common.set_profile(profile)
470
+
471
+ # Connect if we should and if we were previously connected
472
+ if connect and was_connected:
473
+ self.activate_connection()
474
+
475
+ # Deactivate connection if we are connected
476
+ # and the connection should be modified
477
+ # the do_profile will be called in the callback
478
+ if was_connected and connect:
479
+ self.deactivate_connection(do_profile)
480
+ else:
481
+ do_profile()
482
+
483
+ def activate_connection(self, callback: Optional[Callable] = None, prefer_tcp: bool = False):
484
+ if (
485
+ not self.common.in_state(State.GOT_CONFIG)
486
+ and not self.common.in_state(State.DISCONNECTED)
487
+ and not self.common.in_state(State.MAIN)
488
+ ):
489
+ if callback:
490
+ logger.error("invalid state to activate connection")
491
+ callback(False)
492
+ return
493
+ if not self.current_server:
494
+ if callback:
495
+ logger.error("failed to get current server")
496
+ callback(False)
497
+ return
498
+
499
+ def on_connected(success: bool):
500
+ if callback:
501
+ callback(success)
502
+
503
+ self.connect(self.current_server, on_connected, prefer_tcp=prefer_tcp)
504
+
505
+ @run_in_background_thread("cleanup")
506
+ def cleanup(self, callback: Optional[Callable] = None):
507
+ # We retry this cleanup 2 times
508
+ retries = 2
509
+
510
+ # Try to cleanup with a number of retries
511
+ for i in range(retries):
512
+ logger.debug("Cleaning up tokens...")
513
+ try:
514
+ self.common.cleanup()
515
+ except Exception as e:
516
+ # We can try again
517
+ if i < retries - 1:
518
+ logger.debug(
519
+ f"Got an error: {str(e)} while cleaning up, try number: {i+1}. This could mean the connection was not fully disconnected yet. Trying again..."
520
+ )
521
+ else:
522
+ # All retries are done
523
+ logger.debug(f"Got an error: {str(e)} while cleaning up, after full retries: {i+1}.")
524
+ else:
525
+ break
526
+ if self.common.in_state(State.DISCONNECTING):
527
+ self.common.set_state(State.DISCONNECTED)
528
+ if callback:
529
+ callback()
530
+
531
+ def deactivate_connection(self, callback: Optional[Callable] = None, cleanup=True) -> None:
532
+ curr = None
533
+ if self.common.in_state(State.CONNECTED):
534
+ curr = State.CONNECTED
535
+
536
+ if self.common.in_state(State.CONNECTING):
537
+ curr = State.CONNECTING
538
+
539
+ if not curr:
540
+ return
541
+ self.common.set_state(State.DISCONNECTING)
542
+
543
+ def on_disconnected(success: bool):
544
+ if success:
545
+
546
+ def on_cleaned():
547
+ self.common.cancel()
548
+ if callback:
549
+ callback(True)
550
+
551
+ if cleanup:
552
+ self.cleanup(on_cleaned)
553
+ else:
554
+ if self.common.in_state(State.DISCONNECTING):
555
+ self.common.set_state(State.DISCONNECTED)
556
+ on_cleaned()
557
+ else:
558
+ try:
559
+ self.common.set_state(curr)
560
+ except WrappedError as e:
561
+ logger.debug(f"set_state error in deactivate connection: {str(e)}")
562
+ if callback:
563
+ callback(False)
564
+
565
+ self.disconnect(on_disconnected)
566
+
567
+ def search_predefined(self, query: str) -> Iterator[Any]:
568
+ return self.server_db.search_predefined(query)
569
+
570
+ def search_custom(self, query: str) -> Iterator[Any]:
571
+ return self.server_db.search_custom(query)
572
+
573
+
574
+ class Application:
575
+ def __init__(self, variant: ApplicationVariant, common: EduVPN) -> None:
576
+ self.variant = variant
577
+ self.nm_manager = nm.NMManager(variant)
578
+ self.common = common
579
+ directory = variant.config_prefix
580
+ self.config = Configuration.load(directory)
581
+ self.model = ApplicationModel(common, self.config, variant, self.nm_manager)
582
+
583
+ signal.signal(signal.SIGINT, lambda s, f: self.cleanup_sigint(s, f))
584
+
585
+ def cleanup_sigint(self, _signal, _frame):
586
+ self.model.cancel()
587
+ self.common.deregister()
588
+
589
+ def on_network_update_callback(self, state, initial=False):
590
+ try:
591
+ if state == nm.ConnectionState.CONNECTED:
592
+ if (
593
+ not self.common.in_state(State.DISCONNECTED)
594
+ and not self.common.in_state(State.GOT_CONFIG)
595
+ and not initial
596
+ ):
597
+ return
598
+ if not initial:
599
+ self.common.set_state(State.CONNECTING)
600
+ # Already connected
601
+ self.common.set_state(State.CONNECTED)
602
+ elif state == nm.ConnectionState.CONNECTING:
603
+ self.common.set_state(State.CONNECTING)
604
+ elif state == nm.ConnectionState.DISCONNECTED:
605
+ if not self.common.in_state(State.CONNECTED) and not self.common.in_state(State.CONNECTING):
606
+ return
607
+ self.common.set_state(State.DISCONNECTING)
608
+ self.model.cancel()
609
+ self.model.cleanup()
610
+ self.model.disconnect()
611
+ except Exception as e:
612
+ logger.debug(f"error occurred: {str(e)}")
613
+ return
614
+
615
+ def initialize_network(self, needs_update=True) -> None:
616
+ """
617
+ Determine the current network state.
618
+ """
619
+ # Check if a previous network configuration exists.
620
+ uuid = self.nm_manager.existing_connection
621
+ if uuid:
622
+ self.on_network_update_callback(self.nm_manager.connection_state, needs_update)
623
+
624
+ @run_in_background_thread("on-network-update")
625
+ def update(state):
626
+ self.on_network_update_callback(state, False)
627
+
628
+ self.nm_manager.subscribe_to_status_changes(update)