__init__ 24 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040
  1. #!/usr/bin/env bash
  2. # shellcheck shell=bash
  3. ################################################################################
  4. ######################### Main function (script init) ##########################
  5. ################################################################################
  6. function __main__() {
  7. local _FUNCTION_ID="__main__"
  8. local _STATE="0"
  9. # Stores the current date.
  10. readonly _cdate=$(date +%Y%m%d)
  11. # Variables related to the log file. Divided into three parts due
  12. # to the better possibility of manipulation for the user.
  13. # shellcheck disable=SC2154
  14. readonly _log_directory="${_rel}/log"
  15. # shellcheck disable=SC2154
  16. readonly _log_file="${_init_name}.${_cdate}.log"
  17. readonly _log_stdout="${_log_directory}/stdout.log"
  18. readonly _log_path="${_log_directory}/${_log_file}"
  19. # We check if we are a root user.
  20. if [[ "$EUID" -ne 0 ]] ; then
  21. printf "EUID is not equal 0 (no root user)\\n"
  22. _exit_ "1"
  23. fi
  24. # Path to import file.
  25. # shellcheck disable=SC2154
  26. readonly _import_path="${_src}/import"
  27. # External configuration file (-c|--config script param).
  28. config=""
  29. load_state="0"
  30. # Declaration of output variables (--debug and --verbose params).
  31. stdout_mode=""
  32. verbose_mode="false"
  33. # Enable/disable output colors.
  34. # shellcheck disable=SC2034
  35. s_color="true"
  36. # Declaration of total execution time.
  37. time_tracking="false"
  38. export _cmdtime_state="0"
  39. # Create multitor directory.
  40. readonly _multitor_directory="/var/lib/multitor"
  41. # We place here used commands at script runtime, as strings to anything
  42. # unnecessarily run.
  43. readonly commands=(basename dirname stat ps date grep cut sed awk chown \
  44. chmod mkdir pidof tor sudo nc kill \
  45. haproxy polipo privoxy hpts)
  46. # If you intend to specify the full path to the command we do it like:
  47. # readonly exec_gzip="/bin/gzip"
  48. # Stores the names of the missing commands.
  49. missing_hash=()
  50. missing_counter="0"
  51. for i in "${commands[@]}" ; do
  52. if [[ ! -z "$i" ]] ; then
  53. hash "$i" >/dev/null 2>&1 ; state="$?"
  54. # If the command was not found put it in the array
  55. if [[ "$state" -ne 0 ]] ; then
  56. missing_hash+=("$i")
  57. ((missing_counter++))
  58. fi
  59. fi
  60. done
  61. # It is a good idea to terminate the script at this stage
  62. # with information for the user to fix the errors if at least one
  63. # of the required commands in the commands array is not found.
  64. if [[ "$missing_counter" -gt 0 ]] ; then
  65. printf "not found in PATH: %s\\n" "${missing_hash[*]}" >&2
  66. _exit_ "1"
  67. fi
  68. if [[ "$time_tracking" == "true" ]] ; then
  69. _begtime=$(date +%s) ; fi
  70. # shellcheck disable=SC2154
  71. _logger "init" \
  72. "init '${_init_name}' in '${_init_directory}'" && \
  73. _logger "info" \
  74. "__init_params[] = (${__init_params[*]})," \
  75. "__script_params[] = (${__script_params[*]})"
  76. # Include import file.
  77. _load "null" "$_import_path"
  78. # Specifies the call parameters of the script, the exact description
  79. # can be found in _help_ and file README.md.
  80. local _short_opt="i:ksnu:"
  81. local _long_opt="help,debug,verbose,init:,kill,show-id,new-id,user:,socks-port:,control-port:,proxy:,haproxy"
  82. _GETOPT_PARAMS=$(getopt -o "${_short_opt}" --long "${_long_opt}" \
  83. -n "${_init_name}" -- "${__script_params[@]}")
  84. # With this structure, in the case of problems with the parameters placed
  85. # in the _GETOPT_PARAMS variable we finish the script. Keep this in mind
  86. # because it has some consequences - the __main __() function will not be
  87. # executed.
  88. # Ends an error if the parameter or its argument is not valid.
  89. _getopt_state="$?"
  90. if [ "$_getopt_state" != 0 ] ; then
  91. _exit_ "1"
  92. # Ends if no parameter is specified.
  93. elif [[ "${#__script_params[@]}" -eq 0 ]] ; then
  94. _exit_ "0"
  95. fi
  96. eval set -- "$_GETOPT_PARAMS"
  97. while true ; do
  98. case $1 in
  99. --help)
  100. _help_
  101. shift ; _exit_ "0" ;;
  102. --debug)
  103. export stdout_mode="debug"
  104. shift ;;
  105. --verbose)
  106. export verbose_mode="true"
  107. shift ;;
  108. -i|--init)
  109. export init_state="1"
  110. export init_number="${2}"
  111. shift 2 ;;
  112. -k|--kill)
  113. export kill_state="1"
  114. export kill_status="0"
  115. shift ;;
  116. -s|--show-id)
  117. export show_id_state="1"
  118. shift ;;
  119. -n|--new-id)
  120. export new_id_state="1"
  121. shift ;;
  122. -u|--user)
  123. export user_state="1"
  124. export user_name="${2}"
  125. shift 2 ;;
  126. --socks-port)
  127. export socks_port_state=1
  128. export socks_port_number="${2}"
  129. shift 2 ;;
  130. --control-port)
  131. export control_port_state=1
  132. export control_port_number="${2}"
  133. shift 2 ;;
  134. --proxy)
  135. export proxy_state=1
  136. export proxy_type="${2}"
  137. shift 2 ;;
  138. --haproxy)
  139. export frontend_state=1
  140. export frontend_type="haproxy"
  141. shift 2 ;;
  142. *)
  143. if [[ "$2" == "-" ]] || [[ ! -z "$2" ]] ; then
  144. printf "%s: invalid option -- '%s'\\n" "$_init_name" "$2"
  145. _exit_ "1"
  146. # elif [[ -z "$2" ]] ; then break ; fi
  147. else break ; fi
  148. ;;
  149. esac
  150. done
  151. # If you run the script in debug mode, the information
  152. # will be displayed on the screen from this point.
  153. if [[ "$stdout_mode" == "debug" ]] ; then
  154. _logger "info" \
  155. "${_FUNCTION_ID}()" \
  156. "starting debug mode"
  157. fi
  158. # Running tasks before start user functions.
  159. _before_init
  160. ################################# USER SPACE #################################
  161. # ````````````````````````````````````````````````````````````````````````````
  162. # Put here all your variable declarations, function calls
  163. # and all the other code blocks.
  164. # In this section we add external file (for -c|--config script param).
  165. if [[ "$load_state" -eq 1 ]] ; then _load "head" "$config" ; fi
  166. # shellcheck disable=SC2034
  167. # Generate random value.
  168. _random=$(date +"%s")
  169. # Array that stores the names of variables used that are part of the script
  170. # call parameters (_GETOPT_PARAMS). Useful when checking whether all
  171. # or selected parameters without which the script can not work properly
  172. # have been used. Do not add the load_state variable to the _opt_values array,
  173. # which is supported above.
  174. _opt_values=()
  175. local _tproc=""
  176. local _tor_processes_done=0
  177. local _tor_processes_fail=0
  178. local _tor_processes=0
  179. local _pass_gen
  180. local _pass_gen_ha
  181. local _pass_hash
  182. local _num='^[0-9]+$'
  183. local _proxy_list=("polipo" "privoxy" "hpts" "node")
  184. # Checking whether the variable value is a numeric value.
  185. if [[ "$init_number" =~ $_num ]] || \
  186. [[ "$socks_port_number" =~ $_num ]] || \
  187. [[ "$socks_port_number" == "all" ]] || \
  188. [[ "$control_port_number" =~ $_num ]] || \
  189. [[ "$control_port_number" == "all" ]] ; then
  190. # shellcheck disable=SC2034
  191. _ports_limit=$((65536 - init_number))
  192. # shellcheck disable=SC2154
  193. if [[ "$init_state" -eq 1 ]] && [[ "$init_number" -le 0 ]] ; then
  194. _sprintf "stop" "init_number is less or equal 0"
  195. _logger "stop" \
  196. "${_FUNCTION_ID}()" \
  197. "init_number is less then or equal 0"
  198. elif [[ "$socks_port_number" -ne "all" ]] || \
  199. [[ "$control_port_number" -ne "all" ]] ; then
  200. if [[ "$socks_port_state" -eq 1 && "$socks_port_number" -le 1023 ]] ; then
  201. _sprintf "stop" "value is less then or equal 1023"
  202. _logger "stop" \
  203. "${_FUNCTION_ID}()" \
  204. "value is less or equal 1023"
  205. elif [[ "$control_port_state" -eq 1 && "$control_port_number" -le 1023 ]] ; then
  206. _sprintf "stop" "value is less then or equal 1023"
  207. _logger "stop" \
  208. "${_FUNCTION_ID}()" \
  209. "value is less or equal 1023"
  210. elif [[ "$socks_port_state" -eq 1 && "$socks_port_number" -ge 65536 ]] ; then
  211. _sprintf "stop" "value is equal or grather then 65536"
  212. _logger "stop" \
  213. "${_FUNCTION_ID}()" \
  214. "value is equal or grather then 65536"
  215. elif [[ "$socks_port_state" -eq 1 && "$control_port_number" -ge 65536 ]] ; then
  216. _sprintf "stop" "value is equal or grather then 65536"
  217. _logger "stop" \
  218. "${_FUNCTION_ID}()" \
  219. "value is equal or grather then 65536"
  220. elif [[ "$socks_port_number" -gt "$_ports_limit" ]] || \
  221. [[ "$control_port_number" -gt "$_ports_limit" ]] ; then
  222. _sprintf "stop" "too many set processes"
  223. _logger "stop" \
  224. "${_FUNCTION_ID}()" \
  225. "too many set processes"
  226. elif [[ "$socks_port_number" -eq "$control_port_number" ]] ; then
  227. _sprintf "stop" "value mismatch"
  228. _logger "stop" \
  229. "${_FUNCTION_ID}()" \
  230. "value mismatch"
  231. fi
  232. fi
  233. else
  234. if [[ "$kill_state" -eq 1 ]] ; then
  235. true
  236. else
  237. _sprintf "stop" "no numeric value"
  238. _logger "stop" \
  239. "${_FUNCTION_ID}()" \
  240. "no numeric value"
  241. fi
  242. fi
  243. # Checking if the user exists.
  244. if [[ "$user_state" -eq 1 ]] ; then
  245. if ! id "$user_name" >/dev/null 2>&1 ; then
  246. _sprintf "stop" "incorrect user"
  247. _logger "stop" \
  248. "${_FUNCTION_ID}()" \
  249. "incorrect user"
  250. fi
  251. fi
  252. # Checking if proxy is set.
  253. if [[ "$proxy_state" -eq 1 ]] ; then
  254. if [[ "$proxy_type" == "socks" ]] || \
  255. [[ " ${_proxy_list[*]} " =~ $proxy_type ]] ; then
  256. _logger "info" \
  257. "${_FUNCTION_ID}()" \
  258. "correct proxy type: '$proxy_type'"
  259. else
  260. _sprintf "stop" "incorrect proxy type"
  261. _logger "stop" \
  262. "${_FUNCTION_ID}()" \
  263. "incorrect proxy type"
  264. fi
  265. fi
  266. # Checking if proxy is set for '--haproxy' param.
  267. if [[ "$frontend_state" -eq 1 ]] ; then
  268. if [[ "$proxy_state" -ne 1 ]] ; then
  269. _sprintf "stop" "not set '--proxy' param"
  270. _logger "stop" \
  271. "${_FUNCTION_ID}()" \
  272. "not set '--proxy' param"
  273. fi
  274. fi
  275. # We set the value of the variable depending on the call option.
  276. if [[ "$init_state" -eq 1 ]] ; then
  277. local _opt_values=("init_state" "init_number" \
  278. "user_state" "user_name" \
  279. "socks_port_state" "socks_port_number" \
  280. "control_port_state" "control_port_number")
  281. elif [[ "$kill_state" -eq 1 ]] ; then
  282. local _opt_values=("kill_state")
  283. elif [[ "$show_id_state" -eq 1 ]] || [[ "$new_id_state" -eq 1 ]] ; then
  284. local _opt_values=("socks_port_state" "socks_port_number")
  285. else
  286. _sprintf "stop" "one of the required parameters was not found"
  287. _logger "stop" \
  288. "${_FUNCTION_ID}()" \
  289. "one of the required parameters was not found"
  290. fi
  291. # Checking the value of the variables (if they are unset or empty):
  292. # - variables for call parameters
  293. # - variables from the additional configuration files
  294. if [[ "${#_opt_values[@]}" -ne 0 ]] ; then
  295. for i in "${_opt_values[@]}" ; do
  296. _i="" ; eval _i='$'"$i"
  297. _logger "info" \
  298. "${_FUNCTION_ID}()" \
  299. "$i: '$_i'"
  300. if [[ -z "$_i" ]] ; then
  301. _sprintf "stop" "error of argument value: '$i' is unset or empty"
  302. _logger "stop" \
  303. "${_FUNCTION_ID}()" \
  304. "error of argument value: '$i' is unset or empty"
  305. fi
  306. done
  307. fi
  308. if [[ "$init_state" -eq 1 ]] ; then
  309. # First, we remove current processes.
  310. # _tor_processes=($(pidof tor))
  311. IFS=" " read -r -a _tor_processes <<< "$(pidof "tor")"
  312. if [[ ${#_tor_processes[@]} -ne 0 ]] ; then
  313. for _tpr in "${_tor_processes[@]}" ; do
  314. # In this case, we can search for a specific identifier (${_tpr}).
  315. # shellcheck disable=SC2009
  316. _tproc=$(ps -ax | grep "multitor" | grep ".pid" | grep -v "grep" | grep "$_tpr")
  317. if [[ -z "$_tproc" ]] ; then
  318. _logger "warn" \
  319. "${_FUNCTION_ID}()" \
  320. "not found or unknown tor process"
  321. else
  322. DestroyProcess "${_tpr}"
  323. fi
  324. done
  325. else
  326. _logger "warn" \
  327. "${_FUNCTION_ID}()" \
  328. "not found tor processes: ${_tpr}"
  329. fi
  330. # Removed all multitor process data directory.
  331. find ${_multitor_directory}/* -delete >>"$_log_stdout" 2>&1
  332. # Generate random password.
  333. # Does storing the password in this form is security issue?
  334. # shellcheck disable=SC2034
  335. _pass_gen=$(< /dev/urandom tr -dc 'a-zA-Z0-9' | fold -w 18 | head -n 1)
  336. # shellcheck disable=SC2034
  337. _pass_hash=$(sudo -u "$user_name" tor --hash-password "$_pass_gen" | grep "16:")
  338. if [[ "$proxy_state" -eq 1 ]] ; then
  339. # shellcheck disable=SC2034,SC2154
  340. local _tml_ha0="${_tml}/haproxy-template.cfg"
  341. # shellcheck disable=SC2034,SC2154
  342. local _tml_po0="${_tml}/${proxy_type}-template.cfg"
  343. # shellcheck disable=SC2034,SC2154
  344. local _tml_ha1="${_etc}/haproxy.cfg"
  345. # shellcheck disable=SC2034,SC2154
  346. local _tml_po1="${_etc}/${proxy_type}.cfg"
  347. for _tfd in "$_tml_ha1" "$_tml_po1" ; do
  348. # shellcheck disable=SC2154
  349. if [[ -e "$_tfd" ]] ; then
  350. rm -fr "${_tfd}"
  351. fi
  352. done
  353. # Updated auth for HAProxy template configuration file.
  354. # shellcheck disable=SC2154
  355. cp "${_tml_ha0}" "${_tml_ha1}"
  356. # shellcheck disable=SC2034
  357. _pass_gen_ha=$(< /dev/urandom tr -dc 'a-zA-Z0-9' | fold -w 18 | head -n 1)
  358. sed -i "s/__PASSWORD__/$_pass_gen_ha/g" "${_tml_ha1}"
  359. unset _pass_gen_ha
  360. _proxy_ports=()
  361. else
  362. # Flush etc/ directory.
  363. rm -fr "${_etc:?}"/*
  364. fi
  365. for i in $(seq 0 $((init_number - 1))) ; do
  366. _logger "info" \
  367. "${_FUNCTION_ID}()" \
  368. "socks_port_number: '$socks_port_number', control_port_number: '$control_port_number'"
  369. CreateTorProcess "${user_name}" "${socks_port_number}" "${control_port_number}"
  370. # For proxy:
  371. _proxy_ports+=("$socks_port_number")
  372. # In this case, we can search for a specific identifier (${socks_port_number}).
  373. # shellcheck disable=SC2009
  374. _tproc=$(ps -ax | grep "multitor" | grep ".pid" | grep -v "grep" | grep "$socks_port_number")
  375. # We get process information and display it on the screen.
  376. GetTorProcess
  377. # shellcheck disable=SC2154
  378. if [[ "$socks_port_number" == "all" ]] ; then
  379. _tor_pid_status="true"
  380. if [[ "$verbose_mode" == "true" ]] ; then
  381. echo
  382. OutputGen
  383. fi
  384. elif [[ "$socks_port_number" -eq "$_tor_proc_socks" ]] ; then
  385. _tor_pid_status="true"
  386. if [[ "$verbose_mode" == "true" ]] ; then
  387. echo
  388. OutputGen
  389. fi
  390. else
  391. _tor_pid_status="false"
  392. printf " \\e[1;30msocks_port\\e[m: \\e[1;39m%s\\e[m\\n" "$_tor_proc_socks"
  393. printf " \\e[1;30mstatus\\e[m: \\e[1;31m%s\\e[m\\n" "$_tor_pid_status"
  394. fi
  395. socks_port_number=$((socks_port_number + 1))
  396. control_port_number=$((control_port_number + 1))
  397. done
  398. _proxy_processes_list=()
  399. # shellcheck disable=SC2034
  400. # Manages proxy processes stack.
  401. for _proc in "haproxy" "${_proxy_list[@]}" ; do
  402. CheckProxyProcess "${_proc}"
  403. done
  404. # shellcheck disable=SC2154
  405. for _hproc in "${_proxy_processes_list[@]}" ; do
  406. DestroyProcess "${_hproc}"
  407. done
  408. if [[ "$proxy_state" -eq 1 ]] ; then
  409. CreateProxyProcess
  410. fi
  411. # shellcheck disable=SC2034
  412. for _proc in "haproxy" "${_proxy_list[@]}" ; do
  413. CheckProxyProcess "${_proc}"
  414. done
  415. printf "\\n Set processes: \\e[0;39m%d\\e[m\\n" "$init_number"
  416. printf " Created: \\e[0;32m%d\\e[m\\n" "$_tor_processes_done"
  417. printf " Not created: \\e[0;31m%s\\e[m\\n" "$_tor_processes_fail"
  418. printf " Control password: \\e[2;38m%s\\e[m\\n\\n" "$_pass_gen"
  419. # shellcheck disable=SC2154
  420. if [[ ${#_proxy_processes_list[@]} -ne 0 ]] && [[ "$proxy_state" -eq 1 ]] ; then
  421. if [[ "$proxy_type" == "socks" ]] ; then
  422. printf " Proxy state: \\e[2;32m%s\\e[m (haproxy » %s)\\n\\n" "running" "$proxy_type"
  423. elif [[ "$frontend_type" == "haproxy" ]] ; then
  424. printf " Proxy state: \\e[2;32m%s\\e[m (haproxy » %s » socks)\\n\\n" "running" "$proxy_type"
  425. else
  426. printf " Proxy state: \\e[2;32m%s\\e[m (%s » haproxy » socks)\\n\\n" "running" "$proxy_type"
  427. fi
  428. else
  429. printf " Proxy state: \\e[2;31m%s\\e[m (only tor)\\n\\n" "disable"
  430. fi
  431. # Unset password variables.
  432. unset _pass_gen ; unset _pass_hash
  433. elif [[ "$kill_state" -eq 1 ]] ; then
  434. # First, we remove current processes.
  435. # _tor_processes=($(pidof tor))
  436. IFS=" " read -r -a _tor_processes <<< "$(pidof "tor")"
  437. if [[ ${#_tor_processes[@]} -ne 0 ]] ; then
  438. for _tpr in "${_tor_processes[@]}" ; do
  439. # In this case, we can search for a specific identifier (${_tpr}).
  440. # shellcheck disable=SC2009
  441. _tproc=$(ps -ax | grep "multitor" | grep ".pid" | grep -v "grep" | grep "$_tpr")
  442. if [[ -z "$_tproc" ]] ; then
  443. _logger "warn" \
  444. "${_FUNCTION_ID}()" \
  445. "not found or unknown tor process"
  446. else
  447. DestroyProcess "${_tpr}"
  448. kill_status="1"
  449. fi
  450. done
  451. else
  452. _logger "warn" \
  453. "${_FUNCTION_ID}()" \
  454. "not found tor processes: ${_tpr}"
  455. fi
  456. # Removed all multitor process data directory.
  457. find ${_multitor_directory}/* -delete >>"$_log_stdout" 2>&1
  458. # shellcheck disable=SC2034,SC2154
  459. local _tml_ha0="${_tml}/haproxy-template.cfg"
  460. # shellcheck disable=SC2034,SC2154
  461. local _tml_po0="${_tml}/${proxy_type}-template.cfg"
  462. # shellcheck disable=SC2034,SC2154
  463. local _tml_ha1="${_etc}/haproxy.cfg"
  464. # shellcheck disable=SC2034,SC2154
  465. local _tml_po1="${_etc}/${proxy_type}.cfg"
  466. for _tfd in "$_tml_ha1" "$_tml_po1" ; do
  467. # shellcheck disable=SC2154
  468. if [[ -e "$_tfd" ]] ; then
  469. rm -fr "${_tfd}"
  470. kill_status="1"
  471. fi
  472. done
  473. # Flush etc/ directory.
  474. rm -fr "${_etc:?}"/*
  475. # shellcheck disable=SC2034
  476. # Manages proxy processes stack.
  477. for _proc in "haproxy" "${_proxy_list[@]}" ; do
  478. CheckProxyProcess "${_proc}"
  479. done
  480. # shellcheck disable=SC2154
  481. for _hproc in "${_proxy_processes_list[@]}" ; do
  482. DestroyProcess "${_hproc}"
  483. kill_status="1"
  484. done
  485. if [[ "$kill_status" -eq 1 ]] ; then
  486. printf "Multitor processes: \\e[1;31m%s\\e[m\\n" "stop"
  487. fi
  488. elif [[ "$show_id_state" -eq 1 ]] ; then
  489. IFS=" " read -r -a _tor_processes <<< "$(pidof "tor")"
  490. if [[ ${#_tor_processes[@]} -ne 0 ]] ; then
  491. if [[ "$socks_port_number" == "all" ]] ; then
  492. for _tpr in "${_tor_processes[@]}" ; do
  493. # In this case, we can search for a specific identifier (${_tpr}).
  494. # shellcheck disable=SC2009
  495. _tproc=$(ps -ax | grep "multitor" | grep ".pid" | grep -v "grep" | grep "$_tpr")
  496. IFS=" " read -r -a _proc_socks_num_tmp <<< "$(echo "$_tproc" | awk '{print $13}')"
  497. _proc_socks_num+=("${_proc_socks_num_tmp[@]}")
  498. done
  499. # IFS=$'\n' read -r -a _proc_socks_num_sorted <<< "$(sort <<<"${_proc_socks_num[*]}")"
  500. # shellcheck disable=SC2207
  501. _proc_socks_num_sorted=( $( printf "%s\\n" "${_proc_socks_num[@]}" | sort -n ) )
  502. unset IFS
  503. for _tpr in "${_proc_socks_num_sorted[@]}" ; do
  504. # In this case, we can search for a specific identifier (${_tpr}).
  505. # shellcheck disable=SC2009
  506. _tproc=$(ps -ax | grep "multitor" | grep ".pid" | grep -v "grep" | grep "$_tpr")
  507. echo
  508. # We get process information and display it on the screen.
  509. GetTorProcess
  510. if [[ "$socks_port_number" == "all" ]] ; then
  511. _tor_pid_status="true"
  512. OutputGen
  513. elif [[ "$socks_port_number" -eq "$_tor_proc_socks" ]] ; then
  514. _tor_pid_status="true"
  515. OutputGen
  516. else
  517. _tor_pid_status="false"
  518. printf " \\e[1;30msocks_port\\e[m: \\e[1;39m%s\\e[m\\n" "$_tor_proc_socks"
  519. printf " \\e[1;30mstatus\\e[m: \\e[1;31m%s\\e[m\\n" "$_tor_pid_status"
  520. fi
  521. done
  522. else
  523. # In this case, we can search for a specific identifier (${socks_port_number}).
  524. # shellcheck disable=SC2009
  525. _tproc=$(ps -ax | grep "multitor" | grep ".pid" | grep -v "grep" | grep "$socks_port_number")
  526. if [[ -z "$_tproc" ]] ; then
  527. _sprintf "stop" "not found tor process"
  528. _logger "stop" \
  529. "${_FUNCTION_ID}()" \
  530. "not found tor process"
  531. else
  532. echo
  533. # We get process information and display it on the screen.
  534. GetTorProcess
  535. if [[ "$socks_port_number" == "all" ]] ; then
  536. _tor_pid_status="true"
  537. OutputGen
  538. elif [[ "$socks_port_number" -eq "$_tor_proc_socks" ]] ; then
  539. _tor_pid_status="true"
  540. OutputGen
  541. else
  542. _tor_pid_status="false"
  543. _sprintf "stop" "not found tor process"
  544. _logger "stop" \
  545. "${_FUNCTION_ID}()" \
  546. "not found tor process"
  547. fi
  548. fi
  549. fi
  550. else
  551. _sprintf "stop" "not found tor process"
  552. _logger "stop" \
  553. "${_FUNCTION_ID}()" \
  554. "not found tor process"
  555. fi
  556. echo
  557. elif [[ "$new_id_state" -eq 1 ]] ; then
  558. _output_tparams=()
  559. if [[ "$socks_port_number" == "all" ]] ; then
  560. IFS=" " read -r -a _tor_processes <<< "$(pidof "tor")"
  561. else
  562. _tor_processes=("$socks_port_number")
  563. fi
  564. # Password required at this stage.
  565. read -rsp "Enter password: " _pass_in
  566. echo
  567. if [[ ${#_tor_processes[@]} -ne 0 ]] ; then
  568. for _tpr in "${_tor_processes[@]}" ; do
  569. # In this case, we can search for a specific identifier (${_tpr}).
  570. # shellcheck disable=SC2009
  571. _tproc=$(ps -ax | grep "multitor" | grep ".pid" | grep -v "grep" | grep "$_tpr")
  572. if [[ -z "$_tproc" ]] ; then
  573. _logger "warn" \
  574. "${_FUNCTION_ID}()" \
  575. "not found or unknown tor process"
  576. else
  577. # We get process information.
  578. GetTorProcess
  579. if [[ "$socks_port_number" == "all" ]] ; then
  580. _tor_pid_status="true"
  581. elif [[ "$socks_port_number" -eq "$_tor_proc_socks" ]] ; then
  582. _tor_pid_status="true"
  583. else
  584. _tor_pid_status="false"
  585. fi
  586. # shellcheck disable=SC2154
  587. _newnym=$(printf "AUTHENTICATE \"%s\"\\r\\nSIGNAL NEWNYM\\nQUIT\\n" "${_pass_in}" \
  588. | nc 127.0.0.1 "$_tor_proc_control")
  589. if echo "$_newnym" | grep -qi "250 closing connection" ; then
  590. _identity_state="true"
  591. elif echo "$_newnym" | grep -q "Authentication failed" ; then
  592. _identity_state="false"
  593. else
  594. _identity_state="false"
  595. fi
  596. _output_tparams+=("$_tor_proc_id":"$_tor_proc_socks":"$_tor_proc_control":"$_identity_state")
  597. fi
  598. done
  599. else
  600. _sprintf "stop" "not found tor process"
  601. _logger "stop" \
  602. "${_FUNCTION_ID}()" \
  603. "not found tor process"
  604. fi
  605. unset _pass_in
  606. for i in "${_output_tparams[@]}" ; do
  607. # shellcheck disable=SC2034
  608. _key_id=$(echo "$i" | awk -v FS="(:|:)" '{print $1}')
  609. # shellcheck disable=SC2034
  610. _key_socks=$(echo "$i" | awk -v FS="(:|:)" '{print $2}')
  611. # shellcheck disable=SC2034
  612. _key_control=$(echo "$i" | awk -v FS="(:|:)" '{print $3}')
  613. # shellcheck disable=SC2034
  614. _key_state=$(echo "$i" | awk -v FS="(:|:)" '{print $4}')
  615. if [[ "$_key_state" == "true" ]] ; then
  616. printf "New identity for \\e[1;39m%d\\e[m: \\e[0;32m%s\\e[m\\n" "$_key_id" "regenerated"
  617. else
  618. if [[ "$_tor_pid_status" == "false" ]] ; then
  619. _logger "warn" \
  620. "${_FUNCTION_ID}()" \
  621. "not found or unknown tor process"
  622. printf "New identity for \\e[1;39m%d\\e[m: \\e[0;31m%s\\e[m\\n" "$_key_id" "unknown"
  623. else
  624. printf "New identity for \\e[1;39m%d\\e[m: \\e[0;31m%s\\e[m\\n" "$_key_id" "failed"
  625. fi
  626. fi
  627. done
  628. fi
  629. # ````````````````````````````````````````````````````````````````````````````
  630. if [[ "$time_tracking" == "true" ]] ; then
  631. # Counting the execution time.
  632. _endtime=$(date +%s)
  633. _totaltime=$((_endtime - _begtime))
  634. # Print time header.
  635. printf '\\e[m\\e[1;39mTOTAL TIME: %dh:%dm:%ds\\e[m\n' \
  636. $((_totaltime/3600)) $((_totaltime%3600/60)) $((_totaltime%60))
  637. fi
  638. return "$_STATE"
  639. }