有没有办法在 PAM conv 函数中传递 unicode 符号?

Is there a way to pass unicode symbols in the PAM conv function?

我正在创建一个 PAM 模块来向尝试通过 SSH 登录系统的用户显示二维码,以允许他们扫描它并在 phone 上使用生物识别技术进行身份验证。有没有办法将 unicode 字符传递到 PAM conv 函数以允许应用程序将它们显示给用户?

我需要输入unicode字符的原因是因为我想使用uincode字符█(U+2588 Full Block)作为将QR码打印到屏幕的方式。

我已经尝试使用类型 wchar_t 来提交值,也只是尝试将其作为 char 提交,但最终都将缺少的字符问号打印到屏幕上。

如果这不可能,是否有办法在身份验证之前显示二维码,或者常规文本是否是唯一可能显示的内容?

来自 PAM 源的 Pam 转换结构:

struct pam_conv { 
    int (*conv)(int num_msg, const struct pam_message **msg,
        struct pam_response **resp, void *appdata_ptr);
    void *appdata_ptr;
};

编辑 (31/10/21):我已经尝试过将编码作为 UTF8 编码的建议,我相信这样做是这样的:\u[unicode char code]。这产生了以下编译器警告:

src/pam-qr.c:118:58: warning: multi-character character constant [-Wmultichar]
  118 |             row[x] = qrcodegen_getModule(qrcode, x, y) ? '\u2588' : ' ';

和这个输出:

0000000 0  000 00 0000000423O7
0     0      0  0 0     0423O7
0 000 0  00 0  00 0 000 0423O7
0 000 0 0    0 00 0 000 0423O7
0 000 0 00    000 0 000 0423O7
0     0 0         0     0423O7
0000000 0 0 0 0 0 0000000423O7
        000    00        423O7
0   0 0000  0 00 00000  0423O7
 0     0 00 0 000  00    423O7
000  00    00000 0 0 000 423O7
 00000  0  00    0    00 423O7
  00  000  00 0 0000 000042

以下是我使用 # 而不是块字符时得到的输出:

####### #  ### ## #######
#     #      #  # #     #
# ### #  ## #  ## # ### #
# ### # #    # ## # ### #
# ### # ##    ### # ### #
#     # #         #     #
####### # # # # # #######
        ###    ##        
#   # ####  # ## #####  #
 #     # ## # ###  ##    
###  ##    ##### # # ### 
 #####  #  ##    #    ## 
  ##  ###  ## # #### ####
#  ##  # #    #### ### # 
   #  ## ##  ### # ##    
  #### # ## #  #  #   #  
###  ## ## # ## ##### #  
        ### # # #   ### #
####### # ##### # # #    
#     #   ## #  #   # #  
# ### # # # ##  #########
# ### #  #   ### ##    ##
# ### #  ##      ### # # 
#     #     # ##  ### ## 
####### ## # ### # #  ###

这无法扫描,但带有块字符的打印版本可能是我想要使用它的原因。这是使用我试图实现的块字符的所需输出:

███████ █  ███ ██ ███████ 
█     █      █  █ █     █ 
█ ███ █  ██ █  ██ █ ███ █ 
█ ███ █ █    █ ██ █ ███ █ 
█ ███ █ ██    ███ █ ███ █ 
█     █ █         █     █ 
███████ █ █ █ █ █ ███████ 
        ███    ██         
█   █ ████  █ ██ █████  █ 
 █     █ ██ █ ███  ██     
███  ██    █████ █ █ ███  
 █████  █  ██    █    ██  
  ██  ███  ██ █ ████ ████ 
█  ██  █ █    ████ ███ █  
   █  ██ ██  ███ █ ██     
  ████ █ ██ █  █  █   █   
███  ██ ██ █ ██ █████ █   
        ███ █ █ █   ███ █ 
███████ █ █████ █ █ █     
█     █   ██ █  █   █ █   
█ ███ █ █ █ ██  █████████ 
█ ███ █  █   ███ ██    ██ 
█ ███ █  ██      ███ █ █  
█     █     █ ██  ███ ██  
███████ ██ █ ███ █ █  ███

您可以尝试将 Unicode 数据编码为 UTF-8。这是 Linux 上最常用的编码,许多程序有理由拒绝支持任何其他编码。除非您需要发出 U+0000,否则您可以使用标准 C 字符串以 UTF-8 格式存储所有 Unicode 代码点。

但是,如果您的目标是在终端上打印二维码,您可能会遇到问题,因为终端字符通常不是正方形,也没有标准比例。因此,您的二维码可能无法在终端上正常呈现,并且 phone 难以或无法阅读。有一些程序可以做到这一点,所以大概它至少在某些情况下有效,尽管它可能并非在所有情况下都有效。您可能会发现 libqrencode 对您的工作很有帮助。

我发现了问题。我实际上并没有将 ASCII 块字符放入 conv 函数中,而是放入了代码来更改终端的颜色。这最终在身份验证期间按原样打印,因此没有显示 QR 码。

现在通过发送正确的 ASCII 块字符来修复它,当将其视为字符串时,在 PAM 身份验证期间可以完美地打印给用户。