to_pass 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +10 -1
- data/TODO +6 -0
- data/VERSION +1 -1
- data/bin/password_of +14 -0
- data/bin/to_pass +5 -1
- data/lib/to_pass/algorithms/secure.yml +33 -0
- data/lib/to_pass/cli.rb +5 -5
- data/lib/to_pass/converter_reader.rb +1 -1
- data/lib/to_pass/converters/downcase.rb +10 -0
- data/lib/to_pass/converters/expand_below.rb +21 -0
- data/lib/to_pass/converters/remove_repetition.rb +23 -0
- data/lib/to_pass/converters/reverse.rb +7 -0
- data/man/index.txt +8 -0
- data/man/to_pass-algorithm.5 +93 -0
- data/man/to_pass-algorithm.5.html +185 -0
- data/man/to_pass-algorithm.5.ronn +93 -0
- data/man/to_pass-converter.5 +92 -0
- data/man/to_pass-converter.5.html +164 -0
- data/man/to_pass-converter.5.ronn +71 -0
- data/man/to_pass.1 +85 -0
- data/man/to_pass.1.html +160 -0
- data/man/to_pass.1.ronn +69 -0
- data/test/test_algorithms.rb +30 -0
- data/test/test_cli.rb +6 -0
- data/test/test_converters.rb +34 -0
- metadata +24 -5
@@ -0,0 +1,164 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta http-equiv='content-type' value='text/html;charset=utf8'>
|
5
|
+
<meta name='generator' value='Ronn/v0.7.3 (http://github.com/rtomayko/ronn/tree/0.7.3)'>
|
6
|
+
<title>to_pass-converter(5) - converter-class for to_pass(1)</title>
|
7
|
+
<style type='text/css' media='all'>
|
8
|
+
/* style: man */
|
9
|
+
body#manpage {margin:0}
|
10
|
+
.mp {max-width:100ex;padding:0 9ex 1ex 4ex}
|
11
|
+
.mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
|
12
|
+
.mp h2 {margin:10px 0 0 0}
|
13
|
+
.mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
|
14
|
+
.mp h3 {margin:0 0 0 4ex}
|
15
|
+
.mp dt {margin:0;clear:left}
|
16
|
+
.mp dt.flush {float:left;width:8ex}
|
17
|
+
.mp dd {margin:0 0 0 9ex}
|
18
|
+
.mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
|
19
|
+
.mp pre {margin-bottom:20px}
|
20
|
+
.mp pre+h2,.mp pre+h3 {margin-top:22px}
|
21
|
+
.mp h2+pre,.mp h3+pre {margin-top:5px}
|
22
|
+
.mp img {display:block;margin:auto}
|
23
|
+
.mp h1.man-title {display:none}
|
24
|
+
.mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
|
25
|
+
.mp h2 {font-size:16px;line-height:1.25}
|
26
|
+
.mp h1 {font-size:20px;line-height:2}
|
27
|
+
.mp {text-align:justify;background:#fff}
|
28
|
+
.mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
|
29
|
+
.mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
|
30
|
+
.mp u {text-decoration:underline}
|
31
|
+
.mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
|
32
|
+
.mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
|
33
|
+
.mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
|
34
|
+
.mp b.man-ref {font-weight:normal;color:#434241}
|
35
|
+
.mp pre {padding:0 4ex}
|
36
|
+
.mp pre code {font-weight:normal;color:#434241}
|
37
|
+
.mp h2+pre,h3+pre {padding-left:0}
|
38
|
+
ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
|
39
|
+
ol.man-decor {width:100%}
|
40
|
+
ol.man-decor li.tl {text-align:left}
|
41
|
+
ol.man-decor li.tc {text-align:center;letter-spacing:4px}
|
42
|
+
ol.man-decor li.tr {text-align:right;float:right}
|
43
|
+
</style>
|
44
|
+
<style type='text/css' media='all'>
|
45
|
+
/* style: toc */
|
46
|
+
.man-navigation {display:block !important;position:fixed;top:0;left:113ex;height:100%;width:100%;padding:48px 0 0 0;border-left:1px solid #dbdbdb;background:#eee}
|
47
|
+
.man-navigation a,.man-navigation a:hover,.man-navigation a:link,.man-navigation a:visited {display:block;margin:0;padding:5px 2px 5px 30px;color:#999;text-decoration:none}
|
48
|
+
.man-navigation a:hover {color:#111;text-decoration:underline}
|
49
|
+
</style>
|
50
|
+
</head>
|
51
|
+
<!--
|
52
|
+
The following styles are deprecated and will be removed at some point:
|
53
|
+
div#man, div#man ol.man, div#man ol.head, div#man ol.man.
|
54
|
+
|
55
|
+
The .man-page, .man-decor, .man-head, .man-foot, .man-title, and
|
56
|
+
.man-navigation should be used instead.
|
57
|
+
-->
|
58
|
+
<body id='manpage'>
|
59
|
+
<div class='mp' id='man'>
|
60
|
+
|
61
|
+
<div class='man-navigation' style='display:none'>
|
62
|
+
<a href="#NAME">NAME</a>
|
63
|
+
<a href="#DESCRIPTION">DESCRIPTION</a>
|
64
|
+
<a href="#EXAMPLES">EXAMPLES</a>
|
65
|
+
<a href="#CAVEATS">CAVEATS</a>
|
66
|
+
<a href="#AUTHOR">AUTHOR</a>
|
67
|
+
<a href="#SEE-ALSO">SEE ALSO</a>
|
68
|
+
</div>
|
69
|
+
|
70
|
+
<ol class='man-decor man-head man head'>
|
71
|
+
<li class='tl'>to_pass-converter(5)</li>
|
72
|
+
<li class='tc'></li>
|
73
|
+
<li class='tr'>to_pass-converter(5)</li>
|
74
|
+
</ol>
|
75
|
+
|
76
|
+
<h2 id="NAME">NAME</h2>
|
77
|
+
<p class="man-name">
|
78
|
+
<code>to_pass-converter</code> - <span class="man-whatis">converter-class for <a href="to_pass.1.html" class="man-ref">to_pass<span class="s">(1)</span></a></span>
|
79
|
+
</p>
|
80
|
+
|
81
|
+
<h2 id="DESCRIPTION">DESCRIPTION</h2>
|
82
|
+
|
83
|
+
<p>Every converter class is a <a href="http://man.cx/ruby(1)" class="man-ref">ruby<span class="s">(1)</span></a> class which converts a string into a more
|
84
|
+
password-suitable form.</p>
|
85
|
+
|
86
|
+
<p>The converter classes should satisfy the following constraints:</p>
|
87
|
+
|
88
|
+
<ul>
|
89
|
+
<li>the class is scoped inside <code>ToPass::Converters</code></li>
|
90
|
+
<li>the class is named like the camelized version of the converter name</li>
|
91
|
+
<li>the class provides a class-method with the lowercased, underscored version of
|
92
|
+
the converter name</li>
|
93
|
+
</ul>
|
94
|
+
|
95
|
+
|
96
|
+
<p>All converters are called with the string as the first parameter. This string
|
97
|
+
is the result of the previous conversion or the input string, if it is the
|
98
|
+
first converter in the list.</p>
|
99
|
+
|
100
|
+
<p>If the converter accepts an additional argument (like replace), then the second
|
101
|
+
parameter is the complete rules hash. The third parameter is the argument from
|
102
|
+
the algorithm file.</p>
|
103
|
+
|
104
|
+
<p>The method is expected to return a string which should be the result of the
|
105
|
+
intended conversion.</p>
|
106
|
+
|
107
|
+
<h2 id="EXAMPLES">EXAMPLES</h2>
|
108
|
+
|
109
|
+
<p>simple converter class</p>
|
110
|
+
|
111
|
+
<pre><code>module ToPass::Converters
|
112
|
+
class FirstChars
|
113
|
+
|
114
|
+
# reduces every word to its first character, preserving case
|
115
|
+
def self.first_chars(string)
|
116
|
+
string.split(' ').map do |word|
|
117
|
+
word[0].chr
|
118
|
+
end.join(' ')
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
end
|
123
|
+
</code></pre>
|
124
|
+
|
125
|
+
<p>converter which receives additional parameters</p>
|
126
|
+
|
127
|
+
<pre><code>module ToPass::Converters
|
128
|
+
class Replace
|
129
|
+
class << self
|
130
|
+
|
131
|
+
# perform replacements on a string, based on a replacment table
|
132
|
+
def replace(string, rules, tablename)
|
133
|
+
rules['replacements'][tablename].inject(string) do |pwd, map|
|
134
|
+
pwd = pwd.gsub(/#{map[0].to_s}/, map[1].to_s)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
</code></pre>
|
142
|
+
|
143
|
+
<h2 id="CAVEATS">CAVEATS</h2>
|
144
|
+
|
145
|
+
<p>Naming is probaly most biggest concern. The name of the converter should be unique to avoid breaking other algorithms.</p>
|
146
|
+
|
147
|
+
<h2 id="AUTHOR">AUTHOR</h2>
|
148
|
+
|
149
|
+
<p>Matthias Viehweger</p>
|
150
|
+
|
151
|
+
<h2 id="SEE-ALSO">SEE ALSO</h2>
|
152
|
+
|
153
|
+
<p><a href="to_pass.1.html" class="man-ref">to_pass<span class="s">(1)</span></a>, <a href="to_pass-algorithm.5.html" class="man-ref">to_pass-algorithm<span class="s">(5)</span></a>, <a href="http://man.cx/ruby(1)" class="man-ref">ruby<span class="s">(1)</span></a></p>
|
154
|
+
|
155
|
+
|
156
|
+
<ol class='man-decor man-foot man foot'>
|
157
|
+
<li class='tl'></li>
|
158
|
+
<li class='tc'>July 2010</li>
|
159
|
+
<li class='tr'>to_pass-converter(5)</li>
|
160
|
+
</ol>
|
161
|
+
|
162
|
+
</div>
|
163
|
+
</body>
|
164
|
+
</html>
|
@@ -0,0 +1,71 @@
|
|
1
|
+
to_pass-converter(5) -- converter-class for to_pass(1)
|
2
|
+
===================================================
|
3
|
+
|
4
|
+
## DESCRIPTION
|
5
|
+
|
6
|
+
Every converter class is a ruby(1) class which converts a string into a more
|
7
|
+
password-suitable form.
|
8
|
+
|
9
|
+
The converter classes should satisfy the following constraints:
|
10
|
+
|
11
|
+
- the class is scoped inside `ToPass::Converters`
|
12
|
+
- the class is named like the camelized version of the converter name
|
13
|
+
- the class provides a class-method with the lowercased, underscored version of
|
14
|
+
the converter name
|
15
|
+
|
16
|
+
All converters are called with the string as the first parameter. This string
|
17
|
+
is the result of the previous conversion or the input string, if it is the
|
18
|
+
first converter in the list.
|
19
|
+
|
20
|
+
If the converter accepts an additional argument (like replace), then the second
|
21
|
+
parameter is the complete rules hash. The third parameter is the argument from
|
22
|
+
the algorithm file.
|
23
|
+
|
24
|
+
The method is expected to return a string which should be the result of the
|
25
|
+
intended conversion.
|
26
|
+
|
27
|
+
## EXAMPLES
|
28
|
+
|
29
|
+
simple converter class
|
30
|
+
|
31
|
+
module ToPass::Converters
|
32
|
+
class FirstChars
|
33
|
+
|
34
|
+
# reduces every word to its first character, preserving case
|
35
|
+
def self.first_chars(string)
|
36
|
+
string.split(' ').map do |word|
|
37
|
+
word[0].chr
|
38
|
+
end.join(' ')
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
converter which receives additional parameters
|
45
|
+
|
46
|
+
module ToPass::Converters
|
47
|
+
class Replace
|
48
|
+
class << self
|
49
|
+
|
50
|
+
# perform replacements on a string, based on a replacment table
|
51
|
+
def replace(string, rules, tablename)
|
52
|
+
rules['replacements'][tablename].inject(string) do |pwd, map|
|
53
|
+
pwd = pwd.gsub(/#{map[0].to_s}/, map[1].to_s)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
## CAVEATS
|
62
|
+
|
63
|
+
Naming is probaly most biggest concern. The name of the converter should be unique to avoid breaking other algorithms.
|
64
|
+
|
65
|
+
## AUTHOR
|
66
|
+
|
67
|
+
Matthias Viehweger
|
68
|
+
|
69
|
+
## SEE ALSO
|
70
|
+
|
71
|
+
to_pass(1), to_pass-algorithm(5), ruby(1)
|
data/man/to_pass.1
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
.\" generated with Ronn/v0.7.3
|
2
|
+
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
3
|
+
.
|
4
|
+
.TH "TO_PASS" "1" "July 2010" "" ""
|
5
|
+
.
|
6
|
+
.SH "NAME"
|
7
|
+
\fBto_pass\fR \- transform a string to a password
|
8
|
+
.
|
9
|
+
.SH "SYNOPSIS"
|
10
|
+
\fBto_pass\fR [\-a ALG | \-\-algorithm ALG] [\-\-pipe | \-\-no\-pipe] string
|
11
|
+
.
|
12
|
+
.br
|
13
|
+
\fBto_pass\fR [\-a ALG | \-\-algorithm ALG] [\-\-pipe | \-\-no\-pipe] < <file>
|
14
|
+
.
|
15
|
+
.br
|
16
|
+
\fBpassword_of\fR [\-a ALG | \-\-algorithm ALG] [\-\-pipe | \-\-no\-pipe] string
|
17
|
+
.
|
18
|
+
.br
|
19
|
+
\fBpassword_of\fR [\-a ALG | \-\-algorithm ALG] [\-\-pipe | \-\-no\-pipe] < <file>
|
20
|
+
.
|
21
|
+
.SH "DESCRIPTION"
|
22
|
+
\fBto_pass\fR converts a string (be it a word, a sentence or a whole book) into a password\. The transformation is done according to a algorithm which basically is a list of conversion steps\.
|
23
|
+
.
|
24
|
+
.P
|
25
|
+
Some algorithms and conversions are supplied, but you can easily add your own\. User supplied Algorithms are searched in \fB~/\.to_pass/algorithms/\fR, converter classes are searched in \fB~/\.to_pass/converters/\fR\.
|
26
|
+
.
|
27
|
+
.P
|
28
|
+
to_pass\-algorithm(5) files are written in yaml(3pm), to_pass\-converter(5) classes are ruby(1) classes\.
|
29
|
+
.
|
30
|
+
.SH "FILES"
|
31
|
+
The \fBto_pass\fR command can reads both algorithms and converters\.
|
32
|
+
.
|
33
|
+
.P
|
34
|
+
Algorithm names should match the filenames so that the library can find and load them\. Search locations are the user\-directory ~/\.to_pass/algorithm/ and the bundled algorithms\. The file is expected to have a "\.yml"\-extension
|
35
|
+
.
|
36
|
+
.P
|
37
|
+
Converters should be named like the method they provide\. Details about the expected class can be found in to_pass\-converter(5)\.
|
38
|
+
.
|
39
|
+
.SH "OPTIONS"
|
40
|
+
The following options are supported:
|
41
|
+
.
|
42
|
+
.TP
|
43
|
+
\fB\-a ALGORITHM\fR, \fB\-\-algorithm ALGORITHM\fR
|
44
|
+
Use the named algorithm\.
|
45
|
+
.
|
46
|
+
.TP
|
47
|
+
\fB\-\-pipe\fR
|
48
|
+
Output just the resulting string, without a line\-ending\.
|
49
|
+
.
|
50
|
+
.SH "EXAMPLES"
|
51
|
+
Transform the word "test" into a password:
|
52
|
+
.
|
53
|
+
.IP "" 4
|
54
|
+
.
|
55
|
+
.nf
|
56
|
+
|
57
|
+
$ to_pass test
|
58
|
+
t35t
|
59
|
+
.
|
60
|
+
.fi
|
61
|
+
.
|
62
|
+
.IP "" 0
|
63
|
+
.
|
64
|
+
.P
|
65
|
+
Transform a phrase into a password using a different algorithm:
|
66
|
+
.
|
67
|
+
.IP "" 4
|
68
|
+
.
|
69
|
+
.nf
|
70
|
+
|
71
|
+
$ password_of "there is one problem with this sentence: its too long to type into a password field" \-a basic_en
|
72
|
+
ti1pwtsi2ltti@pf
|
73
|
+
.
|
74
|
+
.fi
|
75
|
+
.
|
76
|
+
.IP "" 0
|
77
|
+
.
|
78
|
+
.SH "BUGS"
|
79
|
+
So far, no bugs are known\.
|
80
|
+
.
|
81
|
+
.SH "COPYRIGHT"
|
82
|
+
ToPass is Copyright (C) 2010 Matthias Viehweger
|
83
|
+
.
|
84
|
+
.SH "SEE ALSO"
|
85
|
+
to_pass\-converter(5), to_pass\-algorithm(5)
|
data/man/to_pass.1.html
ADDED
@@ -0,0 +1,160 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta http-equiv='content-type' value='text/html;charset=utf8'>
|
5
|
+
<meta name='generator' value='Ronn/v0.7.3 (http://github.com/rtomayko/ronn/tree/0.7.3)'>
|
6
|
+
<title>to_pass(1) - transform a string to a password</title>
|
7
|
+
<style type='text/css' media='all'>
|
8
|
+
/* style: man */
|
9
|
+
body#manpage {margin:0}
|
10
|
+
.mp {max-width:100ex;padding:0 9ex 1ex 4ex}
|
11
|
+
.mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
|
12
|
+
.mp h2 {margin:10px 0 0 0}
|
13
|
+
.mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
|
14
|
+
.mp h3 {margin:0 0 0 4ex}
|
15
|
+
.mp dt {margin:0;clear:left}
|
16
|
+
.mp dt.flush {float:left;width:8ex}
|
17
|
+
.mp dd {margin:0 0 0 9ex}
|
18
|
+
.mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
|
19
|
+
.mp pre {margin-bottom:20px}
|
20
|
+
.mp pre+h2,.mp pre+h3 {margin-top:22px}
|
21
|
+
.mp h2+pre,.mp h3+pre {margin-top:5px}
|
22
|
+
.mp img {display:block;margin:auto}
|
23
|
+
.mp h1.man-title {display:none}
|
24
|
+
.mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
|
25
|
+
.mp h2 {font-size:16px;line-height:1.25}
|
26
|
+
.mp h1 {font-size:20px;line-height:2}
|
27
|
+
.mp {text-align:justify;background:#fff}
|
28
|
+
.mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
|
29
|
+
.mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
|
30
|
+
.mp u {text-decoration:underline}
|
31
|
+
.mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
|
32
|
+
.mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
|
33
|
+
.mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
|
34
|
+
.mp b.man-ref {font-weight:normal;color:#434241}
|
35
|
+
.mp pre {padding:0 4ex}
|
36
|
+
.mp pre code {font-weight:normal;color:#434241}
|
37
|
+
.mp h2+pre,h3+pre {padding-left:0}
|
38
|
+
ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
|
39
|
+
ol.man-decor {width:100%}
|
40
|
+
ol.man-decor li.tl {text-align:left}
|
41
|
+
ol.man-decor li.tc {text-align:center;letter-spacing:4px}
|
42
|
+
ol.man-decor li.tr {text-align:right;float:right}
|
43
|
+
</style>
|
44
|
+
<style type='text/css' media='all'>
|
45
|
+
/* style: toc */
|
46
|
+
.man-navigation {display:block !important;position:fixed;top:0;left:113ex;height:100%;width:100%;padding:48px 0 0 0;border-left:1px solid #dbdbdb;background:#eee}
|
47
|
+
.man-navigation a,.man-navigation a:hover,.man-navigation a:link,.man-navigation a:visited {display:block;margin:0;padding:5px 2px 5px 30px;color:#999;text-decoration:none}
|
48
|
+
.man-navigation a:hover {color:#111;text-decoration:underline}
|
49
|
+
</style>
|
50
|
+
</head>
|
51
|
+
<!--
|
52
|
+
The following styles are deprecated and will be removed at some point:
|
53
|
+
div#man, div#man ol.man, div#man ol.head, div#man ol.man.
|
54
|
+
|
55
|
+
The .man-page, .man-decor, .man-head, .man-foot, .man-title, and
|
56
|
+
.man-navigation should be used instead.
|
57
|
+
-->
|
58
|
+
<body id='manpage'>
|
59
|
+
<div class='mp' id='man'>
|
60
|
+
|
61
|
+
<div class='man-navigation' style='display:none'>
|
62
|
+
<a href="#NAME">NAME</a>
|
63
|
+
<a href="#SYNOPSIS">SYNOPSIS</a>
|
64
|
+
<a href="#DESCRIPTION">DESCRIPTION</a>
|
65
|
+
<a href="#FILES">FILES</a>
|
66
|
+
<a href="#OPTIONS">OPTIONS</a>
|
67
|
+
<a href="#EXAMPLES">EXAMPLES</a>
|
68
|
+
<a href="#BUGS">BUGS</a>
|
69
|
+
<a href="#COPYRIGHT">COPYRIGHT</a>
|
70
|
+
<a href="#SEE-ALSO">SEE ALSO</a>
|
71
|
+
</div>
|
72
|
+
|
73
|
+
<ol class='man-decor man-head man head'>
|
74
|
+
<li class='tl'>to_pass(1)</li>
|
75
|
+
<li class='tc'></li>
|
76
|
+
<li class='tr'>to_pass(1)</li>
|
77
|
+
</ol>
|
78
|
+
|
79
|
+
<h2 id="NAME">NAME</h2>
|
80
|
+
<p class="man-name">
|
81
|
+
<code>to_pass</code> - <span class="man-whatis">transform a string to a password</span>
|
82
|
+
</p>
|
83
|
+
|
84
|
+
<h2 id="SYNOPSIS">SYNOPSIS</h2>
|
85
|
+
|
86
|
+
<p><code>to_pass</code> [-a ALG | --algorithm ALG] [--pipe | --no-pipe] string<br />
|
87
|
+
<code>to_pass</code> [-a ALG | --algorithm ALG] [--pipe | --no-pipe] < <file><br />
|
88
|
+
<code>password_of</code> [-a ALG | --algorithm ALG] [--pipe | --no-pipe] string<br />
|
89
|
+
<code>password_of</code> [-a ALG | --algorithm ALG] [--pipe | --no-pipe] < <file></p>
|
90
|
+
|
91
|
+
<h2 id="DESCRIPTION">DESCRIPTION</h2>
|
92
|
+
|
93
|
+
<p><strong>to_pass</strong> converts a string (be it a word, a sentence or a whole book) into a
|
94
|
+
password. The transformation is done according to a algorithm which basically is
|
95
|
+
a list of conversion steps.</p>
|
96
|
+
|
97
|
+
<p>Some algorithms and conversions are supplied, but you can easily add your own.
|
98
|
+
User supplied Algorithms are searched in <code>~/.to_pass/algorithms/</code>, converter
|
99
|
+
classes are searched in <code>~/.to_pass/converters/</code>.</p>
|
100
|
+
|
101
|
+
<p><a href="to_pass-algorithm.5.html" class="man-ref">to_pass-algorithm<span class="s">(5)</span></a> files are written in <a href="http://man.cx/yaml(3pm)" class="man-ref">yaml<span class="s">(3pm)</span></a>, <a href="to_pass-converter.5.html" class="man-ref">to_pass-converter<span class="s">(5)</span></a> classes are
|
102
|
+
<a href="http://man.cx/ruby(1)" class="man-ref">ruby<span class="s">(1)</span></a> classes.</p>
|
103
|
+
|
104
|
+
<h2 id="FILES">FILES</h2>
|
105
|
+
|
106
|
+
<p>The <code>to_pass</code> command can reads both algorithms and converters.</p>
|
107
|
+
|
108
|
+
<p>Algorithm names should match the filenames so that the library can find and
|
109
|
+
load them. Search locations are the user-directory ~/.to_pass/algorithm/ and
|
110
|
+
the bundled algorithms. The file is expected to have a ".yml"-extension</p>
|
111
|
+
|
112
|
+
<p>Converters should be named like the method they provide. Details about the
|
113
|
+
expected class can be found in <a href="to_pass-converter.5.html" class="man-ref">to_pass-converter<span class="s">(5)</span></a>.</p>
|
114
|
+
|
115
|
+
<h2 id="OPTIONS">OPTIONS</h2>
|
116
|
+
|
117
|
+
<p>The following options are supported:</p>
|
118
|
+
|
119
|
+
<dl>
|
120
|
+
<dt><code>-a ALGORITHM</code>, <code>--algorithm ALGORITHM</code></dt><dd><p>Use the named algorithm.</p></dd>
|
121
|
+
<dt class="flush"><code>--pipe</code></dt><dd><p>Output just the resulting string, without a line-ending.</p></dd>
|
122
|
+
</dl>
|
123
|
+
|
124
|
+
|
125
|
+
<h2 id="EXAMPLES">EXAMPLES</h2>
|
126
|
+
|
127
|
+
<p>Transform the word "test" into a password:</p>
|
128
|
+
|
129
|
+
<pre><code>$ to_pass test
|
130
|
+
t35t
|
131
|
+
</code></pre>
|
132
|
+
|
133
|
+
<p>Transform a phrase into a password using a different algorithm:</p>
|
134
|
+
|
135
|
+
<pre><code>$ password_of "there is one problem with this sentence: its too long to type into a password field" -a basic_en
|
136
|
+
ti1pwtsi2ltti@pf
|
137
|
+
</code></pre>
|
138
|
+
|
139
|
+
<h2 id="BUGS">BUGS</h2>
|
140
|
+
|
141
|
+
<p>So far, no bugs are known.</p>
|
142
|
+
|
143
|
+
<h2 id="COPYRIGHT">COPYRIGHT</h2>
|
144
|
+
|
145
|
+
<p>ToPass is Copyright (C) 2010 Matthias Viehweger</p>
|
146
|
+
|
147
|
+
<h2 id="SEE-ALSO">SEE ALSO</h2>
|
148
|
+
|
149
|
+
<p><a href="to_pass-converter.5.html" class="man-ref">to_pass-converter<span class="s">(5)</span></a>, <a href="to_pass-algorithm.5.html" class="man-ref">to_pass-algorithm<span class="s">(5)</span></a></p>
|
150
|
+
|
151
|
+
|
152
|
+
<ol class='man-decor man-foot man foot'>
|
153
|
+
<li class='tl'></li>
|
154
|
+
<li class='tc'>July 2010</li>
|
155
|
+
<li class='tr'>to_pass(1)</li>
|
156
|
+
</ol>
|
157
|
+
|
158
|
+
</div>
|
159
|
+
</body>
|
160
|
+
</html>
|
data/man/to_pass.1.ronn
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
to_pass(1) -- transform a string to a password
|
2
|
+
==============================================
|
3
|
+
|
4
|
+
## SYNOPSIS
|
5
|
+
|
6
|
+
`to_pass` [-a ALG | --algorithm ALG] [--pipe | --no-pipe] string<br>
|
7
|
+
`to_pass` [-a ALG | --algorithm ALG] [--pipe | --no-pipe] < <file><br>
|
8
|
+
`password_of` [-a ALG | --algorithm ALG] [--pipe | --no-pipe] string<br>
|
9
|
+
`password_of` [-a ALG | --algorithm ALG] [--pipe | --no-pipe] < <file>
|
10
|
+
|
11
|
+
## DESCRIPTION
|
12
|
+
|
13
|
+
**to_pass** converts a string (be it a word, a sentence or a whole book) into a
|
14
|
+
password. The transformation is done according to a algorithm which basically is
|
15
|
+
a list of conversion steps.
|
16
|
+
|
17
|
+
Some algorithms and conversions are supplied, but you can easily add your own.
|
18
|
+
User supplied Algorithms are searched in `~/.to_pass/algorithms/`, converter
|
19
|
+
classes are searched in `~/.to_pass/converters/`.
|
20
|
+
|
21
|
+
to_pass-algorithm(5) files are written in yaml(3pm), to_pass-converter(5) classes are
|
22
|
+
ruby(1) classes.
|
23
|
+
|
24
|
+
## FILES
|
25
|
+
|
26
|
+
The `to_pass` command can reads both algorithms and converters.
|
27
|
+
|
28
|
+
Algorithm names should match the filenames so that the library can find and
|
29
|
+
load them. Search locations are the user-directory ~/.to_pass/algorithm/ and
|
30
|
+
the bundled algorithms. The file is expected to have a ".yml"-extension
|
31
|
+
|
32
|
+
Converters should be named like the method they provide. Details about the
|
33
|
+
expected class can be found in to_pass-converter(5).
|
34
|
+
|
35
|
+
|
36
|
+
## OPTIONS
|
37
|
+
|
38
|
+
The following options are supported:
|
39
|
+
|
40
|
+
* `-a ALGORITHM`, `--algorithm ALGORITHM`:
|
41
|
+
Use the named algorithm.
|
42
|
+
|
43
|
+
* `--pipe`:
|
44
|
+
Output just the resulting string, without a line-ending.
|
45
|
+
|
46
|
+
|
47
|
+
## EXAMPLES
|
48
|
+
|
49
|
+
Transform the word "test" into a password:
|
50
|
+
|
51
|
+
$ to_pass test
|
52
|
+
t35t
|
53
|
+
|
54
|
+
Transform a phrase into a password using a different algorithm:
|
55
|
+
|
56
|
+
$ password_of "there is one problem with this sentence: its too long to type into a password field" -a basic_en
|
57
|
+
ti1pwtsi2ltti@pf
|
58
|
+
|
59
|
+
## BUGS
|
60
|
+
|
61
|
+
So far, no bugs are known.
|
62
|
+
|
63
|
+
## COPYRIGHT
|
64
|
+
|
65
|
+
ToPass is Copyright (C) 2010 Matthias Viehweger
|
66
|
+
|
67
|
+
## SEE ALSO
|
68
|
+
|
69
|
+
to_pass-converter(5), to_pass-algorithm(5)
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# vim:ft=ruby:enc=utf-8
|
3
|
+
|
4
|
+
require File.dirname(__FILE__)+'/helper'
|
5
|
+
|
6
|
+
class TestAlgorithms < Test::Unit::TestCase
|
7
|
+
def test_basic_de
|
8
|
+
assert_algorithm 't35t', 'test', :basic_de
|
9
|
+
assert_algorithm 'Ds1P@dF', 'Da steht ein Pferd auf dem Flur', :basic_de
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_basic_en
|
13
|
+
assert_algorithm "t35t", 'test', :basic_en
|
14
|
+
assert_algorithm "ti1p4u2", 'there is one problem for us, too', :basic_en
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_secure
|
18
|
+
assert_algorithm '$78bRk0N5fKt5Et', 'test', :secure
|
19
|
+
assert_algorithm '5P2fWb0Wf%$52Cm', 'my cat is cute', :secure
|
20
|
+
end
|
21
|
+
|
22
|
+
protected
|
23
|
+
|
24
|
+
def assert_algorithm(expected, input, algorithm)
|
25
|
+
assert_nothing_raised do
|
26
|
+
pwd = ToPass::Base.new(input, algorithm).to_s
|
27
|
+
assert_equal expected, pwd
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/test/test_cli.rb
CHANGED
@@ -12,6 +12,12 @@ class TestCli < Test::Unit::TestCase
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
+
def test_cli_usage_with_password_of
|
16
|
+
assert_nothing_raised do
|
17
|
+
assert_equal "t35t", `bin/password_of test`.chomp
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
15
21
|
def test_cli_usage_with_algorithm
|
16
22
|
assert_nothing_raised do
|
17
23
|
assert_equal "ti1p4u2", `bin/to_pass 'there is one problem for us, too' -a basic_en`.chomp
|
data/test/test_converters.rb
CHANGED
@@ -7,4 +7,38 @@ class TestConverters < Test::Unit::TestCase
|
|
7
7
|
def test_presence
|
8
8
|
assert_module_defined ToPass::Converters
|
9
9
|
end
|
10
|
+
|
11
|
+
def test_downcase
|
12
|
+
assert_converter 'test', 'downcase', 'tEsT'
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_remove_repetition
|
16
|
+
assert_converter 'helo', 'remove_repetition', 'helo'
|
17
|
+
assert_converter 'hel2o', 'remove_repetition', 'hello'
|
18
|
+
assert_converter 'hel3o', 'remove_repetition', 'helllo'
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_expand_below
|
22
|
+
# digest = "#{MD5.hexdigest(string)}#{MD5.hexdigest(string).reverse}"
|
23
|
+
# 1.upto(digest.length / 2).map { |nr| digest[(nr*2-2),2] }.map { |pair| pair.to_i(16).chr }.map { |char| char if char =~ /\w/i }.compact.join
|
24
|
+
assert_converter 'testkFsNoKrb87d', { 'expand_below' => 5 }, 'test'
|
25
|
+
assert_converter 'testtest', { 'expand_below' => 5 }, 'testtest'
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_reverse
|
29
|
+
assert_converter 'tset', 'reverse', 'test'
|
30
|
+
end
|
31
|
+
|
32
|
+
protected
|
33
|
+
|
34
|
+
def assert_converter(expected, rule, string = 'test')
|
35
|
+
assert_nothing_raised LoadError do
|
36
|
+
result = converter.send(:apply_rule, string, rule)
|
37
|
+
assert_equal expected, result, "Converter '#{rule.inspect}' should convert #{string} to #{expected}."
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def converter
|
42
|
+
ToPass::Converter.new({})
|
43
|
+
end
|
10
44
|
end
|