[[socks5]]
= Socks 5 Component
:author: Daniel Wisnewski
:version: v2.0 July 2017. Reformatted for v8.0.0.


Tigase SOCKS5 component allows for file transfers to be made over a SOCKS5 proxy in accordance with link:http://xmpp.org/extensions/xep-0065.html[XEP-0065 SOCKS5 Bytestreams]. This allows for some useful features such as:
- transfer limits per user, domain, or global
- recording transfers between users
- quotas and credits system implementation

== Installation
Tigase SOCKS5 component comes built into the dist-max archives for Tigase XMPP server, and requires the component to be listed in `config.tdsl` file:
[source,dsl]
-----
proxy {}
-----

You will also need to decide if you wish to use database-based features or not. If you wish to simply run the socks5 proxy without features such as quotas, limits add the following line:
[source,dsl]
-----
proxy {
    'verifier-class' = 'tigase.socks5.verifiers.DummyVerifier'
}
-----

This will enable the SOCKS5 Proxy without any advanced features. If you wish to use those features, see the configuration section below.

== Database Preparation
In order to use the more advanced features of the SOCKS5 Proxy Component, your database needs to be prepared with the proper schema prior to running the server.

You may either edit an existing database, or create a new database for specific use with the Proxy.

=== Edit Existing Database
You can add the proper schema to your existing database using the DBSchemaLoader utility included with Tigase. The database folder contains the schema file for your type of database.

First, backup your database before performing any actions and shut down Tigase XMPP Server.

Then from the Tigase installation directory run the following command:
[source,bash]
-----
java -cp "jars/*" tigase.db.util.DBSchemaLoader -dbType {derby,mysql,postgresql,sqlserver} - dbHostname {db address} -dbName {dbname} -rootUser root -rootPass root -file database/{dbtype}-socks5-schema.sql
-----
You should see the following dialogue
-----
LogLevel: CONFIG
tigase.db.util.DBSchemaLoader     	 <init>          	 CONFIG     Properties: [{dbHostname=localhost, logLevel=CONFIG, dbType=derby, file=database/derby-socks5-schema.sql, rootUser=root, dbPass=tigase_pass, dbName=tigasedb, schemaVersion=7-1, rootPass=root, dbUser=tigase_user}]
tigase.db.util.DBSchemaLoader     	 validateDBConnection 	 INFO       Validating DBConnection, URI: jdbc:derby:tigasedb;create=true
tigase.db.util.DBSchemaLoader     	 validateDBConnection 	 CONFIG     DriverManager (available drivers): [[jTDS 1.3.1, org.apache.derby.jdbc.AutoloadedDriver@34a245ab, com.mysql.jdbc.Driver@3941a79c, org.postgresql.Driver@6e2c634b]]
tigase.db.util.DBSchemaLoader     	 validateDBConnection 	 INFO       Connection OK
tigase.db.util.DBSchemaLoader     	 validateDBExists 	 INFO       Validating whether DB Exists, URI: jdbc:derby:tigasedb;create=true
tigase.db.util.DBSchemaLoader     	 validateDBExists 	 INFO       Exists OK
tigase.db.util.DBSchemaLoader     	 loadSchemaFile  	 INFO       Loading schema from file: database/derby-socks5-schema.sql, URI: jdbc:derby:tigasedb;create=true
tigase.db.util.DBSchemaLoader     	 loadSchemaFile  	 INFO        completed OK
tigase.db.util.DBSchemaLoader     	 shutdownDerby   	 INFO       Validating DBConnection, URI: jdbc:derby:tigasedb;create=true
tigase.db.util.DBSchemaLoader     	 shutdownDerby   	 WARNING    Database 'tigasedb' shutdown.
tigase.db.util.DBSchemaLoader     	 printInfo       	 INFO
-----

One this process is complete, you may begin using SOCKS5 proxy component.

=== Create New Database

If you want to create a new database for the proxy component and use it as a separate socks5 database, create the database using the appropriate schema file in the database folder.
Once this is created, add the following line to your `config.tdsl` folder.
[source,dsl]
-----
proxy {}
-----

For example, a mysql database will have this type of URL: jdbc:mysql://localhost/SOCKS?user=root&password=root to replace database URL. For more options, check the database section of xref:databasePreperation[this documentation].

== Configuration

=== *`verifier-class`*
[source,dsl]
-----
proxy {
    'verifier-class' = '$CLASSNAME'
}
-----
Specifies the class used to verify transfer limits. The following options are available:

==== `LimitsVerifier`
- Class Name: `tigase.socks5.verifiers.LimitsVerifier`

Uses the database to store limits and record the amount of data transferred VIA the proxy. It accepts one parameter, `transfer-update-quantization` which is used to create a value to check if the value of transferred bytes should be updated in the database or not. By default, this value is 1MB.

NOTE: Low values can slow down file transfers, while high values can allow for users to exceed quotas.
[source,dsl]
-----
proxy {
    'verifier-class' = 'tigase.socks5.verifiers.LimitsVerifier'
    tigase.socks5.verifiers.LimitsVerifier {
        'transfer-update-quantization' = '1000'
    }
}
-----

==== `DummyVerifier`
- Class Name: `tigase.socks5.verifiers.DummyVerifier`

This accepts file transfers VIA SOCKS5 proxy from any user and does not check limitations against the database.

=== *`socks5-repo-cls`*
[source,dsl]
-----
proxy {
    'socks5-repo-cls' = '$REPOCLASS'
}
-----

Specifies implementation of repository used to store usage statistics. Two options are available for this setting:
- `tigase.socks5.verirepository.JDBCSocks5Repository` - Uses the database implementation.
- `tigase.socks5.repository.DummySocks5Repository` - ignores data storage, and is the default implementation.


=== *`repo-url`*
[source,dsl]
-----
proxy {
    'repo-url' = 'driver:address'
}
-----
The database connection URL for the socks5 repository.

=== *`verifier-params`*
[source,dsl]
-----
proxy {
    'repo-params' {
        '$PARAM' = '$VALUE'
    }
}
-----

Parameters for `LimitsVerifier` which will override the defaults. All of these limits are on a per calendar month basis.
For example, a user is limited to 10MB for all transfers. If he transfers 8MB between the 1st and the 22nd, he only has 2MB left in his limit. On the 1st of the following month, his limit is reset to 10MB.

Available parameters:

- `global-limit` - Transfer limit for all domains in MB per month.
- `instance-limit` - Transfer limit for server instance in MB per month.
- `default-domain-limit` - The Default transfer limit per domain in MB per month.
- `default-user-limit` - The default transfer limit per user in MB per month.
- `default-file-limit` - The default transfer limit per file in MB per month.

=== *`remote-addresses`*
[source,dsl]
-----
proxy {
    'remote-addresses' = '192.168.1.205,20.255.13.190'
}
-----

Comma seperated list of IP addresses that will be accessible VIA the Socks5 Proxy. This can be useful if you want to specify a specific router address to allow external traffic to transfer files using the proxy to users on an internal network.

=== Port settings
If socks5 is being used as a proxy, you may configure a specific ports for the proxy using the following line in config.tdsl:
[source,dsl]
-----
proxy {
    'connections' {
        'ports' = [ 1080 ]
      }
}
-----

== Database usage for specific settings
The above configuration allows for global settings, however you may also define specifics for users and the scopes of those limitations by editing the database information directly.

The `user_id` field denotes the scope of the limitation.

. Using a `domain_name` defines limits for all users whose JIDs are within that domain.
. Using a `JID` of a user defines limit for this exact user.

If the value set is larger than 0, that is the specific limit.
If value is equal to 0 the limit is not overridden and the global limit is used.
If value equals -1 proxy will forbid any transfer for this user.
It there is no value for user in this table, a new row will be created during first transfer and limits for domain or global limits will be used.

Socks5 database is setup in this manner:

.tig_socks5_users
[width="100%",frame="topbot",options="header"]
|=================================
|uid  |user_id              |sha1_user_id                              |domain     |sha1_domain                              |filesize_limit |transfer_limit_per_user  |transfer_limit_per_domain
|1    |user@domain.com      |c35f2956d804e01ef2dec392ef3adae36289123f  |domain.com |e1000db219f3268b0f02735342fe8005fd5a257a |0              |3000                     |0
|2    |domain.com           |e1000db219f3268b0f02735342fe8005fd5a257a  |domain.com |e1000db219f3268b0f02735342fe8005fd5a257a |500            |0                        |0
|=================================

This example table shows that user@domain.com is limited to 3000MB per transfer whereas all users of domain.com are limited to a max file size of 500MB.
This table will populate as users transfer files using the SOCKS5 proxy, once it begins population, you may edit it as necessary.
A second database is setup tig_socks5_connections that records the connections and transmissions being made, however it does not need to be edited.



== Example `config.tdsl` block
Combined, your `config.tdsl` should look like the below excerpt to run socks5 transfers using a separate database.

[source,dsl]
-----
proxy {
    'repo-url' = 'jdbc:mysql://localhost/SOCKS?user=root&password=root'
    'socks5-repo-cls' = 'tigase.socks5.verirepository.JDBCSocks5Repository'
    'verifier-class' = 'tigase.socks5.verifiers.LimitsVerifier'
}
-----
