ProxyAuth
Linux PAM to authenticate device via Bluetooth device
deauth.c
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <fcntl.h>
5 #include <bluetooth/bluetooth.h>
6 #include <bluetooth/rfcomm.h>
7 #include <bluetooth/sdp.h>
8 #include <bluetooth/sdp_lib.h>
9 #include <errno.h>
10 #include <limits.h>
11 #include <sys/select.h>
12 #include <sys/socket.h>
13 #include <sys/stat.h>
14 #include <sys/time.h>
15 #include <sys/types.h>
16 #include <time.h>
17 #include <unistd.h>
18 
19 #include "pam_misc.h"
20 #include "pam_bt_misc.h"
21 #include "pam_bt_pair.h"
22 #include "pam_bt_trust.h"
23 #include "proxy_dbus.h"
24 
25 
26 #define SERVICE_NAME "Proxy Auth"
27 #define SERVICE_DESC "Continuous Authentication via Bluetooth"
28 #define SERVICE_PROV "ProxyAuth"
29 #define minThroughput 100 //Min Throughput varies depending on devices and work scenarios. Calibrate as needed.
30 
38 sdp_session_t *sdp_connect( const bdaddr_t *src, const bdaddr_t *dst, uint32_t flags );
39 
40 int sdp_close( sdp_session_t *session );
41 
42 int sdp_record_register(sdp_session_t *sess, sdp_record_t *rec, uint8_t flags);
43 
44 void terminate_server(int server, int client, sdp_session_t *session) {
45  if (client) {
46  close(client);
47  }
48  if (server) {
49  close(server);
50  }
51  if (session) {
52  sdp_close(session);
53  }
54 }
55 
65 void set_service(uuid_t *svc_uuid, uuid_t *svc_class_uuid, sdp_list_t **svc_class_list, sdp_record_t *record, uint32_t *svc_uuid_int) {
66  /* set the general service ID */
67 
68  //set svc_uuid (service uuid) by creating an unreserved 128-bit UUID from svc_uuid_int (a list of 4 32-bit uuid).
69  //sdp_uuid128_create is similar to str2ba function which converts the uint32_t uuid (rather than a string) to uuid_t type
70  sdp_uuid128_create(svc_uuid, svc_uuid_int);
71  sdp_set_service_id(record, *svc_uuid);
72 
73  char str[256] = "";
74  sdp_uuid2strn(svc_uuid, str, 256);
75  printf("Registering UUID %s\n", str);
76 
77  // set the service class
78  sdp_uuid16_create(svc_class_uuid, SERIAL_PORT_SVCLASS_ID); //create a Service Class ID
79  *svc_class_list = sdp_list_append(0, svc_class_uuid);
80  sdp_set_service_classes(record, *svc_class_list);
81 }
82 
86 void set_bluetooth_service_info(sdp_profile_desc_t *profile, sdp_list_t **profile_list, sdp_record_t *record) {
87  // set the Bluetooth profile information
88  sdp_uuid16_create(&(profile->uuid), SERIAL_PORT_PROFILE_ID); //create a Profile ID
89  profile->version = 0x0100;
90  *profile_list = sdp_list_append(0, profile);
91  sdp_set_profile_descs(record, *profile_list);
92 }
93 
97 void set_browsable(sdp_list_t **root_list, sdp_record_t *record, uuid_t *root_uuid) {
98  sdp_uuid16_create(root_uuid, PUBLIC_BROWSE_GROUP);
99  *root_list = sdp_list_append(0, root_uuid);
100  sdp_set_browse_groups(record, *root_list);
101 }
102 
106 void set_l2cap_info(sdp_list_t **l2cap_list, sdp_list_t **proto_list, uuid_t *l2cap_uuid) {
107  sdp_uuid16_create(l2cap_uuid, L2CAP_UUID);
108  *l2cap_list = sdp_list_append(0, l2cap_uuid);
109  *proto_list = sdp_list_append(0, *l2cap_list);
110 }
111 
116  sdp_data_t **channel,
117  sdp_record_t *record,
118  sdp_list_t **rfcomm_list,
119  sdp_list_t **proto_list,
120  sdp_list_t **access_proto_list,
121  uuid_t *rfcomm_uuid,
122  uint8_t *rfcomm_channel
123  ) {
124  // register the RFCOMM channel for RFCOMM sockets
125  sdp_uuid16_create(rfcomm_uuid, RFCOMM_UUID);
126  *channel = sdp_data_alloc(SDP_UINT8, rfcomm_channel);
127  *rfcomm_list = sdp_list_append(0, rfcomm_uuid);
128  sdp_list_append(*rfcomm_list, *channel);
129  sdp_list_append(*proto_list, *rfcomm_list);
130 
131  *access_proto_list = sdp_list_append(0, *proto_list);
132  sdp_set_access_protos(record, *access_proto_list);
133 }
134 
135 sdp_session_t *register_service(uint8_t rfcomm_channel) {
136 
137  /* A 128-bit number used to identify this service. The words are ordered from most to least
138  * significant, but within each word, the octets are ordered from least to most significant.
139  * For example, the UUID represneted by this array is 00001101-0000-1000-8000-00805F9B34FB. (The
140  * hyphenation is a convention specified by the Service Discovery Protocol of the Bluetooth Core
141  * Specification, but is not particularly important for this program.)
142  *
143  * This UUID is the Bluetooth Base UUID and is commonly used for simple Bluetooth applications.
144  * Regardless of the UUID used, it must match the one that the Armatus Android app is searching
145  * for.
146  *
147  * NOTE: RFCOMM uses L2CAP as a transport
148  *
149  */
150  //maintain a list of four 32-bit uuid which will be used to form a 128-bit uuid for setting a uuid to our service
151  uint32_t svc_uuid_int[] = { 0x01110000, 0x00100000, 0x80000080, 0xFB349B5F };
152 
153  uuid_t root_uuid;
154  uuid_t l2cap_uuid;
155  uuid_t rfcomm_uuid;
156  uuid_t svc_uuid;
157  uuid_t svc_class_uuid;
158 
159  //NOTE: sdp_list_t is a linkedlist which needs to be free using sdp_list_free after use
160  sdp_list_t *l2cap_list = 0,
161  *rfcomm_list = 0,
162  *root_list = 0,
163  *proto_list = 0,
164  *access_proto_list = 0,
165  *svc_class_list = 0,
166  *profile_list = 0;
167  sdp_data_t *channel = 0;
168  sdp_profile_desc_t profile;
169  sdp_record_t *record = sdp_record_alloc();//{ 0 };
170  sdp_session_t *session = 0;
171 
172  const char *service_name = SERVICE_NAME;
173  const char *svc_dsc = SERVICE_DESC;
174  const char *service_prov = SERVICE_PROV;
175 
176  set_service(&svc_uuid, &svc_class_uuid, &svc_class_list, record, svc_uuid_int);
177 
178  set_bluetooth_service_info(&profile, &profile_list, record);
179 
180  set_browsable(&root_list, record, &root_uuid);
181 
182  set_l2cap_info(&l2cap_list, &proto_list, &l2cap_uuid);
183 
184  register_rfcomm_sock(&channel, record, &rfcomm_list, &proto_list, &access_proto_list, &rfcomm_uuid, &rfcomm_channel);
185 
186  // set the name, provider, and description
187  sdp_set_info_attr(record, service_name, service_prov, svc_dsc);
188 
189  // connect to the local SDP server, register the service record, and disconnect
190  /*
191  * NOTE: Server needs to advertise the Bluetooth Server, so we will use IPC method to tell sdpd
192  * (Bluez implementation of SDP server which is a daemon) what to advertise. This is done through
193  * the pipe `/var/run/sdp`
194  */
195  session = sdp_connect(BDADDR_ANY, BDADDR_LOCAL, SDP_RETRY_IF_BUSY);
196  sdp_record_register(session, record, 0);
197 
198  // cleanup
199  sdp_data_free(channel);
200  sdp_list_free(l2cap_list, 0);
201  sdp_list_free(rfcomm_list, 0);
202  sdp_list_free(root_list, 0);
203  sdp_list_free(proto_list, 0);
204  sdp_list_free(access_proto_list, 0);
205  sdp_list_free(svc_class_list, 0);
206  sdp_list_free(profile_list, 0);
207  sdp_record_free(record);
208  return session;
209 }
210 
216 int init_server(struct sockaddr_rc *loc_addr, sdp_session_t **session) {
217  // allocate socket
218  int s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
219  int port = 1;
220 
221  // local bluetooth adapter
222  loc_addr->rc_family = AF_BLUETOOTH;
223  loc_addr->rc_bdaddr = *BDADDR_ANY;
224  loc_addr->rc_channel = (uint8_t) 1;
225 
226  // bind socket to port 1 of the first available
227  bind(s, (struct sockaddr *)loc_addr, sizeof(*loc_addr));
228 
229  //register service added
230  *session = register_service(port);
231 
232  // put socket into listening mode
233  listen(s, port);
234 
235  return s;
236 }
237 
243 void lock(struct dbus_obj *data_obj) {
244  system("dbus-send --type=method_call --dest=org.gnome.ScreenSaver /org/gnome/ScreenSaver org.gnome.ScreenSaver.Lock");
245  if (data_obj) {
246  terminate(data_obj);
247  exit(0);
248  }
249 }
250 
258 int check_arg(int argc, char **argv) {
259  if (argc <= 1) {
260  fprintf(stderr, "usage: %s bt_addr\n", argv[0]);
261  return 0;
262  }
263 
264  if (!verify_bt_addr(argv[1], NULL)) {
265  fprintf(stderr, "%s: %s is not a valid bluetooth address\n", argv[0], argv[1]);
266  return 0;
267  }
268  return 1;
269 }
270 
277 int is_trusted_client(char *bt_addr, const char *trusted_dir_path) {
278  int status = 0;
279 
280  int num_of_paired, num_of_devices;
281  char *username = getlogin();
282 
283  char **paired_devices = get_paired_devices(&num_of_paired);
284  char **trusted_devices;
285 
286  if (!(trusted_devices = find_trusted_devices(NULL, trusted_dir_path, username, &num_of_devices))) {
287  goto is_trusted_terminate;
288  }
289 
290  //check if device is paired
291  if (!(is_dev_trusted(NULL, bt_addr, paired_devices, num_of_paired))) {
292  goto is_trusted_terminate;
293  }
294 
295  //check if device is in trusted list
296  if (!is_dev_trusted(NULL, bt_addr, trusted_devices, num_of_devices)) {
297  goto is_trusted_terminate;
298  }
299 
300  status = 1;
301 
302 is_trusted_terminate:
303  if (trusted_devices) {
304  free_device_list(trusted_devices, num_of_devices);
305  }
306 
307  if (paired_devices) {
308  free_device_list(paired_devices, num_of_paired);
309  }
310 
311  return status;
312 }
313 
324 int connect_client(int s, struct sockaddr_rc *rem_addr, socklen_t *opt, char *authorized_dev, struct dbus_obj *data_obj) {
325  // accept one connection
326  char buf[1024] = { 0 };
327  int client = accept(s, (struct sockaddr *)rem_addr, opt);
328  fcntl(client, F_SETFL, O_NONBLOCK); //set FD to nonblocking
329 
330  //bdaddr_t stores information about the bluetooth device address.
331  ba2str(&(rem_addr->rc_bdaddr), buf); //converts the bluetooth data structure to string
332 
333  fprintf(stderr, "accepted connection from %s\n", buf);
334 
335  if (!is_trusted_client(buf, trusted_dir_path) || strcmp(buf, authorized_dev) != 0) {
336  printf("%s is not trusted or not authorized to deauthenticate the system\n", buf);
337  lock(data_obj);
338  }
339 
340  return client;
341 }
342 
343 int main (int argc, char **argv)
344 {
345  struct sockaddr_rc loc_addr = { 0 }, rem_addr = { 0 };
346  int server = -1, client = -1, bytes_read, num_bytes_read = 0;
347  socklen_t opt = sizeof(rem_addr);
348  sdp_session_t *session = NULL; //SDP socket
349 
350  if (!check_arg(argc, argv)) {
351  lock(NULL);
352  }
353  //check if the device passed is trusted
354  if (!is_trusted_client(argv[1], trusted_dir_path)) {
355  lock(NULL);
356  }
357 
358 
359  server = init_server(&loc_addr, &session);
360 
361  struct server_data_t server_data = {server, &client, session};
362 
363  time_t start, stop;
364 
365 
366  struct dbus_obj *data_obj = set_lock_listener(&server_data);
367 
368  if (!data_obj) {
369  terminate_server(server_data.server, *(server_data.client), server_data.session);
370  }
371 
372  while(1) {
373  if (client < 0) {
374  client = connect_client(server, &rem_addr, &opt, argv[1], data_obj);
375  start = time(NULL);
376  stop = start;
377  }
378 
379  char buf[1024];
380  memset(buf, 0, sizeof(buf));
381 
382  // read data from the client
383  bytes_read = read(client, buf, sizeof(buf));
384 
385  if(bytes_read > 0 && num_bytes_read < INT_MAX){ //read something, lets append some data to the msg array
386  num_bytes_read += bytes_read;
387  }
388 
389  //when 5 seconds have passsed check throughput in bytes, and see if meeting expected minThroughput
390  if ((stop-start) > 5){
391  double throughput = num_bytes_read/(stop-start);
392 
393  num_bytes_read = 0;
394  start = time(NULL);
395  if (throughput < minThroughput){
396  printf("Failed minimum throughput of %d. Received: %f\n", minThroughput, throughput);
397  lock(data_obj);
398  break;
399  }
400  }
401 
402  stop = time(NULL);
403 
404  if (bytes_read > 0 && write(client, buf, strlen(buf) < 0)) {
405  perror("Error writing to client");
406  }
407  char *msg = "hello";
408  write(client, msg, strlen(msg));
409  check_lock_status(data_obj->context);
410  }
411  //should never come here unless the program is killed or the loop breaks
412  terminate(data_obj);
413 
414  return 0;
415 }
sdp_session_t * sdp_connect(const bdaddr_t *src, const bdaddr_t *dst, uint32_t flags)
void set_l2cap_info(sdp_list_t **l2cap_list, sdp_list_t **proto_list, uuid_t *l2cap_uuid)
Definition: deauth.c:106
void lock(struct dbus_obj *data_obj)
Definition: deauth.c:243
#define SERVICE_PROV
Definition: deauth.c:28
void terminate_server(int server, int client, sdp_session_t *session)
Definition: deauth.c:44
#define SERVICE_DESC
Definition: deauth.c:27
int main(int argc, char **argv)
Definition: deauth.c:343
void set_browsable(sdp_list_t **root_list, sdp_record_t *record, uuid_t *root_uuid)
Definition: deauth.c:97
int connect_client(int s, struct sockaddr_rc *rem_addr, socklen_t *opt, char *authorized_dev, struct dbus_obj *data_obj)
Definition: deauth.c:324
int init_server(struct sockaddr_rc *loc_addr, sdp_session_t **session)
Definition: deauth.c:216
#define SERVICE_NAME
Definition: deauth.c:26
void set_bluetooth_service_info(sdp_profile_desc_t *profile, sdp_list_t **profile_list, sdp_record_t *record)
Definition: deauth.c:86
#define minThroughput
Definition: deauth.c:29
int sdp_close(sdp_session_t *session)
int check_arg(int argc, char **argv)
Definition: deauth.c:258
int is_trusted_client(char *bt_addr, const char *trusted_dir_path)
Definition: deauth.c:277
int sdp_record_register(sdp_session_t *sess, sdp_record_t *rec, uint8_t flags)
void set_service(uuid_t *svc_uuid, uuid_t *svc_class_uuid, sdp_list_t **svc_class_list, sdp_record_t *record, uint32_t *svc_uuid_int)
Definition: deauth.c:65
sdp_session_t * register_service(uint8_t rfcomm_channel)
Definition: deauth.c:135
void register_rfcomm_sock(sdp_data_t **channel, sdp_record_t *record, sdp_list_t **rfcomm_list, sdp_list_t **proto_list, sdp_list_t **access_proto_list, uuid_t *rfcomm_uuid, uint8_t *rfcomm_channel)
Definition: deauth.c:115
int verify_bt_addr(char *address, FILE *log_fp)
Definition: pam_bt_misc.c:5
void free_device_list(char **device_list, int num_of_devices)
Definition: pam_bt_misc.c:55
const char * trusted_dir_path
Definition: pam_bt_misc.c:3
int is_dev_trusted(FILE *log_fp, char *dev, char **trusted_devices, int num_of_devices)
Definition: pam_bt_misc.c:46
char ** get_paired_devices(int *num_of_paired)
Definition: pam_bt_pair.c:86
char ** find_trusted_devices(FILE *log_fp, const char *trusted_dir_path, const char *username, int *num_of_devices)
Definition: pam_bt_trust.c:109
struct dbus_obj * set_lock_listener(struct server_data_t *server)
Definition: proxy_dbus.c:38
void check_lock_status(GMainContext *context)
Definition: proxy_dbus.c:78
void terminate(struct dbus_obj *data_obj)
Definition: proxy_dbus.c:3
int server
Definition: proxy_dbus.h:24
int * client
Definition: proxy_dbus.h:25
GMainContext * context
Definition: proxy_dbus.h:21
sdp_session_t * session
Definition: proxy_dbus.h:17
int * client
Definition: proxy_dbus.h:16