@@ -102,18 +102,22 @@ namespace graphene { namespace app {
102
102
auto op = trx.operations [0 ];
103
103
if ( op.which () != operation::tag<transfer_operation>::value ) // only transfer op for validation
104
104
return false ;
105
+
105
106
const auto acc_id = op.get <transfer_operation>().from ;
107
+ const auto to = op.get <transfer_operation>().to ;
108
+ if ( acc_id != to ) // prevent MITM attacks
109
+ return false ;
106
110
107
111
const auto & signature_keys = trx.get_signature_keys ( db->get_chain_id () );
108
112
if ( signature_keys.empty () )
109
113
return false ;
110
-
114
+
111
115
const auto & public_key = *signature_keys.begin ();
112
-
116
+
113
117
auto key_refs = (*_database_api)->get_key_references ( {public_key} )[0 ];
114
118
if ( std::find ( key_refs.begin (), key_refs.end (), acc_id ) == key_refs.end () )
115
119
return false ;
116
-
120
+
117
121
const auto & acc = acc_id (*db);
118
122
optional< api_access_info_signed_variant > api_access_info_var = _app.get_api_access_info_signed ( acc.name );
119
123
if ( !api_access_info_var )
@@ -123,7 +127,7 @@ namespace graphene { namespace app {
123
127
{
124
128
const auto & api_access_info = api_access_info_var->get <api_access_info_signed>();
125
129
if ( !verify_api_access_info_signed ( acc, api_access_info ) )
126
- return false ; // TODO or try default login then???
130
+ return false ;
127
131
128
132
for ( const auto & api : api_access_info.allowed_apis )
129
133
enable_api ( api );
@@ -150,23 +154,48 @@ namespace graphene { namespace app {
150
154
bool login_api::verify_api_access_info_signed ( const account_object& acc,
151
155
const api_access_info_signed& api_access_info )
152
156
{
157
+ auto db = _app.chain_database ();
158
+
153
159
if ( api_access_info.required_lifetime_member && !acc.is_lifetime_member () )
154
160
return false ;
155
161
156
162
const auto & required_registrar_name = api_access_info.required_registrar ;
157
- if ( required_registrar_name == " " )
163
+ bool registrar_required = required_registrar_name != " " ? true : false ;
164
+
165
+ const auto & required_referrer_name = api_access_info.required_referrer ;
166
+ bool referrer_required = required_referrer_name != " " ? true : false ;
167
+
168
+ if ( !referrer_required && !registrar_required )
158
169
return true ;
159
170
160
- auto db = _app.chain_database ();
161
- const string account_registrar_name = acc.registrar (*db).name ;
162
- string account_original_registrar_name;
163
- if ( acc.original_registrar )
164
- account_original_registrar_name = (*acc.original_registrar )(*db).name ;
165
171
166
- bool has_required_registrar = required_registrar_name == account_registrar_name
167
- || required_registrar_name == account_original_registrar_name;
172
+ bool has_required_registrar = true ;
173
+ if ( registrar_required )
174
+ {
175
+ const string acc_registrar_name = acc.registrar (*db).name ;
176
+
177
+ string acc_original_registrar_name;
178
+ if ( acc.original_registrar )
179
+ acc_original_registrar_name = (*acc.original_registrar )(*db).name ;
180
+
181
+ has_required_registrar = required_registrar_name == acc_registrar_name
182
+ || required_registrar_name == acc_original_registrar_name;
183
+ }
184
+
185
+ bool has_required_referrer = true ;
186
+ if ( referrer_required )
187
+ {
188
+ const string acc_referrer_name = acc.referrer (*db).name ;
189
+
190
+ string acc_original_referrer_name;
191
+ if ( acc.original_referrer )
192
+ acc_original_referrer_name = (*acc.original_registrar )(*db).name ;
193
+
194
+ has_required_referrer = required_referrer_name == acc_referrer_name
195
+ || required_referrer_name == acc_original_referrer_name;
196
+ }
168
197
169
- return has_required_registrar;
198
+ return has_required_registrar && has_required_referrer ;
170
199
}
171
200
172
201
void login_api::enable_api ( const std::string& api_name )
0 commit comments