]> git.mxchange.org Git - friendica.git/blob - mod/dfrn_confirm.php
69c93abd619bdf1254077e703f4512a04c482ee9
[friendica.git] / mod / dfrn_confirm.php
1 <?php
2
3
4
5 function dfrn_confirm_post(&$a) {
6
7         if($a->argc > 1)
8                 $node = $a->argv[1];
9
10         if(x($_POST,'source_url')) {
11
12                 // We are processing an external confirmation to an introduction created by our user.
13
14                 $public_key = $_POST['public_key'];
15                 $dfrn_id = $_POST['dfrn_id'];
16                 $source_url = $_POST['source_url'];
17                 $aes_key = $_POST['aes_key'];
18
19                 // Find our user's account
20
21                 $r = q("SELECT * FROM `user` WHERE `nickname` = '%s' LIMIT 1",
22                         dbesc($node));
23
24                 if(! count($r)) {
25                         xml_status(3); // failure
26                 }
27
28                 $my_prvkey = $r[0]['prvkey'];
29                 $local_uid = $r[0]['uid'];
30
31                 $decrypted_source_url = "";
32
33                 // verify everything
34
35                 openssl_private_decrypt($source_url,$decrypted_source_url,$my_prvkey);
36
37
38                 $ret = q("SELECT * FROM `contact` WHERE `url` = '%s' AND `uid` = %d LIMIT 1",
39                         dbesc($decrypted_source_url),
40                         intval($local_uid));
41
42                 if(! count($ret)) {
43                         // this is either a bogus confirmation or we deleted the original introduction.
44                         xml_status(3); 
45                 }
46
47                 $relation = $r[0]['rel'];
48
49                 // Decrypt all this stuff we just received
50
51                 $foreign_pubkey = $ret[0]['site-pubkey'];
52                 $dfrn_record = $ret[0]['id'];
53                 $decrypted_dfrn_id = "";
54                 openssl_public_decrypt($dfrn_id,$decrypted_dfrn_id,$foreign_pubkey);
55
56                 if(strlen($aes_key)) {
57                         $decrypted_aes_key = "";
58                         openssl_private_decrypt($aes_key,$decrypted_aes_key,$my_prvkey);
59                         $dfrn_pubkey = openssl_decrypt($public_key,'AES-256-CBC',$decrypted_aes_key);
60                 }
61                 else {
62                         $dfrn_pubkey = $public_key;
63                 }
64
65                 $r = q("SELECT * FROM `contact` WHERE `dfrn-id` = '%s' LIMIT 1",
66                         dbesc($decrypted_dfrn_id),
67                         intval($local_uid));
68                 if(count($r))
69                         xml_status(1); // Birthday paradox - duplicate dfrn-id
70
71                 $r = q("UPDATE `contact` SET `dfrn-id` = '%s', `pubkey` = '%s' WHERE `id` = %d LIMIT 1",
72                         dbesc($decrypted_dfrn_id),
73                         dbesc($dfrn_pubkey),
74                         intval($dfrn_record));
75                 if($r) {
76
77                         // We're good but now we have to scrape the profile photo and send notifications.
78
79                         require_once("Photo.php");
80
81                         $photo_failure = false;
82
83                         $r = q("SELECT `photo` FROM `contact` WHERE `id` = %d LIMIT 1",
84                                 intval($dfrn_record));
85                         if(count($r)) {
86
87                                 $filename = basename($r[0]['photo']);
88                                 $img_str = fetch_url($r[0]['photo'],true);
89                                 $img = new Photo($img_str);
90                                 if($img) {
91
92                                         $img->scaleImageSquare(175);
93                                         
94                                         $hash = hash('md5',uniqid(mt_rand(),true));
95
96                                         $r = $img->store($local_uid, $dfrn_record, $hash, $filename, t('Contact Photos') , 4);
97
98                                         if($r === false)
99                                                 $photo_failure = true;
100                                         
101                                         $img->scaleImage(80);
102                                         $r = $img->store($local_uid, $dfrn_record, $hash, $filename, t('Contact Photos') , 5);
103
104                                         if($r === false)
105                                                 $photo_failure = true;
106
107                                         $photo = $a->get_baseurl() . '/photo/' . $hash . '-4.jpg';
108                                         $thumb = $a->get_baseurl() . '/photo/' . $hash . '-5.jpg';      
109                                 }
110                                 else
111                                         $photo_failure = true;
112                         }
113                         else
114                                 $photo_failure = true;
115
116                         if($photo_failure) {
117                                 $photo = $a->get_baseurl() . '/images/default-profile.jpg';
118                                 $thumb = $a->get_baseurl() . '/images/default-profile-sm.jpg';
119                         }
120
121                         $r = q("UPDATE `contact` SET `photo` = '%s', `thumb` = '%s', `rel` = %d, `name-date` = '%s', `uri-date` = '%s', `avatar-date` = '%s', `blocked` = 0, `pending` = 0, `network` = 'dfrn' WHERE `id` = %d LIMIT 1",
122                                 dbesc($photo),
123                                 dbesc($thumb),
124                                 intval(($relation == DIRECTION_IN) ? DIRECTION_BOTH: DIRECTION_OUT),
125                                 dbesc(datetime_convert()),
126                                 dbesc(datetime_convert()),
127                                 dbesc(datetime_convert()),
128                                 intval($dfrn_record)
129                         );
130                         if($r === false)
131                                 notice( t("Unable to set contact photo info.") . EOL);
132
133                         // Otherwise everything seems to have worked and we are almost done. Yay!
134                         // Send an email notification
135
136                         $r = q("SELECT * FROM `contact` LEFT JOIN `user` ON `contact`.`uid` = `user`.`uid`
137                                 WHERE `contact`.`id` = %d LIMIT 1",
138                                 intval($dfrn_record));
139                         if((count($r)) && ($r[0]['notify-flags'] & NOTIFY_CONFIRM)) {
140
141                                 $tpl = file_get_contents('view/intro_complete_eml.tpl');
142                         
143                                 $email_tpl = replace_macros($tpl, array(
144                                         '$sitename' => $a->config['sitename'],
145                                         '$siteurl' =>  $a->get_baseurl(),
146                                         '$username' => $r[0]['username'],
147                                         '$email' => $r[0]['email'],
148                                         '$fn' => $r[0]['name'],
149                                         '$dfrn_url' => $r[0]['url'],
150                                         '$uid' => $newuid )
151                                 );
152         
153                                 $res = mail($r[0]['email'], t("Introduction accepted at ") . $a->config['sitename'],
154                                         $email_tpl,t("From: Administrator@") . $_SERVER[SERVER_NAME] );
155                                 if(!$res) {
156                                         notice( t("Email notification failed.") . EOL );
157                                 }
158                         }
159                         xml_status(0); // Success
160
161                         return; // NOTREACHED
162                 }
163                 else {
164                         xml_status(2);  // Hopefully temporary problem that can be retried.
165                 }
166                 return; // NOTREACHED
167
168         ////////////////////// End of this scenario ///////////////////////////////////////////////
169         }
170         else {
171
172                 // We are processing a local confirmation initiated on this system by our user to an external introduction.
173
174                 $uid = $_SESSION['uid'];
175
176                 if(! $uid) {
177                         notice( t("Permission denied.") . EOL );
178                         return;
179                 }       
180         
181                 $dfrn_id = ((x($_POST,'dfrn_id')) ? notags(trim($_POST['dfrn_id'])) : "");
182                 $intro_id = intval($_POST['intro_id']);
183
184                 $r = q("SELECT * FROM `contact` WHERE `issued-id` = '%s' AND `uid` = %d LIMIT 1",
185                                 dbesc($dfrn_id),
186                                 intval($uid)
187                                 );
188
189                 if((! $r) || (! count($r))) {
190                         notice( t('Node does not exist.') . EOL );
191                         return;
192                 }
193
194                 $contact_id = $r[0]['id'];
195                 $relation = $r[0]['rel'];
196                 $site_pubkey = $r[0]['site-pubkey'];
197                 $dfrn_confirm = $r[0]['confirm'];
198                 $aes_allow = $r[0]['aes_allow'];
199
200                 $res=openssl_pkey_new(array(
201                         'digest_alg' => 'whirlpool',
202                         'private_key_bits' => 4096,
203                         'encrypt_key' => false ));
204
205
206                 $private_key = '';
207
208                 openssl_pkey_export($res, $private_key);
209
210
211                 $pubkey = openssl_pkey_get_details($res);
212                 $public_key = $pubkey["key"];
213
214                 $r = q("UPDATE `contact` SET `issued-pubkey` = '%s', `prvkey` = '%s' WHERE `id` = %d AND `uid` = %d LIMIT 1",
215                         dbesc($public_key),
216                         dbesc($private_key),
217                         intval($contact_id),
218                         intval($uid) 
219                 );
220
221
222                 $params = array();
223
224                 $src_aes_key = random_string();
225                 $result = "";
226
227                 openssl_private_encrypt($dfrn_id,$result,$a->user['prvkey']);
228
229                 $params['dfrn_id'] = $result;
230                 $params['public_key'] = $public_key;
231
232
233                 openssl_public_encrypt($_SESSION['my_url'], $params['source_url'], $site_pubkey);
234
235                 if($aes_allow && function_exists('openssl_encrypt')) {
236                         openssl_public_encrypt($src_aes_key, $params['aes_key'], $site_pubkey);
237                         $params['public_key'] = openssl_encrypt($public_key,'AES-256-CBC',$src_aes_key);
238                 }
239
240                 $res = post_url($dfrn_confirm,$params);
241
242 // uncomment the following two lines and comment the following xml/status lines
243 // to debug the remote confirmation section (when both confirmations 
244 // and responses originate on this system)
245
246 // echo $res;
247 // $status = 0;
248
249                 $xml = simplexml_load_string($res);
250                 $status = (int) $xml->status;
251                 switch($status) {
252                         case 0:
253                                 notice( t("Confirmation completed successfully") . EOL);
254                                 break;
255                         case 1:
256
257                                 // birthday paradox - generate new dfrn-id and fall through.
258
259                                 $new_dfrn_id = random_string();
260                                 $r = q("UPDATE contact SET `issued-id` = '%s' WHERE `id` = %d AND `uid` = %d LIMIT 1",
261                                         dbesc($new_dfrn_id),
262                                         intval($contact_id),
263                                         intval($uid) 
264                                 );
265
266                         case 2:
267                                 notice( t("Temporary failure. Please wait and try again.") . EOL);
268                                 break;
269
270
271                         case 3:
272                                 notice( t("Introduction failed or was revoked. Cannot complete.") . EOL);
273                                 break;
274                 }
275
276                 if(($status == 0 || $status == 3) && ($intro_id)) {
277
278                         //delete the notification
279
280                         $r = q("DELETE FROM `intro` WHERE `id` = %d AND `uid` = %d LIMIT 1",
281                                 intval($intro_id),
282                                 intval($uid)
283                         );
284                         
285                 }
286                 if($status != 0) 
287                         return;
288                 
289
290                 require_once("Photo.php");
291
292                 $photo_failure = false;
293
294                 $r = q("SELECT `photo` FROM `contact` WHERE `id` = %d LIMIT 1",
295                         intval($contact_id));
296                 if(count($r)) {
297
298                         $filename = basename($r[0]['photo']);
299                         $img_str = fetch_url($r[0]['photo'],true);
300                         $img = new Photo($img_str);
301                         if($img) {
302
303                                 $img->scaleImageSquare(175);
304                                         
305                                 $hash = hash('md5',uniqid(mt_rand(),true));
306
307                                 $r = $img->store($uid, $contact_id, $hash, $filename, t('Contact Photos'), 4 );
308
309                                 if($r === false)
310                                         $photo_failure = true;
311                                 $img->scaleImage(80);
312
313                                 $r = $img->store($uid, $contact_id, $hash, $filename, t('Contact Photos'), 5 );
314
315                                 if($r === false)
316                                         $photo_failure = true;
317
318                                 $photo = $a->get_baseurl() . '/photo/' . $hash . '-4.jpg';
319                                 $thumb = $a->get_baseurl() . '/photo/' . $hash . '-5.jpg';
320                         }
321                         else
322                                 $photo_failure = true;
323                 }
324                 else
325                         $photo_failure = true;
326
327                 if($photo_failure) {
328                         $photo = $a->get_baseurl() . '/images/default-profile.jpg';
329                         $thumb = $a->get_baseurl() . '/images/default-profile-sm.jpg';
330                 }
331
332                 $r = q("UPDATE `contact` SET `photo` = '%s', `thumb` = '%s', `rel` = %d, `name-date` = '%s', `uri-date` = '%s', `avatar-date` = '%s', `blocked` = 0, `pending` = 0, `network` = 'dfrn' WHERE `id` = %d LIMIT 1",
333                         dbesc($photo),
334                         dbesc($thumb),
335                         intval(($relation == DIRECTION_OUT) ? DIRECTION_BOTH: DIRECTION_IN),
336                         dbesc(datetime_convert()),
337                         dbesc(datetime_convert()),
338                         dbesc(datetime_convert()),
339                         intval($contact_id)
340                 );
341                 if($r === false)
342                         notice( t('Unable to set contact photo.') . EOL);
343
344                 goaway($a->get_baseurl() . '/contacts/' . intval($contact_id));
345                 return;  //NOTREACHED
346
347         }
348
349         return;
350 }