to_pass 0.4.0 → 0.5.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.
- 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
|