Looking for Android help
#11
As you've probably deciphered from my other post ( https://forum.cuberite.org/thread-3021.html ) I've started writing something like this. So far I'm doing the PC side of things, and I'm counting on being able to connect to CardDAV accounts (such as OwnCloud) as the way to manage content on the phone. Not ideal, but doable. Of course, a direct phone manipulation would have been better.

And yes, your breakdown is pretty much on point. Ideally, the app on the device will not be limited to contacts, but could do other things, too (messages, calendar, files, ...)

There's one piece of software I know of which can do exactly this, but it's closed source and paid - http://www.mobiledit.com/mobiledit . I know because I used to work there for five years Smile Which is exactly why I can't use it (can't give the old boss the satisfaction of seeing my name in the "customers" list). And anyway nowadays I'm too paranoid, so I want an open-source solution. Yes, basically I want to bring my former employer down with open-sourceBig Grin
Reply
Thanks given by:
#12
So, what I'm using.

radicale, hosted at my brothers home, as carddav/daldav server
davdroid on phone, which is foss but paid on the play store (free on fdroid or compile yourself)
Thunderbird on computer.

I have to say it's not the best solution for doing fancy shit cause synchronization could take quite a time until the data appears on the other end.

If I may correct you, I'm not sure if what you are writing makes so much sense, honestly. If you would go with a carddav solution you could either use existing tools or use a library to build your own thing.

What I would do is create both parts, the server on the device and the desktop app, they exchange data in the format like the app receives it (imagining json for transmitting data). The only hard part would be exporting and importing to vCard.
Reply
Thanks given by:
#13
@xoft so I start with what I've described earlier?
Reply
Thanks given by:
#14
Yes please.

Also, it'd be great if you have some way of showing me what kind of data the phone allows for the contacts. I imagine the contacts are stored in some relational DB there (sqlite?), which implies that the contacts have some pre-defined structure, possibly different on each phone. Just to know if there's anything I should be prepared for in the UI part.
Reply
Thanks given by:
#15
Here's my current representation of a contact that should be a reasonable model for anything that could be read from and written to the phone:
https://github.com/madmaxoft/ContactBook.../Contact.h
Reply
Thanks given by:
#16
@xoft so I started creating this (together with a friend who is just learning android).

Ive got a pretty complicated but (I think) neat security workflow, which I am almost done with (I'm currently still establishing a two way connection between Android (Java) and electron (node.js), it is so far a tcp (with tls) connection but handling all this on Android isn't easy (mostly because of multithreading, you can't run networking code on the UI thread and vice versa).

So it's still a long way to go, but as soon as I have a working bidirectional and secure (encrypted and you have to acknowledge each computer once. After all, it's a great lot of stuff the computer can do) connection (abstraction) I can start with the actual implementation of fetching contacts, sending them over to the computer and displaying that....
Reply
Thanks given by:
#17
Sounds great.

Will it also support auto-discovery on local networks? The PC program would send a broadcast, and the device would reply "here I am, name's 'Xoft's phone', you can connect to my IP here"? Also, communication using ADB TCP bridge would be great, so that the PC program could push the app into the phone using ADB and then directly communicate with it.
Reply
Thanks given by:
#18
@xoft 


.png   Bildschirmfoto von »2017-10-10 21-39-42«.png (Size: 36 KB / Downloads: 365)

so the things i have planned so far (and i tick the boxes i have already)

oh, just a note: server = app. client = desktop

[-] Autodiscovery. (1)
[x] Security. If my thought process is flawless here, the communication channel is encrypted, the server's fingerprint confirmed by the user and even man in the middle attacks prevented (2)
[x] Sleek UI (hello dinosaurTongue still work in progress)
[ ] Features. Planned: "Contacts app" on desktop, optionally maybe: SMS messages? notifications? still gotta try out the battery performance with those (3)

(1) Autodiscovery. I actually had that feature implemented before reading your post. My implementation is as follows:
 1. The client sends a WHO udp package to the local network's broadcast address (255.255.255.255) (WHO package is [0x49,0x4c,0x7b,0xae,0x30,0x30,0x69,0x9e] plus the client's public key fingerprint as ASCII encoded (see (2))
 2. The server responds with a HERE udp package directly to the client (HERE is [0x22,0xd6,0xb1,0x4b,0x35,0x28,0x10,0x51] plus one byte known information (0x00 = no info, 0x01 = unknown public key, 0x02 = known public key) and after that the android device name (Build.MANUFACTURER + " " + Build.MODEL). i used this as it identifies the phone fairly well and is usable across all devices


However, this has a few caveats.
 1. UDP holepunching only works when sending messages to specific devices. That means, any firewall running on the pc would probably filter the response from the phone unless configured otherwise (allow udp incoming on port 8877).
 2. Android devices only receive UDP broadcasts when the screen is turned on. Yes, its not "is the app in foreground" or "is the cpu active", its "is the screen turned on". Kinda sucks, so note that for device discovery the screen must be turned on (however, the app doestn have to be shown)
 3. the 0x00 no info code was originally intended that upon server startup, the client sends an empty HERE to the network to immediately appear on computers. i have kinda replaced this with relatively frequent broadcast messages.

(2) Security. On the first server start (or if the certificate expires after a year) the server generates a new keypair and self signed certificate. the actual values aren't important, it is only important for establishing the connection. On the first app start, the client generates a keypair (but without certificate. i deemed it not necessary to have another self signed certificate. where normally the certificate would be used i am using the public key instead). BTW: yes, i am kinda re-implementing something similar to TLS client certificates, but with protection against man in the middle attacks (hence i didnt choose tls client certificates)


Workflow:
 1. Client connects with a normal connect, discards the server's certificate information and makes a secure handshake. (I'm using bouncy castle in its standard setup)
 2. The client sends its public key to the server.
 3. The server answers either with PUBLIC KEY UNKNOWN or PUBLIC KEY KNOWN, in the first case both the client and the server show a popup showing the public keys's sha1 fingerprint. the user then acknowledges the fingerprint in the app and the server sends PUBLIC KEY KNOWN (or closes the connection if the key was rejected)
 4. Next, the server computes a challenge and sends it to the client. Thats actually the part where it differs most from the tls specification. The challenge isnt completely random, it consists of two parts: The server's id (=kinda like the fingerprint but using sha256 and encoded as base64), a colon, and the actual randomness. The server stores this value.
 5. The client checks whether the server's id in the challenge is the same as the server id it computes from the certificate. if so, it signs this data and returns the challenge, if not, it closes the connection
 6. The server checks if the response got from the client actually matches the challenge it sent and is a valid signature, if so, sends an OK
 7. The client sending a similarely formed challenge to the server is planned, so the client doesnt have to rely on the server for man in the middle detection

Now, how does this prevent a man in the middle? Lets assume i am man in the middle and have two connections running with both the server and the client and pass data between both two. Now the client sees my certificate instead of the servers, but cant do anything as its just like the server's self signed. Now the server sends its challenge. I have two options: Either i pass the challenge without changing it and the client will close the connection (as the challenge's serverid isnt the same as the client sees) or i modify the challenge to match my man in the middle certificate before sending it to the client. in this case, the client signs the data, but now it signed the challenge with the fake server id. i cannot change this signature as it would invalidate the signature, so the server sees that the signature signs a different server id that for itself and will close the connection.

there is still two attack scenarios: 1. the "man in the middle" emulates a phone and can without problem accept a client connections. now it didnt earn a thing because the relevant data is on the phone, not the computer. (there is not yet a feature to directly transfer data from one phone to another) 2. the "man in the middle" emulates a computer, but then it either has to steal the computer's private key or get a user confirmation in the app once.

oh btw: confirmed public keys are stored in a database, alongside with their fingerprints (so detecting whether a client should be known or not isnt hard. i say shoudl be as anyone could fake that at this time. however, at connection level they have to send a full public key and afterwards have to confirm they have the private key for that public key too). A notification informs you how many authenticated devices are currently connected similarely to wifi (the app doesnt show connections that have not authenticated (yet) as they dont have access to anything)

(3) Battery drain. I dont know how much this will drain. i'm running a tcp server, am listening for udp packets (but only if the screen is turned on), i'm holding a WIFI lock on android plus a WIFI multicast lock (for the broadcasts), but no wake lock. The service however runs as foreground service, so i dont know whether a wake lock would be redundant or not. If it drains battery a lot, then some longer connection for like notifications wouldnt be good.

EDIT: oh yeah, i missed the most important part

source code on github: https://github.com/monstertoss
android apk isnt available yet, the desktop app can be run using "npm install" inside the project's root (this might take a while), and then "npm start" (first start may take a while)
Reply
Thanks given by:
#19
My intention was that the auto-discover was only to be used once. For that, having the screen on would be a reasonable condition. The point is that from that time on, the device would auto-connect to the computer everytime it connected to the same wifi (use case: you set it up on your home wifi, then everytime you come home, the PC connects to the phone automatically, and can sync contacts / backup texts / whatever. For this to work, we'd probably have to use both directions for the broadcast, the PC -> Device for the initial pairing and Device -> PC for auto-reconnect.
Reply
Thanks given by:
#20
Dinosaur says: "Telling the end users to 'npm install and npm start' is not a good way to write nice UI" Smile
Reply
Thanks given by:




Users browsing this thread: 1 Guest(s)