diff options
| author | 2024-12-19 18:54:15 +0100 | |
|---|---|---|
| committer | 2024-12-19 18:54:15 +0100 | |
| commit | 57a8716f72dd5c75c98ead085fbd8d7f12660da6 (patch) | |
| tree | 745fd52496988f1625a22689870cb94b8f4ddec2 /data.c | |
| parent | Propagate FastCGI variable REMOTE_ADDR. (diff) | |
| download | penes-snac2-57a8716f72dd5c75c98ead085fbd8d7f12660da6.tar.gz penes-snac2-57a8716f72dd5c75c98ead085fbd8d7f12660da6.tar.xz penes-snac2-57a8716f72dd5c75c98ead085fbd8d7f12660da6.zip | |
Added bad login throttling.
Diffstat (limited to 'data.c')
| -rw-r--r-- | data.c | 105 |
1 files changed, 105 insertions, 0 deletions
| @@ -3821,3 +3821,108 @@ xs_str *make_url(const char *href, const char *proxy, int by_token) | |||
| 3821 | 3821 | ||
| 3822 | return url; | 3822 | return url; |
| 3823 | } | 3823 | } |
| 3824 | |||
| 3825 | |||
| 3826 | /** bad login throttle **/ | ||
| 3827 | |||
| 3828 | xs_str *_badlogin_fn(const char *addr) | ||
| 3829 | { | ||
| 3830 | xs *md5 = xs_md5_hex(addr, strlen(addr)); | ||
| 3831 | xs *dir = xs_fmt("%s/badlogin", srv_basedir); | ||
| 3832 | |||
| 3833 | mkdirx(dir); | ||
| 3834 | |||
| 3835 | return xs_fmt("%s/%s", dir, md5); | ||
| 3836 | } | ||
| 3837 | |||
| 3838 | |||
| 3839 | int _badlogin_read(const char *fn, int *failures) | ||
| 3840 | /* reads a badlogin file */ | ||
| 3841 | { | ||
| 3842 | int ok = 0; | ||
| 3843 | FILE *f; | ||
| 3844 | |||
| 3845 | pthread_mutex_lock(&data_mutex); | ||
| 3846 | |||
| 3847 | if ((f = fopen(fn, "r")) != NULL) { | ||
| 3848 | xs *l = xs_readline(f); | ||
| 3849 | fclose(f); | ||
| 3850 | |||
| 3851 | if (sscanf(l, "%d", failures) == 1) | ||
| 3852 | ok = 1; | ||
| 3853 | } | ||
| 3854 | |||
| 3855 | pthread_mutex_unlock(&data_mutex); | ||
| 3856 | |||
| 3857 | return ok; | ||
| 3858 | } | ||
| 3859 | |||
| 3860 | |||
| 3861 | int badlogin_check(const char *user, const char *addr) | ||
| 3862 | /* checks if this address is authorized to try a login */ | ||
| 3863 | { | ||
| 3864 | int valid = 1; | ||
| 3865 | |||
| 3866 | if (xs_type(addr) == XSTYPE_STRING) { | ||
| 3867 | xs *fn = _badlogin_fn(addr); | ||
| 3868 | double mt = mtime(fn); | ||
| 3869 | |||
| 3870 | if (mt > 0) { | ||
| 3871 | int badlogin_expire = xs_number_get(xs_dict_get_def(srv_config, | ||
| 3872 | "badlogin_expire", "300")); | ||
| 3873 | |||
| 3874 | mt += badlogin_expire; | ||
| 3875 | |||
| 3876 | /* if file is expired, delete and give pass */ | ||
| 3877 | if (mt < time(NULL)) { | ||
| 3878 | srv_debug(1, xs_fmt("Login from %s for %s allowed again", addr, user)); | ||
| 3879 | unlink(fn); | ||
| 3880 | } | ||
| 3881 | else { | ||
| 3882 | int failures; | ||
| 3883 | |||
| 3884 | if (_badlogin_read(fn, &failures)) { | ||
| 3885 | int badlogin_max = xs_number_get(xs_dict_get_def(srv_config, | ||
| 3886 | "badlogin_retries", "5")); | ||
| 3887 | |||
| 3888 | if (failures >= badlogin_max) { | ||
| 3889 | valid = 0; | ||
| 3890 | |||
| 3891 | xs *d = xs_str_iso_date((time_t) mt); | ||
| 3892 | |||
| 3893 | srv_debug(1, | ||
| 3894 | xs_fmt("Login from %s for %s forbidden until %s", addr, user, d)); | ||
| 3895 | } | ||
| 3896 | } | ||
| 3897 | } | ||
| 3898 | } | ||
| 3899 | } | ||
| 3900 | |||
| 3901 | return valid; | ||
| 3902 | } | ||
| 3903 | |||
| 3904 | |||
| 3905 | void badlogin_inc(const char *user, const char *addr) | ||
| 3906 | /* increments a bad login from this address */ | ||
| 3907 | { | ||
| 3908 | if (xs_type(addr) == XSTYPE_STRING) { | ||
| 3909 | int failures = 0; | ||
| 3910 | xs *fn = _badlogin_fn(addr); | ||
| 3911 | FILE *f; | ||
| 3912 | |||
| 3913 | _badlogin_read(fn, &failures); | ||
| 3914 | |||
| 3915 | pthread_mutex_lock(&data_mutex); | ||
| 3916 | |||
| 3917 | if ((f = fopen(fn, "w")) != NULL) { | ||
| 3918 | failures++; | ||
| 3919 | |||
| 3920 | fprintf(f, "%d %s %s\n", failures, addr, user); | ||
| 3921 | fclose(f); | ||
| 3922 | |||
| 3923 | srv_log(xs_fmt("Registered %d login failure(s) from %s for %s", failures, addr, user)); | ||
| 3924 | } | ||
| 3925 | |||
| 3926 | pthread_mutex_unlock(&data_mutex); | ||
| 3927 | } | ||
| 3928 | } | ||