mpw 2.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/.gitignore +1 -0
- data/CHANGELOG +13 -0
- data/Gemfile +10 -0
- data/LICENSE +339 -0
- data/README.md +14 -0
- data/VERSION +1 -0
- data/bin/mpw +165 -0
- data/bin/mpw-server +78 -0
- data/bin/mpw-ssh +89 -0
- data/i18n/cli/en.yml +149 -0
- data/i18n/cli/fr.yml +149 -0
- data/i18n/server/en.yml +26 -0
- data/i18n/server/fr.yml +26 -0
- data/lib/mpw/config.rb +231 -0
- data/lib/mpw/item.rb +109 -0
- data/lib/mpw/mpw.rb +332 -0
- data/lib/mpw/server.rb +343 -0
- data/lib/mpw/sync/ftp.rb +81 -0
- data/lib/mpw/sync/mpw.rb +124 -0
- data/lib/mpw/sync/ssh.rb +80 -0
- data/lib/mpw/sync.rb +138 -0
- data/lib/mpw/ui/cli.rb +324 -0
- data/lib/mpw/ui/clissh.rb +42 -0
- data/mpw.gemspec +19 -0
- data/test/files/fixtures.yml +32 -0
- data/test/files/test_import.csv +3 -0
- data/test/files/test_import.yml +23 -0
- data/test/test_item.rb +218 -0
- data/test/test_mpw.rb +191 -0
- data/test/tests.rb +4 -0
- metadata +82 -0
data/bin/mpw-ssh
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
# author: nishiki
|
3
|
+
# mail: nishiki@yaegashi.fr
|
4
|
+
# info: a simple script who manage your passwords
|
5
|
+
|
6
|
+
require 'rubygems'
|
7
|
+
require 'optparse'
|
8
|
+
require 'pathname'
|
9
|
+
require 'locale'
|
10
|
+
require 'i18n'
|
11
|
+
require 'mpw/ui/clissh'
|
12
|
+
require 'mpw/config'
|
13
|
+
|
14
|
+
# --------------------------------------------------------- #
|
15
|
+
# Set local
|
16
|
+
# --------------------------------------------------------- #
|
17
|
+
|
18
|
+
APP_ROOT = File.dirname(Pathname.new(__FILE__).realpath)
|
19
|
+
lang = Locale::Tag.parse(ENV['LANG']).to_simple.to_s[0..1]
|
20
|
+
|
21
|
+
if defined?(I18n.enforce_available_locales)
|
22
|
+
I18n.enforce_available_locales = true
|
23
|
+
end
|
24
|
+
|
25
|
+
I18n::Backend::Simple.send(:include, I18n::Backend::Fallbacks)
|
26
|
+
I18n.load_path = Dir["#{APP_ROOT}/../i18n/cli/*.yml"]
|
27
|
+
I18n.default_locale = :en
|
28
|
+
I18n.locale = lang.to_sym
|
29
|
+
|
30
|
+
# --------------------------------------------------------- #
|
31
|
+
# Options
|
32
|
+
# --------------------------------------------------------- #
|
33
|
+
|
34
|
+
options = {}
|
35
|
+
OptionParser.new do |opts|
|
36
|
+
opts.banner = "#{I18n.t('ssh.option.usage')}: mpw-ssh SEARCH [options]"
|
37
|
+
|
38
|
+
opts.on("-l", "--login LOGIN", I18n.t('ssh.option.login')) do |login|
|
39
|
+
options[:login] = login
|
40
|
+
end
|
41
|
+
|
42
|
+
opts.on("-s", "--server SERVER", I18n.t('ssh.option.server')) do |server|
|
43
|
+
options[:server] = server
|
44
|
+
end
|
45
|
+
|
46
|
+
opts.on("-p", "--port PORT", I18n.t('ssh.option.port')) do |port|
|
47
|
+
options[:port] = port
|
48
|
+
end
|
49
|
+
|
50
|
+
opts.on('-c', '--config CONFIG', I18n.t('cli.option.config')) do |config|
|
51
|
+
options[:config] = config
|
52
|
+
end
|
53
|
+
|
54
|
+
opts.on("-h", "--help", I18n.t('ssh.option.help')) do
|
55
|
+
puts opts
|
56
|
+
exit 0
|
57
|
+
end
|
58
|
+
end.parse!
|
59
|
+
|
60
|
+
# --------------------------------------------------------- #
|
61
|
+
# Main
|
62
|
+
# --------------------------------------------------------- #
|
63
|
+
|
64
|
+
config = MPW::Config.new(options[:config])
|
65
|
+
check_error = config.checkconfig
|
66
|
+
|
67
|
+
cli = CliSSH.new(config)
|
68
|
+
cli.login = options[:login]
|
69
|
+
cli.server = options[:server]
|
70
|
+
cli.port = options[:port]
|
71
|
+
|
72
|
+
search = ARGV[0]
|
73
|
+
|
74
|
+
# Setup a new config
|
75
|
+
if not check_error
|
76
|
+
cli.setup(lang)
|
77
|
+
|
78
|
+
elsif ARGV.length < 1
|
79
|
+
puts "#{I18n.t('ssh.option.usage')}: mpw-ssh SEARCH [options]"
|
80
|
+
exit 2
|
81
|
+
else
|
82
|
+
cli.decrypt
|
83
|
+
cli.sync
|
84
|
+
cli.ssh(search)
|
85
|
+
end
|
86
|
+
|
87
|
+
cli = nil
|
88
|
+
|
89
|
+
exit 0
|
data/i18n/cli/en.yml
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
---
|
2
|
+
en:
|
3
|
+
error:
|
4
|
+
client:
|
5
|
+
no_authorized: "You aren't authorized."
|
6
|
+
config:
|
7
|
+
write: "Can't write the config file!"
|
8
|
+
check: "Checkconfig failed!"
|
9
|
+
key_bad_format: "The key string isn't in good format!"
|
10
|
+
no_key_public: "You haven't the public key of %{key}!"
|
11
|
+
genkey_gpg:
|
12
|
+
exception: "Can't create the GPG key!"
|
13
|
+
name: "You must define a name for your GPG key!"
|
14
|
+
password: "You must define a password for your GPG key!"
|
15
|
+
delete:
|
16
|
+
id_no_exist: "Can't delete the item %{id}, it doesn't exist!"
|
17
|
+
export:
|
18
|
+
unknown_type: "The data type %{type} is unknown!"
|
19
|
+
write: "Can't export, unable to write in %{file}!"
|
20
|
+
gpg_file:
|
21
|
+
decrypt: "Can't decrypt file!"
|
22
|
+
encrypt: "Can't encrypt the GPG file!"
|
23
|
+
import:
|
24
|
+
bad_format: "Can't import, the file is badly formated!"
|
25
|
+
read: "Can't import, unable to read %{file}!"
|
26
|
+
update:
|
27
|
+
name_empty: "You must define a name!"
|
28
|
+
sync:
|
29
|
+
connection: "Connection fail!"
|
30
|
+
communication: "A communication problem with the server is appeared!"
|
31
|
+
download: "Can't download the file!"
|
32
|
+
not_authorized: "You haven't the access to remote file!"
|
33
|
+
upload: "Can't upload the file on the server!"
|
34
|
+
unknown: "An unknown error is occured!"
|
35
|
+
unknown_type: "The sync type is unknown"
|
36
|
+
|
37
|
+
warning:
|
38
|
+
select: 'Your choice is not a valid element!'
|
39
|
+
|
40
|
+
option:
|
41
|
+
usage: "Usage"
|
42
|
+
show: "Search and show the items"
|
43
|
+
show_all: "Show all items"
|
44
|
+
update: "Update an item"
|
45
|
+
remove: "Delete an item"
|
46
|
+
group: "Search the items with specified group"
|
47
|
+
add: "Add an item"
|
48
|
+
config: "Specify the configuration file to use"
|
49
|
+
setup: "Create a new configuration file"
|
50
|
+
protocol: "Select the items with the specified protocol"
|
51
|
+
export: "Export all items in a file"
|
52
|
+
type: "Data's type export file [csv|yaml]"
|
53
|
+
import: "Import item since a yaml or csv file"
|
54
|
+
force: "Force an action"
|
55
|
+
format: "Change the display items format by an alternative format"
|
56
|
+
generate_password: "Generate a random password (default 8 characters)"
|
57
|
+
help: "Show this help message"
|
58
|
+
|
59
|
+
form:
|
60
|
+
select: "Select the item: "
|
61
|
+
add:
|
62
|
+
title: "Add a new item"
|
63
|
+
name: "Enter the name: "
|
64
|
+
group: "Enter the group (optional): "
|
65
|
+
server: "Enter the hostname or ip: "
|
66
|
+
protocol: "Enter the protocol of the connection (ssh, http, other): "
|
67
|
+
login: "Enter the login connection: "
|
68
|
+
password: "Enter the the password: "
|
69
|
+
port: "Enter the connection port (optional): "
|
70
|
+
comment: "Enter a comment (optional): "
|
71
|
+
valid: "Item has been added!"
|
72
|
+
delete:
|
73
|
+
ask: "Are you sure you want to remove the item %{id} ?"
|
74
|
+
valid: "The item %{id} has been removed!"
|
75
|
+
not_valid: "The item %{id} hasn't been removed, because it doesn't exist!"
|
76
|
+
import:
|
77
|
+
ask: "Are you sure you want to import this file %{file} ?"
|
78
|
+
valid: "The import is succesfull!"
|
79
|
+
not_valid: "No data to import!"
|
80
|
+
setup:
|
81
|
+
title: "Setup a new config file"
|
82
|
+
lang: "Choose your language (en, fr, ...): "
|
83
|
+
gpg_key: "Enter the GPG key: "
|
84
|
+
share_gpg_keys: "Enter the GPG keys with who you want to share the passwords: "
|
85
|
+
gpg_file: "Enter the path to encrypt file [default=%{home}/db/default.gpg]: "
|
86
|
+
timeout: "Enter the timeout (in seconde) to GPG password [default=60]: "
|
87
|
+
sync_type: "Synchronization type (mpw, ssh, ftp, or nil): "
|
88
|
+
sync_host: "Synchronization server: "
|
89
|
+
sync_port: "Port of the synchronization server: "
|
90
|
+
sync_user: "Username for the synchronization: "
|
91
|
+
sync_pwd: "Password for the synchronization: "
|
92
|
+
sync_path: "File path for the synchronization : "
|
93
|
+
valid: "The config file has been created!"
|
94
|
+
setup_gpg_key:
|
95
|
+
title: "Setup a GPG key"
|
96
|
+
ask: "Do you want create your GPG key ? (Y/n)"
|
97
|
+
no_create: "You must create manually your GPG key or relaunch the software."
|
98
|
+
name: "Your name and lastname: "
|
99
|
+
password: "A password for the GPG key: "
|
100
|
+
confirm_password: "Confirm your password: "
|
101
|
+
error_password: "Your passwords aren't identical!"
|
102
|
+
length: "Size of the GPG key [default=2048]: "
|
103
|
+
expire: "Expire time of the GPG key [default=0 (unlimited)]: "
|
104
|
+
wait: "Please waiting during the GPG key generate, this process can take few minutes."
|
105
|
+
valid: "Your GPG key has been created ;-)"
|
106
|
+
update:
|
107
|
+
title: "Update an item"
|
108
|
+
name: "Enter the name [%{name}]: "
|
109
|
+
group: "Enter the group [%{group}]: "
|
110
|
+
server: "Enter the hostname or ip [%{server}]: "
|
111
|
+
protocol: "Enter the protocol of the connection [%{protocol}]: "
|
112
|
+
login: "Enter the login connection [%{login}]: "
|
113
|
+
password: "Enter the the password: "
|
114
|
+
port: "Enter the connection port [%{port}]: "
|
115
|
+
comment: "Enter a comment [%{comment}]: "
|
116
|
+
valid: "Item has been updated!"
|
117
|
+
export:
|
118
|
+
valid: "The export in %{file} is succesfull!"
|
119
|
+
|
120
|
+
display:
|
121
|
+
comment: "Comment"
|
122
|
+
error: "ERROR"
|
123
|
+
gpg_password: "Password GPG: "
|
124
|
+
group: "Group"
|
125
|
+
login: "Login"
|
126
|
+
name: "Name"
|
127
|
+
nothing: "Nothing result!"
|
128
|
+
password: "Password"
|
129
|
+
port: "Port"
|
130
|
+
protocol: "Protocol"
|
131
|
+
server: "Server"
|
132
|
+
warning: "Warning"
|
133
|
+
|
134
|
+
ssh:
|
135
|
+
option:
|
136
|
+
usage: "Usage"
|
137
|
+
login: "Change the login"
|
138
|
+
server: "Change the host or the ip"
|
139
|
+
port: "Change the port"
|
140
|
+
help: "Show this help message"
|
141
|
+
display:
|
142
|
+
connect: "Connection to:"
|
143
|
+
nothing: "Nothing result!"
|
144
|
+
|
145
|
+
formats:
|
146
|
+
default: ! '%Y-%m-%d'
|
147
|
+
long: ! '%B %d, %Y'
|
148
|
+
short: ! '%b %d'
|
149
|
+
custom: ! '%A, %M %B, %Y @ %l:%M%P'
|
data/i18n/cli/fr.yml
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
---
|
2
|
+
fr:
|
3
|
+
error:
|
4
|
+
client:
|
5
|
+
no_authorized: "Vous n'êtes pas autorisé!"
|
6
|
+
config:
|
7
|
+
write: "Impossible d'écrire le fichier de configuration!"
|
8
|
+
check: "Le fichier de configuration est invalide!"
|
9
|
+
key_bad_format: "La clé GPG est invalide!"
|
10
|
+
no_key_public: "Vous ne possédez pas la clé publique de %{key}!"
|
11
|
+
genkey_gpg:
|
12
|
+
exception: "La création de la clé GPG n'a pas pu aboutir!"
|
13
|
+
name: "Vous devez définir un nom pour votre clé GPG!"
|
14
|
+
password: "Vous devez définir un mot de passe pour votre clé GPG!"
|
15
|
+
delete:
|
16
|
+
id_no_exist: "Impossible de supprimer l'élément %{id}, car il n'existe pas!"
|
17
|
+
export:
|
18
|
+
unknown_type: "Le type de donnée %{type} est inconnu!"
|
19
|
+
write: "Impossible d'exporter les données dans le fichier %{file}!"
|
20
|
+
gpg_file:
|
21
|
+
decrypt: "Impossible de déchiffrer le fichier GPG!"
|
22
|
+
encrypt: "Impossible de chiffrer le fichier GPG!"
|
23
|
+
import:
|
24
|
+
bad_format: "Impossible d'importer le fichier car son format est incorrect!"
|
25
|
+
read: "Impossible d'importer le fichier %{file}, car il n'est pas lisible!"
|
26
|
+
update:
|
27
|
+
name_empty: "Vous devez définir un nom!"
|
28
|
+
sync:
|
29
|
+
connection: "La connexion n'a pu être établie!"
|
30
|
+
communication: "Un problème de communication avec le serveur est apparu!"
|
31
|
+
download: "Impossible de télécharger le fichier!"
|
32
|
+
not_authorized: "Vous n'avez pas les autorisations d'accès au fichier distant!"
|
33
|
+
upload: "Impossible d'envoyer le fichier sur le serveur!"
|
34
|
+
unknown: "Une erreur inconnue est survenue!"
|
35
|
+
unknown_type: "Le type de synchronisation est inconnu"
|
36
|
+
|
37
|
+
warning:
|
38
|
+
select: "Votre choix n'est pas un élément valide!"
|
39
|
+
|
40
|
+
option:
|
41
|
+
usage: "Utilisation"
|
42
|
+
show: "Recherche et affiche les éléments"
|
43
|
+
show_all: "Affiche tous les éléments"
|
44
|
+
update: "Met à jour un élément"
|
45
|
+
remove: "Supprime un élément"
|
46
|
+
group: "Recherche les éléments appartenant au groupe spécifié"
|
47
|
+
add: "Ajoute un élément"
|
48
|
+
config: "Spécifie le fichier de configuration à utiliser"
|
49
|
+
setup: "Création d'un nouveau fichier de configuration"
|
50
|
+
protocol: "Sélectionne les éléments ayant le protocole spécifié"
|
51
|
+
export: "Exporte tous les éléments dans un fichier"
|
52
|
+
type: "Format des données du fichier d'export [csv|yaml]"
|
53
|
+
import: "Importe des éléments depuis un fichier yaml ou csv"
|
54
|
+
force: "Force une action, l'action ne demandera pas de confirmation"
|
55
|
+
format: "Change le format d'affichage des éléments par un alternatif"
|
56
|
+
generate_password: "Génére un mot de passe aléatoire (défaut 8 caractères)"
|
57
|
+
help: "Affiche ce message d'aide"
|
58
|
+
|
59
|
+
form:
|
60
|
+
select: "Sélectionner l'élément: "
|
61
|
+
add:
|
62
|
+
title: "Ajout d'un nouvel élément"
|
63
|
+
name: "Entrez le nom: "
|
64
|
+
group: "Entrez le groupe (optionnel): "
|
65
|
+
server: "Entrez le nom de domaine ou l'ip: "
|
66
|
+
protocol: "Entrez le protocole de connexion (ssh, http, other): "
|
67
|
+
login: "Entrez l'identifiant de connexion: "
|
68
|
+
password: "Entrez le mot de passe: "
|
69
|
+
port: "Entrez le port de connexion (optionnel): "
|
70
|
+
comment: "Entrez un commentaire (optionnel): "
|
71
|
+
valid: "L'élément a bien été ajouté!"
|
72
|
+
delete:
|
73
|
+
ask: "Êtes vous sûre de vouloir supprimer l'élément %{id} ?"
|
74
|
+
valid: "L'élément %{id} a bien été supprimé!"
|
75
|
+
not_valid: "L'élément %{id} n'a pu être supprimé, car il n'existe pas!"
|
76
|
+
import:
|
77
|
+
ask: "Êtes vous sûre de vouloir importer le fichier %{file} ?"
|
78
|
+
valid: "L'import est un succès!"
|
79
|
+
not_valid: "Aucune donnée à importer!"
|
80
|
+
setup:
|
81
|
+
title: "Création d'un nouveau fichier de configuration"
|
82
|
+
lang: "Choisissez votre langue (en, fr, ...) [défaut=%{lang}]: "
|
83
|
+
gpg_key: "Entrez la clé GPG: "
|
84
|
+
share_gpg_keys: "Entrez les clés GPG avec qui vous voulez partager les mots de passe: "
|
85
|
+
gpg_file: "Entrez le chemin du fichier qui sera chiffré [défaut=%{home}/db/default.gpg]: "
|
86
|
+
timeout: "Entrez le temps (en seconde) du mot de passe GPG [défaut=60]: "
|
87
|
+
sync_type: "Type de synchronisation (mpw, ssh, ftp, or nil): "
|
88
|
+
sync_host: "Serveur de synchronisation: "
|
89
|
+
sync_port: "Port du serveur de synchronisation: "
|
90
|
+
sync_user: "Utilisateur pour la synchronisation: "
|
91
|
+
sync_pwd: "Mot de passe pour la synchronisation: "
|
92
|
+
sync_path: "Chemin du fichier pour la synchronisation: "
|
93
|
+
valid: "Le fichier de configuration a bien été créé!"
|
94
|
+
setup_gpg_key:
|
95
|
+
title: "Configuration d'une clé GPG"
|
96
|
+
ask: "Voulez vous créer votre clé GPG ? (O/n)"
|
97
|
+
no_create: "Veuillez créer manuellement votre clé GPG ou relancer le logiciel."
|
98
|
+
name: "Votre nom et prénom: "
|
99
|
+
password: "Mot de passe de la clé GPG: "
|
100
|
+
confirm_password: "Retapez votre mot de passe: "
|
101
|
+
error_password: "Vos deux mots de passes ne sont pas identiques!"
|
102
|
+
length: "Taille de la clé GPG [défaut=2048]: "
|
103
|
+
expire: "Expiration de la clé GPG [défaut=0 (illimité)]: "
|
104
|
+
wait: "Veuillez patienter durant la génération de votre clé GPG, ce processus peut prendre quelques minutes."
|
105
|
+
valid: "Votre clé GPG a bien été créée ;-)"
|
106
|
+
update:
|
107
|
+
title: "Mis à jour d'un élément"
|
108
|
+
name: "Entrez le nom [%{name}]: "
|
109
|
+
group: "Entrez le groupe [%{group}]: "
|
110
|
+
server: "Entrez le nom de domaine ou l'ip du serveur [%{server}]: "
|
111
|
+
protocol: "Entrez le protocole de connexion [%{protocol}]: "
|
112
|
+
login: "Entrez votre identifiant de connexion [%{login}]: "
|
113
|
+
password: "Entrez le mot de passe: "
|
114
|
+
port: "Entrez un port de connexion [%{port}]: "
|
115
|
+
comment: "Entrez un commentaire [%{comment}]: "
|
116
|
+
valid: "L'élément a bien été mis à jour!"
|
117
|
+
export:
|
118
|
+
valid: "L'export dans %{file} est un succès!"
|
119
|
+
|
120
|
+
display:
|
121
|
+
comment: "Commentaire"
|
122
|
+
error: "ERREUR"
|
123
|
+
gpg_password: "Mot de passe GPG: "
|
124
|
+
group: "Groupe"
|
125
|
+
login: "Identifiant"
|
126
|
+
name: "Nom"
|
127
|
+
nothing: "Aucun résultat!"
|
128
|
+
password: "Mot de passe"
|
129
|
+
port: "Port"
|
130
|
+
protocol: "Protocol"
|
131
|
+
server: "Serveur"
|
132
|
+
warning: "Warning"
|
133
|
+
|
134
|
+
ssh:
|
135
|
+
option:
|
136
|
+
usage: "Utilisation"
|
137
|
+
login: "Change l'identifiant de connexion"
|
138
|
+
server: "Change le nom de domaine ou l'ip du serveur"
|
139
|
+
port: "Change le port de connexion"
|
140
|
+
help: "Affiche ce message d'aide"
|
141
|
+
display:
|
142
|
+
connect: "Connexion à:"
|
143
|
+
nothing: "Aucun résultat!"
|
144
|
+
|
145
|
+
formats:
|
146
|
+
default: ! '%Y-%m-%d'
|
147
|
+
long: ! '%B %d, %Y'
|
148
|
+
short: ! '%b %d'
|
149
|
+
custom: ! '%A, %M %B, %Y @ %l:%M%P'
|
data/i18n/server/en.yml
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
---
|
2
|
+
en:
|
3
|
+
option:
|
4
|
+
usage: "Usage"
|
5
|
+
config: "Specifie the configuration file"
|
6
|
+
checkconfig: "Check the configuration"
|
7
|
+
setup: "Setup a new configuration file"
|
8
|
+
help: "Show this message help"
|
9
|
+
checkconfig:
|
10
|
+
fail: "Checkconfig failed:!"
|
11
|
+
empty: "ERROR: an importe option is missing!"
|
12
|
+
datadir: "ERROR: le data directory doesn't exist!"
|
13
|
+
form:
|
14
|
+
setup:
|
15
|
+
title: "Serveur configuration"
|
16
|
+
host: "IP listen: "
|
17
|
+
port: "Port listen: "
|
18
|
+
data_dir: "Data directory: "
|
19
|
+
timeout: "Timeout to second: "
|
20
|
+
log_file: "Log file path: "
|
21
|
+
not_valid: "ERROR: Impossible to write the configuration file!"
|
22
|
+
formats:
|
23
|
+
default: ! '%Y-%m-%d'
|
24
|
+
long: ! '%B %d, %Y'
|
25
|
+
short: ! '%b %d'
|
26
|
+
custom: ! '%A, %M %B, %Y @ %l:%M%P'
|
data/i18n/server/fr.yml
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
---
|
2
|
+
fr:
|
3
|
+
option:
|
4
|
+
usage: "Utilisation"
|
5
|
+
config: "Spécifie le fichier de configuration"
|
6
|
+
checkconfig: "Vérifie le fichier de configuration"
|
7
|
+
setup: "Permet de générer un nouveau fichier de configuration"
|
8
|
+
help: "Affiche ce message d'aide"
|
9
|
+
checkconfig:
|
10
|
+
fail: "Le fichier de configuration est invalide!"
|
11
|
+
empty: "ERREUR: Une option importante est manquante!"
|
12
|
+
datadir: "ERREUR: Le répertoire des données n'existe pas!"
|
13
|
+
form:
|
14
|
+
setup:
|
15
|
+
title: "Configuration du serveur"
|
16
|
+
host: "IP d'écoute: "
|
17
|
+
port: "Port d'écoute: "
|
18
|
+
data_dir: "Répertoire des données: "
|
19
|
+
log_file: "Chemin du ficier de log: "
|
20
|
+
timeout: "Timeout en seconde: "
|
21
|
+
not_valid: "ERREUR: Impossible d'écire le fichier de configuration!"
|
22
|
+
formats:
|
23
|
+
default: ! '%Y-%m-%d'
|
24
|
+
long: ! '%B %d, %Y'
|
25
|
+
short: ! '%b %d'
|
26
|
+
custom: ! '%A, %M %B, %Y @ %l:%M%P'
|
data/lib/mpw/config.rb
ADDED
@@ -0,0 +1,231 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
# author: nishiki
|
3
|
+
# mail: nishiki@yaegashi.fr
|
4
|
+
|
5
|
+
require 'rubygems'
|
6
|
+
require 'gpgme'
|
7
|
+
require 'yaml'
|
8
|
+
require 'i18n'
|
9
|
+
|
10
|
+
module MPW
|
11
|
+
class Config
|
12
|
+
|
13
|
+
attr_accessor :error_msg
|
14
|
+
|
15
|
+
attr_accessor :key
|
16
|
+
attr_accessor :share_keys
|
17
|
+
attr_accessor :lang
|
18
|
+
attr_accessor :file_gpg
|
19
|
+
attr_accessor :last_update
|
20
|
+
attr_accessor :sync_type
|
21
|
+
attr_accessor :sync_host
|
22
|
+
attr_accessor :sync_port
|
23
|
+
attr_accessor :sync_user
|
24
|
+
attr_accessor :sync_pwd
|
25
|
+
attr_accessor :sync_path
|
26
|
+
attr_accessor :last_sync
|
27
|
+
attr_accessor :dir_config
|
28
|
+
|
29
|
+
# Constructor
|
30
|
+
# @args: file_config -> the specify config file
|
31
|
+
def initialize(file_config=nil)
|
32
|
+
@error_msg = nil
|
33
|
+
|
34
|
+
if /darwin/ =~ RUBY_PLATFORM
|
35
|
+
@dir_config = "#{Dir.home}/Library/Preferences/mpw"
|
36
|
+
elsif /cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM
|
37
|
+
@dir_config = "#{Dir.home}/AppData/Local/mpw"
|
38
|
+
else
|
39
|
+
@dir_config = "#{Dir.home}/.config/mpw"
|
40
|
+
end
|
41
|
+
|
42
|
+
@file_config = "#{@dir_config}/conf/default.cfg"
|
43
|
+
if not file_config.nil? and not file_config.empty?
|
44
|
+
@file_config = file_config
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Create a new config file
|
49
|
+
# @args: key -> the gpg key to encrypt
|
50
|
+
# share_keys -> multiple keys to share the password with other people
|
51
|
+
# lang -> the software language
|
52
|
+
# file_gpg -> the file who is encrypted
|
53
|
+
# sync_type -> the type to synchronization
|
54
|
+
# sync_host -> the server host for synchronization
|
55
|
+
# sync_port -> the server port for synchronization
|
56
|
+
# sync_user -> the user for synchronization
|
57
|
+
# sync_pwd -> the password for synchronization
|
58
|
+
# sync_suffix -> the suffix file (optionnal)
|
59
|
+
# @rtrn: true if le config file is create
|
60
|
+
def setup(key, share_keys, lang, file_gpg, sync_type, sync_host, sync_port, sync_user, sync_pwd, sync_path)
|
61
|
+
|
62
|
+
if not key =~ /[a-zA-Z0-9.-_]+\@[a-zA-Z0-9]+\.[a-zA-Z]+/
|
63
|
+
@error_msg = I18n.t('error.config.key_bad_format')
|
64
|
+
return false
|
65
|
+
end
|
66
|
+
|
67
|
+
if not check_public_gpg_key(share_keys)
|
68
|
+
return false
|
69
|
+
end
|
70
|
+
|
71
|
+
if file_gpg.empty?
|
72
|
+
file_gpg = "#{@dir_config}/db/default.gpg"
|
73
|
+
end
|
74
|
+
|
75
|
+
config = {'config' => {'key' => key,
|
76
|
+
'share_keys' => share_keys,
|
77
|
+
'lang' => lang,
|
78
|
+
'file_gpg' => file_gpg,
|
79
|
+
'sync_type' => sync_type,
|
80
|
+
'sync_host' => sync_host,
|
81
|
+
'sync_port' => sync_port,
|
82
|
+
'sync_user' => sync_user,
|
83
|
+
'sync_pwd' => sync_pwd,
|
84
|
+
'sync_path' => sync_path,
|
85
|
+
'last_sync' => 0
|
86
|
+
}
|
87
|
+
}
|
88
|
+
|
89
|
+
Dir.mkdir("#{@config_dir}/conf", 700)
|
90
|
+
Dir.mkdir("#{@config_dir}/db", 700)
|
91
|
+
File.open(@file_config, 'w') do |file|
|
92
|
+
file << config.to_yaml
|
93
|
+
end
|
94
|
+
|
95
|
+
return true
|
96
|
+
rescue Exception => e
|
97
|
+
@error_msg = "#{I18n.t('error.config.write')}\n#{e}"
|
98
|
+
return false
|
99
|
+
end
|
100
|
+
|
101
|
+
# Setup a new gpg key
|
102
|
+
# @args: password -> the GPG key password
|
103
|
+
# name -> the name of user
|
104
|
+
# length -> length of the GPG key
|
105
|
+
# expire -> the time of expire to GPG key
|
106
|
+
# @rtrn: true if the GPG key is create, else false
|
107
|
+
def setup_gpg_key(password, name, length = 2048, expire = 0)
|
108
|
+
if name.nil? or name.empty?
|
109
|
+
@error_msg = "#{I18n.t('error.config.genkey_gpg.name')}"
|
110
|
+
return false
|
111
|
+
elsif password.nil? or password.empty?
|
112
|
+
@error_msg = "#{I18n.t('error.config.genkey_gpg.password')}"
|
113
|
+
return false
|
114
|
+
end
|
115
|
+
|
116
|
+
param = ''
|
117
|
+
param << '<GnupgKeyParms format="internal">' + "\n"
|
118
|
+
param << "Key-Type: DSA\n"
|
119
|
+
param << "Key-Length: #{length}\n"
|
120
|
+
param << "Subkey-Type: ELG-E\n"
|
121
|
+
param << "Subkey-Length: #{length}\n"
|
122
|
+
param << "Name-Real: #{name}\n"
|
123
|
+
param << "Name-Comment: #{name}\n"
|
124
|
+
param << "Name-Email: #{@key}\n"
|
125
|
+
param << "Expire-Date: #{expire}\n"
|
126
|
+
param << "Passphrase: #{password}\n"
|
127
|
+
param << "</GnupgKeyParms>\n"
|
128
|
+
|
129
|
+
ctx = GPGME::Ctx.new
|
130
|
+
ctx.genkey(param, nil, nil)
|
131
|
+
|
132
|
+
return true
|
133
|
+
rescue Exception => e
|
134
|
+
@error_msg = "#{I18n.t('error.config.genkey_gpg.exception')}\n#{e}"
|
135
|
+
return false
|
136
|
+
end
|
137
|
+
|
138
|
+
# Check the config file
|
139
|
+
# @rtrn: true if the config file is correct
|
140
|
+
def checkconfig
|
141
|
+
config = YAML::load_file(@file_config)
|
142
|
+
@key = config['config']['key']
|
143
|
+
@share_keys = config['config']['share_keys']
|
144
|
+
@lang = config['config']['lang']
|
145
|
+
@file_gpg = config['config']['file_gpg']
|
146
|
+
@sync_type = config['config']['sync_type']
|
147
|
+
@sync_host = config['config']['sync_host']
|
148
|
+
@sync_port = config['config']['sync_port']
|
149
|
+
@sync_user = config['config']['sync_user']
|
150
|
+
@sync_pwd = config['config']['sync_pwd']
|
151
|
+
@sync_path = config['config']['sync_path']
|
152
|
+
@last_sync = config['config']['last_sync'].to_i
|
153
|
+
|
154
|
+
if @key.empty? or @file_gpg.empty?
|
155
|
+
@error_msg = I18n.t('error.config.check')
|
156
|
+
return false
|
157
|
+
end
|
158
|
+
I18n.locale = @lang.to_sym
|
159
|
+
|
160
|
+
return true
|
161
|
+
rescue Exception => e
|
162
|
+
@error_msg = "#{I18n.t('error.config.check')}\n#{e}"
|
163
|
+
return false
|
164
|
+
end
|
165
|
+
|
166
|
+
# Check if private key exist
|
167
|
+
# @rtrn: true if the key exist, else false
|
168
|
+
def check_gpg_key?
|
169
|
+
ctx = GPGME::Ctx.new
|
170
|
+
ctx.each_key(@key, true) do
|
171
|
+
return true
|
172
|
+
end
|
173
|
+
|
174
|
+
return false
|
175
|
+
end
|
176
|
+
|
177
|
+
# Check if private key exist
|
178
|
+
# @args: share_keys -> string with all public keys
|
179
|
+
# @rtrn: true if the key exist, else false
|
180
|
+
def check_public_gpg_key(share_keys = @share_keys)
|
181
|
+
ctx = GPGME::Ctx.new
|
182
|
+
|
183
|
+
share_keys = share_keys.nil? ? '' : share_keys
|
184
|
+
if not share_keys.empty?
|
185
|
+
share_keys.split.each do |k|
|
186
|
+
if not k =~ /[a-zA-Z0-9.-_]+\@[a-zA-Z0-9]+\.[a-zA-Z]+/
|
187
|
+
@error_msg = I18n.t('error.config.key_bad_format')
|
188
|
+
return false
|
189
|
+
end
|
190
|
+
|
191
|
+
ctx.each_key(key, false) do
|
192
|
+
next
|
193
|
+
end
|
194
|
+
|
195
|
+
@error_msg = I18n.t('error.config.no_key_public', key: k)
|
196
|
+
return false
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
return true
|
201
|
+
end
|
202
|
+
|
203
|
+
# Set the last update when there is a sync
|
204
|
+
# @rtrn: true is the file has been updated
|
205
|
+
def set_last_sync
|
206
|
+
config = {'config' => {'key' => @key,
|
207
|
+
'share_keys' => @share_keys,
|
208
|
+
'lang' => @lang,
|
209
|
+
'file_gpg' => @file_gpg,
|
210
|
+
'sync_type' => @sync_type,
|
211
|
+
'sync_host' => @sync_host,
|
212
|
+
'sync_port' => @sync_port,
|
213
|
+
'sync_user' => @sync_user,
|
214
|
+
'sync_pwd' => @sync_pwd,
|
215
|
+
'sync_path' => @sync_path,
|
216
|
+
'last_sync' => Time.now.to_i
|
217
|
+
}
|
218
|
+
}
|
219
|
+
|
220
|
+
File.open(@file_config, 'w') do |file|
|
221
|
+
file << config.to_yaml
|
222
|
+
end
|
223
|
+
|
224
|
+
return true
|
225
|
+
rescue Exception => e
|
226
|
+
@error_msg = "#{I18n.t('error.config.write')}\n#{e}"
|
227
|
+
return false
|
228
|
+
end
|
229
|
+
|
230
|
+
end
|
231
|
+
end
|