Issues (1963)

html/inc/email.inc (2 issues)

1
<?php
2
// This file is part of BOINC.
3
// http://boinc.berkeley.edu
4
// Copyright (C) 2008 University of California
5
//
6
// BOINC is free software; you can redistribute it and/or modify it
7
// under the terms of the GNU Lesser General Public License
8
// as published by the Free Software Foundation,
9
// either version 3 of the License, or (at your option) any later version.
10
//
11
// BOINC is distributed in the hope that it will be useful,
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
// See the GNU Lesser General Public License for more details.
15
//
16
// You should have received a copy of the GNU Lesser General Public License
17
// along with BOINC.  If not, see <http://www.gnu.org/licenses/>.
18
19
// email-related utilities.
20
// Don't put specific message text here.
21
22
require_once("../inc/util.inc");
23
require_once("../inc/token.inc");
24
require_once("../project/project.inc");
25
require_once("../inc/token.inc");
26
27
// send an email, using PHPMailer or not.
28
//
29
function send_email($user, $subject, $body, $body_html=null, $email_addr=null) {
30
    if (!$email_addr) {
31
        $email_addr = $user->email_addr;
32
    }
33
    if (defined('EMAIL_USE_CMD')) {
34
        if ($body_html) {
35
            $cmd = "mail  -a \"Content-type: text/html\" -s \"$subject\" $email_addr";
36
            $pipe = popen($cmd, "w");
37
            fwrite($pipe, $body_html);
38
        } else {
39
            $cmd = "mail  -s \"$subject\" $email_addr";
40
            $pipe = popen($cmd, "w");
41
            fwrite($pipe, $body);
42
        }
43
        pclose($pipe);
44
        return true;
45
    } else if (function_exists("make_php_mailer")) {
46
        if (file_exists("../inc/PHPMailer/src/PHPMailer.php") && file_exists("../inc/PHPMailer/src/SMTP.php")) {
47
            require_once("../inc/PHPMailer/src/PHPMailer.php");
48
            require_once("../inc/PHPMailer/src/SMTP.php");
49
        } else if (file_exists("../inc/phpmailer/class.phpmailer.php")) {
50
            require_once("../inc/phpmailer/class.phpmailer.php");
51
        } else {
52
            echo "PHPMailer not installed";
53
            return false;
54
        }
55
        $mail = make_php_mailer();
56
        $mail->AddAddress($email_addr, $user->name);
57
        $mail->Subject = $subject;
58
        if ($body_html) {
59
            $mail->AltBody = $body;
60
            $mail->Body = $body_html;
61
            $mail->IsHTML(true);
62
        } else {
63
            $mail->Body = $body;
64
        }
65
        if (!$mail->Send()) {
66
            echo $mail->ErrorInfo;
67
            return false;
68
        } else {
69
            return true;
70
        }
71
    } else {
72
        $headers ="";
73
        if (defined('EMAIL_FROM') && defined('EMAIL_FROM_NAME')) {
74
            $headers = "From: ".EMAIL_FROM_NAME." <".EMAIL_FROM.">";
75
        } else if (defined('EMAIL_FROM')) {
76
            $headers = "From: ". EMAIL_FROM;
77
        }
78
        if ($body_html) {
79
            $body = "<html><body>\n";
80
            $body .= $body_html;
81
            $body .= "\n</body></html>\n";
82
            $headers .= 'Content-type: text/html; charset=UTF-8' . "\r\n";
83
        }
84
        return mail($email_addr, $subject, $body, $headers);
85
    }
86
}
87
88
// Send an email describing an account to the user.
89
// There are a few scenarios:
90
//
91
// 1) the account was created by user via web.
92
//    In this case they're currently looking at the "validate account" page
93
//    (account_created.php), although they might have strayed
94
//    so we need to give them a link.
95
// 2) the account was created administratively
96
// 3) the user requested account key for existing account
97
//
98
function send_auth_email($user) {
99
    $body = "";
100
101
    $now = time();
102
    $x = md5($user->id.$user->authenticator.$now);
103
    $x = substr($x, 0, 16);
104
    $subject = PROJECT." account information";
105
    $body = "This email was sent in response to a request on the ".PROJECT." web site.
106
107
To log in to your ".PROJECT." account, visit:
108
".secure_url_base()."login_action.php?id=$user->id&t=$now&h=$x
109
(This link is valid for 1 day).
110
After logging in, you can change your account's password or email address.
111
";
112
113
$body .= "
114
For further information and assistance with ".PROJECT.", visit
115
".secure_url_base()."
116
";
117
118
    return send_email($user, $subject, $body);
119
}
120
121
function send_changed_email($user) {
122
    $duration = TOKEN_DURATION_ONE_WEEK;
123
124
    $token = create_token($user->id, TOKEN_TYPE_CHANGE_EMAIL, $duration);
125
126
    $subject = PROJECT." email address change.";
127
128
    // Body for the new email address to explain how quickly
129
    // they can do another email change.
130
    //
131
    $body_new = "Your email address was changed from ".$user->previous_email_addr.
132
" to ".$user->email_addr." on ".date('F j \a\t g:i a T', $user->email_addr_change_time).
133
".  You will not be able to change your email address again until ".date('F j \a\t g:i a T', $user->email_addr_change_time + $duration).
134
".  If you need to undo this immediately, please look for an email from us at your ".$user->previous_email_addr." address.";
135
136
    // We need to send a different version of the email to the old address.
137
    //
138
    $body_old = "Your email address has been changed. If you did not take this action,
139
then please click on the link below to reverse this process and change your password.
140
141
".secure_url_base()."recover_email.php?id=".$user->id."&token=".$token."
142
143
Note:  Your password will need to be recovered after clicking this link";
144
145
    return send_email($user, $subject, $body_new) && send_email($user, $subject, $body_old, null, $user->previous_email_addr);
146
}
147
148
// return true if the email address
149
// - is syntactically valid according to filter_var()
150
// - if configured, is OK with stopforumspam.com
151
//
152
function is_valid_email_sfs($addr) {
153
    if (!defined("USE_STOPFORUMSPAM")) return true;
154
    if (!USE_STOPFORUMSPAM) return true;
155
    $ip = '';
156
    if (array_key_exists('REMOTE_ADDR', $_SERVER)) {
157
        $ip = $_SERVER['REMOTE_ADDR'];
158
    }
159
    // For obviously private IPs check just the email against SFS,
160
    // otherwise check both IP and email
161
    if ($ip && filter_var(
162
        $ip, FILTER_VALIDATE_IP,
163
        FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE
164
    )) {
165
        $x = @file_get_contents("https://www.stopforumspam.com/api?ip=".$ip."&email=".$addr);
166
    } else {
167
        $x = @file_get_contents("https://www.stopforumspam.com/api?email=".$addr);
168
    }
169
    // could also look at 'frequency' and 'lastseen'
170
    // see https://www.stopforumspam.com/usage
171
    //
172
    if (substr_count($x, '<appears>yes</appears>')) {
0 ignored issues
show
It seems like $x can also be of type false; however, parameter $haystack of substr_count() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

172
    if (substr_count(/** @scrutinizer ignore-type */ $x, '<appears>yes</appears>')) {
Loading history...
173
        error_log("stopforumspam.com rejected email $addr, IP $ip");
0 ignored issues
show
The use of function error_log() is discouraged
Loading history...
174
        return false;
175
    }
176
    return true;
177
}
178
179
function is_valid_email_syntax($addr) {
180
    return filter_var($addr, FILTER_VALIDATE_EMAIL);
181
}
182
183
function send_confirm_delete_email($user) {
184
    $token = create_token($user->id, TOKEN_TYPE_DELETE_ACCOUNT, TOKEN_DURATION_ONE_DAY);
185
    if ($token === null) {
186
        error_page("Error creating token.  Please try again later.");
187
    }
188
189
    $subject = "Confirm your request to delete your account at ".PROJECT;
190
    $body = "This email was sent in response to a request on the ".PROJECT." web site.
191
192
You have requested to delete your account at ".PROJECT.". In order to do this, use the following link to confirm your intent to delete your account. ".
193
"The link will take you to a web page where you will be asked to enter your password and complete the process of deleting your account.
194
195
".secure_url_base()."delete_account_confirm.php?id=$user->id&token=$token
196
197
This link is valid for 1 day.
198
199
For further information and assistance with ".PROJECT.", visit ".secure_url_base();
200
201
    return send_email($user, $subject, $body);
202
}
203
204
function salted_key($key) {
205
    return md5($key.'oogabooga');
206
}
207
208
function opt_out_url($user, $page="opt_out.php") {
209
    return sprintf("%s%s?code=%s&userid=%d",
210
        secure_url_base(),
211
        $page,
212
        salted_key($user->authenticator),
213
        $user->id
214
    );
215
}
216
?>
217