Subject: [PATCH 2/2] - Expose line number from known_hosts file for better error reporting

[PATCH 2/2] - Expose line number from known_hosts file for better error reporting

From: Fritz Elfert <fritz_at_fritz-elfert.de>
Date: Fri, 23 Dec 2011 05:11:50 +0100

Hi guys. me again ;)

Here's a patch to expose the line number from reading the known_hosts file.
With this applied, you now can write something like this (like openssh):

int check = libssh2_knownhost_checkp(...., &host);
switch (check) {
    case LIBSSH2_KNOWNHOST_CHECK_MISMATCH:
        ...
              fprintf(stderr, "Offending key in %s:%d\n", knownhostsfilename, host.linenr + 1);
        ...
}

Background:
Im the maintainer of OpenNX (an OSS GUI frontend for nxssh, which is based on openssh) and
currently trying to write a stripped-down replacement for nxssh using libssh2 - mainly
because libssh2's excellent portability. My GUI uses pipes to communicate with the
underlying ssh and if some key mismatch happens, it offers a dialog where the user has
the option to delete the offending line from the known_hosts file. In order to accomplish
that, my GUI needs the line number from the error message...

Cheers
 -Fritz

---
 include/libssh2.h |    3 ++-
 src/knownhost.c   |   29 ++++++++++++++++-------------
 2 files changed, 18 insertions(+), 14 deletions(-)
diff --git a/include/libssh2.h b/include/libssh2.h
index 3395e6a..2aa1830 100644
--- a/include/libssh2.h
+++ b/include/libssh2.h
@@ -807,6 +807,7 @@ struct libssh2_knownhost {
     char *name; /* this is NULL if no plain text host name exists */
     char *key;  /* key in base64/printable format */
     int typemask;
+    int linenr; /* zero-based line number, if read from known_hosts file, -1 otherwise */
 };
  /*
@@ -969,7 +970,7 @@ libssh2_knownhost_free(LIBSSH2_KNOWNHOSTS *hosts);
  */
 LIBSSH2_API int
 libssh2_knownhost_readline(LIBSSH2_KNOWNHOSTS *hosts,
-                           const char *line, size_t len, int type);
+                           const char *line, size_t len, int type, int linenr);
  /*
  * libssh2_knownhost_readfile
diff --git a/src/knownhost.c b/src/knownhost.c
index 193bda3..3952345 100644
--- a/src/knownhost.c
+++ b/src/knownhost.c
@@ -54,6 +54,7 @@ struct known_host {
      /* this is the struct we expose externally */
     struct libssh2_knownhost external;
+    int linenr;      /* line number in known_hosts file */
 };
  struct _LIBSSH2_KNOWNHOSTS
@@ -120,6 +121,7 @@ static struct libssh2_knownhost *knownhost_to_external(struct known_host *node)
                  LIBSSH2_KNOWNHOST_TYPE_PLAIN)? node->name:NULL;
     ext->key = node->key;
     ext->typemask = node->typemask;
+    ext->linenr = node->linenr;
      return ext;
 }
@@ -129,7 +131,7 @@ knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
               const char *host, const char *salt,
               const char *key, size_t keylen,
               const char *comment, size_t commentlen,
-              int typemask, struct libssh2_knownhost **store)
+              int typemask, struct libssh2_knownhost **store, int linenr)
 {
     struct known_host *entry;
     size_t hostlen = strlen(host);
@@ -225,6 +227,7 @@ knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
     }
      /* add this new host to the big list of known hosts */
+    entry->linenr = linenr;
     _libssh2_list_add(&hosts->head, &entry->node);
      if(store)
@@ -265,7 +268,7 @@ libssh2_knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
                       int typemask, struct libssh2_knownhost **store)
 {
     return knownhost_add(hosts, host, salt, key, keylen, NULL, 0, typemask,
-                         store);
+                         store, -1);
 }
  @@ -304,7 +307,7 @@ libssh2_knownhost_addc(LIBSSH2_KNOWNHOSTS *hosts,
                        int typemask, struct libssh2_knownhost **store)
 {
     return knownhost_add(hosts, host, salt, key, keylen, comment, commentlen,
-                         typemask, store);
+                         typemask, store, 1);
 }
  /*
@@ -574,7 +577,7 @@ libssh2_knownhost_free(LIBSSH2_KNOWNHOSTS *hosts)
 static int oldstyle_hostline(LIBSSH2_KNOWNHOSTS *hosts,
                              const char *host, size_t hostlen,
                              const char *key, size_t keylen, int key_type,
-                             const char *comment, size_t commentlen)
+                             const char *comment, size_t commentlen, int linenr)
 {
     int rc = 0;
     size_t namelen = 0;
@@ -610,7 +613,7 @@ static int oldstyle_hostline(LIBSSH2_KNOWNHOSTS *hosts,
             rc = knownhost_add(hosts, hostbuf, NULL, key, keylen,
                                comment, commentlen,
                                key_type | LIBSSH2_KNOWNHOST_TYPE_PLAIN |
-                               LIBSSH2_KNOWNHOST_KEYENC_BASE64, NULL);
+                               LIBSSH2_KNOWNHOST_KEYENC_BASE64, NULL, linenr);
             if(rc)
                 return rc;
 @@ -628,7 +631,7 @@ static int oldstyle_hostline(LIBSSH2_KNOWNHOSTS *hosts,
 static int hashed_hostline(LIBSSH2_KNOWNHOSTS *hosts,
                            const char *host, size_t hostlen,
                            const char *key, size_t keylen, int key_type,
-                           const char *comment, size_t commentlen)
+                           const char *comment, size_t commentlen, int linenr)
 {
     const char *p;
     char saltbuf[32];
@@ -673,7 +676,7 @@ static int hashed_hostline(LIBSSH2_KNOWNHOSTS *hosts,
         return knownhost_add(hosts, hostbuf, salt, key, keylen, comment,
                              commentlen,
                              key_type | LIBSSH2_KNOWNHOST_TYPE_SHA1 |
-                             LIBSSH2_KNOWNHOST_KEYENC_BASE64, NULL);
+                             LIBSSH2_KNOWNHOST_KEYENC_BASE64, NULL, linenr);
     }
     else
         return 0; /* XXX: This should be an error, shouldn't it? */
@@ -691,7 +694,7 @@ static int hashed_hostline(LIBSSH2_KNOWNHOSTS *hosts,
  */
 static int hostline(LIBSSH2_KNOWNHOSTS *hosts,
                     const char *host, size_t hostlen,
-                    const char *key, size_t keylen)
+                    const char *key, size_t keylen, int linenr)
 {
     const char *comment = NULL;
     size_t commentlen = 0;
@@ -775,12 +778,12 @@ static int hostline(LIBSSH2_KNOWNHOSTS *hosts,
            same key
         */
         return oldstyle_hostline(hosts, host, hostlen, key, keylen, key_type,
-                                 comment, commentlen);
+                                 comment, commentlen, linenr);
     }
     else {
         /* |1|[salt]|[hash] */
         return hashed_hostline(hosts, host, hostlen, key, keylen, key_type,
-                               comment, commentlen);
+                               comment, commentlen, linenr);
     }
 }
 @@ -814,7 +817,7 @@ static int hostline(LIBSSH2_KNOWNHOSTS *hosts,
  */
 LIBSSH2_API int
 libssh2_knownhost_readline(LIBSSH2_KNOWNHOSTS *hosts,
-                           const char *line, size_t len, int type)
+                           const char *line, size_t len, int type, int linenr)
 {
     const char *cp;
     const char *hostp;
@@ -877,7 +880,7 @@ libssh2_knownhost_readline(LIBSSH2_KNOWNHOSTS *hosts,
         keylen--; /* don't include this in the count */
      /* deal with this one host+key line */
-    rc = hostline(hosts, hostp, hostlen, keyp, keylen);
+    rc = hostline(hosts, hostp, hostlen, keyp, keylen, linenr);
     if(rc)
         return rc; /* failed */
 @@ -910,7 +913,7 @@ libssh2_knownhost_readfile(LIBSSH2_KNOWNHOSTS *hosts,
     file = fopen(filename, "r");
     if(file) {
         while(fgets(buf, sizeof(buf), file)) {
-            if(libssh2_knownhost_readline(hosts, buf, strlen(buf), type))
+            if(libssh2_knownhost_readline(hosts, buf, strlen(buf), type, num))
                 break;
             num++;
         }
-- 
1.7.6.4
_______________________________________________
libssh2-devel http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel
Received on 2011-12-23