yopass 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Gemfile +10 -0
- data/README.md +36 -0
- data/conf/config.ru +3 -0
- data/conf/yopass.yaml +9 -0
- data/lib/static/css/bootstrap-theme.min.css +7 -0
- data/lib/static/css/bootstrap.min.css +7 -0
- data/lib/static/css/jumbotron.css +80 -0
- data/lib/static/fonts/glyphicons-halflings-regular.eot +0 -0
- data/lib/static/fonts/glyphicons-halflings-regular.svg +229 -0
- data/lib/static/fonts/glyphicons-halflings-regular.ttf +0 -0
- data/lib/static/fonts/glyphicons-halflings-regular.woff +0 -0
- data/lib/static/foo.css +1 -0
- data/lib/static/js/bootstrap.min.js +7 -0
- data/lib/views/404.erb +10 -0
- data/lib/views/footer.erb +13 -0
- data/lib/views/get_secret.erb +11 -0
- data/lib/views/header.erb +31 -0
- data/lib/views/index.erb +56 -0
- data/lib/views/secret_url.erb +8 -0
- data/lib/yopass.rb +97 -0
- data/lib/yopass/sms_provider.rb +11 -0
- data/lib/yopass/sms_provider/bulksms.rb +18 -0
- metadata +109 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<%= erb :header %>
|
|
2
|
+
<form role="form" method="GET">
|
|
3
|
+
<div class="form-group">
|
|
4
|
+
<label>Password</label>
|
|
5
|
+
<input type="password" class="form-control" name="p" placeholder="Password to decrypt secret">
|
|
6
|
+
<input type="hidden" class="form-control" name="k" value="<%=key%>" hidden="true">
|
|
7
|
+
</div>
|
|
8
|
+
<button type="submit" class="btn btn-default">Submit</button>
|
|
9
|
+
</form>
|
|
10
|
+
<br/>
|
|
11
|
+
<%= erb :footer %>
|
|
@@ -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.0">
|
|
7
|
+
<meta name="description" content="">
|
|
8
|
+
<meta name="author" content="Johan Haals">
|
|
9
|
+
|
|
10
|
+
<title>YoPass Share Secrets</title>
|
|
11
|
+
|
|
12
|
+
<!-- Bootstrap core CSS -->
|
|
13
|
+
<link href="/css/bootstrap.min.css" rel="stylesheet">
|
|
14
|
+
|
|
15
|
+
<!-- Custom styles for this template -->
|
|
16
|
+
<link href="/css/jumbotron.css" rel="stylesheet">
|
|
17
|
+
|
|
18
|
+
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
|
|
19
|
+
<!--[if lt IE 9]>
|
|
20
|
+
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
|
|
21
|
+
<script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
|
|
22
|
+
<![endif]-->
|
|
23
|
+
</head>
|
|
24
|
+
|
|
25
|
+
<body>
|
|
26
|
+
|
|
27
|
+
<div class="container">
|
|
28
|
+
<div class="header">
|
|
29
|
+
<h3 class="text-muted"><a href="/">YoPass</a> Share Secrets Securely</h3>
|
|
30
|
+
</div>
|
|
31
|
+
|
data/lib/views/index.erb
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
<%= erb :header %>
|
|
2
|
+
<form role="form" method="post">
|
|
3
|
+
<div class="form-group">
|
|
4
|
+
<label>Secret</label>
|
|
5
|
+
<textarea placeholder="Your secret" class="form-control" rows="6" name="secret"></textarea>
|
|
6
|
+
</div>
|
|
7
|
+
<label>Self destruct after</label>
|
|
8
|
+
<div class="radio">
|
|
9
|
+
<label>
|
|
10
|
+
<input type="radio" name="lifetime" value="1w" checked>1 Week
|
|
11
|
+
</label>
|
|
12
|
+
</div>
|
|
13
|
+
<div class="radio">
|
|
14
|
+
<label>
|
|
15
|
+
<input type="radio" name="lifetime" value="1d">1 Day
|
|
16
|
+
</label>
|
|
17
|
+
</div>
|
|
18
|
+
<div class="radio">
|
|
19
|
+
<label>
|
|
20
|
+
<input type="radio" name="lifetime" value="1h">1 Hour
|
|
21
|
+
</label>
|
|
22
|
+
</div>
|
|
23
|
+
<% if send_sms %>
|
|
24
|
+
<div class="form-group">
|
|
25
|
+
<label>Send decryption key over SMS</label>
|
|
26
|
+
<i>Remember country code</i>
|
|
27
|
+
<input type="input" class="form-control" name="mobile_number" placeholder="eg 46702224990">
|
|
28
|
+
</div>
|
|
29
|
+
<% end %>
|
|
30
|
+
<button type="submit" class="btn btn-primary">Store Secret</button>
|
|
31
|
+
</form>
|
|
32
|
+
<br/>
|
|
33
|
+
<div class="row marketing">
|
|
34
|
+
<div class="col-lg-6">
|
|
35
|
+
<h4><span class="glyphicon glyphicon-lock"></span> AES-256 Encryption</h4>
|
|
36
|
+
<p>Your secret is encrypted and no records of the decryption key is stored anywhere</p>
|
|
37
|
+
|
|
38
|
+
<h4><span class="glyphicon glyphicon-floppy-remove"></span> Never stored on disk</h4>
|
|
39
|
+
<p>Your secret is stored in memory to incease security</p>
|
|
40
|
+
|
|
41
|
+
<h4><span class="glyphicon glyphicon-eye-open"></span> Visible Once</h4>
|
|
42
|
+
<p>Your secret is only visible once to make sure it's never been seen by anyone except the receiver</p>
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
<div class="col-lg-6">
|
|
46
|
+
<h4><span class="glyphicon glyphicon-time"></span> Self Destruction</h4>
|
|
47
|
+
<p>All secrets will self destruct after X hours</p>
|
|
48
|
+
|
|
49
|
+
<h4><span class="glyphicon glyphicon-bullhorn"></span> Open Source</h4>
|
|
50
|
+
<p>This website is open source meaning you can submit feedback and patches to improve the project</p>
|
|
51
|
+
|
|
52
|
+
<h4><span class="glyphicon glyphicon-minus-sign"></span> No Caching</h4>
|
|
53
|
+
<p>Caching headers are disabled</p>
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
<%= erb :footer %>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<%= erb :header %>
|
|
2
|
+
<h2>URL for your secret</h2>
|
|
3
|
+
<p><b><%=url%></b></p>
|
|
4
|
+
<p>Your secret can only be viewed ONCE, do not open the URL yourself</p>
|
|
5
|
+
<% if key_sent_to_mobile %>
|
|
6
|
+
<p>The decryption key is sent to the receiver via sms, dont forget to provide the URL via another channel</p>
|
|
7
|
+
<% end %>
|
|
8
|
+
<%= erb :footer %>
|
data/lib/yopass.rb
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
require 'memcached'
|
|
2
|
+
require 'sinatra/base'
|
|
3
|
+
require 'securerandom'
|
|
4
|
+
require 'encryptor'
|
|
5
|
+
require 'yaml'
|
|
6
|
+
require 'uri'
|
|
7
|
+
require 'yopass/sms_provider'
|
|
8
|
+
|
|
9
|
+
class Yopass < Sinatra::Base
|
|
10
|
+
configure :development do
|
|
11
|
+
require 'sinatra/reloader'
|
|
12
|
+
register Sinatra::Reloader
|
|
13
|
+
set :config, YAML.load_file('conf/yopass.yaml')
|
|
14
|
+
end
|
|
15
|
+
configure :production do
|
|
16
|
+
set :config, YAML.load_file('/etc/yopass.yaml')
|
|
17
|
+
end
|
|
18
|
+
configure do
|
|
19
|
+
set :cache, Memcached.new(settings.config['memcached_url'])
|
|
20
|
+
set :public_folder, File.dirname(__FILE__) + '/static'
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
get '/' do
|
|
24
|
+
# display mobile number field if send_sms is true
|
|
25
|
+
erb :index, :locals => {:send_sms => settings.config['send_sms']}
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
post '/' do
|
|
29
|
+
headers 'Cache-Control' => 'no-cache, no-store, must-revalidate'
|
|
30
|
+
headers 'Pragma' => 'no-cache'
|
|
31
|
+
headers 'Expires' => '0'
|
|
32
|
+
|
|
33
|
+
lifetime = params[:lifetime]
|
|
34
|
+
# calculate lifetime in secounds
|
|
35
|
+
lifetime_options = { '1w' => 3600*24*7,
|
|
36
|
+
'1d' => 3600*24,
|
|
37
|
+
'1h' => 3600,
|
|
38
|
+
}
|
|
39
|
+
# Verify that user has posted a valid lifetime
|
|
40
|
+
return 'Invalid lifetime' unless lifetime_options.include? lifetime
|
|
41
|
+
return 'No secret submitted' if params[:secret].empty?
|
|
42
|
+
return 'This site is meant to store secrets not novels' if params[:secret].length >= 10000
|
|
43
|
+
|
|
44
|
+
# goes in URL
|
|
45
|
+
key = SecureRandom.urlsafe_base64 8
|
|
46
|
+
# password goes in URL or via SMS if provider is configured
|
|
47
|
+
password = SecureRandom.urlsafe_base64 8
|
|
48
|
+
# encrypt secret with generated password
|
|
49
|
+
data = Encryptor.encrypt(params[:secret], :key => password)
|
|
50
|
+
# store secret in memcached
|
|
51
|
+
settings.cache.set key, data, lifetime_options[lifetime]
|
|
52
|
+
|
|
53
|
+
if settings.config['send_sms'] == true and !params[:mobile_number].nil?
|
|
54
|
+
# strip everything except digits
|
|
55
|
+
mobile_number = params[:mobile_number].gsub(/[^0-9]/, "")
|
|
56
|
+
# load specified sms provider
|
|
57
|
+
sms = SmsProvider.create(settings.config['sms::provider'],
|
|
58
|
+
settings.config['sms::settings'])
|
|
59
|
+
|
|
60
|
+
unless params[:mobile_number].empty?
|
|
61
|
+
# TODO verification
|
|
62
|
+
sms.send(mobile_number, password)
|
|
63
|
+
return erb :secret_url, :locals => {
|
|
64
|
+
:url => URI.join(settings.config['http_base_url'], "get?k=#{key}"),
|
|
65
|
+
:key_sent_to_mobile => true }
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
erb :secret_url, :locals => {:url => URI.join(settings.config['http_base_url'], "get?k=#{key}&p=#{password}")}
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
get '/get' do
|
|
73
|
+
# No password added
|
|
74
|
+
return erb :get_secret, :locals => {:key => params[:k]} if params[:p].nil? or params[:p].empty?
|
|
75
|
+
|
|
76
|
+
# Disable all caching
|
|
77
|
+
headers 'Cache-Control' => 'no-cache, no-store, must-revalidate'
|
|
78
|
+
headers 'Pragma' => 'no-cache'
|
|
79
|
+
headers 'Expires' => '0'
|
|
80
|
+
begin
|
|
81
|
+
result = settings.cache.get params[:k]
|
|
82
|
+
rescue Memcached::NotFound
|
|
83
|
+
return erb :'404'
|
|
84
|
+
end
|
|
85
|
+
content_type 'text/plain'
|
|
86
|
+
|
|
87
|
+
begin
|
|
88
|
+
result = Encryptor.decrypt(:value => result, :key => params[:p])
|
|
89
|
+
rescue OpenSSL::Cipher::CipherError
|
|
90
|
+
return 'Invalid decryption key'
|
|
91
|
+
end
|
|
92
|
+
settings.cache.delete params[:k]
|
|
93
|
+
result
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
run! if app_file == $0
|
|
97
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
class SmsProvider
|
|
2
|
+
def self.create(provider, settings)
|
|
3
|
+
begin
|
|
4
|
+
require "yopass/sms_provider/#{provider.downcase}"
|
|
5
|
+
rescue LoadError => e
|
|
6
|
+
raise "Unsupported provider #{provider}: #{e}"
|
|
7
|
+
end
|
|
8
|
+
class_name = provider.split("_").map {|v| v.capitalize }.join
|
|
9
|
+
const_get(class_name).new settings
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require 'open-uri'
|
|
2
|
+
|
|
3
|
+
class Bulksms
|
|
4
|
+
def initialize(settings)
|
|
5
|
+
@api_url = 'http://bulksms.vsms.net:5567/eapi/submission/send_sms/2/2.0'
|
|
6
|
+
@username = settings['username']
|
|
7
|
+
@password = settings['password']
|
|
8
|
+
@sender = settings['sender']
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def send(to, message)
|
|
12
|
+
url = URI.join(@api_url, "?username=#{@username}&password=#{@password}" \
|
|
13
|
+
"&message=#{message}&msisdn=#{to}&sender=#{@sender}")
|
|
14
|
+
result = open(url).read
|
|
15
|
+
return true if result.include? "IN_PROGRESS"
|
|
16
|
+
false
|
|
17
|
+
end
|
|
18
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: yopass
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Johan Haals
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2014-01-24 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: encryptor
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - '>='
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - '>='
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: memcached
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - '>='
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - '>='
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: sinatra
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - '>='
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0'
|
|
48
|
+
type: :runtime
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - '>='
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
55
|
+
description: Web service for sharing secrets more securely
|
|
56
|
+
email:
|
|
57
|
+
- jhaals@spotify.com
|
|
58
|
+
executables: []
|
|
59
|
+
extensions: []
|
|
60
|
+
extra_rdoc_files: []
|
|
61
|
+
files:
|
|
62
|
+
- Gemfile
|
|
63
|
+
- README.md
|
|
64
|
+
- conf/config.ru
|
|
65
|
+
- conf/yopass.yaml
|
|
66
|
+
- lib/static/css/bootstrap-theme.min.css
|
|
67
|
+
- lib/static/css/bootstrap.min.css
|
|
68
|
+
- lib/static/css/jumbotron.css
|
|
69
|
+
- lib/static/fonts/glyphicons-halflings-regular.eot
|
|
70
|
+
- lib/static/fonts/glyphicons-halflings-regular.svg
|
|
71
|
+
- lib/static/fonts/glyphicons-halflings-regular.ttf
|
|
72
|
+
- lib/static/fonts/glyphicons-halflings-regular.woff
|
|
73
|
+
- lib/static/foo.css
|
|
74
|
+
- lib/static/js/bootstrap.min.js
|
|
75
|
+
- lib/views/404.erb
|
|
76
|
+
- lib/views/footer.erb
|
|
77
|
+
- lib/views/get_secret.erb
|
|
78
|
+
- lib/views/header.erb
|
|
79
|
+
- lib/views/index.erb
|
|
80
|
+
- lib/views/secret_url.erb
|
|
81
|
+
- lib/yopass.rb
|
|
82
|
+
- lib/yopass/sms_provider.rb
|
|
83
|
+
- lib/yopass/sms_provider/bulksms.rb
|
|
84
|
+
homepage: https://github.com/jhaals/yopass
|
|
85
|
+
licenses:
|
|
86
|
+
- Apache 2.0
|
|
87
|
+
metadata: {}
|
|
88
|
+
post_install_message:
|
|
89
|
+
rdoc_options: []
|
|
90
|
+
require_paths:
|
|
91
|
+
- lib
|
|
92
|
+
- conf
|
|
93
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
94
|
+
requirements:
|
|
95
|
+
- - '>='
|
|
96
|
+
- !ruby/object:Gem::Version
|
|
97
|
+
version: 1.8.7
|
|
98
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
99
|
+
requirements:
|
|
100
|
+
- - '>='
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
version: '0'
|
|
103
|
+
requirements: []
|
|
104
|
+
rubyforge_project:
|
|
105
|
+
rubygems_version: 2.0.3
|
|
106
|
+
signing_key:
|
|
107
|
+
specification_version: 4
|
|
108
|
+
summary: Secure sharing for secrets and passwords
|
|
109
|
+
test_files: []
|