From libssh2-devel-bounces@cool.haxx.se  Tue Sep  2 01:07:19 2014
Return-Path: <libssh2-devel-bounces@cool.haxx.se>
Received: from www.haxx.se (localhost.localdomain [127.0.0.1])
	by giant.haxx.se (8.14.4/8.14.4/Debian-7) with ESMTP id s81N6kmi027765;
	Tue, 2 Sep 2014 01:07:13 +0200
Received: from mail-ig0-x234.google.com (mail-ig0-x234.google.com
 [IPv6:2607:f8b0:4001:c05::234])
 by giant.haxx.se (8.14.4/8.14.4/Debian-7) with ESMTP id s81N6h8X027749
 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-RC4-SHA bits=128 verify=NOT)
 for <libssh2-devel@cool.haxx.se>; Tue, 2 Sep 2014 01:06:44 +0200
Received: by mail-ig0-f180.google.com with SMTP id hn18so6356118igb.13
 for <libssh2-devel@cool.haxx.se>; Mon, 01 Sep 2014 16:06:39 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113;
 h=mime-version:from:date:message-id:subject:to:content-type;
 bh=8MLhgZTX/QphCqpy+ooRBV0AeJlZ+KpM4YElD6KUPYY=;
 b=UhddH5HxJkFAtICKqUHWR+WJXH5Jhb7M3YDVtQXP2ihnGjurNmSaCLIuoS4dkbHXuE
 +WsbUyrJi3w7N9l+k7PnydCjysvru1s6EnDH0GLWYcgolxPuXDSz5twhxQQhSX2m90j0
 q7S3PM0XbDlyEWRNnWxy6/qwn69nBaF/Vnih/ns7jzX6ZonO9vQ9gJbbAV80A1yT52EQ
 VllKLlEmz8YvARgdcFGDvCD7aEk8jHsGwk4pfuzdh3XYQJWgkzox1pjgfaNCHDTIxVSF
 vsAM/nOIeHzzM/GtfRzYEiEgnzNujvyDhmuXY4HNsJvFiH1RA/LbZukR9+BoZkmIiZCD
 LgeQ==
X-Received: by 10.42.82.6 with SMTP id b6mr9077591icl.51.1409612799517; Mon,
 01 Sep 2014 16:06:39 -0700 (PDT)
MIME-Version: 1.0
Received: by 10.107.33.75 with HTTP; Mon, 1 Sep 2014 16:06:19 -0700 (PDT)
From: David Calavera <david.calavera@gmail.com>
Date: Mon, 1 Sep 2014 16:06:19 -0700
Message-ID: <CAH7nXcu2pM_WhPtVqPa5Vz8tqS_0sSQPGYR0bZ8kCS_bD+13wA@mail.gmail.com>
Subject: Allow authentication to be passed in memory - blast from the past
To: libssh2-devel@cool.haxx.se
X-BeenThere: libssh2-devel@cool.haxx.se
X-Mailman-Version: 2.1.16
Precedence: list
Reply-To: libssh2 development <libssh2-devel@cool.haxx.se>
List-Id: libssh2 development <libssh2-devel.cool.haxx.se>
List-Unsubscribe: <http://cool.haxx.se/cgi-bin/mailman/options/libssh2-devel>, 
 <mailto:libssh2-devel-request@cool.haxx.se?subject=unsubscribe>
List-Archive: <http://cool.haxx.se/pipermail/libssh2-devel/>
List-Post: <mailto:libssh2-devel@cool.haxx.se>
List-Help: <mailto:libssh2-devel-request@cool.haxx.se?subject=help>
List-Subscribe: <http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel>, 
 <mailto:libssh2-devel-request@cool.haxx.se?subject=subscribe>
Content-Type: multipart/mixed; boundary="===============0718648816=="
Errors-To: libssh2-devel-bounces@cool.haxx.se
Sender: "libssh2-devel" <libssh2-devel-bounces@cool.haxx.se>

--===============0718648816==
Content-Type: multipart/alternative; boundary=485b397dd7012faab10502090ea3

--485b397dd7012faab10502090ea3
Content-Type: text/plain; charset=UTF-8

Hi,

I was doing some digging to see how I could pass auth keys by memory when I
discovered this old thread from 2012 with a patch:

http://www.libssh2.org/mail/libssh2-devel-archive-2012-01/0015.shtml

I'm really interested in seeing this incorporated to libssh2, so I
decided to try to address the problems raised in the next message in
that thread:

http://www.libssh2.org/mail/libssh2-devel-archive-2012-01/0016.shtml

I created a new patch that addressed part those points. You can see it at:

https://github.com/calavera/libssh2/commit/d083300c69f41eff6132da3525722fc590e350cf.patch

I replaced the use of `memcpy_s` to use `memcpy`. I also formatted the code
to use less that 80 columns.

I ran `./configure --enable-debug` to try to address the warnings in the
code, but unfortunately I didn't get any. I'm not sure if I'm doing
anything wrong, I posted the output here:

https://gist.github.com/calavera/639002dd56753640721d

I'd really appreciate if anybody could point me to those warnings if there
is anything I'm missing.

As I said, I'm really interested in seeing this merged into libssh2.
Please, let me know if there is anything else I can help with to make that
possible.

Cheers,
David

--485b397dd7012faab10502090ea3
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Hi,<div><br></div><div>I was doing some digging to see how=
 I could pass auth keys by memory when I discovered this old thread from 20=
12 with a patch:</div><div><br></div><div><div><a href=3D"http://www.libssh=
2.org/mail/libssh2-devel-archive-2012-01/0015.shtml">http://www.libssh2.org=
/mail/libssh2-devel-archive-2012-01/0015.shtml</a><br>

</div><pre style=3D"color:rgb(0,0,0);word-wrap:break-word;white-space:pre-w=
rap"><span style=3D"font-family:arial;color:rgb(34,34,34)">I&#39;m really i=
nterested in seeing this incorporated to libssh2, so I decided to try to ad=
dress the problems raised in the next message in that thread:</span></pre>

</div><div><a href=3D"http://www.libssh2.org/mail/libssh2-devel-archive-201=
2-01/0016.shtml">http://www.libssh2.org/mail/libssh2-devel-archive-2012-01/=
0016.shtml</a><br></div><div><br></div><div>I created a new patch that addr=
essed part those points. You can see it at:</div>

<div><br></div><div><a href=3D"https://github.com/calavera/libssh2/commit/d=
083300c69f41eff6132da3525722fc590e350cf.patch">https://github.com/calavera/=
libssh2/commit/d083300c69f41eff6132da3525722fc590e350cf.patch</a><br></div>

<div><br></div><div>I replaced the use of `memcpy_s` to use `memcpy`. I als=
o formatted the code to use less that 80 columns.</div><div><br></div><div>=
I ran `./configure --enable-debug` to try to address the warnings in the co=
de, but unfortunately I didn&#39;t get any. I&#39;m not sure if I&#39;m doi=
ng anything wrong, I posted the output here:</div>

<div><br></div><div><a href=3D"https://gist.github.com/calavera/639002dd567=
53640721d">https://gist.github.com/calavera/639002dd56753640721d</a><br></d=
iv><div><br></div><div>I&#39;d really appreciate if anybody could point me =
to those warnings if there is anything I&#39;m missing.</div>

<div><br></div><div>As I said, I&#39;m really interested in seeing this mer=
ged into libssh2. Please, let me know if there is anything else I can help =
with to make that possible.</div><div><br></div><div>Cheers,</div><div>

David</div><div><br></div></div>

--485b397dd7012faab10502090ea3--

--===============0718648816==
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: base64
Content-Disposition: inline

X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KbGlic3NoMi1k
ZXZlbCBodHRwOi8vY29vbC5oYXh4LnNlL2NnaS1iaW4vbWFpbG1hbi9saXN0aW5mby9saWJzc2gy
LWRldmVsCg==

--===============0718648816==--

From libssh2-devel-bounces@cool.haxx.se  Tue Sep  2 05:59:36 2014
Return-Path: <libssh2-devel-bounces@cool.haxx.se>
Received: from www.haxx.se (localhost.localdomain [127.0.0.1])
	by giant.haxx.se (8.14.4/8.14.4/Debian-7) with ESMTP id s823x7g3025433;
	Tue, 2 Sep 2014 05:59:30 +0200
Received: from mail-ie0-x229.google.com (mail-ie0-x229.google.com
 [IPv6:2607:f8b0:4001:c03::229])
 by giant.haxx.se (8.14.4/8.14.4/Debian-7) with ESMTP id s823x4gH025246
 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-RC4-SHA bits=128 verify=NOT)
 for <libssh2-devel@cool.haxx.se>; Tue, 2 Sep 2014 05:59:04 +0200
Received: by mail-ie0-f169.google.com with SMTP id tr6so6988859ieb.14
 for <libssh2-devel@cool.haxx.se>; Mon, 01 Sep 2014 20:58:58 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113;
 h=mime-version:in-reply-to:references:from:date:message-id:subject:to
 :content-type; bh=O5+6JDHtDhcpjpfnWdq8J0I9fcPIQ0EJisW4i4tzq5M=;
 b=uxs4yii3nvf/DI+ze6tkKmeoN0Cic/EA1KspPrJM7Pxv6GpRjq9+K4NVlTQWBFROqW
 iEToavjouVCxU8Nd+qU2PdF21nv8Q36Lt5iCirnYKPCWawlcaxVzoDZ8SpgDKTjYCp3T
 P7VSmhlDeKQ7XC8hlaiLbyqsrkSf9m7Bhs7UmDHOhmHJHeSyG8YOnDtLHe54W4S1Qv7J
 f347+u+mZvwr9D2qApfRRUEldknDjfsJM6Ol4jGORtiCGt3P8r0T8WTyuQWTZTurzNzK
 5JUt7o2KdFV5H5zDV4fx70gmTOenjgQXvNPn9DSi211kyVpSM8EEYi1w2tH1dZTZoKQI
 zdiA==
X-Received: by 10.43.136.134 with SMTP id ik6mr29006203icc.6.1409630338222;
 Mon, 01 Sep 2014 20:58:58 -0700 (PDT)
MIME-Version: 1.0
Received: by 10.107.33.75 with HTTP; Mon, 1 Sep 2014 20:58:38 -0700 (PDT)
In-Reply-To: <CAH7nXcu2pM_WhPtVqPa5Vz8tqS_0sSQPGYR0bZ8kCS_bD+13wA@mail.gmail.com>
References: <CAH7nXcu2pM_WhPtVqPa5Vz8tqS_0sSQPGYR0bZ8kCS_bD+13wA@mail.gmail.com>
From: David Calavera <david.calavera@gmail.com>
Date: Mon, 1 Sep 2014 20:58:38 -0700
Message-ID: <CAH7nXcvbPouEsLsPSF94cgfMMpEVp1XCpgDSBhJbaWojUmvi_g@mail.gmail.com>
Subject: Re: Allow authentication to be passed in memory - blast from the past
To: libssh2-devel <libssh2-devel@cool.haxx.se>
X-BeenThere: libssh2-devel@cool.haxx.se
X-Mailman-Version: 2.1.16
Precedence: list
Reply-To: libssh2 development <libssh2-devel@cool.haxx.se>
List-Id: libssh2 development <libssh2-devel.cool.haxx.se>
List-Unsubscribe: <http://cool.haxx.se/cgi-bin/mailman/options/libssh2-devel>, 
 <mailto:libssh2-devel-request@cool.haxx.se?subject=unsubscribe>
List-Archive: <http://cool.haxx.se/pipermail/libssh2-devel/>
List-Post: <mailto:libssh2-devel@cool.haxx.se>
List-Help: <mailto:libssh2-devel-request@cool.haxx.se?subject=help>
List-Subscribe: <http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel>, 
 <mailto:libssh2-devel-request@cool.haxx.se?subject=subscribe>
Content-Type: multipart/mixed; boundary="===============0285068686=="
Errors-To: libssh2-devel-bounces@cool.haxx.se
Sender: "libssh2-devel" <libssh2-devel-bounces@cool.haxx.se>

--===============0285068686==
Content-Type: multipart/alternative; boundary=001a11c21a389313c205020d230f

--001a11c21a389313c205020d230f
Content-Type: text/plain; charset=UTF-8

I cleaned up some warnings that I detected and put together another patch:

https://github.com/calavera/libssh2/commit/2b75806bc60116af5b834508abc9bfc3a9039cb5.patch

I also created a macro for the initial prototype:

+#define libssh2_userauth_publickey_frommemory(session, username, publickey, \
+                                              privatekey, passphrase) \
+ libssh2_userauth_publickey_frommemory_ex((session), (username), \
+                                          (unsigned int)strlen(username),   \
+                                          (publickey),                      \
+                                          (unsigned int)strlen(publickey),  \
+                                          (privatekey),                     \
+                                          (unsigned int)strlen(privatekey), \
+                                          (passphrase))

I just realized that I didn't apply the changes for the documentation of
this new authentication. I'll add it shortly.

I'd really appreciate some feedback.

Cheers,
David


On Mon, Sep 1, 2014 at 4:06 PM, David Calavera <david.calavera@gmail.com>
wrote:

> Hi,
>
> I was doing some digging to see how I could pass auth keys by memory when
> I discovered this old thread from 2012 with a patch:
>
> http://www.libssh2.org/mail/libssh2-devel-archive-2012-01/0015.shtml
>
> I'm really interested in seeing this incorporated to libssh2, so I decided to try to address the problems raised in the next message in that thread:
>
> http://www.libssh2.org/mail/libssh2-devel-archive-2012-01/0016.shtml
>
> I created a new patch that addressed part those points. You can see it at:
>
>
> https://github.com/calavera/libssh2/commit/d083300c69f41eff6132da3525722fc590e350cf.patch
>
> I replaced the use of `memcpy_s` to use `memcpy`. I also formatted the
> code to use less that 80 columns.
>
> I ran `./configure --enable-debug` to try to address the warnings in the
> code, but unfortunately I didn't get any. I'm not sure if I'm doing
> anything wrong, I posted the output here:
>
> https://gist.github.com/calavera/639002dd56753640721d
>
> I'd really appreciate if anybody could point me to those warnings if there
> is anything I'm missing.
>
> As I said, I'm really interested in seeing this merged into libssh2.
> Please, let me know if there is anything else I can help with to make that
> possible.
>
> Cheers,
> David
>
>

--001a11c21a389313c205020d230f
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I cleaned up some warnings that I detected and put togethe=
r another patch:<div><br></div><div><a href=3D"https://github.com/calavera/=
libssh2/commit/2b75806bc60116af5b834508abc9bfc3a9039cb5.patch">https://gith=
ub.com/calavera/libssh2/commit/2b75806bc60116af5b834508abc9bfc3a9039cb5.pat=
ch</a><br>

</div><div><br></div><div>I also created a macro for the initial prototype:=
</div><div><br></div><div><pre style=3D"color:rgb(0,0,0);word-wrap:break-wo=
rd;white-space:pre-wrap">+#define libssh2_userauth_publickey_frommemory(ses=
sion, username, publickey, \
+                                              privatekey, passphrase) \
+ libssh2_userauth_publickey_frommemory_ex((session), (username), \
+                                          (unsigned int)strlen(username), =
  \
+                                          (publickey),                    =
  \
+                                          (unsigned int)strlen(publickey),=
  \
+                                          (privatekey),                   =
  \
+                                          (unsigned int)strlen(privatekey)=
, \
+                                          (passphrase))</pre></div><div>I =
just realized that I didn&#39;t apply the changes for the documentation of =
this new authentication. I&#39;ll add it shortly.</div><div><br></div>

<div>I&#39;d really appreciate some feedback.</div><div><br></div><div>Chee=
rs,</div><div>David</div></div><div class=3D"gmail_extra"><br><br><div clas=
s=3D"gmail_quote">On Mon, Sep 1, 2014 at 4:06 PM, David Calavera <span dir=
=3D"ltr">&lt;<a href=3D"mailto:david.calavera@gmail.com" target=3D"_blank">=
david.calavera@gmail.com</a>&gt;</span> wrote:<br>

<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr">Hi,<div><br></div><div>I wa=
s doing some digging to see how I could pass auth keys by memory when I dis=
covered this old thread from 2012 with a patch:</div>

<div><br></div><div><div><a href=3D"http://www.libssh2.org/mail/libssh2-dev=
el-archive-2012-01/0015.shtml" target=3D"_blank">http://www.libssh2.org/mai=
l/libssh2-devel-archive-2012-01/0015.shtml</a><br>
</div><pre style=3D"color:rgb(0,0,0);word-wrap:break-word;white-space:pre-w=
rap"><span style=3D"font-family:arial;color:rgb(34,34,34)">I&#39;m really i=
nterested in seeing this incorporated to libssh2, so I decided to try to ad=
dress the problems raised in the next message in that thread:</span></pre>


</div><div><a href=3D"http://www.libssh2.org/mail/libssh2-devel-archive-201=
2-01/0016.shtml" target=3D"_blank">http://www.libssh2.org/mail/libssh2-deve=
l-archive-2012-01/0016.shtml</a><br></div><div><br></div><div>I created a n=
ew patch that addressed part those points. You can see it at:</div>


<div><br></div><div><a href=3D"https://github.com/calavera/libssh2/commit/d=
083300c69f41eff6132da3525722fc590e350cf.patch" target=3D"_blank">https://gi=
thub.com/calavera/libssh2/commit/d083300c69f41eff6132da3525722fc590e350cf.p=
atch</a><br>

</div>
<div><br></div><div>I replaced the use of `memcpy_s` to use `memcpy`. I als=
o formatted the code to use less that 80 columns.</div><div><br></div><div>=
I ran `./configure --enable-debug` to try to address the warnings in the co=
de, but unfortunately I didn&#39;t get any. I&#39;m not sure if I&#39;m doi=
ng anything wrong, I posted the output here:</div>


<div><br></div><div><a href=3D"https://gist.github.com/calavera/639002dd567=
53640721d" target=3D"_blank">https://gist.github.com/calavera/639002dd56753=
640721d</a><br></div><div><br></div><div>I&#39;d really appreciate if anybo=
dy could point me to those warnings if there is anything I&#39;m missing.</=
div>


<div><br></div><div>As I said, I&#39;m really interested in seeing this mer=
ged into libssh2. Please, let me know if there is anything else I can help =
with to make that possible.</div><div><br></div><div>Cheers,</div><div>


David</div><div><br></div></div>
</blockquote></div><br></div>

--001a11c21a389313c205020d230f--

--===============0285068686==
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: base64
Content-Disposition: inline

X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KbGlic3NoMi1k
ZXZlbCBodHRwOi8vY29vbC5oYXh4LnNlL2NnaS1iaW4vbWFpbG1hbi9saXN0aW5mby9saWJzc2gy
LWRldmVsCg==

--===============0285068686==--

From libssh2-devel-bounces@cool.haxx.se  Tue Sep  2 06:48:45 2014
Return-Path: <libssh2-devel-bounces@cool.haxx.se>
Received: from www.haxx.se (localhost.localdomain [127.0.0.1])
	by giant.haxx.se (8.14.4/8.14.4/Debian-7) with ESMTP id s824mbn0029692;
	Tue, 2 Sep 2014 06:48:44 +0200
Received: from mail-ig0-x22e.google.com (mail-ig0-x22e.google.com
 [IPv6:2607:f8b0:4001:c05::22e])
 by giant.haxx.se (8.14.4/8.14.4/Debian-7) with ESMTP id s824mYtE029544
 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-RC4-SHA bits=128 verify=NOT)
 for <libssh2-devel@cool.haxx.se>; Tue, 2 Sep 2014 06:48:35 +0200
Received: by mail-ig0-f174.google.com with SMTP id a13so4403109igq.7
 for <libssh2-devel@cool.haxx.se>; Mon, 01 Sep 2014 21:48:29 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113;
 h=mime-version:in-reply-to:references:from:date:message-id:subject:to
 :content-type; bh=GxGB6Qq6fXYyBtZyiUXd+It/U24UPcfXso+N6srHDzM=;
 b=ZALqavFkuqRPVApSDhHKYjWVktP16K+eok/5OcRbwykJKZpDMuMlT36HuaN2l5aAj3
 kNEgJgt3XHz70RpRWtWZ0HN21Iwt2NzoDoQtHVKWXdPpbfwcdWg8sX6xQjyYg9PnosMe
 i5wpADMvDdNb90l+ftQOPWmM4nWWU2S53lETjcde8VyR4r86J2shJFSkiBlVbT3m5Px9
 xaRGYH6aaB43JDVjSkr6b3+KuYqi1D1tZF21AqfjzuwcqdxzGyzusj4eXvBUdlz6PXxy
 s9z1Lp4QVGKzn+VK+5Wp+OmVfvX84LGfnRVpGsmnfU3e/2MlBcc29FwXgxjLI2TIdAe3
 QuNA==
X-Received: by 10.42.107.145 with SMTP id d17mr128364icp.61.1409633309106;
 Mon, 01 Sep 2014 21:48:29 -0700 (PDT)
MIME-Version: 1.0
Received: by 10.107.33.75 with HTTP; Mon, 1 Sep 2014 21:48:08 -0700 (PDT)
In-Reply-To: <CAH7nXcvbPouEsLsPSF94cgfMMpEVp1XCpgDSBhJbaWojUmvi_g@mail.gmail.com>
References: <CAH7nXcu2pM_WhPtVqPa5Vz8tqS_0sSQPGYR0bZ8kCS_bD+13wA@mail.gmail.com>
 <CAH7nXcvbPouEsLsPSF94cgfMMpEVp1XCpgDSBhJbaWojUmvi_g@mail.gmail.com>
From: David Calavera <david.calavera@gmail.com>
Date: Mon, 1 Sep 2014 21:48:08 -0700
Message-ID: <CAH7nXcuwV=DjGFfuqUsHL0OD2WvaDyCfcoqQk7gjBY2uYMh0yg@mail.gmail.com>
Subject: Re: Allow authentication to be passed in memory - blast from the past
To: libssh2-devel <libssh2-devel@cool.haxx.se>
X-BeenThere: libssh2-devel@cool.haxx.se
X-Mailman-Version: 2.1.16
Precedence: list
Reply-To: libssh2 development <libssh2-devel@cool.haxx.se>
List-Id: libssh2 development <libssh2-devel.cool.haxx.se>
List-Unsubscribe: <http://cool.haxx.se/cgi-bin/mailman/options/libssh2-devel>, 
 <mailto:libssh2-devel-request@cool.haxx.se?subject=unsubscribe>
List-Archive: <http://cool.haxx.se/pipermail/libssh2-devel/>
List-Post: <mailto:libssh2-devel@cool.haxx.se>
List-Help: <mailto:libssh2-devel-request@cool.haxx.se?subject=help>
List-Subscribe: <http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel>, 
 <mailto:libssh2-devel-request@cool.haxx.se?subject=subscribe>
Content-Type: multipart/mixed; boundary="===============1858913812=="
Errors-To: libssh2-devel-bounces@cool.haxx.se
Sender: "libssh2-devel" <libssh2-devel-bounces@cool.haxx.se>

--===============1858913812==
Content-Type: multipart/alternative; boundary=20cf301fb60da7281d05020dd4e0

--20cf301fb60da7281d05020dd4e0
Content-Type: text/plain; charset=UTF-8

I added the documentation back, extending it to the macro.

I've also fixed the reference to the initPEMFromMemory functions that
weren't being assigned. This is the full patch:

https://github.com/calavera/libssh2/commit/2b75806bc60116af5b834508abc9bfc3a9039cb5.patch


On Mon, Sep 1, 2014 at 8:58 PM, David Calavera <david.calavera@gmail.com>
wrote:

> I cleaned up some warnings that I detected and put together another patch:
>
>
> https://github.com/calavera/libssh2/commit/2b75806bc60116af5b834508abc9bfc3a9039cb5.patch
>
> I also created a macro for the initial prototype:
>
> +#define libssh2_userauth_publickey_frommemory(session, username, publickey, \
> +                                              privatekey, passphrase) \
> + libssh2_userauth_publickey_frommemory_ex((session), (username), \
> +                                          (unsigned int)strlen(username),   \
> +                                          (publickey),                      \
> +                                          (unsigned int)strlen(publickey),  \
> +                                          (privatekey),                     \
> +                                          (unsigned int)strlen(privatekey), \
> +                                          (passphrase))
>
> I just realized that I didn't apply the changes for the documentation of
> this new authentication. I'll add it shortly.
>
> I'd really appreciate some feedback.
>
> Cheers,
> David
>
>
> On Mon, Sep 1, 2014 at 4:06 PM, David Calavera <david.calavera@gmail.com>
> wrote:
>
>> Hi,
>>
>> I was doing some digging to see how I could pass auth keys by memory when
>> I discovered this old thread from 2012 with a patch:
>>
>> http://www.libssh2.org/mail/libssh2-devel-archive-2012-01/0015.shtml
>>
>> I'm really interested in seeing this incorporated to libssh2, so I decided to try to address the problems raised in the next message in that thread:
>>
>> http://www.libssh2.org/mail/libssh2-devel-archive-2012-01/0016.shtml
>>
>> I created a new patch that addressed part those points. You can see it at:
>>
>>
>> https://github.com/calavera/libssh2/commit/d083300c69f41eff6132da3525722fc590e350cf.patch
>>
>> I replaced the use of `memcpy_s` to use `memcpy`. I also formatted the
>> code to use less that 80 columns.
>>
>> I ran `./configure --enable-debug` to try to address the warnings in the
>> code, but unfortunately I didn't get any. I'm not sure if I'm doing
>> anything wrong, I posted the output here:
>>
>> https://gist.github.com/calavera/639002dd56753640721d
>>
>> I'd really appreciate if anybody could point me to those warnings if
>> there is anything I'm missing.
>>
>> As I said, I'm really interested in seeing this merged into libssh2.
>> Please, let me know if there is anything else I can help with to make that
>> possible.
>>
>> Cheers,
>> David
>>
>>
>

--20cf301fb60da7281d05020dd4e0
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I added the documentation back, extending it to the macro.=
<div><br></div><div>I&#39;ve also fixed the reference to the initPEMFromMem=
ory functions that weren&#39;t being assigned. This is the full patch:</div=
>

<div><br></div><div><a href=3D"https://github.com/calavera/libssh2/commit/2=
b75806bc60116af5b834508abc9bfc3a9039cb5.patch">https://github.com/calavera/=
libssh2/commit/2b75806bc60116af5b834508abc9bfc3a9039cb5.patch</a><br></div>

</div><div class=3D"gmail_extra"><br><br><div class=3D"gmail_quote">On Mon,=
 Sep 1, 2014 at 8:58 PM, David Calavera <span dir=3D"ltr">&lt;<a href=3D"ma=
ilto:david.calavera@gmail.com" target=3D"_blank">david.calavera@gmail.com</=
a>&gt;</span> wrote:<br>

<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr">I cleaned up some warnings =
that I detected and put together another patch:<div><br></div><div><a href=
=3D"https://github.com/calavera/libssh2/commit/2b75806bc60116af5b834508abc9=
bfc3a9039cb5.patch" target=3D"_blank">https://github.com/calavera/libssh2/c=
ommit/2b75806bc60116af5b834508abc9bfc3a9039cb5.patch</a><br>


</div><div><br></div><div>I also created a macro for the initial prototype:=
</div><div><br></div><div><pre style=3D"color:rgb(0,0,0);word-wrap:break-wo=
rd;white-space:pre-wrap">+#define libssh2_userauth_publickey_frommemory(ses=
sion, username, publickey, \
+                                              privatekey, passphrase) \
+ libssh2_userauth_publickey_frommemory_ex((session), (username), \
+                                          (unsigned int)strlen(username), =
  \
+                                          (publickey),                    =
  \
+                                          (unsigned int)strlen(publickey),=
  \
+                                          (privatekey),                   =
  \
+                                          (unsigned int)strlen(privatekey)=
, \
+                                          (passphrase))</pre></div><div>I =
just realized that I didn&#39;t apply the changes for the documentation of =
this new authentication. I&#39;ll add it shortly.</div><div><br></div>


<div>I&#39;d really appreciate some feedback.</div><div><br></div><div>Chee=
rs,</div><div>David</div></div><div class=3D"HOEnZb"><div class=3D"h5"><div=
 class=3D"gmail_extra"><br><br><div class=3D"gmail_quote">On Mon, Sep 1, 20=
14 at 4:06 PM, David Calavera <span dir=3D"ltr">&lt;<a href=3D"mailto:david=
.calavera@gmail.com" target=3D"_blank">david.calavera@gmail.com</a>&gt;</sp=
an> wrote:<br>


<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr">Hi,<div><br></div><div>I wa=
s doing some digging to see how I could pass auth keys by memory when I dis=
covered this old thread from 2012 with a patch:</div>


<div><br></div><div><div><a href=3D"http://www.libssh2.org/mail/libssh2-dev=
el-archive-2012-01/0015.shtml" target=3D"_blank">http://www.libssh2.org/mai=
l/libssh2-devel-archive-2012-01/0015.shtml</a><br>
</div><pre style=3D"color:rgb(0,0,0);word-wrap:break-word;white-space:pre-w=
rap"><span style=3D"font-family:arial;color:rgb(34,34,34)">I&#39;m really i=
nterested in seeing this incorporated to libssh2, so I decided to try to ad=
dress the problems raised in the next message in that thread:</span></pre>



</div><div><a href=3D"http://www.libssh2.org/mail/libssh2-devel-archive-201=
2-01/0016.shtml" target=3D"_blank">http://www.libssh2.org/mail/libssh2-deve=
l-archive-2012-01/0016.shtml</a><br></div><div><br></div><div>I created a n=
ew patch that addressed part those points. You can see it at:</div>



<div><br></div><div><a href=3D"https://github.com/calavera/libssh2/commit/d=
083300c69f41eff6132da3525722fc590e350cf.patch" target=3D"_blank">https://gi=
thub.com/calavera/libssh2/commit/d083300c69f41eff6132da3525722fc590e350cf.p=
atch</a><br>


</div>
<div><br></div><div>I replaced the use of `memcpy_s` to use `memcpy`. I als=
o formatted the code to use less that 80 columns.</div><div><br></div><div>=
I ran `./configure --enable-debug` to try to address the warnings in the co=
de, but unfortunately I didn&#39;t get any. I&#39;m not sure if I&#39;m doi=
ng anything wrong, I posted the output here:</div>



<div><br></div><div><a href=3D"https://gist.github.com/calavera/639002dd567=
53640721d" target=3D"_blank">https://gist.github.com/calavera/639002dd56753=
640721d</a><br></div><div><br></div><div>I&#39;d really appreciate if anybo=
dy could point me to those warnings if there is anything I&#39;m missing.</=
div>



<div><br></div><div>As I said, I&#39;m really interested in seeing this mer=
ged into libssh2. Please, let me know if there is anything else I can help =
with to make that possible.</div><div><br></div><div>Cheers,</div><div>



David</div><div><br></div></div>
</blockquote></div><br></div>
</div></div></blockquote></div><br></div>

--20cf301fb60da7281d05020dd4e0--

--===============1858913812==
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: base64
Content-Disposition: inline

X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KbGlic3NoMi1k
ZXZlbCBodHRwOi8vY29vbC5oYXh4LnNlL2NnaS1iaW4vbWFpbG1hbi9saXN0aW5mby9saWJzc2gy
LWRldmVsCg==

--===============1858913812==--

From libssh2-devel-bounces@cool.haxx.se  Wed Sep 10 22:28:58 2014
Return-Path: <libssh2-devel-bounces@cool.haxx.se>
Received: from www.haxx.se (localhost.localdomain [127.0.0.1])
	by giant.haxx.se (8.14.4/8.14.4/Debian-7) with ESMTP id s8AKSLhv017373;
	Wed, 10 Sep 2014 22:28:51 +0200
Received: from mail-ig0-x230.google.com (mail-ig0-x230.google.com
 [IPv6:2607:f8b0:4001:c05::230])
 by giant.haxx.se (8.14.4/8.14.4/Debian-7) with ESMTP id s8AKSI24017281
 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-RC4-SHA bits=128 verify=NOT)
 for <libssh2-devel@cool.haxx.se>; Wed, 10 Sep 2014 22:28:19 +0200
Received: by mail-ig0-f176.google.com with SMTP id hn18so7230161igb.9
 for <libssh2-devel@cool.haxx.se>; Wed, 10 Sep 2014 13:28:13 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113;
 h=mime-version:in-reply-to:references:from:date:message-id:subject:to
 :content-type; bh=Ap31gkvnewbAlFTEENI5Chh7t7KG5UHab0+LQan5Vwg=;
 b=IDsJ15+V82H6fj+k82eXjMiMH0QkFcJvmrIurxke8hTheVYfK0BXDP/HHGejncWebD
 uGkHVPLgtf+BhudBPX20zYJNpaRWWATwOp1Esd8e/oxeoNUXNh3jZQpxk7sDMXYOEddi
 dl71kcL/DKaTWMW5XrGJTZnZgGsapnCxaI72Mh4aw8jYMDs6YzkWm759DkpVUaVm5nej
 ZvDM4PCqMAO/DI9sG/OEoDdw3awdZ/FbvND2oEBQ6JtT/cO8M00Txr+KCKQOJcxnoUGi
 qID4eFJG3eeouEcg6fSMWp9KIbkAk25AERL/dLUe2yzg3Bu+nmZLe6mX4ZMA+j+LCIAU
 GQmg==
X-Received: by 10.42.199.11 with SMTP id eq11mr29098427icb.5.1410380893529;
 Wed, 10 Sep 2014 13:28:13 -0700 (PDT)
MIME-Version: 1.0
Received: by 10.107.33.75 with HTTP; Wed, 10 Sep 2014 13:27:53 -0700 (PDT)
In-Reply-To: <CAH7nXcuwV=DjGFfuqUsHL0OD2WvaDyCfcoqQk7gjBY2uYMh0yg@mail.gmail.com>
References: <CAH7nXcu2pM_WhPtVqPa5Vz8tqS_0sSQPGYR0bZ8kCS_bD+13wA@mail.gmail.com>
 <CAH7nXcvbPouEsLsPSF94cgfMMpEVp1XCpgDSBhJbaWojUmvi_g@mail.gmail.com>
 <CAH7nXcuwV=DjGFfuqUsHL0OD2WvaDyCfcoqQk7gjBY2uYMh0yg@mail.gmail.com>
From: David Calavera <david.calavera@gmail.com>
Date: Wed, 10 Sep 2014 13:27:53 -0700
Message-ID: <CAH7nXcuA13Dfu91feDg=82UzFto=8sSY+WCtBzTQLvtgGnAGuA@mail.gmail.com>
Subject: Re: Allow authentication to be passed in memory - blast from the past
To: libssh2-devel <libssh2-devel@cool.haxx.se>
X-BeenThere: libssh2-devel@cool.haxx.se
X-Mailman-Version: 2.1.16
Precedence: list
Reply-To: libssh2 development <libssh2-devel@cool.haxx.se>
List-Id: libssh2 development <libssh2-devel.cool.haxx.se>
List-Unsubscribe: <http://cool.haxx.se/cgi-bin/mailman/options/libssh2-devel>, 
 <mailto:libssh2-devel-request@cool.haxx.se?subject=unsubscribe>
List-Archive: <http://cool.haxx.se/pipermail/libssh2-devel/>
List-Post: <mailto:libssh2-devel@cool.haxx.se>
List-Help: <mailto:libssh2-devel-request@cool.haxx.se?subject=help>
List-Subscribe: <http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel>, 
 <mailto:libssh2-devel-request@cool.haxx.se?subject=subscribe>
Content-Type: multipart/mixed; boundary="===============0186266442=="
Errors-To: libssh2-devel-bounces@cool.haxx.se
Sender: "libssh2-devel" <libssh2-devel-bounces@cool.haxx.se>

--===============0186266442==
Content-Type: multipart/alternative; boundary=20cf30334b51282dad0502bbe40f

--20cf30334b51282dad0502bbe40f
Content-Type: text/plain; charset=UTF-8

Hi everyone,

I was wondering if anyone had time to review my patch. I've been using it
in my staging and testing environments and it's working nicely. I'm not
sure if that's any indication that the patch is good to be merged but I'd
like to know what people think.

Please, feel free to comment in the commit directly if that helps to
address the possible issues with the code.

https://github.com/calavera/libssh2/commit/2b75806bc60116af5b834508abc9bfc3a9039cb5
<https://github.com/calavera/libssh2/commit/2b75806bc60116af5b834508abc9bfc3a9039cb5.patch>

Thanks,
David

On Mon, Sep 1, 2014 at 9:48 PM, David Calavera <david.calavera@gmail.com>
wrote:

> I added the documentation back, extending it to the macro.
>
> I've also fixed the reference to the initPEMFromMemory functions that
> weren't being assigned. This is the full patch:
>
>
> https://github.com/calavera/libssh2/commit/2b75806bc60116af5b834508abc9bfc3a9039cb5.patch
>
>
> On Mon, Sep 1, 2014 at 8:58 PM, David Calavera <david.calavera@gmail.com>
> wrote:
>
>> I cleaned up some warnings that I detected and put together another patch:
>>
>>
>> https://github.com/calavera/libssh2/commit/2b75806bc60116af5b834508abc9bfc3a9039cb5.patch
>>
>> I also created a macro for the initial prototype:
>>
>> +#define libssh2_userauth_publickey_frommemory(session, username, publickey, \
>> +                                              privatekey, passphrase) \
>> + libssh2_userauth_publickey_frommemory_ex((session), (username), \
>> +                                          (unsigned int)strlen(username),   \
>> +                                          (publickey),                      \
>> +                                          (unsigned int)strlen(publickey),  \
>> +                                          (privatekey),                     \
>> +                                          (unsigned int)strlen(privatekey), \
>> +                                          (passphrase))
>>
>> I just realized that I didn't apply the changes for the documentation of
>> this new authentication. I'll add it shortly.
>>
>> I'd really appreciate some feedback.
>>
>> Cheers,
>> David
>>
>>
>> On Mon, Sep 1, 2014 at 4:06 PM, David Calavera <david.calavera@gmail.com>
>> wrote:
>>
>>> Hi,
>>>
>>> I was doing some digging to see how I could pass auth keys by memory
>>> when I discovered this old thread from 2012 with a patch:
>>>
>>> http://www.libssh2.org/mail/libssh2-devel-archive-2012-01/0015.shtml
>>>
>>> I'm really interested in seeing this incorporated to libssh2, so I decided to try to address the problems raised in the next message in that thread:
>>>
>>> http://www.libssh2.org/mail/libssh2-devel-archive-2012-01/0016.shtml
>>>
>>> I created a new patch that addressed part those points. You can see it
>>> at:
>>>
>>>
>>> https://github.com/calavera/libssh2/commit/d083300c69f41eff6132da3525722fc590e350cf.patch
>>>
>>> I replaced the use of `memcpy_s` to use `memcpy`. I also formatted the
>>> code to use less that 80 columns.
>>>
>>> I ran `./configure --enable-debug` to try to address the warnings in the
>>> code, but unfortunately I didn't get any. I'm not sure if I'm doing
>>> anything wrong, I posted the output here:
>>>
>>> https://gist.github.com/calavera/639002dd56753640721d
>>>
>>> I'd really appreciate if anybody could point me to those warnings if
>>> there is anything I'm missing.
>>>
>>> As I said, I'm really interested in seeing this merged into libssh2.
>>> Please, let me know if there is anything else I can help with to make that
>>> possible.
>>>
>>> Cheers,
>>> David
>>>
>>>
>>
>

--20cf30334b51282dad0502bbe40f
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Hi everyone,<div><br></div><div>I was wondering if anyone =
had time to review my patch. I&#39;ve been using it in my staging and testi=
ng environments and it&#39;s working nicely. I&#39;m not sure if that&#39;s=
 any indication that the patch is good to be merged but I&#39;d like to kno=
w what people think.</div><div><br></div><div>Please, feel free to comment =
in the commit directly if that helps to address the possible issues with th=
e code.</div><div><br></div><div><a href=3D"https://github.com/calavera/lib=
ssh2/commit/2b75806bc60116af5b834508abc9bfc3a9039cb5.patch" target=3D"_blan=
k" style=3D"font-family:arial,sans-serif;font-size:13px">https://github.com=
/calavera/libssh2/commit/2b75806bc60116af5b834508abc9bfc3a9039cb5</a><br></=
div><div><br></div><div>Thanks,</div><div>David</div></div><div class=3D"gm=
ail_extra"><br><div class=3D"gmail_quote">On Mon, Sep 1, 2014 at 9:48 PM, D=
avid Calavera <span dir=3D"ltr">&lt;<a href=3D"mailto:david.calavera@gmail.=
com" target=3D"_blank">david.calavera@gmail.com</a>&gt;</span> wrote:<br><b=
lockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px =
#ccc solid;padding-left:1ex"><div dir=3D"ltr">I added the documentation bac=
k, extending it to the macro.<div><br></div><div>I&#39;ve also fixed the re=
ference to the initPEMFromMemory functions that weren&#39;t being assigned.=
 This is the full patch:</div>
<div><br></div><div><a href=3D"https://github.com/calavera/libssh2/commit/2=
b75806bc60116af5b834508abc9bfc3a9039cb5.patch" target=3D"_blank">https://gi=
thub.com/calavera/libssh2/commit/2b75806bc60116af5b834508abc9bfc3a9039cb5.p=
atch</a><br></div>
</div><div class=3D"HOEnZb"><div class=3D"h5"><div class=3D"gmail_extra"><b=
r><br><div class=3D"gmail_quote">On Mon, Sep 1, 2014 at 8:58 PM, David Cala=
vera <span dir=3D"ltr">&lt;<a href=3D"mailto:david.calavera@gmail.com" targ=
et=3D"_blank">david.calavera@gmail.com</a>&gt;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr">I cleaned up some warnings =
that I detected and put together another patch:<div><br></div><div><a href=
=3D"https://github.com/calavera/libssh2/commit/2b75806bc60116af5b834508abc9=
bfc3a9039cb5.patch" target=3D"_blank">https://github.com/calavera/libssh2/c=
ommit/2b75806bc60116af5b834508abc9bfc3a9039cb5.patch</a><br>

</div><div><br></div><div>I also created a macro for the initial prototype:=
</div><div><br></div><div><pre style=3D"color:rgb(0,0,0);word-wrap:break-wo=
rd;white-space:pre-wrap">+#define libssh2_userauth_publickey_frommemory(ses=
sion, username, publickey, \
+                                              privatekey, passphrase) \
+ libssh2_userauth_publickey_frommemory_ex((session), (username), \
+                                          (unsigned int)strlen(username), =
  \
+                                          (publickey),                    =
  \
+                                          (unsigned int)strlen(publickey),=
  \
+                                          (privatekey),                   =
  \
+                                          (unsigned int)strlen(privatekey)=
, \
+                                          (passphrase))</pre></div><div>I =
just realized that I didn&#39;t apply the changes for the documentation of =
this new authentication. I&#39;ll add it shortly.</div><div><br></div>

<div>I&#39;d really appreciate some feedback.</div><div><br></div><div>Chee=
rs,</div><div>David</div></div><div><div><div class=3D"gmail_extra"><br><br=
><div class=3D"gmail_quote">On Mon, Sep 1, 2014 at 4:06 PM, David Calavera =
<span dir=3D"ltr">&lt;<a href=3D"mailto:david.calavera@gmail.com" target=3D=
"_blank">david.calavera@gmail.com</a>&gt;</span> wrote:<br>

<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr">Hi,<div><br></div><div>I wa=
s doing some digging to see how I could pass auth keys by memory when I dis=
covered this old thread from 2012 with a patch:</div>

<div><br></div><div><div><a href=3D"http://www.libssh2.org/mail/libssh2-dev=
el-archive-2012-01/0015.shtml" target=3D"_blank">http://www.libssh2.org/mai=
l/libssh2-devel-archive-2012-01/0015.shtml</a><br>
</div><pre style=3D"color:rgb(0,0,0);word-wrap:break-word;white-space:pre-w=
rap"><span style=3D"font-family:arial;color:rgb(34,34,34)">I&#39;m really i=
nterested in seeing this incorporated to libssh2, so I decided to try to ad=
dress the problems raised in the next message in that thread:</span></pre>


</div><div><a href=3D"http://www.libssh2.org/mail/libssh2-devel-archive-201=
2-01/0016.shtml" target=3D"_blank">http://www.libssh2.org/mail/libssh2-deve=
l-archive-2012-01/0016.shtml</a><br></div><div><br></div><div>I created a n=
ew patch that addressed part those points. You can see it at:</div>


<div><br></div><div><a href=3D"https://github.com/calavera/libssh2/commit/d=
083300c69f41eff6132da3525722fc590e350cf.patch" target=3D"_blank">https://gi=
thub.com/calavera/libssh2/commit/d083300c69f41eff6132da3525722fc590e350cf.p=
atch</a><br>

</div>
<div><br></div><div>I replaced the use of `memcpy_s` to use `memcpy`. I als=
o formatted the code to use less that 80 columns.</div><div><br></div><div>=
I ran `./configure --enable-debug` to try to address the warnings in the co=
de, but unfortunately I didn&#39;t get any. I&#39;m not sure if I&#39;m doi=
ng anything wrong, I posted the output here:</div>


<div><br></div><div><a href=3D"https://gist.github.com/calavera/639002dd567=
53640721d" target=3D"_blank">https://gist.github.com/calavera/639002dd56753=
640721d</a><br></div><div><br></div><div>I&#39;d really appreciate if anybo=
dy could point me to those warnings if there is anything I&#39;m missing.</=
div>


<div><br></div><div>As I said, I&#39;m really interested in seeing this mer=
ged into libssh2. Please, let me know if there is anything else I can help =
with to make that possible.</div><div><br></div><div>Cheers,</div><div>


David</div><div><br></div></div>
</blockquote></div><br></div>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div><br></div>

--20cf30334b51282dad0502bbe40f--

--===============0186266442==
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: base64
Content-Disposition: inline

X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KbGlic3NoMi1k
ZXZlbCBodHRwOi8vY29vbC5oYXh4LnNlL2NnaS1iaW4vbWFpbG1hbi9saXN0aW5mby9saWJzc2gy
LWRldmVsCg==

--===============0186266442==--

From libssh2-devel-bounces@cool.haxx.se  Sat Sep 13 06:28:48 2014
Return-Path: <libssh2-devel-bounces@cool.haxx.se>
Received: from www.haxx.se (localhost.localdomain [127.0.0.1])
	by giant.haxx.se (8.14.4/8.14.4/Debian-7) with ESMTP id s8D4S7eU019803;
	Sat, 13 Sep 2014 06:28:43 +0200
Received: from mail-lb0-f181.google.com (mail-lb0-f181.google.com
 [209.85.217.181])
 by giant.haxx.se (8.14.4/8.14.4/Debian-7) with ESMTP id s8D4S5YO019656
 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-RC4-SHA bits=128 verify=NOT)
 for <libssh2-devel@cool.haxx.se>; Sat, 13 Sep 2014 06:28:05 +0200
Received: by mail-lb0-f181.google.com with SMTP id z11so1917945lbi.26
 for <libssh2-devel@cool.haxx.se>; Fri, 12 Sep 2014 21:27:59 -0700 (PDT)
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20130820;
 h=x-gm-message-state:mime-version:in-reply-to:references:date
 :message-id:subject:from:to:content-type;
 bh=gyIMSTQBFJtt1cQDXEczYcqi6xNjlTMCb+IOLcFK0t8=;
 b=iPCt+qwGyVEspcYlW7VjZVS03sLHuruRKMuUbSR2wW04wC8gV4htYfvifDhMwDi50N
 9WOfYaRLlGiakMFycZ0sKUv9yazzAhWtrVa+s5zkZ0edums7bhbRlbAnodSjqZ9Whw24
 4yjUu1g4XngtFXMogV7Nx4jYKXBULd+0QFW+zMIEj+ppI6GQzGYtC92drvkJIpAbVa8l
 kFEyIykE8xbPylaN4b7eSdwcKdU+VoDwjOdhFSgpYtNxGaNTltt/yiqLLLk8SbLAi/T2
 qNRnOQD40rU/nOxMmD+/1B2KhEH0S9w0ce6xUUKoI6P5rSa9SnChU6Up/nRuW5cVyaCK
 d7gA==
X-Gm-Message-State: ALoCoQkneoRX1rCYYtEzEVDdPsMaz2aWXdLoDZHkaekb4DZM8B12aA1Fhib7+yXBb6D+EiS2hqoe
MIME-Version: 1.0
X-Received: by 10.152.170.227 with SMTP id ap3mr13211396lac.15.1410582479834; 
 Fri, 12 Sep 2014 21:27:59 -0700 (PDT)
Received: by 10.114.78.65 with HTTP; Fri, 12 Sep 2014 21:27:59 -0700 (PDT)
In-Reply-To: <20140829084531.GA20487@joerntop.localnet>
References: <20140829084531.GA20487@joerntop.localnet>
Date: Sat, 13 Sep 2014 09:57:59 +0530
Message-ID: <CA+z1VpNTdB2GFWA8yt1u8gjDArwKHVYnuMwwWV+vn76AufqOzg@mail.gmail.com>
Subject: Re: Download text file via SFTP
From: Nitin Deokate <ndeokate@qualys.com>
To: libssh2 development <libssh2-devel@cool.haxx.se>
X-BeenThere: libssh2-devel@cool.haxx.se
X-Mailman-Version: 2.1.16
Precedence: list
Reply-To: libssh2 development <libssh2-devel@cool.haxx.se>
List-Id: libssh2 development <libssh2-devel.cool.haxx.se>
List-Unsubscribe: <http://cool.haxx.se/cgi-bin/mailman/options/libssh2-devel>, 
 <mailto:libssh2-devel-request@cool.haxx.se?subject=unsubscribe>
List-Archive: <http://cool.haxx.se/pipermail/libssh2-devel/>
List-Post: <mailto:libssh2-devel@cool.haxx.se>
List-Help: <mailto:libssh2-devel-request@cool.haxx.se?subject=help>
List-Subscribe: <http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel>, 
 <mailto:libssh2-devel-request@cool.haxx.se?subject=subscribe>
Content-Type: multipart/mixed; boundary="===============2080986327=="
Errors-To: libssh2-devel-bounces@cool.haxx.se
Sender: "libssh2-devel" <libssh2-devel-bounces@cool.haxx.se>

--===============2080986327==
Content-Type: multipart/alternative; boundary=089e013c6558a325840502ead30b

--089e013c6558a325840502ead30b
Content-Type: text/plain; charset=UTF-8

Anybody has thoughts on this? I also faced this issue[
http://www.libssh2.org/mail/libssh2-devel-archive-2014-06/0001.shtml]
I think we should have solution on this as Joern suggested.

-Nitin


On Fri, Aug 29, 2014 at 2:15 PM, Joern Heissler <libssh2@wulf.eu.org> wrote:

> Hi,
>
> I'm trying to download a large text file using the sftp protocol.
>
> The remote server runs on "Maverick SSHD". I'm using libssh2-1.4.3 (debian
> unstable).
>
> I enabled compression and negotiated zlib because it's a text file.
>
> Next, I compared the speed to what OpenSSH's `sftp' utility achieves, and
> libssh2 was just terribly slow.
>
> Then I increased buffer size for libssh2_sftp_read to a big value. It
> helps a little, but the chunks returned by libssh2_sftp_read are exactly
> 2000
> bytes, regardless of my setting.
>
> tcpdump shows that the packets sent by the server are mostly around
> 200-300 bytes which obviously is too small.
>
> I found that when I change MAX_SFTP_READ_SIZE from 2000 to a larger
> value, the packet size increases, as does the download speed.
>
> To me it looks like the server has strange TCP_NODELAY / TCP_CORK
> settings. For each request of 2000 bytes, the data is gzipped and gets
> sent in
> one tcp packet (or multiple if too large).
> I found that a chunk size of 13500 bytes gives me a good ratio of
> uncompressed_bytes / tcp_packets.
>
> The optimal value for MAX_SFTP_READ_SIZE heavily depends on the specific
> use case, so I ask that it's made a configurable option, please :)
>
> Thanks,
> Joern
> _______________________________________________
> libssh2-devel http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel
>

--089e013c6558a325840502ead30b
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Anybody has thoughts on this? I also faced this issue[<a h=
ref=3D"http://www.libssh2.org/mail/libssh2-devel-archive-2014-06/0001.shtml=
">http://www.libssh2.org/mail/libssh2-devel-archive-2014-06/0001.shtml</a>]=
<div>I think we should have solution on this as Joern suggested.</div><div>=
<br></div><div>-Nitin<br><div><br></div></div></div><div class=3D"gmail_ext=
ra"><br><div class=3D"gmail_quote">On Fri, Aug 29, 2014 at 2:15 PM, Joern H=
eissler <span dir=3D"ltr">&lt;<a href=3D"mailto:libssh2@wulf.eu.org" target=
=3D"_blank">libssh2@wulf.eu.org</a>&gt;</span> wrote:<br><blockquote class=
=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd=
ing-left:1ex">Hi,<br>
<br>
I&#39;m trying to download a large text file using the sftp protocol.<br>
<br>
The remote server runs on &quot;Maverick SSHD&quot;. I&#39;m using libssh2-=
1.4.3 (debian unstable).<br>
<br>
I enabled compression and negotiated zlib because it&#39;s a text file.<br>
<br>
Next, I compared the speed to what OpenSSH&#39;s `sftp&#39; utility achieve=
s, and<br>
libssh2 was just terribly slow.<br>
<br>
Then I increased buffer size for libssh2_sftp_read to a big value. It<br>
helps a little, but the chunks returned by libssh2_sftp_read are exactly 20=
00<br>
bytes, regardless of my setting.<br>
<br>
tcpdump shows that the packets sent by the server are mostly around<br>
200-300 bytes which obviously is too small.<br>
<br>
I found that when I change MAX_SFTP_READ_SIZE from 2000 to a larger<br>
value, the packet size increases, as does the download speed.<br>
<br>
To me it looks like the server has strange TCP_NODELAY / TCP_CORK<br>
settings. For each request of 2000 bytes, the data is gzipped and gets sent=
 in<br>
one tcp packet (or multiple if too large).<br>
I found that a chunk size of 13500 bytes gives me a good ratio of uncompres=
sed_bytes / tcp_packets.<br>
<br>
The optimal value for MAX_SFTP_READ_SIZE heavily depends on the specific<br=
>
use case, so I ask that it&#39;s made a configurable option, please :)<br>
<br>
Thanks,<br>
Joern<br>
_______________________________________________<br>
libssh2-devel <a href=3D"http://cool.haxx.se/cgi-bin/mailman/listinfo/libss=
h2-devel" target=3D"_blank">http://cool.haxx.se/cgi-bin/mailman/listinfo/li=
bssh2-devel</a><br>
</blockquote></div><br></div>

--089e013c6558a325840502ead30b--

--===============2080986327==
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: base64
Content-Disposition: inline

X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KbGlic3NoMi1k
ZXZlbCBodHRwOi8vY29vbC5oYXh4LnNlL2NnaS1iaW4vbWFpbG1hbi9saXN0aW5mby9saWJzc2gy
LWRldmVsCg==

--===============2080986327==--

From libssh2-devel-bounces@cool.haxx.se  Mon Sep 15 00:36:06 2014
Return-Path: <libssh2-devel-bounces@cool.haxx.se>
Received: from www.haxx.se (localhost.localdomain [127.0.0.1])
	by giant.haxx.se (8.14.4/8.14.4/Debian-7) with ESMTP id s8EMZakt003934;
	Mon, 15 Sep 2014 00:36:00 +0200
Received: from giant.haxx.se (localhost.localdomain [127.0.0.1])
 by giant.haxx.se (8.14.4/8.14.4/Debian-7) with ESMTP id s8EMZZwZ003930
 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT)
 for <libssh2-devel@cool.haxx.se>; Mon, 15 Sep 2014 00:35:35 +0200
Received: from localhost (dast@localhost)
 by giant.haxx.se (8.14.4/8.14.4/Submit) with ESMTP id s8EMZZ6J003926
 for <libssh2-devel@cool.haxx.se>; Mon, 15 Sep 2014 00:35:35 +0200
X-Authentication-Warning: giant.haxx.se: dast owned process doing -bs
Date: Mon, 15 Sep 2014 00:35:35 +0200 (CEST)
From: Daniel Stenberg <daniel@haxx.se>
X-X-Sender: dast@giant.haxx.se
To: libssh2 development <libssh2-devel@cool.haxx.se>
Subject: Re: Download text file via SFTP
In-Reply-To: <CA+z1VpNTdB2GFWA8yt1u8gjDArwKHVYnuMwwWV+vn76AufqOzg@mail.gmail.com>
Message-ID: <alpine.DEB.2.00.1409150035100.18125@tvnag.unkk.fr>
References: <20140829084531.GA20487@joerntop.localnet>
 <CA+z1VpNTdB2GFWA8yt1u8gjDArwKHVYnuMwwWV+vn76AufqOzg@mail.gmail.com>
User-Agent: Alpine 2.00 (DEB 1167 2008-08-23)
X-fromdanielhimself: yes
MIME-Version: 1.0
X-BeenThere: libssh2-devel@cool.haxx.se
X-Mailman-Version: 2.1.16
Precedence: list
Reply-To: libssh2 development <libssh2-devel@cool.haxx.se>
List-Id: libssh2 development <libssh2-devel.cool.haxx.se>
List-Unsubscribe: <http://cool.haxx.se/cgi-bin/mailman/options/libssh2-devel>, 
 <mailto:libssh2-devel-request@cool.haxx.se?subject=unsubscribe>
List-Archive: <http://cool.haxx.se/pipermail/libssh2-devel/>
List-Post: <mailto:libssh2-devel@cool.haxx.se>
List-Help: <mailto:libssh2-devel-request@cool.haxx.se?subject=help>
List-Subscribe: <http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel>, 
 <mailto:libssh2-devel-request@cool.haxx.se?subject=subscribe>
Content-Type: text/plain; charset="utf-8"; Format="flowed"
Errors-To: libssh2-devel-bounces@cool.haxx.se
Sender: "libssh2-devel" <libssh2-devel-bounces@cool.haxx.se>
Content-Transfer-Encoding: 8bit
X-MIME-Autoconverted: from base64 to 8bit by giant.haxx.se id s8EMZakt003934

On Sat, 13 Sep 2014, Nitin Deokate wrote:

> Anybody has thoughts on this?

"this" being an option to change the "slice size" ?

-- 

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

From libssh2-devel-bounces@cool.haxx.se  Mon Sep 15 00:44:03 2014
Return-Path: <libssh2-devel-bounces@cool.haxx.se>
Received: from www.haxx.se (localhost.localdomain [127.0.0.1])
	by giant.haxx.se (8.14.4/8.14.4/Debian-7) with ESMTP id s8EMhxxg017989;
	Mon, 15 Sep 2014 00:44:03 +0200
Received: from giant.haxx.se (localhost.localdomain [127.0.0.1])
 by giant.haxx.se (8.14.4/8.14.4/Debian-7) with ESMTP id s8EMhxmg017985
 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT)
 for <libssh2-devel@cool.haxx.se>; Mon, 15 Sep 2014 00:43:59 +0200
Received: from localhost (dast@localhost)
 by giant.haxx.se (8.14.4/8.14.4/Submit) with ESMTP id s8EMhw2A017981
 for <libssh2-devel@cool.haxx.se>; Mon, 15 Sep 2014 00:43:58 +0200
X-Authentication-Warning: giant.haxx.se: dast owned process doing -bs
Date: Mon, 15 Sep 2014 00:43:58 +0200 (CEST)
From: Daniel Stenberg <daniel@haxx.se>
X-X-Sender: dast@giant.haxx.se
To: libssh2 development <libssh2-devel@cool.haxx.se>
Subject: Re: Allow authentication to be passed in memory - blast from the past
In-Reply-To: <CAH7nXcuA13Dfu91feDg=82UzFto=8sSY+WCtBzTQLvtgGnAGuA@mail.gmail.com>
Message-ID: <alpine.DEB.2.00.1409150009240.18125@tvnag.unkk.fr>
References: <CAH7nXcu2pM_WhPtVqPa5Vz8tqS_0sSQPGYR0bZ8kCS_bD+13wA@mail.gmail.com>
 <CAH7nXcvbPouEsLsPSF94cgfMMpEVp1XCpgDSBhJbaWojUmvi_g@mail.gmail.com>
 <CAH7nXcuwV=DjGFfuqUsHL0OD2WvaDyCfcoqQk7gjBY2uYMh0yg@mail.gmail.com>
 <CAH7nXcuA13Dfu91feDg=82UzFto=8sSY+WCtBzTQLvtgGnAGuA@mail.gmail.com>
User-Agent: Alpine 2.00 (DEB 1167 2008-08-23)
X-fromdanielhimself: yes
MIME-Version: 1.0
X-BeenThere: libssh2-devel@cool.haxx.se
X-Mailman-Version: 2.1.16
Precedence: list
Reply-To: libssh2 development <libssh2-devel@cool.haxx.se>
List-Id: libssh2 development <libssh2-devel.cool.haxx.se>
List-Unsubscribe: <http://cool.haxx.se/cgi-bin/mailman/options/libssh2-devel>, 
 <mailto:libssh2-devel-request@cool.haxx.se?subject=unsubscribe>
List-Archive: <http://cool.haxx.se/pipermail/libssh2-devel/>
List-Post: <mailto:libssh2-devel@cool.haxx.se>
List-Help: <mailto:libssh2-devel-request@cool.haxx.se?subject=help>
List-Subscribe: <http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel>, 
 <mailto:libssh2-devel-request@cool.haxx.se?subject=subscribe>
Content-Type: text/plain; charset="utf-8"; Format="flowed"
Errors-To: libssh2-devel-bounces@cool.haxx.se
Sender: "libssh2-devel" <libssh2-devel-bounces@cool.haxx.se>
Content-Transfer-Encoding: 8bit
X-MIME-Autoconverted: from base64 to 8bit by giant.haxx.se id s8EMhxxg017989

On Wed, 10 Sep 2014, David Calavera wrote:

> I was wondering if anyone had time to review my patch.

The idea seems reasonable to me, but I would prefer if you'd post the 
patch(es) for review here on the mailing list rather than pointing out 
something (on github) so that we can comment and discuss them here.

I would also wouldn't mind to hear someone else voice their support for this 
functionality just to be sure that we're working on something more people 
actually find sensible to add.

Personally I don't like the use of a macro that is the most widely used 
version of a function that then calls the actual *_ex() function - but I'm 
fully aware that we have a busload of functions done like that already...

Does it also work when built to use gcrypt instead of OpenSSL?

-- 

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

From libssh2-devel-bounces@cool.haxx.se  Mon Sep 15 01:20:56 2014
Return-Path: <libssh2-devel-bounces@cool.haxx.se>
Received: from www.haxx.se (localhost.localdomain [127.0.0.1])
	by giant.haxx.se (8.14.4/8.14.4/Debian-7) with ESMTP id s8ENKhqj025910;
	Mon, 15 Sep 2014 01:20:54 +0200
Received: from mail-ig0-x22e.google.com (mail-ig0-x22e.google.com
 [IPv6:2607:f8b0:4001:c05::22e])
 by giant.haxx.se (8.14.4/8.14.4/Debian-7) with ESMTP id s8ENKeLF025890
 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-RC4-SHA bits=128 verify=NOT)
 for <libssh2-devel@cool.haxx.se>; Mon, 15 Sep 2014 01:20:41 +0200
Received: by mail-ig0-f174.google.com with SMTP id h18so3085167igc.13
 for <libssh2-devel@cool.haxx.se>; Sun, 14 Sep 2014 16:20:36 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113;
 h=mime-version:in-reply-to:references:from:date:message-id:subject:to
 :content-type; bh=xZlNFmimj5fnM0wcnuwjPrZSLZTMHMQwiTA7ZjDWs/8=;
 b=V/HAlqP1C8Tc5bU6Vxj0FdV5FMzuju6Uxc4y/HzC42uK9OcErUokhJe8EjSwd2iKd+
 YrimP2fxordtc90viw90oR3zi/I9LCMo4P2SlSRhTJKpkSgZs4orj5pu+MprHtBjOAeR
 a2R2vVAzwARiC9b99vSqSDNrpbUnNZndgtcbC4PjY5/k6n52JQKzo7/dKW1lo8NZMiom
 DXPWDZBuc73egrne6724QtngzEfHtfZbqDEIW25g3tGyvVqQ0dm+dtogb61Ps2kOP6Iy
 M+kfbq7VsRi/FPw1cfL5wMgan+zC1Q/325Dl+yR7Pd4TLgHuRLet4GIA8Ur2Hv1ti5bt
 94lw==
X-Received: by 10.50.50.195 with SMTP id e3mr17876074igo.9.1410736836517; Sun,
 14 Sep 2014 16:20:36 -0700 (PDT)
MIME-Version: 1.0
Received: by 10.107.33.75 with HTTP; Sun, 14 Sep 2014 16:20:16 -0700 (PDT)
In-Reply-To: <alpine.DEB.2.00.1409150009240.18125@tvnag.unkk.fr>
References: <CAH7nXcu2pM_WhPtVqPa5Vz8tqS_0sSQPGYR0bZ8kCS_bD+13wA@mail.gmail.com>
 <CAH7nXcvbPouEsLsPSF94cgfMMpEVp1XCpgDSBhJbaWojUmvi_g@mail.gmail.com>
 <CAH7nXcuwV=DjGFfuqUsHL0OD2WvaDyCfcoqQk7gjBY2uYMh0yg@mail.gmail.com>
 <CAH7nXcuA13Dfu91feDg=82UzFto=8sSY+WCtBzTQLvtgGnAGuA@mail.gmail.com>
 <alpine.DEB.2.00.1409150009240.18125@tvnag.unkk.fr>
From: David Calavera <david.calavera@gmail.com>
Date: Sun, 14 Sep 2014 16:20:16 -0700
Message-ID: <CAH7nXctMTKesMeZzYU3Py-gLH0DFswtmo6y_2cHNAf-fsRtrEQ@mail.gmail.com>
Subject: Re: Allow authentication to be passed in memory - blast from the past
To: libssh2 development <libssh2-devel@cool.haxx.se>
X-BeenThere: libssh2-devel@cool.haxx.se
X-Mailman-Version: 2.1.16
Precedence: list
Reply-To: libssh2 development <libssh2-devel@cool.haxx.se>
List-Id: libssh2 development <libssh2-devel.cool.haxx.se>
List-Unsubscribe: <http://cool.haxx.se/cgi-bin/mailman/options/libssh2-devel>, 
 <mailto:libssh2-devel-request@cool.haxx.se?subject=unsubscribe>
List-Archive: <http://cool.haxx.se/pipermail/libssh2-devel/>
List-Post: <mailto:libssh2-devel@cool.haxx.se>
List-Help: <mailto:libssh2-devel-request@cool.haxx.se?subject=help>
List-Subscribe: <http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel>, 
 <mailto:libssh2-devel-request@cool.haxx.se?subject=subscribe>
Content-Type: multipart/mixed; boundary="===============0696410535=="
Errors-To: libssh2-devel-bounces@cool.haxx.se
Sender: "libssh2-devel" <libssh2-devel-bounces@cool.haxx.se>

--===============0696410535==
Content-Type: multipart/alternative; boundary=047d7bd75b3003294e05030ec458

--047d7bd75b3003294e05030ec458
Content-Type: text/plain; charset=UTF-8

Thanks for the comments Daniel.

The idea seems reasonable to me, but I would prefer if you'd post the
> patch(es) for review here on the mailing list rather than pointing out
> something (on github) so that we can comment and discuss them here.


I'm posting the code at the end of this email. I thought it would be easier
to read in a slightly richer view, since it's a slightly big patch, but I
totally understand it.

I would also wouldn't mind to hear someone else voice their support for
> this functionality just to be sure that we're working on something more
> people actually find sensible to add.


For what I've seen, someone needed this back in the day, that's where I got
the patch from
http://www.libssh2.org/mail/libssh2-devel-archive-2012-01/0015.shtml

I also saw an initial attempt to something similar in the trac:
http://trac.libssh2.org/ticket/248

I'd say that other people would find it useful, specially those that use
libssh2 as a dependency for their libraries. I'm using it with libgit2 and
the maintainers seemed interested when I talked to them.

I'd love to hear from more people too.

Personally I don't like the use of a macro that is the most widely used
> version of a function that then calls the actual *_ex() function - but I'm
> fully aware that we have a busload of functions done like that already...


It's funny because the original patch didn't have this macro. I added it
because I saw the rest ones :)

Does it also work when built to use gcrypt instead of OpenSSL?


I didn't try. Thanks for the reminder. I'll build it to use gcrypt and I'll
let you know if I find any issue.

This is the patch for everyone else to review:

From af088829281c1051486557a62f54604590849337 Mon Sep 17 00:00:00 2001
From: David Calavera <david.calavera@gmail.com>
Date: Mon, 1 Sep 2014 15:54:05 -0700
Subject: [PATCH] Allow authentication keys to be passed in memory.

All credits go to Joe Turpin, I'm just reaplying and cleaning his
patch:http://www.libssh2.org/mail/libssh2-devel-archive-2012-01/0015.shtml

* Adds libssh2_userauth_publickey_frommemory macro for
libssh2_userauth_publickey_frommemory_ex.
---
 docs/libssh2_userauth_publickey_frommemory.3    |  22 +++
 docs/libssh2_userauth_publickey_frommemory_ex.3 |  55 ++++++
 include/libssh2.h                               |  20 ++
 src/crypto.h                                    |  16 ++
 src/hostkey.c                                   |  66 +++++++
 src/libssh2_priv.h                              |   3 +
 src/openssl.c                                   | 121 +++++++++++++
 src/userauth.c                                  | 231 ++++++++++++++++++++++++
 8 files changed, 534 insertions(+)
 create mode 100644 docs/libssh2_userauth_publickey_frommemory.3
 create mode 100644 docs/libssh2_userauth_publickey_frommemory_ex.3

diff --git a/docs/libssh2_userauth_publickey_frommemory.3
b/docs/libssh2_userauth_publickey_frommemory.3
new file mode 100644
index 0000000..e464e71
--- /dev/null
+++ b/docs/libssh2_userauth_publickey_frommemory.3
@@ -0,0 +1,22 @@
+.TH libssh2_userauth_publickey_frommemory 3 "1 Sep 2014" "libssh2
1.5" "libssh2 manual"
+.SH NAME
+libssh2_userauth_publickey_frommemory - convenience macro for
\fIlibssh2_userauth_publickey_frommemory_ex(3)\fP calls
+.SH SYNOPSIS
+#include <libssh2.h>
+
+int
+libssh2_userauth_publickey_frommemory(LIBSSH2_SESSION *session,
+                                      const char *username,
+                                      const char *publickey,
+                                      const char *privatekey,
+                                      const char *passphrase);
+
+.SH DESCRIPTION
+This is a macro defined in a public libssh2 header file that is using the
+underlying function \fIlibssh2_userauth_publickey_frommemory_ex(3)\fP.
+.SH RETURN VALUE
+See \fIlibssh2_userauth_publickey_frommemory_ex(3)\fP
+.SH ERRORS
+See \fIlibssh2_userauth_publickey_frommemory_ex(3)\fP
+.SH SEE ALSO
+.BR libssh2_userauth_publickey_frommemory_ex(3)
diff --git a/docs/libssh2_userauth_publickey_frommemory_ex.3
b/docs/libssh2_userauth_publickey_frommemory_ex.3
new file mode 100644
index 0000000..6faf5d1
--- /dev/null
+++ b/docs/libssh2_userauth_publickey_frommemory_ex.3
@@ -0,0 +1,55 @@
+.TH libssh2_userauth_publickey_frommemory_ex 3 "1 Sep 2014" "libssh2
1.5" "libssh2 manual"
+.SH NAME
+libssh2_userauth_publickey_frommemory_ex - authenticate a session
with a public key, read from memory
+.SH SYNOPSIS
+#include <libssh2.h>
+
+.nf
+int libssh2_userauth_publickey_frommemory_ex(LIBSSH2_SESSION *session,
+                                           const char *username,
+                                           unsigned int username_len,
+                                           const char *publickeydata,
+                                           size_t publickeydata_len,
+                                           const char *privatekeydata,
+                                           size_t privatekeydata_len,
+                                           const char *passphrase);
+.SH DESCRIPTION
+\fIsession\fP - Session instance as returned by
+.BR libssh2_session_init_ex(3)
+
+\fIusername\fP - Remote user name to authenticate as.
+
+\fIusername_len\fP - Length of username.
+
+\fIpublickeydata\fP - Buffer containing the contents of a public key file.
+
+\fIpublickeydata_len\fP - Length of public key data.
+
+\fIprivatekeydata\fP - Buffer containing the contents of a private key file.
+
+\fIprivatekeydata_len\fP - Length of private key data.
+
+\fIpassphrase\fP - Passphrase to use when decoding private key file.
+
+Attempt public key authentication using a PEM encoded private key
file stored in memory.
+
+.SH RETURN VALUE
+Return 0 on success or negative on failure.  It returns
+LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
+LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
+
+.SH ERRORS
+\fILIBSSH2_ERROR_ALLOC\fP -  An internal memory allocation call failed.
+
+\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
+
+\fILIBSSH2_ERROR_SOCKET_TIMEOUT\fP -
+
+\fILIBSSH2_ERROR_PUBLICKEY_UNVERIFIED\fP - The username/public key
+combination was invalid.
+
+\fILIBSSH2_ERROR_AUTHENTICATION_FAILED\fP - Authentication using the supplied
+public key was not accepted.
+
+.SH SEE ALSO
+.BR libssh2_session_init_ex(3)
diff --git a/include/libssh2.h b/include/libssh2.h
index 565bf06..6e519db 100644
--- a/include/libssh2.h
+++ b/include/libssh2.h
@@ -576,6 +576,26 @@
libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session,
                                         (username),                     \
                                         (unsigned int)strlen(username))

+LIBSSH2_API int
+libssh2_userauth_publickey_frommemory_ex(LIBSSH2_SESSION *session,
+                                      const char *username,
+                                      unsigned int username_len,
+                                      const char *publickeyfiledata,
+                                      size_t publickeyfiledata_len,
+                                      const char *privatekeyfiledata,
+                                      size_t privatekeyfiledata_len,
+                                      const char *passphrase);
+
+#define libssh2_userauth_publickey_frommemory(session, username, publickey, \
+                                              privatekey, passphrase) \
+ libssh2_userauth_publickey_frommemory_ex((session), (username), \
+                                          (unsigned int)strlen(username),   \
+                                          (publickey),                      \
+                                          (unsigned int)strlen(publickey),  \
+                                          (privatekey),                     \
+                                          (unsigned int)strlen(privatekey), \
+                                          (passphrase))
+
 /*
  * response_callback is provided with filled by library prompts array,
  * but client must allocate and fill individual responses. Responses
diff --git a/src/crypto.h b/src/crypto.h
index a615bb1..05f5a5c 100644
--- a/src/crypto.h
+++ b/src/crypto.h
@@ -80,6 +80,10 @@ int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
                            size_t hash_len,
                            unsigned char **signature,
                            size_t *signature_len);
+int _libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa,
+                                        LIBSSH2_SESSION * session,
+                                        const char *filedata, size_t
filedata_len,
+                                        unsigned const char *passphrase);

 #if LIBSSH2_DSA
 int _libssh2_dsa_new(libssh2_dsa_ctx ** dsa,
@@ -102,6 +106,10 @@ int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
 int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
                            const unsigned char *hash,
                            unsigned long hash_len, unsigned char *sig);
+int _libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx ** dsa,
+                                        LIBSSH2_SESSION * session,
+                                        const char *filedata, size_t
filedata_len,
+                                        unsigned const char *passphrase);
 #endif

 int _libssh2_cipher_init(_libssh2_cipher_ctx * h,
@@ -120,6 +128,14 @@ int _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session,
                               size_t *pubkeydata_len,
                               const char *privatekey,
                               const char *passphrase);
+int _libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
+                                    unsigned char **method,
+                                    size_t *method_len,
+                                    unsigned char **pubkeydata,
+                                    size_t *pubkeydata_len,
+                                    const char *privatekeydata,
+                                    size_t privatekeydata_len,
+                                    const char *passphrase);

 void _libssh2_init_aes_ctr(void);

diff --git a/src/hostkey.c b/src/hostkey.c
index 753563d..02d085a 100644
--- a/src/hostkey.c
+++ b/src/hostkey.c
@@ -131,6 +131,38 @@ hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION * session,
 }

 /*
+ * hostkey_method_ssh_rsa_initPEMFromMemory
+ *
+ * Load a Private Key from a memory
+ */
+static int
+hostkey_method_ssh_rsa_initPEMFromMemory(LIBSSH2_SESSION * session,
+                                         const char *privkeyfiledata,
+                                         size_t privkeyfiledata_len,
+                                         unsigned const char *passphrase,
+                                         void **abstract)
+{
+    libssh2_rsa_ctx *rsactx;
+    int ret;
+
+    if (*abstract) {
+        hostkey_method_ssh_rsa_dtor(session, abstract);
+        *abstract = NULL;
+    }
+
+    ret = _libssh2_rsa_new_private_frommemory(&rsactx, session,
+                                              privkeyfiledata,
+                                              privkeyfiledata_len, passphrase);
+    if (ret) {
+        return -1;
+    }
+
+    *abstract = rsactx;
+
+    return 0;
+}
+
+/*
  * hostkey_method_ssh_rsa_sign
  *
  * Verify signature created by remote
@@ -208,6 +240,7 @@ static const LIBSSH2_HOSTKEY_METHOD
hostkey_method_ssh_rsa = {
     MD5_DIGEST_LENGTH,
     hostkey_method_ssh_rsa_init,
     hostkey_method_ssh_rsa_initPEM,
+    hostkey_method_ssh_rsa_initPEMFromMemory,
     hostkey_method_ssh_rsa_sig_verify,
     hostkey_method_ssh_rsa_signv,
     NULL,                       /* encrypt */
@@ -306,6 +339,38 @@ hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION * session,
 }

 /*
+ * hostkey_method_ssh_dss_initPEMFromMemory
+ *
+ * Load a Private Key from memory
+ */
+static int
+hostkey_method_ssh_dss_initPEMFromMemory(LIBSSH2_SESSION * session,
+                                         const char *privkeyfiledata,
+                                         size_t privkeyfiledata_len,
+                                         unsigned const char *passphrase,
+                                         void **abstract)
+{
+    libssh2_dsa_ctx *dsactx;
+    int ret;
+
+    if (*abstract) {
+        hostkey_method_ssh_dss_dtor(session, abstract);
+        *abstract = NULL;
+    }
+
+    ret = _libssh2_dsa_new_private_frommemory(&dsactx, session,
+                                              privkeyfiledata,
+                                              privkeyfiledata_len, passphrase);
+    if (ret) {
+        return -1;
+    }
+
+    *abstract = dsactx;
+
+    return 0;
+}
+
+/*
  * libssh2_hostkey_method_ssh_dss_sign
  *
  * Verify signature created by remote
@@ -392,6 +457,7 @@ static const LIBSSH2_HOSTKEY_METHOD
hostkey_method_ssh_dss = {
     MD5_DIGEST_LENGTH,
     hostkey_method_ssh_dss_init,
     hostkey_method_ssh_dss_initPEM,
+    hostkey_method_ssh_dss_initPEMFromMemory,
     hostkey_method_ssh_dss_sig_verify,
     hostkey_method_ssh_dss_signv,
     NULL,                       /* encrypt */
diff --git a/src/libssh2_priv.h b/src/libssh2_priv.h
index 00ed240..0274d83 100644
--- a/src/libssh2_priv.h
+++ b/src/libssh2_priv.h
@@ -853,6 +853,9 @@ struct _LIBSSH2_HOSTKEY_METHOD
                  size_t hostkey_data_len, void **abstract);
     int (*initPEM) (LIBSSH2_SESSION * session, const char *privkeyfile,
                     unsigned const char *passphrase, void **abstract);
+    int (*initPEMFromMemory) (LIBSSH2_SESSION * session,
+                              const char *privkeyfiledata, size_t
privkeyfiledata_len,
+                              unsigned const char *passphrase, void
**abstract);
     int (*sig_verify) (LIBSSH2_SESSION * session, const unsigned char *sig,
                        size_t sig_len, const unsigned char *m,
                        size_t m_len, void **abstract);
diff --git a/src/openssl.c b/src/openssl.c
index 056b0b7..2e31472 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -388,6 +388,28 @@ typedef void * (*pem_read_bio_func)(BIO *, void
**, pem_password_cb *,
                                     void * u);

 static int
+read_private_key_from_memory(void ** key_ctx,
+                             pem_read_bio_func read_private_key,
+                             const char * filedata,
+                             size_t filedata_len,
+                             unsigned const char *passphrase)
+{
+    BIO * bp;
+
+    *key_ctx = NULL;
+
+    bp = BIO_new_mem_buf(filedata, filedata_len);
+    if (!bp) {
+        return -1;
+    }
+    *key_ctx = read_private_key(bp, NULL, (pem_password_cb *) passphrase_cb,
+                                (void *) passphrase);
+
+    BIO_free(bp);
+    return (*key_ctx) ? 0 : -1;
+}
+
+static int
 read_private_key_from_file(void ** key_ctx,
                            pem_read_bio_func read_private_key,
                            const char * filename,
@@ -409,6 +431,22 @@ read_private_key_from_file(void ** key_ctx,
     return (*key_ctx) ? 0 : -1;
 }

+ int
+_libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa,
+                                    LIBSSH2_SESSION * session,
+                                    const char *filedata, size_t filedata_len,
+                                    unsigned const char *passphrase)
+{
+    pem_read_bio_func read_rsa =
+        (pem_read_bio_func) &PEM_read_bio_RSAPrivateKey;
+    (void) session;
+
+    _libssh2_init_if_needed();
+
+    return read_private_key_from_memory((void **) rsa, read_rsa,
+                                        filedata, filedata_len, passphrase);
+}
+
 int
 _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
                          LIBSSH2_SESSION * session,
@@ -426,6 +464,22 @@ _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,

 #if LIBSSH2_DSA
 int
+_libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx ** dsa,
+                                    LIBSSH2_SESSION * session,
+                                    const char *filedata, size_t filedata_len,
+                                    unsigned const char *passphrase)
+{
+    pem_read_bio_func read_dsa =
+        (pem_read_bio_func) &PEM_read_bio_DSAPrivateKey;
+    (void) session;
+
+    _libssh2_init_if_needed();
+
+    return read_private_key_from_memory((void **) dsa, read_dsa,
+                                        filedata, filedata_len, passphrase);
+}
+
+int
 _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
                          LIBSSH2_SESSION * session,
                          const char *filename, unsigned const char *passphrase)
@@ -817,4 +871,71 @@ _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session,
     return st;
 }

+int
+_libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
+                                unsigned char **method,
+                                size_t *method_len,
+                                unsigned char **pubkeydata,
+                                size_t *pubkeydata_len,
+                                const char *privatekeydata,
+                                size_t privatekeydata_len,
+                                const char *passphrase)
+{
+    int       st;
+    BIO*      bp;
+    EVP_PKEY* pk;
+
+    _libssh2_debug(session,
+                   LIBSSH2_TRACE_AUTH,
+                   "Computing public key from private key.");
+
+    bp = BIO_new_mem_buf(privatekeydata, privatekeydata_len);
+    if (!bp) {
+        return -1;
+    }
+    if (!EVP_get_cipherbyname("des")) {
+        /* If this cipher isn't loaded it's a pretty good indication that none
+         * are.  I have *NO DOUBT* that there's a better way to deal with this
+         * ($#&%#$(%$#( Someone buy me an OpenSSL manual and I'll read up on
+         * it.
+         */
+        OpenSSL_add_all_ciphers();
+    }
+    BIO_reset(bp);
+    pk = PEM_read_bio_PrivateKey(bp, NULL, NULL, (void*)passphrase);
+    BIO_free(bp);
+
+    if (pk == NULL) {
+        return _libssh2_error(session,
+                              LIBSSH2_ERROR_FILE,
+                              "Unable to extract public key "
+                              "from private key file: "
+                              "Wrong passphrase or invalid/unrecognized "
+                              "private key file format");
+    }
+
+    switch (pk->type) {
+    case EVP_PKEY_RSA :
+        st = gen_publickey_from_rsa_evp(session, method, method_len,
+                                        pubkeydata, pubkeydata_len, pk);
+        break;
+
+    case EVP_PKEY_DSA :
+        st = gen_publickey_from_dsa_evp(session, method, method_len,
+                                        pubkeydata, pubkeydata_len, pk);
+        break;
+
+    default :
+        st = _libssh2_error(session,
+                            LIBSSH2_ERROR_FILE,
+                            "Unable to extract public key "
+                            "from private key file: "
+                            "Unsupported private key file format");
+        break;
+    }
+
+    EVP_PKEY_free(pk);
+    return st;
+}
+
 #endif /* LIBSSH2_OPENSSL */
diff --git a/src/userauth.c b/src/userauth.c
index edfe729..afbe172 100644
--- a/src/userauth.c
+++ b/src/userauth.c
@@ -441,6 +441,76 @@ libssh2_userauth_password_ex(LIBSSH2_SESSION
*session, const char *username,
     return rc;
 }

+static int
+memory_read_publickey(LIBSSH2_SESSION * session, unsigned char **method,
+                      size_t *method_len,
+                      unsigned char **pubkeydata,
+                      size_t *pubkeydata_len,
+                      const char *pubkeyfiledata,
+                      size_t pubkeyfiledata_len)
+{
+    unsigned char *pubkey = NULL, *sp1, *sp2, *tmp;
+    size_t pubkey_len = pubkeyfiledata_len;
+    unsigned int tmp_len;
+
+    if (pubkeyfiledata_len <= 1) {
+        return _libssh2_error(session, LIBSSH2_ERROR_FILE,
+                              "Invalid data in public key file");
+    }
+
+    pubkey = LIBSSH2_ALLOC(session, pubkeyfiledata_len);
+    if (!pubkey) {
+        return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
+                              "Unable to allocate memory for public key data");
+    }
+
+    memcpy(pubkey, pubkeyfiledata, pubkeyfiledata_len);
+
+    /*
+     *   Remove trailing whitespace
+     */
+    while (pubkey_len && isspace(pubkey[pubkey_len - 1]))
+        pubkey_len--;
+
+    if (!pubkey_len) {
+        LIBSSH2_FREE(session, pubkey);
+        return _libssh2_error(session, LIBSSH2_ERROR_FILE,
+                              "Missing public key data");
+    }
+
+    if ((sp1 = memchr(pubkey, ' ', pubkey_len)) == NULL) {
+        LIBSSH2_FREE(session, pubkey);
+        return _libssh2_error(session, LIBSSH2_ERROR_FILE,
+                              "Invalid public key data");
+    }
+
+    sp1++;
+
+    if ((sp2 = memchr(sp1, ' ', pubkey_len - (sp1 - pubkey - 1))) == NULL) {
+        /* Assume that the id string is missing, but that it's okay */
+        sp2 = pubkey + pubkey_len;
+    }
+
+    if (libssh2_base64_decode(session, (char **) &tmp, &tmp_len,
+                              (char *) sp1, sp2 - sp1)) {
+        LIBSSH2_FREE(session, pubkey);
+        return _libssh2_error(session, LIBSSH2_ERROR_FILE,
+                                  "Invalid key data, not base64 encoded");
+    }
+
+    /* Wasting some bytes here (okay, more than some), but since it's likely
+     * to be freed soon anyway, we'll just avoid the extra free/alloc and call
+     * it a wash
+     */
+    *method = pubkey;
+    *method_len = sp1 - pubkey - 1;
+
+    *pubkeydata = tmp;
+    *pubkeydata_len = tmp_len;
+
+    return 0;
+}
+
 /*
  * file_read_publickey
  *
@@ -543,7 +613,43 @@ file_read_publickey(LIBSSH2_SESSION * session,
unsigned char **method,
     return 0;
 }

+static int
+memory_read_privatekey(LIBSSH2_SESSION * session,
+                       const LIBSSH2_HOSTKEY_METHOD ** hostkey_method,
+                       void **hostkey_abstract,
+                       const unsigned char *method, int method_len,
+                       const char *privkeyfiledata, size_t privkeyfiledata_len,
+                       const char *passphrase)
+{
+    const LIBSSH2_HOSTKEY_METHOD **hostkey_methods_avail =
+        libssh2_hostkey_methods();
+
+    *hostkey_method = NULL;
+    *hostkey_abstract = NULL;
+    while (*hostkey_methods_avail && (*hostkey_methods_avail)->name) {
+        if ((*hostkey_methods_avail)->initPEMFromMemory
+             && strncmp((*hostkey_methods_avail)->name, (const char *) method,
+                        method_len) == 0) {
+            *hostkey_method = *hostkey_methods_avail;
+            break;
+        }
+        hostkey_methods_avail++;
+    }
+    if (!*hostkey_method) {
+        return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NONE,
+                              "No handler for specified private key");
+    }
+
+    if ((*hostkey_method)->
+        initPEMFromMemory(session, privkeyfiledata, privkeyfiledata_len,
+                          (unsigned char *) passphrase,
+                          hostkey_abstract)) {
+        return _libssh2_error(session, LIBSSH2_ERROR_FILE,
+                              "Unable to initialize private key from file");
+    }

+    return 0;
+}

 /* libssh2_file_read_privatekey
  * Read a PEM encoded private key from an id_??? style file
@@ -592,6 +698,42 @@ struct privkey_file {
 };

 static int
+sign_frommemory(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
+                const unsigned char *data, size_t data_len, void **abstract)
+{
+    struct privkey_file *pk_file = (struct privkey_file *) (*abstract);
+    const LIBSSH2_HOSTKEY_METHOD *privkeyobj;
+    void *hostkey_abstract;
+    struct iovec datavec;
+    int rc;
+
+    rc = memory_read_privatekey(session, &privkeyobj, &hostkey_abstract,
+                                session->userauth_pblc_method,
+                                session->userauth_pblc_method_len,
+                                pk_file->filename,
+                                strlen(pk_file->filename),
+                                pk_file->passphrase);
+    if(rc)
+        return rc;
+
+    datavec.iov_base = (void *)data;
+    datavec.iov_len  = data_len;
+
+    if (privkeyobj->signv(session, sig, sig_len, 1, &datavec,
+                          &hostkey_abstract)) {
+        if (privkeyobj->dtor) {
+            privkeyobj->dtor(session, abstract);
+        }
+        return -1;
+    }
+
+    if (privkeyobj->dtor) {
+        privkeyobj->dtor(session, &hostkey_abstract);
+    }
+    return 0;
+}
+
+static int
 sign_fromfile(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
               const unsigned char *data, size_t data_len, void **abstract)
 {
@@ -1211,6 +1353,65 @@ _libssh2_userauth_publickey(LIBSSH2_SESSION *session,
                           "username/public key combination");
 }

+ /*
+  * userauth_publickey_frommemory
+  * Authenticate using a keypair from memory
+  */
+static int
+userauth_publickey_frommemory(LIBSSH2_SESSION *session,
+                              const char *username,
+                              size_t username_len,
+                              const char *publickeydata,
+                              size_t publickeydata_len,
+                              const char *privatekeydata,
+                              size_t privatekeydata_len,
+                              const char *passphrase)
+{
+    unsigned char *pubkeydata = NULL;
+    size_t pubkeydata_len = 0;
+    struct privkey_file privkey_file;
+    void *abstract = &privkey_file;
+    int rc;
+
+    privkey_file.filename = privatekeydata;
+    privkey_file.passphrase = passphrase;
+
+    if (session->userauth_pblc_state == libssh2_NB_state_idle) {
+        if (publickeydata_len && publickeydata) {
+            rc = memory_read_publickey(session, &session->userauth_pblc_method,
+                                       &session->userauth_pblc_method_len,
+                                       &pubkeydata, &pubkeydata_len,
+                                       publickeydata, publickeydata_len);
+            if(rc)
+                return rc;
+        }
+        else if (privatekeydata_len && privatekeydata) {
+            /* Compute public key from private key. */
+            if (_libssh2_pub_priv_keyfilememory(session,
+                                                &session->userauth_pblc_method,
+
&session->userauth_pblc_method_len,
+                                                &pubkeydata, &pubkeydata_len,
+                                                privatekeydata,
privatekeydata_len,
+                                                passphrase))
+                return _libssh2_error(session, LIBSSH2_ERROR_FILE,
+                                      "Unable to extract public key "
+                                      "from private key.");
+        }
+        else {
+            return _libssh2_error(session, LIBSSH2_ERROR_FILE,
+                                  "Invalid data in public and private key.");
+        }
+    }
+
+    rc = _libssh2_userauth_publickey(session, username, username_len,
+                                     pubkeydata, pubkeydata_len,
+                                     sign_frommemory, &abstract);
+    if(pubkeydata)
+        LIBSSH2_FREE(session, pubkeydata);
+
+    return rc;
+}
+
 /*
  * userauth_publickey_fromfile
  * Authenticate using a keypair found in the named files
@@ -1263,6 +1464,36 @@ userauth_publickey_fromfile(LIBSSH2_SESSION *session,
     return rc;
 }

+/* libssh2_userauth_publickey_frommemory
+ * Authenticate using a keypair from memory
+ */
+LIBSSH2_API int
+libssh2_userauth_publickey_frommemory_ex(LIBSSH2_SESSION *session,
+                                      const char *user,
+                                      unsigned int user_len,
+                                      const char *publickeyfiledata,
+                                      size_t publickeyfiledata_len,
+                                      const char *privatekeyfiledata,
+                                      size_t privatekeyfiledata_len,
+                                      const char *passphrase)
+{
+    int rc;
+
+    if(NULL == passphrase)
+        /* if given a NULL pointer, make it point to a zero-length
+           string to save us from having to check this all over */
+        passphrase="";
+
+    BLOCK_ADJUST(rc, session,
+                 userauth_publickey_frommemory(session, user, user_len,
+                                               publickeyfiledata,
+                                               publickeyfiledata_len,
+                                               privatekeyfiledata,
+                                               privatekeyfiledata_len,
+                                               passphrase));
+    return rc;
+}
+
 /* libssh2_userauth_publickey_fromfile_ex
  * Authenticate using a keypair found in the named files
  */


Thanks again,
David

On Sun, Sep 14, 2014 at 3:43 PM, Daniel Stenberg <daniel@haxx.se> wrote:

> On Wed, 10 Sep 2014, David Calavera wrote:
>
>  I was wondering if anyone had time to review my patch.
>>
>
> The idea seems reasonable to me, but I would prefer if you'd post the
> patch(es) for review here on the mailing list rather than pointing out
> something (on github) so that we can comment and discuss them here.
>
> I would also wouldn't mind to hear someone else voice their support for
> this functionality just to be sure that we're working on something more
> people actually find sensible to add.
>
> Personally I don't like the use of a macro that is the most widely used
> version of a function that then calls the actual *_ex() function - but I'm
> fully aware that we have a busload of functions done like that already...
>
> Does it also work when built to use gcrypt instead of OpenSSL?
>
> --
>
>  / daniel.haxx.se
> _______________________________________________
> libssh2-devel http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel
>

--047d7bd75b3003294e05030ec458
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Thanks for the comments Daniel.<div><br></div><blockquote =
class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1=
px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:=
1ex"><span style=3D"font-family:arial,sans-serif;font-size:13px">The idea s=
eems reasonable to me, but I would prefer if you&#39;d post the patch(es) f=
or review here on the mailing list rather than pointing out something (on g=
ithub) so that we can comment and discuss them here.</span></blockquote><di=
v><br></div><div>I&#39;m posting the code at the end of this email. I thoug=
ht it would be easier to read in a slightly richer view, since it&#39;s a s=
lightly big patch, but I totally understand it.</div><div><br></div><blockq=
uote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-wi=
dth:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-=
left:1ex"><span style=3D"font-family:arial,sans-serif;font-size:13px">I wou=
ld also wouldn&#39;t mind to hear someone else voice their support for this=
 functionality just to be sure that we&#39;re working on something more peo=
ple actually find sensible to add.</span></blockquote><div><br></div><div>F=
or what I&#39;ve seen, someone needed this back in the day, that&#39;s wher=
e I got the patch from=C2=A0<span style=3D"color:rgb(0,0,0);white-space:pre=
-wrap"><a href=3D"http://www.libssh2.org/mail/libssh2-devel-archive-2012-01=
/0015.shtml">http://www.libssh2.org/mail/libssh2-devel-archive-2012-01/0015=
.shtml</a></span></div><div><br></div><div>I also saw an initial attempt to=
 something similar in the trac:</div><div><a href=3D"http://trac.libssh2.or=
g/ticket/248">http://trac.libssh2.org/ticket/248</a></div><div><br></div><d=
iv>I&#39;d say that other people would find it useful, specially those that=
 use libssh2 as a dependency for their libraries. I&#39;m using it with lib=
git2 and the maintainers seemed interested when I talked to them.</div><div=
><br></div><div>I&#39;d love to hear from more people too.</div><div><br></=
div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;bor=
der-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:sol=
id;padding-left:1ex"><span style=3D"font-family:arial,sans-serif;font-size:=
13px">Personally I don&#39;t like the use of a macro that is the most widel=
y used version of a function that then calls the actual *_ex() function - b=
ut I&#39;m fully aware that we have a busload of functions done like that a=
lready...</span></blockquote><div><br></div><div>It&#39;s funny because the=
 original patch didn&#39;t have this macro. I added it because I saw the re=
st ones :)</div><div><br></div><blockquote class=3D"gmail_quote" style=3D"m=
argin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204=
,204);border-left-style:solid;padding-left:1ex"><span style=3D"font-family:=
arial,sans-serif;font-size:13px">Does it also work when built to use gcrypt=
 instead of OpenSSL?</span></blockquote><div>=C2=A0</div><div>I didn&#39;t =
try. Thanks for the reminder. I&#39;ll build it to use gcrypt and I&#39;ll =
let you know if I find any issue.</div><div><br></div><div>This is the patc=
h for everyone else to review:</div><div><br></div><div><pre style=3D"color=
:rgb(0,0,0);word-wrap:break-word;white-space:pre-wrap">From af088829281c105=
1486557a62f54604590849337 Mon Sep 17 00:00:00 2001
From: David Calavera &lt;<a href=3D"mailto:david.calavera@gmail.com">david.=
calavera@gmail.com</a>&gt;
Date: Mon, 1 Sep 2014 15:54:05 -0700
Subject: [PATCH] Allow authentication keys to be passed in memory.

All credits go to Joe Turpin, I&#39;m just reaplying and cleaning his patch=
:
<a href=3D"http://www.libssh2.org/mail/libssh2-devel-archive-2012-01/0015.s=
html">http://www.libssh2.org/mail/libssh2-devel-archive-2012-01/0015.shtml<=
/a>

* Adds libssh2_userauth_publickey_frommemory macro for libssh2_userauth_pub=
lickey_frommemory_ex.
---
 docs/libssh2_userauth_publickey_frommemory.3    |  22 +++
 docs/libssh2_userauth_publickey_frommemory_ex.3 |  55 ++++++
 include/libssh2.h                               |  20 ++
 src/crypto.h                                    |  16 ++
 src/hostkey.c                                   |  66 +++++++
 src/libssh2_priv.h                              |   3 +
 src/openssl.c                                   | 121 +++++++++++++
 src/userauth.c                                  | 231 ++++++++++++++++++++=
++++
 8 files changed, 534 insertions(+)
 create mode 100644 docs/libssh2_userauth_publickey_frommemory.3
 create mode 100644 docs/libssh2_userauth_publickey_frommemory_ex.3

diff --git a/docs/libssh2_userauth_publickey_frommemory.3 b/docs/libssh2_us=
erauth_publickey_frommemory.3
new file mode 100644
index 0000000..e464e71
--- /dev/null
+++ b/docs/libssh2_userauth_publickey_frommemory.3
@@ -0,0 +1,22 @@
+.TH libssh2_userauth_publickey_frommemory 3 &quot;1 Sep 2014&quot; &quot;l=
ibssh2 1.5&quot; &quot;libssh2 manual&quot;
+.SH NAME
+libssh2_userauth_publickey_frommemory - convenience macro for \fIlibssh2_u=
serauth_publickey_frommemory_ex(3)\fP calls
+.SH SYNOPSIS
+#include &lt;libssh2.h&gt;
+
+int
+libssh2_userauth_publickey_frommemory(LIBSSH2_SESSION *session,
+                                      const char *username,
+                                      const char *publickey,
+                                      const char *privatekey,
+                                      const char *passphrase);
+
+.SH DESCRIPTION
+This is a macro defined in a public libssh2 header file that is using the
+underlying function \fIlibssh2_userauth_publickey_frommemory_ex(3)\fP.
+.SH RETURN VALUE
+See \fIlibssh2_userauth_publickey_frommemory_ex(3)\fP
+.SH ERRORS
+See \fIlibssh2_userauth_publickey_frommemory_ex(3)\fP
+.SH SEE ALSO
+.BR libssh2_userauth_publickey_frommemory_ex(3)
diff --git a/docs/libssh2_userauth_publickey_frommemory_ex.3 b/docs/libssh2=
_userauth_publickey_frommemory_ex.3
new file mode 100644
index 0000000..6faf5d1
--- /dev/null
+++ b/docs/libssh2_userauth_publickey_frommemory_ex.3
@@ -0,0 +1,55 @@
+.TH libssh2_userauth_publickey_frommemory_ex 3 &quot;1 Sep 2014&quot; &quo=
t;libssh2 1.5&quot; &quot;libssh2 manual&quot;
+.SH NAME
+libssh2_userauth_publickey_frommemory_ex - authenticate a session with a p=
ublic key, read from memory
+.SH SYNOPSIS
+#include &lt;libssh2.h&gt;
+
+.nf
+int libssh2_userauth_publickey_frommemory_ex(LIBSSH2_SESSION *session,
+                                           const char *username,
+                                           unsigned int username_len,
+                                           const char *publickeydata,
+                                           size_t publickeydata_len,
+                                           const char *privatekeydata,
+                                           size_t privatekeydata_len,
+                                           const char *passphrase);
+.SH DESCRIPTION
+\fIsession\fP - Session instance as returned by
+.BR libssh2_session_init_ex(3)
+
+\fIusername\fP - Remote user name to authenticate as.
+
+\fIusername_len\fP - Length of username.
+
+\fIpublickeydata\fP - Buffer containing the contents of a public key file.
+
+\fIpublickeydata_len\fP - Length of public key data.
+
+\fIprivatekeydata\fP - Buffer containing the contents of a private key fil=
e.
+
+\fIprivatekeydata_len\fP - Length of private key data.
+
+\fIpassphrase\fP - Passphrase to use when decoding private key file.
+
+Attempt public key authentication using a PEM encoded private key file sto=
red in memory.
+
+.SH RETURN VALUE
+Return 0 on success or negative on failure.  It returns
+LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
+LIBSSH2_ERROR_EAGAIN is a negative number, it isn&#39;t really a failure p=
er se.
+
+.SH ERRORS
+\fILIBSSH2_ERROR_ALLOC\fP -  An internal memory allocation call failed.
+
+\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
+
+\fILIBSSH2_ERROR_SOCKET_TIMEOUT\fP -=20
+
+\fILIBSSH2_ERROR_PUBLICKEY_UNVERIFIED\fP - The username/public key
+combination was invalid.
+
+\fILIBSSH2_ERROR_AUTHENTICATION_FAILED\fP - Authentication using the suppl=
ied
+public key was not accepted.
+
+.SH SEE ALSO
+.BR libssh2_session_init_ex(3)
diff --git a/include/libssh2.h b/include/libssh2.h
index 565bf06..6e519db 100644
--- a/include/libssh2.h
+++ b/include/libssh2.h
@@ -576,6 +576,26 @@ libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION=
 *session,
                                         (username),                     \
                                         (unsigned int)strlen(username))
=20
+LIBSSH2_API int
+libssh2_userauth_publickey_frommemory_ex(LIBSSH2_SESSION *session,
+                                      const char *username,
+                                      unsigned int username_len,
+                                      const char *publickeyfiledata,
+                                      size_t publickeyfiledata_len,
+                                      const char *privatekeyfiledata,
+                                      size_t privatekeyfiledata_len,
+                                      const char *passphrase);
+
+#define libssh2_userauth_publickey_frommemory(session, username, publickey=
, \
+                                              privatekey, passphrase) \
+ libssh2_userauth_publickey_frommemory_ex((session), (username), \
+                                          (unsigned int)strlen(username), =
  \
+                                          (publickey),                    =
  \
+                                          (unsigned int)strlen(publickey),=
  \
+                                          (privatekey),                   =
  \
+                                          (unsigned int)strlen(privatekey)=
, \
+                                          (passphrase))
+
 /*
  * response_callback is provided with filled by library prompts array,
  * but client must allocate and fill individual responses. Responses
diff --git a/src/crypto.h b/src/crypto.h
index a615bb1..05f5a5c 100644
--- a/src/crypto.h
+++ b/src/crypto.h
@@ -80,6 +80,10 @@ int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
                            size_t hash_len,
                            unsigned char **signature,
                            size_t *signature_len);
+int _libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa,
+                                        LIBSSH2_SESSION * session,
+                                        const char *filedata, size_t filed=
ata_len,
+                                        unsigned const char *passphrase);
=20
 #if LIBSSH2_DSA
 int _libssh2_dsa_new(libssh2_dsa_ctx ** dsa,
@@ -102,6 +106,10 @@ int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
 int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
                            const unsigned char *hash,
                            unsigned long hash_len, unsigned char *sig);
+int _libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx ** dsa,
+                                        LIBSSH2_SESSION * session,
+                                        const char *filedata, size_t filed=
ata_len,
+                                        unsigned const char *passphrase);
 #endif
=20
 int _libssh2_cipher_init(_libssh2_cipher_ctx * h,
@@ -120,6 +128,14 @@ int _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session=
,
                               size_t *pubkeydata_len,
                               const char *privatekey,
                               const char *passphrase);
+int _libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
+                                    unsigned char **method,
+                                    size_t *method_len,
+                                    unsigned char **pubkeydata,
+                                    size_t *pubkeydata_len,
+                                    const char *privatekeydata,
+                                    size_t privatekeydata_len,
+                                    const char *passphrase);
=20
 void _libssh2_init_aes_ctr(void);
=20
diff --git a/src/hostkey.c b/src/hostkey.c
index 753563d..02d085a 100644
--- a/src/hostkey.c
+++ b/src/hostkey.c
@@ -131,6 +131,38 @@ hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION * sessi=
on,
 }
=20
 /*
+ * hostkey_method_ssh_rsa_initPEMFromMemory
+ *
+ * Load a Private Key from a memory
+ */
+static int
+hostkey_method_ssh_rsa_initPEMFromMemory(LIBSSH2_SESSION * session,
+                                         const char *privkeyfiledata,
+                                         size_t privkeyfiledata_len,
+                                         unsigned const char *passphrase,
+                                         void **abstract)
+{
+    libssh2_rsa_ctx *rsactx;
+    int ret;
+
+    if (*abstract) {
+        hostkey_method_ssh_rsa_dtor(session, abstract);
+        *abstract =3D NULL;
+    }
+
+    ret =3D _libssh2_rsa_new_private_frommemory(&amp;rsactx, session,
+                                              privkeyfiledata,
+                                              privkeyfiledata_len, passphr=
ase);
+    if (ret) {
+        return -1;
+    }
+
+    *abstract =3D rsactx;
+
+    return 0;
+}
+
+/*
  * hostkey_method_ssh_rsa_sign
  *
  * Verify signature created by remote
@@ -208,6 +240,7 @@ static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_=
rsa =3D {
     MD5_DIGEST_LENGTH,
     hostkey_method_ssh_rsa_init,
     hostkey_method_ssh_rsa_initPEM,
+    hostkey_method_ssh_rsa_initPEMFromMemory,
     hostkey_method_ssh_rsa_sig_verify,
     hostkey_method_ssh_rsa_signv,
     NULL,                       /* encrypt */
@@ -306,6 +339,38 @@ hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION * sessi=
on,
 }
=20
 /*
+ * hostkey_method_ssh_dss_initPEMFromMemory
+ *
+ * Load a Private Key from memory
+ */
+static int
+hostkey_method_ssh_dss_initPEMFromMemory(LIBSSH2_SESSION * session,
+                                         const char *privkeyfiledata,
+                                         size_t privkeyfiledata_len,
+                                         unsigned const char *passphrase,
+                                         void **abstract)
+{
+    libssh2_dsa_ctx *dsactx;
+    int ret;
+
+    if (*abstract) {
+        hostkey_method_ssh_dss_dtor(session, abstract);
+        *abstract =3D NULL;
+    }
+
+    ret =3D _libssh2_dsa_new_private_frommemory(&amp;dsactx, session,
+                                              privkeyfiledata,
+                                              privkeyfiledata_len, passphr=
ase);
+    if (ret) {
+        return -1;
+    }
+
+    *abstract =3D dsactx;
+
+    return 0;
+}
+
+/*
  * libssh2_hostkey_method_ssh_dss_sign
  *
  * Verify signature created by remote
@@ -392,6 +457,7 @@ static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_=
dss =3D {
     MD5_DIGEST_LENGTH,
     hostkey_method_ssh_dss_init,
     hostkey_method_ssh_dss_initPEM,
+    hostkey_method_ssh_dss_initPEMFromMemory,
     hostkey_method_ssh_dss_sig_verify,
     hostkey_method_ssh_dss_signv,
     NULL,                       /* encrypt */
diff --git a/src/libssh2_priv.h b/src/libssh2_priv.h
index 00ed240..0274d83 100644
--- a/src/libssh2_priv.h
+++ b/src/libssh2_priv.h
@@ -853,6 +853,9 @@ struct _LIBSSH2_HOSTKEY_METHOD
                  size_t hostkey_data_len, void **abstract);
     int (*initPEM) (LIBSSH2_SESSION * session, const char *privkeyfile,
                     unsigned const char *passphrase, void **abstract);
+    int (*initPEMFromMemory) (LIBSSH2_SESSION * session,
+                              const char *privkeyfiledata, size_t privkeyf=
iledata_len,
+                              unsigned const char *passphrase, void **abst=
ract);
     int (*sig_verify) (LIBSSH2_SESSION * session, const unsigned char *sig=
,
                        size_t sig_len, const unsigned char *m,
                        size_t m_len, void **abstract);
diff --git a/src/openssl.c b/src/openssl.c
index 056b0b7..2e31472 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -388,6 +388,28 @@ typedef void * (*pem_read_bio_func)(BIO *, void **, pe=
m_password_cb *,
                                     void * u);
=20
 static int
+read_private_key_from_memory(void ** key_ctx,
+                             pem_read_bio_func read_private_key,
+                             const char * filedata,
+                             size_t filedata_len,
+                             unsigned const char *passphrase)
+{
+    BIO * bp;
+
+    *key_ctx =3D NULL;
+
+    bp =3D BIO_new_mem_buf(filedata, filedata_len);
+    if (!bp) {
+        return -1;
+    }
+    *key_ctx =3D read_private_key(bp, NULL, (pem_password_cb *) passphrase=
_cb,
+                                (void *) passphrase);
+
+    BIO_free(bp);
+    return (*key_ctx) ? 0 : -1;
+}
+
+static int
 read_private_key_from_file(void ** key_ctx,
                            pem_read_bio_func read_private_key,
                            const char * filename,
@@ -409,6 +431,22 @@ read_private_key_from_file(void ** key_ctx,
     return (*key_ctx) ? 0 : -1;
 }
=20
+ int
+_libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa,
+                                    LIBSSH2_SESSION * session,
+                                    const char *filedata, size_t filedata_=
len,
+                                    unsigned const char *passphrase)
+{
+    pem_read_bio_func read_rsa =3D
+        (pem_read_bio_func) &amp;PEM_read_bio_RSAPrivateKey;
+    (void) session;
+
+    _libssh2_init_if_needed();
+
+    return read_private_key_from_memory((void **) rsa, read_rsa,
+                                        filedata, filedata_len, passphrase=
);
+}
+
 int
 _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
                          LIBSSH2_SESSION * session,
@@ -426,6 +464,22 @@ _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
=20
 #if LIBSSH2_DSA
 int
+_libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx ** dsa,
+                                    LIBSSH2_SESSION * session,
+                                    const char *filedata, size_t filedata_=
len,
+                                    unsigned const char *passphrase)
+{
+    pem_read_bio_func read_dsa =3D
+        (pem_read_bio_func) &amp;PEM_read_bio_DSAPrivateKey;
+    (void) session;
+
+    _libssh2_init_if_needed();
+
+    return read_private_key_from_memory((void **) dsa, read_dsa,
+                                        filedata, filedata_len, passphrase=
);
+}
+
+int
 _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
                          LIBSSH2_SESSION * session,
                          const char *filename, unsigned const char *passph=
rase)
@@ -817,4 +871,71 @@ _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session,
     return st;
 }
=20
+int
+_libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
+                                unsigned char **method,
+                                size_t *method_len,
+                                unsigned char **pubkeydata,
+                                size_t *pubkeydata_len,
+                                const char *privatekeydata,
+                                size_t privatekeydata_len,
+                                const char *passphrase)
+{
+    int       st;
+    BIO*      bp;
+    EVP_PKEY* pk;
+
+    _libssh2_debug(session,
+                   LIBSSH2_TRACE_AUTH,
+                   &quot;Computing public key from private key.&quot;);
+
+    bp =3D BIO_new_mem_buf(privatekeydata, privatekeydata_len);
+    if (!bp) {
+        return -1;
+    }
+    if (!EVP_get_cipherbyname(&quot;des&quot;)) {
+        /* If this cipher isn&#39;t loaded it&#39;s a pretty good indicati=
on that none
+         * are.  I have *NO DOUBT* that there&#39;s a better way to deal w=
ith this
+         * ($#&amp;%#$(%$#( Someone buy me an OpenSSL manual and I&#39;ll =
read up on
+         * it.
+         */
+        OpenSSL_add_all_ciphers();
+    }
+    BIO_reset(bp);
+    pk =3D PEM_read_bio_PrivateKey(bp, NULL, NULL, (void*)passphrase);
+    BIO_free(bp);
+
+    if (pk =3D=3D NULL) {
+        return _libssh2_error(session,
+                              LIBSSH2_ERROR_FILE,
+                              &quot;Unable to extract public key &quot;
+                              &quot;from private key file: &quot;
+                              &quot;Wrong passphrase or invalid/unrecogniz=
ed &quot;
+                              &quot;private key file format&quot;);
+    }
+
+    switch (pk-&gt;type) {
+    case EVP_PKEY_RSA :
+        st =3D gen_publickey_from_rsa_evp(session, method, method_len,
+                                        pubkeydata, pubkeydata_len, pk);
+        break;
+
+    case EVP_PKEY_DSA :
+        st =3D gen_publickey_from_dsa_evp(session, method, method_len,
+                                        pubkeydata, pubkeydata_len, pk);
+        break;
+
+    default :
+        st =3D _libssh2_error(session,
+                            LIBSSH2_ERROR_FILE,
+                            &quot;Unable to extract public key &quot;
+                            &quot;from private key file: &quot;
+                            &quot;Unsupported private key file format&quot=
;);
+        break;
+    }
+
+    EVP_PKEY_free(pk);
+    return st;
+}
+
 #endif /* LIBSSH2_OPENSSL */
diff --git a/src/userauth.c b/src/userauth.c
index edfe729..afbe172 100644
--- a/src/userauth.c
+++ b/src/userauth.c
@@ -441,6 +441,76 @@ libssh2_userauth_password_ex(LIBSSH2_SESSION *session,=
 const char *username,
     return rc;
 }
=20
+static int
+memory_read_publickey(LIBSSH2_SESSION * session, unsigned char **method,
+                      size_t *method_len,
+                      unsigned char **pubkeydata,
+                      size_t *pubkeydata_len,
+                      const char *pubkeyfiledata,
+                      size_t pubkeyfiledata_len)
+{
+    unsigned char *pubkey =3D NULL, *sp1, *sp2, *tmp;
+    size_t pubkey_len =3D pubkeyfiledata_len;
+    unsigned int tmp_len;
+
+    if (pubkeyfiledata_len &lt;=3D 1) {
+        return _libssh2_error(session, LIBSSH2_ERROR_FILE,
+                              &quot;Invalid data in public key file&quot;)=
;
+    }
+
+    pubkey =3D LIBSSH2_ALLOC(session, pubkeyfiledata_len);
+    if (!pubkey) {
+        return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
+                              &quot;Unable to allocate memory for public k=
ey data&quot;);
+    }
+
+    memcpy(pubkey, pubkeyfiledata, pubkeyfiledata_len);
+
+    /*
+     *   Remove trailing whitespace
+     */
+    while (pubkey_len &amp;&amp; isspace(pubkey[pubkey_len - 1]))
+        pubkey_len--;
+
+    if (!pubkey_len) {
+        LIBSSH2_FREE(session, pubkey);
+        return _libssh2_error(session, LIBSSH2_ERROR_FILE,
+                              &quot;Missing public key data&quot;);
+    }
+
+    if ((sp1 =3D memchr(pubkey, &#39; &#39;, pubkey_len)) =3D=3D NULL) {
+        LIBSSH2_FREE(session, pubkey);
+        return _libssh2_error(session, LIBSSH2_ERROR_FILE,
+                              &quot;Invalid public key data&quot;);
+    }
+
+    sp1++;
+
+    if ((sp2 =3D memchr(sp1, &#39; &#39;, pubkey_len - (sp1 - pubkey - 1))=
) =3D=3D NULL) {
+        /* Assume that the id string is missing, but that it&#39;s okay */
+        sp2 =3D pubkey + pubkey_len;
+    }
+
+    if (libssh2_base64_decode(session, (char **) &amp;tmp, &amp;tmp_len,
+                              (char *) sp1, sp2 - sp1)) {
+        LIBSSH2_FREE(session, pubkey);
+        return _libssh2_error(session, LIBSSH2_ERROR_FILE,
+                                  &quot;Invalid key data, not base64 encod=
ed&quot;);
+    }
+
+    /* Wasting some bytes here (okay, more than some), but since it&#39;s =
likely
+     * to be freed soon anyway, we&#39;ll just avoid the extra free/alloc =
and call
+     * it a wash
+     */
+    *method =3D pubkey;
+    *method_len =3D sp1 - pubkey - 1;
+
+    *pubkeydata =3D tmp;
+    *pubkeydata_len =3D tmp_len;
+
+    return 0;
+}
+
 /*
  * file_read_publickey
  *
@@ -543,7 +613,43 @@ file_read_publickey(LIBSSH2_SESSION * session, unsigne=
d char **method,
     return 0;
 }
=20
+static int
+memory_read_privatekey(LIBSSH2_SESSION * session,
+                       const LIBSSH2_HOSTKEY_METHOD ** hostkey_method,
+                       void **hostkey_abstract,
+                       const unsigned char *method, int method_len,
+                       const char *privkeyfiledata, size_t privkeyfiledata=
_len,
+                       const char *passphrase)
+{
+    const LIBSSH2_HOSTKEY_METHOD **hostkey_methods_avail =3D
+        libssh2_hostkey_methods();
+
+    *hostkey_method =3D NULL;
+    *hostkey_abstract =3D NULL;
+    while (*hostkey_methods_avail &amp;&amp; (*hostkey_methods_avail)-&gt;=
name) {
+        if ((*hostkey_methods_avail)-&gt;initPEMFromMemory
+             &amp;&amp; strncmp((*hostkey_methods_avail)-&gt;name, (const =
char *) method,
+                        method_len) =3D=3D 0) {
+            *hostkey_method =3D *hostkey_methods_avail;
+            break;
+        }
+        hostkey_methods_avail++;
+    }
+    if (!*hostkey_method) {
+        return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NONE,
+                              &quot;No handler for specified private key&q=
uot;);
+    }
+
+    if ((*hostkey_method)-&gt;
+        initPEMFromMemory(session, privkeyfiledata, privkeyfiledata_len,
+                          (unsigned char *) passphrase,
+                          hostkey_abstract)) {
+        return _libssh2_error(session, LIBSSH2_ERROR_FILE,
+                              &quot;Unable to initialize private key from =
file&quot;);
+    }
=20
+    return 0;
+}
=20
 /* libssh2_file_read_privatekey
  * Read a PEM encoded private key from an id_??? style file
@@ -592,6 +698,42 @@ struct privkey_file {
 };
=20
 static int
+sign_frommemory(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig=
_len,
+                const unsigned char *data, size_t data_len, void **abstrac=
t)
+{
+    struct privkey_file *pk_file =3D (struct privkey_file *) (*abstract);
+    const LIBSSH2_HOSTKEY_METHOD *privkeyobj;
+    void *hostkey_abstract;
+    struct iovec datavec;
+    int rc;
+
+    rc =3D memory_read_privatekey(session, &amp;privkeyobj, &amp;hostkey_a=
bstract,
+                                session-&gt;userauth_pblc_method,
+                                session-&gt;userauth_pblc_method_len,
+                                pk_file-&gt;filename,
+                                strlen(pk_file-&gt;filename),
+                                pk_file-&gt;passphrase);
+    if(rc)
+        return rc;
+
+    datavec.iov_base =3D (void *)data;
+    datavec.iov_len  =3D data_len;
+
+    if (privkeyobj-&gt;signv(session, sig, sig_len, 1, &amp;datavec,
+                          &amp;hostkey_abstract)) {
+        if (privkeyobj-&gt;dtor) {
+            privkeyobj-&gt;dtor(session, abstract);
+        }
+        return -1;
+    }
+
+    if (privkeyobj-&gt;dtor) {
+        privkeyobj-&gt;dtor(session, &amp;hostkey_abstract);
+    }
+    return 0;
+}
+
+static int
 sign_fromfile(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_l=
en,
               const unsigned char *data, size_t data_len, void **abstract)
 {
@@ -1211,6 +1353,65 @@ _libssh2_userauth_publickey(LIBSSH2_SESSION *session=
,
                           &quot;username/public key combination&quot;);
 }
=20
+ /*
+  * userauth_publickey_frommemory
+  * Authenticate using a keypair from memory
+  */
+static int
+userauth_publickey_frommemory(LIBSSH2_SESSION *session,
+                              const char *username,
+                              size_t username_len,
+                              const char *publickeydata,
+                              size_t publickeydata_len,
+                              const char *privatekeydata,
+                              size_t privatekeydata_len,
+                              const char *passphrase)
+{
+    unsigned char *pubkeydata =3D NULL;
+    size_t pubkeydata_len =3D 0;
+    struct privkey_file privkey_file;
+    void *abstract =3D &amp;privkey_file;
+    int rc;
+
+    privkey_file.filename =3D privatekeydata;
+    privkey_file.passphrase =3D passphrase;
+
+    if (session-&gt;userauth_pblc_state =3D=3D libssh2_NB_state_idle) {
+        if (publickeydata_len &amp;&amp; publickeydata) {
+            rc =3D memory_read_publickey(session, &amp;session-&gt;useraut=
h_pblc_method,
+                                       &amp;session-&gt;userauth_pblc_meth=
od_len,
+                                       &amp;pubkeydata, &amp;pubkeydata_le=
n,
+                                       publickeydata, publickeydata_len);
+            if(rc)
+                return rc;
+        }
+        else if (privatekeydata_len &amp;&amp; privatekeydata) {
+            /* Compute public key from private key. */
+            if (_libssh2_pub_priv_keyfilememory(session,
+                                                &amp;session-&gt;userauth_=
pblc_method,
+                                                &amp;session-&gt;userauth_=
pblc_method_len,
+                                                &amp;pubkeydata, &amp;pubk=
eydata_len,
+                                                privatekeydata, privatekey=
data_len,
+                                                passphrase))
+                return _libssh2_error(session, LIBSSH2_ERROR_FILE,
+                                      &quot;Unable to extract public key &=
quot;
+                                      &quot;from private key.&quot;);
+        }
+        else {
+            return _libssh2_error(session, LIBSSH2_ERROR_FILE,
+                                  &quot;Invalid data in public and private=
 key.&quot;);
+        }
+    }
+
+    rc =3D _libssh2_userauth_publickey(session, username, username_len,
+                                     pubkeydata, pubkeydata_len,
+                                     sign_frommemory, &amp;abstract);
+    if(pubkeydata)
+        LIBSSH2_FREE(session, pubkeydata);
+
+    return rc;
+}
+
 /*
  * userauth_publickey_fromfile
  * Authenticate using a keypair found in the named files
@@ -1263,6 +1464,36 @@ userauth_publickey_fromfile(LIBSSH2_SESSION *session=
,
     return rc;
 }
=20
+/* libssh2_userauth_publickey_frommemory
+ * Authenticate using a keypair from memory
+ */
+LIBSSH2_API int
+libssh2_userauth_publickey_frommemory_ex(LIBSSH2_SESSION *session,
+                                      const char *user,
+                                      unsigned int user_len,
+                                      const char *publickeyfiledata,
+                                      size_t publickeyfiledata_len,
+                                      const char *privatekeyfiledata,
+                                      size_t privatekeyfiledata_len,
+                                      const char *passphrase)
+{
+    int rc;
+
+    if(NULL =3D=3D passphrase)
+        /* if given a NULL pointer, make it point to a zero-length
+           string to save us from having to check this all over */
+        passphrase=3D&quot;&quot;;
+
+    BLOCK_ADJUST(rc, session,
+                 userauth_publickey_frommemory(session, user, user_len,
+                                               publickeyfiledata,
+                                               publickeyfiledata_len,
+                                               privatekeyfiledata,
+                                               privatekeyfiledata_len,
+                                               passphrase));
+    return rc;
+}
+
 /* libssh2_userauth_publickey_fromfile_ex
  * Authenticate using a keypair found in the named files
  */</pre></div><div><br></div><div>Thanks again,</div><div>David</div></di=
v><div class=3D"gmail_extra"><br><div class=3D"gmail_quote">On Sun, Sep 14,=
 2014 at 3:43 PM, Daniel Stenberg <span dir=3D"ltr">&lt;<a href=3D"mailto:d=
aniel@haxx.se" target=3D"_blank">daniel@haxx.se</a>&gt;</span> wrote:<br><b=
lockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px =
#ccc solid;padding-left:1ex"><span class=3D"">On Wed, 10 Sep 2014, David Ca=
lavera wrote:<br>
<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">
I was wondering if anyone had time to review my patch.<br>
</blockquote>
<br></span>
The idea seems reasonable to me, but I would prefer if you&#39;d post the p=
atch(es) for review here on the mailing list rather than pointing out somet=
hing (on github) so that we can comment and discuss them here.<br>
<br>
I would also wouldn&#39;t mind to hear someone else voice their support for=
 this functionality just to be sure that we&#39;re working on something mor=
e people actually find sensible to add.<br>
<br>
Personally I don&#39;t like the use of a macro that is the most widely used=
 version of a function that then calls the actual *_ex() function - but I&#=
39;m fully aware that we have a busload of functions done like that already=
...<br>
<br>
Does it also work when built to use gcrypt instead of OpenSSL?<span class=
=3D"HOEnZb"><font color=3D"#888888"><br>
<br>
-- <br>
<br>
=C2=A0/ <a href=3D"http://daniel.haxx.se" target=3D"_blank">daniel.haxx.se<=
/a><br>
______________________________<u></u>_________________<br>
libssh2-devel <a href=3D"http://cool.haxx.se/cgi-bin/mailman/listinfo/libss=
h2-devel" target=3D"_blank">http://cool.haxx.se/cgi-bin/<u></u>mailman/list=
info/libssh2-devel</a><br>
</font></span></blockquote></div><br></div>

--047d7bd75b3003294e05030ec458--

--===============0696410535==
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: base64
Content-Disposition: inline

X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KbGlic3NoMi1k
ZXZlbCBodHRwOi8vY29vbC5oYXh4LnNlL2NnaS1iaW4vbWFpbG1hbi9saXN0aW5mby9saWJzc2gy
LWRldmVsCg==

--===============0696410535==--

From libssh2-devel-bounces@cool.haxx.se  Mon Sep 15 05:55:56 2014
Return-Path: <libssh2-devel-bounces@cool.haxx.se>
Received: from www.haxx.se (localhost.localdomain [127.0.0.1])
	by giant.haxx.se (8.14.4/8.14.4/Debian-7) with ESMTP id s8F0PpMA013830;
	Mon, 15 Sep 2014 02:26:10 +0200
Received: from foo.stuge.se (qmailr@foo.stuge.se [212.116.89.98])
 by giant.haxx.se (8.14.4/8.14.4/Debian-7) with ESMTP id s8F0Pn3k013741
 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT)
 for <libssh2-devel@cool.haxx.se>; Mon, 15 Sep 2014 02:25:49 +0200
Received: (qmail 5537 invoked by uid 501); 15 Sep 2014 00:25:50 -0000
Message-ID: <20140915002550.5536.qmail@stuge.se>
Date: Mon, 15 Sep 2014 02:25:50 +0200
From: Peter Stuge <peter@stuge.se>
To: libssh2-devel@cool.haxx.se
Subject: Re: Allow authentication to be passed in memory - blast from the past
Mail-Followup-To: libssh2-devel@cool.haxx.se
References: <CAH7nXcu2pM_WhPtVqPa5Vz8tqS_0sSQPGYR0bZ8kCS_bD+13wA@mail.gmail.com>
 <CAH7nXcvbPouEsLsPSF94cgfMMpEVp1XCpgDSBhJbaWojUmvi_g@mail.gmail.com>
 <CAH7nXcuwV=DjGFfuqUsHL0OD2WvaDyCfcoqQk7gjBY2uYMh0yg@mail.gmail.com>
 <CAH7nXcuA13Dfu91feDg=82UzFto=8sSY+WCtBzTQLvtgGnAGuA@mail.gmail.com>
 <alpine.DEB.2.00.1409150009240.18125@tvnag.unkk.fr>
 <CAH7nXctMTKesMeZzYU3Py-gLH0DFswtmo6y_2cHNAf-fsRtrEQ@mail.gmail.com>
MIME-Version: 1.0
Content-Disposition: inline
In-Reply-To: <CAH7nXctMTKesMeZzYU3Py-gLH0DFswtmo6y_2cHNAf-fsRtrEQ@mail.gmail.com>
X-BeenThere: libssh2-devel@cool.haxx.se
X-Mailman-Version: 2.1.16
Precedence: list
Reply-To: libssh2 development <libssh2-devel@cool.haxx.se>
List-Id: libssh2 development <libssh2-devel.cool.haxx.se>
List-Unsubscribe: <http://cool.haxx.se/cgi-bin/mailman/options/libssh2-devel>, 
 <mailto:libssh2-devel-request@cool.haxx.se?subject=unsubscribe>
List-Archive: <http://cool.haxx.se/pipermail/libssh2-devel/>
List-Post: <mailto:libssh2-devel@cool.haxx.se>
List-Help: <mailto:libssh2-devel-request@cool.haxx.se?subject=help>
List-Subscribe: <http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel>, 
 <mailto:libssh2-devel-request@cool.haxx.se?subject=subscribe>
Content-Type: text/plain; charset="utf-8"
Errors-To: libssh2-devel-bounces@cool.haxx.se
Sender: "libssh2-devel" <libssh2-devel-bounces@cool.haxx.se>
Content-Transfer-Encoding: 8bit
X-MIME-Autoconverted: from base64 to 8bit by giant.haxx.se id s8F0PpMA013830

David Calavera wrote:
> I'd love to hear from more people too.

I don't mind adding this functionality, but I *do* mind adding
anything that isn't supported across all different crypto libraries.


> > Does it also work when built to use gcrypt instead of OpenSSL?
> 
> I didn't try.

That's just sad. :\

You make OpenSSL calls and only add the functionality to the
openssl.c file so your patch can not work with anything but
OpenSSL, and I for one want that addressed before I consider
the patch ready for inclusion.


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

From libssh2-devel-bounces@cool.haxx.se  Mon Sep 15 08:58:42 2014
Return-Path: <libssh2-devel-bounces@cool.haxx.se>
Received: from www.haxx.se (localhost.localdomain [127.0.0.1])
	by giant.haxx.se (8.14.4/8.14.4/Debian-7) with ESMTP id s8F4R7Ca002491;
	Mon, 15 Sep 2014 06:27:27 +0200
Received: from mail-la0-f53.google.com (mail-la0-f53.google.com
 [209.85.215.53])
 by giant.haxx.se (8.14.4/8.14.4/Debian-7) with ESMTP id s8F4R493001769
 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-RC4-SHA bits=128 verify=NOT)
 for <libssh2-devel@cool.haxx.se>; Mon, 15 Sep 2014 06:27:05 +0200
Received: by mail-la0-f53.google.com with SMTP id ge10so3740839lab.26
 for <libssh2-devel@cool.haxx.se>; Sun, 14 Sep 2014 21:26:59 -0700 (PDT)
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20130820;
 h=x-gm-message-state:from:references:in-reply-to:mime-version
 :thread-index:date:message-id:subject:to:content-type;
 bh=ZnJ8TKUWY6WQAXaHPVgNbmjv4jDfnqIJDEHUM0fmCNo=;
 b=MD2HFi5bra2u6Ehs8kbJM+pirBjZDcgbqvcJmu/Ybpd8QINF6CI1F245QXy6s2/Kxk
 3fSqUHkcOe+fAS20swxtECMrIMYI4DeJiB19ZKhsoB0CRGnmqCAaAgSdBN62T7sSqRcv
 tsFFco1IofJQc4paP8OjrRdmC58GFYkkyvX6sO3enqSw5zeEwoZrS08lq+jeVFh59sBJ
 WVlxtQgknbcB0uIyQFHy8remi/Sx8O20vDDVxHPcEFORTyw5vxUCj6bAHZaPjQFdgMDH
 s9aV2ERczNxg7KKHqYbjKV+ciBgTUEqLcLaEbfxsIa+JaawBMmslyTT0AFYZD4RTJ4AQ
 N1Gw==
X-Gm-Message-State: ALoCoQmkusEeWsTJyKABefF0KCKOurXF9KALqqNpwWo+OWy8HW53z1thzLrJ5bycpHDIH4aaaKCt
X-Received: by 10.112.55.102 with SMTP id r6mr23568518lbp.23.1410755219335;
 Sun, 14 Sep 2014 21:26:59 -0700 (PDT)
From: Nitin Deokate <ndeokate@qualys.com>
References: <20140829084531.GA20487@joerntop.localnet>
 <CA+z1VpNTdB2GFWA8yt1u8gjDArwKHVYnuMwwWV+vn76AufqOzg@mail.gmail.com>
 <alpine.DEB.2.00.1409150035100.18125@tvnag.unkk.fr>
In-Reply-To: <alpine.DEB.2.00.1409150035100.18125@tvnag.unkk.fr>
MIME-Version: 1.0
X-Mailer: Microsoft Outlook 14.0
Thread-Index: AQFordg0HBhVBiT7hxzSqKAqYbXYmgHDZFH7AOXbsRucupLlgA==
Date: Mon, 15 Sep 2014 09:56:56 +0530
Message-ID: <8abfef00a5f00ef3968e157f5da39e93@mail.gmail.com>
Subject: RE: Download text file via SFTP
To: libssh2 development <libssh2-devel@cool.haxx.se>
X-BeenThere: libssh2-devel@cool.haxx.se
X-Mailman-Version: 2.1.16
Precedence: list
Reply-To: libssh2 development <libssh2-devel@cool.haxx.se>
List-Id: libssh2 development <libssh2-devel.cool.haxx.se>
List-Unsubscribe: <http://cool.haxx.se/cgi-bin/mailman/options/libssh2-devel>, 
 <mailto:libssh2-devel-request@cool.haxx.se?subject=unsubscribe>
List-Archive: <http://cool.haxx.se/pipermail/libssh2-devel/>
List-Post: <mailto:libssh2-devel@cool.haxx.se>
List-Help: <mailto:libssh2-devel-request@cool.haxx.se?subject=help>
List-Subscribe: <http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel>, 
 <mailto:libssh2-devel-request@cool.haxx.se?subject=subscribe>
Content-Type: text/plain; charset="utf-8"
Errors-To: libssh2-devel-bounces@cool.haxx.se
Sender: "libssh2-devel" <libssh2-devel-bounces@cool.haxx.se>
Content-Transfer-Encoding: 8bit
X-MIME-Autoconverted: from base64 to 8bit by giant.haxx.se id s8F4R7Ca002491

Hi Daniel,
No, in this context "this" means the complete problem.

We are getting 2000 bytes in every read call(FYI, I have tried this with low
latency and high latency,
results are same.) and according to you(in older mail thread), we should get
higher chunks in
subsequent calls, which does not happen in any way. Now Joern also
faces the same issue which I faced earlier.

Making the MAX_SFTP_READ_SIZE configurable will solve the issue but
it does not mean we have resolved it completely as we don't get results
which we should(i.e. read returns more bytes in subsequent calls).

Thanks,
Nitin

-----Original Message-----
From: libssh2-devel [mailto:libssh2-devel-bounces@cool.haxx.se] On Behalf Of
Daniel Stenberg
Sent: Monday, September 15, 2014 4:06 AM
To: libssh2 development
Subject: Re: Download text file via SFTP

On Sat, 13 Sep 2014, Nitin Deokate wrote:

> Anybody has thoughts on this?

"this" being an option to change the "slice size" ?

-- 

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

From libssh2-devel-bounces@cool.haxx.se  Mon Sep 15 09:34:20 2014
Return-Path: <libssh2-devel-bounces@cool.haxx.se>
Received: from www.haxx.se (localhost.localdomain [127.0.0.1])
	by giant.haxx.se (8.14.4/8.14.4/Debian-7) with ESMTP id s8F7XtnH031739;
	Mon, 15 Sep 2014 09:34:17 +0200
Received: from foo.stuge.se (qmailr@foo.stuge.se [212.116.89.98])
 by giant.haxx.se (8.14.4/8.14.4/Debian-7) with ESMTP id s8F7XsCC031733
 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT)
 for <libssh2-devel@cool.haxx.se>; Mon, 15 Sep 2014 09:33:54 +0200
Received: (qmail 3818 invoked by uid 501); 15 Sep 2014 07:33:54 -0000
Message-ID: <20140915073354.3817.qmail@stuge.se>
Date: Mon, 15 Sep 2014 09:33:54 +0200
From: Peter Stuge <peter@stuge.se>
To: libssh2-devel@cool.haxx.se
Subject: Re: Download text file via SFTP
Mail-Followup-To: libssh2-devel@cool.haxx.se
References: <20140829084531.GA20487@joerntop.localnet>
 <CA+z1VpNTdB2GFWA8yt1u8gjDArwKHVYnuMwwWV+vn76AufqOzg@mail.gmail.com>
 <alpine.DEB.2.00.1409150035100.18125@tvnag.unkk.fr>
 <8abfef00a5f00ef3968e157f5da39e93@mail.gmail.com>
MIME-Version: 1.0
Content-Disposition: inline
In-Reply-To: <8abfef00a5f00ef3968e157f5da39e93@mail.gmail.com>
X-BeenThere: libssh2-devel@cool.haxx.se
X-Mailman-Version: 2.1.16
Precedence: list
Reply-To: libssh2 development <libssh2-devel@cool.haxx.se>
List-Id: libssh2 development <libssh2-devel.cool.haxx.se>
List-Unsubscribe: <http://cool.haxx.se/cgi-bin/mailman/options/libssh2-devel>, 
 <mailto:libssh2-devel-request@cool.haxx.se?subject=unsubscribe>
List-Archive: <http://cool.haxx.se/pipermail/libssh2-devel/>
List-Post: <mailto:libssh2-devel@cool.haxx.se>
List-Help: <mailto:libssh2-devel-request@cool.haxx.se?subject=help>
List-Subscribe: <http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel>, 
 <mailto:libssh2-devel-request@cool.haxx.se?subject=subscribe>
Content-Type: text/plain; charset="utf-8"
Errors-To: libssh2-devel-bounces@cool.haxx.se
Sender: "libssh2-devel" <libssh2-devel-bounces@cool.haxx.se>
Content-Transfer-Encoding: 8bit
X-MIME-Autoconverted: from base64 to 8bit by giant.haxx.se id s8F7XtnH031739

Nitin Deokate wrote:
> according to you(in older mail thread), we should get higher chunks in
> subsequent calls, which does not happen in any way.

Focus on this - this seems to be the actual issue.


> Making the MAX_SFTP_READ_SIZE configurable will solve the issue

Changing that parameter seems like a workaround which ignores the
actual issue - if chunk size is supposed to increase automatically.


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

From libssh2-devel-bounces@cool.haxx.se  Mon Sep 15 09:38:26 2014
Return-Path: <libssh2-devel-bounces@cool.haxx.se>
Received: from www.haxx.se (localhost.localdomain [127.0.0.1])
	by giant.haxx.se (8.14.4/8.14.4/Debian-7) with ESMTP id s8F7cOd9012187;
	Mon, 15 Sep 2014 09:38:25 +0200
Received: from giant.haxx.se (localhost.localdomain [127.0.0.1])
 by giant.haxx.se (8.14.4/8.14.4/Debian-7) with ESMTP id s8F7cMYu012168
 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT)
 for <libssh2-devel@cool.haxx.se>; Mon, 15 Sep 2014 09:38:22 +0200
Received: from localhost (dast@localhost)
 by giant.haxx.se (8.14.4/8.14.4/Submit) with ESMTP id s8F7cMLi012163
 for <libssh2-devel@cool.haxx.se>; Mon, 15 Sep 2014 09:38:22 +0200
X-Authentication-Warning: giant.haxx.se: dast owned process doing -bs
Date: Mon, 15 Sep 2014 09:38:22 +0200 (CEST)
From: Daniel Stenberg <daniel@haxx.se>
X-X-Sender: dast@giant.haxx.se
To: libssh2 development <libssh2-devel@cool.haxx.se>
Subject: Re: Download text file via SFTP
In-Reply-To: <20140915073354.3817.qmail@stuge.se>
Message-ID: <alpine.DEB.2.00.1409150935440.18125@tvnag.unkk.fr>
References: <20140829084531.GA20487@joerntop.localnet>
 <CA+z1VpNTdB2GFWA8yt1u8gjDArwKHVYnuMwwWV+vn76AufqOzg@mail.gmail.com>
 <alpine.DEB.2.00.1409150035100.18125@tvnag.unkk.fr>
 <8abfef00a5f00ef3968e157f5da39e93@mail.gmail.com>
 <20140915073354.3817.qmail@stuge.se>
User-Agent: Alpine 2.00 (DEB 1167 2008-08-23)
X-fromdanielhimself: yes
MIME-Version: 1.0
X-BeenThere: libssh2-devel@cool.haxx.se
X-Mailman-Version: 2.1.16
Precedence: list
Reply-To: libssh2 development <libssh2-devel@cool.haxx.se>
List-Id: libssh2 development <libssh2-devel.cool.haxx.se>
List-Unsubscribe: <http://cool.haxx.se/cgi-bin/mailman/options/libssh2-devel>, 
 <mailto:libssh2-devel-request@cool.haxx.se?subject=unsubscribe>
List-Archive: <http://cool.haxx.se/pipermail/libssh2-devel/>
List-Post: <mailto:libssh2-devel@cool.haxx.se>
List-Help: <mailto:libssh2-devel-request@cool.haxx.se?subject=help>
List-Subscribe: <http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel>, 
 <mailto:libssh2-devel-request@cool.haxx.se?subject=subscribe>
Content-Type: text/plain; charset="utf-8"; Format="flowed"
Errors-To: libssh2-devel-bounces@cool.haxx.se
Sender: "libssh2-devel" <libssh2-devel-bounces@cool.haxx.se>
Content-Transfer-Encoding: 8bit
X-MIME-Autoconverted: from base64 to 8bit by giant.haxx.se id s8F7cOd9012187

On Mon, 15 Sep 2014, Peter Stuge wrote:

>> according to you(in older mail thread), we should get higher chunks in
>> subsequent calls, which does not happen in any way.
>
> Focus on this - this seems to be the actual issue.

I agree with this.

I think I've explained the idea behind these "chunks" several times by now, 
but if things are still unclear I can try to explain it even further.

If that then ends up not working for anyone in a particular use case, then 
there's a problem and possibly a bug and the way to go from there is of course 
to debug and see why libssh2 doesn't return multple chunks in subsquent calls.

-- 

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

From libssh2-devel-bounces@cool.haxx.se  Tue Sep 16 12:31:08 2014
Return-Path: <libssh2-devel-bounces@cool.haxx.se>
Received: from www.haxx.se (localhost.localdomain [127.0.0.1])
	by giant.haxx.se (8.14.4/8.14.4/Debian-7) with ESMTP id s8GAUctp007621;
	Tue, 16 Sep 2014 12:31:04 +0200
Received: from giant.haxx.se (localhost.localdomain [127.0.0.1])
 by giant.haxx.se (8.14.4/8.14.4/Debian-7) with ESMTP id s8GAUaAP007614
 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT)
 for <libssh2-devel@cool.haxx.se>; Tue, 16 Sep 2014 12:30:36 +0200
Received: from localhost (dast@localhost)
 by giant.haxx.se (8.14.4/8.14.4/Submit) with ESMTP id s8GAUaRo007610
 for <libssh2-devel@cool.haxx.se>; Tue, 16 Sep 2014 12:30:36 +0200
X-Authentication-Warning: giant.haxx.se: dast owned process doing -bs
Date: Tue, 16 Sep 2014 12:30:36 +0200 (CEST)
From: Daniel Stenberg <daniel@haxx.se>
X-X-Sender: dast@giant.haxx.se
To: libssh2 development <libssh2-devel@cool.haxx.se>
Subject: Re: Allow authentication to be passed in memory - blast from the past
In-Reply-To: <20140915002550.5536.qmail@stuge.se>
Message-ID: <alpine.DEB.2.00.1409161222350.18125@tvnag.unkk.fr>
References: <CAH7nXcu2pM_WhPtVqPa5Vz8tqS_0sSQPGYR0bZ8kCS_bD+13wA@mail.gmail.com>
 <CAH7nXcvbPouEsLsPSF94cgfMMpEVp1XCpgDSBhJbaWojUmvi_g@mail.gmail.com>
 <CAH7nXcuwV=DjGFfuqUsHL0OD2WvaDyCfcoqQk7gjBY2uYMh0yg@mail.gmail.com>
 <CAH7nXcuA13Dfu91feDg=82UzFto=8sSY+WCtBzTQLvtgGnAGuA@mail.gmail.com>
 <alpine.DEB.2.00.1409150009240.18125@tvnag.unkk.fr>
 <CAH7nXctMTKesMeZzYU3Py-gLH0DFswtmo6y_2cHNAf-fsRtrEQ@mail.gmail.com>
 <20140915002550.5536.qmail@stuge.se>
User-Agent: Alpine 2.00 (DEB 1167 2008-08-23)
X-fromdanielhimself: yes
MIME-Version: 1.0
X-BeenThere: libssh2-devel@cool.haxx.se
X-Mailman-Version: 2.1.16
Precedence: list
Reply-To: libssh2 development <libssh2-devel@cool.haxx.se>
List-Id: libssh2 development <libssh2-devel.cool.haxx.se>
List-Unsubscribe: <http://cool.haxx.se/cgi-bin/mailman/options/libssh2-devel>, 
 <mailto:libssh2-devel-request@cool.haxx.se?subject=unsubscribe>
List-Archive: <http://cool.haxx.se/pipermail/libssh2-devel/>
List-Post: <mailto:libssh2-devel@cool.haxx.se>
List-Help: <mailto:libssh2-devel-request@cool.haxx.se?subject=help>
List-Subscribe: <http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel>, 
 <mailto:libssh2-devel-request@cool.haxx.se?subject=subscribe>
Content-Type: text/plain; charset="utf-8"; Format="flowed"
Errors-To: libssh2-devel-bounces@cool.haxx.se
Sender: "libssh2-devel" <libssh2-devel-bounces@cool.haxx.se>
Content-Transfer-Encoding: 8bit
X-MIME-Autoconverted: from base64 to 8bit by giant.haxx.se id s8GAUctp007621

On Mon, 15 Sep 2014, Peter Stuge wrote:

> You make OpenSSL calls and only add the functionality to the openssl.c file 
> so your patch can not work with anything but OpenSSL, and I for one want 
> that addressed before I consider the patch ready for inclusion.

I have a slightly less rigid attitude: as long as there's a good story about 
the alternative backends, that they don't break the build and the limitation 
is documented, then I'm fine with an implementation that "heads further" with 
one of the backends than the other(s). If not, we'll get a situation where the 
multitude of backends will hamper innovation as users will just not do things.

-- 

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

From libssh2-devel-bounces@cool.haxx.se  Tue Sep 16 18:42:40 2014
Return-Path: <libssh2-devel-bounces@cool.haxx.se>
Received: from www.haxx.se (localhost.localdomain [127.0.0.1])
	by giant.haxx.se (8.14.4/8.14.4/Debian-7) with ESMTP id s8GGgATU017006;
	Tue, 16 Sep 2014 18:42:35 +0200
Received: from mail-ig0-x22c.google.com (mail-ig0-x22c.google.com
 [IPv6:2607:f8b0:4001:c05::22c])
 by giant.haxx.se (8.14.4/8.14.4/Debian-7) with ESMTP id s8GGg714016823
 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-RC4-SHA bits=128 verify=NOT)
 for <libssh2-devel@cool.haxx.se>; Tue, 16 Sep 2014 18:42:08 +0200
Received: by mail-ig0-f172.google.com with SMTP id h3so5869482igd.17
 for <libssh2-devel@cool.haxx.se>; Tue, 16 Sep 2014 09:42:02 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113;
 h=mime-version:sender:in-reply-to:references:date:message-id:subject
 :from:to:content-type;
 bh=ZiOlP3i7vUSVsM1TUrnSSKBJcyUSTMCTbhtfhXB/Xlw=;
 b=AR/fLhtDiRsKZWze0xpwrxYESG1RoIWEPZmbcxIwsHs5YJtDsI9kf/bdbnw6IdWNsb
 MZTRfQ+AXlrDUZWlF1djYPgUN5Q77X6YphcuprHi0SGCFONbE1tqONiUYnXmvbfPmSR3
 QIKyuMvAEKWxFDTO5zQMFQ1iV0XA06YKRjnZcP5mZYarQ676DoN5rXeadBgWxP9YLgA5
 HLgrqOFKznaEgwlF7/G+mCz0VBjnZxmcv3iOXgLcXwI1Jsm0TpQm7NJ8VzCviB5VtlSs
 dPQUTxUWqgo9F2k/CLv670Vgh8DaWir8FvswIfEB3uhl5KP7PaufZuE1MTx0q6/AJiD7
 lgfw==
MIME-Version: 1.0
X-Received: by 10.50.20.225 with SMTP id q1mr32331610ige.36.1410885722125;
 Tue, 16 Sep 2014 09:42:02 -0700 (PDT)
Received: by 10.50.149.164 with HTTP; Tue, 16 Sep 2014 09:42:01 -0700 (PDT)
Received: by 10.50.149.164 with HTTP; Tue, 16 Sep 2014 09:42:01 -0700 (PDT)
In-Reply-To: <alpine.DEB.2.00.1409161222350.18125@tvnag.unkk.fr>
References: <CAH7nXcu2pM_WhPtVqPa5Vz8tqS_0sSQPGYR0bZ8kCS_bD+13wA@mail.gmail.com>
 <CAH7nXcvbPouEsLsPSF94cgfMMpEVp1XCpgDSBhJbaWojUmvi_g@mail.gmail.com>
 <CAH7nXcuwV=DjGFfuqUsHL0OD2WvaDyCfcoqQk7gjBY2uYMh0yg@mail.gmail.com>
 <CAH7nXcuA13Dfu91feDg=82UzFto=8sSY+WCtBzTQLvtgGnAGuA@mail.gmail.com>
 <alpine.DEB.2.00.1409150009240.18125@tvnag.unkk.fr>
 <CAH7nXctMTKesMeZzYU3Py-gLH0DFswtmo6y_2cHNAf-fsRtrEQ@mail.gmail.com>
 <20140915002550.5536.qmail@stuge.se>
 <alpine.DEB.2.00.1409161222350.18125@tvnag.unkk.fr>
Date: Tue, 16 Sep 2014 17:42:01 +0100
X-Google-Sender-Auth: RTdX0CeTbHuUzdkW6FF8GegkEys
Message-ID: <CADyPeTNNDhdxPzbKrVuHdM4+D09udB8hk-kRJi_LbEM8W99WwA@mail.gmail.com>
Subject: Re: Allow authentication to be passed in memory - blast from the past
From: Alexander Lamaison <swish@lammy.co.uk>
To: libssh2 development <libssh2-devel@cool.haxx.se>
X-BeenThere: libssh2-devel@cool.haxx.se
X-Mailman-Version: 2.1.16
Precedence: list
Reply-To: libssh2 development <libssh2-devel@cool.haxx.se>
List-Id: libssh2 development <libssh2-devel.cool.haxx.se>
List-Unsubscribe: <http://cool.haxx.se/cgi-bin/mailman/options/libssh2-devel>, 
 <mailto:libssh2-devel-request@cool.haxx.se?subject=unsubscribe>
List-Archive: <http://cool.haxx.se/pipermail/libssh2-devel/>
List-Post: <mailto:libssh2-devel@cool.haxx.se>
List-Help: <mailto:libssh2-devel-request@cool.haxx.se?subject=help>
List-Subscribe: <http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel>, 
 <mailto:libssh2-devel-request@cool.haxx.se?subject=subscribe>
Content-Type: multipart/mixed; boundary="===============0004659369=="
Errors-To: libssh2-devel-bounces@cool.haxx.se
Sender: "libssh2-devel" <libssh2-devel-bounces@cool.haxx.se>

--===============0004659369==
Content-Type: multipart/alternative; boundary=047d7bd75ac2493a510503316e61

--047d7bd75ac2493a510503316e61
Content-Type: text/plain; charset=UTF-8

On 16 Sep 2014 11:32, "Daniel Stenberg" <daniel@haxx.se> wrote:
>
> On Mon, 15 Sep 2014, Peter Stuge wrote:
>
>> You make OpenSSL calls and only add the functionality to the openssl.c
file so your patch can not work with anything but OpenSSL, and I for one
want that addressed before I consider the patch ready for inclusion.
>
>
> I have a slightly less rigid attitude: as long as there's a good story
about the alternative backends, that they don't break the build and the
limitation is documented, then I'm fine with an implementation that "heads
further" with one of the backends than the other(s). If not, we'll get a
situation where the multitude of backends will hamper innovation as users
will just not do things.

I agree. In fact, we're already in this situation. For example, complied
against OpenSSL the user can pass just the private key file, but with
libgcrypt they must also pass the public key.

Alex

--047d7bd75ac2493a510503316e61
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<p dir=3D"ltr">On 16 Sep 2014 11:32, &quot;Daniel Stenberg&quot; &lt;<a hre=
f=3D"mailto:daniel@haxx.se">daniel@haxx.se</a>&gt; wrote:<br>
&gt;<br>
&gt; On Mon, 15 Sep 2014, Peter Stuge wrote:<br>
&gt;<br>
&gt;&gt; You make OpenSSL calls and only add the functionality to the opens=
sl.c file so your patch can not work with anything but OpenSSL, and I for o=
ne want that addressed before I consider the patch ready for inclusion.<br>
&gt;<br>
&gt;<br>
&gt; I have a slightly less rigid attitude: as long as there&#39;s a good s=
tory about the alternative backends, that they don&#39;t break the build an=
d the limitation is documented, then I&#39;m fine with an implementation th=
at &quot;heads further&quot; with one of the backends than the other(s). If=
 not, we&#39;ll get a situation where the multitude of backends will hamper=
 innovation as users will just not do things.</p>
<p dir=3D"ltr">I agree. In fact, we&#39;re already in this situation. For e=
xample, complied against OpenSSL the user can pass just the private key fil=
e, but with libgcrypt they must also pass the public key. </p>
<p dir=3D"ltr">Alex<br>
</p>

--047d7bd75ac2493a510503316e61--

--===============0004659369==
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: base64
Content-Disposition: inline

X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KbGlic3NoMi1k
ZXZlbCBodHRwOi8vY29vbC5oYXh4LnNlL2NnaS1iaW4vbWFpbG1hbi9saXN0aW5mby9saWJzc2gy
LWRldmVsCg==

--===============0004659369==--

From libssh2-devel-bounces@cool.haxx.se  Tue Sep 16 19:14:54 2014
Return-Path: <libssh2-devel-bounces@cool.haxx.se>
Received: from www.haxx.se (localhost.localdomain [127.0.0.1])
	by giant.haxx.se (8.14.4/8.14.4/Debian-7) with ESMTP id s8GHEjPc027032;
	Tue, 16 Sep 2014 19:14:52 +0200
Received: from foo.stuge.se (qmailr@foo.stuge.se [212.116.89.98])
 by giant.haxx.se (8.14.4/8.14.4/Debian-7) with ESMTP id s8GHEiu9026927
 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT)
 for <libssh2-devel@cool.haxx.se>; Tue, 16 Sep 2014 19:14:44 +0200
Received: (qmail 22992 invoked by uid 501); 16 Sep 2014 17:14:45 -0000
Message-ID: <20140916171445.22991.qmail@stuge.se>
Date: Tue, 16 Sep 2014 19:14:45 +0200
From: Peter Stuge <peter@stuge.se>
To: libssh2-devel@cool.haxx.se
Subject: Re: Allow authentication to be passed in memory - blast from the past
Mail-Followup-To: libssh2-devel@cool.haxx.se
References: <CAH7nXcu2pM_WhPtVqPa5Vz8tqS_0sSQPGYR0bZ8kCS_bD+13wA@mail.gmail.com>
 <CAH7nXcvbPouEsLsPSF94cgfMMpEVp1XCpgDSBhJbaWojUmvi_g@mail.gmail.com>
 <CAH7nXcuwV=DjGFfuqUsHL0OD2WvaDyCfcoqQk7gjBY2uYMh0yg@mail.gmail.com>
 <CAH7nXcuA13Dfu91feDg=82UzFto=8sSY+WCtBzTQLvtgGnAGuA@mail.gmail.com>
 <alpine.DEB.2.00.1409150009240.18125@tvnag.unkk.fr>
 <CAH7nXctMTKesMeZzYU3Py-gLH0DFswtmo6y_2cHNAf-fsRtrEQ@mail.gmail.com>
 <20140915002550.5536.qmail@stuge.se>
 <alpine.DEB.2.00.1409161222350.18125@tvnag.unkk.fr>
 <CADyPeTNNDhdxPzbKrVuHdM4+D09udB8hk-kRJi_LbEM8W99WwA@mail.gmail.com>
MIME-Version: 1.0
Content-Disposition: inline
In-Reply-To: <CADyPeTNNDhdxPzbKrVuHdM4+D09udB8hk-kRJi_LbEM8W99WwA@mail.gmail.com>
X-BeenThere: libssh2-devel@cool.haxx.se
X-Mailman-Version: 2.1.16
Precedence: list
Reply-To: libssh2 development <libssh2-devel@cool.haxx.se>
List-Id: libssh2 development <libssh2-devel.cool.haxx.se>
List-Unsubscribe: <http://cool.haxx.se/cgi-bin/mailman/options/libssh2-devel>, 
 <mailto:libssh2-devel-request@cool.haxx.se?subject=unsubscribe>
List-Archive: <http://cool.haxx.se/pipermail/libssh2-devel/>
List-Post: <mailto:libssh2-devel@cool.haxx.se>
List-Help: <mailto:libssh2-devel-request@cool.haxx.se?subject=help>
List-Subscribe: <http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel>, 
 <mailto:libssh2-devel-request@cool.haxx.se?subject=subscribe>
Content-Type: text/plain; charset="utf-8"
Errors-To: libssh2-devel-bounces@cool.haxx.se
Sender: "libssh2-devel" <libssh2-devel-bounces@cool.haxx.se>
Content-Transfer-Encoding: 8bit
X-MIME-Autoconverted: from base64 to 8bit by giant.haxx.se id s8GHEjPc027032

Alexander Lamaison wrote:
> we're already in this situation.

Yeah, and I want that to get better instead of worse.


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

From libssh2-devel-bounces@cool.haxx.se  Mon Sep 22 01:30:28 2014
Return-Path: <libssh2-devel-bounces@cool.haxx.se>
Received: from www.haxx.se (localhost.localdomain [127.0.0.1])
	by giant.haxx.se (8.14.4/8.14.4/Debian-7) with ESMTP id s8LNTtZh008272;
	Mon, 22 Sep 2014 01:30:22 +0200
Received: from mail-ie0-x22f.google.com (mail-ie0-x22f.google.com
 [IPv6:2607:f8b0:4001:c03::22f])
 by giant.haxx.se (8.14.4/8.14.4/Debian-7) with ESMTP id s8LNTpPb008216
 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-RC4-SHA bits=128 verify=NOT)
 for <libssh2-devel@cool.haxx.se>; Mon, 22 Sep 2014 01:29:52 +0200
Received: by mail-ie0-f175.google.com with SMTP id rl12so95234iec.6
 for <libssh2-devel@cool.haxx.se>; Sun, 21 Sep 2014 16:29:48 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113;
 h=mime-version:in-reply-to:references:from:date:message-id:subject:to
 :content-type; bh=vO1xag3uzc9augOR1caraB24kAqzLR8CfU2eH8rVmVU=;
 b=ZvrZUfgvuRpj/UGthn+2jZQPsmhbhjJN8DYWlCMuEsaXQuyZDiJ9QoRA+hb6QZZSgM
 zt92kDduAum9grZPp8GKLr7Hyl3yDxngWIYkMfiacvYPQnKt4LOgIQx1nPV8AnXYNzUE
 qgyQrDVOZVPqorBm/3fjMfzG+QNXBGjsLBAzUVXgRn0Y1D9tNnUZaweW2VIhHDdqYLoY
 mXQBoGA+oeYLCZpwTQjDaeiZ6i+8A8W2e6EKTjrx0PzSBORyjzlmrSYdxScB3L7SM65C
 YmeNOXaIIxHYUgD/sT2IpVCA3pMMvSlnXsXXn7Npy0bi7siHRPHrG9OoFUBFZ3Y3Aixv
 6oPQ==
X-Received: by 10.50.50.195 with SMTP id e3mr10972613igo.9.1411342187664; Sun,
 21 Sep 2014 16:29:47 -0700 (PDT)
MIME-Version: 1.0
Received: by 10.107.13.205 with HTTP; Sun, 21 Sep 2014 16:29:26 -0700 (PDT)
In-Reply-To: <20140916171445.22991.qmail@stuge.se>
References: <CAH7nXcu2pM_WhPtVqPa5Vz8tqS_0sSQPGYR0bZ8kCS_bD+13wA@mail.gmail.com>
 <CAH7nXcvbPouEsLsPSF94cgfMMpEVp1XCpgDSBhJbaWojUmvi_g@mail.gmail.com>
 <CAH7nXcuwV=DjGFfuqUsHL0OD2WvaDyCfcoqQk7gjBY2uYMh0yg@mail.gmail.com>
 <CAH7nXcuA13Dfu91feDg=82UzFto=8sSY+WCtBzTQLvtgGnAGuA@mail.gmail.com>
 <alpine.DEB.2.00.1409150009240.18125@tvnag.unkk.fr>
 <CAH7nXctMTKesMeZzYU3Py-gLH0DFswtmo6y_2cHNAf-fsRtrEQ@mail.gmail.com>
 <20140915002550.5536.qmail@stuge.se>
 <alpine.DEB.2.00.1409161222350.18125@tvnag.unkk.fr>
 <CADyPeTNNDhdxPzbKrVuHdM4+D09udB8hk-kRJi_LbEM8W99WwA@mail.gmail.com>
 <20140916171445.22991.qmail@stuge.se>
From: David Calavera <david.calavera@gmail.com>
Date: Sun, 21 Sep 2014 16:29:26 -0700
Message-ID: <CAH7nXcs_iPCNt1uUHSLBr2zhWQ4o4sPophpqc-tg7o91MpUAMA@mail.gmail.com>
Subject: Re: Allow authentication to be passed in memory - blast from the past
To: libssh2 development <libssh2-devel@cool.haxx.se>
X-BeenThere: libssh2-devel@cool.haxx.se
X-Mailman-Version: 2.1.16
Precedence: list
Reply-To: libssh2 development <libssh2-devel@cool.haxx.se>
List-Id: libssh2 development <libssh2-devel.cool.haxx.se>
List-Unsubscribe: <http://cool.haxx.se/cgi-bin/mailman/options/libssh2-devel>, 
 <mailto:libssh2-devel-request@cool.haxx.se?subject=unsubscribe>
List-Archive: <http://cool.haxx.se/pipermail/libssh2-devel/>
List-Post: <mailto:libssh2-devel@cool.haxx.se>
List-Help: <mailto:libssh2-devel-request@cool.haxx.se?subject=help>
List-Subscribe: <http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel>, 
 <mailto:libssh2-devel-request@cool.haxx.se?subject=subscribe>
Content-Type: multipart/mixed; boundary="===============1947081051=="
Errors-To: libssh2-devel-bounces@cool.haxx.se
Sender: "libssh2-devel" <libssh2-devel-bounces@cool.haxx.se>

--===============1947081051==
Content-Type: multipart/alternative; boundary=047d7bd75b30c09e2505039bb533

--047d7bd75b30c09e2505039bb533
Content-Type: text/plain; charset=UTF-8

Thanks for your feedback, Peter, Daniel and Alex.

Peter, I totally understand your concern. I took my time to reply because I
tried to do it right, but I have to be realistic here and honest with
myself.

I feel like reading the keys from memory to implement the same logic for
libgcrypt might not be too complicated, unfortunately my C skills are
really rusty, and I don't think I'm the right person to make it right. On
the other hand, I'll be super glad to assist anybody that can help me, we
can do a remote pair session or talk over skype or whatever is best to
reach a better solution.

As a sort term solution, I added the necessary methods to scr/libgcrypt.c
to return an unimplemented error, like it already does parting public keys
from private key files.

I'd still love to see this merged into the main project, I think it would
be really useful for people implemented on top of libssh2, and I'm at your
disposal for anything I can help.

This is the new patch with those methods inside libgcrypt:

https://github.com/calavera/libssh2/commit/c031101aede6195376415178a5fcce80c556a8e3
https://github.com/calavera/libssh2/commit/c031101aede6195376415178a5fcce80c556a8e3.patch

And this is the raw patch for everybody in the list to see:

From c031101aede6195376415178a5fcce80c556a8e3 Mon Sep 17 00:00:00 2001
From: David Calavera <david.calavera@gmail.com>
Date: Mon, 1 Sep 2014 15:54:05 -0700
Subject: [PATCH] Allow authentication keys to be passed in memory.

All credits go to Joe Turpin, I'm just reaplying and cleaning his
patch:http://www.libssh2.org/mail/libssh2-devel-archive-2012-01/0015.shtml

* Adds libssh2_userauth_publickey_frommemory macro for
libssh2_userauth_publickey_frommemory_ex.
* Use an unimplemented error for extracting keys from memory with libgcrypt.
---
 docs/libssh2_userauth_publickey_frommemory.3    |  22 +++
 docs/libssh2_userauth_publickey_frommemory_ex.3 |  55 ++++++
 include/libssh2.h                               |  20 ++
 src/crypto.h                                    |  16 ++
 src/hostkey.c                                   |  66 +++++++
 src/libgcrypt.c                                 |  37 ++++
 src/libssh2_priv.h                              |   3 +
 src/openssl.c                                   | 121 +++++++++++++
 src/userauth.c                                  | 231 ++++++++++++++++++++++++
 9 files changed, 571 insertions(+)
 create mode 100644 docs/libssh2_userauth_publickey_frommemory.3
 create mode 100644 docs/libssh2_userauth_publickey_frommemory_ex.3

diff --git a/docs/libssh2_userauth_publickey_frommemory.3
b/docs/libssh2_userauth_publickey_frommemory.3
new file mode 100644
index 0000000..e464e71
--- /dev/null
+++ b/docs/libssh2_userauth_publickey_frommemory.3
@@ -0,0 +1,22 @@
+.TH libssh2_userauth_publickey_frommemory 3 "1 Sep 2014" "libssh2
1.5" "libssh2 manual"
+.SH NAME
+libssh2_userauth_publickey_frommemory - convenience macro for
\fIlibssh2_userauth_publickey_frommemory_ex(3)\fP calls
+.SH SYNOPSIS
+#include <libssh2.h>
+
+int
+libssh2_userauth_publickey_frommemory(LIBSSH2_SESSION *session,
+                                      const char *username,
+                                      const char *publickey,
+                                      const char *privatekey,
+                                      const char *passphrase);
+
+.SH DESCRIPTION
+This is a macro defined in a public libssh2 header file that is using the
+underlying function \fIlibssh2_userauth_publickey_frommemory_ex(3)\fP.
+.SH RETURN VALUE
+See \fIlibssh2_userauth_publickey_frommemory_ex(3)\fP
+.SH ERRORS
+See \fIlibssh2_userauth_publickey_frommemory_ex(3)\fP
+.SH SEE ALSO
+.BR libssh2_userauth_publickey_frommemory_ex(3)
diff --git a/docs/libssh2_userauth_publickey_frommemory_ex.3
b/docs/libssh2_userauth_publickey_frommemory_ex.3
new file mode 100644
index 0000000..6faf5d1
--- /dev/null
+++ b/docs/libssh2_userauth_publickey_frommemory_ex.3
@@ -0,0 +1,55 @@
+.TH libssh2_userauth_publickey_frommemory_ex 3 "1 Sep 2014" "libssh2
1.5" "libssh2 manual"
+.SH NAME
+libssh2_userauth_publickey_frommemory_ex - authenticate a session
with a public key, read from memory
+.SH SYNOPSIS
+#include <libssh2.h>
+
+.nf
+int libssh2_userauth_publickey_frommemory_ex(LIBSSH2_SESSION *session,
+                                           const char *username,
+                                           unsigned int username_len,
+                                           const char *publickeydata,
+                                           size_t publickeydata_len,
+                                           const char *privatekeydata,
+                                           size_t privatekeydata_len,
+                                           const char *passphrase);
+.SH DESCRIPTION
+\fIsession\fP - Session instance as returned by
+.BR libssh2_session_init_ex(3)
+
+\fIusername\fP - Remote user name to authenticate as.
+
+\fIusername_len\fP - Length of username.
+
+\fIpublickeydata\fP - Buffer containing the contents of a public key file.
+
+\fIpublickeydata_len\fP - Length of public key data.
+
+\fIprivatekeydata\fP - Buffer containing the contents of a private key file.
+
+\fIprivatekeydata_len\fP - Length of private key data.
+
+\fIpassphrase\fP - Passphrase to use when decoding private key file.
+
+Attempt public key authentication using a PEM encoded private key
file stored in memory.
+
+.SH RETURN VALUE
+Return 0 on success or negative on failure.  It returns
+LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
+LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
+
+.SH ERRORS
+\fILIBSSH2_ERROR_ALLOC\fP -  An internal memory allocation call failed.
+
+\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
+
+\fILIBSSH2_ERROR_SOCKET_TIMEOUT\fP -
+
+\fILIBSSH2_ERROR_PUBLICKEY_UNVERIFIED\fP - The username/public key
+combination was invalid.
+
+\fILIBSSH2_ERROR_AUTHENTICATION_FAILED\fP - Authentication using the supplied
+public key was not accepted.
+
+.SH SEE ALSO
+.BR libssh2_session_init_ex(3)
diff --git a/include/libssh2.h b/include/libssh2.h
index 565bf06..6e519db 100644
--- a/include/libssh2.h
+++ b/include/libssh2.h
@@ -576,6 +576,26 @@
libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session,
                                         (username),                     \
                                         (unsigned int)strlen(username))

+LIBSSH2_API int
+libssh2_userauth_publickey_frommemory_ex(LIBSSH2_SESSION *session,
+                                      const char *username,
+                                      unsigned int username_len,
+                                      const char *publickeyfiledata,
+                                      size_t publickeyfiledata_len,
+                                      const char *privatekeyfiledata,
+                                      size_t privatekeyfiledata_len,
+                                      const char *passphrase);
+
+#define libssh2_userauth_publickey_frommemory(session, username, publickey, \
+                                              privatekey, passphrase) \
+ libssh2_userauth_publickey_frommemory_ex((session), (username), \
+                                          (unsigned int)strlen(username),   \
+                                          (publickey),                      \
+                                          (unsigned int)strlen(publickey),  \
+                                          (privatekey),                     \
+                                          (unsigned int)strlen(privatekey), \
+                                          (passphrase))
+
 /*
  * response_callback is provided with filled by library prompts array,
  * but client must allocate and fill individual responses. Responses
diff --git a/src/crypto.h b/src/crypto.h
index a615bb1..05f5a5c 100644
--- a/src/crypto.h
+++ b/src/crypto.h
@@ -80,6 +80,10 @@ int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
                            size_t hash_len,
                            unsigned char **signature,
                            size_t *signature_len);
+int _libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa,
+                                        LIBSSH2_SESSION * session,
+                                        const char *filedata, size_t
filedata_len,
+                                        unsigned const char *passphrase);

 #if LIBSSH2_DSA
 int _libssh2_dsa_new(libssh2_dsa_ctx ** dsa,
@@ -102,6 +106,10 @@ int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
 int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
                            const unsigned char *hash,
                            unsigned long hash_len, unsigned char *sig);
+int _libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx ** dsa,
+                                        LIBSSH2_SESSION * session,
+                                        const char *filedata, size_t
filedata_len,
+                                        unsigned const char *passphrase);
 #endif

 int _libssh2_cipher_init(_libssh2_cipher_ctx * h,
@@ -120,6 +128,14 @@ int _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session,
                               size_t *pubkeydata_len,
                               const char *privatekey,
                               const char *passphrase);
+int _libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
+                                    unsigned char **method,
+                                    size_t *method_len,
+                                    unsigned char **pubkeydata,
+                                    size_t *pubkeydata_len,
+                                    const char *privatekeydata,
+                                    size_t privatekeydata_len,
+                                    const char *passphrase);

 void _libssh2_init_aes_ctr(void);

diff --git a/src/hostkey.c b/src/hostkey.c
index 753563d..02d085a 100644
--- a/src/hostkey.c
+++ b/src/hostkey.c
@@ -131,6 +131,38 @@ hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION * session,
 }

 /*
+ * hostkey_method_ssh_rsa_initPEMFromMemory
+ *
+ * Load a Private Key from a memory
+ */
+static int
+hostkey_method_ssh_rsa_initPEMFromMemory(LIBSSH2_SESSION * session,
+                                         const char *privkeyfiledata,
+                                         size_t privkeyfiledata_len,
+                                         unsigned const char *passphrase,
+                                         void **abstract)
+{
+    libssh2_rsa_ctx *rsactx;
+    int ret;
+
+    if (*abstract) {
+        hostkey_method_ssh_rsa_dtor(session, abstract);
+        *abstract = NULL;
+    }
+
+    ret = _libssh2_rsa_new_private_frommemory(&rsactx, session,
+                                              privkeyfiledata,
+                                              privkeyfiledata_len, passphrase);
+    if (ret) {
+        return -1;
+    }
+
+    *abstract = rsactx;
+
+    return 0;
+}
+
+/*
  * hostkey_method_ssh_rsa_sign
  *
  * Verify signature created by remote
@@ -208,6 +240,7 @@ static const LIBSSH2_HOSTKEY_METHOD
hostkey_method_ssh_rsa = {
     MD5_DIGEST_LENGTH,
     hostkey_method_ssh_rsa_init,
     hostkey_method_ssh_rsa_initPEM,
+    hostkey_method_ssh_rsa_initPEMFromMemory,
     hostkey_method_ssh_rsa_sig_verify,
     hostkey_method_ssh_rsa_signv,
     NULL,                       /* encrypt */
@@ -306,6 +339,38 @@ hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION * session,
 }

 /*
+ * hostkey_method_ssh_dss_initPEMFromMemory
+ *
+ * Load a Private Key from memory
+ */
+static int
+hostkey_method_ssh_dss_initPEMFromMemory(LIBSSH2_SESSION * session,
+                                         const char *privkeyfiledata,
+                                         size_t privkeyfiledata_len,
+                                         unsigned const char *passphrase,
+                                         void **abstract)
+{
+    libssh2_dsa_ctx *dsactx;
+    int ret;
+
+    if (*abstract) {
+        hostkey_method_ssh_dss_dtor(session, abstract);
+        *abstract = NULL;
+    }
+
+    ret = _libssh2_dsa_new_private_frommemory(&dsactx, session,
+                                              privkeyfiledata,
+                                              privkeyfiledata_len, passphrase);
+    if (ret) {
+        return -1;
+    }
+
+    *abstract = dsactx;
+
+    return 0;
+}
+
+/*
  * libssh2_hostkey_method_ssh_dss_sign
  *
  * Verify signature created by remote
@@ -392,6 +457,7 @@ static const LIBSSH2_HOSTKEY_METHOD
hostkey_method_ssh_dss = {
     MD5_DIGEST_LENGTH,
     hostkey_method_ssh_dss_init,
     hostkey_method_ssh_dss_initPEM,
+    hostkey_method_ssh_dss_initPEMFromMemory,
     hostkey_method_ssh_dss_sig_verify,
     hostkey_method_ssh_dss_signv,
     NULL,                       /* encrypt */
diff --git a/src/libgcrypt.c b/src/libgcrypt.c
index 7d09ffb..e85aecd 100644
--- a/src/libgcrypt.c
+++ b/src/libgcrypt.c
@@ -150,6 +150,17 @@ _libssh2_dsa_new(libssh2_dsa_ctx ** dsactx,
 }

 int
+_libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa,
+                                    LIBSSH2_SESSION * session,
+                                    const char *filedata, size_t filedata_len,
+                                    unsigned const char *passphrase)
+{
+    return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
+                         "Unable to extract private key from memory: "
+                         "Method unimplemented in libgcrypt backend");
+}
+
+int
 _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
                          LIBSSH2_SESSION * session,
                          const char *filename, unsigned const char *passphrase)
@@ -252,6 +263,17 @@ _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
 }

 int
+_libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx ** dsa,
+                                    LIBSSH2_SESSION * session,
+                                    const char *filedata, size_t filedata_len,
+                                    unsigned const char *passphrase)
+{
+    return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
+                         "Unable to extract private key from memory: "
+                         "Method unimplemented in libgcrypt backend");
+}
+
+int
 _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
                          LIBSSH2_SESSION * session,
                          const char *filename, unsigned const char *passphrase)
@@ -567,6 +589,21 @@ _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
 }

 int
+_libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
+                                unsigned char **method,
+                                size_t *method_len,
+                                unsigned char **pubkeydata,
+                                size_t *pubkeydata_len,
+                                const char *privatekeydata,
+                                size_t privatekeydata_len,
+                                const char *passphrase)
+{
+    return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
+                         "Unable to extract public key from private
key in memory: "
+                         "Method unimplemented in libgcrypt backend");
+}
+
+int
 _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session,
                           unsigned char **method,
                           size_t *method_len,
diff --git a/src/libssh2_priv.h b/src/libssh2_priv.h
index 00ed240..0274d83 100644
--- a/src/libssh2_priv.h
+++ b/src/libssh2_priv.h
@@ -853,6 +853,9 @@ struct _LIBSSH2_HOSTKEY_METHOD
                  size_t hostkey_data_len, void **abstract);
     int (*initPEM) (LIBSSH2_SESSION * session, const char *privkeyfile,
                     unsigned const char *passphrase, void **abstract);
+    int (*initPEMFromMemory) (LIBSSH2_SESSION * session,
+                              const char *privkeyfiledata, size_t
privkeyfiledata_len,
+                              unsigned const char *passphrase, void
**abstract);
     int (*sig_verify) (LIBSSH2_SESSION * session, const unsigned char *sig,
                        size_t sig_len, const unsigned char *m,
                        size_t m_len, void **abstract);
diff --git a/src/openssl.c b/src/openssl.c
index 056b0b7..2e31472 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -388,6 +388,28 @@ typedef void * (*pem_read_bio_func)(BIO *, void
**, pem_password_cb *,
                                     void * u);

 static int
+read_private_key_from_memory(void ** key_ctx,
+                             pem_read_bio_func read_private_key,
+                             const char * filedata,
+                             size_t filedata_len,
+                             unsigned const char *passphrase)
+{
+    BIO * bp;
+
+    *key_ctx = NULL;
+
+    bp = BIO_new_mem_buf(filedata, filedata_len);
+    if (!bp) {
+        return -1;
+    }
+    *key_ctx = read_private_key(bp, NULL, (pem_password_cb *) passphrase_cb,
+                                (void *) passphrase);
+
+    BIO_free(bp);
+    return (*key_ctx) ? 0 : -1;
+}
+
+static int
 read_private_key_from_file(void ** key_ctx,
                            pem_read_bio_func read_private_key,
                            const char * filename,
@@ -409,6 +431,22 @@ read_private_key_from_file(void ** key_ctx,
     return (*key_ctx) ? 0 : -1;
 }

+ int
+_libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa,
+                                    LIBSSH2_SESSION * session,
+                                    const char *filedata, size_t filedata_len,
+                                    unsigned const char *passphrase)
+{
+    pem_read_bio_func read_rsa =
+        (pem_read_bio_func) &PEM_read_bio_RSAPrivateKey;
+    (void) session;
+
+    _libssh2_init_if_needed();
+
+    return read_private_key_from_memory((void **) rsa, read_rsa,
+                                        filedata, filedata_len, passphrase);
+}
+
 int
 _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
                          LIBSSH2_SESSION * session,
@@ -426,6 +464,22 @@ _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,

 #if LIBSSH2_DSA
 int
+_libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx ** dsa,
+                                    LIBSSH2_SESSION * session,
+                                    const char *filedata, size_t filedata_len,
+                                    unsigned const char *passphrase)
+{
+    pem_read_bio_func read_dsa =
+        (pem_read_bio_func) &PEM_read_bio_DSAPrivateKey;
+    (void) session;
+
+    _libssh2_init_if_needed();
+
+    return read_private_key_from_memory((void **) dsa, read_dsa,
+                                        filedata, filedata_len, passphrase);
+}
+
+int
 _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
                          LIBSSH2_SESSION * session,
                          const char *filename, unsigned const char *passphrase)
@@ -817,4 +871,71 @@ _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session,
     return st;
 }

+int
+_libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
+                                unsigned char **method,
+                                size_t *method_len,
+                                unsigned char **pubkeydata,
+                                size_t *pubkeydata_len,
+                                const char *privatekeydata,
+                                size_t privatekeydata_len,
+                                const char *passphrase)
+{
+    int       st;
+    BIO*      bp;
+    EVP_PKEY* pk;
+
+    _libssh2_debug(session,
+                   LIBSSH2_TRACE_AUTH,
+                   "Computing public key from private key.");
+
+    bp = BIO_new_mem_buf(privatekeydata, privatekeydata_len);
+    if (!bp) {
+        return -1;
+    }
+    if (!EVP_get_cipherbyname("des")) {
+        /* If this cipher isn't loaded it's a pretty good indication that none
+         * are.  I have *NO DOUBT* that there's a better way to deal with this
+         * ($#&%#$(%$#( Someone buy me an OpenSSL manual and I'll read up on
+         * it.
+         */
+        OpenSSL_add_all_ciphers();
+    }
+    BIO_reset(bp);
+    pk = PEM_read_bio_PrivateKey(bp, NULL, NULL, (void*)passphrase);
+    BIO_free(bp);
+
+    if (pk == NULL) {
+        return _libssh2_error(session,
+                              LIBSSH2_ERROR_FILE,
+                              "Unable to extract public key "
+                              "from private key file: "
+                              "Wrong passphrase or invalid/unrecognized "
+                              "private key file format");
+    }
+
+    switch (pk->type) {
+    case EVP_PKEY_RSA :
+        st = gen_publickey_from_rsa_evp(session, method, method_len,
+                                        pubkeydata, pubkeydata_len, pk);
+        break;
+
+    case EVP_PKEY_DSA :
+        st = gen_publickey_from_dsa_evp(session, method, method_len,
+                                        pubkeydata, pubkeydata_len, pk);
+        break;
+
+    default :
+        st = _libssh2_error(session,
+                            LIBSSH2_ERROR_FILE,
+                            "Unable to extract public key "
+                            "from private key file: "
+                            "Unsupported private key file format");
+        break;
+    }
+
+    EVP_PKEY_free(pk);
+    return st;
+}
+
 #endif /* LIBSSH2_OPENSSL */
diff --git a/src/userauth.c b/src/userauth.c
index edfe729..afbe172 100644
--- a/src/userauth.c
+++ b/src/userauth.c
@@ -441,6 +441,76 @@ libssh2_userauth_password_ex(LIBSSH2_SESSION
*session, const char *username,
     return rc;
 }

+static int
+memory_read_publickey(LIBSSH2_SESSION * session, unsigned char **method,
+                      size_t *method_len,
+                      unsigned char **pubkeydata,
+                      size_t *pubkeydata_len,
+                      const char *pubkeyfiledata,
+                      size_t pubkeyfiledata_len)
+{
+    unsigned char *pubkey = NULL, *sp1, *sp2, *tmp;
+    size_t pubkey_len = pubkeyfiledata_len;
+    unsigned int tmp_len;
+
+    if (pubkeyfiledata_len <= 1) {
+        return _libssh2_error(session, LIBSSH2_ERROR_FILE,
+                              "Invalid data in public key file");
+    }
+
+    pubkey = LIBSSH2_ALLOC(session, pubkeyfiledata_len);
+    if (!pubkey) {
+        return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
+                              "Unable to allocate memory for public key data");
+    }
+
+    memcpy(pubkey, pubkeyfiledata, pubkeyfiledata_len);
+
+    /*
+     *   Remove trailing whitespace
+     */
+    while (pubkey_len && isspace(pubkey[pubkey_len - 1]))
+        pubkey_len--;
+
+    if (!pubkey_len) {
+        LIBSSH2_FREE(session, pubkey);
+        return _libssh2_error(session, LIBSSH2_ERROR_FILE,
+                              "Missing public key data");
+    }
+
+    if ((sp1 = memchr(pubkey, ' ', pubkey_len)) == NULL) {
+        LIBSSH2_FREE(session, pubkey);
+        return _libssh2_error(session, LIBSSH2_ERROR_FILE,
+                              "Invalid public key data");
+    }
+
+    sp1++;
+
+    if ((sp2 = memchr(sp1, ' ', pubkey_len - (sp1 - pubkey - 1))) == NULL) {
+        /* Assume that the id string is missing, but that it's okay */
+        sp2 = pubkey + pubkey_len;
+    }
+
+    if (libssh2_base64_decode(session, (char **) &tmp, &tmp_len,
+                              (char *) sp1, sp2 - sp1)) {
+        LIBSSH2_FREE(session, pubkey);
+        return _libssh2_error(session, LIBSSH2_ERROR_FILE,
+                                  "Invalid key data, not base64 encoded");
+    }
+
+    /* Wasting some bytes here (okay, more than some), but since it's likely
+     * to be freed soon anyway, we'll just avoid the extra free/alloc and call
+     * it a wash
+     */
+    *method = pubkey;
+    *method_len = sp1 - pubkey - 1;
+
+    *pubkeydata = tmp;
+    *pubkeydata_len = tmp_len;
+
+    return 0;
+}
+
 /*
  * file_read_publickey
  *
@@ -543,7 +613,43 @@ file_read_publickey(LIBSSH2_SESSION * session,
unsigned char **method,
     return 0;
 }

+static int
+memory_read_privatekey(LIBSSH2_SESSION * session,
+                       const LIBSSH2_HOSTKEY_METHOD ** hostkey_method,
+                       void **hostkey_abstract,
+                       const unsigned char *method, int method_len,
+                       const char *privkeyfiledata, size_t privkeyfiledata_len,
+                       const char *passphrase)
+{
+    const LIBSSH2_HOSTKEY_METHOD **hostkey_methods_avail =
+        libssh2_hostkey_methods();
+
+    *hostkey_method = NULL;
+    *hostkey_abstract = NULL;
+    while (*hostkey_methods_avail && (*hostkey_methods_avail)->name) {
+        if ((*hostkey_methods_avail)->initPEMFromMemory
+             && strncmp((*hostkey_methods_avail)->name, (const char *) method,
+                        method_len) == 0) {
+            *hostkey_method = *hostkey_methods_avail;
+            break;
+        }
+        hostkey_methods_avail++;
+    }
+    if (!*hostkey_method) {
+        return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NONE,
+                              "No handler for specified private key");
+    }
+
+    if ((*hostkey_method)->
+        initPEMFromMemory(session, privkeyfiledata, privkeyfiledata_len,
+                          (unsigned char *) passphrase,
+                          hostkey_abstract)) {
+        return _libssh2_error(session, LIBSSH2_ERROR_FILE,
+                              "Unable to initialize private key from file");
+    }

+    return 0;
+}

 /* libssh2_file_read_privatekey
  * Read a PEM encoded private key from an id_??? style file
@@ -592,6 +698,42 @@ struct privkey_file {
 };

 static int
+sign_frommemory(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
+                const unsigned char *data, size_t data_len, void **abstract)
+{
+    struct privkey_file *pk_file = (struct privkey_file *) (*abstract);
+    const LIBSSH2_HOSTKEY_METHOD *privkeyobj;
+    void *hostkey_abstract;
+    struct iovec datavec;
+    int rc;
+
+    rc = memory_read_privatekey(session, &privkeyobj, &hostkey_abstract,
+                                session->userauth_pblc_method,
+                                session->userauth_pblc_method_len,
+                                pk_file->filename,
+                                strlen(pk_file->filename),
+                                pk_file->passphrase);
+    if(rc)
+        return rc;
+
+    datavec.iov_base = (void *)data;
+    datavec.iov_len  = data_len;
+
+    if (privkeyobj->signv(session, sig, sig_len, 1, &datavec,
+                          &hostkey_abstract)) {
+        if (privkeyobj->dtor) {
+            privkeyobj->dtor(session, abstract);
+        }
+        return -1;
+    }
+
+    if (privkeyobj->dtor) {
+        privkeyobj->dtor(session, &hostkey_abstract);
+    }
+    return 0;
+}
+
+static int
 sign_fromfile(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
               const unsigned char *data, size_t data_len, void **abstract)
 {
@@ -1211,6 +1353,65 @@ _libssh2_userauth_publickey(LIBSSH2_SESSION *session,
                           "username/public key combination");
 }

+ /*
+  * userauth_publickey_frommemory
+  * Authenticate using a keypair from memory
+  */
+static int
+userauth_publickey_frommemory(LIBSSH2_SESSION *session,
+                              const char *username,
+                              size_t username_len,
+                              const char *publickeydata,
+                              size_t publickeydata_len,
+                              const char *privatekeydata,
+                              size_t privatekeydata_len,
+                              const char *passphrase)
+{
+    unsigned char *pubkeydata = NULL;
+    size_t pubkeydata_len = 0;
+    struct privkey_file privkey_file;
+    void *abstract = &privkey_file;
+    int rc;
+
+    privkey_file.filename = privatekeydata;
+    privkey_file.passphrase = passphrase;
+
+    if (session->userauth_pblc_state == libssh2_NB_state_idle) {
+        if (publickeydata_len && publickeydata) {
+            rc = memory_read_publickey(session, &session->userauth_pblc_method,
+                                       &session->userauth_pblc_method_len,
+                                       &pubkeydata, &pubkeydata_len,
+                                       publickeydata, publickeydata_len);
+            if(rc)
+                return rc;
+        }
+        else if (privatekeydata_len && privatekeydata) {
+            /* Compute public key from private key. */
+            if (_libssh2_pub_priv_keyfilememory(session,
+                                                &session->userauth_pblc_method,
+
&session->userauth_pblc_method_len,
+                                                &pubkeydata, &pubkeydata_len,
+                                                privatekeydata,
privatekeydata_len,
+                                                passphrase))
+                return _libssh2_error(session, LIBSSH2_ERROR_FILE,
+                                      "Unable to extract public key "
+                                      "from private key.");
+        }
+        else {
+            return _libssh2_error(session, LIBSSH2_ERROR_FILE,
+                                  "Invalid data in public and private key.");
+        }
+    }
+
+    rc = _libssh2_userauth_publickey(session, username, username_len,
+                                     pubkeydata, pubkeydata_len,
+                                     sign_frommemory, &abstract);
+    if(pubkeydata)
+        LIBSSH2_FREE(session, pubkeydata);
+
+    return rc;
+}
+
 /*
  * userauth_publickey_fromfile
  * Authenticate using a keypair found in the named files
@@ -1263,6 +1464,36 @@ userauth_publickey_fromfile(LIBSSH2_SESSION *session,
     return rc;
 }

+/* libssh2_userauth_publickey_frommemory
+ * Authenticate using a keypair from memory
+ */
+LIBSSH2_API int
+libssh2_userauth_publickey_frommemory_ex(LIBSSH2_SESSION *session,
+                                      const char *user,
+                                      unsigned int user_len,
+                                      const char *publickeyfiledata,
+                                      size_t publickeyfiledata_len,
+                                      const char *privatekeyfiledata,
+                                      size_t privatekeyfiledata_len,
+                                      const char *passphrase)
+{
+    int rc;
+
+    if(NULL == passphrase)
+        /* if given a NULL pointer, make it point to a zero-length
+           string to save us from having to check this all over */
+        passphrase="";
+
+    BLOCK_ADJUST(rc, session,
+                 userauth_publickey_frommemory(session, user, user_len,
+                                               publickeyfiledata,
+                                               publickeyfiledata_len,
+                                               privatekeyfiledata,
+                                               privatekeyfiledata_len,
+                                               passphrase));
+    return rc;
+}
+
 /* libssh2_userauth_publickey_fromfile_ex
  * Authenticate using a keypair found in the named files
  */


Cheers,
David

On Tue, Sep 16, 2014 at 10:14 AM, Peter Stuge <peter@stuge.se> wrote:

> Alexander Lamaison wrote:
> > we're already in this situation.
>
> Yeah, and I want that to get better instead of worse.
>
>
> //Peter
> _______________________________________________
> libssh2-devel http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel
>

--047d7bd75b30c09e2505039bb533
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Thanks for your feedback, Peter, Daniel and Alex.<div><br>=
</div><div>Peter, I totally understand your concern. I took my time to repl=
y because I tried to do it right, but I have to be realistic here and hones=
t with myself.</div><div><br></div><div>I feel like reading the keys from m=
emory to implement the same logic for libgcrypt might not be too complicate=
d, unfortunately my C skills are really rusty, and I don&#39;t think I&#39;=
m the right person to make it right. On the other hand, I&#39;ll be super g=
lad to assist anybody that can help me, we can do a remote pair session or =
talk over skype or whatever is best to reach a better solution.</div><div><=
br></div><div>As a sort term solution, I added the necessary methods to scr=
/libgcrypt.c to return an unimplemented error, like it already does parting=
 public keys from private key files.</div><div><br></div><div>I&#39;d still=
 love to see this merged into the main project, I think it would be really =
useful for people implemented on top of libssh2, and I&#39;m at your dispos=
al for anything I can help.</div><div><br></div><div>This is the new patch =
with those methods inside libgcrypt:</div><div><br></div><div><a href=3D"ht=
tps://github.com/calavera/libssh2/commit/c031101aede6195376415178a5fcce80c5=
56a8e3">https://github.com/calavera/libssh2/commit/c031101aede6195376415178=
a5fcce80c556a8e3</a><br></div><div><a href=3D"https://github.com/calavera/l=
ibssh2/commit/c031101aede6195376415178a5fcce80c556a8e3.patch">https://githu=
b.com/calavera/libssh2/commit/c031101aede6195376415178a5fcce80c556a8e3.patc=
h</a><br></div><div><br></div><div>And this is the raw patch for everybody =
in the list to see:</div><div><br></div><div><pre style=3D"color:rgb(0,0,0)=
;word-wrap:break-word;white-space:pre-wrap">From c031101aede6195376415178a5=
fcce80c556a8e3 Mon Sep 17 00:00:00 2001
From: David Calavera &lt;<a href=3D"mailto:david.calavera@gmail.com">david.=
calavera@gmail.com</a>&gt;
Date: Mon, 1 Sep 2014 15:54:05 -0700
Subject: [PATCH] Allow authentication keys to be passed in memory.

All credits go to Joe Turpin, I&#39;m just reaplying and cleaning his patch=
:
<a href=3D"http://www.libssh2.org/mail/libssh2-devel-archive-2012-01/0015.s=
html">http://www.libssh2.org/mail/libssh2-devel-archive-2012-01/0015.shtml<=
/a>

* Adds libssh2_userauth_publickey_frommemory macro for libssh2_userauth_pub=
lickey_frommemory_ex.
* Use an unimplemented error for extracting keys from memory with libgcrypt=
.
---
 docs/libssh2_userauth_publickey_frommemory.3    |  22 +++
 docs/libssh2_userauth_publickey_frommemory_ex.3 |  55 ++++++
 include/libssh2.h                               |  20 ++
 src/crypto.h                                    |  16 ++
 src/hostkey.c                                   |  66 +++++++
 src/libgcrypt.c                                 |  37 ++++
 src/libssh2_priv.h                              |   3 +
 src/openssl.c                                   | 121 +++++++++++++
 src/userauth.c                                  | 231 ++++++++++++++++++++=
++++
 9 files changed, 571 insertions(+)
 create mode 100644 docs/libssh2_userauth_publickey_frommemory.3
 create mode 100644 docs/libssh2_userauth_publickey_frommemory_ex.3

diff --git a/docs/libssh2_userauth_publickey_frommemory.3 b/docs/libssh2_us=
erauth_publickey_frommemory.3
new file mode 100644
index 0000000..e464e71
--- /dev/null
+++ b/docs/libssh2_userauth_publickey_frommemory.3
@@ -0,0 +1,22 @@
+.TH libssh2_userauth_publickey_frommemory 3 &quot;1 Sep 2014&quot; &quot;l=
ibssh2 1.5&quot; &quot;libssh2 manual&quot;
+.SH NAME
+libssh2_userauth_publickey_frommemory - convenience macro for \fIlibssh2_u=
serauth_publickey_frommemory_ex(3)\fP calls
+.SH SYNOPSIS
+#include &lt;libssh2.h&gt;
+
+int
+libssh2_userauth_publickey_frommemory(LIBSSH2_SESSION *session,
+                                      const char *username,
+                                      const char *publickey,
+                                      const char *privatekey,
+                                      const char *passphrase);
+
+.SH DESCRIPTION
+This is a macro defined in a public libssh2 header file that is using the
+underlying function \fIlibssh2_userauth_publickey_frommemory_ex(3)\fP.
+.SH RETURN VALUE
+See \fIlibssh2_userauth_publickey_frommemory_ex(3)\fP
+.SH ERRORS
+See \fIlibssh2_userauth_publickey_frommemory_ex(3)\fP
+.SH SEE ALSO
+.BR libssh2_userauth_publickey_frommemory_ex(3)
diff --git a/docs/libssh2_userauth_publickey_frommemory_ex.3 b/docs/libssh2=
_userauth_publickey_frommemory_ex.3
new file mode 100644
index 0000000..6faf5d1
--- /dev/null
+++ b/docs/libssh2_userauth_publickey_frommemory_ex.3
@@ -0,0 +1,55 @@
+.TH libssh2_userauth_publickey_frommemory_ex 3 &quot;1 Sep 2014&quot; &quo=
t;libssh2 1.5&quot; &quot;libssh2 manual&quot;
+.SH NAME
+libssh2_userauth_publickey_frommemory_ex - authenticate a session with a p=
ublic key, read from memory
+.SH SYNOPSIS
+#include &lt;libssh2.h&gt;
+
+.nf
+int libssh2_userauth_publickey_frommemory_ex(LIBSSH2_SESSION *session,
+                                           const char *username,
+                                           unsigned int username_len,
+                                           const char *publickeydata,
+                                           size_t publickeydata_len,
+                                           const char *privatekeydata,
+                                           size_t privatekeydata_len,
+                                           const char *passphrase);
+.SH DESCRIPTION
+\fIsession\fP - Session instance as returned by
+.BR libssh2_session_init_ex(3)
+
+\fIusername\fP - Remote user name to authenticate as.
+
+\fIusername_len\fP - Length of username.
+
+\fIpublickeydata\fP - Buffer containing the contents of a public key file.
+
+\fIpublickeydata_len\fP - Length of public key data.
+
+\fIprivatekeydata\fP - Buffer containing the contents of a private key fil=
e.
+
+\fIprivatekeydata_len\fP - Length of private key data.
+
+\fIpassphrase\fP - Passphrase to use when decoding private key file.
+
+Attempt public key authentication using a PEM encoded private key file sto=
red in memory.
+
+.SH RETURN VALUE
+Return 0 on success or negative on failure.  It returns
+LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
+LIBSSH2_ERROR_EAGAIN is a negative number, it isn&#39;t really a failure p=
er se.
+
+.SH ERRORS
+\fILIBSSH2_ERROR_ALLOC\fP -  An internal memory allocation call failed.
+
+\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
+
+\fILIBSSH2_ERROR_SOCKET_TIMEOUT\fP -=20
+
+\fILIBSSH2_ERROR_PUBLICKEY_UNVERIFIED\fP - The username/public key
+combination was invalid.
+
+\fILIBSSH2_ERROR_AUTHENTICATION_FAILED\fP - Authentication using the suppl=
ied
+public key was not accepted.
+
+.SH SEE ALSO
+.BR libssh2_session_init_ex(3)
diff --git a/include/libssh2.h b/include/libssh2.h
index 565bf06..6e519db 100644
--- a/include/libssh2.h
+++ b/include/libssh2.h
@@ -576,6 +576,26 @@ libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION=
 *session,
                                         (username),                     \
                                         (unsigned int)strlen(username))
=20
+LIBSSH2_API int
+libssh2_userauth_publickey_frommemory_ex(LIBSSH2_SESSION *session,
+                                      const char *username,
+                                      unsigned int username_len,
+                                      const char *publickeyfiledata,
+                                      size_t publickeyfiledata_len,
+                                      const char *privatekeyfiledata,
+                                      size_t privatekeyfiledata_len,
+                                      const char *passphrase);
+
+#define libssh2_userauth_publickey_frommemory(session, username, publickey=
, \
+                                              privatekey, passphrase) \
+ libssh2_userauth_publickey_frommemory_ex((session), (username), \
+                                          (unsigned int)strlen(username), =
  \
+                                          (publickey),                    =
  \
+                                          (unsigned int)strlen(publickey),=
  \
+                                          (privatekey),                   =
  \
+                                          (unsigned int)strlen(privatekey)=
, \
+                                          (passphrase))
+
 /*
  * response_callback is provided with filled by library prompts array,
  * but client must allocate and fill individual responses. Responses
diff --git a/src/crypto.h b/src/crypto.h
index a615bb1..05f5a5c 100644
--- a/src/crypto.h
+++ b/src/crypto.h
@@ -80,6 +80,10 @@ int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
                            size_t hash_len,
                            unsigned char **signature,
                            size_t *signature_len);
+int _libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa,
+                                        LIBSSH2_SESSION * session,
+                                        const char *filedata, size_t filed=
ata_len,
+                                        unsigned const char *passphrase);
=20
 #if LIBSSH2_DSA
 int _libssh2_dsa_new(libssh2_dsa_ctx ** dsa,
@@ -102,6 +106,10 @@ int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
 int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
                            const unsigned char *hash,
                            unsigned long hash_len, unsigned char *sig);
+int _libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx ** dsa,
+                                        LIBSSH2_SESSION * session,
+                                        const char *filedata, size_t filed=
ata_len,
+                                        unsigned const char *passphrase);
 #endif
=20
 int _libssh2_cipher_init(_libssh2_cipher_ctx * h,
@@ -120,6 +128,14 @@ int _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session=
,
                               size_t *pubkeydata_len,
                               const char *privatekey,
                               const char *passphrase);
+int _libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
+                                    unsigned char **method,
+                                    size_t *method_len,
+                                    unsigned char **pubkeydata,
+                                    size_t *pubkeydata_len,
+                                    const char *privatekeydata,
+                                    size_t privatekeydata_len,
+                                    const char *passphrase);
=20
 void _libssh2_init_aes_ctr(void);
=20
diff --git a/src/hostkey.c b/src/hostkey.c
index 753563d..02d085a 100644
--- a/src/hostkey.c
+++ b/src/hostkey.c
@@ -131,6 +131,38 @@ hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION * sessi=
on,
 }
=20
 /*
+ * hostkey_method_ssh_rsa_initPEMFromMemory
+ *
+ * Load a Private Key from a memory
+ */
+static int
+hostkey_method_ssh_rsa_initPEMFromMemory(LIBSSH2_SESSION * session,
+                                         const char *privkeyfiledata,
+                                         size_t privkeyfiledata_len,
+                                         unsigned const char *passphrase,
+                                         void **abstract)
+{
+    libssh2_rsa_ctx *rsactx;
+    int ret;
+
+    if (*abstract) {
+        hostkey_method_ssh_rsa_dtor(session, abstract);
+        *abstract =3D NULL;
+    }
+
+    ret =3D _libssh2_rsa_new_private_frommemory(&amp;rsactx, session,
+                                              privkeyfiledata,
+                                              privkeyfiledata_len, passphr=
ase);
+    if (ret) {
+        return -1;
+    }
+
+    *abstract =3D rsactx;
+
+    return 0;
+}
+
+/*
  * hostkey_method_ssh_rsa_sign
  *
  * Verify signature created by remote
@@ -208,6 +240,7 @@ static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_=
rsa =3D {
     MD5_DIGEST_LENGTH,
     hostkey_method_ssh_rsa_init,
     hostkey_method_ssh_rsa_initPEM,
+    hostkey_method_ssh_rsa_initPEMFromMemory,
     hostkey_method_ssh_rsa_sig_verify,
     hostkey_method_ssh_rsa_signv,
     NULL,                       /* encrypt */
@@ -306,6 +339,38 @@ hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION * sessi=
on,
 }
=20
 /*
+ * hostkey_method_ssh_dss_initPEMFromMemory
+ *
+ * Load a Private Key from memory
+ */
+static int
+hostkey_method_ssh_dss_initPEMFromMemory(LIBSSH2_SESSION * session,
+                                         const char *privkeyfiledata,
+                                         size_t privkeyfiledata_len,
+                                         unsigned const char *passphrase,
+                                         void **abstract)
+{
+    libssh2_dsa_ctx *dsactx;
+    int ret;
+
+    if (*abstract) {
+        hostkey_method_ssh_dss_dtor(session, abstract);
+        *abstract =3D NULL;
+    }
+
+    ret =3D _libssh2_dsa_new_private_frommemory(&amp;dsactx, session,
+                                              privkeyfiledata,
+                                              privkeyfiledata_len, passphr=
ase);
+    if (ret) {
+        return -1;
+    }
+
+    *abstract =3D dsactx;
+
+    return 0;
+}
+
+/*
  * libssh2_hostkey_method_ssh_dss_sign
  *
  * Verify signature created by remote
@@ -392,6 +457,7 @@ static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_=
dss =3D {
     MD5_DIGEST_LENGTH,
     hostkey_method_ssh_dss_init,
     hostkey_method_ssh_dss_initPEM,
+    hostkey_method_ssh_dss_initPEMFromMemory,
     hostkey_method_ssh_dss_sig_verify,
     hostkey_method_ssh_dss_signv,
     NULL,                       /* encrypt */
diff --git a/src/libgcrypt.c b/src/libgcrypt.c
index 7d09ffb..e85aecd 100644
--- a/src/libgcrypt.c
+++ b/src/libgcrypt.c
@@ -150,6 +150,17 @@ _libssh2_dsa_new(libssh2_dsa_ctx ** dsactx,
 }
=20
 int
+_libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa,
+                                    LIBSSH2_SESSION * session,
+                                    const char *filedata, size_t filedata_=
len,
+                                    unsigned const char *passphrase)
+{
+    return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
+                         &quot;Unable to extract private key from memory: =
&quot;
+                         &quot;Method unimplemented in libgcrypt backend&q=
uot;);
+}
+
+int
 _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
                          LIBSSH2_SESSION * session,
                          const char *filename, unsigned const char *passph=
rase)
@@ -252,6 +263,17 @@ _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
 }
=20
 int
+_libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx ** dsa,
+                                    LIBSSH2_SESSION * session,
+                                    const char *filedata, size_t filedata_=
len,
+                                    unsigned const char *passphrase)
+{
+    return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
+                         &quot;Unable to extract private key from memory: =
&quot;
+                         &quot;Method unimplemented in libgcrypt backend&q=
uot;);
+}
+
+int
 _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
                          LIBSSH2_SESSION * session,
                          const char *filename, unsigned const char *passph=
rase)
@@ -567,6 +589,21 @@ _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
 }
=20
 int
+_libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
+                                unsigned char **method,
+                                size_t *method_len,
+                                unsigned char **pubkeydata,
+                                size_t *pubkeydata_len,
+                                const char *privatekeydata,
+                                size_t privatekeydata_len,
+                                const char *passphrase)
+{
+    return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
+                         &quot;Unable to extract public key from private k=
ey in memory: &quot;
+                         &quot;Method unimplemented in libgcrypt backend&q=
uot;);
+}
+
+int
 _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session,
                           unsigned char **method,
                           size_t *method_len,
diff --git a/src/libssh2_priv.h b/src/libssh2_priv.h
index 00ed240..0274d83 100644
--- a/src/libssh2_priv.h
+++ b/src/libssh2_priv.h
@@ -853,6 +853,9 @@ struct _LIBSSH2_HOSTKEY_METHOD
                  size_t hostkey_data_len, void **abstract);
     int (*initPEM) (LIBSSH2_SESSION * session, const char *privkeyfile,
                     unsigned const char *passphrase, void **abstract);
+    int (*initPEMFromMemory) (LIBSSH2_SESSION * session,
+                              const char *privkeyfiledata, size_t privkeyf=
iledata_len,
+                              unsigned const char *passphrase, void **abst=
ract);
     int (*sig_verify) (LIBSSH2_SESSION * session, const unsigned char *sig=
,
                        size_t sig_len, const unsigned char *m,
                        size_t m_len, void **abstract);
diff --git a/src/openssl.c b/src/openssl.c
index 056b0b7..2e31472 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -388,6 +388,28 @@ typedef void * (*pem_read_bio_func)(BIO *, void **, pe=
m_password_cb *,
                                     void * u);
=20
 static int
+read_private_key_from_memory(void ** key_ctx,
+                             pem_read_bio_func read_private_key,
+                             const char * filedata,
+                             size_t filedata_len,
+                             unsigned const char *passphrase)
+{
+    BIO * bp;
+
+    *key_ctx =3D NULL;
+
+    bp =3D BIO_new_mem_buf(filedata, filedata_len);
+    if (!bp) {
+        return -1;
+    }
+    *key_ctx =3D read_private_key(bp, NULL, (pem_password_cb *) passphrase=
_cb,
+                                (void *) passphrase);
+
+    BIO_free(bp);
+    return (*key_ctx) ? 0 : -1;
+}
+
+static int
 read_private_key_from_file(void ** key_ctx,
                            pem_read_bio_func read_private_key,
                            const char * filename,
@@ -409,6 +431,22 @@ read_private_key_from_file(void ** key_ctx,
     return (*key_ctx) ? 0 : -1;
 }
=20
+ int
+_libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa,
+                                    LIBSSH2_SESSION * session,
+                                    const char *filedata, size_t filedata_=
len,
+                                    unsigned const char *passphrase)
+{
+    pem_read_bio_func read_rsa =3D
+        (pem_read_bio_func) &amp;PEM_read_bio_RSAPrivateKey;
+    (void) session;
+
+    _libssh2_init_if_needed();
+
+    return read_private_key_from_memory((void **) rsa, read_rsa,
+                                        filedata, filedata_len, passphrase=
);
+}
+
 int
 _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
                          LIBSSH2_SESSION * session,
@@ -426,6 +464,22 @@ _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
=20
 #if LIBSSH2_DSA
 int
+_libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx ** dsa,
+                                    LIBSSH2_SESSION * session,
+                                    const char *filedata, size_t filedata_=
len,
+                                    unsigned const char *passphrase)
+{
+    pem_read_bio_func read_dsa =3D
+        (pem_read_bio_func) &amp;PEM_read_bio_DSAPrivateKey;
+    (void) session;
+
+    _libssh2_init_if_needed();
+
+    return read_private_key_from_memory((void **) dsa, read_dsa,
+                                        filedata, filedata_len, passphrase=
);
+}
+
+int
 _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
                          LIBSSH2_SESSION * session,
                          const char *filename, unsigned const char *passph=
rase)
@@ -817,4 +871,71 @@ _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session,
     return st;
 }
=20
+int
+_libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
+                                unsigned char **method,
+                                size_t *method_len,
+                                unsigned char **pubkeydata,
+                                size_t *pubkeydata_len,
+                                const char *privatekeydata,
+                                size_t privatekeydata_len,
+                                const char *passphrase)
+{
+    int       st;
+    BIO*      bp;
+    EVP_PKEY* pk;
+
+    _libssh2_debug(session,
+                   LIBSSH2_TRACE_AUTH,
+                   &quot;Computing public key from private key.&quot;);
+
+    bp =3D BIO_new_mem_buf(privatekeydata, privatekeydata_len);
+    if (!bp) {
+        return -1;
+    }
+    if (!EVP_get_cipherbyname(&quot;des&quot;)) {
+        /* If this cipher isn&#39;t loaded it&#39;s a pretty good indicati=
on that none
+         * are.  I have *NO DOUBT* that there&#39;s a better way to deal w=
ith this
+         * ($#&amp;%#$(%$#( Someone buy me an OpenSSL manual and I&#39;ll =
read up on
+         * it.
+         */
+        OpenSSL_add_all_ciphers();
+    }
+    BIO_reset(bp);
+    pk =3D PEM_read_bio_PrivateKey(bp, NULL, NULL, (void*)passphrase);
+    BIO_free(bp);
+
+    if (pk =3D=3D NULL) {
+        return _libssh2_error(session,
+                              LIBSSH2_ERROR_FILE,
+                              &quot;Unable to extract public key &quot;
+                              &quot;from private key file: &quot;
+                              &quot;Wrong passphrase or invalid/unrecogniz=
ed &quot;
+                              &quot;private key file format&quot;);
+    }
+
+    switch (pk-&gt;type) {
+    case EVP_PKEY_RSA :
+        st =3D gen_publickey_from_rsa_evp(session, method, method_len,
+                                        pubkeydata, pubkeydata_len, pk);
+        break;
+
+    case EVP_PKEY_DSA :
+        st =3D gen_publickey_from_dsa_evp(session, method, method_len,
+                                        pubkeydata, pubkeydata_len, pk);
+        break;
+
+    default :
+        st =3D _libssh2_error(session,
+                            LIBSSH2_ERROR_FILE,
+                            &quot;Unable to extract public key &quot;
+                            &quot;from private key file: &quot;
+                            &quot;Unsupported private key file format&quot=
;);
+        break;
+    }
+
+    EVP_PKEY_free(pk);
+    return st;
+}
+
 #endif /* LIBSSH2_OPENSSL */
diff --git a/src/userauth.c b/src/userauth.c
index edfe729..afbe172 100644
--- a/src/userauth.c
+++ b/src/userauth.c
@@ -441,6 +441,76 @@ libssh2_userauth_password_ex(LIBSSH2_SESSION *session,=
 const char *username,
     return rc;
 }
=20
+static int
+memory_read_publickey(LIBSSH2_SESSION * session, unsigned char **method,
+                      size_t *method_len,
+                      unsigned char **pubkeydata,
+                      size_t *pubkeydata_len,
+                      const char *pubkeyfiledata,
+                      size_t pubkeyfiledata_len)
+{
+    unsigned char *pubkey =3D NULL, *sp1, *sp2, *tmp;
+    size_t pubkey_len =3D pubkeyfiledata_len;
+    unsigned int tmp_len;
+
+    if (pubkeyfiledata_len &lt;=3D 1) {
+        return _libssh2_error(session, LIBSSH2_ERROR_FILE,
+                              &quot;Invalid data in public key file&quot;)=
;
+    }
+
+    pubkey =3D LIBSSH2_ALLOC(session, pubkeyfiledata_len);
+    if (!pubkey) {
+        return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
+                              &quot;Unable to allocate memory for public k=
ey data&quot;);
+    }
+
+    memcpy(pubkey, pubkeyfiledata, pubkeyfiledata_len);
+
+    /*
+     *   Remove trailing whitespace
+     */
+    while (pubkey_len &amp;&amp; isspace(pubkey[pubkey_len - 1]))
+        pubkey_len--;
+
+    if (!pubkey_len) {
+        LIBSSH2_FREE(session, pubkey);
+        return _libssh2_error(session, LIBSSH2_ERROR_FILE,
+                              &quot;Missing public key data&quot;);
+    }
+
+    if ((sp1 =3D memchr(pubkey, &#39; &#39;, pubkey_len)) =3D=3D NULL) {
+        LIBSSH2_FREE(session, pubkey);
+        return _libssh2_error(session, LIBSSH2_ERROR_FILE,
+                              &quot;Invalid public key data&quot;);
+    }
+
+    sp1++;
+
+    if ((sp2 =3D memchr(sp1, &#39; &#39;, pubkey_len - (sp1 - pubkey - 1))=
) =3D=3D NULL) {
+        /* Assume that the id string is missing, but that it&#39;s okay */
+        sp2 =3D pubkey + pubkey_len;
+    }
+
+    if (libssh2_base64_decode(session, (char **) &amp;tmp, &amp;tmp_len,
+                              (char *) sp1, sp2 - sp1)) {
+        LIBSSH2_FREE(session, pubkey);
+        return _libssh2_error(session, LIBSSH2_ERROR_FILE,
+                                  &quot;Invalid key data, not base64 encod=
ed&quot;);
+    }
+
+    /* Wasting some bytes here (okay, more than some), but since it&#39;s =
likely
+     * to be freed soon anyway, we&#39;ll just avoid the extra free/alloc =
and call
+     * it a wash
+     */
+    *method =3D pubkey;
+    *method_len =3D sp1 - pubkey - 1;
+
+    *pubkeydata =3D tmp;
+    *pubkeydata_len =3D tmp_len;
+
+    return 0;
+}
+
 /*
  * file_read_publickey
  *
@@ -543,7 +613,43 @@ file_read_publickey(LIBSSH2_SESSION * session, unsigne=
d char **method,
     return 0;
 }
=20
+static int
+memory_read_privatekey(LIBSSH2_SESSION * session,
+                       const LIBSSH2_HOSTKEY_METHOD ** hostkey_method,
+                       void **hostkey_abstract,
+                       const unsigned char *method, int method_len,
+                       const char *privkeyfiledata, size_t privkeyfiledata=
_len,
+                       const char *passphrase)
+{
+    const LIBSSH2_HOSTKEY_METHOD **hostkey_methods_avail =3D
+        libssh2_hostkey_methods();
+
+    *hostkey_method =3D NULL;
+    *hostkey_abstract =3D NULL;
+    while (*hostkey_methods_avail &amp;&amp; (*hostkey_methods_avail)-&gt;=
name) {
+        if ((*hostkey_methods_avail)-&gt;initPEMFromMemory
+             &amp;&amp; strncmp((*hostkey_methods_avail)-&gt;name, (const =
char *) method,
+                        method_len) =3D=3D 0) {
+            *hostkey_method =3D *hostkey_methods_avail;
+            break;
+        }
+        hostkey_methods_avail++;
+    }
+    if (!*hostkey_method) {
+        return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NONE,
+                              &quot;No handler for specified private key&q=
uot;);
+    }
+
+    if ((*hostkey_method)-&gt;
+        initPEMFromMemory(session, privkeyfiledata, privkeyfiledata_len,
+                          (unsigned char *) passphrase,
+                          hostkey_abstract)) {
+        return _libssh2_error(session, LIBSSH2_ERROR_FILE,
+                              &quot;Unable to initialize private key from =
file&quot;);
+    }
=20
+    return 0;
+}
=20
 /* libssh2_file_read_privatekey
  * Read a PEM encoded private key from an id_??? style file
@@ -592,6 +698,42 @@ struct privkey_file {
 };
=20
 static int
+sign_frommemory(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig=
_len,
+                const unsigned char *data, size_t data_len, void **abstrac=
t)
+{
+    struct privkey_file *pk_file =3D (struct privkey_file *) (*abstract);
+    const LIBSSH2_HOSTKEY_METHOD *privkeyobj;
+    void *hostkey_abstract;
+    struct iovec datavec;
+    int rc;
+
+    rc =3D memory_read_privatekey(session, &amp;privkeyobj, &amp;hostkey_a=
bstract,
+                                session-&gt;userauth_pblc_method,
+                                session-&gt;userauth_pblc_method_len,
+                                pk_file-&gt;filename,
+                                strlen(pk_file-&gt;filename),
+                                pk_file-&gt;passphrase);
+    if(rc)
+        return rc;
+
+    datavec.iov_base =3D (void *)data;
+    datavec.iov_len  =3D data_len;
+
+    if (privkeyobj-&gt;signv(session, sig, sig_len, 1, &amp;datavec,
+                          &amp;hostkey_abstract)) {
+        if (privkeyobj-&gt;dtor) {
+            privkeyobj-&gt;dtor(session, abstract);
+        }
+        return -1;
+    }
+
+    if (privkeyobj-&gt;dtor) {
+        privkeyobj-&gt;dtor(session, &amp;hostkey_abstract);
+    }
+    return 0;
+}
+
+static int
 sign_fromfile(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_l=
en,
               const unsigned char *data, size_t data_len, void **abstract)
 {
@@ -1211,6 +1353,65 @@ _libssh2_userauth_publickey(LIBSSH2_SESSION *session=
,
                           &quot;username/public key combination&quot;);
 }
=20
+ /*
+  * userauth_publickey_frommemory
+  * Authenticate using a keypair from memory
+  */
+static int
+userauth_publickey_frommemory(LIBSSH2_SESSION *session,
+                              const char *username,
+                              size_t username_len,
+                              const char *publickeydata,
+                              size_t publickeydata_len,
+                              const char *privatekeydata,
+                              size_t privatekeydata_len,
+                              const char *passphrase)
+{
+    unsigned char *pubkeydata =3D NULL;
+    size_t pubkeydata_len =3D 0;
+    struct privkey_file privkey_file;
+    void *abstract =3D &amp;privkey_file;
+    int rc;
+
+    privkey_file.filename =3D privatekeydata;
+    privkey_file.passphrase =3D passphrase;
+
+    if (session-&gt;userauth_pblc_state =3D=3D libssh2_NB_state_idle) {
+        if (publickeydata_len &amp;&amp; publickeydata) {
+            rc =3D memory_read_publickey(session, &amp;session-&gt;useraut=
h_pblc_method,
+                                       &amp;session-&gt;userauth_pblc_meth=
od_len,
+                                       &amp;pubkeydata, &amp;pubkeydata_le=
n,
+                                       publickeydata, publickeydata_len);
+            if(rc)
+                return rc;
+        }
+        else if (privatekeydata_len &amp;&amp; privatekeydata) {
+            /* Compute public key from private key. */
+            if (_libssh2_pub_priv_keyfilememory(session,
+                                                &amp;session-&gt;userauth_=
pblc_method,
+                                                &amp;session-&gt;userauth_=
pblc_method_len,
+                                                &amp;pubkeydata, &amp;pubk=
eydata_len,
+                                                privatekeydata, privatekey=
data_len,
+                                                passphrase))
+                return _libssh2_error(session, LIBSSH2_ERROR_FILE,
+                                      &quot;Unable to extract public key &=
quot;
+                                      &quot;from private key.&quot;);
+        }
+        else {
+            return _libssh2_error(session, LIBSSH2_ERROR_FILE,
+                                  &quot;Invalid data in public and private=
 key.&quot;);
+        }
+    }
+
+    rc =3D _libssh2_userauth_publickey(session, username, username_len,
+                                     pubkeydata, pubkeydata_len,
+                                     sign_frommemory, &amp;abstract);
+    if(pubkeydata)
+        LIBSSH2_FREE(session, pubkeydata);
+
+    return rc;
+}
+
 /*
  * userauth_publickey_fromfile
  * Authenticate using a keypair found in the named files
@@ -1263,6 +1464,36 @@ userauth_publickey_fromfile(LIBSSH2_SESSION *session=
,
     return rc;
 }
=20
+/* libssh2_userauth_publickey_frommemory
+ * Authenticate using a keypair from memory
+ */
+LIBSSH2_API int
+libssh2_userauth_publickey_frommemory_ex(LIBSSH2_SESSION *session,
+                                      const char *user,
+                                      unsigned int user_len,
+                                      const char *publickeyfiledata,
+                                      size_t publickeyfiledata_len,
+                                      const char *privatekeyfiledata,
+                                      size_t privatekeyfiledata_len,
+                                      const char *passphrase)
+{
+    int rc;
+
+    if(NULL =3D=3D passphrase)
+        /* if given a NULL pointer, make it point to a zero-length
+           string to save us from having to check this all over */
+        passphrase=3D&quot;&quot;;
+
+    BLOCK_ADJUST(rc, session,
+                 userauth_publickey_frommemory(session, user, user_len,
+                                               publickeyfiledata,
+                                               publickeyfiledata_len,
+                                               privatekeyfiledata,
+                                               privatekeyfiledata_len,
+                                               passphrase));
+    return rc;
+}
+
 /* libssh2_userauth_publickey_fromfile_ex
  * Authenticate using a keypair found in the named files
  */</pre></div><div><br></div><div>Cheers,</div><div>David</div></div><div=
 class=3D"gmail_extra"><br><div class=3D"gmail_quote">On Tue, Sep 16, 2014 =
at 10:14 AM, Peter Stuge <span dir=3D"ltr">&lt;<a href=3D"mailto:peter@stug=
e.se" target=3D"_blank">peter@stuge.se</a>&gt;</span> wrote:<br><blockquote=
 class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc soli=
d;padding-left:1ex"><span class=3D"">Alexander Lamaison wrote:<br>
&gt; we&#39;re already in this situation.<br>
<br>
</span>Yeah, and I want that to get better instead of worse.<br>
<div class=3D"HOEnZb"><div class=3D"h5"><br>
<br>
//Peter<br>
_______________________________________________<br>
libssh2-devel <a href=3D"http://cool.haxx.se/cgi-bin/mailman/listinfo/libss=
h2-devel" target=3D"_blank">http://cool.haxx.se/cgi-bin/mailman/listinfo/li=
bssh2-devel</a><br>
</div></div></blockquote></div><br></div>

--047d7bd75b30c09e2505039bb533--

--===============1947081051==
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: base64
Content-Disposition: inline

X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KbGlic3NoMi1k
ZXZlbCBodHRwOi8vY29vbC5oYXh4LnNlL2NnaS1iaW4vbWFpbG1hbi9saXN0aW5mby9saWJzc2gy
LWRldmVsCg==

--===============1947081051==--

From libssh2-devel-bounces@cool.haxx.se  Wed Sep 24 19:47:18 2014
Return-Path: <libssh2-devel-bounces@cool.haxx.se>
Received: from www.haxx.se (localhost.localdomain [127.0.0.1])
	by giant.haxx.se (8.14.4/8.14.4/Debian-7) with ESMTP id s8OHki27025028;
	Wed, 24 Sep 2014 19:47:13 +0200
Received: from mail-lb0-f177.google.com (mail-lb0-f177.google.com
 [209.85.217.177])
 by giant.haxx.se (8.14.4/8.14.4/Debian-7) with ESMTP id s8OHkges025005
 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-RC4-SHA bits=128 verify=NOT)
 for <libssh2-devel@cool.haxx.se>; Wed, 24 Sep 2014 19:46:43 +0200
Received: by mail-lb0-f177.google.com with SMTP id z12so10907749lbi.8
 for <libssh2-devel@cool.haxx.se>; Wed, 24 Sep 2014 10:46:38 -0700 (PDT)
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20130820;
 h=x-gm-message-state:mime-version:in-reply-to:references:date
 :message-id:subject:from:to:content-type;
 bh=xencz5vCkI6tSl8MYRt4oLmTMza5SYqvGeYRBMasQ44=;
 b=UoKnQfemItRIAjuMaFeoLJJD1Wkqalqg50h/bQqSp/CdWOXTBXMiFyH9LDwON+kaPa
 WNWoauda9XUPTlJLpbpjGgtnyuFxaexDcBQt15AwmkLdJFfc99znv3s28x3b64TaHN2x
 7qIdsDCsLMrWdSwHitaCJWWhFozlRVtlzNjwaxuWyf8qFdF2YscFKR4SO3TE2aE/juQH
 eUla4Wpy9vqvZGq3v9wWzrrm9xoLt2ZGHZvAv+ncXRWozM4Lwiq90a0oyb799nKsw8pv
 FKX5skYaBYa4tmUxullEbZQ1HRj0g35A6pqYzknDDbMB2GwZgu4+1jHV3UoSLqc9Xpnk
 s8LA==
X-Gm-Message-State: ALoCoQku0lr+4QPiy/l9f5ekx8Avt53ZCwlyO5Vt+QtgNXt7HUJApfDt9SCMIl4PXxmH1zVH9GZK
MIME-Version: 1.0
X-Received: by 10.152.203.167 with SMTP id kr7mr8093442lac.9.1411580798170;
 Wed, 24 Sep 2014 10:46:38 -0700 (PDT)
Received: by 10.114.78.65 with HTTP; Wed, 24 Sep 2014 10:46:38 -0700 (PDT)
In-Reply-To: <alpine.DEB.2.00.1409150935440.18125@tvnag.unkk.fr>
References: <20140829084531.GA20487@joerntop.localnet>
 <CA+z1VpNTdB2GFWA8yt1u8gjDArwKHVYnuMwwWV+vn76AufqOzg@mail.gmail.com>
 <alpine.DEB.2.00.1409150035100.18125@tvnag.unkk.fr>
 <8abfef00a5f00ef3968e157f5da39e93@mail.gmail.com>
 <20140915073354.3817.qmail@stuge.se>
 <alpine.DEB.2.00.1409150935440.18125@tvnag.unkk.fr>
Date: Wed, 24 Sep 2014 23:16:38 +0530
Message-ID: <CA+z1VpO7NyErE4O-vhWXd+vw2HVXTC0kug9FJsVDBkOm65GQ9g@mail.gmail.com>
Subject: Re: Download text file via SFTP
From: Nitin Deokate <ndeokate@qualys.com>
To: libssh2 development <libssh2-devel@cool.haxx.se>
X-BeenThere: libssh2-devel@cool.haxx.se
X-Mailman-Version: 2.1.16
Precedence: list
Reply-To: libssh2 development <libssh2-devel@cool.haxx.se>
List-Id: libssh2 development <libssh2-devel.cool.haxx.se>
List-Unsubscribe: <http://cool.haxx.se/cgi-bin/mailman/options/libssh2-devel>, 
 <mailto:libssh2-devel-request@cool.haxx.se?subject=unsubscribe>
List-Archive: <http://cool.haxx.se/pipermail/libssh2-devel/>
List-Post: <mailto:libssh2-devel@cool.haxx.se>
List-Help: <mailto:libssh2-devel-request@cool.haxx.se?subject=help>
List-Subscribe: <http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel>, 
 <mailto:libssh2-devel-request@cool.haxx.se?subject=subscribe>
Content-Type: multipart/mixed; boundary="===============2094245013=="
Errors-To: libssh2-devel-bounces@cool.haxx.se
Sender: "libssh2-devel" <libssh2-devel-bounces@cool.haxx.se>

--===============2094245013==
Content-Type: multipart/alternative; boundary=001a1134652e0c08de0503d344a6

--001a1134652e0c08de0503d344a6
Content-Type: text/plain; charset=UTF-8

Hi Peter, Daniel
Correct me if I am wrong or if I am missing something here.
I had tried test program mentioned here:
http://www.libssh2.org/examples/sftp.html with high and low latency.
The issue is reproducible.  hope you can help

thanks
Nitin

On Mon, Sep 15, 2014 at 1:08 PM, Daniel Stenberg <daniel@haxx.se> wrote:

> On Mon, 15 Sep 2014, Peter Stuge wrote:
>
>  according to you(in older mail thread), we should get higher chunks in
>>> subsequent calls, which does not happen in any way.
>>>
>>
>> Focus on this - this seems to be the actual issue.
>>
>
> I agree with this.
>
> I think I've explained the idea behind these "chunks" several times by
> now, but if things are still unclear I can try to explain it even further.
>
> If that then ends up not working for anyone in a particular use case, then
> there's a problem and possibly a bug and the way to go from there is of
> course to debug and see why libssh2 doesn't return multple chunks in
> subsquent calls.
>
>
> --
>
>  / daniel.haxx.se
> _______________________________________________
> libssh2-devel http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel
>

--001a1134652e0c08de0503d344a6
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Hi Peter, Daniel<div>Correct me if I am wrong or if I am m=
issing something here.</div><div>I had tried test program mentioned here:=
=C2=A0<a href=3D"http://www.libssh2.org/examples/sftp.html">http://www.libs=
sh2.org/examples/sftp.html</a> with high and low latency.=C2=A0</div><div>T=
he issue is reproducible. =C2=A0hope you can help</div><div><br></div><div>=
thanks</div><div>Nitin</div></div><div class=3D"gmail_extra"><br><div class=
=3D"gmail_quote">On Mon, Sep 15, 2014 at 1:08 PM, Daniel Stenberg <span dir=
=3D"ltr">&lt;<a href=3D"mailto:daniel@haxx.se" target=3D"_blank">daniel@hax=
x.se</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=3D=
"">On Mon, 15 Sep 2014, Peter Stuge wrote:<br>
<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><blockquote class=3D"gmail_quote" style=3D"m=
argin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
according to you(in older mail thread), we should get higher chunks in<br>
subsequent calls, which does not happen in any way.<br>
</blockquote>
<br>
Focus on this - this seems to be the actual issue.<br>
</blockquote>
<br></span>
I agree with this.<br>
<br>
I think I&#39;ve explained the idea behind these &quot;chunks&quot; several=
 times by now, but if things are still unclear I can try to explain it even=
 further.<br>
<br>
If that then ends up not working for anyone in a particular use case, then =
there&#39;s a problem and possibly a bug and the way to go from there is of=
 course to debug and see why libssh2 doesn&#39;t return multple chunks in s=
ubsquent calls.<div class=3D"HOEnZb"><div class=3D"h5"><br>
<br>
-- <br>
<br>
=C2=A0/ <a href=3D"http://daniel.haxx.se" target=3D"_blank">daniel.haxx.se<=
/a><br>
______________________________<u></u>_________________<br>
libssh2-devel <a href=3D"http://cool.haxx.se/cgi-bin/mailman/listinfo/libss=
h2-devel" target=3D"_blank">http://cool.haxx.se/cgi-bin/<u></u>mailman/list=
info/libssh2-devel</a><br>
</div></div></blockquote></div><br></div>

--001a1134652e0c08de0503d344a6--

--===============2094245013==
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: base64
Content-Disposition: inline

X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KbGlic3NoMi1k
ZXZlbCBodHRwOi8vY29vbC5oYXh4LnNlL2NnaS1iaW4vbWFpbG1hbi9saXN0aW5mby9saWJzc2gy
LWRldmVsCg==

--===============2094245013==--

