├── .github
├── FUNDING.yml
└── workflows
│ └── main.yml
├── LICENSE
├── README.md
├── images
├── demo.gif
└── logo.png
└── tmpsms
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 | custom: https://www.buymeacoffee.com/sdushantha
3 |
--------------------------------------------------------------------------------
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | # This is a basic workflow to help you get started with Actions
2 |
3 | name: Shellcheck
4 |
5 | # Triggers the workflow on push or pull request on all branches
6 | on: [push, pull_request]
7 |
8 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel
9 | jobs:
10 | # This workflow contains a single job called "build"
11 | build:
12 | # The type of runner that the job will run on
13 | runs-on: ubuntu-latest
14 |
15 | # Steps represent a sequence of tasks that will be executed as part of the job
16 | steps:
17 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
18 | - uses: actions/checkout@v2
19 |
20 | # Runs a set of commands using the runners shell
21 | - name: Run shellcheck
22 | run: |
23 | shellcheck -s sh tmpsms
24 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Siddharth Dushantha
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # tmpsms no longer works
2 |
3 | tmpsms was pretty much a wrapper around [Upmasked's](https://upmasked.com/) temporary SMS service but Upmasked seems to have taken down their website as well as their [GitHub account](https://github.com/upmasked/). `tmpsms` may come back in the future if I can find another reliable SMS service. But even if I do find one sometime soon, it unlikely I will further develop `tmpsms` to use that service as I have other priorities.
4 |
5 | ----
6 |
7 |
8 |
9 |
10 |
11 | A temporary SMS right from your terminal written in POSIX sh
12 |
13 |
14 |
15 |
16 | `tmpsms` is a command line utility written in POSIX `sh` that allows you to get a
17 | temporary phone number and receive SMSes. It uses [Upmasked](https://upmasked.com/) temporary SMS service in order to receive the messages. This is a very useful
18 | tool for those testing applications during bug bounty hunting or who just need some privacy and don't want to use a personal phone number.
19 | This is easy to use with simple outputs. `tmpsms` can be integrated with other scripts to improve your workflow.
20 |
21 | ## Dependencies
22 | - `curl`
23 | - [`jq`](https://github.com/stedolan/jq)
24 | - [`fzf`](https://github.com/junegunn/fzf)
25 |
26 | ## Installation
27 | ```bash
28 | # Download the tmpsms file and make it executable
29 | $ curl -L "https://git.io/tmpsms" > tmpsms && chmod +x tmpsms
30 |
31 | # Then move it somewhere in your $PATH. Here is an example:
32 | $ mv tmpsms ~/bin/
33 | ```
34 |
35 | ## Usage
36 | ```console
37 | $ tmpsms --help
38 | tmpsms [--count ]
39 | tmpsms init [--fzf ]
40 | tmpsms -h | --version
41 |
42 | When called with no options or commands, tmpsms lists
43 | the 3 newest messages.
44 |
45 | Options
46 | -h, --help Show this help message
47 | -c, --count Only show the newest messages
48 | --version Show version
49 |
50 | Commands
51 | init Initialize a new phone number by selecting one
52 | from the available ones using 'fzf'
53 | --fzf Extra arguments to use for 'fzf'
54 | ```
55 |
56 | ## Examples
57 | Initialize a new phone number
58 | ```console
59 | $ tmpsms init
60 | ```
61 |
62 | View the 5 newest messages. By default `tmpsms` shows the 3 newest messages.
63 | ```console
64 | $ tmpsms --count 5
65 | ```
66 |
67 | If you find it a hassle to rerun `tmpsms` every few seconds, use `watch` with a delay of 5 seconds. Upmasked only updates messages every 5 seconds.
68 | ```console
69 | $ watch -n 5 "tmpsms"
70 | ```
71 |
--------------------------------------------------------------------------------
/images/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdushantha/tmpsms/06bd6b0fc89485096ec51dede3f72806c158daac/images/demo.gif
--------------------------------------------------------------------------------
/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdushantha/tmpsms/06bd6b0fc89485096ec51dede3f72806c158daac/images/logo.png
--------------------------------------------------------------------------------
/tmpsms:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | #
3 | # by Siddharth Dushantha
4 | #
5 |
6 | VERSION="1.0.0"
7 |
8 | # Everything related to 'tmpsms' will be stored in this directory. Once the
9 | # computer get restarted, this directory gets deleted.
10 | TMPSMS_DIR="/tmp/tmpsms"
11 |
12 | # The phone number that the user has selected gets stored in this file so that
13 | # the do not have reselect at ever run.
14 | TMPSMS_PHONE_NUMBER="$TMPSMS_DIR/phonenumber.txt"
15 |
16 | # 'fzf' is used to allow the user to select a phone number. This variable
17 | # stores extra arguments which the user might to provide, so that 'fzf'
18 | # behaves to their liking.
19 | FZF_ARGUMENTS=""
20 |
21 | # The temporary SMS service is provided by Upmasked
22 | API="https://upmasked.com"
23 |
24 | usage(){
25 | # Using 'cat << EOF' we can easily output a multiline text. This is much
26 | # better than using 'echo' for each line or using '\n' to create a new line.
27 | cat <]
29 | tmpsms init [--fzf ]
30 | tmpsms -h | --version
31 |
32 | When called with no options or commands, tmpsms lists
33 | the 3 newest messages.
34 |
35 | Options
36 | -h, --help Show this help message
37 | -c, --count Only show the newest messages
38 | --version Show version
39 |
40 | Commands
41 | init Initialize a new phone number by selecting one
42 | from the available ones using 'fzf'
43 | --fzf Extra arguments to use for 'fzf'
44 | EOF
45 | }
46 |
47 | print_error(){
48 | # Print error message
49 | #
50 | # The first argument provided to this function will be the error message.
51 | # Script will exit after printing the error message.
52 | printf "%s\n" "Error: $1" >&2
53 | exit 1
54 | }
55 |
56 |
57 | select_phone_number(){
58 | # There are 2 ways which this function is called in this script.
59 | # [1] The user wants to initilize a new phone number by running 'tmpsms init'
60 | # [2] The user runs 'tmpsms' to check for new messages, but $TMPSMS_PHONE_NUMBER
61 | # does't exist. Therefore they have to select phone number before we can
62 | # show them the messages.
63 | #
64 | # When the function 'select_phone_number()' is called with the argument 'true'
65 | # that means this function was called becaues the user ran 'tmpsms init'
66 | #
67 | # We need this variable so we can know whether or not we need to show the user
68 | # the phone number they have selected. If they ran 'tmpsms init', then we will
69 | # show them the phone number they selected. This is so that they can easily
70 | # copy and paste it to whatever site that needs the phone number.
71 | EXTERNALLY=${1:-false}
72 |
73 | # Fetch the available phone numbers
74 | DATA=$(curl -s "$API/api/sms/numbers")
75 |
76 | # Using 'jq' we are able to get the length of the JSON data retreived from
77 | # API. The length indicates the the total number of phone numbers available.
78 | DATA_LENGTH=$(printf %s "$DATA" | jq length)
79 |
80 | # This is where we store the phone numbers which then gets shown to the user
81 | # through 'fzf' so that they can select one.
82 | PHONE_NUMBERS=""
83 |
84 | index=1
85 | while [ $index -le "$DATA_LENGTH" ]; do
86 | # Since arrays in JSON data start at 0, we must subtract
87 | # the value of $index by 1 so that we dont miss one of the
88 | # phone numbers in the array
89 | PHONE_NUMBER_INFO=$(printf %s "$DATA" | jq -r ".[$index-1]")
90 | PHONE_NUMBER=$(printf %s "$PHONE_NUMBER_INFO" | jq -r ".number")
91 | COUNTRY_CODE=$(printf %s "$PHONE_NUMBER_INFO" | jq -r ".country")
92 |
93 | PHONE_NUMBERS="$PHONE_NUMBERS$COUNTRY_CODE +$PHONE_NUMBER\n"
94 | index=$((index+1))
95 | done
96 |
97 | # By default we use 'fzf' without any arguments in order to display the
98 | # phone numbers they can use. If the '--fzf' argument is passed along with
99 | # 'fzf' arguments, 'tmpsms' will make sure to use them.
100 | FZF_COMMAND="fzf"
101 | [ -n "$FZF_ARGUMENTS" ] && FZF_COMMAND="fzf $FZF_ARGUMENTS"
102 |
103 | # If the user did not select a phone number then quit 'tmpsms' as the
104 | # user might have just wanted to check if there were any new number
105 | # that they could use.
106 | SELECTION=$(printf %b "$PHONE_NUMBERS" | $FZF_COMMAND)
107 | [ -z "$SELECTION" ] && print_error "Phone number was not selected"
108 |
109 | # Store the selected phone number in $TMPSMS_PHONE_NUMBER for later use
110 | printf %s "$SELECTION" > "$TMPSMS_PHONE_NUMBER"
111 |
112 | # If the user ran 'tmpsms init', then show them their selection
113 | [ "$EXTERNALLY" = true ] && printf "%s\n" "$SELECTION"
114 | }
115 |
116 | list_messages(){
117 | # By default, the 3 newest messages are shown. But if the user would like
118 | # to see more of the messages, they can provide how many they want to see
119 | # by using the '--count' option.
120 | COUNT="${1:-3}"
121 |
122 | # The provided value to '--count' must be an interger. We can verify that it is
123 | # an integer by checking if $COUNT matches the regex.
124 | REGEX='^[0-9]+$'
125 | if ! printf %s "$COUNT" | grep -Eq "$REGEX";then
126 | print_error "'$COUNT' is not an integer"
127 | fi
128 |
129 | # If /tmp/tmpsms/phonenumber.txt does not exist or is empty that means that
130 | # the user has not initialized a phone number yet.
131 | [ ! -s "$TMPSMS_PHONE_NUMBER" ] && print_error "A phone number must be initilzied in order to view the messages"
132 |
133 | # The country code is needed because it gets displayed to the user. It may
134 | # be useful for the user to know which country the phone number is from
135 | # so that they dont have to guess by looking at the area code.
136 | COUNTRY_CODE=$(awk -F" " '{print $1}' < $TMPSMS_PHONE_NUMBER)
137 | PHONE_NUMBER=$(awk -F"+" '{print $2}' < $TMPSMS_PHONE_NUMBER)
138 | DATA=$(curl -s "$API/api/sms/messages/$PHONE_NUMBER")
139 |
140 | # Even though we are using the phone numbers that are available on
141 | # upmasked.com, there is a chance that they might remove one of the numbers.
142 | # The checking needs to be done in case the phone number that is stored in
143 | # $TMPSMS_PHONE_NUMBER has been removed.
144 | if printf %s "$DATA" | grep -Eq "Not Found"; then
145 | print_error "Looks like the phone number '+$PHONE_NUMBER' no longer exists. Initialize a new one and try again."
146 | fi
147 |
148 | DATA_LENGTH=$(printf %s "$DATA" | jq length)
149 |
150 | # If the number of messages the user wants to view is greater than the
151 | # number of messages that are available, then make sure to show
152 | # all the messages that are available.
153 | [ "$COUNT" -gt "$DATA_LENGTH" ] && COUNT="$DATA_LENGTH"
154 |
155 | # Show a nice little header before showing the messages
156 | printf "%s\n\n" "[ Messages for +$PHONE_NUMBER ($COUNTRY_CODE) ]"
157 |
158 | # All the messages get stored in here
159 | MESSAGES=""
160 |
161 | index=1
162 | while [ $index -le "$COUNT" ]; do
163 | # Since arrays in JSON data start at 0, we must subtract
164 | # the value of $index by 1 so that we dont miss one of the
165 | # messages in the array
166 | MESSAGE_DATA=$(printf %s "$DATA" | jq -r ".[$index-1]")
167 | BODY=$(printf %s "$MESSAGE_DATA" | jq -r ".body" | tr "\n" " ")
168 | SENDER=$(printf %s "$MESSAGE_DATA" | jq -r ".originator")
169 |
170 | # The '||' is used as a divider for 'column'. 'column' will use this
171 | # divider as a point of reference to create the division. By default
172 | # 'column' uses a blank space but that would not work in our case as the
173 | # message could have multiple white spaces and 'column' would
174 | # split the words that are seperated by white space, in different columns.
175 | MESSAGES="$MESSAGES$SENDER ||$BODY\n"
176 |
177 | index=$((index+1))
178 | done
179 |
180 | # Show the messages cleanly
181 | printf "%b" "$MESSAGES" | column -t -s "||"
182 | }
183 |
184 | main(){
185 | # Iterate the array of dependencies and check if the user has them installed.
186 | for dependency in jq curl fzf; do
187 | if ! command -v "$dependency" >/dev/null 2>&1; then
188 | print_error "Could not find '$dependency', is it installed?"
189 | fi
190 | done
191 |
192 | # Create the $TMPSMS_DIR directory and dont throw any errors
193 | # if it already exists
194 | mkdir -p "$TMPSMS_DIR"
195 |
196 | # If no arguments are provided just show the messages
197 | [ $# -eq 0 ] && list_messages && exit 0
198 |
199 | while [ "$1" ]; do
200 | case "$1" in
201 | init)
202 | case "$2" in
203 | --fzf) FZF_ARGUMENTS="$3" && select_phone_number true ;;
204 | "") select_phone_number true ;;
205 | esac ;;
206 | --help | -h) usage && exit ;;
207 | --count | -c) list_messages "$2" && shift 2;;
208 | --version) printf %s "$VERSION" && exit ;;
209 | -*) print_error "option '$1' does not exist" ;;
210 | *) print_error "command '$1' does not exist" ;;
211 | esac
212 | shift
213 | done
214 | }
215 |
216 | main "$@"
217 |
--------------------------------------------------------------------------------