
Security News
Follow-up and Clarification on Recent Malicious Ruby Gems Campaign
A clarification on our recent research investigating 60 malicious Ruby gems.
Trans::Api is an ruby implementation for Transmission RPC (bittorrent client). Based on RPC spec 13328 https://trac.transmissionbt.com/browser/trunk/extras/rpc-spec.txt
It required for the Transmission RPC to run the 'remote access':
OSX:
Transmission > Preferences > Remote (tab) > Enable remote access
This gem is (build and) tested with:
Version (0.0.1)
Version (0.0.2)
Version (0.0.3)
Version (0.0.4)
alt_speed_time_day
Version (0.0.5)
Version (0.0.6)
Version (0.0.3)
The Transmission RPC call 'torrent-remove' (implemented as torrent.delete! and Torrent::delete_all!) will crash the daemon! This is NOT a known Transmission issue.
Due to a Transmission bug (https://trac.transmissionbt.com/ticket/5614) duplicate torrents are accepted by the RPC call. The GUI will eventually crash the daemon, when interacting with these duplicate files (or instances). Torrent.add_file/ add_metainfo queries for duplicates to omit this bug.
On rapid RPC calls the client will ignore the request, and respond with successfull. For example rapid Torrent.delete! will respond with status successfull, but it remains active. You can use a blocked call via waitfor (chained) to make sure the action was completed.
Add this line to your application's Gemfile:
gem 'trans-api', github: "dblommesteijn/trans-api"
And then execute:
$ bundle
Define a configuration for your connection (initialize script)
CONFIG = { host: "localhost", port: 9091, user: "admin", pass: "admin", path: "/transmission/rpc" }
Setup default configuration (initialize script)
Trans::Api::Client.config = CONFIG
Define default torrent fields (bulk requests) NOTE: connection is slow when running many torrents with a large amount of fields (transmission rpc issue). On requesting an additional info field from the torrent object, a new call is made to the RPC (and stored withing the object).
Trans::Api::Torrent.default_fields = [ :id, :status, :name ]
Example
Trans::Api::Torrent.default_fields = [ :id, :status, :name ]
# loads the torrent object of id 1 with fields: :id, :status, :name
id = 1
torrent = Trans::Api::Torrent.find id
# calls the rpc to receive files from the defined torrent
torrent.files
Trans api can be used in two ways:
tc = Trans::Api::Connect.new CONFIG
torrents = tc.torrent_get([:id, :name, :status])
Mapped objects (torrent, file, session classes)
examples below.
Get all registered torrents
Trans::Api::Torrent.all
Get a specific torrent by transmission id NOTE: transmission assigns random ids to torrents on daemon start
id = 1
Trans::Api::Torrent.find id
Start all (start all transfers)
Trans::Api::Torrent.start_all
Stop all (stop all transfers)
Trans::Api::Torrent.stop_all
Delete all (tranmission daemon will crash on rapid call)
torrents = Trans::Api::Torrent.all
# assign explicit torrent objects for removal
Trans::Api::Torrent.delete_all torrents
Add torrent file
file = File.open('some file here')
options = {paused: true}
Trans::Api::Torrent.add_file file, options
Add torrent file (via base64)
file = File.open('some file here')
file_name = File.basename(file, ".*") # required >= 0.0.3/ master
options = {paused: true}
base64_file_contents = Base64.encode64 file.read
Trans::Api::Torrent.add_metainfo base64_file_contents, file_name, options
Add magnet URI
magnet_link = "magnet:?xt=urn:btih:42ae58b8f59bd19fe97d6ca6fd884b2e9666a4d1&dn=debian-6.0.6-amd64-CD-2.iso&tr=http%3A%2F%2Fbttracker.debian.org%3A6969%2Fannounce"
torrent = Trans::Api::Torrent.add_magnet(magnet_link, paused: true)
Get all fields
Trans::Api::Torrent.ACCESSOR_FIELDS
Get all Mutable fields
Trans::Api::Torrent.MUTATOR_FIELDS
Get a torrent object
id = 1
torrent = Trans::Api::Torrent.find id
Save (store changed values)
torrent.save!
Start (activate torrent for transfer)
torrent.start!
Start Now (not sure what's the difference to start!, it's a different API call)
torrent.start_now!
Reset (reload all torrent fields, including later requested ones)
torrent.reset!
Stop (stop torrent transfer)
torrent.stop!
File Objects (returns a list of Trans::Api::File objects)
torrent.files_objects
Status names (get the status name of the torrent)
torrent.status_name
Verify (recheck downloaded files)
torrent.verify!
Reannounce Torrent
torrent.reannounce!
Delete (tranmission daemon will crash on rapid call)
torrent.delete! {delete_local_data: true}
Waitfor (automatic delayed responce after/before chained method is called)
Blocking busy waiting for lambda to return true
# waitfor status name not equals stopped after calling start!
optional = :after
torrent.waitfor( lambda{|t| t.status_name != :stopped}, optional ).start!
# waitfor status name equals stopped after calling stop!
torrent.waitfor( lambda{|t| t.status_name == :stopped}, optional ).stop!
# NOTE: waitfor can be used for blocking without a chained method (optional = :before only)
# via the Torrent object `reset_exception` we can verify if the torrent is probably removed
torrent.waitfor(lambda{|t| t.last_error[:error] == "reset_exception"}).delete!(delete_local_data: true)
NOTE: defined torrent accessor fields are defined as instance methods to the Torrent object
Get session object (singleton)
session = Trans::Api::Session.instance
Get available fields (returns symbols of get/set fields)
session.fields
Get all fields and values
session.fields_and_values
Reset (reload object, request information and not saving changes)
session.reset!
Reload (reload the client connection, and configuration)
session.reload!
Enable set and update blocklist
# set an url
session.blocklist_url = "http://list.iblocklist.com/?list=bt_level3&fileformat=p2p&archiveformat=gz"
# enable blocklist
session.blocklist_enable = true
# save changes
session.save!
# force update
begin
session.update_blocklist!
rescue Exception => e
# handle http exceptions here!
end
NOTE: defined session fields are defined as instance methods to the Session object
Getting files from a torrent (file cannot be used standalone, it's an helper class)
id = 1
torrent = Trans::Api::Torrent.find id
torrent.files_objects.each do |file|
# manipulate or stat the file here! (unwant, want)
end
# save the torrent (internal changes to files_objects are saved as well)
torrent.save!
File name
file.name
File mark unwant (mark for ignore, not download)
file.unwant
File mark want (mark for download)
file.want
File wanted? (marked for download)
file.wanted?
File stat
file.stat
NOTE: changed preferences (want, unwant) set options on the linked Torrent object, after saving torrent (torrent.save!) file mutations are stored.
Run the unittest embedded with the project from the commandline. Configure the CONFIG variable with an escaped json to provide configuration for your transmission client.
# example format: define CONFIG in escaped json
$ CONFIG="{\"host\":\"localhost\",\"port\":1234,\"user\":\"youruser\",\"pass\":\"yourpass\",\"path\":\"/transmission/rpc\"}"
Run 'test/unit/trans_connect.rb' to test the intermediate layer between the RPC API and wrappers.
$ CONFIG="{\"host\":\"localhost\",\"port\":1234,\"user\":\"youruser\",\"pass\":\"yourpass\",\"path\":\"/transmission/rpc\"}" ruby -I test test/unit/trans_connect.rb
Run 'test/unit/trans_session_object.rb' to test the working of Trans::Api::Session.
# run unit test session
$ CONFIG="{\"host\":\"localhost\",\"port\":1234,\"user\":\"youruser\",\"pass\":\"yourpass\",\"path\":\"/transmission/rpc\"}" ruby -I test test/unit/trans_session_object.rb
Run 'test/unit/trans_torrent_object.rb' to test the working of Trans::Api::Torrent.
# run unit test session
$ CONFIG="{\"host\":\"localhost\",\"port\":1234,\"user\":\"youruser\",\"pass\":\"yourpass\",\"path\":\"/transmission/rpc\"}" ruby -I test test/unit/trans_torrent_object.rb
NOTE: test test_torrent_rapid_delete
will fail because of an issue with rapid calling.
Besides running your existing client with Transmission you can test on an isolated virtual machine via Vagrant.
Download Dependencies
Download and follow the installation instructions.
Download and run the testing Debian Linux distribution with a test Transmission client.
$ cd /location/of/trans-api
# download and start a testing box (will take some time)
$ vagrant up testing
Configure the CONFIG variable to target the VM
# use this CONFIG string to connect to the testing instance
$ CONFIG="{\"host\":\"localhost\",\"port\":19091,\"user\":\"admin\",\"pass\":\"adm1n\",\"path\":\"/transmission/rpc\"}"
# run tests like described above
NOTE: don't forget to HALT (and DESTROY) the VM when done!
# power down VM
$ vagrant halt testing
# power down and destroy files
$ vagrant destroy testing
FAQs
Unknown package
We found that trans-api demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
A clarification on our recent research investigating 60 malicious Ruby gems.
Security News
ESLint now supports parallel linting with a new --concurrency flag, delivering major speed gains and closing a 10-year-old feature request.
Research
/Security News
A malicious Go module posing as an SSH brute forcer exfiltrates stolen credentials to a Telegram bot controlled by a Russian-speaking threat actor.