megadown 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. #!/bin/bash
  2. function url_str {
  3. echo $1\
  4. | awk '{gsub("-","+"); gsub("_","/"); gsub(",",""); print}'
  5. }
  6. function json_req {
  7. wget -q -O- --post-data="$1" --header='Content-Type:application/json' "https://g.api.mega.co.nz/cs$2"
  8. }
  9. function key_solver {
  10. echo -n $1 \
  11. | base64 --decode --ignore-garbage \
  12. 2> /dev/null \
  13. | xxd -p \
  14. | tr -d '\n'
  15. }
  16. function json_post {
  17. echo $2\
  18. | awk -v c=$1 -F'"' '{for(i = 1; i <= NF; i++)
  19. {if($i==c)
  20. if((c=="t")||(c=="s")||(c=="ts"))
  21. {gsub(/[[:punct:]]/,"",$(i+1));print $(i+1);}
  22. else
  23. {print $(i+2);}
  24. }
  25. }'
  26. }
  27. function key_dec {
  28. local var=$(key_solver "$(url_str $key)")
  29. echo $(url_str $1)\
  30. | openssl enc -a -d -A -aes-128-ecb -K $var -iv "00000000000000000000000000000000" -nopad \
  31. 2> /dev/null \
  32. | base64
  33. }
  34. function size {
  35. local i=0
  36. local var=$1
  37. local pad=$(((4-${#var}%4)%4))
  38. for i in $(seq 1 $pad); do
  39. var="$var="
  40. done
  41. echo $var
  42. }
  43. function meta_dec_key {
  44. local var
  45. var[0]=$(( 0x${1:00:16} ^ 0x${1:32:16} ))
  46. var[1]=$(( 0x${1:16:16} ^ 0x${1:48:16} ))
  47. meta_key=$(printf "%016x" ${var[*]})
  48. meta_iv="${1:32:16}0000000000000000"
  49. }
  50. function meta_dec {
  51. echo -n $2 \
  52. | openssl enc -a -A -d -aes-128-cbc -K $1 -iv "00000000000000000000000000000000" -nopad \
  53. | tr -d '\0' \
  54. 2> /dev/null
  55. }
  56. function mega_link_vars {
  57. if [[ "$1" == *"/#"* ]]; then
  58. id=`echo $1 | awk -F'!' '{print $2}'`
  59. key=`echo $1 | awk -F'!' '{print $3}'`
  60. fld=`echo $1 | awk -F'!' '{print $1}'`
  61. elif [[ "$1" == *"/folder"*"/file"* ]]; then
  62. fld=`echo $1 | awk '{gsub(/(folder\/).*/,"folder/");print}'`
  63. id=`echo $1 | awk -F'/' '{print $(NF-2)}' | awk -F# '{print $1}'`
  64. key=`echo $1 | awk -F'/' '{print $(NF-2)}' | awk -F# '{print $2}'`
  65. fid=`echo $1 | awk -F'/' '{print $NF}'`
  66. else
  67. fld=`echo $1 | awk '{gsub(/[^\/]*$/,"");print}'`
  68. id=`echo $1 | awk -F'/' '{print $NF}' | awk -F# '{print $1}'`
  69. key=`echo $1 | awk -F'/' '{print $NF}' | awk -F# '{print $2}'`
  70. fi
  71. }
  72. function file_downdec {
  73. echo $1
  74. echo $2
  75. echo $3
  76. echo $4
  77. wget -O "$2".tmp $speed -q --show-progress "$1"
  78. cat "$2.tmp" \
  79. | openssl enc -d -aes-128-ctr -K $3 -iv $4 \
  80. > "$2"
  81. rm -f "$2".tmp
  82. }
  83. function file_down {
  84. wget -O "$2".tmp $speed -q --show-progress "$1"
  85. mv "$2".tmp "$2"
  86. }
  87. function tree_gen {
  88. local i=0
  89. while [[ $i -lt $2 ]] && ! [[ ${names[i]} == "$1" ]]; do
  90. let i++
  91. done
  92. if ! [[ $i == $2 ]]; then
  93. tree_gen ${parents[i]} $2
  94. meta_dec_key "$(key_solver $(key_dec $(size ${keys[i]})))"
  95. file_name="$(json_post 'n' "$(meta_dec $meta_key $(size $(url_str ${attrs[i]})))")"
  96. path=$path/$file_name
  97. fi
  98. }
  99. function error {
  100. echo -e "\033[31merror\e[0m: $1" 1>&2
  101. exit 1
  102. }
  103. function mega {
  104. mega_link_vars $1
  105. if [ "${fld: -1}" == "F" ] || [[ "$fld" == *"folder"* ]];then
  106. json_req '[{"a":"f","c":1,"ca":1,"r":1}]' "?id=&n=$id" > .badown.tmp
  107. [[ $(file .badown.tmp) == *"gzip"* ]] && response1=$(cat .badown.tmp | gunzip) || response1=$(cat .badown.tmp)
  108. keys=($(json_post 'k' $response1 | awk -F':' '{print $2}'))
  109. names=($(json_post 'h' $response1 ))
  110. types=($(json_post 't' $response1 ))
  111. attrs=($(json_post 'a' $response1 ))
  112. sizes=($(json_post 's' $response1 ))
  113. parents=($(json_post 'p' $response1 ))
  114. for i in $(seq 0 $((${#types[@]}-1)));do
  115. unset path
  116. tree_gen ${parents[i]} $((${#types[@]}-1))
  117. meta_dec_key "$(key_solver $(key_dec $(size ${keys[i]})))"
  118. file_name="$(json_post 'n' "$(meta_dec $meta_key $(size $(url_str ${attrs[i]})))")"
  119. path=$path/$file_name
  120. #echo -e "===\n${keys[i]}\n${names[i]}\n${types[i]}\n${attrs[i]}\n${sizes[i]}\n${parents[i]}\n"
  121. #hint if specific folder is specified in names and parents hold value
  122. #probably modify the init phase of mega function to carry new argument of specific folder to download
  123. #maybe add if condition to test how path relate to folder we want to download
  124. if [ -z $fid ]; then
  125. if [ ${types[i]} == 1 ];then
  126. sleep .5;mkdir -p "$PWD$path"
  127. elif [ ${types[i]} == 0 ];then
  128. file_url=$(json_post 'g' $(json_req "[{\"a\":\"g\",\"g\":1,\"n\":\"${names[i]}\"}]" "?id=&n=$id"))
  129. file_downdec $file_url "$file_name" $meta_key $meta_iv
  130. sleep .5;mv "$file_name" "$PWD$path"
  131. fi
  132. else
  133. [ $fid == ${names[i]} ] &&\
  134. file_url=$(json_post 'g' $(json_req "[{\"a\":\"g\",\"g\":1,\"n\":\"${names[i]}\"}]" "?id=&n=$id")) &&\
  135. file_downdec $file_url "$file_name" $meta_key $meta_iv
  136. fi
  137. done
  138. elif [ "${fld: -1}" == "#" ] || [[ "$fld" == *"file"* ]];then
  139. meta_dec_key $(key_solver $(url_str $key))
  140. name_key=$(url_str $(json_post 'at' $(json_req "[{\"a\":\"g\", \"p\":\"$id\"}]" '?id=&ak=')))
  141. file_name="$(json_post 'n' "$(meta_dec $meta_key $(size $name_key))")"
  142. file_url=$(json_post 'g' $(json_req "[{\"a\":\"g\",\"g\":1,\"p\":\"$id\"}]" '?'))
  143. file_downdec $file_url "$file_name" $meta_key $meta_iv
  144. fi
  145. if [ -f .badown.tmp ]; then rm .badown.tmp;fi
  146. }
  147. function switch {
  148. if [[ "$1" == *"mega"* ]]
  149. then
  150. mega "$1"
  151. else
  152. showhelp;exit 1
  153. fi
  154. }
  155. function showhelp {
  156. echo -e "megadown 0.4b"
  157. echo -e "bash downloader for hostsite mega.io light edition"
  158. echo -e "https://github.com/stck-lzm/badown modded by wareck"
  159. echo -e "megadown [OPTION] ['URL']"
  160. echo -e "\tOptions:"
  161. echo -e "\t-s,\t--speed SPEED Download speed limit (integer values: 500B, 70K, 2M)."
  162. echo -e "\t-h,\t--help Display this help."
  163. echo -e ""
  164. echo -e ""
  165. }
  166. TEMP=$(getopt -o "s:h" --long "speed:,help" -n badown -- "$@")
  167. [ $? -eq 0 ] || {
  168. echo "Incorrect options provided"
  169. exit 1
  170. }
  171. eval set -- "$TEMP"
  172. while true; do
  173. case "$1" in
  174. -s|--speed) speed=" --limit-rate $2"; shift 2;;
  175. -h|--help) showhelp; exit 1;;
  176. --) shift; break;;
  177. **) showhelp;exit 1;;
  178. esac
  179. done
  180. switch $1