]> git.mxchange.org Git - friendica.git/blob - mod/dfrn_notify.php
add remove_user hook (it looks like dreamhost changed all my file permissions, this...
[friendica.git] / mod / dfrn_notify.php
1 <?php
2
3 require_once('library/simplepie/simplepie.inc');
4 require_once('include/items.php');
5 require_once('include/event.php');
6
7
8 function dfrn_notify_post(&$a) {
9
10         $dfrn_id      = ((x($_POST,'dfrn_id'))      ? notags(trim($_POST['dfrn_id']))   : '');
11         $dfrn_version = ((x($_POST,'dfrn_version')) ? (float) $_POST['dfrn_version']    : 2.0);
12         $challenge    = ((x($_POST,'challenge'))    ? notags(trim($_POST['challenge'])) : '');
13         $data         = ((x($_POST,'data'))         ? $_POST['data']                    : '');
14         $key          = ((x($_POST,'key'))          ? $_POST['key']                     : '');
15         $dissolve     = ((x($_POST,'dissolve'))     ? intval($_POST['dissolve'])        :  0);
16         $perm         = ((x($_POST,'perm'))         ? notags(trim($_POST['perm']))      : 'r');
17
18         $writable = (-1);
19         if($dfrn_version >= 2.21) {
20                 $writable = (($perm === 'rw') ? 1 : 0);
21         }
22
23         $direction = (-1);
24         if(strpos($dfrn_id,':') == 1) {
25                 $direction = intval(substr($dfrn_id,0,1));
26                 $dfrn_id = substr($dfrn_id,2);
27         }
28
29         $r = q("SELECT * FROM `challenge` WHERE `dfrn-id` = '%s' AND `challenge` = '%s' LIMIT 1",
30                 dbesc($dfrn_id),
31                 dbesc($challenge)
32         );
33         if(! count($r)) {
34                 logger('dfrn_notify: could not match challenge to dfrn_id ' . $dfrn_id . ' challenge=' . $challenge);
35                 xml_status(3);
36         }
37
38         $r = q("DELETE FROM `challenge` WHERE `dfrn-id` = '%s' AND `challenge` = '%s' LIMIT 1",
39                 dbesc($dfrn_id),
40                 dbesc($challenge)
41         );
42
43         // find the local user who owns this relationship.
44
45         $sql_extra = '';
46         switch($direction) {
47                 case (-1):
48                         $sql_extra = sprintf(" AND ( `issued-id` = '%s' OR `dfrn-id` = '%s' ) ", dbesc($dfrn_id), dbesc($dfrn_id));
49                         break;
50                 case 0:
51                         $sql_extra = sprintf(" AND `issued-id` = '%s' AND `duplex` = 1 ", dbesc($dfrn_id));
52                         break;
53                 case 1:
54                         $sql_extra = sprintf(" AND `dfrn-id` = '%s' AND `duplex` = 1 ", dbesc($dfrn_id));
55                         break;
56                 default:
57                         xml_status(3);
58                         break; // NOTREACHED
59         }
60                  
61         // be careful - $importer will contain both the contact information for the contact
62         // sending us the post, and also the user information for the person receiving it.
63         // since they are mixed together, it is easy to get them confused.
64
65         $r = q("SELECT  `contact`.*, `contact`.`uid` AS `importer_uid`, 
66                                         `contact`.`pubkey` AS `cpubkey`, 
67                                         `contact`.`prvkey` AS `cprvkey`, 
68                                         `contact`.`thumb` AS `thumb`, 
69                                         `contact`.`url` as `url`,
70                                         `contact`.`name` as `senderName`,
71                                         `user`.* 
72                         FROM `contact` 
73                         LEFT JOIN `user` ON `contact`.`uid` = `user`.`uid` 
74                         WHERE `contact`.`blocked` = 0 AND `contact`.`pending` = 0 
75                                 AND `user`.`nickname` = '%s' AND `user`.`account_expired` = 0 $sql_extra LIMIT 1",
76                 dbesc($a->argv[1])
77         );
78
79         if(! count($r)) {
80                 logger('dfrn_notify: contact not found for dfrn_id ' . $dfrn_id);
81                 xml_status(3);
82                 //NOTREACHED
83         }
84
85         // $importer in this case contains the contact record for the remote contact joined with the user record of our user. 
86
87         $importer = $r[0];
88
89         if(($writable != (-1)) && ($writable != $importer['writable'])) {
90                 q("UPDATE `contact` SET `writable` = %d WHERE `id` = %d LIMIT 1",
91                         intval($writable),
92                         intval($importer['id'])
93                 );
94                 $importer['writable'] = $writable;
95         }
96
97         logger('dfrn_notify: received notify from ' . $importer['name'] . ' for ' . $importer['username']);
98         logger('dfrn_notify: data: ' . $data, LOGGER_DATA);
99
100         if($dissolve == 1) {
101
102                 /**
103                  * Relationship is dissolved permanently
104                  */
105
106                 require_once('include/Contact.php'); 
107                 contact_remove($importer['id']);
108                 logger('relationship dissolved : ' . $importer['name'] . ' dissolved ' . $importer['username']);
109                 xml_status(0);
110
111         }
112
113         if(strlen($key)) {
114                 $rawkey = hex2bin(trim($key));
115                 logger('rino: md5 raw key: ' . md5($rawkey));
116                 $final_key = '';
117
118                 if($dfrn_version >= 2.1) {
119                         if((($importer['duplex']) && strlen($importer['cprvkey'])) || (! strlen($importer['cpubkey']))) {
120                                 openssl_private_decrypt($rawkey,$final_key,$importer['cprvkey']);
121                         }
122                         else {
123                                 openssl_public_decrypt($rawkey,$final_key,$importer['cpubkey']);
124                         }
125                 }
126                 else {
127                         if((($importer['duplex']) && strlen($importer['cpubkey'])) || (! strlen($importer['cprvkey']))) {
128                                 openssl_public_decrypt($rawkey,$final_key,$importer['cpubkey']);
129                         }
130                         else {
131                                 openssl_private_decrypt($rawkey,$final_key,$importer['cprvkey']);
132                         }
133                 }
134
135                 logger('rino: received key : ' . $final_key);
136                 $data = aes_decrypt(hex2bin($data),$final_key);
137                 logger('rino: decrypted data: ' . $data, LOGGER_DATA);
138         }
139
140
141         $ret = local_delivery($importer,$data);
142         xml_status($ret);
143
144         // NOTREACHED
145 }
146
147
148 function dfrn_notify_content(&$a) {
149
150         if(x($_GET,'dfrn_id')) {
151
152                 // initial communication from external contact, $direction is their direction.
153                 // If this is a duplex communication, ours will be the opposite.
154
155                 $dfrn_id = notags(trim($_GET['dfrn_id']));
156                 $dfrn_version = (float) $_GET['dfrn_version'];
157
158                 logger('dfrn_notify: new notification dfrn_id=' . $dfrn_id);
159
160                 $direction = (-1);
161                 if(strpos($dfrn_id,':') == 1) {
162                         $direction = intval(substr($dfrn_id,0,1));
163                         $dfrn_id = substr($dfrn_id,2);
164                 }
165
166                 $hash = random_string();
167
168                 $status = 0;
169
170                 $r = q("DELETE FROM `challenge` WHERE `expire` < " . intval(time()));
171
172                 $r = q("INSERT INTO `challenge` ( `challenge`, `dfrn-id`, `expire` )
173                         VALUES( '%s', '%s', %d ) ",
174                         dbesc($hash),
175                         dbesc($dfrn_id),
176                         intval(time() + 90 )
177                 );
178
179                 logger('dfrn_notify: challenge=' . $hash, LOGGER_DEBUG );
180
181                 $sql_extra = '';
182                 switch($direction) {
183                         case (-1):
184                                 $sql_extra = sprintf(" AND ( `issued-id` = '%s' OR `dfrn-id` = '%s' ) ", dbesc($dfrn_id), dbesc($dfrn_id));
185                                 $my_id = $dfrn_id;
186                                 break;
187                         case 0:
188                                 $sql_extra = sprintf(" AND `issued-id` = '%s' AND `duplex` = 1 ", dbesc($dfrn_id));
189                                 $my_id = '1:' . $dfrn_id;
190                                 break;
191                         case 1:
192                                 $sql_extra = sprintf(" AND `dfrn-id` = '%s' AND `duplex` = 1 ", dbesc($dfrn_id));
193                                 $my_id = '0:' . $dfrn_id;
194                                 break;
195                         default:
196                                 $status = 1;
197                                 break; // NOTREACHED
198                 }
199
200                 $r = q("SELECT `contact`.*, `user`.`nickname` FROM `contact` LEFT JOIN `user` ON `user`.`uid` = `contact`.`uid` 
201                                 WHERE `contact`.`blocked` = 0 AND `contact`.`pending` = 0 AND `user`.`nickname` = '%s' 
202                                 AND `user`.`account_expired` = 0 $sql_extra LIMIT 1",
203                                 dbesc($a->argv[1])
204                 );
205
206                 if(! count($r))
207                         $status = 1;
208
209                 $challenge = '';
210                 $encrypted_id = '';
211                 $id_str = $my_id . '.' . mt_rand(1000,9999);
212
213                 $prv_key = trim($r[0]['prvkey']);
214                 $pub_key = trim($r[0]['pubkey']);
215                 $dplx = intval($r[0]['duplex']);
216
217                 if((($dplx) && (strlen($prv_key))) || ((strlen($prv_key)) && (!(strlen($pub_key))))) {
218                         openssl_private_encrypt($hash,$challenge,$prv_key);
219                         openssl_private_encrypt($id_str,$encrypted_id,$prv_key);
220                 }
221                 elseif(strlen($pub_key)) {
222                         openssl_public_encrypt($hash,$challenge,$pub_key);
223                         openssl_public_encrypt($id_str,$encrypted_id,$pub_key);
224                 }
225                 else
226                         $status = 1;
227
228                 $challenge    = bin2hex($challenge);
229                 $encrypted_id = bin2hex($encrypted_id);
230
231                 $rino = ((function_exists('mcrypt_encrypt')) ? 1 : 0);
232
233                 $rino_enable = get_config('system','rino_encrypt');
234
235                 if(! $rino_enable)
236                         $rino = 0;
237
238
239                 header("Content-type: text/xml");
240
241                 echo '<?xml version="1.0" encoding="UTF-8"?>' . "\r\n" 
242                         . '<dfrn_notify>' . "\r\n"
243                         . "\t" . '<status>' . $status . '</status>' . "\r\n"
244                         . "\t" . '<dfrn_version>' . DFRN_PROTOCOL_VERSION . '</dfrn_version>' . "\r\n"
245                         . "\t" . '<rino>' . $rino . '</rino>' . "\r\n" 
246                         . "\t" . '<dfrn_id>' . $encrypted_id . '</dfrn_id>' . "\r\n" 
247                         . "\t" . '<challenge>' . $challenge . '</challenge>' . "\r\n"
248                         . '</dfrn_notify>' . "\r\n" ;
249
250                 killme();
251         }
252
253 }