summaryrefslogtreecommitdiff
path: root/authfile.c
diff options
context:
space:
mode:
Diffstat (limited to 'authfile.c')
-rw-r--r--authfile.c138
1 files changed, 138 insertions, 0 deletions
diff --git a/authfile.c b/authfile.c
index 2bd887845..deac28f6a 100644
--- a/authfile.c
+++ b/authfile.c
@@ -68,6 +68,7 @@
68#include "rsa.h" 68#include "rsa.h"
69#include "misc.h" 69#include "misc.h"
70#include "atomicio.h" 70#include "atomicio.h"
71#include "pathnames.h"
71 72
72/* Version identification string for SSH v1 identity files. */ 73/* Version identification string for SSH v1 identity files. */
73static const char authfile_id_string[] = 74static const char authfile_id_string[] =
@@ -814,3 +815,140 @@ key_in_file(Key *key, const char *filename, int strict_type)
814 return ret; 815 return ret;
815} 816}
816 817
818/* Scan a blacklist of known-vulnerable keys in blacklist_file. */
819static int
820blacklisted_key_in_file(const Key *key, const char *blacklist_file, char **fp)
821{
822 int fd = -1;
823 char *dgst_hex = NULL;
824 char *dgst_packed = NULL, *p;
825 int i;
826 size_t line_len;
827 struct stat st;
828 char buf[256];
829 off_t start, lower, upper;
830 int ret = 0;
831
832 debug("Checking blacklist file %s", blacklist_file);
833 fd = open(blacklist_file, O_RDONLY);
834 if (fd < 0) {
835 ret = -1;
836 goto out;
837 }
838
839 dgst_hex = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
840 /* Remove all colons */
841 dgst_packed = xcalloc(1, strlen(dgst_hex) + 1);
842 for (i = 0, p = dgst_packed; dgst_hex[i]; i++)
843 if (dgst_hex[i] != ':')
844 *p++ = dgst_hex[i];
845 /* Only compare least-significant 80 bits (to keep the blacklist
846 * size down)
847 */
848 line_len = strlen(dgst_packed + 12);
849 if (line_len > 32)
850 goto out;
851
852 /* Skip leading comments */
853 start = 0;
854 for (;;) {
855 ssize_t r;
856 char *newline;
857
858 r = atomicio(read, fd, buf, sizeof(buf));
859 if (r <= 0)
860 goto out;
861 if (buf[0] != '#')
862 break;
863
864 newline = memchr(buf, '\n', sizeof(buf));
865 if (!newline)
866 goto out;
867 start += newline + 1 - buf;
868 if (lseek(fd, start, SEEK_SET) < 0)
869 goto out;
870 }
871
872 /* Initialise binary search record numbers */
873 if (fstat(fd, &st) < 0)
874 goto out;
875 lower = 0;
876 upper = (st.st_size - start) / (line_len + 1);
877
878 while (lower != upper) {
879 off_t cur;
880 int cmp;
881
882 cur = lower + (upper - lower) / 2;
883
884 /* Read this line and compare to digest; this is
885 * overflow-safe since cur < max(off_t) / (line_len + 1) */
886 if (lseek(fd, start + cur * (line_len + 1), SEEK_SET) < 0)
887 break;
888 if (atomicio(read, fd, buf, line_len) != line_len)
889 break;
890 cmp = memcmp(buf, dgst_packed + 12, line_len);
891 if (cmp < 0) {
892 if (cur == lower)
893 break;
894 lower = cur;
895 } else if (cmp > 0) {
896 if (cur == upper)
897 break;
898 upper = cur;
899 } else {
900 debug("Found %s in blacklist", dgst_hex);
901 ret = 1;
902 break;
903 }
904 }
905
906out:
907 if (dgst_packed)
908 xfree(dgst_packed);
909 if (ret != 1 && dgst_hex) {
910 xfree(dgst_hex);
911 dgst_hex = NULL;
912 }
913 if (fp)
914 *fp = dgst_hex;
915 if (fd >= 0)
916 close(fd);
917 return ret;
918}
919
920/*
921 * Scan blacklists of known-vulnerable keys. If a vulnerable key is found,
922 * its fingerprint is returned in *fp, unless fp is NULL.
923 */
924int
925blacklisted_key(const Key *key, char **fp)
926{
927 Key *public;
928 char *blacklist_file;
929 int ret, ret2;
930
931 public = key_demote(key);
932 if (public->type == KEY_RSA1)
933 public->type = KEY_RSA;
934
935 xasprintf(&blacklist_file, "%s.%s-%u",
936 _PATH_BLACKLIST, key_type(public), key_size(public));
937 ret = blacklisted_key_in_file(public, blacklist_file, fp);
938 xfree(blacklist_file);
939 if (ret > 0) {
940 key_free(public);
941 return ret;
942 }
943
944 xasprintf(&blacklist_file, "%s.%s-%u",
945 _PATH_BLACKLIST_CONFIG, key_type(public), key_size(public));
946 ret2 = blacklisted_key_in_file(public, blacklist_file, fp);
947 xfree(blacklist_file);
948 if (ret2 > ret)
949 ret = ret2;
950
951 key_free(public);
952 return ret;
953}
954