grim-reaper 1.0.32 ā 1.0.34
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 +4 -4
- data/README.md +105 -0
- data/bin/grim +249 -34
- data/lib/grim_reaper/core.rb +14 -0
- data/lib/grim_reaper/installer.rb +156 -23
- data/lib/grim_reaper/otp_module.rb +275 -0
- data/lib/grim_reaper/version.rb +1 -1
- data/lib/grim_reaper.rb +9 -0
- metadata +17 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3e995dc62a1b7e977043d7356552ca215771c85375621edaaf9b4ee9e62ccdc5
|
4
|
+
data.tar.gz: f01964b9bb32a4d6ca739e4f78ed9da9af81638832bd7967cadf441ae415e83b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9ce86d8d9daee4c5aa4a70d04008bf2608840696b111227c7480535b25208f17766207bd0bf54576896df2ccbb00b9e202797d2ac251eb1267b8c2a6314aa18b
|
7
|
+
data.tar.gz: 74b57781c00e33a617a08b86a3a2c4dffd27b25d60fe9e443649711af5c36057b0090d9bcd5e1e45d06bd193cb28aee5355b40e336a12718c9a02c5326ed136f
|
data/README.md
CHANGED
@@ -8,12 +8,117 @@
|
|
8
8
|
|
9
9
|
Enterprise-grade data protection platform with AI-powered backup decisions, military-grade encryption, multi-algorithm compression, content-based deduplication, real-time monitoring, and automated threat response.
|
10
10
|
|
11
|
+
## š What's New in v1.0.34
|
12
|
+
|
13
|
+
### š **Latest.tar.gz Auto-Download System**
|
14
|
+
- **Direct Install**: Now downloads complete Grim system from `get.grim.so/latest.tar.gz`
|
15
|
+
- **Smart Extraction**: Properly handles `graveyard/reaper/` structure with `--strip-components=2`
|
16
|
+
- **Auto-Environment**: Automatically sets `GRIM_ROOT`, `GRIM_LICENSE=FREE`, `GRIM_REAPER=FALSE`
|
17
|
+
- **Intelligent Paths**: Tries `/root/.grim`, `$HOME/.grim`, or local directory
|
18
|
+
- **Executable Scripts**: Automatically makes all scripts executable
|
19
|
+
- **Bashrc Integration**: Adds environment to `~/.bashrc` for persistence
|
20
|
+
|
21
|
+
### šļø **Professional Tier System (July 2025)**
|
22
|
+
Complete overhaul of pricing structure with 6-tier system:
|
23
|
+
|
24
|
+
- **š FREE** ($0) - 1GB storage, 15 commands, encrypted auto-backups
|
25
|
+
- **š¼ BASIC** ($19) - 25GB cloud, 35 commands, removes encryption friction
|
26
|
+
- **š PRO** ($49) - 100GB storage, 60 commands, AI-powered decisions
|
27
|
+
- **āļø MASTER** ($99) - 1TB storage, 200+ commands, enterprise compliance
|
28
|
+
- **š REAPER** ($499) - Unlimited storage, custom development, 24/7 support
|
29
|
+
- **š¢ ENTERPRISE** (Custom) - Global deployment, source code access, strategic partnership
|
30
|
+
|
31
|
+
### š§ **Critical Infrastructure Fixes (July 26-27, 2025)**
|
32
|
+
- **SSL Certificate Crisis**: Fixed `up.grim.so` SSL mismatch (was `cyberboost.com`)
|
33
|
+
- **Port Configuration**: Corrected auto-update service from `4745` ā `5001`
|
34
|
+
- **Auto-Update Daemon**: Restored background version checking for 5000+ installations
|
35
|
+
- **Nginx Proxy**: Fixed proxy configuration for proper request routing
|
36
|
+
- **Function Dependencies**: Resolved `log_update` function order bugs
|
37
|
+
|
38
|
+
### š **Enhanced Security Features**
|
39
|
+
- **OTP Authentication**: TOTP support with QR codes and backup codes
|
40
|
+
- **Environment Protection**: Smart environment variable detection and setup
|
41
|
+
- **Secure Downloads**: HTTPS-only downloads with SSL verification
|
42
|
+
- **Permission Management**: Automatic executable permissions for all scripts
|
43
|
+
|
11
44
|
## š Quick Install
|
12
45
|
|
13
46
|
```bash
|
14
47
|
gem install grim-reaper
|
15
48
|
```
|
16
49
|
|
50
|
+
## šÆ Quick Start Commands
|
51
|
+
|
52
|
+
```bash
|
53
|
+
# Download and install complete Grim system
|
54
|
+
grim download-latest
|
55
|
+
|
56
|
+
# Setup complete environment (Python, Go, Shell, Scythe)
|
57
|
+
grim setup-complete
|
58
|
+
|
59
|
+
# Check installation status
|
60
|
+
grim check-installation
|
61
|
+
|
62
|
+
# Health check all modules
|
63
|
+
grim health
|
64
|
+
```
|
65
|
+
|
66
|
+
## š Enhanced OTP Authentication
|
67
|
+
|
68
|
+
Enhanced security with One-Time Password (TOTP) authentication:
|
69
|
+
|
70
|
+
```bash
|
71
|
+
# Setup OTP authentication
|
72
|
+
grim otp-setup
|
73
|
+
|
74
|
+
# Use OTP with commands
|
75
|
+
grim health --otp 123456
|
76
|
+
grim setup-complete --otp 789012
|
77
|
+
|
78
|
+
# Check OTP status
|
79
|
+
grim otp-status
|
80
|
+
|
81
|
+
# Verify OTP code
|
82
|
+
grim otp-verify 123456
|
83
|
+
```
|
84
|
+
|
85
|
+
## šÆ Ruby Integration
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
require 'grim_reaper'
|
89
|
+
|
90
|
+
# Initialize with auto-download
|
91
|
+
grim = GrimReaper.new
|
92
|
+
|
93
|
+
# Download latest if not installed
|
94
|
+
installer = GrimReaper::Installer.new
|
95
|
+
installer.download_latest_grim unless installer.find_grim_root
|
96
|
+
|
97
|
+
# Quick operations
|
98
|
+
grim.backup('/important/data')
|
99
|
+
grim.monitor('/var/log')
|
100
|
+
grim.security
|
101
|
+
```
|
102
|
+
|
103
|
+
## š„ Installation Options
|
104
|
+
|
105
|
+
### Option 1: Ruby Gem (Recommended)
|
106
|
+
```bash
|
107
|
+
gem install grim-reaper
|
108
|
+
grim download-latest
|
109
|
+
```
|
110
|
+
|
111
|
+
### Option 2: Direct Download
|
112
|
+
```bash
|
113
|
+
curl -sSL get.grim.so | sudo bash
|
114
|
+
```
|
115
|
+
|
116
|
+
### Option 3: Manual Setup
|
117
|
+
```bash
|
118
|
+
gem install grim-reaper
|
119
|
+
grim setup-complete
|
120
|
+
```
|
121
|
+
|
17
122
|
## šÆ Quick Start
|
18
123
|
|
19
124
|
```ruby
|
data/bin/grim
CHANGED
@@ -12,6 +12,7 @@ class GrimCLI < Thor
|
|
12
12
|
class_option :config, type: :string, default: "grim.yml", desc: "Configuration file path"
|
13
13
|
class_option :verbose, type: :boolean, default: false, desc: "Enable verbose output"
|
14
14
|
class_option :json, type: :boolean, default: false, desc: "Output in JSON format"
|
15
|
+
class_option :otp, type: :string, desc: "One-Time Password for secure authentication"
|
15
16
|
|
16
17
|
desc "version", "Show Grim Reaper version"
|
17
18
|
def version
|
@@ -19,23 +20,173 @@ class GrimCLI < Thor
|
|
19
20
|
puts "The Ultimate Backup, Monitoring, and Security System"
|
20
21
|
puts "By Bernie Gengel and his beagle Buddy"
|
21
22
|
end
|
23
|
+
|
24
|
+
desc "otp-setup", "Setup OTP authentication for Grim Reaper"
|
25
|
+
def otp_setup
|
26
|
+
puts "š Setting up OTP authentication...".colorize(:cyan)
|
27
|
+
|
28
|
+
begin
|
29
|
+
grim = GrimReaper::Core.new(load_config)
|
30
|
+
otp_module = grim.get_otp_module
|
31
|
+
|
32
|
+
if otp_module.setup_otp
|
33
|
+
puts "ā
OTP authentication setup complete!".colorize(:green)
|
34
|
+
puts "š± Scan the QR code with your authenticator app".colorize(:blue)
|
35
|
+
puts "š Save your backup codes in a secure location".colorize(:yellow)
|
36
|
+
else
|
37
|
+
puts "ā OTP setup failed".colorize(:red)
|
38
|
+
exit 1
|
39
|
+
end
|
40
|
+
rescue => e
|
41
|
+
puts "ā OTP setup failed: #{e.message}".colorize(:red)
|
42
|
+
exit 1
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
desc "otp-verify CODE", "Verify OTP code"
|
47
|
+
def otp_verify(code)
|
48
|
+
puts "š Verifying OTP code...".colorize(:cyan)
|
49
|
+
|
50
|
+
begin
|
51
|
+
grim = GrimReaper::Core.new(load_config)
|
52
|
+
otp_module = grim.get_otp_module
|
53
|
+
|
54
|
+
if otp_module.verify_otp(code)
|
55
|
+
puts "ā
OTP verification successful!".colorize(:green)
|
56
|
+
else
|
57
|
+
puts "ā Invalid OTP code".colorize(:red)
|
58
|
+
exit 1
|
59
|
+
end
|
60
|
+
rescue => e
|
61
|
+
puts "ā OTP verification failed: #{e.message}".colorize(:red)
|
62
|
+
exit 1
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
desc "otp-status", "Check OTP authentication status"
|
67
|
+
def otp_status
|
68
|
+
puts "š Checking OTP status...".colorize(:cyan)
|
69
|
+
|
70
|
+
begin
|
71
|
+
grim = GrimReaper::Core.new(load_config)
|
72
|
+
otp_module = grim.get_otp_module
|
73
|
+
status = otp_module.status
|
74
|
+
|
75
|
+
if options[:json]
|
76
|
+
puts JSON.pretty_generate(status)
|
77
|
+
else
|
78
|
+
puts "OTP Status: #{status[:enabled] ? 'Enabled'.colorize(:green) : 'Disabled'.colorize(:red)}"
|
79
|
+
puts "Last Authentication: #{status[:last_auth] || 'Never'}"
|
80
|
+
puts "Failed Attempts: #{status[:failed_attempts] || 0}"
|
81
|
+
end
|
82
|
+
rescue => e
|
83
|
+
puts "ā Status check failed: #{e.message}".colorize(:red)
|
84
|
+
end
|
85
|
+
end
|
22
86
|
|
23
87
|
desc "setup-complete", "Setup complete Grim Reaper environment (installs Python, Go, Shell, Scythe components)"
|
24
88
|
def setup_complete
|
89
|
+
if options[:otp] && !validate_otp_access
|
90
|
+
return
|
91
|
+
end
|
92
|
+
|
25
93
|
puts "š”ļø Setting up complete Grim Reaper environment...".colorize(:cyan)
|
26
94
|
|
27
95
|
begin
|
28
96
|
installer = GrimReaper::Installer.new
|
29
|
-
installer.setup_complete_environment
|
30
|
-
|
97
|
+
if installer.setup_complete_environment
|
98
|
+
puts "ā
Complete Grim Reaper environment setup finished!".colorize(:green)
|
99
|
+
puts "š Installation directory: #{ENV['GRIM_ROOT']}".colorize(:blue)
|
100
|
+
puts "š§ Run 'source ~/.bashrc' to reload environment".colorize(:yellow)
|
101
|
+
else
|
102
|
+
puts "ā Setup failed".colorize(:red)
|
103
|
+
exit 1
|
104
|
+
end
|
31
105
|
rescue => e
|
32
106
|
puts "ā Setup failed: #{e.message}".colorize(:red)
|
33
107
|
exit 1
|
34
108
|
end
|
35
109
|
end
|
110
|
+
|
111
|
+
desc "download-latest", "Download and install latest Grim Reaper from get.grim.so"
|
112
|
+
def download_latest
|
113
|
+
if options[:otp] && !validate_otp_access
|
114
|
+
return
|
115
|
+
end
|
116
|
+
|
117
|
+
puts "š„ Downloading latest Grim Reaper...".colorize(:cyan)
|
118
|
+
|
119
|
+
begin
|
120
|
+
installer = GrimReaper::Installer.new
|
121
|
+
if installer.download_latest_grim
|
122
|
+
puts "ā
Download and installation complete!".colorize(:green)
|
123
|
+
puts "š Installation directory: #{ENV['GRIM_ROOT']}".colorize(:blue)
|
124
|
+
puts "š§ Run 'source ~/.bashrc' to reload environment".colorize(:yellow)
|
125
|
+
puts ""
|
126
|
+
puts "Available commands:".colorize(:blue)
|
127
|
+
puts " grim backup <path> - Create backup"
|
128
|
+
puts " grim monitor <path> - Start monitoring"
|
129
|
+
puts " grim security - Security status"
|
130
|
+
puts " grim rb-setup - Setup Ruby environment"
|
131
|
+
else
|
132
|
+
puts "ā Download failed".colorize(:red)
|
133
|
+
exit 1
|
134
|
+
end
|
135
|
+
rescue => e
|
136
|
+
puts "ā Download failed: #{e.message}".colorize(:red)
|
137
|
+
exit 1
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
desc "check-installation", "Check if Grim Reaper is properly installed"
|
142
|
+
def check_installation
|
143
|
+
puts "š Checking Grim Reaper installation...".colorize(:cyan)
|
144
|
+
|
145
|
+
begin
|
146
|
+
installer = GrimReaper::Installer.new
|
147
|
+
grim_root = ENV["GRIM_ROOT"]
|
148
|
+
|
149
|
+
if grim_root && Dir.exist?(grim_root)
|
150
|
+
puts "ā
GRIM_ROOT found: #{grim_root}".colorize(:green)
|
151
|
+
|
152
|
+
# Check key components
|
153
|
+
components = [
|
154
|
+
"throne/grim_throne.sh",
|
155
|
+
"install.sh",
|
156
|
+
".rip"
|
157
|
+
]
|
158
|
+
|
159
|
+
components.each do |component|
|
160
|
+
path = File.join(grim_root, component)
|
161
|
+
if File.exist?(path)
|
162
|
+
puts "ā
#{component}".colorize(:green)
|
163
|
+
else
|
164
|
+
puts "ā #{component} - Missing".colorize(:red)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
puts ""
|
169
|
+
puts "Environment Variables:".colorize(:blue)
|
170
|
+
puts " GRIM_ROOT=#{ENV['GRIM_ROOT']}".colorize(:blue)
|
171
|
+
puts " GRIM_LICENSE=#{ENV['GRIM_LICENSE']}".colorize(:blue)
|
172
|
+
puts " GRIM_REAPER=#{ENV['GRIM_REAPER']}".colorize(:blue)
|
173
|
+
|
174
|
+
else
|
175
|
+
puts "ā Grim Reaper not installed".colorize(:red)
|
176
|
+
puts "š” Run 'grim download-latest' to install".colorize(:yellow)
|
177
|
+
end
|
178
|
+
|
179
|
+
rescue => e
|
180
|
+
puts "ā Check failed: #{e.message}".colorize(:red)
|
181
|
+
end
|
182
|
+
end
|
36
183
|
|
37
184
|
desc "health", "Check health of all Grim Reaper modules"
|
38
185
|
def health
|
186
|
+
if options[:otp] && !validate_otp_access
|
187
|
+
return
|
188
|
+
end
|
189
|
+
|
39
190
|
puts "š„ Checking Grim Reaper health...".colorize(:cyan)
|
40
191
|
|
41
192
|
begin
|
@@ -48,19 +199,19 @@ class GrimCLI < Thor
|
|
48
199
|
puts "Grim Reaper Health Status:".colorize(:cyan)
|
49
200
|
all_healthy = true
|
50
201
|
|
51
|
-
status_data.each do |module_name,
|
52
|
-
if
|
53
|
-
puts "
|
54
|
-
else
|
55
|
-
puts " ā #{module_name}: #{data[:status]}".colorize(:red)
|
202
|
+
status_data.each do |module_name, result|
|
203
|
+
if result.is_a?(Hash) && result[:error]
|
204
|
+
puts " #{module_name}: ā #{result[:error]}".colorize(:red)
|
56
205
|
all_healthy = false
|
206
|
+
else
|
207
|
+
puts " #{module_name}: ā
Healthy".colorize(:green)
|
57
208
|
end
|
58
209
|
end
|
59
210
|
|
60
211
|
if all_healthy
|
61
|
-
puts "\nš All modules
|
212
|
+
puts "\nš All modules healthy!".colorize(:green)
|
62
213
|
else
|
63
|
-
puts "\nā ļø Some modules
|
214
|
+
puts "\nā ļø Some modules need attention".colorize(:yellow)
|
64
215
|
end
|
65
216
|
end
|
66
217
|
rescue => e
|
@@ -309,6 +460,11 @@ class GrimCLI < Thor
|
|
309
460
|
puts " install Install dependencies"
|
310
461
|
puts " update Update all modules"
|
311
462
|
puts ""
|
463
|
+
puts "š OTP Security Commands:"
|
464
|
+
puts " otp-setup Setup OTP authentication"
|
465
|
+
puts " otp-verify CODE Verify OTP code"
|
466
|
+
puts " otp-status Check OTP authentication status"
|
467
|
+
puts ""
|
312
468
|
puts "š Ruby-Specific Commands:"
|
313
469
|
puts " rb-setup Setup Ruby environment"
|
314
470
|
puts " rb-analyze PATH Analyze Ruby code quality"
|
@@ -324,29 +480,17 @@ class GrimCLI < Thor
|
|
324
480
|
puts " --config FILE Configuration file path (default: grim.yml)"
|
325
481
|
puts " --verbose Enable verbose output"
|
326
482
|
puts " --json Output in JSON format"
|
483
|
+
puts " --otp CODE One-Time Password for secure authentication"
|
327
484
|
puts ""
|
328
|
-
puts "
|
329
|
-
puts "
|
330
|
-
puts "
|
331
|
-
puts "
|
332
|
-
puts "
|
333
|
-
puts " grim status"
|
334
|
-
puts " grim backup /home/user"
|
335
|
-
puts " grim deploy production --verbose"
|
336
|
-
puts " grim execute 'ls -la' --json"
|
485
|
+
puts "š Security Features:"
|
486
|
+
puts " ⢠Two-Factor Authentication (TOTP)"
|
487
|
+
puts " ⢠Backup codes for recovery"
|
488
|
+
puts " ⢠Secure command execution"
|
489
|
+
puts " ⢠Authentication tracking"
|
337
490
|
puts ""
|
338
|
-
puts "
|
339
|
-
puts "
|
340
|
-
puts "
|
341
|
-
puts " ⢠20+ security commands (security-audit, quarantine-isolate, etc.)"
|
342
|
-
puts " ⢠15+ AI/ML commands (ai-analyze, ai-train, ai-predict, etc.)"
|
343
|
-
puts " ⢠10+ optimization commands (optimize-all, heal, etc.)"
|
344
|
-
puts " ⢠License protection system"
|
345
|
-
puts " ⢠Emergency commands"
|
346
|
-
puts " ⢠Web interface and admin server"
|
347
|
-
puts ""
|
348
|
-
puts "š” For the complete Grim Reaper experience, visit: https://get.grim.so"
|
349
|
-
puts "š¦ Or run: curl -sSL https://get.grim.so | bash"
|
491
|
+
puts "š Documentation: https://grim.so/docs"
|
492
|
+
puts "š Full Installation: https://get.grim.so"
|
493
|
+
puts "š Gem Page: https://rubygems.org/gems/grim-reaper"
|
350
494
|
end
|
351
495
|
|
352
496
|
private
|
@@ -362,10 +506,81 @@ class GrimCLI < Thor
|
|
362
506
|
{}
|
363
507
|
end
|
364
508
|
end
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
509
|
+
|
510
|
+
private
|
511
|
+
|
512
|
+
def load_config
|
513
|
+
config_file = options[:config]
|
514
|
+
return {} unless File.exist?(config_file)
|
515
|
+
|
516
|
+
case File.extname(config_file)
|
517
|
+
when '.yml', '.yaml'
|
518
|
+
YAML.load_file(config_file) || {}
|
519
|
+
when '.json'
|
520
|
+
JSON.parse(File.read(config_file))
|
521
|
+
else
|
522
|
+
{}
|
523
|
+
end
|
524
|
+
rescue => e
|
525
|
+
warn "Warning: Could not load config file #{config_file}: #{e.message}"
|
526
|
+
{}
|
527
|
+
end
|
528
|
+
|
529
|
+
def validate_otp_access
|
530
|
+
return true unless options[:otp]
|
531
|
+
|
532
|
+
begin
|
533
|
+
grim = GrimReaper::Core.new(load_config)
|
534
|
+
otp_module = grim.get_otp_module
|
535
|
+
|
536
|
+
if otp_module.verify_otp(options[:otp])
|
537
|
+
puts "ā
OTP authentication successful".colorize(:green)
|
538
|
+
return true
|
539
|
+
else
|
540
|
+
puts "ā Invalid OTP code".colorize(:red)
|
541
|
+
exit 1
|
542
|
+
end
|
543
|
+
rescue => e
|
544
|
+
puts "ā OTP verification failed: #{e.message}".colorize(:red)
|
545
|
+
exit 1
|
546
|
+
end
|
547
|
+
end
|
548
|
+
|
549
|
+
def execute(command, *args)
|
550
|
+
begin
|
551
|
+
grim = GrimReaper::Core.new(load_config)
|
552
|
+
result = grim.execute(command, *args)
|
553
|
+
|
554
|
+
if options[:json]
|
555
|
+
puts JSON.pretty_generate(result)
|
556
|
+
else
|
557
|
+
result.each do |module_name, data|
|
558
|
+
if data.is_a?(Hash) && data[:error]
|
559
|
+
puts " #{module_name}: ā #{data[:error]}".colorize(:red)
|
560
|
+
else
|
561
|
+
puts " #{module_name}: ā
#{data}".colorize(:green)
|
562
|
+
end
|
563
|
+
end
|
564
|
+
end
|
565
|
+
rescue => e
|
566
|
+
puts "ā Command failed: #{e.message}".colorize(:red)
|
567
|
+
exit 1
|
568
|
+
end
|
569
|
+
end
|
570
|
+
|
571
|
+
def redirect_to_grim_so(command)
|
572
|
+
puts "\nš This command is not available in the Ruby gem.".colorize(:yellow)
|
573
|
+
puts "For the complete Grim Reaper ecosystem with all commands, visit:".colorize(:blue)
|
574
|
+
puts " š https://get.grim.so - Complete installation".colorize(:cyan)
|
575
|
+
puts " š https://grim.so/docs - Documentation".colorize(:cyan)
|
576
|
+
puts " š gem install grim-reaper - Ruby gem".colorize(:cyan)
|
577
|
+
puts "\nThe Ruby gem provides Ruby-specific commands and interfaces to other modules."
|
578
|
+
puts "For command '#{command}', you'll need the full Grim Reaper installation."
|
579
|
+
end
|
580
|
+
end
|
581
|
+
|
582
|
+
# Start the CLI if this file is executed directly
|
583
|
+
GrimCLI.start(ARGV) if __FILE__ == $0
|
369
584
|
puts "š¦ Or run: curl -sSL https://get.grim.so | bash".colorize(:cyan)
|
370
585
|
puts ""
|
371
586
|
puts "Available commands in this installation:".colorize(:green)
|
data/lib/grim_reaper/core.rb
CHANGED
@@ -62,10 +62,24 @@ module GrimReaper
|
|
62
62
|
@modules[:python] = PythonModule.new(@config, @grim_root)
|
63
63
|
@modules[:go] = GoModule.new(@config, @grim_root)
|
64
64
|
@modules[:security] = SecurityModule.new(@config, @grim_root)
|
65
|
+
@modules[:otp] = OtpModule.new(@config, @grim_root)
|
65
66
|
rescue LoadError => e
|
66
67
|
warn "Warning: Could not load module: #{e.message}"
|
67
68
|
end
|
68
69
|
|
70
|
+
# Get OTP module instance
|
71
|
+
def get_otp_module
|
72
|
+
@modules[:otp] || OtpModule.new(@config, @grim_root)
|
73
|
+
end
|
74
|
+
|
75
|
+
# Validate OTP access if provided
|
76
|
+
def validate_otp_access(otp_code)
|
77
|
+
return true unless otp_code
|
78
|
+
|
79
|
+
otp_module = get_otp_module
|
80
|
+
return otp_module.verify_otp(otp_code)
|
81
|
+
end
|
82
|
+
|
69
83
|
# Execute a command across all modules
|
70
84
|
def execute(command, *args)
|
71
85
|
results = {}
|
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
require "open3"
|
4
4
|
require "fileutils"
|
5
|
+
require "net/http"
|
6
|
+
require "uri"
|
5
7
|
|
6
8
|
module GrimReaper
|
7
9
|
# Ruby-specific installer and dependency manager
|
@@ -12,6 +14,152 @@ module GrimReaper
|
|
12
14
|
@grim_root = find_grim_root
|
13
15
|
@backup_dir = ENV["HOME"] + "/.graveyard"
|
14
16
|
@install_dir = ENV["HOME"] + "/reaper"
|
17
|
+
setup_environment_variables
|
18
|
+
end
|
19
|
+
|
20
|
+
# Setup environment variables
|
21
|
+
def setup_environment_variables
|
22
|
+
# Set GRIM_ROOT if not already set
|
23
|
+
unless ENV["GRIM_ROOT"]
|
24
|
+
if File.writable?("/root/")
|
25
|
+
ENV["GRIM_ROOT"] = "/root/.grim"
|
26
|
+
elsif File.writable?(ENV["HOME"])
|
27
|
+
ENV["GRIM_ROOT"] = ENV["HOME"] + "/.grim"
|
28
|
+
else
|
29
|
+
ENV["GRIM_ROOT"] = Dir.pwd + "/.grim"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Set default license tier to FREE
|
34
|
+
ENV["GRIM_LICENSE"] ||= "FREE"
|
35
|
+
|
36
|
+
# Set GRIM_REAPER to FALSE for normal install
|
37
|
+
ENV["GRIM_REAPER"] ||= "FALSE"
|
38
|
+
|
39
|
+
puts "š”ļø Grim environment configured:"
|
40
|
+
puts " GRIM_ROOT=#{ENV['GRIM_ROOT']}"
|
41
|
+
puts " GRIM_LICENSE=#{ENV['GRIM_LICENSE']}"
|
42
|
+
puts " GRIM_REAPER=#{ENV['GRIM_REAPER']}"
|
43
|
+
end
|
44
|
+
|
45
|
+
# Download and install latest Grim Reaper from get.grim.so
|
46
|
+
def download_latest_grim
|
47
|
+
puts "š„ Downloading latest Grim Reaper from get.grim.so..."
|
48
|
+
|
49
|
+
install_dir = ENV["GRIM_ROOT"] || (ENV["HOME"] + "/.grim")
|
50
|
+
FileUtils.mkdir_p(install_dir)
|
51
|
+
|
52
|
+
temp_file = File.join(install_dir, "grim-latest.tar.gz")
|
53
|
+
|
54
|
+
begin
|
55
|
+
# Download latest.tar.gz
|
56
|
+
uri = URI("https://get.grim.so/latest.tar.gz")
|
57
|
+
Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
|
58
|
+
request = Net::HTTP::Get.new(uri)
|
59
|
+
response = http.request(request)
|
60
|
+
|
61
|
+
if response.code == "200"
|
62
|
+
File.open(temp_file, "wb") { |file| file.write(response.body) }
|
63
|
+
puts "ā
Download complete"
|
64
|
+
else
|
65
|
+
raise "Failed to download: HTTP #{response.code}"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Extract with proper graveyard/reaper/ handling (strip 2 components)
|
70
|
+
puts "š¦ Extracting Grim Reaper..."
|
71
|
+
success = system("tar", "-xzf", temp_file, "--strip-components=2", "-C", install_dir)
|
72
|
+
|
73
|
+
unless success
|
74
|
+
raise "Failed to extract tarball"
|
75
|
+
end
|
76
|
+
|
77
|
+
# Remove temp file
|
78
|
+
File.delete(temp_file) if File.exist?(temp_file)
|
79
|
+
|
80
|
+
# Make scripts executable
|
81
|
+
make_scripts_executable(install_dir)
|
82
|
+
|
83
|
+
# Setup environment file
|
84
|
+
setup_environment_file(install_dir)
|
85
|
+
|
86
|
+
puts "ā
Grim Reaper installation complete!"
|
87
|
+
puts "š Installed to: #{install_dir}"
|
88
|
+
|
89
|
+
return true
|
90
|
+
|
91
|
+
rescue => e
|
92
|
+
puts "ā Download failed: #{e.message}"
|
93
|
+
File.delete(temp_file) if File.exist?(temp_file)
|
94
|
+
return false
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# Make scripts executable
|
99
|
+
def make_scripts_executable(install_dir)
|
100
|
+
puts "š§ Making scripts executable..."
|
101
|
+
|
102
|
+
scripts = [
|
103
|
+
"throne/grim_throne.sh",
|
104
|
+
"throne/sh_grim_throne.sh",
|
105
|
+
"throne/py_grim_throne.sh",
|
106
|
+
"throne/rb_grim_throne.sh",
|
107
|
+
"throne/go_grim_throne.sh",
|
108
|
+
"install.sh",
|
109
|
+
"master-install.sh",
|
110
|
+
"sh_grim/*.sh",
|
111
|
+
"py_grim/*.py",
|
112
|
+
"go_grim/build/*",
|
113
|
+
".rip/*.sh",
|
114
|
+
"auto_backups/*.sh"
|
115
|
+
]
|
116
|
+
|
117
|
+
scripts.each do |script_pattern|
|
118
|
+
Dir.glob(File.join(install_dir, script_pattern)).each do |script|
|
119
|
+
begin
|
120
|
+
File.chmod(0755, script)
|
121
|
+
rescue => e
|
122
|
+
puts "ā ļø Could not make #{script} executable: #{e.message}"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
# Setup environment file for persistence
|
129
|
+
def setup_environment_file(install_dir)
|
130
|
+
puts "š Setting up environment file..."
|
131
|
+
|
132
|
+
env_file = File.join(install_dir, ".grim_env")
|
133
|
+
|
134
|
+
env_content = <<~ENV
|
135
|
+
# Grim Reaper Environment Configuration
|
136
|
+
export GRIM_ROOT="#{ENV['GRIM_ROOT']}"
|
137
|
+
export GRIM_LICENSE="#{ENV['GRIM_LICENSE']}"
|
138
|
+
export GRIM_REAPER="#{ENV['GRIM_REAPER']}"
|
139
|
+
export PATH="$PATH:#{install_dir}/throne:#{install_dir}/sh_grim:#{install_dir}/py_grim"
|
140
|
+
|
141
|
+
# Load Grim functions
|
142
|
+
if [ -f "#{install_dir}/throne/grim_throne.sh" ]; then
|
143
|
+
source "#{install_dir}/throne/grim_throne.sh"
|
144
|
+
fi
|
145
|
+
ENV
|
146
|
+
|
147
|
+
File.write(env_file, env_content)
|
148
|
+
|
149
|
+
# Add to bashrc if possible
|
150
|
+
bashrc_path = ENV["HOME"] + "/.bashrc"
|
151
|
+
if File.exist?(bashrc_path) && File.writable?(bashrc_path)
|
152
|
+
source_line = "[ -f #{env_file} ] && source #{env_file}"
|
153
|
+
bashrc_content = File.read(bashrc_path)
|
154
|
+
|
155
|
+
unless bashrc_content.include?(source_line)
|
156
|
+
File.open(bashrc_path, "a") do |f|
|
157
|
+
f.puts "\n# Grim Reaper Environment"
|
158
|
+
f.puts source_line
|
159
|
+
end
|
160
|
+
puts "ā
Added Grim environment to ~/.bashrc"
|
161
|
+
end
|
162
|
+
end
|
15
163
|
end
|
16
164
|
|
17
165
|
# Find Grim Reaper root directory
|
@@ -54,10 +202,16 @@ module GrimReaper
|
|
54
202
|
raise Error, "Could not find Grim Reaper root directory"
|
55
203
|
end
|
56
204
|
|
57
|
-
# Setup complete Grim Reaper environment (
|
205
|
+
# Setup complete Grim Reaper environment (installs Python, Go, Shell, Scythe components)
|
58
206
|
def setup_complete_environment
|
59
207
|
puts "š”ļø Setting up complete Grim Reaper environment..."
|
60
208
|
|
209
|
+
# First download the latest version
|
210
|
+
unless download_latest_grim
|
211
|
+
puts "ā Failed to download Grim Reaper"
|
212
|
+
return false
|
213
|
+
end
|
214
|
+
|
61
215
|
# Setup Ruby environment
|
62
216
|
setup_ruby_environment
|
63
217
|
|
@@ -76,10 +230,8 @@ module GrimReaper
|
|
76
230
|
# Create necessary directories
|
77
231
|
create_directories
|
78
232
|
|
79
|
-
# Setup environment file
|
80
|
-
setup_environment_file
|
81
|
-
|
82
233
|
puts "ā
Complete Grim Reaper environment setup finished"
|
234
|
+
return true
|
83
235
|
end
|
84
236
|
|
85
237
|
# Setup Ruby environment
|
@@ -400,25 +552,6 @@ module GrimReaper
|
|
400
552
|
end
|
401
553
|
end
|
402
554
|
|
403
|
-
# Setup environment file
|
404
|
-
def setup_environment_file
|
405
|
-
env_file = File.join(@grim_root, ".env")
|
406
|
-
scythe_dir = File.join(@grim_root, ".graveyard", ".rip", ".scythe")
|
407
|
-
env_content = <<~ENV
|
408
|
-
# Grim Reaper Environment Configuration
|
409
|
-
GRIM_ROOT=#{@grim_root}
|
410
|
-
SCYTHE_DIR=#{scythe_dir}
|
411
|
-
GRIM_BACKUP_DIR=#{@backup_dir}
|
412
|
-
GRIM_HOME=#{@install_dir}
|
413
|
-
GRIM_RUBY_VERSION=#{`ruby -e "puts RUBY_VERSION"`.strip}
|
414
|
-
GRIM_PYTHON_VERSION=#{`python3 --version 2>/dev/null | cut -d' ' -f2` || 'Not installed'}
|
415
|
-
GRIM_GO_VERSION=#{`go version 2>/dev/null | cut -d' ' -f3` || 'Not installed'}
|
416
|
-
ENV
|
417
|
-
|
418
|
-
File.write(env_file, env_content)
|
419
|
-
puts "š Created environment file: #{env_file}"
|
420
|
-
end
|
421
|
-
|
422
555
|
# Verify installation
|
423
556
|
def verify_installation
|
424
557
|
puts "š Verifying installation..."
|
@@ -0,0 +1,275 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "openssl"
|
4
|
+
require "base64"
|
5
|
+
require "uri"
|
6
|
+
require "json"
|
7
|
+
require "fileutils"
|
8
|
+
|
9
|
+
module GrimReaper
|
10
|
+
# OTP (One-Time Password) authentication module
|
11
|
+
class OtpModule
|
12
|
+
attr_reader :config, :grim_root, :secret_file, :config_file
|
13
|
+
|
14
|
+
def initialize(config = {}, grim_root = nil)
|
15
|
+
@config = config
|
16
|
+
@grim_root = grim_root || Dir.pwd
|
17
|
+
@secret_file = File.join(@grim_root, ".grim_otp_secret")
|
18
|
+
@config_file = File.join(@grim_root, ".grim_otp_config")
|
19
|
+
end
|
20
|
+
|
21
|
+
# Setup OTP authentication
|
22
|
+
def setup_otp
|
23
|
+
secret = generate_secret
|
24
|
+
|
25
|
+
# Save secret securely
|
26
|
+
File.write(@secret_file, secret)
|
27
|
+
File.chmod(0o600, @secret_file)
|
28
|
+
|
29
|
+
# Generate QR code URL
|
30
|
+
qr_url = generate_qr_url(secret)
|
31
|
+
|
32
|
+
# Generate backup codes
|
33
|
+
backup_codes = generate_backup_codes
|
34
|
+
|
35
|
+
# Save configuration
|
36
|
+
otp_config = {
|
37
|
+
enabled: true,
|
38
|
+
created_at: Time.now.iso8601,
|
39
|
+
backup_codes: backup_codes.map { |code| { code: code, used: false } },
|
40
|
+
failed_attempts: 0,
|
41
|
+
last_auth: nil
|
42
|
+
}
|
43
|
+
|
44
|
+
File.write(@config_file, JSON.pretty_generate(otp_config))
|
45
|
+
File.chmod(0o600, @config_file)
|
46
|
+
|
47
|
+
puts "š OTP Secret: #{secret}".colorize(:green)
|
48
|
+
puts "š± QR Code URL: #{qr_url}".colorize(:blue)
|
49
|
+
puts "š¾ Backup Codes:".colorize(:yellow)
|
50
|
+
backup_codes.each_with_index do |code, index|
|
51
|
+
puts " #{index + 1}. #{code}".colorize(:cyan)
|
52
|
+
end
|
53
|
+
puts "ā ļø Save these backup codes in a secure location!".colorize(:red)
|
54
|
+
|
55
|
+
true
|
56
|
+
rescue => e
|
57
|
+
puts "Error setting up OTP: #{e.message}".colorize(:red)
|
58
|
+
false
|
59
|
+
end
|
60
|
+
|
61
|
+
# Verify OTP code
|
62
|
+
def verify_otp(code)
|
63
|
+
return false unless otp_enabled?
|
64
|
+
|
65
|
+
config_data = load_config
|
66
|
+
secret = load_secret
|
67
|
+
|
68
|
+
# Check if it's a backup code
|
69
|
+
if verify_backup_code(code, config_data)
|
70
|
+
mark_backup_code_used(code, config_data)
|
71
|
+
update_last_auth(config_data)
|
72
|
+
return true
|
73
|
+
end
|
74
|
+
|
75
|
+
# Verify TOTP code
|
76
|
+
current_time = Time.now.to_i / 30
|
77
|
+
|
78
|
+
# Check current and previous time windows (to handle clock skew)
|
79
|
+
[-1, 0, 1].each do |offset|
|
80
|
+
if generate_totp(secret, current_time + offset) == code.to_s.rjust(6, '0')
|
81
|
+
update_last_auth(config_data)
|
82
|
+
reset_failed_attempts(config_data)
|
83
|
+
return true
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Increment failed attempts
|
88
|
+
increment_failed_attempts(config_data)
|
89
|
+
false
|
90
|
+
rescue => e
|
91
|
+
puts "Error verifying OTP: #{e.message}".colorize(:red)
|
92
|
+
false
|
93
|
+
end
|
94
|
+
|
95
|
+
# Check OTP status
|
96
|
+
def status
|
97
|
+
if otp_enabled?
|
98
|
+
config_data = load_config
|
99
|
+
{
|
100
|
+
enabled: true,
|
101
|
+
last_auth: config_data['last_auth'],
|
102
|
+
failed_attempts: config_data['failed_attempts'] || 0,
|
103
|
+
backup_codes_remaining: count_unused_backup_codes(config_data)
|
104
|
+
}
|
105
|
+
else
|
106
|
+
{
|
107
|
+
enabled: false,
|
108
|
+
last_auth: nil,
|
109
|
+
failed_attempts: 0,
|
110
|
+
backup_codes_remaining: 0
|
111
|
+
}
|
112
|
+
end
|
113
|
+
rescue => e
|
114
|
+
{ error: e.message }
|
115
|
+
end
|
116
|
+
|
117
|
+
# Execute OTP-related commands
|
118
|
+
def execute(command, *args)
|
119
|
+
case command
|
120
|
+
when 'setup'
|
121
|
+
setup_otp
|
122
|
+
when 'verify'
|
123
|
+
verify_otp(args.first)
|
124
|
+
when 'status'
|
125
|
+
status
|
126
|
+
when 'disable'
|
127
|
+
disable_otp
|
128
|
+
when 'regenerate-backup-codes'
|
129
|
+
regenerate_backup_codes
|
130
|
+
else
|
131
|
+
{ error: "Unknown OTP command: #{command}" }
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
# Disable OTP authentication
|
136
|
+
def disable_otp
|
137
|
+
File.delete(@secret_file) if File.exist?(@secret_file)
|
138
|
+
File.delete(@config_file) if File.exist?(@config_file)
|
139
|
+
puts "š OTP authentication disabled".colorize(:yellow)
|
140
|
+
true
|
141
|
+
rescue => e
|
142
|
+
puts "Error disabling OTP: #{e.message}".colorize(:red)
|
143
|
+
false
|
144
|
+
end
|
145
|
+
|
146
|
+
# Regenerate backup codes
|
147
|
+
def regenerate_backup_codes
|
148
|
+
return false unless otp_enabled?
|
149
|
+
|
150
|
+
config_data = load_config
|
151
|
+
backup_codes = generate_backup_codes
|
152
|
+
|
153
|
+
config_data['backup_codes'] = backup_codes.map { |code| { code: code, used: false } }
|
154
|
+
|
155
|
+
File.write(@config_file, JSON.pretty_generate(config_data))
|
156
|
+
|
157
|
+
puts "š¾ New Backup Codes:".colorize(:yellow)
|
158
|
+
backup_codes.each_with_index do |code, index|
|
159
|
+
puts " #{index + 1}. #{code}".colorize(:cyan)
|
160
|
+
end
|
161
|
+
|
162
|
+
true
|
163
|
+
rescue => e
|
164
|
+
puts "Error regenerating backup codes: #{e.message}".colorize(:red)
|
165
|
+
false
|
166
|
+
end
|
167
|
+
|
168
|
+
private
|
169
|
+
|
170
|
+
# Check if OTP is enabled
|
171
|
+
def otp_enabled?
|
172
|
+
File.exist?(@secret_file) && File.exist?(@config_file)
|
173
|
+
end
|
174
|
+
|
175
|
+
# Load OTP configuration
|
176
|
+
def load_config
|
177
|
+
return {} unless File.exist?(@config_file)
|
178
|
+
JSON.parse(File.read(@config_file))
|
179
|
+
rescue JSON::ParserError
|
180
|
+
{}
|
181
|
+
end
|
182
|
+
|
183
|
+
# Load OTP secret
|
184
|
+
def load_secret
|
185
|
+
return nil unless File.exist?(@secret_file)
|
186
|
+
File.read(@secret_file).strip
|
187
|
+
end
|
188
|
+
|
189
|
+
# Generate a random secret for TOTP
|
190
|
+
def generate_secret
|
191
|
+
Base64.encode64(OpenSSL::Random.random_bytes(20)).gsub(/\W/, '')[0, 32]
|
192
|
+
end
|
193
|
+
|
194
|
+
# Generate TOTP code
|
195
|
+
def generate_totp(secret, time_counter)
|
196
|
+
# Convert secret from base64
|
197
|
+
key = Base64.decode64(secret)
|
198
|
+
|
199
|
+
# Create HMAC-SHA1
|
200
|
+
time_bytes = [time_counter].pack('Q>')
|
201
|
+
hmac = OpenSSL::HMAC.digest('sha1', key, time_bytes)
|
202
|
+
|
203
|
+
# Dynamic truncation
|
204
|
+
offset = hmac[-1].ord & 0x0f
|
205
|
+
code = hmac[offset, 4].unpack('N').first & 0x7fffffff
|
206
|
+
|
207
|
+
# Return 6-digit code
|
208
|
+
sprintf('%06d', code % 1000000)
|
209
|
+
end
|
210
|
+
|
211
|
+
# Generate QR code URL for authenticator apps
|
212
|
+
def generate_qr_url(secret)
|
213
|
+
account = "grim-reaper@#{Socket.gethostname}"
|
214
|
+
issuer = "Grim Reaper"
|
215
|
+
|
216
|
+
params = {
|
217
|
+
secret: secret,
|
218
|
+
issuer: issuer,
|
219
|
+
algorithm: 'SHA1',
|
220
|
+
digits: 6,
|
221
|
+
period: 30
|
222
|
+
}
|
223
|
+
|
224
|
+
query_string = URI.encode_www_form(params)
|
225
|
+
"otpauth://totp/#{URI.encode_www_form_component(account)}?#{query_string}"
|
226
|
+
end
|
227
|
+
|
228
|
+
# Generate backup codes
|
229
|
+
def generate_backup_codes(count = 10)
|
230
|
+
Array.new(count) do
|
231
|
+
# Generate 8-character alphanumeric codes
|
232
|
+
Array.new(8) { [*'0'..'9', *'A'..'Z'].sample }.join
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
# Verify backup code
|
237
|
+
def verify_backup_code(code, config_data)
|
238
|
+
backup_codes = config_data['backup_codes'] || []
|
239
|
+
backup_codes.any? { |bc| bc['code'] == code.upcase && !bc['used'] }
|
240
|
+
end
|
241
|
+
|
242
|
+
# Mark backup code as used
|
243
|
+
def mark_backup_code_used(code, config_data)
|
244
|
+
backup_codes = config_data['backup_codes'] || []
|
245
|
+
backup_code = backup_codes.find { |bc| bc['code'] == code.upcase }
|
246
|
+
backup_code['used'] = true if backup_code
|
247
|
+
|
248
|
+
File.write(@config_file, JSON.pretty_generate(config_data))
|
249
|
+
end
|
250
|
+
|
251
|
+
# Count unused backup codes
|
252
|
+
def count_unused_backup_codes(config_data)
|
253
|
+
backup_codes = config_data['backup_codes'] || []
|
254
|
+
backup_codes.count { |bc| !bc['used'] }
|
255
|
+
end
|
256
|
+
|
257
|
+
# Update last authentication time
|
258
|
+
def update_last_auth(config_data)
|
259
|
+
config_data['last_auth'] = Time.now.iso8601
|
260
|
+
File.write(@config_file, JSON.pretty_generate(config_data))
|
261
|
+
end
|
262
|
+
|
263
|
+
# Reset failed attempts counter
|
264
|
+
def reset_failed_attempts(config_data)
|
265
|
+
config_data['failed_attempts'] = 0
|
266
|
+
File.write(@config_file, JSON.pretty_generate(config_data))
|
267
|
+
end
|
268
|
+
|
269
|
+
# Increment failed attempts counter
|
270
|
+
def increment_failed_attempts(config_data)
|
271
|
+
config_data['failed_attempts'] = (config_data['failed_attempts'] || 0) + 1
|
272
|
+
File.write(@config_file, JSON.pretty_generate(config_data))
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
data/lib/grim_reaper/version.rb
CHANGED
data/lib/grim_reaper.rb
CHANGED
@@ -6,6 +6,7 @@ require_relative "grim_reaper/shell_module"
|
|
6
6
|
require_relative "grim_reaper/python_module"
|
7
7
|
require_relative "grim_reaper/go_module"
|
8
8
|
require_relative "grim_reaper/security_module"
|
9
|
+
require_relative "grim_reaper/otp_module"
|
9
10
|
require_relative "grim_reaper/installer"
|
10
11
|
|
11
12
|
# Grim Reaper - The Ultimate Backup, Monitoring, and Security System
|
@@ -38,4 +39,12 @@ module GrimReaper
|
|
38
39
|
def self.security
|
39
40
|
Core.new.execute('security')
|
40
41
|
end
|
42
|
+
|
43
|
+
def self.setup_otp
|
44
|
+
Core.new.get_otp_module.setup_otp
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.verify_otp(code)
|
48
|
+
Core.new.get_otp_module.verify_otp(code)
|
49
|
+
end
|
41
50
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: grim-reaper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.34
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bernie Gengel and his beagle Buddy
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-07-
|
11
|
+
date: 2025-07-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -181,8 +181,8 @@ dependencies:
|
|
181
181
|
description: When data death comes knocking, Grim ensures resurrection is just a command
|
182
182
|
away. License management, auto backups, highly compressed backups, multi-algorithm
|
183
183
|
compression, content-based deduplication, smart storage tiering save up to 60% space,
|
184
|
-
military-grade encryption, license protection, security surveillance,
|
185
|
-
threat response.
|
184
|
+
military-grade encryption, license protection, security surveillance, OTP authentication,
|
185
|
+
and automated threat response.
|
186
186
|
email:
|
187
187
|
- rip@grim.so
|
188
188
|
executables:
|
@@ -206,6 +206,7 @@ files:
|
|
206
206
|
- lib/grim_reaper/core.rb
|
207
207
|
- lib/grim_reaper/go_module.rb
|
208
208
|
- lib/grim_reaper/installer.rb
|
209
|
+
- lib/grim_reaper/otp_module.rb
|
209
210
|
- lib/grim_reaper/python_module.rb
|
210
211
|
- lib/grim_reaper/security_module.rb
|
211
212
|
- lib/grim_reaper/shell_module.rb
|
@@ -219,13 +220,17 @@ metadata:
|
|
219
220
|
source_code_uri: https://github.com/cyber-boost/grim
|
220
221
|
changelog_uri: https://github.com/cyber-boost/grim/blob/main/CHANGELOG.md
|
221
222
|
rubygems_mfa_required: 'true'
|
222
|
-
post_install_message: "\U0001F5E1ļø Grim Reaper Ruby Gem v1.0.
|
223
|
-
|
224
|
-
|
225
|
-
components (
|
226
|
-
|
227
|
-
|
228
|
-
|
223
|
+
post_install_message: "\U0001F5E1ļø Grim Reaper Ruby Gem v1.0.34 installed successfully!\n\n\U0001F195
|
224
|
+
NEW: OTP (One-Time Password) Authentication Support!\nRun 'grim otp-setup' to enable
|
225
|
+
secure two-factor authentication.\n\nThe gem provides a unified interface to all
|
226
|
+
Grim Reaper modules:\n- Python components (scythe, py_grim)\n- Go components (go_grim)\n-
|
227
|
+
Shell components (sh_grim)\n- Ruby components (rb_grim)\n- OTP Security Module (NEW!)\n\nRun
|
228
|
+
'grim rb-setup' to configure your environment and install all components.\nRun 'grim
|
229
|
+
help' to see all available commands.\n\nFor automatic installation of all Grim Reaper
|
230
|
+
components, run:\ngrim setup-complete\n\n\U0001F510 Security Enhancement:\n⢠Use
|
231
|
+
--otp flag for secure command execution\n⢠Setup OTP: grim otp-setup\n⢠Verify OTP:
|
232
|
+
grim otp-verify <code>\n⢠Check status: grim otp-status\n\n\U0001F4A1 For missing
|
233
|
+
commands, visit: https://get.grim.so\n"
|
229
234
|
rdoc_options: []
|
230
235
|
require_paths:
|
231
236
|
- lib
|
@@ -243,5 +248,5 @@ requirements: []
|
|
243
248
|
rubygems_version: 3.4.20
|
244
249
|
signing_key:
|
245
250
|
specification_version: 4
|
246
|
-
summary: 'Grim: Unified Data Protection Ecosystem'
|
251
|
+
summary: 'Grim: Unified Data Protection Ecosystem with OTP Security'
|
247
252
|
test_files: []
|