]> git.mxchange.org Git - friendica.git/blob - mod/dfrn_notify.php
rework remote deletion
[friendica.git] / mod / dfrn_notify.php
1 <?php
2
3 require_once('simplepie/simplepie.inc');
4 require_once('include/items.php');
5
6
7 function dfrn_notify_post(&$a) {
8
9         $dfrn_id      = ((x($_POST,'dfrn_id'))      ? notags(trim($_POST['dfrn_id']))   : '');
10         $dfrn_version = ((x($_POST,'dfrn_version')) ? (float) $_POST['dfrn_version']    : 2.0);
11         $challenge    = ((x($_POST,'challenge'))    ? notags(trim($_POST['challenge'])) : '');
12         $data         = ((x($_POST,'data'))         ? $_POST['data']                    : '');
13         $key          = ((x($_POST,'key'))          ? $_POST['key']                     : '');
14         $dissolve     = ((x($_POST,'dissolve'))     ? intval($_POST['dissolve'])        :  0);
15
16         $direction = (-1);
17         if(strpos($dfrn_id,':') == 1) {
18                 $direction = intval(substr($dfrn_id,0,1));
19                 $dfrn_id = substr($dfrn_id,2);
20         }
21
22         $r = q("SELECT * FROM `challenge` WHERE `dfrn-id` = '%s' AND `challenge` = '%s' LIMIT 1",
23                 dbesc($dfrn_id),
24                 dbesc($challenge)
25         );
26         if(! count($r)) {
27                 logger('dfrn_notify: could not match challenge to dfrn_id ' . $dfrn_id . ' challenge=' . $challenge);
28                 xml_status(3);
29         }
30
31         $r = q("DELETE FROM `challenge` WHERE `dfrn-id` = '%s' AND `challenge` = '%s' LIMIT 1",
32                 dbesc($dfrn_id),
33                 dbesc($challenge)
34         );
35
36         // find the local user who owns this relationship.
37
38         $sql_extra = '';
39         switch($direction) {
40                 case (-1):
41                         $sql_extra = sprintf(" AND ( `issued-id` = '%s' OR `dfrn-id` = '%s' ) ", dbesc($dfrn_id), dbesc($dfrn_id));
42                         break;
43                 case 0:
44                         $sql_extra = sprintf(" AND `issued-id` = '%s' AND `duplex` = 1 ", dbesc($dfrn_id));
45                         break;
46                 case 1:
47                         $sql_extra = sprintf(" AND `dfrn-id` = '%s' AND `duplex` = 1 ", dbesc($dfrn_id));
48                         break;
49                 default:
50                         xml_status(3);
51                         break; // NOTREACHED
52         }
53                  
54
55         $r = q("SELECT `contact`.*, `contact`.`uid` AS `importer_uid`, 
56                 `contact`.`pubkey` AS `cpubkey`, `contact`.`prvkey` AS `cprvkey`, `user`.* FROM `contact` 
57                 LEFT JOIN `user` ON `contact`.`uid` = `user`.`uid` 
58                 WHERE `contact`.`blocked` = 0 AND `contact`.`pending` = 0 
59                 AND `user`.`nickname` = '%s' $sql_extra LIMIT 1",
60                 dbesc($a->argv[1])
61         );
62
63         if(! count($r)) {
64                 logger('dfrn_notify: contact not found for dfrn_id ' . $dfrn_id);
65                 xml_status(3);
66                 //NOTREACHED
67         }
68
69         // $importer in this case contains the contact record for the remote contact joined with the user record of our user. 
70
71         $importer = $r[0];
72
73         logger('dfrn_notify: received notify from ' . $importer['name'] . ' for ' . $importer['username']);
74         logger('dfrn_notify: data: ' . $data, LOGGER_DATA);
75
76         if($dissolve == 1) {
77
78                 /**
79                  * Relationship is dissolved permanently
80                  */
81
82                 require_once('include/Contact.php'); 
83                 contact_remove($importer['id']);
84                 logger('relationship dissolved : ' . $importer['name'] . ' dissolved ' . $importer['username']);
85                 xml_status(0);
86
87         }
88
89         if(strlen($key)) {
90                 $rawkey = hex2bin(trim($key));
91                 logger('rino: md5 raw key: ' . md5($rawkey));
92                 $final_key = '';
93
94                 if($dfrn_version >= 2.1) {
95                         if((($importer['duplex']) && strlen($importer['cprvkey'])) || (! strlen($importer['cpubkey']))) {
96                                 openssl_private_decrypt($rawkey,$final_key,$importer['cprvkey']);
97                         }
98                         else {
99                                 openssl_public_decrypt($rawkey,$final_key,$importer['cpubkey']);
100                         }
101                 }
102                 else {
103                         if((($importer['duplex']) && strlen($importer['cpubkey'])) || (! strlen($importer['cprvkey']))) {
104                                 openssl_public_decrypt($rawkey,$final_key,$importer['cpubkey']);
105                         }
106                         else {
107                                 openssl_private_decrypt($rawkey,$final_key,$importer['cprvkey']);
108                         }
109                 }
110
111                 logger('rino: received key : ' . $final_key);
112                 $data = aes_decrypt(hex2bin($data),$final_key);
113                 logger('rino: decrypted data: ' . $data, LOGGER_DATA);
114         }
115
116
117
118
119         if($importer['readonly']) {
120                 // We aren't receiving stuff from this person. But we will quietly ignore them
121                 // rather than a blatant "go away" message.
122                 logger('dfrn_notify: ignoring');
123                 xml_status(0);
124                 //NOTREACHED
125         }
126
127         // Consume notification feed. This may differ from consuming a public feed in several ways
128         // - might contain email
129         // - might contain remote followup to our message
130         //              - in which case we need to accept it and then notify other conversants
131         // - we may need to send various email notifications
132
133         $feed = new SimplePie();
134         $feed->set_raw_data($data);
135         $feed->enable_order_by_date(false);
136         $feed->init();
137
138         $ismail = false;
139
140         $rawmail = $feed->get_feed_tags( NAMESPACE_DFRN, 'mail' );
141         if(isset($rawmail[0]['child'][NAMESPACE_DFRN])) {
142
143                 logger('dfrn_notify: private message received');
144
145                 $ismail = true;
146                 $base = $rawmail[0]['child'][NAMESPACE_DFRN];
147
148                 $msg = array();
149                 $msg['uid'] = $importer['importer_uid'];
150                 $msg['from-name'] = notags(unxmlify($base['sender'][0]['child'][NAMESPACE_DFRN]['name'][0]['data']));
151                 $msg['from-photo'] = notags(unxmlify($base['sender'][0]['child'][NAMESPACE_DFRN]['avatar'][0]['data']));
152                 $msg['from-url'] = notags(unxmlify($base['sender'][0]['child'][NAMESPACE_DFRN]['uri'][0]['data']));
153                 $msg['contact-id'] = $importer['id'];
154                 $msg['title'] = notags(unxmlify($base['subject'][0]['data']));
155                 $msg['body'] = escape_tags(unxmlify($base['content'][0]['data']));
156                 $msg['seen'] = 0;
157                 $msg['replied'] = 0;
158                 $msg['uri'] = notags(unxmlify($base['id'][0]['data']));
159                 $msg['parent-uri'] = notags(unxmlify($base['in-reply-to'][0]['data']));
160                 $msg['created'] = datetime_convert(notags(unxmlify('UTC','UTC',$base['sentdate'][0]['data'])));
161                 
162                 dbesc_array($msg);
163
164                 $r = dbq("INSERT INTO `mail` (`" . implode("`, `", array_keys($msg)) 
165                         . "`) VALUES ('" . implode("', '", array_values($msg)) . "')" );
166
167                 // send email notification if requested.
168
169                 require_once('bbcode.php');
170                 if($importer['notify-flags'] & NOTIFY_MAIL) {
171
172                         $body = html_entity_decode(strip_tags(bbcode(stripslashes($msg['body']))),ENT_QUOTES,'UTF-8');
173
174                         if(function_exists('quoted_printable_encode'))
175                                 $body = quoted_printable_encode($body);
176                         else
177                                 $body = qp($body);
178
179                         $tpl = load_view_file('view/mail_received_eml.tpl');                    
180                         $email_tpl = replace_macros($tpl, array(
181                                 '$sitename' => $a->config['sitename'],
182                                 '$siteurl' =>  $a->get_baseurl(),
183                                 '$username' => $importer['username'],
184                                 '$email' => $importer['email'],
185                                 '$from' => $msg['from-name'],
186                                 '$title' => stripslashes($msg['title']),
187                                 '$body' => $body
188                         ));
189
190                         $res = mail($importer['email'], t('New mail received at ') . $a->config['sitename'],
191                                 $email_tpl, 'From: ' . t('Administrator') . '@' . $a->get_hostname() . "\r\n"
192                                         . 'MIME-Version: 1.0' . "\r\n"
193                                         . 'Content-type: text/plain; charset=UTF-8' . "\r\n" 
194                                         . 'Content-transfer-encoding: quoted-printable' . "\r\n"
195                         );
196                 }
197                 xml_status(0);
198                 // NOTREACHED
199         }       
200         
201         logger('dfrn_notify: feed item count = ' . $feed->get_item_quantity());
202
203         // process any deleted entries
204
205         $del_entries = $feed->get_feed_tags(NAMESPACE_TOMB, 'deleted-entry');
206         if(is_array($del_entries) && count($del_entries)) {
207                 foreach($del_entries as $dentry) {
208                         $deleted = false;
209                         if(isset($dentry['attribs']['']['ref'])) {
210                                 $uri = $dentry['attribs']['']['ref'];
211                                 $deleted = true;
212                                 if(isset($dentry['attribs']['']['when'])) {
213                                         $when = $dentry['attribs']['']['when'];
214                                         $when = datetime_convert('UTC','UTC', $when, 'Y-m-d H:i:s');
215                                 }
216                                 else
217                                         $when = datetime_convert('UTC','UTC','now','Y-m-d H:i:s');
218                         }
219                         if($deleted) {
220                                 $r = q("SELECT * FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
221                                         dbesc($uri),
222                                         intval($importer['importer_uid'])
223                                 );
224                                 if(count($r)) {
225                                         $item = $r[0];
226
227                                         if(! $item['deleted'])
228                                                 logger('dfrn_notify: deleting item ' . $item['id'] . ' uri=' . $item['uri'], LOGGER_DEBUG);
229
230                                         if($item['uri'] == $item['parent-uri']) {
231                                                 $r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s'
232                                                         WHERE `parent-uri` = '%s' AND `uid` = %d",
233                                                         dbesc($when),
234                                                         dbesc(datetime_convert()),
235                                                         dbesc($item['uri']),
236                                                         intval($importer['importer_uid'])
237                                                 );
238                                         }
239                                         else {
240                                                 $r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s' 
241                                                         WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
242                                                         dbesc($when),
243                                                         dbesc(datetime_convert()),
244                                                         dbesc($uri),
245                                                         intval($importer['importer_uid'])
246                                                 );
247                                                 if($item['last-child']) {
248                                                         // ensure that last-child is set in case the comment that had it just got wiped.
249                                                         $q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d ",
250                                                                 dbesc(datetime_convert()),
251                                                                 dbesc($item['parent-uri']),
252                                                                 intval($item['uid'])
253                                                         );
254                                                         // who is the last child now? 
255                                                         $r = q("SELECT `id` FROM `item` WHERE `parent-uri` = '%s' AND `type` != 'activity' AND `deleted` = 0 AND `uid` = %d
256                                                                 ORDER BY `created` DESC LIMIT 1",
257                                                                         dbesc($item['parent-uri']),
258                                                                         intval($importer['importer_uid'])
259                                                         );
260                                                         if(count($r)) {
261                                                                 q("UPDATE `item` SET `last-child` = 1 WHERE `id` = %d LIMIT 1",
262                                                                         intval($r[0]['id'])
263                                                                 );
264                                                         }       
265                                                 }
266                                         }       
267                                 }
268                         }
269                 }
270         }
271
272
273         foreach($feed->get_items() as $item) {
274
275                 $is_reply = false;              
276                 $item_id = $item->get_id();
277                 $rawthread = $item->get_item_tags( NAMESPACE_THREAD, 'in-reply-to');
278                 if(isset($rawthread[0]['attribs']['']['ref'])) {
279                         $is_reply = true;
280                         $parent_uri = $rawthread[0]['attribs']['']['ref'];
281                 }
282
283                 if($is_reply) {
284                         if($feed->get_item_quantity() == 1) {
285                                 logger('dfrn_notify: received remote comment');
286                                 $is_like = false;
287                                 // remote reply to our post. Import and then notify everybody else.
288                                 $datarray = get_atom_elements($feed,$item);
289                                 $datarray['type'] = 'remote-comment';
290                                 $datarray['wall'] = 1;
291                                 $datarray['parent-uri'] = $parent_uri;
292                                 $datarray['uid'] = $importer['importer_uid'];
293                                 $datarray['contact-id'] = $importer['id'];
294                                 if(($datarray['verb'] == ACTIVITY_LIKE) || ($datarray['verb'] == ACTIVITY_DISLIKE)) {
295                                         $is_like = true;
296                                         $datarray['type'] = 'activity';
297                                         $datarray['gravity'] = GRAVITY_LIKE;
298                                         $datarray['last-child'] = 0;
299                                 }
300                                 $posted_id = item_store($datarray);
301                                 $parent = 0;
302
303                                 if($posted_id) {
304                                         $r = q("SELECT `parent` FROM `item` WHERE `id` = %d AND `uid` = %d LIMIT 1",
305                                                 intval($posted_id),
306                                                 intval($importer['importer_uid'])
307                                         );
308                                         if(count($r))
309                                                 $parent = $r[0]['parent'];
310                         
311                                         if(! $is_like) {
312                                                 $r1 = q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `uid` = %d AND `parent` = %d",
313                                                         dbesc(datetime_convert()),
314                                                         intval($importer['importer_uid']),
315                                                         intval($r[0]['parent'])
316                                                 );
317
318                                                 $r2 = q("UPDATE `item` SET `last-child` = 1, `changed` = '%s' WHERE `uid` = %d AND `id` = %d LIMIT 1",
319                                                         dbesc(datetime_convert()),
320                                                         intval($importer['importer_uid']),
321                                                         intval($posted_id)
322                                                 );
323                                         }
324
325                                         if($posted_id && $parent) {
326                                 
327                                                 $php_path = ((strlen($a->config['php_path'])) ? $a->config['php_path'] : 'php');
328
329                                                 proc_run($php_path,"include/notifier.php","comment-import","$posted_id");
330                                         
331                                                 if((! $is_like) && ($importer['notify-flags'] & NOTIFY_COMMENT) && (! $importer['self'])) {
332                                                         require_once('bbcode.php');
333                                                         $from = stripslashes($datarray['author-name']);
334                                                         $tpl = load_view_file('view/cmnt_received_eml.tpl');                    
335                                                         $email_tpl = replace_macros($tpl, array(
336                                                                 '$sitename' => $a->config['sitename'],
337                                                                 '$siteurl' =>  $a->get_baseurl(),
338                                                                 '$username' => $importer['username'],
339                                                                 '$email' => $importer['email'],
340                                                                 '$display' => $a->get_baseurl() . '/display/' . $importer['nickname'] . '/' . $posted_id, 
341                                                                 '$from' => $from,
342                                                                 '$body' => strip_tags(bbcode(stripslashes($datarray['body'])))
343                                                         ));
344         
345                                                         $res = mail($importer['email'], $from . t(' commented on an item at ') . $a->config['sitename'],
346                                                                 $email_tpl, "From: " . t('Administrator') . '@' . $a->get_hostname() );
347                                                 }
348                                         }
349                                         xml_status(0);
350                                         // NOTREACHED
351                                 }
352                         }
353                         else {
354                                 // regular comment that is part of this total conversation. Have we seen it? If not, import it.
355
356                                 $item_id = $item->get_id();
357
358                                 $r = q("SELECT `uid`, `last-child`, `edited` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
359                                         dbesc($item_id),
360                                         intval($importer['importer_uid'])
361                                 );
362                                 // FIXME update content if 'updated' changes
363                                 if(count($r)) {
364                                         $allow = $item->get_item_tags( NAMESPACE_DFRN, 'comment-allow');
365                                         if($allow && $allow[0]['data'] != $r[0]['last-child']) {
366                                                 $r = q("UPDATE `item` SET `last-child` = %d, `changed` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
367                                                         intval($allow[0]['data']),
368                                                         dbesc(datetime_convert()),
369                                                         dbesc($item_id),
370                                                         intval($importer['importer_uid'])
371                                                 );
372                                         }
373                                         continue;
374                                 }
375                                 $datarray = get_atom_elements($feed,$item);
376                                 $datarray['parent-uri'] = $parent_uri;
377                                 $datarray['uid'] = $importer['importer_uid'];
378                                 $datarray['contact-id'] = $importer['id'];
379                                 if(($datarray['verb'] == ACTIVITY_LIKE) || ($datarray['verb'] == ACTIVITY_DISLIKE)) {
380                                         $datarray['type'] = 'activity';
381                                         $datarray['gravity'] = GRAVITY_LIKE;
382                                 }
383                                 $r = item_store($datarray);
384
385                                 // find out if our user is involved in this conversation and wants to be notified.
386                         
387                                 if(($datarray['type'] != 'activity') && ($importer['notify-flags'] & NOTIFY_COMMENT)) {
388
389                                         $myconv = q("SELECT `author-link` FROM `item` WHERE `parent-uri` = '%s' AND `uid` = %d AND `parent` != 0 ",
390                                                 dbesc($parent_uri),
391                                                 intval($importer['importer_uid'])
392                                         );
393                                         if(count($myconv)) {
394                                                 foreach($myconv as $conv) {
395                                                         if(! link_compare($conv['author-link'],$importer['url']))
396                                                                 continue;
397                                                         require_once('bbcode.php');
398                                                         $from = stripslashes($datarray['author-name']);
399                                                         $tpl = load_view_file('view/cmnt_received_eml.tpl');    
400                                                         $email_tpl = replace_macros($tpl, array(
401                                                                 '$sitename' => $a->config['sitename'],
402                                                                 '$siteurl' =>  $a->get_baseurl(),
403                                                                 '$username' => $importer['username'],
404                                                                 '$email' => $importer['email'],
405                                                                 '$from' => $from,
406                                                                 '$display' => $a->get_baseurl() . '/display/' . $importer['nickname'] . '/' . $r,
407                                                                 '$body' => strip_tags(bbcode(stripslashes($datarray['body'])))
408                                                         ));
409
410                                                         $res = mail($importer['email'], $from . t(" commented on an item at ") 
411                                                                 . $a->config['sitename'],
412                                                                 $email_tpl,t("From: Administrator@") . $a->get_hostname() );
413                                                         break;
414                                                 }
415                                         }
416                                 }
417                                 continue;
418                         }
419                 }
420                 else {
421                         // Head post of a conversation. Have we seen it? If not, import it.
422
423                         $item_id = $item->get_id();
424                         $r = q("SELECT `uid`, `last-child`, `edited` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
425                                 dbesc($item_id),
426                                 intval($importer['importer_uid'])
427                         );
428                         if(count($r)) {
429                                 $allow = $item->get_item_tags( NAMESPACE_DFRN, 'comment-allow');
430                                 if($allow && $allow[0]['data'] != $r[0]['last-child']) {
431                                         $r = q("UPDATE `item` SET `last-child` = %d, `changed` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
432                                                 intval($allow[0]['data']),
433                                                 dbesc(datetime_convert()),
434                                                 dbesc($item_id),
435                                                 intval($importer['importer_uid'])
436                                         );
437                                 }
438                                 continue;
439                         }
440
441
442                         $datarray = get_atom_elements($feed,$item);
443                         $datarray['parent-uri'] = $item_id;
444                         $datarray['uid'] = $importer['importer_uid'];
445                         $datarray['contact-id'] = $importer['id'];
446                         $r = item_store($datarray);
447                         continue;
448                 }
449         }
450
451         xml_status(0);
452         // NOTREACHED
453
454 }
455
456
457 function dfrn_notify_content(&$a) {
458
459         if(x($_GET,'dfrn_id')) {
460
461                 // initial communication from external contact, $direction is their direction.
462                 // If this is a duplex communication, ours will be the opposite.
463
464                 $dfrn_id = notags(trim($_GET['dfrn_id']));
465                 $dfrn_version = (float) $_GET['dfrn_version'];
466
467                 logger('dfrn_notify: new notification dfrn_id=' . $dfrn_id);
468
469                 $direction = (-1);
470                 if(strpos($dfrn_id,':') == 1) {
471                         $direction = intval(substr($dfrn_id,0,1));
472                         $dfrn_id = substr($dfrn_id,2);
473                 }
474
475                 $hash = random_string();
476
477                 $status = 0;
478
479                 $r = q("DELETE FROM `challenge` WHERE `expire` < " . intval(time()));
480
481                 $r = q("INSERT INTO `challenge` ( `challenge`, `dfrn-id`, `expire` )
482                         VALUES( '%s', '%s', %d ) ",
483                         dbesc($hash),
484                         dbesc($dfrn_id),
485                         intval(time() + 90 )
486                 );
487
488                 logger('dfrn_notify: challenge=' . $hash );
489
490                 $sql_extra = '';
491                 switch($direction) {
492                         case (-1):
493                                 $sql_extra = sprintf(" AND ( `issued-id` = '%s' OR `dfrn-id` = '%s' ) ", dbesc($dfrn_id), dbesc($dfrn_id));
494                                 $my_id = $dfrn_id;
495                                 break;
496                         case 0:
497                                 $sql_extra = sprintf(" AND `issued-id` = '%s' AND `duplex` = 1 ", dbesc($dfrn_id));
498                                 $my_id = '1:' . $dfrn_id;
499                                 break;
500                         case 1:
501                                 $sql_extra = sprintf(" AND `dfrn-id` = '%s' AND `duplex` = 1 ", dbesc($dfrn_id));
502                                 $my_id = '0:' . $dfrn_id;
503                                 break;
504                         default:
505                                 $status = 1;
506                                 break; // NOTREACHED
507                 }
508
509                 $r = q("SELECT `contact`.*, `user`.`nickname` FROM `contact` LEFT JOIN `user` ON `user`.`uid` = `contact`.`uid` 
510                                 WHERE `contact`.`blocked` = 0 AND `contact`.`pending` = 0 AND `user`.`nickname` = '%s' $sql_extra LIMIT 1",
511                                 dbesc($a->argv[1])
512                 );
513
514                 if(! count($r))
515                         $status = 1;
516
517                 $challenge = '';
518                 $encrypted_id = '';
519                 $id_str = $my_id . '.' . mt_rand(1000,9999);
520
521                 if((($r[0]['duplex']) && strlen($r[0]['prvkey'])) || (! strlen($r[0]['pubkey']))) {
522                         openssl_private_encrypt($hash,$challenge,$r[0]['prvkey']);
523                         openssl_private_encrypt($id_str,$encrypted_id,$r[0]['prvkey']);
524                 }
525                 else {
526                         openssl_public_encrypt($hash,$challenge,$r[0]['pubkey']);
527                         openssl_public_encrypt($id_str,$encrypted_id,$r[0]['pubkey']);
528                 }
529
530                 $challenge    = bin2hex($challenge);
531                 $encrypted_id = bin2hex($encrypted_id);
532
533                 $rino = ((function_exists('mcrypt_encrypt')) ? 1 : 0);
534
535                 $rino_enable = get_config('system','rino_encrypt');
536
537                 if(! $rino_enable)
538                         $rino = 0;
539
540
541                 header("Content-type: text/xml");
542
543                 echo '<?xml version="1.0" encoding="UTF-8"?>' . "\r\n" 
544                         . '<dfrn_notify>' . "\r\n"
545                         . "\t" . '<status>' . $status . '</status>' . "\r\n"
546                         . "\t" . '<dfrn_version>' . DFRN_PROTOCOL_VERSION . '</dfrn_version>' . "\r\n"
547                         . "\t" . '<rino>' . $rino . '</rino>' . "\r\n" 
548                         . "\t" . '<dfrn_id>' . $encrypted_id . '</dfrn_id>' . "\r\n" 
549                         . "\t" . '<challenge>' . $challenge . '</challenge>' . "\r\n"
550                         . '</dfrn_notify>' . "\r\n" ;
551
552                 killme();
553         }
554
555 }