1###############################################################################
2# Decoder.pm                                                                  #
3# $Date: 12.02.14 $                                                           #
4###############################################################################
5# YaBB: Yet another Bulletin Board                                            #
6# Open-Source Community Software for Webmasters                               #
7# Version:        YaBB 2.6.11                                                 #
8# Packaged:       December 2, 2014                                            #
9# Distributed by: http://www.yabbforum.com                                    #
10# =========================================================================== #
11# Copyright (c) 2000-2014 YaBB (www.yabbforum.com) - All Rights Reserved.     #
12# Software by:  The YaBB Development Team                                     #
13#               with assistance from the YaBB community.                      #
14###############################################################################
15our $VERSION = '2.6.11';
16
17$decoderpmver = 'YaBB 2.6.11 $Revision: 1611 $';
18if ( $action eq 'detailedversion' ) { return 1; }
19
20sub scramble {
21    my ( $input, $user ) = @_;
22    if ( $user eq q{} ) { return; }
23
24    # creating a codekey based on userid
25    my $carrier = q{};
26    for my $n ( 0 .. length $user ) {
27        my $ascii = substr $user, $n, 1;
28        $ascii = ord $ascii;
29        $carrier .= $ascii;
30    }
31    while ( length($carrier) < length $input ) { $carrier .= $carrier; }
32    $carrier = substr $carrier, 0, length $input;
33    my $scramble = encode_password( rand 100 );
34    for my $n ( 0 .. 9 ) {
35        $scramble .= encode_password($scramble);
36    }
37    $scramble =~ s/\//y/gxsm;
38    $scramble =~ s/\+/x/gxsm;
39    $scramble =~ s/\-/Z/gxsm;
40    $scramble =~ s/\:/Q/gxsm;
41
42    # making a mess of the input
43    my $lastvalue = 3;
44    for my $n ( 0 .. length $input ) {
45        $value = ( substr $carrier, $n, 1 ) + $lastvalue + 1;
46        $lastvalue = $value;
47        substr( $scramble, $value, 1 ) = substr $input, $n, 1;
48    }
49
50    # adding code length to code
51    my $len = length($input) + 65;
52    $scramble .= chr $len;
53    return $scramble;
54}
55
56sub descramble {
57    my ( $input, $user ) = @_;
58    if ( $user eq q{} ) { return; }
59
60    # creating a codekey based on userid
61    my $carrier = q{};
62    for my $n ( 0 .. ( length($user) - 1 ) ) {
63        my $ascii = substr $user, $n, 1;
64        $ascii = ord $ascii;
65        $carrier .= $ascii;
66    }
67    my $orgcode = substr $input, length($input) - 1, 1;
68    my $orglength = ord $orgcode;
69
70    while ( length($carrier) < ( $orglength - 65 ) ) { $carrier .= $carrier; }
71    $carrier = substr $carrier, 0, length $input;
72
73    my $lastvalue  = 3;
74    my $descramble = q{};
75
76    # getting code length from encrypted input
77    for my $n ( 0 .. ( $orglength - 66 ) ) {
78        my $value = ( substr $carrier, $n, 1 ) + $lastvalue + 1;
79        $lastvalue = $value;
80        $descramble .= substr $input, $value, 1;
81    }
82    return $descramble;
83}
84
85sub validation_check {
86    my ($checkcode) = @_;
87    if ( $checkcode eq q{} ) { fatal_error('no_verification_code'); }
88    if ( $checkcode !~ /\A[0-9A-Za-z]+\Z/xsm ) {
89        fatal_error('invalid_verification_code');
90    }
91    if ( testcaptcha( $FORM{'sessionid'} ) ne $checkcode ) {
92        fatal_error('wrong_verification_code');
93    }
94    return;
95}
96
97sub validation_code {
98
99    # set the max length of the shown verification code
100    my ( $firstCharsLen, $lastCharsLen );
101    if ($captchaStartChars) { $firstCharsLen = length $captchaStartChars; }
102    if ($captchaEndChars)   { $lastCharsLen  = length $captchaEndChars; }
103    if ( $captchaStartChars && $captchaEndChars ) {
104        $flood_text =
105qq~$floodtxt{'casewarning_1'}$floodtxt{'casewarning_2'} $firstCharsLen $floodtxt{'casewarning_4'} $lastCharsLen $floodtxt{'casewarning_5'}~;
106    }
107    elsif ($captchaStartChars) {
108        $flood_text =
109qq~$floodtxt{'casewarning_1'}$floodtxt{'casewarning_2'} $firstCharsLen $floodtxt{'casewarning_5'}~;
110    }
111    elsif ($captchaEndChars) {
112        $flood_text =
113qq~$floodtxt{'casewarning_1'}$floodtxt{'casewarning_3'} $lastCharsLen $floodtxt{'casewarning_5'}~;
114    }
115    else {
116        $flood_text = qq~$floodtxt{'casewarning'}~;
117    }
118    if ( !$codemaxchars || $codemaxchars < 3 ) { $codemaxchars = 3; }
119    $codemaxchars2 = $codemaxchars + int rand 2;
120    ## Generate a random string
121    $captcha = keygen( $codemaxchars2, $captchastyle );
122    ## now we are going to spice the captcha with the formsession
123    $sessionid = scramble( $captcha, $masterkey );
124    chomp $sessionid;
125
126    $showcheck .=
127qq~<img src="$scripturl?action=$randaction;$randaction=$sessionid" alt="" /><input type="hidden" name="sessionid" value="$sessionid" />~;
128    return $sessionid;
129}
130
131sub testcaptcha {
132    my ($testcode) = @_;
133    chomp $testcode;
134    ## now it is time to decode the session and see if we have a valid code ##
135    my $out = descramble( $testcode, $masterkey );
136    chomp $out;
137    return $out;
138}
139
140sub convert {
141    require Sources::Captcha;
142    my ( $startChars, $endChars );
143    if ($captchaStartChars) { $startChars = $captchaStartChars; }
144    if ($captchaEndChars)   { $endChars   = $captchaEndChars; }
145    $captcha = testcaptcha( $INFO{$randaction} );
146    captcha( $startChars . $captcha . $endChars );
147    return;
148}
149
1501;
151