@@ -920,65 +920,80 @@ bool mg_rpc_check_digest_auth(struct mg_rpc_request_info *ri) {
920
920
}
921
921
922
922
#ifdef MGOS_HAVE_MONGOOSE
923
- if (ri -> auth .len > 0 ) {
924
- struct json_token trealm = JSON_INVALID_TOKEN ,
925
- tusername = JSON_INVALID_TOKEN ,
926
- tnonce = JSON_INVALID_TOKEN , tcnonce = JSON_INVALID_TOKEN ,
927
- tresponse = JSON_INVALID_TOKEN ;
928
-
929
- if (json_scanf (ri -> auth .p , ri -> auth .len ,
930
- "{realm: %T username %T nonce:%T cnonce:%T response:%T}" ,
931
- & trealm , & tusername , & tnonce , & tcnonce , & tresponse ) == 5 ) {
932
- struct mg_str realm = mg_mk_str_n (trealm .ptr , trealm .len );
933
- struct mg_str username = mg_mk_str_n (tusername .ptr , tusername .len );
934
- struct mg_str nonce = mg_mk_str_n (tnonce .ptr , tnonce .len );
935
- struct mg_str cnonce = mg_mk_str_n (tcnonce .ptr , tcnonce .len );
936
- struct mg_str response = mg_mk_str_n (tresponse .ptr , tresponse .len );
937
-
938
- LOG (LL_DEBUG , ("Got auth: Realm:%.*s, Username:%.*s, Nonce: %.*s, "
939
- "CNonce:%.*s, Response:%.*s" ,
940
- (int ) realm .len , realm .p , (int ) username .len , username .p ,
941
- (int ) nonce .len , nonce .p , (int ) cnonce .len , cnonce .p ,
942
- (int ) response .len , response .p ));
943
-
944
- if (mg_vcmp (& realm , mgos_sys_config_get_rpc_auth_domain ()) != 0 ) {
945
- LOG (LL_WARN ,
946
- ("Got auth request with different realm: expected: "
947
- "\"%s\", got: \"%.*s\"" ,
948
- mgos_sys_config_get_rpc_auth_domain (), (int ) realm .len , realm .p ));
949
- } else {
950
- FILE * htdigest_fp = fopen (mgos_sys_config_get_rpc_auth_file (), "r" );
951
-
952
- if (htdigest_fp == NULL ) {
953
- mg_rpc_send_errorf (ri , 500 , "failed to open htdigest file" );
954
- ri = NULL ;
955
- return false;
956
- }
957
-
958
- /*
959
- * TODO(dfrank): add method to the struct mg_rpc_request_info and use
960
- * it as either method or uri
961
- */
962
- int authenticated = mg_check_digest_auth (
963
- mg_mk_str ("dummy_method" ), mg_mk_str ("dummy_uri" ), username , cnonce ,
964
- response , mg_mk_str ("auth" ), mg_mk_str ("1" ), nonce , realm ,
965
- htdigest_fp );
966
-
967
- fclose (htdigest_fp );
968
-
969
- if (authenticated ) {
970
- LOG (LL_DEBUG , ("Auth ok" ));
971
- ri -> authn_info .username = mg_strdup (username );
972
- return true;
973
- } else {
974
- LOG (LL_WARN , ("Invalid digest auth for user %.*s" , (int ) username .len ,
975
- username .p ));
976
- }
977
- }
923
+ if (ri -> auth .len == 0 ) {
924
+ /* No auth info in the frame, it's not an error. */
925
+ return true;
926
+ }
927
+ enum mg_auth_algo algo = MG_AUTH_ALGO_MD5 ;
928
+ struct json_token trealm = JSON_INVALID_TOKEN , tusername = JSON_INVALID_TOKEN ,
929
+ tnonce = JSON_INVALID_TOKEN , tcnonce = JSON_INVALID_TOKEN ,
930
+ tresponse = JSON_INVALID_TOKEN , talgo = JSON_INVALID_TOKEN ;
931
+ json_scanf (
932
+ ri -> auth .p , ri -> auth .len ,
933
+ "{realm: %T username %T nonce:%T cnonce:%T response:%T algorithm:%T}" ,
934
+ & trealm , & tusername , & tnonce , & tcnonce , & tresponse , & talgo );
935
+ struct mg_str realm = mg_mk_str_n (trealm .ptr , trealm .len );
936
+ struct mg_str username = mg_mk_str_n (tusername .ptr , tusername .len );
937
+ struct mg_str nonce = mg_mk_str_n (tnonce .ptr , tnonce .len );
938
+ struct mg_str cnonce = mg_mk_str_n (tcnonce .ptr , tcnonce .len );
939
+ struct mg_str response = mg_mk_str_n (tresponse .ptr , tresponse .len );
940
+ struct mg_str algorithm = mg_mk_str_n (talgo .ptr , talgo .len );
941
+ if (realm .len == 0 || username .len == 0 || nonce .len == 0 ||
942
+ cnonce .len == 0 || response .len == 0 ) {
943
+ /* Incomplete auth info is an error. */
944
+ return false;
945
+ }
946
+ if (algorithm .len > 0 ) {
947
+ if (mg_vcmp (& algorithm , "MD5" ) == 0 ) {
948
+ algo = MG_AUTH_ALGO_MD5 ;
949
+ } else if (mg_vcmp (& algorithm , "SHA-256" ) == 0 ) {
950
+ algo = MG_AUTH_ALGO_SHA256 ;
978
951
} else {
979
- LOG (LL_WARN , ("Not all auth parts are present, ignoring" ));
952
+ LOG (LL_ERROR ,
953
+ ("Unknown auth algo '%.*s'" , (int ) algorithm .len , algorithm .p ));
954
+ return false;
980
955
}
981
956
}
957
+ LOG (LL_DEBUG , ("Got auth: Realm:%.*s, Username:%.*s, Nonce: %.*s, "
958
+ "CNonce:%.*s, Response:%.*s Algo:%d" ,
959
+ (int ) realm .len , realm .p , (int ) username .len , username .p ,
960
+ (int ) nonce .len , nonce .p , (int ) cnonce .len , cnonce .p ,
961
+ (int ) response .len , response .p , algo ));
962
+ if ((int ) algo != mgos_sys_config_get_rpc_auth_algo ()) {
963
+ LOG (LL_ERROR , ("Auth algo mismatch: %d vs %d" , algo ,
964
+ mgos_sys_config_get_rpc_auth_algo ()));
965
+ return false;
966
+ }
967
+
968
+ if (mg_vcmp (& realm , mgos_sys_config_get_rpc_auth_domain ()) != 0 ) {
969
+ LOG (LL_WARN ,
970
+ ("Got auth request with different realm: expected: "
971
+ "\"%s\", got: \"%.*s\"" ,
972
+ mgos_sys_config_get_rpc_auth_domain (), (int ) realm .len , realm .p ));
973
+ return false;
974
+ }
975
+
976
+ FILE * htdigest_fp = fopen (mgos_sys_config_get_rpc_auth_file (), "r" );
977
+ if (htdigest_fp == NULL ) {
978
+ mg_rpc_send_errorf (ri , 500 , "failed to open password file" );
979
+ ri = NULL ;
980
+ return false;
981
+ }
982
+
983
+ int authenticated = mg_check_digest_auth_algo (
984
+ mg_mk_str ("dummy_method" ), mg_mk_str ("dummy_uri" ), username , cnonce ,
985
+ response , mg_mk_str ("auth" ), mg_mk_str ("1" ), nonce , realm , algo ,
986
+ htdigest_fp );
987
+
988
+ fclose (htdigest_fp );
989
+
990
+ if (authenticated ) {
991
+ LOG (LL_DEBUG , ("Auth ok, user %.*s" , (int ) username .len , username .p ));
992
+ ri -> authn_info .username = mg_strdup (username );
993
+ } else {
994
+ LOG (LL_WARN ,
995
+ ("Invalid digest auth for user %.*s" , (int ) username .len , username .p ));
996
+ }
982
997
#endif /* MGOS_HAVE_MONGOOSE */
983
998
984
999
/*
0 commit comments