0

I'm currently trying to port the password scrambling algorithm of NX from QT-C++ to C#.

Source: http://www.nomachine.com/ar/view.php?ar_id=AR01C00125

My current Code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace mynamespace
{
class NxScramble
{
    string ToScramble = "";
    int numValidCharList = 85;
    String dummyString = "{{{{";

    char[] validCharList = new char[]
    {
      '!',  '#',  '$',  '%',  '&',  '(', ')',  '*',  '+',  '-',
      '.',  '0',   '1',  '2',   '3',  '4',  '5',  '6', '7', '8',
      '9', ':',  ';',  '<',  '>',  '?',  '@',  'A',  'B', 'C',
      'D',  'E',  'F',  'G',  'H',  'I',  'J',  'K',  'L', 'M',
      'N', 'O',  'P',  'Q',  'R',  'S',  'T', 'U', 'V', 'W',
      'X',  'Y',  'Z',  '[', ']',  '_',  'a',  'b',  'c',  'd',
      'e',  'f',  'g',  'h',  'i',  'j',  'k',  'l',  'm',  'n',
      'o',  'p',  'q',  'r',  's',  't',  'u',  'v',  'w',  'x',
      'y',  'z',  '{',  '|',  '}'
    };

    public NxScramble(string s)
    {
        ToScramble = s;
    }

    public string scrambleString()
    {
        string sRet = "";

        if (ToScramble == null || ToScramble.Equals(""))
        {
            return ToScramble;
        }

        string str = encodePassword(ToScramble);

        if (str.Length < 32)
        {
            str += dummyString;
        }

        for (int iR = (str.Length - 1); iR >= 0; iR--)
        {
            //
            // Reverse string
            //
            sRet += str.ElementAt(iR);
        }

        if (sRet.Length < 32)
        {
            sRet += dummyString;
        }

        int k = getRandomValidCharFromList();
        int l = k + sRet.Length - 2;

        sRet.Insert(0, k.ToString());

        string retStr = "";

        for (int i1 = 1; i1 < sRet.Length; i1++)
        {
            int j = findCharInList(sRet.ElementAt(i1));

            if (j == -1)
            {
                return ToScramble;
            }
            int i = (j + l * (i1 + 1)) % validCharList.Length;
            /*
             * sRet.ref(i1) = validCharList[i];
             */
            retStr += validCharList[i];
        }

        char c = (char)(getRandomValidCharFromList() + 2);
        sRet += c;

        retStr = retStr.Replace("&", @"&amp;");
        retStr = retStr.Replace("\"", @"&quot;");
        retStr = retStr.Replace("'", @"&apos;");
        retStr = retStr.Replace("<", @"&lt;");
        retStr = retStr.Replace(">", @"&gt;");

        return retStr;
    }

    private string encodePassword(string p)
    {
        string sPass = ":";
        string sTmp = "";

        if (p.Equals(""))
        {
            return "";
        }

        for (int i = 0; i < p.Length; i++)
        {
            char c = (char)p.ElementAt(i);
            sTmp = String.Format("{0:d}:", (c + i + 1));
            sPass += sTmp;
            sTmp = "";
        }

        return sPass;
    }

    private int findCharInList(char c)
    {
        int i = -1;

        for (int j = 0; j < numValidCharList; j++)
        {
            if (validCharList[j] == c)
            {
                i = j;
                return i;
            }
        }
        return i;
    }

    private char getRandomValidCharFromList()
    {
        int k = DateTime.Now.Second;
        return validCharList[k];
    }

}
}

It's generates a string from the given password and I add it to the XML-Config file of the nxclient:

        NxScramble nxs = new NxScramble(passPhrase);
        string ScambledPass = nxs.scrambleString();

        string nxconfig = @"
        ....
        ....
        <group name='Login' >
        <option key='Auth' value='"+ ScambledPass + @"' />
        <option key='Guest Mode' value='false' />
        <option key='Guest password' value='' />
        <option key='Guest username' value='' />
        <option key='Login Method' value='nx' />
        <option key='Public Key' value='
        .........
        .........
        ' />
        <option key='User' value='" + username + @"' />
        </group>
        ";

But the NXClient keeps saying "Authentication failed". So I'm quite sure there must be a mistake in my C#-Port of the C++ code. Especially I'm not sure about this line of the original code: sRet.ref(i1) = validCharList[i];

I have no idea what ref(i1) is doing.

Would be nice if someone discovers my mistake :)

Thanks in advance

user1646933
  • 97
  • 2
  • 6

1 Answers1

0

The upper code part of scrambleString() does initialize and work on sRet, and the lower part on retStr which at last is returned making the work on sRet not used at all. You should probably combine retStr/sRet, maybe just use one string...

sRet.ref(i1) = validCharList[i]

The above code is just a simple char assignment, replacing char at pos i1 in sRet with char from string validCharList at pos i.

Mysticial
  • 464,885
  • 45
  • 335
  • 332
ThinLinc
  • 1
  • 1