Draft: Replace old C code with current huacnlee/rucaptcha Rust code #4

Open
zero wants to merge 1 commit from gitlab-mr-iid-3 into master
Member

Ok before you say anything, I don't expect this to be merged but I wanna just put the alternative on record share some ideas I think are good.

This is based on the same project as the C code that was used in this Elixir library, but it is now Rust, however, the captchas the new code generates seems much stronger.
I just took the project, removed all the Ruby code I didn't need and made a main function to output the same thing as the old C code, in this repository.

I think the new captchas look much stronger and may be harder to crack than the current easy ones right out of the box.

  • Current captcha: curcaptcha1curcaptcha2
  • New captcha: newcaptcha1newcaptcha2

You may say requiring Rust seems like a showstopper because not every one uses captcha or has open registrations, and I would agree with that, however I propose an alternative:

  1. Fork my fork into this GitLab
  2. Setup CI to cross compile it to every supported platform
  3. Edit this library to check for the platform it's running on (x64, ARM, etc) and download the appropriate pre-compiled version from here (kinda like how the Pleroma OTP is downloaded), those should be stored with sha512 hashes or something and the list should updated manually ofc.
    I think the tricky part about this would be check for GNU LibC or MUSL. Maybe just try compile some code like this and check the return code from make or the compile, if it's not 0, it's MUSL?
#include <gnu/libc-version.h>
#include <stdio.h>
#include <unistd.h>

int main() {
    printf("%d.%d\n", __GLIBC__, __GLIBC_MINOR__);
    return 0;
}
  1. Keep the old C code around, if it's not a supported platform, fall back to it. This could mean you can't really increase the number of characters in the captcha, but surely this can be made configurable or detectable somehow? The output of both C and Rust can be changed to be more robust.

I'd also like to show another person had the same idea as me, and used a Go captcha library instead.
This is what his captchas look like: mintcaptcha1mintcaptcha2

The main takeaway here is that modifying the existing C code is way harder than it would be in either of those implementations, and they may also get improved/updated upstream and we could just use that, but custom code can also be added downstream much more easily.

Anyway, this is just an idea not a serious merge request, let me know if any of this makes sense.

Ok before you say anything, I don't expect this to be merged but I wanna just put the alternative on record share some ideas I think are good. This is based on the [same project](https://github.com/huacnlee/rucaptcha) as the C code that was used in this Elixir library, but it is now Rust, however, the captchas the new code generates seems much stronger. I just took the project, removed all the Ruby code I didn't need and made a main function to output the same thing as the old C code, in [this repository](https://github.com/animeavi/rucaptcha). I think the new captchas look much stronger and may be harder to crack than the current easy ones right out of the box. - Current captcha: ![curcaptcha1](/attachments/568792ac-0c9a-4782-b81f-4aaf61e2a048)![curcaptcha2](/attachments/62243aa5-d5a9-4b67-b3d4-0e1df7e52930) - New captcha: ![newcaptcha1](/attachments/b18922fd-8b12-40b2-b586-87c5adc02c7d)![newcaptcha2](/attachments/b826dbcc-6a6d-4856-817c-6c6425752f25) You may say requiring Rust seems like a showstopper because not every one uses captcha or has open registrations, and I would agree with that, however I propose an alternative: 1. Fork my fork into this GitLab 2. Setup CI to cross compile it to every supported platform 3. Edit this library to check for the platform it's running on (x64, ARM, etc) and download the appropriate pre-compiled version from here (kinda like how the Pleroma OTP is downloaded), those should be stored with sha512 hashes or something and the list should updated manually ofc. I think the tricky part about this would be check for GNU LibC or MUSL. Maybe just try compile some code like this and check the return code from make or the compile, if it's not 0, it's MUSL? ```c #include <gnu/libc-version.h> #include <stdio.h> #include <unistd.h> int main() { printf("%d.%d\n", __GLIBC__, __GLIBC_MINOR__); return 0; } ``` 4. Keep the old C code around, if it's not a supported platform, fall back to it. This could mean you can't really increase the number of characters in the captcha, but surely this can be made configurable or detectable somehow? The output of both C and Rust can be changed to be more robust. I'd also like to show another person had the same idea as me, and used [a Go captcha library instead](https://gitgud.io/mintplg/elixir-captcha/-/commits/go-captcha). This is what his captchas look like: ![mintcaptcha1](/attachments/ccbde4fd-91d0-41d5-a24e-6a7c278ba7bf)![mintcaptcha2](/attachments/75204a1b-a0d2-4d62-ae80-f43c8bc7a0fa) The main takeaway here is that modifying the existing C code is way harder than it would be in either of those implementations, and they may also get improved/updated upstream and we could just use that, but custom code can also be added downstream much more easily. Anyway, this is just an idea not a serious merge request, let me know if any of this makes sense.
Owner

I don't think Rust makes much sense as AFAIK none of the Pleroma devs have any experience programming in Rust (while C is pretty extensive) and personally as long as Rust doesn't fixes it's bootstrapping story and distro packaging support, I'd end up maintaining a non-Rust version anyway…

  1. I think the tricky part about this would be check for GNU LibC or MUSL. Maybe just try compile some code like this and check the return code from make or the compile, if it's not 0, it's MUSL?

Check https://docs.pleroma.social/backend/installation/otp_en/#detecting-flavour for a way to detect it through shell.
And #include <gnu/libc-version.h> wouldn't compile on anything non-glibc.

Go code could be a bit interesting but I'm not sure how maintainable the one you pointed at is, it seems to depend on a pretty large dependency.

I don't think Rust makes much sense as AFAIK none of the Pleroma devs have any experience programming in Rust (while C is pretty extensive) and personally as long as Rust doesn't fixes it's bootstrapping story and distro packaging support, I'd end up maintaining a non-Rust version anyway… > 1. I think the tricky part about this would be check for GNU LibC or MUSL. Maybe just try compile some code like this and check the return code from make or the compile, if it's not 0, it's MUSL? Check https://docs.pleroma.social/backend/installation/otp_en/#detecting-flavour for a way to detect it through shell. And `#include <gnu/libc-version.h>` wouldn't compile on anything non-glibc. Go code could be a bit interesting but I'm not sure how maintainable the one you pointed at is, it seems to depend on a pretty large dependency.
Author
Member

Yeah, like you said it doesn't make sense to add Rust code if nobody can work with it.
I looked for other C or C++ captcha libraries and saw CImg had one captcha example in the repository and it actually seems to be much stronger than either of those examples.
download download2 download3

I copied just the captcha code here to make it easier to work with. As you can see CImg.h can be just copied on its own, so it doesn't create a depedency.

It does depend on libpng currently, but both ffmpeg and ImageMagick install that, though they are optional installs in the current Pleroma install guide. The code can be easily changed to save as .bmp if you really don't want that dependency, just by replacing save_png to save_bmp.

I think this one is actually worth exploring, since it's C++.

Edit: I forgot to mention, I replaced the hardcoded captchas from the example with code I found here, it does use C++17 templates but compiles on as low as GCC 7.1 and Clang 5.0.0.
See: https://godbolt.org/z/Yz6hErrbP

Yeah, like you said it doesn't make sense to add Rust code if nobody can work with it. I looked for other C or C++ captcha libraries and saw [CImg](https://github.com/GreycLab/CImg) had one captcha example in the repository and it actually seems to be much stronger than either of those examples. ![download](/attachments/aaade7ca-c8fd-4c7e-97f7-bf37cba9d594) ![download2](/attachments/b4e14cb7-12d2-448b-a7be-24b4aa695988) ![download3](/attachments/9f9326a5-396b-4a1e-a578-1828d83ebd71) I copied just the captcha code [here](https://github.com/animeavi/cimg_captcha) to make it easier to work with. As you can see CImg.h can be just copied on its own, so it doesn't create a depedency. It does depend on libpng currently, but both ffmpeg and ImageMagick install that, though they are optional installs in the current Pleroma install guide. The code can be easily changed to save as .bmp if you really don't want that dependency, just by replacing `save_png` to `save_bmp`. I think this one is actually worth exploring, since it's C++. Edit: I forgot to mention, I replaced the hardcoded captchas from the example with code I found [here](https://stackoverflow.com/a/444614), it does use C++17 templates but compiles on as low as GCC 7.1 and Clang 5.0.0. See: https://godbolt.org/z/Yz6hErrbP
This pull request has changes conflicting with the target branch.
  • Makefile
  • mix.exs
  • src/captcha.c
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin gitlab-mr-iid-3:gitlab-mr-iid-3
git switch gitlab-mr-iid-3

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch master
git merge --no-ff gitlab-mr-iid-3
git switch gitlab-mr-iid-3
git rebase master
git switch master
git merge --ff-only gitlab-mr-iid-3
git switch gitlab-mr-iid-3
git rebase master
git switch master
git merge --no-ff gitlab-mr-iid-3
git switch master
git merge --squash gitlab-mr-iid-3
git switch master
git merge --ff-only gitlab-mr-iid-3
git switch master
git merge gitlab-mr-iid-3
git push origin master
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
pleroma-elixir-libraries/elixir-captcha!4
No description provided.