How to Compile and Run Open Whisper Systems’ Signal Server (TextSecure Server)

The readme.md content from https://github.com/WhisperSystems/Signal-Server do not give a slightest hint of how to build the source.

Reading some hints in http://debabhishek.com/writes/Installing-and-Running-TextSecure-Signal-Server-on-Windows/. It turns out it should be compiled using Maven.

So, let’s download maven first. Then perform some sanity check:

C:\Windows\System32>mvn -version
Apache Maven 3.5.0 (ff8f5e7444045639af65f6095c62210b5713f426; 2017-04-04T02:39:0
6+07:00)
Maven home: C:\Maven\bin\..
Java version: 1.8.0_131, vendor: Oracle Corporation
Java home: C:\PROGRA~2\Java\jdk1.8.0_131\jre
Default locale: en_US, platform encoding: Cp1252
OS name: “windows 7”, version: “6.1”, arch: “x86”, family: “windows”

Now, let’s compile:

D:\Projects\AndroidProgram\Signal\Server>mvn clean install -DskipTests
[INFO] Scanning for projects…
[WARNING] The project org.whispersystems.textsecure:TextSecureServer:jar:1.65 us
es prerequisites which is only intended for maven-plugin projects but not for no
n maven-plugin projects. For such purposes you should use the maven-enforcer-plu
gin. See https://maven.apache.org/enforcer/enforcer-rules/requireMavenVersion.ht
ml
[INFO]
[INFO] ————————————————————————
[INFO] Building TextSecureServer 1.65
[INFO] ————————————————————————
Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven
-source-plugin/2.2.1/maven-source-plugin-2.2.1.pom
[INFO] ————————————————————————
[INFO] BUILD FAILURE
[INFO] ————————————————————————
[INFO] Total time: 22.536 s
[INFO] Finished at: 2017-08-03T09:51:24+07:00
[INFO] Final Memory: 7M/17M
[INFO] ————————————————————————
[ERROR] Plugin org.apache.maven.plugins:maven-source-plugin:2.2.1 or one of its
dependencies could not be resolved: Failed to read artifact descriptor for org.a
pache.maven.plugins:maven-source-plugin:jar:2.2.1: Could not transfer artifact o
rg.apache.maven.plugins:maven-source-plugin:pom:2.2.1 from/to central (https://r
epo.maven.apache.org/maven2): Connect to repo.maven.apache.org:443 [repo.maven.a
pache.org/151.101.40.215] failed: Connection timed out: connect -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e swit
ch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please rea
d the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/PluginResoluti
onException

D:\Projects\AndroidProgram\Signal\Server>

So, perform changes in the Maven’s settings.xml:

After some lengthy POM and JARs download, I have:

[INFO] ————————————————————————
[INFO] BUILD SUCCESS
[INFO] ————————————————————————
[INFO] Total time: 24:57 min
[INFO] Finished at: 2017-08-03T11:06:09+07:00
[INFO] Final Memory: 30M/104M
[INFO] ————————————————————————

Let’s run it:

D:\Projects\AndroidProgram\Signal\Server>java -jar target\TextSecureServer-1.65.jar

D:\Projects\AndroidProgram\Signal\Server>java -jar target\TextSecureServer-1.65.
jar
usage: java -jar TextSecureServer-1.65.jar
[-h] [-v]
{server,check,directory,vacuum,trim,stats,rmuser,accountdb,messagedb}

positional arguments:
{server,check,directory,vacuum,trim,stats,rmuser,accountdb,messagedb}
available commands

optional arguments:
-h, –help show this help message and exit
-v, –version show the application version and exit

Let’s run it using the configuration given from the above website:

java -jar target\TextSecureServer-1.65.jar server config/textsecure.yml

D:\Projects\AndroidProgram\Signal\Server>java -jar target\TextSecureServer-1.65
.jar server config/textsecure.yml
config/textsecure.yml has an error:
* Malformed YAML at line: 8, column: 3; while scanning a simple key
in ‘reader’, line 8, column 1:
+33756796138 #fake
^
could not find expected ‘:’
in ‘reader’, line 9, column 1:
localDomain: foo.org
^

at [Source: java.io.FileInputStream@9175d8; line: 7, column: 2]

So, let’s debug it:

java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=8880,suspend=y -jar target\TextSecureServer-1.65.jar server config/textsecure.yml

The command line result:

D:\Projects\AndroidProgram\Signal\Server>java -Xdebug -Xrunjdwp:transport=dt_soc
ket,server=y,address=8880,suspend=y -jar target\TextSecureServer-1.65.jar serve
r config/textsecure.yml
Listening for transport dt_socket at address: 8888
config/textsecure.yml has an error:
* Malformed YAML at line: 8, column: 3; while scanning a simple key
in ‘reader’, line 8, column 1:
+33756796138 #fake
^
could not find expected ‘:’
in ‘reader’, line 9, column 1:
localDomain: foo.org
^
at [Source: java.io.FileInputStream@f76a6; line: 7, column: 2]

There’s no more helpful information. So, let’s find at what routine or module that give the above error, i.e. the Malformed YAML error string. This is done by extracting files in the JAR and perform binary search into the files by using utilities, such as WinHex. It takes some time, but I think this is one of possible starting point.

But the search turns out … nothing, either by using ASCII or UNICODE format. Hmm, so what to do ?

Try to do googling regarding the error message, I realized that the error location could be somewhere at YamlConfigurationFactory class of io.dropwizard java class utility.

Let’s obtain this source, but first I have to consult the maven repository of the version being used in this java application, and it turns out using v1.1.0.

Try to obtain the source from http://central.maven.org/maven2/io/dropwizard/dropwizard-configuration/1.1.0/dropwizard-configuration-1.1.0-sources.jar proves to be diffcult because what I got is a connection reset error.

After the source code is obtained, and placed it in proper folder on the Netbeans project, I place the breakpoint to this routine:

It is a hit, but the Netbeans is hang when I try to view the call stack.

What I only got is some information like this:

But this should be enough. Upon restarting the Netbeans, turns out to be ok.

After importing proper source code and perform some step traces, I have:

Where the location of the error is at BaseConfigurationFactory.java in io.dropwizard class:

The reason that I do not find “Malformed YAML” error message is because error string is generated programmatically, where as when I try to search for string Malformed I find many instances in the binary files.

So, let’s examine more detail of this error, which is actually originated from MarkedYAMLException:

Checking further:

This is because the config I copied from given by above website is indeed malformed, the spaces is missing, and after fixing the TextSecure.yml config file:

D:\Projects\AndroidProgram\Signal\Server>java -jar target\TextSecureServer-1.65
.jar server config/textsecure.yml
config/textsecure.yml has an error:
* Unrecognized field at: push.host
Did you mean?:
– queueSize

No matter what I modify in the file, I always get this constant message error, and there’s a mysterious suggestion of queueSize. So let’s fire our binary search again shall we ?

Binary search is suggested at BaseConfigurationFactory.java and the suggestion is retrieved using e.getKnownPropertyIds().stream().

OK now, let’s enter this property using blank value and remove the unknown property, and we have:

D:\Projects\AndroidProgram\Signal\Server>java -jar target\TextSecureServer-1.65
.jar server config/textsecure.yml
config/textsecure.yml has an error:
* Unrecognized field at: websocket
Did you mean?:
– webSocket
– cache
– redphone
– server
– metrics
[16 more]

To retrieve complete properties, I have to resort to debugger which is:

s3,cache,federation,read_database,webSocket,testDevices, twilio, directory, gcm, httpClient, push, database, redphone, apn, metrics, messageStore, turn, logging, server

The above keyword should be the complete keyword for the root property configuration options. There’s typo in the given sample text secure configuration from the above website.

D:\Projects\AndroidProgram\Signal\Server>java -jar target\TextSecureServer-1.65
.jar server config/textsecure.yml
config/textsecure.yml has an error:
* Unrecognized field at: webSocket.enabled
Did you mean?:
– requestLog

At this point, I started to wonder the validity of the given configuration from the above website.

After browsing some of the codings, then I realized, that the purpose of the parser is to try to map the text in to the class, at the root class is named WhisperServerConfiguration.java.

After more fiddling with the TextSecure.yml, I finally get:

D:\Projects\AndroidProgram\Signal\Server>java -jar target\TextSecureServer-1.65
.jar server config/textsecure.yml
config/textsecure.yml has the following errors:
* apn may not be null
* gcm may not be null
* turn may not be null
* webSocket.requestLog may not be null

Let’s first tackle the webSocket configuration issue by passing requestLog: abc, since I don’t know the purpose that option yet, and I have:

D:\Projects\AndroidProgram\Signal\Server>java -jar target\TextSecureServer-1.65
.jar server config/textsecure.yml
config/textsecure.yml has an error:
* Failed to parse configuration at: webSocket.requestLog; Can not construct in
stance of io.dropwizard.request.logging.LogbackAccessRequestLogFactory: no Strin
g-argument constructor/factory method to deserialize from String value (‘abc’)
at [Source: N/A; line: -1, column: -1] (through reference chain: org.whispersys
tems.textsecuregcm.WhisperServerConfiguration[“webSocket”]->org.whispersystems.w
ebsocket.configuration.WebSocketConfiguration[“requestLog”])

After some head scratching and source code review, I realized, this must be configuration item from io.dropwizard utility and I found that using this:

Will stop the complain. But what if I purposely mistyped the type ? In this case, I have:

D:\Projects\AndroidProgram\Signal\Server>java -jar target\TextSecureServer-1.65
.jar server config/textsecure.yml
config/textsecure.yml has an error:
* Failed to parse configuration at: webSocket.requestLog.appenders; Could not
resolve type id ‘consolex’ into a subtype of [simple type, class io.dropwizard.l
ogging.AppenderFactory]: known type ids
= [AppenderFactory, console, file, papertrail, syslog]
at [Source: N/A; line: -1, column: -1] (through reference chain: org.whispersys
tems.textsecuregcm.WhisperServerConfiguration[“webSocket”]->org.whispersystems.w
ebsocket.configuration.WebSocketConfiguration[“requestLog”]->io.dropwizard.reque
st.logging.LogbackAccessRequestLogFactory[“appenders”])

Hmm, interesting. There are indeed other types of requestLog option, but let’s revert it back to console, now I have:

D:\Projects\AndroidProgram\Signal\Server>java -jar target\TextSecureServer-1.65
.jar server config/textsecure.yml
config/textsecure.yml has the following errors:
* apn may not be null
* gcm may not be null
* turn may not be null

After proper settings of dummy TextSecure.yml file I have:

D:\Projects\AndroidProgram\Signal\Server>java -jar target\TextSecureServer-1.65
.jar server config/textsecure.yml
null

No exceptions, anything whatsoever, just “null”. Well, I will stop here for a moment.

One Response to “How to Compile and Run Open Whisper Systems’ Signal Server (TextSecure Server)”

  1. khalifahkelima Says:

    Mas, ini ada cara yang lebih gampang nggak?

Leave a comment