验证中非ASCII的用户名或密码的问题

实际的环境中,有些用户使用了非ASCII码的用户名或者密码,这里引发了两个问题:

  • 在非NLA验证中,如果没有把这些字符串正常的转换成Unicode并发送出去,会导致在RDP协议验证过程中失败。因为是在Javascript端做的这个事情,所以要格外注意这一点。Javascript使用的是UTF-16 (也就是Windows里所谓的Unicode)。这种情况下,要注意区分 String.prototype.charCodeAt() 获取到的值是 ASCII 范围内的,还是超出这个范围的,以组成正确的Windows可读的Unicode的字符串。
    示例:
function rdp_write_unicode_string(stream, string, len) {
    var j=0, i=0;
    while(i < len) {
        var code = string.charCodeAt(j++);
        if (code > 256)  {
            code &= 0xffff;
            stream.data[stream.p+i] = code & 0xff;
            i++;
            stream.data[stream.p+i] = (code>>8) & 0xff;
            i++;
        }
        else {
            stream.data[stream.p+i] = code;
            i++;
            stream.data[stream.p+i] = 0;
            i++;
        }
    }
    stream.data[stream.p+i] = 0;
    i++;
    stream.data[stream.p+i] = 0;
    i++;
    stream.p += len + 2;
}
  • 还有一种是NLA验证,这种情况下有可能引起问题的是CharUpperW这个类型的函数。因为在NLA验证中,协议要求(可能如此,根据现有的开源代码进行的推断)把用户名和密码转换成全大写的字符串。问题在于,在非Windows系统中想要做到这点(支持非ASCII码)是比较困难的。FreeRDP中有个关于这个的Issue。最后能找到的解决方案实际上是从Wine这个项目中得到的。在非Windows系统中想要做到CharUpperW,需要使用Wine的相同的功能的函数。并且,需要引入一个自动生成的Map,Map文件的位置是casemap.c。 对于只关心转化到大写的人来说,只要引入wine_casemap_upper 这个Map就可以了。

你可能感兴趣的:(验证中非ASCII的用户名或密码的问题)