hidden-hippo 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +47 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +16 -0
  5. data/Gemfile +3 -0
  6. data/HACKING.md +78 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +31 -0
  9. data/Rakefile +5 -0
  10. data/Vagrantfile +24 -0
  11. data/bin/hh +4 -0
  12. data/ci/install-tshark.sh +21 -0
  13. data/config/gui-dev.ru +6 -0
  14. data/config/mongoid.yml +20 -0
  15. data/gui/public/favicon.png +0 -0
  16. data/gui/public/hidden-hippo.css +18 -0
  17. data/gui/public/user-placeholder.png +0 -0
  18. data/gui/views/dossier.rhtml +12 -0
  19. data/gui/views/index.rhtml +25 -0
  20. data/gui/views/layout.rhtml +31 -0
  21. data/gui/views/possibilities.rhtml +10 -0
  22. data/hidden-hippo.gemspec +31 -0
  23. data/hippo-small.png +0 -0
  24. data/hippo.png +0 -0
  25. data/lib/hidden_hippo/cli/app.rb +23 -0
  26. data/lib/hidden_hippo/cli/database.rb +47 -0
  27. data/lib/hidden_hippo/cli/gui.rb +51 -0
  28. data/lib/hidden_hippo/daemon.rb +90 -0
  29. data/lib/hidden_hippo/dossier.rb +23 -0
  30. data/lib/hidden_hippo/extractors/dhcp_hostname_extractor.rb +16 -0
  31. data/lib/hidden_hippo/extractors/dns_history_extractor.rb +25 -0
  32. data/lib/hidden_hippo/extractors/dns_llmnr_extractor.rb +18 -0
  33. data/lib/hidden_hippo/extractors/http_request_url_extractor.rb +15 -0
  34. data/lib/hidden_hippo/extractors/mdns_hostname_extractor.rb +18 -0
  35. data/lib/hidden_hippo/gui.rb +21 -0
  36. data/lib/hidden_hippo/packets/dhcp.rb +13 -0
  37. data/lib/hidden_hippo/packets/dns.rb +23 -0
  38. data/lib/hidden_hippo/packets/http.rb +13 -0
  39. data/lib/hidden_hippo/packets/packet.rb +73 -0
  40. data/lib/hidden_hippo/paths.rb +15 -0
  41. data/lib/hidden_hippo/possibilities.rb +63 -0
  42. data/lib/hidden_hippo/reader.rb +36 -0
  43. data/lib/hidden_hippo/scanner.rb +51 -0
  44. data/lib/hidden_hippo/update.rb +3 -0
  45. data/lib/hidden_hippo/updator.rb +49 -0
  46. data/lib/hidden_hippo/version.rb +3 -0
  47. data/lib/hidden_hippo.rb +23 -0
  48. data/spec/db_daemon_spec.rb +7 -0
  49. data/spec/dns_scanner_spec.rb +41 -0
  50. data/spec/dossier_spec.rb +72 -0
  51. data/spec/extractors/dhcp_hostname_extractor_spec.rb +43 -0
  52. data/spec/extractors/dns_history_extractor_spec.rb +52 -0
  53. data/spec/extractors/dns_llmnr_extractor_spec.rb +45 -0
  54. data/spec/extractors/http_request_url_extractor_spec.rb +23 -0
  55. data/spec/extractors/mdns_hostname_extractor_spec.rb +45 -0
  56. data/spec/fixtures/dns_elise.pcap +0 -0
  57. data/spec/fixtures/dns_reddit_eth.pcap +0 -0
  58. data/spec/fixtures/tcp_noise.pcap +0 -0
  59. data/spec/gui_daemon_spec.rb +7 -0
  60. data/spec/hidden_hippo_spec.rb +32 -0
  61. data/spec/packet_spec.rb +88 -0
  62. data/spec/possibilities_spec.rb +113 -0
  63. data/spec/spec_helper.rb +33 -0
  64. data/spec/support/cli_controller_examples.rb +136 -0
  65. data/spec/updator_spec.rb +37 -0
  66. metadata +274 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 723e65ca63ec61202d7e3ba1c8e4097a418ad5c4
4
+ data.tar.gz: d60d6875a2378c997e3ec2b68a8cf5637640ea72
5
+ SHA512:
6
+ metadata.gz: a7a3c6d86d8f8a72ad5880728d5fc8248a914f1c0f2363f52f5fad85d5ec51067752843e8c763afa16c71eff71acd4cdce5c39f0590d0afab2661c21bb3625e0
7
+ data.tar.gz: 6235f7eadc6ab0bbcb22ab3f9e24d2165440e195a8c984911988b3d3cf9e90d684ac12bc8106f790df923d2cf21e3e20b055132b129ee73fe6d5b519a5593c08
data/.gitignore ADDED
@@ -0,0 +1,47 @@
1
+ # Created by https://www.gitignore.io
2
+
3
+ *~
4
+
5
+ ### Ruby ###
6
+ *.gem
7
+ *.rbc
8
+ /.config
9
+ /coverage/
10
+ /InstalledFiles
11
+ /pkg/
12
+ /spec/reports/
13
+ /test/tmp/
14
+ /test/version_tmp/
15
+ /tmp/
16
+
17
+ ## Specific to RubyMotion:
18
+ .dat*
19
+ .repl_history
20
+ build/
21
+
22
+ ## Documentation cache and generated files:
23
+ /.yardoc/
24
+ /_yardoc/
25
+ /doc/
26
+ /rdoc/
27
+
28
+ ## Environment normalisation:
29
+ /.bundle/
30
+ /lib/bundler/man/
31
+
32
+ # for a library or gem, you might want to ignore these files since the code is
33
+ # intended to run in multiple environments; otherwise, check them in:
34
+ Gemfile.lock
35
+ .ruby-version
36
+ .ruby-gemset
37
+
38
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
39
+ .rvmrc
40
+
41
+ # Created by https://www.gitignore.io
42
+
43
+ ### Vagrant ###
44
+ .vagrant/
45
+
46
+ .idea/
47
+ hidden-hippo.iml
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,16 @@
1
+ before_install:
2
+ - sudo apt-get update -q
3
+ - sudo apt-get install -y libpcap-dev
4
+ - ./ci/install-tshark.sh
5
+
6
+ services: mongodb
7
+ language: ruby
8
+ rvm:
9
+ - 1.9.3
10
+ - 2.0.0
11
+ - 2.1.5
12
+ - 2.2.0
13
+ - ruby-head
14
+ matrix:
15
+ allow_failures:
16
+ - rvm: ruby-head
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/HACKING.md ADDED
@@ -0,0 +1,78 @@
1
+ Hacking on hidden-hippo
2
+ =======================
3
+
4
+ Here's how to setup your development environment so that you can start hacking
5
+ on hidden-hippo.
6
+
7
+ Check out the source
8
+ --------------------
9
+
10
+ $ git clone git@github.com:beraboris/hidden-hippo
11
+ $ cd hidden-hippo
12
+
13
+ Setup a dev environment
14
+ -----------------------
15
+
16
+ You have two options when it comes to the dev environment. You can use Vagrant,
17
+ which is a magic VM thingy that sets up the whole environment for you. Or you
18
+ can setup the environment yourself. Using Vagrant is the easier option.
19
+
20
+ ### Vagrant
21
+
22
+ If you don't already have it, install [vagrant](https://www.vagrantup.com/downloads.html).
23
+ You're also going to need either VMware or VirtualBox.
24
+
25
+ Setup the VM with: (This will create a VM with a working dev environment.)
26
+
27
+ $ vagrant up
28
+
29
+ Ssh into the VM with:
30
+
31
+ $ vagrant ssh
32
+ $ cd /vagrant
33
+ $ bundle install
34
+
35
+ Once you're done suspend the vm with:
36
+
37
+ $ vagrant suspend
38
+
39
+ In the VM, the code can be found in `/vagrant`. This is a shared folder that is
40
+ automatically setup by vagrant.
41
+
42
+ ### Manual setup
43
+
44
+ Install ruby. We currently support:
45
+
46
+ - ruby 1.9.3
47
+ - ruby 2.0.0
48
+ - ruby 2.1.5
49
+ - ruby 2.2.0
50
+
51
+ Install bundler:
52
+
53
+ $ gem install bundler
54
+
55
+ Install dependencies
56
+
57
+ $ bundle install
58
+
59
+ Install mongodb. This is very platform specific. Look it up in the appropriate wiki. Currently we're only supporting
60
+ version 2.4. It could work with 2.6 but it's not tested. The unit tests assume that mongo is running on
61
+ `localhost:27017`.
62
+
63
+ Install tshark. the `tshark` executable needs to be somewhere in your `$PATH`. tshark is part of the wireshark
64
+ distribution. It is sometimes packaged on its own.
65
+
66
+ Running hidden-hippo
67
+ --------------------
68
+
69
+ $ bundle exec hh ...
70
+
71
+ Running tests
72
+ -------------
73
+
74
+ $ rake
75
+
76
+ or
77
+
78
+ $ rspec spec/...
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Boris Bera, Clément Zotti, François Genois, Ulrich Kossou
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,31 @@
1
+ Hidden Hippo
2
+ ============
3
+
4
+ <img align="right" src="hippo-small.png"/>
5
+
6
+ [![Build Status](https://travis-ci.org/beraboris/hidden-hippo.svg?branch=master)](https://travis-ci.org/beraboris/hidden-hippo)
7
+
8
+ A tool that identifies the people around by sniffing network traffic and mining social networks.
9
+
10
+ Installation
11
+ ------------
12
+
13
+ Install the gem:
14
+
15
+ $ gem install hidden-hippo
16
+
17
+ Usage
18
+ -----
19
+
20
+ TODO: Write usage instructions here
21
+
22
+ Contributing
23
+ ------------
24
+
25
+ 1. Fork it ( https://github.com/beraboris/hidden-hippo/fork )
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create a new Pull Request
30
+
31
+ Check out [HACKING.md](HACKING.md) to setup your development environment.
data/Rakefile ADDED
@@ -0,0 +1,5 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+ task :default => :spec
data/Vagrantfile ADDED
@@ -0,0 +1,24 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ Vagrant.configure(2) do |config|
5
+ config.vm.box = 'ubuntu/trusty32'
6
+
7
+ config.vm.network 'forwarded_port', guest: 5432, host: 5432
8
+ config.vm.network 'forwarded_port', guest: 28018, host: 28018
9
+
10
+ config.vm.provision 'shell', inline: <<-SHELL
11
+ apt-get update
12
+ apt-get install -y build-essential \
13
+ ruby1.9.1-dev \
14
+ git \
15
+ mongodb-server=1:2.4.9-1ubuntu2 \
16
+ tshark=1.10.6-1
17
+ gem install bundler
18
+ SHELL
19
+
20
+ config.vm.provision 'shell', privileged: false, inline: <<-SHELL
21
+ cd /vagrant
22
+ bundle install
23
+ SHELL
24
+ end
data/bin/hh ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require 'hidden_hippo'
3
+
4
+ HiddenHippo::Cli::App.start
@@ -0,0 +1,21 @@
1
+ #!/bin/bash
2
+
3
+ wget https://2.na.dl.wireshark.org/src/wireshark-1.10.13.tar.bz2
4
+ tar xjf wireshark-1.10.13.tar.bz2
5
+ cd wireshark-1.10.13
6
+
7
+ ./configure --prefix /usr \
8
+ --disable-wireshark \
9
+ --disable-capinfos \
10
+ --disable-captype \
11
+ --disable-editcap \
12
+ --disable-dumpcap \
13
+ --disable-mergecap \
14
+ --disable-reordercap \
15
+ --disable-text2pcap \
16
+ --disable-randpkt \
17
+ --disable-dftest \
18
+ --disable-rawshark
19
+
20
+ make
21
+ sudo make install
data/config/gui-dev.ru ADDED
@@ -0,0 +1,6 @@
1
+ require 'hidden_hippo'
2
+ require 'hidden_hippo/gui'
3
+
4
+ HiddenHippo.configure_db! :development
5
+
6
+ run HiddenHippo::Gui
@@ -0,0 +1,20 @@
1
+ production:
2
+ sessions:
3
+ default:
4
+ hosts:
5
+ - localhost:28018
6
+ database: hidden-hippo
7
+
8
+ development:
9
+ sessions:
10
+ default:
11
+ hosts:
12
+ - localhost:27017
13
+ database: hidden-hippo-dev
14
+
15
+ test:
16
+ sessions:
17
+ default:
18
+ hosts:
19
+ - localhost:27017
20
+ database: hidden-hippo-test
Binary file
@@ -0,0 +1,18 @@
1
+ .person-picture {
2
+ width: 150px;
3
+ height: 150px;
4
+ }
5
+
6
+ .dossier-short .caption h3 {
7
+ text-align: center;
8
+ }
9
+
10
+ .dossier-short .name {
11
+ font-weight: bold;
12
+ }
13
+
14
+ .dossier-short .value {
15
+ overflow: hidden;
16
+ text-overflow: ellipsis;
17
+ white-space: nowrap;
18
+ }
Binary file
@@ -0,0 +1,12 @@
1
+ <div class="container">
2
+ <h1 class="page-header"><%= dossier.mac_address %></h1>
3
+
4
+ <%= erb :possibilities, locals: {name: 'Name', possibilities: dossier.name} %>
5
+ <%= erb :possibilities, locals: {name: 'Host name', possibilities: dossier.hostname} %>
6
+ <%= erb :possibilities, locals: {name: 'User name', possibilities: dossier.username} %>
7
+ <%= erb :possibilities, locals: {name: 'Email', possibilities: dossier.email} %>
8
+ <%= erb :possibilities, locals: {name: 'Device', possibilities: dossier.device} %>
9
+ <%= erb :possibilities, locals: {name: 'Gender', possibilities: dossier.gender} %>
10
+ <%= erb :possibilities, locals: {name: 'Age', possibilities: dossier.age} %>
11
+ <%= erb :possibilities, locals: {name: 'History', possibilities: dossier.history} %>
12
+ </div>
@@ -0,0 +1,25 @@
1
+ <div class="container">
2
+ <h1 class="page-header">Hidden Hippo</h1>
3
+ <div class="row">
4
+ <% dossiers.each do |dossier| %>
5
+ <div class="col-md-4">
6
+ <div class="thumbnail dossier-short">
7
+ <img src="user-placeholder.png" class="img-circle person-picture">
8
+ <div class="caption">
9
+ <a href="/<%= dossier.mac_address %>">
10
+ <h3><%= dossier.mac_address %></h3>
11
+ </a>
12
+ <div class="row">
13
+ <div class="col-xs-4 name">Name:</div>
14
+ <div class="col-xs-8 value"><%= dossier.name.first || 'Nothing :(' %></div>
15
+ </div>
16
+ <div class="row">
17
+ <div class="col-xs-4 name">Host Name:</div>
18
+ <div class="col-xs-8 value"><%= dossier.hostname.first || 'Nothing :(' %></div>
19
+ </div>
20
+ </div>
21
+ </div>
22
+ </div>
23
+ <% end %>
24
+ </div>
25
+ </div>
@@ -0,0 +1,31 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1">
7
+ <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
8
+ <title>Hidden Hippo</title>
9
+
10
+ <!-- Latest compiled and minified CSS -->
11
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
12
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap-theme.min.css">
13
+ <link rel="stylesheet" href="hidden-hippo.css">
14
+
15
+ <link rel="icon" type="image/png" href="favicon.png">
16
+
17
+ <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
18
+ <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
19
+ <!--[if lt IE 9]>
20
+ <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
21
+ <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
22
+ <![endif]-->
23
+ </head>
24
+ <body>
25
+
26
+ <%= yield %>
27
+
28
+ <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
29
+ <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
30
+ </body>
31
+ </html>
@@ -0,0 +1,10 @@
1
+ <h3><%= name %></h3>
2
+ <% if possibilities.any? %>
3
+ <ul>
4
+ <% possibilities.each do |possibility| %>
5
+ <li><%= possibility %></li>
6
+ <% end %>
7
+ </ul>
8
+ <% else %>
9
+ <p>Nothing here :(</p>
10
+ <% end %>
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'hidden_hippo/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'hidden-hippo'
8
+ spec.version = HiddenHippo::VERSION
9
+ spec.authors = ['Boris Bera', 'Clément Zotti', 'François Genois', 'Ulrich Kossou']
10
+ spec.email = ['bboris@rsoft.ca', nil, nil, nil]
11
+ spec.summary = %q{A tool that identifies the people around by sniffing network traffic and mining social networks.}
12
+ spec.homepage = 'https://github.com/beraboris/hidden-hippo'
13
+ spec.license = 'MIT'
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ['lib']
19
+
20
+ spec.add_development_dependency 'bundler', '~> 1.7'
21
+ spec.add_development_dependency 'rake', '~> 10.0'
22
+ spec.add_development_dependency 'rspec', '~> 3.2'
23
+ spec.add_development_dependency 'rspec-retry', '~> 0.4'
24
+ spec.add_development_dependency 'shoulda-matchers', '~> 2.8'
25
+ spec.add_development_dependency 'pry'
26
+
27
+ spec.add_dependency 'thor', '~> 0.19'
28
+ spec.add_dependency 'sinatra', '~> 1.4'
29
+ spec.add_dependency 'thin', '~> 1.6'
30
+ spec.add_dependency 'mongoid', '~> 4.0'
31
+ end
data/hippo-small.png ADDED
Binary file
data/hippo.png ADDED
Binary file
@@ -0,0 +1,23 @@
1
+ require 'thor'
2
+ require 'hidden_hippo'
3
+ require 'hidden_hippo/cli/database'
4
+ require 'hidden_hippo/cli/gui'
5
+ require 'hidden_hippo/reader'
6
+
7
+ module HiddenHippo
8
+ module Cli
9
+ class App < Thor
10
+ desc 'db start|stop|status', 'control the database service'
11
+ subcommand 'db', Database
12
+
13
+ desc 'gui start|stop|status', 'control the gui service'
14
+ subcommand 'gui', Gui
15
+
16
+ desc 'read [FILE]', 'parse a pcap file'
17
+ def read(file)
18
+ HiddenHippo.configure_db!
19
+ Reader.new(file).call
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,47 @@
1
+ require 'thor'
2
+ require 'hidden_hippo/daemon'
3
+
4
+ module HiddenHippo
5
+ module Cli
6
+ class Database < Thor
7
+ class Daemon < HiddenHippo::Daemon
8
+ def initialize
9
+ super('db')
10
+ end
11
+
12
+ protected
13
+
14
+ def run
15
+ db_path.mkpath
16
+
17
+ Process.spawn 'mongod',
18
+ '--dbpath', db_path.to_s,
19
+ '--port', '28018',
20
+ '--smallfiles',
21
+ '--logpath', log_file.to_s
22
+ end
23
+
24
+ def db_path
25
+ home + 'store/db'
26
+ end
27
+ end
28
+
29
+ namespace :db
30
+
31
+ desc 'start', 'start the database service'
32
+ def start
33
+ Daemon.new.start
34
+ end
35
+
36
+ desc 'stop', 'stop the database service'
37
+ def stop
38
+ Daemon.new.stop
39
+ end
40
+
41
+ desc 'status', 'check if the database is running'
42
+ def status
43
+ Daemon.new.status
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,51 @@
1
+ require 'thor'
2
+ require 'thin'
3
+ require 'hidden_hippo'
4
+ require 'hidden_hippo/daemon'
5
+ require 'hidden_hippo/gui'
6
+
7
+ module HiddenHippo
8
+ module Cli
9
+ class Gui < Thor
10
+ class Daemon < HiddenHippo::Daemon
11
+ def initialize
12
+ super('gui')
13
+ end
14
+
15
+ protected
16
+
17
+ def run
18
+ pid = fork do
19
+ HiddenHippo.configure_db!
20
+
21
+ server = Thin::Server.new '0.0.0.0', 5432, HiddenHippo::Gui
22
+ server.log_file = log_file.to_s
23
+ server.reopen_log
24
+ server.start
25
+ end
26
+
27
+ puts 'To access the gui, point your browser to http://localhost:5432'
28
+
29
+ pid
30
+ end
31
+ end
32
+
33
+ namespace :gui
34
+
35
+ desc 'start', 'start the gui service'
36
+ def start
37
+ Daemon.new.start
38
+ end
39
+
40
+ desc 'stop', 'stop the gui service'
41
+ def stop
42
+ Daemon.new.stop
43
+ end
44
+
45
+ desc 'status', 'check if the gui service is running'
46
+ def status
47
+ Daemon.new.status
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,90 @@
1
+ require 'hidden_hippo/paths'
2
+
3
+ module HiddenHippo
4
+ class Daemon
5
+ include HiddenHippo::Paths
6
+
7
+ def initialize(name)
8
+ @name = name
9
+ end
10
+
11
+ def start
12
+ if running?
13
+ puts "#{@name} is already running"
14
+ puts "If this is not the case, delete #{pid_file}"
15
+ exit 1
16
+ else
17
+ if stale_pid_file?
18
+ puts 'Found a stale pid file, removing it'
19
+ pid_file.delete
20
+ end
21
+
22
+ pid_file.dirname.mkpath
23
+ log_file.dirname.mkpath
24
+
25
+ pid = run
26
+
27
+ File.write pid_file, pid
28
+
29
+ puts "Started #{@name} service"
30
+ end
31
+ end
32
+
33
+ def stop
34
+ if pid_file.exist?
35
+ pid = pid_file.read.to_i
36
+ Process.kill 15, pid
37
+ pid_file.delete
38
+ else
39
+ puts "#{@name} service is not running"
40
+ exit 1
41
+ end
42
+ end
43
+
44
+ def status
45
+ if pid_file.exist?
46
+ pid = pid_file.read.to_i
47
+ if HiddenHippo.pid_exists? pid
48
+ puts "#{@name} is running with pid #{pid}"
49
+ exit 0
50
+ else
51
+ puts "#{@name} is not running, but the pid file is present"
52
+ puts "You may need to delete #{pid_file}"
53
+ exit 2
54
+ end
55
+ else
56
+ puts "#{@name} is not running"
57
+ exit 1
58
+ end
59
+ end
60
+
61
+ protected
62
+
63
+ # Start the daemon in the background
64
+ #
65
+ # Sub classes should implement this method to start their daemon
66
+ #
67
+ # @return the pid of the process
68
+ def run
69
+ nil
70
+ end
71
+
72
+ def pid_file
73
+ home + 'pid' + "#{@name}.pid"
74
+ end
75
+
76
+ def log_file
77
+ home + 'log' + "#{@name}.log"
78
+ end
79
+
80
+ private
81
+
82
+ def running?
83
+ pid_file.exist? && HiddenHippo.pid_exists?(pid_file.read.to_i)
84
+ end
85
+
86
+ def stale_pid_file?
87
+ pid_file.exist? && !HiddenHippo.pid_exists?(pid_file.read.to_i)
88
+ end
89
+ end
90
+ end