@@ -111,22 +111,62 @@ static void delete_cached_crypto_keys(){
111111 psync_sql_statement ("DELETE FROM cryptofilekey" );
112112}
113113
114- static binresult * get_userinfo_user_digest (psync_socket * sock , const char * username , size_t userlen , const char * pwddig , const char * digest , uint32_t diglen ,
115- const char * device ){
114+ static binresult * login_with_digest (psync_socket * sock , const char * username , size_t userlen , const char * pwddig ,
115+ const char * digest , uint32_t diglen ,
116+ const char * device ) {
116117 binparam params []= {P_STR ("timeformat" , "timestamp" ),
117118 P_LSTR ("username" , username , userlen ),
118119 P_LSTR ("digest" , digest , diglen ),
119120 P_LSTR ("passworddigest" , pwddig , PSYNC_SHA1_DIGEST_HEXLEN ),
120121 P_STR ("device" , device ),
122+ P_STR ("deviceid" , device ),
121123 P_BOOL ("getauth" , 1 ),
122124 P_BOOL ("getapiserver" , 1 ),
123125 P_BOOL ("cryptokeyssign" , 1 ),
124126 P_NUM ("os" , P_OS_ID )};
125127 return send_command (sock , "login" , params );
126128}
127129
128- static binresult * get_userinfo_user_pass (psync_socket * sock , const char * username , const char * password , const char * device ){
129- binparam empty_params []= {P_STR ("MS" , "sucks" )};
130+ static binresult * get_userinfo_user_pass (psync_socket * sock , const char * username , const char * password ,
131+ const char * device ) {
132+ binparam params [] = {P_STR ("timeformat" , "timestamp" ),
133+ P_STR ("username" , username ),
134+ P_STR ("password" , password ),
135+ P_STR ("device" , device ),
136+ P_STR ("deviceid" , device ),
137+ P_BOOL ("getauth" , 1 ),
138+ P_BOOL ("cryptokeyssign" , 1 ),
139+ P_BOOL ("getapiserver" , 1 ),
140+ P_NUM ("os" , P_OS_ID )};
141+ return send_command (sock , "login" , params );
142+ }
143+
144+ static binresult * get_userinfo_auth (psync_socket * sock , const char * auth , const char * device ) {
145+ binparam params []= {P_STR ("timeformat" , "timestamp" ),
146+ P_STR ("auth" , auth ),
147+ P_STR ("device" , device ),
148+ P_STR ("deviceid" , device ),
149+ P_BOOL ("getauth" , 1 ),
150+ P_BOOL ("cryptokeyssign" , 1 ),
151+ P_BOOL ("getapiserver" , 1 ),
152+ P_NUM ("os" , P_OS_ID )};
153+ return send_command (sock , "userinfo" , params );
154+ }
155+
156+ static binresult * get_tfa_auth (psync_socket * sock , const char * token , const char * code , const char * device ) {
157+ binparam params []= {P_STR ("timeformat" , "timestamp" ),
158+ P_STR ("token" , token ),
159+ P_STR ("device" , device ),
160+ P_STR ("deviceid" , device ),
161+ P_NUM ("code" , atol (code )),
162+ P_BOOL ("trustdevice" , psync_setting_get_bool (_PS (trusted ))),
163+ P_NUM ("os" , P_OS_ID )};
164+ return send_command (sock , "tfa_login" , params );
165+ }
166+
167+ static binresult * get_userinfo_user_pass_digest (psync_socket * sock , const char * username , const char * password ,
168+ const char * device ){
169+ binparam empty_params []= {P_STR ("NO_PARAM" , "empty" )};
130170 psync_sha1_ctx ctx ;
131171 binresult * res , * ret ;
132172 const binresult * dig ;
@@ -156,23 +196,23 @@ static binresult *get_userinfo_user_pass(psync_socket *sock, const char *usernam
156196 psync_sha1_update (& ctx , dig -> str , dig -> length );
157197 psync_sha1_final (sha1bin , & ctx );
158198 psync_binhex (sha1hex , sha1bin , PSYNC_SHA1_DIGEST_LEN );
159- ret = get_userinfo_user_digest (sock , username , ul , sha1hex , dig -> str , dig -> length , device );
199+ ret = login_with_digest (sock , username , ul , sha1hex , dig -> str , dig -> length , device );
160200 psync_free (res );
161201 return ret ;
162202}
163203
164204static psync_socket * get_connected_socket (){
165- char * auth , * user , * pass ;
205+ char * auth , * user , * pass , * tfa_pin , * tfa_token , * device ;
166206 psync_socket * sock ;
167207 binresult * res ;
168208 const binresult * cres ;
169209 psync_sql_res * q ;
170- char * device ;
171210 uint64_t result , userid , luserid ;
172211 int saveauth , isbusiness , cryptosetup ;
173- auth = user = pass = NULL ;
212+ auth = user = pass = tfa_pin = tfa_token = NULL ;
174213 psync_is_business = 0 ;
175214 int digest = 1 ;
215+ int auth_reset = 0 ;
176216 while (1 ){
177217 psync_free (auth );
178218 psync_free (user );
@@ -202,30 +242,16 @@ static psync_socket *get_connected_socket(){
202242 }
203243 device = psync_deviceid ();
204244
205- if (user && pass && pass [0 ])
206- if (digest )
245+ if (tfa_token && tfa_pin ) {
246+ res = get_tfa_auth (sock , tfa_token , tfa_pin , device );
247+ } else if ((!auth || auth_reset ) && user && pass && pass [0 ]) {
248+ if (digest ) {
249+ res = get_userinfo_user_pass_digest (sock , user , pass , device );
250+ } else {
207251 res = get_userinfo_user_pass (sock , user , pass , device );
208- else
209- {
210- binparam params []= {P_STR ("timeformat" , "timestamp" ),
211- P_STR ("username" , user ),
212- P_STR ("password" , pass ),
213- P_STR ("device" , device ),
214- P_BOOL ("getauth" , 1 ),
215- P_BOOL ("cryptokeyssign" , 1 ),
216- P_BOOL ("getapiserver" , 1 ),
217- P_NUM ("os" , P_OS_ID )};
218- res = send_command (sock , "login" , params );
219252 }
220- else {
221- binparam params []= {P_STR ("timeformat" , "timestamp" ),
222- P_STR ("auth" , auth ),
223- P_STR ("device" , device ),
224- P_BOOL ("getauth" , 1 ),
225- P_BOOL ("cryptokeyssign" , 1 ),
226- P_BOOL ("getapiserver" , 1 ),
227- P_NUM ("os" , P_OS_ID )};
228- res = send_command (sock , "userinfo" , params );
253+ } else {
254+ res = get_userinfo_auth (sock , auth , device );
229255 }
230256 psync_free (device );
231257 if (unlikely_log (!res )){
@@ -240,33 +266,48 @@ static psync_socket *get_connected_socket(){
240266 if (unlikely (result )){
241267 debug (D_NOTICE , "userinfo returned error %lu %s" , (unsigned long )result , psync_find_result (res , "error" , PARAM_STR )-> str );
242268 psync_socket_close (sock );
243- psync_free (res );
244- if (result == 2000 ){
245- if (user && pass )
269+ if (result == 2000 ) {
270+ if (user && pass ) {
246271 psync_set_status (PSTATUS_TYPE_AUTH , PSTATUS_AUTH_BADLOGIN );
247- else
272+ } else {
248273 psync_set_status (PSTATUS_TYPE_AUTH , PSTATUS_AUTH_BADTOKEN );
274+ }
249275 psync_wait_status (PSTATUS_TYPE_AUTH , PSTATUS_AUTH_PROVIDED );
250- }
251- else if ( result == 4000 )
252- psync_milisleep ( 5 * 60 * 1000 );
253- else if ( result == 2297 ){
276+ } else if ( result == 4000 ) {
277+ psync_milisleep ( 5 * 60 * 1000 );
278+ } else if ( result == 2297 ) {
279+ tfa_token = psync_strdup ( psync_find_result ( res , "token" , PARAM_STR ) -> str );
254280 psync_set_status (PSTATUS_TYPE_AUTH , PSTATUS_AUTH_TFAERR );
255281 psync_wait_status (PSTATUS_TYPE_AUTH , PSTATUS_AUTH_PROVIDED );
256- }
257- else if (result == 2205 || result == 2229 ){
282+ tfa_pin = psync_strdup (psync_my_tfa_pin );
283+ debug (D_NOTICE , "provided token from console: %s" , tfa_pin );
284+ } else if (result == 2064 ) { //Expired 'token'.
285+ debug (D_NOTICE , "expired tfa token" );
286+ psync_free (tfa_token );
287+ psync_free (tfa_pin );
288+ } else if (result == 2012 ) { //"Invalid 'code' provided."
289+ debug (D_NOTICE , "invalid tfa pin" );
290+ psync_free (tfa_pin );
291+ psync_set_status (PSTATUS_TYPE_AUTH , PSTATUS_AUTH_TFAERR );
292+ psync_wait_status (PSTATUS_TYPE_AUTH , PSTATUS_AUTH_PROVIDED );
293+ tfa_pin = psync_strdup (psync_my_tfa_pin );
294+ debug (D_NOTICE , "provided token from console: %s" , tfa_pin );
295+ } else if (result == 2205 || result == 2229 ) {
296+ auth_reset = 1 ;
258297 psync_set_status (PSTATUS_TYPE_AUTH , PSTATUS_AUTH_EXPIRED );
259298 psync_wait_status (PSTATUS_TYPE_AUTH , PSTATUS_AUTH_PROVIDED );
260- } else if (result == 2237 )
261- {
262- digest = 0 ;
299+ } else if (result == 2237 ) {
300+ digest = 0 ;
263301 continue ;
264- }
265-
266- else
302+ } else {
267303 psync_milisleep (PSYNC_SLEEP_BEFORE_RECONNECT );
304+ }
305+ psync_free (res );
268306 continue ;
269307 }
308+ psync_free (tfa_pin );
309+ psync_free (tfa_token );
310+ auth_reset = 0 ;
270311 psync_my_userid = userid = psync_find_result (res , "userid" , PARAM_NUM )-> num ;
271312 current_quota = psync_find_result (res , "quota" , PARAM_NUM )-> num ;
272313 luserid = psync_sql_cellint ("SELECT value FROM setting WHERE id='userid'" , 0 );
0 commit comments