Search code examples
clinuxsshpam

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


I am creating a PAM module to show a QR code to users that are trying to log onto a system over SSH to allow them to scan it and authenticate using biometrics on their phone. Is there a way to pass unicode characters into the PAM conv function to allow the application to display them to the user?

The reason I need to hand in unicode characters is because I want to use the uincode character █ (U+2588 Full Block) as a way to print the QR code to the screen.

I have tried using the type wchar_t to hand in the value and also just trying to hand it in as char but both end up printing the missing character question mark to the screen.

If this is not possible is there a way of being able to show a QR code prior to authentication at all or is regular text the only possible thing to show?

Pam conv struct from PAM source:

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

Edit (31/10/21): I have tried the suggestion of encoding as UTF8 which I beleive is done like so: \u[unicode char code]. This produced the following compiler warning:

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

and this output:

\210\210\210\210\210\210\210 \210  \210\210\210 \210\210 \210\210\210\210\210\210\210\214\2723O\177
\210     \210      \210  \210 \210     \210\214\2723O\177
\210 \210\210\210 \210  \210\210 \210  \210\210 \210 \210\210\210 \210\214\2723O\177
\210 \210\210\210 \210 \210    \210 \210\210 \210 \210\210\210 \210\214\2723O\177
\210 \210\210\210 \210 \210\210    \210\210\210 \210 \210\210\210 \210\214\2723O\177
\210     \210 \210         \210     \210\214\2723O\177
\210\210\210\210\210\210\210 \210 \210 \210 \210 \210 \210\210\210\210\210\210\210\214\2723O\177
        \210\210\210    \210\210        \214\2723O\177
\210   \210 \210\210\210\210  \210 \210\210 \210\210\210\210\210  \210\214\2723O\177
 \210     \210 \210\210 \210 \210\210\210  \210\210    \214\2723O\177
\210\210\210  \210\210    \210\210\210\210\210 \210 \210 \210\210\210 \214\2723O\177
 \210\210\210\210\210  \210  \210\210    \210    \210\210 \214\2723O\177
  \210\210  \210\210\210  \210\210 \210 \210\210\210\210 \210\210\210\210\214\272

The following is the output I get when using # instead of the block character:

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

This can't be scanned but the printed version with the block character can be hence why I want to use it. This is the desired output using the block character that I'm trying to achieve:

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

Solution

  • I found out the issue. I wasn't actually putting in the ASCII block character to the conv function but rather I was putting in code to change the colour of the terminal. This ended up being printed as is during auth hence why the QR code didn't show up.

    Fixed it now by sending in the proper ASCII block character which when treated as a string prints perfectly well to the user during PAM auth.