summaryrefslogtreecommitdiff
path: root/data.c
diff options
context:
space:
mode:
authorGravatar default2024-12-19 18:54:15 +0100
committerGravatar default2024-12-19 18:54:15 +0100
commit57a8716f72dd5c75c98ead085fbd8d7f12660da6 (patch)
tree745fd52496988f1625a22689870cb94b8f4ddec2 /data.c
parentPropagate FastCGI variable REMOTE_ADDR. (diff)
downloadpenes-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.c105
1 files changed, 105 insertions, 0 deletions
diff --git a/data.c b/data.c
index 74861b8..6394d1c 100644
--- a/data.c
+++ b/data.c
@@ -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
3828xs_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
3839int _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
3861int 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
3905void 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}