5/ o/Unix/ h/$1/ cpe:/a:proftpd:proftpd:1.2.5/a
# ProFTPD 1.2.6
match ftp m|^220 ([-.\w]+) FTP server ready\.\r\n214-The following commands are recognized \(\* =>'s unimplemented\)\.\r\n214-USER    PASS    ACCT\*   CWD     XCWD    CDUP    XCUP    SMNT\*   \r\n214-QUIT    REIN\*   PORT    PASV    EPRT    EPSV    TYPE    STRU    \r\n214-MODE    RETR    STOR    STOU    APPE    ALLO\*   REST    RNFR    \r\n214-RNTO    ABOR    DELE    MDTM    RMD     XRMD    MKD     XMKD| p/ProFTPD/ v/1.2.6/ o/Unix/ h/$1/ cpe:/a:proftpd:proftpd:1.2.6/a
match ftp m|^220 ([-.\w]+ )?FTP [sS]erver ready\.?\r\n214-The following commands are recognized \(\* =>'s unimplemented\)\.\r\n214-USER    PASS    ACCT\*   CWD     XCWD    CDUP    XCUP    SMNT\*   \r\n214-QUIT    REIN\*   PORT    PASV    EPRT    EPSV    TYPE    STRU    \r\n214-MODE    RETR    STOR    STOU    APPE    ALLO\*   REST    RNFR    \r\n214-RNTO    ABOR    DELE    MDTM    RMD     XRMD    MKD     XMKD| p/ProFTPD/ v/1.2.6/ o/Unix/ h/$1/ cpe:/a:proftpd:proftpd:1.2.6/a
# ProFTPD 1.2.8
# proftpd 1.2.9 rc1
match ftp m%^220 .*\r\n214-The following commands are recognized \(\* =>'s unimplemented\)\.\r\n(?:214-| )USER    PASS    ACCT\*   CWD     XCWD    CDUP    XCUP    SMNT\*   \r\n(?:214-| )QUIT    REIN\*   PORT    PASV    TYPE    STRU    MODE    RETR    \r\n(?:214-| )STOR    STOU    APPE    ALLO\*   REST    RNFR    RNTO    ABOR    \r\n(?:214-| )DELE    MDTM    RMD     XRMD    MKD     XMKD    PWD     XPWD    \r\n(?:214-| )SIZE% p/ProFTPD/ v/1.2.8 - 1.2.9/ o/Unix/ cpe:/a:proftpd:proftpd/
match ftp m%^220 .*\r\n214-The following commands are recognized \(\* =>'s unimplemented\)\.\r\n(?:214-| )USER    PASS    ACCT\*   CWD     XCWD    CDUP    XCUP    SMNT\*   \r\n(?:214-| )QUIT    REIN\*   PORT    PASV    EPRT    EPSV    TYPE    STRU    \r\n(?:214-| )MODE    RETR    STOR    STOU    APPE    ALLO\*   REST    RNFR    \r\n(?:214-| )RNTO    ABOR    DELE    MDTM    RMD     XRMD    MKD     XMKD    \r\n(?:214-| )PWD     XPWD    SIZE    LIST    NLST    SITE    SYST    STAT    \r\n% p/ProFTPD/ v/1.2.8 - 1.2.9/ o/Unix/ cpe:/a:proftpd:proftpd/
# proftpd 1.2.9rc1 on linux 2.4.19
match ftp m|220 localhost FTP server ready\r\n214-The following commands are recognized \(\* =>'s unimplemented\)\.\r\n214-USER    PASS    ACCT\*   CWD     XCWD    CDUP    XCUP    SMNT\*   \r\n214-QUIT    REIN\*   PORT    PASV    TYPE    STRU    MODE    RETR    \r\n214-STOR    STOU    APPE    ALLO\*   REST    RNFR    RNTO    ABOR    \r\n214-DELE| p/ProFTPD/ v/1.2.9rc1/ o/Unix/ cpe:/a:proftpd:proftpd:1.2.9rc1/a
# proftpd 1.2.10
match ftp m|^220 .*\r\n214-The following commands are recognized \(\* =>'s unimplemented\):\r\n CWD     XCWD    CDUP    XCUP    SMNT\*   QUIT    PORT    PASV    \r\n EPRT    EPSV    ALLO\*   RNFR    RNTO    DELE    MDTM    RMD     \r\n XRMD    MKD     XMKD    PWD     XPWD    SIZE    SYST    HELP    \r\n NOOP    FEAT    OPTS    AUTH\*?   CCC\*    CONF\*   ENC\*    MIC\*    \r\n PBSZ\*?   PROT\*?   TYPE    STRU    MODE    RETR    STOR    STOU    \r\n|s p/ProFTPD/ v/1.2.10/ cpe:/a:proftpd:proftpd:1.2.10/a

match ftp m|^220 .*\r\n214-The following commands are recognized \(\* =>'s unimplemented\):\r\n CWD     XCWD    CDUP    XCUP    SMNT\*   QUIT    PORT    PASV    \r\n EPRT    EPSV    ALLO\*   RNFR    RNTO    DELE    MDTM    RMD     \r\n XRMD    MKD     XMKD    PWD     XPWD    SIZE    SYST    HELP    \r\n|s p/ProFTPD/ cpe:/a:proftpd:proftpd/a

match ftp m|^220[ -].*\r\n214-The following commands are recognized \(\* =>'s unimplemented\):\r\n|s p/ProFTPD/ cpe:/a:proftpd:proftpd/a

match ftp m|^220 .*\r\n214-\xd1\xeb\xe5\xe4\xf3\xfe\xf9\xe8\xe5 \xea\xee\xec\xe0\xed\xe4\xfb \xe1\xfb\xeb\xe8 \xf0\xe0\xf1\xef\xee\xe7\xed\xe0\xed\xfb \(\* => \xed\xe5 \xf0\xe5\xe0\xeb\xe8\xe7\xee\xe2\xe0\xed\xee\):\r\n| p/ProFTPD/ i/locale: ru_RU/ cpe:/a:proftpd:proftpd/a

# Solaris 8 ftpd
match ftp m|^220 ([-.+\w]+) FTP server \(.*\) ready\.\r\n214-The following commands are recognized:\r\n   USER    EPRT    STRU    MAIL\*   ALLO    CWD     STAT\*   XRMD \r\n   PASS    LPRT    MODE    MSND\*   REST\*   XCWD    HELP    PWD \r\n   ACCT\*   EPSV    RETR    MSOM\*   RNFR    LIST    NOOP    XPWD \r\n   REIN\*   LPSV    STOR    MSAM\*   RNTO    NLST    MKD     CDUP \r\n| p/Sun Solaris ftpd/ o/Solaris/ h/$1/ cpe:/o:sun:sunos/a
# Phaser860 printer
match ftp m|^220 FTP server ready\.\r\n214- The following commands are recognized \(\* =>'s unimplemented\)\.\r\n   USER    PORT    STOR    MSAM\*   RNTO\*   NLST\*   MKD\*    CDUP\*   EPLF\*\r\n   PASS    PASV\*   APPE\*   MRSQ\*   ABOR    SITE\*   XMKD\*   XCUP\*\r\n   ACCT\*   TYPE    MLFL\*   MRCP\*   DELE    SYST    RMD\*    STOU \r\n   SMNT\*   STRU    MAIL\*   ALLO\*   CWD\*    STAT    XRMD\*   SIZE\*\r\n   REIN\*   MODE    MSND\*   REST\*   XC| p/Phaser printer ftpd/ d/printer/
match ftp m|^220 FTP server ready\.\r\n214- The following commands are recognized \(\* =>'s unimplemented\)\.\r\n   USER    PORT    MODE    MSND\*   REST\*   XCWD\*   HELP    PWD     MDTM\*\r\n   PASS    EPRT    RETR\*   MSOM\*   RNFR\*   LIST\*   NOOP    XPWD    MACB\*\r\n   ACCT\*   PASV\*   STOR    MSAM\*   RNTO\*   NLST\*   MKD\*    CDUP\*   EPLF\*\r\n   SMNT\*   EPSV    APPE\*   MRSQ\*   ABOR    SITE\*   XMKD\*   XCUP\*\r\n   REIN\*   TYPE    MLFL\*   MRCP\*   DELE    SYST    RMD\*    STOU \r\n   QUIT    STRU    MAIL\*   ALLO\*   CWD\*    STAT    XRMD\*   SIZE\*\r\n214 Direct comments to http://www\.xerox\.com/officeprinting\.\r\n| p/Xerox 8560DN printer ftpd/ d/printer/ cpe:/h:xerox:8560dn/a
# bsd-ftpd 0.3.3 (port of OpenBSD ftp server) on Linux 2.4.20
match ftp m|^220 ([-.\w]+) FTP server ready\.\r\n214- The following commands are recognized \(\* =>'s unimplemented\)\.\r\n   USER    PORT    TYPE    MLFL\*   MRCP\*   DELE    SYST    RMD     STOU \r\n   PASS    LPRT    STRU    MAIL\*   ALLO    CWD     STAT    XRMD    SIZE \r\n   ACCT\*   EPRT    MODE    MSND\*   REST    XCWD    HELP    PWD     MDTM \r\n   SMNT\*   PASV    RETR    MSOM\*   RNFR    LIST    NOOP    XPWD \r| p/bsd-ftpd/ o/Linux/ h/$1/ cpe:/o:linux:linux_kernel/a
# Rhinosoft Serv-U FTP v.4.1 build 4.1.0.0 on Windows XP
match ftp m|^220 .*\r\n214- The following commands are recognized \(\* => unimplemented\)\.\r\n   USER    PORT    RETR    ALLO    DELE    SITE    XMKD    CDUP    FEAT\r\n   PASS    PASV    STOR    REST    CWD     STAT    RMD     XCUP    OPTS\r\n   ACCT    TYPE    APPE    RNFR    XCWD    HELP    XRMD    STOU    AUTH\r\n   REIN    STRU    SMNT    RNTO    LIST    NOOP    PWD     SIZE    PBSZ\r\n| p/Rhinosoft Serv-U FTP/ cpe:/a:serv-u:serv-u/
# BulletProof FTP server 2.15 on Windows XP
match ftp m|^220 .*\r\n530 Please login with USER and PASS first\.\r\n$| p/BulletProof FTPd/ o/Windows/ cpe:/o:microsoft:windows/a
# SGI IRIX 6.5.18f ftpd
match ftp m|^220 ([-.\w]+) FTP server ready\.\r\n214- The following commands are recognized \(\* =>'s unimplemented\)\.\r\n   USER    PORT    STOR    MSAM\*   RNTO    NLST    MKD     CDUP \r\n   PASS    PASV    APPE    MRSQ\*   ABOR    SITE    XMKD    XCUP \r\n   ACCT\*   TYPE    MLFL\*   MRCP\*   DELE    SYST    RMD     STOU \r\n   SMNT\*   STRU    MAIL\*   ALLO    CWD     STAT    XRMD    SIZE \r\n   REIN\*   MODE    MSND\*   REST    XCWD    HELP    PWD     MDTM \r\n   QUIT    RETR    MSOM\*   RNFR    LIST    NOOP    XPWD \r\n214 Direct comments to | p/SGI IRIX ftpd/ o/IRIX/ h/$1/ cpe:/o:sgi:irix/a
match ftp m|^421 Server is temporarily unavailable - please try again later\.\r\n421 Service closing control connection\.\r\n| p/Serv-U ftpd/ i/Server temporarily unavailable/ o/Windows/ cpe:/a:serv-u:serv-u/ cpe:/o:microsoft:windows/a
# FreeBSD 4.10 ftpd
match ftp m|^220 FTP server ready\.\r\n214- The following commands are recognized \(\* =>'s unimplemented\)\.\r\n   USER    PORT    TYPE    MLFL\*   MRCP\*   DELE    SYST    RMD     STOU \r\n   PASS    LPRT    STRU    MAIL\*   ALLO    CWD     STAT    XRMD    SIZE \r\n   ACCT\*   EPRT    MODE    MSND\*   REST    XCWD    HELP    PWD     MDTM \r\n   SMNT\*   PASV    RETR    MSOM\*   RNFR    LIST    NOOP    XPWD \r\n   REIN\*   LPSV    STOR    MSAM\*   RNTO    NLST    MKD     CDUP \r\n   QUIT    EPSV    APPE    MRSQ\*   ABOR    SITE    XMKD    XCUP \r\n214 End\.\r\n| p/FreeBSD ftpd/ o/FreeBSD/ cpe:/o:freebsd:freebsd/a
match ftp m|^220 .*\r\n214-CesarFTP server ([\w.]+) supports the following commands:\r\n| p/ACLogic CesarFTPd/ v/$1/ o/Windows/ cpe:/a:aclogic:cesarftpd:$1/ cpe:/o:microsoft:windows/
match ftp m|^220 Private ftp server, anonymous login not allowed\.\r\n214-The following commands are recognized:\r\n   USER   PASS   QUIT   CWD    PWD    PORT   PASV   TYPE\r\n   LIST   REST   CDUP   RETR   STOR   SIZE   DELE   RMD \r\n   MKD    RNFR   RNTO   ABOR   SYST   NOOP   APPE   NLST\r\n   MDTM   XPWD   XCUP   XMKD   XRMD   NOP    EPSV   EPRT\r\n   AUTH   ADAT   PBSZ   PROT   FEAT   MODE   OPTS   HELP\r\n214 Have a nice day\.\r\n| p/FileZilla ftpd/ i/No anon login/ o/Windows/ cpe:/a:filezilla-project:filezilla_server:ftpd/ cpe:/o:microsoft:windows/a
match ftp m|^220.*\r\n214-The following commands are recognized:\r\n   USER   PASS   QUIT   CWD    PWD    PORT   PASV   TYPE\r\n   LIST   REST   CDUP   RETR   STOR   SIZE   DELE   RMD \r\n   MKD    RNFR   RNTO   ABOR   SYST   NOOP   APPE   NLST\r\n   MDTM   XPWD   XCUP   XMKD   XRMD   NOP    EPSV   EPRT\r\n   AUTH   ADAT   PBSZ   PROT   FEAT   MODE   OPTS   HELP\r\n   ALLO   MLST   MLSD\r\n214 Have a nice day\.\r\n| p/FileZilla ftpd/ o/Windows/ cpe:/a:filezilla-project:filezilla_server/ cpe:/o:microsoft:windows/a
# OpenVMS 7.3-1
match ftp m|^220 ([-\w_.]+) FTP Server \(Version ([\d.]+)\) Ready\.\r\n214-The following commands are recognized:\r\n   USER    TYPE    RETR    RNFR    NLST    PWD     ALLO    EPSV \r\n   PASS    STRU    STOR    RNTO    CWD     CDUP    SYST    QUIT \r\n   SITE    PORT    STOU    DELE    MKD     NOOP    STAT    HELP \r\n   MODE    EPRT    APPE    LIST    RMD     ABOR    PASV \r\n214 End of Help\.\r\n| p/OpenVMS ftpd/ v/$2/ h/$1/
match ftp m|^220 SMTP service ready\r\n214-Commands:\r\r\n214-\tDATA\tRCPT\tMAIL\tQUIT\tRSET\r\r\n214 \tHELO\tVRFY\tEXPN\tHELP\tNOOP\r\n| p/WatchGuard Firebox II firewall ftpd/ d/firewall/

match ftp m|^220 Speak friend, and enter\r\n214-\r\n  ftpd\.bin - Round-robin File Transfer Server, version ([\w.]+)\r\n| p/ftpd.bin round-robin file server/ v/$1/
match ftp m|^220 FTP server ready\.  \r\n214-Ethernet Interface\r\n    \r\n    To access help, cd to the help directory then enter a \"dir\" command\.\r\n    \r\n    \r\n| p|QMS/Minolta Magicolor 2200 DeskLaser printer ftpd| d/printer/
match ftp m|^220 FTPU ready\.\r\n500 Sorry, no such command\.\r\n| p/Netgear DG632 router ftpd/ d/router/ cpe:/h:netgear:dg632/a
match ftp m|^220 ([-\w_.]+) FTP server \(UNIX_SV ([\d.]+)\) ready\.\r\n214-The following commands are recognized \(\* =>'s unimplemented\)\.\r\n   USER    PORT    STOR    MSAM\*   RNTO    NLST    MKD     CDUP \r\n   PASS    PASV    APPE    MRSQ\*   ABOR    SITE    XMKD    XCUP \r\n   ACCT\*   TYPE    MLFL\*   MRCP\*   DELE    SYST    RMD     STOU \r\n   SMNT\*   STRU    MAIL\*   ALLO    CWD     STAT    XRMD    SIZE \r\n   REIN\*   MODE    MSND\*   REST    XCWD    HELP    PWD     MDTM \r\n   QUIT    RETR    MSOM\*   RNFR    LIST    NOOP    XPWD \r\n| p/WU-FTPd/ i/UNIX_SV $2/ o/Unix/ h/$1/ cpe:/a:redhat:wu_ftpd/
match ftp m|^220 server ready\r\n530 Please login with USER and PASS\r\n$| p/Extreme FTPd/
match ftp m|^220 FTP server ready\.\r\n502 Command not implemented\.\r\n$| p/Aruba router ftpd/ d/router/
match ftp m|^220 Type 'site help' or 'quote site help'\.\r\n220-| p/RaidenFTPd/ o/Windows/ cpe:/o:microsoft:windows/a
match ftp m|^220-\r\n220 Features p a \.\r\n214 Please refer to FTP documentation\.\r\n| p/Sami ftpd/ o/Windows/ cpe:/o:microsoft:windows/a
match ftp m|^220 FTP server at \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} ready\.\r\n503 USER expected\.\r\n| p/Linksys NSLU2 ftpd/ d/storage-misc/ cpe:/h:linksys:nslu2/
match ftp m|^220[ -].*\r\n214-The following commands are recognized:\r\n.*\r\n214 Have a nice day\.\r\n|s p/FileZilla ftpd/ o/Windows/ cpe:/a:filezilla-project:filezilla_server/ cpe:/o:microsoft:windows/a
match ftp m|^220 ([-\w_.]+)\r\n214-The following commands are recognized \(\* =>'s unimplemented\)\.\r\n.*\r\n214 Direct comments to|s p/ProFTPD/ h/$1/ cpe:/a:proftpd:proftpd/a
match ftp m|^220 Please enter your login name now\.\r\n502 help is not implemented\.\r\n| p/EvolutionX ftpd/ d/game console/
match ftp m|^220[ -].*\r\n550 SSL/TLS required on the control channel\r\n|s p/ProFTPD/ i/requires SSL/ cpe:/a:proftpd:proftpd/a
match ftp m|^220 FTP server ready\r\n214-The following commands are recognized:\r\nHELP\tUSER\tPASS\tQUIT\tLIST\tNLST\r\nRETR\tSTOR\tCWD\tTYPE\tPORT\tPWD\r\nSTRU\tMODE\tALLO\tACCT\tPASV\tNOOP\r\nDELE\tEPRT\tEPSV\r\n214 End of command list\.\r\n| p|TopLayer/Alcatel ftpd|
match ftp m|^220.*This site is running NcFTPd Server software|s p/NcFTPd/
match ftp m|^220 Connection established\.\r\n214-The following commands are supported:\r\n\tUSER\tPORT\tTYPE\tABOR\tCWD \tLIST\r\n\tPASS\tPASV\tSTRU\tPWD \tXCWD\tNLST\r\n\tQUIT\tSTOR\tRETR\tMODE\tXPWD\tNOOP\r\n\tHELP\r\n214 \r\n| p/Canon imageRUNNER 570 printer ftpd/ d/printer/ cpe:/h:canon:imagerunner_570/
match ftp m|^220 ([\w._-]+) (?:Ver )([\w._-]+) FTP server\.\r\n214- FTPD supported commands\(RFC959 subset\):\r\n| p/Kyocera $1 printer ftpd/ v/$2/ d/printer/ cpe:/h:kyocera:$1/a
match ftp m|^220 ADP LaserStatio FTP server\.\r\n214- FTPD supported commands\(RFC959 subset\):\r\n| p/Kyocera LaserStation 1940 printer ftpd/ d/printer/ cpe:/h:kyocera:laserstation_1940/a
match ftp m|^220 ([\w._ -]+) FTP server\.\r\n214- FTPD supported commands\(RFC959 subset\):\r\n| p/Kyocera $1 printer ftpd/ d/printer/ cpe:/h:kyocera:$1/a
match ftp m|^220.Welcome to ([-\w_.]+)\r\n214-The following SITE commands are recognized\r\n.*214 Pure-FTPd - http://pureftpd\.org/?\r\n|s p/Pure-FTPd/ h/$1/ cpe:/a:pureftpd:pure-ftpd/
match ftp m|^214-The following SITE commands are recognized\r\n.*214 Pure-FTPd - http://pureftpd\.org/\r\n|s p/Pure-FTPd/ cpe:/a:pureftpd:pure-ftpd/
match ftp m|^220.*214 Pure-FTPd - http://pureftpd\.org/?\r\n|s p/Pure-FTPd/ cpe:/a:pureftpd:pure-ftpd/
match ftp m|^220 Welcome to the update FTP server v1\.0\.\r\n502 'HELP' command not implemented\.\r\n| p/Netcomm V300 VoIP adapter update ftpd/ d/VoIP adapter/ cpe:/h:netcomm:v300/a
match ftp m|^220 Connection established\.\r\n214-The following commands are supported:\r\n\tUSER\tPORT\tTYPE\tABOR\tCWD \tLIST\r\n| p/Canon imageRUNNER printer ftpd/ d/printer/
match ftp m|^220 Ftp firmware update utility\r\n500 Unknown command: \"HELP\"\r\n| p|Belkin/BT/D-Link/Gigaset broadband router ftp firmware update| d/broadband router/
match ftp m|^220 FTP Server Ready\r\n.*\r\n214 Direct comments to psp@amoks\.com\.\r\n|s p/Amoks PlayStation Portable ftpd/ d/game console/
match ftp m|^220 FTP server ready\r\n211 HELP text\r\n| p/Alfresco Document Management System ftpd/
match ftp m|^220 FTP Server Ready\r\n500 Unknown cmd HELP\r\n| p/Optus Speedstream 4200 ADSL router ftpd/ d/router/
match ftp m|^214-The following commands are recognized \(\* => unimplemented\.\)\r\n.*\r\n214 Direct comments to support@arcanesoft\.com\.\r\n|s p/Arcanesoft Vermillion ftpd/ o/Windows/ cpe:/o:microsoft:windows/a
match ftp m|^220 Connection established\.\r\n214-The following commands are supported\.\r\n    USER    PORT    TYPE    ABOR    CWD     LIST\r\n    PASS    PASV    STRU    PWD     XCWD    NLST\r\n    QUIT    STOR    MODE    XPWD    NOOP    HELP\r\n214 End of HELP\r\n| p/Canon iPF6100 printer ftpd/ d/printer/ cpe:/h:canon:ipf6100/a
match ftp m|^200 1500\r\nf\0\x18\0\0\0x\xda\x0b\xcd\xcb\xce\xcb/\xcfSH\xce\xcf\xcdM\xccK\xd1\x03\x005\x93\x06\x1e| p/Gene6 ftpd/
match ftp m|^220 Welcome to connection\.\r\n214 FTP Server Help\.\r\n  HUMAX PVR FTP Server\. \r\n214 End\r\n| p/Humax iHDR-5050C DVR ftpd/ d/media device/
match ftp m|^220 Service ready for new user\r\n214-The following commands are recognized\r\n   ABOR\r\n   ALLO\r\n   APPE\r\n   CDUP\r\n   CWD\r\n   DELE\r\n   LIST\r\n   MKD\r\n   MODE\r\n   NLST\r\n   NOOP\r\n   PASS\r\n   PORT\r\n   PWD\r\n   QUIT\r\n   RETR\r\n   RMD\r\n   RNFR\r\n   RNTO\r\n   SIZE\r\n   SMNT\r\n   STOR\r\n   STRU\r\n   SYST\r\n   TYPE\r\n   USER\r\n   XCUP\r\n   XCWD\r\n   XMKD\r\n   XPWD\r\n   XRMD\r\n214 HELP command successful\r\n| p/Lumetrix Imaging Photometer ftpd/
match ftp m|^220 ([\w._-]+) FTP server ready\.\r\n214-\r\n    The following commands are recognized\.\r\n    \(`-' = not implemented, `\+' = supports options\)\r\n    USER    REIN-   TYPE    ALLO    MKD     HELP    MIC     MLST\+   MSND-\r\n    PASS    PORT    STRU    REST    PWD     NOOP\+   CONF    MLSD    MSOM-\r\n    ACCT-   LPRT    MODE    RNFR    LIST    AUTH    ENC     MAIL-   XCUP\r\n    CWD     EPRT    RETR    RNTO    NLST    ADAT    FEAT    MLFL-   XCWD\r\n    CDUP    PASV    STOR    ABOR    SITE    PROT    OPTS    MRCP-   XMKD\r\n    SMNT-   LPSV    STOU    DELE    SYST    PBSZ    MDTM    MRSQ-   XPWD\r\n    QUIT    EPSV    APPE    RMD     STAT    CCC     SIZE    MSAM-   XRMD\r\n214 Direct comments to ftp-bugs@| p/QNX ftpd/ v/$1/ o/QNX/ cpe:/o:qnx:qnx/a
# DS210j, DS207+
match ftp m|^220 ([\w._-]+) FTP server ready\.\r\n214- The following commands are recognized \(\* =>'s unimplemented\)\.\r\n   USER    LPRT    MODE    MSOM\*   RNTO    SITE    RMD     SIZE    PROT \r\n   PASS    EPRT    RETR    MSAM\*   ABOR    SYST    XRMD    MDTM \r\n   ACCT\*   PASV    STOR    MRSQ\*   DELE    STAT    PWD     MFMT \r\n   SMNT\*   LPSV    APPE    MRCP\*   CWD     HELP    XPWD    FEAT \r\n   REIN\*   EPSV    MLFL\*   ALLO    XCWD    NOOP    CDUP    OPTS \r\n   QUIT    TYPE    MAIL\*   REST    LIST    MKD     XCUP    AUTH \r\n   PORT    STRU    MSND\*   RNFR    NLST    XMKD    STOU    PBSZ \r\n214 Direct comments to ftp-bugs@| p/Synology DS200-series NAS device ftpd/ d/storage-misc/ h/$1/
# DSM 5.2-5644 Update 5
match ftp m|^220 ([\w._-]+) FTP server ready\.\r\n214- The following commands are recognized \(\* =>'s unimplemented\)\.\r\n   USER    LPRT    MODE    MSOM\*   RNTO    SITE    RMD     SIZE    AUTH \r\n   PASS    EPRT    RETR    MSAM\*   ABOR    SYST    XRMD    MDTM    PBSZ \r\n   ACCT\*   PASV    STOR    MRSQ\*   DELE    STAT    PWD     MFMT    PROT \r\n   SMNT\*   LPSV    APPE    MRCP\*   CWD     HELP    XPWD    MLSD \r\n   REIN\*   EPSV    MLFL\*   ALLO    XCWD    NOOP    CDUP    MLST \r\n   QUIT    TYPE    MAIL\*   REST    LIST    MKD     XCUP    FEAT \r\n   PORT    STRU    MSND\*   RNFR    NLST    XMKD    STOU    OPTS \r\n214 Direct comments to ftp-bugs@| p/Synology DiskStation Manager 5.2 ftpd/ d/storage-misc/ h/$1/ cpe:/a:synology:diskstation_manager:5.2/
match ftp m|^220 Hi there!\r\n214-This is gatling \(www\.fefe\.de/gatling/\); No help available\.\r\n214 See http://cr\.yp\.to/ftp\.html for FTP help\.\r\n| p/gatling ftpd/
match ftp m|^220 Service ready for new user\r\n214-The following commands are implemented\.\r\nABOR  APPE  CDUP  CWD   DELE  HELP  LIST  MDTM\r\nMKD   MODE  NLST  NOOP  PASS  PASV  PORT  PWD\r\nQUIT  REST  RETR  RMD   RNFR  RNTO  SITE  SIZE\r\nSTAT  STOR  STOU  STRU  SYST  TYPE  USER\r\n214 End of help\r\n| p/Cisco Wireless Control System ftpd/ cpe:/h:cisco:wireless_control_system/
match ftp m|^220 Operation successful\r\n214-Features:\r\n EPSV\r\n PASV\r\n REST STREAM\r\n MDTM\r\n SIZE\r\n214 Ok\r\n| p/BusyBox ftpd/ cpe:/a:busybox:busybox/
match ftp m|^220-Rival Group FTP Server\r\n220-Unauthorized access prohibited\r\n220 All activity is logged\.\r\n214-CesarFTP server ([\w._-]+) supports the following commands:\r\n214-ABOR ACCT ALLO APPE CDUP CWD  DELE HELP LIST\r\n214-MDTM MKD  MODE NLST NOOP PASS PASV PORT PWD \r\n214-QUIT REIN REST RETR RMD  RNFR RNTO SITE SMNT\r\n214-STAT STOR STOU STRU SYST TYPE\r\n214-\r\n214-CesarFTP server [\w._-]+ supports specific commands\r\n214-invoked with the SITE command:\r\n214-\r\n214-SITE MSG\r\n214-\r\n214 \r\n| p/ACLogic CesarFTP/ v/$1/ o/Windows/ cpe:/a:aclogic:cesarftpd:$1/ cpe:/o:microsoft:windows/
match ftp m|^220 pyftpdlib ([\w._-]+) ready\.\r\n214-The following commands are recognized:\r\n ABOR   ALLO   APPE   CDUP   CWD    DELE   EPRT   EPSV  \r\n FEAT   HELP   LIST   MDTM   MKD    MLSD   MLST   MODE  \r\n NLST   NOOP   OPTS   PASS   PASV   PORT   PWD    QUIT  \r\n REIN   REST   RETR   RMD    RNFR   RNTO   SIZE   STAT  \r\n STOR   STOU   STRU   SYST   TYPE   USER   XCUP   XCWD  \r\n XMKD   XPWD   XRMD  \r\n214 Help command successful\.\r\n$| p/pyftpdlib/ v/$1/
# CANOPY Motorola Broadband Wireless Technology Center
match ftp m|^220 Service ready\r\n500 Unsupported command\r\n| p/Motorola Canopy WAP ftpd/ d/WAP/
match ftp m|^220 FTP server ready\r\n214-The following commands are recognized:\r\nHELP\tUSER\tPASS\tQUIT\tLIST\tNLST\nRETR\tSTOR\tCWD\tTYPE\tPORT\tPWD\nSTRU\tMODE\tALLO\tACCT\tPASV\tNOOP\nDELE\n214 End of command list\.\r\n| p/Nortel CES1010E router ftpd/ d/router/ cpe:/h:nortel:ces1010e/
match ftp m|^220 FTP server ready\.\r\n214-The following commands are recognized:\r\nHELP\tUSER\tPASS\tQUIT\tLIST\tNLST\tCDUP\r\nRETR\tSTOR\tCWD\tTYPE\tPORT\tPWD\tXCUP\r\nSTRU\tMODE\tXCWD\tALLO\tACCT\tXPWD\tPASV\r\nNOOP\tSYST\r\n214 End of command list\.\r\n| p/Alcatel Litespan-2000 PBX ftpd/ d/PBX/ cpe:/h:alcatel:litespan-2000/
match ftp m|^220 Opto 22 FTP server ready\.\r\n502 HELP command not implemented, or not allowed\.\r\n| p/Opto 22 ftpd/

# Before version 2.0.8, vsftpd outputs the "Please login" lines in response to
# blank lines, which is caught under GenericLines above." In 2.0.8 and after,
# it ignores blank lines.
match ftp m|^(?:220-.*\r\n)?220 .*\r\n530 Please login with USER and PASS\.\r\n|s p/vsftpd/ v/2.0.8 or later/ cpe:/a:vsftpd:vsftpd/
match ftp m|^220 FTP server ready\.\r\n214- The following commands are recognized \(\* =>'s unimplemented\)\.\r\n   USER    REIN\*   MODE    REST\*   MKD     STAT\*   EPSV    MRSQ\*   XCUP \r\n   PASS    QUIT    RETR    RNFR    PWD     HELP    MLFL\*   MRCP\*   SIZE \r\n   ACCT\*   PORT    STOR    RNTO    LIST    NOOP    MAIL\*   XCWD    MDTM\*\r\n   CWD     PASV    STOU\*   ABOR    NLST    LPRT    MSND\*   XMKD    FEAT\*\r\n   CDUP    TYPE    APPE\*   DELE    SITE\*   LPSV    MSOM\*   XRMD    OPTS\*\r\n   SMNT\*   STRU    ALLO\*   RMD     SYST\*   EPRT    MSAM\*   XPWD \r\n214 End\.\r\n| p/Panasonic AW-HE50 HD Integrated camera ftpd/ d/webcam/ cpe:/h:panasonic:aw-he50/
match ftp m|^220 ftp server ready\r\n502 Command not recognized\r\n| p/Ice Cold Apps FTP Server Ultimate/ o/Android/ cpe:/a:icecoldapps:ftp_server_ultimate/ cpe:/o:google:android/a cpe:/o:linux:linux_kernel/a
match ftp m|^220 FTP server ready\r\n500 Invalid command HELP \r\n| p/DeviceWISE M2M ftpd/ cpe:/a:telit:devicewise_m2m/
match ftp m|^220 FTP server ready\.\r\n214- The following commands are recognized \(\* =>'s unimplemented\)\.\r\n   USER    PORT    TYPE    MLFL\*   MRCP\*   DELE    SYST    XMKD    XCUP \r\n   PASS    LPRT    STRU    MAIL\*   ALLO    CWD     FEAT    RMD     STOU \r\n   ACCT\*   EPRT    MODE    MSND\*   REST    XCWD    STAT    XRMD    SIZE \r\n   SMNT\*   PASV    RETR    MSOM\*   RNFR    LIST    HELP    PWD     MDTM \r\n   REIN\*   LPSV    STOR    MSAM\*   RNTO    NLST    NOOP    XPWD \r\n   QUIT    EPSV    APPE    MRSQ\*   ABOR    SITE    MKD     CDUP \r\n214 End\.\r\n| p/FreeBSD ftpd/ v/6.00LS/
match ftp m|^220 .*\r\n550 Command not recognized or allowed\.\r\n$| p/CrushFTP ftpd/ cpe:/a:crushftp:crushftp/
match ftp m|^220 .*\r\n214-The following commands are recognized \(\* ==>'s unimplemented\)\.\r\n    ABOR \r\n    ACCT \r\n    ADAT \*\r\n    ALLO \r\n    APPE \r\n    AUTH \r\n    CCC \r\n    CDUP \r\n    CWD \r\n    DELE \r\n    ENC \*\r\n    EPRT \r\n    EPSV \r\n    FEAT \r\n    HELP \r\n    HOST \r\n    LANG \r\n    LIST \r\n    MDTM \r\n    MIC \*\r\n    MKD \r\n    MODE \r\n    NLST \r\n    NOOP \r\n    OPTS \r\n    PASS \r\n    PASV \r\n    PBSZ \r\n    PORT \r\n    PROT \r\n    PWD \r\n    QUIT \r\n    REIN \r\n    REST \r\n    RETR \r\n    RMD \r\n    RNFR \r\n    RNTO \r\n    SITE \r\n    SIZE \r\n    SMNT \r\n    STAT \r\n    STOR \r\n    STOU \r\n    STRU \r\n    SYST \r\n    TYPE \r\n    USER \r\n    XCUP \r\n    XCWD \r\n    XMKD \r\n    XPWD \r\n    XRMD \r\n214 HELP command successful\.\r\n| p/IIS ftpd/ v/7/ o/Windows/ cpe:/a:microsoft:internet_information_services:7/ cpe:/o:microsoft:windows/a

match ftp-proxy m|^220 Service Ready\r\n502 Command Not implemented\r\n$| p/Novell iChain ftp proxy/ cpe:/a:novell:ichain/

match finger m|^iFinger v(\d[-.\w]+)\n\n| p/IcculusFinger/ v/$1/
match finger m|^\n    ----------------------------------------------------------------------\n                        Sorry, that user doesn't exist\.\n| p/Stock and Trade Finger Server fingerd/

match freenet m|^HTTP/1\.1 400 Parse error: Could not parse request line \(split\.length=1\): HELP\r\n| p/Freenet/

# http://www.gdsatcom.com/cte_r8000b.php
match gd-comm m|^0:HELP command \[SET, GET,GO, DO, \*IDN\?, ERR\?, CLEAR, HELP\] -or- HELP Tag; HELP Tag will provide detailed formatted information for the field requested\.  Refer to the Programmer's Guide for more details\.\r\n| p/General Dynamics R8000 Communications System Analyzer control/ d/specialized/ cpe:/h:generaldynamics:r8000/

match gnuserv m|^gnudoit: Connection refused\ngnudoit: unable to connect to remote$| p/Gnuserv/

match http m|^HTTP/1\.1 401 Unauthorized\r\nWWW-Authenticate: Basic realm=\"esecsrva\"\r\n\r\n$| p/IBM Director wmicimserver httpd/ cpe:/a:ibm:director/
match http m|^HTTP/1\.1 401 Unauthorized\r\nWWW-Authenticate: Basic realm=\"ANLYX2\"\r\n\r\n$| p/IBM Director wmicimserver httpd/ cpe:/a:ibm:director/

# Dell OpenManage 5.2 (File Version: 3.2.0.364) likes to throw exceptions...
match http m|^HTTP/1\.0 500 Internal Server Error\r\nConnection: Close\r\nContent-Type: text/html\r\n.*<p>java\.lang\.Exception: Invalid request: HELP</p>|s p/Dell PowerEdge OpenManage Server Administrator httpd/ o/Windows/ cpe:/a:dell:openmanage_server_administrator/ cpe:/o:microsoft:windows/a
match http m|^HTTP/1\.1 400 Bad Request\r\n\r\nGET /bst/disconnect HTTP/1\.1\r\nHost: ([\w._-]+)\r\nUser-Agent: DragonFly Storm \(Client; Protocol (\d+)\)\r\nConnection: close\r\n\r\n| p/DragonFly Storm httpd/ i/Protocol $2/ h/$1/
match http m|^HTTP/1\.1 400 Page not found\r\nServer: GoAhead-Webs\r\nDate: .*\r\nPragma: no-cache\r\nCache-Control: no-cache\r\nContent-Type: text/html\r\n\r\n<html><head><title>Document Error: Page not found</title></head>\r\n\t\t<body><h2>Access Error: Page not found</h2>\r\n\t\t<p>Bad request type</p></body></html>\r\n\r\n| p/GoAhead WebServer/ i/TRENDnet TEW-637AP WAP http config/ d/WAP/ cpe:/a:goahead:goahead_webserver/ cpe:/h:trendnet:tew-637ap/a
match http m|^HTTP/1\.1 400 Bad Request\r\nServer: RealVNC/([-.\w]+)\r\nDate: Mon, 27 Jul 2009 08:06:03 GMT\r\nLast-Modified: Mon, 27 Jul 2009 08:06:03 GMT\r\nConnection: close\r\nContent-Type: text/html\r\n\r\n| p/RealVNC/ v/$1/ i/unauthorized/ cpe:/a:realvnc:realvnc:$1/
match http m|^HTTP/1\.0 400 Bad Request\r\nServer: httpd\r\n.*<HTML>\n<HEAD>\n<TITLE>400 Bad Request</TITLE>\n<script language=\"javascript\">\n<!--\n\tvar xmlhttp = false;.*<BODY BGCOLOR=\"#cc9999\">\n<H4>400 Bad Request</H4>\n<script language=\"javascript\">\n<!--\n\tif\(xmlhttp\) {\n\t\talert\('Unauthorizationed'\);|s p/Linksys 4400N WAP http config/ d/WAP/ cpe:/h:linksys:4400n/a
match http m|^HTTP/1\.0 400 Bad Request\r\nServer: httpd\r\n.*<HTML>\n<HEAD>\n<TITLE>400 Bad Request</TITLE>\n<script language=\"javascript\">\n<!--\n\tvar xmlhttp = false;.*<BODY BGCOLOR=\"#cc9999\">\n<H4>400 Bad Request</H4>\n<script language=\"javascript\">\n<!--\n\tif\(xmlhttp\) {\n  \t\talert\('Unauthorizationed'\);|s p/Cisco WAP2000 WAP http config/ d/WAP/ cpe:/h:cisco:wap2000/a
match http m|^HTTP/0\.9 400 Bad Request\r\n\r\n$| p/Ganeti httpd/ cpe:/a:ganeti_project:ganeti/
match http m|^UnknownMethod 400 Bad Request\r\nServer: httpd\r\nDate: .*\r\nConnection: keep-alive\r\nKeep-Alive: timeout=60, max=2000\r\nContent-Type: text/html\r\nContent-length: 130\r\n\r\n<HTML><HEAD><TITLE>Document Error: Bad Request</TITLE></HEAD>\r\n<BODY><H2>Access Error: 400 -- Bad Request</H2>\r\n</BODY></HTML>\r\n\r\n| p/Mbedthis-Appweb/ i/Dell iDRAC6 http config/ d/remote management/ cpe:/a:mbedthis:appweb/ cpe:/h:dell:idrac6/
match http m|^HTTP/1\.1 500 Internal Server Error\r\nContent-Type: text/plain; charset=UTF-8\r\n\r\nFailure: 500 Internal Server Error\r\n$| p/PS3 Media Server httpd/
match http m|^HTTP/1\.1 200 Ignoring bad request from client\r\nServer: Lotus Expeditor Web Container/([\d.]+)\r\nContent-Type: text/html\r\nContent-Length: 122\r\n\r\n<HTML><TITLE>200 Ignoring bad request from client</TITLE><BODY><h1>200 Ignoring bad request from client</h1></BODY></HTML>| p/Lotus Expeditor Web Container/ v/$1/ cpe:/a:ibm:lotus_expeditor:$1/
match http m|^HTTP/1\.1 200 Ignoring bad request from client\r\nServer: Lotus Expeditor Web Container\r\nContent-Type: text/html\r\nContent-Length: 122\r\n\r\n<HTML><TITLE>200 Ignoring bad request from client</TITLE><BODY><h1>200 Ignoring bad request from client</h1></BODY></HTML>| p/Lotus Expeditor Web Container/ cpe:/a:ibm:lotus_expeditor/
# Switched from HTTP 1.0 to 1.1 in 516a5825 (3.6.0)
match http m|^HTTP/1\.0 400 Bad Request \r\nContent-Type: text/plain\r\nDate: .*\r\n\r\nBAD REQUEST: Missing URI\. Usage: GET /example/file\.html$| p/Bukkit JSONAPI httpd for Minecraft game server/ v/3.6.0 or older/
match http m|^HTTP/1\.1 400 Bad Request \r\nContent-Type: text/plain\r\nDate: .*\r\n\r\nBAD REQUEST: Missing URI\. Usage: GET /example/file\.html$| p/Bukkit JSONAPI httpd for Minecraft game server/ v/3.6.0 or later/
match http m|^INV 501 Not Implemented\r\nDate: .*\r\nServer: Intel\(R\) Small Business Technology ([\w._-]+)\r\nContent-Length: 0\r\n\r\n| p/Intel Small Business Technology Platform/ v/$1/ d/remote management/ cpe:/a:intel:small_business_technology_platform:$1/
match http m|^HTTP/1\.1 400 Bad Request\r\nDate: .* GMT\r\nConnection: close\r\nServer: blaze\r\n\r\n$| p/Cisco CSP Collector/ cpe:/a:cisco:common_services_platform_collector/
# 6.2.Alpha
match http m|^HTTP/1\.1 400 Bad Request\r\nContent-Length: 40\r\nContent-Type: text/html\r\n\r\n<h1>400 Bad Request</h1>Bad request line| p/JBoss Enterprise Application Platform/ cpe:/a:redhat:jboss_enterprise_application_platform/
match http m|^HTTP/1\.1 404 Not Found\r\nContent-Type: text/html\r\nContent-Length: \d+\r\nServer: PhpStorm ([\w._-]+)\r\n| p/PhpStorm IDE httpd/ v/$1/ cpe:/a:jetbrains:phpstorm:$1/
match http m|^<html><head><title>Metasploitable2 - Linux</title></head><body>\n<pre>| p/Metasploitable 2 welcome page/ o/Linux/ cpe:/o:linux:linux_kernel/a
match http m|^<HTML><HEAD></HEAD><BODY>HTTP Error: 400</BODY></HTML>\n\n| p/FortiWifi 60CM wireless security appliance httpd/ cpe:/h:fortinet:fortiwifi_60cm/
match http m|^HTTP/1\.1 400 Bad Request - Request Line: HELP tokens\.length 1\r\nConnection: close\r\nContent-Length: 0\r\n\r\n| p/MobileIron Sentry/ cpe:/a:mobileiron:mobileiron_sentry/

# Seen a couple times for just Help probe... -Doug
match http-proxy m|^HTTP/1\.0 200 OK\r\nCache-Control: no-store\r\nPragma: no-cache\r\nCache-Control: no-cache\r\nX-Bypass-Cache: Application and Content Networking System Software ([\d.]+)\r\n| p/Cisco ACNS outbound proxying/ v/$1/ cpe:/a:cisco:application_and_content_networking_system_software:$1/
match http-proxy m|^HTTP/1\.1 403 Bad Protocol\r\n.*<title>(?:I2P )?Warning: Non-HTTP Protocol</title>\r\n<link rel=\"shortcut icon\" href=\"http://proxy\.i2p/themes/console/images/favicon\.ico\" ?>\r\n|s p/I2P anonymizing http proxy/ cpe:/a:i2p_project:i2p/
match http-proxy m|^HTTP/1\.1 403 Bad Protocol\r\n.*<title>(?:I2P )?Warnung: Kein HTTP Protokoll</title>\r\n<link rel=\"shortcut icon\" href=\"http://proxy\.i2p/themes/console/images/favicon\.ico\" ?>\r\n|s p/I2P anonymizing http proxy/ i/German/ cpe:/a:i2p_project:i2p::::de/
match http-proxy m|^HTTP/1\.1 403 Bad Protocol\r\n.*<title>(?:I2P )?Advertencia: Protocolo no HTTP</title>\r\n<link rel=\"shortcut icon\" href=\"http://proxy\.i2p/themes/console/images/favicon\.ico\" ?>\r\n|s p/I2P anonymizing http proxy/ i/Spanish/ cpe:/a:i2p_project:i2p::::es/
match http-proxy m|^HTTP/1\.1 403 Bad Protocol\r\n.*<title>(?:I2P )?Avertissement : protocole non HTTP</title>\r\n<link rel=\"shortcut icon\" href=\"http://proxy\.i2p/themes/console/images/favicon\.ico\" ?>\r\n|s p/I2P anonymizing http proxy/ i/French/ cpe:/a:i2p_project:i2p::::fr/
match http-proxy m|^HTTP/1\.1 403 Bad Protocol\r\n.*<title>(?:I2P )?Peringatan: Protokol Non-HTTP</title>\r\n<link rel=\"shortcut icon\" href=\"http://proxy\.i2p/themes/console/images/favicon\.ico\" ?>\r\n|s p/I2P anonymizing http proxy/ i/Indonesian/ cpe:/a:i2p_project:i2p::::id/
match http-proxy m|^HTTP/1\.1 403 Bad Protocol\r\n.*<title>(?:I2P )?Waarschuwing: non-HTTP protocol</title>\r\n<link rel=\"shortcut icon\" href=\"http://proxy\.i2p/themes/console/images/favicon\.ico\" ?>\r\n|s p/I2P anonymizing http proxy/ i/Dutch/ cpe:/a:i2p_project:i2p::::nl/
match http-proxy m|^HTTP/1\.1 403 Bad Protocol\r\n.*<title>(?:I2P )?Ostrzeżenie: protokół inny niż HTTP</title>\r\n<link rel=\"shortcut icon\" href=\"http://proxy\.i2p/themes/console/images/favicon\.ico\" ?>\r\n|s p/I2P anonymizing http proxy/ i/Polish/ cpe:/a:i2p_project:i2p::::pl/
match http-proxy m|^HTTP/1\.1 403 Bad Protocol\r\n.*<title>(?:I2P )?Aviso: Protocolo não-HTTP</title>\r\n<link rel=\"shortcut icon\" href=\"http://proxy\.i2p/themes/console/images/favicon\.ico\" ?>\r\n|s p/I2P anonymizing http proxy/ i/Brazilian Portuguese/ cpe:/a:i2p_project:i2p::::pt_br/
match http-proxy m|^HTTP/1\.1 403 Bad Protocol\r\n.*<title>(?:I2P )?Aviso: Protocolo fora do padrão HTTP</title>\r\n<link rel=\"shortcut icon\" href=\"http://proxy\.i2p/themes/console/images/favicon\.ico\" ?>\r\n|s p/I2P anonymizing http proxy/ i/Portuguese/ cpe:/a:i2p_project:i2p::::pt/
match http-proxy m|^HTTP/1\.1 403 Bad Protocol\r\n.*<title>(?:I2P )?Atenție: protocolul Non-HTTP</title>\r\n<link rel=\"shortcut icon\" href=\"http://proxy\.i2p/themes/console/images/favicon\.ico\" ?>\r\n|s p/I2P anonymizing http proxy/ i/Romanian/ cpe:/a:i2p_project:i2p::::ro/
match http-proxy m|^HTTP/1\.1 403 Bad Protocol\r\n.*<title>(?:I2P )?Предупреждение: Протокол не HTTP</title>\r\n<link rel=\"shortcut icon\" href=\"http://proxy\.i2p/themes/console/images/favicon\.ico\" ?>\r\n|s p/I2P anonymizing http proxy/ i/Russian/ cpe:/a:i2p_project:i2p::::ru/
match http-proxy m|^HTTP/1\.1 403 Bad Protocol\r\n.*<title>(?:I2P )?Varning: Ej HTTP Protokoll</title>\r\n<link rel=\"shortcut icon\" href=\"http://proxy\.i2p/themes/console/images/favicon\.ico\" ?>\r\n|s p/I2P anonymizing http proxy/ i/Swedish/ cpe:/a:i2p_project:i2p::::sv/
match http-proxy m|^HTTP/1\.1 403 Bad Protocol\r\n.*<title>(?:I2P )?警告：非 HTTP 协议</title>\r\n<link rel=\"shortcut icon\" href=\"http://proxy\.i2p/themes/console/images/favicon\.ico\" ?>\r\n|s p/I2P anonymizing http proxy/ i/Chinese/ cpe:/a:i2p_project:i2p::::zh/
# Also saw Russian-language, so this should catch it:
match http-proxy m|^HTTP/1\.1 403 Bad Protocol\r\nContent-Type: text/html; charset=UTF-8\r\nCache-control: no-cache\r\nConnection: close\r\nProxy-Connection: close\r\n\r\n.*<link rel=\"shortcut icon\" href=\"http://proxy\.i2p/themes/console/images/favicon\.ico\"|s p/I2P anonymizing http proxy/
match http-proxy m|^HTTP/1\.0 503\r\nServer: Charles\r\n| p/Charles http proxy/
match http-proxy m|^ 400 badrequest\r\n.*<title>McAfee Web Gateway - Notification - </title>|s p/McAfee Web Gateway http proxy/ d/proxy server/ cpe:/a:mcafee:web_gateway/
match http-proxy m|^<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4\.01 Transitional//EN" "http://www\.w3\.org/TR/html4/loose\.dtd">\n<HTML><HEAD>\n<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8"> \n<TITLE>\xe9\x94\x99\xe8\xaf\xaf\xef\xbc\x9a\xe6\x82\xa8\xe6\x89\x80\xe8\xaf\xb7\xe6\xb1\x82\xe7\x9a\x84\xe7\xbd\x91\xe5\x9d\x80\xef\xbc\x88URL\xef\xbc\x89\xe6\x97\xa0\xe6\xb3\x95\xe8\x8e\xb7\xe5\x8f\x96</TITLE>\n<STYLE type="text/css"><!--BODY\{background-color:#ffffff;font-family:verdana,sans-serif\}PRE\{font-family:sans-serif\}--></STYLE>\n</HEAD>| p/Squid/ i/Chinese/ cpe:/a:squid-cache:squid::::zh/

match ident m|^0 , 0 : ERROR : UNKNOWN-ERROR\r\n$| p/WatchGuard Firebox firewall identd/ d/firewall/
match ident m|^HELP : USERID : UNIX : trilluser\r\n$| p/Trillian identd/ cpe:/a:trillian:trillian/
match ident m|^HELP : USERID : UNIX : ([-\w_.]+)\r\n$| p/Trillian identd/ i/Name $1/ cpe:/a:trillian:trillian/
# Internet Rex v2.29
match ident m|^\d+, \d+ : USERID : UNIX : [-.@\w]+\r\n| p/Internet Rex identd/
match ident m|^0, 0 : ERROR : UNKNOWN-ERROR$| p/Windows NT identd/ o/Windows/ cpe:/o:microsoft:windows_nt/a

match ipp m|^HTTP/1\.1 405 Method Not Allowed\r\nContent-Length: 23\r\nContent-Type: text/html\r\nUpgrade: TLS/1\.0\r\n\r\n 405 Method Not Allowed| p/Ecosys ipp/ d/print server/

# IRCNet ircd
match irc m|^:([-\w_.]+) 451 \* :You have not registered\r\n$| p/IRCnet-based ircd/ h/$1/
match irc m|^:([-\w_.]+) 020 \* :.*\r\n:[-\w_.]+ 451 \* :You have not registered\r\n| p/IRCnet-based ircd/ h/$1/

# ircu
match irc m|^:([-\w_.]+) 451 \*  :Register first\.\r\n| p/ircu ircd inter-server port/ h/$1/ cpe:/a:undernet:ircu/
match irc m|^:([-\w_.]+) 451 HELP :You have not registered\r\n| p/ircu ircd/ h/$1/ cpe:/a:undernet:ircu/
match irc m|^:([-\w_.]+) 451  HELP :Register first\.\r\n| p/ircu ircd/ h/$1/ cpe:/a:undernet:ircu/
match irc m|^NOTICE AUTH :\*\*\* Checking Ident\r\n:([-\w_.]+) 451 \*  :Register first\.\r\n| p/ircu ircd/ h/$1/ cpe:/a:undernet:ircu/
match irc m|^:([\w._-]+) 451 \* :Connection not registered\r\n| p/ngircd/ h/$1/ cpe:/a:barton:ngircd/
match irc m|^:([\w._-]+) 461 HELP\r\n| p/matterircd/ h/$1/ cpe:/a:42wim:matterircd/
match irc m|^:([-\w_.]+) 290  :\.-----------------=#\[ euIRCd HelpSystem \]#=----------------\.\n| p/euIRCd/ h/$1/

match jabber m|^</stream:stream>$| p/Zimbra 6 jabberd/

match laserfiche m|^HLO 0 0 \. 0 71\r\nContent-type: application/vnd\.laserfiche\.lrnp\r\n\r\nLRNP/1\.1\r\n\r\nlistener\r\nEND\r\nERR 0 1 \. 71 80\r\nContent-type: application/vnd\.laserfiche\.lrnp\r\n\r\n451 0 Invalid message \(-2001\)\r\nEND\r\nMSG 0 2 \. 151 58\r\nContent-type: application/vnd\.laserfiche\.lrnp\r\n\r\nCLOSE 0\r\nEND\r\n$| p/Laserfiche document service/

match lmtp m|^220 ([\w.-]+) LMTP\r\n214-This is DBMail-LMTP\.\r\n214-The following commands are supported:\r\n214-LHLO, RSET, NOOP, QUIT, HELP\.\r\n214-VRFY, EXPN, MAIL, RCPT, DATA\.\r\n214-For more information about a command:\r\n214 Use HELP <command>\.\r\n| p/DBMail lmtpd/ h/$1/ cpe:/a:paul_j_stevens:dbmail/

match nntp m|^200 NNTP server ready\r\n100 Avaliable commands:\r\nARTICLE\r\nAUTHINFO\r\nBODY\r\nGROUP\r\nHEAD\r\nHELP\r\nIHAVE\r\nLAST\r\nLIST\r\nNEWGROUPS\r\nNEWNEWS\r\nNEXT\r\nPOST\r\nQUIT\r\nSLAVE\r\nSTAT\r\nXHDR\r\n\.\r\n| p|Hamster Playground/Kerio nntpd|
match nntp m|^200 ([\w._-]+) news server ready - posting ok\r\n100 Help text follows\r\n$| p/Intersquish nntpd/ o/Windows/ h/$1/ cpe:/o:microsoft:windows/a

match pop3pw m|^200 Welcome to ([\w.-]+) password daemon\.\r\n214-Commands:\r\n214-\tUSER\tPASS\tNEWPASS\tQUIT\tHELP\r\n214-\r\n214-For more info use \"HELP <topic>\"\r\n214 End of HELP info\r\n$| p/Gattaca PASS Server/ o/Windows/ h/$1/ cpe:/o:microsoft:windows/a

match printer m|^([-\w_.]+): lpd: Illegal service request\n$| p/lpd/ h/$1/
match printer m|^\x01Socket \d+ received unknown command 0x48 with arguments ELP$| p/RPM Print Manager lpd/ o/Windows/ cpe:/o:microsoft:windows/a
match printer m|^Command 48 is not supported\n| p/BusyBox lpd/ cpe:/a:busybox:busybox/

match print-monitor m|^false;error while receiving message from client\n$| p/Genius Bytes print monitor/

match bindshell m|^(root@([^:]+):[^#$]+)# bash: HELP: command not found\n\1# \1# $| p/Bash shell/ i/**BACKDOOR**; root shell/ h/$2/ cpe:/a:gnu:bash/
match bindshell m|^(([\w-]+)@([^:]+):[^#$]+)\$ bash: HELP: command not found\n\1\$ \1\$ $| p/Bash shell/ i/**BACKDOOR**; user: $2/ h/$3/ cpe:/a:gnu:bash/
# https://computing.llnl.gov/linux/slurm/
# u32 length, u16 api version, u16 flags (0), u16 msg_type (8001), u32 body_length, u16 forward count, u16 ret count,
# u32 addr, u16 port, len-prefix auth type, u32 auth version, len-prefix auth data, u32 return_code (1008 = SLURM_PROTOCOL_INSANE_MSG_LENGTH)
# API version no longer really tracks software version
# Expect new fingerprints to vary only in the 5th byte
match slurm m|^\0\0\0.\x1b\0\0\0\x1fA\0\0\0\x04\0\0\0\0......\0\0\0\x0bauth/munge\0\0\0\0\n\0\0..MUNGE:[\w/+=]+:\0\0\0\x03\xf0|s p/SLURM/ v/API 2.7/ i|auth/munge|

# Symantec Enterprise Firewall 6.5.2 SMTP proxy on Windows 2000
match smtp m|^220 ([-.+\w]+) Generic SMTP handler\r\n214 Help not supported by this implementation\r\n$| p/Symantec Enterprise Firewall smtp proxy/ h/$1/ cpe:/a:symantec:enterprise_firewall/
# Lotus Notes Domino 6.1 smtp server on Win2K
match smtp m|^220 Welcome to ([-.+\w]+) ESMTP Server at .*\r\n214-Enter one of the following commands:\r\n214-HELO EHLO MAIL RCPT DATA RSET NOOP QUIT\r\n214 HELP VRFY EXPN STARTTLS \r\n$| p/Lotus Notes Domino smtpd/ h/$1/ cpe:/a:ibm:lotus_domino/
match smtp m|^220.*?\n214-Commands supported:\r\n214-    HELO EHLO MAIL RCPT DATA(?: ETRN)?(?: AUTH)?\r\n214     NOOP QUIT RSET HELP \r\n$| p/Exim smtpd/ v/3.X/ cpe:/a:exim:exim:3/
match smtp m|^220.*?\r?\n214-Commands supported:\r\n214 AUTH (?:STARTTLS )?HELO EHLO MAIL RCPT DATA NOOP QUIT RSET HELP(?: VRFY)?\r\n$|s p/Exim smtpd/ v/4.X/ cpe:/a:exim:exim:4/
match smtp m|^220[\s-](\S+) ESMTP ?\r\n214[\s-]qmail home page: http://cr\.yp\.to/qmail\.html, LinuxMagic Support http://www\.linuxmagic\.com\r\n| p/qmail smtpd/ i/LinuxMagic/ h/$1/ cpe:/a:djb:qmail/
match smtp m|^220[\s-](\S+) ESMTP ?\r\n214[- ]qmail home page: http://pobox\.com/~djb/qmail\.html\r\n214[- ]qmail-ldap patch home page: http://www\.nrg4u\.com\r\n| p/qmail-ldap smtpd/ o/Unix/ h/$1/ cpe:/a:djb:qmail/
# Some qmails don't have host ... ?
match smtp m|^220[\s-].*ESMTP ?\r\n214[- ]qmail home page: http://pobox\.com/~djb/qmail\.html\r\n| p/qmail smtpd/ o/Unix/ cpe:/a:djb:qmail/
match smtp m|^220[\s-](\S+) (?:OK )?ESMTP ?\r\n214[- ]qmail home page: http://pobox\.com/~djb/qmail\.html| p/qmail smtpd/ o/Unix/ h/$1/ cpe:/a:djb:qmail/
match smtp m|^220[\s-].*?ESMTP\r\n214 netqmail home page: http://qmail\.org/netqmail\r\n| p/netqmail smtpd/ v/1.04/ o/Unix/
# VirusBuster MailShield for SMTP. Version 1.15.030 on Linux 2.4
match smtp m|^220 ([-.\w]+) SMTP version 1\.00;\r\n214 We strongly advise you to study (?:of )?the RFC ?821\.\.\.\r\n$| p/VirusBuster MailShield for SMTP/ o/$1/
# Postfix 1.1.12, 1.1.13, 2.0.9, 2.0.16
match smtp m|^220 ([-\w_.]+) ESMTP\r\n402 Error: command not implemented\r\n$| p/Postfix smtpd/ h/$1/ cpe:/a:postfix:postfix/a
match smtp m|^220 smtpd\r\n502 [\d.]+ Error: command not recognized\r\n| p/Postfix smtpd/ cpe:/a:postfix:postfix/a
match smtp m|^220 ([-\w_.]+)\r\n502 [\d.]+ Error: command not recognized\r\n| p/Postfix smtpd/ h/$1/ cpe:/a:postfix:postfix/a
match smtp m|^220 ([-\w_.]+) ESMTP (?:[^(]+? )?\(Ubuntu\)\r\n502 5\.5\.2 Error: command not recognized\r\n| p/Postfix smtpd/ o/Linux/ h/$1/ cpe:/a:postfix:postfix/a cpe:/o:canonical:ubuntu_linux/ cpe:/o:linux:linux_kernel/a
match smtp m|^220 (?:.*? )?([-\w_.]+) ESMTP(?: [^\r\n]*)?\r\n502 5\.5\.2 Error: command not recognized\r\n| p/Postfix smtpd/ h/$1/ cpe:/a:postfix:postfix/a
match smtp m|^220 (?:.*? )?([-\w_.]+) ESMTP(?: [^\r\n]*)?\r\n402 4\.5\.2 Error: command not recognized\r\n| p/Postfix smtpd/ h/$1/ cpe:/a:postfix:postfix/a
match smtp m|^220 ([-\w_.]+) SMTP READY\r\n502 5\.5\.2 Error: command not recognized\r\n| p/Postfix smtpd/ h/$1/ cpe:/a:postfix:postfix/a
match smtp m|^220 E?SMTP [^\r\n]*\r\n502 5\.5\.2 Error: command not recognized\r\n| p/Postfix smtpd/ cpe:/a:postfix:postfix/a
match smtp m|^220 .*\r\n502 Error: command not implemented\r\n$| p/Postfix smtpd/ cpe:/a:postfix:postfix/a
match smtp m|^220 ([-\w_.]+) ESMTP \w+\r\n$| p/Postfix smtpd/ h/$1/ cpe:/a:postfix:postfix/a
# Courier ESMTP courier-0.42.0-1.7.3
match smtp m|^220 ([-.\w]+) ESMTP\r\n502 ESMTP command error\r\n$| p/Courier smtpd/ h/$1/
match smtp m|214-2\.0\.0 This is sendmail version (\S+)\r?\n214-2\.0\.0 Topics:|s p/Sendmail/ v/$1/ o/Unix/ cpe:/a:sendmail:sendmail:$1/
match smtp m|214-2\.0\.0 This is sendmail\r\n214-2\.0\.0 Topics:|s p/Sendmail/ o/Unix/ cpe:/a:sendmail:sendmail/
match smtp m|^220 (\S+) E?SMTP Sendmail;| p/Sendmail/ o/Unix/ h/$1/ cpe:/a:sendmail:sendmail/
match smtp m|^220.* Sendmail (\d[-.\w]+) -- HELP not implemented\r\n|s p/Sendmail/ v/$1/ o/Unix/ cpe:/a:sendmail:sendmail:$1/
match smtp m|^220.*214-This is America Online mail version [vV](\S+)|s p/AOL smtpd/ v/$1/
match smtp m|^220.*214 2\.0\.0 http://www\.google\.com/search.*RFC\+2821\s*\r?\n|s p/Google smtpd/
match smtp m|^220.*214 SMTP server comments and bug reports to: \<zmhacks\@nic.funet.fi\>|s p/ZMailer smtpd/
match smtp m|^220.*500 MessageWall: Unrecognized command|s p/MessageWall SMTP proxy/
match smtp m|^220.*500 Unknown or unimplemented command|s p/MAILsweeper SMTP proxy/
match smtp m|^220.*214 See http\:\/\/www\.messagelabs\.com\/support|s p/MessageLabs smtpd/
match smtp m|^220 (\S+) ESMTP Service\r\n502 5\.3\.0 Sendmail Xserve -- HELP not implemented\r\n$| p/Xserve smtpd/ o/Unix/ h/$1/
# Doesn't look like we can always get the host from the following:
match smtp m|^220 .*\r\n214-Commands Supported:\r\n214-HELO EHLO AUTH HELP QUIT MAIL NOOP RSET RCPT DATA ETRN VRFY STARTTLS\r\n214-Copyright \(c\) 1995-200\d, Stalker Software, Inc\.\r\n| p/CommuniGate Pro smtpd/ cpe:/a:stalker:communigate_pro/
match smtp m|^220 Jana-Server ESMTP Service ready\r\n214- Jana Server ([\w.]+)\r\n| p/Jana mail server/ v/$1/ o/Windows/ cpe:/o:microsoft:windows/a
match smtp m|^220 ([-\w_.]+) ESMTP server ready .*\r\n214-This SMTP server is a part of the InterMail E-mail system\.  For\r\n| p/InterMail smtpd/ h/$1/
match smtp m|^220 ([-\w_.]+) ESMTP\r\n535 Authentication required\.\r\n| p/Courier MSA smtpd/ i/Auth required/ h/$1/
match smtp m|^220 ([-\w_.]+) ESMTP\r\n400 STARTTLS is required first\.\r\n| p/Courier MSA smtpd/ i/STARTTLS required/ h/$1/
match smtp m|^220  ESMTP\r\n214 qmail home page: http://pobox\.com/~djb/qmail\.html\r\n| p/qmail smtpd/ cpe:/a:djb:qmail/
match smtp m|^220 ([-\w_.]+) ESMTP\r\n214-Gentoo Linux qmail-([-\w.]+)\r\n214 qmail home page: http://pobox\.com/~djb/qmail\.html\r\n| p/qmail smtpd/ v/$2/ i/Gentoo/ o/Linux/ h/$1/ cpe:/a:djb:qmail/ cpe:/o:gentoo:linux/
match smtp m|^220 .* ESMTP\r\n214-Gentoo Linux qmail-([-\w.]+)\r\n214 qmail home page: http://pobox\.com/~djb/qmail\.html\r\n| p/qmail smtpd/ v/$1/ i/Gentoo/ o/Linux/ cpe:/a:djb:qmail/ cpe:/o:gentoo:linux/
match smtp m|^554 SMTP synchronization error\r\n$| p/Exim smtpd/ cpe:/a:exim:exim/
match smtp m|^220 ([-\w_.]+) ESMTP\r\n214-The following commands are recognized\r\n214-\tdata\tehlo\thelo\thelp\r\n214-\tmail\tnoop\tquit\trcpt\r\n214 \trset\tvrfy\r\n| p/IronPort C60 smtpd/ d/specialized/ o/AsyncOS/ h/$1/ cpe:/o:cisco:asyncos/a
match smtp m|^220 ([-\w_.]+) ESMTP\r\n214-The following commands are recognized\r\n214-\tauth\tdata\tehlo\teuq_full\r\n214-\thelo\thelp\tmail\tnoop\r\n214 \tquit\trcpt\trset\tvrfy\r\n| p/IronPort C600 smtpd/ d/specialized/ o/AsyncOS/ h/$1/ cpe:/o:cisco:asyncos/a
match smtp m|^220  ESMTP\r\n214-The following commands are recognized\r\n214-\tauth\tdata\tehlo\thelo\r\n214-\thelp\tmail\tnoop\tquit\r\n214 \trcpt\trset\tvrfy\r\n| p|Eserv/4 smtpd|
match smtp m|^220 ([-\w_.]+) ESMTP\r\n214-The following commands are recognized\r\n214-\tauth\tdata\tehlo\t| p/IronPort smtpd/ d/specialized/ o/AsyncOS/ h/$1/ cpe:/o:cisco:asyncos/a
match smtp m|^220 ([-\w_.]+) ESMTP ready\r\n214 [\d.]+ Commands: HELO EHLO MAIL RCPT DATA RSET NOOP VRFY QUIT STARTTLS\r\n| p/Kerio smtpd/ h/$1/
match smtp m|^220 \[?([-\w_.]+)\]? ESMTP server ready\.\r\n214-Recognized SMTP commands are:\r\n214-   HELO   EHLO   MAIL   RCPT   DATA   RSET\r\n214-   AUTH   NOOP   QUIT   HELP   VRFY   SOML\r\n214 Mail server account is '([-\w_.]+)'\.\r\n| p|Mercury/32 smtpd| i/Mail server account $2/ h/$1/
match smtp m|^220 ([-\w_.]+) Server ESMTP ready at .*\r\n241-\r\n$| p/BorderWare firewall smtpd/ d/firewall/ h/$1/
match smtp m|^220 ([-\w_.]+) ESMTP \r\n$| p/BorderWare firewall smtpd/ d/firewall/ h/$1/
match smtp m|^220 ([-\w_.]+)\r\n214-Commands supported:\r\n214 AUTH STARTTLS HELO EHLO MAIL RCPT DATA NOOP QUIT RSET HELP\r\n| p/Exim smtpd/ h/$1/ cpe:/a:exim:exim/
match smtp m|^220 ([-\w_.]+) MailShield SMTP\r\n| p/MailShield smtpd/ h/$1/
match smtp m|^220 ([-\w_.]+)\r\n211 DATA EXPN HELO MAIL NOOP QUIT RCPT RSET SAML SEND SOML TURN VRFY\r\n| p/IMail smtpd/ o/Windows/ h/$1/ cpe:/a:ipswitch:imail/ cpe:/o:microsoft:windows/a
match smtp m|^220 ([-\w_.]+) ESMTP\r\n214  qmail home page: http://pobox\.com/~djb/qmail\.html, LinuxMagic Support http://www\.linuxmagic\.com\r\n| p/Linuxmagic qmail-based smtpd/ o/Linux/ h/$1/ cpe:/a:djb:qmail/ cpe:/o:linux:linux_kernel/a
match smtp m|^220 ([-\w_.]+) ESMTP .*\r\n214-qmail home page: http://pobox\.com/~djb/qmail\.html\r\n214 qmail-ldap patch home page: http://www\.nrg4u\.com\r\n| p/qmail smtpd/ i/qmail-ldap support/ h/$1/ cpe:/a:djb:qmail/
match smtp m|^220-([-\w_.]+) ESMTP\r\n220-MagicMail Daemon with Built-In Anti-Spam\r\n220 See http://www\.linuxmagic\.com for info\r\n214 qmail home page: http://cr\.yp\.to/qmail\.html, LinuxMagic Support http://www\.linuxmagic\.com\r\n| p/Linuxmagic qmail-based smtpd/ i/with Anti-Spam/ o/Linux/ h/$1/ cpe:/a:djb:qmail/ cpe:/o:linux:linux_kernel/a
match smtp m|^220 ESMTP Service ready at .*\r\n214-Enter one of the following commands:\r\n214-HELO EHLO MAIL RCPT DATA RSET NOOP QUIT\r\n214 HELP \r\n| p/Lotus Domino smtpd/ cpe:/a:ibm:lotus_domino/
match smtp m|^220 ([-\w_.]+) ESMTP MTA\r\n214-This is Sendmail version AIX([\d.]+)/([\w.]+)\r\n| p/Sendmail/ v/$3/ i/AIX $2/ o/AIX/ h/$1/ cpe:/a:sendmail:sendmail:$3/ cpe:/o:ibm:aix/a
match smtp m|^220 Service ESMTP Ready\r\n214-This is Sendmail version ([\d.]+) \((P[-\w_.]+)\)\r\n.*future enhancements, contact your HP representative|s p/Sendmail/ v/$1 patch $2/ o/HP-UX/ cpe:/a:sendmail:sendmail:$1p$2/ cpe:/o:hp:hp-ux/a
match smtp m|^220 ([-\w_.]+)\r\n502 Command not implemented\r\n| p/IA Mailserver smtpd/ o/Windows/ h/$1/ cpe:/o:microsoft:windows/a
match smtp m|^220 ([-\w_.]+) ESMTP[^\r\n]*\r\n211 DATA HELO EHLO MAIL NOOP QUIT RCPT RSET SAML TURN VRFY\r\n\r\n| p/hMailServer smtpd/ o/Windows/ h/$1/ cpe:/o:microsoft:windows/a
match smtp m|^220 ([-\w_.]+) .*\r\n211 DATA HELO EHLO MAIL NOOP QUIT RCPT RSET SAML TURN VRFY\r\n\r\n| p/hMailServer smtpd/ o/Windows/ h/$1/ cpe:/o:microsoft:windows/a
match smtp m|^220 ([-\w_.]+) - Ready at .*\r\n214-Commands:\r\n214-    HELO  MAIL  RCPT  DATA  RSET  NOOP    QUIT\r\n214-  For more info use 'HELP <topic>'\.\r\n214 End of HELP info\r\n| p/NTMail smtpd/ o/Windows/ h/$1/ cpe:/o:microsoft:windows/a
match smtp m|^220 ESMTP Service ready\r\n500 Command unrecognized\r\n$| p/Zoe Java smtpd/
match smtp m|^220 ([-\w_.]+) \r\n502 Command not implemented\r\n$| p/SmarterMail smtpd/ o/Windows/ h/$1/ cpe:/a:smartertools:smartermail/ cpe:/o:microsoft:windows/a
match smtp m|^220 ([-\w_.]+) ESMTP [-\w_.]+ Mail Server ([\d.]+); .*\r\n214-2\.0\.0 This is [-\w_.]+ Mail Server [-\w_.]+\r\n214-2\.0\.0 Topics:\r\n| p/Merak Mail Server smtpd/ v/$2/ o/Windows/ h/$1/ cpe:/o:microsoft:windows/a
match smtp m|^220 WebMail ESMTP\r\n502 negative vibes\r\n| p/Mozilla Thunderbird WebMail plugin smtpd/ cpe:/a:mozilla:thunderbird/
match smtp m|^220 Mail Server\r\n211 Help:->Supported Commands: HELO,EHLO,QUIT,HELP,RCPT,MAIL,DATA,RSET,NOOP\r\n| p/MailEnable Enterprise/ v/2.0.x/ o/Windows/ cpe:/a:mailenable:mailenable:2.0:-:enterprise/ cpe:/o:microsoft:windows/a
match smtp m|^220 Welcome to the mail server\.\r\n211 DATA EXPN HELO MAIL NOOP QUIT RCPT RSET SAML SEND SOML TURN VRFY\r\n| p/Ipswitch iMail smtpd/ o/Windows/ cpe:/o:microsoft:windows/a
match smtp m|^220 .*\r\n214-This is ArGoSoft Mail Server Pro for WinNT/2000/XP, Version [-\w_.]+ \(([-\w_.]+)\)\r\n| p/ArGoSoft Pro smtpd/ v/$1/ o/Windows/ cpe:/o:microsoft:windows/a
match smtp m|^220 ArGoSoft Mail Server Freeware, Version [-\w_.]+ \(([-\w_.]+)\)\r\n| p/ArGoSoft Freeware smtpd/ v/$1/ o/Windows/ cpe:/o:microsoft:windows/a
match smtp m|^220 ([-\w_.]+) Service ready\.\r\n214- Valid commands are:\r\n214- HELO  MAIL  RCPT  DATA  RSET  QUIT  NOOP\r\n214- HELP  VRFY\r\n214- Commands not valid are:\r\n214- SEND  SOML  SAML  TURN\r\n214- Mail forwarding handled by this server\.\r\n| p|i5/OS V5R4M0 or OS/400 smtpd| h/$1/
match smtp m|^220 Simple Mail Tranfer Service Ready \r\n502 Commande not implement \r\n| p/Brother printer smtpd/ d/printer/
match smtp m|^220 ([-\w_.]+) ESMTP server is ready\r\n.*214-Copyright \(c\) 1995-2004, Stalker Software, Inc\.\r\n|s p/Stalker Software CommuniGate smtpd/ h/$1/ cpe:/a:stalker:communigate/
match smtp m|^220 ([-\w_.]+) ESMTP\r\n211 DATA HELO EHLO MAIL NOOP QUIT RCPT RSET SAML TURN VRFY\r\n| p/hMailServer smtpd/ o/Windows/ h/$1/ cpe:/o:microsoft:windows/a
match smtp m|^220 \[[-\w_.]+\] Courier Mail Server ([-\w_.]+) ESMTP service ready\r\n| p/Courier MSA smtpd/ v/$1/
match smtp m|^220 ([-\w_.]+) ESMTP\r\n214-This is qpsmtpd \r\n214-See http://smtpd\.develooper\.com/\r\n| p/qpsmtpd smtpd/ h/$1/ cpe:/a:ask_bjorn_hansen:qpsmtpd/
match smtp m|^220 ([-\w_.]+) ESMTP Generic Ready\r\n502 Command not implemented\.\r\n| p/MailMarshal smtpd/ h/$1/
match smtp m|^220 ([-\w_.]+) ESMTP SubEthaSMTP\r\n214-This is the SubEthaSMTP ([\w._-]+) server| p/SubEtha smtpd/ v/$2/ h/$1/ cpe:/a:voodoodyne:subethasmtp:$2/
match smtp m|^220 ([-\w_.]+) ESMTP SubEthaSMTP null\r\n| p/SubEtha smtpd/ h/$1/ cpe:/a:voodoodyne:subethasmtp/
match smtp m|^220 ([-\w_.]+) ESMTP SubEthaSMTP (\d[\w._-]*)\r\n| p/SubEtha smtpd/ v/$2/ h/$1/ cpe:/a:voodoodyne:subethasmtp:$2/
match smtp m|^220 ([\w_.-]+) ESMTP.*information about Email Mx, please see http://www\.openwave\.com\r\n|s p/Openwave Email Mx smtpd/ h/$1/
match smtp m|^220 ([\w_.-]+) Welcome\r\n214-ESMTP Mail Server\r\n214-Available commands:\r\n214-    HELO    EHLO    MAIL    RCPT    DATA\r\n214-    RSET    NOOP    QUIT    HELP    VRFY\r\n214-    AUTH    ETRN\r\n214-For information on a specific command, type \"HELP <command>\"\.\r\n214 OK\r\n| p/SurgeMail smtpd/ h/$1/ cpe:/a:netwin:surgemail/
match smtp m|^220 ([\w_.-]+) ESMTP\r\n214-Run 'info anubis' or visit http://www\.gnu\.org/software/anubis/manual/\r\n214 End of HELP info\r\n$| p/GNU Anubis/ h/$1/ cpe:/a:gnu:anubis/
# hMailServer 4.4.1-B273
match smtp m|^220 ([\w_.-]+)\r\n211 DATA HELO EHLO MAIL NOOP QUIT RCPT RSET SAML TURN VRFY\r\n| p/hMailServer/ h/$1/
# Maybe too general, but the greeting was unique.
match smtp m|^220 .+\r\n211 DATA HELO EHLO MAIL NOOP QUIT RCPT RSET SAML TURN VRFY\r\n\r\n| p/hMailServer/
match smtp m|^220 ([\w._-]+) -=- ESMTP\r\n502 unknown command\.\r\n| p/PineApp SeCure SoHo smtpd/ h/$1/ cpe:/a:pineapp:mail-secure/
match smtp m|^220 Ready to receive mail2 -=- ESMTP\r\n502 unknown command\.\r\n| p/PineApp SeCure SoHo smtpd/ cpe:/a:pineapp:mail-secure/
match smtp m|^220 ([\w._-]+) ESMTP service ready\r\n214 2\.0\.0 try reading the RFCs: http://www\.imc\.org/rfcs\.html\r\n| p/PowerMTA smtpd/ h/$1/
match smtp m|^220 SMTP\r\n214-Usage: HELP <topic>\r\n214-Topics:\r\n214-\tHELO EHLO MAIL RCPT DATA\r\n214-\tVRFY EXPN RSET NOOP QUIT\r\n214 End of HELP info\r\n| p/Trend Micro IMSS smtpd/ v/7.0/ o/Windows/ cpe:/o:microsoft:windows/a
match smtp m|^220 ([\w._-]+) ESMTP\r\n214-2\.0\.0 These commands are recognised:\r\n214 2\.0\.0     DATA EHLO HELO HELP MAIL NOOP QUIT RCPT RSET\r\n| p/Koto Internet Services smtpd/ h/$1/
match smtp m|^220 ([\w._-]+) ESMTP\r\n250 2\.0\.0 See http://www\.ietf\.org/rfc/rfc2821\r\n| p|Plan 9 upas/smtpd| o/Plan 9/ h/$1/ cpe:/o:belllabs:plan_9/a
match smtp m|^220 ([\w._-]+) Service ready\r\n214-Commands:\r\n214-\tHELO\tEHLO\tMAIL\tRCPT\tRSET\tNOOP\r\n214-\tQUIT\tHELP\tDATA\tAUTH\tVRFY\tEXPN\r\n214-\r\n214-For more info use \"HELP <topic>\"\r\n214 End of HELP info\r\n| p/Gattaca Server smtpd/ h/$1/
match smtp m|^250 Ok, but unimplemented\r\n220 EventMachine SMTP Server\r\n| p/Mailcatcher smtpd/
match smtp m|^220 uniFLOW SMTP Email Gateway\r\n500 Sorry, not implemented\r\n| p|NT-ware uniFLOW/MOM smtpd|

match smtp-proxy m|^220 SMTP service ready\r\n214-Commands:\r\n214-\tDATA\tRCPT\tMAIL\tQUIT\tRSET\r\n214 \tHELO\tVRFY\tEXPN\tHELP\tNOOP\r\n| p/WatchGuard smtp proxy/ d/firewall/
match smtp-proxy m|^220 ready\r\n214-Commands:\r\n214-    HELO    MAIL    RCPT    DATA\r\n214-    RSET    NOOP    QUIT    HELP\r\n214-    VRFY    EXPN\r\n214-For more info use HELP <topic>\r\n214 End of HELP info\r\n| p/602LAN Suite smtpd/ o/Windows/ cpe:/o:microsoft:windows/a
match smtp-proxy m|^220 ([-\w_.]+) SMTP service ready\r\n214 Help message\r\n| p/CA Secure Content smtp proxy/ h/$1/
match smtp-proxy m|^421 ([-\w_.]+) is too busy\. Please try again later\.\r\n| p/Surfcontrol smtp proxy/ h/$1/
match smtp-proxy m|^220 ([-\w_.]+) SMTP; .*\r\n500 Syntax error, command unrecognized\.\r\n| p/Anti-Spam SMTP Proxy/ h/$1/
match smtp-proxy m|^220 WebShield SMTP MR2\r\n| p/McAfee WebShield smtp proxy/ o/Windows/ cpe:/a:mcafee:webshield_smtp/ cpe:/o:microsoft:windows/a
match smtp-proxy m|^220 SMTP Proxy Server Ready\r\n250 \+OK entry follows, ends in \.\r\n| p/IronMail CipherTrust SMTP Proxy/ cpe:/a:ciphertrust:ironmail/
match smtp-proxy m|^220 SMTP SDC Ready\r\n250 \+OK entry follows, ends in \.\r\n| p/IronMail SMTP proxy/ cpe:/a:ciphertrust:ironmail/
match smtp-proxy m|^220 ([-\w_.]+) SMTP; .* \+\d{4}\r\n500 Syntax error, command unrecognized\r\n| p/Symantec Mail Security smtp proxy/ o/Windows/ h/$1/ cpe:/a:symantec:mail_security/ cpe:/o:microsoft:windows/a
match smtp-proxy m|^220 ([\w._-]+) Symantec Mail Security | p/Symantec Mail Security smtp proxy/ o/Windows/ h/$1/ cpe:/a:symantec:mail_security/ cpe:/o:microsoft:windows/a
match smtp-proxy m|^220 ([-\w_.]+) ESMTP smtprelay service ready\.\r\n214-This is smtprelay\r\n214-Topics:| p/Genua smtprelay/ d/security-misc/ h/$1/
match smtp-proxy m|^220 SMTP ESMTP ready at .*0\r\n214-\r\n214 End of HELP info\r\n| p/SurfControl smtp proxy/ o/Windows/ cpe:/o:microsoft:windows/a
match smtp-proxy m|^220 ([-\w_.]+)\r\n214-HELO domain\r\n214-EHLO domain\r\n214-QUIT\r\n214-MAIL FROM:<reverse-path> \[options\]\r\n| p/RedCondor smtp proxy/ h/$1/
match smtp-proxy m|^220 ([-\w_.]+) ESMTP Ready\r\n211 Help:->Supported Commands: HELO,EHLO,QUIT,HELP,RCPT,MAIL,DATA,RSET,NOOP\r\n| p/NoSpamToday! smtp proxy/ h/$1/
match smtp-proxy m|^220 ([-\w_.]+) SMTP Relay Service ready\r\n500 Syntax error, command unrecognized\r\n| p/Tumbleweed Email Firewall smtp proxy/ o/Windows/ h/$1/ cpe:/o:microsoft:windows/a
match smtp-proxy m|^220 ([\w._-]+) AngelmatoPhylax SMTP proxy\r\n214 see RFC2821\r\n| p/AngelmatoPhylax smtp proxy/ h/$1/
match smtp-proxy m|^503 Synchronization error\r\n| p/Altospam smtp proxy/
match smtp-proxy m|^220 ([\w._-]+)\r\n214-Usage: HELP <topic>\r\n214-Topics:\r\n214-\tHELO EHLO MAIL RCPT DATA\r\n214-\tVRFY EXPN RSET NOOP QUIT\r\n214 End of HELP info\r\n| p/Barracuda Networks Spam Firewall/ h/$1/ cpe:/h:barracudanetworks:spam_%26_virus_firewall_600:-/

match speechd m|^248-  SPEAK           -- say text \r\n248-  KEY             -- say a combination of keys \r\n248-  CHAR            -- say a character \r\n248-  SOUND_ICON      -- execute a sound icon \r\n248-  SET             -- set a parameter \r\n248-  LIST            -- list available arguments \r\n248-  HISTORY         -- commands related to history \r\n248-  QUIT            -- close the connection \r\n248 OK HELP SENT\r\n| p/Speech Dispatcher text to speech/

match tcpmux m|^(sgi_[-.\w]+\r\n(?:[-.\w]+\r\n)*)$| p/SGI IRIX tcpmux/ i/Available services: $SUBST(1, "\r\n", ",")/ o/IRIX/ cpe:/o:sgi:irix/a

match telnet m|^\r\nLDK-300 System\r\nVersion ([\w._-]+) .*\r\nDATE: .*\r\nTIME: .*\r\nSITE NAME.*\r\nENTER PASSWORD: \*| p/AcerTelecom LDK-300 PBX telnetd/ v/$1/ d/PBX/
match telnet m|^HELP\r\n\n\x06 \nATHENA_READ\nATHENA_WRITE\nCHIPVAR_GET\nDEBUGTABLE\nDITEM\nDMEM\nDREG16\nDREG32\nDREG8\nDRV_CAT_FREE\nDRV_CAT_INIT\nDRV_NAME_GET\nDRV_VAL_GET\nDRV_VAL_SET\nEXIT\nGENIOCTL\nGETMIB\nHELP\nHYP_READ       \nHYP_WRITE      \nHYP_WRITEBUFFER\nITEM16\nITEM32\nITEM8\nITEMLIST\nMACCALIBRATE\nMACVARGET\nMACVARSET\nMEM_READ\nMEM_WRITE\nMTAPI\nPITEMLIST\nPRINT_LEVEL\nPROM_READ\nPROM_WRITE\nREAD_FILE\nREBOOT\nRECONF\nRG_CONF_GET\nRG_CONF_SET\nRG_SHELL\nSETMIB\nSHELL\nSTR_READ\nSTR_WRITE\nSYSTEM\nTEST32\nTFTP_GET\nTFTP_PUT\nVER\r\n00>$| p/OpenRG telnetd/ i|Cisco/Linksys WET610N wireless bridge| d/bridge/ o/Linux/ cpe:/o:linux:linux_kernel/a

# http://grey-corner.blogspot.com/2010/12/introducing-vulnserver.html
match vulnserver m|^Welcome to Vulnerable Server! Enter HELP for help\.\nValid Commands:\nHELP\nSTATS \[stat_value\]\nRTIME \[rtime_value\]\nLTIME \[ltime_value\]\nSRUN \[srun_value\]\nTRUN \[trun_value\]\nGMON \[gmon_value\]\nGDOG \[gdog_value\]\nKSTET \[kstet_value\]\nGTER \[gter_value\]\nHTER \[hter_value\]\nLTER \[lter_value\]\nKSTAN \[lstan_value\]\nEXIT\n$| p/Vulnserver/ o/Windows/ cpe:/o:microsoft:windows/

match nut m|^Commands: HELP VER GET LIST SET INSTCMD LOGIN LOGOUT USERNAME PASSWORD STARTTLS\n| p/Network UPS Tools upsd/
match nut m|^Commands: VER REQ HELP LISTVARS LOGOUT LOGIN PASSWORD LISTRW VARTYPE VARDESC ENUM SET INSTCMD LISTINSTCMD INSTCMDDESC FSD MASTER USERNAME STARTTLS\n| p/Network UPS Tools upsd/

# Written in 1986.  More info at
# http://ftp.rge.com/pub/X/X11R5/contrib/xwebster.README
match webster m|^DICTIONARY server protocol:\r\n\r\nContact name is| p/Webster dictionary server/

match xmpp-transport m|^\x05\xff$| p/Spectrum XMPP file transfer/

softmatch smtp m|^220[\s-].*smtp[^\r]*\r\n214[\s-]|i
softmatch ftp m|^220[\s-].*ftp[^\r]*\r\n214[\s-]|i

##############################NEXT PROBE##############################
# SSLv3 ClientHello probe. Will be able to reliably identify the SSL version
# used, unless the server is running SSLv2 only. Note that it will also detect
# TLSv1-only servers, based on a failed handshake alert.
Probe TCP SSLSessionReq q|\x16\x03\0\0S\x01\0\0O\x03\0?G\xd7\xf7\xba,\xee\xea\xb2`~\xf3\0\xfd\x82{\xb9\xd5\x96\xc8w\x9b\xe6\xc4\xdb<=\xdbo\xef\x10n\0\0(\0\x16\0\x13\0\x0a\0f\0\x05\0\x04\0e\0d\0c\0b\0a\0`\0\x15\0\x12\0\x09\0\x14\0\x11\0\x08\0\x06\0\x03\x01\0|
rarity 1
ports 261,271,322,324,443,444,448,465,548,563,585,636,684,853,989,990,992-995,1241,1311,1443,2000,2221,2252,2376,2443,3443,4433,4443,4444,4911,5061,5443,5550,5868,5986,6251,6443,6679,6697,7000,7210,7272,7443,8009,8181,8194,8443,8531,8883,9001,9443,10443,14443,15002,44443,60443
fallback GetRequest

# Unknown service on Vingtor-Stentofon IP intercom echoes only up to the first \n, so softmatching until we know more.
softmatch echo m|^\x16\x03\0\0S\x01\0\0O\x03\0\?G\xd7\xf7\xba,\xee\xea\xb2`~\xf3\0\xfd\x82\{\xb9\xd5\x96\xc8w\x9b\xe6\xc4\xdb<=\xdbo\xef\x10n\0\0\(\0\x16\0\x13\0\n|

# OpenSSL/0.9.7aa, 0.9.8e
match ssl m|^\x16\x03\0\0J\x02\0\0F\x03\0| p/OpenSSL/ i/SSLv3/ cpe:/a:openssl:openssl/

# Microsoft-IIS/5.0 - note that OpenSSL must go above this one because this is more general
match ssl m|^\x16\x03\0..\x02\0\0F\x03\0|s p/Microsoft IIS SSL/ o/Windows/ cpe:/a:microsoft:internet_information_services/ cpe:/o:microsoft:windows/a
# Novell Netware 6 Enterprise Web server 5.1 https
# Novell Netware Ldap over SSL or enterprise web server 5.1 over SSL
match ssl m|^\x16\x03\0\0:\x02\0\x006\x03\0| p/Novell NetWare SSL/ o/NetWare/ cpe:/o:novell:netware/a
# Cisco IDS 4.1 Appliance
match ssl m|^\x16\x03\0\0\*\x02\0\0&\x03\0\xd10:\xbd\\\x8e\xe3\x15\x1c\x0fZ\xe4\x04\x87\x07\xc0\x82\xa9\xd4\x0e\x9c1LXk\xd1\xd2\x0b\x1a\xc6/p\0\0\n\0\x16\x03\0\x026\x0b\0\x022\0| p/Cisco IDS SSL/ d/firewall/
# PGP Corporation Keyserver Web Console 7.0 - custom Apache 1.3
# PGP LDAPS Keyserver 8.X
match ssl m|^\x16\x03\0\0\+\x02\0\0'\x03\0...\?|s p/PGP Corporation product SSL/
# Unreal IRCd SSL
# RemotelyAnywhere
match ssl m|^\x16\x03\0\0\*\x02\0\0&\x03\0\?|
# Tumbleweed SecureTransport 4.1.1 Transaction Manager Secure Port on Solaris
# Dell Openmanage
match ssl m|^\x15\x03[\x01\x00]\0\x02\x01\0$| p/multi-vendor SSL/
# Probably Oracle https?
match ssl m|^}\0\x02\0\0\0\0\0\0\0\0\0\0\0\0\0| p/Oracle https/
match ssl m|^\x15\x03\0\0\x02\x02\(31666:error:1408A0C1:SSL routines:SSL3_GET_CLIENT_HELLO:no shared cipher:s3_srvr\.c:881:\n| p/Webmin SSL Control Panel/
match ssl m|^20928:error:140760FC:SSL routines:SSL23_GET_CLIENT_HELLO:unknown protocol:s23_srvr\.c:565:\n| p/qmail-pop3d behind stunnel/ cpe:/a:djb:qmail/

match ssl m|^\x16\x03\0\0\*\x02\0\0&\x03\0B| p/Tor over SSL/ cpe:/a:torproject:tor/
match ssl m|^\x16\x03\0\0\*\x02\0\0&\x03.*IOS-Self-Signed-Certificate|s p/Cisco IOS ssl/ d/router/
match ssl m|^\x16\x03\0\0\*\x02\0\0&\x03.*\nCalifornia.*\tPalo Alto.*\x0cVMware, Inc\..*\x1bVMware Management Interface|s p/VMware management interface SSLv3/
match ssl m|^\x16\x03\0\0\*\x02\0\0&\x03.*\x0edropbox-client0|s p/Dropbox client SSLv3/ cpe:/a:dropbox:dropbox/
match ssl m|^\x16\x03\0\0\*\x02\0\0&\x03.*vCenterServer_([\w._-]+)|s p/VMware ESXi Server httpd/ v/$1/ cpe:/o:vmware:esxi:$1/

# Alert (Level: Fatal, Description: Protocol Version|Handshake Failure)
match ssl m|^\x15\x03[\x00-\x03]\0\x02\x02[F\x28]|
# Alert (Level: Warning, Description: Close Notify)
match ssl m|^\x15\x03[\x00-\x03]\0\x02\x01\x00|

# Sophos Message Router
match ssl/sophos m|^\x16\x03\0.*Router\$([a-zA-Z0-9_-]+).*Sophos EM Certification Manager|s p/Sophos Message Router/ h/$1/
match ssl/sophos m|^\x16\x03\0.*Sophos EM Certification Manager|s p/Sophos Message Router/

match ssl/openvas m|^\x16\x03\x01\0J\x02\0\0F\x03\x01| p/OpenVAS server/

# Generic: TLSv1.3 ServerHello
match ssl m|^\x16\x03\x03..\x02...\x03\x03|s p/TLSv1.2/
# Generic: TLSv1.2 ServerHello
match ssl m|^\x16\x03\x02..\x02...\x03\x02|s p/TLSv1.1/
# Generic: TLSv1.1 ServerHello
match ssl m|^\x16\x03\x01..\x02...\x03\x01|s p/TLSv1.0/

# Generic: SSLv3 ServerHello
match ssl m|^\x16\x03\0..\x02...\x03\0|s p/SSLv3/
# SSLv3 - TLSv1.3 Alert
match ssl m|^\x15\x03[\0-\x04]\0\x02[\x01\x02].$|s

match adabas m|^,\0,\0\x03\x02\0\0G\xd7\xf7\xbaO\x03\0\?\x05\0\0\0\0\x02\x18\0\xfd\x0b\0\0<=\xdbo\xef\x10n \xd5\x96\xc8w\x9b\xe6\xc4\xdb$| p/ADABAS database/

# Apple Filing Protocol (AFP) over TCP on Mac OS X
# Sometimes we can get a host name or an IP address; those with come before those without.
# These are mostly sorted by the flags field.

# Flags \x80\xfb.
match afp m|^\x01\x03\0\0........\0\0\0\0........\x80\xfb.([^\0\x01]+)[\0\x01].*\tMacintosh\x05\x06AFPX03\x06AFP2\.2\x0eAFPVersion 2\.1\x0eAFPVersion 2\.0\x0eAFPVersion 1\.1.\tDHCAST128|s p/Apple AFP/ i/name: $1; protocol 2.2; Mac OS X 10.1.*/ o/Mac OS X/ cpe:/a:apple:afp_server/a cpe:/o:apple:mac_os_x:10.1/

# Flags \x83\xfb.
match afp m|^\x01\x03\0\0........\0\0\0\0........\x83\xfb.([^\0\x01]+)[\0\x01].*\tMacintosh\x06\x06AFP3\.1\x06AFPX03\x06AFP2\.2\x0eAFPVersion 2\.1\x0eAFPVersion 2\.0\x0eAFPVersion 1\.1.\tDHCAST128.*[\x04\x05]([\w.-]+)\0|s p/Apple AFP/ i/name: $1; protocol 3.1; Mac OS X 10.2.*/ o/Mac OS X/ h/$2/ cpe:/a:apple:afp_server/a cpe:/o:apple:mac_os_x:10.2/
match afp m|^\x01\x03\0\0........\0\0\0\0........\x83\xfb.([^\0\x01]+)[\0\x01].*\tMacintosh\x06\x06AFP3\.1\x06AFPX03\x06AFP2\.2\x0eAFPVersion 2\.1\x0eAFPVersion 2\.0\x0eAFPVersion 1\.1.\tDHCAST128|s p/Apple AFP/ i/name: $1; protocol 3.1; Mac OS X 10.2.*/ o/Mac OS X/ cpe:/a:apple:afp_server/a cpe:/o:apple:mac_os_x:10.2/

match afp m|^\x01\x03\0\0........\0\0\0\0........\x83\xfb.([^\0\x01]+)[\0\x01].*\tMacintosh\x03\x06AFP3\.1\x06AFPX03\x06AFP2\.2.\x06Recon1\rClient Krb v20\0.*[\x04\x05]([\w.-]+)\x01.afpserver/([\w.@-]+)\0|s p/Apple AFP/ i/name: $1; afpserver: $3; protocol 3.1; Mac OS X 10.2.*/ o/Mac OS X/ h/$2/ cpe:/a:apple:afp_server/a cpe:/o:apple:mac_os_x:10.2/

match afp m|^\x01\x03\0\0........\0\0\0\0........\x83\xfb.([^\0\x01]+)[\0\x01].*\tMacintosh\x03\x06AFP3\.1\x06AFPX03\x06AFP2\.2.\tDHCAST128.*[\x04\x05]([\w.-]+)\x01.afpserver/([\w.@-]+)\0|s p/Apple AFP/ i/name: $1; afpserver: $3; protocol 3.1; Mac OS X 10.3.*/ o/Mac OS X/ h/$2/ cpe:/a:apple:afp_server/a cpe:/o:apple:mac_os_x:10.3/
match afp m|^\x01\x03\0\0........\0\0\0\0........\x83\xfb.([^\0\x01]+)[\0\x01].*\tMacintosh\x03\x06AFP3\.1\x06AFPX03\x06AFP2\.2.\tDHCAST128.*[\x04\x05]([\w.-]+)\0|s p/Apple AFP/ i/name: $1; protocol 3.1; Mac OS X 10.3.*/ o/Mac OS X/ h/$2/ cpe:/a:apple:afp_server/a cpe:/o:apple:mac_os_x:10.3/
match afp m|^\x01\x03\0\0........\0\0\0\0........\x83\xfb.([^\0\x01]+)[\0\x01].*\tMacintosh\x03\x06AFP3\.1\x06AFPX03\x06AFP2\.2.\tDHCAST128|s p/Apple AFP/ i/name: $1; protocol 3.1; Mac OS X 10.3.*/ o/Mac OS X/ cpe:/a:apple:afp_server/a cpe:/o:apple:mac_os_x:10.3/

# Flags \x8f\xfa.
match afp m|^\x01\x03\0\0........\0\0\0\0........\x8f\xfa.([^\0\x01]+)[\0\x01].*\tMacintosh\x01\x06AFP3\.1.\tDHCAST128|s p/Apple Airport Extreme AFP/ i/name: $1; protocol 3.1/ d/WAP/ cpe:/h:apple:airport_extreme/

# Flags \x8f\xfb.
match afp m|^\x01\x03\0\0........\0\0\0\0........\x8f\xfb.([^\0\x01]+)[\0\x01].*\tMacintosh\x04\x06AFP3\.2\x06AFP3\.1\x06AFPX03\x06AFP2\.2.\tDHCAST128.*[\x04\x05]([\w.-]+)\x01.afpserver/([-\w_.@]+)\0|s p/Apple AFP/ i/name: $1; afpserver: $3; protocol 3.2; Mac OS X 10.3 - 10.5/ o/Mac OS X/ h/$2/ cpe:/a:apple:afp_server/a cpe:/o:apple:mac_os_x/a
match afp m|^\x01\x03\0\0........\0\0\0\0........\x8f\xfb.([^\0\x01]+)[\0\x01].*\tMacintosh\x04\x06AFP3\.2\x06AFP3\.1\x06AFPX03\x06AFP2\.2.\tDHCAST128.*[\x04\x05]([\w.-]+)\x01.afpserver|s p/Apple AFP/ i/name: $1; protocol 3.2; Mac OS X 10.3 - 10.5/ o/Mac OS X/ h/$2/ cpe:/a:apple:afp_server/a cpe:/o:apple:mac_os_x/a
match afp m|^\x01\x03\0\0........\0\0\0\0........\x8f\xfb.([^\0\x01]+)[\0\x01].*\tMacintosh\x04\x06AFP3\.2\x06AFP3\.1\x06AFPX03\x06AFP2\.2.\tDHCAST128.*[\x04\x05]([\w.-]+)\0|s p/Apple AFP/ i/name: $1; protocol 3.2; Mac OS X 10.3 - 10.5/ o/Mac OS X/ h/$2/ cpe:/a:apple:afp_server/a cpe:/o:apple:mac_os_x/a

match afp m|^\x01\x03\0\0........\0\0\0\0........\x8f\xfb.([^\0\x01]+)[\0\x01].*\tMacintosh\x04\x06AFP3\.2\x06AFP3\.1\x06AFPX03\x06AFP2\.2.\x06Recon1\rClient Krb v2\x0fNo User Authent\0.*[\x04\x05]([\w.-]+)\x01.afpserver/([-\w_.@]+)\0|s p/Apple AFP/ i/name: $1; afpserver: $3; protocol 3.2; Mac OS X 10.5 Server/ o/Mac OS X/ h/$2/ cpe:/a:apple:afp_server/a cpe:/o:apple:mac_os_x_server:10.5/

match afp m|^\x01\x03\0\0........\0\0\0\0........\x8f\xfb.([^\0\x01]+)[\0\x01].*\tMacintosh.\x06AFP3\.3\x06AFP3\.2\x06AFP3\.1\x06AFPX03\x06AFP2\.2.\tDHCAST128.*[\x04\x05]([\w.-]+)\x01.afpserver|s p/Apple AFP/ i/name: $1; protocol 3.3; Mac OS X 10.5/ o/Mac OS X/ h/$2/ cpe:/a:apple:afp_server/a cpe:/o:apple:mac_os_x:10.5/
match afp m|^\x01\x03\0\0........\0\0\0\0........\x8f\xfb.([^\0\x01]+)[\0\x01].*\tMacintosh.\x06AFP3\.3\x06AFP3\.2\x06AFP3\.1\x06AFPX03\x06AFP2\.2.\tDHCAST128|s p/Apple AFP/ i/name: $1; protocol 3.3; Mac OS X 10.5/ o/Mac OS X/ cpe:/a:apple:afp_server/a cpe:/o:apple:mac_os_x:10.5/

match afp m=^\x01\x03\0\0........\0\0\0\0........\x8f\xfb.([^\0\x01]+)[\0\x01].*?(i?Mac(?:mini|Pro|Book(?:Air|Pro)?)?\d+,\d+)\x04\x06AFP3\.3\x06AFP3\.2\x06AFP3\.1\x06AFPX03.\tDHCAST128.*[\x04\x05]([\w.-]+)\x01.afpserver=s p/Apple AFP/ i/name: $1; protocol 3.3; Mac OS X 10.5 - 10.6; $2/ o/Mac OS X/ h/$3/ cpe:/a:apple:afp_server/a cpe:/o:apple:mac_os_x:10.5/ cpe:/o:apple:mac_os_x:10.6/

# Patched version of OS X 10.5 may match these too... wait for corrections
match afp m=^\x01\x03\0\0........\0\0\0\0........\x8f\xfb.([^\0\x01]+)[\0\x01].*?(i?Mac(?:mini|Pro|Book(?:Air|Pro)?)?\d+,\d+)\x04\x06AFP3\.3\x06AFP3\.2\x06AFP3\.1\x06AFPX03.\tDHCAST128.*[\x04\x05]([\w.-]+)\0\0=s p/Apple AFP/ i/name: $1; protocol 3.3; Mac OS X 10.6; $2/ o/Mac OS X/ h/$3/ cpe:/a:apple:afp_server/a cpe:/o:apple:mac_os_x:10.6/

match afp m=^\x01\x03\0\x80........\0\0\0\0........\x8f\xfb.([^\0\x01]+)[\0\x01].*?(i?Mac(?:mini|Pro|Book(?:Air|Pro)?)?\d+,\d+)\x04\x06AFP3\.3\x06AFP3\.2\x06AFP3\.1\x06AFPX03.\tDHCAST128.*[\x04\x05]([\w.-]+)\x01.afpserver=s p/Apple AFP/ i/name: $1; protocol 3.3; Mac OS X 10.5 - 10.6; $2/ o/Mac OS X/ h/$3/ cpe:/a:apple:afp_server/a cpe:/o:apple:mac_os_x:10.5/ cpe:/o:apple:mac_os_x:10.6/
match afp m|^\x01\x03\0\x80........\0\0\0\0........\x8f\xfb.([^\0\x01]+)[\0\x01].*\tMacintosh.\x06AFP3\.3\x06AFP3\.2\x06AFP3\.1\x06AFPX03\x06AFP2\.2.\tDHCAST128.*[\x04\x05]([\w.-]+)\x01.afpserver|s p/Apple AFP/ i/name: $1; protocol 3.3; Mac OS X 10.5/ o/Mac OS X/ h/$2/ cpe:/a:apple:afp_server/a cpe:/o:apple:mac_os_x:10.5/

# Flags \x8f\xfb.
match afp m|^\x01\x03\0\0........\0\0\0\0........\x8f\xfb.([^\0\x01]+)[\0\x01].*AirPort.*AFP3\.2|s p|Apple Airport Extreme/Time Capsule AFP| i/name: $1; protocol 3.2 WAP/ cpe:/h:apple:airport_extreme/
match afp m|^\x01\x03\0\0........\0\0\0\0........\x8f\xfb.([^\0\x01]+)[\0\x01].*TimeCapsule.*AFP3\.3\x06AFP3\.2\x06AFP3\.1.\tDHCAST128.*[\x04\x05]([\w.-]+)\0|s p/Apple Time Capsule AFP/ i/name: $1; protocol 3.3/ d/storage-misc/ h/$2/
match afp m|^\x01\x03\0\0........\0\0\0\0........\x8f\xfb.([^\0\x01]+)[\0\x01].*TimeCapsule.*AFP3\.3\x06AFP3\.2\x06AFP3\.1.\tDHCAST128|s p/Apple Time Capsule AFP/ i/name: $1; protocol 3.3/ d/storage-misc/
match afp m|^\x01\x03\0\0........\0\0\0\0........\x8f\xfb.([^\0\x01]+)[\0\x01].*\tVMware7,1\x04\x06AFP3\.3\x06AFP3\.2\x06AFP3\.1\x06AFPX03.\tDHCAST128\x04DHX2\x06Recon1\rClient\x20Krb\x20v2\0\0.*[\x04\x05]([\w.-]+)\x01.afpserver/([\w.@-]+)\0|s p/Apple AFP/ i/name: $1; afpserver: $3; protocol 3.1; Mac OS X 10.6.3/ o/Mac OS X/ h/$2/ cpe:/a:apple:afp_server/a cpe:/o:apple:mac_os_x/a
# Sometimes the hostname isn't included
match afp m|^\x01\x03\0\0........\0\0\0\0........\x8f\xfb.([^\0\x01]+)[\0\x01].*\tMacintosh\x04\x06AFP3\.2\x06AFP3\.1\x06AFPX03\x06AFP2\.2.\tDHCAST128|s p/Apple AFP/ i/name: $1; protocol 3.2; Mac OS X 10.3 - 10.5/ o/Mac OS X/ cpe:/a:apple:afp_server/a cpe:/o:apple:mac_os_x/a

# Flags \x9f\xf3
match afp m=^\x01\x03\0\0........\0\0\0\0........\x9f\xf3.([^\0\x01]+)[\0\x01].*?(i?Mac(?:mini|Pro|Book(?:Air|Pro)?)?\d+,\d+)\x05\x06AFP3\.4\x06AFP3\.3\x06AFP3\.2\x06AFP3\.1\x06AFPX03=s p/Apple AFP/ i/name: $1; protocol 3.4; OS X 10.9 - 10.11; $2/ o/OS X/ cpe:/a:apple:afp_server/ cpe:/o:apple:mac_os_x:10.10/ cpe:/o:apple:mac_os_x:10.11/ cpe:/o:apple:mac_os_x:10.9/
match afp m|^\x01\x03\0\0........\0\0\0\0........\x9f\xf3.([^\0\x01]+).*?VMware(\d+),(\d+)\x05\x06AFP3\.4\x06AFP3\.3\x06AFP3\.2\x06AFP3\.1\x06AFPX03|s p/Apple AFP/ i/name: $1; protocol 3.4; VMware $2.$3/ o/Mac OS X/ cpe:/a:apple:afp_server/ cpe:/o:apple:mac_os_x/a

# Flags \x9f\xfb.
match afp m=^\x01\x03\0\0........\0\0\0\0........\x9f\xfb.([^\0\x01]+)[\0\x01].*?(i?Mac(?:mini|Pro|Book(?:Air|Pro)?)?\d+,\d+)\x05\x06AFP3\.4\x06AFP3\.3\x06AFP3\.2\x06AFP3\.1\x06AFPX03\x06\tDHCAST128\x04DHX2\x06Recon1\rClient Krb v2\x03GSS\x0fNo User Authent.*\x1b\$not_defined_in_RFC4178@please_ignore$=s p/Apple AFP/ i/name: $1; protocol 3.4; Mac OS X 10.6 - 10.8; $2/ o/Mac OS X/ cpe:/a:apple:afp_server/a cpe:/o:apple:mac_os_x:10.6/ cpe:/o:apple:mac_os_x:10.7/ cpe:/o:apple:mac_os_x:10.8/
match afp m=^\x01\x03\0\0........\0\0\0\0........\x9f\xfb.([^\0\x01]+)[\0\x01].*?(i?Mac(?:mini|Pro|Book(?:Air|Pro)?)?\d+,\d+)\x05\x06AFP3\.4\x06AFP3\.3\x06AFP3\.2\x06AFP3\.1\x06AFPX03\x05\tDHCAST128\x04DHX2\x06Recon1\rClient Krb v2\x03GSS.*\x1b\$not_defined_in_RFC4178@please_ignore=s p/Apple AFP/ i/name: $1; protocol 3.4; Mac OS X 10.6 - 10.8; $2/ o/Mac OS X/ cpe:/a:apple:afp_server/a cpe:/o:apple:mac_os_x:10.6/ cpe:/o:apple:mac_os_x:10.7/ cpe:/o:apple:mac_os_x:10.8/
match afp m|^\x01\x03\0\0........\0\0\0\0........\x9f\xfb.([^\0\x01]+)[\0\x01].*VMware(\d+),(\d+)\x05\x06AFP3\.4\x06AFP3\.3\x06AFP3\.2\x06AFP3\.1\x06AFPX03\x06\tDHCAST128\x04DHX2\x06Recon1\rClient Krb v2\x03GSS\x0fNo User Authent.*\x1b\$not_defined_in_RFC4178@please_ignore$|s p/Apple AFP/ i/name: $1; protocol 3.4; Mac OS X 10.6; VMware $2.$3/ o/Mac OS X/ cpe:/a:apple:afp_server/a cpe:/o:apple:mac_os_x/a
match afp m|^\x01\x03\0\0........\0\0\0\0........\x9f\xfb.([^\0\x01]+)[\0\x01].*Xserve\d+,\d+\x05\x06AFP3\.4\x06AFP3\.3\x06AFP3\.2\x06AFP3\.1\x06AFPX03\x05\tDHCAST128|s p/Apple AFP/ i/name: $1; protocol 3.4; Xserve/ o/Mac OS X/ cpe:/a:apple:afp_server/a cpe:/o:apple:mac_os_x/a
match afp m=^\x01\x03\0\0........\0\0\0\0........\x9f\xfb.([^\0\x01]+)[\0\x01].*?(i?Mac(?:mini|Pro|Book(?:Air|Pro)?)?\d+,\d+)\x05\x06AFP3\.4\x06AFP3\.3\x06AFP3\.2\x06AFP3\.1\x06AFPX03\x05\tDHCAST128\x04DHX2\x06Recon1\x03GSS\x0fNo User Authent=s p/Apple AFP/ i/name: $1; protocol 3.4; OS X 10.8; $2/ o/OS X/ cpe:/a:apple:afp_server/a cpe:/o:apple:mac_os_x:10.8/

softmatch afp m|^\x01\x03\0\0........\0\0\0\0.*AFP|s

match ajp13 m|^AB\0N\x04\x01\x94\0\x06/cccb/\0\0\x02\0\x0cContent-Type\0\0\x17text/html;charset=utf-8\0\0\x0eContent-Length\0\0\x03970\0AB\x03| p/Apache Jserv/

match cpu m|^unsupported auth method\0| p/Plan 9 cpu/ o/Plan 9/ cpe:/o:belllabs:plan_9/a

match decomsrv m|^\x02\0\0\x01\x03\0U\xd0DSQ\x02\0\0\x01\x03\0U\xd0DSQ$| p/Lotus Domino decommission server/ i/decomsrv.exe/ cpe:/a:ibm:lotus_domino/

match dsr-video m|^\0\0\0\0\0\x84\0\x10\x01\xa3{\x10\0\0\0\0$| p/Avocent KVM DSR video/

match ftp m|^220 \r\n451 The parameter is incorrect\. \r\n| p/IIS ftpd/ o/Windows/ cpe:/a:microsoft:internet_information_services/ cpe:/o:microsoft:windows/a
# Better to grab more details elsewhere
softmatch ftp m|^220 .*\r\n451 The parameter is incorrect\. \r\n| p/IIS ftpd/ o/Windows/ cpe:/a:microsoft:internet_information_services/ cpe:/o:microsoft:windows/a

match h.239 m|^BadRecord| p/Polycom People+Content IP H.239/ d/VoIP phone/
match h323q931 m|^\x03\0\x000\x08\x02\0\0}\x08\x02\x80\xe2\x14\x01\0~\0\x1d\x05\x08 \x19\0\x06\0\x08\x91J\0\x05\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0| p/Polycom ViewStation H.323/

match http m|^HTTP/1\.0 500 Internal Server Error\r\nConnection: Close\r\nContent-Type: text/html\r\n.*<p>java\.lang\.Exception: Invalid request: \x16\x03|s p/Dell PowerEdge OpenManage Server Administrator httpd/ o/Windows/ cpe:/a:dell:openmanage_server_administrator/ cpe:/o:microsoft:windows/a
match http m|^HTTP/1\.0 400 Bad Request\nContent-type: text/html\r\nDate: .*\r\nConnection: close\r\n\r\n<HEAD><TITLE>400 Bad Request</TITLE></HEAD>\n<BODY><H1>400 Bad Request</H1>\nUnsupported method\.\n</BODY>\n| p/Brivo EdgeReader access control http interface/ d/security-misc/
match http m|^HTTP/1\.1 400 Bad Request\r\nContent-Length: 30\r\nContent-Type: text/plain\r\n\r\nHTTP requires CRLF terminators| p/CherryPy wsgiserver/ cpe:/a:cherrypy:cherrypy/
match http m|^<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2\.0//EN">\n<html><head>\n<title>501 Method Not Implemented</title>\n</head><body>\n<h1>Method Not Implemented</h1>\n<p>\x16\x03 to /[^ ]* not supported\.<br />\n</p>\n<hr>\n<address>IBM_HTTP_Server at ([\w.-]+) Port \d+</address>\n</body></html>\n| p/IBM HTTP Server/ h/$1/ cpe:/a:ibm:http_server/
match http m|^HTTP/1\.1 400 Bad Request\r\nDate: .*<center>nginx</center>\r\n</body>\r\n</html>\r\n$|s p/nginx/ i/reverse proxy/ cpe:/a:igor_sysoev:nginx/
match http m|^<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2\.0//EN">\n<html><head>\n<title>501 Method Not Implemented</title>\n</head><body>\n<h1>Method Not Implemented</h1>\n<p>\x16\x03 to /[^ ]* not supported\.<br />\n</p>\n<hr>\n<address>Apache Server at ([\w.-]+) Port \d+</address>\n</body></html>\n| p/Apache httpd/ h/$1/ cpe:/a:apache:http_server/a

match http-proxy m|^ 400 badrequest\r\nVia: 1\.0 ([\w.-]+) \(McAfee Web Gateway ([\w._-]+)\)\r\nConnection: Close\r\n| p/McAfee Web Gateway/ v/$2/ i/Via $1/ cpe:/a:mcafee:web_gateway:$2/
match http-proxy m|^HTTP/1\.1 400\r\nConnection: close\r\n\r\nBad request syntax \('\\x16\\x03\\x00\\x00S\\x01\\x00\\x00O\\x03\\x00\?G\\xd7\\xf7\\xba,\\xee\\xea\\xb2`~\\xf3\\x00\\xfd\\x82\{\\xb9\\xd5\\x96\\xc8w\\x9b\\xe6\\xc4\\xdb<=\\xdbo\\xef\\x10n\\x00\\x00\(\\x00\\x16\\x00\\x13\\x00'\)| p/XX-Net web proxy tool/
match http-proxy m|^HTTP/1\.0 414 Request URI too long\r\nContent-Type: text/html\r\nContent-Length: 23\r\nExpires: now\r\nPragma: no-cache\r\nCache-control: no-cache,no-store\r\n\r\nRequest URI is too long| p/Pound http reverse proxy/ cpe:/a:apsis:pound/

match ilo-vm m|^\"\0\x03\0$| p/HP Integrated Lights-Out Virtual Media/ cpe:/h:hp:integrated_lights-out/
match iperf3 m|^\t$|

match login m|^\0\r\nlogin: \^W\^@\^@\^@\^| p/VxWorks logind/ o/VxWorks/ cpe:/o:windriver:vxworks/a

match maxdb m|^.Rejected bad connect packet\0$|s p/SAP MaxDB/

match msexchange-logcopier m|^\x15\x01\0\0\x08\0\0\0\0\x80\t\x03\x08$| p/Microsoft Exchange 2010 log copier/ cpe:/a:microsoft:exchange_server:2010/

# Some echo back the length from the probe?
match modbus m|^\x16\x03\0\0[\0S]\x03[\0\x01]\x80[\x01-\x03]| p/Modbus TCP/
match modbus m|^\x16\x03\0\0[\0S]\x03[\0\x01]\x80[\x0a-\x0b]| p/Modbus TCP/ i/gateway/
# SoftPLC?
match modbus m|^\x16\x03\0\0\0\xfd[\0\x01]\x80[\x01-\x03]\0+$| p/Modbus TCP/
# Mitsubishi variable frequency drive
match modbus m|^\x16\x03\0\0S\x03\0\x93\x01| p/Modbus TCP/

match netbios-ssn m|^\0\0\0%G\xd7\xf7\xba,\xff\xea\xff\xff~\xf3\0\xfd\x82{\xb9\xd5\x96\xc8w\x9b\xe6\xc4\xdb<=\xdbo\xef\x10n\0\0\0\0\x16\0$| p/Konica Minolta bixhub 350 printer smbd/ d/printer/ cpe:/h:konicaminolta:bixhub_350/a

match pbx-alarm m|^1\x0c5\x0c9\x0c\x0b\x03$| p/Aastra Open Interfaces Platform PBX alarm server/ d/PBX/ cpe:/a:aastra:oip/

match pop3-proxy m|^ERR concurrent connection limit in avast! exceeded\(pass:\d+, processes:([\w._-]+)\[\d+\]\)\r\n| p/Avast! anti-virus pop3 proxy/ i/connection limit exceeded by $1/ o/Windows/ cpe:/o:microsoft:windows/

# This funny service runs on port 9001 and seems to echo other service probes,
# however they don't seem to come in any obvious order. Examples:
# ---------- GenericLines ----------
# m|^GET / HTTP/1\.0|
# ---------- GetRequest ----------
# m|^OPTIONS / HTTP/1\.0|
# ---------- SSLSessionReq ----------
# m|^OPTIONS / RTSP/1\.0|
# ---------- SSLv23SessionReq ----------
# m|^\x80\0\0\(r\xfe\x1d\x13\0\0\0\0\0\0\0\x02\0\x01\x86\xa0\0\x01\x97\x7c\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0|
match postx-reporting m|^OPTIONS / RTSP/1\.0| p/PostX IP Reporting alarm system/

match progress m|^\0\0\0\x01\0\x17\0\x14\0\x06\0\0\0.\0\0\0\0\0\0|s p/Progress Database/ cpe:/a:progress:database/

# SecureTransport 5.3
match ptcp m|^\0.\x02\0\0\x02\0CClient /[\d.]+:\d+ has requested unsupported pTCP version 0\x02\0\0\0\0| p/Axway SecureTransport PeSIT over pTCP/ cpe:/a:axway:securetransport/

match ptp-ip m|^\x0c\0\0\0\x05\0\0\0\x03\0\0\0| p/Picture Transport Protocol over IP/

match remoting m|^\.NET\x01\0\x02\0\0\0\0\0\0\0\x02\0\x03\x01\0\x03\0\x01\x01..\0\0System\.Runtime\.Remoting\.RemotingException: |s p/MS .NET Remoting services/ cpe:/a:microsoft:.net_framework/

match siebel m|^\0\0\0\x40\0\0\0\0\0\0\0\x01\0\0\0\0\0\0..\0\0\0\x05\0\0\0\0\0\0\0\0\x4e...\0...\0\0\0\0\0\0\0\0\0\0\0\x05\0\0\0\x0c\0\0\0\x08\0\x12\0\x68\0\0\0\0$| p/Siebel Gateway Name Server/ cpe:/a:oracle:siebel_suite/

match xtel m|^\x15Annuaire \xe9lectronique| p/xteld/ i/French/

match tor m|^\x16\x03\0\0\*\x02\0\0&\x03\0.*T[oO][rR]1.*[\x00-\x20]([-\w_.]+) <identity>|s p/Tor node/ i/Node name: $1/ cpe:/a:torproject:tor/

match storagecraft-image m|^\x15\x01\0\0\x08\0\0\0\0\x80\t\x03\x08\.NET\x01\0\x02\0\0\0\0\0\0\0\x02\0\x03\x01\0\x03\0\x01\x01 \0\0\0Authentication failure on server\x05\0\0\0\0$| p/StorageCraft Image Manager/

match vmware-print m|^\r\0\0+$| p/VMware virtual printing service/

match xamarin m|^ERROR: Another instance is running\n| p/Xamarin MonoTouch/

##############################NEXT PROBE##############################
# This is an RDP connection request with the MSTS cookie set. Some RDP
# listeners (with NLA?) only respond to this one.
# This must be sent before TLSSessionReq because Windows RDP will handshake TLS
# immediately and we don't have a way of identifying RDP at that point.
Probe TCP TerminalServerCookie q|\x03\0\0*%\xe0\0\0\0\0\0Cookie: mstshash=nmap\r\n\x01\0\x08\0\x03\0\0\0|
rarity 7
ports 3388,3389
fallback TerminalServer

# Windows 10
match ms-wbt-server m|^\x03\0\0\x13\x0e\xd0\0\0\x124\0\x02\x1f\x08\0\x02\0\0\0| p/Microsoft Terminal Services/ o/Windows/ cpe:/o:microsoft:windows/a
match ms-wbt-server m|^\x03\0\0\x0b\x06\xd0\0\0\x124\0$| p/Microsoft Terminal Services/ o/Windows XP/ cpe:/o:microsoft:windows_xp/a

##############################NEXT PROBE##############################
# TLSv1.2 ClientHello probe. TLS implementations may choose to ignore (close
# silently) incompatible ClientHello messages like the one in SSLSessionReq.
# This one should be widely compatible, and if we avoid adding non-ssl service
# matches here, we can continue to upgrade it (bytes 10 and 11 and the ranges
# in the match lines)
Probe TCP TLSSessionReq q|\x16\x03\0\0\x69\x01\0\0\x65\x03\x03U\x1c\xa7\xe4random1random2random3random4\0\0\x0c\0/\0\x0a\0\x13\x009\0\x04\0\xff\x01\0\0\x30\0\x0d\0,\0*\0\x01\0\x03\0\x02\x06\x01\x06\x03\x06\x02\x02\x01\x02\x03\x02\x02\x03\x01\x03\x03\x03\x02\x04\x01\x04\x03\x04\x02\x01\x01\x01\x03\x01\x02\x05\x01\x05\x03\x05\x02|
rarity 1
# Remove 3388 and 3389 if the ssl/ms-wbt-server match below doesn't catch stuff well enough.
ports 443,444,465,636,989,990,992,993,994,995,1241,1311,2252,3388,3389,4433,4444,5061,6679,6697,8443,8883,9001
fallback GetRequest

# SSLv3 - TLSv1.3 ServerHello
match ssl m|^\x16\x03[\0-\x04]..\x02\0\0.\x03[\0-\x03]|s
# SSLv3 - TLSv1.3 Alert
match ssl m|^\x15\x03[\0-\x04]\0\x02[\x01\x02].$|s

match autonomic-mrad m|^\x1b\[2J\x1b\[2J\r\n\r\nAutonomic Controls MRAD Bridge version (\d[\w.]+) Release\.\r\nMore info found on the Web http://www\.Autonomic-Controls\.com\r\n\r\nType '\?' for help or 'help <command>' for help on <command>\.\r\n\r\n\r\nError: Unknown command '\x01'\.\r\nError: Unknown command '\x03'\.\r\n| p/Autonomic Controls MRAD Bridge/ v/$1/ d/media device/

match iperf3 m|^\t$|

##############################NEXT PROBE##############################
# SSLv2-compatible ClientHello, 39 ciphers offered.
# Will elicit a ServerHello from most SSL implementations, apart from those
# that are TLSv1-only or SSLv3-only. As it comes after the SSLv3 probe
# (SSLSessionReq), its only added value is the detection of SSLv2-only servers.
# SSLv2-only servers are rare so this probe has a high rarity.
Probe TCP SSLv23SessionReq q|\x80\x9e\x01\x03\x01\x00u\x00\x00\x00 \x00\x00f\x00\x00e\x00\x00d\x00\x00c\x00\x00b\x00\x00:\x00\x009\x00\x008\x00\x005\x00\x004\x00\x003\x00\x002\x00\x00/\x00\x00\x1b\x00\x00\x1a\x00\x00\x19\x00\x00\x18\x00\x00\x17\x00\x00\x16\x00\x00\x15\x00\x00\x14\x00\x00\x13\x00\x00\x12\x00\x00\x11\x00\x00\n\x00\x00\t\x00\x00\x08\x00\x00\x06\x00\x00\x05\x00\x00\x04\x00\x00\x03\x07\x00\xc0\x06\x00@\x04\x00\x80\x03\x00\x80\x02\x00\x80\x01\x00\x80\x00\x00\x02\x00\x00\x01\xe4i<+\xf6\xd6\x9b\xbb\xd3\x81\x9f\xbf\x15\xc1@\xa5o\x14,M \xc4\xc7\xe0\xb6\xb0\xb2\x1f\xf9)\xe8\x98|

rarity 8
ports 443,444,465,548,636,989,990,992,993,994,995,1241,1311,2000,4433,4444,5550,7210,7272,8009,8194,8443,9001
fallback GetRequest

# SSLv2 ServerHello
match ssl m|^..\x04\0.\0\x02|s p/SSLv2/

# TLSv1 ServerHello, compatible with SSLv2:
match ssl m|^\x16\x03\x01..\x02...\x03\x01|s p/TLSv1/

# SSLv3 ServerHello, compatible with SSLv2:
match ssl m|^\x16\x03\0..\x02...\x03\0|s p/SSLv3/

# SSLv3 - TLSv1.3 ServerHello
match ssl m|^\x16\x03[\0-\x04]..\x02\0\0.\x03[\0-\x03]|s

# SSLv3 - TLSv1.2 Alert
match ssl m|^\x15\x03[\0-\x04]\0\x02[\x01\x02].$|s

match iperf3 m|^\t$|
match misys-loaniq m|^\0\0\0#sJ\0\0\0\0\0\0#\0\0\0Invalid time string: \n\0\0\0\0#sJ\0\0\0\0\0\0#\0\0\0Invalid time string: \n\0\0\0\0#sJ\0\0\0\0\0\0#\0\0\0Invalid time string: \n\0\0\0\0#sJ\0\0\0\0\0\0#\0\0\0Invalid time string: \n\0\0\0..sJ\0\0\0\0\0\0..\0\0\n Misys Loan IQ ([\w._-]+) \(Server\)\n Build  : for Windows using Oracle \(built: (\w\w\w \d\d \d\d\d\d_\d\d:\d\d:\d\d) \([\w._-]+@[\w._-]+-C:\\[^)]*\)\)\n Patch Info : \[(?:[\w._-]+(?:, )?)+\]\n\n Environment name: \w+ Prime - \w+\n    ADMCP Primary node: \w+;  Secondary node: \w+; Portdaem Port = (\d+)\n\n Current time: [^\n]*\n On: \w+  \([\w._-]+\)\n OS: (Microsoft Windows[^\n]*)\n MEMORY  \(Tot/Free\) : ([\d.]+) / ([\d.]+) MB\n\n Last Logger Start : [^\n]*\n L$| p/Misys Loan IQ/ v/$1/ i|built $2; portdaem port $3; free memory $6/$5 MB; $4| o/Windows/ cpe:/o:microsoft:windows/a
match misys-loaniq m|^\0\0@\0tJ\0\0\0\0\0\0\0@\0\0\n Misys Loan IQ ([\w._-]+) \(Server\)\n Build  : for Windows using Oracle \(built: (\w\w\w \d\d \d\d\d\d_\d\d:\d\d:\d\d) \([\w._-]+@[\w._-]+-C:\\[^)]*\)\)\n Patch Info : \[\]\n\n Environment name: \w+ \w+\n    ADMCP Primary node: \w+;  Secondary node: \w+; Portdaem Port = (\d+)\n\n Current time: [^\n]*\n On: \w+  \([\w._-]+\)\n OS: (Microsoft Windows[^\n]*)\n MEMORY  \(Tot/Free\) : ([\d.]+) / ([\d.]+) MB\n| p/Misys Loan IQ/ v/$1/ i|built $2; portdaem port $3; free memory $6/$5 MB; $4| o/Windows/ cpe:/o:microsoft:windows/a


##############################NEXT PROBE##############################
# Kerberos AS_REQ with realm NM, server name krbtgt/NM, missing client name.
Probe TCP Kerberos q|\0\0\0\x71\x6a\x81\x6e\x30\x81\x6b\xa1\x03\x02\x01\x05\xa2\x03\x02\x01\x0a\xa4\x81\x5e\x30\x5c\xa0\x07\x03\x05\0\x50\x80\0\x10\xa2\x04\x1b\x02NM\xa3\x17\x30\x15\xa0\x03\x02\x01\0\xa1\x0e\x30\x0c\x1b\x06krbtgt\x1b\x02NM\xa5\x11\x18\x0f19700101000000Z\xa7\x06\x02\x04\x1f\x1e\xb9\xd9\xa8\x17\x30\x15\x02\x01\x12\x02\x01\x11\x02\x01\x10\x02\x01\x17\x02\x01\x01\x02\x01\x03\x02\x01\x02|
rarity 5
ports 88

# MIT 1.2.8
match kerberos-sec m=^\0\0\0[\x88-\x8a]~\x81[\x86-\x88]0\x81[\x83-\x85]\xa0\x03\x02\x01\x05\xa1\x03\x02\x01\x1e\xa2\x11\x18\x0f\d{14}Z\xa4\x11\x18\x0f(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)Z\xa5[\x03-\x05]\x02(?:\x03...|\x02..|\x01.)\xa6\x03\x02\x01\x06\xa9\x04\x1b\x02NM\xaa\x170\x15\xa0\x03\x02\x01\0\xa1\x0e0\x0c\x1b\x06krbtgt\x1b\x02NM\xab\(\x1b&Client not found in Kerberos database\0$=s p/MIT Kerberos/ v/1.2/ i/server time: $1-$2-$3 $4:$5:$6Z/ cpe:/a:mit:kerberos:5-1.2/

# OS X 10.6.2; MIT 1.3.5, 1.6.3, 1.7.
match kerberos-sec m=^\0\0\0[\x6d-\x6f]~[\x6b-\x6d]0[\x69-\x6b]\xa0\x03\x02\x01\x05\xa1\x03\x02\x01\x1e\xa2\x11\x18\x0f\d{14}Z\xa4\x11\x18\x0f(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)Z\xa5[\x03-\x05]\x02(?:\x03...|\x02..|\x01.)\xa6\x03\x02\x01\x06\xa9\x04\x1b\x02NM\xaa\x170\x15\xa0\x03\x02\x01\0\xa1\x0e0\x0c\x1b\x06krbtgt\x1b\x02NM\xab\x0e\x1b\x0cNULL_CLIENT\0$=s p/MIT Kerberos/ v/1.3 - 1.8/ i/server time: $1-$2-$3 $4:$5:$6Z/ cpe:/a:mit:kerberos:5-1/

# Heimdal 1.0.1-5ubuntu4
match kerberos-sec m=^\0\0\0[\x62-\x64]~[\x60-\x62]0[\x5e-\x60]\xa0\x03\x02\x01\x05\xa1\x03\x02\x01\x1e\xa4\x11\x18\x0f(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)Z\xa5[\x03-\x05]\x02(?:\x03...|\x02..|\x01.)\xa6\x03\x02\x01<\xa9\x04\x1b\x02NM\xaa\x170\x15\xa0\x03\x02\x01\0\xa1\x0e0\x0c\x1b\x06krbtgt\x1b\x02NM\xab\x16\x1b\x14No client in request$=s p/Heimdal Kerberos/ i/server time: $1-$2-$3 $4:$5:$6Z/ cpe:/a:heimdal:kerberos/

match kerberos-sec m=^\0\0\0[\x4a-\x4c]~[\x48-\x4a]0[\x46-\x48]\xa0\x03\x02\x01\x05\xa1\x03\x02\x01\x1e\xa4\x11\x18\x0f(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)Z\xa5[\x03-\x05]\x02(?:\x03...|\x02..|\x01.)\xa6\x03\x02\x01D\xa9\x04\x1b\x02NM\xaa\x170\x15\xa0\x03\x02\x01\0\xa1\x0e0\x0c\x1b\x06krbtgt\x1b\x02NM$=s p/Microsoft Windows Kerberos/ i/server time: $1-$2-$3 $4:$5:$6Z/ o/Windows/ cpe:/a:microsoft:kerberos/ cpe:/o:microsoft:windows/a
match kerberos-sec m=^\0\0\0[\x79-\xf0]\0[\x79-\xf0]\0\x01\0\0~[\x71-\xe8]0[\x69-\x80]\xa0\x03\x02\x01\x05\xa1\x03\x02\x01\x1e\xa4\x11\x18\x0f(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)Z\xa5[\x03-\x05]\x02(?:\x03...|\x02..|\x01.)\xa6\x03\x02\x01<\xa9.\x1b.([\w.-]+)\xaa\x1d0\x1b\xa0\x03\x02\x01\0\xa1\x140\x12\x1b\x06kadmin\x1b\x08changepw\xac#\x04!\0\x01Request length was inconsistent=s p/MIT Kerberos/ i/OpenWRT; server time: $1-$2-$3 $4:$5:$6Z; realm: $7/ cpe:/a:mit:kerberos/

match netradio m%^@(?:NETRADIO|MAIN|SYS):[A-Z0-9]+=% p/Yamaha Net Radio/ d/media device/

match qemu-vlan m|^\0\0\0qj\x81n0\x81k\xa1\x03\x02\x01\x05\xa2\x03\x02\x01\n\xa4\x81\^0\\\xa0\x07\x03\x05\0P\x80\0\x10\xa2\x04\x1b\x02NM\xa3\x170\x15\xa0\x03\x02\x01\0\xa1\x0e0\x0c\x1b\x06krbtgt\x1b\x02NM\xa5\x11\x18\x0f19700101000000Z| p/QEMU VLAN listener/ cpe:/a:qemu:qemu/

match sap-gui m|^\0\0\0\x0e\*\*DPTMMSG\*\*\0\0\xf8| p/SAP Gui Dispatcher/ cpe:/a:sap:gui/

softmatch smpp m|^\0\0\0\x10\x80\0\0\0\0\0\0\x03....$|s

# SMB Negotiate Protocol
##############################NEXT PROBE##############################
Probe TCP SMBProgNeg q|\0\0\0\xa4\xff\x53\x4d\x42\x72\0\0\0\0\x08\x01\x40\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x40\x06\0\0\x01\0\0\x81\0\x02PC NETWORK PROGRAM 1.0\0\x02MICROSOFT NETWORKS 1.03\0\x02MICROSOFT NETWORKS 3.0\0\x02LANMAN1.0\0\x02LM1.2X002\0\x02Samba\0\x02NT LANMAN 1.0\0\x02NT LM 0.12\0|
rarity 4
ports 42,88,135,139,445,660,1025,1027,1031,1112,3006,3900,5000,5009,5432,5555,5600,7461,9102,9103,18182,27000-27010

match anynet-sna m|^\0\0MF\xff\xf3MBr\0\0\0\0\x08\x01@\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\0\x81\0\x02PC NETWORK PROGRAM 1\.0\0\x02MICROSOFT NETWORKS 1\.03\0\x02MICROSOFT NETWORKS 3\.0\0\x02LANMAN1\.0\0\x02LM1\.2X002\0\x02Samba\0\x02NT LANMAN 1\.0\0\x02NT LM 0$| p/AnyNet SNA/
match as-signon m|^\0\0\0\x18\xffSMBr\0\0\0\0\x08\x01@\0\x04\xf0\0\0\x01\0\x03$| p/IBM Client Tools signon/

match nomachine-nx m|^...................................................................................................\x00\x00\x00\x00\x00.\x00\x00\x00\x00\x00\x00\x00...\x00\x00\x00\x00\x00...\x84\x8e\x7f\x00\x00......\x00\x00......\x00\x00......\x00\x00......\x00\x00...\x00\x00\x00\x00\x00....\x8e\x7f\x00\x00......\x00\x00......\x00\x00...\x00\x00\x00\x00\x00...\x00\x00\x00\x00\x00...\x00\x00\x00\x00\x00......\x00\x00...\x00\x00\x00\x00\x00....\x00\x00\x00\x00......\x00\x00...\x84\x8e\x7f\x00\x00......\x00\x00......\x00\x00....\x00\x00\x00\x00......\x00\x00...\x00\x00\x00\x00\x00.....\x7f\x00\x00......\x00\x00.\xfe\x7c\x17..\x00\x00......\x00\x00...\x00\x00\x00\x00\x00......\x00\x00......\x00\x00....\x00\x00\x00\x00......\x00\x00...\x00\x00\x00\x00\x00......\x00\x00\x40.....\x00\x00......\x00\x00......\x00\x00......\x00\x00.....\x7f\x00\x00...\x00\x00\x00\x00\x00...\x00\x00\x00\x00\x00...\x00\x00\x00\x00\x00...\x00\x00\x00\x00\x00....\x8e\x7f\x00\x00......\x00\x00...| p/NoMachine NX remote administration/

match airport-admin m|^acpp\0.\0.....\0\0\0\x01| p/Apple AirPort or Time Capsule admin/

match afarianotify m|^\0\0\x017<AfariaNotify version=\"([\w._-]+)\"><Client name=\"\w+\" GUID=\"{[0-9A-F-]+}\"/><Message type=\"Response\" value=\"Client Error\"><Description><!\[CDATA\[\[\w\w\w \w\w\w \d\d \d\d:\d\d:\d\d \d\d\d\d\]\t\[Unrecognized notification header\]:\t\[Expected\]:<AfariaNotify version=\r\n\r\n\]\]></Description></Message></AfariaNotify>| p/Sybase Afaria/ v/$1/ i/Abbott i-STAT blood analyzer/

match ajp13 m|^\0\0\0\x01\0\x0cUnauthorized| p/Oracle Containers for J2EE/ i/unauthorized/ cpe:/a:oracle:containers_for_j2ee/

match bmc-tmart m=^\x15uBMC TM ART Version ([\w._-]+, Build \d+ from [\d-]+), Copyright \? [\d-]+ BMC Software, Inc\. \| All Rights Reserved\.= p/BMC Transaction Management Application Response Time/ v/$1/ cpe:/a:bmc:transaction_management_application_response_time:$1/

match brassmonkey m|^\x08\0\0\0\0\0\x08\x01\0\0\t\0$| p/Brass Monkey controller service/

match byond m|^\0\0\0\x02\0\0$| p/BYOND game platform/

match caigos-conductus m|^\0\0\0\0\0\0\0=r\0\0\0\0\0\0\0\xd8\x97%\x01\x13\0\0\0CONDUCTUS_PG([\w._-]+)\x1a\0\0\0unbekannter Code: 19240920$| p/Conductus/ v/$1/ i/Caigos GIS/
match caigos-pactor m|^\0\0\0\0\0\0\0:r\0\0\0\0\0\0\0\xe8EU\x04\x10\0\0\0PACTOR_PG([\w._-]+)\x1a\0\0\0unbekannter Code: 72697320$| p/Pactor/ v/$1/ i/Caigos GIS/
match caigos-fundus m|^\0\0\0\0\0\0\0;r\0\0\0\0\0\0\0h\xd52\t\x10\0\0\0FUNDUS_PG([\w._-]+)\x1b\0\0\0unbekannter Code: 154326376$| p/Fundus/ v/$1/ i/Caigos GIS/
match caigos-paratus m|^\0\0\0\0\0\0\0;r\0\0\0\0\0\0\0XL\)\x01\x11\0\0\0PARATUS_PG([\w._-]+)\x1a\0\0\0unbekannter Code: 19483736$| p/Paratus/ v/$1/ i/Caigos GIS/
match caigos-conspectus m|^\0\0\0\0\0\0\0>r\0\0\0\0\0\0\0\xf8\x926\x01\x14\0\0\0CONSPECTUS_PG([\w._-]+)\x1a\0\0\0unbekannter Code: 20353784$| p/Conspectus/ v/$1/ i/Caigos GIS/

match digitalwatchdog m|^\x01\0\0\0\0\0\0\(PSPROTOCOL\0\0\0\0\0\0\xa0\0\0\x01\0\0\0\x0c\0\0\0\0\0\0\0\0\xe0\0\0\x04\0\0\0\0\0\0\0\0| p/Digital Watchdog IP camera unknown service/ d/webcam/
# Need more matches. Same response to Kerberos, runs on 1489 and 1490(secure)
match docbroker m|^\0\0\0\x080\x06\x02\x01\0\x02\x01i| p/Documentum Content Server/ cpe:/a:emc:documentum_content_server/
match fastobjects-db m|^\xce\xfa\x01\0\x16\0\0\0\0\0\0\x003\xf6\0\0\0\0\0\0\0\0$| p/Versant FastObjects database/

# Flexlm might be too general: -Doug
match flexlm m|^W.-60\0|s p/FlexLM license manager/
match flexlm m|^W.\0\0\0\0|s p/FlexLM license manager/

match greenplum m|^E\0\0\0\x83SFATAL\0C0A000\0Munsupported frontend protocol 3923\.19778: server supports 1\.0 to 3\.0\0Fpostmaster\.c\0L2504\0RProcessStartupPacket\0\0| p/Greenplum database/

match h2 m|^\x52\x00\x00\x00\x08\x00\x00\x00\x03$| p/H2 database/

match honeywell-hscodbcn m|^\0\0\0\x02\0\x03$| p/Honeywell hscodbcn power management server/

match http m|^HTTP/1\.0 503 OK\r\nContent-Type: text/html\r\n\r\nBusy$| p/D-Link DI-524 WAP http config/ d/WAP/ cpe:/h:dlink:di-524/
match http m|^HTTP/1\.1 414 Request URI Too Long\r\nServer: Catwalk\r\nDate: .*\r\nContent-Length: 0\r\nConnection: close\r\n\r\n$| p/Catwalk httpd/ i/Canon imageRUNNER printer/ d/printer/
match iperf3 m|^\t$|

# Need more examples of this one -Doug
match kerberos-sec m|^.*Internal KDC error, contact administrator|s p/Shishi kerberos-sec/

match libvirt-rpc m|^\0\0\0\xb8\xffSMBr\0\0\0\0\x08\x01@\0\0\0\x01\0\0\0\0\0\0\0\x01\0\0\0'\0\0\0\x07\0\0\0\x01\0\0\0\x30Cannot find program -11317950 version 1912602624\0\0\0\x02\0\0\0\0\0\0\0\x01\0\0\0\x02%s\0\0\0\0\0\x01\0\0\0\x30Cannot find program -11317950 version 1912602624\0\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0| p/libvirt RPC/ cpe:/a:redhat:libvirt/

match lorex-monitor m|^\0\0\x01\x01@\n\0\x08\x80\0\x82\0L\xb8..\xff\xff\xff\xff\0\0\0\0$|s p/Lorex security camera monitor/ d/webcam/

match metatrader m|^A$| p/MetaTrader Data Center/

# Longhorn
match microsoft-ds m|^\0\0\0.\xffSMBr\0\0\0\0\x88\x01@\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\x11\x07\0.\n\0\x01\0\x04\x11\0\0\0\0\x01\0\0\0\0\0\xfd\xe3\x03\0|s p/Microsoft Windows Longhorn microsoft-ds/ o/Windows/ cpe:/o:microsoft:windows/a
# Windows XP SP1
match microsoft-ds m|^\0\0\0.\xffSMBr\0\0\0\0\x88\x01@\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\x11\x07\0.\n\0\x01\0\x04\x11\0\0\0\0\x01\0\0\0\0\0\xfd\xe3\0\0|s p/Microsoft Windows XP microsoft-ds/ o/Windows XP/ cpe:/o:microsoft:windows_xp/a
match microsoft-ds m|^\0\0\0.\xffSMBr\0\0\0\0\x88\x01@\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\x11\x07\0.2\0\x01\0\x04A\0\0\0\0\x01\0\0\0\0\0\xfd\xf3\0\0|s p/Microsoft Windows 2000 microsoft-ds/ o/Windows 2000/ cpe:/o:microsoft:windows_2000/a
# Microsoft Windows 2003 or 2008
match microsoft-ds m|^\0\0\0.\xffSMBr\0\0\0\0\x88\x01@\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\x11\x07\0.2\0\x01\0\x04.\0\0\0\0\x01\0\0\0\0\0\xfd\xf3\x01\0|s p/Microsoft Windows 2003 or 2008 microsoft-ds/ o/Windows/ cpe:/o:microsoft:windows_server_2003/a
# Microsoft Windows 2000 Server
# Microsoft Windows 2000 Server SP4
match microsoft-ds m|^\0\0\0.\xffSMBr\0\0\0\0\x88\x01@\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\x11\x07\0.[}2]\0\x01\0\x04A\0\0\0\0\x01\0\0\0\0\0\xfd[\xe3\xf3]\0\0|s p/Microsoft Windows 2000 microsoft-ds/ o/Windows 2000/ cpe:/o:microsoft:windows_2000/a
match microsoft-ds m|^\0\0\0.\xffSMBr\0\0\0\0\x88\x01@\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\x11\x07\0.2\0\x01\0\x04A\0\0\0\0\x01\0\0\0\0\0\xfc\xe3\x01\0|s p/Microsoft Windows Server 2008 R2 - 2012 microsoft-ds/ o/Windows Server 2008 R2 - 2012/ cpe:/o:microsoft:windows/
match microsoft-ds m|^\0\0\0.\xffSMBr\0\0\0\0\x88\x01@\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\x11\x07\0.2\0\x01\0\x04A\0\0\0\0\x01\0\0\0\0\0\xfc\xf3\x01\0.{21}((?:..)*)\0\0((?:..)*)\0\0|s p/Microsoft Windows Server 2008 R2 - 2012 microsoft-ds/ i/workgroup: $P(1)/ o/Windows/ h/$P(2)/ cpe:/o:microsoft:windows/
match microsoft-ds m|^\0\0\0.\xffSMBr\0\0\0\0\x88\x01@\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\x11\x07\0.\n\0\x01\0\x04\x11\0\0\0\0\x01\0\0\0\0\0\xfc\xe3\x01\0.{21}((?:..)*)\0\0((?:..)*)\0\0|s p/Microsoft Windows 7 - 10 microsoft-ds/ i/workgroup: $P(1)/ o/Windows/ h/$P(2)/ cpe:/o:microsoft:windows/
match microsoft-ds m|^\0\0\0.\xffSMBr\0\0\0\0\x88\x01@\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\x11\x07\0.\n\0\x01\0\x04\x11\0\0\0\0\x01\0\0\0\0\0\xfc\xe3\x01\0|s p/Microsoft Windows 7 - 10 microsoft-ds/ o/Windows/ cpe:/o:microsoft:windows/
match microsoft-ds m|^\0\0\0.\xffSMBr\0\0\0\0\x88\x01@\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\x11\x07\0.2\0\x01\0\x04\x11\0\0\0\0\x01\0\0\0\0\0\xfc\xe3\x01\0.{21}(.*)\0\0(.*)\0\0|s p/Microsoft Windows 7 - 10 microsoft-ds/ i/workgroup: $P(1)/ o/Windows/ h/$P(2)/ cpe:/o:microsoft:windows/
match microsoft-ds m|^\0\0\0.\xffSMBr\0\0\0\0\x88\x01@\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\x11\x07\0.2\0\x01\0\x04\x11\0\0\0\0\x01\0\0\0\0\0\xfc\xe3\x01\0|s p/Microsoft Windows 7 - 10 microsoft-ds/ o/Windows/ cpe:/o:microsoft:windows/
match microsoft-ds m|^\0\0\0.\xffSMBr\0\0\0\0\x88\x01@\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\x11\x07\0.2\0\x01\0\x04A\0\0\0\0\x01\0\0\0\0\0\xfd\xe3\x01\0.{21}((?:..)*)\0\0((?:..)*)\0\0|s p/Microsoft Windows Server 2008 R2 microsoft-ds/ i/workgroup: $P(1)/ o/Windows/ h/$P(2)/ cpe:/o:microsoft:windows_server_2008:r2/a
match microsoft-ds m|^\0\0\0.\xffSMBr\0\0\0\0\x88\x01@\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\x11\x07\0.\x10\0\x01\0\x04\x11\0\0\0\0\x01\0\0\0\0\0\xfc\xe3\x01\0.{21}((?:..)*)\0\0((?:..)*)\0\0|s p/Microsoft Windows Embedded Standard microsoft-ds/ i/workgroup: $P(1)/ o/Windows/ h/$P(2)/ cpe:/o:microsoft:windows/a
match microsoft-ds m|^\0\0\0.\xffSMBr\0\0\0\0\x88\x01@\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\x11\x07\0.\x10\0\x01\0\x04\x11\0\0\0\0\x01\0\0\0\0\0\xfd\xe3\0\0.{21}((?:..)*)\0\0((?:..)*)\0\0|s p/Microsoft Windows XP Embedded microsoft-ds/ i/workgroup: $P(1)/ o/Windows/ h/$P(2)/ cpe:/o:microsoft:windows_xp/a
match microsoft-ds m|^\0\0\0.\xffSMBr\0\0\0\0\x88\x01@\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\x11\x07\0.\x0a\0\x01\0\x04\x11\0\0\0\0\x01\0\0\0\0\0\xfd\xe3\x01\0.{21}((?:..)*)\0\0((?:..)*)\0\0|s p/Microsoft Windows Vista Embedded microsoft-ds/ i/workgroup: $P(1)/ o/Windows/ h/$P(2)/ cpe:/o:microsoft:windows_vista/a

match microsoft-ds m|^\0\0\0.\xffSMBr\0\0\0\0\x88\x01@\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\x11\x07\0.\x05\0\x01\0\x04\x11\0\0\0\0\x01\0\xad\x05\0\0|s p|IBM OS/400 microsoft-ds| o|OS/400| cpe:/o:ibm:os_400/a

# Xerox WorkCentre Pro c3545 and Xerox DocumentCentre 425
match microsoft-ds m|^\0\0\0.\xffSMBr\0\0\0\0\x81\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\r\x03\0|s p/Xerox printer microsoft-ds/ d/printer/
match microsoft-ds m|^\0\0\0\x61\xffSMBr\0\0\0\0\x88\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\x11\x06\0\x02\x0a\0\x01\0....\xff\xff\x00\x00....\0\x03\0\0\0|s p/Xerox WorkCentre 5225 printer microsoft-ds/ d/printer/ cpe:/h:xerox:workcentre_5225/a
# FujiXerox ApeosPort-IV C4470
# Xerox WorkCentre 5225
match microsoft-ds m|^\0\0\0\x61\xffSMBr\0\0\0\0\x88\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\x11\x06\0\x02\x0a\0\x01\0\x04\x11\0\0\xff\xff\0\0....\0\x03\0\0..........\x08\x1c\0........\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0$|s p/Xerox printer microsoft-ds/ d/printer/
match microsoft-ds m|^\0\0\0\x3d\xffSMBr\0\0\0\0\x88\0\x40\0\0\0\0\0\0\0\0\0\0\0\0\0\0..\0\0\x01\0\r\x04\0\x01\0\xfc\x032\0\x03\0\0\0\0\0\0\0......\0\0\0\0\0\0|s p/Edimax PS-1206P print server smbd/ d/print server/
match microsoft-ds m|^\0\0\0\x4d\xffSMBr\0\0\0\0\x88\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0..\0\0\x01\0\x11\x07\0\x02\x02\0\x01\0\xfc\x7f\0\0\0\0\x01\0\x01\0\0\0\0\x02\0\0..........\x08\x08\0\0\0\0\0\0\0\0\0|s p/Sharp MX-M350N printer smbd/ d/printer/ cpe:/h:sharp:mx-m350n/a
match microsoft-ds m|^\0...\xffSMBr\0\0\0\0\x81\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0..\0\0\x01\0\x11\x06\0\x03\x7f\0\x01\0\xff\xff\0\0\xff\xff\0\0\0\0\0\0\xfd\xb3\0\0..........\x08\x22\0........((?:\w\0)+)\0\0((?:\w\0)+)\0\0$|s p/EMC Celerra NAS device smbd/ i/Primary domain: $P(1)/ h/$P(2)/
match microsoft-ds m|^\0...\xffSMBr\0\0\0\0\x98\x01\x40\0\0\0\0\0\0\0\0\0\0\0\0\xff\xff\x40\x06\0\0\x01\0\x11\x07\0\x03\x01\0\x01\0\0\x10\0\0\0\0\x01\0\0\0\0\0\xfd\xe3\0\0..........\x00\x34\0W\0O\0R\0K\0G\0R\0O\0U\0P\0\0\0H\0O\0M\0E\0U\0S\0E\0R\0-\0.\0.\0.\0.\0.\0.\0\0\0|s p/Dionaea honeypot smbd/
match microsoft-ds m|^\0...\xffSMBr\0\0\0\0\x98\x02\xc8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x40\x06\0\0\x01\0\x11\x07\0\x032\0\x01\0\x04\x41\0\0\0\0\x01\0\0\0\0\0\xfc\xc0\0\x80..........\0..................\x60\x5f\x06\x06\+\x06\x01\x05\x05\x02\xa0U0S\xa0\+0\)\x06\t\*\x86H\x86\xf7\x12\x01\x02\x02\x06\x05\+\x05\x01\x05\x02\x06\t\*\x86H\x82\xf7\x12\x01\x02\x02\x06\n\+\x06\x01\x04\x01\x827\x02\x02\n\xa3\$0\"\xa0 \x1b\x1e[\w._-]+/([\w._-]+)@$|s p/Likewise smbd/ h/$1/
# key was \xd7\xd7\xd8\xd8\xd8\xd8\xd8\xd9
match microsoft-ds m|^\0...\xffSMBr\0\0\0\0\x88\x01@\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\x11\x07\0\x03\n\0\x01\0<\[\0\0\0\0\x01\0\0\0\0\0\\\0\0\0........\0\0\x08\x08\0........| p/HP Officejet Pro 8600 printer smbd/ d/printer/ cpe:/h:hp:officejet_pro_8600/a
# key was 4 bytes repeated
match microsoft-ds m|^\0...\xffSMBr\0\0\0\0\x88\x03\xc0\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\x11\x07\0\x02\x01\0\x01\0\xff\xff\0\0\0\0\x01\0\0\0\0\0\}\xa2\0\0..........\x08\x08\0........|s p/Arcadyan ARV752DPW22 (Vodafone EasyBox 803A) WAP smbd/ d/WAP/ cpe:/h:arcadyan:arv752dpw22/
match microsoft-ds m|^\0...\xffSMBr\0\0\0\0\x88\x01H\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\x11\x07\0\x03\n\0\x01\0\0\0\x01\0\0\0\x01\0\0\0\0\0\x7c\xe0\0\0..........\x08\x08\0........|s p/Epson WF-2650 printer smbd/ d/printer/ cpe:/h:epson:wf-2650/a
match microsoft-ds m|^\0...\xffSMBr\0\0\0\0\x88\x01@\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\x11\x07\0\x03\n\0\x01\0\xec\xfa\0\0\0\0\x01\0\0\0\0\0\x7c \0\0..........\x08\x08\0........|s p/Apple Time Capsule smbd/ d/storage-misc/
match microsoft-ds m|^\0...\xffSMBr\0\0\0\0\x88C@\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\x11\x07\0\x03\xff\xff\x01\0\x04A\0\0\x04A\0\0....\xfc\x02\0\0.{21}((?:..)+)\0\0((?:..)+)\0\0| p/Acopia ARX switch smbd/ i/workgroup: $P(1)/ d/storage-misc/ h/$P(2)/
match microsoft-ds m|^\0\0\0.\xffSMBr\0\0\0\0\x88\x01@\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\x11\x07\0\x02\x01\0\x01\0h\x0b\0\0\xff\xff\0\0\0\0\0\0\x07\x02\0\0\0\0\0\0\0\0\0\0..\x08\x08\0\0\0\0\0\0\0\0\0| p/Fujitsu Storagebird LAN smbd/ d/storage-misc/ cpe:/h:fujitsu:storagebird_lan/
match microsoft-ds m|^\0\0\0.\xffSMBr\0\0\0\0\x88\x01H\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\x11\x07\0\x03\n\0\x01\0\0\0\x01\0\0\0\x01\0\0\0\0\0\x7c \0\0..........\x08\x08| p/Epson printer smbd/ d/printer/
match microsoft-ds m|^\0\0\0a\xffSMBr\0\0\0\0\x80\0{16}@\x06\0\0\x01\0\x11\x07\0\x03\x01\0\x14\0@\x1e\0\0\xff\xff\0\0....\x14\x02\0{10}..\x08\x1c\0.{8}((?:(?!\0\0).)+?)\0\0| p/Canon Pixma printer smbd/ i/workgroup: $P(1)/ d/printer/

# Microsoft Windows XP SP1
# Windows 2000
match msrpc m|^\x05\0\r\x03\x10\0\0\0\x18\0\0\0....\x04\0\x01\x05\0...$|s p/Microsoft Windows RPC/ o/Windows/ cpe:/o:microsoft:windows/a
# Microsoft Windows 2000
# samba-2.2.7-5.8.0 on RedHat 8
# samba-2.2.7a-8.9.0 on Red Hat Linux 7.x
match netbios-ssn m|^\0\0\0.\xffSMBr\0\0\0\0\x88\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\x11\x06\0.*\W([-_.\w]+)\0$|s p/Samba smbd/ i/workgroup: $1/ cpe:/a:samba:samba/
# Samba 2.999+3.0.alpha21-5 on Linux
# Samba 3.0.0rc4-Debian
# Samba 4.1.6-ubuntu
# Samba 3.6.x on FreeBSD
# Samba 3.0.x based SMB implementation by Apple
match netbios-ssn m|^\0\0\0.\xffSMBr\0\0\0\0\x88..\0\0[-\w. ]*\0+@\x06\0\0\x01\0\x11\x06\0.{42}(.*)\0\0(.*)\0\0$|s p/Samba smbd/ v/3.X - 4.X/ i/workgroup: $P(1)/ h/$P(2)/ cpe:/a:samba:samba/
# The line below may no longer be required and seems to miss the first capture on test systems
match netbios-ssn m=^\0\0\0.\xffSMBr\0\0\0\0\x88..\0\0[-\w. ]*\0+@\x06\0\0\x01\0\x11\x06\0.*(?:[^\0]|[^_A-Z0-9-]\0)((?:[-\w]\0){2,50})=s p/Samba smbd/ v/3.X - 4.X/ i/workgroup: $P(1)/ cpe:/a:samba:samba/
match netbios-ssn m|^\0\0\0.\xffSMBr\0\0\0\0\x88..\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\x11\x06\0..\0\x01\0..\0\0...\0..\0\0|s p/Samba smbd/ v/3.X - 4.X/ cpe:/a:samba:samba/
# Samba 2.2.8a on Linux 2.4.20
match netbios-ssn m|^\x83\0\0\x01\x81$| p/Samba smbd/ cpe:/a:samba:samba/
match netbios-ssn m|^\0\0\0.\xffSMBr\0\0\0\0\x88..\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\x01\xff\xff\0\0$|s p/Samba smbd/ v/4.6.2/ cpe:/a:samba:samba:4.6.2/
# DAVE 4.1 enhanced windows networks services for Mac on Mac OS X
match netbios-ssn m|^\0\0\0.\xffSMBr\x02\0Y\0\x98\x01.\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\0\x07\0|s p/Thursby DAVE Windows filesharing/ i/Runs on Macintosh systems/ o/Mac OS/ cpe:/o:apple:mac_os/a
# Windows Session Service - 139/tcp - Formerly Window 98 match, actually matches Win 98 through Windows 8 / 2012 R2
match netbios-ssn m|^\x83\0\0\x01\x8f$| p/Microsoft Windows netbios-ssn/ o/Windows/ cpe:/o:microsoft:windows/a
# Netware might just be using Samba?
match netbios-ssn m|^\0\0\0M\xffSMBr\0\0\0\0\x80\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\x11\x07\0\x032\0\x01\0\xff\xff\0\0\0\0\x01\0| p/NetWare 6 SMB Services/ o/NetWare/ cpe:/o:novell:netware:6/
# Network Appliance ONTAP 6.3.3 netbios-ssn
match netbios-ssn m=^\0\0\0.\xffSMBr\0\0\0\0\x98\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\x11\x07\0.*(?:[^\0]|[^_A-Z0-9-]\0)((?:[-\w]\0){2,50})=s p/Netapp ONTAP smbd/ i/workgroup: $P(1)/ cpe:/a:netapp:data_ontap/
match netbios-ssn m|^\0\0\0.\xffSMBr\0\0\0\0\x98\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\x11\x07\0.*\W([-_.\w]+)\0$| p/Netapp ONTAP smbd/ i/workgroup: $1/ cpe:/a:netapp:data_ontap/
match netbios-ssn m|^\0\0\0M\xffSMBr\0\0\0\0\x88\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\x11\x07\0\x02\x02\0\x01\0\0\x80\0\0\0\0\x01\0\x01\0\0\0\0\x02\0\0| p/Kyocera FS-1030D printer smbd/ d/printer/ cpe:/h:kyocera:fs-1030d/a
match netbios-ssn m|^\x82\0\0\0\n-> doHttp: Connection timeouted!\n\ntelnetd: This system \*IN USE\* via telnet\.\nshell restarted\.\n\x08\x08\x08\x08        \*\*\*  EPSON Network Print Server \(([^)]+)\)  \*\*\*\n\n\x08\x08\x08\x08        \nPassword: | p/Epson print server smbd/ v/$1/ d/print server/
match netbios-ssn m|^\0\0\0M\xffSMBr\0\0\0\0\x98. \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\x11\x07\0\x03\x32\0\x01\0....\x00\x00\x01\x00....\xf4\xc2\0\0|s p/IOGear GMFPSU22W6 print server smbd/ d/print server/ cpe:/h:iogear:gmfpsu22w6/a
# match netbios-ssn m|^\0\0\0M\xffSMBr\0\0\0\0\x98\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\x11\x07\0\x032\0\x01\0\x04A\0\0\0\0\x01\0 \0\0\0\xf4\xc2\0\0\x80\x1e\xdd\x8b\xe7\?\xca\x01 \xfe\x08\x08\0z~\xc7\*\xc9\x1f\xd3\x9b"
match netbios-ssn m|^\0\0\0M\xffSMBr\0\0\0\0\x98\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\x11\x07\0\x02\x01\0\x01\0\xff\xff\0\0\xff\xff\0\0\0\0\0\0\x01\x02\0\0| p/Brother MFC-820CW printer smbd/ d/printer/ cpe:/h:brother:mfc-820cw/a
match netbios-ssn m|^\0\0\0G\xffSMBr\0\0\0\0\x88\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\r\x04\0\0\0\xa0\x05\x02\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0WORKGROUP\0$| p/Citizen CLP-521 printer smbd/ d/printer/ cpe:/h:citizen:clp-521/
match netbios-ssn m|^\0\0\0G\xffSMBr\0\0\0\0\x88\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\r\x04\0\0\0\xa0\x05\x02\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0| p/Kyocera Mita KM-1530 printer smbd/ d/printer/ cpe:/h:kyocera:mita_km-1530/a
match netbios-ssn m|^\x82\0\0\0$| p/Konica Minolta bizhub C452 printer smbd/ d/printer/ cpe:/h:konicaminolta:bizhub_c452/

# Too broad, but also gives good info
softmatch microsoft-ds m|^\0\0..\xffSMBr\0\0\0\0[\x80-\xff]..\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\x11[\x01-\x07]\0.{42}(.*)\0\0(.*)\0\0$|s i/workgroup: $P(1)/ h/$P(2)/
softmatch microsoft-ds m|^\0\0..\xffSMBr\0\0\0\0[\x80-\xff]..\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\x06\0\0\x01\0\x11[\x01-\x07]\0|s

match remote-volume m|^\0\0\0\x18\xffSMB\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\x01\0\0\0| p/NetApp Remote Volume protocol/
match netradio m%^@(?:NETRADIO|MAIN|SYS):[A-Z0-9]+=% p/Yamaha Net Radio/ d/media device/

match nightwatchman m|^ACKDONEV\$\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0([\d.]+)\0\0\0| p/1E NightWatchman WakeUp Server/ v/$1/

# HP OpenView Storage Data Protector A.05.10 on Windows 2000
# Hewlett Packard Omniback 4.1 on Windows NT
match omniback m|^\0\0\0.\xff\xfe1\x005\0\0\0 \0\x07\0\x01\0\[\x001\x002\0:\x001\0\]\0\0\0 \0\x07\0\x02\0\[\x002\x000\x000\x003\0\]\0\0\0 |s p/HP OpenView Omniback/ o/Windows/ cpe:/o:microsoft:windows/a
# HP OpenView Storage Data Protector A.05.10 on Linux
match omniback m|^\0\0\0.15\0 \x07\x01\[12:1\]\0 \x07\x02\[2003\]\0 \x07\x051\d+\0 INET\0 ([\w._-]+)\0|s p|HP OpenView Omniback/Data Protector| o/Unix/ h/$1/

match ouman-trend m|^\0\0\0\x05\xffSMBr$| p/Ouman Trend environmental sensor/

#### Match versions based on line numbers in error messages.
# http://seclists.org/nmap-dev/2010/q1/456
# Update like this:
# cd src/backend/postmaster/; git tag -l 'REL*' | while read tag; do git checkout $tag -- postmaster.c; echo $tag:$(grep -n "PG_PROTOCOL_MINOR(PG_PROTOCOL_LATEST))));" postmaster.c) >> lines.txt; done

# The line numbers need to be updated in both the non-Windows and Windows sections

# Amazon Redshift, based on PostgreSQL 8.0.2
# line numbers are distinctly different, as well as the source code path
match postgresql m|^E\0\0\0.SFATAL\0C0A000\0Munsupported frontend protocol 65363\.19778: server supports 1\.0 to 3\.0\0F/home/ec2-user/padb/src/pg/src/backend/postmaster/postmaster\.c\0L2463\0RProcessStartupPacket\0\0$|s p/Amazon Redshift/ v/1.0.1691/ cpe:/a:amazon:redshift:1.0.1691/

# PostgreSQL - Non-Windows platforms
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1287\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/7.4.0 - 7.4.1/ cpe:/a:postgresql:postgresql:7.4/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1293\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/7.4.2 - 7.4.30/ cpe:/a:postgresql:postgresql:7.4/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1408\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.0.0 - 8.0.1/ cpe:/a:postgresql:postgresql:8.0/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1431\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.0.2 - 8.0.4/ cpe:/a:postgresql:postgresql:8.0/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1439\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.0.7 - 8.0.8/ cpe:/a:postgresql:postgresql:8.0/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1443\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.0.9 - 8.0.13/ cpe:/a:postgresql:postgresql:8.0/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1445\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.0.6 or 8.0.14 - 8.0.26/ cpe:/a:postgresql:postgresql:8.0/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1449\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.1.0/ cpe:/a:postgresql:postgresql:8.1.0/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1450\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.1.1/ cpe:/a:postgresql:postgresql:8.1.1/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1448\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.1.3 - 8.1.4/ cpe:/a:postgresql:postgresql:8.1/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1452\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.1.5 - 8.1.9/ cpe:/a:postgresql:postgresql:8.1/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1454\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.1.2 or 8.1.10 - 8.1.23/ cpe:/a:postgresql:postgresql:8.1/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1432\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.2.0/ cpe:/a:postgresql:postgresql:8.2.0/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1437\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.2.1 - 8.2.4/ cpe:/a:postgresql:postgresql:8.2/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1440\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.2.5 - 8.2.19/ cpe:/a:postgresql:postgresql:8.2/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1441\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.0.5 or 8.2.20 - 8.2.23/ cpe:/a:postgresql:postgresql:8.0.5/ cpe:/a:postgresql:postgresql:8.2/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1497\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.3.0 - 8.3.7/ cpe:/a:postgresql:postgresql:8.3/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1507\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.3.8 - 8.3.13/ cpe:/a:postgresql:postgresql:8.3/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1508\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.3.14 - 8.3.18/ cpe:/a:postgresql:postgresql:8.3/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1514\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.3.19/ cpe:/a:postgresql:postgresql:8.3.19/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1515\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.3.20 - 8.3.23/ cpe:/a:postgresql:postgresql:8.3/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1570\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.4.0/ cpe:/a:postgresql:postgresql:8.4.0/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1621\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.4.1 - 8.4.11/ cpe:/a:postgresql:postgresql:8.4/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1626\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.4.12/ cpe:/a:postgresql:postgresql:8.4.12/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1627\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.4.13 - 8.4.19/ cpe:/a:postgresql:postgresql:8.4/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1622\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.4.20 - 8.4.22/ cpe:/a:postgresql:postgresql:8.4/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1666\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.0.0 - 9.0.7/ cpe:/a:postgresql:postgresql:9.0/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1671\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.0.8/ cpe:/a:postgresql:postgresql:9.0.8/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1677\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.0.9 - 9.0.15/ cpe:/a:postgresql:postgresql:9.0/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1672\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.0.16 - 9.0.18/ cpe:/a:postgresql:postgresql:9.0/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1705\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.0.19 - 9.0.22/ cpe:/a:postgresql:postgresql:9.0/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1753\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.0.23/ cpe:/a:postgresql:postgresql:9.0.23/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1694\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.1.0 - 9.1.1/ cpe:/a:postgresql:postgresql:9.1/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1695\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.1.2 - 9.1.3/ cpe:/a:postgresql:postgresql:9.1/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1700\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.1.4/ cpe:/a:postgresql:postgresql:9.1.4/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1706\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.1.5 - 9.1.11/ cpe:/a:postgresql:postgresql:9.1/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1701\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.1.12 - 9.1.14/ cpe:/a:postgresql:postgresql:9.1/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1734\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.1.15 - 9.1.18/ cpe:/a:postgresql:postgresql:9.1/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1803\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.1.19/ cpe:/a:postgresql:postgresql:9.1.19/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1833\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.1.20 - 9.1.24/ cpe:/a:postgresql:postgresql:9.1/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1612\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.2.0 - 9.2.6/ cpe:/a:postgresql:postgresql:9.2/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1607\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.2.7 - 9.2.9/ cpe:/a:postgresql:postgresql:9.2/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1640\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.2.10 - 9.2.13/ cpe:/a:postgresql:postgresql:9.2/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1709\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.2.14/ cpe:/a:postgresql:postgresql:9.2.14/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1739\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.2.15 - 9.2.16/ cpe:/a:postgresql:postgresql:9.2/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1742\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.2.17/ cpe:/a:postgresql:postgresql:9.2.17/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1746\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.2.18 - 9.2.19/ cpe:/a:postgresql:postgresql:9.2/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1747\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.2.20 - 9.2.21/ cpe:/a:postgresql:postgresql:9.2/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1755\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.2.22 - 9.2.24/ cpe:/a:postgresql:postgresql:9.2/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1837\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.3.0 - 9.3.2/ cpe:/a:postgresql:postgresql:9.3/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1834\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.3.3 - 9.3.5/ cpe:/a:postgresql:postgresql:9.3/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1872\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.3.6 - 9.3.9/ cpe:/a:postgresql:postgresql:9.3/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1949\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.3.10/ cpe:/a:postgresql:postgresql:9.3.10/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1979\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.3.11 - 9.3.12/ cpe:/a:postgresql:postgresql:9.3/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1982\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.3.13/ cpe:/a:postgresql:postgresql:9.3.13/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1849\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.4.0/ cpe:/a:postgresql:postgresql:9.4.0/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1881\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.4.1 - 9.4.4/ cpe:/a:postgresql:postgresql:9.4/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1955\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.4.5/ cpe:/a:postgresql:postgresql:9.4.5/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1986\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.3.14 - 9.3.15 or 9.4.6 - 9.4.8/ cpe:/a:postgresql:postgresql:9/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1987\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.3.16 - 9.3.17/ cpe:/a:postgresql:postgresql:9.3/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1994\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.3.21 - 9.3.25/ cpe:/a:postgresql:postgresql:9.3/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1990\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.4.9/ cpe:/a:postgresql:postgresql:9.4.9/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2000\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.4.10/ cpe:/a:postgresql:postgresql:9.4.10/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2001\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.4.11/ cpe:/a:postgresql:postgresql:9.4.11/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2002\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.4.12/ cpe:/a:postgresql:postgresql:9.4.12/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2010\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.4.13 - 9.4.15 or 9.4.22 - 9.4.26/ cpe:/a:postgresql:postgresql:9.4/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2009\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.4.16 - 9.4.21, 9.5.20 (Docker apline image)/ cpe:/a:postgresql:postgresql:9.4/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1991\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.5.0 - 9.5.3/ cpe:/a:postgresql:postgresql:9.5/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L1995\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.3.18 - 9.3.20 or 9.5.4/ cpe:/a:postgresql:postgresql:9/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2005\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.5.5/ cpe:/a:postgresql:postgresql:9.5.5/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2006\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.5.6/ cpe:/a:postgresql:postgresql:9.5.6/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2007\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.5.7/ cpe:/a:postgresql:postgresql:9.5.7/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2015\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.5.8 - 9.5.10 or 9.5.17 - 9.5.23/ cpe:/a:postgresql:postgresql:9.5/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2014\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.5.11 - 9.5.16/ cpe:/a:postgresql:postgresql:9.5/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2016\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.5.25/ cpe:/a:postgresql:postgresql:9.5.25/
# 9.6.0 introduced a nonlocalized error message
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2008\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.6.0 - 9.6.1/ cpe:/a:postgresql:postgresql:9.6/
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2009\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.6.2/ cpe:/a:postgresql:postgresql:9.6.2/
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2023\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.6.3/ cpe:/a:postgresql:postgresql:9.6.3/
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2031\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.6.4 - 9.6.6 or 9.6.13 - 9.6.19/ cpe:/a:postgresql:postgresql:9.6/
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2030\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.6.7 - 9.6.12/ cpe:/a:postgresql:postgresql:9.6/
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2050\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.6.20 - 9.6.23 or 11.14 - 11.17/ cpe:/a:postgresql:postgresql/
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2063\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.6.24/ cpe:/a:postgresql:postgresql:9.6.24/
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2065\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/10.0 - 10.1 or 10.8 - 10.14/ cpe:/a:postgresql:postgresql:10/
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2064\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/10.2 - 10.7/ cpe:/a:postgresql:postgresql:10/
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2086\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/10.15 - 10.18/ cpe:/a:postgresql:postgresql:10/
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2099\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/10.19 - 10.22/ cpe:/a:postgresql:postgresql:10/
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2015\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/11.0 - 11.2/ cpe:/a:postgresql:postgresql:11/
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2016\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/11.3 - 11.9/ cpe:/a:postgresql:postgresql:11/
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2037\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/11.10 - 11.13/ cpe:/a:postgresql:postgresql:11/
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2060\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/12.0 - 12.2/ cpe:/a:postgresql:postgresql:12/
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2071\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/12.3 - 12.4/ cpe:/a:postgresql:postgresql:12/
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2092\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/12.5/ cpe:/a:postgresql:postgresql:12.5/
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2095\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/12.6 - 12.8/ cpe:/a:postgresql:postgresql:12/
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2119\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/12.9 - 12.12/ cpe:/a:postgresql:postgresql:12/
# TODO: confirm 13.0 and later have same error packet
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2108\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/13.0 - 13.1/ cpe:/a:postgresql:postgresql:13/
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2109\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/13.2 - 13.4/ cpe:/a:postgresql:postgresql:13/
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2133\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/13.5 - 13.8/ cpe:/a:postgresql:postgresql:13/
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2114\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/14.0/ cpe:/a:postgresql:postgresql:14.0/
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2138\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/14.1 - 14.5/ cpe:/a:postgresql:postgresql:14/
# 15 BETA 1-3, update/remove when out of beta
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2194\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/15/ cpe:/a:postgresql:postgresql:15/

# PostgreSQL - Docker image - most docker images have the same error message as the release version, these do not.
# Seems images build after the move to from Alpine 3.10 to 3.11 have changed line numbers.
# PR where this behavior starts: https://github.com/docker-library/postgres/pull/657
match postgresql m|^E\0\0\0.SFATAL\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2004\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.4.25 - 9.4.26/ i/Docker alpine image/ cpe:/a:postgresql:postgresql:9.4/ cpe:/a:alpinelinux:alpine_linux:-/
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2025\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.6.16 - 9.6.17/ i/Docker alpine image/ cpe:/a:postgresql:postgresql:9.6/ cpe:/a:alpinelinux:alpine_linux:-/
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2059\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/10.11 - 10.12/ i/Docker alpine image/ cpe:/a:postgresql:postgresql:10/ cpe:/a:alpinelinux:alpine_linux:-/
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2010\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/11.6 - 11.7/ i/Docker alpine image/ cpe:/a:postgresql:postgresql:11/ cpe:/a:alpinelinux:alpine_linux:-/
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0Fpostmaster\.c\0L2054\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/12.1 - 12.2/ i/Docker alpine image/ cpe:/a:postgresql:postgresql:12/ cpe:/a:alpinelinux:alpine_linux:-/


# PostgreSQL - Windows platforms
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1287\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/7.4.0 - 7.4.1/ o/Windows/ cpe:/a:postgresql:postgresql:7.4/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1293\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/7.4.2 - 7.4.30/ o/Windows/ cpe:/a:postgresql:postgresql:7.4/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1408\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.0.0 - 8.0.1/ o/Windows/ cpe:/a:postgresql:postgresql:8.0/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1431\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.0.2 - 8.0.4/ o/Windows/ cpe:/a:postgresql:postgresql:8.0/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1439\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.0.7 - 8.0.8/ o/Windows/ cpe:/a:postgresql:postgresql:8.0/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1443\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.0.9 - 8.0.13/ o/Windows/ cpe:/a:postgresql:postgresql:8.0/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1445\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.0.6 or 8.0.14 - 8.0.26/ o/Windows/ cpe:/a:postgresql:postgresql:8.0/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1449\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.1.0/ o/Windows/ cpe:/a:postgresql:postgresql:8.1.0/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1450\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.1.1/ o/Windows/ cpe:/a:postgresql:postgresql:8.1.1/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1448\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.1.3 - 8.1.4/ o/Windows/ cpe:/a:postgresql:postgresql:8.1/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1452\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.1.5 - 8.1.9/ o/Windows/ cpe:/a:postgresql:postgresql:8.1/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1454\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.1.2 or 8.1.10 - 8.1.23/ o/Windows/ cpe:/a:postgresql:postgresql:8.1/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1432\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.2.0/ o/Windows/ cpe:/a:postgresql:postgresql:8.2.0/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1437\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.2.1 - 8.2.4/ o/Windows/ cpe:/a:postgresql:postgresql:8.2/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1440\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.2.5 - 8.2.19/ o/Windows/ cpe:/a:postgresql:postgresql:8.2/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1441\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.0.5 or 8.2.20 - 8.2.23/ o/Windows/ cpe:/a:postgresql:postgresql:8.0.5/ cpe:/a:postgresql:postgresql:8.2/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1497\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.3.0 - 8.3.7/ o/Windows/ cpe:/a:postgresql:postgresql:8.3/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1507\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.3.8 - 8.3.13/ o/Windows/ cpe:/a:postgresql:postgresql:8.3/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1508\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.3.14 - 8.3.18/ o/Windows/ cpe:/a:postgresql:postgresql:8.3/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1514\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.3.19/ o/Windows/ cpe:/a:postgresql:postgresql:8.3.19/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1515\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.3.20 - 8.3.23/ o/Windows/ cpe:/a:postgresql:postgresql:8.3/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1570\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.4.0/ o/Windows/ cpe:/a:postgresql:postgresql:8.4.0/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1621\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.4.1 - 8.4.11/ o/Windows/ cpe:/a:postgresql:postgresql:8.4/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1626\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.4.12/ o/Windows/ cpe:/a:postgresql:postgresql:8.4.12/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1627\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.4.13 - 8.4.19/ o/Windows/ cpe:/a:postgresql:postgresql:8.4/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1622\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/8.4.20 - 8.4.22/ o/Windows/ cpe:/a:postgresql:postgresql:8.4/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1666\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.0.0 - 9.0.7/ o/Windows/ cpe:/a:postgresql:postgresql:9.0/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1671\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.0.8/ o/Windows/ cpe:/a:postgresql:postgresql:9.0.8/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1677\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.0.9 - 9.0.15/ o/Windows/ cpe:/a:postgresql:postgresql:9.0/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1672\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.0.16 - 9.0.18/ o/Windows/ cpe:/a:postgresql:postgresql:9.0/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1705\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.0.19 - 9.0.22/ o/Windows/ cpe:/a:postgresql:postgresql:9.0/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1753\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.0.23/ o/Windows/ cpe:/a:postgresql:postgresql:9.0.23/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1694\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.1.0 - 9.1.1/ o/Windows/ cpe:/a:postgresql:postgresql:9.1/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1695\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.1.2 - 9.1.3/ o/Windows/ cpe:/a:postgresql:postgresql:9.1/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1700\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.1.4/ o/Windows/ cpe:/a:postgresql:postgresql:9.1.4/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1706\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.1.5 - 9.1.11/ o/Windows/ cpe:/a:postgresql:postgresql:9.1/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1701\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.1.12 - 9.1.14/ o/Windows/ cpe:/a:postgresql:postgresql:9.1/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1734\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.1.15 - 9.1.18/ o/Windows/ cpe:/a:postgresql:postgresql:9.1/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1803\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.1.19/ o/Windows/ cpe:/a:postgresql:postgresql:9.1.19/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1833\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.1.20 - 9.1.24/ o/Windows/ cpe:/a:postgresql:postgresql:9.1/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1612\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.2.0 - 9.2.6/ o/Windows/ cpe:/a:postgresql:postgresql:9.2/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1607\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.2.7 - 9.2.9/ o/Windows/ cpe:/a:postgresql:postgresql:9.2/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1640\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.2.10 - 9.2.13/ o/Windows/ cpe:/a:postgresql:postgresql:9.2/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1709\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.2.14/ o/Windows/ cpe:/a:postgresql:postgresql:9.2.14/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1739\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.2.15 - 9.2.16/ o/Windows/ cpe:/a:postgresql:postgresql:9.2/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1742\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.2.17/ o/Windows/ cpe:/a:postgresql:postgresql:9.2.17/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1746\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.2.18 - 9.2.19/ o/Windows/ cpe:/a:postgresql:postgresql:9.2/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1747\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.2.20 - 9.2.21/ o/Windows/ cpe:/a:postgresql:postgresql:9.2/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1755\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.2.22 - 9.2.24/ o/Windows/ cpe:/a:postgresql:postgresql:9.2/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1837\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.3.0 - 9.3.2/ o/Windows/ cpe:/a:postgresql:postgresql:9.3/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1834\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.3.3 - 9.3.5/ o/Windows/ cpe:/a:postgresql:postgresql:9.3/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1872\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.3.6 - 9.3.9/ o/Windows/ cpe:/a:postgresql:postgresql:9.3/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1949\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.3.10/ o/Windows/ cpe:/a:postgresql:postgresql:9.3.10/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1849\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.4.0/ o/Windows/ cpe:/a:postgresql:postgresql:9.4.0/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1881\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.4.1 - 9.4.4/ o/Windows/ cpe:/a:postgresql:postgresql:9.4/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1955\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.4.5/ o/Windows/ cpe:/a:postgresql:postgresql:9.4.5/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1986\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.3.14 - 9.3.15 or 9.4.6 - 9.4.8/ o/Windows/ cpe:/a:postgresql:postgresql:9/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1987\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.3.16 - 9.3.17/ o/Windows/ cpe:/a:postgresql:postgresql:9.3/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1994\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.3.21 - 9.3.25/ o/Windows/ cpe:/a:postgresql:postgresql:9.3/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1990\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.4.9/ o/Windows/ cpe:/a:postgresql:postgresql:9.4.9/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L2000\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.4.10/ o/Windows/ cpe:/a:postgresql:postgresql:9.4.10/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L2001\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.4.11/ o/Windows/ cpe:/a:postgresql:postgresql:9.4.11/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L2002\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.4.12/ o/Windows/ cpe:/a:postgresql:postgresql:9.4.12/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L2010\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.4.13 - 9.4.15 or 9.4.22 - 9.4.26/ o/Windows/ cpe:/a:postgresql:postgresql:9.4/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L2009\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.4.16 - 9.4.21/ o/Windows/ cpe:/a:postgresql:postgresql:9.4/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1991\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.5.0 - 9.5.3/ o/Windows/ cpe:/a:postgresql:postgresql:9.5/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L1995\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.3.18 - 9.3.20 or 9.5.4/ o/Windows/ cpe:/a:postgresql:postgresql:9/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L2005\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.5.5/ o/Windows/ cpe:/a:postgresql:postgresql:9.5.5/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L2006\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.5.6/ o/Windows/ cpe:/a:postgresql:postgresql:9.5.6/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L2007\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.5.7/ o/Windows/ cpe:/a:postgresql:postgresql:9.5.7/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L2015\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.5.8 - 9.5.10 or 9.5.17 - 9.5.23/ o/Windows/ cpe:/a:postgresql:postgresql:9.5/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L2014\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.5.11 - 9.5.16/ o/Windows/ cpe:/a:postgresql:postgresql:9.5/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L2016\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.5.25/ o/Windows/ cpe:/a:postgresql:postgresql:9.5.25/ cpe:/o:microsoft:windows/a
# 9.6.0 introduced a nonlocalized error message
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L2008\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.6.0 - 9.6.1/ o/Windows/ cpe:/a:postgresql:postgresql:9.6/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L2009\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.6.2/ o/Windows/ cpe:/a:postgresql:postgresql:9.6.2/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L2023\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.6.3/ o/Windows/ cpe:/a:postgresql:postgresql:9.6.3/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L2031\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.6.4 - 9.6.6 or 9.6.13 - 9.6.19/ o/Windows/ cpe:/a:postgresql:postgresql:9.6/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L2030\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.6.7 - 9.6.12/ o/Windows/ cpe:/a:postgresql:postgresql:9.6/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L2050\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.6.20 - 9.6.23 or 11.14 - 11.17/ o/Windows/ cpe:/a:postgresql:postgresql/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L2063\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/9.6.24/ o/Windows/ cpe:/a:postgresql:postgresql:9.6.24/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L2065\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/10.0 - 10.1 or 10.8 - 10.14/ o/Windows/ cpe:/a:postgresql:postgresql:10/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L2064\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/10.2 - 10.7/ o/Windows/ cpe:/a:postgresql:postgresql:10/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L2086\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/10.15 - 10.18/ o/Windows/ cpe:/a:postgresql:postgresql:10/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L2099\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/10.19 - 10.22/ o/Windows/ cpe:/a:postgresql:postgresql:10/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L2015\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/11.0 - 11.2/ o/Windows/ cpe:/a:postgresql:postgresql:11/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L2016\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/11.3 - 11.9/ o/Windows/ cpe:/a:postgresql:postgresql:11/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L2037\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/11.10 - 11.13/ o/Windows/ cpe:/a:postgresql:postgresql:11/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L2060\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/12.0 - 12.2/ o/Windows/ cpe:/a:postgresql:postgresql:12/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L2071\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/12.3 - 12.4/ o/Windows/ cpe:/a:postgresql:postgresql:12/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L2092\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/12.5/ o/Windows/ cpe:/a:postgresql:postgresql:12.5/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L2095\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/12.6 - 12.8/ o/Windows/ cpe:/a:postgresql:postgresql:12/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L2119\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/12.9 - 12.12/ o/Windows/ cpe:/a:postgresql:postgresql:12/ cpe:/o:microsoft:windows/a
# TODO: confirm 13.0 and later have same error packet
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L2108\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/13.0 - 13.1/ o/Windows/ cpe:/a:postgresql:postgresql:13/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L2109\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/13.2 - 13.4/ o/Windows/ cpe:/a:postgresql:postgresql:13/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L2133\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/13.5 - 13.8/ o/Windows/ cpe:/a:postgresql:postgresql:13/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L2114\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/14.0/ o/Windows/ cpe:/a:postgresql:postgresql:14.0/ cpe:/o:microsoft:windows/a
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L2138\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/14.1 - 14.5/ o/Windows/ cpe:/a:postgresql:postgresql:14/ cpe:/o:microsoft:windows/a
# 15 BETA 1-3, update/remove when out of beta
match postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*\0F\.\\src\\backend\\postmaster\\postmaster\.c\0L2194\0RProcessStartupPacket\0\0$|s p/PostgreSQL DB/ v/15/ o/Windows/ cpe:/a:postgresql:postgresql:15/ cpe:/o:microsoft:windows/a

# PostgreSQL - Language specific
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0Mnicht unterst\xc3\xbctztes Frontend-Protokoll 65363\.19778: Server unterst\xc3\xbctzt 1\.0 bis 3\.0\0Fpostmaster\.c\0L\d+\0|s p/PostgreSQL DB/ i/German; Unicode support/ cpe:/a:postgresql:postgresql::::de/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0Mnicht unterst.{1,2}tztes Frontend-Protokoll 65363\.19778: Server unterst.{1,2}tzt 1\.0 bis 3\.0\0Fpostmaster\.c\0L\d+\0|s p/PostgreSQL DB/ i/German/ cpe:/a:postgresql:postgresql::::de/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0MProtocole non support\xc3\xa9e de l'interface 65363\.19778: le serveur supporte de 1\.0 \xc3\xa0 3\.0\0Fpostmaster\.c\0L\d+\0|s p/PostgreSQL DB/ i/French; Unicode support/ cpe:/a:postgresql:postgresql::::fr/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0MProtocole non support\?e de l'interface 65363\.19778 : le serveur supporte de 1\.0 \?\n3\.0\0Fpostmaster\.c\0L1621\0RProcessStartupPacket\0\0| p/PostgreSQL DB/ v/8.4.1 - 8.4.11/ i/French/ cpe:/a:postgresql:postgresql:8.4:::fr/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0MProtocole non support\?e de l'interface 65363\.19778 : le serveur supporte de 1\.0 \?\n3\.0\0Fpostmaster\.c\0L1626\0RProcessStartupPacket\0\0$| p/PostgreSQL DB/ v/8.4.12/ i/French/ cpe:/a:postgresql:postgresql:8.4.12:::fr/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0MProtocole non support[e\xe9]e de l'interface 65363\.19778: le serveur supporte de 1\.0 [a\xe0] 3\.0\0Fpostmaster\.c\0L\d+\0|s p/PostgreSQL DB/ i/French/ cpe:/a:postgresql:postgresql::::fr/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0Mprotocole non support\xe9e de l'interface 65363\.19778: le serveur supporte de 1\.0 \xe0 3\.0\0Fpostmaster\.c\0L\d+\0|s p/PostgreSQL DB/ i/French/ cpe:/a:postgresql:postgresql::::fr/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0Mel protocolo 65363\.19778 no est..? soportado: servidor soporta 1\.0 hasta 3\.0\0Fpostmaster\.c\0L\d+\0|s p/PostgreSQL DB/ i/Spanish/ cpe:/a:postgresql:postgresql::::es/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0Mel protocolo 65363\.19778 no est\? permitido: servidor permite 1\.0 hasta 3\.0\0Fpostmaster\.c\0L\d+\0|s p/PostgreSQL DB/ i/Spanish/ cpe:/a:postgresql:postgresql::::es/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0Mprotocolo 65363\.19778 n\xe3o \xe9 suportado: servidor suporta 1\.0 a 3\.0\0Fpostmaster\.c\0L\d+\0|s p/PostgreSQL DB/ i/Portuguese/ cpe:/a:postgresql:postgresql::::pt/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0Mprotocolo do cliente 65363\.19778 n.{4,6} suportado: servidor suporta 1\.0 a 3\.0\0Fpostmaster\.c\0L\d+\0|s p/PostgreSQL DB/ i/Portuguese/ cpe:/a:postgresql:postgresql::::pt/
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M\xd0\xbd\xd0\xb5\xd0\xbf\xd0\xbe\xd0\xb4\xd0\xb4\xd0\xb5\xd1\x80\xd0\xb6\xd0\xb8\xd0\xb2\xd0\xb0\xd0\xb5\xd0\xbc\xd1\x8b\xd0\xb9 \xd0\xba\xd0\xbb\xd0\xb8\xd0\xb5\xd0\xbd\xd1\x82\xd1\x81\xd0\xba\xd0\xb8\xd0\xb9 \xd0\xbf\xd1\x80\xd0\xbe\xd1\x82\xd0\xbe\xd0\xba\xd0\xbe\xd0\xbb 65363\.19778: \xd1\x81\xd0\xb5\xd1\x80\xd0\xb2\xd0\xb5\xd1\x80 \xd0\xbf\xd0\xbe\xd0\xb4\xd0\xb4\xd0\xb5\xd1\x80\xd0\xb6\xd0\xb8\xd0\xb2\xd0\xb0\xd0\xb5\xd1\x82 \xd0\xbe\xd1\x82 1\.0 \xd0\xb4\xd0\xbe 3\.0\0Fpostmaster\.c\0L\d+\0|s p/PostgreSQL DB/ i/Russian; Unicode support/ cpe:/a:postgresql:postgresql::::ru/
# Supposed to be Ukrainian? submission came from a .ua domain.
match postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\? \?\?\?\?\?\?\?\? \?\?\?\?\?\?\?\?\?\?\? \?\?\?\?\?\?\?\?\?\? 65363\.19778; \?\?\?\?\?\? \?\?\?\?\?\?\?\?\?\?\?\? 1\.0 - 3\.0 \0Fpostmaster\.c\0L1695\0RProcessStartupPacket\0\0$| p/PostgreSQL DB/ v/9.1.2 - 9.1.3/ cpe:/a:postgresql:postgresql:9.1::uk/
# Korean
match postgresql m|^E\0\0\0\xb1S\xec\xb9\x98| p/PostgreSQL DB/ cpe:/a:postgresql:postgresql/

# PostgreSQL softmatch entries, put all hard matches above this line.
softmatch postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0MProtocole non support.{1,2}e de l'interface 65363| p/PostgreSQL DB/ i/French/ cpe:/a:postgresql:postgresql::::fr/
softmatch postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0Mel protocolo 65363| p/PostgreSQL DB/ i/Spanish/ cpe:/a:postgresql:postgresql::::es/
softmatch postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0Mnicht unterst.*?Frontend-Protokoll 65363\.19778:|s p/PostgreSQL DB/ i/German/ cpe:/a:postgresql:postgresql::::de/
softmatch postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M\xe3\x83\x95\xe3\x83\xad\xe3\x83\xb3\xe3\x83\x88\xe3\x82\xa8\xe3\x83\xb3\xe3\x83\x89\xe3\x83\x97\xe3\x83\xad\xe3\x83\x88\xe3\x82\xb3\xe3\x83\xab|s p/PostgreSQL DB/ i/Japanese/ cpe:/a:postgresql:postgresql::::ja/
softmatch postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*?1\.0.*?3\.0.*?\0Fpostmaster\.c\0|s p/PostgreSQL DB/ cpe:/a:postgresql:postgresql/
softmatch postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0M.*?65363\.19778.*?1\.0.*?3\.0.*?\0F\.\\src\\backend\\postmaster\\postmaster\.c\0|s p/PostgreSQL DB/ o/Windows/ cpe:/a:postgresql:postgresql/ cpe:/o:microsoft:windows/a
softmatch postgresql m|^E\0\0\0.S[^\0]+\0C0A000\0Munsupported frontend protocol 65363| p/PostgreSQL DB/ cpe:/a:postgresql:postgresql/

softmatch postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0M.*?65363\.19778.*?1\.0.*?3\.0.*?\0F\.\\src\\backend\\postmaster\\postmaster\.c\0|s p/PostgreSQL DB/ v/9.6.0 or later/ o/Windows/ cpe:/a:postgresql:postgresql/ cpe:/o:microsoft:windows/a
softmatch postgresql m|^E\0\0\0.S[^\0]+\0VFATAL\0C0A000\0Munsupported frontend protocol 65363| p/PostgreSQL DB/ v/9.6.0 or later/ cpe:/a:postgresql:postgresql/

match tcsd m|^\0\0\0\x1c\0\0 \x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0$| p/TCSD daemon/

# Teradata Database 13.10
match teradata m|^\x03\x02\x01\0\0\0\0\0\x004\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x7f\0\0\0\0\0\0\0\0\0\0\0\0\0\x001\x004\0\0\0\0\0K\x1f\(\0The LAN message Format field is invalid\.| p/Teradata database/

match tng-dts m|^\0\0\0\$sequence_number=\[0\] result=\[-2005\] \0$| p/CA DTS Agent/

# SAP Release: SAP ECC (Enterprise Core Component) 6.0 on Windows 2003
match sap-gui m|^\0\0\0\x0e\*\*DPTMMSG\*\*\0\0\xf8| p/SAP Gui Dispatcher/ cpe:/a:sap:gui/

match serversettingsd m|^\0\0\x004main\0\0\x01\0\0\0\0\x0c\0\0\0\0\0\0\0\x0c\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0quit\xff\xff\xff\xffcrpt$| p/Apple serversettingsd administration daemon/ o/Mac OS X/ cpe:/o:apple:mac_os_x/a
match spotify-login m|^\x01\0$| p/Spotify login server/
match symantec-esm m|^\0\x01[#,]$| p/Symantec Enterprise Security Manager agent/ cpe:/a:symantec:enterprise_security_manager/
# Windows 2000 Server Wins name resolution service
# Windows NT 4.0 Wins
# Windows 2003 WINS service
match wins m|^\0\0\0\x1e\xffS\xad\x80\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0...\0\0\x01\0\0\x81\0\x02|s p/Microsoft Windows Wins/ o/Windows/ cpe:/o:microsoft:windows/a

match sap-its m|^\0\0\0\x0c\x01\x03\0\0\0\0\x07.\0\0\0\0\0\0\x07.Content-Type:  text/html; charset=Windows-\d+\r\n\r\n<!--\r\n This page was created by the \r\n SAP Internet Transaction Server|s p/SAP Internet Transaction Server/

# Likely false-positive?
match routersetup m|^\0\0\0.\xffSMBr\0\0\0\0\x80|s p|Nortel/D-Link router instant setup| d/router/
match tally-census m|^\xcd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\x02\0\0\0\0\0$| p/Tally Collection Client/
match bacula-fd m|^\0\0\0\x152999 Invalid command\n\xff\xff\xff\xfc$| p/Bacula file daemon/
match bacula-sd m|^\0\0\0\x0b3999 No go\n$| p/Bacula storage daemon/
match opsec-ufp m|^\0\0\0\x0c\x01\x01\0\x04r\0\0\0$| p/Check-Point NG firewall/

# Spark 1.5.2
match spark m|^\0\0\0\0$| p/Apache Spark/ cpe:/a:apache:spark/

match lexmark-objectstore m|\0\0\0\x80<\?xml version=\"1\.0\" encoding=\"UTF-8\"\?>\r\n<exception requestID=\"0\">\r\n  <message>Unable to parse Message\.</message>\r\n</exception>\r\n| p/Lexmark printer objectstore/ d/printer/
match lexmark-objectstore m|^\0\0\0\x7c<\?xml version="1\.0" encoding="UTF-8"\?>\r\n<exception requestID="0">\n<message>Unable to parse Message\.</message>\n</exception>\r\n| p/Lexmark printer objectstore/ d/printer/

match ftp m|^2[23]0 FTP Server Ready\r\n504 Comand length not supported\.\r\n| p/HP JetDirect ftpd/ d/printer/

match vertica m|^V\0\0\x01f:ErrorMsg\nelevel:23\nfilename:/scratch_a/release/vbuild/vertica/Session/ClientSession\.cpp\nlineno:3800\ncaught:SessionRun\nsqlerrcode:16933376\nverticacode:3753\nmessage:Invalid startup packet layout: expected terminator as last byte\ndetail:\nhint:\nlog_message:Invalid startup packet layout: expected terminator as last byte\nlog_detail:\nlog_hint:\ncursorpos:0\n\.\n| p/HP Vertica database/ v/7.0.1/ cpe:/a:hp:vertica:7.0.1/
softmatch vertica m|^V\0\0\x01f:ErrorMsg\nelevel:23\nfilename:/scratch_a/release/vbuild/vertica/Session/ClientSession\.cpp\nlineno:(\d+)\ncaught:SessionRun\nsqlerrcode:16933376\nverticacode:3753\nmessage:Invalid startup packet layout: expected terminator as last byte\ndetail:\nhint:\nlog_message:Invalid startup packet layout: expected terminator as last byte\nlog_detail:\nlog_hint:\ncursorpos:0\n\.\n| p/HP Vertica database/ i/error line $1/ cpe:/a:hp:vertica/

softmatch smpp m|^\0\0\0\x10\x80\0\0\0\0\0\0\x03....$|s

# From xlsclients
##############################NEXT PROBE##############################
Probe TCP X11Probe q|\x6C\0\x0B\0\0\0\0\0\0\0\0\0|
rarity 4
ports 80,443,497,1550,2002,5302,6000-6020,7000,7100,7101,7777,8000

match acti-control m|^\x01\0\0\0\x01\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0$| p/ACTi E32 camera control server port/ d/webcam/ cpe:/h:acti:e32/

match apcupsd m|^\0\0\x02\0\0\0\0\0\0\0\0\0\x06\0\0\0\0@\x0c\0\x9c\x18\0\0X Consortium\x01\n\x01\0\x05\0\0\0f\x84\x017\0\0\0\0\0\0\0\0$| p/apcupsd/

match fastcgi m|^\x01\x0b\0\0\0\x08\0\0\0\0\0\0\0...|s p/HHVM FastCGI/ cpe:/a:hiphop_virtual_machine_for_php_project:hiphop_virtual_machine_for_php/

# retroclient 6.5.108 on Linux
match font-service m|^\0\0\x02\0\0\0\0\0\0\0\0\0\x06\0\0\0\0@\x0c\0p\x17\0\0X Consortium\x01\n\x01\0\x05\0\0\0....\0\0..\0\0\0\0$|s p/Sun Solaris fs.auto/ o/Solaris/ cpe:/o:sun:sunos/a
# HP-UX 11.11
match font-service m|^\0\0\x02\0\0\0\0\0\0\0\0\0\x06\0\0\0\0@\x0c\0\xd4\x17\0\0X Consortium\x01\n\x01\0\x05\0\0\0....\0\0..\0\0\0\0$|s p/HP-UX X Font Server/ o/HP-UX/ cpe:/o:hp:hp-ux/a
match font-service m|^\0\0\x02\0\0\0\0\0\0\0\0\0\x0e\0\0\0\0 \*\0.\x19\0\0The XFree86 Project[-.\w() ]+..\x01\n\x01\0\x05\0\0\0....\0\0..\0\0\0|s p/XFree86 X Font Server/ o/Unix/ cpe:/a:xfree86:xfree86/
match font-service m|^\0\0\x02\0\0\0\0\0\0\0\0\0\x07\0\0\0\0 \x10\0....X\.Org Foundation\x01\n|s p/X.Org X Font Server/ o/Unix/ cpe:/a:x:x.org_x11/
match font-service m|^\0\0\x02\0\0\0\0\0\0\0\0\0\x07\0\0\0\0.......The X\.Org Group|s p/X.Org X Font Server/ o/Unix/ cpe:/a:x:x.org_x11/
match font-service m|^\0\0\x02\0\0\0\0\0\0\0\0\0\x04\0\0\0\0.......HD\0@|s p/X Font Server for TrueType Fonts/ o/Unix/
match font-service m|^\0\0\x02\0\0\0\0\0\0\0\0\0\r\0\0\0\0.......International Business Machines Corp\.|s p/IBM AIX X Font Server/ o/AIX/ cpe:/o:ibm:aix/a

match modbus m|^l\0\0\0\0\x03\0\x80\x01| p/Modbus TCP/

match networkaudio m|^\0\x19\x02\0\x02\0\x07\0Protocol version mismatch\0| p/Network Audio System/ cpe:/a:radscan:network_audio_system/

match retrospect m|^\0\xca\0\0\0\0\0\x04\0\0\0\0\0\0\x02\($| p/Dantz Retrospect backup client/ cpe:/a:dantz:retrospect/

match rpcapd m|^\0\x01\0\x03\0\0\0/Incompatible version number: message discarded\.$| p/WinPcap remote packet capture daemon/ o/Windows/ cpe:/a:winpcap:winpcap/ cpe:/o:microsoft:windows/a

match sphinx-search m|^\0\0\0\x01\0\x01\0\0\0\0\0\x1c\0\0\0\x18unknown command \(code=0\)| p/Sphinx Search daemon/

match video m|^\0\xdc0@p\xdc0@3\.[0-9a-f]{8}\.[0-9A-F]......\0\x000\0\0\0..(?:\*\0/sda/1/\d+/\d+\.0123\.[0-9a-f]{8}\.[0-9A-F]......\0\x000\0\0\0..)+|s p/ECV ECV-REC16SH webcam video stream/ d/webcam/

match X11 m|^\x01\0\x0b\0\0.....\0\0\0\0.*Sun Microsystems, Inc\.|s p/XSun Solaris X11 server/ o/Solaris/ cpe:/o:sun:sunos/a
match X11 m|^\0\x2D\x0B\0\0\0\x0C\0| i/access denied/
# I think the below means access denied (no authentication protocol
# specified?) or is it a problem w/my probe that I should fix?
match X11 m|^\0\x16\x0b\0\0\0\x06\0No protocol specified\x0a..$|s i/access denied/ o/Unix/
match X11 m|^\x01\0\x0b\0\0\0......\0\0.*The XFree86 Project, Inc|s p/XFree86/ i/open/ o/Unix/ cpe:/a:xfree86:xfree86/
match X11 m|^\x01\0\x0b\0\0\0......\0\0.*The X\.Org Foundation|s p/X.Org/ i/open/ o/Unix/ cpe:/a:x:x.org_x11/
match X11 m|^\x01\0\x0b\0\0\0.....\x02\0\0..\xff\xff\x1f\0\0\x01\0\0.*Gentoo Linux \(XFree86 (\d[^)]+)\)\0\0|s p/XFree86/ v/$1/ i/Gentoo Linux/ o/Linux/ cpe:/a:xfree86:xfree86:$1/ cpe:/o:gentoo:linux/
match X11 m|^\x01\0\x0b\0\0\0.....\x03\0\0..\xff\xff\x1f\0\0\x01\0\0.\0\xff\xff\x01\x07\0\0  \x08\xff....Gentoo Linux \(The X\.Org Foundation ([-\w_.]+), revision ([-\w_.]+)\)\0\0|s p/X.Org/ v/$1 revision $2/ i/Gentoo Linux/ o/Linux/ cpe:/a:x:x.org_x11:$1/ cpe:/o:gentoo:linux/
match X11 m|^\x01\0\x0b\0\0\0.....\x02\0\0.*Mandrake Linux \(XFree86 (\d[^\)]+)\)\0\0|s p/XFree86/ v/$1/ i/Mandrake Linux/ o/Linux/ cpe:/a:xfree86:xfree86:$1/ cpe:/o:mandrakesoft:mandrake_linux/
match X11 m|^\x01\0\x0b\0\0\0.....\x03\0\0.*Mandrakelinux \(X\.Org X11 ([\d.]+), patch level ([\w.]+)\)|s p/X.Org/ v/$1 patch level $2/ i/Mandrake Linux/ o/Linux/ cpe:/a:x:x.org_x11:$1/ cpe:/o:mandrakesoft:mandrake_linux/
match X11 m|^\x01\0\x0b\0\0.*Conectiva Linux \(XFree86 ([\d.]+), patch level (\w+)\)|s p/XFree86/ v/$1 patch level $2/ i/Connectiva Linux/ o/Linux/ cpe:/a:xfree86:xfree86:$1/ cpe:/o:linux:linux_kernel/a
# StarNet X-Win32 v5.4 on Windows XP
match X11 m|^\x01\0\x0b\0\0.....\0\0\0\0.*StarNet Communications Corp\.|s p/StarNet X-Win32/ o/Windows/ cpe:/o:microsoft:windows/a
match X11 m|^\0J\x0b\0\0...This copy of X-Win32 will only accept connections from network ([\d.]+)\0\0|s p/StarNet X-Win32/ i/Only accepting connections from net $1/ o/Windows/ cpe:/o:microsoft:windows/a
match X11 m|^\x01\0\x0b\0\0\0=\0\x01\0\0\0\0\0\xc0\x06\xff\xff\?.*\0DECWINDOWS Digital Equipment Corporation Digital UNIX V(\d[-.\w]+)\0\0\x01\x01|s p/Digital UNIX X-Window/ v/$1/ i/Version is X Server and not of Digital UNIX/ o/Digital UNIX/ cpe:/o:dec:digital_unix/a
# tightvnc 1.2.3 Xvnc
# Tightvnc 3.3.3 Xvnc
match X11 m|^\x01\0\x0b\0\0\0%\0\x04\r\0\0\0\0..\xff\xff\?\0\0\x01\0\0\x1b\0\xff\xff\x01\x02\0\0  \x08\xff....AT&T Laboratories Cambridge\0|s p/Xvnc/
match X11 m|^\x01\0\x0b\0\0......\0\0\0..\xff\xff\?\0.*AT&T Laboratories Cambridge|s p/Xvnc/

# Exceed X server for Win32
match X11 m|^\x01\0\x0b\0\0\0.\0..\0\0\0\0..\xff\xff\x1f\0\x01\0\0\0.\0\xff\xff.\x04\0\0\x08 \x08\xfe...\0Hummingbird Ltd\.\x01\x01 \0|s p/Hummingbird Exceed X server/ v/11.X/ o/Windows/ cpe:/a:hummingbird:exceed:11/ cpe:/o:microsoft:windows/a
match X11 m|^\x01\0\x0b\0\0\0.\0..\0\0\0\0..\xff\xff\?\0\x01\0\0\0.\0\xff\xff.\x04\x01\x01\x08 \x08\xfe...\0Hummingbird Ltd\.\x01\x01 \0|s p/Hummingbird Exceed X server/ v/8.X, 9.X, or 10.X/ o/Windows/ cpe:/a:hummingbird:exceed/ cpe:/o:microsoft:windows/a
match X11 m|^\x01\0\x0b\0\0\0.\0..\0\0\0\0..\xff\xff\?\0\x01\0\0\0.\0\xff\xff\x01\x04\x01\x01\x08 \x08\xfe...\0Hummingbird Communications Ltd\.\0\x01\x01 ...\0\0\x08\x08 ...\0\0\x0c\x0c ...\0\0\x18  ...\0\0.\0\0\0 \0\0\0\xff\xff\xff\0\0\0\0\0|s p/Hummingbird Exceed X server/ v/7.X/ o/Windows/ cpe:/a:hummingbird:exceed:7/ cpe:/o:microsoft:windows/a
match X11 m|^\x01\0\x0b\0\0.....\0\0\0\0..\xff\xff\?\0\x01\0\0\0.\0\xff\xff\x01.\x01\x01\x08 \x08\xfe...\0Hummingbird Communications Ltd\..\x01\x01|s p/Hummingbird Exceed X server/ v/6.X/ o/Windows/ cpe:/a:hummingbird:exceed:6/ cpe:/o:microsoft:windows/a
# General catch-alls
match X11 m|^\x01\0\x0b\0\0.....\0\0\0\0..\xff\xff.\0\x01\0\0..\0\xff\xff......\x08\xfe...\0Hummingbird Communications Ltd\.|s p/Hummingbird Exceed X server/ o/Windows/ cpe:/a:hummingbird:exceed/ cpe:/o:microsoft:windows/a
# This Hummingbird match isn't quite generic enough in some casses.
# I'm not sure what all of the X11 flags are though so rather than
# just make it more generic, I'll comment it out and include a more generic
# one below.  [Brandon]
#match X11 m|^\x01\0\x0b\0\0.....\0\0\0\0..\xff\xff.*Hummingbird Ltd\.|s p/Hummingbird Exceed X server/ o/Windows/ cpe:/o:microsoft:windows/a
match X11 m|^\x01\0\x0b\0\0......?\0\0\0...?\xff\xff.*Hummingbird Ltd\.|s p/Hummingbird Exceed X server/ o/Windows/ cpe:/a:hummingbird:exceed/ cpe:/o:microsoft:windows/a
match X11 m|^\x01\0\x0b\0\0.....\0\0\0\0..\xff\xff\?\0.\0\0..\0\xff\xff......\x08....\0DECWINDOWS compatibility\. Hummingbird|s p/Hummingbird Exceed X server/ i/DECWINDOWS compatibility/ o/Windows/ cpe:/a:hummingbird:exceed/ cpe:/o:microsoft:windows/a
match X11 m|^\x01\0\x0b\0\0.....\0\0\0\0..\xff\xff\?\0.\0\0..\0\xff\xff......\x08....\0DECWINDOWS DigitalEquipmentCorporation, eXcursion|s p/DEC eXcursion X server/ o/Windows/ cpe:/o:microsoft:windows/a
match X11 m|^\x01\0\x0b\0\0......\0\0\0..\xff\xff\?\0.\0\0..\0\xff\xff.*Hewlett-Packard Company\0|s p/Hewlett-Packard X server/ o/HP-UX/ cpe:/o:hp:hp-ux/a
match X11 m|^\x01\0\x0b\0\0......\0\0\0..\xff\xff\?\0.\0\0..\0\xff\xff.*Santa Cruz Operation Inc\.\0|s p/SCO X server/ o/SCO UNIX/ cpe:/o:sco:sco_unix/a

# HP MC/ServiceGuard for Linux A.11.14.02
match X11 m|^\0\0\0\x01\0\0\0\x0c\0\0\0\0$| p|HP MC/ServiceGuard| cpe:/a:hp:serviceguard/

match X11 m|^\x01\0\x0b\0\0......\0\0\0..\xff\xff\?\0.*Labtam Europe Ltd\.\0\0\x01\x01|s p/Labtam X-WinPro/

match X11 m|^\x01\0\x0b\0\0.....\0\0\0\0.*NetSarang Computer, Inc\.|s p/NetSarang XManager/ o/Windows/ cpe:/a:netsarang:xmanager/ cpe:/o:microsoft:windows/a
match X11 m|^\x01\0\x0b\0\0.....\0\0\0\0.*WRQ, Inc\.|s p/ReflectionX/ o/Windows/ cpe:/o:microsoft:windows/a
match X11 m|^\x01\0\x0b\0\0.....\0\0\0\0.*RealVNC Ltd|s p/RealVNC/ cpe:/a:realvnc:realvnc/
match X11 m|^\x01\0\x0b\0\0.....\0\0\0\0.*Pexus Systems, Inc|s p/Pexus X Server/ o/Windows/ cpe:/o:microsoft:windows/a
match X11 m|^\x01\0\x0b\0\0.....\0\0\0\0.*HDS Network Systems, Inc\. \(([^)]+)\)|s p/HDS X Server/ v/$1/ d/terminal server/ o/NetOS/ cpe:/o:hds:netos/
match X11 m|^\x01\0\x0b\0\0.*The Cygwin/X Project|s p/Cygwin X Server Project/ o/Windows/ cpe:/a:redhat:cygwin/ cpe:/o:microsoft:windows/a
match X11 m|^\x01\0\x0b\0\0.....\0\0\0\0.*Labtam Europe Ltd\.|s p/Labtam X-WinPro/ o/Windows/ cpe:/o:microsoft:windows/a
match X11 m|^\x01\0\x0b\0\0.....\0\0\0\0.*ASTEC, Inc\.|s p/ASTEC-X/ o/Windows/ cpe:/o:microsoft:windows/a
match X11 m=^\x01\0\x0b\0\0.....\0\0\0\0.*(?:LabF\.com|LabF)=s p/LabF WinaXe/ o/Windows/ cpe:/o:microsoft:windows/a
match X11 m|^\x01\0\x0b\0\0.....\0\0\0\0.*MicroImages, Inc\.\0|s p/MicroImages MiX/ o/Windows/ cpe:/o:microsoft:windows/a
match X11 m|^\x01\0\x0b\0\0.....\0\0\0\0.*Attachmate Corporation\0|s p/Attachmate Kea! X server/ o/Windows/ cpe:/o:microsoft:windows/a
match X11 m|^\x01\0\x0b\0\0.....\0\0\0\0.*WebTerm X ([\d.]+) by Powerlan USA\0|s p/Powerlan WebTerm X server/ v/$1/ o/Windows/ cpe:/o:microsoft:windows/a
match X11 m|^\x01\0\x0b\0\0.....\0\0\0\0.*Silicon Graphics|s p/SGI IRIX X server/ o/IRIX/ cpe:/o:sgi:irix/a

match X11 m|^\x01\0\x0b\0\0.......\0\0..\xff\xff.\0\0\x01\0\0.\0\xff\xff......\x08\xff....Colin Harrison\0|s p/Xming X server/ o/Windows/ cpe:/a:straightrunning:xming/ cpe:/o:microsoft:windows/a
match X11 m|^\x01\0\x0b\0\0.......\0\0..\xff\xff.\0\0\x01\0\0.\0\xff\xff......\x08\xff....The Xming Project\0| p/Xming X server/ o/Windows/ cpe:/a:straightrunning:xming/ cpe:/o:microsoft:windows/a
match X11 m|^\x01\0\x0b\0\0.....\0\0\0\0.*Open source\0|s p/Android X Server/ d/phone/ o/Android/ cpe:/o:google:android/ cpe:/o:linux:linux_kernel/

# Strange one... X.Org Group?
match X11 m|^\x01\0\x0b\0\0.....\0\0\0\0.*The X\.Org Group\0|s p|Xvnc X11/VNC proxy|
match X11 m|^\x01\0\x0b\0\0......\0\0\0.*Moba/X\0|s p/MobaXterm/ o/Windows/ cpe:/a:mobatek:mobaxterm/ cpe:/o:microsoft:windows/a
match X11 m|^\x01\0\x0b\0\0......\0\0\0.*HC-Consult\0|s p/VcXsrv X server/ o/Windows/ cpe:/a:hc-consult:vcxsrv/ cpe:/o:microsoft:windows/a

match X11 m|^\x01\0\x0b\0\0\0\x4C\0\xA0\xE0\x63\x02\0\0| i/open/
softmatch X11 m|^\x01\0\x0b\0\0......\0\0\0.|s

match xfs m|^\0\0\x02\0\0\0\x01\0\x04\0\0\0\0\r([\w._-]+):\d+\0\x07\0\0\0\0 \x10\0,\x1a\0\0X\.Org Foundation\x01\n\x01\0\x05\0\0\0\xe6\xbf\xc0\xb5\0\0\0\0\0\0\0\0$| p/X.Org xfs font server/ h/$1/ cpe:/a:x:x.org_x11/

match giop m|^GIOP\x01\0\x01\x06\0\0\0\0$| p/omniORB omniNames/ i/Corba naming service/
match domain m|^\x80\xf0\x80\x12\0\x01\0\0\0\0\0\0\x20CKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\0\0!\0\x01| p/Microsoft DNS/ o/Windows/ cpe:/a:microsoft:dns/ cpe:/o:microsoft:windows/a
match gadu m|^UDAG$| p/Kadu polish IM client/ cpe:/a:kadu:kadu/

# Skype - Protocol seems to spew out 14 random characters upon
# connection. Luckily, this shouldn't conflict any other X11 services.
#match skype m|^.{14}$|s p/Skype VoIP data channel/


##############################NEXT PROBE##############################
Probe TCP FourOhFourRequest q|GET /nice%20ports%2C/Tri%6Eity.txt%2ebak HTTP/1.0\r\n\r\n|
rarity 6
ports 80-85,88,2100,8000-8010,8080-8085,8880-8888,9999,49152
sslports 443,4443,8443
fallback GetRequest

match bittorrent-tracker m|^HTTP/1\.0 404 Not Found\r\nContent-Length: \d+\r\nContent-Type: text/plain\r\nPragma: no-cache\r\n\r\nyour file may exist elsewhere in the universe\nbut alas, not here\n| p/BitTornado tracker httpd/

match http m|^HTTP/1\.0 499 Access Denied\.\r\nContent-Length: \d+\r\nContent-Type: text/html\r\nConnection: close\r\n\r\n<HTML><TITLE>Access Denied</TITLE><H2>Navi Error\. Access Denied\.</H2><BODY><P>Please check the typed URL\.</P></BODY></HTML>| p/EMC Clariion CX300 switch http config/ d/switch/ cpe:/h:emc:clariion_cx300/a

match http m|^HTTP/1\.0 200 OK\nContent-Type: text/html \n\n<tr>\n<td>\n<img src=\"/clearpixelIcon\?ac=20\" height=\"5\" width=\"0\" border=\"0\" alt=\"\" title=\"\">| p/Perforce p4web http interface/
match http m|^HTTP/1\.0 200 OK\r\nContent-Type: text/html \r\n\r\n<tr>\n<td>\n<img src=\"/clearpixelIcon\?ac=20\" height=\"5\" width=\"0\" border=\"0\" alt=\"\" title=\"\">| p/Perforce p4web http interface/

match http m|^HTTP/1\.0 404\nContent-Type: text/html\n\n<HTML>\n<HEAD>\n<!-- \(C\) COPYRIGHT IBM CORP\. 1996,2004 -->\n<TITLE>LCFD Error 404</TITLE>\n| p/IBM Tivoli Endpoint httpd/ cpe:/a:ibm:tivoli_endpoint_manager/
# Might be too general:
match http m|^HTTP/1\.0 200\r\nContent-type: text/html\r\n\r\nInvalid request$| p/IBM Tivoli Endpoint httpd/ cpe:/a:ibm:tivoli_endpoint_manager/
match http m|^<html>\n<link rel=stylesheet href=form\.css>\n<body onload='document\.login\.passwd\.focus\(\)'>\n<form name=login method=POST>\n.*System Name &nbsp; : ([^\r\n]+)\n.*Location Name : ([^\r\n]+)\n.*MAC Address &nbsp;&nbsp; : ([-\w]+)\n\n|s p|Allnet/Cameo/D-Link switch http config| i/$1@$2; MAC $3/ d/switch/
match http m|^HTTP/1\.1 401 Unauthorized\r\nContent-Type: text/html\r\nWWW-Authenticate: Digest realm=\"Raid Console\", qop=\"auth\", nonce=\"\w+\"\r\nContent-Length: 0\r\n\r\n| p/Areca RAID-Controller http config/
match http m|^HTTP/1\.1 404 Not Found\r\n\r\n404 Not Found: \[/nice ports,/Trinity\.txt\.bak\]$| p/SHTTPD/
match http m|^HTTP/1\.0 404 Not Found\r\n.*<LINK REL=\"stylesheet\" HREF=\"/style\.css\" TYPE=\"text/css\"></HEAD>\r\n<BODY><H2>URL demand\xe9e introuvable\.</H2>|s p/Lexmark Optra T610 printer http config/ i/French/ d/printer/ cpe:/h:lexmark:optra_t610/a
match http m|^HTTP/1\.0 403 File not found - unknown extension\r\n\r\n| p|apt-cache/apt-proxy httpd| o/Linux/ cpe:/o:linux:linux_kernel/a
match http m|^HTTP/1\.1 403 Sorry, not allowed to fetch that type of file: Tri%6Eity\.txt%2ebak\r\n\r\n| p/apt-cache httpd/
match http m|^HTTP/1\.0 304 Not Modified\r\nContent-Length: 0\r\nServer: Unknown\r\n\r\n| p/McData 4500 fibre switch http config/ d/switch/
match http m|^HTTP/1\.1 404 Not Found\r\nServer: KM-httpd/([-\w_.]+)\r\n.*<em>HTTP Response Code: </em> 404<br><em>From server at: </em> ([-\w_.]+)<br><em>|s p/Konica Minolta printer http config/ v/$1/ d/printer/ h/$2/
match http m|^HTTP/1\.0 404 Object Not Found\r\nContent-Type: text/html\r\n\r\n<body><h1>HTTP/1\.0 404 Object Not Found\r\n</h1></body>| p/Microsoft IIS httpd/ v/3.X/ o/Windows/ cpe:/a:microsoft:internet_information_services:3/ cpe:/o:microsoft:windows/a
match http m|^HTTP/1\.0 \d\d\d (?:[^\r\n]*\r\n(?!\r\n))*?Server: Medusa/([\w.]+)\r\n.*<title>Asterisk/DeStar PBX :: Page not found</title>\n|s p/Medusa httpd/ v/$1/ i/Destar Asterisk PBX http config/
match http m|^HTTP/1\.1 404 Can't find file\r\n$| p|Dynamode/Motorola WAP http config| d/WAP/
match http m|^HTTP/1\.0 404 Not Found\r\n(?:[^\r\n]+\r\n)*?Server: lighttpd/([\d.]+)\r\n|s p/lighttpd/ v/$1/ cpe:/a:lighttpd:lighttpd:$1/
match http m|^HTTP/1\.0 200 OK\r\nContent-Type: text/html\r\nContent-Length: 241\r\n\r\n<html><head><title>POPFile Web Server Error 404| p/POPFile web control interface/
match http m|^HTTP/1\.0 400 No any servlet found for serving /\r\ncontent-type: text/html\r\nconnection: keep-alive\r\ncontent-length: \d+\r\nmime-version: [\d.]+\r\n\r\n<HTML><HEAD><TITLE>400 No any servlet found for serving /</TITLE></HEAD><BODY BGCOLOR=\"#F1D0F2\"><H2>400 No any servlet found for serving /</H2><HR><ADDRESS><A HREF=\"http://tjws\.sourceforge\.net\">Rogatkin's JWS based on Acme\.Serve Version ([\w._-]+), \$Revision: ([\w._-]+) \$| p/Rogatkin's JWS httpd/ v/$2/ i/Based on Acme.Serve $1/
match http m|^HTTP/1\.1 404 Not Found\r\nContent-Type: text/html\r\nConnection: close\r\n\r\n<html>\n  <head>\n    <title>Linksys PAP2 Configuration</title>\r\n| p/Linksys PAP2 VoIP http config/ d/VoIP adapter/
match http m|^HTTP/1\.1 200 OK.*\nServer: HPSMH\n.*\n<title>System Management Homepage</TITLE>|s p/HP System Management Homepage/ o/HP-UX/ cpe:/a:hp:system_management_homepage/ cpe:/o:hp:hp-ux/a
match http m|^HTTP/1\.0 499 Unauthorized user access\. Check User/Password/Scope\. \r\nContent-Length: \d+\r\nContent-Type: text/html\r\nConnection: close\r\n\r\n<HTML><TITLE>Access Denied</TITLE><H2>Navi Error\. Access Denied\.</H2><BODY><P>Please check the typed URL\.</P></BODY></HTML>| p|Dell/EMC CX300 Navisphere http config| d/storage-misc/
match http m|^HTTP/1\.1 200 OK\r\nConnection: close\r\nContent-Length: 0\r\nServer: Indy/([\w._-]+)\r\nSet-Cookie: IDHTTPSESSIONID=\w+; path=/\r\n\r\n$| p/Indy httpd/ v/$1/ i/MediaPortal TV-Server http config/ d/media device/ cpe:/a:indy:httpd:$1/
match http m|^HTTP/1\.1 200 OK\r\n(?:[^\r\n]+\r\n)*?Server: Indy/([\w._-]+)\r\n|s p/Indy httpd/ v/$1/ cpe:/a:indy:httpd:$1/
match http m|^HTTP/1\.0 200 OK\r\nCache-Control: no-cache\r\nContent-Type:text/html\r\nContent-Length:  +\d+\r\n\r\n.*size=\"2\">VoIP System Embedded \n\t\tWEB Server ([\w._-]+),|s p/Perfectone IP301 VoIP phone http config/ v/$1/ d/VoIP phone/ cpe:/h:perfectone:ip301/a
match http m|^HTTP/1\.0 200 OK\nContent-Type: text/html; charset=utf-8\nConnection: close\n\nUnknown operator\.$| p/Arc httpd/
match http m|^HTTP/1\.0 403 Forbidden\r\n.*\r\n<title>Abilis CPX - 403 forbidden</title>|s p/Abilis CPX http config/ d/PBX/
match http m|^HTTP/1\.1 200 OK\r\nConnection: close\r\nCache-Control: no-cache\r\nServer: WEBCAM\r\nCONTENT-LENGTH:\d+\r\n\r\n\r\nHTTP requested /nice%20ports%2C/Tri%6Eity\.txt%2ebak was not found  UID (\d+) PID (\d+)\n| p/Pixord IP Camera http config/ i/UID $1; PID $2/ d/webcam/
match http m|^<html>\n<link rel=stylesheet href=form\.css>\n<body onload='document\.login\.passwd\.focus\(\)'>\n<form name=login method=POST>\n.*<td bgcolor=#C1D6FF>&nbsp;System Name &nbsp; : ([\w._-]+)\n.*&nbsp;MAC Address &nbsp;&nbsp; : ([\w-]+)\n|s p/Web-Smart Gigabit Ethernet Switch http config/ i/MAC $2/ d/switch/ h/$1/
match http m|^HTTP/1\.0 404 Not Found\r\n\r\nThis page does not exist or you are not authorized to view it| p/Google Search Appliance httpd/ d/specialized/ cpe:/a:google:search_appliance_software/
match http m|^HTTP/1\.0 404 Document Follows\r\nContent-Type: text/html\r\nContent-Length: \d+\r\n\r\n<HEAD><TITLE>404 Not Found</TITLE></HEAD>\r\n<BODY><H1>404 Not Found</H1>\r\nUrl '/NICE%20PORTS%2C\\TRI%6EITY\.TXT%2EBAK' not found on server<P>\r\n</BODY>| p/HP StorageWorks MSL4048 http config/ d/storage-misc/
match http m|^HTTP/1\.0 404 Document Follows\r\nContent-Type: text/html\r\nContent-Length: 147\r\n\r\n<HEAD><TITLE>404 Not Found</TITLE></HEAD>\r\n<BODY><H1>404 Not Found</H1>\r\nUrl '/nice%20ports%2C/Tri%6Eity\.txt%2ebak' not found on server<P>\r\n</BODY>| p/Crestron automation system httpd/ d/specialized/ cpe:/h:crestron/
match http m|^HTTP/1\.1 404 (?:[^\r\n]*\r\n(?!\r\n))*?Server: WMI (V[\w._-]+)\r\n.*HTTP/1\.1 404 NOT FOUND!<br>Check flash:/s3p03_00\.web , please\.</h1>|s p/WMI/ v/$1/ i/3Com 4500 switch http config/ d/switch/ cpe:/h:3com:4500/a
match http m|^HTTP/1\.0 401 Unauthorized\r\nWWW-Authenticate: Basic realm=\"/webpages\"\r\nServer: DigiSprite\r\n| p/DigiSprite httpd/ d/webcam/
match http m|^HTTP/1\.1 301 Moved Permanently\r\nDate: .*\r\nLocation: https://([\w_.-]+)/nice%20ports%2C/Tri%6Eity\.txt%2ebak\r\nConnection: close\r\nContent-Type: text/html\r\nContent-Length: 56\r\n\r\n<HTML><BODY><H1>301 Moved Permanently</H1></BODY></HTML>$| p/VMware ESX 4.0 Server httpd/ h/$1/ cpe:/o:vmware:esx:4.0/
match http m|^HTTP/1\.1 404 Not Found\r\nContent-Type: text/html\r\nConnection: close\r\n\r\n<html>\n  <head>\n    <title>Sipura SPA Configuration</title>\r\n  </head>\n  <body>\n        <p><font size=\"5\" color=\"#990000\">404 Not Found\r\n!</p>\n</body>\n</head></html>\n$| p/Sipura SPA-2100 VoIP phone http config/ d/VoIP phone/ cpe:/h:sipura:spa-2100/a
match http m|^HTTP/1\.1 403\r\nConnection: close\r\nContent-Type: text/plain\r\n\r\nAccess denied$| p/Vibe Streamer music server httpd/ o/Windows/ cpe:/o:microsoft:windows/a
match http m|^HTTP/1\.0 404 Not Found\r\nServer: httpd\r\n.*<HTML><HEAD><TITLE>404 Not Found</TITLE></HEAD>\n<BODY BGCOLOR=\"#cc9999\"><H4>404 Not Found</H4>\nFile not found\.\n</BODY></HTML>\n$|s p/DD-WRT milli_httpd/ d/WAP/ o/Linux/ cpe:/o:linux:linux_kernel/a
match http m|^HTTP/1\.1 404 Not Found\r\nServer: HTTP\r\n(?:[^\r\n]+\r\n)*?Content-Type: text/html; charset=utf-8\r\nConnection: close\r\nCache-Control: no-cache\r\n\r\n<HTML><HEAD><TITLE>404 Not Found</TITLE></HEAD>\n<BODY BGCOLOR=\"#fcfcfc\"><H4>404 Not Found</H4>\nFile not found\.\n$|s p/Aladino SIP phone http config/ d/VoIP phone/
match http m|^HTTP/1\.1 404 Not Found\r\nContent-Type: text/html\r\nContent-Length: 232\r\nCache-Control: max-age=0\r\n.*<address>iNTERFACEWARE Iguana Administration Server</address>\r\n</body>\r\n\r\n</html>\r\n|s p/Interfaceware Iguana heathcare management http interface/
match http m|^HTTP/1\.1 404 Not Found\r\nServer: Switch \r\n.*<html dir=ltr>\n<head>.*<h1 style=\"COLOR:000000; FONT: 24pt/30pt \">HTTP/1\.1 404 NOT FOUND!<br>Check flash:/http\.zip , please\.</h1>|s p/3Com switch http config/ d/switch/
match http m|^HTTP/1\.0 404 Not found\r\nDate: .*\r\nServer: Acme\.Serve/v([\w._ -]+)\r\nConnection: close\r\nContent-type: text/html; charset=Cp1252\r\n\r\n| p/Acme.Serve/ v/$1/ i/APC PowerChute/ d/power-device/ cpe:/a:acme:acme.serve:$1/
match http m|^HTTP/1\.0 404 Not found\nDate: .*\nServer: Acme\.Serve/v([\w._ -]+)\nConnection: close\nContent-type: text/html; charset=ISO-8859-1\n\n| p/Acme.Serve/ v/$1/ i/APC PowerChute/ d/power-device/ cpe:/a:acme:acme.serve:$1/
match http m|^HTTP/1\.1 404 Not Found\r\nContent-Type: text/plain\r\nContent-Length: 35\r\nConnection: close\r\n\r\nError 404: Not Found\nFile not found$| p/Mongoose httpd/ cpe:/a:cesanta:mongoose/
match http m|^HTTP/1\.1 404 Not Found\r\nContent-Length: 35\r\nConnection: close\r\n\r\nError 404: Not Found\nFile not found$| p/Mongoose httpd/ v/3.7/ cpe:/a:cesanta:mongoose:3.7/
match http m|^HTTP/1\.0 200 OKContent-Type: text/htmlContent-Length: \d+\r\n\r\nYou have reached Aperio DSC Server running on 0\.0\.0\.0 / \d+\r\n Number of current sessions = \d+\r\n| p/Aperio Digital Slide Conferencing httpd/
match http m|^HTTP/1\.0 404 Not Found\r\nContent-Length: 0\r\nConnection: Close\r\nContent-Type: text/html\r\n\r\n$| p/Google Mini search appliance httpd/
match http m|^HTTP/1\.1 404 Not Found\r\n.*<small>Powered by Jetty://</small>|s p/Jetty/ cpe:/a:mortbay:jetty/
# WebCam webserver Sharx Security SCNC2700 https://www.sharxsecurity.com/products.html
# Elro Network Camera
# foscam ip camera
match http m|^HTTP/1\.1 404 Not Found\r\nServer: Netwave IP Camera\r\n| p/Netwave webcam http config/ d/webcam/
match http m|^HTTP/1\.0 404 Not Found\r\nServer: IP_SHARER WEB ([\w._-]+)\r\nContent-type: text/html\r\nConnection: close\r\n\r\n| p/IP_SHARER WEB/ v/$1/ d/router/ cpe:/a:trendnet:ip_sharer_web:$1/
match http m|^HTTP/1\.0 404 NOT FOUND\r\nContent-Type:text/html\r\n.*<TITLE>\r\n      MiniWeb Client Workbench\r\n    </TITLE>\r\n  </HEAD>\r\n  <link rel=\"stylesheet\" type=\"text/css\" href=\"/CSS/MiniWeb\.css\">\r\n|s p/Siemens Simatic HMI MiniWeb httpd/
match http m|^HTTP/1\.1 404 Not Found\r\nContent-Type: text/html\r\nConnection: close\r\n\r\n<html>\n<head>\n<title>(SPA\w+) Configuration Utility</title>\n| p/Cisco $1 VoIP phone http config/ d/VoIP phone/ cpe:/h:cisco:$1/
match http m|^HTTP/1\.1 400 ERROR\r\nConnection: keep-alive\r\nContent-Length: 17\r\nContent-Type: text/html\r\n\r\n\r\ninvalid request$| p/uTorrent utserver web interface/ o/Linux/ cpe:/a:utorrent:utorrent/ cpe:/o:linux:linux_kernel/
match http m|^HTTP/1\.0 404 Not Found ?\r\nDate: .*\r\nServer: ZWorld Rabbit\r\nConnection: close\r\nContent-Type: text/html\r\n\r\n<HTML><HEAD><TITLE>404 Not Found</TITLE></HEAD><BODY>404 Not Found</BODY></HTML>\r\n\r\n$| p/Z-World Rabbit microcontroller httpd/
match http m|^HTTP/1\.0 200 OK\nContent-Type: text/html\n\n<head><title>File not found</title></head><h1><tt><font color=red>404 / OOPS!</font></tt></h1>\n<i>'File not found'</i>,<br>\nHow dare they say!<br>\nI am here,<br>\njust out of the way\.<br>\n<br>\nHow was I found\?<br>\nA typo\? A mistake\?<br>\nOr were you snooping\?!<br>\n<br>\nNonetheless, we meet at last\.<br>\nI am found - hip hip hooray!<br>\nNevermore can they say:<br>\n<i>'File not found! <a href=index>Back to main page!</a>'</i><br>\n<br>\n<a href=index><img src=\"puretraclogo\.png\" border=0></a>$| p/PureChoice Nose environmental monitor http config/ cpe:/h:purechoice:nose/
match http m|^HTTP/1\.0 200 OK\r\n.*<link rel=\"stylesheet\" type=\"text/css\" href=\"/gsa-style\.css\">\n<!--\[if IE 6\]>\n      \n        <link rel=\"stylesheet\" type=\"text/css\" href=\"IE6fixes\.css\"/>\n        <link rel=\"stylesheet\" type=\"text/css\" href=\"\.\./IE6fixes\.css\"/>\n    <!\[endif\]--><link rel=\"icon\" href=\"/favicon\.gif\" type=\"image/x-icon\">\n<title>Greenbone Security Assistant</title>\n|s p/Greenbone Security Assistant/ cpe:/a:greenbone:greenbone_security_assistant/
match http m|^HTTP/1\.1 200 OK\r\n.*<link rel=\"stylesheet\" type=\"text/css\" href=\"/gsa-style\.css\">\n<!--\[if IE 6\]>\n      \n        <link rel=\"stylesheet\" type=\"text/css\" href=\"IE6fixes\.css\"/>\n        <link rel=\"stylesheet\" type=\"text/css\" href=\"\.\./IE6fixes\.css\"/>\n    <!\[endif\]--><link rel=\"icon\" href=\"/favicon\.gif\" type=\"image/x-icon\">\n<title>Greenbone Security Assistant</title>\n|s p/Greenbone Security Assistant/ v/2.0.1/ cpe:/a:greenbone:greenbone_security_assistant:2.0.1/
match http m|^HTTP/1\.0 404 Not Found\r\nContent-Type: text/html\r\nCache-Control: public\r\nPragma: cache\r\nExpires: .* GMT\r\nDate: .* GMT\r\nLast-Modified: Fri, 12 Aug 2011 00:00:00 GMT\r\nAccept-Ranges: bytes\r\nConnection: close\r\n\r\n<html>\n<head>\n  <title>404 Not Found</title>\n</head>\n<body bgcolor=\"ffffff\">\n  <h2>404 Not Found<h2>\n  <p>\n  \n</body>\n</html>\n$| p/Orange Livebox WAP http config/ d/WAP/
match http m|^HTTP/1\.1 200 OK\r\nCache-Control: private, max-age=0, no-cache\r\nContent-Length: 188\r\nContent-Type: text/html\r\n\r\n<P align=\"center\"><STRONG><FONT color=\"#ff3333\">GSCSERVER DEFAULT HANDLER - FILE NOT FOUND</P><BR><P align=\"center\">REQUESTED FILE = nice%20ports%2C/tri%6eity\.txt%2ebak</FONT></STRONG></P>$| p/Geutebrueck GeViControl video surveillance http admin/ d/security-misc/
match http m|^HTTP/1\.1 200 OK\r\nConnection: close\r\nServer: Apache\r\nContent-Length: 43\r\n\r\n<h3>No site configured at this address</h3>$| p/Metasploit reverse_http stager/
match http m|^HTTP/1\.1 404 Not Found\r\n(?:[^\r\n]+\r\n)*?Expires: Thu, 01-Jan-1970 00:00:00 GMT\r\n.*<title>VMware vCloud Director</title>|s p/VMware vCloud Director/ cpe:/a:vmware:vcloud_director/
match http m|^HTTP/1\.1 404 [^\r\n]*\r\nContent-Type: text/html;charset=.*<h3>Apache Tomcat/([\d.]+)</h3></body></html>$|s p/Apache Tomcat/ v/$1/ cpe:/a:apache:tomcat:$1/a
match http m|^HTTP/1\.1 404 /nice%20ports%2C/Tri%6Eity\.txt%2ebak\r\nContent-Type: text/html;charset=utf-8\r\nContent-Length: \d+\r\nDate: .*\r\nConnection: close\r\nServer: wifi-security-server\r\n\r\n<html><head><title>Apache Tomcat - Error report</title>| p/Apache Tomcat/ cpe:/a:apache:tomcat/a
match http m|^HTTP/1\.1 401 Unauthorized\r\nServer: LG ROAP Server\r\nPragma: no-cache\r\nCache-Control: no-store, no-cache, must-revalidate\r\nConnection: Close\r\nContent-Length: \d+\r\nContent-Type: application/atom\+xml; charset=utf-8\r\n\r\n<\?xml version=\"1\.0\" encoding=\"utf-8\"\?><envelope><ROAPError>401</ROAPError><ROAPErrorDetail>Unauthorized</ROAPErrorDetail></envelope>$| p/LG Smart TV Rights Object Acquisition Protocol/ d/media device/
match http m|^HTTP/1\.1 200 OK\r.*\nX-Powered-By: (Servlet/[\d.]+ JSP/[\d.]+) \(Oracle GlassFish Server ([\d.]+) Java/Oracle Corporation/([\d.]+)\)\r.*\nX-Powered-By: (JSF/[\d.]+)\r\n|s p/Oracle GlassFish application server/ v/$2/ i|$1 $4 Java/$3| cpe:/a:oracle:glassfish_server:$2/
match http m|^HTTP/1\.1 200 OK\r.*\nServer: Oracle GlassFish Server ([\d.]+)\r\n|s p/Oracle GlassFish application server/ v/$1/ cpe:/a:oracle:glassfish_server:$1/
# Milestone ImageServer, Milestone XProtect Enterprise
match http m|^HTTP/1\.1 404 Object Not Found\r\nDate: .*\r\nConnection: close\r\nContent-Type: text/plain\r\n(?:[^\r\n]+\r\n)*?\r\nSorry, file not found\.$|s p/Milestone httpd/
match http m|^HTTP/1\.1 200 OK\r\nContent-Type:text/html\r\nExpires: .*\r\nPragma: no-cache\r\nServer: LPC Http Server/V([\d.]+)\r\n\r\n| p/Konica Minolta LPC httpd/ v/$1/ d/printer/
match http m|^HTTP/1\.1 404 Not Found\r\nServer: ReeCam IP Camera\r\n| p/ReeCam IP Camera httpd/ d/webcam/
match http m|^HTTP/1\.1 301 Moved Permanently\r\nLocation: /error\r\n$| p/Enphase httpd/ d/power-device/
match http m|^HTTP/1\.1 404 Not Found\r\nSet-Cookie: sid=[0-9a-f]{128}; path=/; httponly\r\nContent-Type: application/json\r\nDate: .*\r\nConnection: close\r\n\r\n{\"message\":\"Resource Not Found\",\"status\":404}| p/Node.js/ cpe:/a:nodejs:node.js/
match http m|^HTTP/1\.0 200 OK\r\nLast-modified: .*\r\nServer: ESERV-10/([\d.]+)\n| p/Viola ESERV-10 httpd/ v/$1/
match http m|^HTTP/1\.1 503 DNS error for hostname nice%20ports%2C: Name or service not known\. If nice%20ports%2C refers to a configured cache repository, please check the corresponding configuration file\.\r\nContent-Length: 478\r\nContent-Type: text/html\r\nDate: .*\r\nServer: Debian Apt-Cacher NG/([\w._-]+)\r\nConnection: close\r\n\r\n| p/Debian Apt-Cacher NG/ v/$1/ cpe:/a:debian:apt-cacher:$1/
match http m|^HTTP/1\.1 404 Not Found\r\nContent-Type: text/html\r\nConnection: close\r\n\r\n<html>\r\n<head>\r\n<title>(SPA\d\d\d[\w._-]*) Configuration Utility</title>| p/Cisco $1 http config/ d/VoIP phone/ cpe:/h:cisco:$1/a
match http m|^HTTP/1\.0 \d\d\d \r\n(?:[^\r\n]+\r\n)*?server: CubeCoders-McMyAdmin/IAWS\r\n.*<p id=\"verinfo\">McMyAdmin Enterprise - Web Backend v([\d.]+)</p>|s p/CubeCoders McMyAdmin Enterprise Minecraft control panel/ v/$1/
match http m|^HTTP/1\.1 404 Not Found\r\nContent-Type: text/plain\r\nDate: .*\r\nConnection: close\r\n\r\nCannot GET /nice%20ports%2C/Tri%6Eity\.txt%2ebak| p/Express.js httpd/
match http m|^HTTP/1\.1 200 OK\r\nDate: .* GMT\r\nConnection: Keep-Alive\r\nContent-Type: text/html\r\nCACHE-CONTROL: no-cache\r\nContent-Length: \d+\r\n\r\n<html>\n<head>\n<[Mm][Ee][Tt][Aa] http-equiv=\"Content-Type\" content=\"text/html; charset=[Uu][Tt][Ff]-8\"(?: /)?>\r?\n<title>replace</title>\n<body>\n<script language=\"JavaScript\" type=\"text/javascript\">\nvar pageName = '/';\n| p/Huawei router http admin/ d/broadband router/
match http m|^HTTP/1\.1 401 Unauthorized\r\nAccept-Ranges: bytes\r\nContent-Length: 0\r\nWww-Authenticate: Basic realm="([^"]+)"\r\nSet-Cookie: com\.apple\.servermgrd=.*\r\nDate: .*\r\n\r\n| p/Apple Server Admin/ o/Mac OS X/ h/$1/ cpe:/o:apple:mac_os_x/a
# FIXME: wrong cpe?
match http m|^HTTP/1\.1 404 /nice%20ports%2C/Tri%6Eity\.txt%2ebak\r\nX-FRAME-OPTIONS: SAMEORIGIN\r\nContent-Type: text/html;charset=utf-8\r\nContent-Length: \d+\r\nDate: .*\r\nConnection: close\r\nServer: DSM\r\n\r\n<html><head><title>JBoss Web/([\w._-]+) - JBWEB000064: Error report</title>| p/JBoss Web/ v/$1/ i/Vormetric Data Security Manager/ d/security-misc/ cpe:/a:redhat:jboss_enterprise_web_platform:$1/ cpe:/h:vormetric:data_security_manager/
match http m|^HTTP/1\.0 404 Not Found\r\nContent-Type: text/plain; charset=utf-8\r\nDocker-Distribution-Api-Version: registry/([\d.]+)\r\nX-Content-Type-Options: nosniff\r\nDate: .*\r\nContent-Length: 19\r\n\r\n404 page not found\n| p/Docker Registry/ i/API: $1/ cpe:/a:redhat:docker/
# hp2530
match http m|^HTTP/1\.0 200 OK\r\nServer: eHTTP v([\w._-]+)\r\nConnection: close\r\nContent-Type: text/html\r\nContent-Length: \d+\r\nCache-Control: no-cache\r\nX-Frame-Options: SAMEORIGIN\r\n\r\n| p/eHTTP/ v/$1/ i/HP switch http config/ d/switch/ cpe:/a:ehttp:ehttp:$1/
match http m|^HTTP/1\.1 404 Not Found\r\nContent-Type: text/html\r\nConnection: close\r\n\r\n<html>\n  <head>\n    <title>Cisco SPA Configuration</title>\r\n| p/Cisco SPA IP phone http config/ d/VoIP phone/
match http m|^HTTP/1\.0 302 Moved Temporarily\r\nLocation: \.\./index\.html\r\nServer: NET-DK/([\d.]+)\r\nDate: .*\r\nConnection: close\r\nSet-Cookie: sessionToken=\d+; path=/;\r\n\r\n| p/NET-DK httpd/ v/$1/ i/Compal CH7465LG-ZG cable modem/ d/broadband router/ cpe:/h:compal:ch7465lg-zg/a
match http m|^HTTP/1\.1 404 Not Found\r\nContent-Type: text/html\r\nConnection: close\r\n\r\n<html>\n  <head>\n    <title>Linksys SPA Configuration</title>\r\n  </head>\n  <body>\n        <p><font size="5" color="#990000">404 Not Found\r\n!</p>\n</body>\n</head></html>\n| p/Linksys SPA VoIP phone http config/ d/VoIP phone/
# Rebranded Samsung?
match http m|^HTTP/1\.1 200 OK\r\nContent-Type: unknown\r\nContent-Length: 0\r\n\r\n$| p/Ziggo Mediabox XL/ d/media device/
match http m|^HTTP/1\.1 500 Server error\r\nConnection: close\r\nContent-Type: text/html\r\nContent-Length: \d+\r\nPragma: no-cache\r\nExpires: .*\r\n\r\n<html><head><script>\r\nfunction IWTop\(\)\{| p/Atozed IntraWeb httpd/ cpe:/a:atozed:intraweb/

match http m=^HTTP/1\.0 404 Not Found\r\n(?:[^<]+|<(?!/head>))*?<style>\nbody \{ background-color: #fcfcfc; color: #333333; margin: 0; padding:0; \}\nh1 \{ font-size: 1\.5em; font-weight: normal; background-color: #9999cc; min-height:2em; line-height:2em; border-bottom: 1px inset black; margin: 0; \}\nh1, p \{ padding-left: 10px; \}\ncode\.url \{ background-color: #eeeeee; font-family:monospace; padding:0 2px;\}\n</style>=s p/PHP cli server/ v/5.5 or later/ cpe:/a:php:php/
match http m=^HTTP/1\.0 404 Not Found\r\n(?:[^<]+|<(?!/head>))*?<style>\nbody \{ background-color: #ffffff; color: #000000; \}\nh1 \{ font-family: sans-serif; font-size: 150%; background-color: #9999cc; font-weight: bold; color: #000000; margin-top: 0;\}\n</style>=s p/PHP cli server/ v/5.4/ cpe:/a:php:php:5.4/

match http-proxy m|^HTTP/1\.0 404 Error\r\n.*<HTML><HEAD><TITLE>Extra Systems Proxy Server</TITLE>|s p/Extra Systems http proxy/ o/Windows/ cpe:/o:microsoft:windows/a
match http-proxy m|^HTTP/1\.1 502 Bad Gateway\r\nConnection : close\r\n.*\n<title>The requested URL could not be retrieved</title>\n<link href=\"http://passthrough\.fw-notify\.net/static/default\.css\"|s p/Astaro firewall http proxy/ d/firewall/ cpe:/a:astaro:security_gateway_software/
match http-proxy m|^HTTP/1\.0 404 Not Found\r\nDate: .*\r\nServer: PanWeb Server/ - \r\n| p/Palo Alto PanWeb httpd/ d/firewall/ cpe:/a:paloaltonetworks:panweb/

match raop m|^RTSP/1\.0 401 Unauthorized\r\nServer: AirTunes/([\w._-]+)\r\nWWW-Authenticate: Digest realm=\"raop\" nonce=\"\w+\"\r\n\r\n$| p/Apple AirTunes RAOP/ v/$1/ i/Apple AirPort Express/ d/WAP/ cpe:/h:apple:airport_express/

match rtsp m|^RTSP/1\.0 400 Bad Request\r\nServer: AirTunes/([\w._-]+)\r\n\r\n$| p/Apple AirTunes rtspd/ v/$1/ i/Apple TV/ d/media device/ o/Mac OS X/ cpe:/a:apple:apple_tv/ cpe:/o:apple:mac_os_x/a

match scifinder m|^\0\[T /nic$| p/CAS SciFinder/

match upnp m|^HTTP/1\.1 \d\d\d (?:[^\r\n]*\r\n(?!\r\n))*?.*SERVER: Linux/([\w._+-]+), UPnP/([\d.]+), Intel UPnP SDK/([\w._~-]+)\r\n|s p/Portable SDK for UPnP devices/ v/$3/ i/kernel $1; UPnP $2/ o/Linux/ cpe:/o:linux:linux_kernel:$1/
match upnp m=^HTTP/1\.0 \d\d\d .*\r\nSERVER: (?:TP-LINK )?Wireless (?:N )?(?:Router|AP) ([\w._/-]+)(?:http://www\.tp-link\.com)?, UPnP/([\d.]+)\r\n= p/TP-LINK $1 WAP upnp/ i/UPnP $2/ d/WAP/ cpe:/h:tp-link:$1/
match upnp m|^HTTP/1\.0 \d\d\d (?:[^\r\n]*\r\n(?!\r\n))*?Server: FreeBSD/([\w._-]+), UPnP/1\.0, FUPPES/([\w._-]+)\r\n\r\n|s p/Free UPnP Entertainment Service/ v/$2/ i/FreeBSD $1/ o/FreeBSD/ cpe:/a:ulrich_voelkel:fuppes:$2/ cpe:/o:freebsd:freebsd:$1/
match upnp m|^HTTP/1\.0 \d\d\d (?:[^\r\n]*\r\n(?!\r\n))*?Server: Linux/([\w._-]+), UPnP/1\.0, FUPPES/([\w._-]+)\r\n\r\n|s p/Free UPnP Entertainment Service/ v/$2/ i/Linux $1/ o/Linux/ cpe:/a:ulrich_voelkel:fuppes:$2/ cpe:/o:linux:linux_kernel:$1/
match upnp m|^HTTP/1\.0 \d\d\d (?:[^\r\n]*\r\n(?!\r\n))*?Server: (\w+)/([\w._-]+), UPnP/1\.0, FUPPES/([\w._-]+)\r\n\r\n|s p/Free UPnP Entertainment Service/ v/$3/ o/$1 $2/ cpe:/a:ulrich_voelkel:fuppes:$3/
match upnp m|^HTTP/1\.[01] \d\d\d (?:[^\r\n]*\r\n(?!\r\n))*?SERVER: Linux/(([\d.]+)-[\d.]+) UPnP/([\d.]+) Evolution Media Server DLNADOC/([\d.]+)\r\n|s p/Cisco Evolution Media Server upnpd/ i/UPnP $3; DLNADOC $4; Linux $1/ d/media device/ o/Linux $2/ cpe:/a:cisco:evolution_media_server/ cpe:/o:linux:linux_kernel:$1/a

match vnc-http m|^HTTP/1\.0 404 Not Found\r?\n\r?\n<HTML>\n  <HEAD><TITLE>404 Not Found</TITLE></HEAD>\n  <BODY>\n    <H1>Not Found</H1>\n    The requested file could not be found\.\n  </BODY>\n</HTML>\n| p/TightVNC/ cpe:/a:tightvnc:tightvnc/a

##############################NEXT PROBE##############################
# ftp://ftp.rfc-editor.org/in-notes/rfc1179.txt
Probe TCP LPDString q|\x01default\n|
rarity 6
ports 515,2947,3333,32211,19350

match http m|^<html><head><title>Error</title></head>\n<body>Your client sent an invalid \x01default request without a\nprotocol version \(assuming HTTP v0\.9\)\.\n<p>The request can not be processed\.</body></html>$| p/Polycom VVX VoIP phone http config/ d/VoIP phone/

# Port 19350
match fms-core m|^\x01\x01\x14\0\0%\0\0\0\0\0\0\0\x02\0\x08register\0\0\0\0\0\0\0\0\0\x05\x02\0\r_defaultRoot_| p/Adobe Flash Media Server core/ cpe:/a:adobe:flash_media_server/

match printer m|^\0$|
match printer m|^default: unknown printer\n$| p/Solaris lpd/ o/Solaris/ cpe:/o:sun:sunos/a
# Microsoft Windows 2000 server LPD
match printer m|^\x01\x01$| p/Microsoft lpd/ o/Windows/ cpe:/o:microsoft:windows/a
# Blackbox Terminal Server (IOLAN v4.03.00 a CDi)
# Chase IOLAN terminal server lpd
# Bay Networks MicroAnnex XL  Comm. Server R10.0
match printer m|^[\x01\x02]$|
match printer m|^[-.\w]+: lpsched: unknown printer\n$| p/SGI IRIX lprsrv/ o/IRIX/ cpe:/o:sgi:irix/a
match printer m|^Printer default not found \([\w_]+\)\.\n| p/print server/ d/print server/
match printer m|^VSE Line Printer Daemon has rejected this request\.\0\0| p/VSE lpd/ d/print server/ o|z/VSE| cpe:/o:ibm:z%2fvse/
match printer m|^no queue to check\n\0$| p/Wyse Winterm 1200 LE terminal lpd/ d/terminal/
match printer m|^/usr/local/helios/sbin/lpd Printer default doesn't exist! \n$| p/Helios lpd/
match printer m|^\0\x01\r\n                     Century LPD Service\r\nUnknown printer 'default'\n$| p/Century TinyTERM lpd/
match printer m|^Cirrato printing service \(with PayEx support\)\0| p/Cirrato lpd/ i/with PayEx support/ cpe:/a:cirrato:cirrato/
match rbnb m|^EXM {EXC \0\x1fcom\.rbnb\.api\.SerializeExceptionMSG \0JUnrecognizable parameter read from input stream\.\nElement read was \x01default}\r\nPNG {}\r\n| p/Ring Buffered Network Bus/ i|http://outlet.creare.com/rbnb/|
match rfactor-monitor m|^\x02rFactorMonitor\x000400\0$| p/rFactor game monitor/
match gpsd m|^GPSD,D=\?,E=\?,F=([-\w_./]+),A=\?,U=\?,L=\d ([-\w_.]+) abcdefgiklmnopqrstuvwxyz,T=\?\r\n| p/gpsd/ v/$2/ i/Serial port $1/ cpe:/a:gpsd_project:gpsd:$2/

match winlog m|^\xd0\xb7\x07\x01$| p/Sielco Sistemi Winlog Pro/ cpe:/a:sielcosistemi:winlog_pro/

# Ldap searchRequest for objectClass = * over TCP - elicits response that allows fingerprinting of distinct service and gathering target info, unlike LDAPBindReq
##############################NEXT PROBE##############################
Probe TCP LDAPSearchReq q|\x30\x84\x00\x00\x00\x2d\x02\x01\x07\x63\x84\x00\x00\x00\x24\x04\x00\x0a\x01\x00\x0a\x01\x00\x02\x01\x00\x02\x01\x64\x01\x01\x00\x87\x0b\x6f\x62\x6a\x65\x63\x74\x43\x6c\x61\x73\x73\x30\x84\x00\x00\x00\x00|
rarity 6
ports 256,257,389,390,1702,3268,3892,11711
sslports 636,637,3269,11712

match ldap m|^0\x84\0\0..\x02\x01.*dsServiceName1\x84\0\0\0.\x04.CN=NTDS\x20Settings,CN=([^,]+),CN=Servers,CN=([^,]+),CN=Sites,CN=Configuration,DC=([^,]+),DC=([^,]+)0\x84\0|s p/Microsoft Windows Active Directory LDAP/ i/Domain: $3.$4, Site: $2/ o/Windows/ h/$1/ cpe:/o:microsoft:windows/a
match ldap m|^0\x84\0\0..\x02\x01.*dsServiceName1\x84\0\0\0.\x04.CN=NTDS\x20Settings,CN=([^,]+),CN=Servers,CN=([^,]+),CN=Sites,CN=Configuration,DC=([^,]+),DC=([^,]+),DC=([^,]+)0\x84\0|s p/Microsoft Windows Active Directory LDAP/ i/Domain: $3.$4.$5, Site: $2/ o/Windows/ h/$1/ cpe:/o:microsoft:windows/a
match ldap m|^0\x82\x05.\x02\x01.*vmwPlatformServicesControllerVersion1\x07\x04\x05([\d.]+)0.\x04.*\nserverName1.\x04.cn=([^,.]+)|s p/VMware vCenter or PSC LDAP/ v/PSCv $1/ h/$2/ cpe:/a:vmware:server/

# Ldap searchRequest for objectClass = * over TCP - Active Directory specific
##############################NEXT PROBE##############################
Probe UDP LDAPSearchReqUDP q|\x30\x84\x00\x00\x00\x2d\x02\x01\x07\x63\x84\x00\x00\x00\x24\x04\x00\x0a\x01\x00\x0a\x01\x00\x02\x01\x00\x02\x01\x64\x01\x01\x00\x87\x0b\x6f\x62\x6a\x65\x63\x74\x43\x6c\x61\x73\x73\x30\x84\x00\x00\x00\x00|
rarity 8
ports 389

match ldap m|^0\x84\0\0..\x02\x01.*dsServiceName1\x84\0\0\0.\x04.CN=NTDS\x20Settings,CN=([^,]+),CN=Servers,CN=([^,]+),CN=Sites,CN=Configuration,DC=([^,]+),DC=([^,]+)0\x84\0|s p/Microsoft Windows Active Directory LDAP/ i/Domain: $3.$4, Site: $2/ o/Windows/ h/$1/ cpe:/o:microsoft:windows/a
match ldap m|^0\x84\0\0..\x02\x01.*dsServiceName1\x84\0\0\0.\x04.CN=NTDS\x20Settings,CN=([^,]+),CN=Servers,CN=([^,]+),CN=Sites,CN=Configuration,DC=([^,]+),DC=([^,]+),DC=([^,]+)0\x84\0|s p/Microsoft Windows Active Directory LDAP/ i/Domain: $3.$4.$5, Site: $2/ o/Windows/ h/$1/ cpe:/o:microsoft:windows/a

# Ldap bind request, version 2, null DN, AUTH_TYPE simple, null password
##############################NEXT PROBE##############################
Probe TCP LDAPBindReq q|\x30\x0c\x02\x01\x01\x60\x07\x02\x01\x02\x04\0\x80\0|
rarity 6
ports 256,257,389,390,1702,3268,3892,4035
sslports 636,637,3269,4035

match oo-defrag m|^h\0\0\0\x01\0\0\0\x03\0\0\0\x07\x08\0\0\x02\0\0\0\0d\0\0\0\0\xd9\$\x01\0\0\0\0\0\0T\0\0\0\0\0\0\xb7x\x01\0\0\0\0\0\xc4\x05\0\0\0\0\0\0\xc4\x05\0\0\0\0\0\0\xe2\x0b\0\0\0\0\0\0\xb7\xb5p@\^\xa7\x08\0\0\0\0\0| p/O&O Defrag/ o/Windows/ cpe:/o:microsoft:windows/a

match drobo-dsvc m|^(?:DRIDDSVC\x07\x01.\0\0\0..[^\0]*\0)?DRIDDSVC\x07\x01.\0\0\0..<ESATMUpdate>\r\n\t<mESAUpdateSignature>ESAINFO</mESAUpdateSignature>\r\n\t<mESAUpdateVersion>\d+</mESAUpdateVersion>\r\n\t<mESAUpdateSize>\d+</mESAUpdateSize>\r\n\t<mESAID>\w+</mESAID>\r\n\t<mSerial>\w+</mSerial>\r\n\t<mName>Drobo(?:-FS)?</mName>\r\n\t<mVersion>([][\w._ ]+)</mVersion>\r\n\t<mReleaseDate>([^<]+)</mReleaseDate>\r\n|s p/Drobo-FS DDSVC/ v/$1 ($2)/

match fw1-secureremote m|^[AQ]\0\0\0\0\0\0[^\0]| p/Check Point Firewall-1 SecureRemote/ d/firewall/ cpe:/a:checkpoint:firewall-1/
match fw1-log m|^\0\0\0\t51000000\0\0\0\0[^\0]| p/Check Point Firewall-1 logging service/ d/firewall/ cpe:/a:checkpoint:firewall-1/
# OpenLDAP 2.0.15 on RH Linux 7.3
match ldap m|^0%\x02\x01\x01a \n\x010\x04\0\x04\x19anonymous bind disallowed$| p/OpenLDAP/ i/access denied/ cpe:/a:openldap:openldap/
# OpenLDAP 2.1.22 - doesn't by default allow LDAPv2 request
match ldap m|^02\x02\x01\x01a-\n\x01\x02\x04\0\x04&requested protocol version not allowed$| p/OpenLDAP/ v/2.1.X/ cpe:/a:openldap:openldap:2.1/
# OpenLDAP 2.2.8
match ldap m|^0E\x02\x01\x01a@\n\x01\x02\x04\0\x049historical protocol version requested, use LDAPv3 instead| p/OpenLDAP/ v/2.2.X - 2.3.X/ cpe:/a:openldap:openldap/
match ldap m|^0\x84\0\0\0I\x02\x01\x01a\x84\0\0\0@\n\x01\x02\x04\0\x049historical protocol version requested, use LDAPv3 instead$| p/OpenLDAP/ v/2.4.X/ cpe:/a:openldap:openldap:2.4/

match ldap m|^0\x1a\x02\x01\x01a\x15\n\x01\0\x04\0\x04\x0eanonymous bind| p/Nortel CallPilot LDAP/

# Netware 6
# Macintosh 8
# Win 2000 Advanced server.
match ldap m|^0\x0c\x02\x01\x01a\x07\n\x01\0\x04\0\x04\0| i/Anonymous bind OK/
# MS Windows Win2K SP4 AD server, also Oracle LDAP on Linux
match ldap m|^0\x84\0\0\0\x10\x02\x01\x01a\x84\0\0\0\x07\n\x01\0\x04\0\x04\0$|
# PGP Corporation PGP Keyserver 7.0 (relabeled Freeware PGP Keyserver 2.5.8)
#  PGP LDAP Server 8.x
match ldap m|^0\x17\x02\x01\x01a\x12\n\x01\0\x04\0\x04\x0bPGPError #0$| p/PGP Corp. PGP Keyserver/ cpe:/a:pgp:keyserver/
# OctetString VDE Enterprise Edition on Linux 2.4
match ldap m|^0\x0e\x02\x01\x01a\t\n\x01\0\x04\0\x04\0\x87\0$| p/OctetString VDE directory service/
# Lotus Notes 6.5.3 LDAP on W2K3, anonymous bind not allowed, port 637 (ssl)
match ldap m|^0\.\x02\x01\x01a\)\n\x010\x04\0\x04\"Failed, anonymous bind not allowed$| p/Lotus Domino 6.x LDAP/ i/access denied/ cpe:/a:ibm:lotus_domino/

# This came off a KIRK Wireless VoIP adapter which I *think* uses Cisco LDAP ??
match ldap m|^0\x0c\x02\x01\x01a\x07\n\x011\x04\0\x04\0$| p/Cisco LDAP server/

match ldap m|^0.\x02.*TLS confidentiality required|s i/TLS required/

match ldap m|^0&\x02\x01\x01a!\n\x01\x02\x04\0\x04\x1aOnly LDAP v3 is supported\.$| p/ApacheDS LDAP/ i/LDAPv3/
match ldap m|^0\x1a\x02\x01\x01a\x15\n\x01\0\x04\0\x04\x0eBind succeeded$| p/Siemens DirX/
# Think this means TLS required?
match ldap m|^0 \x02\x01\x01a\x1b\n\x015\x04\0\x04\x14Minimum SSF not met\.| p/Red Hat directory server LDAP/ i/Minimum SSF not met/ o/Linux/ cpe:/a:redhat:ns-slapd/ cpe:/o:redhat:directory_server/
match ldap m|^0\x81\xa0\x02\x01\x01a\x81\x9a\n\x011\x04\0\x04\x81\x92The server has been configured to only allow bind operations that result in authenticated connections\.  Anonymous bind operations are not allowed\.| p/UnboundID LDAP SDK/ i/access denied/ cpe:/a:unboundid:ldap-sdk/

match rse m|^\xa2\x85\x99\xa5\x85\x99@| p/IBM Explorer for zOS (FMID HALG300)/ o|z/OS| cpe:/a:ibm:zos_explorer/ cpe:/o:ibm:z%2fos/

softmatch ldap m|^0..?\x02\x01\x01a..?\n\x01.\x04\0\x04|s

# This probe sends a SIP OPTIONS request.
# Most of the numbers, usernames, and hostnames are abitrary.
##############################NEXT PROBE##############################
Probe TCP SIPOptions q|OPTIONS sip:nm SIP/2.0\r\nVia: SIP/2.0/TCP nm;branch=foo\r\nFrom: <sip:nm@nm>;tag=root\r\nTo: <sip:nm2@nm2>\r\nCall-ID: 50000\r\nCSeq: 42 OPTIONS\r\nMax-Forwards: 70\r\nContent-Length: 0\r\nContact: <sip:nm@nm>\r\nAccept: application/sdp\r\n\r\n|
rarity 5
ports 406,5060,8081,31337
sslports 5061
fallback GetRequest
# Some VoIP phones take longer to respond
totalwaitms 7500

match atalla m|^<00#020035#0101##>\r\n<00#020035#0101##>\r\n<00#020035#0101##>\r\n| p/Atalla Hardware Security Module payment system/ d/specialized/

match honeypot m|^HTTP/1\.0 200 OK\r\nAllow: OPTIONS, GET, HEAD, POST\r\nContent-Length: 0\r\nConnection: close\r\n\r\n| p/Dionaea Honeypot httpd/
match honeypot m|^SIP/2\.0 200 OK\r\nContent-Length: 0\r\nVia: SIP/2\.0/TCP nm;branch=foo\r\nFrom: sip:nm@nm;tag=root\r\nAccept: application/sdp\r\nTo: sip:nm2@nm2\r\nContact: sip:nm2@nm2\r\nCSeq: 42 OPTIONS\r\nAllow: REGISTER, OPTIONS, INVITE, CANCEL, BYE, ACK\r\nCall-ID: 50000\r\nAccept-Language: en\r\n\r\n| p/Dionaea Honeypot sipd/

match http m|^SIP/2\.0 501 Not Implemented\r\nServer: Embedded HTTP Server ([\d.]+)\r\n| p/Embedded HTTP Server/ v/$1/
match http m|^HTTP/1\.1 500 Internal Server Error\r\nServer: Catwalk/([\d.]+)\r\n| p/Catwalk/ v/$1/ i/Canon imageRUNNER C5000-series printer http config/ d/printer/ cpe:/h:canon:imagerunner_c5000/
# Canon iR3235
match http m|^HTTP/1\.1 500 Internal Server Error\r\nServer: Catwalk\r\n| p/Catwalk/ i/Canon imageRUNNER printer http config/ d/printer/
match http m|^HTTP/1\.0 404 Resource not found\r\nServer: Opera/([\w._-]+)\r\n(?:[^\r\n]+\r\n)*?Set-Cookie: unite-session-id=[0-9a-f]+; Max-Age=2073600; path=/\r\n|s p/Opera Unite httpd/ v/$1/
match http m|^HTTP/1\.0 302 Found\r\nLocation: ([\w:/.-]*)sip:nm\r\nServer: BigIP\r\nConnection: close\r\nContent-Length: 0\r\n\r\n$| p/F5 BIG-IP load balancer httpd/ i/redirecting to $1/ d/load balancer/
match http m|^HTTP/1\.1 401 Access Denied\r\n(?:[^\r\n]+\r\n)*?Set-Cookie: logintheme=cpanel; path=/; secure; port=\d+\r\n(?:[^\r\n]+\r\n)*?Server: cpsrvd/([\w._-]+)\r\n|s p/cPanel httpd/ v/$1/
match http m|^HTTP/1\.1 401 Access Denied\r\n(?:[^\r\n]+\r\n)*?Set-Cookie: logintheme=cpanel; path=/; HttpOnly; port=\d+\r\n(?:[^\r\n]+\r\n)*?Server: cpsrvd/([\w._-]+)\r\n|s p/cPanel httpd/ v/$1/ o/Unix/
match http m|^HTTP/1\.1 302 Moved Temporarily\r\nDate: .*\r\nLocation: https://[\w._-]+sip:nm\r\nConnection: close\r\n\r\n$| p/Asterisk PBX httpd/ d/PBX/ cpe:/a:digium:asterisk/
match http m|^HTTP/1\.0 501 Document Follows\r\nContent-Type: text/html\r\nContent-Length: 106\r\n\r\n<HEAD><TITLE>501 Method Not Implemented</TITLE></HEAD>\r\n<BODY><H1>501 Method Not Implemented</H1>\r\n</BODY>$| p/HP StorageWorks MSL2024 tape library httpd/ d/storage-misc/
match http m|^HTTP/2\.0 404 Not Found\r\nDate: .*\r\nServer: Restlet-Framework/([\w._-]+)\r\n.*<title>Status page</title>\n</head>\n<body style=\"font-family: sans-serif;\">\n<p style=\"font-size: 1\.2em;font-weight: bold;margin: 1em 0px;\">Not Found</p>\n<p>The server has not found anything matching the request URI</p>\n|s p/Serviio media server http status/ i/Restlet framework $1/ cpe:/a:restlet:restlet:$1/
match http m|^HTTP/2\.0 404 Not Found\r\n(?:[^\r\n]+\r\n)*?Server: Restlet-Framework/@major-number@\.@minor-number@@release-type@@release-number@\r\n.*<p>The server has not found anything matching the request URI</p>|s p/Serviio media server http status/ v/1.2/ cpe:/a:restlet:restlet/
match http m=^HTTP/1\.1 500 Internal Server Error\r\nContent-Length: \d+\r\nContent-Type: text/plain\r\n\r\nTraceback \(most recent call last\):\n  File \"([\w._/-]+/(?:sickbeard|Sick-Beard)/cherrypy)/wsgiserver/__init__\.py\", line \d+, in communicate\n= p/CherryPy/ i/Sick Beard PVR; path: $1/ cpe:/a:cherrypy:cherrypy/
match http m|^HTTP/1\.1 501 Unimplimented\r\nConnection: close\r\nContent-Length: 0\r\n\r\n| p/Huawei HG8245T modem http config/ d/broadband router/ cpe:/h:huawei:hg8245t/a
match http m|^HTTP/1\.0 501 Not Implemented\r\n(?:[^\r\n]+\r\n)*?\r\n<HTML><HEAD><TITLE>501 Not Implemented</TITLE></HEAD>\n<BODY><H1>501 Not Implemented</H1>\nPOST to non-script is not supported in Boa\.\n</BODY></HTML>\n|s p/Boa httpd/ cpe:/a:boa:boa/
match http m|^HTTP/1\.1 302 Moved\r\nDate: Fri, 27 May 2016 03:15:37 GMT\r\nServer: cPanel\r\nPersistent-Auth: false\r\nCache-Control: no-cache\r\nConnection: close\r\nLocation: https://([\w.-]+):2078sip:nm\r\nVary: Accept-Encoding\r\nExpires: Fri, 01 Jan 1990 00:00:00 GMT\r\nX-Redirect-Reason: requiressl\r\n\r\n| p/cPanel https redirector/ h/$1/

match imsp m|^VIA: BAD IMSP busy\r\nFROM: BAD IMSP busy\r\nTO: BAD IMSP busy\r\n|

match rtsp m|^RTSP/1\.0 405 Method Not Allowed\r\nCSeq: 42\r\n\r\n| p/Lotus Domino Sametime RTSP/ cpe:/a:ibm:lotus_domino/
match rtsp m|^RTSP/1\.0 200 OK\r\nCSeq: 42 OPTIONS\r\nPublic: OPTIONS, DESCRIBE, PLAY, PAUSE, SETUP, TEARDOWN, SET_PARAMETER, GET_PARAMETER\r\nDate: .*\r\n\r\n| p/Hikvision 7513 POE IP camera rtspd/ d/webcam/
match rtsp m|^RTSP/1\.0 401 Unauthorized\r\nCSeq: 42\r\nWWW-Authenticate: Digest realm="Login to ([\w._-]+)", nonce="[a-f\d]{32}"\r\n\r\n| p/Lorex IP camera rtspd/ d/webcam/ h/$1/

match telnet m|^login: Login incorrect\nlogin: Login incorrect\nlogin: Login incorrect\nlogin: Login incorrect\nlogin: Login incorrect\n| p/McAfee firewall telnetd/

match sip m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?User-Agent: PolycomSoundStationIP-SSIP_(\d+)-UA/([\d.]+)_(\w+)\r\n|s p/Polycom SoundStation $1/ v/$2/ i/MAC: $3/ d/VoIP phone/ cpe:/h:polycom:soundstation_$1/
match sip m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?User-Agent: PolycomSoundStationIP-SSIP_(\d+)-UA/([\d.]+)\r\n|s p/Polycom SoundStation $1/ v/$2/ d/VoIP phone/ cpe:/h:polycom:soundstation_$1/
match sip m|^SIP/2\.0 (?:[^\r\n]*\r\n(?!\r\n))*?User-Agent: PolycomSoundPointIP-SPIP_(\d+)-UA/([\d.]+)_(\w+)\r\n|s p/Polycom SoundPoint $1/ v/$2/ i/MAC: $3/ d/VoIP phone/ cpe:/h:polycom:soundpoint_$1/
match sip m|^SIP/2\.0 (?:[^\r\n]*\r\n(?!\r\n))*?User-Agent: PolycomSoundPointIP-SPIP_(\d+)-UA/([\d.]+)\r\n|s p/Polycom SoundPoint $1/ v/$2/ d/VoIP phone/ cpe:/h:polycom:soundpoint_$1/
match sip m|^SIP/2\.0 400 Invalid Contact information\r\n.*received=[\d.]+;ms-received-port=\d+;ms-received-cid=\d+\r\n|s p/Microsoft Live SIP client/ o/Windows/ cpe:/o:microsoft:windows/a
match sip m|^SIP/2\.0 400 Invalid Contact information\r\n(?:[^\r\n]+\r\n)*?Via: SIP/2\.0/TCP nm;branch=foo;received=[\d.]+;ms-received-port=\d+;ms-received-cid=[0-9A-F]{8}\r\nms-diagnostics: \d+;reason=\"Parsing failure\";source=\"([\w._-]+)\"\r\nContent-Length: 0\r\n\r\n$|s p/Microsoft Office Communications Server/ o/Windows/ h/$1/ cpe:/o:microsoft:windows/a
match sip m|^SIP/2\.0 501 Not Implemented.*\r\nServer: SJphone/([-\w_.]+) \(SJ Labs\)\r\n|s p/SJphone SIP client/ v/$1/
match sip m|^SIP/2\.0 405 Method Not Allowed.*\r\nServer: SJphone/([-\w_.]+) \(SJ Labs\)\r\n|s p/SJphone SIP client/ v/$1/
match sip m|^SIP/2\.0 404 Not Found\r\n(?:[^\r\n]+\r\n)*?User-Agent: Speedport ([\w._ -]+) \(|s p/T-Com Speedport/ v/$1/ d/broadband router/
match sip m|^SIP/2\.0 404 Not Found\r\n(?:[^\r\n]+\r\n)*?Server: Speedport/([\d.-]+)\r\n|s p/T-Com Speedport/ v/$1/ d/broadband router/
match sip m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?User-Agent: X-Lite release ([\w._ -]+)\r\n|s p/X-Lite SIP phone/ v/$1/ d/VoIP phone/
match sip m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?User-Agent: X-Lite Beta release ([\w._ -]+)\r\n|s p/X-Lite SIP phone/ v/$1/ d/VoIP phone/
match sip m|^SIP/2\.0 404 Not Found\r\n(?:[^\r\n]+\r\n)*?Server: Twinkle/([\w._-]+)\r\n|s p/Twinkle softphone/ v/$1/ o/Linux/ cpe:/o:linux:linux_kernel/a
match sip m|^SIP/2\.0 500 Server Internal Error\r\n(?:[^\r\n]+\r\n)*?User-Agent: BT Home Hub\r\n|s p/BT HomeHub/ d/VoIP phone/
match sip m|^SIP/2\.0 500 Server Internal Error\r\n(?:[^\r\n]+\r\n)*?User-Agent: BT Home Hub (\d+)\r\n|s p/BT HomeHub/ v/$1/ d/VoIP phone/
match sip m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?Server: TANDBERG/81 \(([\w._ -]+)\)\r\n|s p/Tandberg MXP VoIP server/ v/$1/ d/VoIP adapter/
match sip m|^SIP/2\.0 \d\d\d (?:[^\r\n]*\r\n(?!\r\n))*?Server: TANDBERG/([\w._-]+) \(([\w._ -]+)\)\r\n|s p/Tandberg-$1 VoIP server/ v/$2/ d/VoIP adapter/
match sip m=^SIP/2\.0 \d\d\d .*Server: TANDBERG/(?:69|4098|4100) \(([\w._ -]+)\)\r\n=s p/Tandberg VCS VoIP server/ v/$1/ d/VoIP adapter/
match sip m|^SIP/2\.0 400 Transport protocol incorrect\r\n| p/Microsoft Office Communications Service 2005/
match sip m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?Accept: application/sdp\r\nAccept-Language: en\r\nAllow: INVITE, ACK, CANCEL, OPTIONS, BYE, REGISTER, SUBSCRIBE, NOTIFY, REFER, INFO\r\nSupported: replaces\r\nAllow-Events: presence, message-summary, tunnel-info\r\n|s p/3CX VoIP PBX/ d/PBX/ o/Windows/ cpe:/o:microsoft:windows/a
match sip m|^SIP/2\.0 405 Method Not Allowed\r\n(?:[^\r\n]+\r\n)*?User-Agent: ABS ECC\r\n|s p/Alcatel-Lucent OmniTouch Unified Communication VoIP gateway/ d/PBX/
match sip m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?User-Agent: Zoiper (rev\.\d+)\r\n|s p/Zoiper VoIP software/ v/$1/ cpe:/a:securax:zoiper:$1/
match sip m|^SIP/2\.0 404 Not Found\r\n(?:[^\r\n]+\r\n)*?Server: Asterisk PBX ([\w._~+-]+)\r\n(?:[^\r\n]+\r\n)*?Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO\r\n|s p/Asterisk/ v/$1/ d/PBX/ cpe:/a:digium:asterisk:$1/
match sip m|^SIP/2\.0 404 Not Found\r\n(?:[^\r\n]+\r\n)*?Server: Asterisk PBX ([\w._~+-]+)\r\n(?:[^\r\n]+\r\n)*?Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH\r\n|s p/Asterisk/ v/$1/ d/PBX/ cpe:/a:digium:asterisk:$1/
match sip m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?Server: Asterisk PBX ([\w._~+-]+)\r\nAllow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH\r\n|s p/Asterisk/ v/$1/ d/PBX/ cpe:/a:digium:asterisk:$1/
match sip m|^SIP/2\.0 (?:[^\r\n]*\r\n(?!\r\n))*?Server: Glassfish_SIP_([\w._-]+)\r\n|s p/Glassfish SIP Server/ v/$1/
match sip m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?To: <sip:nm2@nm2>;tag=[0-9a-f-]+\r\n(?:[^\r\n]+\r\n)*?Allow: INVITE,ACK,CANCEL,BYE,OPTIONS,REFER,INFO,NOTIFY,PRACK,MESSAGE\r\n(?:[^\r\n]+\r\n)*?Supported: replaces,timer,100rel\r\nAccept: application/sdp\r\n|s p/Cisco 7940 IP Phone/ d/VoIP phone/
match sip m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?User-Agent: Telepathy-SofiaSIP/([\w._-]+) sofia-sip/([\w._-]+)\r\n|s p/Telepathy-SofiaSIP/ v/$1/ i/sofia-sip $2/
match sip m|^SIP/2\.0 503 Service Unavailable\r\n(?:[^\r\n]+\r\n)*?Warning: 399 \"Routing failed: ccbid=997 tcpindex=2 socket=nm:\d+'\r\n(?:[^\r\n]+\r\n)*?To: <sip:nm2@nm2>;tag=\d+\r\n|s p/Cisco CallManager 6/ cpe:/h:cisco:call_manager:6/
match sip m|^SIP/2\.0 500 Server Internal Error\r\n(?:[^\r\n]+\r\n)*?User-Agent: Thomson Inventel / HW_V[\w._-]+ / FW_V[\w._-]+ / SW_V([\w._-]+)\r\n|s p/Aladino SIP phone/ v/$1/ d/VoIP phone/
match sip m|^SIP/2\.0 406 Not acceptable\r\n(?:[^\r\n]+\r\n)*?Server: sipXecs/([\w._-]+) sipXecs/sipxbridge \(Linux\)\r\n|s p/SIPfoundry sipXecs PBX/ v/$1/ o/Linux/ cpe:/o:linux:linux_kernel/a
match sip m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?User-Agent: VOIP_Agent_001\r\nAllow: INVITE, ACK, BYE, CANCEL, OPTIONS, SUBSCRIBE, REFER, NOTIFY, UPDATE, MESSAGE, SERVICE, INFO, PING\r\n|s p/D-Link DVG-5121SP VoIP adapter/ d/VoIP adapter/ cpe:/h:dlink:dvg-5121sp/a
match sip m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?User-Agent: Sipek on PJSUA v([\w._-]+)/win32\r\n|s p/Sipek VoIP/ v/$1/ i/on PJSUA/
match sip m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?User-Agent: snom([\w._-]+)/([\w._-]+)\r\n|s p/Snom $1 VoIP phone/ v/$2/ d/VoIP phone/ cpe:/h:snom:$1/a
match sip m|^SIP/2\.0 200 OK\r\nVia: SIP/2\.0/TCP nm;branch=foo\r\nFrom: <sip:nm@nm>;tag=root\r\nTo: <sip:nm2@nm2>;tag=\w+\r\nCall-ID: 50000\r\nCSeq: 42 OPTIONS\r\nContact: <sip:[\d.]+:\d+>\r\nAllow: INVITE,ACK,CANCEL,OPTIONS,UPDATE,INFO,NOTIFY,BYE,REFER\r\nAccept: application/sdp,application/media_control\+xml,application/dtmf-relay,application/dtmf,message/sipfrag;version=2\.0\r\nContent-Length: 0\r\n\r\n| p/Tandberg Codian IP GW 3510 VoIP gateway/ d/VoIP adapter/ cpe:/h:tandberg:codian_ip_gw_3510/a
match sip m|^SIP/2\.0 404 Not Found\r\n(?:[^\r\n]+\r\n)*?User-Agent: (AVM FRITZ!Box Fon WLAN [\w._-]+(?: v\d)?) ([\w._-]+ \(\w+ +\d+ \d+\))|s p/$1 SIP/ v/$2/ d/WAP/
match sip m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?User-Agent: QIP ([\w._ -]+)\r\n|s p/QIP instant messenger SIP/ v/$1/
match sip m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?User-Agent: T-Com-IpPbxSrv/([\w._-]+)\r\n|s p/Telekom Netphone VoIP phone SIP/ v/$1/ d/VoIP phone/
match sip m|^SIP/2\.0 403 Not relaying\r\n(?:[^\r\n]+\r\n)*?Server: kamailio \(([\w._-]+) \(x86_64/linux\)\)\r\n|s p/Kamailio/ v/$1/ i/x86_64/ o/Linux/ cpe:/o:linux:linux_kernel/
match sip m|^SIP/2\.0 478 Unresolvable destination \(478/SL\)\r\n(?:[^\r\n]+\r\n)*?Server: kamailio \(([\w._-]+) \(x86_64/linux\)\)\r\n|s p/Kamailio/ v/$1/ i/x86_64/ o/Linux/ cpe:/o:linux:linux_kernel/
match sip m|^SIP/2\.0 405 Method Not Allowed\r\n(?:[^\r\n]+\r\n)*?User-Agent: Patton SN(\w+) 5BIS MxSF v([\w._-]+) [0-9A-F]+ R([\w._-]+) (\d\d\d\d-\d\d-\d\d) H323 SIP BRI\r\n\r\n|s p/Patton SmartNode $1 VoIP adapter http config/ v/$2 $4/ d/VoIP adapter/ o/SmartWare $3/ cpe:/h:patton:sn$1/ cpe:/o:patton:smartware:$3/
match sip m|^SIP/2\.0 404 Not Found\r\nVia: SIP/2\.0/TCP nm;branch=foo;received=[\d.]+\r\nTo: <sip:nm2@nm2>;tag=\w+\r\nFrom: <sip:nm@nm>;tag=root\r\nCall-ID: 50000\r\nCSeq: 42 OPTIONS\r\nContent-Length: 0\r\n\r\n$| p/Nokia N86 phone SIP/ d/phone/ cpe:/h:nokia:n86/
match sip m|^SIP/2\.0 200 OK\r\nVia: SIP/2\.0/TCP nm;received=[\d.]+;branch=foo\r\nCall-ID: 50000\r\nFrom: <sip:nm@nm>;tag=root\r\nTo: <sip:nm2@nm2>;tag=foo\r\nCSeq: 42 OPTIONS\r\nAllow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS\r\nAccept: application/sdp, application/pidf\+xml, application/xpidf\+xml, application/simple-message-summary, message/sipfrag;version=2\.0, application/im-iscomposing\+xml, text/plain\r\nSupported: replaces, 100rel, timer, norefersub\r\nAllow-Events: presence, message-summary, refer\r\nUser-Agent: netTALK\r\n| p/netTALK/ d/phone/
match sip m|^SIP/2\.0 200 OK\r\nVia: SIP/2\.0/TCP nm;branch=foo\r\nTo: <sip:nm2@nm2>;tag=\w+\r\nFrom: <sip:nm@nm>;tag=root\r\nCall-ID: 50000\r\nCSeq: 42 OPTIONS\r\nAllow: INVITE,ACK,CANCEL,BYE,OPTIONS,REFER,NOTIFY\r\nContent-Type: application/sdp\r\nContent-Length: \d+\r\n\r\nv=0\r\no=- \d+ \d+ IN IP4 [\d.]+\r\ns=-\r\nc=IN IP4 [\d.]+\r\nt=0 0\r\nm=audio 0 RTP/AVP 18 4 3 8 0 101\r\na=rtpmap:101 telephone-event/8000\r\n$| p/eyeP Media VoIP phone SIP/ d/VoIP phone/
match sip m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?User-Agent: Aastra (MX-ONE) SN/([\w._-]+)\r\n|s p/Aastra $1 PBX SIP/ v/$2/ d/PBX/
match sip m|^SIP/2\.0 504 Server time-out\r\nms-user-logon-data: RemoteUser\r\nFrom: <sip:nm@nm>;tag=root\r\nTo: <sip:nm2@nm2>;tag=\w+\r\nCall-ID: 50000\r\nCSeq: 42 OPTIONS\r\nVia: SIP/2\.0/TCP nm;branch=foo\r\nContent-Length: 0\r\n\r\n$| p/Microsoft Outlook Web Access SIP/
match sip m|^SIP/2\.0 481 Call Leg/Transaction Does Not Exist\r\nFrom: <sip:nm@nm>;tag=root\r\nTo: <sip:nm2@nm2>;tag=0-\w+-\w+-\w+-\w+\r\nCall-ID: 50000\r\nCSeq: 42 OPTIONS\r\nVia: SIP/2\.0/TCP nm;received=[\d.]+;branch=foo\r\nContent-Length: 0\r\n\r\n$| p/Sony PCS-TL50 videoconferencing SIP/ cpe:/h:sony:pcs-tl50/
match sip m|^SIP/2\.0 404 Not found\r\nVia: SIP/2\.0/TCP nm;branch=foo\r\nFrom: <sip:nm@nm>;tag=root\r\nTo: <sip:nm2@nm2>;tag=local-tag\r\nCall-ID: 50000\r\nCSeq: 42 OPTIONS\r\nContact: <sip:nm@nm>\r\nContent-Length: 0\r\n\r\n$| p/Edgewater Networks Edgemarc 4500 series VoIP gateway SIP/ d/VoIP adapter/
match sip m|^SIP/2\.0 504 Server time-out\r\nms-user-logon-data: RemoteUser\r\nFrom: <sip:nm@nm>;tag=root\r\nTo: <sip:nm2@nm2>;tag=\w+\r\nCall-ID: 50000\r\nCSeq: 42 OPTIONS\r\nVia: SIP/2\.0/TCP nm;branch=foo\r\nServer: RTC/4\.0\r\nContent-Length: 0\r\n\r\n| p/Microsoft Lync SIP/ v/2010/ cpe:/a:microsoft:lync:2010/
match sip m|^SIP/2\.0 504 Server time-out\r\nms-user-logon-data: RemoteUser\r\nFrom: <sip:nm@nm>;tag=root\r\nTo: <sip:nm2@nm2>;tag=\w+\r\nCall-ID: 50000\r\nCSeq: 42 OPTIONS\r\nVia: SIP/2\.0/TCP nm;branch=foo\r\nServer: RTC/5\.0\r\nContent-Length: 0\r\n\r\n| p/Microsoft Lync SIP/ v/2013/ cpe:/a:microsoft:lync:2013/
match sip m|^SIP/2\.0 504 Server time-out\r\nms-user-logon-data: RemoteUser\r\nFrom: <sip:nm@nm>;tag=root\r\nTo: <sip:nm2@nm2>;tag=\w+\r\nCall-ID: 50000\r\nCSeq: 42 OPTIONS\r\nVia: SIP/2\.0/TCP nm;branch=foo\r\nServer: RTC/6\.0\r\nContent-Length: 0\r\n\r\n| p/Microsoft Skype for Business SIP/ v/2015/ cpe:/a:microsoft:skype_for_business:2015/
match sip m|^SIP/2\.0 403 Non-self Request-URI\r\n(?:[^\r\n]+\r\n)*?Server: Epygi Quadro SIP User Agent/v([\w._-]+) \(QUADRO-([^\)]*)\)\r\n|s p/Epygi Quadro $2 PBX SIP/ v/$1/ d/PBX/ cpe:/h:epygi:$2/
match sip m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?Allow: INVITE,ACK,CANCEL,OPTIONS,UPDATE,INFO,NOTIFY,BYE,REFER\r\nAccept: application/sdp,application/media_control\+xml,application/dtmf-relay,application/dtmf,message/sipfrag;version=2\.0\r\n|s p/Cisco TelePresence MCU 4505 videoconference system SIP/ cpe:/h:cisco:telepresence_mcu_4505/
match sip m|^SIP/2\.0 404 Not Found\r\n(?:[^\r\n]+\r\n)*?User-Agent:Polycom (HDX [\w._ -]+) \(Release - ([\w._-]+)\)\r\n|s p/Polycom $1 videoconference system SIP/ v/$2/ cpe:/h:polycom:$1/
match sip m|^SIP/2\.0 403 Forbidden\r\nContent-Type: application/X-NECSIPEXT2MLv1\r\nSupported: timer\r\nFrom: <sip:nm@nm>;tag=root\r\nTo: <sip:nm2@nm2>;tag=\w+\r\nCall-ID: 50000\r\nCSeq: 42 OPTIONS\r\nVia: SIP/2\.0/TCP nm;branch=foo;received=[\d.]+\r\nContent-Length: 99\r\n\r\nInd-ErrDsp=nec-code: 1:Non-Registered Access       ,2: \(Retry after    10 sec\)    ,6:1: EXIT  ,10\r\n| p/NEC SL1100 VoIP PBX/ d/PBX/
match sip m|^SIP/2\.0 500 Server Internal Error\r\n(?:[^\r\n]+\r\n)*?User-Agent: SpeedTouch (\w+)\r\nX-Serialnumber: (\w+)\r\n|s p/SpeedTouch $1 SIP/ i/serial $2/ d/broadband router/
match sip m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?User-Agent: (?:Polycom/[\d.]+ )?PolycomVVX-([\w._]+)-UA/([\d.]+)(?:_[\da-f]+)?\r\n|s p/Polycom $SUBST(1,"_"," ") SIP/ v/$2/ d/VoIP phone/ cpe:/h:polycom:$1/
match sip m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?User-Agent: Auerswald COMpact VoIP sofia-sip/([\w._-]+)\r\n|s p/sofia-sip/ v/$1/ i/Auerswald COMpact 5020 VoIP/ d/PBX/
match sip m|^SIP/2\.0 404 Not Found\r\n(?:[^\r\n]+\r\n)*?User-Agent: FRITZ!OS\r\n|s p/AVM FRITZ!OS SIP/ d/VoIP adapter/
match sip m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?User-Agent:PolycomRealPresenceGroup(\d+)/([\w._-]+)\r\n|s p/Polycom RealPresence Group $1 SIP/ v/$2/
match sip m|^SIP/2\.0 500 Server Internal Error\r\n(?:[^\r\n]+\r\n)*?User-Agent: BT Home Hub ([\w._-]+) Build ([\w._-]+)\r\nX-Serialnumber: (\w+)\r\n|s p/BT Home Hub $1 SIP/ v/$2/ i/serial: $3/ d/VoIP adapter/
match sip m|^SIP/2\.0 400 Invalid Via Port 0\r\n(?:[^\r\n]+\r\n)*?User-Agent: drgos-drg(\d+)-([\w._-]+)\r\n|s p/Genexis DRG $1 SIP/ v/$2/ d/broadband router/
match sip m|^SIP/2\.0 200 OK\r\nFrom: <sip:nm@nm>;tag=root\r\nTo: <sip:nm2@nm2>;tag=[a-f\d-]{58}\r\nCall-ID: 50000\r\nCSeq: 42 OPTIONS\r\nVia: SIP/2\.0/TCP nm;received=[\d.]+;branch=foo\r\nSupported: gruu-10,replaces,msrtc-event-categories\r\nContent-Length: 0\r\n\r\n| p/LifeSize UVC Multipoint SIP/
match sip m|^SIP/2\.0 403 Forbidden\r\nAllow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY\r\n(?:[^\r\n]+\r\n)*?User-Agent: Wowza Streaming Engine ([\w._-]+) build(\d+)\r\n|s p/Wowza Streaming Engine sipd/ v/$1 build $2/ cpe:/a:wowza:wowza_streaming_engine:$1/
match sip m|^SIP/2\.0 400 Invalid Contact information\r\nFrom: <sip:nm@nm>;tag=root\r\nTo: <sip:nm2@nm2>;tag=[0-9A-F]{32}\r\nCall-ID: 50000\r\nCSeq: 42 OPTIONS\r\nVia: SIP/2\.0/TCP nm;branch=foo;received=[\d.]+;ms-received-port=\d+;ms-received-cid=[0-9A-F]+\r\nms-diagnostics: 1018;reason=\"Parsing failure\";source=\"([\w._-]+)\"\r\nContent-Length: 0\r\n\r\n| p/Microsoft Office Communications Server sipd/ v/2007 R2/ h/$1/
match sip m|^SIP/2\.0 404 Not Found\r\n(?:[^\r\n]+\r\n)*?User-Agent: AVM FRITZ!Box ([\w._-]+) Cable \(um\) ([\w._-]+) \([\w ]+\)\r\n|s p/AVM FRITZ!Box $1 sipd/ v/$2/ d/broadband router/
match sip m|^SIP/2\.0 \d\d\d (?:[^\r\n]*\r\n(?!\r\n))*?User-Agent: TAU-1M\.IP/([\w._-]+) SN/\w+ sofia-sip/([\w._-]+)\r\n|s p/sofia-sip/ v/$2/ i/Eltex TAU-1M.IP VoIP gateway, version $1/ d/VoIP adapter/ cpe:/a:sofia-sip:sofia-sip:$2/ cpe:/h:eltex:tau-1m.ip:$1/
match sip m|^SIP/2\.0 \d\d\d (?:[^\r\n]*\r\n(?!\r\n))*?User-Agent: Zoiper for Windows ([\d.]+) (r\d+)\r\n|s p/Zoiper for Windows sipd/ v/$1/ i/$2/ o/Windows/ cpe:/a:securax:zoiper_for_windows:$1/ cpe:/o:microsoft:windows/a
match sip m|^SIP/2\.0 \d\d\d (?:[^\r\n]*\r\n(?!\r\n))*?User-Agent: CommsMundi Softswitch\r\n|s p/Comms Mundi sipd/ cpe:/a:wireless_mundi:comms_mundi/
match sip m|^SIP/2\.0 \d\d\d (?:[^\r\n]*\r\n(?!\r\n))*?User-Agent:Polycom HDX (\d+) HD \(Release - ([\d.-]+)\)\r\n|s p/Polycom HDX $1 videoconferencing system sipd/ v/$2/ d/webcam/ cpe:/h:polycom:hdx_$1/
match sip m|^SIP/2\.0 \d\d\d .*\r\nServer: TANDBERG/4102 \(X7\.0\.2\)\r\n|
match sip m|^SIP/2\.0 200 OK\r\nAccept: application/sdp, application/dtmf-relay, application/QSIG, application/broadsoft\r\n(?:[^\r\n]+\r\n)*?Server: Patton (\w+) [^\r\n]+ M5T SIP Stack/([\w._-]+)\r\n|s p/M5T SIP Client Engine/ v/$2/ i/Patton $1/ d/VoIP adapter/ cpe:/a:media5corp:m5t_sip_client_engine:$2/ cpe:/h:patton:$1/
match sip m|^SIP/2\.0 200 Rawr!!\r\nVia: SIP/2\.0/TCP nm;branch=foo;received=[\d.]+\r\nFrom: <sip:nm@nm>;tag=root\r\nTo: <sip:nm2@nm2>;tag=[\da-f]{32}\.[\da-f]+\r\nCall-ID: 50000\r\nCSeq: 42 OPTIONS\r\nContent-Length: 0\r\n\r\n| p/Kamailio sipd/ cpe:/a:kamailio:kamailio/
match sip m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?User-Agent:Mitel-(\d\w+)-SIP-Phone ([\d.]+) [0-9A-F]{12}\r\n|s p/Mitel SIP phone sipd/ v/$2/ i/model: $1/ cpe:/h:mitel:$1-ip/
match sip m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?User-Agent:Mitel-Mitel-SIP-Phone ([\d.]+) [0-9A-F]{12}\r\n|s p/Mitel SIP phone sipd/ v/$1/
match sip m|^SIP/2\.0 484 Address Incomplete\r\n(?:[^\r\n]+\r\n)*?Server: SIP Pulse (\d[\w.]+)\r\n|s p/SIP Pulse/ v/$1/ cpe:/a:sippulse:sippulse:$1/
match sip m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?User-Agent: FreeSwitch\r\n|s p/FreeSwitch sipd/ cpe:/a:freeswitch:freeswitch/
match sip m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?User-Agent: PJSUA v([\d.]+) Darwin-([\d.]+)/|s p/PJSIP pjsua sipd/ v/$1/ i/Darwin $2/ o/OS X/ cpe:/o:apple:mac_os_x/a
match sip m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?User-Agent: PJSUA v([\d.]+) Linux-([\d.]+)/(ix[\w_]+)|s p/PJSIP pjsua sipd/ v/$1/ i/arch: $3/ o/Linux $2/ cpe:/o:linux:linux_kernel:$2/a
match sip m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?User-Agent: PJSUA v([\d.]+) win32-([\d.]+)/(ix[\w_]+)|s p/PJSIP pjsua sipd/ v/$1/ i/arch: $3/ o/Windows $2/ cpe:/o:microsoft:windows/a
match sip m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?User-Agent: MicroSIP/([\d.]+)\r\n|s p/MicroSIP sipd/ v/$1/ o/Windows/ cpe:/o:microsoft:windows/a
match sip m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?User-Agent: Tely_v([\d.-]+)\r\n|s p/Tely sipd/ v/$1/
match sip m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?User-Agent: CSipSimple_([^/-]+)[-\d]*/(r\d+)\r\n|s p/CSipSimple sipd/ v/$2/ i/device: $SUBST(1,"_"," ")/ cpe:/a:csipsimple:csipsimple:$2/
match sip m|^SIP/2\.0 500 Server Internal Error\r\n(?:[^\r\n]+\r\n)*?User-Agent: Thomson ([\w-]+) Build ([\d.]+)\r\nX-Serialnumber: (\w+)\r\n|s p/Thomson $1 router sipd/ v/$2/ i/serial: $3/ d/broadband router/ cpe:/h:thomson:$1/a
match sip m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?User-Agent: Softphone/([\d.]+) \(RingCentral(?: \(\d+\))?; (Windows \w+) \((\d\d) bits\)/([\d.]+); revision: \d+\)\r\n|s p/RingCentral Softphone/ v/$1/ i/arch: $3-bit; OS Version $4/ o/$2/ cpe:/a:ringcentral:softphone:$1/ cpe:/o:microsoft:$2/
match sip m|^SIP/2\.0 \d\d\d (?:[^\r\n]*\r\n(?!\r\n))*?User-Agent: Yealink (SIP-[\w_]+) ([\d.]+)\r\n|s p/Yealink $1 VoIP phone sipd/ v/$2/ d/VoIP phone/ cpe:/h:yealink:$1/

match sip-proxy m|^SIP/2\.0 (?:[^\r\n]*\r\n(?!\r\n))*?User-Agent: Asterisk PBX ([\w._+-]+)\r\n|s p/Asterisk PBX/ v/$1/ d/PBX/ cpe:/a:digium:asterisk:$1/
match sip-proxy m|^SIP/2\.0 (?:[^\r\n]*\r\n(?!\r\n))*?Server: OpenS[Ee][Rr] \(([\w\d\.-]+) \(([\d\w/]+)\)\)|s p/OpenSER SIP Server/ v/$1/ i/$2/
match sip-proxy m|^SIP/2\.0 (?:[^\r\n]*\r\n(?!\r\n))*?Server: Sip EXpress router \(([\w\d\.-]+) \(([\d\w/]+)\)\)|s p/SIP Express Router/ v/$1/ i/$2/
# OpenSER and SER have joined to become SIP Router
match sip-proxy m|^SIP/2\.0 (?:[^\r\n]*\r\n(?!\r\n))*?Server: SIP Router \(([\w\d\.-]+) \(([\d\w/]+)\)\)|s p/SIP Router/ v/$1/ i/$2/
match sip-proxy m|^SIP/2\.0 (?:[^\r\n]*\r\n(?!\r\n))*?Server: OpenSIPS \(([\w\d\.-]+) \(([\d\w/]+)\)\)|s p/OpenSIPS SIP Server/ v/$1/ i/$2/
match sip-proxy m|^SIP/2\.0 (?:[^\r\n]*\r\n(?!\r\n))*?Server: Cisco-SIPGateway/IOS-([-\d\w.]+)\r\n|s p/Cisco SIP Gateway/ i/IOS $1/ d/router/ o/IOS/ cpe:/o:cisco:ios/a
match sip-proxy m|^SIP/2\.0 (?:[^\r\n]*\r\n(?!\r\n))*?Server: Sphericall/([\w._-]+) Build/(\d+)\r\n|s p/Sphericall VoIP Gateway/ v/$1 build $2/ o/Windows/ cpe:/o:microsoft:windows/a
match sip-proxy m|^SIP/2\.0 (?:[^\r\n]*\r\n(?!\r\n))*?Server: CommuniGatePro/([\w._-]+)\r\n|s p/CommuniGatePro VoIP Gateway/ v/$1/ cpe:/a:stalker:communigate_pro:$1/
match sip-proxy m|^SIP/2\.0 (?:[^\r\n]*\r\n(?!\r\n))*?Server: Sip EXpress router \(([\w._-]+) OpenIMSCore \(i386/linux\)\)\r\n|s p/OpenIMSCore SIP EXpress router/ v/$1/ i/Linux i386/ o/Linux/ cpe:/o:linux:linux_kernel/a
match sip-proxy m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?User-Agent: FreeSWITCH-mod_sofia/([\w._ +~-]+)\r\n|s p/FreeSWITCH mod_sofia/ v/$1/ cpe:/a:freeswitch:freeswitch/
match sip-proxy m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?User-Agent: Configured by 2600hz!\r\n(?:[^\r\n]+\r\n)*?Accept: application/sdp\r\nAllow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, UPDATE, INFO, REGISTER, REFER, NOTIFY, PUBLISH, SUBSCRIBE\r\n|s p/FreeSWITCH/ d/PBX/ cpe:/a:freeswitch:freeswitch/
match sip-proxy m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?\r\nUser-Agent: 3CXPhoneSystem ([\w._-]+)(?: \(\d+\))?\r\n|s p/3CX PhoneSystem PBX/ v/$1/ o/Windows/ cpe:/a:3cx:3cx_phonesystem:$1/ cpe:/o:microsoft:windows/a
match sip-proxy m|^SIP/2\.0 503 Remote end of tunnel is not connected\r\n(?:[^\r\n]+\r\n)*?Warning: \d+ \w+ \"Remote end of the bridge is not connected\"\r\n|s p/3CX PhoneSystem PBX/ i/misconfigured/ d/PBX/ o/Windows/ cpe:/o:microsoft:windows/a
match sip-proxy m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?User-Agent: ComdasysB2BUA([\w._-]+)\r\n|s p/Comdasys SIP Server/ v/$1/
match sip-proxy m|^SIP/2\.0 405 Method Not Allowed\r\n(?:[^\r\n]+\r\n)*?Server: SIParator/([\w._-]+)\r\n|s p/Ingate SIParator/ v/$1/
match sip-proxy m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?Server: Audiocodes-Sip-Gateway-(Mediant [\w._-]+)/v([\w._-]+)\r\n|s p/Audiocodes $1 SIP gateway/ v/$2/ d/VoIP adapter/
match sip-proxy m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?Server: Audiocodes-Sip-Gateway-(MP-[\w._ -]+)/v\.([\w._-]+)\r\n|s p/Audiocodes $1 SIP gateway/ v/$2/ d/VoIP adapter/
match sip-proxy m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?User-Agent: Berofix VOIP Gateway\r\n|s p/Berofix VoIP gateway/ d/VoIP adapter/
match sip-proxy m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?Server: HiPath ([\w._-]+) V([\w._ -]+) SIP Stack/([\w._-]+)\r\n|s p/Siemens HiPath $1 VoIP gateway/ v/$2/ i/SIP stack $3/ d/VoIP adapter/ cpe:/h:siemens:hipath_$1/a
match sip-proxy m|^SIP/2\.0 503 Service Unavailable\r\nVia: SIP/2\.0/TCP nm;branch=foo;received=[\d.]+\r\nFrom: <sip:nm@nm>;tag=root\r\nTo: <sip:nm2@nm2>;tag=\w+\r\nDate: .*?\r\nCall-ID: 50000\r\nCSeq: 42 OPTIONS\r\nWarning: \d+ [\w._-]+ \"Unable to find a device handler for the request received on port \d+ from [\d.]+\"\r\nContent-Length: 0\r\n\r\n| p/Cisco Unified Communications Manager/ cpe:/a:cisco:unified_communications_manager/
# CUCM 6.1.2.1001-4
match sip-proxy m|^SIP/2\.0 503 Service Unavailable\r\nDate: .*\r\nWarning: \d+ \"Routing failed: ccbid=\d+ tcpindex=\d+ socket=nm:\d+'\r\nFrom: <sip:nm@nm>;tag=root\r\nContent-Length: 0\r\nTo: <sip:nm2@nm2>;tag=\d+\r\nCall-ID: 50000\r\nVia: SIP/2\.0/TCP nm;branch=foo;received=[\d.]+\r\nCSeq: 42 OPTIONS\r\n\r\n| p/Cisco Unified Communications Manager/ cpe:/a:cisco:unified_communications_manager/
match sip-proxy m|^SIP/2\.0 100 Trying\r\n(?:[^\r\n]+\r\n)*?Server: Sipwise NGCP Proxy ([\w._-]+)\r\n|s p/Sipwise NGCP SIP/ v/$1/ d/PBX/
match sip-proxy m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?Server: NEC-i SL Series ([\w._-]+)/2\.1\r\n|s p/NEC SL-series VoIP PBX/ v/$1/ d/PBX/
match sip-proxy m|^SIP/2\.0 400 Bad Request - Branch in top Via header has no Magic Cookie\r\nv:SIP/2\.0/TCP nm;branch=foo;received=[\d.]+\r\nf:<sip:nm@nm>;tag=root\r\nt:<sip:nm2@nm2>;tag=to_tag_[\da-f]+\r\ni:50000\r\nCSeq:42 OPTIONS\r\nl:0\r\n\r\n|s p/Nokia CFX-5000 SIP core controller/ d/PBX/
match sip-proxy m|^SIP/2\.0 403 Forbidden\r\nFrom: <sip:nm@nm>;tag=root\r\nTo: <sip:nm2@nm2>;tag=\w{16}\r\nCSeq: 42 OPTIONS\r\nCall-ID: 50000\r\nVia: SIP/2\.0/TCP nm;branch=foo\r\nContent-Length: 0\r\n\r\n| p/Avaya Session Border Controller/ cpe:/a:avaya:session_border_controller/
match sip-proxy m|^SIP/2\.0 \d\d\d (?:[^\r\n]*\r\n(?!\r\n))*?Server: Mediant (\d+)/v\.([\d.]+)[\w.]+\r\n|s p/AudioCodes Mediant $1 session border controller sipd/ v/$2/ cpe:/h:audiocodes:mediant_$1/
match sip-proxy m|^SIP/2\.0 \d\d\d (?:[^\r\n]*\r\n(?!\r\n))*?Server: Altitude vBox\r\n|s p/Altitude vBox VoIP PBX/ d/PBX/
match sip-proxy m|^SIP/2\.0 (?:[^\r\n]*\r\n(?!\r\n))*?Server: Asterisk PBX ([\w._+~-]+)\r\n|s p/Asterisk PBX/ v/$1/ d/PBX/ cpe:/a:digium:asterisk:$1/
match sip-proxy m|^SIP/2\.0 (?:[^\r\n]*\r\n(?!\r\n))*?Server: FPBX-([\d.]+)\(([\d.]+)\)\r\n|s p/FreePBX/ v/$1/ i/Asterisk $2/ d/PBX/ cpe:/a:digium:asterisk:$2/ cpe:/a:sangoma:freepbx:$1/
match sip-proxy m|^SIP/2\.0 (?:[^\r\n]*\r\n(?!\r\n))*?Server: Speedport (W \w+)/Version -([\d.]+)\r\n\r\n|s p/Telekom Speedport router sipd/ v/$2/ i/model $1/ d/broadband router/
match sip-proxy m|^SIP/2\.0 (?:[^\r\n]*\r\n(?!\r\n))*?Server: Mitel SIP-DECT \(SW-Version=([\w._-]+)\)\r\n|s p/Mitel SIP DECT OpenMobility Manager sipd/ v/$1/ cpe:/a:mitel:openmobility_manager:$1/
# notes2.exe 9.0.1
match sip-proxy m|^SIP/2\.0 \d\d\d .*\r\nCall-ID: 50000\r\nCSeq: 42 OPTIONS\r\nFrom: <sip:nm@nm>;tag=root\r\nTo: <sip:nm2@nm2>\r\nVia: SIP/2\.0/TCP nm;branch=foo;received=[^;\n]+;rport=\d+\r\nContact: <sip:[^>]+>;\+sip\.instance="<urn:uuid:[a-f\d]{8}-[a-f\d]{4}-[a-f\d]{4}-[a-f\d]{4}-[a-f\d]{12}>"\r\nAllow: INVITE, ACK, CANCEL, BYE, NOTIFY, INFO, MESSAGE, UPDATE\r\nContent-Length: 0\r\n\r\n| p/IBM Notes sipd/ cpe:/a:ibm:notes/
match sip-proxy m|^SIP/2\.0 404 Not Found\r\nVia: SIP/2\.0/TCP nm:5060;received=[^;]+;branch=foo\r\nCall-ID: 50000\r\nFrom: <sip:nm@nm>;tag=root\r\nTo: <sip:nm2@nm2>;tag=[a-f\d]{8}-[a-f\d]{8}\r\nCSeq: 42 OPTIONS\r\nContent-Length: 0\r\n\r\n| p/Cisco Unified Communications Manager sipd/ cpe:/a:cisco:unified_communications_manager/
match sip-proxy m|^SIP/2\.0 400 Via transport inconsistent with actual transport\r\nVia: SIP/2\.0/TCP nm:5060;received=[^;]+;branch=foo\r\nCall-ID: 50000\r\nFrom: <sip:nm@nm>;tag=root\r\nTo: <sip:nm2@nm2>\r\nCSeq: 42 OPTIONS\r\nContent-Length: 0\r\n\r\n| p/Cisco Unified Communications Manager sipd/ cpe:/a:cisco:unified_communications_manager/
match sip-proxy m|^SIP/2\.0 200 OK\r\nVia: SIP/2\.0/TCP nm;branch=foo;received=.*\r\nFrom: <sip:nm@nm>;tag=root\r\nTo: <sip:nm2@nm2>;tag=[a-f0-9]{32}\r\nCall-ID: 50000\r\nCSeq: 42 OPTIONS\r\nAllow: INVITE, ACK, BYE, CANCEL, REFER, OPTIONS, INFO, NOTIFY, PRACK, UPDATE\r\nAccept: application/sdp\r\nContent-Type: application/sdp\r\nContent-Length: \d+\r\n\r\n| p|Telos Z/IP ONE sipd| d/specialized/
match sip-proxy m|^SIP/2\.0 200 OK\r\nVia: SIP/2\.0/TCP nm;branch=foo;received=[^;]*;rport=\d+;ingress-zone=(\S+)\r\n(?:[^\r\n]+\r\n)*?Server: Cisco-CUCM([\d.]+)\r\n|s p/Cisco Unified Communications Manager sipd/ v/$2/ i/zone: $1/ cpe:/a:cisco:unified_communications_manager:$2/

match ssl/http m|^HTTP/1\.1 501 Not Implemented\r\nConnection: close\r\nServer: AppWork GmbH HttpServer\r\n\r\n| p/AppWork JDownloader2 httpd/ cpe:/a:appwork:jdownloader:2/

# The SIPOptionsProbe can trigger a response out of psyBNC
match irc-proxy m|^Login failed\. Disconnecting\.\r\n$| p/psyBNC/ i/Login Failed/

match upnp m|^HTTP/1\.1 404 Not Found\r\nConnection: close\r\nServer: UPnP/([\w._-]+), DLNADOC/([\w._-]+), Platinum/([\w._-]+)\r\n\r\n| p/Platinum upnpd/ v/$3/ i/XBMC; DLNADOC $2; UPnP $1/ o/Linux/ cpe:/a:plutinosoft:platinum:$3/ cpe:/o:linux:linux_kernel/
match upnp m|^HTTP/1\.1 404 Not Found\r\nContent-Length: \d+\r\nContent-Type: text/html\r\nServer: Linux/(\w+) UPnP/([\d.]+) DLNADOC/([\d.]+) Platinum/([\d.]+)\r\n\r\n| p/Platinum unpnd/ v/$4/ i/arch: $1; UPnP $2; DLNADOC $3/ o/Linux/ cpe:/a:plutinosoft:platinum:$4/ cpe:/o:linux:linux_kernel/a
match upnp m|^HTTP/1\.1 501 Unimplemented\r\nServer: unspecified, UPnP/([\w._-]+), unspecified\r\nConnection: close\r\nContent-Length: 0\r\n\r\n| p/Cisco-Linksys E4200 WAP upnpd/ i/UPnP $1/ cpe:/h:cisco:e4200/

# TODO: enumerate version differences between these two?
match webdav m|^HTTP/1\.1 200 OK\r\n(?:[^\r\n]+\r\n)*?Server: cPanel\r\nContent-Length: 0\r\nConnection: Keep-Alive\r\nAllow: UNLOCK,HEAD,MOVE,OPTIONS,LOCK,POST,PUT,COPY,MKCOL,GET,DELETE,PROPFIND\r\nContent-Type: httpd/unix-directory\r\nDAV: 1,2,<http://apache\.org/dav/propset/fs/1>\r\nKeep-Alive: timeout=15, max=96\r\nMS-Author-Via: DAV\r\n\r\n|s p/cPanel webdav/ o/Linux/ cpe:/o:linux:linux_kernel/a
match webdav m|^HTTP/1\.1 200 OK\r\n(?:[^\r\n]+\r\n)*?Server: cPanel\r\nPersistent-Auth: false\r\nCache-Control: no-cache[^\r\n]*\r\nConnection: Keep-Alive\r\nVary: Accept-Encoding\r\nAllow: [A-Z, ]+\r\nContent-Length: 0\r\nContent-Type: text/plain\r\nExpires: Fri, 01 Jan 1990 00:00:00 GMT\r\nDAV: 1, 2\r\nKeep-Alive: timeout=15, max=96\r\nMS-Author-Via: DAV\r\n\r\n|s p/cPanel webdav/ o/Linux/ cpe:/o:linux:linux_kernel/a

match xmpp m|^<stream:error><bad-format xmlns='urn:ietf:params:xml:ns:xmpp-streams'/></stream:error></stream:stream>$| p/Isode M-Link XMPP/ cpe:/a:isode:m-link/

# internal communication service of Yamaha RX-V2067 AV-Receiver
match yamaha-comm m|^@SYS:INPNAMEMULTICH=MULTI CH\r\n@SYS:INPNAMEPHONO=PHONO\r\n@SYS:INPNAMEAV1=Blu-ray\r\n@SYS:INPNAMEAV2=Dreambox\r\n@SYS:INPNAMEAV3=PS 3\r\n@SYS:INPNAMEAV4=AV4\r\n@SYS:INPNAMEAV5=AV5\r\n@SYS:INPNAMEAV6=AV6\r\n@SYS:INPNAMEAV7=AV7\r\n@SYS:INPNAMEVAUX=V-AUX\r\n@SYS:INPNAMEAUDIO1=TV\r\n@SYS:INPNAMEAUDIO2=AUDIO2\r\n@SYS:INPNAMEAUDIO3=AUDIO3\r\n@SYS:INPNAMEAUDIO4=AUDIO4\r\n@SYS:INPNAMEDOCK=DOCK\r\n@SYS:INPNAMEUSB=USB\r\n@TUN:AVAIL=Not Ready\r\n@MAIN:ZONENAME=Main\r\n| p/Yamaha RX-V2067 AV receiver/ d/media device/ cpe:/h:yamaha:rx-v2067/

match zabbix m|^OK$| p/Zabbix Monitoring System/ cpe:/a:zabbix:zabbix/

match zeiss-axio m|^SIP/2\.0\rID: 50000\rTIONS\r| p/Zeiss Axio Imager microsocope/

softmatch sip m|^SIP/2\.0 ([-\w\s.]+)\r\n(?:[^\r\n]+\r\n)*?Server: ([-\w\s/_\.\(\)]+)\r\n|s p/$2/ i/Status: $1/
softmatch sip m|^SIP/2\.0 ([-\w\s.]+)\r.*\nUser-[Aa]gent: ([-\w\s/_\.\(\)]+)\r\n|s p/$2/ i/Status: $1/
softmatch sip m|^SIP/2\.0 ([-\w\s.]+)\r\n| i/SIP end point; Status: $1/

##############################NEXT PROBE##############################
Probe UDP SIPOptions q|OPTIONS sip:nm SIP/2.0\r\nVia: SIP/2.0/UDP nm;branch=foo;rport\r\nFrom: <sip:nm@nm>;tag=root\r\nTo: <sip:nm2@nm2>\r\nCall-ID: 50000\r\nCSeq: 42 OPTIONS\r\nMax-Forwards: 70\r\nContent-Length: 0\r\nContact: <sip:nm@nm>\r\nAccept: application/sdp\r\n\r\n|
rarity 5
ports 5060
# Some VoIP phones take longer to respond
totalwaitms 7500

softmatch quic m|^\rPTIONS sQ\d\d\d|

match sip m|^SIP/2\.0 404 Not Found\r\n(?:[^\r\n]+\r\n)*?User-Agent: Asterisk PBX \(digium\)\r\n|s p/Digium Switchvox PBX/ i/based on Asterisk/ d/PBX/
match sip m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?User-Agent: SAGEM / 3202\.3 / 2601EC \r\n|s p/Sagem ADSL router/ d/broadband router/
match sip m|^SIP/2\.0 408 Request timeout\r\n(?:[^\r\n]+\r\n)*?Server: sipXecs/([\w._-]+) sipXecs/sipXproxy \(Linux\)\r\n|s p/SIPfoundry sipXecs PBX/ v/$1/ o/Linux/ cpe:/o:linux:linux_kernel/a
match sip m|^SIP/2\.0 404 Not Found\r\n(?:[^\r\n]+\r\n)*?User-Agent: AVM (FRITZ!Box Fon WLAN [\w._ -]+) (?:Annex A )?(?:\(UI\) )?([\w._ -]+ \(\w+ +\d+ +\d+\))|s p/AVM $1 SIP/ v/$2/ d/WAP/ cpe:/h:avm:$1/
match sip m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?Server: NetSapiens SiPBx 1-1205c\r\n|s p/NetSapiens SiPBX SIP switch/ d/switch/
match sip m|^SIP/2\.0 481 Call Leg/Transaction Does Not Exist\r\nFrom: <sip:nm@nm>;tag=root\r\nTo: <sip:nm2@nm2>;tag=0-\w+-\w+-\w+-\w+\r\nCall-ID: 50000\r\nCSeq: 42 OPTIONS\r\nVia: SIP/2\.0/UDP nm;received=[\d.]+;rport=\d+;branch=foo\r\nContent-Length: 0\r\n\r\n$| p/Sony PCS-TL50 videoconferencing SIP/ cpe:/h:sony:pcs-tl50/
match sip m|^SIP/2\.0 200 OK\r\nCSeq: 42 OPTIONS\r\nVia: SIP/2\.0/UDP nm;branch=foo;rport\r\nFrom: <sip:nm@nm>;tag=root\r\nCall-ID: 50000\r\nTo: <sip:nm2@nm2>\r\nContact: <sip:nm2@[\d.]+>\r\nContent-Length: 0\r\n\r\n$| p/Ekiga SIP/ v/3.2.7/ cpe:/a:ekiga:ekiga:3.2.7/
match sip m|^SIP/2\.0 403 Forbidden\r\n(?:[^\r\n]+\r\n)*?From: <sip:nm@nm>;tag=root\r\nTo: <sip:nm2@nm2>;tag=Mitel-([\w._-]+)_\d+-\d+\r\n|s p/Mitel $1 PBX SIP/ d/PBX/
match sip m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?Allow: INVITE, ACK, CANCEL, BYE, OPTIONS, INFO, REFER, SUBSCRIBE, NOTIFY\r\nAccept: application/sdp,application/dtmf-relay,application/simple-message-summary,message/sipfrag\r\nAccept-Encoding: identity\r\n|s p/Siemens Gigaset DX800A VoIP phone SIP/ d/VoIP phone/ cpe:/h:siemens:gigaset_dx800a/a
match sip m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?User-Agent: Zoiper rev\.(\d+)\r\n|s p/Zoiper softphone SIP/ v/$1/ cpe:/a:securax:zoiper:$1/
match sip m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?User-Agent: Ekiga/([\w._-]+)\r\n|s p/Ekiga/ v/$1/ cpe:/a:ekiga:ekiga:$1/
match sip m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?User-Agent: HG4000/([\w._-]+)+\r\n|s p/Hypermedia HG-4000 VoIP GSM gateway SIP/ v/$1/ d/VoIP adapter/
match sip m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?User-Agent: Grandstream (IP\d+) ([\w._-]+)\r\n|s p/Grandstream $1 VoIP phone SIP/ v/$2/ d/VoIP phone/ cpe:/h:grandstream:$1/a
match sip m|^SIP/2\.0 \d\d\d (?:[^\r\n]*\r\n(?!\r\n))*?User-Agent: Yealink (SIP-[\w_]+) ([\d.]+)\r\n|s p/Yealink $1 VoIP phone sipd/ v/$2/ d/VoIP phone/ cpe:/h:yealink:$1/
match sip m|^SIP/2\.0 \d\d\d (?:[^\r\n]*\r\n(?!\r\n))*?User-Agent: (VP\d+\w*) ([\d.]+)\r\n|s p/Yealink $1 VoIP phone sipd/ v/$2/ d/VoIP phone/ cpe:/h:yealink:$1/
match sip m|^SIP/2\.0 404 Not Found\r\n(?:[^\r\n]+\r\n)*?User-Agent: FRITZ!OS\r\n|s p/AVM FRITZ!OS SIP/ d/VoIP adapter/
match sip m|^SIP/2\.0 200 Rawr!!\r\nVia: SIP/2\.0/UDP nm;branch=foo;rport=\d+;received=[\d.]+\r\nFrom: <sip:nm@nm>;tag=root\r\nTo: <sip:nm2@nm2>;tag=[\da-f]{32}\.[\da-f]+\r\nCall-ID: 50000\r\nCSeq: 42 OPTIONS\r\nContent-Length: 0\r\n\r\n| p/Kamailio sipd/ cpe:/a:kamailio:kamailio/

match sip-proxy m|^SIP/2\.0 (?:[^\r\n]*\r\n(?!\r\n))*?Server: FPBX-([\d.]+)\(([\d.]+)\)\r\n|s p/FreePBX/ v/$1/ i/Asterisk $2/ d/PBX/ cpe:/a:digium:asterisk:$2/ cpe:/a:sangoma:freepbx:$1/
match sip-proxy m|^SIP/2\.0 (?:[^\r\n]*\r\n(?!\r\n))*?Server: Asterisk PBX ([\w._+~-]+)\r\n|s p/Asterisk PBX/ v/$1/ d/PBX/ cpe:/a:digium:asterisk:$1/
match sip-proxy m|^SIP/2\.0 (?:[^\r\n]*\r\n(?!\r\n))*?Server: OpenS[Ee][Rr] \(([\w\d\.-]+) \(([\d\w/]+)\)\)|s p/OpenSER SIP Server/ v/$1/ i/$2/
match sip-proxy m|^SIP/2\.0 (?:[^\r\n]*\r\n(?!\r\n))*?Server: Sip EXpress router \(([\w\d\.-]+) \(([\d\w/]+)\)\)|s p/SIP Express Router/ v/$1/ i/$2/
# OpenSER and SER have joined to become SIP Router
match sip-proxy m|^SIP/2\.0 (?:[^\r\n]*\r\n(?!\r\n))*?Server: SIP Router \(([\w\d\.-]+) \(([\d\w/]+)\)\)|s p/SIP Router/ v/$1/ i/$2/
match sip-proxy m|^SIP/2\.0 (?:[^\r\n]*\r\n(?!\r\n))*?User-Agent: Asterisk PBX\r\n|s p/Asterisk PBX/ cpe:/a:digium:asterisk/
match sip-proxy m|^SIP/2\.0 (?:[^\r\n]*\r\n(?!\r\n))*?Server: OpenSIPS \(([\w\d\.-]+) \(([\d\w/]+)\)\)|s p/OpenSIPS SIP Server/ v/$1/ i/$2/
match sip-proxy m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?\r\nUser-Agent: ComdasysB2BUA([\w._-]+)\r\n|s p/Comdasys SIP Server/ v/$1/
match sip-proxy m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?Server: NEC-i SL Series ([\w._-]+)/2\.1\r\n|s p/NEC SL-series VoIP PBX/ v/$1/ d/PBX/
match sip-proxy m|^SIP/2\.0 200 OK\r\nVia: SIP/2\.0/UDP nm;branch=foo;received=[\d.]+;rport=\d+\r\nFrom: <sip:nm@nm>;tag=root\r\nTo: <sip:nm2@nm2>;tag=as\d+\r\nCall-ID: 50000\r\nCSeq: 42 OPTIONS\r\nServer: -(\d[\w._-]+)\((\d[\w._-]+)\)\r\nAllow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH\r\nSupported: replaces, timer\r\nContact: .*\r\nAccept: application/sdp\r\nContent-Length: 0\r\n\r\n| p/Asterisk/ v/$2/ i/FreePBX $1/ cpe:/a:digium:asterisk:$2/
match sip-proxy m|^SIP/2\.0 400 Bad Request - [A-Z] - 16007\r\nv:SIP/2\.0/UDP nm;branch=foo;rport=\d+;received=[\d.]+\r\nf:<sip:nm@nm>;tag=root\r\nt:<sip:nm2@nm2>;tag=\d+\r\ni:50000\r\nCSeq:42 OPTIONS\r\nl:0\r\n\r\n| p/Nokia CFX-5000 SIP core controller/ d/PBX/
match sip-proxy m|^SIP/2\.0 400 Bad Request - [A-Z] - 16007\r\nVia: SIP/2\.0/UDP nm;branch=foo;rport=\d+;received=[\d.]+\r\nFrom: <sip:nm@nm>;tag=root\r\nTo: <sip:nm2@nm2>;tag=\d+\r\nCall-ID: 50000\r\nCSeq: 42 OPTIONS\r\nContent-Length: 0\r\n\r\n| p/Nokia CFX-5000 SIP core controller/ d/PBX/
match sip-proxy m|^SIP/2\.0 404 Not Found\r\n(?:[^\r\n]+\r\n)*?Server: Asterisk PBX\r\n(?:[^\r\n]+\r\n)*?Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO|s p/Asterisk/ d/PBX/ cpe:/a:digium:asterisk/
match sip-proxy m|^SIP/2\.0 (?:[^\r\n]*\r\n(?!\r\n))*?Server: CommuniGatePro/([\w._-]+)\r\n|s p/CommuniGatePro VoIP Gateway/ v/$1/ cpe:/a:stalker:communigate_pro:$1/
match sip-proxy m|^SIP/2\.0 (?:[^\r\n]*\r\n(?!\r\n))*?Server: STARFACE PBX\r\n|s p/STARFACE PBX/ cpe:/a:starface:starface_pbx/

softmatch sip m|^SIP/2\.0 ([-\w\s.]+)\r\n(?:[^\r\n]+\r\n)*?Server: ([-\w\s/_\.\(\)]+)\r\n|s p/$2/ i/Status: $1/
softmatch sip m|^SIP/2\.0 ([-\w\s.]+)\r.*\nUser-[Aa]gent: ([-\w\s/_\.\(\)]+)\r\n|s p/$2/ i/Status: $1/
softmatch sip m|^SIP/2\.0 ([-\w\s.]+)\r\n| i/SIP end point; Status: $1/

# Supposed to be multicast, but apparently something answers unicast?
match ws-discovery m|^<\?xml version=\"1\.0\" encoding=\"UTF-8\"\?>\n<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://www\.w3\.org/2003/05/soap-envelope\" xmlns:SOAP-ENC=\"http://www\.w3\.org/2003/05/soap-encoding\" xmlns:xsi=\"http://www\.w3\.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www\.w3\.org/2001/XMLSchema\" xmlns:wsa=\"http://schemas\.xmlsoap\.org/ws/2004/08/addressing\" xmlns:d=\"http://schemas\.xmlsoap\.org/ws/2005/04/discovery\" xmlns:d3=\"http://www\.onvif\.org/ver10/network/wsdl/RemoteDiscoveryBinding\" xmlns:d4=\"http://www\.onvif\.org/ver10/network/wsdl/DiscoveryLookupBinding\" xmlns:dn=\"http://www\.onvif\.org/ver10/network/wsdl\"><SOAP-ENV:Body><SOAP-ENV:Fault><faultcode>SOAP-ENV:Client</faultcode><faultstring>No XML element tag</faultstring></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>| p/Huacam Cyclops ONVIF 1.0 responder/ d/webcam/
# Brother MFC-9340CDW
match ws-discovery m|^<\?xml version=\"1\.0\" encoding=\"UTF-8\"\?>\n<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://www\.w3\.org/2003/05/soap-envelope\" xmlns:wsa=\"http://schemas\.xmlsoap\.org/ws/2004/08/addressing\" xmlns:wsdisco=\"http://schemas\.xmlsoap\.org/ws/2005/04/discovery\" xmlns:wsdp=\"http://schemas\.xmlsoap\.org/ws/2006/02/devprof\" xmlns:wse=\"http://schemas\.xmlsoap\.org/ws/2004/08/eventing\" xmlns:xop=\"http://www\.w3\.org/2004/08/xop/include\" xmlns:wsx=\"http://schemas\.xmlsoap\.org/ws/2004/09/mex\" xmlns:wxf=\"http://schemas\.xmlsoap\.org/ws/2004/09/transfer\" xmlns:wprt=\"http://schemas\.microsoft\.com/windows/2006/08/wdp/print\" xmlns:wscn=\"http://schemas\.microsoft\.com/windows/2006/08/wdp/scan\"><SOAP-ENV:Body><SOAP-ENV:Fault><faultcode>SOAP-ENV:Client</faultcode><faultstring>HTTP Error: 405 Method Not Allowed</faultstring></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>| p/Brother WS-Print 1.0 responder/ d/printer/
# Softmatch for now, since submission didn't contain specific device
softmatch ws-discovery m|^<\?xml version=\"1\.0\" encoding=\"UTF-8\"\?>\n<SOAP-ENV:Envelope .*xmlns:\w+=\"http://schemas\.xmlsoap\.org/ws/2005/04/discovery\" .*xmlns:\w+=\"http://www\.onvif\.org/ver10/network/wsdl/RemoteDiscoveryBinding\"| p/ONVIF 1.0 responder/ d/webcam/
softmatch ws-discovery m|^<\?xml version=\"1\.0\" encoding=\"UTF-8\"\?>\n<SOAP-ENV:Envelope .*xmlns:\w+=\"http://schemas\.xmlsoap\.org/ws/2005/04/discovery\" .*xmlns:\w+=\"http://schemas\.microsoft\.com/windows/2006/08/wdp/print\"| p/WS-Print 1.0 responder/ d/printer/

##############################NEXT PROBE##############################
Probe TCP LANDesk-RC q|\x54\x4e\x4d\x50\x04\0\0\0\x54\x4e\x4d\x45\0\0\x04\0|
rarity 6
ports 1761-1763,2701,5709
# With Host and User currently logged in
match landesk-rc m|^TNMP.\0\0\0TNME.\0\0\0USER.\x08\x04\0\x08\0.{9}\0R\0\x03\0W\0\xff\xff\0.\0\xfd..\0\0\0\0\x02\0\0\0\0\x01\x04\0\0\0\0\0...\0\xb5\x01\xbb\0Desktop Manager (\d\.\d)\0\x02\x04\x01\x02\x01\0\0\W+([-\w]+)\0([-\w]+)\0\0$|s p/LANDesk RC/ v/$1/ i/User: $3/ h/$2/ cpe:/a:landesk:landesk_management_suite:$1/
# With just hostname
match landesk-rc m|^TNMP.\0\0\0TNME.\0\0\0USER.\x08\x04\0\x08\0.{9}\0R\0\x03\0W\0\xff\xff\0.\0\xfd..\0\0\0\0\x02\0\0\0\0\x01\x04\0\0\0\0\0...\0\xb5\x01\xbb\0Desktop Manager (\d\.\d)\0\x02\x04\x01\x02\x01\0\0\W+(\w+)\0\0\0$|s p/LANDesk RC/ v/$1/ h/$2/ cpe:/a:landesk:landesk_management_suite:$1/
# Being Controled w/ User
match landesk-rc m|^TNMP.\0\0\0TNME.\0\0\0USER.\x08\x04\0\x08\0.{9}\0R\0\x03\0W\0\xff\xff\0.\0\xfd..\0\0\0\0\x02\0\0\0\0\x01\x04\0\0\0\0\0...\0\xb5\x01\xbb\0Desktop Manager (\d\.\d)\0\x02\x04\x01\x02\x01\0\0\W+([\w.:]+)\W+(\w+)\0(\w+)\0\0$|s p/LANDesk RC/ v/$1/ i/User: $4 Controller: $2/ h/$3/ cpe:/a:landesk:landesk_management_suite:$1/
# Being Controled w/o User
#match landesk-rc m|^TNMP.\0\0\0TNME.\0\0\0USER.\x08\x04\0\x08\0.{9}\0R\0\x03\0W\0\xff\xff\0.\0\xfd..\0\0\0\0\x02\0\0\0\0\x01\x04\0\0\0\0\0...\0\xb5\x01\xbb\0Desktop Manager (\d\.\d)\0\x02\x04\x01\x02\x01\0\0\W+([\w.:]+)\W+(\w+)\0(\w+)\0{2,3}$|s v/LANDesk RC/$1/Host: $3 Controler: $2/
match landesk-rc m|^TNMP.\0\0\0TNME.\0\0\0USER.\x08\x04\0\x08\0.{9}\0R\0\x03\0W\0\xff\xff\0.\0\xfd..\0\0\0\0\x02\0\0\0\0\x01\x04\0\0\0\0\0...\0\xb5\x01\xbb\0Desktop Manager (\d\.\d)\0\x02\x04\x01\x02\x01\0\0\W+([\w.:]+)\W+(\w+)\0|s p/LANDesk RC/ v/$1/ i/Controller: $2/ h/$3/ cpe:/a:landesk:landesk_management_suite:$1/

match landesk-rc m|^TNMP\x16\0\0\0TNME\x80\0\xfe\xff..([\w.]+):(\d)$|s p/LANDesk RC/ i/Busy, From $1 on port 176$2/ cpe:/a:landesk:landesk_management_suite/

# Novell Zen Remote Desktop Several 4.0.X submissions
match landesk-rc m|^\0\x04\0| p/Novell Zen Remote Desktop/ v/4.0.X/
# 6.5.14
match landesk-rc m|^\0\x06\x05| p/Novell Zen Remote Desktop/ v/6.5.X/

match landesk-rc m|^TNMP.\0\0\0TNME.\0\0\0USER.\x07\x04\0\x08\0.{9}\0P\0\x03\0U\0\xff\xff\0.*Desktop Manager ([\d.]+)\0|s p/LANDesk RC/ v/$1/ cpe:/a:landesk:landesk_management_suite:$1/

match spice m|^REDQ\x02\0\0\0\x02\0\0\0[^\0]| i/SPICE 2.2/

##############################NEXT PROBE##############################
Probe TCP TerminalServer q|\x03\0\0\x0b\x06\xe0\0\0\0\0\0|
rarity 6
ports 515,1028,1068,1503,1720,1935,2040,3388,3389

match activefax m|^ActiveFax Server: Es befinden sich insgesamt| p/ActFax Communication ActiveFax/ i/German/

match arcserve-gdd m|^\0\0\x0b\x06\xe0\0\0\0\0\0\0\0\0\0\0\0......\0\0\xa0\xf9\x7f\xee\xfb\x7f\0\0|s p/Arcserve Unified Data Protection Global Deduplication DataStore/ cpe:/a:arcserve:udp/

# TLS 1.0 alert "unexpected message"
match ssl/consul-rpc m|^\x15\x03\x01\0\x02\x02\n| p/HashiCorp Consul RPC/ cpe:/a:hashicorp:consul/
# Cisco video conference device port 1720
match H.323/Q.931 m|^\x03\0\0\x10\x08\x02\x80\0}\x08\x02\x80\xe2\x14\x01\0|

match lineage-ii m|^\x03\0.$| p/Lineage II game server/
# TODO: Dissect this; probably too specific
match lineage-ii m|^G\0\0\x01\0\0\0\xce\x1e\0\0\xce\x1e\0\0\xce\x1e\0\0/\x04\0\x000\0,\x006\0,\x003\x003\x003\x002\0,\x003\x003\x003\x003\0\0\0\x81\x8d\0\0\x81\x8d\0\0\x91\x91\0\0\0\0\0\0\x02\0\0\0| p/L2J Lineage II game server/

# \x03 is queue status command for LPD service.  Should be terminated
# by \n, but apparently some dumb lpds allow \0.  For now I will keep
# 515 in the common ports line, I suppose
match printer m|^no entries\n$| p/Xerox lpd/ d/printer/
match printer m|^SB06D2F0: \xe5\x9f\xf0\x18\xe5\x9f\xf0\x18\xe5\x9f\xf0\x18\xe5\x9f\xf0\x18\xe5\x9f\xf0\x18\xe1\xa0 no entries\n$| p/Kyocera Mita KM-1530 lpd/ d/printer/
match printer m|^ActiveFax Server: There are \d+ entries in the Faxlist\r\n| p/ActiveFax lpd/
match printer m|^Host Name: ([-\w_.]+)\nPrinter Device: hp LaserJet (\w+)\nPrinter Status: ([^\r\n]+)\n\0\0| p/NetSarang Xlpd/ i/HP LaserJet $2; Status $3/ o/Windows/ h/$1/ cpe:/o:microsoft:windows/a
match printer m|^Fictive printer queue short information\n$| p/Canon MF4360-4390 lpd/ d/printer/
match printer m|^414A_Citizen_CLP(\d+): \xe5\x9f\xf0\x18\xe5\x9f\xf0\x18\xe5\x9f\xf0\x18\xe5\x9f\xf0\x18\xe5\x9f\xf0\x18\xe1\xa0 no entries\n$| p/Citizen CLP-$1 lpd/ d/printer/

# Windows 2000 Server
# Windows 2000 Advanced Server
# Windows XP Professional
match ms-wbt-server m|^\x03\0\0\x0b\x06\xd0\0\0\x12.\0$|s p/Microsoft Terminal Service/ o/Windows/ cpe:/o:microsoft:windows/a
match ms-wbt-server m|^\x03\0\0\x17\x08\x02\0\0Z~\0\x0b\x05\x05@\x06\0\x08\x91J\0\x02X$| p/Microsoft Terminal Service/ i/Used with Netmeeting, Remote Desktop, Remote Assistance/ o/Windows/ cpe:/o:microsoft:windows/a
match ms-wbt-server m|^\x03\0\0\x11\x08\x02..}\x08\x03\0\0\xdf\x14\x01\x01$|s p/Microsoft NetMeeting Remote Desktop Service/ o/Windows/ cpe:/a:microsoft:netmeeting/ cpe:/o:microsoft:windows/a
match ms-wbt-server m|^\x03\0\0\x0b\x06\xd0\0\0\x03.\0$|s p/Microsoft NetMeeting Remote Desktop Service/ o/Windows/ cpe:/a:microsoft:netmeeting/ cpe:/o:microsoft:windows/a

# Need more samples!
match ms-wbt-server m|^\x03\0\0\x0b\x06\xd0\0\0\0\0\0| p/xrdp/ cpe:/a:jay_sorg:xrdp/
match ms-wbt-server m|^\x03\0\0\x0e\t\xd0\0\0\0[\x02\xa1]\0\xc0\x01\n$| p/IBM Sametime Meeting Services/ o/Windows/ cpe:/a:ibm:sametime/ cpe:/o:microsoft:windows/a

match ms-wbt-server m|^\x03\0\0\x0b\x06\xd0\0\x004\x12\0| p/VirtualBox VM Remote Desktop Service/ o/Windows/ cpe:/a:oracle:vm_virtualbox/ cpe:/o:microsoft:windows/a

match ms-wbt-server-proxy m|^nmproxy: Procotol byte is not 8\n$| p/nmproxy NetMeeting proxy/

# Semi-open protocol from Adobe: http://www.adobe.com/devnet/rtmp/.
# Some reverse engineering at http://wiki.gnashdev.org/RTMP says the server
# handshake is a 0x03 byte followed by 1536 seeming-random bytes. However
# service scan only gets 900 or 1300 bytes, so just check for as much as
# possible up to 1536.
match rtmp m|^\x03.{899,1536}$|s p/Real-Time Messaging Protocol/

match sybase-monitor m|^\0\x01\0\x08\0\0\x01\0$| p/Sybase Monitor Server/ o/Windows/ cpe:/a:sybase:monitor_server/ cpe:/o:microsoft:windows/a

match trillian m|^.\0\x01.....\0([^\0]+)\0|s p/Trillian MSN Module/ i/Name $1/ o/Windows/ cpe:/a:trillian:trillian/ cpe:/o:microsoft:windows/a

match trustwave m|^control\n   ping\n   endping\nendcontrol\n| p/Trustwave SIEM OE/ cpe:/a:trustwave:siem_oe/

##############################NEXT PROBE##############################
# Netware Create Connection Service request
Probe TCP NCP q|\x44\x6d\x64\x54\0\0\0\x17\0\0\0\x01\0\0\0\0\x11\x11\0\xff\x01\xff\x13|
rarity 6
ports 524,1200,1217,2000,3000-3006,3031,6802

match audioworks m|^\0\0$| p/AudioWorks sound server/ o/IRIX/ cpe:/o:sgi:irix/a

# port 3888/tcp. Two identical length-prefixed messages. Same response to afp probe.
match jute m|^\0\0\0\(\0\0\0\x01\0\0\0\0\0\0\0\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\x01\0\0\0\x01\0\0\0\(\0\0\0\x01\0\0\0\0\0\0\0\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\x01\0\0\0\x01| p/Apache ZooKeeper/ cpe:/a:apache:zookeeper/

# Netware 5 and 6
# NCP "OK" reply
match ncp m|^\x74\x4e\x63\x50\0\0\0\x10\x33\x33| p/Novell NetWare NCP/ cpe:/o:novell:netware/
match srun m|^X\0\0\0$| p/Caucho Resin JSP Engine srun/ cpe:/a:caucho:resin/
match progress m|^\0\0\0\x01\0\x17\0\x14\0\x06\0\0\0.\0\0\0\0\0\0|s p/Progress Database/ cpe:/a:progress:database/

# last 4 bytes are LE -88, PI_UNKNOWN_COMMAND
match pigpio m|^DmdT\0\0\0\x17\0\0\0\x01\xa8\xff\xff\xff| p/pigpiod/ cpe:/a:pigpio:pigpiod/

# Apple Remote Events echos a truncated version of the probe back
match appleevents m|^DmdT\0\0\0\x17\0\0\0\x01$| p/Apple Remote Events/ o/Mac OS X/ cpe:/o:apple:mac_os_x/a

match resin-watchdog m|^Q$| p/Caucho Resin Pro Watchdog/ cpe:/a:caucho:resin/

match smpp m|^\0\0\0\(\0\0\0\x01\0\0\0\0\0\0\0\x02\0\0\0\x02\0\0.*\0\0\0\0\0\0\0\x03\0\0\0\0\0\0\0\x03\0\0\0\x01|s p/Apache Zookeeper smpp/

match softplc m|^\x04\xef\xef\xb3\0\0\0\x01\x01\0\xc4\x01\0\0\0\0| p/CODESYS SoftPLC/ cpe:/a:3s-software:codesys_runtime_system/

match tuxedo-wsl m|^\d+SESSIONDENIED&REASON=Protocol violation\n$| p/BEA Tuxedo WorkStation Listener/ cpe:/a:bea:tuxedo/

match telnet m|^\xff\xfd\x98\xff\xfb\x01\xff\xfd\x18\xff\xfd\x98Welcome to UniData Telnet Server\r\nlogin: | p/Rocket UniData RDBMS telnetd/

match textui m|^R:ERROR:6 \"Syntax Error\"\r\n| p/Vantage InFusion home automation controller port/

##############################NEXT PROBE##############################
Probe TCP NotesRPC q|\x3A\x00\x00\x00\x2F\x00\x00\x00\x02\x00\x00\x40\x02\x0F\x00\x01\x00\x3D\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x1F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|
rarity 6
ports 130,427,1352,1972,7171,8728,22001

match intersys-cache m|^O\0\0\0\x03\xff\0\0\0\0\0\0\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0[\0\x01]G\x04\0\x0e\0\x01\0\x0f\0\x0e\0Access Denied$| p/InterSystems Cache database/
match intersys-cache m|^r\0\0\0\x03\xff\0\0\0\0\0\0\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0[\0\x01]\x008\0Cache Direct Server Fatal Error: Invalid subfunc code: 0$| p/InterSystems Cache database/

#match lotusnotes m|^`\0\0\0U\0\0\0\x03\0\0@\x02\x0f\0\x05\x009\x05.....\x03\0\0\0\0\x02\0/\0\x12|s
# Lotus Domino (r) Server (Release 5.0.8 for Windows/32
# Lotus Notes domino 5.0.11
# Lotus Server 6.0.1
# Lotus Domino (r) Server (Release 6.0.1CF1 for Windows/32
match lotusnotes m|^.\0\0\0.\0\0\0\x03\0\0@\x02\x0f\0.*\x03\0\0\0\0\x02\0/\0.\0\0\0\0\0\0\0.*CN=([-.\w ]+)/O=([-.\w ]+)[^-.\w ]|s p/Lotus Domino server/ i/CN=$1;Org=$2/ cpe:/a:ibm:lotus_domino_server/
match lotusnotes m|^.\0\0\0.\0\0\0\x03\0\0@\x02\x0f\0.*\x03\0\0\0\0\x02\0/\0.\0\0\0\0\0\0\0.*CN=([-.\w ]+)/OU=([-.\w ]+)/O=([-.\w ]+)[^-.\w ]|s p/Lotus Domino server/ i/CN=$1;OU=$2;Org=$3/ cpe:/a:ibm:lotus_domino_server/
match lotusnotes m|^.\0\0\0.\0\0\0\x03\0\0@\x02\x0f\0.*\x03\0\0\0\0\x02\0/\0.\0\0\0\0\0\0\0.*CN=([-.\w ]+)/OU=([-.\w ]+)/OU=([-.\w ]+)/O=([-.\w ]+)|s p/Lotus Domino server/ i|CN=$1;OU=$2/$3;Org=$4| cpe:/a:ibm:lotus_domino_server/

match megaraid-monitor m|^\x02\0\0\0\0\0\0/\0\0\0\0\0\0\0\0\0@\x1f\0\0\0\0\0\0\0\0\0/\0\0\0\x02\0\0@\x02\x0f\0\x01\0=\x05\0\0\0\0\0\0\0\0\0\0\0\0\0\)\0\0\0<monitorcontrol><error/></monitorcontrol>$| p/MegaRaid Monitoring Agent/

match routeros-api m|^\x06!fatal\rnot logged in\0| p/MikroTik RouterOS API/ o/RouterOS/ cpe:/o:mikrotik:routeros/

# Interesting service: Not sure if it's RPC
match rpcbind m|^\x18\0\x01\x02Invalid packet length\0| p/Amanda voicemail system/ d/telecom-misc/
# Moved this from SSLSessionReq because it seems more reliable.
# May need to generalize and grab the language if we see non-"en" responses
match srvloc m|^\x02\x02\0\0\x12\0\0\0\0\0\0\0\0\x02en\0\x02$| p/Apple slpd/ o/Mac OS/ cpe:/o:apple:mac_os/a
softmatch svrloc m|^\x02\x02\0\0.\0\0\0\0\0..\0.\w+|s p/SLP Service Agent/
match slp-srvreg m|^\x02\x05\0\0\x12\0\0\0\0\0\0@\0\x02en\xff\xef| p/AIX SLP Directory Agent/ o/AIX/ cpe:/o:ibm:aix/a
softmatch slp-srvreg m|^\x02\x05\0\0.\0\0\0\0\0..\0.\w+|s p/SLP Directory Agent/

softmatch slmp m|^\xd4\0MP\x04\0\0\0TNM\x0b\0P\0\0\0.......|s p/Mitsubishi PLC SLMP/ d/specialized/

match thrift-binary m|^\x04\0\0\0\x11Invalid status 58$| p/Hadoop Hive 2/ cpe:/a:apache:hive/
match tibia m|^V\0\x02\0Your terminal version is too old\.\nPlease get a new version at\nhttp://www\.tibia\.com\.\0$| p/Tibia graphical MUD/

match xplorer m|Access violation at address \w+ in module 'Xplorer\.exe'\. Read of address| p/SoftOne Business Xplorer/ o/Windows/ cpe:/o:microsoft:windows/a

match pc-anywhere m|\x1bY2\0\x01\x03B\0\0\x01\0\x14....................\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0| p/Symantec pcAnywhere/ cpe:/a:symantec:pcanywhere/

##############################NEXT PROBE##############################
Probe TCP DistCCD q|DIST00000001ARGC00000005ARGV00000002ccARGV00000002-cARGV00000006nmap.cARGV00000002-oARGV00000006nmap.oDOTI00000000|
rarity 8
ports 3632

match distccd m|^DONE00000001STAT00000000SERR00000000SOUT00000000DOTO.*?GCC: ([^\0]+)| p/distccd/ v/v1/ i/$1/
match distccd m|^DONE00000001STAT00000100SERR000000\w+/tmp/distccd_.*:\d+: internal compiler error: Segmentation fault| p/distccd/ i/broken/
match distccd m|^DONE00000001.*?DOTO00| p/distccd/ v/v1/ i/unknown compiler/
match distccd m|^DONE00000001.*ccache: failed to create /usr/share/distcc/\.ccache \(Permission denied\)\n| p/distccd/ i/broken/
match distccd m|^DONE00000001.*CRITICAL! distcc seems to have invoked itself recursively!\n|s p/distccd/ i/broken/
match distccd m|^[\w._-]+DONE[\w._-]+ .*ERROR: attempt to use unknown compiler aborted: ([\w._-]+)\n|s p/distccd/ i/broken: compiler $1 doesn't exist/

##############################NEXT PROBE##############################
# Java Remote Method Invocation, version 2, stream protocol
# https://docs.oracle.com/javase/9/docs/specs/rmi/protocol.html
Probe TCP JavaRMI q|\x4a\x52\x4d\x49\0\x02\x4b|
rarity 7
ports 706,999,1030,1035,1090,1098,1099,1100-1103,1129,1199,1234,1440,1981,2199,2809,3273,3333,3900,5520,5521,5580,5999,6060,6789,6996,7700,7800,7801,7878,7890,8050,8051,8085,8091,8205,8303,8642,8686,8701,8888-8890,8901-8903,8999,9001,9003-9005,9050,9090,9099,9300,9500,9711,9809,9810-9815,9875,9910,9991,9999,10001,10098,10099,10162,10990,11001,11099,11333,12000,13013,14000,15000,15001,15200,16000,17200,18980,20000,23791,26256,31099,32913,33000,37718,45230,47001,47002,50050,50500-50504

# 0x4e = ProtocolAck. 0x4f = ProtocolNotSupported.
# 4th byte begins client host ID, which is usually IP address
match java-rmi m|^\x4e..[0-9a-f:.]+\0\0..$|s p/Java RMI/
# GNU Classpath does reverse-lookup of hostname
match java-rmi m|^\x4e..[\w._-]+\0\0..$|s p/GNU Classpath grmiregistry/

# https://github.com/quine/GoProGTFO
match gopro-json m|^\{"rval": -7, "param_size": 0 \}\0| p/GoPro or similar camera json service/ d/webcam/

##############################NEXT PROBE##############################
Probe TCP Radmin q|\x01\x00\x00\x00\x01\x00\x00\x00\x08\x08|
ports 4899,9001
rarity 8

match fcgiwrap m|^\x01\x0b\0\0\0\x08\0\0\0\0\0\0\0\0\0\0$| p/fcgiwrap/

match radmin m|^\x01\x00\x00\x00\x25\x09\x00\x01\x10\x08\x01\x00\x09\x08| p/Famatech Radmin/ v/2.X/ i/Windows Authentication/ o/Windows/ cpe:/a:famatech:radmin:2/ cpe:/o:microsoft:windows/a
match radmin m|^\x01\x00\x00\x00\x25\x0a\x00\x01\x10\x08\x01\x00\x0a\x08| p/Famatech Radmin/ v/2.X/ i/Radmin Authentication/ o/Windows/ cpe:/a:famatech:radmin:2/ cpe:/o:microsoft:windows/a
match radmin m|^\x01\x00\x00\x00\x25\x00\x00\x02\x12\x08\x02\x00\x00\x0a| p/Famatech Radmin/ v/3.X/ i/Radmin Authentication/ o/Windows/ cpe:/a:famatech:radmin:3/ cpe:/o:microsoft:windows/a
match radmin m|^\x01\x00\x00\x00\x25\x71\x00\x02\x12\x08\x02\x00\x71\x0a| p/Famatech Radmin/ v/3.X/ i/Windows Authentication/ o/Windows/ cpe:/a:famatech:radmin:3/ cpe:/o:microsoft:windows/a
match radmin m|^\x01\x00\x00\x00\x25\x08\x00\x02\x12\x08\x02\x00\x08\x0a| p/Famatech Radmin/ v/3.X/ i/Radmin Authentication/ o/Windows/ cpe:/a:famatech:radmin:3/ cpe:/o:microsoft:windows/a
match radmin m|^\x01\x00\x00\x00\x25\x79\x00\x02\x12\x08\x02\x00\x79\x0a| p/Famatech Radmin/ v/3.X/ i/Windows Authentication/ o/Windows/ cpe:/a:famatech:radmin:3/ cpe:/o:microsoft:windows/a
match radmin m|^\x01\x00\x00\x00\x25\x59\x00\x02\x12\x08\x02\x00\x59\x0a| p/Famatech Radmin/ v/3.3/ o/Windows/ cpe:/a:famatech:radmin:3.3/ cpe:/o:microsoft:windows/a
match radmin m|^\x01\x00\x00\x00\x25\x04\x00\x02\x12\x08\x02\x00\x04\x0a| p/Famatech Radmin/ v/3.0/ o/Windows/ cpe:/a:famatech:radmin:3.0/ cpe:/o:microsoft:windows/a
match radmin m|^\x01\x00\x00\x00\x09\x00\x00\x10\x4f\x2f\x10\x00\x00\x04\x00\x00\x00\x1c| p/Famatech Radmin/ v/3.X/ i/Source IP blocked/ o/Windows/ cpe:/a:famatech:radmin:3/ cpe:/o:microsoft:windows/a

softmatch radmin m|^\x01\x00\x00\x00\x25.\x00..\x08.\x00..|s p/Famatech Radmin/ o/Windows/ cpe:/a:famatech:radmin/ cpe:/o:microsoft:windows/a

match srcds m|^\n\0\0\0\0\0\0\0\0\0\0\0\0\0$| p/srcds game server/

##############################NEXT PROBE##############################
Probe UDP Sqlping q|\x02|
rarity 6
ports 1434,19131-19133
match ms-sql-m m|^\x05..ServerName;([\w\-]+);InstanceName;[\w\-]+;IsClustered;\w{2,3};Version;([\d\.]+);np;.+;tcp;(\d{1,5});| p/Microsoft SQL Server/ v/$2/ i/ServerName: $1; TCPPort: $3/ o/Windows/ cpe:/a:microsoft:sql_server:$2/ cpe:/o:microsoft:windows/a
match ms-sql-m m|^\x05..ServerName;([\w\-]+);InstanceName;[\w\-]+;IsClustered;\w{2,3};Version;([\d\.]+);tcp;(\d{1,5});np;.+;$| p/Microsoft SQL Server/ v/$2/ i/ServerName: $1; TCPPort: $3/ o/Windows/ cpe:/a:microsoft:sql_server:$2/ cpe:/o:microsoft:windows/a
match ms-sql-m m|^\x05..ServerName;([\w\-]+);InstanceName;[\w\-]+;IsClustered;\w{2,3};Version;([\d\.]+);tcp;(\d{1,5});;| p/Microsoft SQL Server/ v/$2/ i/ServerName: $1; TCPPort: $3/ o/Windows/ cpe:/a:microsoft:sql_server:$2/ cpe:/o:microsoft:windows/a
match ms-sql-m m|^\x05..ServerName;([\w\-]+);InstanceName;[\w\-]+;IsClustered;\w{2,3};Version;([\d\.]+);;| p/Microsoft SQL Server/ v/$2/ i/ServerName: $1/ o/Windows/ cpe:/a:microsoft:sql_server:$2/ cpe:/o:microsoft:windows/a

# http://wiki.vg/Pocket_Minecraft_Protocol#ID_UNCONNECTED_PING_OPEN_CONNECTIONS_.280x1C.29
match minecraft-pe m|^\x1c................\0\xff\xff\0\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\x12\x34\x56\x78..MCCPP;Demo;([^;]+)|s p/Minecraft Pocket Edition server/ v/pre-0.11/ i/Server Name: $P(1)/ cpe:/a:mojang:minecraft_pocket_edition/
# Server Name field supports colors as \xc2\xa7N where N is a color code (0=black, 2=green, etc)
match minecraft-pe m|^\x1c................\0\xff\xff\0\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\x12\x34\x56\x78..MCPE;([^;]+);\d+;([^;]+);(\d+);(\d+)|s p/Minecraft Pocket Edition server/ v/$2/ i|Server Name: $P(1); $3/$4 players| cpe:/a:mojang:minecraft_pocket_edition:$2/
match minecraft-pe m|^\x1c................\0\xff\xff\0\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\x12\x34\x56\x78..MCPE;;\d+;([^;]+);(\d+);(\d+)|s p/Minecraft Pocket Edition server/ v/$1/ i|$2/$3 players| cpe:/a:mojang:minecraft_pocket_edition:$1/

softmatch minecraft-pe m|^\x1c................\0\xff\xff\0\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\x12\x34\x56\x78| p/Minecraft Pocket Edition server/

##############################NEXT PROBE##############################
Probe UDP NTPRequest q|\xe3\x00\x04\xfa\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc5\x4f\x23\x4b\x71\xb1\x52\xf3|
rarity 5
ports 123,5353,9100

match ca-mq m|^\xfa\xfe\0\x10\0\0\x01\0\0\0\0\0\0\0\0\0$| p/CA Message Queuing Server/ cpe:/a:ca:messaging/

match echo m|^\xe3\x00\x04\xfa\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc5\x4f\x23\x4b\x71\xb1\x52\xf3$|

match ntp m|^[\x24\x64\xa4]\x01..............................................$|s p/NTP/ v/v4/ i/primary server/
match ntp m|^[\x24\x64\xa4][\x02-\x0f]..............................................$|s p/NTP/ v/v4/ i/secondary server/
# Don't think this is valid, but we can uncomment if we get a submission:
#match ntp m|^[\x24\x64\xa4]\x10..............................................$|s p/NTP/ v/v4/ i/unsynchronized/
match ntp m|^\xe4[\0\x10]..............................................$|s p/NTP/ v/v4/ i/unsynchronized/
match ntp m|^\xe4[\x01]..............................................$|s p/NTP/ v/v4/ i/primary server; unsynchronized/
match ntp m|^\xe4[\x01-\x0f]..............................................$|s p/NTP/ v/v4/ i/secondary server; unsynchronized/

match ntp m|^\x1c[\x01-\x0f]..............................................$|s p/NTP/ v/v3/
# This is just unsynchronized NTP v3
match ntp m|^\xdc[\x00-\x0f]..............................................$|s p/Microsoft NTP/ o/Windows/ cpe:/o:microsoft:windows/a
match ntp m|^\x5c\x03..............................................$|s p/Microsoft Windows Server 2003 NTP/ v/v3/ o/Windows 2003/ cpe:/o:microsoft:windows_server_2003/a

# Solaris Internet Name Server (42/udp), see ien116.txt
match nameserver m|^help\r\n\r\n\0\0\0\0\x20CKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\0\0!\0\x01| p/Solaris Internet Name Server/ i/IEN 116/ o/Solaris/ cpe:/o:sun:sunos/a

match mdns m|^\0\0\x84\0\0\0\0\x05\0\0\0\0.Lexmark ([\x20-\x7f]+)\x0c_host-config\x04_udp\x05local\0|s p/Lexmark $1 printer mdns/ d/printer/ cpe:/h:lexmark:$1/a
match hbn3 m|^\0\0\x84\0\0\0\0\x05\0\0\0\0\x15S300-S400 Series \(32\).+ET(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})| p/Lexmark S300-S400 series HBN3/ i/MAC: $1:$2:$3:$4:$5:$6/ d/printer/
match hbn3 m|^\0\0\x84\0\0\0\0\x05\0\0\0\0\x15S300-S400 Series.+ET(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})| p/Lexmark S300-S400 Series HBN3/ i/MAC: $1:$2:$3:$4:$5:$6/ d/printer/

softmatch mdns m|^\0\0\x84\0\0\0\0\x05\0\0\0\0|

match sip m|^SIP/2\.0 200 OK\r\n(?:[^\r\n]+\r\n)*?Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, UPDATE, OPTIONS, MESSAGE, NOTIFY, INFO, REFER\r\n(?:[^\r\n]+\r\n)*?User-Agent: SightSpeedClient v\. ([\w._-]+)\r\n|s p/SightSpeedClient sipd/ v/$1/ i/AVM FRITZ!Box Fon WAP/

# These first two probes only serve to determine the NTP version
# Nessus uses.  The third will match even a newer one, but just show
# the NTP as 1.0.  So we give the highest rarity to these first two
# probes so they will usually only be used for port 1241.  But the
# third is left with a lower rarity to catch Nessus running on
# non-default ports.
#
# These probes have a high likelihood of triggering false positives because
# any service that echos your command back can match.  The docs on the
# the protocol make me think a ^ anchor can be added to the response so
# this should cut down on the the false positives. (Brandon)
#
# See ntp_white_paper_11.txt for more information on the Nessus protocol
#
##############################NEXT PROBE##############################
Probe TCP NessusTPv12 q|< NTP/1.2 >\n|
rarity 9
ports 1241
sslports 1241
match nessus m|^< NTP/1.2 >\n| p/Nessus Daemon/ i/NTP v1.2/ cpe:/a:tenable:nessus/

##############################NEXT PROBE##############################
Probe TCP NessusTPv11 q|< NTP/1.1 >\n|
rarity 9
ports 1241
sslports 1241
match nessus m|^< NTP/1.1 >\n| p/Nessus Daemon/ i/NTP v1.1/ cpe:/a:tenable:nessus/

##############################NEXT PROBE##############################
Probe TCP NessusTPv10 q|< NTP/1.0 >\n|
rarity 8
ports 1241
sslports 1241

match http-proxy m|^HTTP/1\.0 400 Bad Request\r\nServer: squid/([\w._+-]+)\r\n| p/Squid/ v/$1/ cpe:/a:squid-cache:squid:$1/

match nessus m|^< NTP/1.0 >\n| p/Nessus Daemon/ i/NTP v1.0/ cpe:/a:tenable:nessus/
match zabbix m|^NOT OK\n$| p/Zabbix Monitoring System/ cpe:/a:zabbix:zabbix/


##############################NEXT PROBE##############################
Probe UDP SNMPv1public q|0\x82\0/\x02\x01\0\x04\x06public\xa0\x82\0\x20\x02\x04\x4c\x33\xa7\x56\x02\x01\0\x02\x01\0\x30\x82\0\x10\x30\x82\0\x0c\x06\x08\x2b\x06\x01\x02\x01\x01\x05\0\x05\0|
rarity 4
ports 161

match bittorrent-udp-tracker m|^\x03\0\0\0lic\xa0Connection ID missmatch\.\0| p/opentracker UDP tracker/ cpe:/a:dirk_engling:opentracker/
match snmp m|^0.*\x02\x01\0\x04\x06public\xa2.*\x06\x08\+\x06\x01\x02\x01\x01\x05\0\x04[^\0]([^\0]+)|s p/SNMPv1 server/ i/public/ h/$1/

match snmp m|^0.*\x02\x01\0\x04\x06public\xa2|s p/SNMPv1 server/ i/public/

match echo m|^0\x82\0/\x02\x01\0\x04\x06public\xa0\x82\0\x20\x02\x04\x4c\x33\xa7\x56\x02\x01\0\x02\x01\0\x30\x82\0\x10\x30\x82\0\x0c\x06\x08\x2b\x06\x01\x02\x01\x01\x05\0\x05\0$|

##############################NEXT PROBE##############################
Probe UDP SNMPv3GetRequest q|\x30\x3a\x02\x01\x03\x30\x0f\x02\x02\x4a\x69\x02\x03\0\xff\xe3\x04\x01\x04\x02\x01\x03\x04\x10\x30\x0e\x04\0\x02\x01\0\x02\x01\0\x04\0\x04\0\x04\0\x30\x12\x04\0\x04\0\xa0\x0c\x02\x02\x37\xf0\x02\x01\0\x02\x01\0\x30\0|
rarity 4
ports 161

match echo m|^\x30\x3a\x02\x01\x03\x30\x0f\x02\x02\x4a\x69\x02\x03\0\xff\xe3\x04\x01\x04\x02\x01\x03\x04\x10\x30\x0e\x04\0\x02\x01\0\x02\x01\0\x04\0\x04\0\x04\0\x30\x12\x04\0\x04\0\xa0\x0c\x02\x02\x37\xf0\x02\x01\0\x02\x01\0\x30\0$|
# H.225 bandwidthReject
match H.323-gatekeeper-discovery m|^8\x02\x01\x10\0$| p/GNU Gatekeeper discovery/ cpe:/a:gnugk:gnu_gatekeeper/

# Enterprise numbers as used in SNMP engine IDs are here:
# http://www.iana.org/assignments/enterprise-numbers

# Reserved - SNMP Engine ID 0 \x00\x00
# Netgear GS748TS V5.0.0.23
match snmp m|^..\x02\x01\x030.\x02\x02Ji\x02.{3,4}\x04\x01.\x02\x01\x03\x04.{5,6}\0\x00\x00|s

# Cisco - SNMP Engine ID 9 (CiscoSystems) = \x00\x09
match snmp m|^..\x02\x01\x030.\x02\x02Ji\x02.{3,4}\x04\x01.\x02\x01\x03\x04.{5,6}\0\x00\x09|s p/Cisco SNMP service/

# Cisco - SNMP Engine ID 99 (SNMP Research) = \x00\x63
match snmp m|^..\x02\x01\x030.\x02\x02Ji\x02.{3,4}\x04\x01.\x02\x01\x03\x04.{5,6}\0\x00\x63|s p/Cisco SNMP service/

# Xerox - SNMP Engine ID 253 (Xerox) = \x00\xfd
match snmp m|^..\x02\x01\x030.\x02\x02Ji\x02.{3,4}\x04\x01.\x02\x01\x03\x04.{5,6}\0\x00\xfd|s p/Xerox SNMP service/

# Scientific Atlanta - SNMP Engine ID 1429 = \x05\x95
match snmp m|^..\x02\x01\x030.\x02\x02Ji\x02.{3,4}\x04\x01.\x02\x01\x03\x04.{5,6}\0\x05\x95|s p/Scientific Atlanta SNMP service/

# Brocade - SNMP Engine ID 1588 (Brocade Communications Systems, Inc.) = \x06\x34
match snmp m|^..\x02\x01\x030.\x02\x02Ji\x02.{3,4}\x04\x01.\x02\x01\x03\x04.{5,6}\0\x06\x34|s p/Brocade SNMP service/

# QLogic - SNMP Engine ID 1663 (Ancor Communications) = \x06\x7f
match snmp m|^..\x02\x01\x030.\x02\x02Ji\x02.{3,4}\x04\x01.\x02\x01\x03\x04.{5,6}\0\x06\x7f|s p/QLogic SNMP service/

# IBM - SNMP Engine ID 1104 (First Virtual Holdins Incorporated) = \x04\x50
match snmp m|^..\x02\x01\x030.\x02\x02Ji\x02.{3,4}\x04\x01.\x02\x01\x03\x04.{5,6}\0\x04\x50|s p/IBM SNMP service/

# Huawei - SNMP Engine ID 2011 (HUAWEI Technology Co.,Ltd) = \x07\xdb
match snmp m|^..\x02\x01\x030.\x02\x02Ji\x02.{3,4}\x04\x01.\x02\x01\x03\x04.{5,6}\0\x07\xdb|s p/Huawei SNMP service/

# Lexmark - SNMP Engine ID 2021 (Engine Enterprise ID: U.C. Davis, ECE Dept. Tom) = \x07\xe5
match snmp m|^..\x02\x01\x030.\x02\x02Ji\x02.{3,4}\x04\x01.\x02\x01\x03\x04.{5,6}\0\x07\xe5|s p/Lexmark SNMP service/

# Thomson Inc. - SNMP Engine ID 2863 (Thomson Inc.) = \x0b\x2f
match snmp m|^..\x02\x01\x030.\x02\x02Ji\x02.{3,4}\x04\x01.\x02\x01\x03\x04.{5,6}\0\x0b\x2f|s p/Thomson SNMP service/

# Blue Coat - SNMP Engine ID 3417 (CacheFlow Inc.) = \x0d\x59
match snmp m|^..\x02\x01\x030.\x02\x02Ji\x02.{3,4}\x04\x01.\x02\x01\x03\x04.{5,6}\0\x0d\x59|s p/Blue Coat SNMP service/

# Canon - SNMP Engine ID 4976 (Agent++) = \x13\x70
match snmp m|^..\x02\x01\x030.\x02\x02Ji\x02.{3,4}\x04\x01.\x02\x01\x03\x04.{5,6}\0\x13\x70|s p/Canon SNMP service/

# net-snmp (net-snmp.org) - SNMP Engine ID 8072 (net-snmp) = \x1f\x88
match snmp m|^..\x02\x01\x030.\x02\x02Ji\x02.{3,4}\x04\x01.\x02\x01\x03\x04.{5,6}\0\x1f\x88|s p/net-snmp/ cpe:/a:net-snmp:net-snmp/

# Fortigate-310B v4.0,build0324,110520 (MR2 Patch 7)
# Fortinet, Inc. - SNMP Engine ID 12356 = \x30\x44
match snmp m|^..\x02\x01\x030.\x02\x02Ji\x02.{3,4}\x04\x01.\x02\x01\x03\x04.{5,6}\x80\0\x30\x44|s p/Fortinet SNMP service/ d/firewall/

# Aruba Networks - SNMP Engine ID 14823 = \x39\xe7
match snmp m|^..\x02\x01\x030.\x02\x02Ji\x02.{3,4}\x04\x01.\x02\x01\x03\x04.{5,6}\0\x39\xe7|s p/Aruba Networks SNMP service/

# OpenBSD Project - SNMP Engine ID 30155 = \x75\xcb
match snmp m|^..\x02\x01\x030.\x02\x02Ji\x02.{3,4}\x04\x01.\x02\x01\x03\x04.{5,6}\0\x75\xcb|s p/OpenBSD SNMP service/

# Wireshark says <MISSING> for the SNMP Engine ID.
match snmp m|^..\x02\x01\x030.\x02\x02Ji\x02.{3,4}\x04\x01.\x02\x01\x03\x04.{5,6}\x01\0\x02\x03|s p/MikroTik router SNMP service/ d/router/

# Tandberg Video Conferencing equipment
match snmp m|^0\x82\0\x37\x02\x01\0\x04\x06public\xa2\x82\0\x28\x02.{41,43}\nSoftW:\x20([^\0\n]+)\nMCU:\x20([^\0\n]+)\n|s p/$2/ i/$1/

# Zebra GX430T label printer
match snmp m|^0\x82\0\x37\x02\x01\0\x04\x06public\xa2\x82\0\x28.{20}\x2b\x06\x01\x02\x01\x01\x05\0\x04\nZBR_SPICE0|s p/Zebra GX430T label printer SNMP service/ d/printer/ cpe:/h:zebra:gx430t/

# P-660HW-D1 from Zyxel
match snmp m|^0\x82\0\x3a\x02\x01\0\x04\x06public\xa2\x82\0\x2b.{20}\x06\x08\x2b\x06\x01\x02\x01\x01\x05\0\x04\x0bcfr25657985|s p/ZyXEL Prestige 660HW ADSL router/ d/broadband router/ cpe:/h:zyxel:prestige_660hw/

#Generic SNMPv3 matchline
softmatch snmp m|^..\x02\x01\x030.\x02\x02Ji\x02.{3,4}\x04\x01.\x02\x01\x03\x04|s p/SNMPv3 server/

##############################NEXT PROBE##############################
Probe TCP WMSRequest q|\x01\0\0\xfd\xce\xfa\x0b\xb0\xa0\0\0\0MMS\x14\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x12\0\0\0\x01\0\x03\0\xf0\xf0\xf0\xf0\x0b\0\x04\0\x1c\0\x03\0N\0S\0P\0l\0a\0y\0e\0r\0/\09\0.\00\0.\00\0.\02\09\08\00\0;\0 \0{\00\00\00\00\0A\0A\00\00\0-\00\0A\00\00\0-\00\00\0a\00\0-\0A\0A\00\0A\0-\00\00\00\00\0A\00\0A\0A\00\0A\0A\00\0}\0\0\0\xe0\x6d\xdf\x5f|
rarity 6
ports 1549,1755,5001,9090

match afp m|^\x01\x03\0N........\0\0\0\0........\x8f\xfb.([^\0\x01]+)[\0\x01].*\tMacintosh\x05\x06AFP3\.3\x06AFP3\.2\x06AFP3\.1\x06AFPX03\x06AFP2\.2\x05\tDHCAST128.*\x04([\w.]+)\x01.afpserver|s p/Apple AFP/ i/name: $1; protocol 3.3; Mac OS X 10.5/ o/Mac OS X/ h/$2/ cpe:/a:apple:afp_server/a cpe:/o:apple:mac_os_x/a
match afp m|^\x01\x03\0N........\0\0\0\0........\x8f\xfb.([^\0\x01]+)[\0\x01].*\nMacmini3,1\x04\x06AFP3\.3\x06AFP3\.2\x06AFP3\.1\x06AFPX03\x05\tDHCAST128.*\x04([\w.]+)\x01oafpserver|s p/Apple AFP/ i/name: $1; protocol 3.3; Mac OS X 10.6; Mac mini/ o/Mac OS X/ h/$2/ cpe:/a:apple:afp_server/a cpe:/o:apple:mac_os_x/a
# Flags \x9f\xfb.
match afp m|^\x01\x03\0\x4e........\0\0\0\0........\x9f\xfb.([^\0\x01]+)[\0\x01].*MacBookAir\d+,\d+\x05\x06AFP3\.4\x06AFP3\.3\x06AFP3\.2\x06AFP3\.1\x06AFPX03\x06\tDHCAST128\x04DHX2\x06Recon1\rClient Krb v2\x03GSS\x0fNo User Authent.*\x1b\$not_defined_in_RFC4178@please_ignore$|s p/Apple AFP/ i/name: $1; protocol 3.4; Mac OS X 10.6; MacBook Air/ o/Mac OS X/ cpe:/a:apple:afp_server/a cpe:/o:apple:mac_os_x/a
match afp m|^\x01\x03\0\x4e........\0\0\0\0........\x9f\xfb.([^\0\x01]+)[\0\x01].*MacBookPro\d+,\d+\x05\x06AFP3\.4\x06AFP3\.3\x06AFP3\.2\x06AFP3\.1\x06AFPX03\x06\tDHCAST128\x04DHX2\x06Recon1\rClient Krb v2\x03GSS\x0fNo User Authent.*\x1b\$not_defined_in_RFC4178@please_ignore$|s p/Apple AFP/ i/name: $1; protocol 3.4; Mac OS X 10.6; MacBook Pro/ o/Mac OS X/ cpe:/a:apple:afp_server/a cpe:/o:apple:mac_os_x/a

match dec-notes m|^\x08\0\0\0\x01\0\x02\x04\0\0\0\0$| p/DEC Notes/ o/VMS/

# http://www.corepointhealth.com/resource-center/hl7-resources/mlp-minimum-layer-protocol
match hl7-mlp m|^\x0b\x1c\r| p/HL7 Minimum Layer Protocol/

match jsonrpc m|^{\n   \"error\" : {\n      \"code\" : -32700,\n      \"message\" : \"Parse error\.\"\n   },\n   \"id\" : 0,\n   \"jsonrpc\" : \"([\w._-]+)\"\n}\n| p/XBMC JSON-RPC/ v/$1/ d/media device/ o/Linux/ cpe:/o:linux:linux_kernel/
match jsonrpc m|^{\"error\":{\"code\":-32700,\"message\":\"Parse error\.\"},\"id\":null,\"jsonrpc\":\"([\w._-]+)\"}| p/XBMC JSON-RPC/ v/$1/ d/media device/ o/Linux/ cpe:/o:linux:linux_kernel/

match shivahose m|^\x02\x06$| i/Shiva network modem access/
match slingbox m|^\x01\x01\0\xfd\xce\xfa\x0b\xb0\xa0\0\0\0\x0f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x12$| p/Slingbox streaming video/
softmatch slmp m|^\xd4\0MP\x04\0\0\0TNM\x0b\0P\0\0\0.......|s p/Mitsubishi PLC SLMP/ d/specialized/

# Also www.getmangos.com: Mangos Realms Server.
match warcraft m|^\0\0\x09$| p/World of Warcraft game server/

#WMS 4.1.0.3927
match wms m|^\x01\0\0.\xce\xfa\x0b\xb0.\0\0\0MMS .\0{7}.{9}\0\0\0\x01\0\x04\0\0\0\0\0\xf0\xf0\xf0\xf0\x0b\0\x04\0\x1c\0\x03\0\0\0\0\0\0\0\xf0\?\x01\0\0\0\x01\0\0\0\0\x80\0\0...\0.\0\0\0\0\0\0\0\0\0\0\0.\0\0\x00(\d)\0\.\x00(\d)\0\.\x00(\d)\0\.\x00(\d)\x00(\d)\x00(\d)\x00(\d)\0\0\0|s p/Microsoft Windows Media Services/ v/$1.$2.$3.$4$5$6$7/ o/Windows/ cpe:/a:microsoft:windows_media_services:$1.$2.$3.$4$5$6$7/a cpe:/o:microsoft:windows/a
match wms m|^\x01\0\0.\xce\xfa\x0b\xb0.\0\0\0MMS .\0{7}.{9}\0\0\0\x01\0\x04\0\0\0\0\0\xf0\xf0\xf0\xf0\x0b\0\x04\0\x1c\0\x03\0\0\0\0\0\0\0\xf0\?\x01\0\0\0\x01\0\0\0\0\x80\0\0...\0.\0\0\0\0\0\0\0\0\0\0\0.\0\0\x00(\d)\0\.\x00(\d)\x00(\d)\0\.\x00(\d)\x00(\d)\0\.\x00(\d)\x00(\d)\x00(\d)\x00(\d)\0\0\0|s p/Microsoft Windows Media Services/ v/$1.$2$3.$4$5.$6$7$8$9/ o/Windows/ cpe:/a:microsoft:windows_media_services:$1.$2$3.$4$5.$6$7$8$9/a cpe:/o:microsoft:windows/a

##############################NEXT PROBE##############################
Probe TCP oracle-tns q|\0Z\0\0\x01\0\0\0\x016\x01,\0\0\x08\0\x7F\xFF\x7F\x08\0\0\0\x01\0 \0:\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\04\xE6\0\0\0\x01\0\0\0\0\0\0\0\0(CONNECT_DATA=(COMMAND=version))|
rarity 7
ports 1035,1521,1522,1525,1526,1574,1748,1754,14238,20000

match http m|^HTTP/1\.0 400 Bad Request\r\nDate: .*\r\nServer: Boa/([\w._-]+)\r\nConnection: close\r\nContent-Type: text/html\r\n\r\n<HTML><HEAD><TITLE>400 Bad Request</TITLE></HEAD>\n<BODY><H1>400 Bad Request</H1>\nYour client has issued a malformed or illegal request\.\n</BODY></HTML>\n$| p/Boa httpd/ v/$1/ i/Prolink ADSL router/ d/broadband router/ cpe:/a:boa:boa:$1/

match iscsi m|^\x3f\x80\x04\0\0\0\x00\x30\0\0\0\0\0\0\0\0\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\xf7\0\0\0\0\0\0\0\0\0\0\0\0\0Z\0\0\x01\0\0\0\x016\x01\x2c\0\0\x08\0\x7f\xff\x7f\x08\0\0\0\x01\0\x20\0\x3a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x004\xe6\0\0$| p/iSCSI/
match iscsi m|^\x3f\x80\x04\0\0\0\x00\x30\0\0\0\0\0\0\0\0\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x00\x00\0\0\0\0\0\0\0\0\0\0\0\0\0Z\0\0\x01\0\0\0\x016\x01\x2c\0\0\x08\0\x7f\xff\x7f\x08\0\0\0\x01\0\x20\0\x3a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x004\xe6\0\0$| p/HP StorageWorks D2D backup system iSCSI/ d/storage-misc/

match palm-hotsync m|^\x01.\0\0\0\x14\x11\x01\0\0\0\0\0\0\0\x20\0\0\0\x06\x01\0..\0\0$|s p/Palm Pilot HotSync/

match oracle-tns m|^\0.\0\0[\x02\x04]\0\0\0.*TNSLSNR for ([-.+/ \w]{2,24}): Version ([-\d.]+) - Production|s p/Oracle TNS Listener/ v/$2/ i/for $1/
match dbsnmp m|^\0.\0\0\x02\0\0\0.*\(IAGENT = \(AGENT_VERSION = ([\d.]+)\)\(RPC_VERSION = ([\d.]+)\)\)|s p/Oracle Intelligent Agent/ v/$1/ i/RPC v$2/
match oracle m|^\0\x20\0\0\x02\0\0\0\x016\0\0\x08\0\x7f\xff\x01\0\0\0\0\x20|s p/Oracle Database/ cpe:/a:oracle:database_server/
match oracle m|^\+\0\0\0$| p/Oracle Database/ cpe:/a:oracle:database_server/
match oracle-tns m|^..\0\0\x04\0\0\0\"\0..\(DESCRIPTION=\(TMP=\)\(VSNNUM=\d+\)\(ERR=1189\)\(ERROR_STACK=\(ERROR=\(CODE=1189\)\(EMFI=4\)\)| p/Oracle TNS Listener/ i/unauthorized/
match oracle-tns m|^..\0\0\x04\0\0\0\"\0..\(DESCRIPTION=\(TMP=\)\(VSNNUM=\d+\)\(ERR=1194\)\(ERROR_STACK=\(ERROR=\(CODE=1194\)\(EMFI=4\)\)\)\)| p/Oracle TNS Listener/ i/insecure transport/
match oracle-tns m|^..\0\0\x04\0\0\0\"\0..\(DESCRIPTION=\(ERR=12504\)\)\0| p/Oracle TNS listener/ i/requires service name/
softmatch oracle-tns m|^\0.\0\0[\x02\x04]\0\0\0.*\([ABD-Z]|s p/Oracle TNS Listener/
match dbsnmp m|^\0,\0\0\x04\0\0\0\"\0\0 \(CONNECT_DATA=\(COMMAND=version\)\)| p/Oracle DBSNMP/

match hp-radia m|^\xff\xff$| p/HP Radia configuration server/

match winbox m|^.\x01\0.M2\x01\0\xff\x88\0\0\x02\0\xff\x88[\x01\x02]\0|s p/MikroTik WinBox/ cpe:/a:mikrotik:winbox/

# TrinityCore
match wow m|^\0\0\t.{32}\x01..{32}| p/World of Warcraft authserver/

##############################NEXT PROBE##############################
Probe UDP xdmcp q|\0\x01\0\x02\0\x01\0|
rarity 6
ports 177
match bacnet m|^\x81\n\0\t\x01\0`\x01\t$| p/BACnet building automation/
match xdmcp m|^\0\x01\0\x05..\0\0\0.(.+)\0.(.+)|s p/XDMCP/ i/willing; status: $2/ o/Unix/ h/$1/
match xdmcp m|^\0\x01\0\x06..\0.(.+)\0.(.+)|s p/XDMCP/ i/unwilling; status: $2/ o/Unix/ h/$1/
match tftp m|^\0\x05\0\x04Illegal TFTP operation\0| p/Windows 2003 Server Deployment Service/ o/Windows/ cpe:/o:microsoft:windows_server_2003/a
match tftp m|^\0\x05\0\x01File not found\.\0$| p/Enistic zone controller tftpd/
match tftp m|^\0\x05\0\x02No such file or directory\0| p/Windows 10 IoT tftpd/ o/Windows 10/ cpe:/o:microsoft:windows_10/a

softmatch coap m|^`E|

##############################NEXT PROBE##############################
# AFS version probing
Probe UDP AFSVersionRequest q|\0\0\x03\xe7\0\0\0\0\0\0\0\x65\0\0\0\0\0\0\0\0\x0d\x05\0\0\0\0\0\0\0\0\0\0|
rarity 5
ports 7001,1719
# OpenAFS
match afs m|^[\d\D]{28}\s*OpenAFS\s+([\d\.]+)\s+([^\0]+)\0| p/OpenAFS/ v/$1/ i/$2/ cpe:/a:openafs:openafs:$1/
match afs m|^[\d\D]{28}\s*OpenAFS\s+stable\s+([\d\.]+)\s+([^\0]+)\0| p/OpenAFS/ v/$1/ i/$2 stable/ cpe:/a:openafs:openafs:$1/
match afs m|^[\d\D]{28}\s*OpenAFS([\d\.]{3}[^\s\0]*)\s+([^\0]+)\0| p/OpenAFS/ v/$1/ i/$2/ cpe:/a:openafs:openafs:$1/
match afs m|^[\d\D]{28}\s*OpenAFS([\d\.]{3}[^\s\0]*)\0| p/OpenAFS/ v/$1/ cpe:/a:openafs:openafs:$1/
# Transarc AFS
match afs m|^[\d\D]{28}\s*Base\sconfiguration\safs([\d\.]+)\s+[^\s\0\;]+[\0\;]| p/Transarc AFS/ v/$1/
# Arla
match afs m|^[\d\D]{28}\s*arla-([\d\.]+)\0| p/Arla/ v/$1/

# OpenSSL 0.9.8g: openssl s_server -dtls1
# Alert (21), DTLS 1.0 (0xfeff)
match dtls m|^\x15\xfe\xff\0\0\0\0\0\0\0\0\0\x07\x02\x16\0\0\0\0\0$| p/OpenSSL DTLS 1.0/ cpe:/a:openssl:openssl/

match H.323-gatekeeper-discovery m|^\x04\x80\x03\xe7\0\x08\0D\0E\0U\0G\0K\0......$|s p/GNU Gatekeeper discovery/ cpe:/a:gnugk:gnu_gatekeeper/
match H.323-gatekeeper-discovery m|^\x04\x80\x03\xe7\0\x10\0D\0E\0U\0C\0O\0S\0R\0V\x003\0\n\x08\x01\x03\x06\xb7$| p/GNU Gatekeeper discovery/ v/2.3.2/ cpe:/a:gnugk:gnu_gatekeeper:2.3.2/
match H.323-gatekeeper-discovery m|^\x06\x80\x03\xe7\x06\0\x08\x91J\0\x05\x12\0G\0A\0T\0E\0K\0E\0E\0P\0E\0R\0......| p/Cisco Unified Communications Manager Gatekeeper RAS service/ cpe:/a:cisco:unified_communications_manager/

### do not slow down the scan

Probe TCP mydoom q|\x0d\x0d|
rarity 9
ports 706,3127-3198
match mydoom m|\x04\x5b\0\0\0\0\0\0| p/MyDoom virus backdoor/ v/v012604/

match silc m|^\0\x13\0\x01\r\0\x08\0\x01S\x96Rz\xc2\x02\0\xff\0.............4$|s p/SILCd conferencing service/

Probe TCP WWWOFFLEctrlstat q|WWWOFFLE STATUS\r\n|
rarity 9
ports 706,8081
match http-proxy-ctrl m|^WWWOFFLE Server Status\n-*\nVersion *: (\d.*)\n| p/WWWOFFLE proxy control/ v/$1/
match http-proxy-ctrl m|^WWWOFFLE Incorrect Password\n| p/WWWOFFLE proxy control/ i/Unauthorized/

match silc m|^\0\x13\0\x01\r\0\x08\0\x01S\x96Rz\xc2\x02\0\xff\0.............4$|s p/SILCd conferencing service/

##########################################################################################################
# Cross Match Verifier E TCP/IP fingerprint reader (http://www.crossmatch.com/products_singlescan_vE.html)
# The device runs an embedded Linux
#
Probe TCP Verifier q|Subscribe\n|
rarity 8
ports 1500
totalwaitms 11000
match crossmatchverifier m=^(?:Idle|Notify)\r\n$= p/Cross Match Verifier E fingerprint control/
match secure-socket m|^\0$| p/CA Secure Socket Adapter/

Probe TCP VerifierAdvanced q|Query\n|
rarity 8
ports 1501
match crossmatchverifier m|^Settings\r\nGain\x20(\d+)\r\nContrast\x20(\d+)\r\nTime\x20(\d+)\r\nIllumination\x20(\d+)\r\nProcessed\r\n$| p/Cross Match Verifier E fingerprint advanced control/ i/Gain: $1; Contrast: $2; Time: $3; Illumination: $4/




############ SOCKS PROBES ############

# These are some simple probes that query a SOCKS server as specified in the
# following RFCs/documents:
#
# SOCKS4.Protocol - SOCKS Protocol Version 4
# RFC 1928 - SOCKS Protocol Version 5
# RFC 1929 - Username/Password Authentication for SOCKS V5
# RFC 1961 - GSS-API Authentication Method for SOCKS Version 5


# The following probe is designed to check the status of a SOCKS5 implementation.
#
# It attempts to create a TCP connection to google.com:80 assuming the SOCKS server
# allows unauthenticated connections. The probe also tells the SOCKS server
# that we support all major types of authentication so we can determine which
# authentication method the server requires.
#
# We don't try to establish TCP port bindings on the SOCKS server and we don't
# try UDP connections though these could easily be added to new probes.

Probe TCP Socks5 q|\x05\x04\x00\x01\x02\x80\x05\x01\x00\x03\x0agoogle.com\x00\x50GET / HTTP/1.0\r\n\r\n|
rarity 8
ports 199,1080,1090,1095,1100,1105,1109,3128,6588,6660-6669,7777,8000,8008,8010,8080,8088,9481

match caldav m|^HTTP/1\.1 503 Service Unavailable\r\nServer: DavMail Gateway ([\w._-]+)\r\nDAV: 1, calendar-access, calendar-schedule, calendarserver-private-events, addressbook\r\n(?:[^\r\n]+\r\n)*?Content-Length: 83\r\n\r\nInvalid header: google\.com\0PGET / HTTP/1\.0, HTTPS connection to an HTTP listener \? |s p/DavMail CalDAV http gateway/ v/$1/ d/proxy server/

# http://freenetproject.org/fcp.html
match fcp m|^ProtocolError\nFatal=true\nCodeDescription=ClientHello must be first message\nCode=1\nEndMessage\n$| p/Freenet Client Protocol 2.0/

match http m|^HTTP/1\.1 400 ERROR\r\nConnection: keep-alive\r\nContent-Length: 17\r\nContent-Type: text/html\r\n\r\n\r\ninvalid requestHTTP/1\.1 400 ERROR\r\nConnection: keep-alive\r\nContent-Length: 17\r\nContent-Type: text/html\r\n\r\n\r\ninvalid request| p/uTorrent http admin/ v/3.0/ cpe:/a:utorrent:utorrent:3.0/
match http m|^HTTP/1\.0 500 Unexpected new line: \x05\x04\0\x01\x02\x3f\x05\x01\0\x03\[CRLF\]\.\r\nContent-Type: text/html\r\nContent-Length: 763\r\nConnection: Close\r\n\r\n<html>\r\n    <head>\r\n        <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\r\n        <title>Unexpected new line: \x05\x04\0\x01\x02\?\x05\x01\0\x03\[CRLF\]\.</title>\r\n    </head>\r\n    <body>\r\n        <h1>500 - Unexpected new line: \x05\x04\0\x01\x02\?\x05\x01\0\x03\[CRLF\]\.</h1>\r\n        <pre>System\.InvalidOperationException: Unexpected new line: \x05\x04\0\x01\x02\?\x05\x01\0\x03\[CRLF\]\.\n  at fp\.bb \(Char A_0\) \[0x00000\] in <filename unknown>:0 \n  at ha\.d \(\) \[0x00000\] in <filename unknown>:0 \n  at ha\.b \(System\.Byte\[\] A_0, Int32 A_1, Int32 A_2\) \[0x00000\] in <filename unknown>:0 \n| p/McMyAdmin Minecraft game admin console/ v/2.2.14/
match http m|^HTTP/1\.0 500 Unexpected new line: \x05\x04\0\x01\x02\xef\xbf\xbd\x05\x01\0\x03\[CRLF\]\.\r\nContent-Type: text/html\r\nContent-Length: 769\r\nConnection: Close\r\n\r\n<html>\r\n    <head>\r\n        <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\r\n        <title>Unexpected new line: \x05\x04\0\x01\x02\xef\xbf\xbd\x05\x01\0\x03\[CRLF\]\.</title>\r\n    </head>\r\n    <body>\r\n        <h1>500 - Unexpected new line: \x05\x04\0\x01\x02\xef\xbf\xbd\x05\x01\0\x03\[CRLF\]\.</h1>\r\n        <pre>System\.InvalidOperationException: Unexpected new line: \x05\x04\0\x01\x02\xef\xbf\xbd\x05\x01\0\x03\[CRLF\]\.\n  at fp\.ba \(Char A_0\) \[0x00000\] in <filename unknown>:0 \n| p/McMyAdmin Minecraft game admin console/ v/2.2.14/
match http m|^HTTP/1\.0 500 Unexpected new line: \x05\x04\0\x01\x02\xef\xbf\xbd\x05\x01\0\x03\[CRLF\]\.\r\nContent-Type: text/html\r\nContent-Length: 769\r\nConnection: Close\r\n\r\n<html>\r\n    <head>\r\n        <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\r\n        <title>Unexpected new line: \x05\x04\0\x01\x02\xef\xbf\xbd\x05\x01\0\x03\[CRLF\]\.</title>\r\n    </head>\r\n    <body>\r\n        <h1>500 - Unexpected new line: \x05\x04\0\x01\x02\xef\xbf\xbd\x05\x01\0\x03\[CRLF\]\.</h1>\r\n        <pre>System\.InvalidOperationException: Unexpected new line: \x05\x04\0\x01\x02\xef\xbf\xbd\x05\x01\0\x03\[CRLF\]\.\n  at f8\.be \(Char A_0\) \[0x00000\] in <filename unknown>:0 \n| p/McMyAdmin Minecraft game admin console/
match http m|^HTTP/1\.1 400 Page not found\r\nServer: IPCamera-Web\r\nDate: .* \d\d\d\d\r\nPragma: no-cache\r\nCache-Control: no-cache\r\nContent-Type: text/html\r\n\r\n<html><head><title>Document Error: Page not found</title></head>\r\n\t\t<body><h2>Access Error: Page not found</h2>\r\n\t\t<p>Bad request type</p></body></html>\r\n\r\n| p/Tenvis IP camera admin httpd/ d/webcam/
match http m|^\x05\x04\0\x01\x02\x80\x05\x01\0\x03\ngoogle\.com\0PGET / HTTP/1\.0\r\n\r\n\0HTTP/1\.0 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n| p/DeviceWISE Enterprise M2M httpd/ cpe:/a:telit:devicewise_m2m/

match http-proxy m|^<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2\.0//EN\">\n<HTML><HEAD><TITLE>Error</TITLE></HEAD>\n<BODY><h2>400 Can not find method and URI in request</h2>\r\nWhen trying to load <a href=\"smartcache://url-parse-error\">smartcache://url-parse-error</a>\.\n<hr noshade size=1>\r\nGenerated by smart\.cache \(<a href=\"http://scache\.sourceforge\.net/\">Smart Cache ([\w._-]+)</a>\)\r\n</BODY></HTML>\r\n$| p/Smart Cache http-proxy/ v/$1/

match socks5 m|^\x05\0\x05\0\0\x01.{6}HTTP|s i/No authentication required; connection ok/
match socks5 m|^\x05\0\x05\x01| i/No authentication; general failure/
match socks5 m|^\x05\0\x05\x02| i/No authentication; connection not allowed by ruleset/
match socks5 m|^\x05\0\x05\x03| i/No authentication; network unreachable/
match socks5 m|^\x05\0\x05\x04| i/No authentication; host unreachable/
match socks5 m|^\x05\0\x05\x05| i/No authentication; connection refused by destination host/
match socks5 m|^\x05\0\x05\x06| i/No authentication; TTL expired/
match socks5 m|^\x05\0\x05\x07| i|No authentication; command not supported/protocol error|
match socks5 m|^\x05\0\x05\x08| i/No authentication; address type not supported/

match socks5 m|^\x05\x01| i/GSSAPI authentication required/
match socks5 m|^\x05\x02| i|Username/password authentication required|

match socks5 m|^\x05\xFF$| i/No acceptable authentication method/

# When server doesn't buffer our probe properly. Seen on XMPP socks servers like Apple iChat, PyMSN, jabberd
match socks5 m|^\x05\0$| i/No authentication; connection failed/

softmatch socks5 m|^\x05|

# The following probe is designed to check the status of a SOCKS4 implementation.
#
# It attempts to create a TCP connection to 127.0.0.1:22. We supply a username root
# in the user id string field. We don't try to establish TCP port bindings on
# the SOCKS server though this could easily be added to a new probe.

Probe TCP Socks4 q|\x04\x01\x00\x16\x7f\x00\x00\x01root\x00|
rarity 8
ports 199,1080,1090,1095,1100,1105,1109,3128,6588,6660-6669,8000,8008,8080,8088

match socks4 m|^\0\x5a| i/Connection ok/
match socks4 m|^\0\x5b| i/Connection rejected or failed; connections possibly ok/
match socks4 m|^\0\x5c| i/Connection failed; ident required/
match socks4 m|^\0\x5d| i/Connection failed; username required/

match shell m|^\0Access is denied\n$| p/Windows Services for Unix rsh/ o/Windows/ cpe:/a:microsoft:windows_services_for_unix/ cpe:/o:microsoft:windows/a


##############################NEXT PROBE##############################
Probe TCP OfficeScan q|GET /?CAVIT HTTP/1.1\r\n\r\n|
rarity 9
ports 12345
fallback GetRequest
match http m|^HTTP/1.0 \d\d\d .*\r\nServer: OfficeScan Client| p/Trend Micro OfficeScan Antivirus http config/



##############################NEXT PROBE##############################
Probe TCP ms-sql-s q|\x12\x01\x00\x34\x00\x00\x00\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x0c\x03\x00\x28\x00\x04\xff\x08\x00\x01\x55\x00\x00\x00\x4d\x53\x53\x51\x4c\x53\x65\x72\x76\x65\x72\x00\x48\x0f\x00\x00|
rarity 7
ports 1433

match iscsi m|^\?\x80\x04\0\0\0\x000\0\0\0\0\0\0\0\0\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\x12\x01\x004\0\0\0\0\0\0\x15\0\x06\x01\0\x1b\0\x01\x02\0\x1c\0\x0c\x03\0\(\0\x04\xff\x08\0\x01U\0\0\0MSSQLServer\0$| p/iSCSI Target/ d/phone/ o/iOS/ cpe:/o:apple:iphone_os/

# Specific minor version lines. Check bytes 30–33:
# \x0a \x32 \x06\x40 → 10.50.1600
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x08\x00\x00\xc2| p/Microsoft SQL Server 2000/ v/8.00.194; RTM/ o/Windows/ cpe:/a:microsoft:sql_server:2000:gold/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x08\x00\x01\x37| p/Microsoft SQL Server 2000/ v/8.00.311; RTMa/ o/Windows/ cpe:/a:microsoft:sql_server:2000/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x08\x00\x01\x7e| p/Microsoft SQL Server 2000/ v/8.00.384; SP1/ o/Windows/ cpe:/a:microsoft:sql_server:2000:sp1/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x08\x00\x01\x80| p/Microsoft SQL Server 2000/ v/8.00.384; SP1/ o/Windows/ cpe:/a:microsoft:sql_server:2000:sp1/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x08\x00\x02\x14| p/Microsoft SQL Server 2000/ v/8.00.532; SP2/ o/Windows/ cpe:/a:microsoft:sql_server:2000:sp2/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x08\x00\x02\x16| p/Microsoft SQL Server 2000/ v/8.00.534; SP2/ o/Windows/ cpe:/a:microsoft:sql_server:2000:sp2/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x08\x00\x02\xf8| p/Microsoft SQL Server 2000/ v/8.00.760; SP3/ o/Windows/ cpe:/a:microsoft:sql_server:2000:sp3/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x08\x00\x02\xfe| p/Microsoft SQL Server 2000/ v/8.00.766; SP3a/ o/Windows/ cpe:/a:microsoft:sql_server:2000:sp3a/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x08\x00\x03\x32| p/Microsoft SQL Server 2000/ v/8.00.818; SP3+ MS03-031/ o/Windows/ cpe:/a:microsoft:sql_server:2000:sp3/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x08\x00\x07\xf7| p/Microsoft SQL Server 2000/ v/8.00.2039; SP4/ o/Windows/ cpe:/a:microsoft:sql_server:2000:sp4/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x08\x00\x08\x02| p/Microsoft SQL Server 2000/ v/8.00.2050; SP4+ MS08-040/ o/Windows/ cpe:/a:microsoft:sql_server:2000:sp4/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x08\x00\x08\x07| p/Microsoft SQL Server 2000/ v/8.00.2055; SP4+ MS09-004/ o/Windows/ cpe:/a:microsoft:sql_server:2000:sp4/ cpe:/o:microsoft:windows/

match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x09\x00\x05\x77| p/Microsoft SQL Server 2005/ v/9.00.1399; RTM/ o/Windows/ cpe:/a:microsoft:sql_server:2005:gold/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x09\x00\x05\x7e| p/Microsoft SQL Server 2005/ v/9.00.1406/ o/Windows/ cpe:/a:microsoft:sql_server:2005/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x09\x00\x07\xff| p/Microsoft SQL Server 2005/ v/9.00.2047; SP1/ o/Windows/ cpe:/a:microsoft:sql_server:2005:sp1/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x09\x00\x08\x7a| p/Microsoft SQL Server 2005/ v/9.00.2170; SP1+/ o/Windows/ cpe:/a:microsoft:sql_server:2005:sp1/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x09\x00\x0b\xe2| p/Microsoft SQL Server 2005/ v/9.00.3042; SP2/ o/Windows/ cpe:/a:microsoft:sql_server:2005:sp2/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x09\x00\x0b\xee| p/Microsoft SQL Server 2005/ v/9.00.3054; SP2+/ o/Windows/ cpe:/a:microsoft:sql_server:2005:sp2/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x09\x00\x0b\xfc| p/Microsoft SQL Server 2005/ v/9.00.3068; SP2+ MS08-040/ o/Windows/ cpe:/a:microsoft:sql_server:2005:sp2/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x09\x00\x0c\x01| p/Microsoft SQL Server 2005/ v/9.00.3073; SP2+ MS08-052/ o/Windows/ cpe:/a:microsoft:sql_server:2005:sp2/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x09\x00\x0c\x05| p/Microsoft SQL Server 2005/ v/9.00.3077; SP2+ MS09-004/ o/Windows/ cpe:/a:microsoft:sql_server:2005:sp2/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x09\x00\x0c\x08| p/Microsoft SQL Server 2005/ v/9.00.3080; SP2+ MS09-062/ o/Windows/ cpe:/a:microsoft:sql_server:2005:sp2/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x09\x00\x0f\xc3| p/Microsoft SQL Server 2005/ v/9.00.4035; SP3/ o/Windows/ cpe:/a:microsoft:sql_server:2005:sp3/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x09\x00\x0f\xd5| p/Microsoft SQL Server 2005/ v/9.00.4053; SP3+ MS09-062/ o/Windows/ cpe:/a:microsoft:sql_server:2005:sp3/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x09\x00\x10\x73| p/Microsoft SQL Server 2005/ v/9.00.4211; SP3+/ o/Windows/ cpe:/a:microsoft:sql_server:2005:sp3/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x09\x00\x13\x88| p/Microsoft SQL Server 2005/ v/9.00.5000; SP4/ o/Windows/ cpe:/a:microsoft:sql_server:2005:sp4/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x09\x00\x13\xcd| p/Microsoft SQL Server 2005/ v/9.00.5069; SP4+ MS12-070/ o/Windows/ cpe:/a:microsoft:sql_server:2005:sp4/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x09\x00\x14\xcc| p/Microsoft SQL Server 2005/ v/9.00.5324; SP4+ MS12-070 cumulative/ o/Windows/ cpe:/a:microsoft:sql_server:2005:sp4/ cpe:/o:microsoft:windows/
# Generic match for SQL Server 2005
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x09\x00(..)|s p/Microsoft SQL Server 2005/ v/9.00.$I(1,">")/ o/Windows/ cpe:/a:microsoft:sql_server:2005/ cpe:/o:microsoft:windows/

match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0a\x00\x04\x33| p/Microsoft SQL Server 2008/ v/10.00.1075; CTP/ o/Windows/ cpe:/a:microsoft:sql_server:2008/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0a\x00\x06\x40| p/Microsoft SQL Server 2008/ v/10.00.1600; RTM/ o/Windows/ cpe:/a:microsoft:sql_server:2008:gold/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0a\x00\x06\xfb| p/Microsoft SQL Server 2008/ v/10.00.1787; Cumulative Update 3/ o/Windows/ cpe:/a:microsoft:sql_server:2008/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0a\x00\x09\xe3| p/Microsoft SQL Server 2008/ v/10.00.2531; SP1/ o/Windows/ cpe:/a:microsoft:sql_server:2008:sp1/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0a\x00\x0a\xba| p/Microsoft SQL Server 2008/ v/10.00.2746; SP1+ Cumulative Update 5/ o/Windows/ cpe:/a:microsoft:sql_server:2008:sp1/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0a\x00\x0f\xa0| p/Microsoft SQL Server 2008/ v/10.00.4000; SP2/ o/Windows/ cpe:/a:microsoft:sql_server:2008:sp2/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0a\x00\x0f\xe0| p/Microsoft SQL Server 2008/ v/10.00.4064; SP2+ MS11-049/ o/Windows/ cpe:/a:microsoft:sql_server:2008/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0a\x00\x15\x7c| p/Microsoft SQL Server 2008/ v/10.00.5500; SP3/ o/Windows/ cpe:/a:microsoft:sql_server:2008:sp3/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0a\x00\x15\x88| p/Microsoft SQL Server 2008/ v/10.00.5512; SP3+ MS12-070/ o/Windows/ cpe:/a:microsoft:sql_server:2008:sp3/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0a\x00\x15\xa2| p/Microsoft SQL Server 2008/ v/10.00.5538; SP3+ MS15-058/ o/Windows/ cpe:/a:microsoft:sql_server:2008:sp3/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0a\x00\x17\x70| p/Microsoft SQL Server 2008/ v/10.00.6000; SP4/ o/Windows/ cpe:/a:microsoft:sql_server:2008:sp4/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0a\x00\x18\x61| p/Microsoft SQL Server 2008/ v/10.00.6241; SP4+ MS15-058/ o/Windows/ cpe:/a:microsoft:sql_server:2008:sp4/ cpe:/o:microsoft:windows/
# Generic match for SQL Server 2008
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0a\x00(..)|s p/Microsoft SQL Server 2008/ v/10.00.$I(1,">")/ o/Windows/ cpe:/a:microsoft:sql_server:2008/ cpe:/o:microsoft:windows/

match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0a\x32\x06\x40| p/Microsoft SQL Server 2008 R2/ v/10.50.1600; RTM/ o/Windows/ cpe:/a:microsoft:sql_server:2008_r2:gold/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0a\x32\x06\x51| p/Microsoft SQL Server 2008 R2/ v/10.50.1617; RTM+ MS11-049/ o/Windows/ cpe:/a:microsoft:sql_server:2008_r2/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0a\x32\x09\xc4| p/Microsoft SQL Server 2008 R2/ v/10.50.2500; SP1/ o/Windows/ cpe:/a:microsoft:sql_server:2008_r2:sp1/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0a\x32\x09\xf6| p/Microsoft SQL Server 2008 R2/ v/10.50.2550; SP1+ MS12-070/ o/Windows/ cpe:/a:microsoft:sql_server:2008_r2:sp1/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0a\x32\x0f\xa0| p/Microsoft SQL Server 2008 R2/ v/10.50.4000; SP2/ o/Windows/ cpe:/a:microsoft:sql_server:2008_r2:sp2/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0a\x32\x10\xb4| p/Microsoft SQL Server 2008 R2/ v/10.50.4276; SP2+ Cumulative Update 5/ o/Windows/ cpe:/a:microsoft:sql_server:2008_r2:sp2/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0a\x32\x17\x70| p/Microsoft SQL Server 2008 R2/ v/10.50.6000; SP3/ o/Windows/ cpe:/a:microsoft:sql_server:2008_r2:sp3/ cpe:/o:microsoft:windows/
# Generic match for SQL Server 2008 R2
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0a\x32(..)|s p/Microsoft SQL Server 2008 R2/ v/10.50.$I(1,">")/ o/Windows/ cpe:/a:microsoft:sql_server:2008_r2/ cpe:/o:microsoft:windows/

match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0b\x00\x08\x34| p/Microsoft SQL Server 2012/ v/11.00.2100; RTM/ o/Windows/ cpe:/a:microsoft:sql_server:2012:gold/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0b\x00\x0b\xb8| p/Microsoft SQL Server 2012/ v/11.00.3000; SP1/ o/Windows/ cpe:/a:microsoft:sql_server:2012:sp1/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0b\x00\x0c\x38| p/Microsoft SQL Server 2012/ v/11.00.3128; SP1+/ o/Windows/ cpe:/a:microsoft:sql_server:2012:sp1/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0b\x00\x13\xc2| p/Microsoft SQL Server 2012/ v/11.00.5058; SP2/ o/Windows/ cpe:/a:microsoft:sql_server:2012:sp2/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0b\x00\x17\x84| p/Microsoft SQL Server 2012/ v/11.00.6020; SP3/ o/Windows/ cpe:/a:microsoft:sql_server:2012:sp3/ cpe:/o:microsoft:windows/
# Generic match for SQL Server 2012
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0b\x00(..)| p/Microsoft SQL Server 2012/ v/11.00.$I(1,">")/ o/Windows/ cpe:/a:microsoft:sql_server:2012/ cpe:/o:microsoft:windows/

match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0c\x00\x07\xd0| p/Microsoft SQL Server 2014/ v/12.00.2000/ o/Windows/ cpe:/a:microsoft:sql_server:2014/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0c\x00\x10\x04| p/Microsoft SQL Server 2014/ v/12.00.4100; SP1/ o/Windows/ cpe:/a:microsoft:sql_server:2014:sp1/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0c\x00\x10\x75| p/Microsoft SQL Server 2014/ v/12.00.4213; SP1+ MS15-058/ o/Windows/ cpe:/a:microsoft:sql_server:2014:sp1/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0c\x00\x13\x88| p/Microsoft SQL Server 2014/ v/12.00.5000; SP2/ o/Windows/ cpe:/a:microsoft:sql_server:2014:sp2/ cpe:/o:microsoft:windows/
# Generic match for SQL Server 2014
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0c\x00(..)|s p/Microsoft SQL Server 2014/ v/12.00.$I(1,">")/ o/Windows/ cpe:/a:microsoft:sql_server:2014/ cpe:/o:microsoft:windows/

# Generic match for SQL Server 2016
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0d\x00\x06\x41| p/Microsoft SQL Server 2016/ v/13.00.1601/ o/Windows/ cpe:/a:microsoft:sql_server:2016/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0d\x00\x0f\xa1| p/Microsoft SQL Server 2016/ v/13.00.4001; SP1/ o/Windows/ cpe:/a:microsoft:sql_server:2016:sp1/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0d\x00\x13\xa2| p/Microsoft SQL Server 2016/ v/13.00.5026; SP2/ o/Windows/ cpe:/a:microsoft:sql_server:2016:sp2/ cpe:/o:microsoft:windows/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0d\x00(..)| p/Microsoft SQL Server 2016/ v/13.00.$I(1,">")/ o/Windows/ cpe:/a:microsoft:sql_server:2016/ cpe:/o:microsoft:windows/

# No longer Windows-only
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0e\x00\x03\xe8|s p/Microsoft SQL Server 2017/ v/14.00.1000/ cpe:/a:microsoft:sql_server:2017/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0e\x00\x0c\xb9|s p/Microsoft SQL Server 2017/ v/14.00.3257; CU18/ cpe:/a:microsoft:sql_server:2017:cu18/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0e\x00(..)|s p/Microsoft SQL Server 2017/ v/14.00.$I(1,">")/ cpe:/a:microsoft:sql_server:2017/
match ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x01\x03\x00\x1d\x00\x00\xff\x0f\x00(..)|s p/Microsoft SQL Server 2019/ v/15.00.$I(1,">")/ cpe:/a:microsoft:sql_server:2019/


softmatch ms-sql-s m|^\x04\x01\x00\x25\x00\x00\x01| p/Microsoft SQL Server/ o/Windows/ cpe:/a:microsoft:sql_server/ cpe:/o:microsoft:windows/

match ms-sql-s m|^\x04\x01\x00\x2b\x00\x00\x00\x00\x00\x00\x1a\x00\x06\x01\x00\x20\x00\x01\x02\x00\x21\x00\x01\x03\x00\x22\x00\x00\x04\x00\x22\x00\x01\xff\x08\x00\x02\x10\x00\x00\x02\x00\x00| p/Dionaea honeypot MS-SQL server/


##############################NEXT PROBE##############################
# ActiveMQ's STOMP (Streaming Text Orientated Messaging Protocol)
Probe TCP HELP4STOMP q|HELP\n\n\0|
rarity 8
ports 6163,61613
#### Match versions based on line numbers in error messages.
# git clone https://github.com/apache/activemq.git
# cd activemq/activemq-stomp/src/main/java/org/apache/activemq/transport/stomp/
# git tag -l | while read tag; do git checkout $tag -- ProtocolConverter.java; echo $tag:$(grep -n "Unknown STOMP action" ProtocolConverter.java) >> lines.txt; done

match stomp m|^ERROR\ncontent-type:text/plain\nmessage:Unknown STOMP action: HELP\n\norg\.apache\.activemq\.transport\.stomp\.ProtocolException: Unknown STOMP action: HELP\r\n\tat org\.apache\.activemq\.transport\.stomp\.ProtocolConverter\.onStompCommand\(ProtocolConverter\.java:270\)|s p/Apache ActiveMQ/ v/5.6.0 - 5.7.0 or 5.15.5 - 5.15.9/ cpe:/a:apache:activemq:5/
match stomp m|^ERROR\ncontent-type:text/plain\nmessage:Unknown STOMP action: HELP\n\norg\.apache\.activemq\.transport\.stomp\.ProtocolException: Unknown STOMP action: HELP\r\n\tat org\.apache\.activemq\.transport\.stomp\.ProtocolConverter\.onStompCommand\(ProtocolConverter\.java:254\)|s p/Apache ActiveMQ/ v/5.8.0/ cpe:/a:apache:activemq:5.8.0/
match stomp m|^ERROR\ncontent-type:text/plain\nmessage:Unknown STOMP action: HELP\n\norg\.apache\.activemq\.transport\.stomp\.ProtocolException: Unknown STOMP action: HELP\r\n\tat org\.apache\.activemq\.transport\.stomp\.ProtocolConverter\.onStompCommand\(ProtocolConverter\.java:241\)|s p/Apache ActiveMQ/ v/5.9.0 - 5.9.1/ cpe:/a:apache:activemq:5.9/
match stomp m|^ERROR\ncontent-type:text/plain\nmessage:Unknown STOMP action: HELP\n\norg\.apache\.activemq\.transport\.stomp\.ProtocolException: Unknown STOMP action: HELP\r\n\tat org\.apache\.activemq\.transport\.stomp\.ProtocolConverter\.onStompCommand\(ProtocolConverter\.java:267\)|s p/Apache ActiveMQ/ v/5.10.0/ cpe:/a:apache:activemq:5.10.0/
match stomp m|^ERROR\ncontent-type:text/plain\nmessage:Unknown STOMP action: HELP\n\norg\.apache\.activemq\.transport\.stomp\.ProtocolException: Unknown STOMP action: HELP\r\n\tat org\.apache\.activemq\.transport\.stomp\.ProtocolConverter\.onStompCommand\(ProtocolConverter\.java:266\)|s p/Apache ActiveMQ/ v/5.10.1 - 5.11.1/ cpe:/a:apache:activemq:5/
match stomp m|^ERROR\ncontent-type:text/plain\nmessage:Unknown STOMP action: HELP\n\norg\.apache\.activemq\.transport\.stomp\.ProtocolException: Unknown STOMP action: HELP\r\n\tat org\.apache\.activemq\.transport\.stomp\.ProtocolConverter\.onStompCommand\(ProtocolConverter\.java:268\)|s p/Apache ActiveMQ/ v/5.11.2 - 5.11.4/ cpe:/a:apache:activemq:5.11/
match stomp m|^ERROR\ncontent-type:text/plain\nmessage:Unknown STOMP action: HELP\n\norg\.apache\.activemq\.transport\.stomp\.ProtocolException: Unknown STOMP action: HELP\r\n\tat org\.apache\.activemq\.transport\.stomp\.ProtocolConverter\.onStompCommand\(ProtocolConverter\.java:269\)|s p/Apache ActiveMQ/ v/5.12.0 - 5.15.4/ cpe:/a:apache:activemq:5/
match stomp m|^ERROR\ncontent-type:text/plain\nmessage:Unknown STOMP action: HELP\n\norg\.apache\.activemq\.transport\.stomp\.ProtocolException: Unknown STOMP action: HELP\r\n\tat org\.apache\.activemq\.transport\.stomp\.ProtocolConverter\.onStompCommand\(ProtocolConverter\.java:270\)|s p/Apache ActiveMQ/ v/5.15.5 - 5.15.9/ cpe:/a:apache:activemq:5.15/
match stomp m|^ERROR\ncontent-type:text/plain\nmessage:Unknown STOMP action: HELP\n\norg\.apache\.activemq\.transport\.stomp\.ProtocolException: Unknown STOMP action: HELP\r\n\tat org\.apache\.activemq\.transport\.stomp\.ProtocolConverter\.onStompCommand\(ProtocolConverter\.java:244\)|s p/Apache ActiveMQ/ v/5.15.10 - 5.15.12/ cpe:/a:apache:activemq:5.15/
# Possibly also 4.0 - 5.7.0
match stomp m|^ERROR\ncontent-type:text/plain\nmessage:Unknown STOMP action: HELP\n\norg\.apache\.activemq\.transport\.stomp\.ProtocolException: Unknown STOMP action: HELP\r\n\tat org\.apache\.activemq\.transport\.stomp\.ProtocolConverter\.onStompCommand\(ProtocolConverter\.java:258\)|s p/Apache ActiveMQ/ v/5.15.13 - 5.17.2/ cpe:/a:apache:activemq:5/

# catch-all softmatch. Add submitted fingerprints above using the line number as above.
softmatch stomp m|^ERROR\n(?:[^\n]+\n)?message:Unknown STOMP action:.+ org\.apache\.activemq\.|s p/Apache ActiveMQ/ cpe:/a:apache:activemq/
match stomp m|^ERROR\nmessage:Illegal command\ncontent-type:text/plain\nversion:([\d.,]+)\ncontent-length:\d+\n\nYou must log in using CONNECT first\0\n| p/RabbitMQ/ i/versions: $1/ cpe:/a:pivotal_software:rabbitmq/

# The following line matches IPDS (IBM's Intelligent Printer Data Stream) on port 9600
# match ipds m|^%%\[ Error: syntaxerror; Offending Command:|s p/IPDS Service/ d/printer/

##############################NEXT PROBE##############################
# Sends string 'stats' and matches memcached and zookeeper
Probe TCP Memcache q|stats\r\n|
rarity 8
ports 2181,11211
match memcached m|^STAT pid \d+\r\nSTAT uptime (\d+)\r\nSTAT time \d+\r\nSTAT version ([.\d]+)\r\n|s p/Memcached/ v/$2/ i/uptime $1 seconds/ cpe:/a:memcached:memcached:$2/
match memcached m|^STAT pid \d+\r\nSTAT uptime (\d+)\r\nSTAT time \d+\r\nSTAT version ([.\d]+) \(?Ubuntu\)?\r\n|s p/Memcached/ v/$2/ i/uptime $1 seconds; Ubuntu/ o/Linux/ cpe:/a:memcached:memcached:$2/ cpe:/o:canonical:ubuntu_linux/ cpe:/o:linux:linux_kernel/a
match zookeeper m|^Zookeeper version: ([\w.-]+), built on ([\w./]+)| p/Zookeeper/ v/$1/ i/Built on $2/ cpe:/a:zookeeper:zookeeper:$1/

softmatch memcached m|^STAT pid \d+\r\n|

##############################NEXT PROBE##############################
# Beast Trojan v2
Probe TCP beast2 q|666|
rarity 9
ports 666,6666
match backdoor m|^666(\d+)\xff(\d+)\xff(\d+)\xff$| p/Beast Trojan/ v/version 2/ i/**BACKDOOR**; No password; New server port: $1; New client ports: $2, $3/ o/Windows/ cpe:/o:microsoft:windows/a


##############################NEXT PROBE##############################
Probe TCP firebird q|\0\0\0\x01\0\0\0\x13\0\0\0\x02\0\0\0\x24\0\0\0\x0bservice_mgr\0\0\0\0\x02\0\0\0\x13\x01\x08scanner \x04\x05nmap \x06\0\0\0\0\0\x08\0\0\0\x01\0\0\0\x02\0\0\0\x03\0\0\0\x02\0\0\0\x0a\0\0\0\x01\0\0\0\x02\0\0\0\x03\0\0\0\x04|
rarity 8
ports 3050

match firebird m|^\0\0\0\x03\0\0\0\x0a\0\0\0\x01| p/Firebird RDBMS/ v/Protocol version 10/ cpe:/a:firebirdsql:firebird/
softmatch firebird m|^\0\0\0\x03\0\0\0.\0\0\0.|s p/Firebird RDBMS/ cpe:/a:firebirdsql:firebird/

match cisco-smartinstall m|^\0\0\0\x04\0\0\0\0\0\0\0\x04\0\0\0\x04\0\0\0\x01| p/Cisco Switch Smart Install/ d/switch/ o/IOS/ cpe:/o:cisco:ios/a


# Following 4 probes created by Tom Sellers:
##############################NEXT PROBE##############################
Probe TCP ibm-db2-das q|\0\0\0\0DB2DAS      \x01\x04\0\0\0\x10\x39\x7a\0\x01\0\0\0\0\0\0\0\0\0\0\x01\x0c\0\0\0\0\0\0\x0c\0\0\0\x0c\0\0\0\x04|
rarity 8
ports 523,9930-9934,9090,50000
match ibm-db2 m|^\0\0\0\0DB2DAS\x20\x20\x20\x20\x20\x20.{28}\x9b\0\0\0\x0c\0\0\0Z\0\0\0\x10\0\0\0\x0c\0\0\0L\0\0\0\0\0\0\0\$\0\0\0\x0c\0\0\0O\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\0\0\0\x0c\0\0\0L\0\0\0\0\0\0\0\x19\0\0\0\x0c\0\0\0\x04\0\0\x04\xb8SQL0(\d)(\d\d)(\d+)|s p/IBM DB2 Database Server/ v/$1.$2.$3/ cpe:/a:ibm:db2:$1.$2.$3/

# 8001 = version, 0003 = EXCEPTION
match thrift-binary m|^\x80\x01\0\x03\0\0\0\0B2DA\x0b\0\x01\0\0\0\0\x08\0\x02\0\0\0\x02\0| p/Apache Thrift TBinary/

# If this is too general, switch to the more specific match here:
#match softether-rpc m|^@{1000}@*$| p/SoftEther VPN client config port/
match softether-rpc m|^@+$| p/SoftEther VPN client config port/

##############################NEXT PROBE##############################
Probe TCP ibm-db2 q|\x01\xc2\0\0\0\x04\0\0\xb6\x01\0\0SQLDB2RA\0\x01\0\0\x04\x01\x01\0\x05\0\x1d\0\x88\0\0\0\x01\0\0\x80\0\0\0\x01\x09\0\0\0\x01\0\0\x40\0\0\0\x01\x09\0\0\0\x01\0\0\x40\0\0\0\x01\x08\0\0\0\x04\0\0\x40\0\0\0\x01\x04\0\0\0\x01\0\0\x40\0\0\0\x40\x04\0\0\0\x04\0\0\x40\0\0\0\x01\x04\0\0\0\x04\0\0\x40\0\0\0\x01\x04\0\0\0\x04\0\0\x40\0\0\0\x01\x04\0\0\0\x02\0\0\x40\0\0\0\x01\x04\0\0\0\x04\0\0\x40\0\0\0\x01\0\0\0\0\x01\0\0\x40\0\0\0\0\x04\0\0\0\x04\0\0\x80\0\0\0\x01\x04\0\0\0\x04\0\0\x80\0\0\0\x01\x04\0\0\0\x03\0\0\x80\0\0\0\x01\x04\0\0\0\x04\0\0\x80\0\0\0\x01\x08\0\0\0\x01\0\0\x40\0\0\0\x01\x04\0\0\0\x04\0\0\x40\0\0\0\x01\x10\0\0\0\x01\0\0\x80\0\0\0\x01\x10\0\0\0\x01\0\0\x80\0\0\0\x01\x04\0\0\0\x04\0\0\x40\0\0\0\x01\x09\0\0\0\x01\0\0\x40\0\0\0\x01\x09\0\0\0\x01\0\0\x80\0\0\0\x01\x04\0\0\0\x03\0\0\x80\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\x01\x04\0\0\x01\0\0\x80\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\x40\0\0\0\x01\0\0\0\0\x01\0\0\x40\0\0\0\0\x20\x20\x20\x20\x20\x20\x20\x20\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xe4\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x7f|
rarity 8
ports 523,50000-50025,60000-60025

match hbase m|FatalConnectionException\x12.Expected\x20HEADER=HBas| p/Apache HBase/ cpe:/a:apache:hbase/
match ibm-db2 m|(?<=.)DB2/([^\0]+)\0\0\0\0\0\0\0\0.{1,4}\0\0\0\0\0\0\0SQL0(\d)(\d\d)(\d+)|s p/IBM DB2 Database Server/ v/$2.$3.$4/ o/$1/ cpe:/a:ibm:db2:$2.$3.$4/
match ibm-db2 m|^\0\xa9\x10..\x01\0\0SQLDB2RA\x01\0\x05\0.{10,13}SQLCA|s p/IBM DB2 Database Server/ cpe:/a:ibm:db2/
match ibm-db2 m|^\0\xa9\x10..\x01\x0e\x10SQLDB2RA\x01\0\x05\0.{10,13}SQLCA|s p/IBM DB2 Database Server/ cpe:/a:ibm:db2/

##############################NEXT PROBE##############################
Probe TCP pervasive-relational q|Client string for PARC version 1 Wire Encryption version 1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0|
rarity 8
ports 1583,3351

match psql m|^\0{255}| p/Pervasive.SQL Server - Relational Engine/
match psql m|^\0Server string for PARC version 1 Wire Encryption version 1\0| p/Pervasive.SQL Server - Relational Engine/ i/encrypted/


##############################NEXT PROBE##############################
Probe TCP pervasive-btrieve q|\x3c\0\x4b\0\0\0\x20\0\0\0\0\0\0\0\0\0\xff\xff\xff\xff\0\0\x0a\x04\xa0\xbe\x53\x03\x55\x52\0\0\x3c\0\0\0\x05\0\0\0\0\0\0\0\0\0\x1a\0\x3c\0\0\0\0\0\x0a\0\0\0\0\0|
ports 1583,3351
rarity 8
match psql-btrieve m|^A\0K\0\0\0....\0\0\0\0\0\0\xff\xff\xff\xff\0\0\n\x04\xa0|s p/Pervasive.SQL Server - Btrieve Engine/

# Following probe created by Patrik Karlsson:
##############################NEXT PROBE##############################
Probe UDP ibm-db2-das-udp q|DB2GETADDR\0SQL08010\0|
rarity 8
ports 523

match ibm-db2 m|^DB2RETADDR\0SQL0(\d)(\d\d)(\d+)\0([^\0]+)\0|s p/IBM DB2 Database Server/ v/$1.$2.$3/ i/Hostname: $4/ cpe:/a:ibm:db2:$1.$2.$3/

##############################NEXT PROBE##############################
# Apache JServe Protocol (ajp) v1.3 Ping request
Probe TCP ajp q|\x12\x34\x00\x01\x0a|
rarity 8
ports 8008,8009

# AJP 1.3 Ping response
match ajp13 m|^\x41\x42\x00\x01\x09$| p/Apache Jserv/ i/Protocol v1.3/


##############################NEXT PROBE##############################
# DNS-based service discovery (DNS-SD). Asks for all services on the host.
# http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt, section 9.
Probe UDP DNS-SD q|\0\0\0\0\0\x01\0\0\0\0\0\0\x09_services\x07_dns-sd\x04_udp\x05local\0\0\x0c\0\x01|
rarity 4
ports 5353

# mDNSResponder-176.3
# Avahi under Ubuntu
match mdns m|^\0\0\x84\0\0\x01..\0\0\0\0\x09_services\x07_dns-sd\x04_udp\x05local\0\0\x0c\0\x01|s p/DNS-based service discovery/
match hbn3 m|^\0\0\x84\0\0\0\0\x01\0\0\0\0.Lexmark (\w+)\x0c_host-config\x04_udp\x05local\0\0\x10\0\x01\0\0\0<\x01\x19.IPADDRESS [\d.]+.IPNETMASK [\d.]+.IPGATEWAY [\d.]+.IPNAME \"([\w._-]+)\"\x15MACLAA \"000000000000\"\x15MACUAA \"([0-9A-F]{12})\"|s p/Lexmark hbn3 (DNS-SD-like configuration)/ i/Lexmark $1 printer; MAC $3/ d/printer/ h/$2/ cpe:/h:lexmark:$1/a

match isakmp m|^\0\0\0\0\0\x01\0\0\0\0\0\0\t_servic\x0b\x10\x05\0\0\0\0\0\0\0\0\(\0\0\0\x0c\0\0\0\x01\x01\0\0\x05| p/Openswan ISAKMP/ cpe:/a:openswan:openswan/
match isakmp m|^\0\0\0\0\0\x01\0\0\0\0\0\0\t_servic\) % \0\0\0\0\0\0\0\$\0\0\0\x08\0\0\0\x05| p/StrongSwan ISAKMP/ cpe:/a:strongswan:strongswan/

##############################NEXT PROBE##############################
# HP Printer Job Language, supported on most PostScript printers.
# http://h20000.www2.hp.com/bc/docs/support/SupportManual/bpl13208/bpl13208.pdf
# http://h20000.www2.hp.com/bc/docs/support/SupportManual/bpl13207/bpl13207.pdf
Probe TCP hp-pjl q|\x1b%-12345X@PJL INFO ID\x0d\x0a\x1b%-12345X\x0d\x0a|
ports 9100-9107
rarity 9

# Most printers respond with the printer version in quotes
match hp-pjl m|^@PJL INFO ID\r?\n\"([^"]+)\"\r?\n| p/$1/ d/printer/
# Some respond without the quotes
match hp-pjl m|^@PJL INFO ID ?\r?\n([\w\d _-]+)\r?\n| p/$1/ d/printer/
# Some respond with blank info
match hp-pjl m|@PJL\x20INFO\x20ID\r?\n\r?\n| d/printer/

# COMMENTING THIS SOFTMATCH OUT. It is meant to stop causing a bunch
# of extra printing of probes against PJL ports (those port numbers
# are excluded by default anyway), but it caused problems described in
# this thread: http://seclists.org/nmap-dev/2010/q2/753
# But it might be useful for people doing pjl testing specifically.
# softmatch hp-pjl m|^| i/hp-pjl probe got something back/

##############################NEXT PROBE##############################
# Citrix MetaFrame application discovery service
# http://sh0dan.org/oldfiles/hackingcitrix.html
Probe UDP Citrix q|\x1e\0\x01\x30\x02\xfd\xa8\xe3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0|
rarity 5
ports 1604

# Citrix MetaFrame
match icabrowser m|^\x30\0\x02\x31\x02\xfd\xa8\xe3\x02\0\x06\x44| p/Citrix MetaFrame/ cpe:/a:citrix:metaframe/

match ntp m|^\x1e\xc0\x010\x02\0\xa8\xe3\0\0\0\0$| p/Digium Switchvox PBX ntpd/ d/PBX/

match openvpn m|^\.\x83&SU\xe3_\xd5V\x01\0\0\0\0\0\x010\x02\xfd\xa8\xe3\0| p/SoftEther VPN OpenVPN Clone Function/

##############################NEXT PROBE##############################
# Kerberos AS_REQ with realm NM, server name krbtgt/NM, missing client name.
Probe UDP Kerberos q|\x6a\x81\x6e\x30\x81\x6b\xa1\x03\x02\x01\x05\xa2\x03\x02\x01\x0a\xa4\x81\x5e\x30\x5c\xa0\x07\x03\x05\0\x50\x80\0\x10\xa2\x04\x1b\x02NM\xa3\x17\x30\x15\xa0\x03\x02\x01\0\xa1\x0e\x30\x0c\x1b\x06krbtgt\x1b\x02NM\xa5\x11\x18\x0f19700101000000Z\xa7\x06\x02\x04\x1f\x1e\xb9\xd9\xa8\x17\x30\x15\x02\x01\x12\x02\x01\x11\x02\x01\x10\x02\x01\x17\x02\x01\x01\x02\x01\x03\x02\x01\x02|
rarity 5
ports 88

# MIT 1.2.8
match kerberos-sec m=^~\x81[\x86-\x88]0\x81[\x83-\x85]\xa0\x03\x02\x01\x05\xa1\x03\x02\x01\x1e\xa2\x11\x18\x0f\d{14}Z\xa4\x11\x18\x0f(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)Z\xa5[\x03-\x05]\x02(?:\x03...|\x02..|\x01.)\xa6\x03\x02\x01\x06\xa9\x04\x1b\x02NM\xaa\x170\x15\xa0\x03\x02\x01\0\xa1\x0e0\x0c\x1b\x06krbtgt\x1b\x02NM\xab\(\x1b&Client not found in Kerberos database\0$=s p/MIT Kerberos/ v/1.2/ i/server time: $1-$2-$3 $4:$5:$6Z/ cpe:/a:mit:kerberos:5-1.2/
# OS X 10.6.2; MIT 1.3.5, 1.6.3, 1.7.
match kerberos-sec m=^~[\x6b-\x6d]0[\x69-\x6b]\xa0\x03\x02\x01\x05\xa1\x03\x02\x01\x1e\xa2\x11\x18\x0f\d{14}Z\xa4\x11\x18\x0f(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)Z\xa5[\x03-\x05]\x02(?:\x03...|\x02..|\x01.)\xa6\x03\x02\x01\x06\xa9\x04\x1b\x02NM\xaa\x170\x15\xa0\x03\x02\x01\0\xa1\x0e0\x0c\x1b\x06krbtgt\x1b\x02NM\xab\x0e\x1b\x0cNULL_CLIENT\0$=s p/MIT Kerberos/ v/1.3 - 1.8/ i/server time: $1-$2-$3 $4:$5:$6Z/ cpe:/a:mit:kerberos:5-1/

# Heimdal 1.0.1-5ubuntu4
match kerberos-sec m=^~[\x60-\x62]0[\x5e-\x60]\xa0\x03\x02\x01\x05\xa1\x03\x02\x01\x1e\xa4\x11\x18\x0f(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)Z\xa5[\x03-\x05]\x02(?:\x03...|\x02..|\x01.)\xa6\x03\x02\x01<\xa9\x04\x1b\x02NM\xaa\x170\x15\xa0\x03\x02\x01\0\xa1\x0e0\x0c\x1b\x06krbtgt\x1b\x02NM\xab\x16\x1b\x14No client in request$=s p/Heimdal Kerberos/ i/server time: $1-$2-$3 $4:$5:$6Z/ cpe:/a:heimdal:kerberos/

match kerberos-sec m=^~[\x48-\x4a]0[\x46-\x48]\xa0\x03\x02\x01\x05\xa1\x03\x02\x01\x1e\xa4\x11\x18\x0f(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)Z\xa5[\x03-\x05]\x02(?:\x03...|\x02..|\x01.)\xa6\x03\x02\x01D\xa9\x04\x1b\x02NM\xaa\x170\x15\xa0\x03\x02\x01\0\xa1\x0e0\x0c\x1b\x06krbtgt\x1b\x02NM$=s p/Microsoft Windows Kerberos/ i/server time: $1-$2-$3 $4:$5:$6Z/ o/Windows/ cpe:/a:microsoft:kerberos/ cpe:/o:microsoft:windows/a

# DCE RPC Reject
match msrpc m|^\x04\x06\x20\0\x10\0\0\x03\x02\x01\x05\xa2\x03\x02\x01\n\xa4\x81\x5e0\x5c\xa0\x07\x03\x05\0\x50\x80\0\x10\xa2\x04\x1b\x02NM\xa3\x170\x15\xa0\x03\x02\x01\0\xa1\x0e0\x0c\x1b\x06krbtg....|s p/Microsoft RPC/ o/Windows/ cpe:/o:microsoft:windows/a

##############################NEXT PROBE##############################
# SqueezeCenter discovery
Probe UDP SqueezeCenter q|eIPAD\0NAME\0JSON\0VERS\0UUID\0JVID\x06\x12\x34\x56\x78\x12\x34|
rarity 8
ports 3483

match squeezecenter m|^ENAME.{1}(.+)JSON.{1}(\d+)VERS.{1}(.+)UUID.{1}(.+)$| p/Logitech SqueezeCenter music server/ v/$3/ i/Server Name: $1, JSON: $2, UUID: $4/


##############################NEXT PROBE##############################
# AFP - Request GetStatus
Probe TCP afp q|\x00\x03\0\x01\0\0\0\0\0\0\0\x02\0\0\0\0\x0f\0|
rarity 6
ports 548

# See other AFP matches in SSLSessionReq.

# Netatalk 3.1.1
match afp m|^\x01\x03\0\x01\0\0\0\0....\0\0\0\0........\x8f[\x59\x79].([^\0\x01]+)[\0\x01].*Netatalk([\w._-]+)\x06\x06AFP2\.2\x06AFPX03\x06AFP3\.1\x06AFP3\.2\x06AFP3\.3\x06AFP3\.4|s p/Netatalk/ v/$2/ i/name: $1; protocol 3.4/ o/Unix/ cpe:/a:netatalk:netatalk:$2/
# Netatalk 2.2.2
match afp m|^\x01\x03\0\x01\0\0\0\0....\0\0\0\0........\x8f\x7b.([^\0\x01]+)[\0\x01].*Netatalk([\w._-]+)\x05\x06AFP2\.2\x06AFPX03\x06AFP3\.1\x06AFP3\.2\x06AFP3\.3|s p/Netatalk/ v/$2/ i/name: $1; protocol 3.3/ o/Unix/ cpe:/a:netatalk:netatalk:$2/
match afp m|^\x01\x03\0\x01\0\0\0\0....\0\0\0\0........\x8f\x59.([^\0\x01]+)[\0\x01].*Netatalk([\w._-]+)\x05\x06AFP2\.2\x06AFPX03\x06AFP3\.1\x06AFP3\.2\x06AFP3\.3|s p/Netatalk/ v/$2/ i/name: $1; protocol 3.3/ o/Unix/ cpe:/a:netatalk:netatalk:$2/
match afp m|^\x01\x03\0\x01\0\0\0\0....\0\0\0\0........\x8f\x5d.MyBookWorld[\0\x01].*Netatalk([\w._-]+)\x05\x06AFP2\.2\x06AFPX03\x06AFP3\.1\x06AFP3\.2\x06AFP3\.3|s p/Netatalk/ v/$1/ i/Western Digital MyBook World NAS device; name: MyBookWorld; protocol 3.3/ o/Unix/ cpe:/a:netatalk:netatalk:$1/
# Netatalk 2.2.1dev
match afp m|^\x01\x03\0\x01\0\0\0\0....\0\0\0\0........\x8f\x7d.([^\0\x01]+)[\0\x01].*Netatalk([\w._-]+)\x05\x06AFP2\.2\x06AFPX03\x06AFP3\.1\x06AFP3\.2\x06AFP3\.3|s p/Netatalk/ v/$2/ i/name: $1; protocol 3.3/ o/Unix/ cpe:/a:netatalk:netatalk:$2/
# Netatalk 2.2.0
match afp m|^\x01\x03\0\x01\0\0\0\0....\0\0\0\0........\x8f\x79.([^\0\x01]+)[\0\x01].*Netatalk ([\w._-]+)\x05\x06AFP2\.2\x06AFPX03\x06AFP3\.1\x06AFP3\.2\x06AFP3\.3|s p/Netatalk/ v/$2/ i/name: $1; protocol 3.3/ o/Unix/ cpe:/a:netatalk:netatalk:$2/
# Netatalk 2.2.1
match afp m|^\x01\x03\0\x01\0\0\0\0....\0\0\0\0........\x8f\x79.([\w._-]+)[\0\x01].*Netatalk([\w._-]+)\x05\x06AFP2\.2\x06AFPX03\x06AFP3\.1\x06AFP3\.2\x06AFP3\.3|s p/Netatalk/ v/$2/ i/name: $1; protocol 3.3/ o/Unix/ cpe:/a:netatalk:netatalk:$2/
# Netatalk 2.2.0
match afp m|^\x01\x03\0\x01\0\0\0\0....\0\0\0\0........\x8f\x7d.(FreeNAS)[\0\x01].*Netatalk ([\w._-]+)\x05\x06AFP2\.2\x06AFPX03\x06AFP3\.1\x06AFP3\.2\x06AFP3\.3|s p/Netatalk/ v/$2/ i/FreeNAS; name: $1; protocol 3.3/ o/FreeBSD/ cpe:/a:netatalk:netatalk:$2/ cpe:/o:freebsd:freebsd/
# Netatalk 2.2.1.1-0u
match afp m|^\x01\x03\0\x01\0\0\0\0....\0\0\0\0........\x8f\x5d.([\w._-]+)[\0\x01].*Netatalk[ \0]?([\w._-]+)\x05\x06AFP2\.2\x06AFPX03\x06AFP3\.1\x06AFP3\.2\x06AFP3\.3|s p/Netatalk/ v/$2/ i/name: $1; protocol 3.3/ o/Unix/ cpe:/a:netatalk:netatalk:$2/

match afp m|^\x01\x03\0\x01\0\0\0\0....\0\0\0\0........\x8f\x7d.([^\0\x01]+)[\0\x01].*Netatalk ([\w._-]+)\x05\x06AFP2\.2\x06AFPX03\x06AFP3\.1\x06AFP3\.2\x06AFP3\.3|s p/Netatalk/ v/$2/ i/name: $1; protocol 3.3/ o/Unix/ cpe:/a:netatalk:netatalk:$2/
match afp m|^\x01\x03\0\x01\0\0\0\0....\0\0\0\0........\x8f\x7d.([^\0\x01]+)[\0\x01].*Netatalk([\w._-]+)\x06\x06AFP2\.2\x06AFPX03\x06AFP3\.1\x06AFP3\.2\x06AFP3\.3\x06AFP3\.4| p/Netatalk/ v/$2/ i/name: $1; protocol 3.4/ o/Unix/ cpe:/a:netatalk:netatalk:$2/
match afp m|^\x01\x03\0\x01\0\0\0\0....\0\0\0\0........\x8f\x7d.(MyBookWorld)[\0\x01].*Netatalk ([\w._-]+)\x05\x06AFP2\.2\x06AFPX03\x06AFP3\.1\x06AFP3\.2\x06AFP3\.3|s p/Netatalk/ v/$SUBST(2,"-",".")/ i/Western Digital MyBook World NAS device; name: $1; protocol 3.3/ o/Unix/ cpe:/a:netatalk:netatalk:$SUBST(2,"-",".")/
match afp m|^\x01\x03\0\x01\0\0\0\0....\0\0\0\0........\x8f\x7d.([\w._-]+)[\0\x01].*Netatalk([\w._-]+)\x08\x0eAFPVersion 1\.1\x0eAFPVersion 2\.0\x0eAFPVersion 2\.1\x06AFP2\.2\x06AFPX03\x06AFP3\.1\x06AFP3\.2\x06AFP3\.3|s p/Netatalk/ v/$SUBST(2,"-",".")/ i/QNAP NAS TS-219P+; name: $1; protocol 3.3/ o/Linux/ cpe:/a:netatalk:netatalk:$SUBST(2,"-",".")/ cpe:/o:linux:linux_kernel:2.6/

match afp m|^\x01\x03\0\x01\0\0\0\0....\0\0\0\0........\x81\x7d\0\0.*Netatalk\x06\x0eAFPVersion 1\.1\x0eAFPVersion 2\.0\x0eAFPVersion 2\.1\x06AFP2\.2\x06AFPX03\x06AFP3\.1\x04\x04DHX2\tDHCAST128|s p/Netatalk/ i/protocol 3.1/ o/Unix/ cpe:/a:netatalk:netatalk/
match afp m|^\x01\x03\0\x01\0\0\0\0....\0\0\0\0........\x83\x7f.([^\0\x01]+)[\0\x01].*Netatalk\x04\x06AFP2\.2\x06AFPX03\x06AFP3\.1\x06AFP3\.2|s p/Netatalk/ v/2/ i/name: $1; protocol 3.2/ o/Unix/ cpe:/a:netatalk:netatalk:2/

# Netatalk 2.0.5
match afp m|^\x01\x03\0\x01\0\0\0\0....\0\0\0\0........\x83\x7d.([^\0\x01]+)[\0\x01].*\x08Netatalk\x04\x06AFP2\.2\x06AFPX03\x06AFP3\.1\x06AFP3\.2|s p/Netatalk/ v/2/ i/name: $1; protocol 3.2/ o/Unix/ cpe:/a:netatalk:netatalk:2/
match afp m|^\x01\x03\0\x01\0\0\0\0....\0\0\0\0........\x83\x7d.([^\0\x01]+)[\0\x01].*\x08Netatalk\x06\x0eAFPVersion 1\.1\x0eAFPVersion 2\.0\x0eAFPVersion 2\.1\x06AFP2\.2\x06AFPX03\x06AFP3\.1|s p/Netatalk/ v/2/ i/name: $1; protocol 3.1/ o/Unix/ cpe:/a:netatalk:netatalk:2/
match afp m|^\x01\x03\0\x01\0\0\0\0....\0\0\0\0........\x83\x7d.([^\0\x01]+)[\0\x01].*\x08Netatalk\x07\x0eAFPVersion 1\.1\x0eAFPVersion 2\.0\x0eAFPVersion 2\.1\x06AFP2\.2\x06AFPX03\x06AFP3\.1\x06AFP3\.2| p/Netatalk/ v/2/ i/name: $1; protocol 3.2/ o/Unix/ cpe:/a:netatalk:netatalk:2/

# Netatalk 2.0.4
# Netatalk 2.0.3
match afp m|^\x01\x03\0\x01\0\0\0\0....\0\0\0\0........\x83\x79.([^\0\x01]+)[\0\x01].*\x08Netatalk\x06\x0eAFPVersion 1\.1\x0eAFPVersion 2\.0\x0eAFPVersion 2\.1\x06AFP2\.2\x06AFPX03\x06AFP3\.1|s p/Netatalk/ v/2/ i/name: $1; protocol 3.1/ o/Unix/ cpe:/a:netatalk:netatalk:2/
match afp m|^\x01\x03\0\x01\0\0\0\0....\0\0\0\0........\x83\x79.([^\0\x01]+)[\0\x01].*\x08Netatalk\x04\x06AFP2\.2\x06AFPX03\x06AFP3\.1\x06AFP3\.2|s p/Netatalk/ v/2/ i/name: $1; protocol 3.2/ o/Unix/ cpe:/a:netatalk:netatalk:2/

match afp m|^\x01\x03\0\x01\0\0\0\0....\0\0\0\0........\x83\x59.([^\0\x01]+)[\0\x01].*\x08Netatalk\x06\x0eAFPVersion 1\.1\x0eAFPVersion 2\.0\x0eAFPVersion 2\.1\x06AFP2\.2\x06AFPX03\x06AFP3\.1|s p/Netatalk/ v/2/ i/name: $1; protocol 3.1/ o/Unix/ cpe:/a:netatalk:netatalk:2/

# Netatalk 1.6.4
match afp m|^\x01\x03\0\x01\0\0\0\0....\0\0\0\0........\x80\x7d.([^\0\x01]+)[\0\x01].*\x04unix\x04\x0eAFPVersion 1\.1\x0eAFPVersion 2\.0\x0eAFPVersion 2\.1\x06AFP2\.2|s p/Netatalk/ v/1.6/ i/name: $1; protocol 2.2/ o/Unix/ cpe:/a:netatalk:netatalk:1.6/

match afp m|^\x01\x03\0\x01\0\0\0\0....\0\0\0\0........\x8f\x79.([^\0\x01]+)[\0\x01].*Netatal(\d[\w.]+)|s p/Netatalk/ v/$2/ i/name: $1/ o/Unix/ cpe:/a:netatalk:netatalk:$2/

# Novell NetWare AFP
match afp m|^\x01\x03\0\x01\0\0\0\0....\0\0\0\0........\0\xbf.([^\0]+)\0.*\x16Novell NetWare ([0-9.]+)\x06\x0eAFPVersion 1\.1\x0eAFPVersion 2\.0\x0eAFPVersion 2\.1\x06AFP2\.2\x06AFPX03\x06AFP3\.1\x02\x10[^\x16]+\x16|s p/Novell NetWare AFP/ v/$2/ i/name: $1; protocol 3.1/ o/NetWare/ cpe:/o:novell:netware/a

# Novell Open Enterprise Server
match afp m|^\x01\x03\0\x01\0\0\0\0....\0\0\0\0........\0\xb7.([^\0]+)\0.*\x1fNovell\x20Open\x20Enterprise\x20Server\x202|s p/Novell Open Enterprise Server/ v/2/ i/name: $1/ o/Linux/ cpe:/a:novell:open_enterprise_server:2/ cpe:/o:linux:linux_kernel/a

# Windows NT or Windows 2000
match afp m|^\x01\x03\0\x01\0\0\0\0....\0\0\0\0........\x80\x7f.([^\0\x01]+)[\0\x01].*\x0aWindows NT\x03\x0eAFPVersion 2\.0\x0eAFPVersion 2\.1\x06AFP2\.2\x03\x10ClearTxt Passwrd\x0eMicrosoft V1\.0\x05MS2\.0|s i/name: $1; protocol 2.2; MS2.0/ o/Windows/ cpe:/o:microsoft:windows/
match afp m|^\x01\x03\0\x01\0\0\0\0....\0\0\0\0........\x80\x7f.([^\0\x01]+)[\0\x01].*\x0aWindows NT\x03\x0eAFPVersion 2\.0\x0eAFPVersion 2\.1\x06AFP2\.2\x03\x0eMicrosoft V1\.0\x05MS2\.0\x05MS3\.0|s i/name: $1; protocol 2.2; MS3.0/ o/Windows/ cpe:/o:microsoft:windows/

# Seems to repeat the length in the first reserved field.
match afp m|^\x01\x03\0\x01\0\0\0\0................\x03\xff.([^\0\x01]+)[\0\x01].*Windows Version: ([\d.]+ \(2\) build \d+ (?:Service Pack \d+)?) (\d+)-bit \(ExtremeZ-IP ([\w._-]+)\).*afpserver/([\w._@-]+)\0|s p/ExtremeZ-IP AFP/ v/$4/ i/name: $1; afpserver: $5; $3-bit/ o/Windows $2/ cpe:/o:microsoft:windows/a
match afp m|^\x01\x03\0\x01\0\0\0\0................\x03\xff.([^\0\x01]+)[\0\x01].*Windows Version: ([\d.]+ \(2\) build \d+ (?:Service Pack \d+)?) (\d+)-bit \(ExtremeZ-IP ([\w._-]+)\).*|s p/ExtremeZ-IP AFP/ v/$4/ i/name: $1; $3-bit/ o/Windows $2/ cpe:/o:microsoft:windows/a

softmatch afp m|^\x01\x03\0\x01\0\0\0\0....\0\0\0\0.*AFP|s

match lsf-mbd m|^\0\"\0\0\x17\0\0\0\0\0\0\0\0\0\0\0| p/Platform Load Sharing Facility MBD/ cpe:/a:platform:load_sharing_facility/
match pigpio m|^\0\x03\0\x01\0\0\0\0\0\0\0\x02\xa8\xff\xff\xff| p/pigpiod/ cpe:/a:pigpio:pigpiod/

##############################NEXT PROBE##############################
# Quake1 server info
Probe UDP Quake1_server_info q|\x80\x00\x00\x0c\x02\x51\x55\x41\x4b\x45\x00\x03|
rarity 9
ports 26000-26004

match quake m|^\x80\x00..\x83([^\x00]*)\x00([^\x00]*)\x00| p/Quake 1 server/ i/address: $1, name: $2/

##############################NEXT PROBE##############################
# Quake2 status
Probe UDP Quake2_status q|\xff\xff\xff\xffstatus|
rarity 8
ports 27910-27914

match quake2 m|^\xff\xff\xff\xffprint\n.*\\version\\([^\\]* Linux)(?=\\).*\\gamename\\data1(?=\\)| p/Alien Arena game server/ v/$1/ o/Linux/ cpe:/o:linux:linux_kernel/a

##############################NEXT PROBE##############################
# Quake3 getstatus
Probe UDP Quake3_getstatus q|\xff\xff\xff\xffgetstatus|
rarity 8
ports 26000-26004,27960-27964,30720-30724,44400

match quake3 m|^\xff\xff\xff\xffstatusResponse\n.*\\gamename\\Nexuiz(?=\\).*\\gameversion\\([^\\]*)(?=\\)| p/Nexuiz game server/ v/$1/
match quake3 m|^\xff\xff\xff\xffstatusResponse\n.*\\version\\([^\\]* linux-[^\\]*)(?=\\).*\\gamename\\baseoa(?=\\)| p/OpenArena game server/ v/$1/ o/Linux/ cpe:/o:linux:linux_kernel/a
match quake3 m|^\xff\xff\xff\xffstatusResponse\n.*\\version\\([^\\]* freebsd-[^\\]*)(?=\\).*\\gamename\\baseoa(?=\\)| p/OpenArena game server/ v/$1/ o/FreeBSD/ cpe:/o:freebsd:freebsd/a
match quake3 m|^\xff\xff\xff\xffstatusResponse\n.*\\version\\tremulous ([^\\]* linux-[^\\]*)(?=\\)| p/Tremulous game server/ v/$1/ o/Linux/ cpe:/o:linux:linux_kernel/a
match quake3 m|^\xff\xff\xff\xffstatusResponse\n.*\\version\\tremulous ([^\\]* freebsd-[^\\]*)(?=\\)| p/Tremulous game server/ v/$1/ o/FreeBSD/ cpe:/o:freebsd:freebsd/a
match quake3 m|^\xff\xff\xff\xffstatusResponse\n.*\\version\\([^\\]* linux-[^\\]*)(?=\\).*\\gamename\\q3ut4(?=\\)| p/Urban Terror game server/ v/$1/ o/Linux/ cpe:/o:linux:linux_kernel/a
match quake3 m|^\xff\xff\xff\xffstatusResponse\n.*\\version\\([^\\]* freebsd-[^\\]*)(?=\\).*\\gamename\\q3ut4(?=\\)| p/Urban Terror game server/ v/$1/ o/FreeBSD/ cpe:/o:freebsd:freebsd/a
match quake3 m|^\xff\xff\xff\xffstatusResponse\n.*\\version\\([^\\]* Linux)(?=\\).*\\gamename\\Warsow(?=\\)| p/Warsow game server/ v/$1/ o/Linux/ cpe:/o:linux:linux_kernel/a
match quake3 m|^\xff\xff\xff\xffstatusResponse\n.*\\version\\([^\\]* linux-[^\\]*)(?=\\)| p/World of Padman game server/ v/$1/ o/Linux/ cpe:/o:linux:linux_kernel/a
match quake3 m|^\xff\xff\xff\xffstatusResponse\n.*\\version\\([^\\]* freebsd-[^\\]*)(?=\\)| p/World of Padman game server/ v/$1/ o/FreeBSD/ cpe:/o:freebsd:freebsd/a

##############################NEXT PROBE##############################
# Quake 3 and other games
# http://svn.icculus.org/twilight/trunk/dpmaster/doc/techinfo.txt?view=markup
# Protocol 68 is a specific revision of Quake 3, but the server should respond
# with an empty server list even if it doesn't know that game.
Probe UDP Quake3_master_getservers q|\xff\xff\xff\xffgetservers 68 empty full|
rarity 9
ports 27950,30710

match quake3-master m|^\xff\xff\xff\xffgetserversResponse|

##############################NEXT PROBE##############################
# SqueezeCenter CLI
# http://wiki.slimdevices.com/index.php/CLI
Probe TCP SqueezeCenter_CLI q|serverstatus\r\n|
rarity 8
ports 9090

match squeezecli m|^serverstatus.*version%3A([\.\d]+) uuid%3A([-\w]+) info%20total%20albums%3A\d+ info%20total%20artists%3A\d+ info%20total%20genres%3A\d+ info%20total%20songs%3A(\d+) player%20count%3A\d+ sn%20player%20count%3A\d+ other%20player%20count%3A\d+\r\n|s p/SqueezeCenter CLI/ v/$1/ i/UUID: $2, Total songs: $3/

##############################NEXT PROBE##############################
# Arucer backdoor
# http://www.kb.cert.org/vuls/id/154421
# The probe is the UUID for the 'YES' command, which is basically a ping command, encoded by XORing with 0xE5 (the original string is "E2AC5089-3820-43fe-8A4D-A7028FAD8C28"). The response is the string 'YES', encoded the same way.
Probe TCP Arucer q|\xC2\xE5\xE5\xE5\x9E\xA0\xD7\xA4\xA6\xD0\xD5\xDD\xDC\xC8\xD6\xDD\xD7\xD5\xC8\xD1\xD6\x83\x80\xC8\xDD\xA4\xD1\xA1\xC8\xA4\xD2\xD5\xD7\xDD\xA3\xA4\xA1\xDD\xA6\xD7\xDD\x98\xE5|
rarity 8
ports 7777

match arucer m|^\xbc\xa0\xb6$| p/Arucer backdoor/ i/**BACKDOOR**/ o/Windows/ cpe:/o:microsoft:windows/a

##############################NEXT PROBE##############################
# Mac OS X Server serialnumberd; checks for other servers with the same serial
# number on the local network. AAAAAA is a dummy value.
Probe UDP serialnumberd q|SNQUERY: 127.0.0.1:AAAAAA:xsvr|
rarity 8
ports 626

match serialnumber m|^SNRESPS:127\.0\.0\.1:(0x[0-9A-F]{40}):xsvr:(0x[0-9A-F]{40}):(0x[0-9a-f]{8}):(0x[0-9A-F]{40}):127\.0\.0\.1\0$| p/Mac OS X Server serialnumberd/ i/numbers: $1 $2 $3 $4/ o/Mac OS X/ cpe:/o:apple:mac_os_x/a
match serialnumber m|^SNRESPS:([\w._-]+):(0x[0-9A-F]{40}):xsvr:(0x[0-9A-F]{40}):(0x[0-9a-f]{8}):(0x[0-9A-F]{40}):[\w._-]+\0$| p/Mac OS X Server serialnumberd/ i/numbers: $2 $3 $4 $5/ o/Mac OS X/ h/$1/ cpe:/o:apple:mac_os_x/a

##############################NEXT PROBE##############################
# Lotus Domino Console
#
Probe TCP dominoconsole q|#ST\n|
rarity 8
sslports 2050

match dominoconsole m|^([^/]+)/([\w._-]+):([^:]*):([^:]*):| p/Lotus Domino Console/ i/domain: $1; description: "$4"/ o/$3/ h/$2/ cpe:/a:ibm:lotus_domino/

##############################NEXT PROBE##############################
# Informix probe
#
Probe TCP informix q|\0\x94\x01\x3c\0\0\0\x64\0\x65\0\0\0\x3d\0\x06IEEEM\0\0lsqlexec\0\0\0\0\0\0\x069.280\0\0\x0cRDS#R000000\0\0\x05sqli\0\0\0\x01\x33\0\0\0\0\0\0\0\0\0\x01\0\x05nmap\0\0\x05nmap\0ol\0\0\0\0\0\0\0\0\0=tlitcp\0\0\0\0\0\x01\0\x68\0\x0b\0\0\0\x03\0\x05nmap\0\0\0\0\0\0\0\0\0\0\0\0\x6a\0\0\0\x7f|
rarity 8
ports 1526,9088-9100

match informix m|^..\x03<\x10\0\0d\0e\0\0\0=\0\x06IEEEI\0\0lsrvinfx\0\0\0\0\0\0\x05V1\.0\0\0\x04SER\0\0\x08asfecho\0{19}o[ln]\0{9}=soctcp\0{5}\x01\0f\0{6}\xfcI..\0\0\0\x01\0\0\0.nmap@[\d\w.-]+\0k\0\0\0\0\0\0..\0\0\0\0\0.(.*)\0\0..*\0\0.([A-Z]\:[^/]*)\0\0t\0\x08\x01Y\0\x06\x01Y\0\0\0\x7f$|s p/Informix Dynamic Server/ v/11.50/ i/Path: $2/ o/Windows/ h/$1/ cpe:/a:ibm:informix_dynamic_server:11.50/ cpe:/o:microsoft:windows/a
match informix m|^..\x03<\x10\0\0d\0e\0\0\0=\0\x06IEEEI\0\0lsrvinfx\0\0\0\0\0\0\x05V1\.0\0\0\x04SER\0\0\x08asfecho\0{19}o[ln]\0{9}=soctcp\0{5}\x01\0f\0{6}\xfcI..\0\0\0\x01\0\0\0.nmap@[\d\w.-]+\0k\0\0\0\0\0\0..\0\0\0\0\0.(.*)\0\0..*\0\0.([^\\]*)\0\0t\0\x08\0\0\x03\xe9\0\0\x03\xe9\0\x7f$|s p/Informix Dynamic Server/ v/11.50/ i/Path: $2/ h/$1/ cpe:/a:ibm:informix_dynamic_server:11.50/
# Should we detect windows paths here, too?
# non-capturing group is a path that may be interesting. e.g.: /opt/SinoDB_Software_Bundle/bin/oninit
match informix m|^..\x03<\x10\0\0d\0e\0\0\0=\0\x06IEEEI\0\0lsrvinfx\0\0\0\0\0\0\x05V1\.0\0\0\x04SER\0\0\x08asfecho\0{19}o[ln]\0{9}=soctcp\0{5}\x01\0f\0{6}\xfcI..\0\0\0\x01\0\0\0.nmap@[\d\w.-]+\0k\0\0\0\0\0\0..\0\0\0\0\0.(.+)\0\0..*\0\0.([^\\]+)\0\0n\0\x04\0{5}t\x001\0\0\x03\xe9\0\0\x03\xe9..(?:[^\0]+)\0\0\x7f|s p/Informix Dynamic Server/ v/11.70/ i/Path: $2/ h/$1/ cpe:/a:ibm:informix_dynamic_server:11.70/

match informix m|^..\x03<\x10\0\0d\0e\0\0\0=\0\x06IEEEI\0\0lsrvinfx\0\0\0\0\0\0\x05V1\.0\0\0\x04SER\0\0\x08asfecho\0{19}o[ln]\0{9}=soctcp\0{5}\x01\0f\0{6}\xfcI..\0\0\0\x01\0\0\0.nmap@[\d\w.-]+\0k\0\0\0\0\0\x03..\0\0\0\0\0.([^\0]+)\0\0.[^\0]*\0\0.([A-Z]\:[^/]*)\0|s p/Informix Dynamic Server/ i/Path: $2/ o/Windows/ h/$1/ cpe:/a:ibm:informix_dynamic_server/ cpe:/o:microsoft:windows/a
match informix m|^..\x03<\x10\0\0d\0e\0\0\0=\0\x06IEEEI\0\0lsrvinfx\0\0\0\0\0\0\x05V1\.0\0\0\x04SER\0\0\x08asfecho\0{19}o[ln]\0{9}=soctcp\0{5}\x01\0f\0{6}\xfcI..\0\0\0\x01\0\0\0.nmap@[\d\w.-]+\0k\0\0\0\0\0\x03..\0\0\0\0\0.([^\0]+)\0\0.[^\0]*\0\0.([^\\]*)\0|s p/Informix Dynamic Server/ i/Path: $2/ h/$1/ cpe:/a:ibm:informix_dynamic_server/

softmatch informix m|^..\x03<\x10\0\0d\0e\0\0\0=|

##############################NEXT PROBE##############################
# The DRDA protocol is used by both Informix and DB2
#
Probe TCP drda q|\0\x32\xd0\x01\0\x01\0\x2c\x10\x41\0\x04\x11\x5e\0\x04\x11\x6d\0\x04\x11\x5a\0\x18\x14\x04\x14\x03\x00\x07\x24\x07\0\x08\x24\x0f\x00\x08\x14\x40\0\x08\x14\x74\0\x08\0\x04\x11\x47|
rarity 8
ports 50000,60000,1526,1527,9088-9100

softmatch drda m|^\0.......\x14\x43..\x11\x5e.*\x11\x47|

match oo-defrag m|^\x10\0\0\0\x01\0\0\0\x03\0\0\0\r\x08\0\0\x02\0{7}j\0\0\0\x01\0\0\0\x03\0\0\0\x07\x08\0\0\x02\0{97}\x10\0\0\0\x01\0\0\0\x03\0\0\0\r\x08\0\0\x02\0{7}j\0\0\0\x01\0\0\0\x03\0\0\0\x07\x08\0\0\x02\0{97}\x0c\0\0\0\x01\0{7}\xd7\x07\0{6}| p/O&O Defrag/ o/Windows/ cpe:/o:microsoft:windows/a

##############################NEXT PROBE##############################
# MQ Initial Packet Queue-manager=nmap-probe; channel=SYSTEM.ADMIN.SRVCONN
#
Probe TCP ibm-mqseries q|TSH\x20\x00\x00\x00\xEC\x01\x01\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x11\x04\xB8\x00\x00\x49\x44\x20\x20\x0A\x26\x00\x00\x00\x00\x00\x00\x00\x00\x7F\xF6\x06\x40\x00\x00\x00\x00\x00\x00SYSTEM.ADMIN.SVRCONN\x51\x00\x04\xB8nmap-probe\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x00\x00\x00\x01\x00\x6A\x00\x00\x00\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0A\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02MQJB00000000CANNED_DATA\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20|
rarity 8
ports 1414-1420

match ibm-mqseries m|^TSH\x20\0\0\0\xec\x02\x01\x02\0\0\0\0\0\0\0\0\0\x11\x01\x00\x00..\0\0ID\x20\x20\x08&\0\x98\0\0\0\0\xf6\x7f\x00\x00\0\x00\x40\0\0\0\0\0([^\s]*)\s*\x2c\x01\0\0\0\0\0\0\0\xff\0\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\n\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x02MQJB00000000CANNED_DATA\s*$|s p/IBM WebSphere MQ/ v/6.0/ i/channel: $1/ cpe:/a:ibm:websphere_mq:6.0/
match ibm-mqseries m|^TSH\x20\0\0\0\xec\x02\x01\x02\0\0\0\0\0\0\0\0\0\x11\x01\x00\x00..\0\0ID\x20\x20\x0a&\0\x90\0\0\0\0\xf6\x7f\x00\x00\0\x00\x40\0\0\0\0\0([^\s]*)\s*\x51\x00\xb5\x01([^\s]*)\s*\x2c\x01\0\0\0\0\0\0\0\xff\0\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\n\0\0\0\0\0\0\0..\0\0.\0\0\0.\0\0\0[^\s]*\s*$|s p/IBM WebSphere MQ/ v/7.0/ i/queue manager: $2, channel: $1/ cpe:/a:ibm:websphere_mq:7.0/
match ibm-mqseries m|^TSH\x20\0\0\0\xec\x01\x01\x02\0\0\0\0\0\0\0\0\0\x00\x00\x01\x11..\0\0ID\x20\x20\x0a&\0\x90\0\0\0\0\x00\x00\x7f\xf6\0\x40\x00\0\0\0\0\0([^\s]*)\s*\x00\x00\x01\x2c\0\0\0\0\0\xff\0\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\n\0\0\0\0\0.*MQMM07000107JJ\.PRD\.(QM02_\d\d\d\d-\d\d-\d\d_\d+\.\d+\.\d+)\s*$|s p/IBM WebSphere MQ/ v/7.0/ i/channel: $1; $2/ cpe:/a:ibm:websphere_mq:7.0/
match ibm-mqseries m|^TSH\x20\0\0\0\$\x01\x05\n\0\0\0\0\0\0\0\0\0\0\0\x02\"\x04\xb8\0\0\0\0\0\x08\0\0\0\x01$| p/IBM WebSphere MQ/ v/7.0.1/ cpe:/a:ibm:websphere_mq:7.0.1/

softmatch ibm-mqseries m|^TSH\x20\0\0\0| p/IBM WebSphere MQ/ cpe:/a:ibm:websphere_mq/

##############################NEXT PROBE##############################
# Queries iPhoto for the /server-info url containing the shared library name
#
Probe TCP apple-iphoto q|GET /server-info HTTP/1.1\r\nClient-DPAP-Version: 1.1\r\nUser-Agent: iPhoto/9.1.1  (Macintosh; N; PPC)\r\n\r\n|
rarity 8
ports 8770

match apple-iphoto m|^HTTP/1\.1 200 OK\r\nDate: .*\r\nDPAP-Server: iPhoto/(.*)\r\nContent-Type: application/x-dmap-tagged\r\nContent-Length: \d+\r\n\r\nmsrv\0\0\0\x83mstt\0\0\0\x04\0\0\0\xc8mpro\0\0\0\x04\0\x02\0\0ppro\0\0\0\x04\0\x01\0\x01minm\0\0\0.(.*)mslr\0\0\0\x01\0mstm\0\0\0\x04\0\0\x07\x08msal\0\0\0\x01\0msau\0\0\0\x01\x02msas\0\0\0\x01\x03msix\0\0\0\x01\0msdc\0\0\0\x04\0\0\0\x01$| p/Apple iPhoto/ v/$1/ i/Library name: $2/ cpe:/a:apple:iphoto:$1/

##############################NEXT PROBE##############################
# Zend Java Bridge, vulnerable control port, see
# <http://www.zerodayinitiative.com/advisories/ZDI-11-113/>
# GetClassName called on an empty string.
Probe TCP ZendJavaBridge q|\0\0\0\x1f\0\0\0\0\0\0\0\x0cGetClassName\0\0\0\x02\x04\0\0\0\0\x01\0|
rarity 9
ports 5000,5001,5002,10001-10003

match h.239 m|^BadRecord| p/Polycom People+Content IP H.239/ d/VoIP phone/

# LOGO! 7 on port 10001
match siemens-logo m|^\x06\x03\x04\0\0\x002| p/Siemens LOGO! PLC/ d/specialized/

# port 5002 on Mitsubishi PLC: http://plcremote.net/143-2/
match mitsubishi-qj71e71 m|^\x80\[\0K\xc7P| p/Mitsubishi QJ71E71/ d/specializied/

match sybase-adaptive m|^\x04\x01\0\x28\0\0\0\0\xaa\x14\0\xa2\x0f\0\0\x01\x0eLogin failed\.\n\xfd\x02\0\x02\0\0\0\0\0$| p/Sybase Adaptive Server/ o/Windows/ cpe:/a:sybase:adaptive_server/ cpe:/o:microsoft:windows/a
match sybase-monitor m|^\x04\x01\0\x1a\0\0\0\0\xaa\x01\x0eLogin failed\.\n\xfd$| p/Sybase Monitor Server/ o/Windows/ cpe:/a:sybase:monitor_server/ cpe:/o:microsoft:windows/a

match zend-java-bridge m|^\0\0\0\x15\x04\0\0\0\x10java\.lang\.String$|

##############################NEXT PROBE##############################
# BackOrifice PING message, no password. The probe is the encryption of
# "*!*QWTY?\x13\0\0\0\0\0\0\0\x01\0\0". Servers with a password set will
# not reply.
# http://web.cip.com.br/flaviovs/boproto.html
Probe UDP BackOrifice q|\xCE\x63\xD1\xD2\x16\xE7\x13\xCF\x38\xA5\xA5\x86\xB2\x75\x4B\x99\xAA\x32\x58|
ports 31337
rarity 9

# Encryption of "*!*QWTY?........\x01  !PONG!1.20!".
match BackOrifice m|^\xCE\x63\xD1\xD2\x16\xE7\x13\xCF........\x01\x12\x78\xC4\xE3\xD6\xA6\x65\x51\x75\x51\xEB\x2A\x3F|s p/BackOrifice trojan/ v/1.20/ i/no password/ o/Windows/ cpe:/o:microsoft:windows/a

##############################NEXT PROBE##############################
Probe TCP gkrellm q|gkrellm 0.0.0|
rarity 9
ports 19150

match gkrellm m|^<gkrellmd_setup>\n<version>\ngkrellmd ([\w._-]+)\n| p/GKrellM System Monitor/ v/$1/

##############################NEXT PROBE##############################
Probe TCP metasploit-xmlrpc q|<?xml version="1.0" ?><methodCall><methodName>nmap.probe</methodName></methodCall>\n\0|
ports 9390,55553
sslports 55553
rarity 9
match metasploit-xmlrpc m|<\?xml\x20version=\"1\.0\"\x20\?><methodResponse><fault><value><struct><member><name>faultCode</name><value><i4>-99</i4></value></member><member><name>faultString</name><value><string>Method\x20nmap\.probe\x20missing\x20or\x20wrong\x20number\x20of\x20parameters!</string></value></member></struct></value></fault></methodResponse>\n\0|

match omp m|^<omp_response status=\"400\" status_text=\"First command must be AUTHENTICATE, COMMANDS or GET_VERSION\"/>| p/OpenVAS Management Protocol/ cpe:/a:openvas:openvas_manager/

##############################NEXT PROBE##############################
# MongoDB probe, this is a status request
# See http://www.mongodb.org/display/DOCS/Mongo+Wire+Protocol for more details
Probe TCP mongodb q|\x41\0\0\0\x3a\x30\0\0\xff\xff\xff\xff\xd4\x07\0\0\0\0\0\0test.$cmd\0\0\0\0\0\xff\xff\xff\xff\x1b\0\0\0\x01serverStatus\0\0\0\0\0\0\0\xf0\x3f\0|
rarity 8
# ports 9001 and 49153 supported by Shodan search for "It looks like you are trying to access MongoDB"
ports 9001,27017,49153
match mongodb m|^.*version.....([\.\d]+)|s p/MongoDB/ v/$1/ cpe:/a:mongodb:mongodb:$1/
match mongodb m|^\xcb\0\0\0....:0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\xa7\0\0\0\x01uptime\0\0\0\0\0\0 `@\x03globalLock\09\0\0\0\x01totalTime\0\0\0\0\x7c\xf0\x9a\x9eA\x01lockTime\0\0\0\0\0\0\xac\x9e@\x01ratio\0!\xc6\$G\xeb\x08\xf0>\0\x03mem\0<\0\0\0\x10resident\0\x03\0\0\0\x10virtual\0\xa2\0\0\0\x08supported\0\x01\x12mapped\0\0\0\0\0\0\0\0\0\0\x01ok\0\0\0\0\0\0\0\xf0\?\0$|s p/MongoDB/ cpe:/a:mongodb:mongodb/
match mongodb m|^.\0\0\0....:0\0\0\x01\0\0\0\x08\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\+\0\0\0\x02errmsg\0\x0e\0\0\0need to login\0\x01ok\0\0\0\0\0\0\0\0\0\0|s p/MongoDB/ i/need to login/ cpe:/a:mongodb:mongodb/
match mongodb m|^.\0\0\0....:0\0\0\x01\0\0\0\x08\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0.\0\0\0\x01ok\0\0\0\0\0\0\0\0\0\x02errmsg\0.\0\0\0not authorized on (\S+) to execute command \{ serverStatus: 1\.0 \}\0\x10code\0\r\0\0\0|s p/MongoDB/ i/not authorized; database: $1/ cpe:/a:mongodb:mongodb/

##############################NEXT PROBE##############################
# Sybase SQL Anywhere Ping Probe
Probe UDP sybaseanywhere q|\x1b\0\0\x3d\0\0\0\0\x12CONNECTIONLESS_TDS\0\0\0\x01\0\0\x04\0\x05\0\x05\0\0\x01\x02\0\0\x03\x01\x01\x04\x08\0\0\0\0\0\0\0\0\x07\x02\x04\xb1|
rarity 7
ports 2638
match sybaseanywhere m|^\x1b\0\0.\0\0\0\0\x12CONNECTIONLESS_TDS\0\0\0\x01\x01\0\x04\0\x05\0\x05\0.(.*)\0\x01\x02..\x03\x01\x02\x04\x08\0\0\0\0\0\0\0\0\x07\x02\x04\xb1|s p/Sybase SQL Anywhere/ i/Instance name: $1/ cpe:/a:sybase:sql_anywhere/

##############################NEXT PROBE##############################
# Vuze DHT PING probe
# See http://wiki.vuze.com/w/Distributed_hash_table#PING
Probe UDP vuze-dht q|\xff\xf0\x97\x0d\x2e\x60\xd1\x6f\0\0\x04\0\0\x55\xab\xec\x32\0\0\0\0\0\x32\x04\x0a\0\xc8\x75\xf8\x16\0\x5c\xb9\x65\0\0\0\0\x4e\xd1\xf5\x28|
rarity 8
ports 17555,49152-49156
match vuze-dht m|^\0\0\x04\x01\0U\xab\xec\xff\xf0\x97\r\.`\xd1o..........|s p/Vuze/ cpe:/a:azureus:vuze/

##############################NEXT PROBE##############################
# PC-Anywhere probe
Probe UDP pc-anywhere q|NQ|
rarity 8
ports 5632
match pc-anywhere m|^NR([^_]*)_*AHM_3___\0$|s p/Symantec pcAnywhere/ i/Servername: $1/ cpe:/a:symantec:pcanywhere/

##############################NEXT PROBE##############################
# PC-DUO host probe
Probe UDP pc-duo q|\0\x80\x80\x08\xff\0|
rarity 8
ports 1505
match pc-duo m|^.........(.*)\0|s p/Vector PC-Duo/ i/Servername: $1/

##############################NEXT PROBE##############################
# PC-DUO Gateway probe
Probe UDP pc-duo-gw q|\x20\x90\x80\x08\xff\0|
rarity 8
ports 2303
match pc-duo-gw m|^.........(.*)\0|s p/Vector PC-Duo Gateway Server/ i/Servername: $1/

##############################NEXT PROBE##############################
# Redis key-value store
Probe TCP redis-server q|*1\r\n$4\r\ninfo\r\n|
rarity 8
ports 6379
match redis m|-ERR operation not permitted\r\n|s p/Redis key-value store/ cpe:/a:redislabs:redis/
match redis m|^\$\d+\r\n(?:#[^\r\n]*\r\n)*redis_version:([.\d]+)\r\n|s p/Redis key-value store/ v/$1/ cpe:/a:redislabs:redis:$1/

##############################NEXT PROBE##############################
# Memcached distributed memory object caching system
Probe UDP memcached q|\0\x01\0\0\0\x01\0\0stats\r\n|
rarity 8
ports 11211
match memcached m|^\0\x01\0\0\0\x01\0\0STAT pid \d+\r\nSTAT uptime \d+\r\nSTAT time \d+\r\nSTAT version ([.\d]+)\r\n|s p/Memcached/ v/$1/ cpe:/a:memcached:memcached:$1/
match memcached m|^\0\x01\0\0\0\x01\0\0STAT pid \d+\r\nSTAT uptime \d+\r\nSTAT time \d+\r\nSTAT version ([.\d]+) \(?Ubuntu\)?\r\n|s p/Memcached/ v/$1/ i/Ubuntu/ o/Linux/ cpe:/a:memcached:memcached:$1/ cpe:/o:canonical:ubuntu_linux/ cpe:/o:linux:linux_kernel/a
# May as well softmatch to avoid further probing
softmatch memcached m|^\0\x01\0\0\0\x01\0\0STAT |

##############################NEXT PROBE##############################
# Sends a ServerInfo PBC request to the Basho Riak distributed database
Probe TCP riak-pbc q|\0\0\0\x01\x07|
rarity 8
ports 8087
match riak-pbc m|^....\x08..(riak@[\w._-]+)..([\w._-]+)$|s p/Basho Riak/ v/$2/ h/$1/

##############################NEXT PROBE##############################
# Sends a ServerInfo PBC request to the Basho Riak distributed database
Probe TCP tarantool q|show info\r\n|
rarity 8
ports 9001,33015
match tarantool m|---\r\ninfo:\r\n  version: \"([^\"]*)\"\r\n  uptime: (\d*)\r\n  pid: (\d*)\r\n  (?:[._\w\s]*: .*\r\n)*  config: \"([^\"]*)\"| p/Tarantool/ v/$1/ i/Uptime: $2, PID: $3, Config: $4/

match haproxy-stats m|^Name: HAProxy\nVersion: (\d[\w._~+-]*)\n.*\nUptime: (.+)\n|s p/HAProxy stats socket/ v/$1/ i/uptime: $2/ cpe:/a:haproxy:haproxy:$1/

##############################NEXT PROBE##############################
# Sends a stats request to a Couchbase Membase server
Probe TCP couchbase-data q|\x80\x10\0\0\0\0\0\0\0\0\0\0\x15\xf0\xd1\x62\0\0\0\0\0\0\0\0|
rarity 8
ports 11210
match couchbase-tap m|^\x81\x10..\0\0\0\0\0\0\0.....\0\0\0\0\0\0\0\0ep_version([._\w]+).*ep_dbname([_\\\/\w\s:]+)|s p/Couchbase Membase/ v/$1/ i/DB name: $2/
match couchbase-tap m|^\x81\x10..\0\0\0\0\0\0\0.....\0\0\0\0\0\0\0\0ep_version([._\w]+)|s p/Couchbase Membase/ v/$1/

##############################NEXT PROBE##############################
# Sends a Get all registered names probe to the EPMD daemon
Probe TCP epmd q|\0\x01\x6e|
rarity 8
ports 4369
match epmd m|^\0\0\x11\x11| p/Erlang Port Mapper Daemon/

##############################NEXT PROBE##############################
# Voldemort Native Protocol Version 3 connect probe
Probe TCP vp3 q|vp3|
rarity 8
ports 6666
match vp3 m|^ok$| p/Voldemort/

##############################NEXT PROBE##############################
# Kumofs kumo-server version probe
Probe TCP kumo-server q|\x94\0\xcd\xef\xd1\x61\x91\x03|
rarity 8
ports 3333,19800,19700,59100
match kumo-server m|^\x94\x01\xcd\xef\xd1\xc0\xda\0.([^\s]+)|s p/Kumofs/ v/$1/
match kumo-manager m|^\x94\x01\xcd\xef\xd1\x05\xc0$| p/Kumofs/

match dec-notes m|^\x7c\0\0\0\x01\0\x1f\x83\x01\x80\x1f\x86\x013%NOTES-E-SRV_INVSEQ, invalid sequence of operations\0\0\x1f\x83\x01\x80\x1f\x86\x013%NOTES-E-SRV_INVSEQ, invalid sequence of operations\0\0| p/DEC Notes/ o/VMS/

match directfb m|^\x1c\0\0\0\0\0\0\0\x02\0\0\0\xd1a\x91\x03\x05\0\0\0\0\0\0\0\0\0\0\0|

# TODO: get more samples
match rhpp m|^\0\0\0\x80\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xc0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x80j\x81n0\x81k\xa1\x03\x02\x01\x05\xa2\x03\x02\x01\n\xa4\x81\^0\\\xa0\x07\x03\x05\0P\x80\0\x10\xa2\x04\0\x80\xc8\x10\xa3\x170\x15\xa0\x03\x02\x01\0\xa1\x0e0\x0c\x1b\x06k\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1f\x1e\xb9\xd9\xa8\x170\x15\x02\x01\x12\x02\x01\x11\x02\x01\x10\x02\x01\x17\x02\x01\x01\x02\x03\x01\xff\0\0\0\0\0\0\0\0\0\0\0\0\0| p/Ricoh Reliability Host Printing Protocol/ d/printer/

match upnp m|^HTTP/0\.0 \d\d\d (?:[^\r\n]*\r\n(?!\r\n))*?SERVER: Linux/([-+\w_.]+), UPnP/([\d.]+), Intel SDK for UPnP devices ?/([\w._~-]+)\r\n|s p/Intel UPnP reference SDK/ v/$3/ i/Linux $1; UPnP $2/ o/Linux/ cpe:/o:linux:linux_kernel:$1/

##############################NEXT PROBE##############################
# Metasploit msgpack-based RPC. https://community.rapid7.com/docs/DOC-1516
Probe TCP metasploit-msgrpc q|GET /api HTTP/1.0\r\n\r\n|
rarity 9
# http://seclists.org/nmap-dev/2012/q2/971
ports 50505,55552
sslports 3790
match metasploit-msgrpc m|^HTTP/1\.1 200 OK\r\nContent-Type: binary/message-pack\r\nConnection: close\r\nServer: Rex\r\nContent-Length: 1084\r\n\r\n\x85\xa5error\xc3\xaberror_class\xadArgumentError\xacerror_string\xbdInvalid Request Verb: '\"GET\"'\xaferror_backtrace\xdc\x00\x12\xda\x000lib/msf/core/rpc/v10/service\.rb:107:in `process'\xda\x006lib/msf/core/rpc/v10/service\.rb:88:in `on_request_uri'\xda\x006lib/msf/core/rpc/v10/service\.rb:70:in `block in start'\xda\x00/lib/rex/proto/http/handler/proc\.rb:37:in `call'\xda\x005lib/rex/proto/http/handler/proc\.rb:37:in `on_request'\xda\x00| p/Metasploit Remote API/ v/4.4.0-dev/

##############################NEXT PROBE##############################
# svrloc
Probe UDP svrloc q|\x02\x01\x00\x006 \x00\x00\x00\x00\x00\x01\x00\x02en\x00\x00\x00\x15service:service-agent\x00\x07default\x00\x00\x00\x00|
rarity 8
ports 427
match svrloc m|^\x02\x0b| p/Service Location Protocol/ v/2/

##############################NEXT PROBE##############################
# Hazelcast In-Memory Data Grid >= 1.9-RC http://www.hazelcast.com/
# http://seclists.org/nmap-dev/2013/q2/7
Probe TCP hazelcast-http q|GET /hazelcast/rest/cluster HTTP/1.0\r\n\r\n\r\n|
rarity 9
ports 5701-5709
# Sample:
# |HTTP/1\.1 200 OK\r\nContent-Length: 114\r\n\r\nCluster \[2\] {\n\tMember \[127\.0\.0\.1\]:5701 this\n\tMember \[127\.0\.0\.1\]:5702\n}\n\nConnectionCount: 1\nAllConnectionCount: 95\n\r\n|
match hazelcast m|^HTTP/1\.1 200 OK\r\nContent-Length: \d+\r\n\r\nCluster \[\d+\] {\n\tMember (.*?)}\n\nConnectionCount: (\d+)\nAllConnectionCount: (\d+)\n\r\n$|s p/Hazelcast/ i/ConnectionCount $2; AllConnectionCount $3; $SUBST(1,"\n\tMember",",")/ cpe:/a:hazelcast:hazelcast/


##############################NEXT PROBE##############################
# Minecraft Server List Ping http://mc.kev009.com/Server_List_Ping
Probe TCP minecraft-ping q|\xFE\x01|
rarity 8
ports 25565

# Fields are Protocol version, Software version, motd, current player count, max players
match minecraft m|^\xff\x00.\x00\xa7\x00\x31\x00\x00(.+?)\x00\x00(.+?)\x00\x00(.+?)\x00\x00(.+?)\x00\x00(.+)|s p/Minecraft/ v/$P(2)/ i|Protocol: $P(1), Message: $P(3), Users: $P(4)/$P(5)|

match minecraft-classic m|^\x01\x01\x0eUnhandled message id "254"! {37}| p/MCGalaxy Minecraft server/

##############################NEXT PROBE##############################
# Sends a distribution handshake to an Erlang Distribution Node.
# send_name request of protocol version 0, with only capability flags
# DFLAG_EXTENDED_REFERENCES and DFLAG_EXTENDED_PIDS_PORTS, and with a node name
# of "nm@p"
# http://erlang.org/doc/apps/erts/erl_dist_protocol.html#id90729
# http://seclists.org/nmap-dev/2013/q1/360
Probe TCP erlang-node q|\0\x0bn\0\0\0\0\x01\x04nm@p|
rarity 9

match erlang-node m|^\0\x03sok\0.n\0\0.{8}(.+).|s p/Erlang Distribution Node/ i/Node name: $1/
match erlang-node m|^\0[^\x03]s(.+)|s p/Erlang Distribution Node/ i/Status: $1/


##############################NEXT PROBE##############################
# UDP ping. "abcdefgh" is an identifier. See
# http://mumble.sourceforge.net/Protocol.
# http://seclists.org/nmap-dev/2013/q2/413
Probe UDP Murmur q|\0\0\0\0abcdefgh|
rarity 9
ports 64738

match murmur m|^\0...abcdefgh............$|s p/Murmur/ v/1.2.X/


##############################NEXT PROBE##############################
# Ventrilo 2.1.2+
# UDP general status request (encrypted).
# See http://aluigi.altervista.org/papers.htm#ventrilo
# http://seclists.org/nmap-dev/2013/q2/413
Probe UDP Ventrilo q|\x01\xe7\xe5\x75\x31\xa3\x17\x0b\x21\xcf\xbf\x2b\x99\x4e\xdd\x19\xac\xde\x08\x5f\x8b\x24\x0a\x11\x19\xb6\x73\x6f\xad\x28\x13\xd2\x0a\xb9\x12\x75|
rarity 9
ports 3784

match ventrilo m|^.{111}|s p/Ventrilo/ v/2.1.2+/


##############################NEXT PROBE##############################
# TeamSpeak 2 TCPQuery "ver" command.
# http://seclists.org/nmap-dev/2013/q2/413
Probe TCP teamspeak-tcpquery-ver q|ver\r\n|
rarity 9
ports 51234,9998

match teamspeak-tcpquery m|^\[TS\]\r\n([\w._-]+) Win32 ([\w._-]+)\r\nOK\r\n$| p/TeamSpeak 2 TCPQuery/ v/$1/ i/$2/ o/Windows/ cpe:/a:teamspeak:teamspeak2:$1/ cpe:/o:microsoft:windows/a
match teamspeak-tcpquery m|^\[TS\]\r\n([\w._-]+) Linux ([\w._-]+)\r\nOK\r\n$| p/TeamSpeak 2 TCPQuery/ v/$1/ i/$2/ o/Linux/ cpe:/a:teamspeak:teamspeak2:$1/ cpe:/o:linux:linux_kernel/a

match uptime-agent m|^up.time agent ([\d.]+) \(build (\d+)\) linux\n| p/Idera Uptime Infrastructure Monitor/ v/$1/ i/build $2/ o/Linux/ cpe:/a:idera:uptime_infrastructure_monitor:$1/ cpe:/o:linux:linux_kernel/a
match uptime-agent m|^up.time agent ([\d.]+) \(build (\d+)\) ([\w._-]+)\n| p/Idera Uptime Infrastructure Monitor/ v/$1/ i/build $2/ o/$3/ cpe:/a:idera:uptime_infrastructure_monitor:$1/

##############################NEXT PROBE##############################
# Login request.
# See http://wiki.wireshark.org/TeamSpeak2
# http://seclists.org/nmap-dev/2013/q2/413
Probe UDP TeamSpeak2 q|\xf4\xbe\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x32\x78\xba\x85\x09\x54\x65\x61\x6d\x53\x70\x65\x61\x6b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0a\x57\x69\x6e\x64\x6f\x77\x73\x20\x58\x50\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x20\x00\x3c\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x6e\x69\x63\x6b\x6e\x61\x6d\x65\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|
rarity 9
ports 8767

# Offset  Type   Value                  Comment
# 0-1     uint16 0xBEF4                 Class: connection
# 2-3     uint16 0x0004                 Type: login reply
# 4-7     uint32 0                      Session key; zero on first reply
# 8-11    uint32 client id
# 12-15   uint32 2                      Sequence number; 2 on first reply
# 16-19   uint32 some crc32 checksum
# 20      uint8  server name length
# 21-49   string server name
# 50      uint8  platform length
# 51-79   string platform
# 80-81   uint16 1. version             E.g. the "2" in "2.0.23.19"
# 82-83   uint16 2. version             E.g. the "0" in "2.0.23.19"
# 84-85   uint16 3. version             E.g. the "23" in "2.0.23.19"
# 86-87   uint16 4. version             E.g. the "19" in "2.0.23.19"
# 88-179  bytes  unknown
# 180     uint8  welcome message length
# 181-435 string welcome message

match teamspeak2 m|^\xf4\xbe\x04\x00\x00\x00\x00\x00....\x02\x00\x00\x00.....([^\0]+)\0*.Win32\0*\x02\x00\x00\x00\x17\x00\x13\x00|s p/TeamSpeak 2/ v/2.0.23.19/ i/name: $1; no password/ o/Windows/ cpe:/a:teamspeak:teamspeak2:2.0.23.19/ cpe:/o:microsoft:windows/
match teamspeak2 m|^\xf4\xbe\x04\x00\x00\x00\x00\x00....\x02\x00\x00\x00.....([^\0]+)\0*.Linux\0*\x02\x00\x00\x00\x17\x00\x13\x00|s p/TeamSpeak 2/ v/2.0.23.19/ i/name: $1; no password/ o/Linux/ cpe:/a:teamspeak:teamspeak2:2.0.23.19/ cpe:/o:linux:linux_kernel/
match teamspeak2 m|^\xf4\xbe\x04\x00\x00\x00\x00\x00....\x02\x00\x00\x00....\0{60}.{356}$|s p/TeamSpeak 2/ cpe:/a:teamspeak:teamspeak2/


##############################NEXT PROBE##############################
# UDP login request (encrypted)
# http://seclists.org/nmap-dev/2013/q3/72
Probe UDP TeamSpeak3 q|\x05\xca\x7f\x16\x9c\x11\xf9\x89\x00\x00\x00\x00\x02\x9d\x74\x8b\x45\xaa\x7b\xef\xb9\x9e\xfe\xad\x08\x19\xba\xcf\x41\xe0\x16\xa2\x32\x6c\xf3\xcf\xf4\x8e\x3c\x44\x83\xc8\x8d\x51\x45\x6f\x90\x95\x23\x3e\x00\x97\x2b\x1c\x71\xb2\x4e\xc0\x61\xf1\xd7\x6f\xc5\x7e\xf6\x48\x52\xbf\x82\x6a\xa2\x3b\x65\xaa\x18\x7a\x17\x38\xc3\x81\x27\xc3\x47\xfc\xa7\x35\xba\xfc\x0f\x9d\x9d\x72\x24\x9d\xfc\x02\x17\x6d\x6b\xb1\x2d\x72\xc6\xe3\x17\x1c\x95\xd9\x69\x99\x57\xce\xdd\xdf\x05\xdc\x03\x94\x56\x04\x3a\x14\xe5\xad\x9a\x2b\x14\x30\x3a\x23\xa3\x25\xad\xe8\xe6\x39\x8a\x85\x2a\xc6\xdf\xe5\x5d\x2d\xa0\x2f\x5d\x9c\xd7\x2b\x24\xfb\xb0\x9c\xc2\xba\x89\xb4\x1b\x17\xa2\xb6|
rarity 9
ports 9987

# These are the bytes in common, but a lot of the bytes are close in value
# #match ts3 m|^........\x00\x00\x02......\xef.....\x19|s p/TeamSpeak 3 server/
match ts3 m|^........\x00\x00\x02\x97\x76\x8b\x54\xad\x79\xe3\xaf\x87\xeb\xaa\x1a\x19\xba\xcf\x41\xe0\x16\xa2\x32\x6c\xf3\xcf\xf4\x8e\x3c\x44\x83\xc8\x8d\x51\x45\x6f\x90\x95\x23\x33\x08\x86\x2d\x40|s p/TeamSpeak 3 server/ cpe:/a:teamspeak:teamspeak3/
match ts3 m|^........\x00\x00\x02\x9bj\x90O\xb6/\xef\xb3\xca\xbf\xf6L\x19\xb6\xd0V\xb5\x14\xf33Y\xdc\xd4\xf8\xcd\x12n\xc2\xcb\x8c\x15\x19T\xde\xc7v%\t\x938\x18\(\xd3W\xc4U\xdc\xd5m\xf7Z\xcd~@\x8e\x8fN\x97h|s p/TeamSpeak 3 server/ cpe:/a:teamspeak:teamspeak3/

##############################NEXT PROBE##############################
# xmlsysd info request
# http://www.phy.duke.edu/~rgb/brahma/Resources/xmlsysd.php
Probe TCP xmlsysd q|init\noff all\non identity version\nsend\nquit\n|
rarity 9
ports 7887

match xmlsysd m|^Content-Length: [0-9]+\n\n<\?xml version=\"1\.0\"\?>\s*<xmlsysd init=\"1\">\s*<system>\s*<identity>\s*<hostname>([^<]*)</hostname>\s*<hostip>([^<]*)</hostip>\s*</identity>\s*</system>\s*<proc>\s*<version>([^<]*)</version>\s*</proc>\s*</xmlsysd>|s p/xmlsysd daemon/ i/IP: $2/ o/$3/ h/$1/ cpe:/a:wulfware:xmlsysd/

##############################NEXT PROBE##############################
# Freelancer game server status query
# http://sourceforge.net/projects/gameq/
# (relevant files: games.ini, packets.ini, freelancer.php)
Probe UDP FreelancerStatus q|\x00\x02\xf1\x26\x01\x26\xf0\x90\xa6\xf0\x26\x57\x4e\xac\xa0\xec\xf8\x68\xe4\x8d\x21|
rarity 9
ports 2302

match freelancer m|^\x00\x03\xf1\x26.{88}(.*)\0\0(?:.*?:){5}(.*)\0\0$|s p/Freelancer/ i/name: $P(1); description: $P(2)/

# All-Seeing Eye service provided by some game servers for querying
# the server's status
# For more info on the protocol see:
# http://int64.org/docs/gamestat-protocols/ase.html
# http://aluigi.altervista.org/papers.htm#ase
# http://sourceforge.net/projects/gameq/
# (relevant files: games.ini, packets.ini, ase.php)
Probe UDP ASE q|s|
rarity 9
ports 1258,2126,3123,12444,13200,23196,26000,27138,27244,27777,28138

match allseeingeye m=^EYE1.(.*?)(\x02\d|\x03\d{2}|\x04\d{3}|\x05\d{4}|\x06\d{5})=s p/All-Seeing Eye/ i/game: $1; port: $P(2)/

##############################NEXT PROBE##############################
Probe UDP AndroMouse q|AMSNIFF|
rarity 9
ports 8888

match AndroMouse m|^GOTBACK$|s p/AndroMouse Android remote mouse server/

##############################NEXT PROBE##############################
Probe UDP AirHID q|from:airhid|
rarity 9
ports 13246

match AirHID m|^andReceiver-\d+\.\d+\.\d+$|s p/AirHID Andrioid remote mouse server/

##############################NEXT PROBE##############################
Probe UDP NetMotionMobility q|\0\x40\x50\0\0\0\0\x85\x5d\xb4\x91\x28\0\0\0\0\0\x01\x7c\x91\x40\0\0\0\xaa\x39\xda\x42\x37\x65\xcf\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0|
rarity 7
ports 5008
match NetMotionMobility m|^\0\x40\x51\0\0\0\0| p/NetMotion Mobility VPN/

##############################NEXT PROBE##############################
# Queries Docker APIs for the /version url containing version information.
# https://docs.docker.com/reference/api/docker_remote_api/
#
Probe TCP docker q|GET /version HTTP/1.1\r\n\r\n|
rarity 8
ports 2375,2379,2380
sslports 2376

match docker m|^HTTP/1\.1 200 OK\r\nContent-Type: application/json\r\nJob-Name: version\r\nDate: .*\r\nContent-Length: \d+\r\n\r\n{.*\"ApiVersion\":\"([^"]+)\",.*\"KernelVersion\":\"([^"]+)\",.*\"Os\":\"([^"]+)\",.*\"Version\":\"([^"]+)\"| p/Docker remote API/ v/$4/ i/API $1; KernelVersion $2/ o/$3/ cpe:/a:docker:docker:$4/
# Ordering doesn't matter, we'd like to at least grab ApiVersion and Version
match docker m|^HTTP/1\.1 200 OK\r\nContent-Type: application/json\r\nJob-Name: version\r\nDate: .*\r\nContent-Length: \d+\r\n\r\n{.*\"ApiVersion\":\"([^"]+)\",.*\"Version\":\"([^"]+)\"| p/Docker remote API/ v/$2/ i/API $1/ cpe:/a:docker:docker:$2/
match docker m|^HTTP/1\.1 200 OK\r\nContent-Type: application/json\r\nJob-Name: version\r\nDate: .*\r\nContent-Length: \d+\r\n\r\n{.*\"Version\":\"([^"]+)\",.*\"ApiVersion\":\"([^"]+)\"| p/Docker remote API/ v/$1/ i/API $2/ cpe:/a:docker:docker:$1/
# Similar to above, but without the Job-Name header.
match docker m|^HTTP/1\.1 200 OK\r\nContent-Type: application/json\r\nServer: Docker.*\r\nDate: .*\r\nContent-Length: \d+\r\n\r\n{.*\"Version\":\"([^"]+)\",.*\"ApiVersion\":\"([^"]+)\",.*\"Os\":\"([^"]+)\",.*\"KernelVersion\":\"([^"]+)\"| p/Docker remote API/ v/$1/ i/API $2; KernelVersion $4/ o/$3/ cpe:/a:docker:docker:$1/
match docker m|^HTTP/1\.1 200 OK\r\nContent-Type: application/json\r\nServer: Docker.*\r\nDate: .*\r\nContent-Length: \d+\r\n\r\n{.*\"Version\":\"([^"]+)\",.*\"ApiVersion\":\"([^"]+)\"| p/Docker remote API/ v/$1/ i/API $2/ cpe:/a:docker:docker:$1/

# API spec only lists Version, GoVersion, ApiVersion (in API >= 1.12), and GitCommit.
# Assuming the above matches will get ApiVersion if it's present, this one can report ApiVersion <= 1.11
match docker m|^HTTP/1\.1 200 OK\r\nContent-Type: application/json\r\nJob-Name: version\r\nDate: .*\r\nContent-Length: \d+\r\n\r\n{.*\"Version\":\"([^"]+)\"| p/Docker remote API/ v/$1/ i/API 1.11 or older/ cpe:/a:docker:docker:$1/


##############################NEXT PROBE##############################
# VERSIONS cell indicating support for protocol versions 3, 4, 5, and 6.
# https://spec.torproject.org/torspec (see sections 3 and 4.1)
# Version 6 doesn't exist as of 2018, but send it in the hope of
# catching a future change.
# Structure is:
#   CircID       2 bytes
#   Command (7)  1 byte
#   Length       2 bytes
#   array of 2-byte version numbers
# We can't detect protocol versions 1 and 2, because those require you to
# do the SSL handshake in a particular way (version 1 requires you to use
# specific ciphersuites and send a client certificate ("the v1 handshake")
# and version 2 requires a renegotiation after the initial handshake ("the
# v2 handshake")).
Probe TCP tor-versions q|\x00\x00\x07\x00\x08\x00\x03\x00\x04\x00\x05\x00\x06|
rarity 8
sslports 443,9001,9002

# Since 0.3.1.1-alpha - 2017-05-22
# https://gitweb.torproject.org/tor.git/tree/ChangeLog: "adds some
# basic padding to resist netflow-based traffic analysis"
# https://bugs.torproject.org/16861
# https://gitweb.torproject.org/torspec.git/tree/proposals/251-netflow-padding.txt
# https://gitweb.torproject.org/torspec.git/tree/proposals/254-padding-negotiation.txt
match tor-orport m|^\x00\x00\x07\x00\x06\x00\x03\x00\x04\x00\x05| p/Tor/ v/0.3.1.1 or later/ i/supported protocol versions: 3, 4, 5/ cpe:/a:torproject:tor/

# Since 0.2.4.11-alpha - 2013-03-11.
# https://gitweb.torproject.org/tor.git/tree/ChangeLog: "Support a new version
# of the link protocol that allows 4-byte circuit IDs."
# https://bugs.torproject.org/7351
# https://gitweb.torproject.org/torspec.git/tree/proposals/214-longer-circids.txt
match tor-orport m|^\x00\x00\x07\x00\x04\x00\x03\x00\x04| p/Tor/ v/0.2.4.11 - 0.3.1.1/ i/supported protocol versions: 3, 4/ cpe:/a:torproject:tor/

# 0.2.3.6-alpha - 2011-10-26
# https://gitweb.torproject.org/tor.git/tree/ChangeLog: "This release also
# features support for a new v3 connection handshake protocol..."
#
# Also matches this independent JavaScript implementation: https://github.com/Ayms/node-Tor
# You can distinguish node-Tor from mainstream tor because it sends a response
# with version 3 even if you indicate client support for only versions 1 and 2.
# But that requires sending another version probe.
match tor-orport m|^\x00\x00\x07\x00\x02\x00\x03| p/Tor/ v/0.2.3.7 - 0.2.4.11/ i/supported protocol versions: 3/

# An independent implementation that "only returns the highest
# understood version matching what the server supports, instead of a
# list of all supported versions."
# https://github.com/tvdw/gotor
# https://lists.torproject.org/pipermail/tor-dev/2015-January/008135.html
match tor-orport m|^\x00\x00\x07\x00\x02\x00\x04| p/GoTor/ i/supported protocol versions: 4/

##############################NEXT PROBE##############################
# TLS with Pre-Shared Key handshake, generated by NSE's tls.lua
# SSL services that only support PSK will not respond to other probes.
# http://seclists.org/nmap-dev/2015/q2/47
Probe TCP TLS-PSK q|\x16\x03\x00\x00u\x01\x00\x00q\x03\x03U8*bETXSJDSZNHMDFAONDKJXXZYZHWHR\x00\x000\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb2\x00\xb3\x00\xb6\x00\xb7\x01\x00\x00\x18\x00\r\x00\x14\x00\x12\x00\x01\x00\x02\x00\x03\x01\x01\x01\x02\x01\x03\x02\x01\x02\x02\x02\x03|
rarity 9
ports 27036

match ssl/steam m|^\x16\x03\x03\0.\x02\0\0.\x03\x03.*\x16\x03\x03\0\x0b\x0c\0\0\x07\0\x05steam|s p/Valve Steam In-Home Streaming service/ i/TLSv1.2 PSK/

match ssl m=^\x16\x03[\0-\x03]..\x02\0\0.\x03[\0-\x03].*\x16\x03[\0-\x03]\0.\x0c.....(.+?)(?:\x16\x03[\0-\x03]|$)=s p/TLS PSK/ i/PSK identity hint: $P(1)/

# SSLv3 - TLSv1.3 Alert
match ssl m|^\x15\x03[\0-\x04]\0\x02[\x01\x02].$|s

##############################NEXT PROBE##############################
# Queries z/OS Network Job Entry
# Sends an NJE Probe with the following information (text is converted to EBCDIC):
# TYPE        = OPEN
# OHOST       = FAKE
# RHOST       = FAKE
# RIP and OIP = 0.0.0.0
# R           = 0
# Based on http://www-01.ibm.com/support/knowledgecenter/SSLTBW_2.1.0/com.ibm.zos.v2r1.hasa600/init.htm
Probe TCP NJE q|\xd6\xd7\xc5\xd5@@@@\xc6\xc1\xd2\xc5@@@@\0\0\0\0\xc6\xc1\xd2\xc5@@@@\0\0\0\0\0|
rarity 9
ports 175
sslports 2252
# If the port supports NJE it will respond with either a 'NAK' or 'ACK' in EBCDIC
match nje m|^\xd5\xc1\xd2| p/IBM Network Job Entry (JES)/
match nje m|^\xc1\xc3\xd2| p/IBM Network Job Entry (JES)/

##############################NEXT PROBE##############################
# Detects TN3270 Servers which send IAC DO TTYPE on initial connection
# instead of IAC DO TN3270E
Probe TCP tn3270 q|\xff\xfb\x18\xff\xfa\x18\x00IBM-3279-4-E\xff\xf0\xff\xfb\x19\xff\xfd\x19\xff\xfb\0\xff\xfd\0|
rarity 8
ports 23,2323,2023,623
sslports 992

# IAC DO TERMINAL TYPE, IAC SB TERMINAL TYPE SEND SE, .*, IAC DO EOR
match tn3270 m|^\xff\xfd\x18\xff\xfa\x18\x01\xff\xf0.*?\xff\xfd\x19| p/IBM Telnet TN3270/ i/traditional tn3270/

match telnet m|^\xff\xfd\x18\xff\xfa\x18\x01\xff\xf0\xff\xfb\x01\xff\xfb\x03\xff\xfd\x01\r\n\r\nSunOS UNIX \(([^)]+)\)\r\n\r\0\r\n\r\0login: | p/SunOS telnetd/ o/SunOS/ h/$1/ cpe:/o:sun:sunos/a
match telnet m|^\xff\xfd\x18\xff\xfa\x18\x01\xff\xf0\xff\xfb\x01\xff\xfb\x03\xff\xfd\x01\r\n\r\nUltrix(?:-32)? V([\d.]+) \(Rev\.? (\d+)\) \(([^)]+)\)\r\n\r\r\n\rlogin: |i p/Ultrix telnetd/ o/Ultrix $1/ h/$3/ cpe:/o:dec:ultrix:$1:$2/
match telnet m|^\xff\xfb\x01\xff\xfb\x03\xff\xfd\x18\xff\xfa\x18\x01\xff\xf0\x1b\[;H\x1b\[2JTERM=ibm-3279-4-e\r\n         C{10}      hh       YYYY      YYYY {13}\r\n| p/ChiYu HandPunch attendance software telnetd/ cpe:/a:chiyu:handpunch/

# Softmatch because we can get way more specific with most of these.
softmatch telnet m|^\xff\xfd\x18\xff\xfa\x18\x01\xff\xf0\xff\xfb\x01\xff\xfb\x03\xff\xfd\x01| p/2.11BSD-derived telnetd/ o/Unix/

##############################NEXT PROBE##############################
# CORBA GIOP (General Inter-ORB Protocol)
# GIOP Header:
# - Magic: GIOP
# - Version: 1.0 (\x01\x00)
# - Msge type: Request (\x00)
# - Msg size: 36 ($\x00\x00\x00 i.e \x24\x00\x00\x00)
# Request Data:
# - ServiceContextList (\x00\x00\x00\x00)
# - Request Id: 1 (\x01\x00\x00\x00)
# - Response expected: 1 (\x01)
# - Object key Length: 6 (\x06x\00\x00\x00)
# - Object Key: 616263646566
# - Operation length : 4 (\x04\x00\x00\x00)
# - Req Operation: get (i.e \x67\x65\x74\x00)
# - Requesting Principal Length: 0 (\x00\x00\x00\x00)
Probe TCP giop q|GIOP\x01\x00\x01\x00$\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x06\x00\x00\x00abcdef\x00\x00\x04\x00\x00\x00get\x00\x00\x00\x00\x00|
# rarity 7 because it has been observed on non-standard ports
rarity 7
ports 2481
sslports 2482

# Filemaker Pro Advanced 11
match giop m|^GIOP\x01\0\x01\x01@\0\0\0\0\0\0\0\x01\0\0\0\x02\0\0\0'\0\0\0IDL:omg\.org/CORBA/OBJECT_NOT_EXIST:1\.0\0| p/omg.org CORBA naming service/
# Mitel networks IIOP
match giop m|^GIOP\x01\0\0\x01\0\0\0@\0\0\0\0\0\0\0\x01\0\0\0\x02\0\0\0'IDL:omg\.org/CORBA/OBJECT_NOT_EXIST:1\.0\0\0OM\0\x02\0\0\0\x01| p/omg.org CORBA naming service/
softmatch giop m|^GIOP\x01\x00\x01\x01........\x01\x00\x00\x00|
softmatch giop m|^GIOP.*IDL:omg\.org|s

match iscsi m|^#\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x02\0\0\0\0\0\0\0\0\0\0\0| p/Synology DSM iSCSI/

##############################NEXT PROBE##############################
# P_CONTROL_HARD_RESET_CLIENT_V2
Probe TCP OpenVPN q|\0\x0e87\xa5&\x08\xa2\x1b\xa0\xb1\0\0\0\0\0|
ports 1194,443,500
rarity 9
match openvpn m|^\0\x1a@........\x01\0\0\0\x007\xa5&\x08\xa2\x1b\xa0\xb1\0\0\0\0$| p/OpenVPN/
# No version info submitted; update to hard match when it's available
softmatch openvpn m|^\0\x1e@........\x02\0\0\0\0\0\0\0\x007\xa5&\x08\xa2\x1b\xa0\xb1\0\0\0\0\0\x0e@........\0\0\0\0\0|


##############################NEXT PROBE##############################
# P_CONTROL_HARD_RESET_CLIENT_V2
Probe UDP OpenVPN q|8d\xc1x\x01\xb8\x9b\xcb\x8f\0\0\0\0\0|
ports 1194,443,500
rarity 9
match openvpn m|^@........\x01\0\0\0\0d\xc1x\x01\xb8\x9b\xcb\x8f\0\0\0\0|s p/OpenVPN/
# INVALID-MAJOR-VERSION
softmatch isakmp m|^................\x0b\x10\x05\0\0\0\0\0\0\0\0\(\0\0\0\x0c\0\0\0\x01\x01\0\0\x05|

##############################NEXT PROBE##############################
# Phoenix Contact PCWorx
Probe TCP pcworx q|\x01\x01\x00\x1a\x00\x00\x00\x00x\x80\x00\x03\x00\x0cIBETH01N0_M\x00|
rarity 9
ports 1962

match pcworx m|\x81\x01\0\x14\0\0\0\x01\0\0\0\0\0\x02\0\0\0.\0\0| p/Phoenix Contact PCWorx/

##############################NEXT PROBE##############################
# ProConOs protocol
Probe TCP proconos q|\xcc\x01\x00\x0b\x40\x02\x00\x00\x47\xee|
rarity 9
ports 20547

match proconos m|^\xcc\x01...\x02\x92\0V\d+\.\d+ProConOS V([\d.]+) \w\w\w +\d+ \d+\0+\0([^\0]+)\0+([^\0]+)\0+([^\0]+)\0+([^\0]+)\0|s p/ProConOS/ v/$1/ i|PLC: $2; project: $3/$4; source: $5|
match echo m|^\xcc\x01\0\x0b@\x02\0\0G\xee|

##############################NEXT PROBE##############################
# Tridium Niagara Fox
Probe TCP niagara-fox q|fox a 1 -1 fox hello\n{\nfox.version=s:1.0\nid=i:1\n};;\n|
rarity 9
ports 1911
sslports 4911

match niagara-fox m|^fox a 0 -1 fox hello\n\{\nfox\.version=s:([\d.]+)\nid=i:\d+.*\napp\.name=s:Station\napp\.version=s:([\d.]+)\n|s p/Tridium Niagara/ v/$2/ i/fox version $1/ cpe:/a:tridium:niagara:$2/
softmatch niagara-fox m|^fox a 0|

##############################NEXT PROBE##############################
# MQTT v3.1.1 CONNECT
Probe TCP mqtt q|\x10\x10\x00\x04MQTT\x04\x02\x00\x1e\x00\x04nmap|
rarity 9
ports 1883
sslports 8883

match mqtt m|^\x20\x02\x00.$|

##############################NEXT PROBE##############################
# RMCP Get Channel Auth Capabilities
Probe UDP ipmi-rmcp q|\x06\0\xff\x07\0\0\0\0\0\0\0\0\0\x09\x20\x18\xc8\x81\0\x38\x8e\x04\xb5|
rarity 9
ports 623

softmatch asf-rmcp m|^\x06\0\xff\x07\0\0\0\0\0\0\0\0\0\x10|

##############################NEXT PROBE##############################
# CoAP GET .well-known/core
Probe UDP coap-request q|@\x01\x01\xce\xbb.well-known\x04core|
rarity 9
ports 5683
sslports 5684

softmatch coap m|^`E|

##############################NEXT PROBE##############################
# DTLS Client Hello. Dissection available in nmap-payloads
Probe UDP DTLSSessionReq q|\x16\xfe\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x36\x01\x00\x00\x2a\x00\x00\x00\x00\x00\x00\x00\x2a\xfe\xfd\x00\x00\x00\x00\x7c\x77\x40\x1e\x8a\xc8\x22\xa0\xa0\x18\xff\x93\x08\xca\xac\x0a\x64\x2f\xc9\x22\x64\xbc\x08\xa8\x16\x89\x19\x30\x00\x00\x00\x02\x00\x2f\x01\x00|
rarity 5
ports 443,853,4433,4740,5349,5684,5868,6514,6636,8232,10161,10162,12346,12446,12546,12646,12746,12846,12946,13046

# OpenSSL 1.1.0 s_server -dtls -listen
# HelloVerifyRequest always uses DTLS 1.1 version, per RFC 6347
match dtls m|^\x16\xfe\xff\0\0\0\0\0\0\0\0..\x03...\0\0\0\0\0...\xfe\xff.|
# Except when it doesn't? This was from IKEA's E1526 Trådfri Gateway, but could be anything.
match dtls m|^\x16\xfe\xfd\0\0\0\0\0\0\0\0..\x03...\0\0\0\0\0...\xfe\xfd.|
# ServerHello
match dtls m|^\x16\xfe[\xfd\xff]\0\0\0\0\0\0\0\0..\x02...\0\0\0\0\0...\xfe[\xfd\xff].|

#DTLS 1.0 alert: Handshake Failure
match dtls m|^\x15\xfe\xff\0\0\0\0\0\0\0\0..\x02\(\0\0\0\0\0|

##############################NEXT PROBE##############################
# Detects iperf3 servers by sending a string longer than the 37-byte test identifer or cookie
# https://github.com/esnet/iperf/wiki/IperfProtocolStates#test-initiation
Probe TCP iperf3 q|0000000000000000000000000000000000000\0\0\0\0|
ports 5201
rarity 9
match iperf3 m|^\t$|

##############################NEXT PROBE##############################
# QUIC initialization with random CID, advertising version Q999, which should elicit a version negotiation packet from the server
Probe UDP QUIC q|\r\x89\xc1\x9c\x1c*\xff\xfc\xf1Q999\x00|
ports 80,443
rarity 6

softmatch quic m|^\r\x89\xc1\x9c\x1c\*\xff\xfc\xf1((?:Q[0-8]\d\d)+)$| i/QUIC versions$SUBST(1,"Q",", Q")/

##############################NEXT PROBE##############################
# Detects ClamAV servers and possibly other services that respond to the string VERSION
Probe TCP VersionRequest q|VERSION|
ports 3310
rarity 8
match clam m|^ClamAV ([\w.]+)/(\w+)/(.+)$| p/ClamAV/ v/$1 ($2)/ i/AV definitions updated on:$3/

##############################NEXT PROBE##############################
# NoMachine Network Server
# Announce client version 5.6.7 (could be anything)
Probe TCP NoMachine q|NXSH-5.6.7\n|
ports 4000
rarity 9

match nomachine-nx m|^NXD-([\d.]+)\n| p/NoMachine NX Server remote desktop/ v/$1/ cpe:/a:nomachine:nx_server:$1/

##############################NEXT PROBE##############################
# JMON for z/OS (FMID HALG300)
Probe TCP JMON q|CONNECT01 v09\n|
rarity 9
ports 6715
sslports 6715

match jmon m|^ACKNOWLEDGE| p/JMON for zOS (FMID HALG300)/ o|z/OS| cpe:/a:ibm:zos_explorer/ cpe:/o:ibm:z%2fos/

##############################NEXT PROBE##############################
# LibreOffice Impress Remote Server
# Requests to pair a remote called "Nmap" with the pin 0000
Probe TCP LibreOfficeImpressSCPair q|LO_SERVER_CLIENT_PAIR\nNmap\n0000\n\n|
rarity 9
ports 1599
match impress-remote m|^LO_SERVER_VALIDATING_PIN\n$| p/LibreOffice Impress remote/ cpe:/a:libreoffice:libreoffice/

##############################NEXT PROBE##############################
# Apple Remote Desktop
Probe UDP ARD q|\0\x14\0\x01\x03|
rarity 8
ports 3283

# Need to figure out what is different between these versions:
match netassistant m|^\0\x01\x03\xea\x001\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x12\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0[^\0]([^\0]+)\0|s p/Apple Remote Desktop/ i/name: $P(1)/
match netassistant m|^\0\x01\x01d\x001\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x12\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0[^\0]([^\0]+)\0|s p/Apple Remote Desktop/ i/name: $P(1)/

##############################NEXT PROBE##############################
# LinuxSampler Control Protocol
# https://www.linuxsampler.org/api/draft-linuxsampler-protocol.html
Probe TCP LSCP q|GET SERVER INFO\r\n|
rarity 9
ports 8888

match lscp m|^DESCRIPTION: LinuxSampler - modular, streaming capable sampler\r\nVERSION: ([\d.]+)\r\nPROTOCOL_VERSION: ([\d.]+)\r\n| p/LinuxSampler/ v/$1/ i/LSCP $2/ cpe:/a:linuxsampler:linuxsampler:$1/

##############################NEXT PROBE##############################
# Hamlib rotctld get_info
# https://www.systutorials.com/docs/linux/man/8-rotctld/
Probe TCP rotctl q|get_info\n|
rarity 9
ports 4533

# Maybe rigctld also?
match rotctld m|^get_info: (.*)\nRPRT 0\n| p/Hamlib rotctld/ i/model: $1/

##############################NEXT PROBE##############################
# Ubiquiti Discovery Protocol
Probe UDP UbiquitiDiscoveryv1 q|\x01\0\0\0|
rarity 9
ports 10001

# Valid response is protocol version (\x01) and cmd (\0) followed
# by 2 bytes of length then TLV groups
match ubiquiti-discovery m|^\x01\0.[^\0].*\x0c\0\x06AirCam|s p/Ubiquiti Discovery Service/ i/v1 protocol, AirCam/ cpe:/h:ubnt:aircam:/
match ubiquiti-discovery m|^\x01\0.[^\0].*\x0c\0\nAirCamDome|s p/Ubiquiti Discovery Service/ i/v1 protocol, AirCamDome/ cpe:/h:ubnt:aircam_dome:/

# Match short model name = \x0c followed by 2 byte len then value
# No known type bytes fall in \w the following regex should be safe
match ubiquiti-discovery m|^\x01\0.[^\0].*\x0c\0.([\w-]+)|s p/Ubiquiti Discovery Service/ i/v1 protocol, $1/

softmatch ubiquiti-discovery m|^\x01\0.[^\0].{48}|s p/Ubiquiti Discovery Service/ i/v1 protocol/

##############################NEXT PROBE##############################
# Ubiquiti Discovery Protocol
Probe UDP UbiquitiDiscoveryv2 q|\x02\x08\0\0|
rarity 9
ports 10001

# Valid response is protocol version (\x02 ) and cmd followed
# by 2 bytes of length then TLV groups
# Known cmd values are \x06, \x09, and \x0b
match ubiquiti-discovery m|^\x02[\x06\x09\x0b].[^\0].*\x15\0.([\w-]+)\x16\0.([\d.]+)|s p/Ubiquiti Discovery Service/ i/v2 protocol, $1 software ver. $2/
match ubiquiti-discovery m|^\x02[\x06\x09\x0b].[^\0].*\x15\0.([\w-]+)|s p/Ubiquiti Discovery Service/ i/v2 protocol, $1/
softmatch ubiquiti-discovery m|^\x02[\x06\x09\x0b].[^\0].{48}|s p/Ubiquiti Discovery Service/ i/v2 protocol/

##############################NEXT PROBE##############################
# Sharp TV IP/Serial remote control protocol
# 4 requests: device name, model name, software version, IP protocol version.
# http://files.sharpusa.com/Downloads/ForHome/HomeEntertainment/LCDTVs/Manuals/tel_man_LC70LE734U.pdf
Probe TCP SharpTV q|TVNM1   \rMNRD1   \rSWVN1   \rIPPV1   \r|
rarity 9
ports 10002

# Fake impossible match; delete once we get a real probe response
match sharp-remote m|^(?!x)x|

##############################NEXT PROBE##############################
# Android Debug Bridge CONNECT probe
# https://android.googlesource.com/platform/system/core/+/master/adb/protocol.txt
Probe TCP adbConnect q|CNXN\0\0\0\x01\0\x10\0\0\x07\0\0\0\x32\x02\0\0\xbc\xb1\xa7\xb1host::\0|
rarity 8
ports 5555

match adb m|^CNXN\0\0\0\x01\0\x10\0\0........\xbc\xb1\xa7\xb1(\w+)::ro.product.name=([^;]+);ro.product.model=([^;]+);ro.product.device=([^;]+);\0$|s p/Android Debug Bridge $1/ i/name: $2; model: $3; device: $4/ o/Android/ cpe:/o:google:android/a cpe:/o:linux:linux_kernel/a
match adb m|^CNXN\0\0\0\x01\0\x10\0\0........\xbc\xb1\xa7\xb1(\w+)::ro.product.name=([^;]+);ro.product.model=([^;]+);ro.product.device=([^;]+);features=([^\0]+)$|s p/Android Debug Bridge $1/ i/name: $2; model: $3; device: $4; features: $5/ o/Android/ cpe:/o:google:android/a cpe:/o:linux:linux_kernel/a

match adb m|CNXN\0\0\0\x01\0\x10\0\0\t\0\0\0\xe4\x02\0\0\xbc\xb1\xa7\xb1device::\0$| p/Android Debug Bridge device/ i/no auth/ o/Android/ cpe:/o:google:android/a cpe:/o:linux:linux_kernel/a
# If it has identifying info, softmatch so we can make a better fingerprint
softmatch adb m|^CNXN\0\0\0\x01\0\x10\0\0........\xbc\xb1\xa7\xb1(\w+):[^:]*:[^\0]+\0$|s p/Android Debug Bridge $1/ i/no auth/ o/Android/ cpe:/o:google:android/a cpe:/o:linux:linux_kernel/a

match adb m|^AUTH\x01\0\0\0\0\0\0\0........\xbc\xb1\xa7\xb1|s p/Android Debug Bridge/ i/token auth required/ o/Android/ cpe:/o:google:android/a cpe:/o:linux:linux_kernel/a
softmatch adb m|^AUTH(.)\0\0\0\0\0\0\0........\xbc\xb1\xa7\xb1|s p/Android Debug Bridge/ i/auth required: $I(1,"<")/ o/Android/ cpe:/o:google:android/a cpe:/o:linux:linux_kernel/a

##############################NEXT PROBE##############################
# pi-hole "telnet API"
Probe TCP piholeVersion q|>version\n|
rarity 9
ports 4711

match pi-hole-stats m|^version v(\d[\w._-]+)| p/pi-hole Telnet API/ v/$1/ cpe:/a:pi-hole:pi-hole:$1/
match pi-hole-stats m|^unknown command: .*---EOM---\n\n$|s p/pi-hole Telnet API/ cpe:/a:pi-hole:pi-hole/

##############################NEXT PROBE##############################
# BearWare TeamTalk login probe
Probe TCP teamtalk-login q|login\n|
rarity 9
ports 10333

# Authentication required
match teamtalk m%^(?:teamtalk|welcome) userid=\d+ servername="([^"]+)" .* protocol="([\d.]+)"\r\nerror number=2002 message="Invalid user account"\r\n% p/BearWare TeamTalk/ i/protocol: $2; servername: $1/ cpe:/a:bearware:teamtalk/
# Open chat server
match teamtalk m%^(?:teamtalk|welcome) userid=\d+ servername="([^"]+)" .* protocol="([\d.]+)"\r\naccepted .*\r\nserverupdate .* version="([\d.]+)"\r\n% p/BearWare TeamTalk/ v/$3/ i/protocol: $2; servername: $1; no authentication required/ cpe:/a:bearware:teamtalk:$2/

# Sometimes server name isn't available
match teamtalk m%^(?:teamtalk|welcome) userid=\d+ servername="" .* protocol="([\d.]+)"\r\nerror number=2002 message="Invalid user account"\r\n% p/BearWare TeamTalk/ i/protocol: $1/ cpe:/a:bearware:teamtalk/
match teamtalk m%^(?:teamtalk|welcome) userid=\d+ servername="" .* protocol="([\d.]+)"\r\naccepted .*\r\nserverupdate .* version="([\d.]+)"\r\n% p/BearWare TeamTalk/ v/$2/ i/protocol: $1; no authentication required/ cpe:/a:bearware:teamtalk:$2/

match teamtalk m%^(?:teamtalk|welcome) userid=\d+ servername=\"([^"]+)\" .* protocol=\"([\w._-]+)\"\r\n% p/Bearware TeamTalk/ i/servername: $1; protocol: $2/ cpe:/a:bearware:teamtalk/
match teamtalk m%^(?:teamtalk|welcome) userid=\d+ servername=\"\" .* protocol=\"([\w._-]+)\"\r\n% p/Bearware TeamTalk/ i/protocol: $1/ cpe:/a:bearware:teamtalk/

##############################NEXT PROBE##############################
# Insteon PLM device info probe
Probe TCP insteonPLM q|\x02\x60|
rarity 9
ports 9761

# Response bytes:
# 0260 - device info
# ... - device ID, usually displayed as hex
# . - Device type: https://github.com/automategreen/home-controller/blob/3899a8bc7d739449c53c90982ed94bf66b8fce0c/lib/Insteon/utils.js#L3
# . - Device sub-type (no key available)
# 9b/9c - PLM version.
# 06 - ACK (15 is NACK)
match insteon-plm m|^\x02\x60...(.).\x9b\x06$| p/Insteon SmartLinc PLM/ i/device type: $I(1,">")/
match insteon-plm m|^\x02\x60...(.).[\x9c\x9d]\x06$| p/Insteon Hub PLM/ i/device type: $I(1,">")/
                                                                                                                /*
 * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#ifndef OPENSSL_EVP_H
# define OPENSSL_EVP_H
# pragma once

# include <openssl/macros.h>
# ifndef OPENSSL_NO_DEPRECATED_3_0
#  define HEADER_ENVELOPE_H
# endif

# include <stdarg.h>

# ifndef OPENSSL_NO_STDIO
#  include <stdio.h>
# endif

# include <openssl/opensslconf.h>
# include <openssl/types.h>
# include <openssl/core.h>
# include <openssl/core_dispatch.h>
# include <openssl/symhacks.h>
# include <openssl/bio.h>
# include <openssl/evperr.h>
# include <openssl/params.h>

# define EVP_MAX_MD_SIZE                 64/* longest known is SHA512 */
# define EVP_MAX_KEY_LENGTH              64
# define EVP_MAX_IV_LENGTH               16
# define EVP_MAX_BLOCK_LENGTH            32

# define PKCS5_SALT_LEN                  8
/* Default PKCS#5 iteration count */
# define PKCS5_DEFAULT_ITER              2048

# include <openssl/objects.h>

# ifndef OPENSSL_NO_DEPRECATED_3_0
#  define EVP_PK_RSA      0x0001
#  define EVP_PK_DSA      0x0002
#  define EVP_PK_DH       0x0004
#  define EVP_PK_EC       0x0008
#  define EVP_PKT_SIGN    0x0010
#  define EVP_PKT_ENC     0x0020
#  define EVP_PKT_EXCH    0x0040
#  define EVP_PKS_RSA     0x0100
#  define EVP_PKS_DSA     0x0200
#  define EVP_PKS_EC      0x0400
# endif

# define EVP_PKEY_NONE   NID_undef
# define EVP_PKEY_RSA    NID_rsaEncryption
# define EVP_PKEY_RSA2   NID_rsa
# define EVP_PKEY_RSA_PSS NID_rsassaPss
# define EVP_PKEY_DSA    NID_dsa
# define EVP_PKEY_DSA1   NID_dsa_2
# define EVP_PKEY_DSA2   NID_dsaWithSHA
# define EVP_PKEY_DSA3   NID_dsaWithSHA1
# define EVP_PKEY_DSA4   NID_dsaWithSHA1_2
# define EVP_PKEY_DH     NID_dhKeyAgreement
# define EVP_PKEY_DHX    NID_dhpublicnumber
# define EVP_PKEY_EC     NID_X9_62_id_ecPublicKey
# define EVP_PKEY_SM2    NID_sm2
# define EVP_PKEY_HMAC   NID_hmac
# define EVP_PKEY_CMAC   NID_cmac
# define EVP_PKEY_SCRYPT NID_id_scrypt
# define EVP_PKEY_TLS1_PRF NID_tls1_prf
# define EVP_PKEY_HKDF   NID_hkdf
# define EVP_PKEY_POLY1305 NID_poly1305
# define EVP_PKEY_SIPHASH NID_siphash
# define EVP_PKEY_X25519 NID_X25519
# define EVP_PKEY_ED25519 NID_ED25519
# define EVP_PKEY_X448 NID_X448
# define EVP_PKEY_ED448 NID_ED448
/* Special indicator that the object is uniquely provider side */
# define EVP_PKEY_KEYMGMT -1

/* Easy to use macros for EVP_PKEY related selections */
# define EVP_PKEY_KEY_PARAMETERS                                            \
    ( OSSL_KEYMGMT_SELECT_ALL_PARAMETERS )
# define EVP_PKEY_PRIVATE_KEY                                               \
    ( EVP_PKEY_KEY_PARAMETERS | OSSL_KEYMGMT_SELECT_PRIVATE_KEY )
# define EVP_PKEY_PUBLIC_KEY                                                \
    ( EVP_PKEY_KEY_PARAMETERS | OSSL_KEYMGMT_SELECT_PUBLIC_KEY )
# define EVP_PKEY_KEYPAIR                                                   \
    ( EVP_PKEY_PUBLIC_KEY | OSSL_KEYMGMT_SELECT_PRIVATE_KEY )

#ifdef  __cplusplus
extern "C" {
#endif

int EVP_set_default_properties(OSSL_LIB_CTX *libctx, const char *propq);
int EVP_default_properties_is_fips_enabled(OSSL_LIB_CTX *libctx);
int EVP_default_properties_enable_fips(OSSL_LIB_CTX *libctx, int enable);

# define EVP_PKEY_MO_SIGN        0x0001
# define EVP_PKEY_MO_VERIFY      0x0002
# define EVP_PKEY_MO_ENCRYPT     0x0004
# define EVP_PKEY_MO_DECRYPT     0x0008

# ifndef EVP_MD
#  ifndef OPENSSL_NO_DEPRECATED_3_0
OSSL_DEPRECATEDIN_3_0 EVP_MD *EVP_MD_meth_new(int md_type, int pkey_type);
OSSL_DEPRECATEDIN_3_0 EVP_MD *EVP_MD_meth_dup(const EVP_MD *md);
OSSL_DEPRECATEDIN_3_0 void EVP_MD_meth_free(EVP_MD *md);
OSSL_DEPRECATEDIN_3_0
int EVP_MD_meth_set_input_blocksize(EVP_MD *md, int blocksize);
OSSL_DEPRECATEDIN_3_0
int EVP_MD_meth_set_result_size(EVP_MD *md, int resultsize);
OSSL_DEPRECATEDIN_3_0
int EVP_MD_meth_set_app_datasize(EVP_MD *md, int datasize);
OSSL_DEPRECATEDIN_3_0
int EVP_MD_meth_set_flags(EVP_MD *md, unsigned long flags);
OSSL_DEPRECATEDIN_3_0
int EVP_MD_meth_set_init(EVP_MD *md, int (*init)(EVP_MD_CTX *ctx));
OSSL_DEPRECATEDIN_3_0
int EVP_MD_meth_set_update(EVP_MD *md, int (*update)(EVP_MD_CTX *ctx,
                                                     const void *data,
                                                     size_t count));
OSSL_DEPRECATEDIN_3_0
int EVP_MD_meth_set_final(EVP_MD *md, int (*final)(EVP_MD_CTX *ctx,
                                                   unsigned char *md));
OSSL_DEPRECATEDIN_3_0
int EVP_MD_meth_set_copy(EVP_MD *md, int (*copy)(EVP_MD_CTX *to,
                                                 const EVP_MD_CTX *from));
OSSL_DEPRECATEDIN_3_0
int EVP_MD_meth_set_cleanup(EVP_MD *md, int (*cleanup)(EVP_MD_CTX *ctx));
OSSL_DEPRECATEDIN_3_0
int EVP_MD_meth_set_ctrl(EVP_MD *md, int (*ctrl)(EVP_MD_CTX *ctx, int cmd,
                                                 int p1, void *p2));
OSSL_DEPRECATEDIN_3_0 int EVP_MD_meth_get_input_blocksize(const EVP_MD *md);
OSSL_DEPRECATEDIN_3_0 int EVP_MD_meth_get_result_size(const EVP_MD *md);
OSSL_DEPRECATEDIN_3_0 int EVP_MD_meth_get_app_datasize(const EVP_MD *md);
OSSL_DEPRECATEDIN_3_0 unsigned long EVP_MD_meth_get_flags(const EVP_MD *md);
OSSL_DEPRECATEDIN_3_0
int (*EVP_MD_meth_get_init(const EVP_MD *md))(EVP_MD_CTX *ctx);
OSSL_DEPRECATEDIN_3_0
int (*EVP_MD_meth_get_update(const EVP_MD *md))(EVP_MD_CTX *ctx,
                                                const void *data, size_t count);
OSSL_DEPRECATEDIN_3_0
int (*EVP_MD_meth_get_final(const EVP_MD *md))(EVP_MD_CTX *ctx,
                                               unsigned char *md);
OSSL_DEPRECATEDIN_3_0
int (*EVP_MD_meth_get_copy(const EVP_MD *md))(EVP_MD_CTX *to,
                                              const EVP_MD_CTX *from);
OSSL_DEPRECATEDIN_3_0
int (*EVP_MD_meth_get_cleanup(const EVP_MD *md))(EVP_MD_CTX *ctx);
OSSL_DEPRECATEDIN_3_0
int (*EVP_MD_meth_get_ctrl(const EVP_MD *md))(EVP_MD_CTX *ctx, int cmd,
                                              int p1, void *p2);
#  endif
/* digest can only handle a single block */
#  define EVP_MD_FLAG_ONESHOT     0x0001

/* digest is extensible-output function, XOF */
#  define EVP_MD_FLAG_XOF         0x0002

/* DigestAlgorithmIdentifier flags... */

#  define EVP_MD_FLAG_DIGALGID_MASK               0x0018

/* NULL or absent parameter accepted. Use NULL */

#  define EVP_MD_FLAG_DIGALGID_NULL               0x0000

/* NULL or absent parameter accepted. Use NULL for PKCS#1 otherwise absent */

#  define EVP_MD_FLAG_DIGALGID_ABSENT             0x0008

/* Custom handling via ctrl */

#  define EVP_MD_FLAG_DIGALGID_CUSTOM             0x0018

/* Note if suitable for use in FIPS mode */
#  define EVP_MD_FLAG_FIPS        0x0400

/* Digest ctrls */

#  define EVP_MD_CTRL_DIGALGID                    0x1
#  define EVP_MD_CTRL_MICALG                      0x2
#  define EVP_MD_CTRL_XOF_LEN                     0x3
#  define EVP_MD_CTRL_TLSTREE                     0x4

/* Minimum Algorithm specific ctrl value */

#  define EVP_MD_CTRL_ALG_CTRL                    0x1000

# endif                         /* !EVP_MD */

/* values for EVP_MD_CTX flags */

# define EVP_MD_CTX_FLAG_ONESHOT         0x0001/* digest update will be
                                                * called once only */
# define EVP_MD_CTX_FLAG_CLEANED         0x0002/* context has already been
                                                * cleaned */
# define EVP_MD_CTX_FLAG_REUSE           0x0004/* Don't free up ctx->md_data
                                                * in EVP_MD_CTX_reset */
/*
 * FIPS and pad options are ignored in 1.0.0, definitions are here so we
 * don't accidentally reuse the values for other purposes.
 */

/* This flag has no effect from openssl-3.0 onwards */
# define EVP_MD_CTX_FLAG_NON_FIPS_ALLOW  0x0008

/*
 * The following PAD options are also currently ignored in 1.0.0, digest
 * parameters are handled through EVP_DigestSign*() and EVP_DigestVerify*()
 * instead.
 */
# define EVP_MD_CTX_FLAG_PAD_MASK        0xF0/* RSA mode to use */
# define EVP_MD_CTX_FLAG_PAD_PKCS1       0x00/* PKCS#1 v1.5 mode */
# define EVP_MD_CTX_FLAG_PAD_X931        0x10/* X9.31 mode */
# define EVP_MD_CTX_FLAG_PAD_PSS         0x20/* PSS mode */

# define EVP_MD_CTX_FLAG_NO_INIT         0x0100/* Don't initialize md_data */
/*
 * Some functions such as EVP_DigestSign only finalise copies of internal
 * contexts so additional data can be included after the finalisation call.
 * This is inefficient if this functionality is not required: it is disabled
 * if the following flag is set.
 */
# define EVP_MD_CTX_FLAG_FINALISE        0x0200
/* NOTE: 0x0400 is reserved for internal usage */
# ifndef OPENSSL_NO_DEPRECATED_3_0
OSSL_DEPRECATEDIN_3_0
EVP_CIPHER *EVP_CIPHER_meth_new(int cipher_type, int block_size, int key_len);
OSSL_DEPRECATEDIN_3_0
EVP_CIPHER *EVP_CIPHER_meth_dup(const EVP_CIPHER *cipher);
OSSL_DEPRECATEDIN_3_0
void EVP_CIPHER_meth_free(EVP_CIPHER *cipher);
OSSL_DEPRECATEDIN_3_0
int EVP_CIPHER_meth_set_iv_length(EVP_CIPHER *cipher, int iv_len);
OSSL_DEPRECATEDIN_3_0
int EVP_CIPHER_meth_set_flags(EVP_CIPHER *cipher, unsigned long flags);
OSSL_DEPRECATEDIN_3_0
int EVP_CIPHER_meth_set_impl_ctx_size(EVP_CIPHER *cipher, int ctx_size);
OSSL_DEPRECATEDIN_3_0
int EVP_CIPHER_meth_set_init(EVP_CIPHER *cipher,
                             int (*init) (EVP_CIPHER_CTX *ctx,
                                          const unsigned char *key,
                                          const unsigned char *iv,
                                          int enc));
OSSL_DEPRECATEDIN_3_0
int EVP_CIPHER_meth_set_do_cipher(EVP_CIPHER *cipher,
                                  int (*do_cipher) (EVP_CIPHER_CTX *ctx,
                                                    unsigned char *out,
                                                    const unsigned char *in,
                                                    size_t inl));
OSSL_DEPRECATEDIN_3_0
int EVP_CIPHER_meth_set_cleanup(EVP_CIPHER *cipher,
                                int (*cleanup) (EVP_CIPHER_CTX *));
OSSL_DEPRECATEDIN_3_0
int EVP_CIPHER_meth_set_set_asn1_params(EVP_CIPHER *cipher,
                                        int (*set_asn1_parameters) (EVP_CIPHER_CTX *,
                                                                    ASN1_TYPE *));
OSSL_DEPRECATEDIN_3_0
int EVP_CIPHER_meth_set_get_asn1_params(EVP_CIPHER *cipher,
                                        int (*get_asn1_parameters) (EVP_CIPHER_CTX *,
                                                                    ASN1_TYPE *));
OSSL_DEPRECATEDIN_3_0
int EVP_CIPHER_meth_set_ctrl(EVP_CIPHER *cipher,
                             int (*ctrl) (EVP_CIPHER_CTX *, int type,
                                          int arg, void *ptr));
OSSL_DEPRECATEDIN_3_0 int
(*EVP_CIPHER_meth_get_init(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *ctx,
                                                      const unsigned char *key,
                                                      const unsigned char *iv,
                                                      int enc);
OSSL_DEPRECATEDIN_3_0 int
(*EVP_CIPHER_meth_get_do_cipher(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *ctx,
                                                           unsigned char *out,
                                                           const unsigned char *in,
                                                           size_t inl);
OSSL_DEPRECATEDIN_3_0 int
(*EVP_CIPHER_meth_get_cleanup(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *);
OSSL_DEPRECATEDIN_3_0 int
(*EVP_CIPHER_meth_get_set_asn1_params(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *,
                                                                 ASN1_TYPE *);
OSSL_DEPRECATEDIN_3_0 int
(*EVP_CIPHER_meth_get_get_asn1_params(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *,
                                                                 ASN1_TYPE *);
OSSL_DEPRECATEDIN_3_0 int
(*EVP_CIPHER_meth_get_ctrl(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *, int type,
                                                      int arg, void *ptr);
# endif

/* Values for cipher flags */

/* Modes for ciphers */

# define         EVP_CIPH_STREAM_CIPHER          0x0
# define         EVP_CIPH_ECB_MODE               0x1
# define         EVP_CIPH_CBC_MODE               0x2
# define         EVP_CIPH_CFB_MODE               0x3
# define         EVP_CIPH_OFB_MODE               0x4
# define         EVP_CIPH_CTR_MODE               0x5
# define         EVP_CIPH_GCM_MODE               0x6
# define         EVP_CIPH_CCM_MODE               0x7
# define         EVP_CIPH_XTS_MODE               0x10001
# define         EVP_CIPH_WRAP_MODE              0x10002
# define         EVP_CIPH_OCB_MODE               0x10003
# define         EVP_CIPH_SIV_MODE               0x10004
# define         EVP_CIPH_MODE                   0xF0007
/* Set if variable length cipher */
# define         EVP_CIPH_VARIABLE_LENGTH        0x8
/* Set if the iv handling should be done by the cipher itself */
# define         EVP_CIPH_CUSTOM_IV              0x10
/* Set if the cipher's init() function should be called if key is NULL */
# define         EVP_CIPH_ALWAYS_CALL_INIT       0x20
/* Call ctrl() to init cipher parameters */
# define         EVP_CIPH_CTRL_INIT              0x40
/* Don't use standard key length function */
# define         EVP_CIPH_CUSTOM_KEY_LENGTH      0x80
/* Don't use standard block padding */
# define         EVP_CIPH_NO_PADDING             0x100
/* cipher handles random key generation */
# define         EVP_CIPH_RAND_KEY               0x200
/* cipher has its own additional copying logic */
# define         EVP_CIPH_CUSTOM_COPY            0x400
/* Don't use standard iv length function */
# define         EVP_CIPH_CUSTOM_IV_LENGTH       0x800
/* Legacy and no longer relevant: Allow use default ASN1 get/set iv */
# define         EVP_CIPH_FLAG_DEFAULT_ASN1      0
/* Free:                                         0x1000 */
/* Buffer length in bits not bytes: CFB1 mode only */
# define         EVP_CIPH_FLAG_LENGTH_BITS       0x2000
/* Deprecated FIPS flag: was 0x4000 */
# define         EVP_CIPH_FLAG_FIPS              0
/* Deprecated FIPS flag: was 0x8000 */
# define         EVP_CIPH_FLAG_NON_FIPS_ALLOW    0

/*
 * Cipher handles any and all padding logic as well as finalisation.
 */
# define         EVP_CIPH_FLAG_CTS               0x4000
# define         EVP_CIPH_FLAG_CUSTOM_CIPHER     0x100000
# define         EVP_CIPH_FLAG_AEAD_CIPHER       0x200000
# define         EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK 0x400000
/* Cipher can handle pipeline operations */
# define         EVP_CIPH_FLAG_PIPELINE          0X800000
/* For provider implementations that handle  ASN1 get/set param themselves */
# define         EVP_CIPH_FLAG_CUSTOM_ASN1       0x1000000
/* For ciphers generating unprotected CMS attributes */
# define         EVP_CIPH_FLAG_CIPHER_WITH_MAC   0x2000000
/* For supplementary wrap cipher support */
# define         EVP_CIPH_FLAG_GET_WRAP_CIPHER   0x4000000
# define         EVP_CIPH_FLAG_INVERSE_CIPHER    0x8000000

/*
 * Cipher context flag to indicate we can handle wrap mode: if allowed in
 * older applications it could overflow buffers.
 */

# define         EVP_CIPHER_CTX_FLAG_WRAP_ALLOW  0x1

/* ctrl() values */

# define         EVP_CTRL_INIT                   0x0
# define         EVP_CTRL_SET_KEY_LENGTH         0x1
# define         EVP_CTRL_GET_RC2_KEY_BITS       0x2
# define         EVP_CTRL_SET_RC2_KEY_BITS       0x3
# define         EVP_CTRL_GET_RC5_ROUNDS         0x4
# define         EVP_CTRL_SET_RC5_ROUNDS         0x5
# define         EVP_CTRL_RAND_KEY               0x6
# define         EVP_CTRL_PBE_PRF_NID            0x7
# define         EVP_CTRL_COPY                   0x8
# define         EVP_CTRL_AEAD_SET_IVLEN         0x9
# define         EVP_CTRL_AEAD_GET_TAG           0x10
# define         EVP_CTRL_AEAD_SET_TAG           0x11
# define         EVP_CTRL_AEAD_SET_IV_FIXED      0x12
# define         EVP_CTRL_GCM_SET_IVLEN          EVP_CTRL_AEAD_SET_IVLEN
# define         EVP_CTRL_GCM_GET_TAG            EVP_CTRL_AEAD_GET_TAG
# define         EVP_CTRL_GCM_SET_TAG            EVP_CTRL_AEAD_SET_TAG
# define         EVP_CTRL_GCM_SET_IV_FIXED       EVP_CTRL_AEAD_SET_IV_FIXED
# define         EVP_CTRL_GCM_IV_GEN             0x13
# define         EVP_CTRL_CCM_SET_IVLEN          EVP_CTRL_AEAD_SET_IVLEN
# define         EVP_CTRL_CCM_GET_TAG            EVP_CTRL_AEAD_GET_TAG
# define         EVP_CTRL_CCM_SET_TAG            EVP_CTRL_AEAD_SET_TAG
# define         EVP_CTRL_CCM_SET_IV_FIXED       EVP_CTRL_AEAD_SET_IV_FIXED
# define         EVP_CTRL_CCM_SET_L              0x14
# define         EVP_CTRL_CCM_SET_MSGLEN         0x15
/*
 * AEAD cipher deduces payload length and returns number of bytes required to
 * store MAC and eventual padding. Subsequent call to EVP_Cipher even
 * appends/verifies MAC.
 */
# define         EVP_CTRL_AEAD_TLS1_AAD          0x16
/* Used by composite AEAD ciphers, no-op in GCM, CCM... */
# define         EVP_CTRL_AEAD_SET_MAC_KEY       0x17
/* Set the GCM invocation field, decrypt only */
# define         EVP_CTRL_GCM_SET_IV_INV         0x18

# define         EVP_CTRL_TLS1_1_MULTIBLOCK_AAD  0x19
# define         EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT      0x1a
# define         EVP_CTRL_TLS1_1_MULTIBLOCK_DECRYPT      0x1b
# define         EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE  0x1c

# define         EVP_CTRL_SSL3_MASTER_SECRET             0x1d

/* EVP_CTRL_SET_SBOX takes the char * specifying S-boxes */
# define         EVP_CTRL_SET_SBOX                       0x1e
/*
 * EVP_CTRL_SBOX_USED takes a 'size_t' and 'char *', pointing at a
 * pre-allocated buffer with specified size
 */
# define         EVP_CTRL_SBOX_USED                      0x1f
/* EVP_CTRL_KEY_MESH takes 'size_t' number of bytes to mesh the key after,
 * 0 switches meshing off
 */
# define         EVP_CTRL_KEY_MESH                       0x20
/* EVP_CTRL_BLOCK_PADDING_MODE takes the padding mode */
# define         EVP_CTRL_BLOCK_PADDING_MODE             0x21

/* Set the output buffers to use for a pipelined operation */
# define         EVP_CTRL_SET_PIPELINE_OUTPUT_BUFS       0x22
/* Set the input buffers to use for a pipelined operation */
# define         EVP_CTRL_SET_PIPELINE_INPUT_BUFS        0x23
/* Set the input buffer lengths to use for a pipelined operation */
# define         EVP_CTRL_SET_PIPELINE_INPUT_LENS        0x24
/* Get the IV length used by the cipher */
# define         EVP_CTRL_GET_IVLEN                      0x25
/* 0x26 is unused */
/* Tell the cipher it's doing a speed test (SIV disallows multiple ops) */
# define         EVP_CTRL_SET_SPEED                      0x27
/* Get the unprotectedAttrs from cipher ctx */
# define         EVP_CTRL_PROCESS_UNPROTECTED            0x28
/* Get the supplementary wrap cipher */
#define          EVP_CTRL_GET_WRAP_CIPHER                0x29
/* TLSTREE key diversification */
#define          EVP_CTRL_TLSTREE                        0x2A

/* Padding modes */
#define EVP_PADDING_PKCS7       1
#define EVP_PADDING_ISO7816_4   2
#define EVP_PADDING_ANSI923     3
#define EVP_PADDING_ISO10126    4
#define EVP_PADDING_ZERO        5

/* RFC 5246 defines additional data to be 13 bytes in length */
# define         EVP_AEAD_TLS1_AAD_LEN           13

typedef struct {
    unsigned char *out;
    const unsigned char *inp;
    size_t len;
    unsigned int interleave;
} EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM;

/* GCM TLS constants */
/* Length of fixed part of IV derived from PRF */
# define EVP_GCM_TLS_FIXED_IV_LEN                        4
/* Length of explicit part of IV part of TLS records */
# define EVP_GCM_TLS_EXPLICIT_IV_LEN                     8
/* Length of tag for TLS */
# define EVP_GCM_TLS_TAG_LEN                             16

/* CCM TLS constants */
/* Length of fixed part of IV derived from PRF */
# define EVP_CCM_TLS_FIXED_IV_LEN                        4
/* Length of explicit part of IV part of TLS records */
# define EVP_CCM_TLS_EXPLICIT_IV_LEN                     8
/* Total length of CCM IV length for TLS */
# define EVP_CCM_TLS_IV_LEN                              12
/* Length of tag for TLS */
# define EVP_CCM_TLS_TAG_LEN                             16
/* Length of CCM8 tag for TLS */
# define EVP_CCM8_TLS_TAG_LEN                            8

/* Length of tag for TLS */
# define EVP_CHACHAPOLY_TLS_TAG_LEN                      16

typedef struct evp_cipher_info_st {
    const EVP_CIPHER *cipher;
    unsigned char iv[EVP_MAX_IV_LENGTH];
} EVP_CIPHER_INFO;


/* Password based encryption function */
typedef int (EVP_PBE_KEYGEN) (EVP_CIPHER_CTX *ctx, const char *pass,
                              int passlen, ASN1_TYPE *param,
                              const EVP_CIPHER *cipher, const EVP_MD *md,
                              int en_de);

typedef int (EVP_PBE_KEYGEN_EX) (EVP_CIPHER_CTX *ctx, const char *pass,
                                 int passlen, ASN1_TYPE *param,
                                 const EVP_CIPHER *cipher, const EVP_MD *md,
                                 int en_de, OSSL_LIB_CTX *libctx, const char *propq);

# ifndef OPENSSL_NO_DEPRECATED_3_0
#  define EVP_PKEY_assign_RSA(pkey,rsa) EVP_PKEY_assign((pkey),EVP_PKEY_RSA,\
                                                         (rsa))
# endif

# ifndef OPENSSL_NO_DSA
#  define EVP_PKEY_assign_DSA(pkey,dsa) EVP_PKEY_assign((pkey),EVP_PKEY_DSA,\
                                        (dsa))
# endif

# if !defined(OPENSSL_NO_DH) && !defined(OPENSSL_NO_DEPRECATED_3_0)
#  define EVP_PKEY_assign_DH(pkey,dh) EVP_PKEY_assign((pkey),EVP_PKEY_DH,(dh))
# endif

# ifndef OPENSSL_NO_DEPRECATED_3_0
#  ifndef OPENSSL_NO_EC
#   define EVP_PKEY_assign_EC_KEY(pkey,eckey) \
        EVP_PKEY_assign((pkey), EVP_PKEY_EC, (eckey))
#  endif
# endif
# ifndef OPENSSL_NO_SIPHASH
#  define EVP_PKEY_assign_SIPHASH(pkey,shkey) EVP_PKEY_assign((pkey),\
                                        EVP_PKEY_SIPHASH,(shkey))
# endif

# ifndef OPENSSL_NO_POLY1305
#  define EVP_PKEY_assign_POLY1305(pkey,polykey) EVP_PKEY_assign((pkey),\
                                        EVP_PKEY_POLY1305,(polykey))
# endif

/* Add some extra combinations */
# define EVP_get_digestbynid(a) EVP_get_digestbyname(OBJ_nid2sn(a))
# define EVP_get_digestbyobj(a) EVP_get_digestbynid(OBJ_obj2nid(a))
# define EVP_get_cipherbynid(a) EVP_get_cipherbyname(OBJ_nid2sn(a))
# define EVP_get_cipherbyobj(a) EVP_get_cipherbynid(OBJ_obj2nid(a))

int EVP_MD_get_type(const EVP_MD *md);
# define EVP_MD_type EVP_MD_get_type
# define EVP_MD_nid EVP_MD_get_type
const char *EVP_MD_get0_name(const EVP_MD *md);
# define EVP_MD_name EVP_MD_get0_name
const char *EVP_MD_get0_description(const EVP_MD *md);
int EVP_MD_is_a(const EVP_MD *md, const char *name);
int EVP_MD_names_do_all(const EVP_MD *md,
                        void (*fn)(const char *name, void *data),
                        void *data);
const OSSL_PROVIDER *EVP_MD_get0_provider(const EVP_MD *md);
int EVP_MD_get_pkey_type(const EVP_MD *md);
# define EVP_MD_pkey_type EVP_MD_get_pkey_type
int EVP_MD_get_size(const EVP_MD *md);
# define EVP_MD_size EVP_MD_get_size
int EVP_MD_get_block_size(const EVP_MD *md);
# define EVP_MD_block_size EVP_MD_get_block_size
unsigned long EVP_MD_get_flags(const EVP_MD *md);
# define EVP_MD_flags EVP_MD_get_flags

const EVP_MD *EVP_MD_CTX_get0_md(const EVP_MD_CTX *ctx);
EVP_MD *EVP_MD_CTX_get1_md(EVP_MD_CTX *ctx);
# ifndef OPENSSL_NO_DEPRECATED_3_0
OSSL_DEPRECATEDIN_3_0
const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx);
OSSL_DEPRECATEDIN_3_0
int (*EVP_MD_CTX_update_fn(EVP_MD_CTX *ctx))(EVP_MD_CTX *ctx,
                                             const void *data, size_t count);
OSSL_DEPRECATEDIN_3_0
void EVP_MD_CTX_set_update_fn(EVP_MD_CTX *ctx,
                              int (*update) (EVP_MD_CTX *ctx,
                                             const void *data, size_t count));
# endif
# define EVP_MD_CTX_get0_name(e)       EVP_MD_get0_name(EVP_MD_CTX_get0_md(e))
# define EVP_MD_CTX_get_size(e)        EVP_MD_get_size(EVP_MD_CTX_get0_md(e))
# define EVP_MD_CTX_size               EVP_MD_CTX_get_size
# define EVP_MD_CTX_get_block_size(e)  EVP_MD_get_block_size(EVP_MD_CTX_get0_md(e))
# define EVP_MD_CTX_block_size EVP_MD_CTX_get_block_size
# define EVP_MD_CTX_get_type(e)            EVP_MD_get_type(EVP_MD_CTX_get0_md(e))
# define EVP_MD_CTX_type EVP_MD_CTX_get_type
EVP_PKEY_CTX *EVP_MD_CTX_get_pkey_ctx(const EVP_MD_CTX *ctx);
# define EVP_MD_CTX_pkey_ctx EVP_MD_CTX_get_pkey_ctx
void EVP_MD_CTX_set_pkey_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pctx);
void *EVP_MD_CTX_get0_md_data(const EVP_MD_CTX *ctx);
# define EVP_MD_CTX_md_data EVP_MD_CTX_get0_md_data

int EVP_CIPHER_get_nid(const EVP_CIPHER *cipher);
# define EVP_CIPHER_nid EVP_CIPHER_get_nid
const char *EVP_CIPHER_get0_name(const EVP_CIPHER *cipher);
# define EVP_CIPHER_name EVP_CIPHER_get0_name
const char *EVP_CIPHER_get0_description(const EVP_CIPHER *cipher);
int EVP_CIPHER_is_a(const EVP_CIPHER *cipher, const char *name);
int EVP_CIPHER_names_do_all(const EVP_CIPHER *cipher,
                            void (*fn)(const char *name, void *data),
                            void *data);
const OSSL_PROVIDER *EVP_CIPHER_get0_provider(const EVP_CIPHER *cipher);
int EVP_CIPHER_get_block_size(const EVP_CIPHER *cipher);
# define EVP_CIPHER_block_size EVP_CIPHER_get_block_size
# ifndef OPENSSL_NO_DEPRECATED_3_0
OSSL_DEPRECATEDIN_3_0
int EVP_CIPHER_impl_ctx_size(const EVP_CIPHER *cipher);
# endif
int EVP_CIPHER_get_key_length(const EVP_CIPHER *cipher);
# define EVP_CIPHER_key_length EVP_CIPHER_get_key_length
int EVP_CIPHER_get_iv_length(const EVP_CIPHER *cipher);
# define EVP_CIPHER_iv_length EVP_CIPHER_get_iv_length
unsigned long EVP_CIPHER_get_flags(const EVP_CIPHER *cipher);
# define EVP_CIPHER_flags EVP_CIPHER_get_flags
int EVP_CIPHER_get_mode(const EVP_CIPHER *cipher);
# define EVP_CIPHER_mode EVP_CIPHER_get_mode
int EVP_CIPHER_get_type(const EVP_CIPHER *cipher);
# define EVP_CIPHER_type EVP_CIPHER_get_type
EVP_CIPHER *EVP_CIPHER_fetch(OSSL_LIB_CTX *ctx, const char *algorithm,
                             const char *properties);
int EVP_CIPHER_up_ref(EVP_CIPHER *cipher);
void EVP_CIPHER_free(EVP_CIPHER *cipher);

const EVP_CIPHER *EVP_CIPHER_CTX_get0_cipher(const EVP_CIPHER_CTX *ctx);
EVP_CIPHER *EVP_CIPHER_CTX_get1_cipher(EVP_CIPHER_CTX *ctx);
int EVP_CIPHER_CTX_is_encrypting(const EVP_CIPHER_CTX *ctx);
# define EVP_CIPHER_CTX_encrypting EVP_CIPHER_CTX_is_encrypting
int EVP_CIPHER_CTX_get_nid(const EVP_CIPHER_CTX *ctx);
# define EVP_CIPHER_CTX_nid EVP_CIPHER_CTX_get_nid
int EVP_CIPHER_CTX_get_block_size(const EVP_CIPHER_CTX *ctx);
# define EVP_CIPHER_CTX_block_size EVP_CIPHER_CTX_get_block_size
int EVP_CIPHER_CTX_get_key_length(const EVP_CIPHER_CTX *ctx);
# define EVP_CIPHER_CTX_key_length EVP_CIPHER_CTX_get_key_length
int EVP_CIPHER_CTX_get_iv_length(const EVP_CIPHER_CTX *ctx);
# define EVP_CIPHER_CTX_iv_length EVP_CIPHER_CTX_get_iv_length
int EVP_CIPHER_CTX_get_tag_length(const EVP_CIPHER_CTX *ctx);
# define EVP_CIPHER_CTX_tag_length EVP_CIPHER_CTX_get_tag_length
# ifndef OPENSSL_NO_DEPRECATED_3_0
const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx);
OSSL_DEPRECATEDIN_3_0 const unsigned char *EVP_CIPHER_CTX_iv(const EVP_CIPHER_CTX *ctx);
OSSL_DEPRECATEDIN_3_0 const unsigned char *EVP_CIPHER_CTX_original_iv(const EVP_CIPHER_CTX *ctx);
OSSL_DEPRECATEDIN_3_0 unsigned char *EVP_CIPHER_CTX_iv_noconst(EVP_CIPHER_CTX *ctx);
# endif
int EVP_CIPHER_CTX_get_updated_iv(EVP_CIPHER_CTX *ctx, void *buf, size_t len);
int EVP_CIPHER_CTX_get_original_iv(EVP_CIPHER_CTX *ctx, void *buf, size_t len);
# ifndef OPENSSL_NO_DEPRECATED_3_0
OSSL_DEPRECATEDIN_3_0
unsigned char *EVP_CIPHER_CTX_buf_noconst(EVP_CIPHER_CTX *ctx);
# endif
int EVP_CIPHER_CTX_get_num(const EVP_CIPHER_CTX *ctx);
# define EVP_CIPHER_CTX_num EVP_CIPHER_CTX_get_num
int EVP_CIPHER_CTX_set_num(EVP_CIPHER_CTX *ctx, int num);
int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in);
void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx);
void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data);
void *EVP_CIPHER_CTX_get_cipher_data(const EVP_CIPHER_CTX *ctx);
void *EVP_CIPHER_CTX_set_cipher_data(EVP_CIPHER_CTX *ctx, void *cipher_data);
# define EVP_CIPHER_CTX_get0_name(c) EVP_CIPHER_get0_name(EVP_CIPHER_CTX_get0_cipher(c))
# define EVP_CIPHER_CTX_get_type(c)  EVP_CIPHER_get_type(EVP_CIPHER_CTX_get0_cipher(c))
# define EVP_CIPHER_CTX_type         EVP_CIPHER_CTX_get_type
# ifndef OPENSSL_NO_DEPRECATED_1_1_0
#  define EVP_CIPHER_CTX_flags(c)    EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(c))
# endif
# define EVP_CIPHER_CTX_get_mode(c)  EVP_CIPHER_get_mode(EVP_CIPHER_CTX_get0_cipher(c))
# define EVP_CIPHER_CTX_mode         EVP_CIPHER_CTX_get_mode

# define EVP_ENCODE_LENGTH(l)    ((((l)+2)/3*4)+((l)/48+1)*2+80)
# define EVP_DECODE_LENGTH(l)    (((l)+3)/4*3+80)

# define EVP_SignInit_ex(a,b,c)          EVP_DigestInit_ex(a,b,c)
# define EVP_SignInit(a,b)               EVP_DigestInit(a,b)
# define EVP_SignUpdate(a,b,c)           EVP_DigestUpdate(a,b,c)
# define EVP_VerifyInit_ex(a,b,c)        EVP_DigestInit_ex(a,b,c)
# define EVP_VerifyInit(a,b)             EVP_DigestInit(a,b)
# define EVP_VerifyUpdate(a,b,c)         EVP_DigestUpdate(a,b,c)
# define EVP_OpenUpdate(a,b,c,d,e)       EVP_DecryptUpdate(a,b,c,d,e)
# define EVP_SealUpdate(a,b,c,d,e)       EVP_EncryptUpdate(a,b,c,d,e)

# ifdef CONST_STRICT
void BIO_set_md(BIO *, const EVP_MD *md);
# else
#  define BIO_set_md(b,md)          BIO_ctrl(b,BIO_C_SET_MD,0,(void *)(md))
# endif
# define BIO_get_md(b,mdp)          BIO_ctrl(b,BIO_C_GET_MD,0,(mdp))
# define BIO_get_md_ctx(b,mdcp)     BIO_ctrl(b,BIO_C_GET_MD_CTX,0,(mdcp))
# define BIO_set_md_ctx(b,mdcp)     BIO_ctrl(b,BIO_C_SET_MD_CTX,0,(mdcp))
# define BIO_get_cipher_status(b)   BIO_ctrl(b,BIO_C_GET_CIPHER_STATUS,0,NULL)
# define BIO_get_cipher_ctx(b,c_pp) BIO_ctrl(b,BIO_C_GET_CIPHER_CTX,0,(c_pp))

/*__owur*/ int EVP_Cipher(EVP_CIPHER_CTX *c,
                          unsigned char *out,
                          const unsigned char *in, unsigned int inl);

# define EVP_add_cipher_alias(n,alias) \
        OBJ_NAME_add((alias),OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS,(n))
# define EVP_add_digest_alias(n,alias) \
        OBJ_NAME_add((alias),OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,(n))
# define EVP_delete_cipher_alias(alias) \
        OBJ_NAME_remove(alias,OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS);
# define EVP_delete_digest_alias(alias) \
        OBJ_NAME_remove(alias,OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS);

int EVP_MD_get_params(const EVP_MD *digest, OSSL_PARAM params[]);
int EVP_MD_CTX_set_params(EVP_MD_CTX *ctx, const OSSL_PARAM params[]);
int EVP_MD_CTX_get_params(EVP_MD_CTX *ctx, OSSL_PARAM params[]);
const OSSL_PARAM *EVP_MD_gettable_params(const EVP_MD *digest);
const OSSL_PARAM *EVP_MD_settable_ctx_params(const EVP_MD *md);
const OSSL_PARAM *EVP_MD_gettable_ctx_params(const EVP_MD *md);
const OSSL_PARAM *EVP_MD_CTX_settable_params(EVP_MD_CTX *ctx);
const OSSL_PARAM *EVP_MD_CTX_gettable_params(EVP_MD_CTX *ctx);
int EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void *p2);
EVP_MD_CTX *EVP_MD_CTX_new(void);
int EVP_MD_CTX_reset(EVP_MD_CTX *ctx);
void EVP_MD_CTX_free(EVP_MD_CTX *ctx);
# define EVP_MD_CTX_create()     EVP_MD_CTX_new()
# define EVP_MD_CTX_init(ctx)    EVP_MD_CTX_reset((ctx))
# define EVP_MD_CTX_destroy(ctx) EVP_MD_CTX_free((ctx))
__owur int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in);
void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags);
void EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags);
int EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, int flags);
__owur int EVP_DigestInit_ex2(EVP_MD_CTX *ctx, const EVP_MD *type,
                              const OSSL_PARAM params[]);
__owur int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type,
                                 ENGINE *impl);
__owur int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d,
                                size_t cnt);
__owur int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md,
                                  unsigned int *s);
__owur int EVP_Digest(const void *data, size_t count,
                          unsigned char *md, unsigned int *size,
                          const EVP_MD *type, ENGINE *impl);
__owur int EVP_Q_digest(OSSL_LIB_CTX *libctx, const char *name,
                        const char *propq, const void *data, size_t datalen,
                        unsigned char *md, size_t *mdlen);

__owur int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in);
__owur int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type);
__owur int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md,
                           unsigned int *s);
__owur int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, unsigned char *md,
                              size_t len);

__owur EVP_MD *EVP_MD_fetch(OSSL_LIB_CTX *ctx, const char *algorithm,
                            const char *properties);

int EVP_MD_up_ref(EVP_MD *md);
void EVP_MD_free(EVP_MD *md);

int EVP_read_pw_string(char *buf, int length, const char *prompt, int verify);
int EVP_read_pw_string_min(char *buf, int minlen, int maxlen,
                           const char *prompt, int verify);
void EVP_set_pw_prompt(const char *prompt);
char *EVP_get_pw_prompt(void);

__owur int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md,
                          const unsigned char *salt,
                          const unsigned char *data, int datal, int count,
                          unsigned char *key, unsigned char *iv);

void EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags);
void EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags);
int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags);

__owur int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
                           const unsigned char *key, const unsigned char *iv);
/*__owur*/ int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx,
                                  const EVP_CIPHER *cipher, ENGINE *impl,
                                  const unsigned char *key,
                                  const unsigned char *iv);
__owur int EVP_EncryptInit_ex2(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
                               const unsigned char *key,
                               const unsigned char *iv,
                               const OSSL_PARAM params[]);
/*__owur*/ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
                                 int *outl, const unsigned char *in, int inl);
/*__owur*/ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out,
                                   int *outl);
/*__owur*/ int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out,
                                int *outl);

__owur int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
                           const unsigned char *key, const unsigned char *iv);
/*__owur*/ int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx,
                                  const EVP_CIPHER *cipher, ENGINE *impl,
                                  const unsigned char *key,
                                  const unsigned char *iv);
__owur int EVP_DecryptInit_ex2(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
                               const unsigned char *key,
                               const unsigned char *iv,
                               const OSSL_PARAM params[]);
/*__owur*/ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
                                 int *outl, const unsigned char *in, int inl);
__owur int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm,
                            int *outl);
/*__owur*/ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm,
                                   int *outl);

__owur int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
                          const unsigned char *key, const unsigned char *iv,
                          int enc);
/*__owur*/ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx,
                                 const EVP_CIPHER *cipher, ENGINE *impl,
                                 const unsigned char *key,
                                 const unsigned char *iv, int enc);
__owur int EVP_CipherInit_ex2(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
                              const unsigned char *key, const unsigned char *iv,
                              int enc, const OSSL_PARAM params[]);
__owur int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
                            int *outl, const unsigned char *in, int inl);
__owur int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm,
                           int *outl);
__owur int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm,
                              int *outl);

__owur int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s,
                         EVP_PKEY *pkey);
__owur int EVP_SignFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s,
                            EVP_PKEY *pkey, OSSL_LIB_CTX *libctx,
                            const char *propq);

__owur int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret,
                          size_t *siglen, const unsigned char *tbs,
                          size_t tbslen);

__owur int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf,
                           unsigned int siglen, EVP_PKEY *pkey);
__owur int EVP_VerifyFinal_ex(EVP_MD_CTX *ctx, const unsigned char *sigbuf,
                              unsigned int siglen, EVP_PKEY *pkey,
                              OSSL_LIB_CTX *libctx, const char *propq);

__owur int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret,
                            size_t siglen, const unsigned char *tbs,
                            size_t tbslen);

int EVP_DigestSignInit_ex(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
                          const char *mdname, OSSL_LIB_CTX *libctx,
                          const char *props, EVP_PKEY *pkey,
                          const OSSL_PARAM params[]);
/*__owur*/ int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
                                  const EVP_MD *type, ENGINE *e,
                                  EVP_PKEY *pkey);
int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize);
__owur int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
                               size_t *siglen);

int EVP_DigestVerifyInit_ex(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
                            const char *mdname, OSSL_LIB_CTX *libctx,
                            const char *props, EVP_PKEY *pkey,
                            const OSSL_PARAM params[]);
__owur int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
                                const EVP_MD *type, ENGINE *e,
                                EVP_PKEY *pkey);
int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize);
__owur int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
                                 size_t siglen);

__owur int EVP_OpenInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
                        const unsigned char *ek, int ekl,
                        const unsigned char *iv, EVP_PKEY *priv);
__owur int EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);

__owur int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
                        unsigned char **ek, int *ekl, unsigned char *iv,
                        EVP_PKEY **pubk, int npubk);
__owur int EVP_SealFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);

EVP_ENCODE_CTX *EVP_ENCODE_CTX_new(void);
void EVP_ENCODE_CTX_free(EVP_ENCODE_CTX *ctx);
int EVP_ENCODE_CTX_copy(EVP_ENCODE_CTX *dctx, const EVP_ENCODE_CTX *sctx);
int EVP_ENCODE_CTX_num(EVP_ENCODE_CTX *ctx);
void EVP_EncodeInit(EVP_ENCODE_CTX *ctx);
int EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
                     const unsigned char *in, int inl);
void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl);
int EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int n);

void EVP_DecodeInit(EVP_ENCODE_CTX *ctx);
int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
                     const unsigned char *in, int inl);
int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned
                    char *out, int *outl);
int EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n);

# ifndef OPENSSL_NO_DEPRECATED_1_1_0
#  define EVP_CIPHER_CTX_init(c)      EVP_CIPHER_CTX_reset(c)
#  define EVP_CIPHER_CTX_cleanup(c)   EVP_CIPHER_CTX_reset(c)
# endif
EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void);
int EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *c);
void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *c);
int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen);
int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *c, int pad);
int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr);
int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key);
int EVP_CIPHER_get_params(EVP_CIPHER *cipher, OSSL_PARAM params[]);
int EVP_CIPHER_CTX_set_params(EVP_CIPHER_CTX *ctx, const OSSL_PARAM params[]);
int EVP_CIPHER_CTX_get_params(EVP_CIPHER_CTX *ctx, OSSL_PARAM params[]);
const OSSL_PARAM *EVP_CIPHER_gettable_params(const EVP_CIPHER *cipher);
const OSSL_PARAM *EVP_CIPHER_settable_ctx_params(const EVP_CIPHER *cipher);
const OSSL_PARAM *EVP_CIPHER_gettable_ctx_params(const EVP_CIPHER *cipher);
const OSSL_PARAM *EVP_CIPHER_CTX_settable_params(EVP_CIPHER_CTX *ctx);
const OSSL_PARAM *EVP_CIPHER_CTX_gettable_params(EVP_CIPHER_CTX *ctx);

const BIO_METHOD *BIO_f_md(void);
const BIO_METHOD *BIO_f_base64(void);
const BIO_METHOD *BIO_f_cipher(void);
const BIO_METHOD *BIO_f_reliable(void);
__owur int BIO_set_cipher(BIO *b, const EVP_CIPHER *c, const unsigned char *k,
                          const unsigned char *i, int enc);

const EVP_MD *EVP_md_null(void);
# ifndef OPENSSL_NO_MD2
const EVP_MD *EVP_md2(void);
# endif
# ifndef OPENSSL_NO_MD4
const EVP_MD *EVP_md4(void);
# endif
# ifndef OPENSSL_NO_MD5
const EVP_MD *EVP_md5(void);
const EVP_MD *EVP_md5_sha1(void);
# endif
# ifndef OPENSSL_NO_BLAKE2
const EVP_MD *EVP_blake2b512(void);
const EVP_MD *EVP_blake2s256(void);
# endif
const EVP_MD *EVP_sha1(void);
const EVP_MD *EVP_sha224(void);
const EVP_MD *EVP_sha256(void);
const EVP_MD *EVP_sha384(void);
const EVP_MD *EVP_sha512(void);
const EVP_MD *EVP_sha512_224(void);
const EVP_MD *EVP_sha512_256(void);
const EVP_MD *EVP_sha3_224(void);
const EVP_MD *EVP_sha3_256(void);
const EVP_MD *EVP_sha3_384(void);
const EVP_MD *EVP_sha3_512(void);
const EVP_MD *EVP_shake128(void);
const EVP_MD *EVP_shake256(void);

# ifndef OPENSSL_NO_MDC2
const EVP_MD *EVP_mdc2(void);
# endif
# ifndef OPENSSL_NO_RMD160
const EVP_MD *EVP_ripemd160(void);
# endif
# ifndef OPENSSL_NO_WHIRLPOOL
const EVP_MD *EVP_whirlpool(void);
# endif
# ifndef OPENSSL_NO_SM3
const EVP_MD *EVP_sm3(void);
# endif
const EVP_CIPHER *EVP_enc_null(void); /* does nothing :-) */
# ifndef OPENSSL_NO_DES
const EVP_CIPHER *EVP_des_ecb(void);
const EVP_CIPHER *EVP_des_ede(void);
const EVP_CIPHER *EVP_des_ede3(void);
const EVP_CIPHER *EVP_des_ede_ecb(void);
const EVP_CIPHER *EVP_des_ede3_ecb(void);
const EVP_CIPHER *EVP_des_cfb64(void);
#  define EVP_des_cfb EVP_des_cfb64
const EVP_CIPHER *EVP_des_cfb1(void);
const EVP_CIPHER *EVP_des_cfb8(void);
const EVP_CIPHER *EVP_des_ede_cfb64(void);
#  define EVP_des_ede_cfb EVP_des_ede_cfb64
const EVP_CIPHER *EVP_des_ede3_cfb64(void);
#  define EVP_des_ede3_cfb EVP_des_ede3_cfb64
const EVP_CIPHER *EVP_des_ede3_cfb1(void);
const EVP_CIPHER *EVP_des_ede3_cfb8(void);
const EVP_CIPHER *EVP_des_ofb(void);
const EVP_CIPHER *EVP_des_ede_ofb(void);
const EVP_CIPHER *EVP_des_ede3_ofb(void);
const EVP_CIPHER *EVP_des_cbc(void);
const EVP_CIPHER *EVP_des_ede_cbc(void);
const EVP_CIPHER *EVP_des_ede3_cbc(void);
const EVP_CIPHER *EVP_desx_cbc(void);
const EVP_CIPHER *EVP_des_ede3_wrap(void);
/*
 * This should now be supported through the dev_crypto ENGINE. But also, why
 * are rc4 and md5 declarations made here inside a "NO_DES" precompiler
 * branch?
 */
# endif
# ifndef OPENSSL_NO_RC4
const EVP_CIPHER *EVP_rc4(void);
const EVP_CIPHER *EVP_rc4_40(void);
#  ifndef OPENSSL_NO_MD5
const EVP_CIPHER *EVP_rc4_hmac_md5(void);
#  endif
# endif
# ifndef OPENSSL_NO_IDEA
const EVP_CIPHER *EVP_idea_ecb(void);
const EVP_CIPHER *EVP_idea_cfb64(void);
#  define EVP_idea_cfb EVP_idea_cfb64
const EVP_CIPHER *EVP_idea_ofb(void);
const EVP_CIPHER *EVP_idea_cbc(void);
# endif
# ifndef OPENSSL_NO_RC2
const EVP_CIPHER *EVP_rc2_ecb(void);
const EVP_CIPHER *EVP_rc2_cbc(void);
const EVP_CIPHER *EVP_rc2_40_cbc(void);
const EVP_CIPHER *EVP_rc2_64_cbc(void);
const EVP_CIPHER *EVP_rc2_cfb64(void);
#  define EVP_rc2_cfb EVP_rc2_cfb64
const EVP_CIPHER *EVP_rc2_ofb(void);
# endif
# ifndef OPENSSL_NO_BF
const EVP_CIPHER *EVP_bf_ecb(void);
const EVP_CIPHER *EVP_bf_cbc(void);
const EVP_CIPHER *EVP_bf_cfb64(void);
#  define EVP_bf_cfb EVP_bf_cfb64
const EVP_CIPHER *EVP_bf_ofb(void);
# endif
# ifndef OPENSSL_NO_CAST
const EVP_CIPHER *EVP_cast5_ecb(void);
const EVP_CIPHER *EVP_cast5_cbc(void);
const EVP_CIPHER *EVP_cast5_cfb64(void);
#  define EVP_cast5_cfb EVP_cast5_cfb64
const EVP_CIPHER *EVP_cast5_ofb(void);
# endif
# ifndef OPENSSL_NO_RC5
const EVP_CIPHER *EVP_rc5_32_12_16_cbc(void);
const EVP_CIPHER *EVP_rc5_32_12_16_ecb(void);
const EVP_CIPHER *EVP_rc5_32_12_16_cfb64(void);
#  define EVP_rc5_32_12_16_cfb EVP_rc5_32_12_16_cfb64
const EVP_CIPHER *EVP_rc5_32_12_16_ofb(void);
# endif
const EVP_CIPHER *EVP_aes_128_ecb(void);
const EVP_CIPHER *EVP_aes_128_cbc(void);
const EVP_CIPHER *EVP_aes_128_cfb1(void);
const EVP_CIPHER *EVP_aes_128_cfb8(void);
const EVP_CIPHER *EVP_aes_128_cfb128(void);
# define EVP_aes_128_cfb EVP_aes_128_cfb128
const EVP_CIPHER *EVP_aes_128_ofb(void);
const EVP_CIPHER *EVP_aes_128_ctr(void);
const EVP_CIPHER *EVP_aes_128_ccm(void);
const EVP_CIPHER *EVP_aes_128_gcm(void);
const EVP_CIPHER *EVP_aes_128_xts(void);
const EVP_CIPHER *EVP_aes_128_wrap(void);
const EVP_CIPHER *EVP_aes_128_wrap_pad(void);
# ifndef OPENSSL_NO_OCB
const EVP_CIPHER *EVP_aes_128_ocb(void);
# endif
const EVP_CIPHER *EVP_aes_192_ecb(void);
const EVP_CIPHER *EVP_aes_192_cbc(void);
const EVP_CIPHER *EVP_aes_192_cfb1(void);
const EVP_CIPHER *EVP_aes_192_cfb8(void);
const EVP_CIPHER *EVP_aes_192_cfb128(void);
# define EVP_aes_192_cfb EVP_aes_192_cfb128
const EVP_CIPHER *EVP_aes_192_ofb(void);
const EVP_CIPHER *EVP_aes_192_ctr(void);
const EVP_CIPHER *EVP_aes_192_ccm(void);
const EVP_CIPHER *EVP_aes_192_gcm(void);
const EVP_CIPHER *EVP_aes_192_wrap(void);
const EVP_CIPHER *EVP_aes_192_wrap_pad(void);
# ifndef OPENSSL_NO_OCB
const EVP_CIPHER *EVP_aes_192_ocb(void);
# endif
const EVP_CIPHER *EVP_aes_256_ecb(void);
const EVP_CIPHER *EVP_aes_256_cbc(void);
const EVP_CIPHER *EVP_aes_256_cfb1(void);
const EVP_CIPHER *EVP_aes_256_cfb8(void);
const EVP_CIPHER *EVP_aes_256_cfb128(void);
# define EVP_aes_256_cfb EVP_aes_256_cfb128
const EVP_CIPHER *EVP_aes_256_ofb(void);
const EVP_CIPHER *EVP_aes_256_ctr(void);
const EVP_CIPHER *EVP_aes_256_ccm(void);
const EVP_CIPHER *EVP_aes_256_gcm(void);
const EVP_CIPHER *EVP_aes_256_xts(void);
const EVP_CIPHER *EVP_aes_256_wrap(void);
const EVP_CIPHER *EVP_aes_256_wrap_pad(void);
# ifndef OPENSSL_NO_OCB
const EVP_CIPHER *EVP_aes_256_ocb(void);
# endif
const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void);
const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void);
const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha256(void);
const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha256(void);
# ifndef OPENSSL_NO_ARIA
const EVP_CIPHER *EVP_aria_128_ecb(void);
const EVP_CIPHER *EVP_aria_128_cbc(void);
const EVP_CIPHER *EVP_aria_128_cfb1(void);
const EVP_CIPHER *EVP_aria_128_cfb8(void);
const EVP_CIPHER *EVP_aria_128_cfb128(void);
#  define EVP_aria_128_cfb EVP_aria_128_cfb128
const EVP_CIPHER *EVP_aria_128_ctr(void);
const EVP_CIPHER *EVP_aria_128_ofb(void);
const EVP_CIPHER *EVP_aria_128_gcm(void);
const EVP_CIPHER *EVP_aria_128_ccm(void);
const EVP_CIPHER *EVP_aria_192_ecb(void);
const EVP_CIPHER *EVP_aria_192_cbc(void);
const EVP_CIPHER *EVP_aria_192_cfb1(void);
const EVP_CIPHER *EVP_aria_192_cfb8(void);
const EVP_CIPHER *EVP_aria_192_cfb128(void);
#  define EVP_aria_192_cfb EVP_aria_192_cfb128
const EVP_CIPHER *EVP_aria_192_ctr(void);
const EVP_CIPHER *EVP_aria_192_ofb(void);
const EVP_CIPHER *EVP_aria_192_gcm(void);
const EVP_CIPHER *EVP_aria_192_ccm(void);
const EVP_CIPHER *EVP_aria_256_ecb(void);
const EVP_CIPHER *EVP_aria_256_cbc(void);
const EVP_CIPHER *EVP_aria_256_cfb1(void);
const EVP_CIPHER *EVP_aria_256_cfb8(void);
const EVP_CIPHER *EVP_aria_256_cfb128(void);
#  define EVP_aria_256_cfb EVP_aria_256_cfb128
const EVP_CIPHER *EVP_aria_256_ctr(void);
const EVP_CIPHER *EVP_aria_256_ofb(void);
const EVP_CIPHER *EVP_aria_256_gcm(void);
const EVP_CIPHER *EVP_aria_256_ccm(void);
# endif
# ifndef OPENSSL_NO_CAMELLIA
const EVP_CIPHER *EVP_camellia_128_ecb(void);
const EVP_CIPHER *EVP_camellia_128_cbc(void);
const EVP_CIPHER *EVP_camellia_128_cfb1(void);
const EVP_CIPHER *EVP_camellia_128_cfb8(void);
const EVP_CIPHER *EVP_camellia_128_cfb128(void);
#  define EVP_camellia_128_cfb EVP_camellia_128_cfb128
const EVP_CIPHER *EVP_camellia_128_ofb(void);
const EVP_CIPHER *EVP_camellia_128_ctr(void);
const EVP_CIPHER *EVP_camellia_192_ecb(void);
const EVP_CIPHER *EVP_camellia_192_cbc(void);
const EVP_CIPHER *EVP_camellia_192_cfb1(void);
const EVP_CIPHER *EVP_camellia_192_cfb8(void);
const EVP_CIPHER *EVP_camellia_192_cfb128(void);
#  define EVP_camellia_192_cfb EVP_camellia_192_cfb128
const EVP_CIPHER *EVP_camellia_192_ofb(void);
const EVP_CIPHER *EVP_camellia_192_ctr(void);
const EVP_CIPHER *EVP_camellia_256_ecb(void);
const EVP_CIPHER *EVP_camellia_256_cbc(void);
const EVP_CIPHER *EVP_camellia_256_cfb1(void);
const EVP_CIPHER *EVP_camellia_256_cfb8(void);
const EVP_CIPHER *EVP_camellia_256_cfb128(void);
#  define EVP_camellia_256_cfb EVP_camellia_256_cfb128
const EVP_CIPHER *EVP_camellia_256_ofb(void);
const EVP_CIPHER *EVP_camellia_256_ctr(void);
# endif
# ifndef OPENSSL_NO_CHACHA
const EVP_CIPHER *EVP_chacha20(void);
#  ifndef OPENSSL_NO_POLY1305
const EVP_CIPHER *EVP_chacha20_poly1305(void);
#  endif
# endif

# ifndef OPENSSL_NO_SEED
const EVP_CIPHER *EVP_seed_ecb(void);
const EVP_CIPHER *EVP_seed_cbc(void);
const EVP_CIPHER *EVP_seed_cfb128(void);
#  define EVP_seed_cfb EVP_seed_cfb128
const EVP_CIPHER *EVP_seed_ofb(void);
# endif

# ifndef OPENSSL_NO_SM4
const EVP_CIPHER *EVP_sm4_ecb(void);
const EVP_CIPHER *EVP_sm4_cbc(void);
const EVP_CIPHER *EVP_sm4_cfb128(void);
#  define EVP_sm4_cfb EVP_sm4_cfb128
const EVP_CIPHER *EVP_sm4_ofb(void);
const EVP_CIPHER *EVP_sm4_ctr(void);
# endif

# ifndef OPENSSL_NO_DEPRECATED_1_1_0
#  define OPENSSL_add_all_algorithms_conf() \
    OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS \
                        | OPENSSL_INIT_ADD_ALL_DIGESTS \
                        | OPENSSL_INIT_LOAD_CONFIG, NULL)
#  define OPENSSL_add_all_algorithms_noconf() \
    OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS \
                        | OPENSSL_INIT_ADD_ALL_DIGESTS, NULL)

#  ifdef OPENSSL_LOAD_CONF
#   define OpenSSL_add_all_algorithms() OPENSSL_add_all_algorithms_conf()
#  else
#   define OpenSSL_add_all_algorithms() OPENSSL_add_all_algorithms_noconf()
#  endif

#  define OpenSSL_add_all_ciphers() \
    OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS, NULL)
#  define OpenSSL_add_all_digests() \
    OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_DIGESTS, NULL)

#  define EVP_cleanup() while(0) continue
# endif

int EVP_add_cipher(const EVP_CIPHER *cipher);
int EVP_add_digest(const EVP_MD *digest);

const EVP_CIPHER *EVP_get_cipherbyname(const char *name);
const EVP_MD *EVP_get_digestbyname(const char *name);

void EVP_CIPHER_do_all(void (*fn) (const EVP_CIPHER *ciph,
                                   const char *from, const char *to, void *x),
                       void *arg);
void EVP_CIPHER_do_all_sorted(void (*fn)
                               (const EVP_CIPHER *ciph, const char *from,
                                const char *to, void *x), void *arg);
void EVP_CIPHER_do_all_provided(OSSL_LIB_CTX *libctx,
                                void (*fn)(EVP_CIPHER *cipher, void *arg),
                                void *arg);

void EVP_MD_do_all(void (*fn) (const EVP_MD *ciph,
                               const char *from, const char *to, void *x),
                   void *arg);
void EVP_MD_do_all_sorted(void (*fn)
                           (const EVP_MD *ciph, const char *from,
                            const char *to, void *x), void *arg);
void EVP_MD_do_all_provided(OSSL_LIB_CTX *libctx,
                            void (*fn)(EVP_MD *md, void *arg),
                            void *arg);

/* MAC stuff */

EVP_MAC *EVP_MAC_fetch(OSSL_LIB_CTX *libctx, const char *algorithm,
                       const char *properties);
int EVP_MAC_up_ref(EVP_MAC *mac);
void EVP_MAC_free(EVP_MAC *mac);
const char *EVP_MAC_get0_name(const EVP_MAC *mac);
const char *EVP_MAC_get0_description(const EVP_MAC *mac);
int EVP_MAC_is_a(const EVP_MAC *mac, const char *name);
const OSSL_PROVIDER *EVP_MAC_get0_provider(const EVP_MAC *mac);
int EVP_MAC_get_params(EVP_MAC *mac, OSSL_PARAM params[]);

EVP_MAC_CTX *EVP_MAC_CTX_new(EVP_MAC *mac);
void EVP_MAC_CTX_free(EVP_MAC_CTX *ctx);
EVP_MAC_CTX *EVP_MAC_CTX_dup(const EVP_MAC_CTX *src);
EVP_MAC *EVP_MAC_CTX_get0_mac(EVP_MAC_CTX *ctx);
int EVP_MAC_CTX_get_params(EVP_MAC_CTX *ctx, OSSL_PARAM params[]);
int EVP_MAC_CTX_set_params(EVP_MAC_CTX *ctx, const OSSL_PARAM params[]);

size_t EVP_MAC_CTX_get_mac_size(EVP_MAC_CTX *ctx);
size_t EVP_MAC_CTX_get_block_size(EVP_MAC_CTX *ctx);
unsigned char *EVP_Q_mac(OSSL_LIB_CTX *libctx, const char *name, const char *propq,
                         const char *subalg, const OSSL_PARAM *params,
                         const void *key, size_t keylen,
                         const unsigned char *data, size_t datalen,
                         unsigned char *out, size_t outsize, size_t *outlen);
int EVP_MAC_init(EVP_MAC_CTX *ctx, const unsigned char *key, size_t keylen,
                 const OSSL_PARAM params[]);
int EVP_MAC_update(EVP_MAC_CTX *ctx, const unsigned char *data, size_t datalen);
int EVP_MAC_final(EVP_MAC_CTX *ctx,
                  unsigned char *out, size_t *outl, size_t outsize);
int EVP_MAC_finalXOF(EVP_MAC_CTX *ctx, unsigned char *out, size_t outsize);
const OSSL_PARAM *EVP_MAC_gettable_params(const EVP_MAC *mac);
const OSSL_PARAM *EVP_MAC_gettable_ctx_params(const EVP_MAC *mac);
const OSSL_PARAM *EVP_MAC_settable_ctx_params(const EVP_MAC *mac);
const OSSL_PARAM *EVP_MAC_CTX_gettable_params(EVP_MAC_CTX *ctx);
const OSSL_PARAM *EVP_MAC_CTX_settable_params(EVP_MAC_CTX *ctx);

void EVP_MAC_do_all_provided(OSSL_LIB_CTX *libctx,
                             void (*fn)(EVP_MAC *mac, void *arg),
                             void *arg);
int EVP_MAC_names_do_all(const EVP_MAC *mac,
                         void (*fn)(const char *name, void *data),
                         void *data);

/* RAND stuff */
EVP_RAND *EVP_RAND_fetch(OSSL_LIB_CTX *libctx, const char *algorithm,
                         const char *properties);
int EVP_RAND_up_ref(EVP_RAND *rand);
void EVP_RAND_free(EVP_RAND *rand);
const char *EVP_RAND_get0_name(const EVP_RAND *rand);
const char *EVP_RAND_get0_description(const EVP_RAND *md);
int EVP_RAND_is_a(const EVP_RAND *rand, const char *name);
const OSSL_PROVIDER *EVP_RAND_get0_provider(const EVP_RAND *rand);
int EVP_RAND_get_params(EVP_RAND *rand, OSSL_PARAM params[]);

EVP_RAND_CTX *EVP_RAND_CTX_new(EVP_RAND *rand, EVP_RAND_CTX *parent);
void EVP_RAND_CTX_free(EVP_RAND_CTX *ctx);
EVP_RAND *EVP_RAND_CTX_get0_rand(EVP_RAND_CTX *ctx);
int EVP_RAND_CTX_get_params(EVP_RAND_CTX *ctx, OSSL_PARAM params[]);
int EVP_RAND_CTX_set_params(EVP_RAND_CTX *ctx, const OSSL_PARAM params[]);
const OSSL_PARAM *EVP_RAND_gettable_params(const EVP_RAND *rand);
const OSSL_PARAM *EVP_RAND_gettable_ctx_params(const EVP_RAND *rand);
const OSSL_PARAM *EVP_RAND_settable_ctx_params(const EVP_RAND *rand);
const OSSL_PARAM *EVP_RAND_CTX_gettable_params(EVP_RAND_CTX *ctx);
const OSSL_PARAM *EVP_RAND_CTX_settable_params(EVP_RAND_CTX *ctx);

void EVP_RAND_do_all_provided(OSSL_LIB_CTX *libctx,
                              void (*fn)(EVP_RAND *rand, void *arg),
                              void *arg);
int EVP_RAND_names_do_all(const EVP_RAND *rand,
                          void (*fn)(const char *name, void *data),
                          void *data);

__owur int EVP_RAND_instantiate(EVP_RAND_CTX *ctx, unsigned int strength,
                                int prediction_resistance,
                                const unsigned char *pstr, size_t pstr_len,
                                const OSSL_PARAM params[]);
int EVP_RAND_uninstantiate(EVP_RAND_CTX *ctx);
__owur int EVP_RAND_generate(EVP_RAND_CTX *ctx, unsigned char *out,
                             size_t outlen, unsigned int strength,
                             int prediction_resistance,
                             const unsigned char *addin, size_t addin_len);
int EVP_RAND_reseed(EVP_RAND_CTX *ctx, int prediction_resistance,
                    const unsigned char *ent, size_t ent_len,
                    const unsigned char *addin, size_t addin_len);
__owur int EVP_RAND_nonce(EVP_RAND_CTX *ctx, unsigned char *out, size_t outlen);
__owur int EVP_RAND_enable_locking(EVP_RAND_CTX *ctx);

int EVP_RAND_verify_zeroization(EVP_RAND_CTX *ctx);
unsigned int EVP_RAND_get_strength(EVP_RAND_CTX *ctx);
int EVP_RAND_get_state(EVP_RAND_CTX *ctx);

# define EVP_RAND_STATE_UNINITIALISED    0
# define EVP_RAND_STATE_READY            1
# define EVP_RAND_STATE_ERROR            2

/* PKEY stuff */
# ifndef OPENSSL_NO_DEPRECATED_3_0
OSSL_DEPRECATEDIN_3_0 int EVP_PKEY_decrypt_old(unsigned char *dec_key,
                                          const unsigned char *enc_key,
                                          int enc_key_len,
                                          EVP_PKEY *private_key);
OSSL_DEPRECATEDIN_3_0 int EVP_PKEY_encrypt_old(unsigned char *enc_key,
                                          const unsigned char *key,
                                          int key_len, EVP_PKEY *pub_key);
# endif
int EVP_PKEY_is_a(const EVP_PKEY *pkey, const char *name);
int EVP_PKEY_type_names_do_all(const EVP_PKEY *pkey,
                               void (*fn)(const char *name, void *data),
                               void *data);
int EVP_PKEY_type(int type);
int EVP_PKEY_get_id(const EVP_PKEY *pkey);
# define EVP_PKEY_id EVP_PKEY_get_id
int EVP_PKEY_get_base_id(const EVP_PKEY *pkey);
# define EVP_PKEY_base_id EVP_PKEY_get_base_id
int EVP_PKEY_get_bits(const EVP_PKEY *pkey);
# define EVP_PKEY_bits EVP_PKEY_get_bits
int EVP_PKEY_get_security_bits(const EVP_PKEY *pkey);
# define EVP_PKEY_security_bits EVP_PKEY_get_security_bits
int EVP_PKEY_get_size(const EVP_PKEY *pkey);
# define EVP_PKEY_size EVP_PKEY_get_size
int EVP_PKEY_can_sign(const EVP_PKEY *pkey);
int EVP_PKEY_set_type(EVP_PKEY *pkey, int type);
int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len);
int EVP_PKEY_set_type_by_keymgmt(EVP_PKEY *pkey, EVP_KEYMGMT *keymgmt);
# ifndef OPENSSL_NO_DEPRECATED_3_0
#  ifndef OPENSSL_NO_ENGINE
OSSL_DEPRECATEDIN_3_0
int EVP_PKEY_set1_engine(EVP_PKEY *pkey, ENGINE *e);
OSSL_DEPRECATEDIN_3_0
ENGINE *EVP_PKEY_get0_engine(const EVP_PKEY *pkey);
#  endif
OSSL_DEPRECATEDIN_3_0
int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key);
OSSL_DEPRECATEDIN_3_0
void *EVP_PKEY_get0(const EVP_PKEY *pkey);
OSSL_DEPRECATEDIN_3_0
const unsigned char *EVP_PKEY_get0_hmac(const EVP_PKEY *pkey, size_t *len);
#  ifndef OPENSSL_NO_POLY1305
OSSL_DEPRECATEDIN_3_0
const unsigned char *EVP_PKEY_get0_poly1305(const EVP_PKEY *pkey, size_t *len);
#  endif
#  ifndef OPENSSL_NO_SIPHASH
OSSL_DEPRECATEDIN_3_0
const unsigned char *EVP_PKEY_get0_siphash(const EVP_PKEY *pkey, size_t *len);
#  endif

struct rsa_st;
OSSL_DEPRECATEDIN_3_0
int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, struct rsa_st *key);
OSSL_DEPRECATEDIN_3_0
const struct rsa_st *EVP_PKEY_get0_RSA(const EVP_PKEY *pkey);
OSSL_DEPRECATEDIN_3_0
struct rsa_st *EVP_PKEY_get1_RSA(EVP_PKEY *pkey);

#  ifndef OPENSSL_NO_DSA
struct dsa_st;
OSSL_DEPRECATEDIN_3_0
int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, struct dsa_st *key);
OSSL_DEPRECATEDIN_3_0
const struct dsa_st *EVP_PKEY_get0_DSA(const EVP_PKEY *pkey);
OSSL_DEPRECATEDIN_3_0
struct dsa_st *EVP_PKEY_get1_DSA(EVP_PKEY *pkey);
#  endif

#  ifndef OPENSSL_NO_DH
struct dh_st;
OSSL_DEPRECATEDIN_3_0 int EVP_PKEY_set1_DH(EVP_PKEY *pkey, struct dh_st *key);
OSSL_DEPRECATEDIN_3_0 const struct dh_st *EVP_PKEY_get0_DH(const EVP_PKEY *pkey);
OSSL_DEPRECATEDIN_3_0 struct dh_st *EVP_PKEY_get1_DH(EVP_PKEY *pkey);
#  endif

#  ifndef OPENSSL_NO_EC
struct ec_key_st;
OSSL_DEPRECATEDIN_3_0
int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, struct ec_key_st *key);
OSSL_DEPRECATEDIN_3_0
const struct ec_key_st *EVP_PKEY_get0_EC_KEY(const EVP_PKEY *pkey);
OSSL_DEPRECATEDIN_3_0
struct ec_key_st *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey);
#  endif
# endif /* OPENSSL_NO_DEPRECATED_3_0 */

EVP_PKEY *EVP_PKEY_new(void);
int EVP_PKEY_up_ref(EVP_PKEY *pkey);
EVP_PKEY *EVP_PKEY_dup(EVP_PKEY *pkey);
void EVP_PKEY_free(EVP_PKEY *pkey);
const char *EVP_PKEY_get0_description(const EVP_PKEY *pkey);
const OSSL_PROVIDER *EVP_PKEY_get0_provider(const EVP_PKEY *key);

EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp,
                        long length);
int i2d_PublicKey(const EVP_PKEY *a, unsigned char **pp);


EVP_PKEY *d2i_PrivateKey_ex(int type, EVP_PKEY **a, const unsigned char **pp,
                            long length, OSSL_LIB_CTX *libctx,
                            const char *propq);
EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp,
                         long length);
EVP_PKEY *d2i_AutoPrivateKey_ex(EVP_PKEY **a, const unsigned char **pp,
                                long length, OSSL_LIB_CTX *libctx,
                                const char *propq);
EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp,
                             long length);
int i2d_PrivateKey(const EVP_PKEY *a, unsigned char **pp);

int i2d_KeyParams(const EVP_PKEY *a, unsigned char **pp);
EVP_PKEY *d2i_KeyParams(int type, EVP_PKEY **a, const unsigned char **pp,
                        long length);
int i2d_KeyParams_bio(BIO *bp, const EVP_PKEY *pkey);
EVP_PKEY *d2i_KeyParams_bio(int type, EVP_PKEY **a, BIO *in);

int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from);
int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey);
int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode);
int EVP_PKEY_parameters_eq(const EVP_PKEY *a, const EVP_PKEY *b);
int EVP_PKEY_eq(const EVP_PKEY *a, const EVP_PKEY *b);

# ifndef OPENSSL_NO_DEPRECATED_3_0
OSSL_DEPRECATEDIN_3_0
int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b);
OSSL_DEPRECATEDIN_3_0
int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b);
# endif

int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
                          int indent, ASN1_PCTX *pctx);
int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
                           int indent, ASN1_PCTX *pctx);
int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
                          int indent, ASN1_PCTX *pctx);
# ifndef OPENSSL_NO_STDIO
int EVP_PKEY_print_public_fp(FILE *fp, const EVP_PKEY *pkey,
                             int indent, ASN1_PCTX *pctx);
int EVP_PKEY_print_private_fp(FILE *fp, const EVP_PKEY *pkey,
                              int indent, ASN1_PCTX *pctx);
int EVP_PKEY_print_params_fp(FILE *fp, const EVP_PKEY *pkey,
                             int indent, ASN1_PCTX *pctx);
# endif

int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid);
int EVP_PKEY_get_default_digest_name(EVP_PKEY *pkey,
                                     char *mdname, size_t mdname_sz);
int EVP_PKEY_digestsign_supports_digest(EVP_PKEY *pkey, OSSL_LIB_CTX *libctx,
                                        const char *name, const char *propq);

# ifndef OPENSSL_NO_DEPRECATED_3_0
/*
 * For backwards compatibility. Use EVP_PKEY_set1_encoded_public_key in
 * preference
 */
#  define EVP_PKEY_set1_tls_encodedpoint(pkey, pt, ptlen) \
          EVP_PKEY_set1_encoded_public_key((pkey), (pt), (ptlen))
# endif

int EVP_PKEY_set1_encoded_public_key(EVP_PKEY *pkey,
                                     const unsigned char *pub, size_t publen);

# ifndef OPENSSL_NO_DEPRECATED_3_0
/*
 * For backwards compatibility. Use EVP_PKEY_get1_encoded_public_key in
 * preference
 */
#  define EVP_PKEY_get1_tls_encodedpoint(pkey, ppt) \
          EVP_PKEY_get1_encoded_public_key((pkey), (ppt))
# endif

size_t EVP_PKEY_get1_encoded_public_key(EVP_PKEY *pkey, unsigned char **ppub);

/* calls methods */
int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type);

/* These are used by EVP_CIPHER methods */
int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type);

/* PKCS5 password based encryption */
int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
                       ASN1_TYPE *param, const EVP_CIPHER *cipher,
                       const EVP_MD *md, int en_de);
int PKCS5_PBE_keyivgen_ex(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
                          ASN1_TYPE *param, const EVP_CIPHER *cipher,
                          const EVP_MD *md, int en_de, OSSL_LIB_CTX *libctx,
                          const char *propq);
int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
                           const unsigned char *salt, int saltlen, int iter,
                           int keylen, unsigned char *out);
int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
                      const unsigned char *salt, int saltlen, int iter,
                      const EVP_MD *digest, int keylen, unsigned char *out);
int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
                          ASN1_TYPE *param, const EVP_CIPHER *cipher,
                          const EVP_MD *md, int en_de);
int PKCS5_v2_PBE_keyivgen_ex(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
                             ASN1_TYPE *param, const EVP_CIPHER *cipher,
                             const EVP_MD *md, int en_de,
                             OSSL_LIB_CTX *libctx, const char *propq);

#ifndef OPENSSL_NO_SCRYPT
int EVP_PBE_scrypt(const char *pass, size_t passlen,
                   const unsigned char *salt, size_t saltlen,
                   uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem,
                   unsigned char *key, size_t keylen);
int EVP_PBE_scrypt_ex(const char *pass, size_t passlen,
                      const unsigned char *salt, size_t saltlen,
                      uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem,
                      unsigned char *key, size_t keylen,
                      OSSL_LIB_CTX *ctx, const char *propq);

int PKCS5_v2_scrypt_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
                             int passlen, ASN1_TYPE *param,
                             const EVP_CIPHER *c, const EVP_MD *md, int en_de);
int PKCS5_v2_scrypt_keyivgen_ex(EVP_CIPHER_CTX *ctx, const char *pass,
                                int passlen, ASN1_TYPE *param,
                                const EVP_CIPHER *c, const EVP_MD *md, int en_de,
                                OSSL_LIB_CTX *libctx, const char *propq);
#endif

void PKCS5_PBE_add(void);

int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
                       ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de);

int EVP_PBE_CipherInit_ex(ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
                          ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de,
                          OSSL_LIB_CTX *libctx, const char *propq);

/* PBE type */

/* Can appear as the outermost AlgorithmIdentifier */
# define EVP_PBE_TYPE_OUTER      0x0
/* Is an PRF type OID */
# define EVP_PBE_TYPE_PRF        0x1
/* Is a PKCS#5 v2.0 KDF */
# define EVP_PBE_TYPE_KDF        0x2

int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid,
                         int md_nid, EVP_PBE_KEYGEN *keygen);
int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md,
                    EVP_PBE_KEYGEN *keygen);
int EVP_PBE_find(int type, int pbe_nid, int *pcnid, int *pmnid,
                 EVP_PBE_KEYGEN **pkeygen);
int EVP_PBE_find_ex(int type, int pbe_nid, int *pcnid, int *pmnid,
                    EVP_PBE_KEYGEN **pkeygen, EVP_PBE_KEYGEN_EX **pkeygen_ex);
void EVP_PBE_cleanup(void);
int EVP_PBE_get(int *ptype, int *ppbe_nid, size_t num);

# define ASN1_PKEY_ALIAS         0x1
# define ASN1_PKEY_DYNAMIC       0x2
# define ASN1_PKEY_SIGPARAM_NULL 0x4

# define ASN1_PKEY_CTRL_PKCS7_SIGN       0x1
# define ASN1_PKEY_CTRL_PKCS7_ENCRYPT    0x2
# define ASN1_PKEY_CTRL_DEFAULT_MD_NID   0x3
# define ASN1_PKEY_CTRL_CMS_SIGN         0x5
# define ASN1_PKEY_CTRL_CMS_ENVELOPE     0x7
# define ASN1_PKEY_CTRL_CMS_RI_TYPE      0x8

# define ASN1_PKEY_CTRL_SET1_TLS_ENCPT   0x9
# define ASN1_PKEY_CTRL_GET1_TLS_ENCPT   0xa
# define ASN1_PKEY_CTRL_CMS_IS_RI_TYPE_SUPPORTED 0xb

int EVP_PKEY_asn1_get_count(void);
const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx);
const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type);
const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe,
                                                   const char *str, int len);
int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth);
int EVP_PKEY_asn1_add_alias(int to, int from);
int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *pkey_base_id,
                            int *ppkey_flags, const char **pinfo,
                            const char **ppem_str,
                            const EVP_PKEY_ASN1_METHOD *ameth);

const EVP_PKEY_ASN1_METHOD *EVP_PKEY_get0_asn1(const EVP_PKEY *pkey);
EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_new(int id, int flags,
                                        const char *pem_str,
                                        const char *info);
void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst,
                        const EVP_PKEY_ASN1_METHOD *src);
void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth);
void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth,
                              int (*pub_decode) (EVP_PKEY *pk,
                                                 const X509_PUBKEY *pub),
                              int (*pub_encode) (X509_PUBKEY *pub,
                                                 const EVP_PKEY *pk),
                              int (*pub_cmp) (const EVP_PKEY *a,
                                              const EVP_PKEY *b),
                              int (*pub_print) (BIO *out,
                                                const EVP_PKEY *pkey,
                                                int indent, ASN1_PCTX *pctx),
                              int (*pkey_size) (const EVP_PKEY *pk),
                              int (*pkey_bits) (const EVP_PKEY *pk));
void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth,
                               int (*priv_decode) (EVP_PKEY *pk,
                                                   const PKCS8_PRIV_KEY_INFO
                                                   *p8inf),
                               int (*priv_encode) (PKCS8_PRIV_KEY_INFO *p8,
                                                   const EVP_PKEY *pk),
                               int (*priv_print) (BIO *out,
                                                  const EVP_PKEY *pkey,
                                                  int indent,
                                                  ASN1_PCTX *pctx));
void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth,
                             int (*param_decode) (EVP_PKEY *pkey,
                                                  const unsigned char **pder,
                                                  int derlen),
                             int (*param_encode) (const EVP_PKEY *pkey,
                                                  unsigned char **pder),
                             int (*param_missing) (const EVP_PKEY *pk),
                             int (*param_copy) (EVP_PKEY *to,
                                                const EVP_PKEY *from),
                             int (*param_cmp) (const EVP_PKEY *a,
                                               const EVP_PKEY *b),
                             int (*param_print) (BIO *out,
                                                 const EVP_PKEY *pkey,
                                                 int indent,
                                                 ASN1_PCTX *pctx));

void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth,
                            void (*pkey_free) (EVP_PKEY *pkey));
void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
                            int (*pkey_ctrl) (EVP_PKEY *pkey, int op,
                                              long arg1, void *arg2));
void EVP_PKEY_asn1_set_item(EVP_PKEY_ASN1_METHOD *ameth,
                            int (*item_verify) (EVP_MD_CTX *ctx,
                                                const ASN1_ITEM *it,
                                                const void *data,
                                                const X509_ALGOR *a,
                                                const ASN1_BIT_STRING *sig,
                                                EVP_PKEY *pkey),
                            int (*item_sign) (EVP_MD_CTX *ctx,
                                              const ASN1_ITEM *it,
                                              const void *data,
                                              X509_ALGOR *alg1,
                                              X509_ALGOR *alg2,
                                              ASN1_BIT_STRING *sig));

void EVP_PKEY_asn1_set_siginf(EVP_PKEY_ASN1_METHOD *ameth,
                              int (*siginf_set) (X509_SIG_INFO *siginf,
                                                 const X509_ALGOR *alg,
                                                 const ASN1_STRING *sig));

void EVP_PKEY_asn1_set_check(EVP_PKEY_ASN1_METHOD *ameth,
                             int (*pkey_check) (const EVP_PKEY *pk));

void EVP_PKEY_asn1_set_public_check(EVP_PKEY_ASN1_METHOD *ameth,
                                    int (*pkey_pub_check) (const EVP_PKEY *pk));

void EVP_PKEY_asn1_set_param_check(EVP_PKEY_ASN1_METHOD *ameth,
                                   int (*pkey_param_check) (const EVP_PKEY *pk));

void EVP_PKEY_asn1_set_set_priv_key(EVP_PKEY_ASN1_METHOD *ameth,
                                    int (*set_priv_key) (EVP_PKEY *pk,
                                                         const unsigned char
                                                            *priv,
                                                         size_t len));
void EVP_PKEY_asn1_set_set_pub_key(EVP_PKEY_ASN1_METHOD *ameth,
                                   int (*set_pub_key) (EVP_PKEY *pk,
                                                       const unsigned char *pub,
                                                       size_t len));
void EVP_PKEY_asn1_set_get_priv_key(EVP_PKEY_ASN1_METHOD *ameth,
                                    int (*get_priv_key) (const EVP_PKEY *pk,
                                                         unsigned char *priv,
                                                         size_t *len));
void EVP_PKEY_asn1_set_get_pub_key(EVP_PKEY_ASN1_METHOD *ameth,
                                   int (*get_pub_key) (const EVP_PKEY *pk,
                                                       unsigned char *pub,
                                                       size_t *len));

void EVP_PKEY_asn1_set_security_bits(EVP_PKEY_ASN1_METHOD *ameth,
                                     int (*pkey_security_bits) (const EVP_PKEY
                                                                *pk));

int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **md);
int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md);

int EVP_PKEY_CTX_set1_id(EVP_PKEY_CTX *ctx, const void *id, int len);
int EVP_PKEY_CTX_get1_id(EVP_PKEY_CTX *ctx, void *id);
int EVP_PKEY_CTX_get1_id_len(EVP_PKEY_CTX *ctx, size_t *id_len);

int EVP_PKEY_CTX_set_kem_op(EVP_PKEY_CTX *ctx, const char *op);

const char *EVP_PKEY_get0_type_name(const EVP_PKEY *key);

# define EVP_PKEY_OP_UNDEFINED           0
# define EVP_PKEY_OP_PARAMGEN            (1<<1)
# define EVP_PKEY_OP_KEYGEN              (1<<2)
# define EVP_PKEY_OP_FROMDATA            (1<<3)
# define EVP_PKEY_OP_SIGN                (1<<4)
# define EVP_PKEY_OP_VERIFY              (1<<5)
# define EVP_PKEY_OP_VERIFYRECOVER       (1<<6)
# define EVP_PKEY_OP_SIGNCTX             (1<<7)
# define EVP_PKEY_OP_VERIFYCTX           (1<<8)
# define EVP_PKEY_OP_ENCRYPT             (1<<9)
# define EVP_PKEY_OP_DECRYPT             (1<<10)
# define EVP_PKEY_OP_DERIVE              (1<<11)
# define EVP_PKEY_OP_ENCAPSULATE         (1<<12)
# define EVP_PKEY_OP_DECAPSULATE         (1<<13)

# define EVP_PKEY_OP_TYPE_SIG    \
        (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY | EVP_PKEY_OP_VERIFYRECOVER \
                | EVP_PKEY_OP_SIGNCTX | EVP_PKEY_OP_VERIFYCTX)

# define EVP_PKEY_OP_TYPE_CRYPT \
        (EVP_PKEY_OP_ENCRYPT | EVP_PKEY_OP_DECRYPT)

# define EVP_PKEY_OP_TYPE_NOGEN \
        (EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT | EVP_PKEY_OP_DERIVE)

# define EVP_PKEY_OP_TYPE_GEN \
        (EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN)


int EVP_PKEY_CTX_set_mac_key(EVP_PKEY_CTX *ctx, const unsigned char *key,
                             int keylen);

# define EVP_PKEY_CTRL_MD                1
# define EVP_PKEY_CTRL_PEER_KEY          2
# define EVP_PKEY_CTRL_SET_MAC_KEY       6
# define EVP_PKEY_CTRL_DIGESTINIT        7
/* Used by GOST key encryption in TLS */
# define EVP_PKEY_CTRL_SET_IV            8
# ifndef OPENSSL_NO_DEPRECATED_3_0
#  define EVP_PKEY_CTRL_PKCS7_ENCRYPT     3
#  define EVP_PKEY_CTRL_PKCS7_DECRYPT     4
#  define EVP_PKEY_CTRL_PKCS7_SIGN        5
#  define EVP_PKEY_CTRL_CMS_ENCRYPT       9
#  define EVP_PKEY_CTRL_CMS_DECRYPT       10
#  define EVP_PKEY_CTRL_CMS_SIGN          11
# endif
# define EVP_PKEY_CTRL_CIPHER            12
# define EVP_PKEY_CTRL_GET_MD            13
# define EVP_PKEY_CTRL_SET_DIGEST_SIZE   14
# define EVP_PKEY_CTRL_SET1_ID           15
# define EVP_PKEY_CTRL_GET1_ID           16
# define EVP_PKEY_CTRL_GET1_ID_LEN       17

# define EVP_PKEY_ALG_CTRL               0x1000

# define EVP_PKEY_FLAG_AUTOARGLEN        2
/*
 * Method handles all operations: don't assume any digest related defaults.
 */
# define EVP_PKEY_FLAG_SIGCTX_CUSTOM     4
# ifndef OPENSSL_NO_DEPRECATED_3_0
OSSL_DEPRECATEDIN_3_0 const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type);
OSSL_DEPRECATEDIN_3_0 EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags);
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags,
                                              const EVP_PKEY_METHOD *meth);
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst,
                                         const EVP_PKEY_METHOD *src);
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth);
OSSL_DEPRECATEDIN_3_0 int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth);
OSSL_DEPRECATEDIN_3_0 int EVP_PKEY_meth_remove(const EVP_PKEY_METHOD *pmeth);
OSSL_DEPRECATEDIN_3_0 size_t EVP_PKEY_meth_get_count(void);
OSSL_DEPRECATEDIN_3_0 const EVP_PKEY_METHOD *EVP_PKEY_meth_get0(size_t idx);
# endif

EVP_KEYMGMT *EVP_KEYMGMT_fetch(OSSL_LIB_CTX *ctx, const char *algorithm,
                               const char *properties);
int EVP_KEYMGMT_up_ref(EVP_KEYMGMT *keymgmt);
void EVP_KEYMGMT_free(EVP_KEYMGMT *keymgmt);
const OSSL_PROVIDER *EVP_KEYMGMT_get0_provider(const EVP_KEYMGMT *keymgmt);
const char *EVP_KEYMGMT_get0_name(const EVP_KEYMGMT *keymgmt);
const char *EVP_KEYMGMT_get0_description(const EVP_KEYMGMT *keymgmt);
int EVP_KEYMGMT_is_a(const EVP_KEYMGMT *keymgmt, const char *name);
void EVP_KEYMGMT_do_all_provided(OSSL_LIB_CTX *libctx,
                                 void (*fn)(EVP_KEYMGMT *keymgmt, void *arg),
                                 void *arg);
int EVP_KEYMGMT_names_do_all(const EVP_KEYMGMT *keymgmt,
                             void (*fn)(const char *name, void *data),
                             void *data);
const OSSL_PARAM *EVP_KEYMGMT_gettable_params(const EVP_KEYMGMT *keymgmt);
const OSSL_PARAM *EVP_KEYMGMT_settable_params(const EVP_KEYMGMT *keymgmt);
const OSSL_PARAM *EVP_KEYMGMT_gen_settable_params(const EVP_KEYMGMT *keymgmt);

EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e);
EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e);
EVP_PKEY_CTX *EVP_PKEY_CTX_new_from_name(OSSL_LIB_CTX *libctx,
                                         const char *name,
                                         const char *propquery);
EVP_PKEY_CTX *EVP_PKEY_CTX_new_from_pkey(OSSL_LIB_CTX *libctx,
                                         EVP_PKEY *pkey, const char *propquery);
EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *ctx);
void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);
int EVP_PKEY_CTX_is_a(EVP_PKEY_CTX *ctx, const char *keytype);

int EVP_PKEY_CTX_get_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params);
const OSSL_PARAM *EVP_PKEY_CTX_gettable_params(const EVP_PKEY_CTX *ctx);
int EVP_PKEY_CTX_set_params(EVP_PKEY_CTX *ctx, const OSSL_PARAM *params);
const OSSL_PARAM *EVP_PKEY_CTX_settable_params(const EVP_PKEY_CTX *ctx);
int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
                      int cmd, int p1, void *p2);
int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
                          const char *value);
int EVP_PKEY_CTX_ctrl_uint64(EVP_PKEY_CTX *ctx, int keytype, int optype,
                             int cmd, uint64_t value);

int EVP_PKEY_CTX_str2ctrl(EVP_PKEY_CTX *ctx, int cmd, const char *str);
int EVP_PKEY_CTX_hex2ctrl(EVP_PKEY_CTX *ctx, int cmd, const char *hex);

int EVP_PKEY_CTX_md(EVP_PKEY_CTX *ctx, int optype, int cmd, const char *md);

int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx);
void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen);

EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e,
                               const unsigned char *key, int keylen);
EVP_PKEY *EVP_PKEY_new_raw_private_key_ex(OSSL_LIB_CTX *libctx,
                                          const char *keytype,
                                          const char *propq,
                                          const unsigned char *priv, size_t len);
EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *e,
                                       const unsigned char *priv,
                                       size_t len);
EVP_PKEY *EVP_PKEY_new_raw_public_key_ex(OSSL_LIB_CTX *libctx,
                                         const char *keytype, const char *propq,
                                         const unsigned char *pub, size_t len);
EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *e,
                                      const unsigned char *pub,
                                      size_t len);
int EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, unsigned char *priv,
                                 size_t *len);
int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, unsigned char *pub,
                                size_t *len);

# ifndef OPENSSL_NO_DEPRECATED_3_0
OSSL_DEPRECATEDIN_3_0
EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
                                size_t len, const EVP_CIPHER *cipher);
# endif

void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data);
void *EVP_PKEY_CTX_get_data(const EVP_PKEY_CTX *ctx);
EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx);

EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx);

void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data);
void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx);

void EVP_SIGNATURE_free(EVP_SIGNATURE *signature);
int EVP_SIGNATURE_up_ref(EVP_SIGNATURE *signature);
OSSL_PROVIDER *EVP_SIGNATURE_get0_provider(const EVP_SIGNATURE *signature);
EVP_SIGNATURE *EVP_SIGNATURE_fetch(OSSL_LIB_CTX *ctx, const char *algorithm,
                                   const char *properties);
int EVP_SIGNATURE_is_a(const EVP_SIGNATURE *signature, const char *name);
const char *EVP_SIGNATURE_get0_name(const EVP_SIGNATURE *signature);
const char *EVP_SIGNATURE_get0_description(const EVP_SIGNATURE *signature);
void EVP_SIGNATURE_do_all_provided(OSSL_LIB_CTX *libctx,
                                   void (*fn)(EVP_SIGNATURE *signature,
                                              void *data),
                                   void *data);
int EVP_SIGNATURE_names_do_all(const EVP_SIGNATURE *signature,
                               void (*fn)(const char *name, void *data),
                               void *data);
const OSSL_PARAM *EVP_SIGNATURE_gettable_ctx_params(const EVP_SIGNATURE *sig);
const OSSL_PARAM *EVP_SIGNATURE_settable_ctx_params(const EVP_SIGNATURE *sig);

void EVP_ASYM_CIPHER_free(EVP_ASYM_CIPHER *cipher);
int EVP_ASYM_CIPHER_up_ref(EVP_ASYM_CIPHER *cipher);
OSSL_PROVIDER *EVP_ASYM_CIPHER_get0_provider(const EVP_ASYM_CIPHER *cipher);
EVP_ASYM_CIPHER *EVP_ASYM_CIPHER_fetch(OSSL_LIB_CTX *ctx, const char *algorithm,
                                       const char *properties);
int EVP_ASYM_CIPHER_is_a(const EVP_ASYM_CIPHER *cipher, const char *name);
const char *EVP_ASYM_CIPHER_get0_name(const EVP_ASYM_CIPHER *cipher);
const char *EVP_ASYM_CIPHER_get0_description(const EVP_ASYM_CIPHER *cipher);
void EVP_ASYM_CIPHER_do_all_provided(OSSL_LIB_CTX *libctx,
                                     void (*fn)(EVP_ASYM_CIPHER *cipher,
                                                void *arg),
                                     void *arg);
int EVP_ASYM_CIPHER_names_do_all(const EVP_ASYM_CIPHER *cipher,
                                 void (*fn)(const char *name, void *data),
                                 void *data);
const OSSL_PARAM *EVP_ASYM_CIPHER_gettable_ctx_params(const EVP_ASYM_CIPHER *ciph);
const OSSL_PARAM *EVP_ASYM_CIPHER_settable_ctx_params(const EVP_ASYM_CIPHER *ciph);

void EVP_KEM_free(EVP_KEM *wrap);
int EVP_KEM_up_ref(EVP_KEM *wrap);
OSSL_PROVIDER *EVP_KEM_get0_provider(const EVP_KEM *wrap);
EVP_KEM *EVP_KEM_fetch(OSSL_LIB_CTX *ctx, const char *algorithm,
                       const char *properties);
int EVP_KEM_is_a(const EVP_KEM *wrap, const char *name);
const char *EVP_KEM_get0_name(const EVP_KEM *wrap);
const char *EVP_KEM_get0_description(const EVP_KEM *wrap);
void EVP_KEM_do_all_provided(OSSL_LIB_CTX *libctx,
                             void (*fn)(EVP_KEM *wrap, void *arg), void *arg);
int EVP_KEM_names_do_all(const EVP_KEM *wrap,
                         void (*fn)(const char *name, void *data), void *data);
const OSSL_PARAM *EVP_KEM_gettable_ctx_params(const EVP_KEM *kem);
const OSSL_PARAM *EVP_KEM_settable_ctx_params(const EVP_KEM *kem);

int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx);
int EVP_PKEY_sign_init_ex(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[]);
int EVP_PKEY_sign(EVP_PKEY_CTX *ctx,
                  unsigned char *sig, size_t *siglen,
                  const unsigned char *tbs, size_t tbslen);
int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx);
int EVP_PKEY_verify_init_ex(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[]);
int EVP_PKEY_verify(EVP_PKEY_CTX *ctx,
                    const unsigned char *sig, size_t siglen,
                    const unsigned char *tbs, size_t tbslen);
int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx);
int EVP_PKEY_verify_recover_init_ex(EVP_PKEY_CTX *ctx,
                                    const OSSL_PARAM params[]);
int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx,
                            unsigned char *rout, size_t *routlen,
                            const unsigned char *sig, size_t siglen);
int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx);
int EVP_PKEY_encrypt_init_ex(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[]);
int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx,
                     unsigned char *out, size_t *outlen,
                     const unsigned char *in, size_t inlen);
int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx);
int EVP_PKEY_decrypt_init_ex(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[]);
int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
                     unsigned char *out, size_t *outlen,
                     const unsigned char *in, size_t inlen);

int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx);
int EVP_PKEY_derive_init_ex(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[]);
int EVP_PKEY_derive_set_peer_ex(EVP_PKEY_CTX *ctx, EVP_PKEY *peer,
                                int validate_peer);
int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer);
int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);

int EVP_PKEY_encapsulate_init(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[]);
int EVP_PKEY_encapsulate(EVP_PKEY_CTX *ctx,
                         unsigned char *wrappedkey, size_t *wrappedkeylen,
                         unsigned char *genkey, size_t *genkeylen);
int EVP_PKEY_decapsulate_init(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[]);
int EVP_PKEY_decapsulate(EVP_PKEY_CTX *ctx,
                         unsigned char *unwrapped, size_t *unwrappedlen,
                         const unsigned char *wrapped, size_t wrappedlen);

typedef int EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx);

int EVP_PKEY_fromdata_init(EVP_PKEY_CTX *ctx);
int EVP_PKEY_fromdata(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey, int selection,
                      OSSL_PARAM param[]);
const OSSL_PARAM *EVP_PKEY_fromdata_settable(EVP_PKEY_CTX *ctx, int selection);

int EVP_PKEY_todata(const EVP_PKEY *pkey, int selection, OSSL_PARAM **params);
int EVP_PKEY_export(const EVP_PKEY *pkey, int selection,
                    OSSL_CALLBACK *export_cb, void *export_cbarg);

const OSSL_PARAM *EVP_PKEY_gettable_params(const EVP_PKEY *pkey);
int EVP_PKEY_get_params(const EVP_PKEY *pkey, OSSL_PARAM params[]);
int EVP_PKEY_get_int_param(const EVP_PKEY *pkey, const char *key_name,
                           int *out);
int EVP_PKEY_get_size_t_param(const EVP_PKEY *pkey, const char *key_name,
                              size_t *out);
int EVP_PKEY_get_bn_param(const EVP_PKEY *pkey, const char *key_name,
                          BIGNUM **bn);
int EVP_PKEY_get_utf8_string_param(const EVP_PKEY *pkey, const char *key_name,
                                    char *str, size_t max_buf_sz, size_t *out_sz);
int EVP_PKEY_get_octet_string_param(const EVP_PKEY *pkey, const char *key_name,
                                    unsigned char *buf, size_t max_buf_sz,
                                    size_t *out_sz);

const OSSL_PARAM *EVP_PKEY_settable_params(const EVP_PKEY *pkey);
int EVP_PKEY_set_params(EVP_PKEY *pkey, OSSL_PARAM params[]);
int EVP_PKEY_set_int_param(EVP_PKEY *pkey, const char *key_name, int in);
int EVP_PKEY_set_size_t_param(EVP_PKEY *pkey, const char *key_name, size_t in);
int EVP_PKEY_set_bn_param(EVP_PKEY *pkey, const char *key_name,
                          const BIGNUM *bn);
int EVP_PKEY_set_utf8_string_param(EVP_PKEY *pkey, const char *key_name,
                                   const char *str);
int EVP_PKEY_set_octet_string_param(EVP_PKEY *pkey, const char *key_name,
                                    const unsigned char *buf, size_t bsize);

int EVP_PKEY_get_ec_point_conv_form(const EVP_PKEY *pkey);
int EVP_PKEY_get_field_type(const EVP_PKEY *pkey);

EVP_PKEY *EVP_PKEY_Q_keygen(OSSL_LIB_CTX *libctx, const char *propq,
                            const char *type, ...);
int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx);
int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);
int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx);
int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);
int EVP_PKEY_generate(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);
int EVP_PKEY_check(EVP_PKEY_CTX *ctx);
int EVP_PKEY_public_check(EVP_PKEY_CTX *ctx);
int EVP_PKEY_public_check_quick(EVP_PKEY_CTX *ctx);
int EVP_PKEY_param_check(EVP_PKEY_CTX *ctx);
int EVP_PKEY_param_check_quick(EVP_PKEY_CTX *ctx);
int EVP_PKEY_private_check(EVP_PKEY_CTX *ctx);
int EVP_PKEY_pairwise_check(EVP_PKEY_CTX *ctx);

# define EVP_PKEY_get_ex_new_index(l, p, newf, dupf, freef) \
    CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_EVP_PKEY, l, p, newf, dupf, freef)
int EVP_PKEY_set_ex_data(EVP_PKEY *key, int idx, void *arg);
void *EVP_PKEY_get_ex_data(const EVP_PKEY *key, int idx);

void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb);
EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx);

int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx);
# ifndef OPENSSL_NO_DEPRECATED_3_0
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth,
                                             int (*init) (EVP_PKEY_CTX *ctx));
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_set_copy
    (EVP_PKEY_METHOD *pmeth, int (*copy) (EVP_PKEY_CTX *dst,
                                          const EVP_PKEY_CTX *src));
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_set_cleanup
    (EVP_PKEY_METHOD *pmeth, void (*cleanup) (EVP_PKEY_CTX *ctx));
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_set_paramgen
    (EVP_PKEY_METHOD *pmeth, int (*paramgen_init) (EVP_PKEY_CTX *ctx),
     int (*paramgen) (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey));
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_set_keygen
    (EVP_PKEY_METHOD *pmeth, int (*keygen_init) (EVP_PKEY_CTX *ctx),
     int (*keygen) (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey));
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_set_sign
    (EVP_PKEY_METHOD *pmeth, int (*sign_init) (EVP_PKEY_CTX *ctx),
     int (*sign) (EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
                  const unsigned char *tbs, size_t tbslen));
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_set_verify
    (EVP_PKEY_METHOD *pmeth, int (*verify_init) (EVP_PKEY_CTX *ctx),
     int (*verify) (EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen,
                    const unsigned char *tbs, size_t tbslen));
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_set_verify_recover
    (EVP_PKEY_METHOD *pmeth, int (*verify_recover_init) (EVP_PKEY_CTX *ctx),
     int (*verify_recover) (EVP_PKEY_CTX *ctx, unsigned char *sig,
                            size_t *siglen, const unsigned char *tbs,
                            size_t tbslen));
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_set_signctx
    (EVP_PKEY_METHOD *pmeth, int (*signctx_init) (EVP_PKEY_CTX *ctx,
                                                  EVP_MD_CTX *mctx),
     int (*signctx) (EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
                     EVP_MD_CTX *mctx));
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_set_verifyctx
    (EVP_PKEY_METHOD *pmeth, int (*verifyctx_init) (EVP_PKEY_CTX *ctx,
                                                    EVP_MD_CTX *mctx),
     int (*verifyctx) (EVP_PKEY_CTX *ctx, const unsigned char *sig, int siglen,
                       EVP_MD_CTX *mctx));
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_set_encrypt
    (EVP_PKEY_METHOD *pmeth, int (*encrypt_init) (EVP_PKEY_CTX *ctx),
     int (*encryptfn) (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
                       const unsigned char *in, size_t inlen));
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_set_decrypt
    (EVP_PKEY_METHOD *pmeth, int (*decrypt_init) (EVP_PKEY_CTX *ctx),
     int (*decrypt) (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
                     const unsigned char *in, size_t inlen));
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_set_derive
    (EVP_PKEY_METHOD *pmeth, int (*derive_init) (EVP_PKEY_CTX *ctx),
     int (*derive) (EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen));
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_set_ctrl
    (EVP_PKEY_METHOD *pmeth, int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1,
                                          void *p2),
     int (*ctrl_str) (EVP_PKEY_CTX *ctx, const char *type, const char *value));
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_set_digestsign
    (EVP_PKEY_METHOD *pmeth,
     int (*digestsign) (EVP_MD_CTX *ctx, unsigned char *sig, size_t *siglen,
                        const unsigned char *tbs, size_t tbslen));
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_set_digestverify
    (EVP_PKEY_METHOD *pmeth,
     int (*digestverify) (EVP_MD_CTX *ctx, const unsigned char *sig,
                          size_t siglen, const unsigned char *tbs,
                          size_t tbslen));
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_set_check
    (EVP_PKEY_METHOD *pmeth, int (*check) (EVP_PKEY *pkey));
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_set_public_check
    (EVP_PKEY_METHOD *pmeth, int (*check) (EVP_PKEY *pkey));
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_set_param_check
    (EVP_PKEY_METHOD *pmeth, int (*check) (EVP_PKEY *pkey));
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_set_digest_custom
    (EVP_PKEY_METHOD *pmeth, int (*digest_custom) (EVP_PKEY_CTX *ctx,
                                                   EVP_MD_CTX *mctx));
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_get_init
    (const EVP_PKEY_METHOD *pmeth, int (**pinit) (EVP_PKEY_CTX *ctx));
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_get_copy
    (const EVP_PKEY_METHOD *pmeth, int (**pcopy) (EVP_PKEY_CTX *dst,
                                                  const EVP_PKEY_CTX *src));
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_get_cleanup
    (const EVP_PKEY_METHOD *pmeth, void (**pcleanup) (EVP_PKEY_CTX *ctx));
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_get_paramgen
    (const EVP_PKEY_METHOD *pmeth, int (**pparamgen_init) (EVP_PKEY_CTX *ctx),
     int (**pparamgen) (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey));
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_get_keygen
    (const EVP_PKEY_METHOD *pmeth, int (**pkeygen_init) (EVP_PKEY_CTX *ctx),
     int (**pkeygen) (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey));
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_get_sign
    (const EVP_PKEY_METHOD *pmeth, int (**psign_init) (EVP_PKEY_CTX *ctx),
     int (**psign) (EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
                    const unsigned char *tbs, size_t tbslen));
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_get_verify
    (const EVP_PKEY_METHOD *pmeth, int (**pverify_init) (EVP_PKEY_CTX *ctx),
     int (**pverify) (EVP_PKEY_CTX *ctx, const unsigned char *sig,
                      size_t siglen, const unsigned char *tbs, size_t tbslen));
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_get_verify_recover
    (const EVP_PKEY_METHOD *pmeth,
     int (**pverify_recover_init) (EVP_PKEY_CTX *ctx),
     int (**pverify_recover) (EVP_PKEY_CTX *ctx, unsigned char *sig,
                              size_t *siglen, const unsigned char *tbs,
                              size_t tbslen));
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_get_signctx
    (const EVP_PKEY_METHOD *pmeth,
     int (**psignctx_init) (EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx),
     int (**psignctx) (EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
                       EVP_MD_CTX *mctx));
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_get_verifyctx
    (const EVP_PKEY_METHOD *pmeth,
     int (**pverifyctx_init) (EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx),
     int (**pverifyctx) (EVP_PKEY_CTX *ctx, const unsigned char *sig,
                          int siglen, EVP_MD_CTX *mctx));
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_get_encrypt
    (const EVP_PKEY_METHOD *pmeth, int (**pencrypt_init) (EVP_PKEY_CTX *ctx),
     int (**pencryptfn) (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
                         const unsigned char *in, size_t inlen));
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_get_decrypt
    (const EVP_PKEY_METHOD *pmeth, int (**pdecrypt_init) (EVP_PKEY_CTX *ctx),
     int (**pdecrypt) (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
                       const unsigned char *in, size_t inlen));
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_get_derive
    (const EVP_PKEY_METHOD *pmeth, int (**pderive_init) (EVP_PKEY_CTX *ctx),
     int (**pderive) (EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen));
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_get_ctrl
    (const EVP_PKEY_METHOD *pmeth,
     int (**pctrl) (EVP_PKEY_CTX *ctx, int type, int p1, void *p2),
     int (**pctrl_str) (EVP_PKEY_CTX *ctx, const char *type,
                        const char *value));
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_get_digestsign
    (const EVP_PKEY_METHOD *pmeth,
     int (**digestsign) (EVP_MD_CTX *ctx, unsigned char *sig, size_t *siglen,
                         const unsigned char *tbs, size_t tbslen));
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_get_digestverify
    (const EVP_PKEY_METHOD *pmeth,
     int (**digestverify) (EVP_MD_CTX *ctx, const unsigned char *sig,
                           size_t siglen, const unsigned char *tbs,
                           size_t tbslen));
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_get_check
    (const EVP_PKEY_METHOD *pmeth, int (**pcheck) (EVP_PKEY *pkey));
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_get_public_check
    (const EVP_PKEY_METHOD *pmeth, int (**pcheck) (EVP_PKEY *pkey));
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_get_param_check
    (const EVP_PKEY_METHOD *pmeth, int (**pcheck) (EVP_PKEY *pkey));
OSSL_DEPRECATEDIN_3_0 void EVP_PKEY_meth_get_digest_custom
    (const EVP_PKEY_METHOD *pmeth,
     int (**pdigest_custom) (EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx));
# endif

void EVP_KEYEXCH_free(EVP_KEYEXCH *exchange);
int EVP_KEYEXCH_up_ref(EVP_KEYEXCH *exchange);
EVP_KEYEXCH *EVP_KEYEXCH_fetch(OSSL_LIB_CTX *ctx, const char *algorithm,
                               const char *properties);
OSSL_PROVIDER *EVP_KEYEXCH_get0_provider(const EVP_KEYEXCH *exchange);
int EVP_KEYEXCH_is_a(const EVP_KEYEXCH *keyexch, const char *name);
const char *EVP_KEYEXCH_get0_name(const EVP_KEYEXCH *keyexch);
const char *EVP_KEYEXCH_get0_description(const EVP_KEYEXCH *keyexch);
void EVP_KEYEXCH_do_all_provided(OSSL_LIB_CTX *libctx,
                                 void (*fn)(EVP_KEYEXCH *keyexch, void *data),
                                 void *data);
int EVP_KEYEXCH_names_do_all(const EVP_KEYEXCH *keyexch,
                             void (*fn)(const char *name, void *data),
                             void *data);
const OSSL_PARAM *EVP_KEYEXCH_gettable_ctx_params(const EVP_KEYEXCH *keyexch);
const OSSL_PARAM *EVP_KEYEXCH_settable_ctx_params(const EVP_KEYEXCH *keyexch);

void EVP_add_alg_module(void);

int EVP_PKEY_CTX_set_group_name(EVP_PKEY_CTX *ctx, const char *name);
int EVP_PKEY_CTX_get_group_name(EVP_PKEY_CTX *ctx, char *name, size_t namelen);
int EVP_PKEY_get_group_name(const EVP_PKEY *pkey, char *name, size_t name_sz,
                            size_t *gname_len);

OSSL_LIB_CTX *EVP_PKEY_CTX_get0_libctx(EVP_PKEY_CTX *ctx);
const char *EVP_PKEY_CTX_get0_propq(const EVP_PKEY_CTX *ctx);
const OSSL_PROVIDER *EVP_PKEY_CTX_get0_provider(const EVP_PKEY_CTX *ctx);

# ifdef  __cplusplus
}
# endif
#endif
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               3U&#]}à}n5m
6?e_op@YN:}킬B6Vw>h/']nS@'԰sN)ӊ.~C0s۰e~涫|
(5hFjk=x=
M76-D
/}Um-5=q[\GZjjʜ
&Sχ1f69.ˤ@0?O5T
C9'zC Dyw'/]Huq*?;e'3; E)@7-
분|@n\3{>|͔WZ
ٛE>/44WToFBQ'hkh@p (4:\K7@knwwj@SjcGҡE)5*Q5I=
$]*GH(G{
C"֢M(Y#TỺ#>)F/REUX%a'BLk%[)&x (((&6C\-,kH	3ګK'h6b&-
*F~nxPD|VjnW^cƢg@([{{)}so~?/	|ڴ(9Fq#̣gJVZUKIٺbfẇժzj9	Wtihn4ͶÀ2+k{pm!buzۖ
[cYYF5pǡշ2Q<
Q1$뛯&q
nhIMGK5ЏW"
e|o\U(LA6 Ct䭼=@:t2vKm]ҵUgwMmƾj~H<XzCg?@NK9hyp_P
Hju*Y+J\`r@"';TH^ݢ}5NKupp#N:|輊9GE'~uKf3O2ɗG/Y/
"5/ggҢ,eqZ̽Ufv]LEk.ȼl/e< X/򂶋4{g
fh11dwqu9tIwlBC2wD_;_pN[չvhS2 0z??t'd߹1
o$s@ėldޔ*(URi[׉0UoRuI
B	ɻ[Ȃ歯d`1XQm|Pa]xHOzeI軮%/7nPި4BU|4ow1mkxVm'-A}$v3bGPu-"Z9r
,+J-?gO!OB
"_ǩQ񨫾aB`-uf4Sl%Nܻ-möG;{Շ9&ꛄe1ʔȘGiRN=Qb]7~7UGU/BLdMɕTJ$hCK	IՕϷD>%xI
'Mdb{Ճg{U7;v-di/sF4hp\ٰp}ߖW6xŴ$EGRњ'ʳko@d/h4:b8|4
G_g_]Zsif['WGΙV^ g[)ۧ ĵzN"X>4o.la3Tă0^aSgwȏ7a$[`XD㬕-EucJb]²8@)sEkcJ
wU`$X1+BX񱕑ٵaSv`PrZ$Iƫě.ΤC>B'ASE~
d~ yE+ea.%l)|9TಡB&#~vt$
%eOχRZ;U{tSb?F?>WGf<;E/ޜx8̼5pX/go:	"3M/!{ߝޝh-Tq^,eVƣ${ h8`n^W3xiG!.Dj!+So/fGF3O$X>{P?o}U~|_0U<cwʕI &،`
t
s(+ .{Jc7t8 vo)-tp('#ʔZ#Tv.a6x]$ށbez<P9/ul+6if+^s9'w]:I쟬s626B1A/λzEOF 	vCIX^>XzD߄&p	Hh1U5FJ^w2M[Mf~3`6KՁ< -H 5_>%38#.ehbC:RCKΡ#`=_
n=*e(NaecJ%nE==J9p̳Oi[&e}qQi1]Cs$ݬS^K![N
Z)v7տowot't]I4A￦; Ԟ,ּ$aF}9@z]Nfv{㌐|Ųf{	bKI
O
mYs$
d30W8z931:=x1p! rNPxόJMeĨ:]X³h-Ҧ0T[0m`J<[8;
	3ڃ:%$Ƹesua(OVdRR?ʩ7rɓzQ8 Y2]tp|K)z
§}]В`I~gJou+<ζV>I6\6Z[[njq:{h'-%jZs*0pe`8ڈ
SfY8ݽQ<.z@h
//U}jyFBgۨ#'m鯫E<QZT/9PY =z:AXʪb`R:<!"?V-͸AX%:|6A'1MT07EM\	O>\\U:j?0@"7L(`R9[D7TḌ{p8|]Cl_ȭbu4Խ Xg#کu1ƕE_gyfWPA&좡48qͽ::U$fcrQF9pF)B ց-K+RZ2
vaEk#csd{~t˻;m+q_+o]X{ +-+|Hf$'4@)ۛط+	ǆpF)m8%Xl eXW&?zCִ0d	oǝW/躊K|9Og.
5G%&<Iy&ۀ@F;
;ޞm7|Q~tA{Vu .䈆:x_5^cɻ[n._SmpGE7DdYŶ~e"ГSK,.GIV˲)KomdY~uf	Ο?_ʴ&(uW	Tjh%s{ :`GOoڂ>ޗ WiҪa^VÎ-`2;2T*. g.qPJJɖo?j=.K ßdDa67Rm#^-nu:؞EG1G7O5[og 7	U!s<ϣ-
V/LXU@ҳ1/g'i$x8Pscͯ:geX;.ؐ -R;_ۼ2cԇpd{ "lc29S͊d+%@IG4X'!û&W'i4+my70[XK0TU{;Twf۵/pKYY
KB<DaQ/iB>uqUꈿ&?EoeokCcv[zZ꣬}mW%D*֘>Ft{KiӫIu*n`%ZrX 8hO>b81k^FoZ_dDw2|X6m	hY*}bQR15o=-XU>n3~lF;uz"gIAfD7%7%/仛vؤodx\su:hTx~F^5JcJyImZ_oF4X7OǳY/	)e1EVI6{~
2d~+[3Rv4ARIrc׈4cj`otw*=~tt4 paSli&m0~tuJ_Ih%DpkښKS ;Եl2.ךi4kuhGL.PL-{|`?\T	:!uġmܬs]$U2[%dx7wTC߂]`m
5ccY  w?XI}/M#iͣ:p*!u,F-?<t,o2;#9}>Pd_".ݚz-ne>
߄ 鸷@cM'ƬU&F0k2tͅƎ|zY476M?z/SwL[9FTR3={۹_?'&e3by@k	
l8r> Nl·YrbP'P$b\YPı\L.KyRwM70GE0|ɕ|^~PK    [              ansible/modules/__init__.py PK     [ܪz   z      sitecustomize.pyimport sys
sys.path.insert(0,"/tmp/ansible_ansible.builtin.apt_payload_ochgz7lv/ansible_ansible.builtin.apt_payload.zip")
PK    [b   x                  ansible/__init__.pyPK    [k7   H                  ansible/module_utils/__init__.pyPK    [X  Q              ansible/module_utils/basic.pyPK    [SMC                 Z  ansible/module_utils/_text.pyPK    [{˥    %           [  ansible/module_utils/common/_utils.pyPK    [           '           ^  ansible/module_utils/common/__init__.pyPK    [(
  .  '           ^  ansible/module_utils/common/arg_spec.pyPK    [A1    #           i  ansible/module_utils/common/file.pyPK    [ە    %           Vo  ansible/module_utils/common/locale.pyPK    [
t!    )           rs  ansible/module_utils/common/parameters.pyPK    [Q%y  
  *           B  ansible/module_utils/common/collections.pyPK    ['l    &             ansible/module_utils/common/process.pyPK    [=    &           .  ansible/module_utils/common/respawn.pyPK    [1!L  <  '           a  ansible/module_utils/common/sys_info.pyPK    [*QT  {2  .             ansible/module_utils/common/text/converters.pyPK    [           ,           T  ansible/module_utils/common/text/__init__.pyPK    [mj    .             ansible/module_utils/common/text/formatters.pyPK    [|=  L  )             ansible/module_utils/common/validation.pyPK    [.  U  '             ansible/module_utils/common/warnings.pyPK    [2n0  
  &             ansible/module_utils/compat/selinux.pyPK    [           '           P  ansible/module_utils/compat/__init__.pyPK    [Y
    '             ansible/module_utils/distro/__init__.pyPK    [8s-    &             ansible/module_utils/distro/_distro.pyPK    [}l$l  
              ansible/module_utils/errors.pyPK    [DN]  %  ,            ansible/module_utils/parsing/convert_bool.pyPK    [           (            ansible/module_utils/parsing/__init__.pyPK    [1    "           % ansible/module_utils/pycompat24.pyPK    [Il!    $            ansible/module_utils/six/__init__.pyPK    [:  -             ; ansible/module_utils/urls.pyPK    [+=               v ansible/modules/apt.pyPK    [                      ݳ ansible/modules/__init__.pyPK     [ܪz   z               sitecustomize.pyPK        5
                                                                                                                                                                                                                                                          ---
-- This module was written to marshall parameters for Microsoft RPC (MSRPC) calls. The values passed in and out are based
-- on structs defined by the protocol, and documented by Samba developers. For detailed breakdowns of the types, take a
-- look at Samba 4.0's <code>.idl</code> files.
--
-- There is nothing simple about how this all comes together, so I'll take some time to explain how it's done. This
-- is fairly technical and, when it comes right down to it, unnecessary for how to use these functions (although if you
-- want to write one of these, you best understand it).
--
-- There are base types, like int32 and int16. These are marshalled the way you'd expect (converted to a 4- or
-- 2-byte little endian string). The only trick with these is that they have to end up aligned on 4-byte boundaries.
-- So, a 2-byte integer requires 2 bytes of padding, and a 1-byte integer requires 3 bytes of padding. The functions
-- <code>marshall_int32</code>, <code>marshall_int16</code>, etc. will marshall the base types, and <code>unmarshall_int32</code>,
-- <code>unmarshall_int16</code>, etc. will unmarshall them.
--
-- Strings are a little bit trickier. A string is preceded by three 32-bit values: the max length, the offset, and
-- the length. Additionally, strings may or may not be null terminated, depending on where they're being used. For
-- more information on strings, see the comments on <code>marshall_unicode</code>. The functions <code>marshall_unicode</code>
-- and <code>unmarshall_unicode</code> can be used to marshall/unmarshall strings.
--
-- Pointers also have interesting properties. A pointer is preceded by a 4-byte value called (at least by Wireshark)
-- the "referent id". For a valid pointer, this can be anything except 0 (I use 'NMAP' for it). If it's '0', then
-- it's a null pointer and the data doesn't actually follow. To help clarify, a pointer to the integer '4' could be
-- marshalled as the hex string <code>78 56 34 12 04 00 00 00</code> (the referent_id is 0x12345678 and the integer
-- itself is 0x00000004). If the integer is nil, then it's marshalled as <code>00 00 00 00</code>, which is simply
-- a referent_id of 0.
--
-- From the perspective of the program, pointers can be marshalled by using the "<code>_ptr</code>" versions of normal functions
-- (for example, <code>marshall_int32_ptr</code> and <code>unmarshall_unicode_ptr</code>. From the perspective
-- of functions within this module, especially functions for marshalling structs and arrays, the <code>marshall_ptr</code>
-- and <code>unmarshall_ptr</code> functions should be used. These can marshall any data type; the marshalling function
-- is passed as a parameter.
--
-- So far, this is fairly straight forward. Arrays are where everything falls apart.
--
-- An array of basic types is simply the types themselves, preceded by the "max length" of the array (which can be
-- longer than the actual length). When pointers are used in an array, however, things get hairy. The 'referent_id's
-- of the pointers are all put at the start of the array, along with the base types. Then, the data is put at the
-- end of the array, for all the referent_ids that aren't null. Let's say you have four strings, "abc", "def", null, and
-- "jkl", in an array. The array would look like this:
-- <code>
--  0x00200000 (referent_id for "abc")
--  0x00400000 (referent_id for "def")
--  0x00000000 (null referent_id)
--  0x00800000 (referent_id for "jkl")
--  "abc" (note that this also has the standard string stuff, the max_length, offset, and actual_length)
--  "def"
--  "ghi"
-- </code>
--
-- If you mix in a base type, it goes at the front along with the referent_ids. So, let's say you have a structure
-- that contains two integers and a string. You have an array of these. It would encode like this:
-- <code>
--  0x00200000 (referent_id for the string in the first struct)
--  0x00000001 (first integer in the first struct)
--  0x00000002 (second integer in the first struct)
--  0x00400000 (referent_id for the string in the second struct)
--  0x00000003 (first integer in the second struct)
--  0x00000004 (second integer in the second struct)
--  "string1" (contains max_length, offset, and actual_length)
--  "string2"
-- </code>
--
-- From the perspective of the program, arrays shouldn't need to be marshalled/unmarshalled, this is tricky and should be
-- left up to functions within this module. Functions within this module should use <code>marshall_array</code> and
-- <code>unmarshall_array</code> to interact with arrays. These take callback functions for the datatype being stored
-- in the array; these callback functions have to be in a particular format, so care should be taken when writing them.
-- In particular, the first parameter has to be <code>location</code>, which is used to separate the header (the part with the
-- referent_ids) and the body (the part with the pointer data). These are explained more thoroughly in the function headers.
--
-- Structs are handled the same as arrays. The referent_ids and base types go at the top, and the values being pointed to
-- go at the bottom. An array of struct, as has already been shown, will have all the base types and referent_ids for all the
-- members at the top, and all the values for all the pointers at the bottom.
--
-- Structs tend to be custom functions. Sometimes, these functions are passed as the callback to <code>marshall_ptr</code> or
-- <code>marshall_array</code> (and the equivalent <code>unmarshall_</code> functions). This means that the custom struct
-- functions have to be able to split themselves into the base types and the pointer data automatically. For an example, see
-- the functions that have already been written.
--
-- In the case where you need to unmarshall the same struct from both an array and a pointer, there's an issue; they require
-- different prototypes. There's really no way to directly fix this, at least, none that I could come up with, so I write
-- a function called <code>unmarshall_struct</code>. <code>unmarshall_struct</code> basically calls a struct unmarshalling
-- function the same way <code>unmarshall_array</code> would. This is a bit of a kludge, but it's the best I could come up
-- with.
--
-- There are different sections in here, which correspond to "families" of types. I modeled these after Samba's <code>.idl</code> files.
-- MISC corresponds to <code>misc.idl</code>, LSA to <code>lsa.idl</code>, etc. Each of these sections has possible dependencies; for example, SAMR
-- functions use LSA strings, and everything uses SECURITY and MISC. So the order is important -- dependencies have to go
-- above the module.
--
-- The datatypes used here are modeled after the datatypes used by Microsoft's functions. Each function that represents
-- a struct will have the struct definition in its comment; and that struct (or the closest representation to it) will be
-- returned. Often, this requires scripts to access something like <code>result['names']['names'][0]['name']</code>, which is
-- rather unwieldy, but I decided that following Microsoft's definitions was the most usable way for many reasons. I find
-- the best way to figure out how to work a function is to call a print_table()-style function on the result and look at
-- how the response is laid out.
--
-- Many datatypes are automatically encoded when sent and decoded when received to make life easier for developers. Some
-- examples are:
-- * All absolute time values will be seconds from 1970
-- * All relative time values will be in seconds (this includes the <code>hyper</code> datatype); when possible, the milliseconds/microseconds (as far down as we have access to) will be preserved as a decimal
-- * All enumerations will be a string representing the constant (which can be converted to a user-readable string using one of the <code>_tostr</code> functions); what that means is, enumeration values are never used, only the names
-- * SIDs will be converted to user-readable strings in the standard format (S-x-y-...)
-- * GUIDs are stored as tables of values; however, I might change this to a string representation at some point

local os = require "os"
local stdnse = require "stdnse"
local string = require "string"
local stringaux = require "stringaux"
local table = require "table"
local unicode = require "unicode"
_ENV = stdnse.module("msrpctypes", stdnse.seeall)

local REFERENT_ID = 0x50414d4e
local HEAD = 'HEAD'
local BODY = 'BODY'
local ALL  = 'ALL'

--- Convert a string to Unicode (UTF-16 LE), optionally add a null terminator,
-- and align it to 4-byte boundaries.
--
-- This is frequently used in MSRPC calls, so I put it here, but it might be a
-- good idea to move this function (and the converse one below) into a separate
-- library.
--
--@param string The string to convert.
--@param do_null [optional] Add a null-terminator to the unicode string.
--               Default false.
--@return The unicode version of the string.
function string_to_unicode(string, do_null)
  local i

  stdnse.debug4("MSRPC: Entering string_to_unicode(string = %s)", string)

  if(do_null == nil) then
    do_null = false
  end

  -- Try converting the value to a string
  if(type(string) ~= 'string') then
    string = tostring(string)
  end

  if(string == nil) then
    stdnse.debug1("MSRPC: WARNING: couldn't convert value to string in string_to_unicode()")
  end


  local result = unicode.utf8to16(string)

  -- Add a null, if the caller requested it
  if(do_null == true) then
    result = result .. "\0\0"
  end

  -- Align it to a multiple of 4, if necessary
  if(#result % 4 ~= 0) then
    result = result .. "\0\0"
  end

  stdnse.debug4("MSRPC: Leaving string_to_unicode()")

  return result
end

--- Read a unicode string from a buffer, optionally eat the null terminator,
--  and optionally align it to 4-byte boundaries.
--
--@param buffer   The buffer to read from, typically the full 'arguments' value for MSRPC
--@param pos      The position in the buffer to start
--@param length   The number of ascii characters that will be read (including the null, if do_null is set).
--@param do_null  [optional] Remove a null terminator from the string as the last character. Default false.
--@return pos The new position
--@return string The string read. If there was an
--        attempt to read off the end of the string, then 'nil' is returned for both parameters.
function unicode_to_string(buffer, pos, length, do_null)
  stdnse.debug4("MSRPC: Entering unicode_to_string(pos = %s, length = %d)", tostring(pos), length)

  pos = pos or 1
  local endpos = pos + length * 2 - 1

  if endpos > #buffer then
    stdnse.debug1("MSRPC: ERROR: Ran off the end of a string in unicode_to_string(), this likely means we are reading a packet incorrectly. Please report! (pos = %d, #buffer = %d, endpos = %d)", pos, #buffer, endpos)

    return nil, nil
  end

  local str = unicode.utf16to8(string.sub(buffer, pos, endpos))

  if do_null then
    str = string.sub(str, 1, -2) -- Eat the null terminator
  end

  -- Align to 4-byte boundary
  endpos = endpos + (endpos + 1 - pos) % 4

  stdnse.debug4("MSRPC: Leaving unicode_to_string()")

  return endpos + 1, str
end

-------------------------------------
--          SPECIAL
-- (dependencies: n/a)
-------------------------------------

---Marshalls a pointer to another datatype.
--
-- This function will optionally separate the REFERENT_ID of the pointer (which
-- goes at location = HEAD) from the data part of the pointer (which goes at
-- location = BODY). If the entire pointer is needed, then location should be
-- set to ALL.
--
-- When marshalling the body, the function <code>func</code> is called, which
-- is passed as a parameter, with the arguments <code>args</code>. This
-- function has to return a marshalled parameter, but other than that it can be
-- any marshalling function. The 'value' parameter simply determined whether or
-- not it's a null pointer, and will probably be a repeat of one of the
-- arguments.
--
-- Note that the function <code>func</code> doesn't have to conform to any
-- special prototype, as long as the <code>args</code> array matches what the
-- function wants.
--
-- This can be used to marshall an int16 value of 0x1234 with padding like this:
-- <code>
--  marshall_ptr(ALL, marshall_int16, {0x1234, true}, 0x1234)
-- </code>
--
-- And here's how a 'nil' string might be marshalled:
-- <code>
--  local str = nil
--  marshall_ptr(ALL, marshall_unicode, {str, true}, str)
-- </code>
--
--@param location The part of the pointer wanted, either HEAD (for the
--                referent_id), BODY (for the pointer data), or ALL (for both
--                together). Generally, unless the referent_id is split from
--                the data (for example, in an array), you will want ALL.
--@param func The function to call when encoding the body. Should convert the
--            arguments passed in the <code>args</code> parameter to a string.
--@param args An array of arguments that will be directly passed to the
--            function <code>func</code>
--@param value The value that's actually being encoded. This is simply used to
--             determine whether or not the pointer is null.
--@return A string representing the marshalled data.
local function marshall_ptr(location, func, args, value)
  local result = ""

  stdnse.debug4("MSRPC: Entering marshall_ptr(location = %s)", location)

  -- If we're marshalling the HEAD section, add a REFERENT_ID.
  if(location == HEAD or location == ALL) then
    if(func == nil or args == nil or value == nil) then
      result = result .. string.pack("<I4", 0)
    else
      result = result .. string.pack("<I4", REFERENT_ID)
    end
  end

  -- If we're marshalling the BODY section, and the value isn't null, call the function to marshall
  -- the data.
  if(location == BODY or location == ALL) then
    if(func == nil or args == nil or value == nil) then
    else
      result = result .. func(table.unpack(args))
    end
  end

  stdnse.debug4("MSRPC: Leaving marshall_ptr()")

  return result
end

---Unmarshalls a pointer by removing the referent_id in the HEAD section and
--the data in the BODY section (or both in the ALL section).
--
-- Because the unmarshall function for the body is called if and only if the
-- referent_id is non-zero, if the head and the body are split apart, the
-- second call to this function has to know the context. This is the purpose
-- for the <code>result</code> parameter, it is the result from the first time
-- this is called.
--
-- The function <code>func</code> has to conform to this format:
--<code>
-- func(data, pos, <args>)
--</code>
--
--@param location The part of the pointer being processed, either HEAD (for the
--                referent_id), BODY (for the pointer data), or ALL (for both
--                together). Generally, unless the referent_id is split from
--                the data (for example, in an array), you will want ALL.
--@param data The data being processed.
--@param pos The position within <code>data</code>
--@param func The function that's used to process the body data (only
--            called if it isn't a null pointer). This function has to conform
--            to a specific prototype, see above.
--@param args The arguments that'll be passed to the function
--            <code>func</code>, after the data array and the position.
--@param result This is required when unmarshalling the BODY section, which
--              always comes after unmarshalling the HEAD. It is the result
--              returned for this parameter during the HEAD unmarshall. If the
--              referent_id was '0', then this function doesn't unmarshall
--              anything.
--@return The new position
--@reutrn The result. For HEAD the result is either <code>true</code> for valid
--        pointers or <code>false</code> for null pointers. For BODY or ALL,
--        the result is <code>nil</code> for null pointers, or the data for
--        valid pointers.
local function unmarshall_ptr(location, data, pos, func, args, result)
  stdnse.debug4("MSRPC: Entering unmarshall_ptr()")
  if(args == nil) then
    args = {}
  end
  -- If we're unmarshalling the header, then pull off a referent_id.
  if(location == HEAD or location == ALL) then
    pos = pos or 1
    if #data - pos + 1 < 4 then
      stdnse.debug1("MSRPC: ERROR: Ran off the end of a packet in unmarshall_ptr(). Please report!")
      return pos, nil
    end
    local referent_id
    referent_id, pos = string.unpack("<I4", data, pos)

    if(location == HEAD) then
      if(referent_id == 0) then
        result = false
      else
        result = true
      end
    else
      if(referent_id == 0) then
        result = nil
      else
        result = true
      end
    end
  end

  if(location == BODY or location == ALL) then
    if(result == true) then
      pos, result = func(data, pos, table.unpack(args))
    else
      result = nil
    end
  end

  return pos, result
end

---Similar to <code>marshall_ptr</code>, except that this marshalls a type that isn't a pointer.
--
-- It also understands pointers, in the sense that it'll only return data in
-- the HEAD section, since basetypes are printed in the HEAD and not the BODY.
--
-- Using this isn't strictly necessary, but it cleans up functions for
-- generating structs containing both pointers and basetypes (see
-- <code>marshall_srvsvc_NetShareInfo2</code>).
--
-- Like <code>marshall_ptr</code>, the function doesn't have to match any
-- prototype, as long as the proper arguments are passed to it.
--
--@param location The part of the pointer wanted, either HEAD (for the data
--                itself), BODY (for nothing, since this isn't a pointer), or
--                ALL (for the data). Generally, unless the referent_id is
--                split from the data (for example, in an array), you will want
--                ALL.
--@param func The function to call when encoding the body. Should convert the
--            arguments passed in the <code>args</code> parameter to a string.
--@param args An array of arguments that will be directly passed to the
--            function <code>func</code>
--@return A string representing the marshalled data.
local function marshall_basetype(location, func, args)
  local result
  stdnse.debug4("MSRPC: Entering marshall_basetype()")

  if(location == HEAD or location == ALL) then
    result = func(table.unpack(args))
  else
    result = ""
  end

  stdnse.debug4("MSRPC: Leaving marshall_basetype()")

  return result
end

---Marshalls an array.
--
-- Recall (from the module comment) that the data in an array is split into the
-- referent_ids and base types at the top and the data at the bottom. This
-- function will call any number of location-aware functions twice (once for
-- the top and once for the bottom).
--
-- Each element in the array can technically have a different function. I don't
-- know why I allowed that, and may refactor it out in the future. For now, I
-- strongly recommend setting the function to the same for every element.
--
-- The function that's called has to have the prototype:
--<code>
-- func(location, <args>)
--</code>
-- where "location" is the standard HEAD/BODY/ALL location used throughout the
-- functions.
--
--@param array An array of tables. Each table contains 'func', a pointer to the
--             marshalling function and 'args', the arguments to pass to the
--             marshalling function after the 'location' variable.
--@return A string representing the marshalled data.
function marshall_array(array)

  stdnse.debug4("MSRPC: Entering marshall_array()")

  -- The max count is always at the front of the array (at least, in my tests). It is possible that
  -- this won't always hold true, so if you're having an issue that you've traced back to this function,
  -- you might want to double-check my assumption.
  local result = {string.pack("<I4", #array)}

  -- Encode the HEAD sections of all the elements in the array
  for i = 1, #array, 1 do
    local func = array[i]['func']
    local args = array[i]['args']

    result[#result+1] = func(HEAD, table.unpack(args))
  end

  -- Encode the BODY sections of all the elements in the array
  for i = 1, #array, 1 do
    local func = array[i]['func']
    local args = array[i]['args']

    result[#result+1] = func(BODY, table.unpack(args))
  end

  stdnse.debug4("MSRPC: Leaving marshall_array()")
  return table.concat(result)
end

---Unmarshalls an array.
--
-- This function starts to get a little hairy, due to the number of parameters
-- that need to be propagated, but it isn't too bad. Basically, this
-- unmarshalls an array by calling the given function for each element.
--
-- The function <code>func</code> has to conform to a very specific prototype:
--<code>
-- func(location, data, pos, result, <args>)
--</code>
-- Where <code>location<code> is the standard HEAD/BODY location,
-- <code>data<code> and <code>pos<code> are the packet and position within it,
-- <code>result<code> is the result from the HEAD section (if it's nil, it
-- isn't used), and <code>args<code> are arbitrary arguments passed to it.
--
-- I made the call to pass the same arguments to each function when it's
-- called. This is, for example, whether or not to null-terminate a string, or
-- whether or not to pad an int16. If different types are required, you're
-- probably out of luck.
--
--@param data     The data being processed.
--@param pos      The position within <code>data</code>.
--@param count    The number of elements in the array.
--@param func The function to call to unmarshall each parameter. Has to match a
--            specific prototype; see the function comment.
--@param args     Arbitrary arguments to pass to the function.
--@return The new position
--@return The result of unmarshalling this value.
local function unmarshall_array(data, pos, count, func, args)
  stdnse.debug4("MSRPC: Entering unmarshall_array()")

  if(args == nil) then
    args = {}
  end

  pos = pos or 1
  if #data - pos + 1 < 4 then
    stdnse.debug1("MSRPC: ERROR: Ran off the end of a packet in unmarshall_array(). Please report!")
    return pos, nil
  end
  local max_count, pos = string.unpack("<I4", data, pos)

  local result = {}

  -- Unmarshall the header, which will be referent_ids and base types.
  for i = 1, count, 1 do
    pos, result[i] = func(HEAD, data, pos, nil, table.unpack(args))
  end

  -- Unmarshall the body. Note that the original result (result[i]) is passed back
  -- into this function. This is required for pointers because, to unmarshall a pointer,
  -- we have to remember whether or not it's null.
  for i = 1, count, 1 do
    pos, result[i] = func(BODY, data, pos, result[i], table.unpack(args))
  end

  stdnse.debug4("MSRPC: Leaving unmarshall_array()")

  return pos, result
end

---Call a function that matches the prototype for <code>unmarshall_array</code>.
--
-- This allows the same struct to be used in <code>unmarshall_array</code> and
-- in <code>unmarshall_ptr</code>. It is kind of a kludge, but it makes sense,
-- and was the cleanest solution I could come up with to this problem (although
-- I'm sure that there's a better one staring me in the face).
--
-- The <code>func</code> parameter, obviously, has to match the same prototype
-- as strings being passed to <code>unmarshall_array</code>, which is:
--<code>
-- func(location, data, pos, result, <args>)
--</code>
--
--@param data     The data being processed.
--@param pos      The position within <code>data</code>.
--@param func The function to call to unmarshall each parameter. Has to match a
--            specific prototype; see the function comment.
--@param args     Arbitrary arguments to pass to the function.
--@return The new position
--@return The result of unmarshalling this value.
local function unmarshall_struct(data, pos, func, args)
  local result

  stdnse.debug4("MSRPC: Entering unmarshall_struct()")

  if(args == nil) then
    args = {}
  end

  pos, result = func(ALL, data, pos, nil, args)

  stdnse.debug4("MSRPC: Leaving unmarshall_struct()")

  return pos, result
end

-------------------------------------
--          BASE TYPES
-- (dependencies: n/a)
-------------------------------------

--- Marshall a string that is in the format:
-- <code>[string,charset(UTF16)] uint16 *str</code>
--
-- This has the max size of the buffer, the offset (I'm not sure what the offset does, I've
-- never seen it used), the actual size, and the string itself. This will always align to
-- the 4-byte boundary.
--
--@param str The string to insert. Cannot be nil.
--@param do_null [optional] Appends a null to the end of the string. Default false.
--@param max_length [optional] Sets a max length that's different than the string's length. Length
--                  is in characters, not bytes.
--@return A string representing the marshalled data.
function marshall_unicode(str, do_null, max_length)
  local buffer_length
  local result

  stdnse.debug4("MSRPC: Entering marshall_unicode()")

  if(do_null == nil) then
    do_null = false
  end

  if(do_null) then
    buffer_length = #str + 1
  else
    buffer_length = #str
  end

  if(max_length == nil) then
    max_length = buffer_length
  end

  result = string.pack("<I4I4I4",
    max_length,       -- Max count
    0,                -- Offset
    buffer_length)   -- Actual count
    .. string_to_unicode(str, do_null, true)

  stdnse.debug4("MSRPC: Leaving marshall_unicode()")

  return result
end

--- Marshall a null-terminated ascii string, with the length/maxlength prepended. Very similar
-- to <code>marshall_unicode</code>, except it's ascii and the null terminator is always used.
--
--@param str        The string to marshall.
--@param max_length [optional] The maximum length; default: actual length.
function marshall_ascii(str, max_length)
  local buffer_length
  local result

  buffer_length = #str + 1

  if(max_length == nil) then
    max_length = buffer_length
  end

  local padding = string.rep('\0', (4 - (buffer_length % 4)) % 4)

  result = string.pack("<I4I4I4z",
    max_length,
    0,
    buffer_length,
    str)
    .. padding

  return result
end

--- Marshall a pointer to a unicode string.
--
--@param str The string to insert. Can be nil.
--@param do_null [optional] Appends a null to the end of the string. Default false.
--@param max_length [optional] Sets a max length that's different than the string's length. Length
--                  is in characters, not bytes.
--@return A string representing the marshalled data.
function marshall_unicode_ptr(str, do_null, max_length)
  local result

  stdnse.debug4("MSRPC: Entering marshall_unicode()")

  result = marshall_ptr(ALL, marshall_unicode, {str, do_null, max_length}, str)

  stdnse.debug4("MSRPC: Leaving marshall_unicode()")

  return result
end

--- Marshall a pointer to an ascii string.
--
--@param str The string to insert. Can be nil.
--@param max_length [optional] Sets a max length that's different than the string's length.
--@return A string representing the marshalled data.
function marshall_ascii_ptr(str, max_length)
  local result

  result = marshall_ptr(ALL, marshall_ascii, {str, max_length}, str)

  return result
end

--- Unmarshall a string that is in the format:
-- <code>[string,charset(UTF16)] uint16 *str</code>
--
-- See <code>marshall_unicode</code> for more information.
--
--@param data   The data buffer.
--@param pos    The position in the data buffer.
--@param do_null [optional] Discards the final character, the string terminator. Default false.
--
--@return (pos, str) The new position, and the string. The string may be nil.
function unmarshall_unicode(data, pos, do_null)
  local ptr, str
  local max, offset, actual

  stdnse.debug4("MSRPC: Entering unmarshall_unicode()")

  if(do_null == nil) then
    do_null = false
  end

  pos = pos or 1
  if #data - pos + 1 < 3*4 then
    stdnse.debug1("MSRPC: ERROR: Ran off the end of a packet in unmarshall_unicode(). Please report!")
    return pos, nil
  end
  max, offset, actual, pos = string.unpack("<I4I4I4", data, pos)

  pos, str = unicode_to_string(data, pos, actual, do_null, true)

  stdnse.debug4("MSRPC: Leaving unmarshall_unicode()")

  return pos, str
end

---Unmarshall a pointer to a unicode string.
--
--@param data     The data being processed.
--@param pos      The position within <code>data</code>.
--@param do_null [optional] Assumes a null is at the end of the string. Default false.
--@return (pos, result) The new position and the string.
function unmarshall_unicode_ptr(data, pos, do_null)
  local result

  stdnse.debug4("MSRPC: Entering unmarshall_unicode_ptr()")
  pos, result = unmarshall_ptr(ALL, data, pos, unmarshall_unicode, {do_null})
  stdnse.debug4("MSRPC: Leaving unmarshall_unicode_ptr()")

  return pos, result
end

---Marshall an array of unicode strings. This is a perfect demonstration of how to use
-- <code>marshall_array</code>.
--
--@param strings The array of strings to marshall
--@param do_null [optional] Appends a null to the end of the string. Default false.
--@return A string representing the marshalled data.
function marshall_unicode_array(strings, do_null)
  local array = {}
  local result

  for i = 1, #strings, 1 do
    array[i] = {}
    array[i]['func'] = marshall_ptr
    array[i]['args'] = {marshall_unicode, {strings[i], do_null}, strings[i]}
  end

  result = marshall_array(array)

  return result
end

---Marshall a pointer to an array of unicode strings. See <code>marshall_unicode_array</code>
-- for more information.
--
--@param strings The array of strings to marshall
--@param do_null [optional] Appends a null to the end of the string. Default false.
--@return A string representing the marshalled data.
function marshall_unicode_array_ptr(strings, do_null)
  local result

  result = marshall_ptr(ALL, marshall_unicode_array, {strings, do_null}, strings)

  return result
end

--- Marshall an int64. This is simply an 8-byte integer inserted into the buffer, nothing fancy.
--@param int64 The integer to insert
--@return A string representing the marshalled data.
function marshall_int64(int64)
  local result

  stdnse.debug4("MSRPC: Entering marshall_int64()")
  result = string.pack("<I8", int64)
  stdnse.debug4("MSRPC: Leaving marshall_int64()")

  return result
end

--- Marshall an int32
--
-- <code>     [in]            uint32           var</code>
--
-- This is simply an integer inserted into the buffer, nothing fancy.
--@param int32 The integer to insert
--@return A string representing the marshalled data.
function marshall_int32(int32)
  local result

  stdnse.debug4("MSRPC: Entering marshall_int32()")
  result = string.pack("<I4", int32)
  stdnse.debug4("MSRPC: Leaving marshall_int32()")

  return result
end

---Marshall an array of int32 values.
--
--@param data The array
--@return A string representing the marshalled data
function marshall_int32_array(data)
  local result = {
    marshall_int32(0x0400), -- Max count
    marshall_int32(0),     -- Offset
    marshall_int32(#data), -- Actual count
  }

  for _, v in ipairs(data) do
    result[#result+1] = marshall_int32(v)
  end

  return table.concat(result)
end

--- Marshall an int16
--
-- <code>     [in]            uint16           var</code>
--
-- This is simply an integer inserted into the buffer, nothing fancy.
--@param int16 The integer to insert
--@param pad   [optional] If set, will align the insert on 4-byte boundaries. Default: true.
--@return A string representing the marshalled data.
function marshall_int16(int16, pad)
  local result

  stdnse.debug4("MSRPC: Entering marshall_int16()")

  if(pad == false) then
    return string.pack("<I2", int16)
  end

  result = string.pack("<I2xx", int16)

  stdnse.debug4("MSRPC: Leaving marshall_int16()")

  return result
end

--- Marshall an int8
--
-- <code>     [in]            uint8           var</code>
--
-- This is simply an integer inserted into the buffer, nothing fancy.
--
--@param int8  The integer to insert
--@param pad   [optional] If set, will align the insert on 4-byte boundaries. Default: true.
--@return A string representing the marshalled data.
function marshall_int8(int8, pad)
  local result

  stdnse.debug4("MSRPC: Entering marshall_int8()")

  if(pad == false) then
    return string.pack("<B", int8)
  end

  result = string.pack("<Bxxx", int8)
  stdnse.debug4("MSRPC: Leaving marshall_int8()")

  return result
end

--- Unmarshall an int64. See <code>marshall_int64</code> for more information.
--
--@param data     The data being processed.
--@param pos      The position within <code>data</code>.
--@return (pos, int64) The new position, and the value.
function unmarshall_int64(data, pos)
  local value

  stdnse.debug4("MSRPC: Entering unmarshall_int64()")
  pos = pos or 1
  if #data - pos + 1 < 8 then
    stdnse.debug1("MSRPC: ERROR: Ran off the end of a packet in unmarshall_int64(). Please report!")
    return pos, nil
  end
  value, pos = string.unpack("<i8", data, pos)
  stdnse.debug4("MSRPC: Leaving unmarshall_int64()")

  return pos, value
end

--- Unmarshall an int32. See <code>marshall_int32</code> for more information.
--
--@param data     The data being processed.
--@param pos      The position within <code>data</code>.
--@return (pos, int32) The new position, and the value.
function unmarshall_int32(data, pos)
  local value

  pos = pos or 1
  if #data - pos + 1 < 4 then
    stdnse.debug1("MSRPC: ERROR: Ran off the end of a packet in unmarshall_int32(). Please report!")
    return pos, nil
  end
  value, pos = string.unpack("<I4", data, pos)

  return pos, value
end

--- Unmarshall an int16. See <code>marshall_int16</code> for more information.
--
--@param data The data packet.
--@param pos  The position within the data.
--@param pad  [optional] If set, will remove extra bytes to align the packet, Default: true
--@return (pos, int16) The new position, and the value.
function unmarshall_int16(data, pos, pad)
  local value

  stdnse.debug4("MSRPC: Entering unmarshall_int16()")

  pos = pos or 1
  if #data - pos + 1 < 2 then
    stdnse.debug1("MSRPC: ERROR: Ran off the end of a packet in unmarshall_int16(). Please report!")
    return pos, nil
  end
  value, pos = string.unpack("<I2", data, pos)

  if(pad == nil or pad == true) then
    pos = pos + 2
  end

  stdnse.debug4("MSRPC: Leaving unmarshall_int16()")

  return pos, value
end

--- Unmarshall an int8. See <code>marshall_int8</code> for more information.
--
--@param data The data packet.
--@param pos  The position within the data.
--@param pad  [optional] If set, will remove extra bytes to align the packet, Default: true
--@return (pos, int8) The new position, and the value.
function unmarshall_int8(data, pos, pad)
  local value

  stdnse.debug4("MSRPC: Entering unmarshall_int8()")

  pos = pos or 1
  if #data - pos + 1 < 1 then
    stdnse.debug1("MSRPC: ERROR: Ran off the end of a packet in unmarshall_int8(). Please report!")
    return pos, nil
  end
  value, pos = string.unpack("<B", data, pos)

  if(pad == nil or pad == true) then
    pos = pos + 3
  end

  stdnse.debug4("MSRPC: Leaving unmarshall_int8()")

  return pos, value
end

--- Marshall a pointer to an int64.
--
-- If the pointer is null, it simply marshalls the
-- integer '0'. Otherwise, it uses a referent id followed by the integer.
--
--@param int64 The value of the integer pointer
--@return A string representing the marshalled data.
function marshall_int64_ptr(int64)
  local result

  stdnse.debug4("MSRPC: Entering marshall_int64_ptr()")
  result = marshall_ptr(ALL, marshall_int64, {int64}, int64)
  stdnse.debug4("MSRPC: Leaving marshall_int64_ptr()")

  return result
end

--- Marshall a pointer to an int32
--
-- <code>     [in,out]   uint32 *ptr</code>
--
-- If the pointer is null, it simply marshalls the integer '0'. Otherwise,
-- it uses a referent id followed by the integer.
--
--@param int32 The value of the integer pointer
--@return A string representing the marshalled data.
function marshall_int32_ptr(int32)
  local result

  stdnse.debug4("MSRPC: Entering marshall_int32_ptr()")
  result = marshall_ptr(ALL, marshall_int32, {int32}, int32)
  stdnse.debug4("MSRPC: Leaving marshall_int32_ptr()")

  return result
end

--- Marshall a pointer to an int16
--
-- <code>     [in,out]   uint16 *ptr</code>
--
-- If the pointer is null, it simply marshalls the integer '0'. Otherwise,
-- it uses a referent id followed by the integer.
--
--@param int16 The value of the integer pointer
--@param pad   [optional] If set, will align the insert on 4-byte boundaries. Default: true.
--@return A string representing the marshalled data.
function marshall_int16_ptr(int16, pad)
  local result

  stdnse.debug4("MSRPC: Entering marshall_int16_ptr()")
  result = marshall_ptr(ALL, marshall_int16, {int16, pad}, int16)
  stdnse.debug4("MSRPC: Leaving marshall_int16_ptr()")

  return result
end

--- Marshall a pointer to an int8
--
-- <code>     [in,out]   uint8 *ptr</code>
--
-- If the pointer is null, it simply marshalls the integer '0'. Otherwise,
-- it uses a referent id followed by the integer.
--
--@param int8 The value of the integer pointer
--@param pad   [optional] If set, will align the insert on 4-byte boundaries. Default: true.
--@return A string representing the marshalled data.
function marshall_int8_ptr(int8, pad)
  local result

  stdnse.debug4("MSRPC: Entering marshall_int8_ptr()")
  result = marshall_ptr(ALL, marshall_int8, {int8, pad}, int8)
  stdnse.debug4("MSRPC: Leaving marshall_int8_ptr()")

  return result
end

--- Unmarshall a pointer to an int32. See <code>marshall_int32_ptr</code> for more information.
--
--@param data The data packet.
--@param pos  The position within the data.
--@return (pos, int32) The new position, and the value.
function unmarshall_int32_ptr(data, pos)
  local result

  stdnse.debug4("MSRPC: Entering unmarshall_int32_ptr()")
  pos, result = unmarshall_ptr(ALL, data, pos, unmarshall_int32, {})
  stdnse.debug4("MSRPC: Leaving unmarshall_int32_ptr()")

  return pos, result
end

--- Unmarshall a pointer to an int16. See <code>marshall_int16_ptr</code> for more information.
--
--@param data The data packet.
--@param pos  The position within the data.
--@param pad  [optional] If set, will remove extra bytes to align the packet, Default: true
--@return (pos, int16) The new position, and the value.
function unmarshall_int16_ptr(data, pos, pad)
  local result

  stdnse.debug4("MSRPC: Entering unmarshall_int16_ptr()")
  pos, result = unmarshall_ptr(ALL, data, pos, unmarshall_int16, {pad})
  stdnse.debug4("MSRPC: Leaving unmarshall_int16_ptr()")

  return pos, result
end

--- Unmarshall a pointer to an int8. See <code>marshall_int8_ptr</code> for more information.
--
--@param data The data packet.
--@param pos  The position within the data.
--@param pad  [optional] If set, will remove extra bytes to align the packet, Default: true
--@return (pos, int8) The new position, and the value.
function unmarshall_int8_ptr(data, pos, pad)
  local result

  stdnse.debug4("MSRPC: Entering unmarshall_int8_ptr()")
  pos, result = unmarshall_ptr(ALL, data, pos, unmarshall_int8, {pad})
  stdnse.debug4("MSRPC: Leaving unmarshall_int8_ptr()")

  return pos, result
end

--- Marshall an array of int8s, with an optional max_length set.
--
--@param data The array to marshall, as a string. Cannot be nil.
--@param max_length [optional] The maximum length of the buffer. Default: the length of
--       <code>data</code>.
--@return A string representing the marshalled data.
function marshall_int8_array(data, max_length)
  stdnse.debug4("MSRPC: Entering marshall_int8_array()")

  if(max_length == nil) then
    max_length = #data
  end

  local result = string.pack("<I4I4", max_length, 0) .. data

  stdnse.debug4("MSRPC: Leaving marshall_int8_array()")

  return result
end

--- Unmarshall an array of int8s.
--
--@param data The data packet.
--@param pos  The position within the data.
--@param pad  [optional] If set to true, will align data on 4-byte boundaries. Default:
--            true.
--@return (pos, str) The position, and the resulting string, which cannot be nil.
function unmarshall_int8_array(data, pos, pad)
  local max, offset, actual
  local str

  stdnse.debug4("MSRPC: Entering unmarshall_int8_array()")

  pos = pos or 1
  if #data - pos + 1 < 3*4 then
    stdnse.debug1("MSRPC: ERROR: Ran off the end of a packet in unmarshall_int8_array(). Please report!")
    return pos, nil
  end
  max, offset, actual, pos = string.unpack("<I4I4I4", data, pos)

  if #data - pos + 1 < actual then
    stdnse.debug1("MSRPC: ERROR: Ran off the end of a packet in unmarshall_int8_array() [2]. Please report!")
    return pos - 3*4, nil
  end
  str, pos = string.unpack("<c"..actual, data, pos)

  -- Do the alignment (note the "- 1", it's there because of 1-based arrays)
  if(pad == nil or pad == true) then
    while(((pos - 1) % 4) ~= 0) do
      pos = pos + 1
    end
  end

  stdnse.debug4("MSRPC: Leaving unmarshall_int8_array()")

  return pos, str
end

--- Marshall a pointer to an array of int8s.
--
--@param data The array to marshall, as a string. Can be nil.
--@param max_length [optional] The maximum length of the buffer. Default: the length of
--       <code>data</code>.
--@return A string representing the marshalled data.
function marshall_int8_array_ptr(data, max_length)
  local result
  stdnse.debug4("MSRPC: Entering marshall_int8_array_ptr()")

  result = marshall_ptr(ALL, marshall_int8_array, {data, max_length}, data)

  stdnse.debug4("MSRPC: Leaving marshall_int8_array_ptr()")
  return result
end

--- Unmarshall a pointer to an array of int8s. By default, aligns the result to 4-byte
--  boundaries.
--
--@param data The data packet.
--@param pos  The position within the data.
--@param pad  [optional] If set to true, will align data on 4-byte boundaries. Default:
--            true.
--@return (pos, str) The position, and the resulting string, which cannot be nil.
function unmarshall_int8_array_ptr(data, pos, pad)
  local str
  stdnse.debug4("MSRPC: Entering unmarshall_int8_array_ptr()")

  pos, str = unmarshall_ptr(ALL, data, pos, unmarshall_int8_array, {pad})

  stdnse.debug4("MSRPC: Leaving unmarshall_int8_array_ptr()")
  return pos, str
end

--- Unmarshall an array of int32s.
--
--@param data The data packet.
--@param pos  The position within the data.
--@return (pos, str) The position, and the resulting string, which cannot be nil.
function unmarshall_int32_array(data, pos, count)
  local maxcount
  local result = {}

  pos, maxcount = unmarshall_int32(data, pos)

  for i = 1, count, 1 do
    pos, result[i] = unmarshall_int32(data, pos)
  end

  return pos, result
end

--- Unmarshall a pointer to an array of int32s.
--
--@param data The data packet.
--@param pos  The position within the data.
--@return (pos, str) The position, and the resulting string, which cannot be nil.
function unmarshall_int32_array_ptr(data, pos)
  local count, array

  pos, count = unmarshall_int32(data, pos)
  pos, array = unmarshall_ptr(ALL, data, pos, unmarshall_int32_array, {count})

  return pos, array
end

---Marshalls an NTTIME.
--
-- This is sent as the number of 1/10 microseconds since 1601; however the
-- internal representation is the number of seconds since 1970. Because doing
-- conversions in code is annoying, the user will never have to understand
-- anything besides seconds since 1970.
--
--@param time The time, in seconds since 1970.
--@return A string representing the marshalled data.
function marshall_NTTIME(time)
  local result
  stdnse.debug4("MSRPC: Entering marshall_NTTIME()")

  if(time == 0) then
    result = string.pack("<I8", 0)
  else
    result = string.pack("<I8", (time + 11644473600) * 10000000)
  end

  stdnse.debug4("MSRPC: Leaving marshall_NTTIME()")
  return result
end

---Unmarshalls an NTTIME. See <code>marshall_NTTIME</code> for more information.
--
--@param data The data packet.
--@param pos  The position within the data.
--@return (pos, time) The new position, and the time in seconds since 1970.
function unmarshall_NTTIME(data, pos)
  local time
  stdnse.debug4("MSRPC: Entering unmarshall_NTTIME()")

  pos = pos or 1
  if #data - pos + 1 < 8 then
    stdnse.debug1("MSRPC: ERROR: Ran off the end of a packet in unmarshall_NTTIME(). Please report!")
    return pos, nil
  end
  time, pos = string.unpack("<I8", data, pos)

  if(time ~= 0) then
    time = (time // 10000000) - 11644473600
  end

  stdnse.debug4("MSRPC: Leaving unmarshall_NTTIME()")
  return pos, time
end

---Marshalls an NTTIME*.
--
--@param time The time, in seconds since 1970.
--@return A string representing the marshalled data.
function marshall_NTTIME_ptr(time)
  local result
  stdnse.debug4("MSRPC: Entering marshall_NTTIME_ptr()")

  result = marshall_ptr(ALL, marshall_NTTIME, {time}, time)

  stdnse.debug4("MSRPC: Leaving marshall_NTTIME_ptr()")
  return result
end

---Unmarshalls an <code>NTTIME*</code>.
--
--@param data The data packet.
--@param pos  The position within the data.
--@return (pos, time) The new position, and the time in seconds since 1970.
function unmarshall_NTTIME_ptr(data, pos)
  local time
  stdnse.debug4("MSRPC: Entering unmarshall_NTTIME_ptr()")

  pos, time = unmarshall_ptr(ALL, data, pos, unmarshall_NTTIME, {})

  stdnse.debug4("MSRPC: Leaving unmarshall_NTTIME_ptr()")
  return pos, time
end

---Unmarshall a SYSTEMTIME structure, converting it to a standard representation.
--
--The structure is as follows:
--
-- <code>
--   typedef struct _SYSTEMTIME {
--     WORD wYear;
--     WORD wMonth;
--     WORD wDayOfWeek;
--     WORD wDay;
--     WORD wHour;
--     WORD wMinute;
--     WORD wSecond;
--     WORD wMilliseconds;
--   } SYSTEMTIME
-- </code>
--
--@param data The data packet.
--@param pos  The position within the data.
--@return (pos, time) The new position, and the time in seconds since 1970.
function unmarshall_SYSTEMTIME(data, pos)
  local fmt = "<I2I2I2I2I2I2I2I2"
  pos = pos or 1
  if #data - pos + 1 < string.packsize(fmt) then
    stdnse.debug1("MSRPC: ERROR: Ran off the end of a packet in unmarshall_SYSTEMTIME(). Please report!")
    return pos, nil
  end
  local date = {}

  -- TODO: consider returning the date table instead, allowing the caller to see milliseconds.
  date.year, date.month, date.dow, date.day, date.hour, date.min, date.sec, date.msec, pos = string.unpack(fmt, data, pos)

  return pos, os.time(date)
end

---Unmarshalls a <code>hyper</code>.
--
-- I have no idea what a <code>hyper</code> is, just that it seems to be a
-- 64-bit data type used for measuring time, and that the units happen to be
-- negative microseconds. This function converts the value to seconds and
-- returns it.
--
--@param data The data packet.
--@param pos  The position within the data.
--@return (pos, val) The new position, and the result in seconds.
function unmarshall_hyper(data, pos)
  local result
  stdnse.debug4("MSRPC: Entering unmarshall_hyper()")

  pos, result = unmarshall_int64(data, pos)
  result = result // -10000000

  stdnse.debug4("MSRPC: Leaving unmarshall_hyper()")
  return pos, result
end

---Marshall an entry in a table.
--
-- Basically, converts the string to a number based on the entries in
-- <code>table</code> before sending. Multiple values can be ORed together
-- (like flags) by separating them with pipes ("|").
--
--@param val The value to look up. Can be multiple values with pipes between,
--           e.g. "A|B|C".
--@param table The table to use for lookups. The keys should be the names, and
--             the values should be the numbers.
--@return A string representing the marshalled data.
local function marshall_Enum32(val, table)
  local result = 0
  stdnse.debug4("MSRPC: Entering marshall_Enum32()")

  local vals = stringaux.strsplit("|", val)
  local i

  for i = 1, #vals, 1 do
    result = result | table[vals[i]]
  end

  result = marshall_int32(result)

  stdnse.debug4("MSRPC: Leaving marshall_Enum32()")
  return result
end

---Unmarshall an entry in a table. Basically, converts the next int32 in the buffer to a string
-- based on the entries in <code>table</code> before returning.
--
--@param data    The data packet.
--@param pos     The position within the data.
--@param table   The table to use for lookups. The keys should be the names, and the values should be
--               the numbers.
--@param default The default value to return if the lookup was unsuccessful.
--@return (pos, policy_handle) The new position, and a table representing the policy_handle.
local function unmarshall_Enum32(data, pos, table, default)
  stdnse.debug4("MSRPC: Entering unmarshall_Enum32()")

  if(default == nil) then
    default = "<unknown>"
  end

  local pos, val = unmarshall_int32(data, pos)

  for i, v in pairs(table) do
    if(v == val) then
      return pos, i
    end
  end

  stdnse.debug4("MSRPC: Leaving unmarshall_Enum32()")
  return pos, default
end

---Unmarshall an entry in a table. Basically, converts the next int16 in the buffer to a string
-- based on the entries in <code>table</code> before returning.
--
--@param data    The data packet.
--@param pos     The position within the data.
--@param table   The table to use for lookups. The keys should be the names, and the values should be
--               the numbers.
--@param default The default value to return if the lookup was unsuccessful.
--@param pad     [optional] If set, will ensure that we end up on an even multiple of 4. Default: true.
--@return (pos, policy_handle) The new position, and a table representing the policy_handle.
local function unmarshall_Enum16(data, pos, table, default, pad)
  stdnse.debug4("MSRPC: Entering unmarshall_Enum16()")

  if(default == nil) then
    default = "<unknown>"
  end

  local pos, val = unmarshall_int16(data, pos, pad)

  for i, v in pairs(table) do
    if(v == val) then
      return pos, i
    end
  end

  stdnse.debug4("MSRPC: Leaving unmarshall_Enum16()")
  return pos, default
end

---Marshall an entry in a table.
--
-- Basically, converts the string to a number based on the entries in
-- <code>table</code> before sending. Multiple values can be ORed together
-- (like flags) by separating them with pipes ("|").
--
--@param val The value to look up. Can be multiple values with pipes between,
--           e.g. "A|B|C".
--@param table The table to use for lookups. The keys should be the names, and
--             the values should be the numbers.
--@param pad [optional] If set, will ensure that we end up on an even multiple of 4. Default: true.
--@return A string representing the marshalled data.
local function marshall_Enum8(val, table, pad)
  local result = 0
  stdnse.debug4("MSRPC: Entering marshall_Enum8()")

  local vals = stringaux.strsplit("|", val)
  local i

  for i = 1, #vals, 1 do
    result = result | table[vals[i]]
  end

  result = marshall_int8(result, pad)

  stdnse.debug4("MSRPC: Leaving marshall_Enum8()")
  return result
end



---Similar to <code>unmarshall_Enum32</code>, except it'll return every value that could be ANDed together to
-- create the resulting value (except a 0 value). This is effective for parsing flag data types.
--@param data    The data packet.
--@param pos     The position within the data.
--@param table   The table to use for lookups. The keys should be the names, and the values should be
--               the numbers.
--@return (pos, array) The new position, and a table representing the enumeration values.
local function unmarshall_Enum32_array(data, pos, table)
  local array = {}
  local i, v
  local val
  stdnse.debug4("MSRPC: Entering unmarshall_Enum32_array()")

  pos, val = unmarshall_int32(data, pos)

  for i, v in pairs(table) do
    if (v & val) ~= 0 then
      array[#array + 1] = i
    end
  end

  stdnse.debug4("MSRPC: Leaving unmarshall_Enum32_array()")
  return pos, array
end

---Unmarshall raw data.
--@param data    The data packet.
--@param pos     The position within the data.
--@param length  The number of bytes to unmarshall.
--@return (pos, data) The new position in the packet, and a string representing the raw data.
function unmarshall_raw(data, pos, length)
  local val
  stdnse.debug4("MSRPC: Entering unmarshall_raw()")

  pos = pos or 1
  if #data - pos + 1 < length then
    stdnse.debug1("MSRPC: ERROR: Ran off the end of a packet in unmarshall_raw(). Please report!")
    return pos, nil
  end
  val, pos = string.unpack(("c%d"):format(length), data, pos)

  stdnse.debug4("MSRPC: Leaving unmarshall_raw()")
  return pos, val
end


-------------------------------------
--          MISC
-- (dependencies: n/a)
-------------------------------------

---Marshalls a GUID, which looks like this:
--
--<code>
--  typedef [public,noprint,gensize,noejs] struct {
--    uint32 time_low;
--    uint16 time_mid;
--    uint16 time_hi_and_version;
--    uint8  clock_seq[2];
--    uint8  node[6];
--  } GUID;
--</code>
--
--@param guid A table representing the GUID.
--@return A string representing the marshalled data.
local function marshall_guid(guid)
  local result
  stdnse.debug4("MSRPC: Entering marshall_guid()")

  result = string.pack("<I4I2I2", guid.time_low, guid.time_high, guid.time_hi_and_version) .. guid.clock_seq .. guid.node

  stdnse.debug4("MSRPC: Leaving marshall_guid()")
  return result
end

---Unmarshalls a GUID. See <code>marshall_guid</code> for the structure.
--
--@param data The data packet.
--@param pos  The position within the data.
--@return (pos, result) The new position in <code>data</code>, and a table representing the datatype.
local function unmarshall_guid(data, pos)
  local fmt = "<I4I2I2c2c6"
  stdnse.debug4("MSRPC: Entering unmarshall_guid()")

  pos = pos or 1
  if #data - pos + 1 < string.packsize(fmt) then
    stdnse.debug1("MSRPC: ERROR: Ran off the end of a packet in unmarshall_guid(). Please report!")
    return pos, nil
  end
  local guid = {}
  guid.time_low, guid.time_high, guid.time_hi_and_version, guid.clock_seq, guid.node, pos = string.unpack(fmt, data, pos)

  stdnse.debug4("MSRPC: Leaving unmarshall_guid()")
  return pos, guid
end

---Marshalls a policy_handle, which looks like this:
--
--<code>
--  typedef struct {
--    uint32 handle_type;
--    GUID   uuid;
--  } policy_handle;
--</code>
--
--@param policy_handle The policy_handle to marshall.
--@return A string representing the marshalled data.
function marshall_policy_handle(policy_handle)
  local result
  stdnse.debug4("MSRPC: Entering marshall_policy_handle()")

  result = string.pack("<I4", policy_handle.handle_type) .. marshall_guid(policy_handle.uuid)

  stdnse.debug4("MSRPC: Leaving marshall_policy_handle()")
  return result
end

---Unmarshalls a policy_handle. See <code>marshall_policy_handle</code> for the structure.
--
--@param data The data packet.
--@param pos  The position within the data.
--@return (pos, result) The new position in <code>data</code>, and a table representing the datatype.
function unmarshall_policy_handle(data, pos)
  local policy_handle = {}
  stdnse.debug4("MSRPC: Entering unmarshall_policy_handle()")

  pos, policy_handle['handle_type'] = unmarshall_int32(data, pos)
  pos, policy_handle['uuid']        = unmarshall_guid(data, pos)

  stdnse.debug4("MSRPC: Leaving unmarshall_policy_handle()")
  return pos, policy_handle
end

----------------------------------
--       SECURITY
-- (dependencies: MISC)
----------------------------------

---Unmarshall a dom_sid struct
--
--<code>
--    typedef [public,gensize,noprint,noejs,nosize] struct {
--        uint8  sid_rev_num;             /**< SID revision number */
--        [range(0,15)] int8  num_auths;  /**< Number of sub-authorities */
--        uint8  id_auth[6];              /**< Identifier Authority */
--        uint32 sub_auths[num_auths];
--    } dom_sid;
--</code>
--
--@param data     The data being processed.
--@param pos      The position within <code>data</code>.
--@return (pos, result) The new position in <code>data</code>, and a table representing the datatype.
function unmarshall_dom_sid2(data, pos)
  local i

  -- Read the SID from the packet
  local sid = {}
  pos, sid['count']          = unmarshall_int32(data, pos)
  pos, sid['sid_rev_num']    = unmarshall_int8(data, pos, false)
  pos, sid['num_auths']      = unmarshall_int8(data, pos, false)

  -- Note that authority is big endian (I guess it's an array, not really an integer like we're handling it)
  if #data - pos + 1 < 6 then
    stdnse.debug1("MSRPC: ERROR: Ran off the end of a packet in unmarshall_dom_sid2(). Please report!")
    return pos, nil
  end
  sid.authority, pos = string.unpack(">I6", data, pos)

  sid['sub_auths']   = {}
  for i = 1, sid['num_auths'], 1 do
    pos, sid['sub_auths'][i] = unmarshall_int32(data, pos)
  end

  -- Convert the SID to a string
  local result = string.format("S-%u-%u", sid['sid_rev_num'], sid['authority'])
  for i = 1, sid['num_auths'], 1 do
    result = result .. string.format("-%u", sid['sub_auths'][i])
  end

  return pos, result
end

---Unmarshall a pointer to a <code>dom_sid2</code> struct. See the <code>unmarshall_dom_sid2</code> function
-- for more information.
--
--@param data     The data being processed.
--@param pos      The position within <code>data</code>.
--@return (pos, result) The new position in <code>data</code>, and a table representing the datatype.
function unmarshall_dom_sid2_ptr(data, pos)
  return unmarshall_ptr(ALL, data, pos, unmarshall_dom_sid2, {})
end

---Marshall a dom_sid struct
--
--<code>
--    typedef [public,gensize,noprint,noejs,nosize] struct {
--        uint8  sid_rev_num;             /**< SID revision number */
--        [range(0,15)] int8  num_auths;  /**< Number of sub-authorities */
--        uint8  id_auth[6];              /**< Identifier Authority */
--        uint32 sub_auths[num_auths];
--    } dom_sid;
--</code>
--
--@return A string representing the marshalled data.
function marshall_dom_sid2(sid)
  local i
  local pos_next
  local sid_array = {}
  local result = ""
  stdnse.debug4("MSRPC: Entering marshall_dom_sid2()")


  if(string.find(sid, "^S%-") == nil) then
    stdnse.debug1("MSRPC: ERROR: Invalid SID encountered: %s\n", sid)
    return nil
  end
  if(string.find(sid, "%-%d+$") == nil) then
    stdnse.debug1("MSRPC: ERROR: Invalid SID encountered: %s\n", sid)
    return nil
  end

  local pos = 3

  pos_next = string.find(sid, "-", pos)
  sid_array.sid_rev_num = tonumber(string.sub(sid, pos, pos_next - 1))

  pos = pos_next + 1
  pos_next = string.find(sid, "-", pos)
  sid_array.authority = tonumber(string.sub(sid, pos, pos_next - 1))

  sid_array['sub_auths'] = {}
  i = 1
  repeat
    pos = pos_next + 1
    pos_next = string.find(sid, "-", pos)
    if(pos_next == nil) then
      sid_array['sub_auths'][i] = tonumber(string.sub(sid, pos))
    else
      sid_array['sub_auths'][i] = tonumber(string.sub(sid, pos, pos_next - 1))
    end
    i = i + 1
  until pos_next == nil
  sid_array['num_auths'] = i - 1

  result = {
    -- TODO: Is the first 32-bit integer here supposed to be num_auths, or some
    -- other count value?
    string.pack("<I4BB>I6", sid_array.num_auths, sid_array.sid_rev_num, sid_array.num_auths, sid_array.authority),
  }
  for i = 1, sid_array['num_auths'], 1 do
    result[#result+1] = string.pack("<I4", sid_array['sub_auths'][i])
  end

  stdnse.debug4("MSRPC: Leaving marshall_dom_sid2()")
  return table.concat(result)
end




----------------------------------
--       LSA
-- (dependencies: SECURITY)
----------------------------------


---A <code>lsa_String</code> is a buffer that holds a non-null-terminated string. It can have a max size that's different
-- from its actual size. I tagged this one as "internal" because I don't want the user to have to provide
-- a "location".
--
-- This is the format:
--
--<code>
--    typedef [public,noejs] struct {
--        [value(2*strlen_m(string))] uint16 length;
--        [value(2*strlen_m(string))] uint16 size;
--        [charset(UTF16),size_is(size/2),length_is(length/2)] uint16 *string;
--    } lsa_String;
--</code>
--
--@param location   The part of the pointer wanted, either HEAD (for the referent_id), BODY
--                  (for the pointer data), or ALL (for both together). Generally, unless the
--                  referent_id is split from the data (for example, in an array), you will want
--                  ALL.
--@param str        The string to marshall
--@param max_length [optional] The maximum size of the buffer, in characters, including the null terminator.
--                  Defaults to the length of the string, including the null.
--@param do_null    [optional] Appends a null to the end of the string. Default false.
--@return A string representing the marshalled data.
local function marshall_lsa_String_internal(location, str, max_length, do_null)
  local length
  local result = ""
  stdnse.debug4("MSRPC: Entering marshall_lsa_String_internal()")

  -- Handle default max lengths
  if(max_length == nil) then
    if(str == nil) then
      max_length = 0
    else
      max_length = #str
    end
  end

  if(str == nil) then
    length = 0
  else
    length = #str
  end

  if(do_null == nil) then
    do_null = false
  end

  if(location == HEAD or location == ALL) then
    result = result .. string.pack("<I2I2", length * 2, max_length * 2) .. marshall_ptr(HEAD, marshall_unicode, {str, do_null, max_length}, str)
  end

  if(location == BODY or location == ALL) then
    result = result .. marshall_ptr(BODY, marshall_unicode, {str, do_null, max_length}, str)
  end

  stdnse.debug4("MSRPC: Leaving marshall_lsa_String_internal()")
  return result
end

---Unmarshall a <code>lsa_String</code> value. See <code>marshall_lsa_String_internal</code> for more information.
--
--@param location The part of the pointer wanted, either HEAD (for the data itself), BODY
--                (for nothing, since this isn't a pointer), or ALL (for the data). Generally, unless the
--                referent_id is split from the data (for example, in an array), you will want
--                ALL.
--@param data     The data packet.
--@param pos      The position within the data.
--@param result   This is required when unmarshalling the BODY section, which always comes after
--                unmarshalling the HEAD. It is the result returned for this parameter during the
--                HEAD unmarshall. If the referent_id was '0', then this function doesn't unmarshall
--                anything.
--@return (pos, str) The new position, and the unmarshalled string.
local function unmarshall_lsa_String_internal(location, data, pos, result)
  local length, size
  local str
  stdnse.debug4("MSRPC: Entering unmarshall_lsa_String_internal()")

  if(location == HEAD or location == ALL) then
    pos, length = unmarshall_int16(data, pos, false)
    pos, size   = unmarshall_int16(data, pos, false)

    pos, str = unmarshall_ptr(HEAD, data, pos, unmarshall_unicode, {false})
  end

  if(location == BODY or location == ALL) then
    pos, str = unmarshall_ptr(BODY, data, pos, unmarshall_unicode, {false}, result)
  end

  stdnse.debug4("MSRPC: Leaving unmarshall_lsa_String_internal()")
  return pos, str
end

---Public version of <code>marshall_lsa_String_internal</code> -- see that function on that for more information.
-- This version doesn't require a <code>location</code>, so it's suitable to be a public function.
--
--@param str        The string to marshall
--@param max_length [optional] The maximum size of the buffer, in characters, including the null terminator.
--                  Defaults to the length of the string, including the null.
--@return A string representing the marshalled data.
function marshall_lsa_String(str, max_length)
  local result
  stdnse.debug4("MSRPC: Entering marshall_lsa_String()")

  result = marshall_lsa_String_internal(ALL, str, max_length)

  stdnse.debug4("MSRPC: Leaving marshall_lsa_String()")
  return result
end

---Marshall an array of lsa_String objects. This is a perfect demonstration of how to use
-- <code>marshall_array</code>.
--
--@param strings The array of strings to marshall
--@return A string representing the marshalled data.
function marshall_lsa_String_array(strings)
  local array = {}
  local result
  stdnse.debug4("MSRPC: Entering marshall_lsa_String_array()")

  for i = 1, #strings, 1 do
    array[i] = {}
    array[i]['func'] = marshall_lsa_String_internal
    array[i]['args'] = {strings[i]}
  end

  result = marshall_array(array)

  stdnse.debug4("MSRPC: Leaving marshall_lsa_String_array()")
  return result
end

---Basically the same as <code>marshall_lsa_String_array</code>, except it has a different structure
--
--@param strings The array of strings to marshall
function marshall_lsa_String_array2(strings)
  local array = {}
  local result

  for i = 1, #strings, 1 do
    array[i] = {}
    array[i]['func'] = marshall_lsa_String_internal
    array[i]['args'] = {strings[i], nil, nil, false}
  end

  result = marshall_int32(1000) -- Max length
  .. marshall_int32(0) -- Offset
  .. marshall_array(array)

  --require 'nsedebug'
  --nsedebug.print_hex(result)
  --os.exit()
  return result
end

---Table of SID types.
local lsa_SidType =
{
  SID_NAME_USE_NONE = 0, -- NOTUSED
  SID_NAME_USER     = 1, -- user
  SID_NAME_DOM_GRP  = 2, -- domain group
  SID_NAME_DOMAIN   = 3, -- domain: don't know what this is
  SID_NAME_ALIAS    = 4, -- local group
  SID_NAME_WKN_GRP  = 5, -- well-known group
  SID_NAME_DELETED  = 6, -- deleted account: needed for c2 rating
  SID_NAME_INVALID  = 7, -- invalid account
  SID_NAME_UNKNOWN  = 8, -- oops.
  SID_NAME_COMPUTER = 9  -- machine
}
---String versions of SID types
local lsa_SidType_str =
{
  SID_NAME_USE_NONE = "n/a",
  SID_NAME_USER     = "User",
  SID_NAME_DOM_GRP  = "Domain group",
  SID_NAME_DOMAIN   = "Domain",
  SID_NAME_ALIAS    = "Local group",
  SID_NAME_WKN_GRP  = "Well known group",
  SID_NAME_DELETED  = "Deleted account",
  SID_NAME_INVALID  = "Invalid account",
  SID_NAME_UNKNOWN  = "Unknown account",
  SID_NAME_COMPUTER = "Machine"
}
---Marshall a <code>lsa_SidType</code>. This datatype is tied to the table above with that
-- name.
--
--@param sid_type The value to marshall, as a string
--@return The marshalled integer representing the given value, or <code>nil</code> if it wasn't
--        found.
function marshall_lsa_SidType(sid_type)
  local result
  stdnse.debug4("MSRPC: Entering marshall_lsa_SidType()")

  result = marshall_Enum32(sid_type, lsa_SidType)

  stdnse.debug4("MSRPC: Leaving marshall_lsa_SidType()")
  return result
end

---Unmarshall a <code>lsa_SidType</code>. This datatype is tied to the table with that name.
--
--@param data The data packet.
--@param pos  The position within the data.
--@return (pos, str) The new position, and the string representing the datatype.
function unmarshall_lsa_SidType(data, pos)
  local str
  stdnse.debug4("MSRPC: Entering unmarshall_lsa_SidType()")

  pos, str = unmarshall_Enum16(data, pos, lsa_SidType)

  stdnse.debug4("MSRPC: Leaving unmarshall_lsa_SidType()")
  return pos, str
end

---Convert a <code>lsa_SidType</code> value to a string that can be shown to the user. This is
-- based on the <code>_str</code> table.
--
--@param val The string value (returned by the <code>unmarshall_</code> function) to convert.
--@return A string suitable for displaying to the user, or <code>nil</code> if it wasn't found.
function lsa_SidType_tostr(val)
  local result
  stdnse.debug4("MSRPC: Entering lsa_SidType_tostr()")

  result = lsa_SidType_str[val]

  stdnse.debug4("MSRPC: Leaving lsa_SidType_tostr()")
  return result
end

---LSA name levels.
local lsa_LookupNamesLevel =
{
  LOOKUP_NAMES_ALL                  = 1,
  LOOKUP_NAMES_DOMAINS_ONLY         = 2,
  LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY  = 3,
  LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY  = 4,
  LOOKUP_NAMES_FOREST_TRUSTS_ONLY   = 5,
  LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2 = 6
}
---LSA name level strings.
local lsa_LookupNamesLevel_str =
{
  LOOKUP_NAMES_ALL                  = "All",
  LOOKUP_NAMES_DOMAINS_ONLY         = "Domains only",
  LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY  = "Primary domains only",
  LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY  = "Uplevel trusted domains only",
  LOOKUP_NAMES_FOREST_TRUSTS_ONLY   = "Forest trusted domains only",
  LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2 = "Uplevel trusted domains only (2)"
}
---Marshall a <code>lsa_LookupNamesLevel</code>. This datatype is tied to the table above with that
-- name.
--
--@param names_level The value to marshall, as a string
--@return The marshalled integer representing the given value, or <code>nil</code> if it wasn't
--        found.
function marshall_lsa_LookupNamesLevel(names_level)
  local result
  stdnse.debug4("MSRPC: Entering marshall_lsa_LookupNamesLevel()")

  result = marshall_Enum32(names_level, lsa_LookupNamesLevel)

  stdnse.debug4("MSRPC: Leaving marshall_lsa_LookupNamesLevel()")
  return result
end

---Unmarshall a <code>lsa_LookupNamesLevel</code>. This datatype is tied to the table with that name.
--
--@param data The data packet.
--@param pos  The position within the data.
--@return (pos, str) The new position, and the string representing the datatype.
function unmarshall_lsa_LookupNamesLevel(data, pos)
  local str
  stdnse.debug4("MSRPC: Entering unmarshall_lsa_LookupNamesLevel()")

  pos, str = unmarshall_Enum32(data, pos, lsa_LookupNamesLevel)

  stdnse.debug4("MSRPC: Leaving unmarshall_lsa_LookupNamesLevel()")
  return pos, str
end

---Convert a <code>lsa_LookupNamesLevel</code> value to a string that can be shown to the user. This is
-- based on the <code>_str</code> table.
--
--@param val The string value (returned by the <code>unmarshall_</code> function) to convert.
--@return A string suitable for displaying to the user, or <code>nil</code> if it wasn't found.
function lsa_LookupNamesLevel_tostr(val)
  local result
  stdnse.debug4("MSRPC: Entering lsa_LookupNamesLevel_tostr()")

  result = lsa_LookupNamesLevel_str[val]

  stdnse.debug4("MSRPC: Leaving lsa_LookupNamesLevel_tostr()")
  return result
end

---Marshall a lsa_TranslatedSid2 struct
--
--<code>
--    typedef struct {
--        lsa_SidType sid_type;
--        uint32 rid;
--        uint32 sid_index;
--        uint32 unknown;
--    } lsa_TranslatedSid2;
--</code>
--
--@param location The part of the pointer wanted, either HEAD (for the data itself), BODY
--                (for nothing, since this isn't a pointer), or ALL (for the data). Generally, unless the
--                referent_id is split from the data (for example, in an array), you will want
--                ALL.
--@param sid_type  The <code>sid_type</code> value (I don't know what this means)
--@param rid       The <code>rid</code> (a number representing the user)
--@param sid_index The <code>sid_index</code> value (I don't know what this means, either)
--@param unknown   An unknown value (is normally 0).
--@return A string representing the marshalled data.
local function marshall_lsa_TranslatedSid2(location, sid_type, rid, sid_index, unknown)
  local result = ""
  stdnse.debug4("MSRPC: Entering marshall_lsa_TranslatedSid2()")

  -- Set some default values
  if(sid_type == nil)  then sid_type  = "SID_NAME_USE_NONE" end
  if(rid == nil)       then rid       = 0 end
  if(sid_index == nil) then sid_index = 0 end
  if(unknown == nil)   then unknown   = 0 end

  if(location == HEAD or location == ALL) then
    result = marshall_lsa_SidType(sid_type)
    .. marshall_int32(rid)
    .. marshall_int32(sid_index)
    .. marshall_int32(unknown)
  end

  if(location == BODY or location == ALL) then
  end

  stdnse.debug4("MSRPC: Leaving marshall_lsa_TranslatedSid2()")
  return result
end

---Unmarshall a lsa_TranslatedSid2 struct
--
--<code>
--    typedef struct {
--        lsa_SidType sid_type;
--        uint32 rid;
--        uint32 sid_index;
--        uint32 unknown;
--    } lsa_TranslatedSid2;
--</code>
--
--@param location The part of the pointer wanted, either HEAD (for the data itself), BODY
--                (for nothing, since this isn't a pointer), or ALL (for the data). Generally, unless the
--                referent_id is split from the data (for example, in an array), you will want
--                ALL.
--@param data     The data being processed.
--@param pos      The position within <code>data</code>.
--@param result   This is required when unmarshalling the BODY section, which always comes after
--                unmarshalling the HEAD. It is the result returned for this parameter during the
--                HEAD unmarshall. If the referent_id was '0', then this function doesn't unmarshall
--                anything.
--@return (pos, result) The new position in <code>data</code>, and a table representing the datatype.
local function unmarshall_lsa_TranslatedSid2(location, data, pos, result)
  if(result == nil) then
    result = {}
  end

  if(location == HEAD or location == ALL) then
    pos, result['sid_type']  = unmarshall_lsa_SidType(data, pos)
    pos, result['rid']       = unmarshall_int32(data, pos)
    pos, result['sid_index'] = unmarshall_int32(data, pos)
    pos, result['unknown']   = unmarshall_int32(data, pos)
  end


  if(location == BODY or location == ALL) then
  end

  return pos, result
end

---Marshall a lsa_TranslatedName2 struct
--
--<code>
--    typedef struct {
--        lsa_SidType sid_type;
--        lsa_String name;
--        uint32 sid_index;
--        uint32 unknown;
--    } lsa_TranslatedName2;
--</code>
--
--@param location  The part of the pointer wanted, either HEAD (for the data itself), BODY
--                 (for nothing, since this isn't a pointer), or ALL (for the data). Generally, unless the
--                 referent_id is split from the data (for example, in an array), you will want
--                 ALL.
--@param sid_type  The <code>sid_type</code> value, as a string
--@param name      The name of the user
--@param sid_index The sid_index (I don't know what this is)
--@param unknown   An unknown value, normally 0
--@return A string representing the marshalled data.
local function marshall_lsa_TranslatedName2(location, sid_type, name, sid_index, unknown)
  local result = ""
  stdnse.debug4("MSRPC: Entering marshall_lsa_TranslatedName2()")

  -- Set some default values
  if(sid_type == nil)  then sid_type  = "SID_NAME_USE_NONE" end
  if(name == nil)      then name      = "" end
  if(sid_index == nil) then sid_index = 0 end
  if(unknown == nil)   then unknown   = 0 end

  if(location == HEAD or location == ALL) then
    result = marshall_lsa_SidType(sid_type)
    .. marshall_lsa_String_internal(HEAD, name)
    .. marshall_int32(sid_index)
    .. marshall_int32(unknown)
  end

  if(location == BODY or location == ALL) then
    result = result .. marshall_lsa_String_internal(BODY, name)
  end

  stdnse.debug4("MSRPC: Leaving marshall_lsa_TranslatedName2()")
  return result
end

--@param location The part of the pointer wanted, either HEAD (for the data itself), BODY
--                (for nothing, since this isn't a pointer), or ALL (for the data). Generally, unless the
--                referent_id is split from the data (for example, in an array), you will want
--                ALL.
--@param data     The data being processed.
--@param pos      The position within <code>data</code>.
--@param result   This is required when unmarshalling the BODY section, which always comes after
--                unmarshalling the HEAD. It is the result returned for this parameter during the
--                HEAD unmarshall. If the referent_id was '0', then this function doesn't unmarshall
--                anything.
--@return (pos, result) The new position in <code>data</code>, and a table representing the datatype.
local function unmarshall_lsa_TranslatedName2(location, data, pos, result)
  stdnse.debug4("MSRPC: Entering unmarshall_lsa_TranslatedName2()")
  if(result == nil) then
    result = {}
  end

  if(location == HEAD or location == ALL) then
    pos, result['sid_type']  = unmarshall_lsa_SidType(data, pos)
    pos, result['name']      = unmarshall_lsa_String_internal(HEAD, data, pos)
    pos, result['sid_index'] = unmarshall_int32(data, pos)
    pos, result['unknown']   = unmarshall_int32(data, pos)
  end


  if(location == BODY or location == ALL) then
    pos, result['name']      = unmarshall_lsa_String_internal(BODY, data, pos, result['name'])
  end

  stdnse.debug4("MSRPC: Leaving unmarshall_lsa_TranslatedName2()")
  return pos, result
end


---Marshall a lsa_TransSidArray2 struct
--
--<code>
--    typedef struct {
--        [range(0,1000)] uint32 count;
--        [size_is(count)] lsa_TranslatedSid2 *sids;
--    } lsa_TransSidArray2;
--</code>
--
--@param sids An array of SIDs to translate (as strings)
--@return A string representing the marshalled data.
function marshall_lsa_TransSidArray2(sids)
  local array = {}
  stdnse.debug4("MSRPC: Entering marshall_lsa_TransSidArray2()")


  for i = 1, #sids, 1 do
    array[i] = {}
    array[i]['func'] = marshall_lsa_TranslatedSid2
    array[i]['args'] = {sids[i]['sid_type'], sids[i]['rid'], sids[i]['sid_index'], sids[i]['unknown']}
  end

  local result = marshall_int32(#sids)
  .. marshall_ptr(ALL, marshall_array, {array}, array)

  stdnse.debug4("MSRPC: Leaving marshall_lsa_TransSidArray2()")
  return result
end

---Marshall a lsa_StringLarge struct
--
--<code>
--    typedef [public] struct {
--        [value(2*strlen_m(string))] uint16 length;
--        [value(2*(strlen_m(string)+1))] uint16 size;
--        [charset(UTF16),size_is(size/2),length_is(length/2)] uint16 *string;
--    } lsa_StringLarge;
--</code>
--
--@param location The part of the pointer wanted, either HEAD (for the data itself), BODY
--                (for nothing, since this isn't a pointer), or ALL (for the data). Generally, unless the
--                referent_id is split from the data (for example, in an array), you will want
--                ALL.
--@param data     The data being processed.
--@param pos      The position within <code>data</code>.
--@param result   This is required when unmarshalling the BODY section, which always comes after
--                unmarshalling the HEAD. It is the result returned for this parameter during the
--                HEAD unmarshall. If the referent_id was '0', then this function doesn't unmarshall
--                anything.
--@return (pos, result) The new position in <code>data</code>, and the string value.
local function unmarshall_lsa_StringLarge(location, data, pos, result)
  local length, size
  local str
  stdnse.debug4("MSRPC: Entering unmarshall_lsa_StringLarge()")

  if(location == HEAD or location == ALL) then
    pos, length = unmarshall_int16(data, pos, false)
    pos, size   = unmarshall_int16(data, pos, false)

    pos, str = unmarshall_ptr(HEAD, data, pos, unmarshall_unicode, {false})
  end

  if(location == BODY or location == ALL) then
    pos, str = unmarshall_ptr(BODY, data, pos, unmarshall_unicode, {false}, result)
  end

  stdnse.debug4("MSRPC: Leaving unmarshall_lsa_StringLarge()")
  return pos, str
end

---Unmarshall a lsa_DomainInfo struct
--
--<code>
--    typedef struct {
--        lsa_StringLarge name;
--        dom_sid2 *sid;
--    } lsa_DomainInfo;
--</code>
--
--@param location The part of the pointer wanted, either HEAD (for the data itself), BODY
--                (for nothing, since this isn't a pointer), or ALL (for the data). Generally, unless the
--                referent_id is split from the data (for example, in an array), you will want
--                ALL.
--@param data     The data being processed.
--@param pos      The position within <code>data</code>.
--@param result   This is required when unmarshalling the BODY section, which always comes after
--                unmarshalling the HEAD. It is the result returned for this parameter during the
--                HEAD unmarshall. If the referent_id was '0', then this function doesn't unmarshall
--                anything.
--@return (pos, result) The new position in <code>data</code>, and a table representing the datatype.
local function unmarshall_lsa_DomainInfo(location, data, pos, result)
  stdnse.debug4("MSRPC: Entering unmarshall_lsa_DomainInfo()")
  if(result == nil) then
    result = {}
  end

  if(location == HEAD or location == ALL) then
    pos, result['name'] = unmarshall_lsa_StringLarge(HEAD, data, pos)
    pos, result['sid']  = unmarshall_ptr(HEAD, data, pos, unmarshall_dom_sid2)
  end

  if(location == BODY or location == ALL) then
    pos, result['name'] = unmarshall_lsa_StringLarge(BODY, data, pos, result['name'])
    pos, result['sid']  = unmarshall_ptr(BODY, data, pos, unmarshall_dom_sid2, {}, result['sid'])
  end

  stdnse.debug4("MSRPC: Leaving unmarshall_lsa_DomainInfo()")
  return pos, result
end

---Unmarshall a lsa_RefDomainList struct
--
--<code>
--    typedef struct {
--        [range(0,1000)] uint32 count;
--        [size_is(count)] lsa_DomainInfo *domains;
--        uint32 max_size;
--    } lsa_RefDomainList;
--</code>
--
--@param data     The data being processed.
--@param pos      The position within <code>data</code>.
--@return (pos, result) The new position in <code>data</code>, and a table representing the datatype.
function unmarshall_lsa_RefDomainList(data, pos)
  local result = {}
  stdnse.debug4("MSRPC: Entering unmarshall_lsa_RefDomainList()")

  -- Head
  pos, result['count'] = unmarshall_int32(data, pos)
  pos, result['domains'] = unmarshall_ptr(HEAD, data, pos, unmarshall_array, {result['count'], unmarshall_lsa_DomainInfo, {}})
  pos, result['max_size'] = unmarshall_int32(data, pos)

  -- Body
  pos, result['domains'] = unmarshall_ptr(BODY, data, pos, unmarshall_array, {result['count'], unmarshall_lsa_DomainInfo, {}}, result['domains'])

  stdnse.debug4("MSRPC: Leaving unmarshall_lsa_RefDomainList()")
  return pos, result
end

---Unmarshall a pointer to a <code>lsa_RefDomainList</code>. See the <code>unmarshall_lsa_RefDomainList</code> function
-- for more information.
--
--@param data     The data being processed.
--@param pos      The position within <code>data</code>.
--@return (pos, result) The new position in <code>data</code>, and a table representing the datatype.
function unmarshall_lsa_RefDomainList_ptr(data, pos)
  local result
  stdnse.debug4("MSRPC: Entering unmarshall_lsa_RefDomainList_ptr()")

  pos, result = unmarshall_ptr(ALL, data, pos, unmarshall_lsa_RefDomainList, nil)

  stdnse.debug4("MSRPC: Leaving unmarshall_lsa_RefDomainList_ptr()")
  return pos, result
end

---Unmarshall a lsa_TransSidArray2 struct
--
--<code>
--    typedef struct {
--        [range(0,1000)] uint32 count;
--        [size_is(count)] lsa_TranslatedSid2 *sids;
--    } lsa_TransSidArray2;
--</code>
--
--@param data     The data being processed.
--@param pos      The position within <code>data</code>.
--@return (pos, result) The new position in <code>data</code>, and a table representing the datatype.
function unmarshall_lsa_TransSidArray2(data, pos)
  local result = {}
  stdnse.debug4("MSRPC: Entering unmarshall_lsa_TransSidArray2()")

  pos, result['count'] = unmarshall_int32(data, pos)
  pos, result['sid']   = unmarshall_ptr(ALL, data, pos, unmarshall_array, {result['count'], unmarshall_lsa_TranslatedSid2, {}})

  stdnse.debug4("MSRPC: Leaving unmarshall_lsa_TransSidArray2()")
  return pos, result
end

---Marshall a lsa_QosInfo struct
--
--<code>
--    typedef struct {
--        uint32  len; /* ignored */
--        uint16  impersonation_level;
--        uint8   context_mode;
--        uint8   effective_only;
--    } lsa_QosInfo;
--</code>
--
-- I didn't bother letting the user specify values, since I don't know what any of them do. The
-- defaults seem to work really well.
--
--@return A string representing the marshalled data.
function marshall_lsa_QosInfo()
  stdnse.debug4("MSRPC: Entering marshall_lsa_QosInfo()")

  local result = marshall_int32(12)
  .. marshall_int16(2, false)
  .. marshall_int8(1, false)
  .. marshall_int8(0, false)

  stdnse.debug4("MSRPC: Leaving marshall_lsa_QosInfo()")
  return result
end

---Marshall a lsa_ObjectAttribute struct
--
--<code>
--    typedef struct {
--        uint32 len; /* ignored */
--        uint8 *root_dir;
--        [string,charset(UTF16)] uint16 *object_name;
--        uint32 attributes;
--        security_descriptor *sec_desc;
--        lsa_QosInfo *sec_qos;
--    } lsa_ObjectAttribute;
--</code>
--
-- I didn't bother letting the user specify values, since I don't know what any of them do. The
-- defaults seem to work really well.
--
--@return A string representing the marshalled data.
function marshall_lsa_ObjectAttribute()
  stdnse.debug4("MSRPC: Entering marshall_lsa_ObjectAttribute()")

  local result = marshall_int32(24)
  .. marshall_int32(0)  -- Null'ing out these pointers for now. Maybe we'll need them in the future...
  .. marshall_int32(0)
  .. marshall_int32(0)
  .. marshall_int32(0)
  .. marshall_ptr(ALL, marshall_lsa_QosInfo, {})

  stdnse.debug4("MSRPC: Leaving marshall_lsa_ObjectAttribute()")
  return result
end

---Marshall a lsa_SidPtr struct
--
--<code>
--    typedef struct {
--        dom_sid2 *sid;
--    } lsa_SidPtr;
--</code>
--
--@param location The part of the pointer wanted, either HEAD (for the data itself), BODY
--                (for nothing, since this isn't a pointer), or ALL (for the data). Generally, unless the
--                referent_id is split from the data (for example, in an array), you will want
--                ALL.
--@param sid      The SID to marshall (as a string).
--@return A string representing the marshalled data.
local function marshall_lsa_SidPtr(location, sid)
  local result
  stdnse.debug4("MSRPC: Entering marshall_lsa_SidPtr()")

  result = marshall_ptr(location, marshall_dom_sid2, {sid}, sid)

  stdnse.debug4("MSRPC: Leaving marshall_lsa_SidPtr()")
  return result
end

---Marshall a lsa_SidArray struct
--
--<code>
--    typedef [public] struct {
--        [range(0,1000)] uint32 num_sids;
--        [size_is(num_sids)] lsa_SidPtr *sids;
--    } lsa_SidArray;
--</code>
--
--@param sids The array of SIDs to marshall (as strings).
--@return A string representing the marshalled data.
function marshall_lsa_SidArray(sids)
  local array = {}

  for i = 1, #sids, 1 do
    array[i] = {}
    array[i]['func'] = marshall_lsa_SidPtr
    array[i]['args'] = {sids[i]}
  end

  local result = marshall_int32(#sids)
  .. marshall_ptr(ALL, marshall_array, {array}, array)

  return result
end

---Unmarshall a lsa_SidPtr struct
--
--<code>
--    typedef struct {
--        dom_sid2 *sid;
--    } lsa_SidPtr;
--</code>
--
--@param location The part of the pointer wanted, either HEAD (for the data itself), BODY
--                (for nothing, since this isn't a pointer), or ALL (for the data). Generally, unless the
--                referent_id is split from the data (for example, in an array), you will want
--                ALL.
--@param data     The data being processed.
--@param pos      The position within <code>data</code>.
--@param result   This is required when unmarshalling the BODY section, which always comes after
--                unmarshalling the HEAD. It is the result returned for this parameter during the
--                HEAD unmarshall. If the referent_id was '0', then this function doesn't unmarshall
--                anything.
--@return (pos, result) The new position in <code>data</code>, and a table representing the datatype.
function unmarshall_lsa_SidPtr(location, data, pos, result)
  return unmarshall_ptr(location, data, pos, unmarshall_dom_sid2, {}, result)
end

---Unmarshall a lsa_SidArray struct
--
--    typedef [public] struct {
--        [range(0,1000)] uint32 num_sids;
--        [size_is(num_sids)] lsa_SidPtr *sids;
--    } lsa_SidArray;
--
--@param data     The data being processed.
--@param pos      The position within <code>data</code>.
--@return (pos, result) The new position in <code>data</code>, and a table representing the datatype.
function unmarshall_lsa_SidArray(data, pos)
  local sidarray = {}

  pos, sidarray['count'] = unmarshall_int32(data, pos)
  pos, sidarray['sids']  = unmarshall_ptr(ALL, data, pos, unmarshall_array, {sidarray['count'], unmarshall_lsa_SidPtr, {}})

  return pos, sidarray
end

---Marshall a lsa_TransNameArray2 struct
--
--<code>
--    typedef struct {
--        [range(0,1000)] uint32 count;
--        [size_is(count)] lsa_TranslatedName2 *names;
--    } lsa_TransNameArray2;
--</code>
--
--@param names An array of names to translate.
--@return A string representing the marshalled data.
function marshall_lsa_TransNameArray2(names)
  local result = ""
  local array = {}
  stdnse.debug4("MSRPC: Entering marshall_lsa_TransNameArray2()")

  if(names == nil) then
    result = result .. marshall_int32(0)
    array = nil
  else
    result = result .. marshall_int32(#names)

    for i = 1, #names, 1 do
      array[i] = {}
      array[i]['func'] = marshall_lsa_TranslatedName2
      array[i]['args'] = {names[i]['sid_type'], names[i]['name'], names[i]['sid_index'], names[i]['unknown']}
    end
  end

  result = result .. marshall_ptr(ALL, marshall_array, {array}, array)

  stdnse.debug4("MSRPC: Leaving marshall_lsa_TransNameArray2()")
  return result
end

---Unmarshall a <code>lsa_TransNameArray2</code> structure. See the <code>marshall_lsa_TransNameArray2</code> for more
-- information.
--
--@param data     The data being processed.
--@param pos      The position within <code>data</code>.
--@return (pos, result) The new position in <code>data</code>, and a table representing the datatype.
function unmarshall_lsa_TransNameArray2(data, pos)
  local result = {}
  stdnse.debug4("MSRPC: Entering unmarshall_lsa_TransNameArray2()")

  pos, result['count'] = unmarshall_int32(data, pos)
  pos, result['names'] = unmarshall_ptr(ALL, data, pos, unmarshall_array, {result['count'], unmarshall_lsa_TranslatedName2, {}})

  stdnse.debug4("MSRPC: Leaving unmarshall_lsa_TransNameArray2()")
  return pos, result
end



-------------------------------------
--          WINREG
-- (dependencies: LSA, INITSHUTDOWN, SECURITY)
-------------------------------------
--- Access masks for Windows registry calls
local winreg_AccessMask =
{
  DELETE_ACCESS          = 0x00010000,
  READ_CONTROL_ACCESS    = 0x00020000,
  WRITE_DAC_ACCESS       = 0x00040000,
  WRITE_OWNER_ACCESS     = 0x00080000,
  SYNCHRONIZE_ACCESS     = 0x00100000,
  ACCESS_SACL_ACCESS     = 0x00800000,
  SYSTEM_SECURITY_ACCESS = 0x01000000,
  MAXIMUM_ALLOWED_ACCESS = 0x02000000,
  GENERIC_ALL_ACCESS     = 0x10000000,
  GENERIC_EXECUTE_ACCESS = 0x20000000,
  GENERIC_WRITE_ACCESS   = 0x40000000,
  GENERIC_READ_ACCESS    = 0x80000000
}
--- String versions of access masks for Windows registry calls
local winreg_AccessMask_str =
{
  DELETE_ACCESS          = "Delete",
  READ_CONTROL_ACCESS    = "Read",
  WRITE_DAC_ACCESS       = "Write",
  WRITE_OWNER_ACCESS     = "Write (owner)",
  SYNCHRONIZE_ACCESS     = "Synchronize",
  ACCESS_SACL_ACCESS     = "Access SACL",
  SYSTEM_SECURITY_ACCESS = "System security",
  MAXIMUM_ALLOWED_ACCESS = "Maximum allowed access",
  GENERIC_ALL_ACCESS     = "All access",
  GENERIC_EXECUTE_ACCESS = "Execute access",
  GENERIC_WRITE_ACCESS   = "Write access",
  GENERIC_READ_ACCESS    = "Read access"
}

---Marshall a <code>winreg_AccessMask</code>.
--
--@param accessmask The access mask as a string (see the <code>winreg_AccessMask</code>
--                  table)
--@return A string representing the marshalled data.
function marshall_winreg_AccessMask(accessmask)
  local result
  stdnse.debug4("MSRPC: Entering marshall_winreg_AccessMask()")

  result = marshall_Enum32(accessmask, winreg_AccessMask)

  stdnse.debug4("MSRPC: Leaving marshall_winreg_AccessMask()")
  return result
end

---Unmarshall a <code>winreg_AccessMask</code>. This datatype is tied to the table with that name.
--
--@param data The data packet.
--@param pos  The position within the data.
--@return (pos, str) The new position, and the string representing the datatype.
function unmarshall_winreg_AccessMask(data, pos)
  local str
  stdnse.debug4("MSRPC: Entering unmarshall_winreg_AccessMask()")

  pos, str = unmarshall_Enum32(data, pos, winreg_AccessMask)

  stdnse.debug4("MSRPC: Leaving unmarshall_winreg_AccessMask()")
  return pos, str
end

---Convert a <code>winreg_AccessMask</code> value to a string that can be shown to the user. This is
-- based on the <code>_str</code> table.
--
--@param val The string value (returned by the <code>unmarshall_</code> function) to convert.
--@return A string suitable for displaying to the user, or <code>nil</code> if it wasn't found.
function winreg_AccessMask_tostr(val)
  local result
  stdnse.debug4("MSRPC: Entering winreg_AccessMask_tostr()")

  result = winreg_AccessMask_str[val]

  stdnse.debug4("MSRPC: Leaving winreg_AccessMask_tostr()")
  return result
end

---Registry types
winreg_Type =
{
  REG_NONE                       = 0,
  REG_SZ                         = 1,
  REG_EXPAND_SZ                  = 2,
  REG_BINARY                     = 3,
  REG_DWORD                      = 4,
  REG_DWORD_BIG_ENDIAN           = 5,
  REG_LINK                       = 6,
  REG_MULTI_SZ                   = 7,
  REG_RESOURCE_LIST              = 8,
  REG_FULL_RESOURCE_DESCRIPTOR   = 9,
  REG_RESOURCE_REQUIREMENTS_LIST = 10,
  REG_QWORD                      = 11
}

---Registry type strings
winreg_Type_str =
{
  REG_NONE                       = "None",
  REG_SZ                         = "String",
  REG_EXPAND_SZ                  = "String (expanded)",
  REG_BINARY                     = "Binary",
  REG_DWORD                      = "Dword",
  REG_DWORD_BIG_ENDIAN           = "Dword (big endian)",
  REG_LINK                       = "Link",
  REG_MULTI_SZ                   = "String (multi)",
  REG_RESOURCE_LIST              = "Resource list",
  REG_FULL_RESOURCE_DESCRIPTOR   = "Full resource descriptor",
  REG_RESOURCE_REQUIREMENTS_LIST = "Resource requirements list",
  REG_QWORD                      = "Qword"
}

---Marshall a <code>winreg_Type</code>. This datatype is tied to the table above with that
-- name.
--
--@param winregtype The value to marshall, as a string
--@return The marshalled integer representing the given value, or <code>nil</code> if it wasn't
--        found.
function marshall_winreg_Type(winregtype)
  local result
  stdnse.debug4("MSRPC: Entering marshall_winreg_Type()")

  result = marshall_Enum32(winregtype, winreg_Type)

  stdnse.debug4("MSRPC: Leaving marshall_winreg_Type()")
  return result
end

---Unmarshall a <code>winreg_Type</code>. This datatype is tied to the table with that name.
--
--@param data The data packet.
--@param pos  The position within the data.
--@return (pos, str) The new position, and the string representing the datatype.
function unmarshall_winreg_Type(data, pos)
  local str
  stdnse.debug4("MSRPC: Entering unmarshall_winreg_Type()")

  pos, str = unmarshall_Enum32(data, pos, winreg_Type)

  stdnse.debug4("MSRPC: Leaving unmarshall_winreg_Type()")
  return pos, str
end

---Marshall a pointer to a <code>winreg_Type</code>. This datatype is tied to the table above with that
-- name.
--
--@param winreg_type The value to marshall, as a string
--@return The marshalled integer representing the given value, or <code>nil</code> if it wasn't
--        found.
function marshall_winreg_Type_ptr(winreg_type)
  local result
  stdnse.debug4("MSRPC: Entering marshall_winreg_Type_ptr()")

  result = marshall_ptr(ALL, marshall_winreg_Type, {winreg_type}, winreg_type)

  stdnse.debug4("MSRPC: Leaving marshall_winreg_Type_ptr()")
  return result
end

---Unmarshall a pointer to a <code>winreg_Type</code>. This datatype is tied to the table with that name.
--
--@param data The data packet.
--@param pos  The position within the data.
--@return (pos, str) The new position, and the string representing the datatype.
function unmarshall_winreg_Type_ptr(data, pos)
  local str
  stdnse.debug4("MSRPC: Entering unmarshall_winreg_Type_ptr()")

  pos, str = unmarshall_ptr(ALL, data, pos, unmarshall_winreg_Type, {})

  stdnse.debug4("MSRPC: Leaving unmarshall_winreg_Type_ptr()")
  return pos, str
end

---Convert a <code>winreg_Type</code> value to a string that can be shown to the user. This is
-- based on the <code>_str</code> table.
--
--@param val The string value (returned by the <code>unmarshall_</code> function) to convert.
--@return A string suitable for displaying to the user, or <code>nil</code> if it wasn't found.
function winreg_Type_tostr(val)
  local result
  stdnse.debug4("MSRPC: Entering winreg_Type_tostr()")

  result = winreg_Type_str[val]

  stdnse.debug4("MSRPC: Leaving winreg_Type_tostr()")
  return result
end

--- A winreg_stringbuf is a buffer that holds a null-terminated string. It can have a max size that's different
--  from its actual size.
--
-- This is the format:
--
--<code>
--  typedef struct {
--    [value(strlen_m_term(name)*2)] uint16 length;
--    uint16 size;
--    [size_is(size/2),length_is(length/2),charset(UTF16)] uint16 *name;
--  } winreg_StringBuf;
--</code>
--
--@param table The table to marshall. Will probably contain just the 'name' entry.
--@param max_length [optional] The maximum size of the buffer, in characters, including the null terminator.
--                  Defaults to the length of the string, including the null.
--@return A string representing the marshalled data.
function marshall_winreg_StringBuf(table, max_length)
  local result
  stdnse.debug4("MSRPC: Entering marshall_winreg_StringBuf()")

  local name = table['name']
  local length

  -- Handle default max lengths
  if(max_length == nil) then
    if(name == nil) then
      max_length = 0
    else
      max_length = #name + 1
    end
  end

  -- For some reason, 0-length strings are handled differently (no null terminator)...
  if(name == "") then
    length = 0
    result = string.pack("<I2I2", length * 2, max_length * 2) .. marshall_ptr(ALL, marshall_unicode, {name, false, max_length}, name)
  else
    if(name == nil) then
      length = 0
    else
      length = #name + 1
    end

    result = string.pack("<I2I2", length * 2, max_length * 2) .. marshall_ptr(ALL, marshall_unicode, {name, true, max_length}, name)
  end

  stdnse.debug4("MSRPC: Leaving marshall_winreg_StringBuf()")
  return result
end

---Unmarshall a winreg_StringBuf buffer.
--
--@param data   The data buffer.
--@param pos    The position in the data buffer.
--@return (pos, str) The new position and the string.
function unmarshall_winreg_StringBuf(data, pos)
  local length, size
  local str
  stdnse.debug4("MSRPC: Entering unmarshall_winreg_StringBuf()")

  pos, length = unmarshall_int16(data, pos, false)
  pos, size   = unmarshall_int16(data, pos, false)

  pos, str = unmarshall_ptr(ALL, data, pos, unmarshall_unicode, {true})

  stdnse.debug4("MSRPC: Leaving unmarshall_winreg_StringBuf()")
  return pos, str
end

---Marshall a winreg_StringBuffer pointer. Same as <code>marshall_winreg_StringBuf</code>, except
-- the string can be <code>nil</code>.
--
--@param table The table representing the String.
--@param max_length [optional] The maximum size of the buffer, in characters. Defaults to the length of the string, including the null.
--@return A string representing the marshalled data.
function marshall_winreg_StringBuf_ptr(table, max_length)
  local result
  stdnse.debug4("MSRPC: Entering marshall_winreg_StringBuf_ptr()")

  result = marshall_ptr(ALL, marshall_winreg_StringBuf, {table, max_length}, table)

  stdnse.debug4("MSRPC: Leaving marshall_winreg_StringBuf_ptr()")
  return result
end

---Unmarshall a winreg_StringBuffer pointer
--
--@param data   The data buffer.
--@param pos    The position in the data buffer.
--@return (pos, str) The new position and the string.
function unmarshall_winreg_StringBuf_ptr(data, pos)
  local str
  stdnse.debug4("MSRPC: Entering unmarshall_winreg_StringBuf_ptr()")

  pos, str = unmarshall_ptr(ALL, data, pos, unmarshall_winreg_StringBuf, {})

  stdnse.debug4("MSRPC: Leaving unmarshall_winreg_StringBuf_ptr()")
  return pos, str
end


--- A winreg_String has the same makeup as a winreg_StringBuf, as far as I can tell, so delegate to that function.
--
--@param table The table representing the String.
--@param max_length [optional] The maximum size of the buffer, in characters. Defaults to the length of the string, including the null.
--@return A string representing the marshalled data.
function marshall_winreg_String(table, max_length)
  local result
  stdnse.debug4("MSRPC: Entering marshall_winreg_String()")

  result = marshall_winreg_StringBuf(table, max_length)

  stdnse.debug4("MSRPC: Leaving marshall_winreg_String()")
  return result
end

---Unmarshall a winreg_String. Since it has the same makeup as winreg_StringBuf, delegate to that.
--
--@param data   The data buffer.
--@param pos    The position in the data buffer.
--@return (pos, str) The new position and the string.
function unmarshall_winreg_String(data, pos)
  local str
  stdnse.debug4("MSRPC: Entering unmarshall_winreg_String()")

  pos, str = unmarshall_winreg_StringBuf(data, pos)

  stdnse.debug4("MSRPC: Leaving unmarshall_winreg_String()")
  return pos, str
end


-------------------------------------
--          SRVSVC
-- (dependencies: SECURITY, SVCCTL)
-------------------------------------
---Share types
local srvsvc_ShareType =
{
  STYPE_DISKTREE           = 0x00000000,
  STYPE_DISKTREE_TEMPORARY = 0x40000000,
  STYPE_DISKTREE_HIDDEN    = 0x80000000,
  STYPE_PRINTQ             = 0x00000001,
  STYPE_PRINTQ_TEMPORARY   = 0x40000001,
  STYPE_PRINTQ_HIDDEN      = 0x80000001,
  STYPE_DEVICE             = 0x00000002, -- Serial device
  STYPE_DEVICE_TEMPORARY   = 0x40000002,
  STYPE_DEVICE_HIDDEN      = 0x80000002,
  STYPE_IPC                = 0x00000003, -- Interprocess communication (IPC)
  STYPE_IPC_TEMPORARY      = 0x40000003,
  STYPE_IPC_HIDDEN         = 0x80000003
}
---Share type strings
local srvsvc_ShareType_str =
{
  STYPE_DISKTREE           = "Disk",
  STYPE_DISKTREE_TEMPORARY = "Disk (temporary)",
  STYPE_DISKTREE_HIDDEN    = "Disk (hidden)",
  STYPE_PRINTQ             = "Print queue",
  STYPE_PRINTQ_TEMPORARY   = "Print queue (temporary)",
  STYPE_PRINTQ_HIDDEN      = "Print queue (hidden)",
  STYPE_DEVICE             = "Serial device",
  STYPE_DEVICE_TEMPORARY   = "Serial device (temporary)",
  STYPE_DEVICE_HIDDEN      = "Serial device (hidden)",
  STYPE_IPC                = "Interprocess Communication",
  STYPE_IPC_TEMPORARY      = "Interprocess Communication (temporary)",
  STYPE_IPC_HIDDEN         = "Interprocess Communication (hidden)"
}

---Marshall a <code>srvsvc_ShareType</code>. This datatype is tied to the table above with that
-- name.
--
--@param sharetype The value to marshall, as a string
--@return The marshalled integer representing the given value, or <code>nil</code> if it wasn't
--        found.
function marshall_srvsvc_ShareType(sharetype)
  local result
  stdnse.debug4("MSRPC: Entering marshall_srvsvc_ShareType()")

  result = marshall_Enum32(sharetype, srvsvc_ShareType)

  stdnse.debug4("MSRPC: Leaving marshall_srvsvc_ShareType()")
  return result
end

---Unmarshall a <code>srvsvc_ShareType</code>. This datatype is tied to the table with that name.
--
--@param data The data packet.
--@param pos  The position within the data.
--@return (pos, str) The new position, and the string representing the datatype.
function unmarshall_srvsvc_ShareType(data, pos)
  local str
  stdnse.debug4("MSRPC: Entering unmarshall_srvsvc_ShareType()")

  pos, str = unmarshall_Enum32(data, pos, srvsvc_ShareType)

  stdnse.debug4("MSRPC: Leaving unmarshall_srvsvc_ShareType()")
  return pos, str
end

---Convert a <code>srvsvc_ShareType</code> value to a string that can be shown to the user. This is
-- based on the <code>_str</code> table.
--
--@param val The string value (returned by the <code>unmarshall_</code> function) to convert.
--@return A string suitable for displaying to the user, or <code>nil</code> if it wasn't found.
function srvsvc_ShareType_tostr(val)
  local result
  stdnse.debug4("MSRPC: Entering srvsvc_ShareType_tostr()")

  result = srvsvc_ShareType_str[val]

  stdnse.debug4("MSRPC: Leaving srvsvc_ShareType_tostr()")
  return result
end

---Marshall a NetShareInfo type 0, which is just a name.
--
--<code>
--    typedef struct {
--        [string,charset(UTF16)] uint16 *name;
--    } srvsvc_NetShareInfo0;
--</code>
--
--@param location The part of the pointer wanted, either HEAD (for the data itself), BODY
--                (for nothing, since this isn't a pointer), or ALL (for the data). Generally, unless the
--                referent_id is split from the data (for example, in an array), you will want
--                ALL.
--@param name     The name to marshall.
--@return A string representing the marshalled data.
local function marshall_srvsvc_NetShareInfo0(location, name)
  local result
  stdnse.debug4("MSRPC: Entering marshall_srvsvc_NetShareInfo0()")

  result = marshall_ptr(location, marshall_unicode, {name, true}, name)

  stdnse.debug4("MSRPC: Leaving marshall_srvsvc_NetShareInfo0()")
  return result
end

---Unmarshall a NetShareInfo type 0, which is just a name. See the marshall function for more information.
--
--@param location The part of the pointer wanted, either HEAD (for the data itself), BODY
--                (for nothing, since this isn't a pointer), or ALL (for the data). Generally, unless the
--                referent_id is split from the data (for example, in an array), you will want
--                ALL.
--@param data   The data packet.
--@param pos    The position within the data.
--@param result   This is required when unmarshalling the BODY section, which always comes after
--                unmarshalling the HEAD. It is the result returned for this parameter during the
--                HEAD unmarshall. If the referent_id was '0', then this function doesn't unmarshall
--                anything.
--@return (pos, result) The new position in <code>data</code>, and a table representing the datatype.
local function unmarshall_srvsvc_NetShareInfo0(location, data, pos, result)
  stdnse.debug4("MSRPC: Entering unmarshall_srvsvc_NetShareInfo0()")
  if(result == nil) then
    result = {}
  end

  if(location == HEAD or location == ALL) then
    pos, result['name'] = unmarshall_ptr(HEAD, data, pos, unmarshall_unicode, {true})
  end

  if(location == BODY or location == ALL) then
    pos, result['name'] = unmarshall_ptr(BODY, data, pos, unmarshall_unicode, {true}, result['name'])
  end

  stdnse.debug4("MSRPC: Leaving unmarshall_srvsvc_NetShareInfo0()")
  return pos, result
end

---Marshall a NetShareInfo type 1, which is the name and a few other things.
--
--<code>
--    typedef struct {
--        [string,charset(UTF16)] uint16 *name;
--        srvsvc_ShareType type;
--        [string,charset(UTF16)] uint16 *comment;
--    } srvsvc_NetShareInfo1;
--</code>
--
--@param location  The part of the pointer wanted, either HEAD (for the data itself), BODY
--                 (for nothing, since this isn't a pointer), or ALL (for the data). Generally, unless the
--                 referent_id is split from the data (for example, in an array), you will want
--                 ALL.
--@param name      The name to marshall.
--@param sharetype The sharetype to marshall (as a string).
--@param comment   The comment to marshall.
--@return A string representing the marshalled data.
local function marshall_srvsvc_NetShareInfo1(location, name, sharetype, comment)
  local result
  stdnse.debug4("MSRPC: Entering marshall_srvsvc_NetShareInfo1()")
  local name      = marshall_ptr(location, marshall_unicode, {name, true}, name)
  local sharetype = marshall_basetype(location, marshall_srvsvc_ShareType, {sharetype})
  local comment   = marshall_ptr(location, marshall_unicode, {comment, true}, comment)

  result = name .. sharetype .. comment

  stdnse.debug4("MSRPC: Leaving marshall_srvsvc_NetShareInfo1()")
  return result
end

---Unmarshall a NetShareInfo type 1, which is a name and a couple other things. See the marshall
-- function for more information.
--
--@param location The part of the pointer wanted, either HEAD (for the data itself), BODY
--                (for nothing, since this isn't a pointer), or ALL (for the data). Generally, unless the
--                referent_id is split from the data (for example, in an array), you will want
--                ALL.
--@param data     The data packet.
--@param pos      The position within the data.
--@param result   This is required when unmarshalling the BODY section, which always comes after
--                unmarshalling the HEAD. It is the result returned for this parameter during the
--                HEAD unmarshall. If the referent_id was '0', then this function doesn't unmarshall
--                anything.
--@return (pos, result) The new position in <code>data</code>, and a table representing the datatype.
local function unmarshall_srvsvc_NetShareInfo1(location, data, pos, result)
  stdnse.debug4("MSRPC: Entering unmarshall_srvsvc_NetShareInfo1()")
  if(result == nil) then
    result = {}
  end

  if(location == HEAD or location == ALL) then
    pos, result['name']      = unmarshall_ptr(HEAD, data, pos, unmarshall_unicode, {true})
    pos, result['sharetype'] = unmarshall_srvsvc_ShareType(data, pos)
    pos, result['comment']   = unmarshall_ptr(HEAD, data, pos, unmarshall_unicode, {true})
  end

  if(location == BODY or location == ALL) then
    pos, result['name']    = unmarshall_ptr(BODY, data, pos, unmarshall_unicode, {true}, result['name'])
    pos, result['comment'] = unmarshall_ptr(BODY, data, pos, unmarshall_unicode, {true}, result['comment'])
  end

  stdnse.debug4("MSRPC: Leaving unmarshall_srvsvc_NetShareInfo1()")
  return pos, result
end


---Marshall a NetShareInfo type 2, which is the name and a few other things.
--
--<code>
--    typedef struct {
--        [string,charset(UTF16)] uint16 *name;
--        srvsvc_ShareType type;
--        [string,charset(UTF16)] uint16 *comment;
--        uint32 permissions;
--        uint32 max_users;
--        uint32 current_users;
--        [string,charset(UTF16)] uint16 *path;
--        [string,charset(UTF16)] uint16 *password;
--    } srvsvc_NetShareInfo2;
--</code>
--
--@param location      The part of the pointer wanted, either HEAD (for the data itself), BODY
--                     (for nothing, since this isn't a pointer), or ALL (for the data). Generally, unless the
--                     referent_id is split from the data (for example, in an array), you will want
--                     ALL.
--@param name          The name to marshall.
--@param sharetype     The sharetype to marshall (as a string).
--@param comment       The comment to marshall.
--@param permissions   The permissions, an integer.
--@param max_users     The max users, an integer.
--@param current_users The current users, an integer.
--@param path          The path, a string.
--@param password      The share-level password, a string (never used on Windows).
--@return A string representing the marshalled data.
local function marshall_srvsvc_NetShareInfo2(location, name, sharetype, comment, permissions, max_users, current_users, path, password)
  local result
  stdnse.debug4("MSRPC: Entering marshall_srvsvc_NetShareInfo2()")
  local name          = marshall_ptr(location, marshall_unicode, {name,    true},   name)
  local sharetype     = marshall_basetype(location, marshall_srvsvc_ShareType, {sharetype})
  local comment       = marshall_ptr(location, marshall_unicode, {comment, true},   comment)
  local permissions   = marshall_basetype(location, marshall_int32, {permissions})
  local max_users     = marshall_basetype(location, marshall_int32, {max_users})
  local current_users = marshall_basetype(location, marshall_int32, {current_users})
  local path          = marshall_ptr(location, marshall_unicode, {path, true},      path)
  local password      = marshall_ptr(location, marshall_unicode, {password, true}, password)

  result =  name .. sharetype .. comment .. permissions .. max_users .. current_users .. path .. password

  stdnse.debug4("MSRPC: Leaving marshall_srvsvc_NetShareInfo2()")
  return result
end

---Unmarshall a NetShareInfo type 2, which is a name and a few other things. See the marshall
-- function for more information.
--
--@param location The part of the pointer wanted, either HEAD (for the data itself), BODY
--                (for nothing, since this isn't a pointer), or ALL (for the data). Generally, unless the
--                referent_id is split from the data (for example, in an array), you will want
--                ALL.
--@param data     The data packet.
--@param pos      The position within the data.
--@param result   This is required when unmarshalling the BODY section, which always comes after
--                unmarshalling the HEAD. It is the result returned for this parameter during the
--                HEAD unmarshall. If the referent_id was '0', then this function doesn't unmarshall
--                anything.
--@return (pos, result) The new position in <code>data</code>, and a table representing the datatype.
local function unmarshall_srvsvc_NetShareInfo2(location, data, pos, result)
  stdnse.debug4("MSRPC: Entering unmarshall_srvsvc_NetShareInfo2()")
  if(result == nil) then
    result = {}
  end

  if(location == HEAD or location == ALL) then
    pos, result['name']          = unmarshall_ptr(HEAD, data, pos, unmarshall_unicode, {true})
    pos, result['sharetype']     = unmarshall_srvsvc_ShareType(data, pos)
    pos, result['comment']       = unmarshall_ptr(HEAD, data, pos, unmarshall_unicode, {true})
    pos, result['permissions']   = unmarshall_int32(data, pos)
    pos, result['max_users']     = unmarshall_int32(data, pos)
    pos, result['current_users'] = unmarshall_int32(data, pos)
    pos, result['path']          = unmarshall_ptr(HEAD, data, pos, unmarshall_unicode, {true})
    pos, result['password']      = unmarshall_ptr(HEAD, data, pos, unmarshall_unicode, {true})
  end

  if(location == BODY or location == ALL) then
    pos, result['name']     = unmarshall_ptr(BODY, data, pos, unmarshall_unicode, {true}, result['name'])
    pos, result['comment']  = unmarshall_ptr(BODY, data, pos, unmarshall_unicode, {true}, result['comment'])
    pos, result['path']     = unmarshall_ptr(BODY, data, pos, unmarshall_unicode, {true}, result['path'])
    pos, result['password'] = unmarshall_ptr(BODY, data, pos, unmarshall_unicode, {true}, result['password'])
  end

  stdnse.debug4("MSRPC: Leaving unmarshall_srvsvc_NetShareInfo2()")
  return pos, result
end

---Marshall a NetShareCtr (container) type 0.
--
--It is a simple array with the following definition:
--
--<code>
--     typedef struct {
--        uint32 count;
--        [size_is(count)] srvsvc_NetShareInfo0 *array;
--    } srvsvc_NetShareCtr0;
--</code>
--
--@param NetShareCtr0 A table representing the structure.
--@return A string representing the marshalled data.
function marshall_srvsvc_NetShareCtr0(NetShareCtr0)
  local i
  local result = {}
  stdnse.debug4("MSRPC: Entering marshall_srvsvc_NetShareCtr0()")

  if(NetShareCtr0 == nil) then
    result[#result+1] = string.pack("<I4", 0)
  else
    local array = NetShareCtr0['array']
    local marshall = nil

    if(array == nil) then
      result[#result+1] = string.pack("<I4", 0)
    else
      result[#result+1] = string.pack("<I4", #array) -- count

      -- Build the array that we can marshall
      marshall = {}
      for i = 1, #array, 1 do
        marshall[i] = {}
        marshall[i]['func'] = marshall_srvsvc_NetShareInfo0
        marshall[i]['args'] = {array[i]['name']}
      end
    end

    result[#result+1] = marshall_ptr(ALL, marshall_array, {marshall}, marshall) -- array
  end

  stdnse.debug4("MSRPC: Leaving marshall_srvsvc_NetShareCtr0()")
  return table.concat(result)
end

---Unmarshall a NetShareCtr (container) type 0. See the marshall function for the definition.
--
--@param data The data packet.
--@param pos  The position within the data.
--@return (pos, result) The new position in <code>data</code>, and a table representing the datatype.
function unmarshall_srvsvc_NetShareCtr0(data, pos)
  local count
  local result = {}
  stdnse.debug4("MSRPC: Entering unmarshall_srvsvc_NetShareCtr0()")

  pos, count = unmarshall_int32(data, pos)

  pos, result['array'] = unmarshall_ptr(ALL, data, pos, unmarshall_array, {count, unmarshall_srvsvc_NetShareInfo0, {}})

  stdnse.debug4("MSRPC: Leaving unmarshall_srvsvc_NetShareCtr0()")
  return pos, result
end

---Marshall a NetShareCtr (container) type 1.
--
--It is a simple array with the following definition:
--
--<code>
--    typedef struct {
--        uint32 count;
--        [size_is(count)] srvsvc_NetShareInfo1 *array;
--    } srvsvc_NetShareCtr1;
--</code>
--
--@param NetShareCtr1 A table representing the structure.
--@return A string representing the marshalled data.
function marshall_srvsvc_NetShareCtr1(NetShareCtr1)
  local i
  local result = {}
  stdnse.debug4("MSRPC: Entering marshall_srvsvc_NetShareCtr1()")

  if(NetShareCtr1 == nil) then
    result[#result+1] = string.pack("<I4", 0)
  else
    local array = NetShareCtr1['array']
    local marshall = nil

    if(array == nil) then
      result[#result+1] = string.pack("<I4", 0)
    else
      result[#result+1] = string.pack("<I4", #array) -- count

      -- Build the array that we can marshall
      marshall = {}
      for i = 1, #array, 1 do
        marshall[i] = {}
        marshall[i]['func'] = marshall_srvsvc_NetShareInfo1
        marshall[i]['args'] = {array[i]['name'], array[i]['sharetype'], array[i]['comment']}
      end
    end

    result[#result+1] = marshall_ptr(ALL, marshall_array, {marshall}, marshall) -- array
  end

  stdnse.debug4("MSRPC: Leaving marshall_srvsvc_NetShareCtr1()")
  return table.concat(result)
end


---Marshall a NetShareCtr (container) type 2.
--
--It is a simple array with the following definition:
--
--<code>
--    typedef struct {
--        uint32 count;
--        [size_is(count)] srvsvc_NetShareInfo2 *array;
--    } srvsvc_NetShareCtr2;
--</code>
--
--@param NetShareCtr2 A pointer to the structure.
--@return A string representing the marshalled data.
function marshall_srvsvc_NetShareCtr2(NetShareCtr2)
  local i
  local result = {}
  stdnse.debug4("MSRPC: Entering marshall_srvsvc_NetShareCtr2()")

  if(NetShareCtr2 == nil) then
    result[#result+1] = string.pack("<I4", 0)
  else
    local array = NetShareCtr2['array']
    local marshall = nil

    if(array == nil) then
      result[#result+1] = string.pack("<I4", 0)
    else
      result[#result+1] = string.pack("<I4", #array) -- count

      -- Build the array that we can marshall
      marshall = {}
      for i = 1, #array, 1 do
        marshall[i] = {}
        marshall[i]['func'] = marshall_srvsvc_NetShareInfo2
        marshall[i]['args'] = {array[i]['name'], array[i]['sharetype'], array[i]['comment'], array[i]['permissions'], array[i]['max_users'], array[i]['current_users'], array[i]['path'], array[i]['password']}
        marshall[i]['args'] = {array[i]['name']}
      end
    end

    result[#result+1] = marshall_ptr(ALL, marshall_array, {marshall}, marshall) -- array
  end

  stdnse.debug4("MSRPC: Leaving marshall_srvsvc_NetShareCtr2()")
  return table.concat(result)
end

---Marshall the top-level NetShareCtr. This is a union of a bunch of different containers:
--
--<code>
--    typedef union {
--        [case(0)] srvsvc_NetShareCtr0 *ctr0;
--        [case(1)] srvsvc_NetShareCtr1 *ctr1;
--        [case(2)] srvsvc_NetShareCtr2 *ctr2;
--        [case(501)] srvsvc_NetShareCtr501 *ctr501;
--        [case(502)] srvsvc_NetShareCtr502 *ctr502;
--        [case(1004)] srvsvc_NetShareCtr1004 *ctr1004;
--        [case(1005)] srvsvc_NetShareCtr1005 *ctr1005;
--        [case(1006)] srvsvc_NetShareCtr1006 *ctr1006;
--        [case(1007)] srvsvc_NetShareCtr1007 *ctr1007;
--        [case(1501)] srvsvc_NetShareCtr1501 *ctr1501;
--        [default] ;
--    } srvsvc_NetShareCtr;
--</code>
--
-- Not all of them are implemented, however; look at the code to see which are implemented (at the
-- time of this writing, it's 0, 1, and 2).
--
--@param level The level to request. Different levels will return different results, but also require
--             different access levels to call.
--@param data  The data to populate the array with. Depending on the level, this data will be different.
--             For level 0, you'll probably want a table containing array=nil.
--@return A string representing the marshalled data, or 'nil' if it couldn't be marshalled.
function marshall_srvsvc_NetShareCtr(level, data)
  stdnse.debug4("MSRPC: Entering marshall_srvsvc_NetShareCtr()")

  local marshaller
  if(level == 0) then
    marshaller = marshall_srvsvc_NetShareCtr0
  elseif(level == 1) then
    marshaller = marshall_srvsvc_NetShareCtr1
  elseif(level == 2) then
    marshaller = marshall_srvsvc_NetShareCtr2
  else
    stdnse.debug1("MSRPC: ERROR: Script requested an unknown level for srvsvc_NetShareCtr: %d", level)
    return nil
  end
  local result = string.pack("<I4", level) .. marshall_ptr(ALL, marshaller, {data}, data)

  stdnse.debug4("MSRPC: Leaving marshall_srvsvc_NetShareCtr()")
  return result
end

---Unmarshall the top-level NetShareCtr. This is a union of a bunch of containers, see the equivalent
-- marshall function for more information; at the time of this writing I've only implemented level = 0.
--
--@param data The data packet.
--@param pos  The position within the data.
--@return (pos, result) The new position in <code>data</code>, and a table representing the datatype.
--        The result may be <code>nil</code> if there's an error.
function unmarshall_srvsvc_NetShareCtr(data, pos)
  local level
  local result
  stdnse.debug4("MSRPC: Entering unmarshall_srv_NetShareCtr()")

  pos, level = unmarshall_int32(data, pos)

  if(level == 0) then
    pos, result = unmarshall_ptr(ALL, data, pos, unmarshall_srvsvc_NetShareCtr0, {})
  else
    stdnse.debug1("MSRPC: ERROR: Server returned an unknown level for srvsvc_NetShareCtr: %d", level)
    pos, result = nil, nil
  end

  stdnse.debug4("MSRPC: Leaving unmarshall_srv_NetShareCtr()")
  return pos, result
end

---Unmarshall the top-level NetShareInfo. This is a union of a bunch of different structs:
--
--<code>
--    typedef union {
--        [case(0)] srvsvc_NetShareInfo0 *info0;
--        [case(1)] srvsvc_NetShareInfo1 *info1;
--        [case(2)] srvsvc_NetShareInfo2 *info2;
--        [case(501)] srvsvc_NetShareInfo501 *info501;
--        [case(502)] srvsvc_NetShareInfo502 *info502;
--        [case(1004)] srvsvc_NetShareInfo1004 *info1004;
--        [case(1005)] srvsvc_NetShareInfo1005 *info1005;
--        [case(1006)] srvsvc_NetShareInfo1006 *info1006;
--        [case(1007)] srvsvc_NetShareInfo1007 *info1007;
--        [case(1501)] sec_desc_buf *info1501;
--        [default] ;
--    } srvsvc_NetShareInfo;
--</code>
--
-- Not all of them are implemented, however; look at the code to see which are implemented (at the
-- time of this writing, it's 0, 1, and 2).
--
--@param data     The data being processed.
--@param pos      The position within <code>data</code>.
--@return (pos, result) The new position in <code>data</code>, and a table representing the datatype. This may be
--                <code>nil</code> if there was an error.
function unmarshall_srvsvc_NetShareInfo(data, pos)
  local level
  local result
  stdnse.debug4("MSRPC: Entering unmarshall_srvsvc_NetShareInfo()")
  pos, level = unmarshall_int32(data, pos)

  if(level == 0) then
    pos, result = unmarshall_ptr(ALL, data, pos, unmarshall_struct, {unmarshall_srvsvc_NetShareInfo0, {}})
  elseif(level == 1) then
    pos, result = unmarshall_ptr(ALL, data, pos, unmarshall_struct, {unmarshall_srvsvc_NetShareInfo1, {}})
  elseif(level == 2) then
    pos, result = unmarshall_ptr(ALL, data, pos, unmarshall_struct, {unmarshall_srvsvc_NetShareInfo2, {}})
  else
    stdnse.debug1("MSRPC: ERROR: Invalid level returned by NetShareInfo: %d\n", level)
    pos, result = nil, nil
  end

  stdnse.debug4("MSRPC: Leaving unmarshall_srvsvc_NetShareInfo()")
  return pos, result
end

---Marshall a NetSessInfo type 10.
--
--<code>
--    typedef struct {
--        [string,charset(UTF16)] uint16 *client;
--        [string,charset(UTF16)] uint16 *user;
--        uint32 time;
--        uint32 idle_time;
--    } srvsvc_NetSessInfo10;
--</code>
--
--@param location  The part of the pointer wanted, either HEAD (for the data itself), BODY
--                 (for nothing, since this isn't a pointer), or ALL (for the data). Generally, unless the
--                 referent_id is split from the data (for example, in an array), you will want
--                 ALL.
--@param client    The client string.
--@param user      The user string.
--@param time      The number of seconds that the user has been logged on.
--@param idle_time The number of seconds that the user's been idle.
--@return A string representing the marshalled data.
local function marshall_srvsvc_NetSessInfo10(location, client, user, time, idle_time)
  local result
  stdnse.debug4("MSRPC: Entering marshall_srvsvc_NetShareInfo10()")
  local client    = marshall_ptr(location, marshall_unicode, {client, true}, client)
  local user      = marshall_ptr(location, marshall_unicode, {user, true}, user)
  local time      = marshall_basetype(location, marshall_int32, {time})
  local idle_time = marshall_basetype(location, marshall_int32, {idle_time})

  result = client .. user .. time .. idle_time

  stdnse.debug4("MSRPC: Leaving marshall_srvsvc_NetShareInfo10()")
  return result
end

---Unmarshall a NetSessInfo type 10. For more information, see the marshall function.
--
--@param location  The part of the pointer wanted, either HEAD (for the data itself), BODY
--                 (for nothing, since this isn't a pointer), or ALL (for the data). Generally, unless the
--                 referent_id is split from the data (for example, in an array), you will want
--                 ALL.
--@param data   The data packet.
--@param pos    The position within the data.
--@param result   This is required when unmarshalling the BODY section, which always comes after
--                unmarshalling the HEAD. It is the result returned for this parameter during the
--                HEAD unmarshall. If the referent_id was '0', then this function doesn't unmarshall
--                anything.
--@return (pos, result) The new position in <code>data</code>, and a table representing the datatype.
local function unmarshall_srvsvc_NetSessInfo10(location, data, pos, result)
  stdnse.debug4("MSRPC: Entering unmarshall_srvsvc_NetSessInfo10()")
  if(result == nil) then
    result = {}
  end

  if(location == HEAD or location == ALL) then
    pos, result['client']    = unmarshall_ptr(HEAD, data, pos, unmarshall_unicode, {true})
    pos, result['user']      = unmarshall_ptr(HEAD, data, pos, unmarshall_unicode, {true})
    pos, result['time']      = unmarshall_int32(data, pos)
    pos, result['idle_time'] = unmarshall_int32(data, pos)
  end

  if(location == BODY or location == ALL) then
    pos, result['client'] = unmarshall_ptr(BODY, data, pos, unmarshall_unicode, {true}, result['client'])
    pos, result['user']   = unmarshall_ptr(BODY, data, pos, unmarshall_unicode, {true}, result['user'])
  end

  stdnse.debug4("MSRPC: Leaving unmarshall_srvsvc_NetSessInfo10()")
  return pos, result
end

---Marshall a NetSessCtr (session container) type 10.
--
--It is a simple array with the following definition:
--
--<code>
--    typedef struct {
--        uint32 count;
--        [size_is(count)] srvsvc_NetSessInfo10 *array;
--    } srvsvc_NetSessCtr10;
--</code>
--
--@param NetSessCtr10 A table representing the structure.
--@return A string representing the marshalled data.
function marshall_srvsvc_NetSessCtr10(NetSessCtr10)
  local i
  local result = {}
  stdnse.debug4("MSRPC: Entering marshall_srvsvc_NetSessCtr10()")

  if(NetSessCtr10 == nil) then
    result[#result+1] = string.pack("<I4", 0)
  else
    local array = NetSessCtr10['array']
    local marshall = nil

    if(array == nil) then
      result[#result+1] = string.pack("<I4", 0)
    else
      result[#result+1] = string.pack("<I4", #array) -- count

      -- Build the array that we can marshall
      marshall = {}
      for i = 1, #array, 1 do
        marshall[i] = {}
        marshall[i]['func'] = marshall_srvsvc_NetSessInfo10
        marshall[i]['args'] = {array[i]['client'], array[i]['user'], array[i]['time'], array[i]['idle_time']}
      end
    end

    result[#result+1] = marshall_ptr(ALL, marshall_array, {marshall}, marshall) -- array
  end

  stdnse.debug4("MSRPC: Leaving marshall_srvsvc_NetSessCtr10()")
  return table.concat(result)
end

---Unmarshall a NetSessCtr (session container) type 10. See the marshall function for the definition.
--
--@param data The data packet.
--@param pos  The position within the data.
--@return (pos, result) The new position in <code>data</code>, and a table representing the datatype.
function unmarshall_srvsvc_NetSessCtr10(data, pos)
  local count
  local result = {}
  stdnse.debug4("MSRPC: Entering unmarshall_srvsvc_NetSessCtr10()")

  pos, count = unmarshall_int32(data, pos)

  pos, result['array'] = unmarshall_ptr(ALL, data, pos, unmarshall_array, {count, unmarshall_srvsvc_NetSessInfo10, {}})

  stdnse.debug4("MSRPC: Leaving unmarshall_srvsvc_NetSessCtr10()")
  return pos, result
end

---Marshall the top-level NetShareCtr. This is a union of a bunch of different containers:
--
--<code>
--    typedef union {
--        [case(0)] srvsvc_NetSessCtr0 *ctr0;
--        [case(1)] srvsvc_NetSessCtr1 *ctr1;
--        [case(2)] srvsvc_NetSessCtr2 *ctr2;
--        [case(10)] srvsvc_NetSessCtr10 *ctr10;
--        [case(502)] srvsvc_NetSessCtr502 *ctr502;
--        [default] ;
--    } srvsvc_NetSessCtr;
--</code>
--
-- Not all of them are implemented, however; look at the code to see which are implemented (at the
-- time of this writing, it's just 10).
--
--@param level The level to request. Different levels will return different results, but also require
--             different access levels to call.
--@param data  The data to populate the array with. Depending on the level, this data will be different.
--@return A string representing the marshalled data.
function marshall_srvsvc_NetSessCtr(level, data)
  local result
  stdnse.debug4("MSRPC: Entering marshall_srvsvc_NetShareCtr()")

  if(level == 10) then
    result = string.pack("<I4", level) .. marshall_ptr(ALL, marshall_srvsvc_NetSessCtr10, {data}, data)
  else
    stdnse.debug1("MSRPC: ERROR: Script requested an unknown level for srvsvc_NetSessCtr")
    result = nil
  end

  stdnse.debug4("MSRPC: Leaving marshall_srvsvc_NetShareCtr()")
  return result
end

---Unmarshall the top-level NetShareCtr. This is a union; see the marshall function for more information.
--
--@param data     The data being processed.
--@param pos      The position within <code>data</code>
--@return (pos, result) The new position in <code>data</code>, and a table representing the datatype. Can be
--                <code>nil</code> if there's an error.
function unmarshall_srvsvc_NetSessCtr(data, pos)
  local level
  local result
  stdnse.debug4("MSRPC: Entering unmarshall_srvsvc_NetSessCtr()")

  level, pos = string.unpack("<I4", data, pos)

  if(level == 10) then
    pos, result = unmarshall_ptr(ALL, data, pos, unmarshall_srvsvc_NetSessCtr10, {})
  else
    stdnse.debug1("MSRPC: ERROR: Invalid level returned by NetSessCtr: %d\n", level)
    pos, result = nil, nil
  end

  stdnse.debug4("MSRPC: Leaving unmarshall_srvsvc_NetSessCtr()")
  return pos, result
end


---Unmarshall a <code>srvsvc_Statistics</code> packet. This is basically a great big struct:
--
--<code>
--    typedef struct {
--        uint32 start;
--        uint32 fopens;
--        uint32 devopens;
--        uint32 jobsqueued;
--        uint32 sopens;
--        uint32 stimeouts;
--        uint32 serrorout;
--        uint32 pwerrors;
--        uint32 permerrors;
--        uint32 syserrors;
--        uint32 bytessent_low;
--        uint32 bytessent_high;
--        uint32 bytesrcvd_low;
--        uint32 bytesrcvd_high;
--        uint32 avresponse;
--        uint32 reqbufneed;
--        uint32 bigbufneed;
--    } srvsvc_Statistics;
--</code>
--
-- Note that Wireshark (at least, the version I'm using, 1.0.3) gets this wrong, so be careful.
--
--@param data     The data being processed.
--@param pos      The position within <code>data</code>
--@return (pos, result) The new position in <code>data</code>, and a table representing the datatype.
function unmarshall_srvsvc_Statistics(data, pos)
  local response = {}
  stdnse.debug4("MSRPC: Entering unmarshall_srvsvc_Statistics()")

  pos, response['start']          = unmarshall_int32(data, pos)
  pos, response['fopens']         = unmarshall_int32(data, pos)
  pos, response['devopens']       = unmarshall_int32(data, pos)
  pos, response['jobsqueued']     = unmarshall_int32(data, pos)
  pos, response['sopens']         = unmarshall_int32(data, pos)
  pos, response['stimeouts']      = unmarshall_int32(data, pos)
  pos, response['serrorout']      = unmarshall_int32(data, pos)
  pos, response['pwerrors']       = unmarshall_int32(data, pos)
  pos, response['permerrors']     = unmarshall_int32(data, pos)
  pos, response['syserrors']      = unmarshall_int32(data, pos)
  pos, response['bytessent_low']  = unmarshall_int32(data, pos)
  pos, response['bytessent_high'] = unmarshall_int32(data, pos)
  pos, response['bytesrcvd_low']  = unmarshall_int32(data, pos)
  pos, response['bytesrcvd_high'] = unmarshall_int32(data, pos)
  pos, response['avresponse']     = unmarshall_int32(data, pos)
  pos, response['reqbufneed']     = unmarshall_int32(data, pos)
  pos, response['bigbufneed']     = unmarshall_int32(data, pos)

  stdnse.debug4("MSRPC: Leaving unmarshall_srvsvc_Statistics()")
  return pos, response
end

---Unmarshalls a <code>srvsvc_Statistics</code> as a pointer. Wireshark fails to do this, and ends
-- up parsing the packet wrong, so take care when packetlogging.
--
-- See <code>unmarshall_srvsvc_Statistics</code> for more information.
--
--@param data     The data being processed.
--@param pos      The position within <code>data</code>
--@return (pos, result) The new position in <code>data</code>, and a table representing the datatype.
function unmarshall_srvsvc_Statistics_ptr(data, pos)
  local result
  stdnse.debug4("MSRPC: Entering unmarshall_srvsvc_Statistics_ptr()")

  pos, result = unmarshall_ptr(ALL, data, pos, unmarshall_srvsvc_Statistics, {})

  stdnse.debug4("MSRPC: Leaving unmarshall_srvsvc_Statistics_ptr()")
  return pos, result
end



----------------------------------
--       SAMR
-- (dependencies: MISC, LSA, SECURITY)
----------------------------------

local samr_ConnectAccessMask =
{
  SAMR_ACCESS_CONNECT_TO_SERVER   = 0x00000001,
  SAMR_ACCESS_SHUTDOWN_SERVER     = 0x00000002,
  SAMR_ACCESS_INITIALIZE_SERVER   = 0x00000004,
  SAMR_ACCESS_CREATE_DOMAIN       = 0x00000008,
  SAMR_ACCESS_ENUM_DOMAINS        = 0x00000010,
  SAMR_ACCESS_OPEN_DOMAIN         = 0x00000020
}
local samr_ConnectAccessMask_str =
{
  SAMR_ACCESS_CONNECT_TO_SERVER   = "Connect to server",
  SAMR_ACCESS_SHUTDOWN_SERVER     = "Shutdown server",
  SAMR_ACCESS_INITIALIZE_SERVER   = "Initialize server",
  SAMR_ACCESS_CREATE_DOMAIN       = "Create domain",
  SAMR_ACCESS_ENUM_DOMAINS        = "Enum domains",
  SAMR_ACCESS_OPEN_DOMAIN         = "Open domain"
}

---Marshall a <code>samr_ConnectAccessMask</code>. This datatype is tied to the table above with that
-- name.
--
--@param accessmask The value to marshall, as a string
--@return The marshalled integer representing the given value, or <code>nil</code> if it wasn't
--        found.
function marshall_samr_ConnectAccessMask(accessmask)
  local result
  stdnse.debug4("MSRPC: Entering marshall_samr_ConnectAccessMask()")

  result = marshall_Enum32(accessmask, samr_ConnectAccessMask)

  stdnse.debug4("MSRPC: Leaving marshall_samr_ConnectAccessMask()")
  return result
end

---Unmarshall a <code>samr_ConnectAccessMask</code>. This datatype is tied to the table with that name.
--
--@param data The data packet.
--@param pos  The position within the data.
--@return (pos, result) The new position in <code>data</code>, and a table representing the datatype.
function unmarshall_samr_ConnectAccessMask(data, pos)
  local result
  stdnse.debug4("MSRPC: Entering unmarshall_samr_ConnectAccessMask()")

  pos, result = unmarshall_Enum32(data, pos, samr_ConnectAccessMask)

  stdnse.debug4("MSRPC: Leaving unmarshall_samr_ConnectAccessMask()")
  return pos, result
end

---Convert a <code>samr_ConnectAccessMask</code> value to a string that can be shown to the user. This is
-- based on the <code>_str</code> table.
--
--@param val The string value (returned by the <code>unmarshall_</code> function) to convert.
--@return A string suitable for displaying to the user, or <code>nil</code> if it wasn't found.
function samr_ConnectAccessMask_tostr(val)
  local result
  stdnse.debug4("MSRPC: Entering samr_ConnectAccessMask_tostr()")

  result = samr_ConnectAccessMask_str[val]

  stdnse.debug4("MSRPC: Leaving samr_ConnectAccessMask_tostr()")
  return result
end

local samr_DomainAccessMask =
{
  DOMAIN_ACCESS_LOOKUP_INFO_1  = 0x00000001,
  DOMAIN_ACCESS_SET_INFO_1     = 0x00000002,
  DOMAIN_ACCESS_LOOKUP_INFO_2  = 0x00000004,
  DOMAIN_ACCESS_SET_INFO_2     = 0x00000008,
  DOMAIN_ACCESS_CREATE_USER    = 0x00000010,
  DOMAIN_ACCESS_CREATE_GROUP   = 0x00000020,
  DOMAIN_ACCESS_CREATE_ALIAS   = 0x00000040,
  DOMAIN_ACCESS_LOOKUP_ALIAS   = 0x00000080,
  DOMAIN_ACCESS_ENUM_ACCOUNTS  = 0x00000100,
  DOMAIN_ACCESS_OPEN_ACCOUNT   = 0x00000200,
  DOMAIN_ACCESS_SET_INFO_3     = 0x00000400
}
local samr_DomainAccessMask_str =
{
  DOMAIN_ACCESS_LOOKUP_INFO_1  = "Lookup info (1)",
  DOMAIN_ACCESS_SET_INFO_1     = "Set info (1)",
  DOMAIN_ACCESS_LOOKUP_INFO_2  = "Lookup info (2)",
  DOMAIN_ACCESS_SET_INFO_2     = "Set info (2)",
  DOMAIN_ACCESS_CREATE_USER    = "Create user",
  DOMAIN_ACCESS_CREATE_GROUP   = "Create group",
  DOMAIN_ACCESS_CREATE_ALIAS   = "Create alias",
  DOMAIN_ACCESS_LOOKUP_ALIAS   = "Lookup alias",
  DOMAIN_ACCESS_ENUM_ACCOUNTS  = "Enum accounts",
  DOMAIN_ACCESS_OPEN_ACCOUNT   = "Open account",
  DOMAIN_ACCESS_SET_INFO_3     = "Set info (3)"
}

---Marshall a <code>samr_DomainAccessMask</code>. This datatype is tied to the table above with that
-- name.
--
--@param accessmask The value to marshall, as a string
--@return The marshalled integer representing the given value, or <code>nil</code> if it wasn't
--        found.
function marshall_samr_DomainAccessMask(accessmask)
  local result
  stdnse.debug4("MSRPC: Entering marshall_samr_DomainAccessMask()")

  result = marshall_Enum32(accessmask, samr_DomainAccessMask)

  stdnse.debug4("MSRPC: Leaving marshall_samr_DomainAccessMask()")
  return result
end

---Unmarshall a <code>samr_DomainAccessMask</code>. This datatype is tied to the table with that name.
--
--@param data The data packet.
--@param pos  The position within the data.
--@return (pos, result) The new position in <code>data</code>, and a table representing the datatype.
function unmarshall_samr_DomainAccessMask(data, pos)
  local result
  stdnse.debug4("MSRPC: Entering unmarshall_samr_DomainAccessMask()")

  pos, result = unmarshall_Enum32(data, pos, samr_DomainAccessMask)

  stdnse.debug4("MSRPC: Leaving unmarshall_samr_DomainAccessMask()")
  return pos, result
end

---Convert a <code>samr_DomainAccessMask</code> value to a string that can be shown to the user. This is
-- based on the <code>_str</code> table.
--
--@param val The string value (returned by the <code>unmarshall_</code> function) to convert.
--@return A string suitable for displaying to the user, or <code>nil</code> if it wasn't found.
function samr_DomainAccessMask_tostr(val)
  local result
  stdnse.debug4("MSRPC: Entering samr_DomainAccessMask_tostr()")

  result = samr_DomainAccessMask_str[val]

  stdnse.debug4("MSRPC: Leaving samr_DomainAccessMask_tostr()")
  return result
end

local samr_AcctFlags =
{
  ACB_NONE                    = 0x0000000,
  ACB_DISABLED                = 0x00000001,  -- User account disabled
  ACB_HOMDIRREQ               = 0x00000002,  -- Home directory required
  ACB_PWNOTREQ                = 0x00000004,  -- User password not required
  ACB_TEMPDUP                 = 0x00000008,  -- Temporary duplicate account
  ACB_NORMAL                  = 0x00000010,  -- Normal user account
  ACB_MNS                     = 0x00000020,  -- MNS logon user account
  ACB_DOMTRUST                = 0x00000040,  -- Interdomain trust account
  ACB_WSTRUST                 = 0x00000080,  -- Workstation trust account
  ACB_SVRTRUST                = 0x00000100,  -- Server trust account
  ACB_PWNOEXP                 = 0x00000200,  -- User password does not expire
  ACB_AUTOLOCK                = 0x00000400,  -- Account auto locked
  ACB_ENC_TXT_PWD_ALLOWED     = 0x00000800,  -- Encryped text password is allowed
  ACB_SMARTCARD_REQUIRED      = 0x00001000,  -- Smart Card required
  ACB_TRUSTED_FOR_DELEGATION  = 0x00002000,  -- Trusted for Delegation
  ACB_NOT_DELEGATED           = 0x00004000,  -- Not delegated
  ACB_USE_DES_KEY_ONLY        = 0x00008000,  -- Use DES key only
  ACB_DONT_REQUIRE_PREAUTH    = 0x00010000,  -- Preauth not required
  ACB_PW_EXPIRED              = 0x00020000,  -- Password Expired
  ACB_NO_AUTH_DATA_REQD       = 0x00080000   -- No authorization data required
}
local samr_AcctFlags_str =
{
  ACB_NONE                    = "n/a",
  ACB_DISABLED                = "Account disabled",
  ACB_HOMDIRREQ               = "Home directory required",
  ACB_PWNOTREQ                = "Password not required",
  ACB_TEMPDUP                 = "Temporary duplicate account",
  ACB_NORMAL                  = "Normal user account",
  ACB_MNS                     = "MNS logon user account",
  ACB_DOMTRUST                = "Interdomain trust account",
  ACB_WSTRUST                 = "Workstation trust account",
  ACB_SVRTRUST                = "Server trust account",
  ACB_PWNOEXP                 = "Password does not expire",
  ACB_AUTOLOCK                = "Auto locked",
  ACB_ENC_TXT_PWD_ALLOWED     = "Encryped text password is allowed",
  ACB_SMARTCARD_REQUIRED      = "Smart Card required",
  ACB_TRUSTED_FOR_DELEGATION  = "Trusted for Delegation",
  ACB_NOT_DELEGATED           = "Not delegated",
  ACB_USE_DES_KEY_ONLY        = "Use DES key only",
  ACB_DONT_REQUIRE_PREAUTH    = "Preauth not required",
  ACB_PW_EXPIRED              = "Password Expired",
  ACB_NO_AUTH_DATA_REQD       = "No authorization data required"
}

---Marshall a <code>samr_AcctFlags</code>. This datatype is tied to the table above with that
-- name.
--
--@param flags The value to marshall, as a string
--@return The marshalled integer representing the given value, or <code>nil</code> if it wasn't
--        found.
function marshall_samr_AcctFlags(flags)
  local result
  stdnse.debug4("MSRPC: Entering marshall_samr_AcctFlags()")

  result = marshall_Enum32(flags, samr_AcctFlags)

  stdnse.debug4("MSRPC: Leaving marshall_samr_AcctFlags()")
  return result
end

---Unmarshall a <code>samr_AcctFlags</code>. This datatype is tied to the table with that name.
--
--@param data The data packet.
--@param pos  The position within the data.
--@return (pos, str) The new position, and the string representing the datatype.
function unmarshall_samr_AcctFlags(data, pos)
  local str
  stdnse.debug4("MSRPC: Entering unmarshall_samr_AcctFlags()")

  pos, str = unmarshall_Enum32_array(data, pos, samr_AcctFlags)

  stdnse.debug4("MSRPC: Leaving unmarshall_samr_AcctFlags()")
  return pos, str
end

---Convert a <code>samr_AcctFlags</code> value to a string that can be shown to the user. This is
-- based on the <code>_str</code> table.
--
--@param val The string value (returned by the <code>unmarshall_</code> function) to convert.
--@return A string suitable for displaying to the user, or <code>nil</code> if it wasn't found.
function samr_AcctFlags_tostr(val)
  local result
  stdnse.debug4("MSRPC: Entering samr_AcctFlags_tostr()")

  result = samr_AcctFlags_str[val]

  stdnse.debug4("MSRPC: Leaving samr_AcctFlags_tostr()")
  return result
end

local samr_PasswordProperties =
{
  DOMAIN_PASSWORD_COMPLEX         = 0x00000001,
  DOMAIN_PASSWORD_NO_ANON_CHANGE  = 0x00000002,
  DOMAIN_PASSWORD_NO_CLEAR_CHANGE = 0x00000004,
  DOMAIN_PASSWORD_LOCKOUT_ADMINS  = 0x00000008,
  DOMAIN_PASSWORD_STORE_CLEARTEXT = 0x00000010,
  DOMAIN_REFUSE_PASSWORD_CHANGE   = 0x00000020
}
local samr_PasswordProperties_str =
{
  DOMAIN_PASSWORD_COMPLEX         = "Complexity requirements exist",
  DOMAIN_PASSWORD_NO_ANON_CHANGE  = "Must be logged in to change password",
  DOMAIN_PASSWORD_NO_CLEAR_CHANGE = "Cannot change passwords in cleartext",
  DOMAIN_PASSWORD_LOCKOUT_ADMINS  = "Admin account can be locked out",
  DOMAIN_PASSWORD_STORE_CLEARTEXT = "Cleartext passwords can be stored",
  DOMAIN_REFUSE_PASSWORD_CHANGE   = "Passwords cannot be changed"
}

---Marshall a <code>samr_PasswordProperties</code>. This datatype is tied to the table above with that
-- name.
--
--@param properties The value to marshall, as a string
--@return The marshalled integer representing the given value, or <code>nil</code> if it wasn't
--        found.
function marshall_samr_PasswordProperties(properties)
  local result
  stdnse.debug4("MSRPC: Entering marshall_samr_PasswordProperties()")

  result = marshall_Enum32(properties, samr_PasswordProperties)

  stdnse.debug4("MSRPC: Leaving marshall_samr_PasswordProperties()")
  return result
end

---Unmarshall a <code>samr_PasswordProperties</code>. This datatype is tied to the table with that name.
--
--@param data The data packet.
--@param pos  The position within the data.
--@return (pos, str) The new position, and the string representing the datatype.
function unmarshall_samr_PasswordProperties(data, pos)
  local str
  stdnse.debug4("MSRPC: Entering unmarshall_samr_PasswordProperties()")

  pos, str = unmarshall_Enum32_array(data, pos, samr_PasswordProperties)

  stdnse.debug4("MSRPC: Leaving unmarshall_samr_PasswordProperties()")
  return pos, str
end

---Convert a <code>samr_PasswordProperties</code> value to a string that can be shown to the user. This is
-- based on the <code>_str</code> table.
--
--@param val The string value (returned by the <code>unmarshall_</code> function) to convert.
--@return A string suitable for displaying to the user, or <code>nil</code> if it wasn't found.
function samr_PasswordProperties_tostr(val)
  local result
  stdnse.debug4("MSRPC: Entering samr_PasswordProperties_tostr()")

  result = samr_PasswordProperties_str[val]

  stdnse.debug4("MSRPC: Leaving samr_PasswordProperties_tostr()")
  return result
end


---Unmarshall a samr_SamEntry struct
--
--<code>
--    typedef struct {
--        uint32 idx;
--        lsa_String name;
--    } samr_SamEntry;
--</code>
--
--@param location The part of the pointer wanted, either HEAD (for the data itself), BODY
--                (for nothing, since this isn't a pointer), or ALL (for the data). Generally, unless the
--                referent_id is split from the data (for example, in an array), you will want
--                ALL.
--@param data     The data being processed.
--@param pos      The position within <code>data</code>.
--@param result   This is required when unmarshalling the BODY section, which always comes after
--                unmarshalling the HEAD. It is the result returned for this parameter during the
--                HEAD unmarshall. If the referent_id was '0', then this function doesn't unmarshall
--                anything.
--@return (pos, result) The new position in <code>data</code>, and a table representing the datatype.
local function unmarshall_samr_SamEntry(location, data, pos, result)
  stdnse.debug4("MSRPC: Entering unmarshall_samr_SamEntry()")
  if(result == nil) then
    result = {}
  end

  if(location == HEAD or location == ALL) then
    pos, result['idx']       = unmarshall_int32(data, pos)
    pos, result['name']      = unmarshall_lsa_String_internal(HEAD, data, pos)
  end


  if(location == BODY or location == ALL) then
    pos, result['name']      = unmarshall_lsa_String_internal(BODY, data, pos, result['name'])
  end

  stdnse.debug4("MSRPC: Leaving unmarshall_samr_SamEntry()")
  return pos, result
end

---Unmarshall a samr_SamArray struct
--
--<code>
--    typedef struct {
--        uint32 count;
--        [size_is(count)] samr_SamEntry *entries;
--    } samr_SamArray;
--</code>
--
--@param data     The data being processed.
--@param pos      The position within <code>data</code>.
--@return (pos, result) The new position in <code>data</code>, and a table representing the datatype.
function unmarshall_samr_SamArray(data, pos)
  local result = {}
  stdnse.debug4("MSRPC: Entering unmarshall_samr_SamArray()")

  pos, result['count']   = unmarshall_int32(data, pos)
  pos, result['entries'] = unmarshall_ptr(ALL, data, pos, unmarshall_array, {result['count'], unmarshall_samr_SamEntry, {}})

  stdnse.debug4("MSRPC: Leaving unmarshall_samr_SamArray()")
  return pos, result
end

---Unmarshall a pointer to a <code>samr_SamArray</code> type. See <code>unmarshall_samr_SamArray</code> for
-- more information.
--
--@param data     The data being processed.
--@param pos      The position within <code>data</code>.
--@return (pos, result) The new position in <code>data</code>, and a table representing the datatype.
function unmarshall_samr_SamArray_ptr(data, pos)
  local result
  stdnse.debug4("MSRPC: Entering unmarshall_samr_SamArray_ptr()")

  pos, result = unmarshall_ptr(ALL, data, pos, unmarshall_samr_SamArray, {})

  stdnse.debug4("MSRPC: Leaving unmarshall_samr_SamArray_ptr()")
  return pos, result
end

---Unmarshall a samr_DispEntryGeneral struct
--
--<code>
--    typedef struct {
--        uint32    idx;
--        uint32    rid;
--        samr_AcctFlags acct_flags;
--        lsa_String account_name;
--        lsa_String description;
--        lsa_String full_name;
--    } samr_DispEntryGeneral;
--</code>
--
--@param location The part of the pointer wanted, either HEAD (for the data itself), BODY
--                (for nothing, since this isn't a pointer), or ALL (for the data). Generally, unless the
--                referent_id is split from the data (for example, in an array), you will want
--                ALL.
--@param data     The data being processed.
--@param pos      The position within <code>data</code>.
--@param result   This is required when unmarshalling the BODY section, which always comes after
--                unmarshalling the HEAD. It is the result returned for this parameter during the
--                HEAD unmarshall. If the referent_id was '0', then this function doesn't unmarshall
--                anything.
--@return (pos, result) The new position in <code>data</code>, and a table representing the datatype.
local function unmarshall_samr_DispEntryGeneral(location, data, pos, result)
  stdnse.debug4("MSRPC: Entering unmarshall_samr_DispEntryGeneral()")
  if(result == nil) then
    result = {}
  end

  if(location == HEAD or location == ALL) then
    pos, result['idx']          = unmarshall_int32(data, pos)
    pos, result['rid']          = unmarshall_int32(data, pos)
    pos, result['acct_flags']   = unmarshall_samr_AcctFlags(data, pos)
    pos, result['account_name'] = unmarshall_lsa_String_internal(HEAD, data, pos)
    pos, result['description']  = unmarshall_lsa_String_internal(HEAD, data, pos)
    pos, result['full_name']    = unmarshall_lsa_String_internal(HEAD, data, pos)
  end


  if(location == BODY or location == ALL) then
    pos, result['account_name'] = unmarshall_lsa_String_internal(BODY, data, pos, result['account_name'])
    pos, result['description']  = unmarshall_lsa_String_internal(BODY, data, pos, result['description'])
    pos, result['full_name']    = unmarshall_lsa_String_internal(BODY, data, pos, result['full_name'])
  end

  stdnse.debug4("MSRPC: Leaving unmarshall_samr_DispEntryGeneral()")
  return pos, result
end

---Unmarshall a samr_DispInfoGeneral struct
--
--<code>
--    typedef struct {
--        uint32 count;
--        [size_is(count)] samr_DispEntryGeneral *entries;
--    } samr_DispInfoGeneral;
--</code>
--
--@param data     The data being processed.
--@param pos      The position within <code>data</code>.
--@return (pos, result) The new position in <code>data</code>, and a table representing the datatype.
function unmarshall_samr_DispInfoGeneral(data, pos)
  local result = {}
  stdnse.debug4("MSRPC: Entering unmarshall_samr_DispInfoGeneral()")

  pos, result['count']   = unmarshall_int32(data, pos)
  pos, result['entries'] = unmarshall_ptr(ALL, data, pos, unmarshall_array, {result['count'], unmarshall_samr_DispEntryGeneral, {}})

  stdnse.debug4("MSRPC: Leaving unmarshall_samr_DispInfoGeneral()")
  return pos, result
end


---Unmarshall a samr_DispInfo struct
--
--<code>
--    typedef [switch_type(uint16)] union {
--        [case(1)] samr_DispInfoGeneral info1;/* users */
--        [case(2)] samr_DispInfoFull info2; /* trust accounts? */
--        [case(3)] samr_DispInfoFullGroups info3; /* groups */
--        [case(4)] samr_DispInfoAscii info4; /* users */
--        [case(5)] samr_DispInfoAscii info5; /* groups */
--    } samr_DispInfo;
--</code>
--
--@param data     The data being processed.
--@param pos      The position within <code>data</code>.
--@return (pos, result) The new position in <code>data</code>, and a table representing the datatype. It may also return
--                <code>nil</code>, if there was an error.
function unmarshall_samr_DispInfo(data, pos)
  local level
  local result
  stdnse.debug4("MSRPC: Entering unmarshall_samr_DispInfo()")

  pos, level = unmarshall_int16(data, pos)

  if(level == 1) then
    pos, result = unmarshall_samr_DispInfoGeneral(data, pos)
  else
    stdnse.debug1("MSRPC: ERROR: Server returned an unknown level for samr_DispInfo: %d", level)
    pos, result = nil, nil
  end

  stdnse.debug4("MSRPC: Leaving unmarshall_samr_DispInfo()")
  return pos, result
end

---Unmarshall a samr_DomInfo1 struct
--
--<code>
--  typedef struct {
--    uint16 min_password_length;
--    uint16 password_history_length;
--    samr_PasswordProperties password_properties;
--    /* yes, these are signed. They are in negative 100ns */
--    dlong  max_password_age;
--    dlong  min_password_age;
--  } samr_DomInfo1;
--</code>
--
--@param data     The data being processed.
--@param pos      The position within <code>data</code>.
--@return (pos, result) The new position in <code>data</code>, and a table representing the datatype.
function unmarshall_samr_DomInfo1(data, pos)
  local result = {}
  stdnse.debug4("MSRPC: Entering unmarshall_samr_DomInfo1()")

  pos, result['min_password_length']     = unmarshall_int16(data, pos, false)
  pos, result['password_history_length'] = unmarshall_int16(data, pos, false)
  pos, result['password_properties']     = unmarshall_samr_PasswordProperties(data, pos)
  pos, result['max_password_age']        = unmarshall_hyper(data, pos)
  pos, result['min_password_age']        = unmarshall_hyper(data, pos)

  stdnse.debug4("MSRPC: Leaving unmarshall_samr_DomInfo1()")
  return pos, result
end

---Unmarshall a samr_DomInfo8 struct
--
--<code>
--  typedef struct {
--    hyper sequence_num;
--    NTTIME domain_create_time;
--  } samr_DomInfo8;
--</code>
--
--@param data     The data being processed.
--@param pos      The position within <code>data</code>.
--@return (pos, result) The new position in <code>data</code>, and a table representing the datatype.
function unmarshall_samr_DomInfo8(data, pos)
  local result = {}
  stdnse.debug4("MSRPC: Entering unmarshall_samr_DomInfo8()")

  pos, result['sequence_num']       = unmarshall_hyper(data, pos)
  pos, result['domain_create_time'] = unmarshall_NTTIME(data, pos)

  stdnse.debug4("MSRPC: Leaving unmarshall_samr_DomInfo8()")
  return pos, result
end

---Unmarshall a samr_DomInfo12 struct
--
--<code>
--  typedef struct {
--    hyper lockout_duration;
--    hyper lockout_window;
--    uint16 lockout_threshold;
--  } samr_DomInfo12;
--</code>
--
--@param data     The data being processed.
--@param pos      The position within <code>data</code>.
--@return (pos, result) The new position in <code>data</code>, and a table representing the datatype.
function unmarshall_samr_DomInfo12(data, pos)
  local result = {}
  stdnse.debug4("MSRPC: Entering unmarshall_samr_DomInfo12()")

  pos, result['lockout_duration']  = unmarshall_hyper(data, pos)
  pos, result['lockout_window']    = unmarshall_hyper(data, pos)
  pos, result['lockout_threshold'] = unmarshall_int16(data, pos)

  stdnse.debug4("MSRPC: Leaving unmarshall_samr_DomInfo12()")
  return pos, result
end

---Unmarshall a samr_DomainInfo union
--
--<code>
--  typedef [switch_type(uint16)] union {
--    [case(1)] samr_DomInfo1 info1;
--    [case(2)] samr_DomInfo2 info2;
--    [case(3)] samr_DomInfo3 info3;
--    [case(4)] samr_DomInfo4 info4;
--    [case(5)] samr_DomInfo5 info5;
--    [case(6)] samr_DomInfo6 info6;
--    [case(7)] samr_DomInfo7 info7;
--    [case(8)] samr_DomInfo8 info8;
--    [case(9)] samr_DomInfo9 info9;
--    [case(11)] samr_DomInfo11 info11;
--    [case(12)] samr_DomInfo12 info12;
--    [case(13)] samr_DomInfo13 info13;
--  } samr_DomainInfo;
--</code>
--
--@param data     The data being processed.
--@param pos      The position within <code>data</code>.
--@return (pos, result) The new position in <code>data</code>, and a table representing the datatype. May return
--                <code>nil</code> if there was an error.
function unmarshall_samr_DomainInfo(data, pos)
  local level
  local result
  stdnse.debug4("MSRPC: Entering unmarshall_samr_DomainInfo()")

  pos, level = unmarshall_int16(data, pos)

  if(level == 1) then
    pos, result = unmarshall_samr_DomInfo1(data, pos)
  elseif(level == 8) then
    pos, result = unmarshall_samr_DomInfo8(data, pos)
  elseif(level == 12) then
    pos, result = unmarshall_samr_DomInfo12(data, pos)
  else
    stdnse.debug1("MSRPC: ERROR: Server returned an unknown level for samr_DomainInfo: %d", level)
    pos, result = nil, nil
  end

  stdnse.debug4("MSRPC: Leaving unmarshall_samr_DomainInfo()")
  return pos, result
end

---Unmarshall a pointer to a <code>samr_DomainInfo</code>. See <code>unmarshall_samr_DomainInfo</code> for
-- more information.
--
--@param data     The data being processed.
--@param pos      The position within <code>data</code>.
--@return (pos, result) The new position in <code>data</code>, and a table representing the datatype. May return
--                <code>nil</code> if there was an error.
function unmarshall_samr_DomainInfo_ptr(data, pos)
  local result
  stdnse.debug4("MSRPC: Entering unmarshall_samr_DomainInfo_ptr()")

  pos, result = unmarshall_ptr(ALL, data, pos, unmarshall_samr_DomainInfo, {})

  stdnse.debug4("MSRPC: Leaving unmarshall_samr_DomainInfo_ptr()")
  return pos, result
end

---Unmarshall a samr_Ids struct
--
--<code>
--    typedef struct {
--        [range(0,1024)]  uint32 count;
--        [size_is(count)] uint32 *ids;
--    } samr_Ids;
--</code>
--
--@param data     The data being processed.
--@param pos      The position within <code>data</code>.
--@return (pos, result) The new position in <code>data</code>, and a table representing the datatype. May return
--                <code>nil</code> if there was an error.
function unmarshall_samr_Ids(data, pos)
  local array

  pos, array = unmarshall_int32_array_ptr(data, pos)

  return pos, array
end

----------------------------------
--       SVCCTL
-- (dependencies: MISC)
----------------------------------

local svcctl_ControlCode =
{
  SERVICE_CONTROL_CONTINUE       = 0x00000003,
  SERVICE_CONTROL_INTERROGATE    = 0x00000004,
  SERVICE_CONTROL_NETBINDADD     = 0x00000007,
  SERVICE_CONTROL_NETBINDDISABLE = 0x0000000A,
  SERVICE_CONTROL_NETBINDENABLE  = 0x00000009,
  SERVICE_CONTROL_NETBINDREMOVE  = 0x00000008,
  SERVICE_CONTROL_PARAMCHANGE    = 0x00000006,
  SERVICE_CONTROL_PAUSE          = 0x00000002,
  SERVICE_CONTROL_STOP           = 0x00000001,
}
local svcctl_ControlCode_str =
{
  SERVICE_CONTROL_CONTINUE       = "Notifies a paused service that it should resume.",
  SERVICE_CONTROL_INTERROGATE    = "Notifies a service that it should report its current status information to the service control manager.",
  SERVICE_CONTROL_NETBINDADD     = "Notifies a network service that there is a new component for binding. Deprecated.",
  SERVICE_CONTROL_NETBINDDISABLE = "Notifies a network service that one of its bindings has been disabled. Deprecated.",
  SERVICE_CONTROL_NETBINDENABLE  = "Notifies a network service that a disabled binding has been enabled. Deprecated",
  SERVICE_CONTROL_NETBINDREMOVE  = "Notifies a network service that a component for binding has been removed. Deprecated",
  SERVICE_CONTROL_PARAMCHANGE    = "Notifies a service that its startup parameters have changed.",
  SERVICE_CONTROL_PAUSE          = "Notifies a service that it should pause.",
  SERVICE_CONTROL_STOP           = "Notifies a service that it should stop."
}


---Marshall a <code>svcctl_ControlCode</code>. This datatype is tied to the table above with that
-- name.
--
--@param flags The value to marshall, as a string
--@return The marshalled integer representing the given value, or <code>nil</code> if it wasn't
--        found.
function marshall_svcctl_ControlCode(flags)
  local result
  stdnse.debug4("MSRPC: Entering marshall_svcctl_ControlCode()")

  result = marshall_Enum32(flags, svcctl_ControlCode)

  stdnse.debug4("MSRPC: Leaving marshall_svcctl_ControlCode()")
  return result
end

---Unmarshall a <code>svcctl_ControlCode</code>. This datatype is tied to the table with that name.
--
--@param data The data packet.
--@param pos  The position within the data.
--@return (pos, str) The new position, and the string representing the datatype.
function unmarshall_svcctl_ControlCode(data, pos)
  local str
  stdnse.debug4("MSRPC: Entering unmarshall_svcctl_ControlCode()")

  pos, str = unmarshall_Enum32_array(data, pos, svcctl_ControlCode)

  stdnse.debug4("MSRPC: Leaving unmarshall_svcctl_ControlCode()")
  return pos, str
end

---Convert a <code>svcctl_ControlCode</code> value to a string that can be shown to the user. This is
-- based on the <code>_str</code> table.
--
--@param val The string value (returned by the <code>unmarshall_</code> function) to convert.
--@return A string suitable for displaying to the user, or <code>nil</code> if it wasn't found.
function svcctl_ControlCode_tostr(val)
  local result
  stdnse.debug4("MSRPC: Entering svcctl_ControlCode_tostr()")

  result = svcctl_ControlCode_str[val]

  stdnse.debug4("MSRPC: Leaving svcctl_ControlCode_tostr()")
  return result
end

local svcctl_Type =
{
  SERVICE_TYPE_KERNEL_DRIVER       = 0x01,
  SERVICE_TYPE_FS_DRIVER           = 0x02,
  SERVICE_TYPE_ADAPTER             = 0x04,
  SERVICE_TYPE_RECOGNIZER_DRIVER   = 0x08,
  SERVICE_TYPE_DRIVER              = 0x0B,
  SERVICE_TYPE_WIN32_OWN_PROCESS   = 0x10,
  SERVICE_TYPE_WIN32_SHARE_PROCESS = 0x20,
  SERVICE_TYPE_WIN32               = 0x30
}

---Marshall a <code>svcctl_Type</code>. This datatype is tied to the table above with that
-- name.
--
--@param flags The value to marshall, as a string
--@return The marshalled integer representing the given value, or <code>nil</code> if it wasn't
--        found.
function marshall_svcctl_Type(flags)
  local result
  stdnse.debug4("MSRPC: Entering marshall_svcctl_Type()")

  result = marshall_Enum32(flags, svcctl_Type)

  stdnse.debug4("MSRPC: Leaving marshall_svcctl_Type()")
  return result
end

---Unmarshall a <code>svcctl_Type</code>. This datatype is tied to the table with that name.
--
--@param data The data packet.
--@param pos  The position within the data.
--@return (pos, str) The new position, and the string representing the datatype.
function unmarshall_svcctl_Type(data, pos)
  local str
  stdnse.debug4("MSRPC: Entering unmarshall_svcctl_Type()")

  pos, str = unmarshall_Enum32_array(data, pos, svcctl_Type)

  stdnse.debug4("MSRPC: Leaving unmarshall_svcctl_Type()")
  return pos, str
end

--[[Convert a <code>svcctl_Type</code> value to a string that can be shown to the user. This is
-- based on the <code>_str</code> table.
--
--@param val The string value (returned by the <code>unmarshall_</code> function) to convert.
--@return A string suitable for displaying to the user, or <code>nil</code> if it wasn't found.
function svcctl_Type_tostr(val)
  local result
  stdnse.debug4("MSRPC: Entering svcctl_Type_tostr()")

  result = svcctl_Type_str[val]

  stdnse.debug4("MSRPC: Leaving svcctl_Type_tostr()")
  return result
end]]--



local svcctl_State =
{
  SERVICE_STOPPED          = 0x01,
  SERVICE_START_PENDING    = 0x02,
  SERVICE_STOP_PENDING     = 0x03,
  SERVICE_RUNNING          = 0x04,
  SERVICE_CONTINUE_PENDING = 0x05,
  SERVICE_PAUSE_PENDING    = 0x06,
  SERVICE_PAUSED           = 0x07,
}

---Marshall a <code>svcctl_State</code>. This datatype is tied to the table above with that
-- name.
--
--@param flags The value to marshall, as a string
--@return The marshalled integer representing the given value, or <code>nil</code> if it wasn't
--        found.
function marshall_svcctl_State(flags)
  local result
  stdnse.debug4("MSRPC: Entering marshall_svcctl_State()")

  result = marshall_Enum32(flags, svcctl_State)

  stdnse.debug4("MSRPC: Leaving marshall_svcctl_State()")
  return result
end

---Unmarshall a <code>svcctl_State</code>. This datatype is tied to the table with that name.
--
--@param data The data packet.
--@param pos  The position within the data.
--@return (pos, str) The new position, and the string representing the datatype.
function unmarshall_svcctl_State(data, pos)
  local str
  stdnse.debug4("MSRPC: Entering unmarshall_svcctl_State()")

  pos, str = unmarshall_Enum32_array(data, pos, svcctl_State)

  stdnse.debug4("MSRPC: Leaving unmarshall_svcctl_State()")
  return pos, str
end

--[[Convert a <code>svcctl_State</code> value to a string that can be shown to the user. This is
-- based on the <code>_str</code> table.
--
--@param val The string value (returned by the <code>unmarshall_</code> function) to convert.
--@return A string suitable for displaying to the user, or <code>nil</code> if it wasn't found.
function svcctl_State_tostr(val)
  local result
  stdnse.debug4("MSRPC: Entering svcctl_State_tostr()")

  result = svcctl_State_str[val]

  stdnse.debug4("MSRPC: Leaving svcctl_State_tostr()")
  return result
end]]--


---Unmarshall a SERVICE_STATUS struct, converting it to a table.
--
-- The structure is as follows:
--
-- <code>
--    typedef struct {
--        uint32 type;
--        uint32 state;
--        uint32 controls_accepted;
--        WERROR win32_exit_code;
--        uint32 service_exit_code;
--        uint32 check_point;
--        uint32 wait_hint;
--    } SERVICE_STATUS;
-- </code>
--
--@param data The data packet.
--@param pos  The position within the data.
--@return (pos, table) The new position, and the table of values.
function unmarshall_SERVICE_STATUS(data, pos)
  local result = {}

  pos, result['type']              = unmarshall_svcctl_Type(data, pos)
  pos, result['state']             = unmarshall_svcctl_State(data, pos)
  pos, result['controls_accepted'] = unmarshall_svcctl_ControlCode(data, pos)
  pos, result['win32_exit_code']   = unmarshall_int32(data, pos)
  pos, result['service_exit_code'] = unmarshall_int32(data, pos)
  pos, result['check_point']       = unmarshall_int32(data, pos)
  pos, result['wait_hint']         = unmarshall_int32(data, pos)

  return pos, result
end


--- Unmarshalls a null-terminated Unicode string (LPTSTR datatype)
-- @param w_str     The data being processed
-- @param startpos  The current position within the data
-- @return The new position
-- @return The unmarshalled string
function unmarshall_lptstr(w_str, startpos)

  local _
  local endpos = startpos

  repeat
    _, endpos = w_str:find("\0\0", endpos, true)
    if not endpos then
      return
    end
  until endpos % 2 == 0

  return endpos + 1, w_str:sub(startpos, endpos)

end

local atsvc_DaysOfMonth =
{
  First           =       0x00000001,
  Second          =       0x00000002,
  Third           =       0x00000004,
  Fourth          =       0x00000008,
  Fifth           =       0x00000010,
  Sixth           =       0x00000020,
  Seventh         =       0x00000040,
  Eighth          =       0x00000080,
  Ninth           =       0x00000100,
  Tenth           =       0x00000200,
  Eleventh        =       0x00000400,
  Twelfth         =       0x00000800,
  Thirteenth      =       0x00001000,
  Fourteenth      =       0x00002000,
  Fifteenth       =       0x00004000,
  Sixteenth       =       0x00008000,
  Seventeenth     =       0x00010000,
  Eighteenth      =       0x00020000,
  Ninteenth       =       0x00040000,
  Twentieth       =       0x00080000,
  Twentyfirst     =       0x00100000,
  Twentysecond    =       0x00200000,
  Twentythird     =       0x00400000,
  Twentyfourth    =       0x00800000,
  Twentyfifth     =       0x01000000,
  Twentysixth     =       0x02000000,
  Twentyseventh   =       0x04000000,
  Twentyeighth    =       0x08000000,
  Twentyninth     =       0x10000000,
  Thirtieth       =       0x20000000,
  Thirtyfirst     =       0x40000000
}

---Marshall a <code>atsvc_DaysOfMonth</code>. This datatype is tied to the table above with that
-- name.
--
--@param flags The value to marshall, as a string
--@return The marshalled integer representing the given value, or <code>nil</code> if it wasn't
--        found.
function marshall_atsvc_DaysOfMonth(flags)
  local result
  stdnse.debug4("MSRPC: Entering marshall_atsvc_DaysOfMonth()")

  result = marshall_Enum32(flags, atsvc_DaysOfMonth)

  stdnse.debug4("MSRPC: Leaving marshall_atsvc_DaysOfMonth()")
  return result
end


local atsvc_Flags =
{
  JOB_RUN_PERIODICALLY    = 0x01,
  JOB_EXEC_ERROR          = 0x02,
  JOB_RUNS_TODAY          = 0x04,
  JOB_ADD_CURRENT_DATE    = 0x08,
  JOB_NONINTERACTIVE      = 0x10
}
---Marshall a <code>atsvc_Flags</code>. This datatype is tied to the table above with that
-- name.
--
--@param flags The value to marshall, as a string
--@return The marshalled integer representing the given value, or <code>nil</code> if it wasn't
--        found.
function marshall_atsvc_Flags(flags)
  local result
  stdnse.debug4("MSRPC: Entering marshall_atsvc_Flags()")

  result = marshall_Enum8(flags, atsvc_Flags, false)

  stdnse.debug4("MSRPC: Leaving marshall_atsvc_Flags()")
  return result
end


local atsvc_DaysOfWeek =
{
  DAYSOFWEEK_MONDAY    = 0x01,
  DAYSOFWEEK_TUESDAY   = 0x02,
  DAYSOFWEEK_WEDNESDAY = 0x04,
  DAYSOFWEEK_THURSDAY  = 0x08,
  DAYSOFWEEK_FRIDAY    = 0x10,
  DAYSOFWEEK_SATURDAY  = 0x20,
  DAYSOFWEEK_SUNDAY    = 0x40
}
---Marshall a <code>atsvc_DaysOfWeek</code>. This datatype is tied to the table above with that
-- name.
--
--@param flags The value to marshall, as a string
--@return The marshalled integer representing the given value, or <code>nil</code> if it wasn't
--        found.
function marshall_atsvc_DaysOfWeek(flags)
  local result
  stdnse.debug4("MSRPC: Entering marshall_atsvc_DaysOfWeek()")

  result = marshall_Enum8(flags, atsvc_DaysOfWeek, false)

  stdnse.debug4("MSRPC: Leaving marshall_atsvc_DaysOfWeek()")
  return result
end

---Marshall a JobInfo struct.
--
--The structure is as follows:
--
--<code>
--    typedef struct {
--        uint32 job_time;
--        atsvc_DaysOfMonth days_of_month;
--        atsvc_DaysOfWeek days_of_week;
--        atsvc_Flags flags;
--        [string,charset(UTF16)] uint16 *command;
--    } atsvc_JobInfo;
--</code>
--
--@param command The command to run. This has to be just the command, no parameters; if a
--               program requires parameters, then the best way to run it is through a batch
--               file.
--@param time The time at which to run the job, in milliseconds from midnight.
function marshall_atsvc_JobInfo(command, time)
  local result = marshall_int32(time)                       -- Job time
  .. marshall_int32(0)                          -- Day of month
  .. marshall_int8(0, false)                    -- Day of week
  .. marshall_atsvc_Flags("JOB_NONINTERACTIVE") -- Flags
  .. marshall_int16(0, false)                   -- Padding
  .. marshall_unicode_ptr(command, true)        -- Command

  return result
end




return _ENV;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       /*
 * WARNING: do not edit!
 * Generated by Makefile from include/openssl/x509.h.in
 *
 * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */



#ifndef OPENSSL_X509_H
# define OPENSSL_X509_H
# pragma once

# include <openssl/macros.h>
# ifndef OPENSSL_NO_DEPRECATED_3_0
#  define HEADER_X509_H
# endif

# include <openssl/e_os2.h>
# include <openssl/types.h>
# include <openssl/symhacks.h>
# include <openssl/buffer.h>
# include <openssl/evp.h>
# include <openssl/bio.h>
# include <openssl/asn1.h>
# include <openssl/safestack.h>
# include <openssl/ec.h>

# ifndef OPENSSL_NO_DEPRECATED_1_1_0
#  include <openssl/rsa.h>
#  include <openssl/dsa.h>
#  include <openssl/dh.h>
# endif

# include <openssl/sha.h>
# include <openssl/x509err.h>

#ifdef  __cplusplus
extern "C" {
#endif

/* Needed stacks for types defined in other headers */
SKM_DEFINE_STACK_OF_INTERNAL(X509_NAME, X509_NAME, X509_NAME)
#define sk_X509_NAME_num(sk) OPENSSL_sk_num(ossl_check_const_X509_NAME_sk_type(sk))
#define sk_X509_NAME_value(sk, idx) ((X509_NAME *)OPENSSL_sk_value(ossl_check_const_X509_NAME_sk_type(sk), (idx)))
#define sk_X509_NAME_new(cmp) ((STACK_OF(X509_NAME) *)OPENSSL_sk_new(ossl_check_X509_NAME_compfunc_type(cmp)))
#define sk_X509_NAME_new_null() ((STACK_OF(X509_NAME) *)OPENSSL_sk_new_null())
#define sk_X509_NAME_new_reserve(cmp, n) ((STACK_OF(X509_NAME) *)OPENSSL_sk_new_reserve(ossl_check_X509_NAME_compfunc_type(cmp), (n)))
#define sk_X509_NAME_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_X509_NAME_sk_type(sk), (n))
#define sk_X509_NAME_free(sk) OPENSSL_sk_free(ossl_check_X509_NAME_sk_type(sk))
#define sk_X509_NAME_zero(sk) OPENSSL_sk_zero(ossl_check_X509_NAME_sk_type(sk))
#define sk_X509_NAME_delete(sk, i) ((X509_NAME *)OPENSSL_sk_delete(ossl_check_X509_NAME_sk_type(sk), (i)))
#define sk_X509_NAME_delete_ptr(sk, ptr) ((X509_NAME *)OPENSSL_sk_delete_ptr(ossl_check_X509_NAME_sk_type(sk), ossl_check_X509_NAME_type(ptr)))
#define sk_X509_NAME_push(sk, ptr) OPENSSL_sk_push(ossl_check_X509_NAME_sk_type(sk), ossl_check_X509_NAME_type(ptr))
#define sk_X509_NAME_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_X509_NAME_sk_type(sk), ossl_check_X509_NAME_type(ptr))
#define sk_X509_NAME_pop(sk) ((X509_NAME *)OPENSSL_sk_pop(ossl_check_X509_NAME_sk_type(sk)))
#define sk_X509_NAME_shift(sk) ((X509_NAME *)OPENSSL_sk_shift(ossl_check_X509_NAME_sk_type(sk)))
#define sk_X509_NAME_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_X509_NAME_sk_type(sk),ossl_check_X509_NAME_freefunc_type(freefunc))
#define sk_X509_NAME_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_X509_NAME_sk_type(sk), ossl_check_X509_NAME_type(ptr), (idx))
#define sk_X509_NAME_set(sk, idx, ptr) ((X509_NAME *)OPENSSL_sk_set(ossl_check_X509_NAME_sk_type(sk), (idx), ossl_check_X509_NAME_type(ptr)))
#define sk_X509_NAME_find(sk, ptr) OPENSSL_sk_find(ossl_check_X509_NAME_sk_type(sk), ossl_check_X509_NAME_type(ptr))
#define sk_X509_NAME_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_X509_NAME_sk_type(sk), ossl_check_X509_NAME_type(ptr))
#define sk_X509_NAME_find_all(sk, ptr, pnum) OPENSSL_sk_find_all(ossl_check_X509_NAME_sk_type(sk), ossl_check_X509_NAME_type(ptr), pnum)
#define sk_X509_NAME_sort(sk) OPENSSL_sk_sort(ossl_check_X509_NAME_sk_type(sk))
#define sk_X509_NAME_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_X509_NAME_sk_type(sk))
#define sk_X509_NAME_dup(sk) ((STACK_OF(X509_NAME) *)OPENSSL_sk_dup(ossl_check_const_X509_NAME_sk_type(sk)))
#define sk_X509_NAME_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(X509_NAME) *)OPENSSL_sk_deep_copy(ossl_check_const_X509_NAME_sk_type(sk), ossl_check_X509_NAME_copyfunc_type(copyfunc), ossl_check_X509_NAME_freefunc_type(freefunc)))
#define sk_X509_NAME_set_cmp_func(sk, cmp) ((sk_X509_NAME_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_X509_NAME_sk_type(sk), ossl_check_X509_NAME_compfunc_type(cmp)))
SKM_DEFINE_STACK_OF_INTERNAL(X509, X509, X509)
#define sk_X509_num(sk) OPENSSL_sk_num(ossl_check_const_X509_sk_type(sk))
#define sk_X509_value(sk, idx) ((X509 *)OPENSSL_sk_value(ossl_check_const_X509_sk_type(sk), (idx)))
#define sk_X509_new(cmp) ((STACK_OF(X509) *)OPENSSL_sk_new(ossl_check_X509_compfunc_type(cmp)))
#define sk_X509_new_null() ((STACK_OF(X509) *)OPENSSL_sk_new_null())
#define sk_X509_new_reserve(cmp, n) ((STACK_OF(X509) *)OPENSSL_sk_new_reserve(ossl_check_X509_compfunc_type(cmp), (n)))
#define sk_X509_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_X509_sk_type(sk), (n))
#define sk_X509_free(sk) OPENSSL_sk_free(ossl_check_X509_sk_type(sk))
#define sk_X509_zero(sk) OPENSSL_sk_zero(ossl_check_X509_sk_type(sk))
#define sk_X509_delete(sk, i) ((X509 *)OPENSSL_sk_delete(ossl_check_X509_sk_type(sk), (i)))
#define sk_X509_delete_ptr(sk, ptr) ((X509 *)OPENSSL_sk_delete_ptr(ossl_check_X509_sk_type(sk), ossl_check_X509_type(ptr)))
#define sk_X509_push(sk, ptr) OPENSSL_sk_push(ossl_check_X509_sk_type(sk), ossl_check_X509_type(ptr))
#define sk_X509_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_X509_sk_type(sk), ossl_check_X509_type(ptr))
#define sk_X509_pop(sk) ((X509 *)OPENSSL_sk_pop(ossl_check_X509_sk_type(sk)))
#define sk_X509_shift(sk) ((X509 *)OPENSSL_sk_shift(ossl_check_X509_sk_type(sk)))
#define sk_X509_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_X509_sk_type(sk),ossl_check_X509_freefunc_type(freefunc))
#define sk_X509_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_X509_sk_type(sk), ossl_check_X509_type(ptr), (idx))
#define sk_X509_set(sk, idx, ptr) ((X509 *)OPENSSL_sk_set(ossl_check_X509_sk_type(sk), (idx), ossl_check_X509_type(ptr)))
#define sk_X509_find(sk, ptr) OPENSSL_sk_find(ossl_check_X509_sk_type(sk), ossl_check_X509_type(ptr))
#define sk_X509_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_X509_sk_type(sk), ossl_check_X509_type(ptr))
#define sk_X509_find_all(sk, ptr, pnum) OPENSSL_sk_find_all(ossl_check_X509_sk_type(sk), ossl_check_X509_type(ptr), pnum)
#define sk_X509_sort(sk) OPENSSL_sk_sort(ossl_check_X509_sk_type(sk))
#define sk_X509_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_X509_sk_type(sk))
#define sk_X509_dup(sk) ((STACK_OF(X509) *)OPENSSL_sk_dup(ossl_check_const_X509_sk_type(sk)))
#define sk_X509_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(X509) *)OPENSSL_sk_deep_copy(ossl_check_const_X509_sk_type(sk), ossl_check_X509_copyfunc_type(copyfunc), ossl_check_X509_freefunc_type(freefunc)))
#define sk_X509_set_cmp_func(sk, cmp) ((sk_X509_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_X509_sk_type(sk), ossl_check_X509_compfunc_type(cmp)))
SKM_DEFINE_STACK_OF_INTERNAL(X509_REVOKED, X509_REVOKED, X509_REVOKED)
#define sk_X509_REVOKED_num(sk) OPENSSL_sk_num(ossl_check_const_X509_REVOKED_sk_type(sk))
#define sk_X509_REVOKED_value(sk, idx) ((X509_REVOKED *)OPENSSL_sk_value(ossl_check_const_X509_REVOKED_sk_type(sk), (idx)))
#define sk_X509_REVOKED_new(cmp) ((STACK_OF(X509_REVOKED) *)OPENSSL_sk_new(ossl_check_X509_REVOKED_compfunc_type(cmp)))
#define sk_X509_REVOKED_new_null() ((STACK_OF(X509_REVOKED) *)OPENSSL_sk_new_null())
#define sk_X509_REVOKED_new_reserve(cmp, n) ((STACK_OF(X509_REVOKED) *)OPENSSL_sk_new_reserve(ossl_check_X509_REVOKED_compfunc_type(cmp), (n)))
#define sk_X509_REVOKED_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_X509_REVOKED_sk_type(sk), (n))
#define sk_X509_REVOKED_free(sk) OPENSSL_sk_free(ossl_check_X509_REVOKED_sk_type(sk))
#define sk_X509_REVOKED_zero(sk) OPENSSL_sk_zero(ossl_check_X509_REVOKED_sk_type(sk))
#define sk_X509_REVOKED_delete(sk, i) ((X509_REVOKED *)OPENSSL_sk_delete(ossl_check_X509_REVOKED_sk_type(sk), (i)))
#define sk_X509_REVOKED_delete_ptr(sk, ptr) ((X509_REVOKED *)OPENSSL_sk_delete_ptr(ossl_check_X509_REVOKED_sk_type(sk), ossl_check_X509_REVOKED_type(ptr)))
#define sk_X509_REVOKED_push(sk, ptr) OPENSSL_sk_push(ossl_check_X509_REVOKED_sk_type(sk), ossl_check_X509_REVOKED_type(ptr))
#define sk_X509_REVOKED_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_X509_REVOKED_sk_type(sk), ossl_check_X509_REVOKED_type(ptr))
#define sk_X509_REVOKED_pop(sk) ((X509_REVOKED *)OPENSSL_sk_pop(ossl_check_X509_REVOKED_sk_type(sk)))
#define sk_X509_REVOKED_shift(sk) ((X509_REVOKED *)OPENSSL_sk_shift(ossl_check_X509_REVOKED_sk_type(sk)))
#define sk_X509_REVOKED_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_X509_REVOKED_sk_type(sk),ossl_check_X509_REVOKED_freefunc_type(freefunc))
#define sk_X509_REVOKED_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_X509_REVOKED_sk_type(sk), ossl_check_X509_REVOKED_type(ptr), (idx))
#define sk_X509_REVOKED_set(sk, idx, ptr) ((X509_REVOKED *)OPENSSL_sk_set(ossl_check_X509_REVOKED_sk_type(sk), (idx), ossl_check_X509_REVOKED_type(ptr)))
#define sk_X509_REVOKED_find(sk, ptr) OPENSSL_sk_find(ossl_check_X509_REVOKED_sk_type(sk), ossl_check_X509_REVOKED_type(ptr))
#define sk_X509_REVOKED_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_X509_REVOKED_sk_type(sk), ossl_check_X509_REVOKED_type(ptr))
#define sk_X509_REVOKED_find_all(sk, ptr, pnum) OPENSSL_sk_find_all(ossl_check_X509_REVOKED_sk_type(sk), ossl_check_X509_REVOKED_type(ptr), pnum)
#define sk_X509_REVOKED_sort(sk) OPENSSL_sk_sort(ossl_check_X509_REVOKED_sk_type(sk))
#define sk_X509_REVOKED_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_X509_REVOKED_sk_type(sk))
#define sk_X509_REVOKED_dup(sk) ((STACK_OF(X509_REVOKED) *)OPENSSL_sk_dup(ossl_check_const_X509_REVOKED_sk_type(sk)))
#define sk_X509_REVOKED_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(X509_REVOKED) *)OPENSSL_sk_deep_copy(ossl_check_const_X509_REVOKED_sk_type(sk), ossl_check_X509_REVOKED_copyfunc_type(copyfunc), ossl_check_X509_REVOKED_freefunc_type(freefunc)))
#define sk_X509_REVOKED_set_cmp_func(sk, cmp) ((sk_X509_REVOKED_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_X509_REVOKED_sk_type(sk), ossl_check_X509_REVOKED_compfunc_type(cmp)))
SKM_DEFINE_STACK_OF_INTERNAL(X509_CRL, X509_CRL, X509_CRL)
#define sk_X509_CRL_num(sk) OPENSSL_sk_num(ossl_check_const_X509_CRL_sk_type(sk))
#define sk_X509_CRL_value(sk, idx) ((X509_CRL *)OPENSSL_sk_value(ossl_check_const_X509_CRL_sk_type(sk), (idx)))
#define sk_X509_CRL_new(cmp) ((STACK_OF(X509_CRL) *)OPENSSL_sk_new(ossl_check_X509_CRL_compfunc_type(cmp)))
#define sk_X509_CRL_new_null() ((STACK_OF(X509_CRL) *)OPENSSL_sk_new_null())
#define sk_X509_CRL_new_reserve(cmp, n) ((STACK_OF(X509_CRL) *)OPENSSL_sk_new_reserve(ossl_check_X509_CRL_compfunc_type(cmp), (n)))
#define sk_X509_CRL_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_X509_CRL_sk_type(sk), (n))
#define sk_X509_CRL_free(sk) OPENSSL_sk_free(ossl_check_X509_CRL_sk_type(sk))
#define sk_X509_CRL_zero(sk) OPENSSL_sk_zero(ossl_check_X509_CRL_sk_type(sk))
#define sk_X509_CRL_delete(sk, i) ((X509_CRL *)OPENSSL_sk_delete(ossl_check_X509_CRL_sk_type(sk), (i)))
#define sk_X509_CRL_delete_ptr(sk, ptr) ((X509_CRL *)OPENSSL_sk_delete_ptr(ossl_check_X509_CRL_sk_type(sk), ossl_check_X509_CRL_type(ptr)))
#define sk_X509_CRL_push(sk, ptr) OPENSSL_sk_push(ossl_check_X509_CRL_sk_type(sk), ossl_check_X509_CRL_type(ptr))
#define sk_X509_CRL_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_X509_CRL_sk_type(sk), ossl_check_X509_CRL_type(ptr))
#define sk_X509_CRL_pop(sk) ((X509_CRL *)OPENSSL_sk_pop(ossl_check_X509_CRL_sk_type(sk)))
#define sk_X509_CRL_shift(sk) ((X509_CRL *)OPENSSL_sk_shift(ossl_check_X509_CRL_sk_type(sk)))
#define sk_X509_CRL_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_X509_CRL_sk_type(sk),ossl_check_X509_CRL_freefunc_type(freefunc))
#define sk_X509_CRL_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_X509_CRL_sk_type(sk), ossl_check_X509_CRL_type(ptr), (idx))
#define sk_X509_CRL_set(sk, idx, ptr) ((X509_CRL *)OPENSSL_sk_set(ossl_check_X509_CRL_sk_type(sk), (idx), ossl_check_X509_CRL_type(ptr)))
#define sk_X509_CRL_find(sk, ptr) OPENSSL_sk_find(ossl_check_X509_CRL_sk_type(sk), ossl_check_X509_CRL_type(ptr))
#define sk_X509_CRL_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_X509_CRL_sk_type(sk), ossl_check_X509_CRL_type(ptr))
#define sk_X509_CRL_find_all(sk, ptr, pnum) OPENSSL_sk_find_all(ossl_check_X509_CRL_sk_type(sk), ossl_check_X509_CRL_type(ptr), pnum)
#define sk_X509_CRL_sort(sk) OPENSSL_sk_sort(ossl_check_X509_CRL_sk_type(sk))
#define sk_X509_CRL_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_X509_CRL_sk_type(sk))
#define sk_X509_CRL_dup(sk) ((STACK_OF(X509_CRL) *)OPENSSL_sk_dup(ossl_check_const_X509_CRL_sk_type(sk)))
#define sk_X509_CRL_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(X509_CRL) *)OPENSSL_sk_deep_copy(ossl_check_const_X509_CRL_sk_type(sk), ossl_check_X509_CRL_copyfunc_type(copyfunc), ossl_check_X509_CRL_freefunc_type(freefunc)))
#define sk_X509_CRL_set_cmp_func(sk, cmp) ((sk_X509_CRL_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_X509_CRL_sk_type(sk), ossl_check_X509_CRL_compfunc_type(cmp)))


/* Flags for X509_get_signature_info() */
/* Signature info is valid */
# define X509_SIG_INFO_VALID     0x1
/* Signature is suitable for TLS use */
# define X509_SIG_INFO_TLS       0x2

# define X509_FILETYPE_PEM       1
# define X509_FILETYPE_ASN1      2
# define X509_FILETYPE_DEFAULT   3

# define X509v3_KU_DIGITAL_SIGNATURE     0x0080
# define X509v3_KU_NON_REPUDIATION       0x0040
# define X509v3_KU_KEY_ENCIPHERMENT      0x0020
# define X509v3_KU_DATA_ENCIPHERMENT     0x0010
# define X509v3_KU_KEY_AGREEMENT         0x0008
# define X509v3_KU_KEY_CERT_SIGN         0x0004
# define X509v3_KU_CRL_SIGN              0x0002
# define X509v3_KU_ENCIPHER_ONLY         0x0001
# define X509v3_KU_DECIPHER_ONLY         0x8000
# define X509v3_KU_UNDEF                 0xffff

struct X509_algor_st {
    ASN1_OBJECT *algorithm;
    ASN1_TYPE *parameter;
} /* X509_ALGOR */ ;

typedef STACK_OF(X509_ALGOR) X509_ALGORS;

typedef struct X509_val_st {
    ASN1_TIME *notBefore;
    ASN1_TIME *notAfter;
} X509_VAL;

typedef struct X509_sig_st X509_SIG;

typedef struct X509_name_entry_st X509_NAME_ENTRY;

SKM_DEFINE_STACK_OF_INTERNAL(X509_NAME_ENTRY, X509_NAME_ENTRY, X509_NAME_ENTRY)
#define sk_X509_NAME_ENTRY_num(sk) OPENSSL_sk_num(ossl_check_const_X509_NAME_ENTRY_sk_type(sk))
#define sk_X509_NAME_ENTRY_value(sk, idx) ((X509_NAME_ENTRY *)OPENSSL_sk_value(ossl_check_const_X509_NAME_ENTRY_sk_type(sk), (idx)))
#define sk_X509_NAME_ENTRY_new(cmp) ((STACK_OF(X509_NAME_ENTRY) *)OPENSSL_sk_new(ossl_check_X509_NAME_ENTRY_compfunc_type(cmp)))
#define sk_X509_NAME_ENTRY_new_null() ((STACK_OF(X509_NAME_ENTRY) *)OPENSSL_sk_new_null())
#define sk_X509_NAME_ENTRY_new_reserve(cmp, n) ((STACK_OF(X509_NAME_ENTRY) *)OPENSSL_sk_new_reserve(ossl_check_X509_NAME_ENTRY_compfunc_type(cmp), (n)))
#define sk_X509_NAME_ENTRY_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_X509_NAME_ENTRY_sk_type(sk), (n))
#define sk_X509_NAME_ENTRY_free(sk) OPENSSL_sk_free(ossl_check_X509_NAME_ENTRY_sk_type(sk))
#define sk_X509_NAME_ENTRY_zero(sk) OPENSSL_sk_zero(ossl_check_X509_NAME_ENTRY_sk_type(sk))
#define sk_X509_NAME_ENTRY_delete(sk, i) ((X509_NAME_ENTRY *)OPENSSL_sk_delete(ossl_check_X509_NAME_ENTRY_sk_type(sk), (i)))
#define sk_X509_NAME_ENTRY_delete_ptr(sk, ptr) ((X509_NAME_ENTRY *)OPENSSL_sk_delete_ptr(ossl_check_X509_NAME_ENTRY_sk_type(sk), ossl_check_X509_NAME_ENTRY_type(ptr)))
#define sk_X509_NAME_ENTRY_push(sk, ptr) OPENSSL_sk_push(ossl_check_X509_NAME_ENTRY_sk_type(sk), ossl_check_X509_NAME_ENTRY_type(ptr))
#define sk_X509_NAME_ENTRY_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_X509_NAME_ENTRY_sk_type(sk), ossl_check_X509_NAME_ENTRY_type(ptr))
#define sk_X509_NAME_ENTRY_pop(sk) ((X509_NAME_ENTRY *)OPENSSL_sk_pop(ossl_check_X509_NAME_ENTRY_sk_type(sk)))
#define sk_X509_NAME_ENTRY_shift(sk) ((X509_NAME_ENTRY *)OPENSSL_sk_shift(ossl_check_X509_NAME_ENTRY_sk_type(sk)))
#define sk_X509_NAME_ENTRY_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_X509_NAME_ENTRY_sk_type(sk),ossl_check_X509_NAME_ENTRY_freefunc_type(freefunc))
#define sk_X509_NAME_ENTRY_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_X509_NAME_ENTRY_sk_type(sk), ossl_check_X509_NAME_ENTRY_type(ptr), (idx))
#define sk_X509_NAME_ENTRY_set(sk, idx, ptr) ((X509_NAME_ENTRY *)OPENSSL_sk_set(ossl_check_X509_NAME_ENTRY_sk_type(sk), (idx), ossl_check_X509_NAME_ENTRY_type(ptr)))
#define sk_X509_NAME_ENTRY_find(sk, ptr) OPENSSL_sk_find(ossl_check_X509_NAME_ENTRY_sk_type(sk), ossl_check_X509_NAME_ENTRY_type(ptr))
#define sk_X509_NAME_ENTRY_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_X509_NAME_ENTRY_sk_type(sk), ossl_check_X509_NAME_ENTRY_type(ptr))
#define sk_X509_NAME_ENTRY_find_all(sk, ptr, pnum) OPENSSL_sk_find_all(ossl_check_X509_NAME_ENTRY_sk_type(sk), ossl_check_X509_NAME_ENTRY_type(ptr), pnum)
#define sk_X509_NAME_ENTRY_sort(sk) OPENSSL_sk_sort(ossl_check_X509_NAME_ENTRY_sk_type(sk))
#define sk_X509_NAME_ENTRY_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_X509_NAME_ENTRY_sk_type(sk))
#define sk_X509_NAME_ENTRY_dup(sk) ((STACK_OF(X509_NAME_ENTRY) *)OPENSSL_sk_dup(ossl_check_const_X509_NAME_ENTRY_sk_type(sk)))
#define sk_X509_NAME_ENTRY_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(X509_NAME_ENTRY) *)OPENSSL_sk_deep_copy(ossl_check_const_X509_NAME_ENTRY_sk_type(sk), ossl_check_X509_NAME_ENTRY_copyfunc_type(copyfunc), ossl_check_X509_NAME_ENTRY_freefunc_type(freefunc)))
#define sk_X509_NAME_ENTRY_set_cmp_func(sk, cmp) ((sk_X509_NAME_ENTRY_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_X509_NAME_ENTRY_sk_type(sk), ossl_check_X509_NAME_ENTRY_compfunc_type(cmp)))


# define X509_EX_V_NETSCAPE_HACK         0x8000
# define X509_EX_V_INIT                  0x0001
typedef struct X509_extension_st X509_EXTENSION;
SKM_DEFINE_STACK_OF_INTERNAL(X509_EXTENSION, X509_EXTENSION, X509_EXTENSION)
#define sk_X509_EXTENSION_num(sk) OPENSSL_sk_num(ossl_check_const_X509_EXTENSION_sk_type(sk))
#define sk_X509_EXTENSION_value(sk, idx) ((X509_EXTENSION *)OPENSSL_sk_value(ossl_check_const_X509_EXTENSION_sk_type(sk), (idx)))
#define sk_X509_EXTENSION_new(cmp) ((STACK_OF(X509_EXTENSION) *)OPENSSL_sk_new(ossl_check_X509_EXTENSION_compfunc_type(cmp)))
#define sk_X509_EXTENSION_new_null() ((STACK_OF(X509_EXTENSION) *)OPENSSL_sk_new_null())
#define sk_X509_EXTENSION_new_reserve(cmp, n) ((STACK_OF(X509_EXTENSION) *)OPENSSL_sk_new_reserve(ossl_check_X509_EXTENSION_compfunc_type(cmp), (n)))
#define sk_X509_EXTENSION_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_X509_EXTENSION_sk_type(sk), (n))
#define sk_X509_EXTENSION_free(sk) OPENSSL_sk_free(ossl_check_X509_EXTENSION_sk_type(sk))
#define sk_X509_EXTENSION_zero(sk) OPENSSL_sk_zero(ossl_check_X509_EXTENSION_sk_type(sk))
#define sk_X509_EXTENSION_delete(sk, i) ((X509_EXTENSION *)OPENSSL_sk_delete(ossl_check_X509_EXTENSION_sk_type(sk), (i)))
#define sk_X509_EXTENSION_delete_ptr(sk, ptr) ((X509_EXTENSION *)OPENSSL_sk_delete_ptr(ossl_check_X509_EXTENSION_sk_type(sk), ossl_check_X509_EXTENSION_type(ptr)))
#define sk_X509_EXTENSION_push(sk, ptr) OPENSSL_sk_push(ossl_check_X509_EXTENSION_sk_type(sk), ossl_check_X509_EXTENSION_type(ptr))
#define sk_X509_EXTENSION_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_X509_EXTENSION_sk_type(sk), ossl_check_X509_EXTENSION_type(ptr))
#define sk_X509_EXTENSION_pop(sk) ((X509_EXTENSION *)OPENSSL_sk_pop(ossl_check_X509_EXTENSION_sk_type(sk)))
#define sk_X509_EXTENSION_shift(sk) ((X509_EXTENSION *)OPENSSL_sk_shift(ossl_check_X509_EXTENSION_sk_type(sk)))
#define sk_X509_EXTENSION_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_X509_EXTENSION_sk_type(sk),ossl_check_X509_EXTENSION_freefunc_type(freefunc))
#define sk_X509_EXTENSION_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_X509_EXTENSION_sk_type(sk), ossl_check_X509_EXTENSION_type(ptr), (idx))
#define sk_X509_EXTENSION_set(sk, idx, ptr) ((X509_EXTENSION *)OPENSSL_sk_set(ossl_check_X509_EXTENSION_sk_type(sk), (idx), ossl_check_X509_EXTENSION_type(ptr)))
#define sk_X509_EXTENSION_find(sk, ptr) OPENSSL_sk_find(ossl_check_X509_EXTENSION_sk_type(sk), ossl_check_X509_EXTENSION_type(ptr))
#define sk_X509_EXTENSION_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_X509_EXTENSION_sk_type(sk), ossl_check_X509_EXTENSION_type(ptr))
#define sk_X509_EXTENSION_find_all(sk, ptr, pnum) OPENSSL_sk_find_all(ossl_check_X509_EXTENSION_sk_type(sk), ossl_check_X509_EXTENSION_type(ptr), pnum)
#define sk_X509_EXTENSION_sort(sk) OPENSSL_sk_sort(ossl_check_X509_EXTENSION_sk_type(sk))
#define sk_X509_EXTENSION_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_X509_EXTENSION_sk_type(sk))
#define sk_X509_EXTENSION_dup(sk) ((STACK_OF(X509_EXTENSION) *)OPENSSL_sk_dup(ossl_check_const_X509_EXTENSION_sk_type(sk)))
#define sk_X509_EXTENSION_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(X509_EXTENSION) *)OPENSSL_sk_deep_copy(ossl_check_const_X509_EXTENSION_sk_type(sk), ossl_check_X509_EXTENSION_copyfunc_type(copyfunc), ossl_check_X509_EXTENSION_freefunc_type(freefunc)))
#define sk_X509_EXTENSION_set_cmp_func(sk, cmp) ((sk_X509_EXTENSION_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_X509_EXTENSION_sk_type(sk), ossl_check_X509_EXTENSION_compfunc_type(cmp)))

typedef STACK_OF(X509_EXTENSION) X509_EXTENSIONS;
typedef struct x509_attributes_st X509_ATTRIBUTE;
SKM_DEFINE_STACK_OF_INTERNAL(X509_ATTRIBUTE, X509_ATTRIBUTE, X509_ATTRIBUTE)
#define sk_X509_ATTRIBUTE_num(sk) OPENSSL_sk_num(ossl_check_const_X509_ATTRIBUTE_sk_type(sk))
#define sk_X509_ATTRIBUTE_value(sk, idx) ((X509_ATTRIBUTE *)OPENSSL_sk_value(ossl_check_const_X509_ATTRIBUTE_sk_type(sk), (idx)))
#define sk_X509_ATTRIBUTE_new(cmp) ((STACK_OF(X509_ATTRIBUTE) *)OPENSSL_sk_new(ossl_check_X509_ATTRIBUTE_compfunc_type(cmp)))
#define sk_X509_ATTRIBUTE_new_null() ((STACK_OF(X509_ATTRIBUTE) *)OPENSSL_sk_new_null())
#define sk_X509_ATTRIBUTE_new_reserve(cmp, n) ((STACK_OF(X509_ATTRIBUTE) *)OPENSSL_sk_new_reserve(ossl_check_X509_ATTRIBUTE_compfunc_type(cmp), (n)))
#define sk_X509_ATTRIBUTE_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_X509_ATTRIBUTE_sk_type(sk), (n))
#define sk_X509_ATTRIBUTE_free(sk) OPENSSL_sk_free(ossl_check_X509_ATTRIBUTE_sk_type(sk))
#define sk_X509_ATTRIBUTE_zero(sk) OPENSSL_sk_zero(ossl_check_X509_ATTRIBUTE_sk_type(sk))
#define sk_X509_ATTRIBUTE_delete(sk, i) ((X509_ATTRIBUTE *)OPENSSL_sk_delete(ossl_check_X509_ATTRIBUTE_sk_type(sk), (i)))
#define sk_X509_ATTRIBUTE_delete_ptr(sk, ptr) ((X509_ATTRIBUTE *)OPENSSL_sk_delete_ptr(ossl_check_X509_ATTRIBUTE_sk_type(sk), ossl_check_X509_ATTRIBUTE_type(ptr)))
#define sk_X509_ATTRIBUTE_push(sk, ptr) OPENSSL_sk_push(ossl_check_X509_ATTRIBUTE_sk_type(sk), ossl_check_X509_ATTRIBUTE_type(ptr))
#define sk_X509_ATTRIBUTE_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_X509_ATTRIBUTE_sk_type(sk), ossl_check_X509_ATTRIBUTE_type(ptr))
#define sk_X509_ATTRIBUTE_pop(sk) ((X509_ATTRIBUTE *)OPENSSL_sk_pop(ossl_check_X509_ATTRIBUTE_sk_type(sk)))
#define sk_X509_ATTRIBUTE_shift(sk) ((X509_ATTRIBUTE *)OPENSSL_sk_shift(ossl_check_X509_ATTRIBUTE_sk_type(sk)))
#define sk_X509_ATTRIBUTE_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_X509_ATTRIBUTE_sk_type(sk),ossl_check_X509_ATTRIBUTE_freefunc_type(freefunc))
#define sk_X509_ATTRIBUTE_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_X509_ATTRIBUTE_sk_type(sk), ossl_check_X509_ATTRIBUTE_type(ptr), (idx))
#define sk_X509_ATTRIBUTE_set(sk, idx, ptr) ((X509_ATTRIBUTE *)OPENSSL_sk_set(ossl_check_X509_ATTRIBUTE_sk_type(sk), (idx), ossl_check_X509_ATTRIBUTE_type(ptr)))
#define sk_X509_ATTRIBUTE_find(sk, ptr) OPENSSL_sk_find(ossl_check_X509_ATTRIBUTE_sk_type(sk), ossl_check_X509_ATTRIBUTE_type(ptr))
#define sk_X509_ATTRIBUTE_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_X509_ATTRIBUTE_sk_type(sk), ossl_check_X509_ATTRIBUTE_type(ptr))
#define sk_X509_ATTRIBUTE_find_all(sk, ptr, pnum) OPENSSL_sk_find_all(ossl_check_X509_ATTRIBUTE_sk_type(sk), ossl_check_X509_ATTRIBUTE_type(ptr), pnum)
#define sk_X509_ATTRIBUTE_sort(sk) OPENSSL_sk_sort(ossl_check_X509_ATTRIBUTE_sk_type(sk))
#define sk_X509_ATTRIBUTE_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_X509_ATTRIBUTE_sk_type(sk))
#define sk_X509_ATTRIBUTE_dup(sk) ((STACK_OF(X509_ATTRIBUTE) *)OPENSSL_sk_dup(ossl_check_const_X509_ATTRIBUTE_sk_type(sk)))
#define sk_X509_ATTRIBUTE_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(X509_ATTRIBUTE) *)OPENSSL_sk_deep_copy(ossl_check_const_X509_ATTRIBUTE_sk_type(sk), ossl_check_X509_ATTRIBUTE_copyfunc_type(copyfunc), ossl_check_X509_ATTRIBUTE_freefunc_type(freefunc)))
#define sk_X509_ATTRIBUTE_set_cmp_func(sk, cmp) ((sk_X509_ATTRIBUTE_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_X509_ATTRIBUTE_sk_type(sk), ossl_check_X509_ATTRIBUTE_compfunc_type(cmp)))

typedef struct X509_req_info_st X509_REQ_INFO;
typedef struct X509_req_st X509_REQ;
typedef struct x509_cert_aux_st X509_CERT_AUX;
typedef struct x509_cinf_st X509_CINF;

/* Flags for X509_print_ex() */

# define X509_FLAG_COMPAT                0
# define X509_FLAG_NO_HEADER             1L
# define X509_FLAG_NO_VERSION            (1L << 1)
# define X509_FLAG_NO_SERIAL             (1L << 2)
# define X509_FLAG_NO_SIGNAME            (1L << 3)
# define X509_FLAG_NO_ISSUER             (1L << 4)
# define X509_FLAG_NO_VALIDITY           (1L << 5)
# define X509_FLAG_NO_SUBJECT            (1L << 6)
# define X509_FLAG_NO_PUBKEY             (1L << 7)
# define X509_FLAG_NO_EXTENSIONS         (1L << 8)
# define X509_FLAG_NO_SIGDUMP            (1L << 9)
# define X509_FLAG_NO_AUX                (1L << 10)
# define X509_FLAG_NO_ATTRIBUTES         (1L << 11)
# define X509_FLAG_NO_IDS                (1L << 12)
# define X509_FLAG_EXTENSIONS_ONLY_KID   (1L << 13)

/* Flags specific to X509_NAME_print_ex() */

/* The field separator information */

# define XN_FLAG_SEP_MASK        (0xf << 16)

# define XN_FLAG_COMPAT          0/* Traditional; use old X509_NAME_print */
# define XN_FLAG_SEP_COMMA_PLUS  (1 << 16)/* RFC2253 ,+ */
# define XN_FLAG_SEP_CPLUS_SPC   (2 << 16)/* ,+ spaced: more readable */
# define XN_FLAG_SEP_SPLUS_SPC   (3 << 16)/* ;+ spaced */
# define XN_FLAG_SEP_MULTILINE   (4 << 16)/* One line per field */

# define XN_FLAG_DN_REV          (1 << 20)/* Reverse DN order */

/* How the field name is shown */

# define XN_FLAG_FN_MASK         (0x3 << 21)

# define XN_FLAG_FN_SN           0/* Object short name */
# define XN_FLAG_FN_LN           (1 << 21)/* Object long name */
# define XN_FLAG_FN_OID          (2 << 21)/* Always use OIDs */
# define XN_FLAG_FN_NONE         (3 << 21)/* No field names */

# define XN_FLAG_SPC_EQ          (1 << 23)/* Put spaces round '=' */

/*
 * This determines if we dump fields we don't recognise: RFC2253 requires
 * this.
 */

# define XN_FLAG_DUMP_UNKNOWN_FIELDS (1 << 24)

# define XN_FLAG_FN_ALIGN        (1 << 25)/* Align field names to 20
                                           * characters */

/* Complete set of RFC2253 flags */

# define XN_FLAG_RFC2253 (ASN1_STRFLGS_RFC2253 | \
                        XN_FLAG_SEP_COMMA_PLUS | \
                        XN_FLAG_DN_REV | \
                        XN_FLAG_FN_SN | \
                        XN_FLAG_DUMP_UNKNOWN_FIELDS)

/* readable oneline form */

# define XN_FLAG_ONELINE (ASN1_STRFLGS_RFC2253 | \
                        ASN1_STRFLGS_ESC_QUOTE | \
                        XN_FLAG_SEP_CPLUS_SPC | \
                        XN_FLAG_SPC_EQ | \
                        XN_FLAG_FN_SN)

/* readable multiline form */

# define XN_FLAG_MULTILINE (ASN1_STRFLGS_ESC_CTRL | \
                        ASN1_STRFLGS_ESC_MSB | \
                        XN_FLAG_SEP_MULTILINE | \
                        XN_FLAG_SPC_EQ | \
                        XN_FLAG_FN_LN | \
                        XN_FLAG_FN_ALIGN)

typedef struct X509_crl_info_st X509_CRL_INFO;

typedef struct private_key_st {
    int version;
    /* The PKCS#8 data types */
    X509_ALGOR *enc_algor;
    ASN1_OCTET_STRING *enc_pkey; /* encrypted pub key */
    /* When decrypted, the following will not be NULL */
    EVP_PKEY *dec_pkey;
    /* used to encrypt and decrypt */
    int key_length;
    char *key_data;
    int key_free;               /* true if we should auto free key_data */
    /* expanded version of 'enc_algor' */
    EVP_CIPHER_INFO cipher;
} X509_PKEY;

typedef struct X509_info_st {
    X509 *x509;
    X509_CRL *crl;
    X509_PKEY *x_pkey;
    EVP_CIPHER_INFO enc_cipher;
    int enc_len;
    char *enc_data;
} X509_INFO;
SKM_DEFINE_STACK_OF_INTERNAL(X509_INFO, X509_INFO, X509_INFO)
#define sk_X509_INFO_num(sk) OPENSSL_sk_num(ossl_check_const_X509_INFO_sk_type(sk))
#define sk_X509_INFO_value(sk, idx) ((X509_INFO *)OPENSSL_sk_value(ossl_check_const_X509_INFO_sk_type(sk), (idx)))
#define sk_X509_INFO_new(cmp) ((STACK_OF(X509_INFO) *)OPENSSL_sk_new(ossl_check_X509_INFO_compfunc_type(cmp)))
#define sk_X509_INFO_new_null() ((STACK_OF(X509_INFO) *)OPENSSL_sk_new_null())
#define sk_X509_INFO_new_reserve(cmp, n) ((STACK_OF(X509_INFO) *)OPENSSL_sk_new_reserve(ossl_check_X509_INFO_compfunc_type(cmp), (n)))
#define sk_X509_INFO_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_X509_INFO_sk_type(sk), (n))
#define sk_X509_INFO_free(sk) OPENSSL_sk_free(ossl_check_X509_INFO_sk_type(sk))
#define sk_X509_INFO_zero(sk) OPENSSL_sk_zero(ossl_check_X509_INFO_sk_type(sk))
#define sk_X509_INFO_delete(sk, i) ((X509_INFO *)OPENSSL_sk_delete(ossl_check_X509_INFO_sk_type(sk), (i)))
#define sk_X509_INFO_delete_ptr(sk, ptr) ((X509_INFO *)OPENSSL_sk_delete_ptr(ossl_check_X509_INFO_sk_type(sk), ossl_check_X509_INFO_type(ptr)))
#define sk_X509_INFO_push(sk, ptr) OPENSSL_sk_push(ossl_check_X509_INFO_sk_type(sk), ossl_check_X509_INFO_type(ptr))
#define sk_X509_INFO_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_X509_INFO_sk_type(sk), ossl_check_X509_INFO_type(ptr))
#define sk_X509_INFO_pop(sk) ((X509_INFO *)OPENSSL_sk_pop(ossl_check_X509_INFO_sk_type(sk)))
#define sk_X509_INFO_shift(sk) ((X509_INFO *)OPENSSL_sk_shift(ossl_check_X509_INFO_sk_type(sk)))
#define sk_X509_INFO_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_X509_INFO_sk_type(sk),ossl_check_X509_INFO_freefunc_type(freefunc))
#define sk_X509_INFO_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_X509_INFO_sk_type(sk), ossl_check_X509_INFO_type(ptr), (idx))
#define sk_X509_INFO_set(sk, idx, ptr) ((X509_INFO *)OPENSSL_sk_set(ossl_check_X509_INFO_sk_type(sk), (idx), ossl_check_X509_INFO_type(ptr)))
#define sk_X509_INFO_find(sk, ptr) OPENSSL_sk_find(ossl_check_X509_INFO_sk_type(sk), ossl_check_X509_INFO_type(ptr))
#define sk_X509_INFO_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_X509_INFO_sk_type(sk), ossl_check_X509_INFO_type(ptr))
#define sk_X509_INFO_find_all(sk, ptr, pnum) OPENSSL_sk_find_all(ossl_check_X509_INFO_sk_type(sk), ossl_check_X509_INFO_type(ptr), pnum)
#define sk_X509_INFO_sort(sk) OPENSSL_sk_sort(ossl_check_X509_INFO_sk_type(sk))
#define sk_X509_INFO_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_X509_INFO_sk_type(sk))
#define sk_X509_INFO_dup(sk) ((STACK_OF(X509_INFO) *)OPENSSL_sk_dup(ossl_check_const_X509_INFO_sk_type(sk)))
#define sk_X509_INFO_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(X509_INFO) *)OPENSSL_sk_deep_copy(ossl_check_const_X509_INFO_sk_type(sk), ossl_check_X509_INFO_copyfunc_type(copyfunc), ossl_check_X509_INFO_freefunc_type(freefunc)))
#define sk_X509_INFO_set_cmp_func(sk, cmp) ((sk_X509_INFO_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_X509_INFO_sk_type(sk), ossl_check_X509_INFO_compfunc_type(cmp)))


/*
 * The next 2 structures and their 8 routines are used to manipulate Netscape's
 * spki structures - useful if you are writing a CA web page
 */
typedef struct Netscape_spkac_st {
    X509_PUBKEY *pubkey;
    ASN1_IA5STRING *challenge;  /* challenge sent in atlas >= PR2 */
} NETSCAPE_SPKAC;

typedef struct Netscape_spki_st {
    NETSCAPE_SPKAC *spkac;      /* signed public key and challenge */
    X509_ALGOR sig_algor;
    ASN1_BIT_STRING *signature;
} NETSCAPE_SPKI;

/* Netscape certificate sequence structure */
typedef struct Netscape_certificate_sequence {
    ASN1_OBJECT *type;
    STACK_OF(X509) *certs;
} NETSCAPE_CERT_SEQUENCE;

/*- Unused (and iv length is wrong)
typedef struct CBCParameter_st
        {
        unsigned char iv[8];
        } CBC_PARAM;
*/

/* Password based encryption structure */

typedef struct PBEPARAM_st {
    ASN1_OCTET_STRING *salt;
    ASN1_INTEGER *iter;
} PBEPARAM;

/* Password based encryption V2 structures */

typedef struct PBE2PARAM_st {
    X509_ALGOR *keyfunc;
    X509_ALGOR *encryption;
} PBE2PARAM;

typedef struct PBKDF2PARAM_st {
/* Usually OCTET STRING but could be anything */
    ASN1_TYPE *salt;
    ASN1_INTEGER *iter;
    ASN1_INTEGER *keylength;
    X509_ALGOR *prf;
} PBKDF2PARAM;

#ifndef OPENSSL_NO_SCRYPT
typedef struct SCRYPT_PARAMS_st {
    ASN1_OCTET_STRING *salt;
    ASN1_INTEGER *costParameter;
    ASN1_INTEGER *blockSize;
    ASN1_INTEGER *parallelizationParameter;
    ASN1_INTEGER *keyLength;
} SCRYPT_PARAMS;
#endif

#ifdef  __cplusplus
}
#endif

# include <openssl/x509_vfy.h>
# include <openssl/pkcs7.h>

#ifdef  __cplusplus
extern "C" {
#endif

# define X509_EXT_PACK_UNKNOWN   1
# define X509_EXT_PACK_STRING    2

# define         X509_extract_key(x)     X509_get_pubkey(x)/*****/
# define         X509_REQ_extract_key(a) X509_REQ_get_pubkey(a)
# define         X509_name_cmp(a,b)      X509_NAME_cmp((a),(b))

void X509_CRL_set_default_method(const X509_CRL_METHOD *meth);
X509_CRL_METHOD *X509_CRL_METHOD_new(int (*crl_init) (X509_CRL *crl),
                                     int (*crl_free) (X509_CRL *crl),
                                     int (*crl_lookup) (X509_CRL *crl,
                                                        X509_REVOKED **ret,
                                                        const
                                                        ASN1_INTEGER *serial,
                                                        const
                                                        X509_NAME *issuer),
                                     int (*crl_verify) (X509_CRL *crl,
                                                        EVP_PKEY *pk));
void X509_CRL_METHOD_free(X509_CRL_METHOD *m);

void X509_CRL_set_meth_data(X509_CRL *crl, void *dat);
void *X509_CRL_get_meth_data(X509_CRL *crl);

const char *X509_verify_cert_error_string(long n);

int X509_verify(X509 *a, EVP_PKEY *r);
int X509_self_signed(X509 *cert, int verify_signature);

int X509_REQ_verify_ex(X509_REQ *a, EVP_PKEY *r, OSSL_LIB_CTX *libctx,
                       const char *propq);
int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r);
int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r);
int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r);

NETSCAPE_SPKI *NETSCAPE_SPKI_b64_decode(const char *str, int len);
char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *x);
EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x);
int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey);

int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki);

int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent);
int X509_signature_print(BIO *bp, const X509_ALGOR *alg,
                         const ASN1_STRING *sig);

int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md);
int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx);
int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md);
int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx);
int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md);
int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx);
int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md);

int X509_pubkey_digest(const X509 *data, const EVP_MD *type,
                       unsigned char *md, unsigned int *len);
int X509_digest(const X509 *data, const EVP_MD *type,
                unsigned char *md, unsigned int *len);
ASN1_OCTET_STRING *X509_digest_sig(const X509 *cert,
                                   EVP_MD **md_used, int *md_is_fallback);
int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type,
                    unsigned char *md, unsigned int *len);
int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type,
                    unsigned char *md, unsigned int *len);
int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type,
                     unsigned char *md, unsigned int *len);

X509 *X509_load_http(const char *url, BIO *bio, BIO *rbio, int timeout);
X509_CRL *X509_CRL_load_http(const char *url, BIO *bio, BIO *rbio, int timeout);
# ifndef OPENSSL_NO_DEPRECATED_3_0
#  include <openssl/http.h> /* OSSL_HTTP_REQ_CTX_nbio_d2i */
#  define X509_http_nbio(rctx, pcert) \
      OSSL_HTTP_REQ_CTX_nbio_d2i(rctx, pcert, ASN1_ITEM_rptr(X509))
#  define X509_CRL_http_nbio(rctx, pcrl) \
      OSSL_HTTP_REQ_CTX_nbio_d2i(rctx, pcrl, ASN1_ITEM_rptr(X509_CRL))
# endif

# ifndef OPENSSL_NO_STDIO
X509 *d2i_X509_fp(FILE *fp, X509 **x509);
int i2d_X509_fp(FILE *fp, const X509 *x509);
X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl);
int i2d_X509_CRL_fp(FILE *fp, const X509_CRL *crl);
X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req);
int i2d_X509_REQ_fp(FILE *fp, const X509_REQ *req);
#  ifndef OPENSSL_NO_DEPRECATED_3_0
OSSL_DEPRECATEDIN_3_0 RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa);
OSSL_DEPRECATEDIN_3_0 int i2d_RSAPrivateKey_fp(FILE *fp, const RSA *rsa);
OSSL_DEPRECATEDIN_3_0 RSA *d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa);
OSSL_DEPRECATEDIN_3_0 int i2d_RSAPublicKey_fp(FILE *fp, const RSA *rsa);
OSSL_DEPRECATEDIN_3_0 RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa);
OSSL_DEPRECATEDIN_3_0 int i2d_RSA_PUBKEY_fp(FILE *fp, const RSA *rsa);
#  endif
#  ifndef OPENSSL_NO_DEPRECATED_3_0
#   ifndef OPENSSL_NO_DSA
OSSL_DEPRECATEDIN_3_0 DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa);
OSSL_DEPRECATEDIN_3_0 int i2d_DSA_PUBKEY_fp(FILE *fp, const DSA *dsa);
OSSL_DEPRECATEDIN_3_0 DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa);
OSSL_DEPRECATEDIN_3_0 int i2d_DSAPrivateKey_fp(FILE *fp, const DSA *dsa);
#   endif
#  endif
#  ifndef OPENSSL_NO_DEPRECATED_3_0
#   ifndef OPENSSL_NO_EC
OSSL_DEPRECATEDIN_3_0 EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey);
OSSL_DEPRECATEDIN_3_0 int i2d_EC_PUBKEY_fp(FILE *fp, const EC_KEY *eckey);
OSSL_DEPRECATEDIN_3_0 EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey);
OSSL_DEPRECATEDIN_3_0 int i2d_ECPrivateKey_fp(FILE *fp, const EC_KEY *eckey);
#   endif /* OPENSSL_NO_EC */
#  endif /* OPENSSL_NO_DEPRECATED_3_0 */
X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8);
int i2d_PKCS8_fp(FILE *fp, const X509_SIG *p8);
X509_PUBKEY *d2i_X509_PUBKEY_fp(FILE *fp, X509_PUBKEY **xpk);
int i2d_X509_PUBKEY_fp(FILE *fp, const X509_PUBKEY *xpk);
PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,
                                                PKCS8_PRIV_KEY_INFO **p8inf);
int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, const PKCS8_PRIV_KEY_INFO *p8inf);
int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, const EVP_PKEY *key);
int i2d_PrivateKey_fp(FILE *fp, const EVP_PKEY *pkey);
EVP_PKEY *d2i_PrivateKey_ex_fp(FILE *fp, EVP_PKEY **a, OSSL_LIB_CTX *libctx,
                               const char *propq);
EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a);
int i2d_PUBKEY_fp(FILE *fp, const EVP_PKEY *pkey);
EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a);
# endif

X509 *d2i_X509_bio(BIO *bp, X509 **x509);
int i2d_X509_bio(BIO *bp, const X509 *x509);
X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl);
int i2d_X509_CRL_bio(BIO *bp, const X509_CRL *crl);
X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req);
int i2d_X509_REQ_bio(BIO *bp, const X509_REQ *req);
#  ifndef OPENSSL_NO_DEPRECATED_3_0
OSSL_DEPRECATEDIN_3_0 RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa);
OSSL_DEPRECATEDIN_3_0 int i2d_RSAPrivateKey_bio(BIO *bp, const RSA *rsa);
OSSL_DEPRECATEDIN_3_0 RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa);
OSSL_DEPRECATEDIN_3_0 int i2d_RSAPublicKey_bio(BIO *bp, const RSA *rsa);
OSSL_DEPRECATEDIN_3_0 RSA *d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa);
OSSL_DEPRECATEDIN_3_0 int i2d_RSA_PUBKEY_bio(BIO *bp, const RSA *rsa);
#  endif
#  ifndef OPENSSL_NO_DEPRECATED_3_0
#   ifndef OPENSSL_NO_DSA
OSSL_DEPRECATEDIN_3_0 DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa);
OSSL_DEPRECATEDIN_3_0 int i2d_DSA_PUBKEY_bio(BIO *bp, const DSA *dsa);
OSSL_DEPRECATEDIN_3_0 DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa);
OSSL_DEPRECATEDIN_3_0 int i2d_DSAPrivateKey_bio(BIO *bp, const DSA *dsa);
#   endif
#  endif

#  ifndef OPENSSL_NO_DEPRECATED_3_0
#   ifndef OPENSSL_NO_EC
OSSL_DEPRECATEDIN_3_0 EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey);
OSSL_DEPRECATEDIN_3_0 int i2d_EC_PUBKEY_bio(BIO *bp, const EC_KEY *eckey);
OSSL_DEPRECATEDIN_3_0 EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey);
OSSL_DEPRECATEDIN_3_0 int i2d_ECPrivateKey_bio(BIO *bp, const EC_KEY *eckey);
#   endif /* OPENSSL_NO_EC */
#  endif /* OPENSSL_NO_DEPRECATED_3_0 */

X509_SIG *d2i_PKCS8_bio(BIO *bp, X509_SIG **p8);
int i2d_PKCS8_bio(BIO *bp, const X509_SIG *p8);
X509_PUBKEY *d2i_X509_PUBKEY_bio(BIO *bp, X509_PUBKEY **xpk);
int i2d_X509_PUBKEY_bio(BIO *bp, const X509_PUBKEY *xpk);
PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,
                                                 PKCS8_PRIV_KEY_INFO **p8inf);
int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, const PKCS8_PRIV_KEY_INFO *p8inf);
int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, const EVP_PKEY *key);
int i2d_PrivateKey_bio(BIO *bp, const EVP_PKEY *pkey);
EVP_PKEY *d2i_PrivateKey_ex_bio(BIO *bp, EVP_PKEY **a, OSSL_LIB_CTX *libctx,
                                const char *propq);
EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a);
int i2d_PUBKEY_bio(BIO *bp, const EVP_PKEY *pkey);
EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a);

DECLARE_ASN1_DUP_FUNCTION(X509)
DECLARE_ASN1_DUP_FUNCTION(X509_ALGOR)
DECLARE_ASN1_DUP_FUNCTION(X509_ATTRIBUTE)
DECLARE_ASN1_DUP_FUNCTION(X509_CRL)
DECLARE_ASN1_DUP_FUNCTION(X509_EXTENSION)
DECLARE_ASN1_DUP_FUNCTION(X509_PUBKEY)
DECLARE_ASN1_DUP_FUNCTION(X509_REQ)
DECLARE_ASN1_DUP_FUNCTION(X509_REVOKED)
int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype,
                    void *pval);
void X509_ALGOR_get0(const ASN1_OBJECT **paobj, int *pptype,
                     const void **ppval, const X509_ALGOR *algor);
void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md);
int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b);
int X509_ALGOR_copy(X509_ALGOR *dest, const X509_ALGOR *src);

DECLARE_ASN1_DUP_FUNCTION(X509_NAME)
DECLARE_ASN1_DUP_FUNCTION(X509_NAME_ENTRY)

int X509_cmp_time(const ASN1_TIME *s, time_t *t);
int X509_cmp_current_time(const ASN1_TIME *s);
int X509_cmp_timeframe(const X509_VERIFY_PARAM *vpm,
                       const ASN1_TIME *start, const ASN1_TIME *end);
ASN1_TIME *X509_time_adj(ASN1_TIME *s, long adj, time_t *t);
ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s,
                            int offset_day, long offset_sec, time_t *t);
ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj);

const char *X509_get_default_cert_area(void);
const char *X509_get_default_cert_dir(void);
const char *X509_get_default_cert_file(void);
const char *X509_get_default_cert_dir_env(void);
const char *X509_get_default_cert_file_env(void);
const char *X509_get_default_private_dir(void);

X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md);
X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey);

DECLARE_ASN1_FUNCTIONS(X509_ALGOR)
DECLARE_ASN1_ENCODE_FUNCTIONS(X509_ALGORS, X509_ALGORS, X509_ALGORS)
DECLARE_ASN1_FUNCTIONS(X509_VAL)

DECLARE_ASN1_FUNCTIONS(X509_PUBKEY)

X509_PUBKEY *X509_PUBKEY_new_ex(OSSL_LIB_CTX *libctx, const char *propq);
int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey);
EVP_PKEY *X509_PUBKEY_get0(const X509_PUBKEY *key);
EVP_PKEY *X509_PUBKEY_get(const X509_PUBKEY *key);
int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain);
long X509_get_pathlen(X509 *x);
DECLARE_ASN1_ENCODE_FUNCTIONS_only(EVP_PKEY, PUBKEY)
EVP_PKEY *d2i_PUBKEY_ex(EVP_PKEY **a, const unsigned char **pp, long length,
                        OSSL_LIB_CTX *libctx, const char *propq);
# ifndef OPENSSL_NO_DEPRECATED_3_0
DECLARE_ASN1_ENCODE_FUNCTIONS_only_attr(OSSL_DEPRECATEDIN_3_0,RSA, RSA_PUBKEY)
# endif
# ifndef OPENSSL_NO_DEPRECATED_3_0
#  ifndef OPENSSL_NO_DSA
DECLARE_ASN1_ENCODE_FUNCTIONS_only_attr(OSSL_DEPRECATEDIN_3_0,DSA, DSA_PUBKEY)
#  endif
# endif
# ifndef OPENSSL_NO_DEPRECATED_3_0
#  ifndef OPENSSL_NO_EC
DECLARE_ASN1_ENCODE_FUNCTIONS_only_attr(OSSL_DEPRECATEDIN_3_0, EC_KEY, EC_PUBKEY)
#  endif
# endif

DECLARE_ASN1_FUNCTIONS(X509_SIG)
void X509_SIG_get0(const X509_SIG *sig, const X509_ALGOR **palg,
                   const ASN1_OCTET_STRING **pdigest);
void X509_SIG_getm(X509_SIG *sig, X509_ALGOR **palg,
                   ASN1_OCTET_STRING **pdigest);

DECLARE_ASN1_FUNCTIONS(X509_REQ_INFO)
DECLARE_ASN1_FUNCTIONS(X509_REQ)
X509_REQ *X509_REQ_new_ex(OSSL_LIB_CTX *libctx, const char *propq);

DECLARE_ASN1_FUNCTIONS(X509_ATTRIBUTE)
X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value);

DECLARE_ASN1_FUNCTIONS(X509_EXTENSION)
DECLARE_ASN1_ENCODE_FUNCTIONS(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS)

DECLARE_ASN1_FUNCTIONS(X509_NAME_ENTRY)

DECLARE_ASN1_FUNCTIONS(X509_NAME)

int X509_NAME_set(X509_NAME **xn, const X509_NAME *name);

DECLARE_ASN1_FUNCTIONS(X509_CINF)
DECLARE_ASN1_FUNCTIONS(X509)
X509 *X509_new_ex(OSSL_LIB_CTX *libctx, const char *propq);
DECLARE_ASN1_FUNCTIONS(X509_CERT_AUX)

#define X509_get_ex_new_index(l, p, newf, dupf, freef) \
    CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509, l, p, newf, dupf, freef)
int X509_set_ex_data(X509 *r, int idx, void *arg);
void *X509_get_ex_data(const X509 *r, int idx);
DECLARE_ASN1_ENCODE_FUNCTIONS_only(X509,X509_AUX)

int i2d_re_X509_tbs(X509 *x, unsigned char **pp);

int X509_SIG_INFO_get(const X509_SIG_INFO *siginf, int *mdnid, int *pknid,
                      int *secbits, uint32_t *flags);
void X509_SIG_INFO_set(X509_SIG_INFO *siginf, int mdnid, int pknid,
                       int secbits, uint32_t flags);

int X509_get_signature_info(X509 *x, int *mdnid, int *pknid, int *secbits,
                            uint32_t *flags);

void X509_get0_signature(const ASN1_BIT_STRING **psig,
                         const X509_ALGOR **palg, const X509 *x);
int X509_get_signature_nid(const X509 *x);

void X509_set0_distinguishing_id(X509 *x, ASN1_OCTET_STRING *d_id);
ASN1_OCTET_STRING *X509_get0_distinguishing_id(X509 *x);
void X509_REQ_set0_distinguishing_id(X509_REQ *x, ASN1_OCTET_STRING *d_id);
ASN1_OCTET_STRING *X509_REQ_get0_distinguishing_id(X509_REQ *x);

int X509_alias_set1(X509 *x, const unsigned char *name, int len);
int X509_keyid_set1(X509 *x, const unsigned char *id, int len);
unsigned char *X509_alias_get0(X509 *x, int *len);
unsigned char *X509_keyid_get0(X509 *x, int *len);

DECLARE_ASN1_FUNCTIONS(X509_REVOKED)
DECLARE_ASN1_FUNCTIONS(X509_CRL_INFO)
DECLARE_ASN1_FUNCTIONS(X509_CRL)
X509_CRL *X509_CRL_new_ex(OSSL_LIB_CTX *libctx, const char *propq);

int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev);
int X509_CRL_get0_by_serial(X509_CRL *crl,
                            X509_REVOKED **ret, const ASN1_INTEGER *serial);
int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x);

X509_PKEY *X509_PKEY_new(void);
void X509_PKEY_free(X509_PKEY *a);

DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKI)
DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKAC)
DECLARE_ASN1_FUNCTIONS(NETSCAPE_CERT_SEQUENCE)

X509_INFO *X509_INFO_new(void);
void X509_INFO_free(X509_INFO *a);
char *X509_NAME_oneline(const X509_NAME *a, char *buf, int size);

#ifndef OPENSSL_NO_DEPRECATED_3_0
OSSL_DEPRECATEDIN_3_0
int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *algor1,
                ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey);
OSSL_DEPRECATEDIN_3_0
int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data,
                unsigned char *md, unsigned int *len);
OSSL_DEPRECATEDIN_3_0
int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2,
              ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey,
              const EVP_MD *type);
#endif
int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *data,
                     unsigned char *md, unsigned int *len);
int ASN1_item_verify(const ASN1_ITEM *it, const X509_ALGOR *alg,
                     const ASN1_BIT_STRING *signature, const void *data,
                     EVP_PKEY *pkey);
int ASN1_item_verify_ctx(const ASN1_ITEM *it, const X509_ALGOR *alg,
                         const ASN1_BIT_STRING *signature, const void *data,
                         EVP_MD_CTX *ctx);
int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
                   ASN1_BIT_STRING *signature, const void *data,
                   EVP_PKEY *pkey, const EVP_MD *md);
int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1,
                       X509_ALGOR *algor2, ASN1_BIT_STRING *signature,
                       const void *data, EVP_MD_CTX *ctx);

#define X509_VERSION_1 0
#define X509_VERSION_2 1
#define X509_VERSION_3 2

long X509_get_version(const X509 *x);
int X509_set_version(X509 *x, long version);
int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial);
ASN1_INTEGER *X509_get_serialNumber(X509 *x);
const ASN1_INTEGER *X509_get0_serialNumber(const X509 *x);
int X509_set_issuer_name(X509 *x, const X509_NAME *name);
X509_NAME *X509_get_issuer_name(const X509 *a);
int X509_set_subject_name(X509 *x, const X509_NAME *name);
X509_NAME *X509_get_subject_name(const X509 *a);
const ASN1_TIME * X509_get0_notBefore(const X509 *x);
ASN1_TIME *X509_getm_notBefore(const X509 *x);
int X509_set1_notBefore(X509 *x, const ASN1_TIME *tm);
const ASN1_TIME *X509_get0_notAfter(const X509 *x);
ASN1_TIME *X509_getm_notAfter(const X509 *x);
int X509_set1_notAfter(X509 *x, const ASN1_TIME *tm);
int X509_set_pubkey(X509 *x, EVP_PKEY *pkey);
int X509_up_ref(X509 *x);
int X509_get_signature_type(const X509 *x);

# ifndef OPENSSL_NO_DEPRECATED_1_1_0
#  define X509_get_notBefore X509_getm_notBefore
#  define X509_get_notAfter X509_getm_notAfter
#  define X509_set_notBefore X509_set1_notBefore
#  define X509_set_notAfter X509_set1_notAfter
#endif


/*
 * This one is only used so that a binary form can output, as in
 * i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x), &buf)
 */
X509_PUBKEY *X509_get_X509_PUBKEY(const X509 *x);
const STACK_OF(X509_EXTENSION) *X509_get0_extensions(const X509 *x);
void X509_get0_uids(const X509 *x, const ASN1_BIT_STRING **piuid,
                    const ASN1_BIT_STRING **psuid);
const X509_ALGOR *X509_get0_tbs_sigalg(const X509 *x);

EVP_PKEY *X509_get0_pubkey(const X509 *x);
EVP_PKEY *X509_get_pubkey(X509 *x);
ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x);

#define X509_REQ_VERSION_1 0

long X509_REQ_get_version(const X509_REQ *req);
int X509_REQ_set_version(X509_REQ *x, long version);
X509_NAME *X509_REQ_get_subject_name(const X509_REQ *req);
int X509_REQ_set_subject_name(X509_REQ *req, const X509_NAME *name);
void X509_REQ_get0_signature(const X509_REQ *req, const ASN1_BIT_STRING **psig,
                             const X509_ALGOR **palg);
void X509_REQ_set0_signature(X509_REQ *req, ASN1_BIT_STRING *psig);
int X509_REQ_set1_signature_algo(X509_REQ *req, X509_ALGOR *palg);
int X509_REQ_get_signature_nid(const X509_REQ *req);
int i2d_re_X509_REQ_tbs(X509_REQ *req, unsigned char **pp);
int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey);
EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req);
EVP_PKEY *X509_REQ_get0_pubkey(X509_REQ *req);
X509_PUBKEY *X509_REQ_get_X509_PUBKEY(X509_REQ *req);
int X509_REQ_extension_nid(int nid);
int *X509_REQ_get_extension_nids(void);
void X509_REQ_set_extension_nids(int *nids);
STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req);
int X509_REQ_add_extensions_nid(X509_REQ *req,
                                const STACK_OF(X509_EXTENSION) *exts, int nid);
int X509_REQ_add_extensions(X509_REQ *req, const STACK_OF(X509_EXTENSION) *ext);
int X509_REQ_get_attr_count(const X509_REQ *req);
int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos);
int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, const ASN1_OBJECT *obj,
                             int lastpos);
X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc);
X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc);
int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr);
int X509_REQ_add1_attr_by_OBJ(X509_REQ *req,
                              const ASN1_OBJECT *obj, int type,
                              const unsigned char *bytes, int len);
int X509_REQ_add1_attr_by_NID(X509_REQ *req,
                              int nid, int type,
                              const unsigned char *bytes, int len);
int X509_REQ_add1_attr_by_txt(X509_REQ *req,
                              const char *attrname, int type,
                              const unsigned char *bytes, int len);

#define X509_CRL_VERSION_1 0
#define X509_CRL_VERSION_2 1

int X509_CRL_set_version(X509_CRL *x, long version);
int X509_CRL_set_issuer_name(X509_CRL *x, const X509_NAME *name);
int X509_CRL_set1_lastUpdate(X509_CRL *x, const ASN1_TIME *tm);
int X509_CRL_set1_nextUpdate(X509_CRL *x, const ASN1_TIME *tm);
int X509_CRL_sort(X509_CRL *crl);
int X509_CRL_up_ref(X509_CRL *crl);

# ifndef OPENSSL_NO_DEPRECATED_1_1_0
#  define X509_CRL_set_lastUpdate X509_CRL_set1_lastUpdate
#  define X509_CRL_set_nextUpdate X509_CRL_set1_nextUpdate
#endif

long X509_CRL_get_version(const X509_CRL *crl);
const ASN1_TIME *X509_CRL_get0_lastUpdate(const X509_CRL *crl);
const ASN1_TIME *X509_CRL_get0_nextUpdate(const X509_CRL *crl);
#ifndef OPENSSL_NO_DEPRECATED_1_1_0
OSSL_DEPRECATEDIN_1_1_0 ASN1_TIME *X509_CRL_get_lastUpdate(X509_CRL *crl);
OSSL_DEPRECATEDIN_1_1_0 ASN1_TIME *X509_CRL_get_nextUpdate(X509_CRL *crl);
#endif
X509_NAME *X509_CRL_get_issuer(const X509_CRL *crl);
const STACK_OF(X509_EXTENSION) *X509_CRL_get0_extensions(const X509_CRL *crl);
STACK_OF(X509_REVOKED) *X509_CRL_get_REVOKED(X509_CRL *crl);
void X509_CRL_get0_signature(const X509_CRL *crl, const ASN1_BIT_STRING **psig,
                             const X509_ALGOR **palg);
int X509_CRL_get_signature_nid(const X509_CRL *crl);
int i2d_re_X509_CRL_tbs(X509_CRL *req, unsigned char **pp);

const ASN1_INTEGER *X509_REVOKED_get0_serialNumber(const X509_REVOKED *x);
int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial);
const ASN1_TIME *X509_REVOKED_get0_revocationDate(const X509_REVOKED *x);
int X509_REVOKED_set_revocationDate(X509_REVOKED *r, ASN1_TIME *tm);
const STACK_OF(X509_EXTENSION) *
X509_REVOKED_get0_extensions(const X509_REVOKED *r);

X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer,
                        EVP_PKEY *skey, const EVP_MD *md, unsigned int flags);

int X509_REQ_check_private_key(X509_REQ *x509, EVP_PKEY *pkey);

int X509_check_private_key(const X509 *x509, const EVP_PKEY *pkey);
int X509_chain_check_suiteb(int *perror_depth,
                            X509 *x, STACK_OF(X509) *chain,
                            unsigned long flags);
int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags);
STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain);

int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b);
unsigned long X509_issuer_and_serial_hash(X509 *a);

int X509_issuer_name_cmp(const X509 *a, const X509 *b);
unsigned long X509_issuer_name_hash(X509 *a);

int X509_subject_name_cmp(const X509 *a, const X509 *b);
unsigned long X509_subject_name_hash(X509 *x);

# ifndef OPENSSL_NO_MD5
unsigned long X509_issuer_name_hash_old(X509 *a);
unsigned long X509_subject_name_hash_old(X509 *x);
# endif

# define X509_ADD_FLAG_DEFAULT  0
# define X509_ADD_FLAG_UP_REF   0x1
# define X509_ADD_FLAG_PREPEND  0x2
# define X509_ADD_FLAG_NO_DUP   0x4
# define X509_ADD_FLAG_NO_SS    0x8
int X509_add_cert(STACK_OF(X509) *sk, X509 *cert, int flags);
int X509_add_certs(STACK_OF(X509) *sk, STACK_OF(X509) *certs, int flags);

int X509_cmp(const X509 *a, const X509 *b);
int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b);
#ifndef OPENSSL_NO_DEPRECATED_3_0
# define X509_NAME_hash(x) X509_NAME_hash_ex(x, NULL, NULL, NULL)
OSSL_DEPRECATEDIN_3_0 int X509_certificate_type(const X509 *x,
                                                const EVP_PKEY *pubkey);
#endif
unsigned long X509_NAME_hash_ex(const X509_NAME *x, OSSL_LIB_CTX *libctx,
                                const char *propq, int *ok);
unsigned long X509_NAME_hash_old(const X509_NAME *x);

int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b);
int X509_CRL_match(const X509_CRL *a, const X509_CRL *b);
int X509_aux_print(BIO *out, X509 *x, int indent);
# ifndef OPENSSL_NO_STDIO
int X509_print_ex_fp(FILE *bp, X509 *x, unsigned long nmflag,
                     unsigned long cflag);
int X509_print_fp(FILE *bp, X509 *x);
int X509_CRL_print_fp(FILE *bp, X509_CRL *x);
int X509_REQ_print_fp(FILE *bp, X509_REQ *req);
int X509_NAME_print_ex_fp(FILE *fp, const X509_NAME *nm, int indent,
                          unsigned long flags);
# endif

int X509_NAME_print(BIO *bp, const X509_NAME *name, int obase);
int X509_NAME_print_ex(BIO *out, const X509_NAME *nm, int indent,
                       unsigned long flags);
int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflag,
                  unsigned long cflag);
int X509_print(BIO *bp, X509 *x);
int X509_ocspid_print(BIO *bp, X509 *x);
int X509_CRL_print_ex(BIO *out, X509_CRL *x, unsigned long nmflag);
int X509_CRL_print(BIO *bp, X509_CRL *x);
int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflag,
                      unsigned long cflag);
int X509_REQ_print(BIO *bp, X509_REQ *req);

int X509_NAME_entry_count(const X509_NAME *name);
int X509_NAME_get_text_by_NID(const X509_NAME *name, int nid,
                              char *buf, int len);
int X509_NAME_get_text_by_OBJ(const X509_NAME *name, const ASN1_OBJECT *obj,
                              char *buf, int len);

/*
 * NOTE: you should be passing -1, not 0 as lastpos. The functions that use
 * lastpos, search after that position on.
 */
int X509_NAME_get_index_by_NID(const X509_NAME *name, int nid, int lastpos);
int X509_NAME_get_index_by_OBJ(const X509_NAME *name, const ASN1_OBJECT *obj,
                               int lastpos);
X509_NAME_ENTRY *X509_NAME_get_entry(const X509_NAME *name, int loc);
X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc);
int X509_NAME_add_entry(X509_NAME *name, const X509_NAME_ENTRY *ne,
                        int loc, int set);
int X509_NAME_add_entry_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, int type,
                               const unsigned char *bytes, int len, int loc,
                               int set);
int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type,
                               const unsigned char *bytes, int len, int loc,
                               int set);
X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne,
                                               const char *field, int type,
                                               const unsigned char *bytes,
                                               int len);
X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid,
                                               int type,
                                               const unsigned char *bytes,
                                               int len);
int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type,
                               const unsigned char *bytes, int len, int loc,
                               int set);
X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne,
                                               const ASN1_OBJECT *obj, int type,
                                               const unsigned char *bytes,
                                               int len);
int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, const ASN1_OBJECT *obj);
int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type,
                             const unsigned char *bytes, int len);
ASN1_OBJECT *X509_NAME_ENTRY_get_object(const X509_NAME_ENTRY *ne);
ASN1_STRING * X509_NAME_ENTRY_get_data(const X509_NAME_ENTRY *ne);
int X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne);

int X509_NAME_get0_der(const X509_NAME *nm, const unsigned char **pder,
                       size_t *pderlen);

int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x);
int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x,
                          int nid, int lastpos);
int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *x,
                          const ASN1_OBJECT *obj, int lastpos);
int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *x,
                               int crit, int lastpos);
X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc);
X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc);
STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x,
                                         X509_EXTENSION *ex, int loc);

int X509_get_ext_count(const X509 *x);
int X509_get_ext_by_NID(const X509 *x, int nid, int lastpos);
int X509_get_ext_by_OBJ(const X509 *x, const ASN1_OBJECT *obj, int lastpos);
int X509_get_ext_by_critical(const X509 *x, int crit, int lastpos);
X509_EXTENSION *X509_get_ext(const X509 *x, int loc);
X509_EXTENSION *X509_delete_ext(X509 *x, int loc);
int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc);
void *X509_get_ext_d2i(const X509 *x, int nid, int *crit, int *idx);
int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit,
                      unsigned long flags);

int X509_CRL_get_ext_count(const X509_CRL *x);
int X509_CRL_get_ext_by_NID(const X509_CRL *x, int nid, int lastpos);
int X509_CRL_get_ext_by_OBJ(const X509_CRL *x, const ASN1_OBJECT *obj,
                            int lastpos);
int X509_CRL_get_ext_by_critical(const X509_CRL *x, int crit, int lastpos);
X509_EXTENSION *X509_CRL_get_ext(const X509_CRL *x, int loc);
X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc);
int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc);
void *X509_CRL_get_ext_d2i(const X509_CRL *x, int nid, int *crit, int *idx);
int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit,
                          unsigned long flags);

int X509_REVOKED_get_ext_count(const X509_REVOKED *x);
int X509_REVOKED_get_ext_by_NID(const X509_REVOKED *x, int nid, int lastpos);
int X509_REVOKED_get_ext_by_OBJ(const X509_REVOKED *x, const ASN1_OBJECT *obj,
                                int lastpos);
int X509_REVOKED_get_ext_by_critical(const X509_REVOKED *x, int crit,
                                     int lastpos);
X509_EXTENSION *X509_REVOKED_get_ext(const X509_REVOKED *x, int loc);
X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc);
int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc);
void *X509_REVOKED_get_ext_d2i(const X509_REVOKED *x, int nid, int *crit,
                               int *idx);
int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit,
                              unsigned long flags);

X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex,
                                             int nid, int crit,
                                             ASN1_OCTET_STRING *data);
X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex,
                                             const ASN1_OBJECT *obj, int crit,
                                             ASN1_OCTET_STRING *data);
int X509_EXTENSION_set_object(X509_EXTENSION *ex, const ASN1_OBJECT *obj);
int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit);
int X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data);
ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex);
ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ne);
int X509_EXTENSION_get_critical(const X509_EXTENSION *ex);

int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x);
int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid,
                           int lastpos);
int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk,
                           const ASN1_OBJECT *obj, int lastpos);
X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc);
X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc);
STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
                                           X509_ATTRIBUTE *attr);
STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE)
                                                  **x, const ASN1_OBJECT *obj,
                                                  int type,
                                                  const unsigned char *bytes,
                                                  int len);
STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE)
                                                  **x, int nid, int type,
                                                  const unsigned char *bytes,
                                                  int len);
STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE)
                                                  **x, const char *attrname,
                                                  int type,
                                                  const unsigned char *bytes,
                                                  int len);
void *X509at_get0_data_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *x,
                              const ASN1_OBJECT *obj, int lastpos, int type);
X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid,
                                             int atrtype, const void *data,
                                             int len);
X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr,
                                             const ASN1_OBJECT *obj,
                                             int atrtype, const void *data,
                                             int len);
X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr,
                                             const char *atrname, int type,
                                             const unsigned char *bytes,
                                             int len);
int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj);
int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype,
                             const void *data, int len);
void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, int atrtype,
                               void *data);
int X509_ATTRIBUTE_count(const X509_ATTRIBUTE *attr);
ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr);
ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx);

int EVP_PKEY_get_attr_count(const EVP_PKEY *key);
int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid, int lastpos);
int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, const ASN1_OBJECT *obj,
                             int lastpos);
X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc);
X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc);
int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr);
int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key,
                              const ASN1_OBJECT *obj, int type,
                              const unsigned char *bytes, int len);
int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key,
                              int nid, int type,
                              const unsigned char *bytes, int len);
int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key,
                              const char *attrname, int type,
                              const unsigned char *bytes, int len);

/* lookup a cert from a X509 STACK */
X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, const X509_NAME *name,
                                     const ASN1_INTEGER *serial);
X509 *X509_find_by_subject(STACK_OF(X509) *sk, const X509_NAME *name);

DECLARE_ASN1_FUNCTIONS(PBEPARAM)
DECLARE_ASN1_FUNCTIONS(PBE2PARAM)
DECLARE_ASN1_FUNCTIONS(PBKDF2PARAM)
#ifndef OPENSSL_NO_SCRYPT
DECLARE_ASN1_FUNCTIONS(SCRYPT_PARAMS)
#endif

int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
                         const unsigned char *salt, int saltlen);
int PKCS5_pbe_set0_algor_ex(X509_ALGOR *algor, int alg, int iter,
                            const unsigned char *salt, int saltlen,
                            OSSL_LIB_CTX *libctx);

X509_ALGOR *PKCS5_pbe_set(int alg, int iter,
                          const unsigned char *salt, int saltlen);
X509_ALGOR *PKCS5_pbe_set_ex(int alg, int iter,
                             const unsigned char *salt, int saltlen,
                             OSSL_LIB_CTX *libctx);

X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
                           unsigned char *salt, int saltlen);
X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
                              unsigned char *salt, int saltlen,
                              unsigned char *aiv, int prf_nid);
X509_ALGOR *PKCS5_pbe2_set_iv_ex(const EVP_CIPHER *cipher, int iter,
                                 unsigned char *salt, int saltlen,
                                 unsigned char *aiv, int prf_nid,
                                 OSSL_LIB_CTX *libctx);

#ifndef OPENSSL_NO_SCRYPT
X509_ALGOR *PKCS5_pbe2_set_scrypt(const EVP_CIPHER *cipher,
                                  const unsigned char *salt, int saltlen,
                                  unsigned char *aiv, uint64_t N, uint64_t r,
                                  uint64_t p);
#endif

X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
                             int prf_nid, int keylen);
X509_ALGOR *PKCS5_pbkdf2_set_ex(int iter, unsigned char *salt, int saltlen,
                                int prf_nid, int keylen,
                                OSSL_LIB_CTX *libctx);

/* PKCS#8 utilities */

DECLARE_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO)

EVP_PKEY *EVP_PKCS82PKEY(const PKCS8_PRIV_KEY_INFO *p8);
EVP_PKEY *EVP_PKCS82PKEY_ex(const PKCS8_PRIV_KEY_INFO *p8, OSSL_LIB_CTX *libctx,
                            const char *propq);
PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(const EVP_PKEY *pkey);

int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj,
                    int version, int ptype, void *pval,
                    unsigned char *penc, int penclen);
int PKCS8_pkey_get0(const ASN1_OBJECT **ppkalg,
                    const unsigned char **pk, int *ppklen,
                    const X509_ALGOR **pa, const PKCS8_PRIV_KEY_INFO *p8);

const STACK_OF(X509_ATTRIBUTE) *
PKCS8_pkey_get0_attrs(const PKCS8_PRIV_KEY_INFO *p8);
int PKCS8_pkey_add1_attr(PKCS8_PRIV_KEY_INFO *p8, X509_ATTRIBUTE *attr);
int PKCS8_pkey_add1_attr_by_NID(PKCS8_PRIV_KEY_INFO *p8, int nid, int type,
                                const unsigned char *bytes, int len);
int PKCS8_pkey_add1_attr_by_OBJ(PKCS8_PRIV_KEY_INFO *p8, const ASN1_OBJECT *obj,
                                int type, const unsigned char *bytes, int len);


int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj,
                           int ptype, void *pval,
                           unsigned char *penc, int penclen);
int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg,
                           const unsigned char **pk, int *ppklen,
                           X509_ALGOR **pa, const X509_PUBKEY *pub);
int X509_PUBKEY_eq(const X509_PUBKEY *a, const X509_PUBKEY *b);

# ifdef  __cplusplus
}
# endif
#endif
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    PKMH$Ul#0JQ-BҜKswHT"y}o<<6V;B xCc9R{Q!"+뷄"L:֫zkvՖ"޹;gSNZ:ScgrS}{g)N}k3Q<lG5u:n~&KM/
.p
v!8~`	S1`؜1s+K46)__2莺@+%TrԳ5yRKAb&dy
xN?i QQ=nnmͽ_D}D!A޲lA|$%L:%-Skz30elC\o<G+\$o	vL:灪eئG^iI  /9oЭ$L:Ъ=BwL+L:Ns@]ɮQ0@}`ZmVbՖ0a)oNBߖxd탕_`t~0IяOݻ&G%8[1XGv1Mˤcl&'L:>eZI8nZB1]xbKdA]Ђ'1H-ϒTueAE(R`|X^%=z7$bU!tEiV/]g]wM.:ZXQt\Ov@Z!;ZIuAE$,/`ڳKx=A{T_8j8:5XD}]\hXQy5}F8%\!S8BYȺʴJ
|=Qq{fH'şQ"*?ƭ"XݢZT>0w#DsWřDՃBg@\vXTx3j$3H.`rՌ28c4hIB텂`3 _
=

љXaXl]18:Q1lAO.6}^7C͊rXэ+4blJ&CP 6`9JZQ*X:G[)X!ҀG0s%T[FdjT́/08E79Z*{R/7W)bA 
b{H)F}4X.li/%ڂAŕdvD5RLz@LV+:A+z[I#p,'EoX<P8qI"^ V%+Y/8$&
TZ
-REjjq5oGpT_
M_HE
 X.0CfV驯2(XZ%e8*Q)ՏoW~gy䢢*
΀HS?h6d ͸FUu,A{״ea2ڛD
%p
㘡a.6[3KgffP7
m$6m뱲&iC]Ȣϲ(iCFjj'&vN1k.,e0q\:Yp[
DDv0Z
o0x(i#5O]b#^ jG+%fWPz 3B(O,/a~R
%N4Y9U7'Eǉڦ:_4yN iĺ%Q(xֲK͕+UQ5grpqEFdQwס8JZ>.R"U ZF&3(#T`FIORS8芹ТUtik`;r+.,MIX+&(!Ha`Vi<UV&LA&gz[2o\UKZR/ ӼY^$GgGHFwvl{js3W3!&Wܘ^7˟#5J3݅@}ߪXah\ Ma#[lQS7C
g.ƂQBlcE36j1.1' 7z2Ye¢?ĖnAPg9ߎ_33,7=-gkfAP#PIQPql>]gfy@Zc
{,Q84n-=>C}`/%P4{xб*凉3cT\"q1k@}^>th$kpVme+T?NEeqlE=fJ0 L5{2szaَf.LÖ:
r䅆a#/4lF&a_	T_"<b
F"a
#JoUGL&$9WKj շ>3ZBgE1CVJ|j vC{5vh/LV5"3wd }f\OoZ
qmc5Fٴ\X6	tymZq1V))իz%AZ%,k9_I^ʯ%*(3
yNT_	LV;i2{g
łeDnq6V/+5 ՗UV.aL#տd.տGט}C%-SY\t&X8k\h`ӂo_\o{?'_/8<l5jY.o{Ԭ%~?"ְhL2
2+JZ%9
S\ D+WϊIYB7QDHz	'}P'>Uy6e mIEkD͔IO<u8=<%l]<Iȩ[2^N:v?qn-`zH6 ANZ>173~ę{Ce
 QhJ@2Y9W{OqƌF_]!ϫo ZJ%Z(t%KghhḧM!UL}YYLQ<GE-'r1v{5at%`AK.XopQ`eO.XqY,YueBYJڮ޳ Dӎ%ؼBïs]<9`rkD pb=@Rߛe%V$]PļjI;1,j ʻc.	KM`vatq &MzN+0 j!9;Lߐ9#`0~πc110!y]81]'XkbI LX0鸅v蘇ʗɤcH@a4F0N#1j$37_z[ǠE{fN:o ¤B?/j%6(!Jydf,OǺjM$h0`Rq1VR6x@h[_-l7zS.Lu2$Ԑ´Jz	4̏H{O"&]>ddD*I[(kt|.P֤,=a
H9Ƥ{,Kq$″^N'-?zR=em)R4ܸiilj\4i KA}g;Ke4wh[~"-nEj=

;'1j֬0lD{A^j>?RL <!'cF0肝:t7*ɁS^-w(Aufpʌ\L㤉3V:1X~8
!VQnF#Jo3Wq8ƣjYW\1QN;?iE>8Ƹ𙽭rol]
ɚѓN(QBGR15PU4jqywB=P,:y'	.cqqbWt1x#aq!E.Ht]'a)l(;GsoNc`zN!޻!`
*G+]qGI
Kc*֔,Jkzǻr%-09[d`kpt-k:e%Ɉ:Z08Y:()D>XC0:ؘt$#KK_BR @-"c>(s_.!xpKWy.LFnHhY1ΣKF (iͬ}"^Ծ7<tͳϋ1!~; "ax -6" ZEp	TYc-Wq{#bJZv,pڷg`o&В5V B<,!.7Њ
)Y<Mz{8P!~1tYyll'8<a"RwmsZGv(Z
kHȲEʲJMBb~bgĴk	uJ,;lEްwP6nIYnſT*UA׬ [7gTL:<"@hDt8 i@7'`Fai((il%(	G簢+:DIbV$#$[v@Id
:"W}aBDiV>Y=;Yދ@	7
5Iw.e}@=)Q;%LLc)Š8/$5Y=TcK俜|N0޳W0T
EpwKFs60 }A63zl
E_PćjJN_*\`Y!oB 7AI++`RohȺwJշkeQlIo48T4OU4,$P1sR!+L$1UL0j*xΫMzp QI5uSVҲ^]lXyG]l	)Q-fҝ&dL:Vsx26Ce.z}ý@E8>,W+5NnDZ`U;,Ji4j T=1Qh@࿏4r0R=E}$8dt7HA~ w44)j4 /Dlj=ı2&7gaDS8܃Bu Eha0kԓ?j&cR&V%

ռ"P@d
p+WE`݇oM	gЃ[7}wɠACdfȸke+h0mgamy@VEdG
*yH80 nUȍC!nzslܨ׌'7	ǽ-	m-9d:?g$:~Pp#{/'ޅqA׌4j]*DrjQ`1Iq`vŹw"ቂ9-/y۱&R5791%q\B,!*QVH&kc2]A)Z4(s]L)]4M4֐67"we`a
X"^P{WPMp .O+M5f7԰VGEY\3?Q#ܩDYaEH'k#PN,o-daOqi0ٰwh{?44hAWXUV6xTp	 ZA
@w tw(ȟڻ(
8r5?/K5yn!H5,/=a
85/]C.(iUh@8GAQhq;J܃Cx_q,Y"C܅ff!]ggtB>`C{(xX02Yl`)deF(/)t{荛o:yoG6{HSF!%#ѫ\o  ?sr_vw #?9c).\]=hnd|ڻr\wɳ+A	׍ڻ[xY*
odn2ZZt}wO(ȏbIĐl]`o.#usJN]PQ"wtlE V(q_YkR+{c/5z!"$g4W6dR9&c4a]gBb{7T?B^8= G
-7
4AIn."%J3H7\`19qL:F% %-#?Re6CaPkX/Q<F VR"0@-BGH^rǈUp++>"x8%=.ʁ@|اP#wشY0! ,аֽ㊡{]DΩ+ŞVW<bt, 㓇6q>f
i@
HݪX{R*K
9Y`X1:V\P5PP)I)2F-b@0Yu 誤;1Tx/j6j@^NQXz1opWBFV^}/Ua͍5c?yc8͕v]E(
)]1dvqs(c*;{.RJp{8bG"g]1k\Azu<H>.j/#pQEHJ©{1wL÷*{?t%<(S{NEBV%?`H{!B)R<g(p)2|( =@]/ǫ{!gFB-P}	(
WVC{2)Y3. L:v7G#N`QD=XޏT&[7EXV9C@xtܛ`-Kc>5]$YJr 'uS4  R\!=)B"^)Egej\[\())8N:vu]İ^8)D⤏8Bq	Ei,a7N"$'
4$%}(醎dNg*1 $L:vVڀF,YGeyi4V
c	},iA[KptcXv,fV]=a[&"8=z,ee
5q)mN^S$;&EDO0Qq {"x`'./4m>pKWDEP>82_|}rќ]=Z0<Mu窗QC;I!0Yk՗@v.bZ:5@fWS%w/Y1PR.>{{odT7L~zjISQmVu"{`Bj;!0s:NpR.yc1Gpv|HM u=Xac hu((ZٔgӪ]9#I+`TJau{IʬVzuTpEK[crǛe*Ya`?Ihu+I5ɩtFUJnłI'Ze1H,	z IGa ߗ5eT'Iqh)4ϼBC3޳Wux[~61KGL ysl<Ѭ3=pK!rȇIw855P|%'J:<QC&NcQ5e℻( Q٧9>s
ݯ097Ϊ˫;aX.Z܁ðza?6@%&H	!oX77]@H-	yzaqHyz=I(e
-cqtkD,
WV\'Wd-;{U	Ӓ=IǲC;ٱo7U^cktqI۵Ēl\BCcTypJˡDؘ&f/J	s+,ķ'*oV`Dcx{ñ\x\xI.X^@Cǀ|kSZ*E7,p.ᅆ Y$%q^({ÖPWU+i@x^
ĨZ/B -#P0
eo¿@T.p25G8r9.-&%jS~w
$PBf酇T!3٣8S^\4}ߥ{@2&+-a(?~K7c+Q_:0JH&^@(i0ū	>r1ض"n$eMmO4ѡcQ/|TAҪd,; p&i?w0pTe4baKB*1'g%',sjEnE}Y+pq-Y#n']i-teKsR6	(094zK< .<Y`dj#iG8\d1_ZЍ%kKxRy4Pmٖl4>xpڪ+
E~N&P(,5ͲbVDeҀ$^7ۡc+ǝjyic9rM憥Z+kI1l3T;eW.*1CC}ٺ@X_r~.c
Yje^pZ
yƏED?32f/Nku*},ޤ	ڳPi.LFH,{!>)XhȆBBΉ5Ҁs
&1MD@ZFP$t}{ӊ3H.As5DmӸYCS;7-)}]߭T+i9j~N]p}Z<y$ ]JIˏ2zZsz;/ocEa.ˀBCC'˽J()v{؇6/<i
RpM.cb$GHI2#e>Yуge1ք'*j
9gsn(OFpmiϽ-`If;d}hQE }0H,wyd79e"V{VI'NT"T9 `
5`1ʿ	4p! 5&
 dA Q"5Nq@Jjwd])B9RԔ;RDH9$#12yi.	P(L,-΢3dt`
S6C?DKDdOaP)igpRw!X :v>R
U13vxWMIM垥2Rumjb9%x=KeYr(
PQ!­qR1ұ(tN
5B'VaZ:>.Hr7A9m$@U0$8=M	
iV!SKӢu,OoUEɥW4*>zo<NQ_FX9!<D$NRqs#q6N|DXK,UD{!eah
<qD@&K<mLGW*;ք(8CA;`2%:V6Qұ*oi,D1U'C`wPR^tEn&j9%O7.@*Xveo)FU&kQ*X@r2]3
L!_f&x*|i\?٠GGs4Qa(aq|F鑎Y@07$6eg~$xtXhoAp/>+JZwm45߽=EL2gm4G]jt7˗%cgZ)[NzwʣER=Fy<2vfO]4Dɐ}V*iR
ZY|%?-+8Vurl#o1HP}$!A]H:ئK--]s|TI7d3~+c2]<|	;cI\~+SD=?j/)DұZsgܳ\_jl3+ߩM:6me~wan CD19sJX*mQy{K%Πp; g O@@mJH
?z1bz&/9CiHT*Bk(@i
6eInlRұ03]7<\5?B ۦA6KP&>Q	\P7wtb/zQ:%rC]A1ܷMD]KBMlm+[ބ-O>u.㞭ͲT5!77V:iǐHf-9QVn	98kOH;w;&e.z?<[sIKݻFyT+E7@0<xz/z:ԽK!W"a0ՉwIp>{]qi\5}Vdn\"'cow= "kdR{(I;a7QSrhH\Io&9aZA4)
L`!z28gKhУ&- |Tb,?w)A5&,uTh[hHdǄHK(i̔Jaܽ{(q9g~4)
"U%W1fO[d+ԷWp+	R4UczX,]EdD,xUܺfbEZ8N:IW	}]Et5CA _smQn)'>xd	!e\ˈ^#<?F-2ڳ4.
#}"u$I2FwQ,OMjQ#;=RuX#OJF1Go=</YweX&|pmmdQ'o1Lw5܎&kƜ$whE95(Iuvc\]3q Gxs9i1[ mQ0 X-"נXz! eQ?NEOQp)Yq {
(IE k/WiH.=3i+&&H| OLdVpl= <	OM`w8x$^LF:	Q ,A};+sӰh`FxR] 6ݺb)n":6{HψNdsU6X9%nIx!vf@ylV$cMT`ߥ#O>i,0Z@w'ٛ7G߭r2/:яc\<"vs1dm@Cʹ@{vT7b
e ,8,ۂM,M(5rThĭLVanJ%Q}AE')u -eItlrH>%r(#|\h*2NN7
ػrr_]8阎!PmIocI4bQ8-	*dsi*!|S! iWҁ30JEĽrq q^{ƔbZ@<`2A`t|r3s#Q6ccd2ČHCE#IAWFqzK"UC8~q%hKr+qqK
+[XVLZA
^A䢻hAN{Pʠ`%,
o8ߵtұ<bcWR &K`W1	Mg
WxYX׳#9rb̄---
-- Implements functionality related to Server Message Block (SMB, an extension
-- of CIFS) traffic, which is a Windows protocol.
--
-- SMB traffic is normally sent to/from ports 139 or 445 of Windows systems. Other systems
-- implement SMB as well, including Samba and a lot of embedded devices. Some of them implement
-- it properly and many of them not. Although the protocol has been documented decently
-- well by Samba and others, many 3rd party implementations are broken or make assumptions.
-- Even Samba's and Windows' implementations aren't completely compatible. As a result,
-- creating an implementation that accepts everything is a bit of a minefield. Microsoft's
-- extensive documentation is available at the following URLs:
-- * SMB: http://msdn.microsoft.com/en-us/library/cc246231(v=prot.13).aspx
-- * CIFS: http://msdn.microsoft.com/en-us/library/ee442092(v=prot.13).aspx
--
-- Where possible, this implementation, since it's intended for scanning, will attempt to
-- accept any invalid implementations it can, and fail gracefully if it can't. This has
-- been tested against a great number of weird implementations, and it now works against
-- all of them.
--
-- The intention of this library is to eventually handle all aspects of the SMB protocol.
-- That being said, I'm only implementing the pieces that I (Ron Bowes) need. If you
-- require something more, let me know and I'll put it on my todo list.
--
-- A programmer using this library should already have some knowledge of the SMB protocol,
-- although a lot isn't necessary. You can pick up a lot by looking at the code. The basic
-- login/logoff is this:
--
-- <code>
-- [connect]
-- C->S SMB_COM_NEGOTIATE
-- S->C SMB_COM_NEGOTIATE
-- C->S SMB_COM_SESSION_SETUP_ANDX
-- S->C SMB_COM_SESSION_SETUP_ANDX
-- C->S SMB_COM_TREE_CONNECT_ANDX
-- S->C SMB_COM_TREE_CONNECT_ANDX
-- ...
-- C->S SMB_COM_TREE_DISCONNECT
-- S->C SMB_COM_TREE_DISCONNECT
-- C->S SMB_COM_LOGOFF_ANDX
-- S->C SMB_COM_LOGOFF_ANDX
-- [disconnect]
-- </code>
--
-- In terms of functions here, the protocol is:
--
-- <code>
-- status, smbstate = smb.start(host)
-- status, err      = smb.negotiate_protocol(smbstate, {})
-- status, err      = smb.start_session(smbstate, {})
-- status, err      = smb.tree_connect(smbstate, path, {})
-- ...
-- status, err      = smb.tree_disconnect(smbstate)
-- status, err      = smb.logoff(smbstate)
-- status, err      = smb.stop(smbstate)
-- </code>
--
-- The <code>stop</code> function will automatically call tree_disconnect and logoff,
-- cleaning up the session, if it hasn't been done already.
--
-- To initially begin the connection, there are two options:
--
-- 1) Attempt to start a raw session over 445, if it's open.
--
-- 2) Attempt to start a NetBIOS session over 139. Although the
--    protocol's the same, it requires a <code>session request</code> packet.
--    That packet requires the computer's name, which is requested
--    using a NBSTAT probe over UDP port 137.
--
-- Once it's connected, a <code>SMB_COM_NEGOTIATE</code> packet is sent, requesting the protocol
-- "NT LM 0.12", which is the most commonly supported one. Among other things, the server's
-- response contains the host's security level, the system time, and the computer/domain name.
-- Some systems will refuse to use that protocol and return "-1" or "1" instead of 0. If that's
-- detected, we kill the connection (because the protocol following won't work).
--
-- If that's successful, <code>SMB_COM_SESSION_SETUP_ANDX</code> is sent. It is essentially the logon
-- packet, where the username, domain, and password are sent to the server for verification.
-- The username and password are generally picked up from the program parameters, which are
-- set when running a script, or from the registry where it can be set by other scripts (for
-- example, <code>smb-brute.nse</code>). However, they can also be passed as parameters to the
-- function, which will override any other username/password set.
--
-- If a username and password are set, they are used for the first login attempt. If a login fails,
-- or they weren't set, a connection as the 'GUEST' account with a blank password is attempted. If
-- that fails, then a NULL session is established, which should always work. The username/password
-- will give the highest access level, GUEST will give lower access, and NULL will give the lowest
-- (often, NULL will give no access).
--
-- The actual login protocol used by <code>SMB_COM_SESSION_SETUP_ANDX</code> is explained in detail
-- in <code>smbauth.lua</code>.
--
-- Thanks go to Christopher R. Hertel and his book Implementing CIFS, which
-- taught me everything I know about Microsoft's protocols. Additionally, I used Samba's
-- list of error codes for my constants. Although I don't believe they would be covered
-- by GPL, since they're public now anyways, but I'm not a lawyer and, if somebody feels
-- differently, let me know and we can sort this out.
--
-- Scripts that use this module can use the script arguments listed below
-- example of using these script arguments:
-- <code>
-- nmap --script=smb-<script>.nse --script-args=smbuser=ron,smbpass=iagotest2k3,smbbasic=1,smbsign=force <host>
-- </code>
--
-- @args  smbbasic    Forces the authentication to use basic security, as opposed to "extended security".
--                   Against most modern systems, extended security should work, but there may be cases
--                   where you want to force basic. There's a chance that you'll get better results for
--                   enumerating users if you turn on basic authentication.
-- @args smbsign      Controls whether or not server signatures are checked in SMB packets. By default, on Windows,
--                   server signatures aren't enabled or required. By default, this library will always sign
--                   packets if it knows how, and will check signatures if the server says to. Possible values are:
-- * <code>force</code>:      Always check server signatures, even if server says it doesn't support them (will
--                           probably fail, but is technically more secure).
-- * <code>negotiate</code>: [default] Use signatures if server supports them.
-- * <code>ignore</code>:    Never check server signatures. Not recommended.
-- * <code>disable</code>:   Don't send signatures, at all, and don't check the server's. not recommended.
--                   More information on signatures can be found in <code>smbauth.lua</code>.
-- @args smbport      Override the default port choice. If <code>smbport</code> is open, it's used. It's assumed
--                   to be the same protocol as port 445, not port 139. Since it probably isn't possible to change
--                   Windows' ports normally, this is mostly useful if you're bouncing through a relay or something.
-- @args randomseed   Set to a value to change the filenames/service names that are randomly generated.
--
-- @author Ron Bowes <ron@skullsecurity.net>
-- @copyright Same as Nmap--See https://nmap.org/book/man-legal.html
-----------------------------------------------------------------------
local asn1 = require "asn1"
local datetime = require "datetime"
local io = require "io"
local math = require "math"
local match = require "match"
local netbios = require "netbios"
local nmap = require "nmap"
local smbauth = require "smbauth"
local stdnse = require "stdnse"
local string = require "string"
local table = require "table"
local tableaux = require "tableaux"
local unicode = require "unicode"
local smb2 = require "smb2"
_ENV = stdnse.module("smb", stdnse.seeall)

-- These arrays are filled in with constants at the bottom of this file
command_codes = {}
command_names = {}
status_codes = {}
status_names = {}
filetype_codes = {}
filetype_names = {}

local TIMEOUT = 10000

---Wrapper around <code>smbauth.add_account</code>.
function add_account(host, username, domain, password, password_hash, hash_type, is_admin)
  smbauth.add_account(host, username, domain, password, password_hash, hash_type, is_admin)
end

---Wrapper around <code>smbauth.get_account</code>.
function get_account(host)
  return smbauth.get_account(host)
end
---Create an 'overrides' table
function get_overrides(username, domain, password, password_hash, hash_type, overrides)
  if(not(overrides)) then
    return {username=username, domain=domain, password=password, password_hash=password_hash, hash_type=hash_type}
  else
    overrides['username'] = username
    overrides['domain'] = domain
    overrides['password'] = password
    overrides['password_hash'] = password_hash
    overrides['hash_type'] = hash_type
  end
end

---Get an 'overrides' table for the anonymous user
--
--@param overrides [optional] A base table of overrides. The appropriate fields will be added.
function get_overrides_anonymous(overrides)
  if(not(overrides)) then
    return {username='', domain='', password='', password_hash=nil, hash_type='none'}
  else
    overrides['username'] = ''
    overrides['domain'] = ''
    overrides['password'] = ''
    overrides['password_hash'] = ''
    overrides['hash_type'] = 'none'
  end
end

---Convert a status number from the SMB header into a status name, returning an error message (not nil) if
-- it wasn't found.
--
--@param status The numerical status.
--@return A string representing the error. Never nil.
function get_status_name(status)

  if(status_names[status] == nil) then
    -- If the name wasn't found in the array, do a linear search on it
    for i, v in pairs(status_names) do
      if(v == status) then
        return i
      end
    end

    return string.format("NT_STATUS_UNKNOWN (0x%08x)", status)
  else
    return status_names[status]
  end
end


--- Determines whether or not SMB checks are possible on this host, and, if they are,
--  which port is best to use. This is how it decides:
--
-- * If port tcp/445 is open, use it for a raw connection
-- * Otherwise, if ports tcp/139 and udp/137 are open, do a NetBIOS connection. Since UDP scanning isn't default, we're also ok with udp/137 in an unknown state.
--
--@param host The host object.
--@return The port number to use, or nil if we don't have an SMB port
function get_port(host)
  local port_u137 = nmap.get_port_state(host, {number=137, protocol="udp"})
  local port_t139 = nmap.get_port_state(host, {number=139, protocol="tcp"})
  local port_t445 = nmap.get_port_state(host, {number=445, protocol="tcp"})
  local custom_port = nil

  if(nmap.registry.args.smbport ~= nil) then
    custom_port = nmap.get_port_state(host, {number=tonumber(nmap.registry.args.smbport), protocol="tcp"})
  end

  -- Try a user-defined port first
  if(custom_port ~= nil and custom_port.state == "open") then
    return custom_port.number
  end

  if(port_t445 ~= nil and port_t445.state == "open") then
    -- tcp/445 is open, we're good
    return 445
  end

  if(port_t139 ~= nil and port_t139.state == "open") then
    -- tcp/139 is open, check uf udp/137 is open or unknown
    if(port_u137 == nil or port_u137.state == "open" or port_u137.state == "open|filtered") then
      return 139
    end
  end

  return nil
end

---Turn off extended security negotiations for this connection.
--
-- There are a few reasons you might want to do that, the main ones being that
-- extended security is going to be marginally slower and it's not going to
-- give the same level of information in some cases (namely, it doesn't present
-- the server's name).
--@param smb The SMB state table.
function disable_extended(smb)
  smb['extended_security'] = false
end

--- Begins a SMB session, automatically determining the best way to connect.
--
-- @param host The host object
-- @return (status, smb) if the status is true, result is the newly crated smb object;
--         otherwise, socket is the error message.
function start(host)
  local port = get_port(host)
  local status, result
  local state = {}

  state['uid']      = 0
  state['tid']      = 0
  state['mid']      = 1
  state['pid']      = math.random(32766) + 1
  state['host']     = host
  state['ip']       = host.ip
  state['sequence'] = -1

  -- Check whether or not the user requested basic authentication
  if(stdnse.get_script_args( "smbbasic" )) then
    state['extended_security'] = false
  else
    state['extended_security'] = true
  end

  -- Store the name of the server
  local nbcache_mutex = nmap.mutex("Netbios lookup mutex")
  nbcache_mutex "lock"
  if ( not(host.registry['netbios_name']) ) then
    status, result = netbios.get_server_name(host.ip)
    if(status == true) then
      host.registry['netbios_name'] = result
      state['name'] = result
    end
  else
    stdnse.debug2("SMB: Resolved netbios name from cache")
    state['name'] = host.registry['netbios_name']
  end
  nbcache_mutex "done"

  stdnse.debug2("SMB: Starting SMB session for %s (%s)", host.name, host.ip)

  if(port == nil) then
    return false, "SMB: Couldn't find a valid port to check"
  end

  -- Initialize the accounts for logging on
  smbauth.init_account(host)

  if(port ~= 139) then
    status, state['socket'] = start_raw(host, port)
    state['port'] = port

    if(status == false) then
      return false, state['socket']
    end
    return true, state

  else
    status, state['socket'] = start_netbios(host, port)
    state['port'] = port
    if(status == false) then
      return false, state['socket']
    end
    return true, state

  end

  return false, "SMB: Couldn't find a valid port to check"
end

---Initiates a SMB connection over whichever port it can, then optionally sends
-- the common initialization packets.
--
-- Note that each packet depends on the previous one, so if you want to go all
-- the way up to create_file, you have to set all parameters.
--
-- If anything fails, we back out of the connection and return an error, so the
-- calling function doesn't have to call smb.stop().
--
--@param host The host object.
--@param bool_negotiate_protocol [optional] If 'true', send the protocol
--                               negotiation. Default: false.
--@param bool_start_session [optional] If 'true', start the session. Default:
--                          false.
--@param str_tree_connect [optional] The tree to connect to, if given (eg.
--                        "IPC$" or "C$"). If not given, packet isn't sent.
--@param str_create_file [optional] The path and name of the file (or pipe)
--                       that's created, if given. If not given, packet isn't
--                       sent.
--@param overrides [optional] A table of overrides (for, for example, username,
--                 password, etc.) to pass to all functions.
--@param bool_disable_extended [optional] If set to true, disables extended
--                             security negotiations.
function start_ex(host, bool_negotiate_protocol, bool_start_session, str_tree_connect, str_create_file, bool_disable_extended, overrides)
  local smbstate
  local status, err

  -- Make sure we have overrides
  overrides = overrides or {}

  -- Begin the SMB session
  status, smbstate = start(host)
  if(status == false) then
    return false, smbstate
  end

  -- Disable extended security if it was requested
  if(bool_disable_extended == true) then
    disable_extended(smbstate)
  end

  if(bool_negotiate_protocol == true) then
    -- Negotiate the protocol
    status, err = negotiate_protocol(smbstate, overrides)
    if(status == false) then
      stop(smbstate)
      return false, err
    end

    if(bool_start_session == true) then
      -- Start up a session
      status, err = start_session(smbstate, overrides)
      if(status == false) then
        stop(smbstate)
        return false, err
      end

      if(str_tree_connect ~= nil) then
        -- Connect to share
        status, err = tree_connect(smbstate, str_tree_connect, overrides)
        if(status == false) then
          stop(smbstate)
          return false, err
        end

        if(str_create_file ~= nil) then
          -- Try to connect to requested pipe
          status, err = create_file(smbstate, str_create_file, overrides)
          if(status == false) then
            stop(smbstate)
            return false, err
          end
        end
      end
    end
  end

  -- Return everything
  return true, smbstate
end

--- Kills the SMB connection and closes the socket.
--
--  In addition to killing the connection, this function will log off the user and disconnect
--  the connected tree, if possible.
--
--@param smb    The SMB object associated with the connection
--@return (status, result) If status is false, result is an error message. Otherwise, result
--        is undefined.
function stop(smb)

  if(smb['tid'] ~= 0) then
    tree_disconnect(smb)
  end

  if(smb['uid'] ~= 0) then
    logoff(smb)
  end

  stdnse.debug2("SMB: Closing socket")
  if(smb['socket'] ~= nil) then
    local status, err = smb['socket']:close()

    if(status == false) then
      return false, "SMB: Failed to close socket: " .. err
    end
  end

  return true
end

--- Begins a raw SMB session, likely over port 445. Since nothing extra is required, this
--  function simply makes a connection and returns the socket.
--
--@param host The host object to check.
--@param port The port to use (most likely 445).
--@return (status, socket) if status is true, result is the newly created socket.
--        Otherwise, socket is the error message.
function start_raw(host, port)
  local status, err
  local socket = nmap.new_socket()

  socket:set_timeout(TIMEOUT)
  status, err = socket:connect(host, port, "tcp")

  if(status == false) then
    return false, "SMB: Failed to connect to host: " .. err
  end

  return true, socket
end

--- This function will take a string like "a.b.c.d" and return "a", "a.b", "a.b.c", and "a.b.c.d".
--
--  This is used for discovering NetBIOS names. If a NetBIOS name is unknown, the substrings of the
--  DNS name can be used in this way.
--
--@param name The name to take apart
--@return An array of the sub names
local function get_subnames(name)
  local i = -1
  local list = {}

  repeat
    local subname = name

    i = string.find(name, "[.]", i + 1)
    if(i ~= nil) then
      subname = string.sub(name, 1, i - 1)
    end

    list[#list + 1] = string.upper(subname)

  until i == nil

  return list
end

--- Begins a SMB session over NetBIOS.
--
-- This requires a NetBIOS Session Start message to be sent first, which in
-- turn requires the NetBIOS name. The name can be provided as a parameter, or
-- it can be automatically determined.
--
-- Automatically determining the name is interesting, to say the least. Here
-- are the names it tries, and the order it tries them in:
-- * The name the user provided, if present
-- * The name pulled from NetBIOS (udp/137), if possible
-- * The generic name "*SMBSERVER"
-- * Each subset of the domain name (for example, scanme.insecure.org would
--   attempt "scanme", "scanme.insecure", and "scanme.insecure.org")
--
-- This whole sequence is a little hackish, but it's the standard way of doing
-- it.
--
--@param host The host object to check.
--@param port The port to use (most likely 139).
--@param name [optional] The NetBIOS name of the host. Will attempt to
--            automatically determine if it isn't given.
--@return (status, socket) if status is true, result is the port
--        Otherwise, socket is the error message.
function start_netbios(host, port, name)
  local i
  local status, err
  local pos, result, flags, length
  local socket = nmap.new_socket()

  -- First, populate the name array with all possible names, in order of significance
  local names = {}

  -- Use the name parameter
  if(name ~= nil) then
    names[#names + 1] = name
  end

  -- Get the name of the server from NetBIOS
  status, name = netbios.get_server_name(host.ip)
  if(status == true) then
    names[#names + 1] = name
  end

  -- "*SMBSERVER" is a special name that any server should respond to
  names[#names + 1] = "*SMBSERVER"

  -- If all else fails, use each substring of the DNS name (this is a HUGE hack, but is actually
  -- a recommended way of doing this!)
  if(host.name ~= nil and host.name ~= "") then
    local new_names = get_subnames(host.name)
    for i = 1, #new_names, 1 do
      names[#names + 1] = new_names[i]
    end
  end

  -- This loop will try all the NetBIOS names we've collected, hoping one of them will work. Yes,
  -- this is a hackish way, but it's actually the recommended way.
  i = 1
  repeat

    -- Use the current name
    name = names[i]

    -- Some debug information
    stdnse.debug1("SMB: Trying to start NetBIOS session with name = '%s'", name)
    -- Request a NetBIOS session
    local session_request = string.pack(">BBI2zz",
      0x81,                        -- session request
      0x00,                        -- flags
      0x44,                        -- length
      netbios.name_encode(name),   -- server name
      netbios.name_encode("NMAP")  -- client name
      );

    stdnse.debug3("SMB: Connecting to %s", host.ip)
    socket:set_timeout(TIMEOUT)
    status, err = socket:connect(host, port, "tcp")
    if(status == false) then
      socket:close()
      return false, "SMB: Failed to connect: " .. err
    end

    -- Send the session request
    stdnse.debug3("SMB: Sending NetBIOS session request with name %s", name)
    status, err = socket:send(session_request)
    if(status == false) then
      socket:close()
      return false, "SMB: Failed to send: " .. err
    end
    socket:set_timeout(TIMEOUT)

    -- Receive the session response
    stdnse.debug3("SMB: Receiving NetBIOS session response")
    status, result = socket:receive_buf(match.numbytes(4), true);
    if(status == false) then
      socket:close()
      return false, "SMB: Failed to close socket: " .. result
    end
    result, flags, length, pos = string.unpack(">BBI2", result)

    -- Check for a positive session response (0x82)
    if result == 0x82 then
      stdnse.debug3("SMB: Successfully established NetBIOS session with server name %s", name)
      return true, socket
    end

    -- If the session failed, close the socket and try the next name
    stdnse.debug1("SMB: Session request failed, trying next name")
    socket:close()

    -- Try the next name
    i = i + 1

  until i > #names

  -- We reached the end of our names list
  stdnse.debug1("SMB: None of the NetBIOS names worked!")
  return false, "SMB: Couldn't find a NetBIOS name that works for the server. Sorry!"
end

--- Creates a string containing a SMB packet header. The header looks like this:
--
--<code>
-- --------------------------------------------------------------------------------------------------
-- | 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9  8  7  6  5  4  3  2  1  0 |
-- --------------------------------------------------------------------------------------------------
-- |         0xFF           |          'S'          |        'M'            |         'B'           |
-- --------------------------------------------------------------------------------------------------
-- |        Command         |                             Status...                                 |
-- --------------------------------------------------------------------------------------------------
-- |    ...Status           |        Flags          |                    Flags2                     |
-- --------------------------------------------------------------------------------------------------
-- |                    PID_high                    |                  Signature.....               |
-- --------------------------------------------------------------------------------------------------
-- |                                        ....Signature....                                       |
-- --------------------------------------------------------------------------------------------------
-- |              ....Signature                     |                    Unused                     |
-- --------------------------------------------------------------------------------------------------
-- |                      TID                       |                     PID                       |
-- --------------------------------------------------------------------------------------------------
-- |                      UID                       |                     MID                       |
-- -------------------------------------------------------------------------------------------------
--</code>
--
-- All fields are, incidentally, encoded in little endian byte order.
--
-- For the purposes here, the program doesn't care about most of the fields so they're given default
-- values. The "command" field is the only one we ever have to set manually, in my experience. The TID
-- and UID need to be set, but those are stored in the smb state and don't require user intervention.
--
--@param smb     The smb state table.
--@param command The command to use.
--@param overrides The overrides table. Keep in mind that overriding things like flags is generally a very bad idea, unless you know what you're doing.
--@return A binary string containing the packed packet header.
function smb_encode_header(smb, command, overrides)
  -- Make sure we have an overrides array
  overrides = overrides or {}

  -- Used for the header
  local sig = "\xFFSMB"

  -- Pretty much every flags is deprecated. We set these two because they're required to be on.
  local flags  = (0x10 | 0x08) -- SMB_FLAGS_CANONICAL_PATHNAMES | SMB_FLAGS_CASELESS_PATHNAMES
  -- These flags are less deprecated. We negotiate 32-bit status codes and long names. We also don't include Unicode, which tells
  -- the server that we deal in ASCII.
  local flags2 = (0x4000 | 0x2000 | 0x0040 | 0x0001) -- SMB_FLAGS2_32BIT_STATUS | SMB_FLAGS2_EXECUTE_ONLY_READS | SMB_FLAGS2_IS_LONG_NAME | SMB_FLAGS2_KNOWS_LONG_NAMES

  -- Unless the user's disabled the security signature, add it
  if(nmap.registry.args.smbsign ~= "disable") then
    flags2 = (flags2 | 0x0004) -- SMB_FLAGS2_SECURITY_SIGNATURE
  end


  if(smb['extended_security'] == true) then
    flags2 = (flags2 | 0x0800) -- SMB_EXTENDED_SECURITY
  end

  -- TreeID should never ever be 'nil', but it seems to happen once in awhile so print an error
  if(smb['tid'] == nil) then
    return false, string.format("SMB: ERROR: TreeID value was set to nil on host %s", smb['ip'])
  end

  local header = string.pack("<BBBBB I4 B I2 I2 I8 I2 I2 I2 I2 I2",
    sig:byte(1),  -- Header
    sig:byte(2),  -- Header
    sig:byte(3),  -- Header
    sig:byte(4),  -- Header
    command,      -- Command
    (overrides['status'] or 0),        -- status
    (overrides['flags'] or flags),     -- flags
    (overrides['flags2'] or flags2),   -- flags2
    (overrides['pid_high'] or 0),      -- extra (pid_high)
    (overrides['signature'] or 0),     -- extra (signature)
    (overrides['extra'] or 0),         -- extra (unused)
    (overrides['tid'] or smb['tid']),  -- tid
    (overrides['pid'] or smb['pid']),  -- pid
    (overrides['uid'] or smb['uid']),  -- uid
    (overrides['mid'] or smb['mid'])   -- mid
    )

  return header
end

--- Converts a string containing the parameters section into the encoded
--  parameters string.
--
-- The encoding is simple:
-- * (1 byte)   The number of 2-byte values in the parameters section
-- * (variable) The parameter section
-- This is automatically done by <code>smb_send</code>.
--
-- @param parameters The parameters section.
-- @param overrides The overrides table. The only thing possible to override here is the length.
-- @return The encoded parameters.
local function smb_encode_parameters(parameters, overrides)
  -- Make sure we have an overrides array
  overrides = overrides or {}

  return string.pack("<B", overrides['parameters_length'] or (#parameters / 2)) .. parameters
end

--- Converts a string containing the data section into the encoded data string.
--
-- The encoding is simple:
-- * (2 bytes)  The number of bytes in the data section
-- * (variable) The data section
-- This is automatically done by <code>smb_send</code>.
--
-- @param data The data section.
-- @param overrides The overrides table. The only thing possible to override here is the length.
-- @return The encoded data.
local function smb_encode_data(data, overrides)
  -- Make sure we have an overrides array
  overrides = overrides or {}

  return string.pack("<I2", overrides['data_length'] or #data) .. data
end

---Sign the message, if possible. This is done by replacing the signature with the sequence
-- number, creating a hash, then putting that hash in the signature location.
--@param smb  The smb state object.
--@param body The body of the packet that's being signed.
--@return The body of the packet, with the signature in place.
local function message_sign(smb, body)
  smb['sequence'] = smb['sequence'] + 1

  if(smb['mac_key'] == nil) then
    stdnse.debug3("SMB: Not signing message (missing mac_key)")
    return body
  elseif(nmap.registry.args.smbsign == "disable") then
    stdnse.debug3("SMB: Not signing message (disabled by user)")

    return body
  end

  -- Convert the sequence number to a string
  local sequence = string.pack("<I8", smb['sequence'])
  -- Create a new string, with the sequence number in place
  local new_packet = string.sub(body, 1, 14) .. sequence .. string.sub(body, 23)
  -- Calculate the signature
  local signature = smbauth.calculate_signature(smb['mac_key'], new_packet)

  return string.sub(body, 1, 14) .. signature .. string.sub(body, 23)
end

---Check the signature of the message.
--
-- This is the opposite of <code>message_sign</code>, and works the same way
-- (replaces the signature with the sequence number, calculates hash, checks)
--@param smb  The smb state object.
--@param body The body of the packet that's being checked.
--@return A true/false value -- true if the packet was signed properly, false if it wasn't.
local function message_check_signature(smb, body)
  smb['sequence'] = smb['sequence'] + 1

  if(smb['mac_key'] == nil) then
    stdnse.debug3("SMB: Not signing message (missing mac_key)")
    return true
  elseif(nmap.registry.args.smbsign ~= "force" and (smb['security_mode'] & 0x0A) ~= 0) then
    stdnse.debug3("SMB: Not signing message (server doesn't support it -- default)")
    return true
  elseif(nmap.registry.args.smbsign == "disable" or nmap.registry.args.smbsign == "ignore") then
    stdnse.debug3("SMB: Not signing message (disabled by user)")
    return true
  end

  -- Pull out the signature that they used
  local signature  = string.sub(body, 15, 22)

  -- Turn the sequence into a string
  local sequence   = string.pack("<I8", smb['sequence'])
  -- Create a new string, with the sequence number in place
  local new_packet = string.sub(body, 1, 14) .. sequence .. string.sub(body, 23)

  -- Calculate the proper signature
  local real_signature = smbauth.calculate_signature(smb['mac_key'], new_packet)

  -- Validate the signature
  return signature == real_signature
end

--- Prepends the NetBIOS header to the packet, which is essentially the length, encoded
--  in 4 bytes of big endian, and sends it out.
--
--  The length field is actually 17 or 24 bits wide, depending on whether or
--  not we're using raw, but that shouldn't matter.
--
--@param smb        The SMB object associated with the connection
--@param header     The header, encoded with <code>smb_get_header</code>.
--@param parameters The parameters.
--@param data       The data.
--@param overrides  Overrides table.
--@return (result, err) If result is false, err is the error message. Otherwise, err is
--        undefined
function smb_send(smb, header, parameters, data, overrides)
  overrides = overrides or {}

  local encoded_parameters = smb_encode_parameters(parameters, overrides)
  local encoded_data       = smb_encode_data(data, overrides)
  local body               = header .. encoded_parameters .. encoded_data
  local status, err

  -- Calculate the message signature
  body = message_sign(smb, body)

  local out = string.pack(">s4", body)


  stdnse.debug3("SMB: Sending SMB packet (len: %d)", #out)
  status, err = smb['socket']:send(out)

  if not status then
    stdnse.debug1("SMB: Sending packet failed.")
  end

  return status, err
end

--- Reads the next packet from the socket, and parses it into the header, parameters,
--  and data.
--
--@param smb The SMB object associated with the connection
--@param read_data [optional] This function will read the data section if and only if
--       this value is true. This is a workaround for a bug in the tree connect packet,
--       where the length is set incorrectly. Default: true.
--@return (status, header, parameters, data) If status is true, the header,
--        parameters, and data are all the raw arrays (with the lengths already
--        removed). If status is false, header contains an error message and parameters/
--        data are undefined.
function smb_read(smb, read_data)
  local pos, netbios_data, netbios_length, length, header, parameter_length, parameters, data_length, data

  stdnse.debug3("SMB: Receiving SMB packet")

  -- Receive the response -- we make sure to receive at least 4 bytes, the length of the NetBIOS length
  smb['socket']:set_timeout(TIMEOUT)

  -- attempt to read the Netbios header
  local status, netbios_data = smb['socket']:receive_buf(match.numbytes(4), true);

  -- Make sure the connection is still alive
  if not status then
    return false, "SMB: Failed to receive bytes: " .. netbios_data
  end

  -- The length of the packet is 4 bytes of big endian (for our purposes).
  -- The NetBIOS header is 24 bits, big endian
  netbios_length, pos = string.unpack(">I4", netbios_data)
  -- Make the length 24 bits
  netbios_length = (netbios_length & 0x00FFFFFF)

  -- The total length is the netbios_length, plus 4 (for the length itself)
  length = netbios_length + 4

  local status, smb_data = smb['socket']:receive_buf(match.numbytes(netbios_length), true)

  -- Make sure the connection is still alive
  if not status then
    return false, "SMB: Failed to receive bytes: " .. smb_data
  end

  local result = netbios_data .. smb_data
  if(#result ~= length) then
    stdnse.debug1("SMB: ERROR: Received wrong number of bytes, there will likely be issues (received %d, expected %d)", #result, length)
    return false, string.format("SMB: ERROR: Didn't receive the expected number of bytes; received %d, expected %d. This will almost certainly cause some errors.", #result, length)
  end

  -- Check the message signature (ignoring the first four bytes, which are the netbios header)
  local good_signature = message_check_signature(smb, string.sub(result, 5))
  if(good_signature == false) then
    return false, "SMB: ERROR: Server returned invalid signature"
  end

  local header_format = "<c32 B"
  if (#result - pos + 1) < string.packsize(header_format) then
    return false, "SMB: ERROR: Server returned less data than needed for header"
  end
  header, parameter_length, pos = string.unpack("<c32 B", result, pos)

  -- Double the length parameter, since parameters are two-byte values.
  if (length - pos + 1) < (parameter_length * 2) then
    return false, "SMB: ERROR: parameter_length greater than response length"
  end
  parameters, pos = string.unpack(("<c%d"):format(parameter_length*2), result, pos)

  -- The data length is a 2-byte value.
  data_length, pos = string.unpack("<I2", result, pos)

  -- Read that many bytes of data.
  if(read_data == nil or read_data == true) then
    if (length - pos + 1) < data_length then
      return false, "SMB: ERROR: data_length greater than response length"
    end
    data = string.unpack("c" .. data_length, result, pos)
  else
    data = nil
  end

  stdnse.debug3("SMB: Received %d bytes", #result)
  return true, header, parameters, data
end

---
-- Negotiates SMBv1 connections
--
-- Sends the following:
-- * List of known protocols
--
-- This function adds to <code>smb</code>:
-- * 'security_mode'    Whether or not to use cleartext passwords, message signatures, etc.
-- * 'max_mpx'          Maximum number of multiplexed connections
-- * 'max_vc'           Maximum number of virtual circuits
-- * 'max_buffer'       Maximum buffer size
-- * 'max_raw_buffer'   Maximum buffer size for raw connections (considered obsolete)
-- * 'session_key'      A value that's basically just echoed back
-- * 'capabilities'     The server's capabilities
-- * 'time'             The server's time (in UNIX-style seconds since 1970)
-- * 'date'             The server's date in a user-readable format
-- * 'timezone'         The server's timezone, in hours from UTC
-- * 'timezone_str'     The server's timezone, as a string
-- * 'server_challenge' A random string used for challenge/response
-- * 'domain'           The server's primary domain or workgroup
-- * 'server'           The server's name
--
-- @param smb The SMB object associated with the connection.
-- @param overrides Overrides table.
-- @return Boolean status
-- @return The negotiated dialect in human readable form or an error message.
---
function negotiate_v1(smb, overrides)
  local header = smb_encode_header(smb, command_codes['SMB_COM_NEGOTIATE'], overrides)
  -- Make sure we have overrides
  overrides = overrides or {}

  -- Parameters are blank
  local parameters = ""
  local data = string.pack("<BzBz", 2, (overrides['dialect'] or "NT LM 0.12"), 2, "")

  -- Send the negotiate request
  stdnse.debug2("SMB: Sending SMB_COM_NEGOTIATE")
  local result, err = smb_send(smb, header, parameters, data, overrides)
  if(result == false) then
    return false, err
  end
  -- Read the result
  local status, header, parameters, data = smb_read(smb)
  if(status ~= true) then
    return false, header
  end

  -- Check if we fell off the packet
  local header_format = "<c4 B I4 B I2 I2 i8 I2 I2 I2 I2 I2"
  if #header < string.packsize(header_format) then
    return false, "SMB: ERROR: Server returned less data than it was supposed to (one or more fields are missing); aborting [8]"
  end

  -- Parse out the header
  local protocol_version, command, status, flags, flags2, pid_high, signature, unused, tid, pid, uid, mid, pos = string.unpack(header_format, header)

  -- Get the protocol version
  if(protocol_version == ("\xFESMB")) then
    return false, "SMB: Server returned a SMBv2 packet, don't know how to handle"
  end

  -- Since this is the first response seen, check any necessary flags here
  if((flags2 & 0x0800) ~= 0x0800) then
    smb['extended_security'] = false
  end

  -- Parse the parameter section
  local dialect_format = "<I2"
  local parameters_format = "<BI2 I2 I4 I4 I4 I4"
  if #parameters < (string.packsize(dialect_format) + string.packsize(parameters_format)) then
    return false, "SMB: ERROR: Server returned less data than it was supposed to (one or more fields are missing); aborting [9]"
  end
  smb['dialect'], pos = string.unpack(dialect_format, parameters)

  -- Check if the server didn't like our requested protocol
  if(smb['dialect'] ~= 0) then
    stdnse.debug2("Server negotiated an unknown protocol (#%d) -- aborting", smb['dialect'])
    return false, string.format("Server negotiated an unknown protocol (#%d) -- aborting", smb['dialect'])
  end

  smb.security_mode, smb.max_mpx, smb.max_vc, smb.max_buffer, smb.max_raw_buffer, smb.session_key, smb.capabilities, pos = string.unpack(parameters_format, parameters, pos)
  -- Some broken implementations of SMB don't send these variables
  smb.time = 0
  smb.timezone = 0
  smb.key_length = 0
  smb.byte_count = 0
  if (#parameters - pos + 1) >= 8 then
    smb.time, pos = string.unpack("<I8", parameters, pos)
    if (#parameters - pos + 1) >= 2 then
      smb.timezone, pos = string.unpack("<i2", parameters, pos)
      if (#parameters - pos + 1) >= 1 then
        smb.key_length, pos = string.unpack("B", parameters, pos)
        if (#parameters - pos + 1) >= 2 then
          smb.byte_count, pos = string.unpack("<I2", parameters, pos)
        end
      end
    end
  end

  -- Convert the time and timezone to more useful values
  smb['time'] = (smb['time'] // 10000000) - 11644473600
  smb['date'] = datetime.format_timestamp(smb['time'])
  smb['timezone'] = -(smb['timezone'] / 60)
  if(smb['timezone'] == 0) then
    smb['timezone_str'] = "UTC+0"
  elseif(smb['timezone'] < 0) then
    smb['timezone_str'] = "UTC-" .. math.abs(smb['timezone'])
  else
    smb['timezone_str'] = "UTC+" .. smb['timezone']
  end

  -- Data section
  if(smb['extended_security'] == true) then
    if #data < 16 then
      return false, "SMB: ERROR: not enough data for extended security"
    end
    smb.server_guid, pos = string.unpack("<c16", data)

    -- do we have a security blob?
    if ( #data - pos + 1 > 0 ) then
      smb.security_blob = data:sub(pos)
      pos = #data + 1
    end
  else
    if #data < smb.key_length then
      return false, "SMB: ERROR: not enough data for server_challenge"
    end
    smb.server_challenge, pos = string.unpack(string.format("<c%d", smb['key_length']), data)

    -- Get the (null-terminated) domain as a Unicode string
    smb['domain'] = ""
    smb['server'] = ""

    local remainder = unicode.utf16to8(string.sub(data, pos))
    pos, pos = string.find(remainder, "\0", 1, true)
    if pos == nil then
      return false, "SMB: ERROR: Server returned less data than it was supposed to (one or more fields are missing); aborting [14]"
    end
    smb['domain'] = string.sub(remainder, 1, pos)

    -- Get the server name as a Unicode string
    -- Note: This can be nil, Samba leaves this off
    local pos2 = pos + 1
    pos, pos = string.find(remainder, "\0", pos2, true)
    if pos ~= nil then
      smb['server'] = string.sub(remainder, pos2, pos)
    end
  end

  stdnse.debug2("SMB_COM_NEGOTIATE got status:%s", status)
  if status == 0 then
    return true, overrides['dialect'] or "NT LM 0.12"
  end
end

---
-- Wrapper function to negotiate the protocol to use in the SMB connection.
-- By default it attempts to negotiate with using following dialects:
-- * NT LM 12.0 (SMBv1)
-- @param smb The SMB object
-- @param overrides Overrides table
-- @return Boolean status
---
function negotiate_protocol(smb, overrides)
  local status, dialect
  status, dialect = negotiate_v1(smb, overrides)
  if status then
    return true
  else
    stdnse.debug1("Couldn't negotiate a SMBv1 connection:%s", dialect)
    return false, string.format("Could not negotiate a connection:%s", dialect)
  end
end

---
-- Returns list of supported dialects for SMBv1, SMBv2 and SMBv3.
-- @param host       The SMB host to connect to.
-- @param overrides [optional] Overrides for various fields.
-- @return Boolean status
-- @return Table of supported dialects or error message
---
function list_dialects(host, overrides)
  local supported_dialects = {}
  local status, smb1_dialect
  local smbstate

  overrides = tableaux.tcopy(overrides or {})

  -- Check for SMBv1 first
  stdnse.debug2("Checking if SMBv1 is supported")
  status, smbstate = start(host)
  if(status == false) then
    return false, smbstate
  end

  status, smb1_dialect = negotiate_v1(smbstate, overrides)
  if status then --Add SMBv1 as a dialect
    table.insert(supported_dialects, smb1_dialect)
  end
  stop(smbstate) -- Finish SMBv1 and close connection

  status, smbstate = start(host)
  if(status == false) then
    return false, smbstate
  end
  stdnse.debug2("Checking if SMB 2+ is supported in general")
  overrides['Dialects'] = nil
  local max_dialect
  status, max_dialect = smb2.negotiate_v2(smbstate, overrides)
  stop(smbstate)
  if not status then -- None of SMB2 dialects accepted by the target
    return true, supported_dialects
  end
  stdnse.debug2("SMB2: Dialect '%s' is the highest supported", smb2.dialect_name(max_dialect))

  -- Check individual SMB2 and SMB3 dialects
  for i, dialect in pairs(smb2.dialects()) do
    if dialect == max_dialect then
      break
    end
    local dialect_name = smb2.dialect_name(dialect)
    -- we need a clean connection for each negotiate request
    status, smbstate = start(host)
    if(status == false) then
      return false, smbstate
    end
    stdnse.debug2("SMB2: Checking if dialect '%s' is supported", dialect_name)
    overrides['Dialects'] = {dialect}
    status = smb2.negotiate_v2(smbstate, overrides)
    --clean smb connection
    stop(smbstate)
    if status then
      stdnse.debug2("SMB2: Dialect '%s' is supported", dialect_name)
      table.insert(supported_dialects, dialect_name)
    end
  end
  table.insert(supported_dialects, smb2.dialect_name(max_dialect))

  return true, supported_dialects
end

--- This is an internal function and should not be called externally. Use
--  the start_session() function instead.
local function start_session_basic(smb, log_errors, overrides)
  local i, err
  local status, result
  local header, parameters, data, domain
  local andx_command, andx_reserved, andx_offset, action
  local os, lanmanager
  local username, domain, password, password_hash, hash_type
  local busy_count = 0

  header = smb_encode_header(smb, command_codes['SMB_COM_SESSION_SETUP_ANDX'], overrides)

  -- Get the first account, unless they overrode it
  if(overrides ~= nil and overrides['username'] ~= nil) then
    result = true
    username      = overrides['username']
    domain        = overrides['domain']
    password      = overrides['password']
    password_hash = overrides['password_hash']
    hash_type     = overrides['hash_type']
  else
    result, username, domain, password, password_hash, hash_type = smbauth.get_account(smb['host'])
  end

  while result ~= false do
    local lanman, ntlm

    lanman, ntlm, smb['mac_key'] = smbauth.get_password_response(smb['ip'], username, domain, password, password_hash, hash_type, smb['server_challenge'], false)

    -- Parameters
    parameters = string.pack("<BBI2 I2I2 I2 I4 I2I2 I4I4",
      0xFF,               -- ANDX -- no further commands
      0x00,               -- ANDX -- Reserved (0)
      0x0000,             -- ANDX -- next offset
      0xFFFF,             -- Max buffer size
      0x0001,             -- Max multiplexes
      0x0001,             -- Virtual circuit num
      smb['session_key'], -- The session key
      #lanman,            -- ANSI/Lanman password length
      #ntlm,              -- Unicode/NTLM password length
      0x00000000,         -- Reserved
      0x00000050          -- Capabilities
      )

    -- Data is a list of strings, terminated by a blank one.
    data = lanman -- ANSI/Lanman password
    .. ntlm -- Unicode/NTLM password
    .. string.pack("<zzzz",
      username,               -- Account
      domain,                 -- Domain
      "Nmap",                 -- OS
      "Native Lanman"         -- Native LAN Manager
      )

    -- Send the session setup request
    stdnse.debug2("SMB: Sending SMB_COM_SESSION_SETUP_ANDX")
    result, err = smb_send(smb, header, parameters, data, overrides)
    if(result == false) then
      return false, err
    end

    -- Read the result
    status, header, parameters, data = smb_read(smb)
    if(status ~= true) then
      return false, header
    end

    local header_format = "<c4 B I4 B I2 I2 i8 I2 I2 I2 I2 I2"
    if #header < string.packsize(header_format) then
      return false, "SMB: ERROR: Server returned less data than it was supposed to (one or more fields are missing); aborting [17]"
    end
    -- Check if we were allowed in
    local protocol_version, command, flags, flags2, pid_high, signature, unused, tid, pid, uid, mid, pos
    protocol_version, command, status, flags, flags2, pid_high, signature, unused, tid, pid, uid, mid, pos = string.unpack(header_format, header)

    -- Check if we're successful
    if(status == 0) then

      -- Parse the parameters
      local parameters_format = "<BB I2 I2"
      if #parameters < string.packsize(parameters_format) then
        return false, "SMB: ERROR: Server returned less data than needed"
      end
      andx_command, andx_reserved, andx_offset, action, pos = string.unpack(parameters_format, parameters)

      -- Parse the data
      status, os, lanmanager, domain, pos = pcall(string.unpack, "<zzz", data)
      if not status then
        return false, "SMB: ERROR: Server returned less data than it was supposed to (one or more fields are missing); aborting [19]"
      end

      -- Fill in the smb object and smb string
      smb['uid']        = uid
      smb['is_guest']   = (action & 1)
      smb['os']         = os
      smb['lanmanager'] = lanmanager

      -- Check if they're using an un-supported system
      if(os == "" or lanmanager == "" or domain == "") then
        stdnse.debug1("SMB: WARNING: the server is using a non-standard SMB implementation; your mileage may vary (%s)", smb['ip'])
      elseif(os == "Unix" or string.sub(lanmanager, 1, 5) == "Samba") then
        stdnse.debug1("SMB: WARNING: the server appears to be Unix; your mileage may vary.")
      end

      -- Check if they were logged in as a guest
      if(log_errors == nil or log_errors == true) then
        if(smb['is_guest'] == 1) then
          stdnse.debug1("SMB: Login as %s\\%s failed, but was given guest access (username may be wrong, or system may only allow guest)", domain, stdnse.string_or_blank(username))
        else
          stdnse.debug2("SMB: Login as %s\\%s succeeded", domain, stdnse.string_or_blank(username))
        end
      end

      -- Set the initial sequence number
      smb['sequence'] = 1

      return true

    else
      -- Check if we got the error NT_STATUS_REQUEST_NOT_ACCEPTED
      if(status == 0xc00000d0) then
        busy_count = busy_count + 1

        if(busy_count > 9) then
          return false, "SMB: ERROR: Server has too many active connections; giving up."
        end

        local backoff = math.random() * 10
        stdnse.debug1("SMB: Server has too many active connections; pausing for %s seconds.", math.floor(backoff * 100) / 100)
        stdnse.sleep(backoff)
      else
        -- This username failed, print a warning and keep going
        if(log_errors == nil or log_errors == true) then
          stdnse.debug1("SMB: Login as %s\\%s failed (%s)", domain, stdnse.string_or_blank(username), get_status_name(status))
        end

        -- Go to the next account
        if(overrides == nil or overrides['username'] == nil) then
          smbauth.next_account(smb['host'])
          result, username, domain, password, password_hash, hash_type = smbauth.get_account(smb['host'])
        else
          result = false
        end
      end
    end
  end

  if(log_errors ~= false) then
    stdnse.debug1("SMB: ERROR: %s", username)
  end

  if (status ~= nil) then
    return false, get_status_name(status)
  else
    return false, username
  end
end

--- This is an internal function and should not be called externally. Use
--  the start_session() function instead.
local function start_session_extended(smb, log_errors, overrides)
  local i
  local status, status_name, result, err
  local header, parameters, data
  local andx_command, andx_reserved, andx_offset, action, security_blob_length
  local os, lanmanager
  local username, domain, password, password_hash, hash_type
  local busy_count = 0

  -- Set a default status_name, in case everything fails
  status_name = "An unknown error has occurred"

  -- Get the first account, unless they overrode it
  if(overrides ~= nil and overrides['username'] ~= nil) then
    result = true
    username      = overrides['username']
    domain        = overrides['domain']
    password      = overrides['password']
    password_hash = overrides['password_hash']
    hash_type     = overrides['hash_type']
  else
    result, username, domain, password, password_hash, hash_type = smbauth.get_account(smb['host'])
    if(not(result)) then
      return result, username
    end
  end

  -- check what kind of security blob we were given in the negotiate protocol request
  local sp_nego = false
  if ( smb['security_blob'] and #smb['security_blob'] > 11 ) then
    local oid, pos = string.unpack(">c6", smb['security_blob'], 5)
    sp_nego = ( oid == "\x2b\x06\x01\x05\x05\x02" or oid == "\x06\x06\x2b\x06\x01\x05" ) -- check for SPNEGO OID 1.3.6.1.5.5.2
  end

  local ntlm_challenge_accepted = false
  while result ~= false do
    -- These are loop variables
    local security_blob = nil
    local security_blob_length = 0

    -- This loop takes care of the multiple packets that "extended security" requires
    repeat
      -- Get the new security blob, passing the old security blob as a parameter. If there was no previous security blob, then nil is passed, which creates a new one
      if ( not(security_blob) ) then
        status, security_blob, smb['mac_key'] = smbauth.get_security_blob(security_blob, smb['ip'], username, domain, password, password_hash, hash_type, (sp_nego and 0x00088215))

        if ( sp_nego ) then
          local enc = asn1.ASN1Encoder:new()
          local mechtype = enc:encode( { type = 'A0', value = enc:encode( { type = '30', value = enc:encode( { type = '06', value = stdnse.fromhex("2b06010401823702020a") } ) } ) } )
          local oid = enc:encode( { type = '06', value = stdnse.fromhex("2b0601050502") } )

          security_blob = enc:encode(security_blob)
          security_blob = enc:encode( { type = 'A2', value = security_blob } )
          security_blob = mechtype .. security_blob
          security_blob = enc:encode( { type = '30', value = security_blob } )
          security_blob = enc:encode( { type = 'A0', value = security_blob } )
          security_blob = oid .. security_blob
          security_blob = enc:encode( { type = '60', value = security_blob } )
        end
      else
        if ( sp_nego ) then
          if (smb['domain'] or smb['server']) and (not domain or #domain == 0) then
            domain = smb['domain'] or smb['server']
          end
          hash_type = "ntlm"
        end

        status, security_blob, smb['mac_key'] = smbauth.get_security_blob(security_blob, smb['ip'], username, domain, password, password_hash, hash_type, (sp_nego and 0x00088215))

        if ( sp_nego ) then
          local enc = asn1.ASN1Encoder:new()
          security_blob = enc:encode(security_blob)
          security_blob = enc:encode( { type = 'A2', value = security_blob } )
          security_blob = enc:encode( { type = '30', value = security_blob } )
          security_blob = enc:encode( { type = 'A1', value = security_blob } )
        end

      end

      -- There was an error processing the security blob
      if(status == false) then
        return false, string.format("SMB: ERROR: Security blob: %s", security_blob)
      end

      header     = smb_encode_header(smb, command_codes['SMB_COM_SESSION_SETUP_ANDX'], overrides)

      -- Data is a list of strings, terminated by a blank one.
      data = security_blob -- Security blob
      .. string.pack("<zzz",
        "Nmap",                -- OS
        "Native Lanman",       -- Native LAN Manager
        ""                     -- Primary domain
        )

      -- Parameters
      parameters = string.pack("<BB I2 I2 I2 I2 I4 I2 I4 I4",
        0xFF,               -- ANDX -- no further commands
        0x00,               -- ANDX -- Reserved (0)
        #data + 24 + #header + 3, -- ANDX -- next offset
        0xFFFF,             -- Max buffer size
        0x0001,             -- Max multiplexes
        0x0001,             -- Virtual circuit num
        smb['session_key'], -- The session key
        #security_blob,     -- Security blob length
        0x00000000,         -- Reserved
        0x80000050          -- Capabilities
        )

      -- Send the session setup request
      stdnse.debug2("SMB: Sending SMB_COM_SESSION_SETUP_ANDX")
      result, err = smb_send(smb, header, parameters, data, overrides)
      if(result == false) then
        return false, err
      end

      -- Read the result
      status, header, parameters, data = smb_read(smb)
      if(status ~= true) then
        return false, header
      end

      local header_format = "<c4 B I4 B I2 I2 i8 I2 I2 I2 I2 I2"
      if #header < string.packsize(header_format) then
        return false, "SMB: ERROR: Server returned less data than it was supposed to (one or more fields are missing); aborting [8]"
      end

      -- Check if we were allowed in
      local protocol_version, command, status, flags, flags2, pid_high, signature, unused, tid, pid, uid, mid, pos = string.unpack(header_format, header)
      smb['uid'] = uid

      -- Get a human readable name
      status_name = get_status_name(status)

      -- Only parse the parameters if it's ok or if we're going to keep going
      if(status_name == "NT_STATUS_SUCCESS" or status_name == "NT_STATUS_MORE_PROCESSING_REQUIRED") then
        -- Parse the parameters
        local parameters_format = "<BBI2 I2 I2"
        if #parameters < string.packsize(parameters_format) then
          return false, "SMB: ERROR: Server returned less data than needed"
        end
        andx_command, andx_reserved, andx_offset, action, security_blob_length, pos = string.unpack(parameters_format, parameters)
        smb['is_guest']   = (action & 1)

        -- Parse the data
        if #data < security_blob_length then
          return false, "SMB: ERROR: Server returned less data than needed"
        end
        security_blob, pos = string.unpack(("<c%d"):format(security_blob_length), data)
        status, os, lanmanager, pos = pcall(string.unpack, "zz", data, pos)

        if not ntlm_challenge_accepted then
          if ( status_name == "NT_STATUS_MORE_PROCESSING_REQUIRED" and sp_nego ) then
            local start = security_blob:find("NTLMSSP")
            security_blob = security_blob:sub(start)
          end

          if not status or security_blob == nil then
            return false, "SMB: ERROR: NTLM challenge not accepted or lanmanager missing"
          end
          smb['os']         = os
          smb['lanmanager'] = lanmanager

          local host_info = smbauth.get_host_info_from_security_blob(security_blob)
          if ( host_info ) then
            smb['fqdn'] = host_info['fqdn']
            smb['domain_dns'] = host_info['dns_domain_name']
            smb['forest_dns'] = host_info['dns_forest_name']
            smb['server'] = host_info['netbios_computer_name']
            smb['domain'] = host_info['netbios_domain_name']
          end
          ntlm_challenge_accepted = true
        end


        -- If it's ok, do a cleanup and return true
        if(status_name == "NT_STATUS_SUCCESS") then
          -- Check if they're using an un-supported system
          if not status then
            stdnse.debug1("SMB: WARNING: the server is using a non-standard SMB implementation; your mileage may vary (%s)", smb['ip'])
          elseif(os == "Unix" or string.sub(lanmanager, 1, 5) == "Samba") then
            stdnse.debug1("SMB: WARNING: the server appears to be Unix; your mileage may vary.")
          end

          -- Check if they were logged in as a guest
          if(log_errors == nil or log_errors == true) then
            if(smb['is_guest'] == 1) then
              stdnse.debug1("SMB: Extended login to %s as %s\\%s failed, but was given guest access (username may be wrong, or system may only allow guest)", smb['ip'], domain, stdnse.string_or_blank(username))
            else
              stdnse.debug2("SMB: Extended login to %s as %s\\%s succeeded", smb['ip'], domain, stdnse.string_or_blank(username))
            end
          end

          -- Set the initial sequence number
          smb['sequence'] = 1

          return true
        end -- Status is ok
      end -- Should we parse the parameters/data?
    until status_name ~= "NT_STATUS_MORE_PROCESSING_REQUIRED"

    -- Check if we got the error NT_STATUS_REQUEST_NOT_ACCEPTED
    if(status == 0xc00000d0) then
      busy_count = busy_count + 1

      if(busy_count > 9) then
        return false, "SMB: ERROR: Server has too many active connections; giving up."
      end

      local backoff = math.random() * 10
      stdnse.debug1("SMB: Server has too many active connections; pausing for %s seconds.", math.floor(backoff * 100) / 100)
      stdnse.sleep(backoff)
    else
      -- Display a message to the user, and try the next account
      if(log_errors == nil or log_errors == true) then
        stdnse.debug1("SMB: Extended login to %s as %s\\%s failed (%s)", smb['ip'], domain, stdnse.string_or_blank(username), status_name)
      end

      -- Go to the next account
      if(overrides == nil or overrides['username'] == nil) then
        smbauth.next_account(smb['host'])
        result, username, domain, password, password_hash, hash_type = smbauth.get_account(smb['host'])
        if(not(result)) then
          return false, username
        end
      else
        result = false
      end
    end

    -- Reset the user id
    smb['uid'] = 0

  end -- Loop over the accounts

  if(log_errors == nil or log_errors == true) then
    stdnse.debug1("SMB: ERROR: All logins failed, sorry it didn't work out!")
  end

  return false, status_name
end

--- Sends out SMB_COM_SESSION_SETUP_ANDX, which attempts to log a user in.
--
-- Sends the following:
-- * Negotiated parameters (multiplexed connections, virtual circuit, capabilities)
-- * Passwords (plaintext, unicode, lanman, ntlm, lmv2, ntlmv2, etc)
-- * Account name
-- * OS (I just send "Nmap")
-- * Native LAN Manager (no clue what that is, but it seems to be ignored)
--
-- Receives the following:
-- * User ID
-- * Server OS
--
--@param smb          The SMB object associated with the connection
--@param overrides    [optional] A table of overrides for username, domain, password, password_hash, and hash_type.
--                    If any of these are given, it's used first. If they aren't, then Nmap parameters, Nmap registry entries,
--                    guest, and NULL sessions are used.
--@param log_errors   [optional] If set, will display login. Default: true.
--@return (status, result) If status is false, result is an error message. Otherwise, result is nil and the following
--        elements are added to the smb table:
--    *  'uid'         The UserID for the session
--    *  'is_guest'    If set, the username wasn't found so the user was automatically logged in as the guest account
--    *  'os'          The operating system
--    *  'lanmanager'  The server's LAN Manager
function start_session(smb, overrides, log_errors)
  -- Use a mutex to avoid some issues (see http://seclists.org/nmap-dev/2011/q1/464)
  local smb_auth_mutex = nmap.mutex( "SMB Authentication Mutex" )
  smb_auth_mutex( "lock" )

  local status, result
  if(smb['extended_security'] == true) then
    status, result = start_session_extended(smb, log_errors, overrides)
  else
    status, result = start_session_basic(smb, log_errors, overrides)
  end

  smb_auth_mutex( "done" )
  return status, result
end

--- Sends out <code>SMB_COM_SESSION_TREE_CONNECT_ANDX</code>, which attempts to
-- connect to a share.
--
-- Sends the following:
-- * Password (for share-level security, which we don't support)
-- * Share name
-- * Share type (or "?????" if it's unknown, that's what we do)
--
-- Receives the following:
-- * Tree ID
--
--@param smb       The SMB object associated with the connection
--@param path      The path to connect (eg, <code>"\\servername\C$"</code>)
--@param overrides [optional] Overrides for various fields
--@return (status, result) If status is false, result is an error message. Otherwise, result is a
--        table with the following elements:
--      * 'tid'         The TreeID for the session
function tree_connect(smb, path, overrides)
  local header, parameters, data, err, result
  local andx_command, andx_reserved, andx_offset, action
  local status

  -- Make sure we have overrides
  overrides = overrides or {}

  header = smb_encode_header(smb, command_codes['SMB_COM_TREE_CONNECT_ANDX'], overrides)
  parameters = string.pack("<BBI2 I2 I2",
    0xFF,   -- ANDX no further commands
    0x00,   -- ANDX reserved
    0x0000, -- ANDX offset
    (overrides['tree_connect_flags'] or 0x0000), -- flags
    0x0000 -- password length (for share-level security)
    )
  data = string.pack("zz",
    -- Share-level password
    path,   -- Path
    (overrides['tree_type'] or "?????") -- Type of tree ("?????" = any)
    )

  -- Send the tree connect request
  stdnse.debug2("SMB: Sending SMB_COM_TREE_CONNECT_ANDX")
  result, err = smb_send(smb, header, parameters, data, overrides)
  if(result == false) then
    return false, err
  end

  -- Read the result
  status, header, parameters, data = smb_read(smb)
  if(status ~= true) then
    return false, header
  end

  local header_format = "<c4 B I4 B I2 I2 i8 I2 I2 I2 I2 I2"
  if #header < string.packsize(header_format) then
    return false, "SMB: ERROR: Server returned less data than it was supposed to (one or more fields are missing); aborting [8]"
  end
  -- Check if we were allowed in
  local protocol_version, command, status, flags, flags2, pid_high, signature, unused, tid, pid, uid, mid, pos = string.unpack(header_format, header)

  if(status ~= 0) then
    return false, get_status_name(status)
  end

  if(tid == 0 or tonumber(tid) == 0) then
    return false, "SMB: ERROR: Server didn't establish a proper tree connection (likely an embedded system)"
  end

  smb['tid'] = tid

  return true

end

--- Disconnects a tree session. Should be called before logging off and disconnecting.
--@param smb    The SMB object associated with the connection
--@param overrides THe overrides table
--@return (status, result) If status is false, result is an error message. If status is true,
--              the disconnect was successful.
function tree_disconnect(smb, overrides)
  overrides = overrides or {}
  local header

  header = smb_encode_header(smb, command_codes['SMB_COM_TREE_DISCONNECT'], overrides)

  -- Send the tree disconnect request
  stdnse.debug2("SMB: Sending SMB_COM_TREE_DISCONNECT")
  local result, err = smb_send(smb, header, "", "", overrides)
  if(result == false) then
    return false, err
  end

  -- Read the result
  local status, header, parameters, data = smb_read(smb)
  if(status ~= true) then
    return false, header
  end

  local header_format = "<c4 B I4 B I2 I2 i8 I2 I2 I2 I2 I2"
  if #header < string.packsize(header_format) then
    return false, "SMB: ERROR: Server returned less data than it was supposed to (one or more fields are missing); aborting [8]"
  end

  -- Check if there was an error
  local protocol_version, command, status, flags, flags2, pid_high, signature, unused, tid, pid, uid, mid, pos = string.unpack(header_format, header)

  if(status ~= 0) then
    return false, get_status_name(status)
  end

  smb['tid'] = 0

  return true

end

---Logs off the current user. Strictly speaking this isn't necessary, but it's the polite thing to do.
--
--@param smb    The SMB object associated with the connection
--@param overrides THe overrides table
--@return (status, result) If status is false, result is an error message. If status is true,
--              the logoff was successful.
function logoff(smb, overrides)
  overrides = overrides or {}
  local header, parameters, data
  local status

  header = smb_encode_header(smb, command_codes['SMB_COM_LOGOFF_ANDX'], overrides)

  -- Parameters are a blank ANDX block
  parameters = string.pack("<BB I2",
    0xFF,   -- ANDX no further commands
    0x00,   -- ANDX reserved
    0x0000  -- ANDX offset
    )

  -- Send the tree disconnect request
  stdnse.debug2("SMB: Sending SMB_COM_LOGOFF_ANDX")
  local result, err = smb_send(smb, header, parameters, "", overrides)
  if(result == false) then
    return false, err
  end

  -- Read the result
  status, header, parameters, data = smb_read(smb)
  if(status ~= true) then
    return false, header
  end

  -- Reset session variables (note: this has to come after the smb_read(), otherwise the message signatures cause a problem
  smb['uid']      = 0
  smb['sequence'] = -1
  smb['mac_key']  = nil

  local header_format = "<c4 B I4 B I2 I2 i8 I2 I2 I2 I2 I2"
  if #header < string.packsize(header_format) then
    return false, "SMB: ERROR: Server returned less data than it was supposed to (one or more fields are missing); aborting [22]"
  end

  -- Check if there was an error
  local protocol_version, command, status, flags, flags2, pid_high, signature, unused, tid, pid, uid, mid, pos = string.unpack(header_format, header)

  if(status == 0xc0000022) then
    stdnse.debug1("SMB: ERROR: Access was denied in 'logoff', indicating a problem with your message signatures")
    return false, "SMB: ERROR: Access was denied in 'logoff', indicating a problem with your message signatures"
  end
  if(status ~= 0) then
    return false, get_status_name(status)
  end

  return true

end

--- This sends a SMB request to open or create a file.
--
--  Most of the parameters I pass here are used directly from a packetlog,
--  especially the various permissions fields and flags.  I might make this
--  more adjustable in the future, but this has been working for me.
--
--@param smb       The SMB object associated with the connection
--@param path      The path of the file or pipe to open
--@param overrides [optional] Overrides for various fields
--@return (status, result) If status is false, result is an error message. Otherwise, result is a table
--        containing a lot of different elements, the most important one being 'fid', the handle to the opened file.
function create_file(smb, path, overrides)
  local header, parameters, data
  local andx_command, andx_reserved, andx_offset
  local oplock_level, fid, create_action, created, last_access, last_write, last_change, attributes, allocation_size, end_of_file, filetype, ipc_state, is_directory
  local error_count = 0

  local status, pos
  repeat
    local mutex = nmap.mutex(smb['host'])
    mutex "lock"

    -- Make sure we have overrides
    overrides = overrides or {}

    header = smb_encode_header(smb, command_codes['SMB_COM_NT_CREATE_ANDX'], overrides)
    parameters = string.pack("<BBI2 B I2 I4 I4 I4 I8 I4 I4 I4 I4 I4 B",
      0xFF,   -- ANDX no further commands
      0x00,   -- ANDX reserved
      0x0000, -- ANDX offset
      0x00,   -- Reserved
      #path, -- Path length
      (overrides['file_create_flags']            or 0x00000016),         -- Create flags
      (overrides['file_create_root_fid']         or 0x00000000),         -- Root FID
      (overrides['file_create_access_mask']      or 0x02000000),         -- Access mask
      (overrides['file_create_allocation_size']  or 0x0000000000000000), -- Allocation size
      (overrides['file_create_attributes']       or 0x00000000),         -- File attributes
      (overrides['file_create_share_attributes'] or 0x00000007),         -- Share attributes
      (overrides['file_create_disposition']      or 0x00000000),         -- Disposition
      (overrides['file_create_options']          or 0x00000000),         -- Create options
      (overrides['file_create_impersonation']    or 0x00000002),         -- Impersonation
      (overrides['file_create_security_flags']   or 0x01)                -- Security flags
      )

    data = string.pack("z", path)

    -- Send the create file
    stdnse.debug2("SMB: Sending SMB_COM_NT_CREATE_ANDX")
    local result, err = smb_send(smb, header, parameters, data, overrides)
    if(result == false) then
      mutex "done"
      return false, err
    end

    -- Read the result
    status, header, parameters, data = smb_read(smb, false)
    mutex "done"
    if(status ~= true) then
      return false, header
    end

    local header_format = "<c4 B I4 B I2 I2 i8 I2 I2 I2 I2 I2"
    if #header < string.packsize(header_format) then
      return false, "SMB: ERROR: Server returned less data than it was supposed to (one or more fields are missing); aborting [23]"
    end

    -- Check if we were allowed in
    local protocol_version, command, flags, flags2, pid_high, signature, unused, tid, pid, uid, mid
    protocol_version, command, status, flags, flags2, pid_high, signature, unused, tid, pid, uid, mid, pos = string.unpack(header_format, header)

    if(status == 0xc00000ac) then
      error_count = error_count + 1
      if(error_count > 10) then
        return false, "SMB: ERROR: Server returned NT_STATUS_PIPE_NOT_AVAILABLE too many times; giving up."
      end
      stdnse.debug1("WARNING: Server refused connection with NT_STATUS_PIPE_NOT_AVAILABLE; trying again")
      stdnse.sleep(.2)
    end
  until (status ~= 0xc00000ac)

  if(status ~= 0) then
    return false, get_status_name(status)
  end

  -- Parse the parameters
  local parameters_format = "<BBI2 BI2 I4 I8 I8 I8 I8 I4 I8 I8 I2 I2 B"
  if #parameters < string.packsize(parameters_format) then
    return false, "SMB: ERROR: Server returned less data than needed"
  end
  andx_command, andx_reserved, andx_offset, oplock_level, fid, create_action, created, last_access, last_write, last_change, attributes, allocation_size, end_of_file, filetype, ipc_state, is_directory, pos = string.unpack(parameters_format, parameters)

  -- Fill in the smb table
  smb['oplock_level']    = oplock_level
  smb['fid']             = fid
  smb['create_action']   = create_action
  smb['created']         = created
  smb['last_access']     = last_access
  smb['last_write']      = last_write
  smb['last_change']     = last_change
  smb['attributes']      = attributes
  smb['allocation_size'] = allocation_size
  smb['end_of_file']     = end_of_file
  smb['filetype']        = filetype
  smb['ipc_state']       = ipc_state
  smb['is_directory']    = is_directory

  return true
end

--- This sends a SMB request to read from a file (or a pipe).
--
--@param smb    The SMB object associated with the connection
--@param offset The offset to read from (ignored if it's a pipe)
--@param count  The maximum number of bytes to read
--@param overrides The overrides table
--@return (status, result) If status is false, result is an error message. Otherwise, result is a table
--        containing a lot of different elements.
function read_file(smb, offset, count, overrides)
  overrides = overrides or {}
  local header, parameters, data
  local andx_command, andx_reserved, andx_offset
  local remaining, data_compaction_mode, reserved_1, data_length_low, data_offset, data_length_high, reserved_2, reserved_3
  local response = {}
  local status

  header = smb_encode_header(smb, command_codes['SMB_COM_READ_ANDX'], overrides)
  parameters = string.pack("<BBI2 I2 I4 I2 I2 I4 I2 I4",
    0xFF,   -- ANDX no further commands
    0x00,   -- ANDX reserved
    0x0000, -- ANDX offset
    smb['fid'], -- FID
    offset,     -- Offset
    count,      -- Max count low
    count,      -- Min count
    0xFFFFFFFF, -- Reserved
    0,          -- Remaining
    0x00000000  -- High offset
    )

  data = ""

  -- Send the create file
  stdnse.debug2("SMB: Sending SMB_COM_READ_ANDX")
  local result, err = smb_send(smb, header, parameters, data, overrides)
  if(result == false) then
    return false, err
  end

  -- Read the result
  status, header, parameters, data = smb_read(smb)
  if(status ~= true) then
    return false, header
  end

  local header_format = "<c4 B I4 B I2 I2 i8 I2 I2 I2 I2 I2"
  if #header < string.packsize(header_format) then
    return false, "SMB: ERROR: Server returned less data than it was supposed to (one or more fields are missing); aborting [25]"
  end

  -- Check if we were allowed in
  local protocol_version, command, status, flags, flags2, pid_high, signature, unused, tid, pid, uid, mid, pos = string.unpack(header_format, header)

  if(status ~= 0 and
      (status ~= status_codes.NT_STATUS_BUFFER_OVERFLOW and (smb['filetype'] == filetype_codes.FILE_TYPE_BYTE_MODE_PIPE or
      smb['filetype'] == filetype_codes.FILE_TYPE_MESSAGE_MODE_PIPE) ) ) then
    return false, get_status_name(status)
  end

  -- Parse the parameters
  local parameters_format = "<BBI2 I2 I2 I2 I2 I2 I4 I2 I4"
  if #parameters < string.packsize(parameters_format) then
    return false, "SMB: ERROR: Server returned less data than needed"
  end
  andx_command, andx_reserved, andx_offset, remaining, data_compaction_mode, reserved_1, data_length_low, data_offset, data_length_high, reserved_2, reserved_3, pos = string.unpack(parameters_format, parameters)

  response['remaining']   = remaining
  response['data_length'] = (data_length_low | (data_length_high << 16))
  response['status']      = status


  -- data_start is the offset of the beginning of the data section -- we use this to calculate where the read data lives
  if(response['data_length'] == 0) then
    response['data'] = 0
  else
    local data_start = #header + 1 + #parameters + 2
    if(data_offset < data_start) then
      return false, "SMB: Start of data isn't in data section"
    end

    -- Figure out the offset into the data section
    data_offset = data_offset - data_start

    -- Make sure we don't run off the edge of the packet
    if(data_offset + response['data_length'] > #data) then
      return false, "SMB: Data returned runs off the end of the packet"
    end

    -- Pull the data string out of the data
    response['data'] = string.sub(data, data_offset + 1, data_offset + response['data_length'])
  end

  return true, response
end

--- This sends a SMB request to write to a file (or a pipe).
--
--@param smb        The SMB object associated with the connection
--@param write_data The data to write
--@param offset     The offset to write it to (ignored for pipes)
--@param overrides  The overrides table
--@return (status, result) If status is false, result is an error message. Otherwise, result is a table
--        containing a lot of different elements, the most important one being 'fid', the handle to the opened file.
function write_file(smb, write_data, offset, overrides)
  overrides = overrides or {}
  local header, parameters, data
  local andx_command, andx_reserved, andx_offset
  local response = {}
  local status

  header = smb_encode_header(smb, command_codes['SMB_COM_WRITE_ANDX'], overrides)
  parameters = string.pack("<BBI2 I2 I4 I4 I2 I2 I2 I2 I2 I4",
    0xFF,   -- ANDX no further commands
    0x00,   -- ANDX reserved
    0x0000, -- ANDX offset
    smb['fid'], -- FID
    offset,     -- Offset
    0xFFFFFFFF, -- Reserved
    0x0008,     -- Write mode (Message start, don't write raw, don't return remaining, don't write through
    #write_data,-- Remaining
    0x0000,     -- Data length high
    #write_data,-- Data length low -- TODO: set this properly (to the 2-byte value)
    0x003F,     -- Data offset
    0x00000000  -- Data offset high
    )

  data = write_data

  -- Send the create file
  stdnse.debug2("SMB: Sending SMB_COM_WRITE_ANDX")
  local result, err = smb_send(smb, header, parameters, data, overrides)
  if(result == false) then
    return false, err
  end


  -- Read the result
  status, header, parameters, data = smb_read(smb)
  if(status ~= true) then
    return false, header
  end

  local header_format = "<c4 B I4 B I2 I2 i8 I2 I2 I2 I2 I2"
  if #header < string.packsize(header_format) then
    return false, "SMB: ERROR: Server returned less data than it was supposed to (one or more fields are missing); aborting [8]"
  end

  -- Check if we were allowed in
  local protocol_version, command, status, flags, flags2, pid_high, signature, unused, tid, pid, uid, mid, pos = string.unpack(header_format, header)

  if(status ~= 0) then
    return false, get_status_name(status)
  end

  -- Parse the parameters
  local parameters_format = "<BBI2 I2 I2 I2 I2"
  if #parameters < string.packsize(parameters_format) then
    return false, "SMB: ERROR: Server returned less data than needed"
  end
  local count_reserved, count_high, remaining, count_low
  andx_command, andx_reserved, andx_offset, count_low, remaining, count_high, count_reserved, pos = string.unpack(parameters_format, parameters)

  response['count_low']  = count_low
  response['remaining']  = remaining
  response['count_high'] = count_high
  response['reserved']   = count_reserved

  return true, response
end

--- This sends a SMB request to close a file (or a pipe).
--
--@param smb        The SMB object associated with the connection
--@param overrides  The overrides table
--@return (status, result) If status is false, result is an error message. Otherwise, result is undefined.
function close_file(smb, overrides)
  overrides = overrides or {}
  local header, parameters, data
  local pos
  local status
  local andx_command, andx_reserved, andx_offset
  local response = {}

  header = smb_encode_header(smb, command_codes['SMB_COM_CLOSE'], overrides)
  parameters = string.pack("<I2 I4",
    smb['fid'], -- FID
    0xFFFFFFFF  -- Last write (unspecified)
    )

  data = ""

  -- Send the close file
  stdnse.debug2("SMB: Sending SMB_CLOSE")
  local result, err = smb_send(smb, header, parameters, data, overrides)
  if(result == false) then
    return false, err
  end

  -- Read the result
  status, header, parameters, data = smb_read(smb)
  if(status ~= true) then
    return false, header
  end

  local header_format = "<c4 B I4 B I2 I2 i8 I2 I2 I2 I2 I2"
  if #header < string.packsize(header_format) then
    return false, "SMB: ERROR: Server returned less data than it was supposed to (one or more fields are missing); aborting [27]"
  end

  -- Check if the close was successful
  local protocol_version, command, status, flags, flags2, pid_high, signature, unused, tid, pid, uid, mid, pos = string.unpack(header_format, header)

  if(status ~= 0) then
    return false, get_status_name(status)
  end

  -- Close response has no parameters or data
  return true, response
end

--- This sends a SMB request to delete a file (or a pipe).
--
--@param smb    The SMB object associated with the connection
--@param path   The path of the file to delete
--@param overrides The overrides table
--@return (status, result) If status is false, result is an error message. Otherwise, result is undefined.
function delete_file(smb, path, overrides)
  overrides = overrides or {}
  local header, parameters, data
  local andx_command, andx_reserved, andx_offset
  local status

  header = smb_encode_header(smb, command_codes['SMB_COM_DELETE'], overrides)
  parameters = string.pack("<I2",
    0x0027 -- Search attributes (0x27 = include read only, hidden, system, and archive)
    )

  data = string.pack("<Bz",
    0x04, -- Ascii formatted filename
    path)

  -- Send the close file
  stdnse.debug2("SMB: Sending SMB_CLOSE")
  local result, err = smb_send(smb, header, parameters, data, overrides)
  if(result == false) then
    return false, err
  end

  -- Read the result
  status, header, parameters, data = smb_read(smb)
  if(status ~= true) then
    return false, header
  end

  local header_format = "<c4 B I4 B I2 I2 i8 I2 I2 I2 I2 I2"
  if #header < string.packsize(header_format) then
    return false, "SMB: ERROR: Server returned less data than it was supposed to (one or more fields are missing); aborting [8]"
  end

  -- Check if the close was successful
  local protocol_version, command, status, flags, flags2, pid_high, signature, unused, tid, pid, uid, mid, pos = string.unpack(header_format, header)

  if(status ~= 0) then
    return false, get_status_name(status)
  end

  -- Close response has no parameters or data
  return true
end

---
-- Implements SMB_COM_TRANSACTION2 to support the find_files function
-- This function has not been extensively tested
--
--@param smb           SMB object associated with the connection
--@param sub_command   code of a SMB_COM_TRANSACTION2 sub command
--@param trans2_param  Parameter data to pass to the function
--@param trans2_data   Data to send with the packet
--@param overrides     The overrides table
--@return status       Boolean outcome of the request
--@return error        error message if the status is false
local function send_transaction2(smb, sub_command, trans2_param, trans2_data, overrides)
  overrides = overrides or {}
  trans2_param = trans2_param or ""
  trans2_data = trans2_data or ""

  local header = smb_encode_header(smb, command_codes['SMB_COM_TRANSACTION2'], overrides)
  local pad1 = "\0\0\0" -- Name, Pad1
  local pad2 = ("\0"):rep((4 - #trans2_param % 4) % 4)

  local trans2_param_len = #trans2_param
    -- 68 = 32  SMB header
    --    + 31  SMB parameters
    --    +  2  SMB data ByteCount field
    --    +  3  #pad1
  local trans2_param_pos = 68
  local trans2_data_len = #trans2_data
  local trans2_data_pos = trans2_param_pos + trans2_param_len + #pad2
  if trans2_data_len == 0 then
    pad2 = ""
    trans2_data_pos = 0
  end

  -- SMB parameters are 31 bytes long, incl. initial WordCount field
  -- https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/f7d148cd-e3d5-49ae-8b37-9633822bfeac
  local parameters = string.pack("<I2 I2 I2 I2 BB I2 I4 I2 I2 I2 I2 I2 BB I2 ",
            trans2_param_len,    -- Total parameter count
            trans2_data_len,     -- Total data count
            0x000a,              -- Max parameter count
            0xff80,              -- Max data count
            0x00,                -- Max setup count
            0x00,                -- Reserved
            0x0000,              -- Flags (2-way transaction, don't disconnect TIDs)
            5000,                -- Timeout (ms)
            0x0000,              -- Reserved
            trans2_param_len,    -- Parameter count
            trans2_param_pos,    -- Parameter offset
            trans2_data_len,     -- Data count
            trans2_data_pos,     -- Data offset
            0x01,                -- Setup count
            0x00,                -- Reserved
            sub_command          -- Sub command
            )

  local data = pad1 .. trans2_param .. pad2 .. trans2_data

  -- Send the transaction request
  stdnse.debug2("SMB: Sending SMB_COM_TRANSACTION2")
  return smb_send(smb, header, parameters, data, overrides)
end

local function receive_transaction2(smb)

  -- Read the result
  local status, header, parameters, data = smb_read(smb)
  if(status ~= true) then
    return false, header
  end

  local header_format = "<c4 B I4 B I2 I2 i8 I2 I2 I2 I2 I2"
  if #header < string.packsize(header_format) then
    return false, "SMB: ERROR: Server returned less data than it was supposed to (one or more fields are missing); aborting [8]"
  end

  -- Check if it worked
  local protocol_version, command, status, flags, flags2, pid_high, signature, unused, tid, pid, uid, mid, pos = string.unpack(header_format, header)

  if(status ~= 0) then
    if(status_names[status] == nil) then
      return false, string.format("Unknown SMB error: 0x%08x\n", status)
    else
      return false, status_names[status]
    end
  end

  -- Parse the parameters
  local parameters_format = "<I2 I2 I2 I2 I2 I2 I2 I2 I2 BB"
  if #parameters < string.packsize(parameters_format) then
    return false, "SMB: ERROR: Server returned less data than needed"
  end
  local total_word_count, total_data_count, reserved1, parameter_count, parameter_offset, parameter_displacement, data_count, data_offset, data_displacement, setup_count, reserved2, pos = string.unpack(parameters_format, parameters)

  -- Convert the parameter/data offsets into something more useful (the offset into the data section)
  -- - 0x20 for the header, - 0x01 for the length.
  parameter_offset = parameter_offset - 0x20 - 0x01 - #parameters - 0x02;
  -- - 0x20 for the header, - 0x01 for parameter length, the parameter length, and - 0x02 for the data length.
  data_offset = data_offset - 0x20 - 0x01 - #parameters - 0x02;

  -- I'm not sure I entirely understand why the '+1' is here, but I think it has to do with the string starting at '1' and not '0'.
  local function_parameters = string.sub(data, parameter_offset + 1, parameter_offset + parameter_count)
  local function_data       = string.sub(data, data_offset      + 1, data_offset      + data_count)

  local response = {}
  response['parameters'] = function_parameters
  response['data']       = function_data

  return true, response
end



---This is the core of making MSRPC calls. It sends out a MSRPC packet with the
-- given parameters and data.
--
-- Don't confuse these parameters and data with SMB's concepts of parameters
-- and data -- they are completely different. In fact, these parameters and
-- data are both sent in the SMB packet's 'data' section.
--
-- It is probably best to think of this as another protocol layer. This
-- function will wrap SMB stuff around a MSRPC call, make the call, then unwrap
-- the SMB stuff from it before returning.
--
--@param smb The SMB object associated with the connection
--@param function_parameters The parameter data to pass to the function. This
--                           is untested, since none of the transactions I've
--                           done have required parameters.
--@param function_data The data to send with the packet. This is basically the
--                     next protocol layer
--@param pipe [optional] The pipe to transact on. Default: "\PIPE\".
--@param no_setup [optional] If set, the 'setup' is set to 0 and some
--                parameters are left off. This occurs while using the LANMAN
--                Remote API. Default: false.
--@param overrides The overrides table
--@return (status, result) If status is false, result is an error message.
--        Otherwise, result is a table containing 'parameters' and 'data',
--        representing the parameters and data returned by the server.
function send_transaction_named_pipe(smb, function_parameters, function_data, pipe, no_setup, overrides)
  overrides = overrides or {}
  local header, parameters, data
  local parameter_offset = 0
  local parameter_size   = 0
  local data_offset      = 0
  local data_size        = 0
  local total_word_count, total_data_count, reserved1, parameter_count, parameter_displacement, data_count, data_displacement, setup_count, reserved2
  local response = {}
  local status

  if(pipe == nil) then
    pipe = "\\PIPE\\"
  end

  -- Header is 0x20 bytes long (not counting NetBIOS header).
  header = smb_encode_header(smb, command_codes['SMB_COM_TRANSACTION'], overrides) -- 0x25 = SMB_COM_TRANSACTION

  -- 0x20 for SMB header, 0x01 for parameters header, 0x20 for parameters length, 0x02 for data header, 0x07 for "\PIPE\"
  if(function_parameters) then
    parameter_offset = 0x20 + 0x01 + 0x20 + 0x02 + (#pipe + 1)
    parameter_size = #function_parameters
  end

  if(function_data) then
    data_offset       = 0x20 + 0x01 + 0x20 + 0x02 + (#pipe + 1) + parameter_size
    data_size         = #function_data
  end

  local setup
  if(no_setup) then
    setup = string.pack("<BB",
      0x00,                            -- Number of 'setup' words (none)
      0x00                             -- Reserved.
      )
  else
    setup = string.pack("<BBI2 I2 ",
      0x02,                            -- Number of 'setup' words
      0x00,                            -- Reserved.
      0x0026,                          -- Function to call.
      smb['fid']                       -- Handle to open file
      )
  end

  -- Parameters are 0x20 bytes long.
  parameters = string.pack("<I2 I2 I2 I2 BBI2 I4 I2 I2 I2 I2 I2",
    parameter_size,                  -- Total parameter count.
    data_size,                       -- Total data count.
    0x0008,                          -- Max parameter count.
    0x3984,                          -- Max data count.
    0x00,                            -- Max setup count.
    0x00,                            -- Reserved.
    0x0000,                          -- Flags (0x0000 = 2-way transaction, don't disconnect TIDs).
    0x00001388,                      -- Timeout (0x00000000 = return immediately).
    0x0000,                          -- Reserved.
    parameter_size,                  -- Parameter bytes.
    parameter_offset,                -- Parameter offset.
    data_size,                       -- Data bytes.
    data_offset                      -- Data offset.
    ) .. setup

  data = string.pack("<zI4", pipe, 0) -- Padding
  .. (function_parameters or '')
  .. (function_data or '')

  -- Send the transaction request
  stdnse.debug2("SMB: Sending SMB_COM_TRANSACTION")
  local result, err = smb_send(smb, header, parameters, data, overrides)
  if(result == false) then
    return false, err
  end

  -- Read the result
  status, header, parameters, data = smb_read(smb)
  if(status ~= true) then
    return false, header
  end

  local header_format = "<c4 B I4 B I2 I2 i8 I2 I2 I2 I2 I2"
  if #header < string.packsize(header_format) then
    return false, "SMB: ERROR: Server returned less data than it was supposed to (one or more fields are missing); aborting [8]"
  end

  -- Check if it worked
  local protocol_version, command, status, flags, flags2, pid_high, signature, unused, tid, pid, uid, mid, pos = string.unpack(header_format, header)

  if(status ~= 0) then
    if(status_names[status] == nil) then
      return false, string.format("Unknown SMB error: 0x%08x\n", status)
    else
      return false, status_names[status]
    end
  end

  -- Parse the parameters
  local parameters_format = "<I2 I2 I2 I2 I2 I2 I2 I2 I2 BB"
  if #parameters < string.packsize(parameters_format) then
    return false, "SMB: ERROR: Server returned less data than needed"
  end
  total_word_count, total_data_count, reserved1, parameter_count, parameter_offset, parameter_displacement, data_count, data_offset, data_displacement, setup_count, reserved2, pos = string.unpack(parameters_format, parameters)

  -- Convert the parameter/data offsets into something more useful (the offset into the data section)
  -- - 0x20 for the header, - 0x01 for the length.
  parameter_offset = parameter_offset - 0x20 - 0x01 - #parameters - 0x02;
  -- - 0x20 for the header, - 0x01 for parameter length, the parameter length, and - 0x02 for the data length.
  data_offset = data_offset - 0x20 - 0x01 - #parameters - 0x02;

  -- I'm not sure I entirely understand why the '+1' is here, but I think it has to do with the string starting at '1' and not '0'.
  function_parameters = string.sub(data, parameter_offset + 1, parameter_offset + parameter_count)
  function_data       = string.sub(data, data_offset      + 1, data_offset      + data_count)

  response['parameters'] = function_parameters
  response['data']       = function_data

  return true, response
end

function send_transaction_waitnamedpipe(smb, priority, pipe, overrides)
  overrides = overrides or {}
  local header, parameters, data
  local parameter_offset, data_offset
  local total_word_count, total_data_count, reserved1, parameter_count, parameter_offset, parameter_displacement, data_count, data_offset, data_displacement, setup_count, reserved2
  local response = {}
  local padding = ""
  local status

  -- Header is 0x20 bytes long (not counting NetBIOS header).
  header = smb_encode_header(smb, command_codes['SMB_COM_TRANSACTION'], overrides) -- 0x25 = SMB_COM_TRANSACTION

  -- Parameters are 0x20 bytes long.
  parameters = string.pack("<I2 I2 I2 I2 BBI2 I4 I2 I2 I2 I2 I2 BBI2 I2 ",
    0,                               -- Total parameter count.
    0,                               -- Total data count.
    0x000,                           -- Max parameter count.
    0x400,                           -- Max data count.
    0x00,                            -- Max setup count.
    0x00,                            -- Reserved.
    0x0000,                          -- Flags (0x0000 = 2-way transaction, don't disconnect TIDs).
    30,                              -- Timeout (0x00000000 = return immediately).
    0x0000,                          -- Reserved.
    0,                               -- Parameter bytes.
    0,                               -- Parameter offset.
    0,                               -- Data bytes.
    0,                               -- Data offset.
    0x02,                            -- Number of 'setup' words (only ever seen '2').
    0x00,                            -- Reserved.
    0x0053,                          -- Function to call.
    priority                         -- Handle to open file
    )

  data = string.pack("z", pipe) .. string.rep('\0', (4 - ((#pipe+1) % 4)) % 4)

  -- Send the transaction request
  stdnse.debug2("SMB: Sending SMB_COM_TRANSACTION (WaitNamedPipe)")
  local result, err = smb_send(smb, header, parameters, data, overrides)
  if(result == false) then
    return false, err
  end

  -- Read the result
  status, header, parameters, data = smb_read(smb)
  if(status ~= true) then
    return false, header
  end

  local header_format = "<c4 B I4 B I2 I2 i8 I2 I2 I2 I2 I2"
  if #header < string.packsize(header_format) then
    return false, "SMB: ERROR: Server returned less data than it was supposed to (one or more fields are missing); aborting [8]"
  end

  -- Parse out the header
  local protocol_version, command, status, flags, flags2, pid_high, signature, unused, tid, pid, uid, mid, pos = string.unpack(header_format, header)

  if(status ~= 0) then
    if(status_names[status] == nil) then
      return false, string.format("Unknown SMB error: 0x%08x\n", status)
    else
      return false, status_names[status]
    end
  end

  -- Parse the parameters
  local parameters_format = "<I2 I2 I2 I2 I2 I2 I2 I2 I2 BB"
  if #parameters < string.packsize(parameters_format) then
    return false, "SMB: ERROR: Server returned less data than needed"
  end
  total_word_count, total_data_count, reserved1, parameter_count, parameter_offset, parameter_displacement, data_count, data_offset, data_displacement, setup_count, reserved2, pos = string.unpack(parameters_format, parameters)

  return true, response
end

---Upload a file from the local machine to the remote machine, on the given share.
--
--@param host       The host object
--@param localfile  The file on the local machine, relative to the nmap path
--@param share      The share to upload it to (eg, C$).
--@param remotefile The remote file on the machine. It is relative to the share's root.
--@param overrides  A table of override values that's passed to the smb functions.
--@param encoded    Set to 'true' if the file is encoded (xor'ed with 0xFF), It will be decoded before upload. Default: false
--@return (status, err) If status is false, err is an error message. Otherwise, err is undefined.
function file_upload(host, localfile, share, remotefile, overrides, encoded)
  local status, err, smbstate
  local chunk = 1024

  -- Attempt to open a handle to the file without adding a path to it
  local handle = io.open(localfile, "r")

  -- If the open failed, try to search for the file
  if(not(handle)) then
    stdnse.debug1("Couldn't open %s directly, searching Nmap's paths...", localfile)
    local filename = nmap.fetchfile(localfile)

    -- Check if it was found
    if(filename == nil) then
      return false, string.format("Couldn't find the file to upload (%s)", localfile)
    end
    handle = io.open(filename, "r")
  end

  -- Create the SMB session
  status, smbstate = start_ex(host, true, true, share, remotefile, nil, overrides)
  if(status == false) then
    return false, smbstate
  end


  local i = 0
  local data = handle:read(chunk)
  local new_data = {}
  while(data ~= nil and #data > 0) do

    if(encoded) then
      for j = 1, #data, 1 do
        new_data[j] = string.char(0xFF ~ string.byte(data, j))
      end
      data = table.concat(new_data, "", 1, #data)
    end

    status, err = write_file(smbstate, data, i)
    if(status == false) then
      stop(smbstate)
      return false, err
    end

    data = handle:read(chunk)
    i = i + chunk
  end

  handle:close()
  status, err = close_file(smbstate)
  if(status == false) then
    stop(smbstate)
    return false, err
  end

  -- Stop the session
  stop(smbstate)

  return true
end

---Write given data to the remote machine on the given share. This is similar to <code>file_upload</code>, except the
-- data is given as a string, not a file.
--
--@param host          The host object
--@param data          The string containing the data to be written
--@param share         The share to upload it to (eg, C$).
--@param remotefile    The remote file on the machine. It is relative to the share's root.
--@param use_anonymous [optional] If set to 'true', test is done by the anonymous user rather than the current user.
--@return (status, err) If status is false, err is an error message. Otherwise, err is undefined.
function file_write(host, data, share, remotefile, use_anonymous)
  local status, err, smbstate
  local chunk = 1024
  local overrides = nil

  -- If anonymous is being used, create some overrides
  if(use_anonymous) then
    overrides = get_overrides_anonymous()
  end

  -- Create the SMB session
  status, smbstate = start_ex(host, true, true, share, remotefile, nil, overrides)

  if(status == false) then
    return false, smbstate
  end

  local i = 1
  while(i <= #data) do
    local chunkdata = string.sub(data, i, i + chunk - 1)
    status, err = write_file(smbstate, chunkdata, i - 1)
    if(status == false) then
      stop(smbstate)
      return false, err
    end

    i = i + chunk
  end

  status, err = close_file(smbstate)
  if(status == false) then
    stop(smbstate)
    return false, err
  end

  -- Stop the session
  stop(smbstate)

  return true
end

---Write given data to the remote machine on the given share. This is similar to <code>file_upload</code>, except the
-- data is given as a string, not a file.
--
--@param host          The host object
--@param share         The share to read it from (eg, C$).
--@param remotefile    The remote file on the machine. It is relative to the share's root.
--@param use_anonymous [optional] If set to 'true', test is done by the anonymous user rather than the current user.
--@param overrides     [optional] Override various fields in the SMB packets.
--@return (status, err) If status is false, err is an error message. Otherwise, err is undefined.
function file_read(host, share, remotefile, use_anonymous, overrides)
  local status, err, smbstate
  local result
  local chunk = 1024
  local read = ""

  -- Make sure we got overrides
  overrides = overrides or {}

  -- If anonymous is being used, create some overrides
  if(use_anonymous) then
    overrides = get_overrides_anonymous(overrides)
  end

  -- Create the SMB session
  status, smbstate = start_ex(host, true, true, share, remotefile, nil, overrides)

  if(status == false) then
    return false, smbstate
  end

  local i = 1
  while true do
    status, result = read_file(smbstate, i - 1, chunk)
    if(status == false) then
      stop(smbstate)
      return false, result
    end

    if(result['data_length'] == 0) then
      break
    end

    read = read .. result['data']
    i = i + chunk
  end

  status, err = close_file(smbstate)
  if(status == false) then
    stop(smbstate)
    return false, err
  end

  -- Stop the session
  stop(smbstate)
  return true, read
end

---Check how many files, in a given list, exist on the given share.
--
--@param host          The host object
--@param share         The share to read it from (eg, C$).
--@param files         A list of files to look for; it is relative to the share's root.
--@param overrides     [optional] Override various fields in the SMB packets.
--@return status: A true/false value indicating success
--@return count:  The number of files that existed, or an error message if status is 'false'
--@return files:  A list of the files that existed.
function files_exist(host, share, files, overrides)
  local status, smbstate, result, err

  -- Make sure we got overrides
  overrides = overrides or {}

  -- We don't wan to be creating the files
  overrides['file_create_disposition'] = 1

  -- Create the SMB session
  status, smbstate = start_ex(host, true, true, share, nil, nil, overrides)

  if(status == false) then
    return false, smbstate
  end

  local exist = 0
  local list  = {}

  for _, file in ipairs(files) do
    -- Try and open the file
    status, result = create_file(smbstate, file, overrides)

    -- If there was an error other than 'file already exists', return an error
    if(not(status) and result ~= 'NT_STATUS_OBJECT_NAME_NOT_FOUND') then
      return false, result
    end

    -- If the file existed, count it and close it
    if(status) then
      exist = exist + 1
      table.insert(list, file)
      status, err = close_file(smbstate)
      if(status == false) then
        stop(smbstate)
        return false, err
      end
    end
  end

  -- Stop the session
  stop(smbstate)
  return true, exist, list
end

---Delete a file from the remote machine
--
--@param host       The host object
--@param share      The share to upload it to (eg, C$).
--@param remotefile The remote file on the machine. It is relative to the share's root. It can be a string, or an array.
--@return (status, err) If status is false, err is an error message. Otherwise, err is undefined.
function file_delete(host, share, remotefile)
  local status, smbstate, err

  -- Create the SMB session
  status, smbstate = start_ex(host, true, true, share)
  if(status == false) then
    return false, smbstate
  end

  -- Make sure the remotefile is always a table, to save on duplicate code
  if(type(remotefile) ~= "table") then
    remotefile = {remotefile}
  end


  for _, file in ipairs(remotefile) do
    status, err = delete_file(smbstate, file)
    if(status == false) then
      stdnse.debug1("SMB: Couldn't delete %s\\%s: %s", share, file, err)
      if(err ~= 'NT_STATUS_OBJECT_NAME_NOT_FOUND') then
        stop(smbstate)
        return false, err
      end
    end
  end

  -- Stop the session
  stop(smbstate)

  return true
end

-- Sends TRANS2_FIND_FIRST2 / TRANS2_FIND_NEXT2 request, takes care of
-- short/fragmented responses, and returns a list of file entries
--
-- @param smbstate the SMB object associated with the connection
-- @param srch_id of search to resume (for TRANS2_FIND_NEXT2) or nil
-- @param trans2_params string representing Trans2_Parameters
-- @return status of the request
-- @return srch_id of search to resume later, or nil if the search completed
--                 or the error message if status is false
-- @return list of file entries
local function send_and_receive_find_request(smbstate, srch_id, trans2_params)
  local TRANS2_FIND_FIRST2 = 1
  local TRANS2_FIND_NEXT2  = 2
  local sub_command = srch_id and TRANS2_FIND_NEXT2 or TRANS2_FIND_FIRST2
  local status = send_transaction2(smbstate, sub_command, trans2_params, "")
  if not status then
    return false, "Failed to send data to server: send_transaction2"
  end

  local resp
  status, resp = receive_transaction2(smbstate)
  if not status or #resp.parameters < 2 then
    return false, "Failed to receive data from server: receive_transaction2"
  end

  local param_pos = 1
  if sub_command == TRANS2_FIND_FIRST2 then
    srch_id, param_pos = string.unpack("<I2", resp.parameters, param_pos)
  end

  -- parse Trans2_Parameters
  -- https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/4e65d94e-09af-4511-a77a-b73adf1c52d6
  local param_fmt = "<I2 I2 xx I2"
  if #resp.parameters < param_pos - 1 + param_fmt:packsize() then
    return false, "Truncated response from server: receive_transaction2"
  end
  local srch_cnt, srch_end, last_name_pos = param_fmt:unpack(resp.parameters, param_pos)

  -- format of SMB_FIND_FILE_BOTH_DIRECTORY_INFO, without trailing FileName
  -- https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/2aa849f4-1bc0-42bf-9c8f-d09f11fccc4c
  local entry_fmt = "<I4 xxxx I8 I8 I8 I8 I8 I8 I4 I4 xxxx B x c24"
  local entry_len = entry_fmt:packsize()

  -- check if we need more packets to reassemble this transaction
  while #resp.data < last_name_pos + entry_len do
    local status, tmp = receive_transaction2(smbstate)
    if not status then
      return false, "Truncated response from receive_transaction2"
    end
    resp.data = resp.data .. tmp.data
  end

  -- parse response, based on SMB_FIND_FILE_BOTH_DIRECTORY_INFO
  local entries = {}
  local data_pos = 1
  while srch_cnt > 0 do
    if #resp.data - data_pos + 1 < entry_len then
      return false, "Truncated response from receive_transaction2"
    end
    local entry = {}
    local next_pos, fn_pos, fn_len, sfn_len
    next_pos, entry.created, entry.accessed, entry.write, entry.change,
      entry.eof, entry.alloc_size, entry.attrs, fn_len, sfn_len,
      entry.s_fname, fn_pos = entry_fmt:unpack(resp.data, data_pos)

    local time = entry.created
    time = (time // 10000000) - 11644473600
    entry.created = datetime.format_timestamp(time)

    if sfn_len > 0 then
      entry.s_fname = entry.s_fname:sub(1, sfn_len)
    else
      entry.s_fname = nil
    end

    if #resp.data - fn_pos + 1 < fn_len then
      return false, "Truncated response from receive_transaction2"
    end
    entry.fname = string.unpack("z", resp.data, fn_pos)
    table.insert(entries, entry)
    data_pos = data_pos + next_pos
    srch_cnt = srch_cnt - 1
  end
  return true, (srch_end == 0 and srch_id or nil), entries
end

---
-- List files based on a pattern within a given share and directory
--
-- @param smbstate the SMB object associated with the connection
-- @param fname filename to search for, relative to share path
-- @param options table containing none or more of the following
--        <code>maxfiles</code> how many files to request in a single Trans2 op
--        <code>srch_attrs</code> table containing one or more of the following boolean attributes:
--              <code>ro</code> - find read only files
--              <code>hidden</code> - find hidden files
--              <code>system</code> - find system files
--              <code>volid</code> - include volume ids in result
--              <code>dir</code> - find directories
--              <code>archive</code> - find archived files
-- @return iterator function retrieving the next result
function find_files (smbstate, fname, options)
  options = options or {}

  -- convert options.srch_attrs to a bitmap
  local xlat_srch_attrs = {ro      = "SMB_FILE_ATTRIBUTE_READONLY",
                           hidden  = "SMB_FILE_ATTRIBUTE_HIDDEN",
                           system  = "SMB_FILE_ATTRIBUTE_SYSTEM",
                           volid   = "SMB_FILE_ATTRIBUTE_VOLUME",
                           dir     = "SMB_FILE_ATTRIBUTE_DIRECTORY",
                           archive = "SMB_FILE_ATTRIBUTE_ARCHIVE"}
  local srch_attrs_mask = 0
  local srch_attrs = options.srch_attrs or {ro=true, hidden=false, system=true, dir=true}
  for k, v in pairs(srch_attrs) do
    if v then
      srch_attrs_mask = srch_attrs_mask | file_attributes[xlat_srch_attrs[k]]
    end
  end

  fname = fname or '\\*'
  if fname:sub(1,1) ~= '\\' then
    fname = '\\' .. fname
  end

  local srch_flags = 0x0002 | 0x0004 -- SMB_FIND_CLOSE_AT_EOS, SMB_FIND_RETURN_RESUME_KEYS
  local srch_info_lvl = 0x0104       -- SMB_FIND_FILE_BOTH_DIRECTORY_INFO
  local max_srch_cnt = tonumber(options.maxfiles)
  if max_srch_cnt and max_srch_cnt > 0 then
    max_srch_cnt = math.floor(4 + math.min(1020, max_srch_cnt))
  else
    max_srch_cnt = 1024
  end

  -- state variables for next_entry() iterator
  local first_run = true
  local srch_id = nil
  local last_fname = nil
  local entries = {}
  local entry_idx = 1

  local function next_entry()
    if entry_idx > #entries then  -- get more file entries from the target
      local trans2_params
      if first_run then -- TRANS2_FIND_FIRST2
        first_run = false
        -- https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/b2b2a730-9499-4f05-884e-d5bb7b9caf90
        trans2_params = string.pack("<I2 I2 I2 I2 I4 z",
                                  srch_attrs_mask, -- what types of files to return
                                  max_srch_cnt,    -- maximum number of returned entries
                                  srch_flags,      -- Flags
                                  srch_info_lvl,   -- level of returned file details
                                  0,               -- SearchStorageType
                                  fname)           -- file name to search for
      -- FIXME filename ASCII vs UNICODE
      else -- TRANS2_FIND_NEXT2
        if not srch_id then  -- the search is over
          return
        end
        -- https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/80dc980e-fe03-455c-ada6-7c5dd6c551ba
        trans2_params = string.pack("<I2 I2 I2 I4 I2 z",
                                  srch_id,         -- which search to resume
                                  max_srch_cnt,    -- maximum number of returned entries
                                  srch_info_lvl,   -- level of returned file details
                                  0,               -- ResumeKey
                                  srch_flags,      -- Flags
                                  last_fname)      -- last file name previously returned
        -- FIXME wtf is ResumeKey?
      end
      local status
      status, srch_id, entries = send_and_receive_find_request(smbstate, srch_id, trans2_params)
      if not status then
        stdnse.debug1("Routine find_files failed with error: %s", srch_id)
        srch_id = nil
        entries = {}
      end
      entry_idx = 1
      if #entries == 0 then
        return
      end
    end
    local entry = entries[entry_idx]
    last_fname = entry.fname
    entry_idx = entry_idx + 1
    return entry
  end
  return next_entry
end

---Determine whether or not the anonymous user has write access on the share. This is done by creating then
-- deleting a file.
--
--@param host     The host object
--@param share    The share to test
--@return (status, result) If status is false, result is an error message. The error message 'NT_STATUS_OBJECT_NAME_NOT_FOUND'
--        should be handled gracefully; it indicates that the share isn't a fileshare. Otherwise, result is a boolean value:
--        true if the file was successfully written, false if it was not.
function share_anonymous_can_write(host, share)
  local filename, status, err

  -- First, choose a filename. This should be random.
  filename = "nmap-test-file"

  -- Next, attempt to write to that file
  status, err = file_write(host, string.rep("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 10), share, filename, true)
  if(status == false) then
    if(err == "NT_STATUS_OBJECT_NAME_NOT_FOUND") then
      return false, err
    end

    if(err == "NT_STATUS_ACCESS_DENIED" or err == "NT_STATUS_INVALID_PARAMETER") then
      return true, false
    end

    return false, "Error writing test file to disk as anonymous: " .. err
  end

  -- Now the important part: delete it
  status, err = file_delete(host, share, filename)
  if(status == false) then
    return false, "Error deleting test file as anonymous: " .. err
  end

  return true, true
end


---Determine whether or not the current user has read or read/write access on the share. This is done by creating then
-- deleting a file.
--
--@param host     The host object
--@param share    The share to test
--@return (status, result) If status is false, result is an error message. The error message 'NT_STATUS_OBJECT_NAME_NOT_FOUND'
--        should be handled gracefully; it indicates that the share isn't a fileshare. Otherwise, result is a boolean value:
--        true if the file was successfully written, false if it was not.
function share_user_can_write(host, share)

  local filename, status, err

  -- First, choose a filename. This should be random.
  filename = "nmap-test-file"

  -- Next, attempt to write to that file
  status, err = file_write(host, string.rep("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 10), share, filename)
  if(status == false) then
    if(err == "NT_STATUS_OBJECT_NAME_NOT_FOUND") then
      return false, err
    end

    if(err == "NT_STATUS_ACCESS_DENIED" or err == "NT_STATUS_INVALID_PARAMETER") then
      return true, false
    end

    return false, "Error writing test file to disk as user: " .. err
  end

  -- Now the important part: delete it
  status, err = file_delete(host, share, filename)
  if(status == false) then
    return false, "Error deleting test file as user: " .. err
  end

  return true, true
end

---Check whether or not a share is accessible by the anonymous user. Assumes that <code>share_host_returns_proper_error</code>
-- has been called and returns <code>true</code>.
--
--@param host     The host object
--@param share    The share to test
--@return (status, result) If status is false, result is an error message. Otherwise, result is a boolean value:
--        true if anonymous access is permitted, false otherwise.
function share_anonymous_can_read(host, share)
  local status, smbstate, err
  local overrides = get_overrides_anonymous()

  -- Begin the SMB session
  status, smbstate = start(host)
  if(status == false) then
    return false, smbstate
  end

  -- Negotiate the protocol
  status, err = negotiate_protocol(smbstate, overrides)
  if(status == false) then
    stop(smbstate)
    return false, err
  end

  -- Start up a null session
  status, err = start_session(smbstate, overrides)

  if(status == false) then
    stop(smbstate)
    return false, err
  end

  -- Attempt a connection to the share
  status, err = tree_connect(smbstate, share, overrides)
  if(status == false) then

    -- Stop the session
    stop(smbstate)

    -- ACCESS_DENIED is the expected error: it tells us that the connection failed
    if(err == 0xc0000022 or err == 'NT_STATUS_ACCESS_DENIED') then
      return true, false
    else
      return false, err
    end
  end



  stop(smbstate)
  return true, true
end

---Check whether or not a share is accessible by the current user. Assumes that <code>share_host_returns_proper_error</code>
-- has been called and returns <code>true</code>.
--
--@param host     The host object
--@param share    The share to test
--@return (status, result) If status is false, result is an error message. Otherwise, result is a boolean value:
--        true if anonymous access is permitted, false otherwise.
function share_user_can_read(host, share)
  local status, smbstate, err
  local overrides = {}

  -- Begin the SMB session
  status, smbstate = start(host)
  if(status == false) then
    return false, smbstate
  end

  -- Negotiate the protocol
  status, err = negotiate_protocol(smbstate, overrides)
  if(status == false) then
    stop(smbstate)
    return false, err
  end

  -- Start up a null session
  status, err = start_session(smbstate, overrides)
  if(status == false) then
    stop(smbstate)
    return false, err
  end

  -- Attempt a connection to the share
  status, err = tree_connect(smbstate, share, overrides)
  if(status == false) then

    -- Stop the session
    stop(smbstate)

    -- ACCESS_DENIED is the expected error: it tells us that the connection failed
    if(err == 0xc0000022 or err == 'NT_STATUS_ACCESS_DENIED') then
      return true, false
    else
      return false, err
    end
  end

  stop(smbstate)
  return true, true
end

---Determine whether or not a host will accept any share name (I've seen this on certain systems; it's
-- bad, because it means we cannot tell whether or not a share exists).
--
--@param host     The host object
--@param use_anonymous [optional] If set to 'true', test is done by the anonymous user rather than the current user.
--@return (status, result) If status is false, result is an error message. Otherwise, result is a boolean value:
--        true if the file was successfully written, false if it was not.
function share_host_returns_proper_error(host, use_anonymous)
  local status, smbstate, err
  local share = "nmap-share-test"
  local overrides

  if ( use_anonymous ) then
    overrides = get_overrides_anonymous()
  end

  -- Begin the SMB session
  status, smbstate = start(host)
  if(status == false) then
    return false, smbstate
  end

  -- Negotiate the protocol
  status, err = negotiate_protocol(smbstate, overrides)
  if(status == false) then
    stop(smbstate)
    return false, err
  end

  -- Start up a null session
  status, err = start_session(smbstate, overrides)
  if(status == false) then
    stop(smbstate)
    return false, err
  end

  -- Connect to the share
  stdnse.debug1("SMB: Trying a random share to see if server responds properly: %s", share)
  status, err = tree_connect(smbstate, share, overrides)

  if(status == false) then
    -- If the error is NT_STATUS_ACCESS_DENIED (0xc0000022), that's bad -- we don't want non-existent shares
    -- showing up as 'access denied'. Any other error is ok.
    if(err == 0xc0000022 or err == 'NT_STATUS_ACCESS_DENIED') then
      stdnse.debug1("SMB: Server doesn't return proper value for non-existent shares (returns ACCESS_DENIED)")
      stop(smbstate)
      return true, false
    end
  else
    -- If we were actually able to connect to this share, then there's probably a serious issue
    stdnse.debug1("SMB: Server doesn't return proper value for non-existent shares (accepts the connection)")
    stop(smbstate)
    return true, false
  end

  stop(smbstate)
  return true, true
end

---Get all the details we can about the share. These details are stored in a table and returned.
--
--@param host   The host object.
--@param share An array of shares to check.
--@return (status, result) If status is false, result is an error message. Otherwise, result is a boolean value:
--        true if the file was successfully written, false if it was not.
function share_get_details(host, share)
  local msrpc = require "msrpc" -- avoid require cycle
  local smbstate, status, result
  local i
  local details = {}

  --Transform name to FQPN form
  status, share = get_fqpn(host, share)
  if not status then
    stdnse.debug1("SMB:Couldn't obtain FQPN share name. Trying with '%s'", share)
  end

  -- Save the name
  details['name'] = share

  -- Check if the current user can read the share
  stdnse.debug1("SMB: Checking if share %s can be read by the current user", share)
  status, result = share_user_can_read(host, share)
  if(status == false) then
    return false, result
  end
  details['user_can_read'] = result

  -- Check if the anonymous reader can read the share
  stdnse.debug1("SMB: Checking if share %s can be read by the anonymous user", share)
  status, result = share_anonymous_can_read(host, share)
  if(status == true) then
    details['anonymous_can_read'] = result
  end

  -- Check if the current user can write to the share
  stdnse.debug1("SMB: Checking if share %s can be written by the current user", share)
  status, result = share_user_can_write(host, share)
  if(status == false) then
    if(result == "NT_STATUS_OBJECT_NAME_NOT_FOUND") then
      details['user_can_write'] = "NT_STATUS_OBJECT_NAME_NOT_FOUND"
    else
      return false, result
    end
  end
  details['user_can_write'] = result

  -- Check if the anonymous user can write to the share
  stdnse.debug1("SMB: Checking if share %s can be written by the anonymous user", share)
  status, result = share_anonymous_can_write(host, share)
  if(status == false and result == "NT_STATUS_OBJECT_NAME_NOT_FOUND") then
    details['anonymous_can_write'] = "NT_STATUS_OBJECT_NAME_NOT_FOUND"
  elseif( status == true ) then
    details['anonymous_can_write'] = result
  end

  -- Try and get full details about the share
  status, result = msrpc.get_share_info(host, share)
  if(status == false) then
    -- We don't stop for this error (it's pretty common since administrative privileges are required here)
    stdnse.debug1("SMB: Failed to get share info for %s: %s", share, result)
    details['details'] = result
  else
    -- Process the result a bit
    result = result['info']
    if(result['max_users'] == 0xFFFFFFFF) then
      result['max_users'] = "<unlimited>"
    end
    details['details'] = result
  end

  return true, details
end

---Retrieve a list of fileshares, along with any details that could be pulled. This is the core of smb-enum-shares.nse, but
-- can also be used by any script that needs to find an open share.
--
-- In the best care, the shares are determined by calling <code>msrpc.enum_shares</code>, and information is gathered by calling
-- <code>msrpc.get_share_info</code>. These require a certain level of access, though, so as a fallback, a pre-programmed list of
-- shares is used, and these are verified by attempting a connection.
--
--@param host The host object.
--@return (status, result, extra) If status is false, result is an error message. Otherwise, result is an array of shares with as much
--        detail as we could get. If extra isn't nil, it is set to extra information that should be displayed (such as a warning).
function share_get_list(host)
  local msrpc = require "msrpc" -- avoid require cycle
  local status, result
  local enum_status
  local extra = ""
  local shares = {}
  local share_details = {}

  -- Try and do this the good way, make a MSRPC call to get the shares
  stdnse.debug1("SMB: Attempting to log into the system to enumerate shares")
  enum_status, shares = msrpc.enum_shares(host)

  -- If that failed, try doing it with brute force. This almost certainly won't find everything, but it's the
  -- best we can do.
  if(enum_status == false) then
    stdnse.debug1("SMB: Enumerating shares failed, guessing at common ones (%s)", shares)
    extra = string.format("ERROR: Enumerating shares failed, guessing at common ones (%s)", shares)

    -- Take some common share names I've seen (thanks to Brandon Enright for most of these, except the last few)
    shares = {"ADMIN", "BACKUP", "DATA", "DESKTOP", "DOCS", "FILES", "GROUPS", "HD", "HOME", "INFO", "IPC", "MEDIA", "MY DOCUMENTS", "NETLOGON", "PICTURES", "PORN", "PR0N", "PRINT", "PROGRAMS", "PRON", "PUBLIC", "SHARE", "SHARED", "SOFTWARE", "STMP", "TEMP", "TEST", "TMP", "USERS", "WEB DOCUMENTS","WEBSERVER", "WWW", "XSERVE" }

    -- Try every alphabetic share
    for i = string.byte("A", 1), string.byte("Z", 1), 1 do
      shares[#shares + 1] = string.char(i)
    end

    -- For each share, add one with the same name and a trailing '$'
    local sharesLength = #shares
    for shareItr = 1, sharesLength, 1 do
      shares[ sharesLength + shareItr ] = shares[ shareItr ] .. '$'
    end
  else
    stdnse.debug1("SMB: Found %d shares, will attempt to find more information", #shares)
  end

  -- Sort the shares
  table.sort(shares)

  -- Ensure that the server returns the proper error message
  -- first try anonymously, then using a user account (in case anonymous connections are not supported)
  for _, anon in ipairs({true, false}) do
    status, result = share_host_returns_proper_error(host, anon)

    if(status == true and result == false) then
      return false, "Server doesn't return proper value for non-existent shares; can't enumerate shares"
    end
  end

  if(status == false) then
    return false, result
  end

  -- Get more information on each share
  for i = 1, #shares, 1 do
    local status, result
    stdnse.debug1("SMB: Getting information for share: %s", shares[i])
    status, result = share_get_details(host, shares[i])
    if(status == false and result == 'NT_STATUS_BAD_NETWORK_NAME') then
      stdnse.debug1("SMB: Share doesn't exist: %s", shares[i])
    elseif(status == false) then
      stdnse.debug1("SMB: Error while getting share details: %s", result)
      return false, result
    else
      -- Save the share details
      table.insert(share_details, result)
    end
  end

  return true, share_details, extra
end

---Find a share that the current user can write to. Return it, along with its path. If no share could be found,
-- an error is returned. If the path cannot be determined, the returned path is nil.
--
--@param host The host object.
--@return (status, name, path, names) If status is false, result is an error message. Otherwise, name is the name of the share,
--        path is its path, if it could be determined, and names is a list of all writable shares.
function share_find_writable(host)
  local i
  local status, shares
  local main_name, main_path
  local names = {}
  local writable = {}

  status, shares = share_get_list(host)
  if(status == false) then
    return false, shares
  end

  for i = 1, #shares, 1 do
    if(shares[i]['user_can_write'] == true) then
      if(main_name == nil) then
        main_name = shares[i]['name']

        if(shares[i]['details'] ~= nil) then
          main_path = shares[i]['details']['path']
        end
      end

      table.insert(names, shares[i]['name'])
    end
  end

  if(main_name == nil) then
    return false, "Couldn't find a writable share!"
  else
    return true, main_name, main_path, names
  end
end

--- Converts numbered Windows version strings (<code>"Windows 5.0"</code>, <code>"Windows 5.1"</code>) to names (<code>"Windows 2000"</code>, <code>"Windows XP"</code>).
--@param os The numbered OS version.
--@return The actual name of the OS (or the same as the <code>os</code> parameter if no match was found).
function get_windows_version(os)

  if(os == "Windows 5.0") then
    return "Windows 2000"
  elseif(os == "Windows 5.1")then
    return "Windows XP"
  end

  return os

end

---Retrieve information about the host's operating system. This should always be possible to call, as long as there isn't already
-- a SMB session established.
--
-- The returned table has the following keys (shown here with sample values).
-- * <code>os</code>: <code>"Windows 7 Professional 7601 Service Pack 1"</code>
-- * <code>lanmanager</code>: <code>"Windows 7 Professional 6.1"</code>
-- * <code>domain</code>: <code>"WORKGROUP"</code>
-- * <code>server</code>: <code>"COMPUTERNAME"</code>
-- * <code>time</code>: <code>1347121470.0462</code>
-- * <code>date</code>: <code>"2012-09-08 09:24:30"</code>
-- * <code>timezone</code>: <code>-7</code>
-- * <code>timezone_str</code>: <code>UTC-7</code>
-- * <code>port</code>: <code>445</code>
-- The table may also contain these additional keys:
-- * <code>fqdn</code>: <code>"Sql2008.lab.test.local"</code>
-- * <code>domain_dns</code>: <code>"lab.test.local"</code>
-- * <code>forest_dns</code>: <code>"test.local"</code>
-- * <code>workgroup</code>
--
--@param host The host object
--@return (status, data) If status is true, data is a table of values; otherwise, data is an error message.
function get_os(host)
  local state
  local status, smbstate

  local response = {}

  -- Start up SMB
  status, smbstate = start_ex(host, true, true, nil, nil, true)
  if(status == false) then
    return false, smbstate
  end

  -- See if we actually got something
  if(smbstate['os'] == nil and smbstate['lanmanager'] == nil) then
    return false, "Server didn't return OS details"
  end

  response['os']           = smbstate['os']
  response['lanmanager']   = smbstate['lanmanager']
  response['domain']       = smbstate['domain']
  response['server']       = smbstate['server']
  response['date']         = smbstate['date']
  response['time']         = smbstate['time']
  response['timezone_str'] = smbstate['timezone_str']
  response['timezone']     = smbstate['timezone']
  response['port']         = smbstate['port']

  -- Kill SMB
  stop(smbstate)


  -- Start another session with extended security. This will allow us to get
  -- additional information about the target.
  status, smbstate = start_ex(host, true, true, nil, nil, false)
  if(status == true) then
    -- See if we actually got something
    if (smbstate['fqdn'] or smbstate['domain_dns'] or smbstate['forest_dns']) then
      response['fqdn']         = smbstate['fqdn']
      response['domain_dns']   = smbstate['domain_dns']
      response['forest_dns']   = smbstate['forest_dns']
      -- After a non-extended security negotiation, smbstate['domain'] will
      -- contain the NetBIOS domain name, or the workgroup name. However,
      -- after an extended-security session setup, smbstate['domain'] will
      -- contain the NetBIOS domain name. For hosts in a workgroup, Windows
      -- uses the NetBIOS hostname as the NetBIOS domain name. Comparing the
      -- two will reveal whether the target is in a domain or a workgroup.
      if ( smbstate['domain'] ~= nil and response['domain'] ~= smbstate['domain'] ) then
        response['workgroup']    = response['domain']
        response['domain']       = nil
      end
    end

    -- Kill SMB again
    stop(smbstate)
  end

  return true, response
end

---Basically a wrapper around <code>socket:get_info</code>, except that it also makes a SMB connection before calling the
-- <code>get_info</code> function. Returns the mac address as well, for convenience.
--
--@param host The host object
--@return status: true for successful, false otherwise.
--@return If status is true, the local ip address; otherwise, an error message.
--@return The local port (not really meaningful, since it'll change next time).
--@return The remote ip address.
--@return The report port.
--@return The mac address, if possible; nil otherwise.
function get_socket_info(host)
  local status, lhost, lport, rhost, rport
  local smbstate, socket

  -- Start SMB (we need a socket to get the proper local ip
  status, smbstate = start_ex(host)
  if(status == false) then
    return false, smbstate
  end

  socket = smbstate['socket']
  status, lhost, lport, rhost, rport = socket:get_info()
  if(status == false) then
    return false, lhost
  end

  -- Stop SMB
  stop(smbstate)

  -- Get the mac in hex format, if possible
  local lmac = nil
  if(host.mac_addr_src) then
    lmac = stdnse.tohex(host.mac_addr_src, {separator = ":"})
  end

  return true, lhost, lport, rhost, rport, lmac
end

---Generate a string that's somewhat unique, but is based on factors that won't
-- change on a host.
--
-- At the moment, this is a very simple hash based on the IP address. This hash
-- is *very* likely to have collisions, and that's by design -- while it should
-- be somewhat unique, I don't want it to be trivial to uniquely determine who
-- it originated from.
--
-- TODO: At some point, I should re-do this function properly, with a method of
-- hashing that's somewhat proven.
--
--@param host      The host object
--@param extension [optional] The extension to add on the end of the file.
--                 Default: none.
--@param seed [optional] Some randomness on which to base the name. If you want
--            to do multiple files, each with its own uniqueish name, this can
--            be used.
--@return (status, data) If status is true, data is a table of values;
--        otherwise, data is an error message. Can be any kind of string.
function get_uniqueish_name(host, extension, seed)

  local status
  local lhost, lport, rhost, rport
  if(type(host) == "table") then
    status, lhost = get_socket_info(host)
  else
    lhost = host
  end

  -- Create our ultra-weak hash by using a simple xor/shift algorithm
  -- I tested this, and in 255 tests, there were roughly 10 collisions. That's about what I'm looking for.
  local hash = 0
  local i
  local str = lhost .. (seed or "") .. (extension or "") .. (nmap.registry.args.randomseed or "")

  for i = 1, #str, 1 do
    local chr = str:byte(i)
    hash = hash ~ chr
    hash = (hash << 3) | (hash >> 29)
    hash = hash ~ 3
    hash = hash & 0xFFFFFFFF
  end

  local response
  if(extension) then
    response = string.format("%x.%s", hash, extension)
  else
    response = string.format("%x", hash)
  end

  return true, response
end

---Determines, as accurately as possible, whether or not an account is an administrator. If there is an error,
-- 'false' is simply returned.
function is_admin(host, username, domain, password, password_hash, hash_type)
  local msrpc = require "msrpc" -- avoid require cycle
  local overrides = get_overrides(username, domain, password, password_hash, hash_type)

  stdnse.debug1("SMB: Checking if %s is an administrator", username)

  local status, smbstate = start(host)
  if(status == false) then
    stdnse.debug1("SMB; is_admin: Failed to start SMB: %s [%s]", smbstate, username)
    stop(smbstate)
    return false
  end

  local status, err      = negotiate_protocol(smbstate, overrides)
  if(status == false) then
    stdnse.debug1("SMB; is_admin: Failed to negotiate protocol: %s [%s]", err, username)
    stop(smbstate)
    return false
  end

  status, err      = start_session(smbstate, overrides)
  if(status == false) then
    stdnse.debug1("SMB; is_admin: Failed to start session %s [%s]", err, username)
    stop(smbstate)
    return false
  end

  local _, fqpn_share = get_fqpn(host, "IPC$")
  status, err      = tree_connect(smbstate, fqpn_share, overrides)
  if(status == false) then
    stdnse.debug1("SMB; is_admin: Failed to connect tree: %s [%s]", err, username)
    stop(smbstate)
    return false
  end

  status, err      = create_file(smbstate, msrpc.SRVSVC_PATH, overrides)
  if(status == false) then
    stdnse.debug1("SMB; is_admin: Failed to create file: %s [%s]", err, username)
    stop(smbstate)
    return false
  end

  status, err      = msrpc.bind(smbstate, msrpc.SRVSVC_UUID, msrpc.SRVSVC_VERSION, nil)
  if(status == false) then
    stdnse.debug1("SMB; is_admin: Failed to bind: %s [%s]", err, username)
    stop(smbstate)
    return false
  end

  -- Call netservergetstatistics for 'server'
  status, err = msrpc.srvsvc_netservergetstatistics(smbstate, host.ip)
  if(status == false) then
    stdnse.debug1("SMB; is_admin: Couldn't get server stats (may be normal): %s [%s]", err, username)
    stop(smbstate)
    return false
  end

  stop(smbstate)

  return true
end

---
-- Returns the fully qualified path name (FQPN) for shares.
-- This is required for modern versions of Windows.
-- Returns \\<ip>\<sharename> when successful. Otherwise, returns the same share name.
---
function get_fqpn(host, sharename)
  if host.ip and sharename then
    return true, string.format("\\\\%s\\%s", host.ip, sharename)
  end
  stdnse.debug1("SMB: get_fqpn: Couldn't determine server IP address")
  return false, sharename
end

command_codes =
{
  SMB_COM_CREATE_DIRECTORY          = 0x00,
  SMB_COM_DELETE_DIRECTORY          = 0x01,
  SMB_COM_OPEN                      = 0x02,
  SMB_COM_CREATE                    = 0x03,
  SMB_COM_CLOSE                     = 0x04,
  SMB_COM_FLUSH                     = 0x05,
  SMB_COM_DELETE                    = 0x06,
  SMB_COM_RENAME                    = 0x07,
  SMB_COM_QUERY_INFORMATION         = 0x08,
  SMB_COM_SET_INFORMATION           = 0x09,
  SMB_COM_READ                      = 0x0A,
  SMB_COM_WRITE                     = 0x0B,
  SMB_COM_LOCK_BYTE_RANGE           = 0x0C,
  SMB_COM_UNLOCK_BYTE_RANGE         = 0x0D,
  SMB_COM_CREATE_TEMPORARY          = 0x0E,
  SMB_COM_CREATE_NEW                = 0x0F,
  SMB_COM_CHECK_DIRECTORY           = 0x10,
  SMB_COM_PROCESS_EXIT              = 0x11,
  SMB_COM_SEEK                      = 0x12,
  SMB_COM_LOCK_AND_READ             = 0x13,
  SMB_COM_WRITE_AND_UNLOCK          = 0x14,
  SMB_COM_READ_RAW                  = 0x1A,
  SMB_COM_READ_MPX                  = 0x1B,
  SMB_COM_READ_MPX_SECONDARY        = 0x1C,
  SMB_COM_WRITE_RAW                 = 0x1D,
  SMB_COM_WRITE_MPX                 = 0x1E,
  SMB_COM_WRITE_MPX_SECONDARY       = 0x1F,
  SMB_COM_WRITE_COMPLETE            = 0x20,
  SMB_COM_QUERY_SERVER              = 0x21,
  SMB_COM_SET_INFORMATION2          = 0x22,
  SMB_COM_QUERY_INFORMATION2        = 0x23,
  SMB_COM_LOCKING_ANDX              = 0x24,
  SMB_COM_TRANSACTION               = 0x25,
  SMB_COM_TRANSACTION_SECONDARY     = 0x26,
  SMB_COM_IOCTL                     = 0x27,
  SMB_COM_IOCTL_SECONDARY           = 0x28,
  SMB_COM_COPY                      = 0x29,
  SMB_COM_MOVE                      = 0x2A,
  SMB_COM_ECHO                      = 0x2B,
  SMB_COM_WRITE_AND_CLOSE           = 0x2C,
  SMB_COM_OPEN_ANDX                 = 0x2D,
  SMB_COM_READ_ANDX                 = 0x2E,
  SMB_COM_WRITE_ANDX                = 0x2F,
  SMB_COM_NEW_FILE_SIZE             = 0x30,
  SMB_COM_CLOSE_AND_TREE_DISC       = 0x31,
  SMB_COM_TRANSACTION2              = 0x32,
  SMB_COM_TRANSACTION2_SECONDARY    = 0x33,
  SMB_COM_FIND_CLOSE2               = 0x34,
  SMB_COM_FIND_NOTIFY_CLOSE         = 0x35,
  SMB_COM_TREE_CONNECT              = 0x70,
  SMB_COM_TREE_DISCONNECT           = 0x71,
  SMB_COM_NEGOTIATE                 = 0x72,
  SMB_COM_SESSION_SETUP_ANDX        = 0x73,
  SMB_COM_LOGOFF_ANDX               = 0x74,
  SMB_COM_TREE_CONNECT_ANDX         = 0x75,
  SMB_COM_QUERY_INFORMATION_DISK    = 0x80,
  SMB_COM_SEARCH                    = 0x81,
  SMB_COM_FIND                      = 0x82,
  SMB_COM_FIND_UNIQUE               = 0x83,
  SMB_COM_FIND_CLOSE                = 0x84,
  SMB_COM_NT_TRANSACT               = 0xA0,
  SMB_COM_NT_TRANSACT_SECONDARY     = 0xA1,
  SMB_COM_NT_CREATE_ANDX            = 0xA2,
  SMB_COM_NT_CANCEL                 = 0xA4,
  SMB_COM_NT_RENAME                 = 0xA5,
  SMB_COM_OPEN_PRINT_FILE           = 0xC0,
  SMB_COM_WRITE_PRINT_FILE          = 0xC1,
  SMB_COM_CLOSE_PRINT_FILE          = 0xC2,
  SMB_COM_GET_PRINT_QUEUE           = 0xC3,
  SMB_COM_READ_BULK                 = 0xD8,
  SMB_COM_WRITE_BULK                = 0xD9,
  SMB_COM_WRITE_BULK_DATA           = 0xDA,
  SMB_NO_FURTHER_COMMANDS           = 0xFF
}

for i, v in pairs(command_codes) do
  command_names[v] = i
end


-- https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/2198f480-e047-4df0-ba64-f28eadef00b9
file_attributes =
{
  SMB_FILE_ATTRIBUTE_NORMAL      = 0x0000,
  SMB_FILE_ATTRIBUTE_READONLY    = 0x0001,
  SMB_FILE_ATTRIBUTE_HIDDEN      = 0x0002,
  SMB_FILE_ATTRIBUTE_SYSTEM      = 0x0004,
  SMB_FILE_ATTRIBUTE_VOLUME      = 0x0008,
  SMB_FILE_ATTRIBUTE_DIRECTORY   = 0x0010,
  SMB_FILE_ATTRIBUTE_ARCHIVE     = 0x0020,
  SMB_SEARCH_ATTRIBUTE_READONLY  = 0x0100,
  SMB_SEARCH_ATTRIBUTE_HIDDEN    = 0x0200,
  SMB_SEARCH_ATTRIBUTE_SYSTEM    = 0x0400,
  SMB_SEARCH_ATTRIBUTE_DIRECTORY = 0x1000,
  SMB_SEARCH_ATTRIBUTE_ARCHIVE   = 0x2000
}


-- see http://msdn.microsoft.com/en-us/library/cc231196(v=prot.10).aspx
status_codes =
{
  NT_STATUS_SUCCESS                           = 0x00000000,
  NT_STATUS_WERR_BADFILE                      = 0x00000002,
  NT_STATUS_WERR_ACCESS_DENIED                = 0x00000005,
  NT_STATUS_WERR_INVALID_PARAMETER            = 0x00000057,
  NT_STATUS_WERR_INVALID_NAME                 = 0x0000007b,
  NT_STATUS_WERR_UNKNOWN_LEVEL                = 0x0000007c,
  NT_STATUS_WERR_MORE_DATA                    = 0x000000ea,
  NT_STATUS_NO_MORE_ITEMS                     = 0x00000103,
  NT_STATUS_MORE_ENTRIES                      = 0x00000105,
  NT_STATUS_SOME_NOT_MAPPED                   = 0x00000107,
  NT_STATUS_SERVICE_REQUEST_TIMEOUT           = 0x0000041D,
  NT_STATUS_SERVICE_NO_THREAD                 = 0x0000041E,
  NT_STATUS_SERVICE_DATABASE_LOCKED           = 0x0000041F,
  NT_STATUS_SERVICE_ALREADY_RUNNING           = 0x00000420,
  NT_STATUS_INVALID_SERVICE_ACCOUNT           = 0x00000421,
  NT_STATUS_SERVICE_DISABLED                  = 0x00000422,
  NT_STATUS_CIRCULAR_DEPENDENCY               = 0x00000423,
  NT_STATUS_SERVICE_DOES_NOT_EXIST            = 0x00000424,
  NT_STATUS_SERVICE_CANNOT_ACCEPT_CTRL        = 0x00000425,
  NT_STATUS_SERVICE_NOT_ACTIVE                = 0x00000426,
  NT_STATUS_FAILED_SERVICE_CONTROLLER_CONNECT = 0x00000427,
  NT_STATUS_EXCEPTION_IN_SERVICE              = 0x00000428,
  NT_STATUS_DATABASE_DOES_NOT_EXIST           = 0x00000429,
  NT_STATUS_SERVICE_SPECIFIC_ERROR            = 0x0000042a,
  NT_STATUS_PROCESS_ABORTED                   = 0x0000042b,
  NT_STATUS_SERVICE_DEPENDENCY_FAIL           = 0x0000042c,
  NT_STATUS_SERVICE_LOGON_FAILED              = 0x0000042d,
  NT_STATUS_SERVICE_START_HANG                = 0x0000042e,
  NT_STATUS_INVALID_SERVICE_LOCK              = 0x0000042f,
  NT_STATUS_SERVICE_MARKED_FOR_DELETE         = 0x00000430,
  NT_STATUS_SERVICE_EXISTS                    = 0x00000431,
  NT_STATUS_ALREADY_RUNNING_LKG               = 0x00000432,
  NT_STATUS_SERVICE_DEPENDENCY_DELETED        = 0x00000433,
  NT_STATUS_BOOT_ALREADY_ACCEPTED             = 0x00000434,
  NT_STATUS_SERVICE_NEVER_STARTED             = 0x00000435,
  NT_STATUS_DUPLICATE_SERVICE_NAME            = 0x00000436,
  NT_STATUS_DIFFERENT_SERVICE_ACCOUNT         = 0x00000437,
  NT_STATUS_CANNOT_DETECT_DRIVER_FAILURE      = 0x00000438,
  DOS_STATUS_UNKNOWN_ERROR                    = 0x00010001,
  DOS_STATUS_NONSPECIFIC_ERROR                = 0x00010002,
  DOS_STATUS_DIRECTORY_NOT_FOUND              = 0x00030001,
  DOS_STATUS_ACCESS_DENIED                    = 0x00050001,
  DOS_STATUS_INVALID_FID                      = 0x00060001,
  DOS_STATUS_INVALID_NETWORK_NAME             = 0x00060002,
  NT_STATUS_BUFFER_OVERFLOW                   = 0x80000005,
  NT_STATUS_UNSUCCESSFUL                      = 0xc0000001,
  NT_STATUS_NOT_IMPLEMENTED                   = 0xc0000002,
  NT_STATUS_INVALID_INFO_CLASS                = 0xc0000003,
  NT_STATUS_INFO_LENGTH_MISMATCH              = 0xc0000004,
  NT_STATUS_ACCESS_VIOLATION                  = 0xc0000005,
  NT_STATUS_IN_PAGE_ERROR                     = 0xc0000006,
  NT_STATUS_PAGEFILE_QUOTA                    = 0xc0000007,
  NT_STATUS_INVALID_HANDLE                    = 0xc0000008,
  NT_STATUS_BAD_INITIAL_STACK                 = 0xc0000009,
  NT_STATUS_BAD_INITIAL_PC                    = 0xc000000a,
  NT_STATUS_INVALID_CID                       = 0xc000000b,
  NT_STATUS_TIMER_NOT_CANCELED                = 0xc000000c,
  NT_STATUS_INVALID_PARAMETER                 = 0xc000000d,
  NT_STATUS_NO_SUCH_DEVICE                    = 0xc000000e,
  NT_STATUS_NO_SUCH_FILE                      = 0xc000000f,
  NT_STATUS_INVALID_DEVICE_REQUEST            = 0xc0000010,
  NT_STATUS_END_OF_FILE                       = 0xc0000011,
  NT_STATUS_WRONG_VOLUME                      = 0xc0000012,
  NT_STATUS_NO_MEDIA_IN_DEVICE                = 0xc0000013,
  NT_STATUS_UNRECOGNIZED_MEDIA                = 0xc0000014,
  NT_STATUS_NONEXISTENT_SECTOR                = 0xc0000015,
  NT_STATUS_MORE_PROCESSING_REQUIRED          = 0xc0000016,
  NT_STATUS_NO_MEMORY                         = 0xc0000017,
  NT_STATUS_CONFLICTING_ADDRESSES             = 0xc0000018,
  NT_STATUS_NOT_MAPPED_VIEW                   = 0xc0000019,
  NT_STATUS_UNABLE_TO_FREE_VM                 = 0xc000001a,
  NT_STATUS_UNABLE_TO_DELETE_SECTION          = 0xc000001b,
  NT_STATUS_INVALID_SYSTEM_SERVICE            = 0xc000001c,
  NT_STATUS_ILLEGAL_INSTRUCTION               = 0xc000001d,
  NT_STATUS_INVALID_LOCK_SEQUENCE             = 0xc000001e,
  NT_STATUS_INVALID_VIEW_SIZE                 = 0xc000001f,
  NT_STATUS_INVALID_FILE_FOR_SECTION          = 0xc0000020,
  NT_STATUS_ALREADY_COMMITTED                 = 0xc0000021,
  NT_STATUS_ACCESS_DENIED                     = 0xc0000022,
  NT_STATUS_BUFFER_TOO_SMALL                  = 0xc0000023,
  NT_STATUS_OBJECT_TYPE_MISMATCH              = 0xc0000024,
  NT_STATUS_NONCONTINUABLE_EXCEPTION          = 0xc0000025,
  NT_STATUS_INVALID_DISPOSITION               = 0xc0000026,
  NT_STATUS_UNWIND                            = 0xc0000027,
  NT_STATUS_BAD_STACK                         = 0xc0000028,
  NT_STATUS_INVALID_UNWIND_TARGET             = 0xc0000029,
  NT_STATUS_NOT_LOCKED                        = 0xc000002a,
  NT_STATUS_PARITY_ERROR                      = 0xc000002b,
  NT_STATUS_UNABLE_TO_DECOMMIT_VM             = 0xc000002c,
  NT_STATUS_NOT_COMMITTED                     = 0xc000002d,
  NT_STATUS_INVALID_PORT_ATTRIBUTES           = 0xc000002e,
  NT_STATUS_PORT_MESSAGE_TOO_LONG             = 0xc000002f,
  NT_STATUS_INVALID_PARAMETER_MIX             = 0xc0000030,
  NT_STATUS_INVALID_QUOTA_LOWER               = 0xc0000031,
  NT_STATUS_DISK_CORRUPT_ERROR                = 0xc0000032,
  NT_STATUS_OBJECT_NAME_INVALID               = 0xc0000033,
  NT_STATUS_OBJECT_NAME_NOT_FOUND             = 0xc0000034,
  NT_STATUS_OBJECT_NAME_COLLISION             = 0xc0000035,
  NT_STATUS_HANDLE_NOT_WAITABLE               = 0xc0000036,
  NT_STATUS_PORT_DISCONNECTED                 = 0xc0000037,
  NT_STATUS_DEVICE_ALREADY_ATTACHED           = 0xc0000038,
  NT_STATUS_OBJECT_PATH_INVALID               = 0xc0000039,
  NT_STATUS_OBJECT_PATH_NOT_FOUND             = 0xc000003a,
  NT_STATUS_OBJECT_PATH_SYNTAX_BAD            = 0xc000003b,
  NT_STATUS_DATA_OVERRUN                      = 0xc000003c,
  NT_STATUS_DATA_LATE_ERROR                   = 0xc000003d,
  NT_STATUS_DATA_ERROR                        = 0xc000003e,
  NT_STATUS_CRC_ERROR                         = 0xc000003f,
  NT_STATUS_SECTION_TOO_BIG                   = 0xc0000040,
  NT_STATUS_PORT_CONNECTION_REFUSED           = 0xc0000041,
  NT_STATUS_INVALID_PORT_HANDLE               = 0xc0000042,
  NT_STATUS_SHARING_VIOLATION                 = 0xc0000043,
  NT_STATUS_QUOTA_EXCEEDED                    = 0xc0000044,
  NT_STATUS_INVALID_PAGE_PROTECTION           = 0xc0000045,
  NT_STATUS_MUTANT_NOT_OWNED                  = 0xc0000046,
  NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED          = 0xc0000047,
  NT_STATUS_PORT_ALREADY_SET                  = 0xc0000048,
  NT_STATUS_SECTION_NOT_IMAGE                 = 0xc0000049,
  NT_STATUS_SUSPEND_COUNT_EXCEEDED            = 0xc000004a,
  NT_STATUS_THREAD_IS_TERMINATING             = 0xc000004b,
  NT_STATUS_BAD_WORKING_SET_LIMIT             = 0xc000004c,
  NT_STATUS_INCOMPATIBLE_FILE_MAP             = 0xc000004d,
  NT_STATUS_SECTION_PROTECTION                = 0xc000004e,
  NT_STATUS_EAS_NOT_SUPPORTED                 = 0xc000004f,
  NT_STATUS_EA_TOO_LARGE                      = 0xc0000050,
  NT_STATUS_NONEXISTENT_EA_ENTRY              = 0xc0000051,
  NT_STATUS_NO_EAS_ON_FILE                    = 0xc0000052,
  NT_STATUS_EA_CORRUPT_ERROR                  = 0xc0000053,
  NT_STATUS_FILE_LOCK_CONFLICT                = 0xc0000054,
  NT_STATUS_LOCK_NOT_GRANTED                  = 0xc0000055,
  NT_STATUS_DELETE_PENDING                    = 0xc0000056,
  NT_STATUS_CTL_FILE_NOT_SUPPORTED            = 0xc0000057,
  NT_STATUS_UNKNOWN_REVISION                  = 0xc0000058,
  NT_STATUS_REVISION_MISMATCH                 = 0xc0000059,
  NT_STATUS_INVALID_OWNER                     = 0xc000005a,
  NT_STATUS_INVALID_PRIMARY_GROUP             = 0xc000005b,
  NT_STATUS_NO_IMPERSONATION_TOKEN            = 0xc000005c,
  NT_STATUS_CANT_DISABLE_MANDATORY            = 0xc000005d,
  NT_STATUS_NO_LOGON_SERVERS                  = 0xc000005e,
  NT_STATUS_NO_SUCH_LOGON_SESSION             = 0xc000005f,
  NT_STATUS_NO_SUCH_PRIVILEGE                 = 0xc0000060,
  NT_STATUS_PRIVILEGE_NOT_HELD                = 0xc0000061,
  NT_STATUS_INVALID_ACCOUNT_NAME              = 0xc0000062,
  NT_STATUS_USER_EXISTS                       = 0xc0000063,
  NT_STATUS_NO_SUCH_USER                      = 0xc0000064,
  NT_STATUS_GROUP_EXISTS                      = 0xc0000065,
  NT_STATUS_NO_SUCH_GROUP                     = 0xc0000066,
  NT_STATUS_MEMBER_IN_GROUP                   = 0xc0000067,
  NT_STATUS_MEMBER_NOT_IN_GROUP               = 0xc0000068,
  NT_STATUS_LAST_ADMIN                        = 0xc0000069,
  NT_STATUS_WRONG_PASSWORD                    = 0xc000006a,
  NT_STATUS_ILL_FORMED_PASSWORD               = 0xc000006b,
  NT_STATUS_PASSWORD_RESTRICTION              = 0xc000006c,
  NT_STATUS_LOGON_FAILURE                     = 0xc000006d,
  NT_STATUS_ACCOUNT_RESTRICTION               = 0xc000006e,
  NT_STATUS_INVALID_LOGON_HOURS               = 0xc000006f,
  NT_STATUS_INVALID_WORKSTATION               = 0xc0000070,
  NT_STATUS_PASSWORD_EXPIRED                  = 0xc0000071,
  NT_STATUS_ACCOUNT_DISABLED                  = 0xc0000072,
  NT_STATUS_NONE_MAPPED                       = 0xc0000073,
  NT_STATUS_TOO_MANY_LUIDS_REQUESTED          = 0xc0000074,
  NT_STATUS_LUIDS_EXHAUSTED                   = 0xc0000075,
  NT_STATUS_INVALID_SUB_AUTHORITY             = 0xc0000076,
  NT_STATUS_INVALID_ACL                       = 0xc0000077,
  NT_STATUS_INVALID_SID                       = 0xc0000078,
  NT_STATUS_INVALID_SECURITY_DESCR            = 0xc0000079,
  NT_STATUS_PROCEDURE_NOT_FOUND               = 0xc000007a,
  NT_STATUS_INVALID_IMAGE_FORMAT              = 0xc000007b,
  NT_STATUS_NO_TOKEN                          = 0xc000007c,
  NT_STATUS_BAD_INHERITANCE_ACL               = 0xc000007d,
  NT_STATUS_RANGE_NOT_LOCKED                  = 0xc000007e,
  NT_STATUS_DISK_FULL                         = 0xc000007f,
  NT_STATUS_SERVER_DISABLED                   = 0xc0000080,
  NT_STATUS_SERVER_NOT_DISABLED               = 0xc0000081,
  NT_STATUS_TOO_MANY_GUIDS_REQUESTED          = 0xc0000082,
  NT_STATUS_GUIDS_EXHAUSTED                   = 0xc0000083,
  NT_STATUS_INVALID_ID_AUTHORITY              = 0xc0000084,
  NT_STATUS_AGENTS_EXHAUSTED                  = 0xc0000085,
  NT_STATUS_INVALID_VOLUME_LABEL              = 0xc0000086,
  NT_STATUS_SECTION_NOT_EXTENDED              = 0xc0000087,
  NT_STATUS_NOT_MAPPED_DATA                   = 0xc0000088,
  NT_STATUS_RESOURCE_DATA_NOT_FOUND           = 0xc0000089,
  NT_STATUS_RESOURCE_TYPE_NOT_FOUND           = 0xc000008a,
  NT_STATUS_RESOURCE_NAME_NOT_FOUND           = 0xc000008b,
  NT_STATUS_ARRAY_BOUNDS_EXCEEDED             = 0xc000008c,
  NT_STATUS_FLOAT_DENORMAL_OPERAND            = 0xc000008d,
  NT_STATUS_FLOAT_DIVIDE_BY_ZERO              = 0xc000008e,
  NT_STATUS_FLOAT_INEXACT_RESULT              = 0xc000008f,
  NT_STATUS_FLOAT_INVALID_OPERATION           = 0xc0000090,
  NT_STATUS_FLOAT_OVERFLOW                    = 0xc0000091,
  NT_STATUS_FLOAT_STACK_CHECK                 = 0xc0000092,
  NT_STATUS_FLOAT_UNDERFLOW                   = 0xc0000093,
  NT_STATUS_INTEGER_DIVIDE_BY_ZERO            = 0xc0000094,
  NT_STATUS_INTEGER_OVERFLOW                  = 0xc0000095,
  NT_STATUS_PRIVILEGED_INSTRUCTION            = 0xc0000096,
  NT_STATUS_TOO_MANY_PAGING_FILES             = 0xc0000097,
  NT_STATUS_FILE_INVALID                      = 0xc0000098,
  NT_STATUS_ALLOTTED_SPACE_EXCEEDED           = 0xc0000099,
  NT_STATUS_INSUFFICIENT_RESOURCES            = 0xc000009a,
  NT_STATUS_DFS_EXIT_PATH_FOUND               = 0xc000009b,
  NT_STATUS_DEVICE_DATA_ERROR                 = 0xc000009c,
  NT_STATUS_DEVICE_NOT_CONNECTED              = 0xc000009d,
  NT_STATUS_DEVICE_POWER_FAILURE              = 0xc000009e,
  NT_STATUS_FREE_VM_NOT_AT_BASE               = 0xc000009f,
  NT_STATUS_MEMORY_NOT_ALLOCATED              = 0xc00000a0,
  NT_STATUS_WORKING_SET_QUOTA                 = 0xc00000a1,
  NT_STATUS_MEDIA_WRITE_PROTECTED             = 0xc00000a2,
  NT_STATUS_DEVICE_NOT_READY                  = 0xc00000a3,
  NT_STATUS_INVALID_GROUP_ATTRIBUTES          = 0xc00000a4,
  NT_STATUS_BAD_IMPERSONATION_LEVEL           = 0xc00000a5,
  NT_STATUS_CANT_OPEN_ANONYMOUS               = 0xc00000a6,
  NT_STATUS_BAD_VALIDATION_CLASS              = 0xc00000a7,
  NT_STATUS_BAD_TOKEN_TYPE                    = 0xc00000a8,
  NT_STATUS_BAD_MASTER_BOOT_RECORD            = 0xc00000a9,
  NT_STATUS_INSTRUCTION_MISALIGNMENT          = 0xc00000aa,
  NT_STATUS_INSTANCE_NOT_AVAILABLE            = 0xc00000ab,
  NT_STATUS_PIPE_NOT_AVAILABLE                = 0xc00000ac,
  NT_STATUS_INVALID_PIPE_STATE                = 0xc00000ad,
  NT_STATUS_PIPE_BUSY                         = 0xc00000ae,
  NT_STATUS_ILLEGAL_FUNCTION                  = 0xc00000af,
  NT_STATUS_PIPE_DISCONNECTED                 = 0xc00000b0,
  NT_STATUS_PIPE_CLOSING                      = 0xc00000b1,
  NT_STATUS_PIPE_CONNECTED                    = 0xc00000b2,
  NT_STATUS_PIPE_LISTENING                    = 0xc00000b3,
  NT_STATUS_INVALID_READ_MODE                 = 0xc00000b4,
  NT_STATUS_IO_TIMEOUT                        = 0xc00000b5,
  NT_STATUS_FILE_FORCED_CLOSED                = 0xc00000b6,
  NT_STATUS_PROFILING_NOT_STARTED             = 0xc00000b7,
  NT_STATUS_PROFILING_NOT_STOPPED             = 0xc00000b8,
  NT_STATUS_COULD_NOT_INTERPRET               = 0xc00000b9,
  NT_STATUS_FILE_IS_A_DIRECTORY               = 0xc00000ba,
  NT_STATUS_NOT_SUPPORTED                     = 0xc00000bb,
  NT_STATUS_REMOTE_NOT_LISTENING              = 0xc00000bc,
  NT_STATUS_DUPLICATE_NAME                    = 0xc00000bd,
  NT_STATUS_BAD_NETWORK_PATH                  = 0xc00000be,
  NT_STATUS_NETWORK_BUSY                      = 0xc00000bf,
  NT_STATUS_DEVICE_DOES_NOT_EXIST             = 0xc00000c0,
  NT_STATUS_TOO_MANY_COMMANDS                 = 0xc00000c1,
  NT_STATUS_ADAPTER_HARDWARE_ERROR            = 0xc00000c2,
  NT_STATUS_INVALID_NETWORK_RESPONSE          = 0xc00000c3,
  NT_STATUS_UNEXPECTED_NETWORK_ERROR          = 0xc00000c4,
  NT_STATUS_BAD_REMOTE_ADAPTER                = 0xc00000c5,
  NT_STATUS_PRINT_QUEUE_FULL                  = 0xc00000c6,
  NT_STATUS_NO_SPOOL_SPACE                    = 0xc00000c7,
  NT_STATUS_PRINT_CANCELLED                   = 0xc00000c8,
  NT_STATUS_NETWORK_NAME_DELETED              = 0xc00000c9,
  NT_STATUS_NETWORK_ACCESS_DENIED             = 0xc00000ca,
  NT_STATUS_BAD_DEVICE_TYPE                   = 0xc00000cb,
  NT_STATUS_BAD_NETWORK_NAME                  = 0xc00000cc,
  NT_STATUS_TOO_MANY_NAMES                    = 0xc00000cd,
  NT_STATUS_TOO_MANY_SESSIONS                 = 0xc00000ce,
  NT_STATUS_SHARING_PAUSED                    = 0xc00000cf,
  NT_STATUS_REQUEST_NOT_ACCEPTED              = 0xc00000d0,
  NT_STATUS_REDIRECTOR_PAUSED                 = 0xc00000d1,
  NT_STATUS_NET_WRITE_FAULT                   = 0xc00000d2,
  NT_STATUS_PROFILING_AT_LIMIT                = 0xc00000d3,
  NT_STATUS_NOT_SAME_DEVICE                   = 0xc00000d4,
  NT_STATUS_FILE_RENAMED                      = 0xc00000d5,
  NT_STATUS_VIRTUAL_CIRCUIT_CLOSED            = 0xc00000d6,
  NT_STATUS_NO_SECURITY_ON_OBJECT             = 0xc00000d7,
  NT_STATUS_CANT_WAIT                         = 0xc00000d8,
  NT_STATUS_PIPE_EMPTY                        = 0xc00000d9,
  NT_STATUS_CANT_ACCESS_DOMAIN_INFO           = 0xc00000da,
  NT_STATUS_CANT_TERMINATE_SELF               = 0xc00000db,
  NT_STATUS_INVALID_SERVER_STATE              = 0xc00000dc,
  NT_STATUS_INVALID_DOMAIN_STATE              = 0xc00000dd,
  NT_STATUS_INVALID_DOMAIN_ROLE               = 0xc00000de,
  NT_STATUS_NO_SUCH_DOMAIN                    = 0xc00000df,
  NT_STATUS_DOMAIN_EXISTS                     = 0xc00000e0,
  NT_STATUS_DOMAIN_LIMIT_EXCEEDED             = 0xc00000e1,
  NT_STATUS_OPLOCK_NOT_GRANTED                = 0xc00000e2,
  NT_STATUS_INVALID_OPLOCK_PROTOCOL           = 0xc00000e3,
  NT_STATUS_INTERNAL_DB_CORRUPTION            = 0xc00000e4,
  NT_STATUS_INTERNAL_ERROR                    = 0xc00000e5,
  NT_STATUS_GENERIC_NOT_MAPPED                = 0xc00000e6,
  NT_STATUS_BAD_DESCRIPTOR_FORMAT             = 0xc00000e7,
  NT_STATUS_INVALID_USER_BUFFER               = 0xc00000e8,
  NT_STATUS_UNEXPECTED_IO_ERROR               = 0xc00000e9,
  NT_STATUS_UNEXPECTED_MM_CREATE_ERR          = 0xc00000ea,
  NT_STATUS_UNEXPECTED_MM_MAP_ERROR           = 0xc00000eb,
  NT_STATUS_UNEXPECTED_MM_EXTEND_ERR          = 0xc00000ec,
  NT_STATUS_NOT_LOGON_PROCESS                 = 0xc00000ed,
  NT_STATUS_LOGON_SESSION_EXISTS              = 0xc00000ee,
  NT_STATUS_INVALID_PARAMETER_1               = 0xc00000ef,
  NT_STATUS_INVALID_PARAMETER_2               = 0xc00000f0,
  NT_STATUS_INVALID_PARAMETER_3               = 0xc00000f1,
  NT_STATUS_INVALID_PARAMETER_4               = 0xc00000f2,
  NT_STATUS_INVALID_PARAMETER_5               = 0xc00000f3,
  NT_STATUS_INVALID_PARAMETER_6               = 0xc00000f4,
  NT_STATUS_INVALID_PARAMETER_7               = 0xc00000f5,
  NT_STATUS_INVALID_PARAMETER_8               = 0xc00000f6,
  NT_STATUS_INVALID_PARAMETER_9               = 0xc00000f7,
  NT_STATUS_INVALID_PARAMETER_10              = 0xc00000f8,
  NT_STATUS_INVALID_PARAMETER_11              = 0xc00000f9,
  NT_STATUS_INVALID_PARAMETER_12              = 0xc00000fa,
  NT_STATUS_REDIRECTOR_NOT_STARTED            = 0xc00000fb,
  NT_STATUS_REDIRECTOR_STARTED                = 0xc00000fc,
  NT_STATUS_STACK_OVERFLOW                    = 0xc00000fd,
  NT_STATUS_NO_SUCH_PACKAGE                   = 0xc00000fe,
  NT_STATUS_BAD_FUNCTION_TABLE                = 0xc00000ff,
  NT_STATUS_DIRECTORY_NOT_EMPTY               = 0xc0000101,
  NT_STATUS_FILE_CORRUPT_ERROR                = 0xc0000102,
  NT_STATUS_NOT_A_DIRECTORY                   = 0xc0000103,
  NT_STATUS_BAD_LOGON_SESSION_STATE           = 0xc0000104,
  NT_STATUS_LOGON_SESSION_COLLISION           = 0xc0000105,
  NT_STATUS_NAME_TOO_LONG                     = 0xc0000106,
  NT_STATUS_FILES_OPEN                        = 0xc0000107,
  NT_STATUS_CONNECTION_IN_USE                 = 0xc0000108,
  NT_STATUS_MESSAGE_NOT_FOUND                 = 0xc0000109,
  NT_STATUS_PROCESS_IS_TERMINATING            = 0xc000010a,
  NT_STATUS_INVALID_LOGON_TYPE                = 0xc000010b,
  NT_STATUS_NO_GUID_TRANSLATION               = 0xc000010c,
  NT_STATUS_CANNOT_IMPERSONATE                = 0xc000010d,
  NT_STATUS_IMAGE_ALREADY_LOADED              = 0xc000010e,
  NT_STATUS_ABIOS_NOT_PRESENT                 = 0xc000010f,
  NT_STATUS_ABIOS_LID_NOT_EXIST               = 0xc0000110,
  NT_STATUS_ABIOS_LID_ALREADY_OWNED           = 0xc0000111,
  NT_STATUS_ABIOS_NOT_LID_OWNER               = 0xc0000112,
  NT_STATUS_ABIOS_INVALID_COMMAND             = 0xc0000113,
  NT_STATUS_ABIOS_INVALID_LID                 = 0xc0000114,
  NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE      = 0xc0000115,
  NT_STATUS_ABIOS_INVALID_SELECTOR            = 0xc0000116,
  NT_STATUS_NO_LDT                            = 0xc0000117,
  NT_STATUS_INVALID_LDT_SIZE                  = 0xc0000118,
  NT_STATUS_INVALID_LDT_OFFSET                = 0xc0000119,
  NT_STATUS_INVALID_LDT_DESCRIPTOR            = 0xc000011a,
  NT_STATUS_INVALID_IMAGE_NE_FORMAT           = 0xc000011b,
  NT_STATUS_RXACT_INVALID_STATE               = 0xc000011c,
  NT_STATUS_RXACT_COMMIT_FAILURE              = 0xc000011d,
  NT_STATUS_MAPPED_FILE_SIZE_ZERO             = 0xc000011e,
  NT_STATUS_TOO_MANY_OPENED_FILES             = 0xc000011f,
  NT_STATUS_CANCELLED                         = 0xc0000120,
  NT_STATUS_CANNOT_DELETE                     = 0xc0000121,
  NT_STATUS_INVALID_COMPUTER_NAME             = 0xc0000122,
  NT_STATUS_FILE_DELETED                      = 0xc0000123,
  NT_STATUS_SPECIAL_ACCOUNT                   = 0xc0000124,
  NT_STATUS_SPECIAL_GROUP                     = 0xc0000125,
  NT_STATUS_SPECIAL_USER                      = 0xc0000126,
  NT_STATUS_MEMBERS_PRIMARY_GROUP             = 0xc0000127,
  NT_STATUS_FILE_CLOSED                       = 0xc0000128,
  NT_STATUS_TOO_MANY_THREADS                  = 0xc0000129,
  NT_STATUS_THREAD_NOT_IN_PROCESS             = 0xc000012a,
  NT_STATUS_TOKEN_ALREADY_IN_USE              = 0xc000012b,
  NT_STATUS_PAGEFILE_QUOTA_EXCEEDED           = 0xc000012c,
  NT_STATUS_COMMITMENT_LIMIT                  = 0xc000012d,
  NT_STATUS_INVALID_IMAGE_LE_FORMAT           = 0xc000012e,
  NT_STATUS_INVALID_IMAGE_NOT_MZ              = 0xc000012f,
  NT_STATUS_INVALID_IMAGE_PROTECT             = 0xc0000130,
  NT_STATUS_INVALID_IMAGE_WIN_16              = 0xc0000131,
  NT_STATUS_LOGON_SERVER_CONFLICT             = 0xc0000132,
  NT_STATUS_TIME_DIFFERENCE_AT_DC             = 0xc0000133,
  NT_STATUS_SYNCHRONIZATION_REQUIRED          = 0xc0000134,
  NT_STATUS_DLL_NOT_FOUND                     = 0xc0000135,
  NT_STATUS_OPEN_FAILED                       = 0xc0000136,
  NT_STATUS_IO_PRIVILEGE_FAILED               = 0xc0000137,
  NT_STATUS_ORDINAL_NOT_FOUND                 = 0xc0000138,
  NT_STATUS_ENTRYPOINT_NOT_FOUND              = 0xc0000139,
  NT_STATUS_CONTROL_C_EXIT                    = 0xc000013a,
  NT_STATUS_LOCAL_DISCONNECT                  = 0xc000013b,
  NT_STATUS_REMOTE_DISCONNECT                 = 0xc000013c,
  NT_STATUS_REMOTE_RESOURCES                  = 0xc000013d,
  NT_STATUS_LINK_FAILED                       = 0xc000013e,
  NT_STATUS_LINK_TIMEOUT                      = 0xc000013f,
  NT_STATUS_INVALID_CONNECTION                = 0xc0000140,
  NT_STATUS_INVALID_ADDRESS                   = 0xc0000141,
  NT_STATUS_DLL_INIT_FAILED                   = 0xc0000142,
  NT_STATUS_MISSING_SYSTEMFILE                = 0xc0000143,
  NT_STATUS_UNHANDLED_EXCEPTION               = 0xc0000144,
  NT_STATUS_APP_INIT_FAILURE                  = 0xc0000145,
  NT_STATUS_PAGEFILE_CREATE_FAILED            = 0xc0000146,
  NT_STATUS_NO_PAGEFILE                       = 0xc0000147,
  NT_STATUS_INVALID_LEVEL                     = 0xc0000148,
  NT_STATUS_WRONG_PASSWORD_CORE               = 0xc0000149,
  NT_STATUS_ILLEGAL_FLOAT_CONTEXT             = 0xc000014a,
  NT_STATUS_PIPE_BROKEN                       = 0xc000014b,
  NT_STATUS_REGISTRY_CORRUPT                  = 0xc000014c,
  NT_STATUS_REGISTRY_IO_FAILED                = 0xc000014d,
  NT_STATUS_NO_EVENT_PAIR                     = 0xc000014e,
  NT_STATUS_UNRECOGNIZED_VOLUME               = 0xc000014f,
  NT_STATUS_SERIAL_NO_DEVICE_INITED           = 0xc0000150,
  NT_STATUS_NO_SUCH_ALIAS                     = 0xc0000151,
  NT_STATUS_MEMBER_NOT_IN_ALIAS               = 0xc0000152,
  NT_STATUS_MEMBER_IN_ALIAS                   = 0xc0000153,
  NT_STATUS_ALIAS_EXISTS                      = 0xc0000154,
  NT_STATUS_LOGON_NOT_GRANTED                 = 0xc0000155,
  NT_STATUS_TOO_MANY_SECRETS                  = 0xc0000156,
  NT_STATUS_SECRET_TOO_LONG                   = 0xc0000157,
  NT_STATUS_INTERNAL_DB_ERROR                 = 0xc0000158,
  NT_STATUS_FULLSCREEN_MODE                   = 0xc0000159,
  NT_STATUS_TOO_MANY_CONTEXT_IDS              = 0xc000015a,
  NT_STATUS_LOGON_TYPE_NOT_GRANTED            = 0xc000015b,
  NT_STATUS_NOT_REGISTRY_FILE                 = 0xc000015c,
  NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED      = 0xc000015d,
  NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR         = 0xc000015e,
  NT_STATUS_FT_MISSING_MEMBER                 = 0xc000015f,
  NT_STATUS_ILL_FORMED_SERVICE_ENTRY          = 0xc0000160,
  NT_STATUS_ILLEGAL_CHARACTER                 = 0xc0000161,
  NT_STATUS_UNMAPPABLE_CHARACTER              = 0xc0000162,
  NT_STATUS_UNDEFINED_CHARACTER               = 0xc0000163,
  NT_STATUS_FLOPPY_VOLUME                     = 0xc0000164,
  NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND          = 0xc0000165,
  NT_STATUS_FLOPPY_WRONG_CYLINDER             = 0xc0000166,
  NT_STATUS_FLOPPY_UNKNOWN_ERROR              = 0xc0000167,
  NT_STATUS_FLOPPY_BAD_REGISTERS              = 0xc0000168,
  NT_STATUS_DISK_RECALIBRATE_FAILED           = 0xc0000169,
  NT_STATUS_DISK_OPERATION_FAILED             = 0xc000016a,
  NT_STATUS_DISK_RESET_FAILED                 = 0xc000016b,
  NT_STATUS_SHARED_IRQ_BUSY                   = 0xc000016c,
  NT_STATUS_FT_ORPHANING                      = 0xc000016d,
  NT_STATUS_PARTITION_FAILURE                 = 0xc0000172,
  NT_STATUS_INVALID_BLOCK_LENGTH              = 0xc0000173,
  NT_STATUS_DEVICE_NOT_PARTITIONED            = 0xc0000174,
  NT_STATUS_UNABLE_TO_LOCK_MEDIA              = 0xc0000175,
  NT_STATUS_UNABLE_TO_UNLOAD_MEDIA            = 0xc0000176,
  NT_STATUS_EOM_OVERFLOW                      = 0xc0000177,
  NT_STATUS_NO_MEDIA                          = 0xc0000178,
  NT_STATUS_NO_SUCH_MEMBER                    = 0xc000017a,
  NT_STATUS_INVALID_MEMBER                    = 0xc000017b,
  NT_STATUS_KEY_DELETED                       = 0xc000017c,
  NT_STATUS_NO_LOG_SPACE                      = 0xc000017d,
  NT_STATUS_TOO_MANY_SIDS                     = 0xc000017e,
  NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED      = 0xc000017f,
  NT_STATUS_KEY_HAS_CHILDREN                  = 0xc0000180,
  NT_STATUS_CHILD_MUST_BE_VOLATILE            = 0xc0000181,
  NT_STATUS_DEVICE_CONFIGURATION_ERROR        = 0xc0000182,
  NT_STATUS_DRIVER_INTERNAL_ERROR             = 0xc0000183,
  NT_STATUS_INVALID_DEVICE_STATE              = 0xc0000184,
  NT_STATUS_IO_DEVICE_ERROR                   = 0xc0000185,
  NT_STATUS_DEVICE_PROTOCOL_ERROR             = 0xc0000186,
  NT_STATUS_BACKUP_CONTROLLER                 = 0xc0000187,
  NT_STATUS_LOG_FILE_FULL                     = 0xc0000188,
  NT_STATUS_TOO_LATE                          = 0xc0000189,
  NT_STATUS_NO_TRUST_LSA_SECRET               = 0xc000018a,
  NT_STATUS_NO_TRUST_SAM_ACCOUNT              = 0xc000018b,
  NT_STATUS_TRUSTED_DOMAIN_FAILURE            = 0xc000018c,
  NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE      = 0xc000018d,
  NT_STATUS_EVENTLOG_FILE_CORRUPT             = 0xc000018e,
  NT_STATUS_EVENTLOG_CANT_START               = 0xc000018f,
  NT_STATUS_TRUST_FAILURE                     = 0xc0000190,
  NT_STATUS_MUTANT_LIMIT_EXCEEDED             = 0xc0000191,
  NT_STATUS_NETLOGON_NOT_STARTED              = 0xc0000192,
  NT_STATUS_ACCOUNT_EXPIRED                   = 0xc0000193,
  NT_STATUS_POSSIBLE_DEADLOCK                 = 0xc0000194,
  NT_STATUS_NETWORK_CREDENTIAL_CONFLICT       = 0xc0000195,
  NT_STATUS_REMOTE_SESSION_LIMIT              = 0xc0000196,
  NT_STATUS_EVENTLOG_FILE_CHANGED             = 0xc0000197,
  NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT = 0xc0000198,
  NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT = 0xc0000199,
  NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT      = 0xc000019a,
  NT_STATUS_DOMAIN_TRUST_INCONSISTENT         = 0xc000019b,
  NT_STATUS_FS_DRIVER_REQUIRED                = 0xc000019c,
  NT_STATUS_NO_USER_SESSION_KEY               = 0xc0000202,
  NT_STATUS_USER_SESSION_DELETED              = 0xc0000203,
  NT_STATUS_RESOURCE_LANG_NOT_FOUND           = 0xc0000204,
  NT_STATUS_INSUFF_SERVER_RESOURCES           = 0xc0000205,
  NT_STATUS_INVALID_BUFFER_SIZE               = 0xc0000206,
  NT_STATUS_INVALID_ADDRESS_COMPONENT         = 0xc0000207,
  NT_STATUS_INVALID_ADDRESS_WILDCARD          = 0xc0000208,
  NT_STATUS_TOO_MANY_ADDRESSES                = 0xc0000209,
  NT_STATUS_ADDRESS_ALREADY_EXISTS            = 0xc000020a,
  NT_STATUS_ADDRESS_CLOSED                    = 0xc000020b,
  NT_STATUS_CONNECTION_DISCONNECTED           = 0xc000020c,
  NT_STATUS_CONNECTION_RESET                  = 0xc000020d,
  NT_STATUS_TOO_MANY_NODES                    = 0xc000020e,
  NT_STATUS_TRANSACTION_ABORTED               = 0xc000020f,
  NT_STATUS_TRANSACTION_TIMED_OUT             = 0xc0000210,
  NT_STATUS_TRANSACTION_NO_RELEASE            = 0xc0000211,
  NT_STATUS_TRANSACTION_NO_MATCH              = 0xc0000212,
  NT_STATUS_TRANSACTION_RESPONDED             = 0xc0000213,
  NT_STATUS_TRANSACTION_INVALID_ID            = 0xc0000214,
  NT_STATUS_TRANSACTION_INVALID_TYPE          = 0xc0000215,
  NT_STATUS_NOT_SERVER_SESSION                = 0xc0000216,
  NT_STATUS_NOT_CLIENT_SESSION                = 0xc0000217,
  NT_STATUS_CANNOT_LOAD_REGISTRY_FILE         = 0xc0000218,
  NT_STATUS_DEBUG_ATTACH_FAILED               = 0xc0000219,
  NT_STATUS_SYSTEM_PROCESS_TERMINATED         = 0xc000021a,
  NT_STATUS_DATA_NOT_ACCEPTED                 = 0xc000021b,
  NT_STATUS_NO_BROWSER_SERVERS_FOUND          = 0xc000021c,
  NT_STATUS_VDM_HARD_ERROR                    = 0xc000021d,
  NT_STATUS_DRIVER_CANCEL_TIMEOUT             = 0xc000021e,
  NT_STATUS_REPLY_MESSAGE_MISMATCH            = 0xc000021f,
  NT_STATUS_MAPPED_ALIGNMENT                  = 0xc0000220,
  NT_STATUS_IMAGE_CHECKSUM_MISMATCH           = 0xc0000221,
  NT_STATUS_LOST_WRITEBEHIND_DATA             = 0xc0000222,
  NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID  = 0xc0000223,
  NT_STATUS_PASSWORD_MUST_CHANGE              = 0xc0000224,
  NT_STATUS_NOT_FOUND                         = 0xc0000225,
  NT_STATUS_NOT_TINY_STREAM                   = 0xc0000226,
  NT_STATUS_RECOVERY_FAILURE                  = 0xc0000227,
  NT_STATUS_STACK_OVERFLOW_READ               = 0xc0000228,
  NT_STATUS_FAIL_CHECK                        = 0xc0000229,
  NT_STATUS_DUPLICATE_OBJECTID                = 0xc000022a,
  NT_STATUS_OBJECTID_EXISTS                   = 0xc000022b,
  NT_STATUS_CONVERT_TO_LARGE                  = 0xc000022c,
  NT_STATUS_RETRY                             = 0xc000022d,
  NT_STATUS_FOUND_OUT_OF_SCOPE                = 0xc000022e,
  NT_STATUS_ALLOCATE_BUCKET                   = 0xc000022f,
  NT_STATUS_PROPSET_NOT_FOUND                 = 0xc0000230,
  NT_STATUS_MARSHALL_OVERFLOW                 = 0xc0000231,
  NT_STATUS_INVALID_VARIANT                   = 0xc0000232,
  NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND       = 0xc0000233,
  NT_STATUS_ACCOUNT_LOCKED_OUT                = 0xc0000234,
  NT_STATUS_HANDLE_NOT_CLOSABLE               = 0xc0000235,
  NT_STATUS_CONNECTION_REFUSED                = 0xc0000236,
  NT_STATUS_GRACEFUL_DISCONNECT               = 0xc0000237,
  NT_STATUS_ADDRESS_ALREADY_ASSOCIATED        = 0xc0000238,
  NT_STATUS_ADDRESS_NOT_ASSOCIATED            = 0xc0000239,
  NT_STATUS_CONNECTION_INVALID                = 0xc000023a,
  NT_STATUS_CONNECTION_ACTIVE                 = 0xc000023b,
  NT_STATUS_NETWORK_UNREACHABLE               = 0xc000023c,
  NT_STATUS_HOST_UNREACHABLE                  = 0xc000023d,
  NT_STATUS_PROTOCOL_UNREACHABLE              = 0xc000023e,
  NT_STATUS_PORT_UNREACHABLE                  = 0xc000023f,
  NT_STATUS_REQUEST_ABORTED                   = 0xc0000240,
  NT_STATUS_CONNECTION_ABORTED                = 0xc0000241,
  NT_STATUS_BAD_COMPRESSION_BUFFER            = 0xc0000242,
  NT_STATUS_USER_MAPPED_FILE                  = 0xc0000243,
  NT_STATUS_AUDIT_FAILED                      = 0xc0000244,
  NT_STATUS_TIMER_RESOLUTION_NOT_SET          = 0xc0000245,
  NT_STATUS_CONNECTION_COUNT_LIMIT            = 0xc0000246,
  NT_STATUS_LOGIN_TIME_RESTRICTION            = 0xc0000247,
  NT_STATUS_LOGIN_WKSTA_RESTRICTION           = 0xc0000248,
  NT_STATUS_IMAGE_MP_UP_MISMATCH              = 0xc0000249,
  NT_STATUS_INSUFFICIENT_LOGON_INFO           = 0xc0000250,
  NT_STATUS_BAD_DLL_ENTRYPOINT                = 0xc0000251,
  NT_STATUS_BAD_SERVICE_ENTRYPOINT            = 0xc0000252,
  NT_STATUS_LPC_REPLY_LOST                    = 0xc0000253,
  NT_STATUS_IP_ADDRESS_CONFLICT1              = 0xc0000254,
  NT_STATUS_IP_ADDRESS_CONFLICT2              = 0xc0000255,
  NT_STATUS_REGISTRY_QUOTA_LIMIT              = 0xc0000256,
  NT_STATUS_PATH_NOT_COVERED                  = 0xc0000257,
  NT_STATUS_NO_CALLBACK_ACTIVE                = 0xc0000258,
  NT_STATUS_LICENSE_QUOTA_EXCEEDED            = 0xc0000259,
  NT_STATUS_PWD_TOO_SHORT                     = 0xc000025a,
  NT_STATUS_PWD_TOO_RECENT                    = 0xc000025b,
  NT_STATUS_PWD_HISTORY_CONFLICT              = 0xc000025c,
  NT_STATUS_PLUGPLAY_NO_DEVICE                = 0xc000025e,
  NT_STATUS_UNSUPPORTED_COMPRESSION           = 0xc000025f,
  NT_STATUS_INVALID_HW_PROFILE                = 0xc0000260,
  NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH      = 0xc0000261,
  NT_STATUS_DRIVER_ORDINAL_NOT_FOUND          = 0xc0000262,
  NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND       = 0xc0000263,
  NT_STATUS_RESOURCE_NOT_OWNED                = 0xc0000264,
  NT_STATUS_TOO_MANY_LINKS                    = 0xc0000265,
  NT_STATUS_QUOTA_LIST_INCONSISTENT           = 0xc0000266,
  NT_STATUS_FILE_IS_OFFLINE                   = 0xc0000267,
  NT_STATUS_DS_NO_MORE_RIDS                   = 0xc00002a8,
  NT_STATUS_NOT_A_REPARSE_POINT               = 0xc0000275,
  NT_STATUS_NO_SUCH_JOB                       = 0xc0000EDE
}

for i, v in pairs(status_codes) do
  status_names[v] = i
end


local NP_LIBRARY_NAME = "PIPE"

namedpipes =
{
  get_pipe_subpath = function( pipeName, writeToDebugLog )
    local status, pipeSubPath
    if not pipeName then return false end

    local _, _, match = pipeName:match( "^(\\+)(.-)\\pipe(\\.-)$" )
    if match then
      pipeSubPath = match
      status = true
      if writeToDebugLog then
        stdnse.debug2("%s: Converting %s to subpath %s", NP_LIBRARY_NAME, pipeName, match )
      end
    else
      status = false
      pipeSubPath = pipeName
    end

    return status, pipeSubPath
  end,


  make_pipe_name = function( hostnameOrIp, pipeSubPath )
    if pipeSubPath:sub(1,1) ~= "\\" then
      pipeSubPath = "\\" .. pipeSubPath
    end

    return string.format( "\\\\%s\\pipe%s", hostnameOrIp, pipeSubPath )
  end,


  named_pipe = {

    _smbstate = nil,
    _host = nil,
    _pipeSubPath = nil,
    _overrides = nil,
    name = nil,

    new = function(self,o)
      o = o or {}
      setmetatable(o, self)
      self.__index = self
      return o
    end,


    connect = function( self, host, pipeSubPath, overrides )

      stdnse.debug2("%s: connect() called with %s", NP_LIBRARY_NAME, tostring( pipeSubPath ) )
      self._overrides = overrides or {}
      self._host = host
      self._pipeSubPath = pipeSubPath
      if not host and not host.ip then return false, "host table is required" end
      if not pipeSubPath then return false, "pipeSubPath is required" end

      -- If we got a full pipe name, not a sub-path, fix it
      if ( pipeSubPath:match( "^\\\\(.-)$" ) ) then
        local status
        status, self._pipeSubPath = namedpipes.get_pipe_subpath( self._pipeSubPath, true )
        if ( not status ) then
          stdnse.debug1("%s: Attempt to connect to invalid pipe name: %s", NP_LIBRARY_NAME, tostring( pipeSubPath ) )
          return false, "Invalid pipe name"
        end
      end
      self.name = namedpipes.make_pipe_name( self._host.ip, self._pipeSubPath )

      stdnse.debug2("%s: Connecting to named pipe: %s", NP_LIBRARY_NAME, self.name )
      local errorMessage
      local bool_negotiate_protocol, bool_start_session, bool_disable_extended = true, true, false
      local _, fqpn_share = get_fqpn(host, "IPC$")
      local status, result = start_ex( self._host, bool_negotiate_protocol, bool_start_session,
        fqpn_share, self._pipeSubPath, bool_disable_extended, self._overrides )

      if status then
        self._smbstate = result
      else
        errorMessage = string.format( "Connection failed: %s", result )
        stdnse.debug2("%s: Connection to named pipe (%s) failed: %s",
          NP_LIBRARY_NAME, self.name, errorMessage )
      end

      return status, errorMessage, result
    end,


    disconnect = function( self )
      if ( self._smbstate ) then
        stdnse.debug2("%s: Disconnecting named pipe: %s", NP_LIBRARY_NAME, self.name )
        return stop( self._smbstate )
      else
        stdnse.debug2("%s: disconnect() called, but SMB connection is already closed: %s", NP_LIBRARY_NAME, self.name )
      end
    end,


    send = function( self, messageData )
      if not self._smbstate then
        stdnse.debug2("%s: send() called on closed pipe (%s)", NP_LIBRARY_NAME, self.name )
        return false, "Failed to send message on named pipe"
      end

      local offset = 0 -- offset is actually ignored for named pipes, but we'll define the argument for clarity
      local status, result, errorMessage

      status, result = write_file( self._smbstate, messageData, offset, self._overrides )

      -- if status is true, result is data that we don't need to pay attention to
      if not status then
        stdnse.debug2("%s: Write to named pipe (%s) failed: %s",
          NP_LIBRARY_NAME, self.name, result )
        errorMessage = "Failed to send message on named pipe", result
      end

      return status, errorMessage
    end,


    receive = function( self )
      if not self._smbstate then
        stdnse.debug2("%s: receive() called on closed pipe (%s)", NP_LIBRARY_NAME, self.name )
        return false, "Failed to read from named pipe"
      end

      local status, result, messageData
      -- Packet header values
      local offset = 0 -- offset is actually ignored for named pipes, but we'll define the argument for clarity
      local MAX_BYTES_PER_READ = 4096

      status, result = read_file( self._smbstate, offset, MAX_BYTES_PER_READ, self._overrides )

      if status and result.data then
        messageData = result.data
      else
        stdnse.debug2("%s: Read from named pipe (%s) failed: %s",
          NP_LIBRARY_NAME, self.name, result )
        return false, "Failed to read from named pipe", result
      end

      while (result["status"] == status_codes.NT_STATUS_BUFFER_OVERFLOW) do
        status, result = read_file( self._smbstate, offset, MAX_BYTES_PER_READ, self._overrides )

        if status and result.data then
          messageData = messageData .. result.data
        else
          stdnse.debug2("%s: Read additional data from named pipe (%s) failed: %s",
            NP_LIBRARY_NAME, self.name, result )
          return false, "Failed to read from named pipe", result
        end
      end

      return status, messageData
    end,
  }

}

filetype_codes =
{
  FILE_TYPE_DISK              = 0x00,
  FILE_TYPE_BYTE_MODE_PIPE    = 0x01,
  FILE_TYPE_MESSAGE_MODE_PIPE = 0x02,
  FILE_TYPE_PRINTER           = 0x03,
  FILE_TYPE_UNKNOWN           = 0xFF
}

for i, v in pairs(filetype_codes) do
  filetype_names[v] = i
end

return _ENV;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        /*
 * WARNING: do not edit!
 * Generated by Makefile from include/openssl/x509.h.in
 *
 * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */



#ifndef OPENSSL_X509_H
# define OPENSSL_X509_H
# pragma once

# include <openssl/macros.h>
# ifndef OPENSSL_NO_DEPRECATED_3_0
#  define HEADER_X509_H
# endif

# include <openssl/e_os2.h>
# include <openssl/types.h>
# include <openssl/symhacks.h>
# include <openssl/buffer.h>
# include <openssl/evp.h>
# include <openssl/bio.h>
# include <openssl/asn1.h>
# include <openssl/safestack.h>
# include <openssl/ec.h>

# ifndef OPENSSL_NO_DEPRECATED_1_1_0
#  include <openssl/rsa.h>
#  include <openssl/dsa.h>
#  include <openssl/dh.h>
# endif

# include <openssl/sha.h>
# include <openssl/x509err.h>

#ifdef  __cplusplus
extern "C" {
#endif

/* Needed stacks for types defined in other headers */
SKM_DEFINE_STACK_OF_INTERNAL(X509_NAME, X509_NAME, X509_NAME)
#define sk_X509_NAME_num(sk) OPENSSL_sk_num(ossl_check_const_X509_NAME_sk_type(sk))
#define sk_X509_NAME_value(sk, idx) ((X509_NAME *)OPENSSL_sk_value(ossl_check_const_X509_NAME_sk_type(sk), (idx)))
#define sk_X509_NAME_new(cmp) ((STACK_OF(X509_NAME) *)OPENSSL_sk_new(ossl_check_X509_NAME_compfunc_type(cmp)))
#define sk_X509_NAME_new_null() ((STACK_OF(X509_NAME) *)OPENSSL_sk_new_null())
#define sk_X509_NAME_new_reserve(cmp, n) ((STACK_OF(X509_NAME) *)OPENSSL_sk_new_reserve(ossl_check_X509_NAME_compfunc_type(cmp), (n)))
#define sk_X509_NAME_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_X509_NAME_sk_type(sk), (n))
#define sk_X509_NAME_free(sk) OPENSSL_sk_free(ossl_check_X509_NAME_sk_type(sk))
#define sk_X509_NAME_zero(sk) OPENSSL_sk_zero(ossl_check_X509_NAME_sk_type(sk))
#define sk_X509_NAME_delete(sk, i) ((X509_NAME *)OPENSSL_sk_delete(ossl_check_X509_NAME_sk_type(sk), (i)))
#define sk_X509_NAME_delete_ptr(sk, ptr) ((X509_NAME *)OPENSSL_sk_delete_ptr(ossl_check_X509_NAME_sk_type(sk), ossl_check_X509_NAME_type(ptr)))
#define sk_X509_NAME_push(sk, ptr) OPENSSL_sk_push(ossl_check_X509_NAME_sk_type(sk), ossl_check_X509_NAME_type(ptr))
#define sk_X509_NAME_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_X509_NAME_sk_type(sk), ossl_check_X509_NAME_type(ptr))
#define sk_X509_NAME_pop(sk) ((X509_NAME *)OPENSSL_sk_pop(ossl_check_X509_NAME_sk_type(sk)))
#define sk_X509_NAME_shift(sk) ((X509_NAME *)OPENSSL_sk_shift(ossl_check_X509_NAME_sk_type(sk)))
#define sk_X509_NAME_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_X509_NAME_sk_type(sk),ossl_check_X509_NAME_freefunc_type(freefunc))
#define sk_X509_NAME_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_X509_NAME_sk_type(sk), ossl_check_X509_NAME_type(ptr), (idx))
#define sk_X509_NAME_set(sk, idx, ptr) ((X509_NAME *)OPENSSL_sk_set(ossl_check_X509_NAME_sk_type(sk), (idx), ossl_check_X509_NAME_type(ptr)))
#define sk_X509_NAME_find(sk, ptr) OPENSSL_sk_find(ossl_check_X509_NAME_sk_type(sk), ossl_check_X509_NAME_type(ptr))
#define sk_X509_NAME_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_X509_NAME_sk_type(sk), ossl_check_X509_NAME_type(ptr))
#define sk_X509_NAME_find_all(sk, ptr, pnum) OPENSSL_sk_find_all(ossl_check_X509_NAME_sk_type(sk), ossl_check_X509_NAME_type(ptr), pnum)
#define sk_X509_NAME_sort(sk) OPENSSL_sk_sort(ossl_check_X509_NAME_sk_type(sk))
#define sk_X509_NAME_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_X509_NAME_sk_type(sk))
#define sk_X509_NAME_dup(sk) ((STACK_OF(X509_NAME) *)OPENSSL_sk_dup(ossl_check_const_X509_NAME_sk_type(sk)))
#define sk_X509_NAME_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(X509_NAME) *)OPENSSL_sk_deep_copy(ossl_check_const_X509_NAME_sk_type(sk), ossl_check_X509_NAME_copyfunc_type(copyfunc), ossl_check_X509_NAME_freefunc_type(freefunc)))
#define sk_X509_NAME_set_cmp_func(sk, cmp) ((sk_X509_NAME_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_X509_NAME_sk_type(sk), ossl_check_X509_NAME_compfunc_type(cmp)))
SKM_DEFINE_STACK_OF_INTERNAL(X509, X509, X509)
#define sk_X509_num(sk) OPENSSL_sk_num(ossl_check_const_X509_sk_type(sk))
#define sk_X509_value(sk, idx) ((X509 *)OPENSSL_sk_value(ossl_check_const_X509_sk_type(sk), (idx)))
#define sk_X509_new(cmp) ((STACK_OF(X509) *)OPENSSL_sk_new(ossl_check_X509_compfunc_type(cmp)))
#define sk_X509_new_null() ((STACK_OF(X509) *)OPENSSL_sk_new_null())
#define sk_X509_new_reserve(cmp, n) ((STACK_OF(X509) *)OPENSSL_sk_new_reserve(ossl_check_X509_compfunc_type(cmp), (n)))
#define sk_X509_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_X509_sk_type(sk), (n))
#define sk_X509_free(sk) OPENSSL_sk_free(ossl_check_X509_sk_type(sk))
#define sk_X509_zero(sk) OPENSSL_sk_zero(ossl_check_X509_sk_type(sk))
#define sk_X509_delete(sk, i) ((X509 *)OPENSSL_sk_delete(ossl_check_X509_sk_type(sk), (i)))
#define sk_X509_delete_ptr(sk, ptr) ((X509 *)OPENSSL_sk_delete_ptr(ossl_check_X509_sk_type(sk), ossl_check_X509_type(ptr)))
#define sk_X509_push(sk, ptr) OPENSSL_sk_push(ossl_check_X509_sk_type(sk), ossl_check_X509_type(ptr))
#define sk_X509_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_X509_sk_type(sk), ossl_check_X509_type(ptr))
#define sk_X509_pop(sk) ((X509 *)OPENSSL_sk_pop(ossl_check_X509_sk_type(sk)))
#define sk_X509_shift(sk) ((X509 *)OPENSSL_sk_shift(ossl_check_X509_sk_type(sk)))
#define sk_X509_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_X509_sk_type(sk),ossl_check_X509_freefunc_type(freefunc))
#define sk_X509_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_X509_sk_type(sk), ossl_check_X509_type(ptr), (idx))
#define sk_X509_set(sk, idx, ptr) ((X509 *)OPENSSL_sk_set(ossl_check_X509_sk_type(sk), (idx), ossl_check_X509_type(ptr)))
#define sk_X509_find(sk, ptr) OPENSSL_sk_find(ossl_check_X509_sk_type(sk), ossl_check_X509_type(ptr))
#define sk_X509_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_X509_sk_type(sk), ossl_check_X509_type(ptr))
#define sk_X509_find_all(sk, ptr, pnum) OPENSSL_sk_find_all(ossl_check_X509_sk_type(sk), ossl_check_X509_type(ptr), pnum)
#define sk_X509_sort(sk) OPENSSL_sk_sort(ossl_check_X509_sk_type(sk))
#define sk_X509_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_X509_sk_type(sk))
#define sk_X509_dup(sk) ((STACK_OF(X509) *)OPENSSL_sk_dup(ossl_check_const_X509_sk_type(sk)))
#define sk_X509_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(X509) *)OPENSSL_sk_deep_copy(ossl_check_const_X509_sk_type(sk), ossl_check_X509_copyfunc_type(copyfunc), ossl_check_X509_freefunc_type(freefunc)))
#define sk_X509_set_cmp_func(sk, cmp) ((sk_X509_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_X509_sk_type(sk), ossl_check_X509_compfunc_type(cmp)))
SKM_DEFINE_STACK_OF_INTERNAL(X509_REVOKED, X509_REVOKED, X509_REVOKED)
#define sk_X509_REVOKED_num(sk) OPENSSL_sk_num(ossl_check_const_X509_REVOKED_sk_type(sk))
#define sk_X509_REVOKED_value(sk, idx) ((X509_REVOKED *)OPENSSL_sk_value(ossl_check_const_X509_REVOKED_sk_type(sk), (idx)))
#define sk_X509_REVOKED_new(cmp) ((STACK_OF(X509_REVOKED) *)OPENSSL_sk_new(ossl_check_X509_REVOKED_compfunc_type(cmp)))
#define sk_X509_REVOKED_new_null() ((STACK_OF(X509_REVOKED) *)OPENSSL_sk_new_null())
#define sk_X509_REVOKED_new_reserve(cmp, n) ((STACK_OF(X509_REVOKED) *)OPENSSL_sk_new_reserve(ossl_check_X509_REVOKED_compfunc_type(cmp), (n)))
#define sk_X509_REVOKED_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_X509_REVOKED_sk_type(sk), (n))
#define sk_X509_REVOKED_free(sk) OPENSSL_sk_free(ossl_check_X509_REVOKED_sk_type(sk))
#define sk_X509_REVOKED_zero(sk) OPENSSL_sk_zero(ossl_check_X509_REVOKED_sk_type(sk))
#define sk_X509_REVOKED_delete(sk, i) ((X509_REVOKED *)OPENSSL_sk_delete(ossl_check_X509_REVOKED_sk_type(sk), (i)))
#define sk_X509_REVOKED_delete_ptr(sk, ptr) ((X509_REVOKED *)OPENSSL_sk_delete_ptr(ossl_check_X509_REVOKED_sk_type(sk), ossl_check_X509_REVOKED_type(ptr)))
#define sk_X509_REVOKED_push(sk, ptr) OPENSSL_sk_push(ossl_check_X509_REVOKED_sk_type(sk), ossl_check_X509_REVOKED_type(ptr))
#define sk_X509_REVOKED_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_X509_REVOKED_sk_type(sk), ossl_check_X509_REVOKED_type(ptr))
#define sk_X509_REVOKED_pop(sk) ((X509_REVOKED *)OPENSSL_sk_pop(ossl_check_X509_REVOKED_sk_type(sk)))
#define sk_X509_REVOKED_shift(sk) ((X509_REVOKED *)OPENSSL_sk_shift(ossl_check_X509_REVOKED_sk_type(sk)))
#define sk_X509_REVOKED_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_X509_REVOKED_sk_type(sk),ossl_check_X509_REVOKED_freefunc_type(freefunc))
#define sk_X509_REVOKED_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_X509_REVOKED_sk_type(sk), ossl_check_X509_REVOKED_type(ptr), (idx))
#define sk_X509_REVOKED_set(sk, idx, ptr) ((X509_REVOKED *)OPENSSL_sk_set(ossl_check_X509_REVOKED_sk_type(sk), (idx), ossl_check_X509_REVOKED_type(ptr)))
#define sk_X509_REVOKED_find(sk, ptr) OPENSSL_sk_find(ossl_check_X509_REVOKED_sk_type(sk), ossl_check_X509_REVOKED_type(ptr))
#define sk_X509_REVOKED_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_X509_REVOKED_sk_type(sk), ossl_check_X509_REVOKED_type(ptr))
#define sk_X509_REVOKED_find_all(sk, ptr, pnum) OPENSSL_sk_find_all(ossl_check_X509_REVOKED_sk_type(sk), ossl_check_X509_REVOKED_type(ptr), pnum)
#define sk_X509_REVOKED_sort(sk) OPENSSL_sk_sort(ossl_check_X509_REVOKED_sk_type(sk))
#define sk_X509_REVOKED_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_X509_REVOKED_sk_type(sk))
#define sk_X509_REVOKED_dup(sk) ((STACK_OF(X509_REVOKED) *)OPENSSL_sk_dup(ossl_check_const_X509_REVOKED_sk_type(sk)))
#define sk_X509_REVOKED_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(X509_REVOKED) *)OPENSSL_sk_deep_copy(ossl_check_const_X509_REVOKED_sk_type(sk), ossl_check_X509_REVOKED_copyfunc_type(copyfunc), ossl_check_X509_REVOKED_freefunc_type(freefunc)))
#define sk_X509_REVOKED_set_cmp_func(sk, cmp) ((sk_X509_REVOKED_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_X509_REVOKED_sk_type(sk), ossl_check_X509_REVOKED_compfunc_type(cmp)))
SKM_DEFINE_STACK_OF_INTERNAL(X509_CRL, X509_CRL, X509_CRL)
#define sk_X509_CRL_num(sk) OPENSSL_sk_num(ossl_check_const_X509_CRL_sk_type(sk))
#define sk_X509_CRL_value(sk, idx) ((X509_CRL *)OPENSSL_sk_value(ossl_check_const_X509_CRL_sk_type(sk), (idx)))
#define sk_X509_CRL_new(cmp) ((STACK_OF(X509_CRL) *)OPENSSL_sk_new(ossl_check_X509_CRL_compfunc_type(cmp)))
#define sk_X509_CRL_new_null() ((STACK_OF(X509_CRL) *)OPENSSL_sk_new_null())
#define sk_X509_CRL_new_reserve(cmp, n) ((STACK_OF(X509_CRL) *)OPENSSL_sk_new_reserve(ossl_check_X509_CRL_compfunc_type(cmp), (n)))
#define sk_X509_CRL_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_X509_CRL_sk_type(sk), (n))
#define sk_X509_CRL_free(sk) OPENSSL_sk_free(ossl_check_X509_CRL_sk_type(sk))
#define sk_X509_CRL_zero(sk) OPENSSL_sk_zero(ossl_check_X509_CRL_sk_type(sk))
#define sk_X509_CRL_delete(sk, i) ((X509_CRL *)OPENSSL_sk_delete(ossl_check_X509_CRL_sk_type(sk), (i)))
#define sk_X509_CRL_delete_ptr(sk, ptr) ((X509_CRL *)OPENSSL_sk_delete_ptr(ossl_check_X509_CRL_sk_type(sk), ossl_check_X509_CRL_type(ptr)))
#define sk_X509_CRL_push(sk, ptr) OPENSSL_sk_push(ossl_check_X509_CRL_sk_type(sk), ossl_check_X509_CRL_type(ptr))
#define sk_X509_CRL_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_X509_CRL_sk_type(sk), ossl_check_X509_CRL_type(ptr))
#define sk_X509_CRL_pop(sk) ((X509_CRL *)OPENSSL_sk_pop(ossl_check_X509_CRL_sk_type(sk)))
#define sk_X509_CRL_shift(sk) ((X509_CRL *)OPENSSL_sk_shift(ossl_check_X509_CRL_sk_type(sk)))
#define sk_X509_CRL_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_X509_CRL_sk_type(sk),ossl_check_X509_CRL_freefunc_type(freefunc))
#define sk_X509_CRL_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_X509_CRL_sk_type(sk), ossl_check_X509_CRL_type(ptr), (idx))
#define sk_X509_CRL_set(sk, idx, ptr) ((X509_CRL *)OPENSSL_sk_set(ossl_check_X509_CRL_sk_type(sk), (idx), ossl_check_X509_CRL_type(ptr)))
#define sk_X509_CRL_find(sk, ptr) OPENSSL_sk_find(ossl_check_X509_CRL_sk_type(sk), ossl_check_X509_CRL_type(ptr))
#define sk_X509_CRL_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_X509_CRL_sk_type(sk), ossl_check_X509_CRL_type(ptr))
#define sk_X509_CRL_find_all(sk, ptr, pnum) OPENSSL_sk_find_all(ossl_check_X509_CRL_sk_type(sk), ossl_check_X509_CRL_type(ptr), pnum)
#define sk_X509_CRL_sort(sk) OPENSSL_sk_sort(ossl_check_X509_CRL_sk_type(sk))
#define sk_X509_CRL_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_X509_CRL_sk_type(sk))
#define sk_X509_CRL_dup(sk) ((STACK_OF(X509_CRL) *)OPENSSL_sk_dup(ossl_check_const_X509_CRL_sk_type(sk)))
#define sk_X509_CRL_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(X509_CRL) *)OPENSSL_sk_deep_copy(ossl_check_const_X509_CRL_sk_type(sk), ossl_check_X509_CRL_copyfunc_type(copyfunc), ossl_check_X509_CRL_freefunc_type(freefunc)))
#define sk_X509_CRL_set_cmp_func(sk, cmp) ((sk_X509_CRL_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_X509_CRL_sk_type(sk), ossl_check_X509_CRL_compfunc_type(cmp)))


/* Flags for X509_get_signature_info() */
/* Signature info is valid */
# define X509_SIG_INFO_VALID     0x1
/* Signature is suitable for TLS use */
# define X509_SIG_INFO_TLS       0x2

# define X509_FILETYPE_PEM       1
# define X509_FILETYPE_ASN1      2
# define X509_FILETYPE_DEFAULT   3

# define X509v3_KU_DIGITAL_SIGNATURE     0x0080
# define X509v3_KU_NON_REPUDIATION       0x0040
# define X509v3_KU_KEY_ENCIPHERMENT      0x0020
# define X509v3_KU_DATA_ENCIPHERMENT     0x0010
# define X509v3_KU_KEY_AGREEMENT         0x0008
# define X509v3_KU_KEY_CERT_SIGN         0x0004
# define X509v3_KU_CRL_SIGN              0x0002
# define X509v3_KU_ENCIPHER_ONLY         0x0001
# define X509v3_KU_DECIPHER_ONLY         0x8000
# define X509v3_KU_UNDEF                 0xffff

struct X509_algor_st {
    ASN1_OBJECT *algorithm;
    ASN1_TYPE *parameter;
} /* X509_ALGOR */ ;

typedef STACK_OF(X509_ALGOR) X509_ALGORS;

typedef struct X509_val_st {
    ASN1_TIME *notBefore;
    ASN1_TIME *notAfter;
} X509_VAL;

typedef struct X509_sig_st X509_SIG;

typedef struct X509_name_entry_st X509_NAME_ENTRY;

SKM_DEFINE_STACK_OF_INTERNAL(X509_NAME_ENTRY, X509_NAME_ENTRY, X509_NAME_ENTRY)
#define sk_X509_NAME_ENTRY_num(sk) OPENSSL_sk_num(ossl_check_const_X509_NAME_ENTRY_sk_type(sk))
#define sk_X509_NAME_ENTRY_value(sk, idx) ((X509_NAME_ENTRY *)OPENSSL_sk_value(ossl_check_const_X509_NAME_ENTRY_sk_type(sk), (idx)))
#define sk_X509_NAME_ENTRY_new(cmp) ((STACK_OF(X509_NAME_ENTRY) *)OPENSSL_sk_new(ossl_check_X509_NAME_ENTRY_compfunc_type(cmp)))
#define sk_X509_NAME_ENTRY_new_null() ((STACK_OF(X509_NAME_ENTRY) *)OPENSSL_sk_new_null())
#define sk_X509_NAME_ENTRY_new_reserve(cmp, n) ((STACK_OF(X509_NAME_ENTRY) *)OPENSSL_sk_new_reserve(ossl_check_X509_NAME_ENTRY_compfunc_type(cmp), (n)))
#define sk_X509_NAME_ENTRY_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_X509_NAME_ENTRY_sk_type(sk), (n))
#define sk_X509_NAME_ENTRY_free(sk) OPENSSL_sk_free(ossl_check_X509_NAME_ENTRY_sk_type(sk))
#define sk_X509_NAME_ENTRY_zero(sk) OPENSSL_sk_zero(ossl_check_X509_NAME_ENTRY_sk_type(sk))
#define sk_X509_NAME_ENTRY_delete(sk, i) ((X509_NAME_ENTRY *)OPENSSL_sk_delete(ossl_check_X509_NAME_ENTRY_sk_type(sk), (i)))
#define sk_X509_NAME_ENTRY_delete_ptr(sk, ptr) ((X509_NAME_ENTRY *)OPENSSL_sk_delete_ptr(ossl_check_X509_NAME_ENTRY_sk_type(sk), ossl_check_X509_NAME_ENTRY_type(ptr)))
#define sk_X509_NAME_ENTRY_push(sk, ptr) OPENSSL_sk_push(ossl_check_X509_NAME_ENTRY_sk_type(sk), ossl_check_X509_NAME_ENTRY_type(ptr))
#define sk_X509_NAME_ENTRY_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_X509_NAME_ENTRY_sk_type(sk), ossl_check_X509_NAME_ENTRY_type(ptr))
#define sk_X509_NAME_ENTRY_pop(sk) ((X509_NAME_ENTRY *)OPENSSL_sk_pop(ossl_check_X509_NAME_ENTRY_sk_type(sk)))
#define sk_X509_NAME_ENTRY_shift(sk) ((X509_NAME_ENTRY *)OPENSSL_sk_shift(ossl_check_X509_NAME_ENTRY_sk_type(sk)))
#define sk_X509_NAME_ENTRY_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_X509_NAME_ENTRY_sk_type(sk),ossl_check_X509_NAME_ENTRY_freefunc_type(freefunc))
#define sk_X509_NAME_ENTRY_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_X509_NAME_ENTRY_sk_type(sk), ossl_check_X509_NAME_ENTRY_type(ptr), (idx))
#define sk_X509_NAME_ENTRY_set(sk, idx, ptr) ((X509_NAME_ENTRY *)OPENSSL_sk_set(ossl_check_X509_NAME_ENTRY_sk_type(sk), (idx), ossl_check_X509_NAME_ENTRY_type(ptr)))
#define sk_X509_NAME_ENTRY_find(sk, ptr) OPENSSL_sk_find(ossl_check_X509_NAME_ENTRY_sk_type(sk), ossl_check_X509_NAME_ENTRY_type(ptr))
#define sk_X509_NAME_ENTRY_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_X509_NAME_ENTRY_sk_type(sk), ossl_check_X509_NAME_ENTRY_type(ptr))
#define sk_X509_NAME_ENTRY_find_all(sk, ptr, pnum) OPENSSL_sk_find_all(ossl_check_X509_NAME_ENTRY_sk_type(sk), ossl_check_X509_NAME_ENTRY_type(ptr), pnum)
#define sk_X509_NAME_ENTRY_sort(sk) OPENSSL_sk_sort(ossl_check_X509_NAME_ENTRY_sk_type(sk))
#define sk_X509_NAME_ENTRY_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_X509_NAME_ENTRY_sk_type(sk))
#define sk_X509_NAME_ENTRY_dup(sk) ((STACK_OF(X509_NAME_ENTRY) *)OPENSSL_sk_dup(ossl_check_const_X509_NAME_ENTRY_sk_type(sk)))
#define sk_X509_NAME_ENTRY_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(X509_NAME_ENTRY) *)OPENSSL_sk_deep_copy(ossl_check_const_X509_NAME_ENTRY_sk_type(sk), ossl_check_X509_NAME_ENTRY_copyfunc_type(copyfunc), ossl_check_X509_NAME_ENTRY_freefunc_type(freefunc)))
#define sk_X509_NAME_ENTRY_set_cmp_func(sk, cmp) ((sk_X509_NAME_ENTRY_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_X509_NAME_ENTRY_sk_type(sk), ossl_check_X509_NAME_ENTRY_compfunc_type(cmp)))


# define X509_EX_V_NETSCAPE_HACK         0x8000
# define X509_EX_V_INIT                  0x0001
typedef struct X509_extension_st X509_EXTENSION;
SKM_DEFINE_STACK_OF_INTERNAL(X509_EXTENSION, X509_EXTENSION, X509_EXTENSION)
#define sk_X509_EXTENSION_num(sk) OPENSSL_sk_num(ossl_check_const_X509_EXTENSION_sk_type(sk))
#define sk_X509_EXTENSION_value(sk, idx) ((X509_EXTENSION *)OPENSSL_sk_value(ossl_check_const_X509_EXTENSION_sk_type(sk), (idx)))
#define sk_X509_EXTENSION_new(cmp) ((STACK_OF(X509_EXTENSION) *)OPENSSL_sk_new(ossl_check_X509_EXTENSION_compfunc_type(cmp)))
#define sk_X509_EXTENSION_new_null() ((STACK_OF(X509_EXTENSION) *)OPENSSL_sk_new_null())
#define sk_X509_EXTENSION_new_reserve(cmp, n) ((STACK_OF(X509_EXTENSION) *)OPENSSL_sk_new_reserve(ossl_check_X509_EXTENSION_compfunc_type(cmp), (n)))
#define sk_X509_EXTENSION_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_X509_EXTENSION_sk_type(sk), (n))
#define sk_X509_EXTENSION_free(sk) OPENSSL_sk_free(ossl_check_X509_EXTENSION_sk_type(sk))
#define sk_X509_EXTENSION_zero(sk) OPENSSL_sk_zero(ossl_check_X509_EXTENSION_sk_type(sk))
#define sk_X509_EXTENSION_delete(sk, i) ((X509_EXTENSION *)OPENSSL_sk_delete(ossl_check_X509_EXTENSION_sk_type(sk), (i)))
#define sk_X509_EXTENSION_delete_ptr(sk, ptr) ((X509_EXTENSION *)OPENSSL_sk_delete_ptr(ossl_check_X509_EXTENSION_sk_type(sk), ossl_check_X509_EXTENSION_type(ptr)))
#define sk_X509_EXTENSION_push(sk, ptr) OPENSSL_sk_push(ossl_check_X509_EXTENSION_sk_type(sk), ossl_check_X509_EXTENSION_type(ptr))
#define sk_X509_EXTENSION_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_X509_EXTENSION_sk_type(sk), ossl_check_X509_EXTENSION_type(ptr))
#define sk_X509_EXTENSION_pop(sk) ((X509_EXTENSION *)OPENSSL_sk_pop(ossl_check_X509_EXTENSION_sk_type(sk)))
#define sk_X509_EXTENSION_shift(sk) ((X509_EXTENSION *)OPENSSL_sk_shift(ossl_check_X509_EXTENSION_sk_type(sk)))
#define sk_X509_EXTENSION_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_X509_EXTENSION_sk_type(sk),ossl_check_X509_EXTENSION_freefunc_type(freefunc))
#define sk_X509_EXTENSION_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_X509_EXTENSION_sk_type(sk), ossl_check_X509_EXTENSION_type(ptr), (idx))
#define sk_X509_EXTENSION_set(sk, idx, ptr) ((X509_EXTENSION *)OPENSSL_sk_set(ossl_check_X509_EXTENSION_sk_type(sk), (idx), ossl_check_X509_EXTENSION_type(ptr)))
#define sk_X509_EXTENSION_find(sk, ptr) OPENSSL_sk_find(ossl_check_X509_EXTENSION_sk_type(sk), ossl_check_X509_EXTENSION_type(ptr))
#define sk_X509_EXTENSION_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_X509_EXTENSION_sk_type(sk), ossl_check_X509_EXTENSION_type(ptr))
#define sk_X509_EXTENSION_find_all(sk, ptr, pnum) OPENSSL_sk_find_all(ossl_check_X509_EXTENSION_sk_type(sk), ossl_check_X509_EXTENSION_type(ptr), pnum)
#define sk_X509_EXTENSION_sort(sk) OPENSSL_sk_sort(ossl_check_X509_EXTENSION_sk_type(sk))
#define sk_X509_EXTENSION_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_X509_EXTENSION_sk_type(sk))
#define sk_X509_EXTENSION_dup(sk) ((STACK_OF(X509_EXTENSION) *)OPENSSL_sk_dup(ossl_check_const_X509_EXTENSION_sk_type(sk)))
#define sk_X509_EXTENSION_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(X509_EXTENSION) *)OPENSSL_sk_deep_copy(ossl_check_const_X509_EXTENSION_sk_type(sk), ossl_check_X509_EXTENSION_copyfunc_type(copyfunc), ossl_check_X509_EXTENSION_freefunc_type(freefunc)))
#define sk_X509_EXTENSION_set_cmp_func(sk, cmp) ((sk_X509_EXTENSION_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_X509_EXTENSION_sk_type(sk), ossl_check_X509_EXTENSION_compfunc_type(cmp)))

typedef STACK_OF(X509_EXTENSION) X509_EXTENSIONS;
typedef struct x509_attributes_st X509_ATTRIBUTE;
SKM_DEFINE_STACK_OF_INTERNAL(X509_ATTRIBUTE, X509_ATTRIBUTE, X509_ATTRIBUTE)
#define sk_X509_ATTRIBUTE_num(sk) OPENSSL_sk_num(ossl_check_const_X509_ATTRIBUTE_sk_type(sk))
#define sk_X509_ATTRIBUTE_value(sk, idx) ((X509_ATTRIBUTE *)OPENSSL_sk_value(ossl_check_const_X509_ATTRIBUTE_sk_type(sk), (idx)))
#define sk_X509_ATTRIBUTE_new(cmp) ((STACK_OF(X509_ATTRIBUTE) *)OPENSSL_sk_new(ossl_check_X509_ATTRIBUTE_compfunc_type(cmp)))
#define sk_X509_ATTRIBUTE_new_null() ((STACK_OF(X509_ATTRIBUTE) *)OPENSSL_sk_new_null())
#define sk_X509_ATTRIBUTE_new_reserve(cmp, n) ((STACK_OF(X509_ATTRIBUTE) *)OPENSSL_sk_new_reserve(ossl_check_X509_ATTRIBUTE_compfunc_type(cmp), (n)))
#define sk_X509_ATTRIBUTE_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_X509_ATTRIBUTE_sk_type(sk), (n))
#define sk_X509_ATTRIBUTE_free(sk) OPENSSL_sk_free(ossl_check_X509_ATTRIBUTE_sk_type(sk))
#define sk_X509_ATTRIBUTE_zero(sk) OPENSSL_sk_zero(ossl_check_X509_ATTRIBUTE_sk_type(sk))
#define sk_X509_ATTRIBUTE_delete(sk, i) ((X509_ATTRIBUTE *)OPENSSL_sk_delete(ossl_check_X509_ATTRIBUTE_sk_type(sk), (i)))
#define sk_X509_ATTRIBUTE_delete_ptr(sk, ptr) ((X509_ATTRIBUTE *)OPENSSL_sk_delete_ptr(ossl_check_X509_ATTRIBUTE_sk_type(sk), ossl_check_X509_ATTRIBUTE_type(ptr)))
#define sk_X509_ATTRIBUTE_push(sk, ptr) OPENSSL_sk_push(ossl_check_X509_ATTRIBUTE_sk_type(sk), ossl_check_X509_ATTRIBUTE_type(ptr))
#define sk_X509_ATTRIBUTE_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_X509_ATTRIBUTE_sk_type(sk), ossl_check_X509_ATTRIBUTE_type(ptr))
#define sk_X509_ATTRIBUTE_pop(sk) ((X509_ATTRIBUTE *)OPENSSL_sk_pop(ossl_check_X509_ATTRIBUTE_sk_type(sk)))
#define sk_X509_ATTRIBUTE_shift(sk) ((X509_ATTRIBUTE *)OPENSSL_sk_shift(ossl_check_X509_ATTRIBUTE_sk_type(sk)))
#define sk_X509_ATTRIBUTE_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_X509_ATTRIBUTE_sk_type(sk),ossl_check_X509_ATTRIBUTE_freefunc_type(freefunc))
#define sk_X509_ATTRIBUTE_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_X509_ATTRIBUTE_sk_type(sk), ossl_check_X509_ATTRIBUTE_type(ptr), (idx))
#define sk_X509_ATTRIBUTE_set(sk, idx, ptr) ((X509_ATTRIBUTE *)OPENSSL_sk_set(ossl_check_X509_ATTRIBUTE_sk_type(sk), (idx), ossl_check_X509_ATTRIBUTE_type(ptr)))
#define sk_X509_ATTRIBUTE_find(sk, ptr) OPENSSL_sk_find(ossl_check_X509_ATTRIBUTE_sk_type(sk), ossl_check_X509_ATTRIBUTE_type(ptr))
#define sk_X509_ATTRIBUTE_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_X509_ATTRIBUTE_sk_type(sk), ossl_check_X509_ATTRIBUTE_type(ptr))
#define sk_X509_ATTRIBUTE_find_all(sk, ptr, pnum) OPENSSL_sk_find_all(ossl_check_X509_ATTRIBUTE_sk_type(sk), ossl_check_X509_ATTRIBUTE_type(ptr), pnum)
#define sk_X509_ATTRIBUTE_sort(sk) OPENSSL_sk_sort(ossl_check_X509_ATTRIBUTE_sk_type(sk))
#define sk_X509_ATTRIBUTE_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_X509_ATTRIBUTE_sk_type(sk))
#define sk_X509_ATTRIBUTE_dup(sk) ((STACK_OF(X509_ATTRIBUTE) *)OPENSSL_sk_dup(ossl_check_const_X509_ATTRIBUTE_sk_type(sk)))
#define sk_X509_ATTRIBUTE_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(X509_ATTRIBUTE) *)OPENSSL_sk_deep_copy(ossl_check_const_X509_ATTRIBUTE_sk_type(sk), ossl_check_X509_ATTRIBUTE_copyfunc_type(copyfunc), ossl_check_X509_ATTRIBUTE_freefunc_type(freefunc)))
#define sk_X509_ATTRIBUTE_set_cmp_func(sk, cmp) ((sk_X509_ATTRIBUTE_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_X509_ATTRIBUTE_sk_type(sk), ossl_check_X509_ATTRIBUTE_compfunc_type(cmp)))

typedef struct X509_req_info_st X509_REQ_INFO;
typedef struct X509_req_st X509_REQ;
typedef struct x509_cert_aux_st X509_CERT_AUX;
typedef struct x509_cinf_st X509_CINF;

/* Flags for X509_print_ex() */

# define X509_FLAG_COMPAT                0
# define X509_FLAG_NO_HEADER             1L
# define X509_FLAG_NO_VERSION            (1L << 1)
# define X509_FLAG_NO_SERIAL             (1L << 2)
# define X509_FLAG_NO_SIGNAME            (1L << 3)
# define X509_FLAG_NO_ISSUER             (1L << 4)
# define X509_FLAG_NO_VALIDITY           (1L << 5)
# define X509_FLAG_NO_SUBJECT            (1L << 6)
# define X509_FLAG_NO_PUBKEY             (1L << 7)
# define X509_FLAG_NO_EXTENSIONS         (1L << 8)
# define X509_FLAG_NO_SIGDUMP            (1L << 9)
# define X509_FLAG_NO_AUX                (1L << 10)
# define X509_FLAG_NO_ATTRIBUTES         (1L << 11)
# define X509_FLAG_NO_IDS                (1L << 12)
# define X509_FLAG_EXTENSIONS_ONLY_KID   (1L << 13)

/* Flags specific to X509_NAME_print_ex() */

/* The field separator information */

# define XN_FLAG_SEP_MASK        (0xf << 16)

# define XN_FLAG_COMPAT          0/* Traditional; use old X509_NAME_print */
# define XN_FLAG_SEP_COMMA_PLUS  (1 << 16)/* RFC2253 ,+ */
# define XN_FLAG_SEP_CPLUS_SPC   (2 << 16)/* ,+ spaced: more readable */
# define XN_FLAG_SEP_SPLUS_SPC   (3 << 16)/* ;+ spaced */
# define XN_FLAG_SEP_MULTILINE   (4 << 16)/* One line per field */

# define XN_FLAG_DN_REV          (1 << 20)/* Reverse DN order */

/* How the field name is shown */

# define XN_FLAG_FN_MASK         (0x3 << 21)

# define XN_FLAG_FN_SN           0/* Object short name */
# define XN_FLAG_FN_LN           (1 << 21)/* Object long name */
# define XN_FLAG_FN_OID          (2 << 21)/* Always use OIDs */
# define XN_FLAG_FN_NONE         (3 << 21)/* No field names */

# define XN_FLAG_SPC_EQ          (1 << 23)/* Put spaces round '=' */

/*
 * This determines if we dump fields we don't recognise: RFC2253 requires
 * this.
 */

# define XN_FLAG_DUMP_UNKNOWN_FIELDS (1 << 24)

# define XN_FLAG_FN_ALIGN        (1 << 25)/* Align field names to 20
                                           * characters */

/* Complete set of RFC2253 flags */

# define XN_FLAG_RFC2253 (ASN1_STRFLGS_RFC2253 | \
                        XN_FLAG_SEP_COMMA_PLUS | \
                        XN_FLAG_DN_REV | \
                        XN_FLAG_FN_SN | \
                        XN_FLAG_DUMP_UNKNOWN_FIELDS)

/* readable oneline form */

# define XN_FLAG_ONELINE (ASN1_STRFLGS_RFC2253 | \
                        ASN1_STRFLGS_ESC_QUOTE | \
                        XN_FLAG_SEP_CPLUS_SPC | \
                        XN_FLAG_SPC_EQ | \
                        XN_FLAG_FN_SN)

/* readable multiline form */

# define XN_FLAG_MULTILINE (ASN1_STRFLGS_ESC_CTRL | \
                        ASN1_STRFLGS_ESC_MSB | \
                        XN_FLAG_SEP_MULTILINE | \
                        XN_FLAG_SPC_EQ | \
                        XN_FLAG_FN_LN | \
                        XN_FLAG_FN_ALIGN)

typedef struct X509_crl_info_st X509_CRL_INFO;

typedef struct private_key_st {
    int version;
    /* The PKCS#8 data types */
    X509_ALGOR *enc_algor;
    ASN1_OCTET_STRING *enc_pkey; /* encrypted pub key */
    /* When decrypted, the following will not be NULL */
    EVP_PKEY *dec_pkey;
    /* used to encrypt and decrypt */
    int key_length;
    char *key_data;
    int key_free;               /* true if we should auto free key_data */
    /* expanded version of 'enc_algor' */
    EVP_CIPHER_INFO cipher;
} X509_PKEY;

typedef struct X509_info_st {
    X509 *x509;
    X509_CRL *crl;
    X509_PKEY *x_pkey;
    EVP_CIPHER_INFO enc_cipher;
    int enc_len;
    char *enc_data;
} X509_INFO;
SKM_DEFINE_STACK_OF_INTERNAL(X509_INFO, X509_INFO, X509_INFO)
#define sk_X509_INFO_num(sk) OPENSSL_sk_num(ossl_check_const_X509_INFO_sk_type(sk))
#define sk_X509_INFO_value(sk, idx) ((X509_INFO *)OPENSSL_sk_value(ossl_check_const_X509_INFO_sk_type(sk), (idx)))
#define sk_X509_INFO_new(cmp) ((STACK_OF(X509_INFO) *)OPENSSL_sk_new(ossl_check_X509_INFO_compfunc_type(cmp)))
#define sk_X509_INFO_new_null() ((STACK_OF(X509_INFO) *)OPENSSL_sk_new_null())
#define sk_X509_INFO_new_reserve(cmp, n) ((STACK_OF(X509_INFO) *)OPENSSL_sk_new_reserve(ossl_check_X509_INFO_compfunc_type(cmp), (n)))
#define sk_X509_INFO_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_X509_INFO_sk_type(sk), (n))
#define sk_X509_INFO_free(sk) OPENSSL_sk_free(ossl_check_X509_INFO_sk_type(sk))
#define sk_X509_INFO_zero(sk) OPENSSL_sk_zero(ossl_check_X509_INFO_sk_type(sk))
#define sk_X509_INFO_delete(sk, i) ((X509_INFO *)OPENSSL_sk_delete(ossl_check_X509_INFO_sk_type(sk), (i)))
#define sk_X509_INFO_delete_ptr(sk, ptr) ((X509_INFO *)OPENSSL_sk_delete_ptr(ossl_check_X509_INFO_sk_type(sk), ossl_check_X509_INFO_type(ptr)))
#define sk_X509_INFO_push(sk, ptr) OPENSSL_sk_push(ossl_check_X509_INFO_sk_type(sk), ossl_check_X509_INFO_type(ptr))
#define sk_X509_INFO_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_X509_INFO_sk_type(sk), ossl_check_X509_INFO_type(ptr))
#define sk_X509_INFO_pop(sk) ((X509_INFO *)OPENSSL_sk_pop(ossl_check_X509_INFO_sk_type(sk)))
#define sk_X509_INFO_shift(sk) ((X509_INFO *)OPENSSL_sk_shift(ossl_check_X509_INFO_sk_type(sk)))
#define sk_X509_INFO_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_X509_INFO_sk_type(sk),ossl_check_X509_INFO_freefunc_type(freefunc))
#define sk_X509_INFO_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_X509_INFO_sk_type(sk), ossl_check_X509_INFO_type(ptr), (idx))
#define sk_X509_INFO_set(sk, idx, ptr) ((X509_INFO *)OPENSSL_sk_set(ossl_check_X509_INFO_sk_type(sk), (idx), ossl_check_X509_INFO_type(ptr)))
#define sk_X509_INFO_find(sk, ptr) OPENSSL_sk_find(ossl_check_X509_INFO_sk_type(sk), ossl_check_X509_INFO_type(ptr))
#define sk_X509_INFO_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_X509_INFO_sk_type(sk), ossl_check_X509_INFO_type(ptr))
#define sk_X509_INFO_find_all(sk, ptr, pnum) OPENSSL_sk_find_all(ossl_check_X509_INFO_sk_type(sk), ossl_check_X509_INFO_type(ptr), pnum)
#define sk_X509_INFO_sort(sk) OPENSSL_sk_sort(ossl_check_X509_INFO_sk_type(sk))
#define sk_X509_INFO_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_X509_INFO_sk_type(sk))
#define sk_X509_INFO_dup(sk) ((STACK_OF(X509_INFO) *)OPENSSL_sk_dup(ossl_check_const_X509_INFO_sk_type(sk)))
#define sk_X509_INFO_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(X509_INFO) *)OPENSSL_sk_deep_copy(ossl_check_const_X509_INFO_sk_type(sk), ossl_check_X509_INFO_copyfunc_type(copyfunc), ossl_check_X509_INFO_freefunc_type(freefunc)))
#define sk_X509_INFO_set_cmp_func(sk, cmp) ((sk_X509_INFO_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_X509_INFO_sk_type(sk), ossl_check_X509_INFO_compfunc_type(cmp)))


/*
 * The next 2 structures and their 8 routines are used to manipulate Netscape's
 * spki structures - useful if you are writing a CA web page
 */
typedef struct Netscape_spkac_st {
    X509_PUBKEY *pubkey;
    ASN1_IA5STRING *challenge;  /* challenge sent in atlas >= PR2 */
} NETSCAPE_SPKAC;

typedef struct Netscape_spki_st {
    NETSCAPE_SPKAC *spkac;      /* signed public key and challenge */
    X509_ALGOR sig_algor;
    ASN1_BIT_STRING *signature;
} NETSCAPE_SPKI;

/* Netscape certificate sequence structure */
typedef struct Netscape_certificate_sequence {
    ASN1_OBJECT *type;
    STACK_OF(X509) *certs;
} NETSCAPE_CERT_SEQUENCE;

/*- Unused (and iv length is wrong)
typedef struct CBCParameter_st
        {
        unsigned char iv[8];
        } CBC_PARAM;
*/

/* Password based encryption structure */

typedef struct PBEPARAM_st {
    ASN1_OCTET_STRING *salt;
    ASN1_INTEGER *iter;
} PBEPARAM;

/* Password based encryption V2 structures */

typedef struct PBE2PARAM_st {
    X509_ALGOR *keyfunc;
    X509_ALGOR *encryption;
} PBE2PARAM;

typedef struct PBKDF2PARAM_st {
/* Usually OCTET STRING but could be anything */
    ASN1_TYPE *salt;
    ASN1_INTEGER *iter;
    ASN1_INTEGER *keylength;
    X509_ALGOR *prf;
} PBKDF2PARAM;

#ifndef OPENSSL_NO_SCRYPT
typedef struct SCRYPT_PARAMS_st {
    ASN1_OCTET_STRING *salt;
    ASN1_INTEGER *costParameter;
    ASN1_INTEGER *blockSize;
    ASN1_INTEGER *parallelizationParameter;
    ASN1_INTEGER *keyLength;
} SCRYPT_PARAMS;
#endif

#ifdef  __cplusplus
}
#endif

# include <openssl/x509_vfy.h>
# include <openssl/pkcs7.h>

#ifdef  __cplusplus
extern "C" {
#endif

# define X509_EXT_PACK_UNKNOWN   1
# define X509_EXT_PACK_STRING    2

# define         X509_extract_key(x)     X509_get_pubkey(x)/*****/
# define         X509_REQ_extract_key(a) X509_REQ_get_pubkey(a)
# define         X509_name_cmp(a,b)      X509_NAME_cmp((a),(b))

void X509_CRL_set_default_method(const X509_CRL_METHOD *meth);
X509_CRL_METHOD *X509_CRL_METHOD_new(int (*crl_init) (X509_CRL *crl),
                                     int (*crl_free) (X509_CRL *crl),
                                     int (*crl_lookup) (X509_CRL *crl,
                                                        X509_REVOKED **ret,
                                                        const
                                                        ASN1_INTEGER *serial,
                                                        const
                                                        X509_NAME *issuer),
                                     int (*crl_verify) (X509_CRL *crl,
                                                        EVP_PKEY *pk));
void X509_CRL_METHOD_free(X509_CRL_METHOD *m);

void X509_CRL_set_meth_data(X509_CRL *crl, void *dat);
void *X509_CRL_get_meth_data(X509_CRL *crl);

const char *X509_verify_cert_error_string(long n);

int X509_verify(X509 *a, EVP_PKEY *r);
int X509_self_signed(X509 *cert, int verify_signature);

int X509_REQ_verify_ex(X509_REQ *a, EVP_PKEY *r, OSSL_LIB_CTX *libctx,
                       const char *propq);
int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r);
int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r);
int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r);

NETSCAPE_SPKI *NETSCAPE_SPKI_b64_decode(const char *str, int len);
char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *x);
EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x);
int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey);

int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki);

int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent);
int X509_signature_print(BIO *bp, const X509_ALGOR *alg,
                         const ASN1_STRING *sig);

int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md);
int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx);
int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md);
int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx);
int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md);
int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx);
int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md);

int X509_pubkey_digest(const X509 *data, const EVP_MD *type,
                       unsigned char *md, unsigned int *len);
int X509_digest(const X509 *data, const EVP_MD *type,
                unsigned char *md, unsigned int *len);
ASN1_OCTET_STRING *X509_digest_sig(const X509 *cert,
                                   EVP_MD **md_used, int *md_is_fallback);
int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type,
                    unsigned char *md, unsigned int *len);
int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type,
                    unsigned char *md, unsigned int *len);
int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type,
                     unsigned char *md, unsigned int *len);

X509 *X509_load_http(const char *url, BIO *bio, BIO *rbio, int timeout);
X509_CRL *X509_CRL_load_http(const char *url, BIO *bio, BIO *rbio, int timeout);
# ifndef OPENSSL_NO_DEPRECATED_3_0
#  include <openssl/http.h> /* OSSL_HTTP_REQ_CTX_nbio_d2i */
#  define X509_http_nbio(rctx, pcert) \
      OSSL_HTTP_REQ_CTX_nbio_d2i(rctx, pcert, ASN1_ITEM_rptr(X509))
#  define X509_CRL_http_nbio(rctx, pcrl) \
      OSSL_HTTP_REQ_CTX_nbio_d2i(rctx, pcrl, ASN1_ITEM_rptr(X509_CRL))
# endif

# ifndef OPENSSL_NO_STDIO
X509 *d2i_X509_fp(FILE *fp, X509 **x509);
int i2d_X509_fp(FILE *fp, const X509 *x509);
X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl);
int i2d_X509_CRL_fp(FILE *fp, const X509_CRL *crl);
X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req);
int i2d_X509_REQ_fp(FILE *fp, const X509_REQ *req);
#  ifndef OPENSSL_NO_DEPRECATED_3_0
OSSL_DEPRECATEDIN_3_0 RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa);
OSSL_DEPRECATEDIN_3_0 int i2d_RSAPrivateKey_fp(FILE *fp, const RSA *rsa);
OSSL_DEPRECATEDIN_3_0 RSA *d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa);
OSSL_DEPRECATEDIN_3_0 int i2d_RSAPublicKey_fp(FILE *fp, const RSA *rsa);
OSSL_DEPRECATEDIN_3_0 RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa);
OSSL_DEPRECATEDIN_3_0 int i2d_RSA_PUBKEY_fp(FILE *fp, const RSA *rsa);
#  endif
#  ifndef OPENSSL_NO_DEPRECATED_3_0
#   ifndef OPENSSL_NO_DSA
OSSL_DEPRECATEDIN_3_0 DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa);
OSSL_DEPRECATEDIN_3_0 int i2d_DSA_PUBKEY_fp(FILE *fp, const DSA *dsa);
OSSL_DEPRECATEDIN_3_0 DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa);
OSSL_DEPRECATEDIN_3_0 int i2d_DSAPrivateKey_fp(FILE *fp, const DSA *dsa);
#   endif
#  endif
#  ifndef OPENSSL_NO_DEPRECATED_3_0
#   ifndef OPENSSL_NO_EC
OSSL_DEPRECATEDIN_3_0 EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey);
OSSL_DEPRECATEDIN_3_0 int i2d_EC_PUBKEY_fp(FILE *fp, const EC_KEY *eckey);
OSSL_DEPRECATEDIN_3_0 EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey);
OSSL_DEPRECATEDIN_3_0 int i2d_ECPrivateKey_fp(FILE *fp, const EC_KEY *eckey);
#   endif /* OPENSSL_NO_EC */
#  endif /* OPENSSL_NO_DEPRECATED_3_0 */
X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8);
int i2d_PKCS8_fp(FILE *fp, const X509_SIG *p8);
X509_PUBKEY *d2i_X509_PUBKEY_fp(FILE *fp, X509_PUBKEY **xpk);
int i2d_X509_PUBKEY_fp(FILE *fp, const X509_PUBKEY *xpk);
PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,
                                                PKCS8_PRIV_KEY_INFO **p8inf);
int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, const PKCS8_PRIV_KEY_INFO *p8inf);
int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, const EVP_PKEY *key);
int i2d_PrivateKey_fp(FILE *fp, const EVP_PKEY *pkey);
EVP_PKEY *d2i_PrivateKey_ex_fp(FILE *fp, EVP_PKEY **a, OSSL_LIB_CTX *libctx,
                               const char *propq);
EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a);
int i2d_PUBKEY_fp(FILE *fp, const EVP_PKEY *pkey);
EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a);
# endif

X509 *d2i_X509_bio(BIO *bp, X509 **x509);
int i2d_X509_bio(BIO *bp, const X509 *x509);
X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl);
int i2d_X509_CRL_bio(BIO *bp, const X509_CRL *crl);
X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req);
int i2d_X509_REQ_bio(BIO *bp, const X509_REQ *req);
#  ifndef OPENSSL_NO_DEPRECATED_3_0
OSSL_DEPRECATEDIN_3_0 RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa);
OSSL_DEPRECATEDIN_3_0 int i2d_RSAPrivateKey_bio(BIO *bp, const RSA *rsa);
OSSL_DEPRECATEDIN_3_0 RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa);
OSSL_DEPRECATEDIN_3_0 int i2d_RSAPublicKey_bio(BIO *bp, const RSA *rsa);
OSSL_DEPRECATEDIN_3_0 RSA *d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa);
OSSL_DEPRECATEDIN_3_0 int i2d_RSA_PUBKEY_bio(BIO *bp, const RSA *rsa);
#  endif
#  ifndef OPENSSL_NO_DEPRECATED_3_0
#   ifndef OPENSSL_NO_DSA
OSSL_DEPRECATEDIN_3_0 DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa);
OSSL_DEPRECATEDIN_3_0 int i2d_DSA_PUBKEY_bio(BIO *bp, const DSA *dsa);
OSSL_DEPRECATEDIN_3_0 DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa);
OSSL_DEPRECATEDIN_3_0 int i2d_DSAPrivateKey_bio(BIO *bp, const DSA *dsa);
#   endif
#  endif

#  ifndef OPENSSL_NO_DEPRECATED_3_0
#   ifndef OPENSSL_NO_EC
OSSL_DEPRECATEDIN_3_0 EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey);
OSSL_DEPRECATEDIN_3_0 int i2d_EC_PUBKEY_bio(BIO *bp, const EC_KEY *eckey);
OSSL_DEPRECATEDIN_3_0 EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey);
OSSL_DEPRECATEDIN_3_0 int i2d_ECPrivateKey_bio(BIO *bp, const EC_KEY *eckey);
#   endif /* OPENSSL_NO_EC */
#  endif /* OPENSSL_NO_DEPRECATED_3_0 */

X509_SIG *d2i_PKCS8_bio(BIO *bp, X509_SIG **p8);
int i2d_PKCS8_bio(BIO *bp, const X509_SIG *p8);
X509_PUBKEY *d2i_X509_PUBKEY_bio(BIO *bp, X509_PUBKEY **xpk);
int i2d_X509_PUBKEY_bio(BIO *bp, const X509_PUBKEY *xpk);
PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,
                                                 PKCS8_PRIV_KEY_INFO **p8inf);
int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, const PKCS8_PRIV_KEY_INFO *p8inf);
int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, const EVP_PKEY *key);
int i2d_PrivateKey_bio(BIO *bp, const EVP_PKEY *pkey);
EVP_PKEY *d2i_PrivateKey_ex_bio(BIO *bp, EVP_PKEY **a, OSSL_LIB_CTX *libctx,
                                const char *propq);
EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a);
int i2d_PUBKEY_bio(BIO *bp, const EVP_PKEY *pkey);
EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a);

DECLARE_ASN1_DUP_FUNCTION(X509)
DECLARE_ASN1_DUP_FUNCTION(X509_ALGOR)
DECLARE_ASN1_DUP_FUNCTION(X509_ATTRIBUTE)
DECLARE_ASN1_DUP_FUNCTION(X509_CRL)
DECLARE_ASN1_DUP_FUNCTION(X509_EXTENSION)
DECLARE_ASN1_DUP_FUNCTION(X509_PUBKEY)
DECLARE_ASN1_DUP_FUNCTION(X509_REQ)
DECLARE_ASN1_DUP_FUNCTION(X509_REVOKED)
int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype,
                    void *pval);
void X509_ALGOR_get0(const ASN1_OBJECT **paobj, int *pptype,
                     const void **ppval, const X509_ALGOR *algor);
void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md);
int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b);
int X509_ALGOR_copy(X509_ALGOR *dest, const X509_ALGOR *src);

DECLARE_ASN1_DUP_FUNCTION(X509_NAME)
DECLARE_ASN1_DUP_FUNCTION(X509_NAME_ENTRY)

int X509_cmp_time(const ASN1_TIME *s, time_t *t);
int X509_cmp_current_time(const ASN1_TIME *s);
int X509_cmp_timeframe(const X509_VERIFY_PARAM *vpm,
                       const ASN1_TIME *start, const ASN1_TIME *end);
ASN1_TIME *X509_time_adj(ASN1_TIME *s, long adj, time_t *t);
ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s,
                            int offset_day, long offset_sec, time_t *t);
ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj);

const char *X509_get_default_cert_area(void);
const char *X509_get_default_cert_dir(void);
const char *X509_get_default_cert_file(void);
const char *X509_get_default_cert_dir_env(void);
const char *X509_get_default_cert_file_env(void);
const char *X509_get_default_private_dir(void);

X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md);
X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey);

DECLARE_ASN1_FUNCTIONS(X509_ALGOR)
DECLARE_ASN1_ENCODE_FUNCTIONS(X509_ALGORS, X509_ALGORS, X509_ALGORS)
DECLARE_ASN1_FUNCTIONS(X509_VAL)

DECLARE_ASN1_FUNCTIONS(X509_PUBKEY)

X509_PUBKEY *X509_PUBKEY_new_ex(OSSL_LIB_CTX *libctx, const char *propq);
int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey);
EVP_PKEY *X509_PUBKEY_get0(const X509_PUBKEY *key);
EVP_PKEY *X509_PUBKEY_get(const X509_PUBKEY *key);
int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain);
long X509_get_pathlen(X509 *x);
DECLARE_ASN1_ENCODE_FUNCTIONS_only(EVP_PKEY, PUBKEY)
EVP_PKEY *d2i_PUBKEY_ex(EVP_PKEY **a, const unsigned char **pp, long length,
                        OSSL_LIB_CTX *libctx, const char *propq);
# ifndef OPENSSL_NO_DEPRECATED_3_0
DECLARE_ASN1_ENCODE_FUNCTIONS_only_attr(OSSL_DEPRECATEDIN_3_0,RSA, RSA_PUBKEY)
# endif
# ifndef OPENSSL_NO_DEPRECATED_3_0
#  ifndef OPENSSL_NO_DSA
DECLARE_ASN1_ENCODE_FUNCTIONS_only_attr(OSSL_DEPRECATEDIN_3_0,DSA, DSA_PUBKEY)
#  endif
# endif
# ifndef OPENSSL_NO_DEPRECATED_3_0
#  ifndef OPENSSL_NO_EC
DECLARE_ASN1_ENCODE_FUNCTIONS_only_attr(OSSL_DEPRECATEDIN_3_0, EC_KEY, EC_PUBKEY)
#  endif
# endif

DECLARE_ASN1_FUNCTIONS(X509_SIG)
void X509_SIG_get0(const X509_SIG *sig, const X509_ALGOR **palg,
                   const ASN1_OCTET_STRING **pdigest);
void X509_SIG_getm(X509_SIG *sig, X509_ALGOR **palg,
                   ASN1_OCTET_STRING **pdigest);

DECLARE_ASN1_FUNCTIONS(X509_REQ_INFO)
DECLARE_ASN1_FUNCTIONS(X509_REQ)
X509_REQ *X509_REQ_new_ex(OSSL_LIB_CTX *libctx, const char *propq);

DECLARE_ASN1_FUNCTIONS(X509_ATTRIBUTE)
X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value);

DECLARE_ASN1_FUNCTIONS(X509_EXTENSION)
DECLARE_ASN1_ENCODE_FUNCTIONS(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS)

DECLARE_ASN1_FUNCTIONS(X509_NAME_ENTRY)

DECLARE_ASN1_FUNCTIONS(X509_NAME)

int X509_NAME_set(X509_NAME **xn, const X509_NAME *name);

DECLARE_ASN1_FUNCTIONS(X509_CINF)
DECLARE_ASN1_FUNCTIONS(X509)
X509 *X509_new_ex(OSSL_LIB_CTX *libctx, const char *propq);
DECLARE_ASN1_FUNCTIONS(X509_CERT_AUX)

#define X509_get_ex_new_index(l, p, newf, dupf, freef) \
    CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509, l, p, newf, dupf, freef)
int X509_set_ex_data(X509 *r, int idx, void *arg);
void *X509_get_ex_data(const X509 *r, int idx);
DECLARE_ASN1_ENCODE_FUNCTIONS_only(X509,X509_AUX)

int i2d_re_X509_tbs(X509 *x, unsigned char **pp);

int X509_SIG_INFO_get(const X509_SIG_INFO *siginf, int *mdnid, int *pknid,
                      int *secbits, uint32_t *flags);
void X509_SIG_INFO_set(X509_SIG_INFO *siginf, int mdnid, int pknid,
                       int secbits, uint32_t flags);

int X509_get_signature_info(X509 *x, int *mdnid, int *pknid, int *secbits,
                            uint32_t *flags);

void X509_get0_signature(const ASN1_BIT_STRING **psig,
                         const X509_ALGOR **palg, const X509 *x);
int X509_get_signature_nid(const X509 *x);

void X509_set0_distinguishing_id(X509 *x, ASN1_OCTET_STRING *d_id);
ASN1_OCTET_STRING *X509_get0_distinguishing_id(X509 *x);
void X509_REQ_set0_distinguishing_id(X509_REQ *x, ASN1_OCTET_STRING *d_id);
ASN1_OCTET_STRING *X509_REQ_get0_distinguishing_id(X509_REQ *x);

int X509_alias_set1(X509 *x, const unsigned char *name, int len);
int X509_keyid_set1(X509 *x, const unsigned char *id, int len);
unsigned char *X509_alias_get0(X509 *x, int *len);
unsigned char *X509_keyid_get0(X509 *x, int *len);

DECLARE_ASN1_FUNCTIONS(X509_REVOKED)
DECLARE_ASN1_FUNCTIONS(X509_CRL_INFO)
DECLARE_ASN1_FUNCTIONS(X509_CRL)
X509_CRL *X509_CRL_new_ex(OSSL_LIB_CTX *libctx, const char *propq);

int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev);
int X509_CRL_get0_by_serial(X509_CRL *crl,
                            X509_REVOKED **ret, const ASN1_INTEGER *serial);
int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x);

X509_PKEY *X509_PKEY_new(void);
void X509_PKEY_free(X509_PKEY *a);

DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKI)
DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKAC)
DECLARE_ASN1_FUNCTIONS(NETSCAPE_CERT_SEQUENCE)

X509_INFO *X509_INFO_new(void);
void X509_INFO_free(X509_INFO *a);
char *X509_NAME_oneline(const X509_NAME *a, char *buf, int size);

#ifndef OPENSSL_NO_DEPRECATED_3_0
OSSL_DEPRECATEDIN_3_0
int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *algor1,
                ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey);
OSSL_DEPRECATEDIN_3_0
int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data,
                unsigned char *md, unsigned int *len);
OSSL_DEPRECATEDIN_3_0
int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2,
              ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey,
              const EVP_MD *type);
#endif
int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *data,
                     unsigned char *md, unsigned int *len);
int ASN1_item_verify(const ASN1_ITEM *it, const X509_ALGOR *alg,
                     const ASN1_BIT_STRING *signature, const void *data,
                     EVP_PKEY *pkey);
int ASN1_item_verify_ctx(const ASN1_ITEM *it, const X509_ALGOR *alg,
                         const ASN1_BIT_STRING *signature, const void *data,
                         EVP_MD_CTX *ctx);
int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
                   ASN1_BIT_STRING *signature, const void *data,
                   EVP_PKEY *pkey, const EVP_MD *md);
int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1,
                       X509_ALGOR *algor2, ASN1_BIT_STRING *signature,
                       const void *data, EVP_MD_CTX *ctx);

#define X509_VERSION_1 0
#define X509_VERSION_2 1
#define X509_VERSION_3 2

long X509_get_version(const X509 *x);
int X509_set_version(X509 *x, long version);
int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial);
ASN1_INTEGER *X509_get_serialNumber(X509 *x);
const ASN1_INTEGER *X509_get0_serialNumber(const X509 *x);
int X509_set_issuer_name(X509 *x, const X509_NAME *name);
X509_NAME *X509_get_issuer_name(const X509 *a);
int X509_set_subject_name(X509 *x, const X509_NAME *name);
X509_NAME *X509_get_subject_name(const X509 *a);
const ASN1_TIME * X509_get0_notBefore(const X509 *x);
ASN1_TIME *X509_getm_notBefore(const X509 *x);
int X509_set1_notBefore(X509 *x, const ASN1_TIME *tm);
const ASN1_TIME *X509_get0_notAfter(const X509 *x);
ASN1_TIME *X509_getm_notAfter(const X509 *x);
int X509_set1_notAfter(X509 *x, const ASN1_TIME *tm);
int X509_set_pubkey(X509 *x, EVP_PKEY *pkey);
int X509_up_ref(X509 *x);
int X509_get_signature_type(const X509 *x);

# ifndef OPENSSL_NO_DEPRECATED_1_1_0
#  define X509_get_notBefore X509_getm_notBefore
#  define X509_get_notAfter X509_getm_notAfter
#  define X509_set_notBefore X509_set1_notBefore
#  define X509_set_notAfter X509_set1_notAfter
#endif


/*
 * This one is only used so that a binary form can output, as in
 * i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x), &buf)
 */
X509_PUBKEY *X509_get_X509_PUBKEY(const X509 *x);
const STACK_OF(X509_EXTENSION) *X509_get0_extensions(const X509 *x);
void X509_get0_uids(const X509 *x, const ASN1_BIT_STRING **piuid,
                    const ASN1_BIT_STRING **psuid);
const X509_ALGOR *X509_get0_tbs_sigalg(const X509 *x);

EVP_PKEY *X509_get0_pubkey(const X509 *x);
EVP_PKEY *X509_get_pubkey(X509 *x);
ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x);

#define X509_REQ_VERSION_1 0

long X509_REQ_get_version(const X509_REQ *req);
int X509_REQ_set_version(X509_REQ *x, long version);
X509_NAME *X509_REQ_get_subject_name(const X509_REQ *req);
int X509_REQ_set_subject_name(X509_REQ *req, const X509_NAME *name);
void X509_REQ_get0_signature(const X509_REQ *req, const ASN1_BIT_STRING **psig,
                             const X509_ALGOR **palg);
void X509_REQ_set0_signature(X509_REQ *req, ASN1_BIT_STRING *psig);
int X509_REQ_set1_signature_algo(X509_REQ *req, X509_ALGOR *palg);
int X509_REQ_get_signature_nid(const X509_REQ *req);
int i2d_re_X509_REQ_tbs(X509_REQ *req, unsigned char **pp);
int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey);
EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req);
EVP_PKEY *X509_REQ_get0_pubkey(X509_REQ *req);
X509_PUBKEY *X509_REQ_get_X509_PUBKEY(X509_REQ *req);
int X509_REQ_extension_nid(int nid);
int *X509_REQ_get_extension_nids(void);
void X509_REQ_set_extension_nids(int *nids);
STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req);
int X509_REQ_add_extensions_nid(X509_REQ *req,
                                const STACK_OF(X509_EXTENSION) *exts, int nid);
int X509_REQ_add_extensions(X509_REQ *req, const STACK_OF(X509_EXTENSION) *ext);
int X509_REQ_get_attr_count(const X509_REQ *req);
int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos);
int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, const ASN1_OBJECT *obj,
                             int lastpos);
X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc);
X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc);
int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr);
int X509_REQ_add1_attr_by_OBJ(X509_REQ *req,
                              const ASN1_OBJECT *obj, int type,
                              const unsigned char *bytes, int len);
int X509_REQ_add1_attr_by_NID(X509_REQ *req,
                              int nid, int type,
                              const unsigned char *bytes, int len);
int X509_REQ_add1_attr_by_txt(X509_REQ *req,
                              const char *attrname, int type,
                              const unsigned char *bytes, int len);

#define X509_CRL_VERSION_1 0
#define X509_CRL_VERSION_2 1

int X509_CRL_set_version(X509_CRL *x, long version);
int X509_CRL_set_issuer_name(X509_CRL *x, const X509_NAME *name);
int X509_CRL_set1_lastUpdate(X509_CRL *x, const ASN1_TIME *tm);
int X509_CRL_set1_nextUpdate(X509_CRL *x, const ASN1_TIME *tm);
int X509_CRL_sort(X509_CRL *crl);
int X509_CRL_up_ref(X509_CRL *crl);

# ifndef OPENSSL_NO_DEPRECATED_1_1_0
#  define X509_CRL_set_lastUpdate X509_CRL_set1_lastUpdate
#  define X509_CRL_set_nextUpdate X509_CRL_set1_nextUpdate
#endif

long X509_CRL_get_version(const X509_CRL *crl);
const ASN1_TIME *X509_CRL_get0_lastUpdate(const X509_CRL *crl);
const ASN1_TIME *X509_CRL_get0_nextUpdate(const X509_CRL *crl);
#ifndef OPENSSL_NO_DEPRECATED_1_1_0
OSSL_DEPRECATEDIN_1_1_0 ASN1_TIME *X509_CRL_get_lastUpdate(X509_CRL *crl);
OSSL_DEPRECATEDIN_1_1_0 ASN1_TIME *X509_CRL_get_nextUpdate(X509_CRL *crl);
#endif
X509_NAME *X509_CRL_get_issuer(const X509_CRL *crl);
const STACK_OF(X509_EXTENSION) *X509_CRL_get0_extensions(const X509_CRL *crl);
STACK_OF(X509_REVOKED) *X509_CRL_get_REVOKED(X509_CRL *crl);
void X509_CRL_get0_signature(const X509_CRL *crl, const ASN1_BIT_STRING **psig,
                             const X509_ALGOR **palg);
int X509_CRL_get_signature_nid(const X509_CRL *crl);
int i2d_re_X509_CRL_tbs(X509_CRL *req, unsigned char **pp);

const ASN1_INTEGER *X509_REVOKED_get0_serialNumber(const X509_REVOKED *x);
int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial);
const ASN1_TIME *X509_REVOKED_get0_revocationDate(const X509_REVOKED *x);
int X509_REVOKED_set_revocationDate(X509_REVOKED *r, ASN1_TIME *tm);
const STACK_OF(X509_EXTENSION) *
X509_REVOKED_get0_extensions(const X509_REVOKED *r);

X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer,
                        EVP_PKEY *skey, const EVP_MD *md, unsigned int flags);

int X509_REQ_check_private_key(X509_REQ *x509, EVP_PKEY *pkey);

int X509_check_private_key(const X509 *x509, const EVP_PKEY *pkey);
int X509_chain_check_suiteb(int *perror_depth,
                            X509 *x, STACK_OF(X509) *chain,
                            unsigned long flags);
int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags);
STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain);

int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b);
unsigned long X509_issuer_and_serial_hash(X509 *a);

int X509_issuer_name_cmp(const X509 *a, const X509 *b);
unsigned long X509_issuer_name_hash(X509 *a);

int X509_subject_name_cmp(const X509 *a, const X509 *b);
unsigned long X509_subject_name_hash(X509 *x);

# ifndef OPENSSL_NO_MD5
unsigned long X509_issuer_name_hash_old(X509 *a);
unsigned long X509_subject_name_hash_old(X509 *x);
# endif

# define X509_ADD_FLAG_DEFAULT  0
# define X509_ADD_FLAG_UP_REF   0x1
# define X509_ADD_FLAG_PREPEND  0x2
# define X509_ADD_FLAG_NO_DUP   0x4
# define X509_ADD_FLAG_NO_SS    0x8
int X509_add_cert(STACK_OF(X509) *sk, X509 *cert, int flags);
int X509_add_certs(STACK_OF(X509) *sk, STACK_OF(X509) *certs, int flags);

int X509_cmp(const X509 *a, const X509 *b);
int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b);
#ifndef OPENSSL_NO_DEPRECATED_3_0
# define X509_NAME_hash(x) X509_NAME_hash_ex(x, NULL, NULL, NULL)
OSSL_DEPRECATEDIN_3_0 int X509_certificate_type(const X509 *x,
                                                const EVP_PKEY *pubkey);
#endif
unsigned long X509_NAME_hash_ex(const X509_NAME *x, OSSL_LIB_CTX *libctx,
                                const char *propq, int *ok);
unsigned long X509_NAME_hash_old(const X509_NAME *x);

int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b);
int X509_CRL_match(const X509_CRL *a, const X509_CRL *b);
int X509_aux_print(BIO *out, X509 *x, int indent);
# ifndef OPENSSL_NO_STDIO
int X509_print_ex_fp(FILE *bp, X509 *x, unsigned long nmflag,
                     unsigned long cflag);
int X509_print_fp(FILE *bp, X509 *x);
int X509_CRL_print_fp(FILE *bp, X509_CRL *x);
int X509_REQ_print_fp(FILE *bp, X509_REQ *req);
int X509_NAME_print_ex_fp(FILE *fp, const X509_NAME *nm, int indent,
                          unsigned long flags);
# endif

int X509_NAME_print(BIO *bp, const X509_NAME *name, int obase);
int X509_NAME_print_ex(BIO *out, const X509_NAME *nm, int indent,
                       unsigned long flags);
int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflag,
                  unsigned long cflag);
int X509_print(BIO *bp, X509 *x);
int X509_ocspid_print(BIO *bp, X509 *x);
int X509_CRL_print_ex(BIO *out, X509_CRL *x, unsigned long nmflag);
int X509_CRL_print(BIO *bp, X509_CRL *x);
int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflag,
                      unsigned long cflag);
int X509_REQ_print(BIO *bp, X509_REQ *req);

int X509_NAME_entry_count(const X509_NAME *name);
int X509_NAME_get_text_by_NID(const X509_NAME *name, int nid,
                              char *buf, int len);
int X509_NAME_get_text_by_OBJ(const X509_NAME *name, const ASN1_OBJECT *obj,
                              char *buf, int len);

/*
 * NOTE: you should be passing -1, not 0 as lastpos. The functions that use
 * lastpos, search after that position on.
 */
int X509_NAME_get_index_by_NID(const X509_NAME *name, int nid, int lastpos);
int X509_NAME_get_index_by_OBJ(const X509_NAME *name, const ASN1_OBJECT *obj,
                               int lastpos);
X509_NAME_ENTRY *X509_NAME_get_entry(const X509_NAME *name, int loc);
X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc);
int X509_NAME_add_entry(X509_NAME *name, const X509_NAME_ENTRY *ne,
                        int loc, int set);
int X509_NAME_add_entry_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, int type,
                               const unsigned char *bytes, int len, int loc,
                               int set);
int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type,
                               const unsigned char *bytes, int len, int loc,
                               int set);
X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne,
                                               const char *field, int type,
                                               const unsigned char *bytes,
                                               int len);
X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid,
                                               int type,
                                               const unsigned char *bytes,
                                               int len);
int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type,
                               const unsigned char *bytes, int len, int loc,
                               int set);
X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne,
                                               const ASN1_OBJECT *obj, int type,
                                               const unsigned char *bytes,
                                               int len);
int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, const ASN1_OBJECT *obj);
int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type,
                             const unsigned char *bytes, int len);
ASN1_OBJECT *X509_NAME_ENTRY_get_object(const X509_NAME_ENTRY *ne);
ASN1_STRING * X509_NAME_ENTRY_get_data(const X509_NAME_ENTRY *ne);
int X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne);

int X509_NAME_get0_der(const X509_NAME *nm, const unsigned char **pder,
                       size_t *pderlen);

int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x);
int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x,
                          int nid, int lastpos);
int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *x,
                          const ASN1_OBJECT *obj, int lastpos);
int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *x,
                               int crit, int lastpos);
X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc);
X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc);
STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x,
                                         X509_EXTENSION *ex, int loc);

int X509_get_ext_count(const X509 *x);
int X509_get_ext_by_NID(const X509 *x, int nid, int lastpos);
int X509_get_ext_by_OBJ(const X509 *x, const ASN1_OBJECT *obj, int lastpos);
int X509_get_ext_by_critical(const X509 *x, int crit, int lastpos);
X509_EXTENSION *X509_get_ext(const X509 *x, int loc);
X509_EXTENSION *X509_delete_ext(X509 *x, int loc);
int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc);
void *X509_get_ext_d2i(const X509 *x, int nid, int *crit, int *idx);
int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit,
                      unsigned long flags);

int X509_CRL_get_ext_count(const X509_CRL *x);
int X509_CRL_get_ext_by_NID(const X509_CRL *x, int nid, int lastpos);
int X509_CRL_get_ext_by_OBJ(const X509_CRL *x, const ASN1_OBJECT *obj,
                            int lastpos);
int X509_CRL_get_ext_by_critical(const X509_CRL *x, int crit, int lastpos);
X509_EXTENSION *X509_CRL_get_ext(const X509_CRL *x, int loc);
X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc);
int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc);
void *X509_CRL_get_ext_d2i(const X509_CRL *x, int nid, int *crit, int *idx);
int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit,
                          unsigned long flags);

int X509_REVOKED_get_ext_count(const X509_REVOKED *x);
int X509_REVOKED_get_ext_by_NID(const X509_REVOKED *x, int nid, int lastpos);
int X509_REVOKED_get_ext_by_OBJ(const X509_REVOKED *x, const ASN1_OBJECT *obj,
                                int lastpos);
int X509_REVOKED_get_ext_by_critical(const X509_REVOKED *x, int crit,
                                     int lastpos);
X509_EXTENSION *X509_REVOKED_get_ext(const X509_REVOKED *x, int loc);
X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc);
int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc);
void *X509_REVOKED_get_ext_d2i(const X509_REVOKED *x, int nid, int *crit,
                               int *idx);
int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit,
                              unsigned long flags);

X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex,
                                             int nid, int crit,
                                             ASN1_OCTET_STRING *data);
X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex,
                                             const ASN1_OBJECT *obj, int crit,
                                             ASN1_OCTET_STRING *data);
int X509_EXTENSION_set_object(X509_EXTENSION *ex, const ASN1_OBJECT *obj);
int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit);
int X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data);
ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex);
ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ne);
int X509_EXTENSION_get_critical(const X509_EXTENSION *ex);

int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x);
int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid,
                           int lastpos);
int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk,
                           const ASN1_OBJECT *obj, int lastpos);
X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc);
X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc);
STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
                                           X509_ATTRIBUTE *attr);
STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE)
                                                  **x, const ASN1_OBJECT *obj,
                                                  int type,
                                                  const unsigned char *bytes,
                                                  int len);
STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE)
                                                  **x, int nid, int type,
                                                  const unsigned char *bytes,
                                                  int len);
STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE)
                                                  **x, const char *attrname,
                                                  int type,
                                                  const unsigned char *bytes,
                                                  int len);
void *X509at_get0_data_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *x,
                              const ASN1_OBJECT *obj, int lastpos, int type);
X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid,
                                             int atrtype, const void *data,
                                             int len);
X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr,
                                             const ASN1_OBJECT *obj,
                                             int atrtype, const void *data,
                                             int len);
X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr,
                                             const char *atrname, int type,
                                             const unsigned char *bytes,
                                             int len);
int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj);
int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype,
                             const void *data, int len);
void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, int atrtype,
                               void *data);
int X509_ATTRIBUTE_count(const X509_ATTRIBUTE *attr);
ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr);
ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx);

int EVP_PKEY_get_attr_count(const EVP_PKEY *key);
int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid, int lastpos);
int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, const ASN1_OBJECT *obj,
                             int lastpos);
X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc);
X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc);
int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr);
int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key,
                              const ASN1_OBJECT *obj, int type,
                              const unsigned char *bytes, int len);
int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key,
                              int nid, int type,
                              const unsigned char *bytes, int len);
int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key,
                              const char *attrname, int type,
                              const unsigned char *bytes, int len);

/* lookup a cert from a X509 STACK */
X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, const X509_NAME *name,
                                     const ASN1_INTEGER *serial);
X509 *X509_find_by_subject(STACK_OF(X509) *sk, const X509_NAME *name);

DECLARE_ASN1_FUNCTIONS(PBEPARAM)
DECLARE_ASN1_FUNCTIONS(PBE2PARAM)
DECLARE_ASN1_FUNCTIONS(PBKDF2PARAM)
#ifndef OPENSSL_NO_SCRYPT
DECLARE_ASN1_FUNCTIONS(SCRYPT_PARAMS)
#endif

int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
                         const unsigned char *salt, int saltlen);
int PKCS5_pbe_set0_algor_ex(X509_ALGOR *algor, int alg, int iter,
                            const unsigned char *salt, int saltlen,
                            OSSL_LIB_CTX *libctx);

X509_ALGOR *PKCS5_pbe_set(int alg, int iter,
                          const unsigned char *salt, int saltlen);
X509_ALGOR *PKCS5_pbe_set_ex(int alg, int iter,
                             const unsigned char *salt, int saltlen,
                             OSSL_LIB_CTX *libctx);

X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
                           unsigned char *salt, int saltlen);
X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
                              unsigned char *salt, int saltlen,
                              unsigned char *aiv, int prf_nid);
X509_ALGOR *PKCS5_pbe2_set_iv_ex(const EVP_CIPHER *cipher, int iter,
                                 unsigned char *salt, int saltlen,
                                 unsigned char *aiv, int prf_nid,
                                 OSSL_LIB_CTX *libctx);

#ifndef OPENSSL_NO_SCRYPT
X509_ALGOR *PKCS5_pbe2_set_scrypt(const EVP_CIPHER *cipher,
                                  const unsigned char *salt, int saltlen,
                                  unsigned char *aiv, uint64_t N, uint64_t r,
                                  uint64_t p);
#endif

X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
                             int prf_nid, int keylen);
X509_ALGOR *PKCS5_pbkdf2_set_ex(int iter, unsigned char *salt, int saltlen,
                                int prf_nid, int keylen,
                                OSSL_LIB_CTX *libctx);

/* PKCS#8 utilities */

DECLARE_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO)

EVP_PKEY *EVP_PKCS82PKEY(const PKCS8_PRIV_KEY_INFO *p8);
EVP_PKEY *EVP_PKCS82PKEY_ex(const PKCS8_PRIV_KEY_INFO *p8, OSSL_LIB_CTX *libctx,
                            const char *propq);
PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(const EVP_PKEY *pkey);

int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj,
                    int version, int ptype, void *pval,
                    unsigned char *penc, int penclen);
int PKCS8_pkey_get0(const ASN1_OBJECT **ppkalg,
                    const unsigned char **pk, int *ppklen,
                    const X509_ALGOR **pa, const PKCS8_PRIV_KEY_INFO *p8);

const STACK_OF(X509_ATTRIBUTE) *
PKCS8_pkey_get0_attrs(const PKCS8_PRIV_KEY_INFO *p8);
int PKCS8_pkey_add1_attr(PKCS8_PRIV_KEY_INFO *p8, X509_ATTRIBUTE *attr);
int PKCS8_pkey_add1_attr_by_NID(PKCS8_PRIV_KEY_INFO *p8, int nid, int type,
                                const unsigned char *bytes, int len);
int PKCS8_pkey_add1_attr_by_OBJ(PKCS8_PRIV_KEY_INFO *p8, const ASN1_OBJECT *obj,
                                int type, const unsigned char *bytes, int len);


int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj,
                           int ptype, void *pval,
                           unsigned char *penc, int penclen);
int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg,
                           const unsigned char **pk, int *ppklen,
                           X509_ALGOR **pa, const X509_PUBKEY *pub);
int X509_PUBKEY_eq(const X509_PUBKEY *a, const X509_PUBKEY *b);

# ifdef  __cplusplus
}
# endif
#endif
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    9M"uIJX.{ǂs9v#˂
3W;?ڈTX;$xڇy 9ku
/3UZq[o
S65HDX8M<*
F jafa@y<IQXj[0|.T~sT}[xr6hrI.@(>9@k46dsr_xS׾=Z jy 0ϕ~oZF(Jpp<iF\E[p{H8ݲu<4ӢmO o!X}:~.F_.ö+H=Dh3U81~Z>Hj5YYXoaI,o0֛d՚G'^_Bǚ"l|c
=@R7N/e]9"wVik@"5`q,m;ͣfdv,ƀFtњuK
u<Cr{oە׶mZ-\sp7|9\)޴1_m{@W1XM,	Jk둿Jb~B3!V_ԥ2<,
= ~NW%Jݠ9N%	4H}5)-ں-s
(P/"h<peE.޴X:KJu<^өyH*%	}̘'uoR{nxO>B9Y8&C99*޴v|MWadQ"
<~=GXM%N
|5	#$E6.7%Ր"TK &Z 
A)p̋܅3-v^1\`]~r"[ؽ#OJ@MW]yh f@?M6)b /Nܤ0T'ڀI7ͅeΞW-!!³: s"|G,FD(dTbW<O]].>,݁ѕ㙄F߁~e7%潚>zRuڄ D8#672]`֐7±:BWJN(o%ś oŻʕhl&StnG`'#֐7<}~~`ɐ+ iА̥%]FaTrͰel[ld?o7b2nE
j܀8Y`@r%sӕx]_%KI7-$bCw8vi;a)"M30AbQJS Nf6i`*|	i~F4JOVHK f<W&?
/#p9?"q8DhslIWo*18`3'$g8s}ؾ1dy3v# JCց`w cXW퀈p0QX
&h6#F`1Gz2MkN{[mg\GS΃VA$#Ke	xs 85xwx";p8T\ ٙoMf;	H\n#oM~BIxbľՊ
b.Icdf`KI;2rDOaf愒=suLgt[e32L{l6J^f3N4\*
%~2O9_FĞ<P2ބ:<̘cK.]BɾQJk.f(ԹtF^K'l̜g4):d'-g̲e~9rEfVFRSJf3N0fϞ0'?{gP$V$٤(-~	Sg,U8FY$EgG#TbQ~j
}?g7 `, N?Y9yYYKXJ.S4lgԌi3}8IIIIqޑAdP9sܘkLbG1Gb,
,jEGi#^13E
|ysdrU@:~hRuD&K,&bS9GЪȬ-ejZvUH4F:a5q%\35/Y#mZF4l	ɊG\uu#Fv$-2BjylI=ѥE#i5/-eNY(nRL1g*a{p6RgM%zL.Ƞ1J:O(SZ-J12HrΕ&E^KQ3&8FQ$iQ|Jc1Kx1ǢiaeѤZr2Qc$yE*=ĘML)+}!vL*GQtF/)mtDf;ö6ӬlӌlYBL:f3Q)#EOXGlŕ3Ӡ3FJIX$&a,+EαW5BIiDJvTLӼ+FrdF(iɎ28*&&`dqQ-xe3jȠ λ2[(!5aEO3f*.+Vi;lhZdT=QLj:$67&s+-
zu15~!g3欭<'f+WR3W3䜥k1f^cqe5\RV̫ɹKFrWJ-̫d+yf>̵,,,+k$9h+ZkjJjMY5䪫-.ZkJJK9s)WVy+le5kY[<gYqYѸJnV3yjRf%̱bH]]aaqi]Yma]aؚm(f.cJ&-99RWZYW֖笙˘je\e%_HI/̩hz*kquܺJVn\U̫feU5IyjΚ9UJj򖜼ҲҒqe%_Yͼf5'(+fNKmV\V̷R3ߪ̥jhYgNeEKͼ*+9U=[XUVRU}u5WV3Q'99JΚyUr1u̵f>c)f.55Z/f^ckʪjsy-ϰR<Kܺ95--e<Z\/f~ue5K,%%ϼjRg̥.*3RvY<kJ9sZ*Kk[V̫fs^6洹Ǥbd>bZɛϥY|.m'),:/xJy-%K9Sk9FP蒛̯gP^PiP;ʠd(&Tw0"֖ҊkIeLZSSWfϴM
e儊̀lN`2 ĿbbO=
Q ?.泌'd.fd_ߚcH]i-kL)xq3g6Exsi72kKTFf:N32n;R/h}.^6Kk*ŏR+FQs6ON+hRő9ƌ#J&b$JO<IKiXRRәYtWE
&sESP(sR4-f@YA1u+[ʮZRj%Z)O-YW4QS7˘caQfXT0Y6#6z6ɞf26"]r::}).\$}!"/39_-r	KԬLl	}2ǖ܇\_;Ți\yZ:}<Ψs9&"N(N-gacΧ\1m}.y@b`1ҫ\FϘfͰ4K1&T$>a_r}.P~E>蒓AO0cFʖQ2ʗ_β(s3\6K(6	Д6X8̀>EcPX1Z>V1Thc'g;KǊP`5+"X|,>9