language server protocol: sync at editor start-up - language-server-protocol

I'm implementing both client and server side for LSP.
I'd like to follow the protocol as strictly as possible.
When I start my editor (the client) it should inform the server what the local code base looks like right now, (a git sha plus some changes since most-recent-common-ancestor,) so that the server can answer correctly when I e.g. go-to-definition.
How do you do that in LSP?
I know I can send a textDocument/didChange for each document which has changes since most-recent-common-ancestor.
But how can the server send its current git SHA to the client, and how can the client send the most-recent-common-ancestor to the server? As far as I can see, this information is needed, but not part of the Langserver Protocol.

The LSP is currently designed with the assumption that both the LSP client and server can access the same filesystem - for which such "sync" operations are not necessary. It also doesn't assume anything about SCM or Git (which is fair as most of the code written isn't necessarily in a Git repository).
You can add extensions to the protocol to let the client (IDE or editor) send a "snapshot" of the project on startup, but it would become both server and client specific integration, diminishing the value of using LSP.

Related

Client Server: How to make it more difficult for client to modify their source code

I have an imaginary program that I've distributed to dozens of clients which involve their home thermostats. The script performs two tasks:
When a request from my server is received, the script will modify the temperature of the user's thermostat to the designated temperature.
When a request from my server is received, the script will reply back the current set temperature of the thermostat.
The program being ran on the clients computer is programmed in a scripting language and is not compiled. The source code can be modified at any time and the new modified script can be re-ran at will.
I have three problems:
What changes can I make to the script running on the client's computer and/or the program running on my server such that I feel more confident that the user did not tamper with the source code of the script?
How can I be relatively sure that the user is running the most up-to-date version of my program?
Without using IP addresses, how can the client know a request came from the server and not another client?
I understand that code running on a client's PC is impossible to police. However I want to make it less trivial for someone to modify the source code of my script.
As you correctly point out, it's impossible to guarantee nobody modifies your source - or replaces your client with an entirely different one they write from scratch. It simply cannot be done and it's not even because your client is implemented as a script; binaries can be replaced/spoofed as well.
What changes can I make to the script running on the client's computer and/or the program running on my server such that I feel more confident that the user did not tamper with the source code of the script?
Make your script compute a cryptographically secure hash of its own source code and send that hash to the server. You'll know what the hash of your client's source code is and can make sure this is the same. This does not guarantee the client is not pretending to be running your source (they could compute the hash of your client and send it while running entirely other code) but this will prevent casual and/or accidental modifications to the script from working (i.e. it guarantees any spoofing is intentional).
How can I be relatively sure that the user is running the most up-to-date version of my program?
Include a version number in the client source code you distribute so you can guarantee each new version has a unique hash with almost 100% probability. Then, you can have a history of versions with corresponding client hashes.
Without using IP addresses, how can the client know a request came from the server and not another client?
This one you can actually do correctly. Have your server use its private key to sign the messages it sends, and have your client verify the signature using your server's public key (which the client source code can contain). Since only your server could possibly have signed the messages with the correct private key, the client can be confident that success with the corresponding public key means your server sent the message.
If it is a home thermostat, the whole architecture is likely wrong. Your server will not be able to connect to devices on your customers' home networks (or at least they will have to perform configuration that you should not expect to be done).
So in a better architecture, you have your service on the internet, to which your devices connect. Note that these connections can be long ones as well, not necessarily just the typical short-lived http connections.
The client software running on a device can be modified by your users arbitrarily, or they can make other clients, you cannot do much about this. In reality, unless this is very valuable for some reason, nobody will bother, especially in a commercial way, because any change to your api will break 3rd party clients. One option to still make client code harder to modify is obfuscation, but be aware that it is not really a security feature, but it does increase the necessary effort.
Checking the version of the client is straightforward, it can just be sent with requests. However, the usual way to achieve what I think you wanted is to version your API. You probably don't care about the exact version of the client, but you do care about which version of the service (the API) it supports. If that is your goal, look into API versioning.
Authenticating the server in this architecture is straightforward if communication uses TLS. With TLS (eg. https), server authentication is implicit. You still want to authenticate the client though, which can be done via the standard means, a username-password, tokens or a client certificate. When talking about devices, you might want to consider a device with a TPM chip so that it can securely hold secrets, but whether you need that depends on the exact scenario and your threat model (who will have physical access, what happens if they can impersonate other devices and so on).

Meteor.js: is the DDP implemenation suitable for an inbox-messaging apps?

I'm looking at Meteor to build a site that is comparable to a stripped-down Facebook. i.e.
It will have users that can connect to other users (either by 'friending' and / or 'following')
users can interact with content that either they or other users create/share
I would like to implement a 'wall' and 'news feed' like concept
The first thing you notice on the framework is how data syncs instantaneously across all clients. I'm assuming this is what the framework refers to as 'DDP'? (Please let me know if that is not correct).
Question:
Is this 'DDP'-like thing reliable enough to build an 'inbox' messaging functionality (i.e. Facebook messenger)?
DDP(roughly) is an efficient combination of some XHR techniques and web socket. And Meteor is a framework to build programs using DDP. You can check the specification.
DDP is a protocol between a client and a server that supports two operations:
Remote procedure calls by the client to the server.
The client subscribing to a set of documents, and the server keeping the client informed about the contents of those documents as they change over time.
If your application needs reactivity and you decides not to use Meteor, you are likely to invent a layer between client and server, which is very similar to DDP.

in noVNC is there a way to receive String(a log) from the server which is not part of Frame(Screen)

in noVNC there is a way to send a string from client to server using the api 'send_string' which is implemented inside websock.js, one thing i noticed is sending string this way is it is not RFB encoded(correct me if i am wrong), so the advantage in this case is commands can be send to intermediate proxy which intern connect to VNC server...
Now my query is .. is there a way for this intermediate proxy to send back some string back to vnc client... means it is not RFB encoded, so will be handled differently # client
Thanks in advance
The websock.js library is the client-side part of the websockify project. The purpose of websockify is to bridge between WebSockets (which are message based) and normal TCP sockets (which are stream based).
The API that websock.js presents is a streaming API rather than a message based one. In addition, websockify/websock.js enables sending/receiving of binary data to the remote target even if the older WebSocket protocol (Hixie) is used which does not natively support binary data.
The send_string function is a convenience function so that you don't have to convert a string to an array form of the data before sending it. The data is still sent to the final target (it is not intercepted by websockify). The beginning of the RFB handshake is string based and so noVNC uses send_string in a couple of places (again, as a convenience).
If you want to have out-of-band communication between websock.js and websockify then you will need to modify both sides, perhaps by adding an initial byte to every message that indicates whether it is out-of-band signalling or part of the in-band stream. It is not builtin functionality.
Disclaimer: I made noVNC and websockify.

If Node.js is server side then is it not visible to the client?

I undesrand that Node.js is a server side (implementation?) of JavaScript. Server side means executes on the server (like say PHP or Python). Does that mean the code you write in JavaScript in Node is "invisible" (to the client)? I'm not quiet keen on server side stuff and this subject interests me. So say, you write something really super simple such as console.log("Hello World"); then that gets executed on the server and doesn't get shown to the client (like View Source, etc.)? Am I right?
I'm asking this here to seek an easier (small) explanation of the idea. Also, is this possibly something I'm looking for?
Yes, Node.js code runs completely on the server (just like python). In your link the goal is to encrypt the source code because a client has access to the servers filesystem. To communicate with the client you will need another component like the http module.

Sending and performing commands from node.js to bash

I'm developing a sort of Flash Operator Pannel for Asterisk but, with Node.js and Socket.io instead of depending of Flash.
I've polished the node server and the front end BUT I don't know how could I send events from Asterisk to node server and do things that will be sended over the socket.
Given the fact that we have a heavily tuned Asterisk to suit our company needs, connecting to the AMI nor the Asterisk socket will solve my problem because we aren't working with real extensions.
So, despite the Asterisk part, I want to know how could I send info to node through bash or curls or whatever
I thought about using curls to the server but this could cause that someone who knows the commands (pretty unlikely) could alter the application flow with unreal data.
EDIT: Rethinking about it, I would just want to be able to receive requests through the socket/server ??? and then be able to perform actions that will be emited through socket.io.
Is that even possible?
The answer really depends upon what specific data you are trying to get from Asterisk to Node. You're trying to replace the Flash Operator Panel, yet you don't have real extensions. I'm guessing that you are using Asterisk as an SBC/proxy of sorts.
If you truly want an event-driven approach, I suggest modifying your dialplan to reach out to Node whenever needed, with whatever data you want. This would most easily be achieved by calling an AGI script with some number of arguments (written in whatever language) that then connects to Node via an HTTP POST, socket, or other.
If you want a more passive approach, you could have Node stream-read the asterisk log files for data, or, as already suggested, connect to the Asterisk Manager Interface (AMI) and stream from there. Contrary to what has been stated previously, I don't consider this to be a very daunting task.
You want to open a socket from Node to Asterisk's AMI (asterisk manager interface). I never used Node, but I would imagine the code would look roughly like this:
var astman = new net.socket().connect(5038);//connect to port 5039 on localhost
astman.on('data', function(data) {
//do something with received data
});
One of the most well maintained ami libraries are FreePBX's php-astmanager. While it's written in php, it should give you a pretty good idea of what your need to do.
You could certainly set up your node.js program to listen on a socket for messages from Asterisk. But you'd have to roll your own connection management scheme, authentication scheme, message durability (possibly), etc.
Alternatively -- and especially if there is the node server and asterisk server are not on the same machine -- you could use a message queue program like RabbitMQ. That takes care of a lot of the important details involved in interprocess communications. It's pretty easy, too. On the node side, check out https://github.com/postwait/node-amqp
I've never used Asterisk but running command line programs can be done with the child_process module.
http://nodejs.org/docs/latest/api/child_processes.html

Resources