logo

New Response

« Return to the blog entry

You are replying to:

    • avatar
    • axel
    • Posted on Mon 5 Nov 2012 12:20 AM

    Hi,

    I found this interesting discussion, when I tried to help someone on our german notes forum to integrate the JCaptcha library.

    I've come up with a completly different proposal, which consists intackling the Jcaptcha-1.0.jar library with very dirty Java.

    In my own words I found out that it consists of 3 projects:

    project i: generates the captcha-image, the solution of the captcha challenge and an id controlled by the user of the library.

    project ii: stores captcha-image, the solution of the captcha challenge and the id in kind of a temporary storage and manages the access to this "database"

    project iii: integration for all sorts of java frameworks like servlets/jsp, spring, etc.

    Those parts are closely coupled. This coupling is intended by the authors of the library.

    From a Domino standpoint you only need project i. You just need the captcha and the solution of the challenge. You may store and manage the access to that data in Domino. Whereas project ii) and iii) complicate the usage of jcaptcha in Domino. Unfortunatedly the authors of JCaptcha restrict the access to the solution of the captcha with Java access modifiers.

    Now, you may

    a) patch JCaptcha-1.0.jar by rewriting 2 of the access modifiers deep inside the projects code and recompile/repackage.

    b) you may hack your way to the information by using Java reflection.

    The code below demonstrates the b) path. If someone stumbles into this thread, I hope that trying out the code gives some idea about what the the heck I am talking about.

    There may be other cases, when usage of one of the many Java open source libs may be easier by just analysing and if necesary even changing the open open source library itself.

    In a real world scenario I would patch the open source library and not go the reflection way. Anyway: The code gives the idea, which 2 access modifiers in jcaptcha-1.0-all.jar you have to change to break the coupling of project i with ii, iii and use project i in isolation.

    Anybody trying this out should put jcaptcha-1.0-all.jar, commons-collections-3.2.1.jar and commons-logging-1.1.1.jar into the class path (for example in an eclipse project).

    I posted this to add another aspect to an interesting and informed discussion and because I kind of like my solution.

    public class NewTest {

    private static String BASE_VERZEICHNIS_FUER_BILDER = "/Users/axeljanssen/";

    public static void main(String args[]) {

    String id = "1";

    DefaultManageableImageCaptchaService instance = new DefaultManageableImageCaptchaService();

    ByteArrayOutputStream imgOutputStream = new ByteArrayOutputStream();

    BufferedImage im = instance.getImageChallengeForID(id, Locale.GERMAN);

    BufferedOutputStream fous = null;

    try {

    Class clazz = instance.getClass().getSuperclass().getSuperclass()

    .getSuperclass();

    System.out.println(instance.getClass().getSuperclass()

    .getSuperclass().getSuperclass().getName());

    // for (Field field : clazz.getDeclaredFields()) {

    // System.out.println("field:" + field.getName() + ":" +

    // field.getClass().getName());

    // }

    Field firstDoor = clazz.getDeclaredField("store");

    firstDoor.setAccessible(true); // ha ha

    FastHashMapCaptchaStore firstDoorOpen = (FastHashMapCaptchaStore) firstDoor

    .get(instance);

    Gimpy gimpy = (Gimpy) firstDoorOpen.getCaptcha(id);

    Class <Gimpy>clazz2 = (Class<Gimpy>) gimpy.getClass();

    Field secondDoor = clazz2.getDeclaredField("response");

    secondDoor.setAccessible(true);

    String ratsAreDancingInThePantry = (String) secondDoor

    .get(gimpy);

    System.out.println("DER CAPTCHA TEXT IST:" + ratsAreDancingInThePantry);

    } catch (Exception e1) {

    e1.printStackTrace();

    System.out.println("ECHTER ALARM");

    }

    try {

    ImageIO.write(im, "png", imgOutputStream);

    byte[] captchaBytes = imgOutputStream.toByteArray();

    fous = new BufferedOutputStream(new FileOutputStream(

    BASE_VERZEICHNIS_FUER_BILDER + id + ".png"));

    System.out.println("Bild wurde gespeichert in:" + BASE_VERZEICHNIS_FUER_BILDER + id + ".png");

    fous.write(captchaBytes);

    fous.flush();

    } catch (IOException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    } finally {

    if (fous != null) {

    try {

    fous.close();

    } catch (IOException e) {

    // Exception verschlucken i.O. in tcftc Konstrukt.

    }

    }

    }

    }

    }

Your Comments

Name:
E-mail:
(optional)
Website:
(optional)
Comment: