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 224c6aa80..4d0823209 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[] =
@@ -754,3 +755,140 @@ key_in_file(Key *key, const char *filename, int strict_type)
754 return ret; 755 return ret;
755} 756}
756 757
758/* Scan a blacklist of known-vulnerable keys in blacklist_file. */
759static int
760blacklisted_key_in_file(const Key *key, const char *blacklist_file, char **fp)
761{
762 int fd = -1;
763 char *dgst_hex = NULL;
764 char *dgst_packed = NULL, *p;
765 int i;
766 size_t line_len;
767 struct stat st;
768 char buf[256];
769 off_t start, lower, upper;
770 int ret = 0;
771
772 debug("Checking blacklist file %s", blacklist_file);
773 fd = open(blacklist_file, O_RDONLY);
774 if (fd < 0) {
775 ret = -1;
776 goto out;
777 }
778
779 dgst_hex = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
780 /* Remove all colons */
781 dgst_packed = xcalloc(1, strlen(dgst_hex) + 1);
782 for (i = 0, p = dgst_packed; dgst_hex[i]; i++)
783 if (dgst_hex[i] != ':')
784 *p++ = dgst_hex[i];
785 /* Only compare least-significant 80 bits (to keep the blacklist
786 * size down)
787 */
788 line_len = strlen(dgst_packed + 12);
789 if (line_len > 32)
790 goto out;
791
792 /* Skip leading comments */
793 start = 0;
794 for (;;) {
795 ssize_t r;
796 char *newline;
797
798 r = atomicio(read, fd, buf, sizeof(buf));
799 if (r <= 0)
800 goto out;
801 if (buf[0] != '#')
802 break;
803
804 newline = memchr(buf, '\n', sizeof(buf));
805 if (!newline)
806 goto out;
807 start += newline + 1 - buf;
808 if (lseek(fd, start, SEEK_SET) < 0)
809 goto out;
810 }
811
812 /* Initialise binary search record numbers */
813 if (fstat(fd, &st) < 0)
814 goto out;
815 lower = 0;
816 upper = (st.st_size - start) / (line_len + 1);
817
818 while (lower != upper) {
819 off_t cur;
820 int cmp;
821
822 cur = lower + (upper - lower) / 2;
823
824 /* Read this line and compare to digest; this is
825 * overflow-safe since cur < max(off_t) / (line_len + 1) */
826 if (lseek(fd, start + cur * (line_len + 1), SEEK_SET) < 0)
827 break;
828 if (atomicio(read, fd, buf, line_len) != line_len)
829 break;
830 cmp = memcmp(buf, dgst_packed + 12, line_len);
831 if (cmp < 0) {
832 if (cur == lower)
833 break;
834 lower = cur;
835 } else if (cmp > 0) {
836 if (cur == upper)
837 break;
838 upper = cur;
839 } else {
840 debug("Found %s in blacklist", dgst_hex);
841 ret = 1;
842 break;
843 }
844 }
845
846out:
847 if (dgst_packed)
848 xfree(dgst_packed);
849 if (ret != 1 && dgst_hex) {
850 xfree(dgst_hex);
851 dgst_hex = NULL;
852 }
853 if (fp)
854 *fp = dgst_hex;
855 if (fd >= 0)
856 close(fd);
857 return ret;
858}
859
860/*
861 * Scan blacklists of known-vulnerable keys. If a vulnerable key is found,
862 * its fingerprint is returned in *fp, unless fp is NULL.
863 */
864int
865blacklisted_key(const Key *key, char **fp)
866{
867 Key *public;
868 char *blacklist_file;
869 int ret, ret2;
870
871 public = key_demote(key);
872 if (public->type == KEY_RSA1)
873 public->type = KEY_RSA;
874
875 xasprintf(&blacklist_file, "%s.%s-%u",
876 _PATH_BLACKLIST, key_type(public), key_size(public));
877 ret = blacklisted_key_in_file(public, blacklist_file, fp);
878 xfree(blacklist_file);
879 if (ret > 0) {
880 key_free(public);
881 return ret;
882 }
883
884 xasprintf(&blacklist_file, "%s.%s-%u",
885 _PATH_BLACKLIST_CONFIG, key_type(public), key_size(public));
886 ret2 = blacklisted_key_in_file(public, blacklist_file, fp);
887 xfree(blacklist_file);
888 if (ret2 > ret)
889 ret = ret2;
890
891 key_free(public);
892 return ret;
893}
894