summaryrefslogtreecommitdiffstats
path: root/tor_extension.php
blob: e4ab9b57ae49e337f41ff189384619caead52d97 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
<?php
/**
 * Tor Extension for YAMN Web Interface
 * 
 * This file provides functions to enable Tor connectivity for YAMN
 * using torsocks to force all connections through Tor.
 */

// Constants
define('YAMN_PATH', '/opt/yamn-master/yamn');
define('YAMN_CONFIG', '/opt/yamn-master/yamn.yml');
define('TOR_PROXY', '127.0.0.1:9050');  // Default Tor SOCKS proxy
define('TOR_CONFIG_FILE', '/var/www/yamnweb/tor_config.ini');
define('TORSOCKS_PATH', 'torsocks');    // Path to torsocks command (assuming it's in PATH)

/**
 * Debug logger function
 * 
 * @param string $message Message to log
 * @param bool $include_timestamp Whether to include timestamp
 * @return void
 */
function logDebug($message, $include_timestamp = true) {
    $log_file = '/var/www/yamnweb/debug.log';
    $log_entry = ($include_timestamp ? date('Y-m-d H:i:s') . " - " : "") . $message . "\n";
    file_put_contents($log_file, $log_entry, FILE_APPEND);
}

/**
 * Check if Tor is available on the system
 * 
 * @return bool True if Tor service is available
 */
function isTorAvailable() {
    logDebug("Checking if Tor is available...");
    
    // Check if torsocks is installed
    $torsocks_check = shell_exec('which torsocks 2>&1');
    if (empty($torsocks_check) || strpos($torsocks_check, 'no torsocks') !== false) {
        logDebug("WARNING: torsocks not found in PATH. Tor routing may not work correctly.");
    } else {
        logDebug("torsocks found: " . trim($torsocks_check));
    }
    
    // Check if Tor SOCKS proxy is listening
    $connection = @fsockopen('127.0.0.1', 9050, $errno, $errstr, 1);
    if (is_resource($connection)) {
        fclose($connection);
        logDebug("Tor is available: SOCKS proxy connection successful");
        return true;
    }
    
    logDebug("SOCKS proxy connection failed: $errno - $errstr");
    
    // Alternative: Check if Tor service is running
    $tor_running = shell_exec('pgrep -f "tor" | wc -l');
    if (intval($tor_running) > 0) {
        logDebug("Tor is available: Tor process is running");
        return true;
    }
    
    logDebug("Tor is NOT available: No Tor process found");
    return false;
}

/**
 * Check if an email address belongs to an .onion domain
 * 
 * @param string $email The email address to check
 * @return bool True if the email is for an .onion domain
 */
function isOnionEmail($email) {
    // Extract domain from email address
    if (preg_match('/@([^>]+)/', $email, $matches)) {
        $domain = $matches[1];
        $is_onion = (strpos($domain, '.onion') !== false);
        logDebug("Email domain check: $domain - " . ($is_onion ? "is .onion" : "is NOT .onion"));
        return $is_onion;
    }
    logDebug("No domain found in email: $email");
    return false;
}

/**
 * Determine if Tor should be used for the current email
 * Always returns true since Tor is now mandatory
 * 
 * @param string $to The recipient email address
 * @return bool Always returns true
 */
function shouldUseTor($to) {
    logDebug("Checking if Tor should be used for recipient: $to");
    logDebug("Tor usage is mandatory for all communications");
    return true;
}

/**
 * Configure environment variables for Tor
 * 
 * @return void
 */
function configureTorForYamn() {
    logDebug("Configuring environment for YAMN with Tor (mandatory)");
    
    // Set environment variables that torsocks and YAMN might check for Tor configuration
    putenv("SOCKS_PROXY=" . TOR_PROXY);
    putenv("ALL_PROXY=socks5://" . TOR_PROXY);
    putenv("socks_proxy=" . TOR_PROXY);
    putenv("all_proxy=socks5://" . TOR_PROXY);
    putenv("TORSOCKS_ALLOW_INBOUND=1");  // Allow inbound connections through torsocks
    
    logDebug("Environment variables set for Tor usage");
    
    // Display current environment settings
    logDebug("Current environment settings:");
    logDebug("SOCKS_PROXY: " . getenv("SOCKS_PROXY"), false);
    logDebug("ALL_PROXY: " . getenv("ALL_PROXY"), false);
    logDebug("TORSOCKS_ALLOW_INBOUND: " . getenv("TORSOCKS_ALLOW_INBOUND"), false);
}

/**
 * Send an email through YAMN with Tor routing using torsocks
 * 
 * @param string $chain The remailer chain string
 * @param int $copies Number of copies to send
 * @param string $messageFile Path to the message file
 * @param bool $useTor Parameter kept for compatibility, but ignored (Tor is always used)
 * @return array Array containing success status and output
 */
function sendYamnEmail($chain, $copies, $messageFile, $useTor = true) {
    logDebug("=== STARTING EMAIL SEND PROCESS ===");
    logDebug("Chain: $chain");
    logDebug("Copies: $copies");
    logDebug("Message file: $messageFile");
    logDebug("Using Tor: Yes (mandatory with torsocks)");
    
    // Check if message file exists
    if (!file_exists($messageFile)) {
        logDebug("ERROR: Message file does not exist: $messageFile");
        return [
            'success' => false,
            'tor_used' => true,
            'add_to_pool' => [
                'command' => '',
                'output' => ['Message file not found'],
                'return_var' => 1
            ],
            'send' => [
                'command' => '',
                'output' => ['Skipped due to previous error'],
                'return_var' => 1
            ]
        ];
    }
    
    // Check if YAMN exists and is executable
    if (!file_exists(YAMN_PATH)) {
        logDebug("ERROR: YAMN executable not found at: " . YAMN_PATH);
        return [
            'success' => false,
            'tor_used' => true,
            'add_to_pool' => [
                'command' => '',
                'output' => ['YAMN executable not found'],
                'return_var' => 1
            ],
            'send' => [
                'command' => '',
                'output' => ['Skipped due to previous error'],
                'return_var' => 1
            ]
        ];
    }
    
    if (!is_executable(YAMN_PATH)) {
        logDebug("ERROR: YAMN is not executable: " . YAMN_PATH);
        return [
            'success' => false,
            'tor_used' => true,
            'add_to_pool' => [
                'command' => '',
                'output' => ['YAMN is not executable'],
                'return_var' => 1
            ],
            'send' => [
                'command' => '',
                'output' => ['Skipped due to previous error'],
                'return_var' => 1
            ]
        ];
    }
    
    // Check if YAMN config exists
    if (!file_exists(YAMN_CONFIG)) {
        logDebug("ERROR: YAMN config not found at: " . YAMN_CONFIG);
        return [
            'success' => false,
            'tor_used' => true,
            'add_to_pool' => [
                'command' => '',
                'output' => ['YAMN config not found'],
                'return_var' => 1
            ],
            'send' => [
                'command' => '',
                'output' => ['Skipped due to previous error'],
                'return_var' => 1
            ]
        ];
    }
    
    // Check if torsocks is available
    $torsocks_check = shell_exec('which torsocks 2>/dev/null');
    if (empty($torsocks_check)) {
        logDebug("ERROR: torsocks not found. Cannot route traffic through Tor.");
        return [
            'success' => false,
            'tor_used' => true,
            'add_to_pool' => [
                'command' => '',
                'output' => ['torsocks not installed'],
                'return_var' => 1
            ],
            'send' => [
                'command' => '',
                'output' => ['Skipped due to previous error'],
                'return_var' => 1
            ]
        ];
    }
    
    // Configure environment for torsocks
    configureTorForYamn();
    
    // Build YAMN command to add message to pool with torsocks
    $command_add_to_pool = TORSOCKS_PATH . " " . YAMN_PATH . " " .
                          "--config=" . YAMN_CONFIG . " " .
                          "--mail " .
                          "--chain=\"$chain\" " .
                          "--copies=$copies < $messageFile 2>&1";
    
    // Command to send emails in pool with torsocks
    $command_send = TORSOCKS_PATH . " " . YAMN_PATH . " " .
                   "--config=" . YAMN_CONFIG . " -S 2>&1";
    
    // Log the commands
    logDebug("Add to pool command: $command_add_to_pool");
    
    // Execute add to pool command
    logDebug("Executing add to pool command...");
    exec($command_add_to_pool, $output_add_to_pool, $return_var_add_to_pool);
    
    // Log the output and return code
    logDebug("Add to pool output: " . implode("\n", $output_add_to_pool));
    logDebug("Add to pool return code: $return_var_add_to_pool");
    
    // Only execute send command if add to pool was successful
    if ($return_var_add_to_pool == 0) {
        logDebug("Send command: $command_send");
        logDebug("Executing send command...");
        exec($command_send, $output_send, $return_var_send);
        logDebug("Send output: " . implode("\n", $output_send));
        logDebug("Send return code: $return_var_send");
    } else {
        logDebug("Skipping send command due to add to pool failure");
        $output_send = ["Skipped - add to pool command failed"];
        $return_var_send = -1;
    }
    
    // Standard log entry
    $log_entry = date('Y-m-d H:i:s') . " | Chain: $chain | Copies: $copies | Tor: Yes | Status: " . 
                 (($return_var_send == 0 && $return_var_add_to_pool == 0) ? "Success" : "Failed") . "\n";
    file_put_contents('/var/www/yamnweb/yamn_send.log', $log_entry, FILE_APPEND);
    
    // Success status
    $success = ($return_var_send == 0 && $return_var_add_to_pool == 0);
    logDebug("Operation " . ($success ? "SUCCEEDED" : "FAILED"));
    logDebug("=== EMAIL SEND PROCESS COMPLETE ===");
    
    return [
        'success' => $success,
        'tor_used' => true,
        'add_to_pool' => [
            'command' => $command_add_to_pool,
            'output' => $output_add_to_pool,
            'return_var' => $return_var_add_to_pool
        ],
        'send' => [
            'command' => $command_send,
            'output' => $output_send,
            'return_var' => $return_var_send
        ]
    ];
}

/**
 * Alternative version that uses proxychains4 instead of torsocks
 * Uncomment and modify the above function if you prefer proxychains4
 */
/*
function sendYamnEmail($chain, $copies, $messageFile, $useTor = true) {
    // Configuration similar to above, but using proxychains4
    // ...
    
    // Build YAMN command with proxychains4
    $command_add_to_pool = "proxychains4 -q " . YAMN_PATH . " " .
                          "--config=" . YAMN_CONFIG . " " .
                          "--mail " .
                          "--chain=\"$chain\" " .
                          "--copies=$copies < $messageFile 2>&1";
    
    $command_send = "proxychains4 -q " . YAMN_PATH . " " .
                   "--config=" . YAMN_CONFIG . " -S 2>&1";
    
    // Rest of the function is the same
    // ...
}
*/
?>