1#!/bin/sh
2
3#
4# Copyright (C) 2013 The Android Open Source Project
5#
6# Licensed under the Apache License, Version 2.0 (the "License");
7# you may not use this file except in compliance with the License.
8# You may obtain a copy of the License at
9#
10#      http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS,
14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15# See the License for the specific language governing permissions and
16# limitations under the License.
17#
18
19# Set the PPP username and password to be used when making connections on
20# a cellular service.
21
22PROGRAM=$(basename $0)
23FLAGS_HELP="Usage:
24
25Show current PPP username
26  ${PROGRAM}
27
28Set PPP username and/or password
29  ${PROGRAM} [-u <username>] [-p <password>]
30
31Clear PPP username and password
32  ${PROGRAM} -c
33"
34
35. /usr/share/misc/shflags
36
37DEFAULT_PROFILE_NAME=default
38FLIMFLAM=org.chromium.flimflam
39IMANAGER=${FLIMFLAM}.Manager
40IPROFILE=${FLIMFLAM}.Profile
41ISERVICE=${FLIMFLAM}.Service
42PASSWORD_PROPERTY=Cellular.PPP.Password
43PROFILE_PROPERTY=Profile
44USERNAME_PROPERTY=Cellular.PPP.Username
45
46usage() {
47  echo "$*"
48  echo
49  flags_help
50  exit 1
51}
52
53dbus() {
54  local object="$1"
55  local method="$2"
56  shift 2
57
58  dbus-send --system --print-reply --fixed --dest="${FLIMFLAM}" \
59    "${object}" "${method}" "$@"
60}
61
62get_property() {
63  local interface="${1:?internal error}"
64  local object="${2:?internal error}"
65  local property="${3:?nternal error}"
66
67  dbus "${object}" "${interface}.GetProperties" 2>/dev/null \
68    | sed -n "/\/${property}/{s/.* //p}"
69}
70
71display_username() {
72  local service="$1"
73  local username="$(get_property ${ISERVICE} ${service} ${USERNAME_PROPERTY})"
74
75  if [ -n "${username}" ]; then
76    echo "PPP username: " ${username}
77    exit 0
78  fi
79
80  echo "No PPP username."
81  exit 0
82}
83
84set_username() {
85  local service="$1"
86  local username="$2"
87
88  echo "Setting PPP username \"${username}\" for service ${service}"
89  dbus "${service}" "${ISERVICE}.SetProperty" \
90    "string:${USERNAME_PROPERTY}" "variant:string:${username}"
91}
92
93set_password() {
94  local service="$1"
95  local password="$2"
96
97  echo "Setting PPP pasword for service ${service}"
98  dbus "${service}" "${ISERVICE}.SetProperty" \
99    "string:${PASSWORD_PROPERTY}" "variant:string:${password}"
100}
101
102clear_property() {
103  local service="$1"
104  local property="$2"
105
106  echo "Clearing ${property} for service ${service}"
107  dbus "${service}" "${ISERVICE}.ClearProperty" "string:${property}"
108}
109
110get_profiles() {
111  dbus / "${IMANAGER}.GetProperties" 2>/dev/null \
112    | sed -n "/\/Profiles\//{s/.* //p}"
113}
114
115get_services() {
116  dbus / "${IMANAGER}.GetProperties" 2>/dev/null \
117    | sed -n "/\/Services\//{s/.* //p}"
118}
119
120get_default_profile() {
121  local profile
122  local profile_name
123
124  for profile in $(get_profiles); do
125    profile_name="$(get_property ${IPROFILE} ${profile} Name)"
126    if [ ${profile_name} = ${DEFAULT_PROFILE_NAME} ]; then
127      echo "${profile}"
128      break
129    fi
130  done
131}
132
133get_first_cellular_service() {
134  local service
135  local service_type
136
137  for service in $(get_services); do
138    service_type="$(get_property ${ISERVICE} ${service} Type)"
139    if [ "${service_type}" = "cellular" ]; then
140      echo "${service}"
141      break
142    fi
143  done
144}
145
146move_service_to_profile() {
147  local service="$1"
148  local profile="$2"
149
150  if [ -z "${service}" ]; then
151    return 1
152  fi
153
154  if [ -z "${profile}" ]; then
155    return 1
156  fi
157
158  dbus "${service}" "${ISERVICE}.SetProperty" \
159    "string:${PROFILE_PROPERTY}" "variant:string:${profile}"
160
161  local new_profile=$(
162    get_property "${ISERVICE}" "${service}" "${PROFILE_PROPERTY}")
163  if [ "${new_profile}" != "${profile}" ]; then
164    return 1
165  else
166    return 0
167  fi
168}
169
170service="$(get_first_cellular_service)"
171if [ -z "${service}" ]; then
172  echo "No cellular service exists."
173  exit 1
174fi
175
176if [ $# -lt 1 ]; then
177  display_username "${service}"
178fi
179
180DEFINE_string 'username' "" 'PPP username for the Service' 'u'
181DEFINE_string 'password' "" 'PPP password for the Service' 'p'
182DEFINE_boolean 'clear' false \
183  'clear any username and password that has been previously set' 'c'
184FLAGS "$@" || exit 1
185eval set -- "${FLAGS_ARGV}"
186
187if [ "${FLAGS_clear}" -ne 0 ]; then
188  if [ $# -ne 0 ]; then
189    usage "Too many arguments."
190  fi
191  if [ -n "${FLAGS_username}" ]; then
192    set_username "${service}" "${FLAGS_username}"
193  fi
194  if [ -n "${FLAGS_password}" ]; then
195    set_password "${service}" "${FLAGS_password}"
196  fi
197  echo  #  newline to separate from set_username/set_password output
198  if move_service_to_profile "${service}" "$(get_default_profile)"; then
199    cat <<-END
200	When your cellular dongle is connected to the system, its connection
201	will be available to any user of this Chromebook, including guest users.
202
203	If you want to leave the dongle connected, without sharing its
204	connection with other users, you will need to clear the PPP username
205	and password by running the following command:
206	        ${PROGRAM} -c
207
208	If you clear the PPP username and password, you will need to re-run
209	${PROGRAM} the next time you need to connect.
210END
211  else
212    cat <<-END
213	Your cellular connection could not be configured for sharing with
214	other users of this Chromebook. If you would like to share this
215	connection with them, please try running this command again.
216END
217  fi
218else
219  if [ $# -ne 0 ]; then
220    usage "Too many arguments."
221  fi
222  clear_property "${service}" "${USERNAME_PROPERTY}"
223  clear_property "${service}" "${PASSWORD_PROPERTY}"
224fi
225