On Tue, 25 Oct 2011, Jernej Kovacic wrote:

Now I have modified the function to call _libssh2_error(), converted tabs to spaces (hopefully none have remained) and reverted the changes in comp.c. I have also added a few important lines into the doc. file to ensure that the function will be used properly when "asked" for compression methods.

This is better but I still wish you'd pay more attention to: trailing white space, source code style and line lengths. You also modified some unrelated lines.

See the attachment here for my edited version showing my points. I'll commit this within shortly and then we can continue polishing it based on what we have in git.

I only have one comment left here: 'char ***arg' is a really unfortunate argument type. I bet that will scare weak-hearted users really good. The least we can do is to offer an example in the man page showing how to use it...

--

 / daniel.haxx.se
From f4e5ca2f1444f9db50886640ac03e7825d5a5f2e Mon Sep 17 00:00:00 2001
From: Jernej Kovacic <jkova...@gmail.com>
Date: Tue, 25 Oct 2011 23:50:44 +0200
Subject: [PATCH] libssh2_session_supported_algs: added

---
 docs/Makefile.am                      |    1 +
 docs/libssh2_session_supported_algs.3 |   48 ++++++++++++++
 include/libssh2.h                     |   16 +++++-
 src/kex.c                             |  110 +++++++++++++++++++++++++++++++++
 4 files changed, 174 insertions(+), 1 deletions(-)
 create mode 100644 docs/libssh2_session_supported_algs.3

diff --git a/docs/Makefile.am b/docs/Makefile.am
index bcd9faa..58dc6c8 100644
--- a/docs/Makefile.am
+++ b/docs/Makefile.am
@@ -112,6 +112,7 @@ dist_man_MANS = \
 	libssh2_session_set_blocking.3 \
 	libssh2_session_set_timeout.3 \
 	libssh2_session_startup.3 \
+	libssh2_session_supported_algs.3 \
 	libssh2_sftp_close.3 \
 	libssh2_sftp_close_handle.3 \
 	libssh2_sftp_closedir.3 \
diff --git a/docs/libssh2_session_supported_algs.3 b/docs/libssh2_session_supported_algs.3
new file mode 100644
index 0000000..ec54246
--- /dev/null
+++ b/docs/libssh2_session_supported_algs.3
@@ -0,0 +1,48 @@
+.TH libssh2_session_supported_algs 3 "23 Oct 2011" "libssh2 1.3.1" "libssh2 manual"
+.SH NAME
+libssh2_session_supported_algs - get list of supported algorithms
+.SH SYNOPSIS
+.nf
+#include <libssh2.h>
+
+int libssh2_session_supported_algs(LIBSSH2_SESSION* session,
+                                   int method_type,
+                                   const char*** algs);
+.SH DESCRIPTION
+\fIsession\fP - An instance of initialized LIBSSH2_SESSION (the function will
+use its pointer to the memory allocation function).  \fImethod_type\fP - Method
+type. See .BR \fIlibssh2_session_method_pref(3)\fP.  \fIalgs\fP - Address of a
+pointer that will point to an array af returned algorithms
+
+Get a list of supported algorithms for the given \fImethod_type\fP. The
+method_type parameter is equivalent to method_type in
+\fIlibssh2_session_method_pref(3)\fP. If successful, the function will
+allocate the appropriate amount of memory. When not needed anymore, it must be
+deallocated by calling \fIlibssh2_free(3)\fP. When this function is
+unsuccessful, this must not be done.
+
+In order to get a list of all supported compression algorithms,
+libssh2_session_flag(session, LIBSSH2_FLAG_COMPRESS, 1) must be called before
+calling this function, otherwise only "none" will be returned.
+
+If successful, the function will allocate and fill the array with supported
+algorithms (the same names as defined in RFC 4253).  The array is not NULL
+terminated.
+.SH RETURN VALUE
+On success, a number of returned algorithms (i.e a positive number will be
+returned).  In case of a failure, an error code (a negative number, see below)
+is returned.  0 should never be returned.
+.SH ERRORS
+\fILIBSSH2_ERROR_BAD_USE\fP - Invalid address of algs.
+
+\fILIBSSH2_ERROR_METHOD_NOT_SUPPORTED\fP -  Unknown method type.
+
+\fILIBSSH2_ERROR_INVAL\fP - Internal error (normally should not occur).
+
+\fILIBSSH2_ERROR_ALLOC\fP - Allocation of memory failed.
+.SH AVAILABILITY
+Added in 1.3.1
+.SH SEE ALSO
+.BR libssh2_session_methods(3),
+.BR libssh2_session_method_pref(3)
+.BR libssh2_free(3)
diff --git a/include/libssh2.h b/include/libssh2.h
index 8dc547c..65182cf 100644
--- a/include/libssh2.h
+++ b/include/libssh2.h
@@ -441,6 +441,20 @@ LIBSSH2_API void libssh2_exit(void);
  */
 LIBSSH2_API void libssh2_free(LIBSSH2_SESSION *session, void *ptr);
 
+/*
+ * libssh2_session_supported_algs()
+ *
+ * Fills algs with a list of supported acryptographic algorithms. Returns a
+ * non-negative number (number of supported algorithms) on success or a
+ * negative number (an eror code) on failure.
+ *
+ * NOTE: on success, algs must be deallocated (by calling libssh2_free) when
+ * not needed anymore
+ */
+LIBSSH2_API int libssh2_session_supported_algs(LIBSSH2_SESSION* session,
+                                               int method_type,
+                                               const char*** algs);
+
 /* Session API */
 LIBSSH2_API LIBSSH2_SESSION *
 libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC((*my_alloc)),
@@ -1027,7 +1041,7 @@ libssh2_knownhost_get(LIBSSH2_KNOWNHOSTS *hosts,
 
 struct libssh2_agent_publickey {
     unsigned int magic;              /* magic stored by the library */
-    void *node;	    /* handle to the internal representation of key */
+    void *node;     /* handle to the internal representation of key */
     unsigned char *blob;           /* public key blob */
     size_t blob_len;               /* length of the public key blob */
     char *comment;                 /* comment in printable format */
diff --git a/src/kex.c b/src/kex.c
index d26b5f3..6d2e31e 100644
--- a/src/kex.c
+++ b/src/kex.c
@@ -1896,3 +1896,113 @@ libssh2_session_method_pref(LIBSSH2_SESSION * session, int method_type,
     return 0;
 }
 
+/*
+ * libssh2_session_supported_algs()
+ * returns a number of returned algorithms (a positive number) on success,
+ * a negative number on failure
+ */
+
+LIBSSH2_API int libssh2_session_supported_algs(LIBSSH2_SESSION* session,
+                                               int method_type,
+                                               const char*** algs)
+{
+    unsigned int i;
+    unsigned int j;
+    unsigned int ialg;
+    const LIBSSH2_COMMON_METHOD **mlist;
+
+    /* to prevent coredumps due to dereferencing of NULL */
+    if (NULL == algs)
+        return _libssh2_error(session, LIBSSH2_ERROR_BAD_USE,
+                              "algs must not be NULL");
+
+    switch (method_type) {
+    case LIBSSH2_METHOD_KEX:
+        mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_kex_methods;
+        break;
+
+    case LIBSSH2_METHOD_HOSTKEY:
+        mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_hostkey_methods();
+        break;
+
+    case LIBSSH2_METHOD_CRYPT_CS:
+    case LIBSSH2_METHOD_CRYPT_SC:
+        mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_crypt_methods();
+        break;
+
+    case LIBSSH2_METHOD_MAC_CS:
+    case LIBSSH2_METHOD_MAC_SC:
+        mlist = (const LIBSSH2_COMMON_METHOD **) _libssh2_mac_methods();
+        break;
+
+    case LIBSSH2_METHOD_COMP_CS:
+    case LIBSSH2_METHOD_COMP_SC:
+        mlist = (const LIBSSH2_COMMON_METHOD **) _libssh2_comp_methods(session);
+        break;
+
+    default:
+        return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
+                              "Unknown method type");
+    }  /* switch */
+
+    /* weird situation */
+    if (NULL==mlist)
+        return _libssh2_error(session, LIBSSH2_ERROR_INVAL,
+                              "No algorithm found");
+
+    /*
+      mlist is looped through twice. The first time to find the number od
+      supported algorithms (needed to allocate the proper size of array) and
+      the second time to actually copy the pointers.  Typically this function
+      will not be called often (typically at the beginning of a session) and
+      the number of algorithms (i.e. niumber of iterations in one loop) will
+      not be high (typically it will not exceed 20) for quite a long time.
+
+      So double looping really shouldn't be an issue and it is definitely a
+      better solution than reallocation several times.
+    */
+
+    /* count the number of supported algorithms */
+    for ( i=0, ialg=0; NULL!=mlist[i]; i++) {
+        /* do not count fields with NULL name */
+        if (mlist[i]->name)
+            ialg++;
+    }
+
+    /* weird situation, no algorithm found */
+    if (0==ialg)
+        return _libssh2_error(session, LIBSSH2_ERROR_INVAL,
+                              "No algorithm found");
+
+    /* allocate buffer */
+    *algs = (const char**) LIBSSH2_ALLOC(session, ialg*sizeof(const char*));
+    if ( NULL==*algs ) {
+        return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
+                              "Memory allocation failed");
+    }
+    /* Past this point *algs must be deallocated in case of an error!! */
+
+    /* copy non-NULL pointers only */
+    for ( i=0, j=0; NULL!=mlist[i] && j<ialg; i++ ) {
+        if ( NULL==mlist[i]->name ){
+            /* maybe a weird situation but if it occurs, do not include NULL
+               pointers */
+            continue;
+        }
+
+        /* note that [] has higher priority than * (dereferencing) */
+        (*algs)[j++] = mlist[i]->name;
+    }
+
+    /* correct number of pointers copied? (test the code above) */
+    if ( j!=ialg ) {
+        /* deallocate buffer */
+        LIBSSH2_FREE(session, *algs);
+        *algs = NULL;
+
+        return _libssh2_error(session, LIBSSH2_ERROR_BAD_USE,
+                              "Internal error");
+    }
+
+    return ialg;
+}
-- 
1.7.7

_______________________________________________
libssh2-devel http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel

Reply via email to