Changeset View
Changeset View
Standalone View
Standalone View
src/org/kde/kdeconnect/Backends/LanBackend/LanLinkProvider.java
Show First 20 Lines • Show All 215 Lines • ▼ Show 20 Line(s) | 203 | private void identityPacketReceived(final NetworkPacket identityPacket, final Socket socket, final LanLink.ConnectionStarted connectionStarted) { | |||
---|---|---|---|---|---|
216 | try { | 216 | try { | ||
217 | if (identityPacket.getInt("protocolVersion") >= MIN_VERSION_WITH_SSL_SUPPORT) { | 217 | if (identityPacket.getInt("protocolVersion") >= MIN_VERSION_WITH_SSL_SUPPORT) { | ||
218 | 218 | | |||
219 | SharedPreferences preferences = context.getSharedPreferences("trusted_devices", Context.MODE_PRIVATE); | 219 | SharedPreferences preferences = context.getSharedPreferences("trusted_devices", Context.MODE_PRIVATE); | ||
220 | boolean isDeviceTrusted = preferences.getBoolean(deviceId, false); | 220 | boolean isDeviceTrusted = preferences.getBoolean(deviceId, false); | ||
221 | 221 | | |||
222 | if (isDeviceTrusted && !SslHelper.isCertificateStored(context, deviceId)) { | 222 | if (isDeviceTrusted && !SslHelper.isCertificateStored(context, deviceId)) { | ||
223 | //Device paired with and old version, we can't use it as we lack the certificate | 223 | //Device paired with and old version, we can't use it as we lack the certificate | ||
224 | BackgroundService.RunCommand(context, new BackgroundService.InstanceCallback() { | 224 | BackgroundService.RunCommand(context, service -> { | ||
225 | @Override | | |||
226 | public void onServiceStart(BackgroundService service) { | | |||
227 | Device device = service.getDevice(deviceId); | 225 | Device device = service.getDevice(deviceId); | ||
228 | if (device == null) return; | 226 | if (device == null) return; | ||
229 | device.unpair(); | 227 | device.unpair(); | ||
230 | //Retry as unpaired | 228 | //Retry as unpaired | ||
231 | identityPacketReceived(identityPacket, socket, connectionStarted); | 229 | identityPacketReceived(identityPacket, socket, connectionStarted); | ||
232 | } | | |||
233 | }); | 230 | }); | ||
234 | } | 231 | } | ||
235 | 232 | | |||
236 | Log.i("KDE/LanLinkProvider", "Starting SSL handshake with " + identityPacket.getString("deviceName") + " trusted:" + isDeviceTrusted); | 233 | Log.i("KDE/LanLinkProvider", "Starting SSL handshake with " + identityPacket.getString("deviceName") + " trusted:" + isDeviceTrusted); | ||
237 | 234 | | |||
238 | final SSLSocket sslsocket = SslHelper.convertToSslSocket(context, socket, deviceId, isDeviceTrusted, clientMode); | 235 | final SSLSocket sslsocket = SslHelper.convertToSslSocket(context, socket, deviceId, isDeviceTrusted, clientMode); | ||
239 | sslsocket.addHandshakeCompletedListener(new HandshakeCompletedListener() { | 236 | sslsocket.addHandshakeCompletedListener(event -> { | ||
240 | @Override | | |||
241 | public void handshakeCompleted(HandshakeCompletedEvent event) { | | |||
242 | String mode = clientMode ? "client" : "server"; | 237 | String mode = clientMode ? "client" : "server"; | ||
243 | try { | 238 | try { | ||
244 | Certificate certificate = event.getPeerCertificates()[0]; | 239 | Certificate certificate = event.getPeerCertificates()[0]; | ||
245 | identityPacket.set("certificate", Base64.encodeToString(certificate.getEncoded(), 0)); | 240 | identityPacket.set("certificate", Base64.encodeToString(certificate.getEncoded(), 0)); | ||
246 | Log.i("KDE/LanLinkProvider", "Handshake as " + mode + " successful with " + identityPacket.getString("deviceName") + " secured with " + event.getCipherSuite()); | 241 | Log.i("KDE/LanLinkProvider", "Handshake as " + mode + " successful with " + identityPacket.getString("deviceName") + " secured with " + event.getCipherSuite()); | ||
247 | addLink(identityPacket, sslsocket, connectionStarted); | 242 | addLink(identityPacket, sslsocket, connectionStarted); | ||
248 | } catch (Exception e) { | 243 | } catch (Exception e) { | ||
249 | Log.e("KDE/LanLinkProvider", "Handshake as " + mode + " failed with " + identityPacket.getString("deviceName")); | 244 | Log.e("KDE/LanLinkProvider", "Handshake as " + mode + " failed with " + identityPacket.getString("deviceName")); | ||
250 | e.printStackTrace(); | 245 | e.printStackTrace(); | ||
251 | BackgroundService.RunCommand(context, new BackgroundService.InstanceCallback() { | 246 | BackgroundService.RunCommand(context, service -> { | ||
252 | @Override | | |||
253 | public void onServiceStart(BackgroundService service) { | | |||
254 | Device device = service.getDevice(deviceId); | 247 | Device device = service.getDevice(deviceId); | ||
255 | if (device == null) return; | 248 | if (device == null) return; | ||
256 | device.unpair(); | 249 | device.unpair(); | ||
257 | } | | |||
258 | }); | 250 | }); | ||
259 | } | 251 | } | ||
260 | } | | |||
261 | }); | 252 | }); | ||
262 | //Handshake is blocking, so do it on another thread and free this thread to keep receiving new connection | 253 | //Handshake is blocking, so do it on another thread and free this thread to keep receiving new connection | ||
263 | new Thread(new Runnable() { | 254 | new Thread(() -> { | ||
264 | @Override | | |||
265 | public void run() { | | |||
266 | try { | 255 | try { | ||
267 | sslsocket.startHandshake(); | 256 | sslsocket.startHandshake(); | ||
268 | } catch (Exception e) { | 257 | } catch (Exception e) { | ||
269 | Log.e("KDE/LanLinkProvider", "Handshake failed with " + identityPacket.getString("deviceName")); | 258 | Log.e("KDE/LanLinkProvider", "Handshake failed with " + identityPacket.getString("deviceName")); | ||
270 | e.printStackTrace(); | 259 | e.printStackTrace(); | ||
271 | 260 | | |||
272 | //String[] ciphers = sslsocket.getSupportedCipherSuites(); | 261 | //String[] ciphers = sslsocket.getSupportedCipherSuites(); | ||
273 | //for (String cipher : ciphers) { | 262 | //for (String cipher : ciphers) { | ||
274 | // Log.i("SupportedCiphers","cipher: " + cipher); | 263 | // Log.i("SupportedCiphers","cipher: " + cipher); | ||
275 | //} | 264 | //} | ||
276 | } | 265 | } | ||
277 | } | | |||
278 | }).start(); | 266 | }).start(); | ||
279 | } else { | 267 | } else { | ||
280 | addLink(identityPacket, socket, connectionStarted); | 268 | addLink(identityPacket, socket, connectionStarted); | ||
281 | } | 269 | } | ||
282 | } catch (Exception e) { | 270 | } catch (Exception e) { | ||
283 | e.printStackTrace(); | 271 | e.printStackTrace(); | ||
284 | } | 272 | } | ||
285 | 273 | | |||
Show All 40 Lines | 313 | try { | |||
326 | server = new DatagramSocket(udpPort); | 314 | server = new DatagramSocket(udpPort); | ||
327 | server.setReuseAddress(true); | 315 | server.setReuseAddress(true); | ||
328 | server.setBroadcast(true); | 316 | server.setBroadcast(true); | ||
329 | } catch (SocketException e) { | 317 | } catch (SocketException e) { | ||
330 | Log.e("LanLinkProvider", "Error creating udp server"); | 318 | Log.e("LanLinkProvider", "Error creating udp server"); | ||
331 | e.printStackTrace(); | 319 | e.printStackTrace(); | ||
332 | return null; | 320 | return null; | ||
333 | } | 321 | } | ||
334 | new Thread(new Runnable() { | 322 | new Thread(() -> { | ||
335 | @Override | | |||
336 | public void run() { | | |||
337 | while (listening) { | 323 | while (listening) { | ||
338 | final int bufferSize = 1024 * 512; | 324 | final int bufferSize = 1024 * 512; | ||
339 | byte[] data = new byte[bufferSize]; | 325 | byte[] data = new byte[bufferSize]; | ||
340 | DatagramPacket packet = new DatagramPacket(data, bufferSize); | 326 | DatagramPacket packet = new DatagramPacket(data, bufferSize); | ||
341 | try { | 327 | try { | ||
342 | server.receive(packet); | 328 | server.receive(packet); | ||
343 | udpPacketReceived(packet); | 329 | udpPacketReceived(packet); | ||
344 | } catch (Exception e) { | 330 | } catch (Exception e) { | ||
345 | e.printStackTrace(); | 331 | e.printStackTrace(); | ||
346 | Log.e("LanLinkProvider", "UdpReceive exception"); | 332 | Log.e("LanLinkProvider", "UdpReceive exception"); | ||
347 | } | 333 | } | ||
348 | } | 334 | } | ||
349 | Log.w("UdpListener", "Stopping UDP listener"); | 335 | Log.w("UdpListener", "Stopping UDP listener"); | ||
350 | } | | |||
351 | }).start(); | 336 | }).start(); | ||
352 | return server; | 337 | return server; | ||
353 | } | 338 | } | ||
354 | 339 | | |||
355 | private void setupTcpListener() { | 340 | private void setupTcpListener() { | ||
356 | 341 | | |||
357 | try { | 342 | try { | ||
358 | tcpServer = openServerSocketOnFreePort(MIN_PORT); | 343 | tcpServer = openServerSocketOnFreePort(MIN_PORT); | ||
359 | new Thread(new Runnable() { | 344 | new Thread(() -> { | ||
360 | @Override | | |||
361 | public void run() { | | |||
362 | while (listening) { | 345 | while (listening) { | ||
363 | try { | 346 | try { | ||
364 | Socket socket = tcpServer.accept(); | 347 | Socket socket = tcpServer.accept(); | ||
365 | configureSocket(socket); | 348 | configureSocket(socket); | ||
366 | tcpPacketReceived(socket); | 349 | tcpPacketReceived(socket); | ||
367 | } catch (Exception e) { | 350 | } catch (Exception e) { | ||
368 | e.printStackTrace(); | 351 | e.printStackTrace(); | ||
369 | Log.e("LanLinkProvider", "TcpReceive exception"); | 352 | Log.e("LanLinkProvider", "TcpReceive exception"); | ||
370 | } | 353 | } | ||
371 | } | 354 | } | ||
372 | Log.w("TcpListener", "Stopping TCP listener"); | 355 | Log.w("TcpListener", "Stopping TCP listener"); | ||
373 | } | | |||
374 | }).start(); | 356 | }).start(); | ||
375 | 357 | | |||
376 | } catch (Exception e) { | 358 | } catch (Exception e) { | ||
377 | e.printStackTrace(); | 359 | e.printStackTrace(); | ||
378 | } | 360 | } | ||
379 | } | 361 | } | ||
380 | 362 | | |||
381 | static ServerSocket openServerSocketOnFreePort(int minPort) throws IOException { | 363 | static ServerSocket openServerSocketOnFreePort(int minPort) throws IOException { | ||
Show All 14 Lines | |||||
396 | 378 | | |||
397 | private void broadcastUdpPacket() { | 379 | private void broadcastUdpPacket() { | ||
398 | 380 | | |||
399 | if (NetworkHelper.isOnMobileNetwork(context)) { | 381 | if (NetworkHelper.isOnMobileNetwork(context)) { | ||
400 | Log.w("LanLinkProvider", "On 3G network, not sending broadcast."); | 382 | Log.w("LanLinkProvider", "On 3G network, not sending broadcast."); | ||
401 | return; | 383 | return; | ||
402 | } | 384 | } | ||
403 | 385 | | |||
404 | new Thread(new Runnable() { | 386 | new Thread(() -> { | ||
405 | @Override | | |||
406 | public void run() { | | |||
407 | 387 | | |||
408 | String deviceListPrefs = PreferenceManager.getDefaultSharedPreferences(context).getString(CustomDevicesActivity.KEY_CUSTOM_DEVLIST_PREFERENCE, ""); | 388 | String deviceListPrefs = PreferenceManager.getDefaultSharedPreferences(context).getString(CustomDevicesActivity.KEY_CUSTOM_DEVLIST_PREFERENCE, ""); | ||
409 | ArrayList<String> iplist = new ArrayList<>(); | 389 | ArrayList<String> iplist = new ArrayList<>(); | ||
410 | if (!deviceListPrefs.isEmpty()) { | 390 | if (!deviceListPrefs.isEmpty()) { | ||
411 | iplist = CustomDevicesActivity.deserializeIpList(deviceListPrefs); | 391 | iplist = CustomDevicesActivity.deserializeIpList(deviceListPrefs); | ||
412 | } | 392 | } | ||
413 | iplist.add("255.255.255.255"); //Default: broadcast. | 393 | iplist.add("255.255.255.255"); //Default: broadcast. | ||
414 | 394 | | |||
Show All 25 Lines | 411 | for (String ipstr : iplist) { | |||
440 | } | 420 | } | ||
441 | } | 421 | } | ||
442 | } | 422 | } | ||
443 | 423 | | |||
444 | if (socket != null) { | 424 | if (socket != null) { | ||
445 | socket.close(); | 425 | socket.close(); | ||
446 | } | 426 | } | ||
447 | 427 | | |||
448 | } | | |||
449 | }).start(); | 428 | }).start(); | ||
450 | } | 429 | } | ||
451 | 430 | | |||
452 | @Override | 431 | @Override | ||
453 | public void onStart() { | 432 | public void onStart() { | ||
454 | //Log.i("KDE/LanLinkProvider", "onStart"); | 433 | //Log.i("KDE/LanLinkProvider", "onStart"); | ||
455 | if (!listening) { | 434 | if (!listening) { | ||
456 | 435 | | |||
▲ Show 20 Lines • Show All 52 Lines • Show Last 20 Lines |