#include "crypto_uint32.h"
#include "crypto_uint16.h"
#include "crypto_int32.h"
#include "crypto_int16.h"
#include "crypto_int8.h"
#include "randombytes.h"
#include "crypto_verify_32.h"
#include "crypto_hash_sha512.h"
#include "crypto_kem_sntrup4591761.h"
/* int32_sort.c */
static void minmax(crypto_int32 *x,crypto_int32 *y)
{
crypto_uint32 xi = *x;
crypto_uint32 yi = *y;
crypto_uint32 xy = xi ^ yi;
crypto_uint32 c = yi - xi;
c ^= xy & (c ^ yi);
c >>= 31;
c = -c;
c &= xy;
*x = xi ^ c;
*y = yi ^ c;
}
static void int32_sort(crypto_int32 *x,int n)
{
int top,p,q,i;
if (n < 2) return;
top = 1;
while (top < n - top) top += top;
for (p = top;p > 0;p >>= 1) {
for (i = 0;i < n - p;++i)
if (!(i & p))
minmax(x + i,x + i + p);
for (q = top;q > p;q >>= 1)
for (i = 0;i < n - q;++i)
if (!(i & p))
minmax(x + i + p,x + i + q);
}
}
/* swap.c */
static void swap(void *x,void *y,int bytes,int mask)
{
int i;
char xi, yi, c, t;
c = mask;
for (i = 0;i < bytes;++i) {
xi = i[(char *) x];
yi = i[(char *) y];
t = c & (xi ^ yi);
xi ^= t;
yi ^= t;
i[(char *) x] = xi;
i[(char *) y] = yi;
}
}
/* params.h */
#ifndef params_h
#define params_h
#define q 4591
/* XXX: also built into modq in various ways */
#define qshift 2295
#define p 761
#define w 286
#define rq_encode_len 1218
#define small_encode_len 191
#endif
/* small.h */
typedef crypto_int8 small;
/* small.c */
/* XXX: these functions rely on p mod 4 = 1 */
/* all coefficients in -1, 0, 1 */
static void small_encode(unsigned char *c,const small *f)
{
small c0;
int i;
for (i = 0;i < p/4;++i) {
c0 = *f++ + 1;
c0 += (*f++ + 1) << 2;
c0 += (*f++ + 1) << 4;
c0 += (*f++ + 1) << 6;
*c++ = c0;
}
c0 = *f++ + 1;
*c++ = c0;
}
static void small_decode(small *f,const unsigned char *c)
{
unsigned char c0;
int i;
for (i = 0;i < p/4;++i) {
c0 = *c++;
*f++ = ((small) (c0 & 3)) - 1; c0 >>= 2;
*f++ = ((small) (c0 & 3)) - 1; c0 >>= 2;
*f++ = ((small) (c0 & 3)) - 1; c0 >>= 2;
*f++ = ((small) (c0 & 3)) - 1;
}
c0 = *c++;
*f++ = ((small) (c0 & 3)) - 1;
}
/* random32.c */
#ifdef KAT
/* NIST KAT generator fails to provide chunk-independence */
static unsigned char x[4*761];
static long long pos = 4*761;
#endif
static crypto_int32 small_random32(void)
{
#ifdef KAT
if (pos == 4*761) {
randombytes(x,sizeof x);
pos = 0;
}
pos += 4;
return x[pos - 4] + (x[pos - 3] << 8) + (x[pos - 2] << 16) + (x[pos - 1] << 24);
#else
unsigned char x[4];
randombytes(x,4);
return x[0] + (x[1] << 8) + (x[2] << 16) + (x[3] << 24);
#endif
}
/* randomsmall.c */
static void small_random(small *g)
{
int i;
for (i = 0;i < p;++i) {
crypto_uint32 r = small_random32();
g[i] = (small) (((1073741823 & r) * 3) >> 30) - 1;
}
}
/* randomweightw.c */
static void small_random_weightw(small *f)
{
crypto_int32 r[p];
int i;
for (i = 0;i < p;++i) r[i] = small_random32();
for (i = 0;i < w;++i) r[i] &= -2;
for (i = w;i < p;++i) r[i] = (r[i] & -3) | 1;
int32_sort(r,p);
for (i = 0;i < p;++i) f[i] = ((small) (r[i] & 3)) - 1;
}
/* mod3.h */
#ifndef mod3_h
#define mod3_h
/* -1 if x is nonzero, 0 otherwise */
static inline int mod3_nonzero_mask(small x)
{
return -x*x;
}
/* input between -100000 and 100000 */
/* output between -1 and 1 */
static inline small mod3_freeze(crypto_int32 a)
{
a -= 3 * ((10923 * a) >> 15);
a -= 3 * ((89478485 * a + 134217728) >> 28);
return a;
}
static inline small mod3_minusproduct(small a,small b,small c)
{
crypto_int32 A = a;
crypto_int32 B = b;
crypto_int32 C = c;
return mod3_freeze(A - B * C);
}
static inline small mod3_plusproduct(small a,small b,small c)
{
crypto_int32 A = a;
crypto_int32 B = b;
crypto_int32 C = c;
return mod3_freeze(A + B * C);
}
static inline small mod3_product(small a,small b)
{
return a * b;
}
static inline small mod3_sum(small a,small b)
{
crypto_int32 A = a;
crypto_int32 B = b;
return mod3_freeze(A + B);
}
static inline small mod3_reciprocal(small a1)
{
return a1;
}
static inline small mod3_quotient(small num,small den)
{
return mod3_product(num,mod3_reciprocal(den));
}
#endif
/* r3_mult.c */
static void r3_mult(small *h,const small *f,const small *g)
{
small fg[p + p - 1];
small result;
int i, j;
for (i = 0;i < p;++i) {
result = 0;
for (j = 0;j <= i;++j)
result = mod3_plusproduct(result,f[j],g[i - j]);
fg[i] = result;
}
for (i = p;i < p + p - 1;++i) {
result = 0;
for (j = i - p + 1;j < p;++j)
result = mod3_plusproduct(result,f[j],g[i - j]);
fg[i] = result;
}
for (i = p + p - 2;i >= p;--i) {
fg[i - p] = mod3_sum(fg[i - p],fg[i]);
fg[i - p + 1] = mod3_sum(fg[i - p + 1],fg[i]);
}
for (i = 0;i < p;++i)
h[i] = fg[i];
}
/* r3_recip.c */
/* caller must ensure that x-y does not overflow */
static int smaller_mask(int x,int y)
{
return (x - y) >> 31;
}
static void vectormod3_product(small *z,int len,const small *x,const small c)
{
int i;
for (i = 0;i < len;++i) z[i] = mod3_product(x[i],c);
}
static void vectormod3_minusproduct(small *z,int len,const small *x,const small *y,const small c)
{
int i;
for (i = 0;i < len;++i) z[i] = mod3_minusproduct(x[i],y[i],c);
}
static void vectormod3_shift(small *z,int len)
{
int i;
for (i = len - 1;i > 0;--i) z[i] = z[i - 1];
z[0] = 0;
}
/*
r = s^(-1) mod m, returning 0, if s is invertible mod m
or returning -1 if s is not invertible mod m
r,s are polys of degree = loops) break;
c = mod3_quotient(g[p],f[p]);
vectormod3_minusproduct(g,p + 1,g,f,c);
vectormod3_shift(g,p + 1);
#ifdef SIMPLER
vectormod3_minusproduct(v,loops + 1,v,u,c);
vectormod3_shift(v,loops + 1);
#else
if (loop < p) {
vectormod3_minusproduct(v,loop + 1,v,u,c);
vectormod3_shift(v,loop + 2);
} else {
vectormod3_minusproduct(v + loop - p,p + 1,v + loop - p,u + loop - p,c);
vectormod3_shift(v + loop - p,p + 2);
}
#endif
e -= 1;
++loop;
swapmask = smaller_mask(e,d) & mod3_nonzero_mask(g[p]);
swap(&e,&d,sizeof e,swapmask);
swap(f,g,(p + 1) * sizeof(small),swapmask);
#ifdef SIMPLER
swap(u,v,(loops + 1) * sizeof(small),swapmask);
#else
if (loop < p) {
swap(u,v,(loop + 1) * sizeof(small),swapmask);
} else {
swap(u + loop - p,v + loop - p,(p + 1) * sizeof(small),swapmask);
}
#endif
}
c = mod3_reciprocal(f[p]);
vectormod3_product(r,p,u + p,c);
return smaller_mask(0,d);
}
/* modq.h */
#ifndef modq_h
#define modq_h
typedef crypto_int16 modq;
/* -1 if x is nonzero, 0 otherwise */
static inline int modq_nonzero_mask(modq x)
{
crypto_int32 r = (crypto_uint16) x;
r = -r;
r >>= 30;
return r;
}
/* input between -9000000 and 9000000 */
/* output between -2295 and 2295 */
static inline modq modq_freeze(crypto_int32 a)
{
a -= 4591 * ((228 * a) >> 20);
a -= 4591 * ((58470 * a + 134217728) >> 28);
return a;
}
static inline modq modq_minusproduct(modq a,modq b,modq c)
{
crypto_int32 A = a;
crypto_int32 B = b;
crypto_int32 C = c;
return modq_freeze(A - B * C);
}
static inline modq modq_plusproduct(modq a,modq b,modq c)
{
crypto_int32 A = a;
crypto_int32 B = b;
crypto_int32 C = c;
return modq_freeze(A + B * C);
}
static inline modq modq_product(modq a,modq b)
{
crypto_int32 A = a;
crypto_int32 B = b;
return modq_freeze(A * B);
}
static inline modq modq_square(modq a)
{
crypto_int32 A = a;
return modq_freeze(A * A);
}
static inline modq modq_sum(modq a,modq b)
{
crypto_int32 A = a;
crypto_int32 B = b;
return modq_freeze(A + B);
}
static inline modq modq_reciprocal(modq a1)
{
modq a2 = modq_square(a1);
modq a3 = modq_product(a2,a1);
modq a4 = modq_square(a2);
modq a8 = modq_square(a4);
modq a16 = modq_square(a8);
modq a32 = modq_square(a16);
modq a35 = modq_product(a32,a3);
modq a70 = modq_square(a35);
modq a140 = modq_square(a70);
modq a143 = modq_product(a140,a3);
modq a286 = modq_square(a143);
modq a572 = modq_square(a286);
modq a1144 = modq_square(a572);
modq a1147 = modq_product(a1144,a3);
modq a2294 = modq_square(a1147);
modq a4588 = modq_square(a2294);
modq a4589 = modq_product(a4588,a1);
return a4589;
}
static inline modq modq_quotient(modq num,modq den)
{
return modq_product(num,modq_reciprocal(den));
}
#endif
/* rq.c */
static void rq_encode(unsigned char *c,const modq *f)
{
crypto_int32 f0, f1, f2, f3, f4;
int i;
for (i = 0;i < p/5;++i) {
f0 = *f++ + qshift;
f1 = *f++ + qshift;
f2 = *f++ + qshift;
f3 = *f++ + qshift;
f4 = *f++ + qshift;
/* now want f0 + 6144*f1 + ... as a 64-bit integer */
f1 *= 3;
f2 *= 9;
f3 *= 27;
f4 *= 81;
/* now want f0 + f1<<11 + f2<<22 + f3<<33 + f4<<44 */
f0 += f1 << 11;
*c++ = f0; f0 >>= 8;
*c++ = f0; f0 >>= 8;
f0 += f2 << 6;
*c++ = f0; f0 >>= 8;
*c++ = f0; f0 >>= 8;
f0 += f3 << 1;
*c++ = f0; f0 >>= 8;
f0 += f4 << 4;
*c++ = f0; f0 >>= 8;
*c++ = f0; f0 >>= 8;
*c++ = f0;
}
/* XXX: using p mod 5 = 1 */
f0 = *f++ + qshift;
*c++ = f0; f0 >>= 8;
*c++ = f0;
}
static void rq_decode(modq *f,const unsigned char *c)
{
crypto_uint32 c0, c1, c2, c3, c4, c5, c6, c7;
crypto_uint32 f0, f1, f2, f3, f4;
int i;
for (i = 0;i < p/5;++i) {
c0 = *c++;
c1 = *c++;
c2 = *c++;
c3 = *c++;
c4 = *c++;
c5 = *c++;
c6 = *c++;
c7 = *c++;
/* f0 + f1*6144 + f2*6144^2 + f3*6144^3 + f4*6144^4 */
/* = c0 + c1*256 + ... + c6*256^6 + c7*256^7 */
/* with each f between 0 and 4590 */
c6 += c7 << 8;
/* c6 <= 23241 = floor(4591*6144^4/2^48) */
/* f4 = (16/81)c6 + (1/1296)(c5+[0,1]) - [0,0.75] */
/* claim: 2^19 f4 < x < 2^19(f4+1) */
/* where x = 103564 c6 + 405(c5+1) */
/* proof: x - 2^19 f4 = (76/81)c6 + (37/81)c5 + 405 - (32768/81)[0,1] + 2^19[0,0.75] */
/* at least 405 - 32768/81 > 0 */
/* at most (76/81)23241 + (37/81)255 + 405 + 2^19 0.75 < 2^19 */
f4 = (103564*c6 + 405*(c5+1)) >> 19;
c5 += c6 << 8;
c5 -= (f4 * 81) << 4;
c4 += c5 << 8;
/* f0 + f1*6144 + f2*6144^2 + f3*6144^3 */
/* = c0 + c1*256 + c2*256^2 + c3*256^3 + c4*256^4 */
/* c4 <= 247914 = floor(4591*6144^3/2^32) */
/* f3 = (1/54)(c4+[0,1]) - [0,0.75] */
/* claim: 2^19 f3 < x < 2^19(f3+1) */
/* where x = 9709(c4+2) */
/* proof: x - 2^19 f3 = 19418 - (1/27)c4 - (262144/27)[0,1] + 2^19[0,0.75] */
/* at least 19418 - 247914/27 - 262144/27 > 0 */
/* at most 19418 + 2^19 0.75 < 2^19 */
f3 = (9709*(c4+2)) >> 19;
c4 -= (f3 * 27) << 1;
c3 += c4 << 8;
/* f0 + f1*6144 + f2*6144^2 */
/* = c0 + c1*256 + c2*256^2 + c3*256^3 */
/* c3 <= 10329 = floor(4591*6144^2/2^24) */
/* f2 = (4/9)c3 + (1/576)c2 + (1/147456)c1 + (1/37748736)c0 - [0,0.75] */
/* claim: 2^19 f2 < x < 2^19(f2+1) */
/* where x = 233017 c3 + 910(c2+2) */
/* proof: x - 2^19 f2 = 1820 + (1/9)c3 - (2/9)c2 - (32/9)c1 - (1/72)c0 + 2^19[0,0.75] */
/* at least 1820 - (2/9)255 - (32/9)255 - (1/72)255 > 0 */
/* at most 1820 + (1/9)10329 + 2^19 0.75 < 2^19 */
f2 = (233017*c3 + 910*(c2+2)) >> 19;
c2 += c3 << 8;
c2 -= (f2 * 9) << 6;
c1 += c2 << 8;
/* f0 + f1*6144 */
/* = c0 + c1*256 */
/* c1 <= 110184 = floor(4591*6144/2^8) */
/* f1 = (1/24)c1 + (1/6144)c0 - (1/6144)f0 */
/* claim: 2^19 f1 < x < 2^19(f1+1) */
/* where x = 21845(c1+2) + 85 c0 */
/* proof: x - 2^19 f1 = 43690 - (1/3)c1 - (1/3)c0 + 2^19 [0,0.75] */
/* at least 43690 - (1/3)110184 - (1/3)255 > 0 */
/* at most 43690 + 2^19 0.75 < 2^19 */
f1 = (21845*(c1+2) + 85*c0) >> 19;
c1 -= (f1 * 3) << 3;
c0 += c1 << 8;
f0 = c0;
*f++ = modq_freeze(f0 + q - qshift);
*f++ = modq_freeze(f1 + q - qshift);
*f++ = modq_freeze(f2 + q - qshift);
*f++ = modq_freeze(f3 + q - qshift);
*f++ = modq_freeze(f4 + q - qshift);
}
c0 = *c++;
c1 = *c++;
c0 += c1 << 8;
*f++ = modq_freeze(c0 + q - qshift);
}
/* rq_mult.c */
static void rq_mult(modq *h,const modq *f,const small *g)
{
modq fg[p + p - 1];
modq result;
int i, j;
for (i = 0;i < p;++i) {
result = 0;
for (j = 0;j <= i;++j)
result = modq_plusproduct(result,f[j],g[i - j]);
fg[i] = result;
}
for (i = p;i < p + p - 1;++i) {
result = 0;
for (j = i - p + 1;j < p;++j)
result = modq_plusproduct(result,f[j],g[i - j]);
fg[i] = result;
}
for (i = p + p - 2;i >= p;--i) {
fg[i - p] = modq_sum(fg[i - p],fg[i]);
fg[i - p + 1] = modq_sum(fg[i - p + 1],fg[i]);
}
for (i = 0;i < p;++i)
h[i] = fg[i];
}
/* rq_recip3.c */
/* caller must ensure that x-y does not overflow */
static int smaller_maskq(int x,int y)
{
return (x - y) >> 31;
}
static void vectormodq_product(modq *z,int len,const modq *x,const modq c)
{
int i;
for (i = 0;i < len;++i) z[i] = modq_product(x[i],c);
}
static void vectormodq_minusproduct(modq *z,int len,const modq *x,const modq *y,const modq c)
{
int i;
for (i = 0;i < len;++i) z[i] = modq_minusproduct(x[i],y[i],c);
}
static void vectormodq_shift(modq *z,int len)
{
int i;
for (i = len - 1;i > 0;--i) z[i] = z[i - 1];
z[0] = 0;
}
/*
r = (3s)^(-1) mod m, returning 0, if s is invertible mod m
or returning -1 if s is not invertible mod m
r,s are polys of degree
= loops) break;
c = modq_quotient(g[p],f[p]);
vectormodq_minusproduct(g,p + 1,g,f,c);
vectormodq_shift(g,p + 1);
#ifdef SIMPLER
vectormodq_minusproduct(v,loops + 1,v,u,c);
vectormodq_shift(v,loops + 1);
#else
if (loop < p) {
vectormodq_minusproduct(v,loop + 1,v,u,c);
vectormodq_shift(v,loop + 2);
} else {
vectormodq_minusproduct(v + loop - p,p + 1,v + loop - p,u + loop - p,c);
vectormodq_shift(v + loop - p,p + 2);
}
#endif
e -= 1;
++loop;
swapmask = smaller_maskq(e,d) & modq_nonzero_mask(g[p]);
swap(&e,&d,sizeof e,swapmask);
swap(f,g,(p + 1) * sizeof(modq),swapmask);
#ifdef SIMPLER
swap(u,v,(loops + 1) * sizeof(modq),swapmask);
#else
if (loop < p) {
swap(u,v,(loop + 1) * sizeof(modq),swapmask);
} else {
swap(u + loop - p,v + loop - p,(p + 1) * sizeof(modq),swapmask);
}
#endif
}
c = modq_reciprocal(f[p]);
vectormodq_product(r,p,u + p,c);
return smaller_maskq(0,d);
}
/* rq_round3.c */
static void rq_round3(modq *h,const modq *f)
{
int i;
for (i = 0;i < p;++i)
h[i] = ((21846 * (f[i] + 2295) + 32768) >> 16) * 3 - 2295;
}
/* rq_rounded.c */
static void rq_encoderounded(unsigned char *c,const modq *f)
{
crypto_int32 f0, f1, f2;
int i;
for (i = 0;i < p/3;++i) {
f0 = *f++ + qshift;
f1 = *f++ + qshift;
f2 = *f++ + qshift;
f0 = (21846 * f0) >> 16;
f1 = (21846 * f1) >> 16;
f2 = (21846 * f2) >> 16;
/* now want f0 + f1*1536 + f2*1536^2 as a 32-bit integer */
f2 *= 3;
f1 += f2 << 9;
f1 *= 3;
f0 += f1 << 9;
*c++ = f0; f0 >>= 8;
*c++ = f0; f0 >>= 8;
*c++ = f0; f0 >>= 8;
*c++ = f0;
}
/* XXX: using p mod 3 = 2 */
f0 = *f++ + qshift;
f1 = *f++ + qshift;
f0 = (21846 * f0) >> 16;
f1 = (21846 * f1) >> 16;
f1 *= 3;
f0 += f1 << 9;
*c++ = f0; f0 >>= 8;
*c++ = f0; f0 >>= 8;
*c++ = f0;
}
static void rq_decoderounded(modq *f,const unsigned char *c)
{
crypto_uint32 c0, c1, c2, c3;
crypto_uint32 f0, f1, f2;
int i;
for (i = 0;i < p/3;++i) {
c0 = *c++;
c1 = *c++;
c2 = *c++;
c3 = *c++;
/* f0 + f1*1536 + f2*1536^2 */
/* = c0 + c1*256 + c2*256^2 + c3*256^3 */
/* with each f between 0 and 1530 */
/* f2 = (64/9)c3 + (1/36)c2 + (1/9216)c1 + (1/2359296)c0 - [0,0.99675] */
/* claim: 2^21 f2 < x < 2^21(f2+1) */
/* where x = 14913081*c3 + 58254*c2 + 228*(c1+2) */
/* proof: x - 2^21 f2 = 456 - (8/9)c0 + (4/9)c1 - (2/9)c2 + (1/9)c3 + 2^21 [0,0.99675] */
/* at least 456 - (8/9)255 - (2/9)255 > 0 */
/* at most 456 + (4/9)255 + (1/9)255 + 2^21 0.99675 < 2^21 */
f2 = (14913081*c3 + 58254*c2 + 228*(c1+2)) >> 21;
c2 += c3 << 8;
c2 -= (f2 * 9) << 2;
/* f0 + f1*1536 */
/* = c0 + c1*256 + c2*256^2 */
/* c2 <= 35 = floor((1530+1530*1536)/256^2) */
/* f1 = (128/3)c2 + (1/6)c1 + (1/1536)c0 - (1/1536)f0 */
/* claim: 2^21 f1 < x < 2^21(f1+1) */
/* where x = 89478485*c2 + 349525*c1 + 1365*(c0+1) */
/* proof: x - 2^21 f1 = 1365 - (1/3)c2 - (1/3)c1 - (1/3)c0 + (4096/3)f0 */
/* at least 1365 - (1/3)35 - (1/3)255 - (1/3)255 > 0 */
/* at most 1365 + (4096/3)1530 < 2^21 */
f1 = (89478485*c2 + 349525*c1 + 1365*(c0+1)) >> 21;
c1 += c2 << 8;
c1 -= (f1 * 3) << 1;
c0 += c1 << 8;
f0 = c0;
*f++ = modq_freeze(f0 * 3 + q - qshift);
*f++ = modq_freeze(f1 * 3 + q - qshift);
*f++ = modq_freeze(f2 * 3 + q - qshift);
}
c0 = *c++;
c1 = *c++;
c2 = *c++;
f1 = (89478485*c2 + 349525*c1 + 1365*(c0+1)) >> 21;
c1 += c2 << 8;
c1 -= (f1 * 3) << 1;
c0 += c1 << 8;
f0 = c0;
*f++ = modq_freeze(f0 * 3 + q - qshift);
*f++ = modq_freeze(f1 * 3 + q - qshift);
}
/* keypair.c */
#if crypto_kem_sntrup4591761_tinynacl_PUBLICKEYBYTES != rq_encode_len
#error "crypto_kem_sntrup4591761_tinynacl_PUBLICKEYBYTES must match rq_encode_len"
#endif
#if crypto_kem_sntrup4591761_tinynacl_SECRETKEYBYTES != rq_encode_len + 2 * small_encode_len
#error "crypto_kem_sntrup4591761_tinynacl_SECRETKEYBYTES must match rq_encode_len + 2 * small_encode_len"
#endif
int crypto_kem_sntrup4591761_tinynacl_keypair(unsigned char *pk,unsigned char *sk)
{
small g[p];
small grecip[p];
small f[p];
modq f3recip[p];
modq h[p];
do
small_random(g);
while (r3_recip(grecip,g) != 0);
small_random_weightw(f);
rq_recip3(f3recip,f);
rq_mult(h,f3recip,g);
rq_encode(pk,h);
small_encode(sk,f);
small_encode(sk + small_encode_len,grecip);
memcpy(sk + 2 * small_encode_len,pk,rq_encode_len);
return 0;
}
/* enc.c */
#ifdef KAT
#endif
int crypto_kem_sntrup4591761_tinynacl_enc(
unsigned char *cstr,
unsigned char *k,
const unsigned char *pk
)
{
small r[p];
modq h[p];
modq c[p];
unsigned char rstr[small_encode_len];
unsigned char hash[64];
small_random_weightw(r);
#ifdef KAT
{
int i;
printf("encrypt r:");
for (i = 0;i < p;++i)
if (r[i] == 1) printf(" +%d",i);
else if (r[i] == -1) printf(" -%d",i);
printf("\n");
}
#endif
small_encode(rstr,r);
crypto_hash_sha512(hash,rstr,sizeof rstr);
rq_decode(h,pk);
rq_mult(c,h,r);
rq_round3(c,c);
memcpy(k,hash + 32,32);
memcpy(cstr,hash,32);
rq_encoderounded(cstr + 32,c);
return 0;
}
/* dec.c */
#ifdef KAT
#endif
int crypto_kem_sntrup4591761_tinynacl_dec(
unsigned char *k,
const unsigned char *cstr,
const unsigned char *sk
)
{
small f[p];
modq h[p];
small grecip[p];
modq c[p];
modq t[p];
small t3[p];
small r[p];
modq hr[p];
unsigned char rstr[small_encode_len];
unsigned char hash[64];
int i;
int result = 0;
int weight;
small_decode(f,sk);
small_decode(grecip,sk + small_encode_len);
rq_decode(h,sk + 2 * small_encode_len);
rq_decoderounded(c,cstr + 32);
rq_mult(t,c,f);
for (i = 0;i < p;++i) t3[i] = mod3_freeze(modq_freeze(3*t[i]));
r3_mult(r,t3,grecip);
#ifdef KAT
{
int j;
printf("decrypt r:");
for (j = 0;j < p;++j)
if (r[j] == 1) printf(" +%d",j);
else if (r[j] == -1) printf(" -%d",j);
printf("\n");
}
#endif
weight = 0;
for (i = 0;i < p;++i) weight += (1 & r[i]);
weight -= w;
result |= modq_nonzero_mask(weight); /* XXX: puts limit on p */
rq_mult(hr,h,r);
rq_round3(hr,hr);
for (i = 0;i < p;++i) result |= modq_nonzero_mask(hr[i] - c[i]);
small_encode(rstr,r);
crypto_hash_sha512(hash,rstr,sizeof rstr);
result |= crypto_verify_32(hash,cstr);
for (i = 0;i < 32;++i) k[i] = (hash[32 + i] & ~result);
return result;
}
#if 0
Script used for merge into single file:
#!/bin/sh
rm crypto_kem_sntrup4591761.c || :
(
echo '/*'
echo 'Original code: libpqcrypto-20180314/crypto_kem/sntrup4591761/ref'
echo 'Modifications (Jan Mojzis):'
echo '- source code merged into single file'
echo '- crypto_kem renamed to crypto_kem_sntrup4591761_tinynacl'
echo '*/'
echo
echo '/* See https://ntruprime.cr.yp.to/software.html for detailed documentation. */'
echo
echo '#include '
echo '#include "crypto_uint32.h"'
echo '#include "crypto_uint16.h"'
echo '#include "crypto_int32.h"'
echo '#include "crypto_int16.h"'
echo '#include "crypto_int8.h"'
echo '#include "randombytes.h"'
echo '#include "crypto_verify_32.h"'
echo '#include "crypto_hash_sha512.h"'
echo '#include "crypto_kem_sntrup4591761.h"'
echo
(
echo '/* int32_sort.c */'
cat int32_sort.c | sed 's/^void /static void /'
echo
echo '/* swap.c */'
cat swap.c | sed 's/^void /static void /'
echo
echo '/* params.h */'
cat params.h
echo
echo '/* small.h */'
echo 'typedef crypto_int8 small;'
echo
echo '/* small.c */'
cat small.c | sed 's/^void /static void /'
echo
echo '/* random32.c */'
cat random32.c | sed 's/^crypto_int32 /static crypto_int32 /'
echo
echo '/* randomsmall.c */'
cat randomsmall.c | sed 's/^void /static void /'
echo
echo '/* randomweightw.c */'
cat randomweightw.c | sed 's/^void /static void /'
echo
echo '/* mod3.h */'
cat mod3.h
echo
echo '/* r3_mult.c */'
cat r3_mult.c | sed 's/^void /static void /'
echo
echo '/* r3_recip.c */'
cat r3_recip.c | sed 's/^void /static void /'
echo
echo '/* modq.h */'
cat modq.h
echo
echo '/* rq.c */'
cat rq.c | sed 's/^void /static void /'
echo
echo '/* rq_mult.c */'
cat rq_mult.c | sed 's/^void /static void /'
echo
echo '/* rq_recip3.c */'
cat rq_recip3.c | sed 's/smaller_mask/smaller_maskq/' | sed 's/^int /static int /'
echo
echo '/* rq_round3.c */'
cat rq_round3.c | sed 's/^void /static void /'
echo
echo '/* rq_rounded.c */'
cat rq_rounded.c | sed 's/^void /static void /'
echo
(
echo '/* keypair.c */'
cat keypair.c
echo
echo '/* enc.c */'
cat enc.c
echo
echo '/* dec.c */'
cat dec.c
echo
) | sed 's/crypto_kem/crypto_kem_sntrup4591761_tinynacl/g'
) | grep -v '^#include' | grep -v 'See https://ntruprime.cr.yp.to/software.html for detailed documentation'
echo
echo '#if 0'
echo 'Script used for merge into single file:'
echo
cat $0
echo
echo '#endif'
) > crypto_kem_sntrup4591761.c.tmp
mv -f crypto_kem_sntrup4591761.c.tmp crypto_kem_sntrup4591761.c
#endif
tinyssh-20190101/crypto/crypto_kem_sntrup4591761.h 0000664 0000000 0000000 00000002467 13412736503 0021530 0 ustar 00root root 0000000 0000000 #ifndef crypto_kem_sntrup4591761_H
#define crypto_kem_sntrup4591761_H
#define crypto_kem_sntrup4591761_tinynacl_SECRETKEYBYTES 1600
#define crypto_kem_sntrup4591761_tinynacl_PUBLICKEYBYTES 1218
#define crypto_kem_sntrup4591761_tinynacl_CIPHERTEXTBYTES 1047
#define crypto_kem_sntrup4591761_tinynacl_BYTES 32
extern int crypto_kem_sntrup4591761_tinynacl_keypair(unsigned char *, unsigned char *);
extern int crypto_kem_sntrup4591761_tinynacl_enc(unsigned char *, unsigned char *, const unsigned char *);
extern int crypto_kem_sntrup4591761_tinynacl_dec(unsigned char *, const unsigned char *, const unsigned char *);
#define crypto_kem_sntrup4591761_keypair crypto_kem_sntrup4591761_tinynacl_keypair
#define crypto_kem_sntrup4591761_enc crypto_kem_sntrup4591761_tinynacl_enc
#define crypto_kem_sntrup4591761_dec crypto_kem_sntrup4591761_tinynacl_dec
#define crypto_kem_sntrup4591761_SECRETKEYBYTES crypto_kem_sntrup4591761_tinynacl_SECRETKEYBYTES
#define crypto_kem_sntrup4591761_PUBLICKEYBYTES crypto_kem_sntrup4591761_tinynacl_PUBLICKEYBYTES
#define crypto_kem_sntrup4591761_CIPHERTEXTBYTES crypto_kem_sntrup4591761_tinynacl_CIPHERTEXTBYTES
#define crypto_kem_sntrup4591761_BYTES crypto_kem_sntrup4591761_tinynacl_BYTES
#define crypto_kem_sntrup4591761_IMPLEMENTATION "tinynacl"
#define crypto_kem_sntrup4591761_VERSION "-"
#endif
tinyssh-20190101/crypto/crypto_kem_sntrup4591761x25519.c 0000664 0000000 0000000 00000007447 13412736503 0022324 0 ustar 00root root 0000000 0000000 /*
20181225
Jan Mojzis
Public domain.
*/
#include "randombytes.h"
#include "cleanup.h"
#include "crypto_hash_sha512.h"
#include "crypto_scalarmult_curve25519.h"
#include "crypto_kem_sntrup4591761.h"
#include "crypto_kem_sntrup4591761x25519.h"
#define sntrup4591761_BYTES crypto_kem_sntrup4591761_BYTES
#define x25519_BYTES crypto_scalarmult_curve25519_BYTES
#define x25519_SCALARBYTES crypto_scalarmult_curve25519_SCALARBYTES
#define sx_BYTES sntrup4591761_BYTES + x25519_BYTES
#define sntrup4591761_PUBLICKEYBYTES crypto_kem_sntrup4591761_PUBLICKEYBYTES
#define sntrup4591761_SECRETKEYBYTES crypto_kem_sntrup4591761_SECRETKEYBYTES
#define sx_PUBLICKEYBYTES sntrup4591761_PUBLICKEYBYTES + x25519_BYTES
#define sx_SECRETKEYBYTES sntrup4591761_SECRETKEYBYTES + x25519_SCALARBYTES
static unsigned char returnmask(int x) {
unsigned long long ret = 1ULL;
ret <<= 8 * sizeof(int);
ret -= (unsigned long long)(unsigned int)x;
ret >>= 8 * sizeof(int);
return ret - 1;
}
int crypto_kem_sntrup4591761x25519_tinynacl_enc(unsigned char *c,
unsigned char *k,
const unsigned char *pk) {
int r = 0;
long long i;
unsigned char onetimesk[x25519_SCALARBYTES];
unsigned char buf[sx_BYTES];
unsigned char tmp[sx_BYTES];
unsigned char b;
/* sntrup4591761 */
r |= crypto_kem_sntrup4591761_enc(c, buf, pk);
pk += crypto_kem_sntrup4591761_PUBLICKEYBYTES;
c += crypto_kem_sntrup4591761_CIPHERTEXTBYTES;
/* x25519 */
randombytes(onetimesk, sizeof onetimesk);
r |= crypto_scalarmult_curve25519_base(/*onetimepk*/ c, onetimesk);
r |= crypto_scalarmult_curve25519(buf + sntrup4591761_BYTES, onetimesk, pk);
/* if something fails, fill the buffer with random data */
randombytes(tmp, sizeof tmp);
b = returnmask(r);
for (i = 0; i < sx_BYTES; ++i) tmp[i] = b & (tmp[i] ^ buf[i]);
for (i = 0; i < sx_BYTES; ++i) buf[i] ^= tmp[i];
/* hash together sntrup459176 KEM-key and x25519 shared secret */
crypto_hash_sha512(k, buf, sizeof buf);
/* cleanup */
cleanup(buf);
cleanup(onetimesk);
return r;
}
int crypto_kem_sntrup4591761x25519_tinynacl_dec(unsigned char *k,
const unsigned char *c,
const unsigned char *sk) {
int r = 0;
long long i;
unsigned char buf[sx_BYTES];
unsigned char tmp[sx_BYTES];
unsigned char b;
/* sntrup4591761 */
r |= crypto_kem_sntrup4591761_dec(buf, c, sk);
sk += crypto_kem_sntrup4591761_SECRETKEYBYTES;
c += crypto_kem_sntrup4591761_CIPHERTEXTBYTES;
/* x25519 */
r |= crypto_scalarmult_curve25519(buf + sntrup4591761_BYTES, sk, c);
/* if something fails, fill the buffer with random data */
randombytes(tmp, sizeof tmp);
b = returnmask(r);
for (i = 0; i < sx_BYTES; ++i) tmp[i] = b & (tmp[i] ^ buf[i]);
for (i = 0; i < sx_BYTES; ++i) buf[i] ^= tmp[i];
/* hash together sntrup459176 KEM-key and x25519 shared secret */
crypto_hash_sha512(k, buf, sizeof buf);
/* cleanup */
cleanup(buf);
return r;
}
int crypto_kem_sntrup4591761x25519_tinynacl_keypair(unsigned char *pk,
unsigned char *sk) {
int r = 0;
long long i;
unsigned char b;
/* sntrup4591761 */
r |= crypto_kem_sntrup4591761_keypair(pk, sk);
/* x25519 */
randombytes(sk + sntrup4591761_SECRETKEYBYTES, x25519_SCALARBYTES);
r |= crypto_scalarmult_curve25519_base(pk + sntrup4591761_PUBLICKEYBYTES,
sk + sntrup4591761_SECRETKEYBYTES);
b = ~returnmask(r);
for (i = 0; i < sx_PUBLICKEYBYTES; ++i) pk[i] &= b;
for (i = 0; i < sx_SECRETKEYBYTES; ++i) sk[i] &= b;
return r;
}
tinyssh-20190101/crypto/crypto_kem_sntrup4591761x25519.h 0000664 0000000 0000000 00000002715 13412736503 0022322 0 ustar 00root root 0000000 0000000 #ifndef crypto_kem_sntrup4591761x25519_H
#define crypto_kem_sntrup4591761x25519_H
#define crypto_kem_sntrup4591761x25519_tinynacl_SECRETKEYBYTES 1632
#define crypto_kem_sntrup4591761x25519_tinynacl_PUBLICKEYBYTES 1250
#define crypto_kem_sntrup4591761x25519_tinynacl_CIPHERTEXTBYTES 1079
#define crypto_kem_sntrup4591761x25519_tinynacl_BYTES 64
extern int crypto_kem_sntrup4591761x25519_tinynacl_keypair(unsigned char *, unsigned char *);
extern int crypto_kem_sntrup4591761x25519_tinynacl_enc(unsigned char *, unsigned char *, const unsigned char *);
extern int crypto_kem_sntrup4591761x25519_tinynacl_dec(unsigned char *, const unsigned char *, const unsigned char *);
#define crypto_kem_sntrup4591761x25519_keypair crypto_kem_sntrup4591761x25519_tinynacl_keypair
#define crypto_kem_sntrup4591761x25519_enc crypto_kem_sntrup4591761x25519_tinynacl_enc
#define crypto_kem_sntrup4591761x25519_dec crypto_kem_sntrup4591761x25519_tinynacl_dec
#define crypto_kem_sntrup4591761x25519_SECRETKEYBYTES crypto_kem_sntrup4591761x25519_tinynacl_SECRETKEYBYTES
#define crypto_kem_sntrup4591761x25519_PUBLICKEYBYTES crypto_kem_sntrup4591761x25519_tinynacl_PUBLICKEYBYTES
#define crypto_kem_sntrup4591761x25519_CIPHERTEXTBYTES crypto_kem_sntrup4591761x25519_tinynacl_CIPHERTEXTBYTES
#define crypto_kem_sntrup4591761x25519_BYTES crypto_kem_sntrup4591761x25519_tinynacl_BYTES
#define crypto_kem_sntrup4591761x25519_IMPLEMENTATION "tinynacl"
#define crypto_kem_sntrup4591761x25519_VERSION "-"
#endif
tinyssh-20190101/crypto/crypto_onetimeauth_poly1305.c 0000664 0000000 0000000 00000012741 13412736503 0022445 0 ustar 00root root 0000000 0000000 /*
20180104
*/
/*
Based on poly1305-donna (https://github.com/floodyberry/poly1305-opt/blob/master/extensions/poly1305_ref-32.c)
- modified for NaCl API
*/
#include "crypto_onetimeauth_poly1305.h"
static unsigned long unpack(const unsigned char *x) {
return
(unsigned long) (x[0]) \
| (((unsigned long) (x[1])) << 8) \
| (((unsigned long) (x[2])) << 16) \
| (((unsigned long) (x[3])) << 24);
}
static void pack(unsigned char *x, unsigned long u) {
x[0] = u; u >>= 8;
x[1] = u; u >>= 8;
x[2] = u; u >>= 8;
x[3] = u;
}
int crypto_onetimeauth_poly1305_tinynacl(unsigned char *o, const unsigned char *m, unsigned long long n, const unsigned char *k) {
unsigned long h0, h1, h2, h3, h4;
unsigned long r0, r1, r2, r3, r4;
unsigned long s1, s2, s3, s4;
unsigned long long d0, d1, d2, d3, d4;
unsigned long c, mask;
unsigned long long f;
long long i;
/* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
r0 = (unpack(k + 0) ) & 0x3ffffff;
r1 = (unpack(k + 3) >> 2) & 0x3ffff03;
r2 = (unpack(k + 6) >> 4) & 0x3ffc0ff;
r3 = (unpack(k + 9) >> 6) & 0x3f03fff;
r4 = (unpack(k + 12) >> 8) & 0x00fffff;
s1 = r1 * 5;
s2 = r2 * 5;
s3 = r3 * 5;
s4 = r4 * 5;
/* h = 0 */
h0 = h1 = h2 = h3 = h4 = 0;
while ((long long)n > 0) {
/* h += m[i] */
if (n >= 16) {
h0 += (unpack(m ) ) & 0x3ffffff;
h1 += (unpack(m + 3) >> 2) & 0x3ffffff;
h2 += (unpack(m + 6) >> 4) & 0x3ffffff;
h3 += (unpack(m + 9) >> 6) & 0x3ffffff;
h4 += (unpack(m + 12) >> 8) | 16777216;
}
else {
unsigned char mm[16];
for (i = 0; i < 16; ++i) mm[i] = 0;
for (i = 0; i < n; ++i) mm[i] = m[i];
mm[i] = 1;
h0 += (unpack(mm ) ) & 0x3ffffff;
h1 += (unpack(mm + 3) >> 2) & 0x3ffffff;
h2 += (unpack(mm + 6) >> 4) & 0x3ffffff;
h3 += (unpack(mm + 9) >> 6) & 0x3ffffff;
h4 += (unpack(mm + 12) >> 8);
}
/* h *= r */
d0 = ((unsigned long long)h0 * r0) + ((unsigned long long)h1 * s4) + ((unsigned long long)h2 * s3) + ((unsigned long long)h3 * s2) + ((unsigned long long)h4 * s1);
d1 = ((unsigned long long)h0 * r1) + ((unsigned long long)h1 * r0) + ((unsigned long long)h2 * s4) + ((unsigned long long)h3 * s3) + ((unsigned long long)h4 * s2);
d2 = ((unsigned long long)h0 * r2) + ((unsigned long long)h1 * r1) + ((unsigned long long)h2 * r0) + ((unsigned long long)h3 * s4) + ((unsigned long long)h4 * s3);
d3 = ((unsigned long long)h0 * r3) + ((unsigned long long)h1 * r2) + ((unsigned long long)h2 * r1) + ((unsigned long long)h3 * r0) + ((unsigned long long)h4 * s4);
d4 = ((unsigned long long)h0 * r4) + ((unsigned long long)h1 * r3) + ((unsigned long long)h2 * r2) + ((unsigned long long)h3 * r1) + ((unsigned long long)h4 * r0);
/* (partial) h %= p */
c = (unsigned long)(d0 >> 26); h0 = (unsigned long)d0 & 0x3ffffff;
d1 += c; c = (unsigned long)(d1 >> 26); h1 = (unsigned long)d1 & 0x3ffffff;
d2 += c; c = (unsigned long)(d2 >> 26); h2 = (unsigned long)d2 & 0x3ffffff;
d3 += c; c = (unsigned long)(d3 >> 26); h3 = (unsigned long)d3 & 0x3ffffff;
d4 += c; c = (unsigned long)(d4 >> 26); h4 = (unsigned long)d4 & 0x3ffffff;
h0 += c * 5; c = (h0 >> 26); h0 = h0 & 0x3ffffff;
h1 += c;
m += 16;
n -= 16;
}
/* fully carry h */
c = h1 >> 26; h1 = h1 & 0x3ffffff;
h2 += c; c = h2 >> 26; h2 = h2 & 0x3ffffff;
h3 += c; c = h3 >> 26; h3 = h3 & 0x3ffffff;
h4 += c; c = h4 >> 26; h4 = h4 & 0x3ffffff;
h0 += c * 5; c = h0 >> 26; h0 = h0 & 0x3ffffff;
h1 += c;
/* compute h + -p */
r0 = h0 + 5; c = r0 >> 26; r0 &= 0x3ffffff;
r1 = h1 + c; c = r1 >> 26; r1 &= 0x3ffffff;
r2 = h2 + c; c = r2 >> 26; r2 &= 0x3ffffff;
r3 = h3 + c; c = r3 >> 26; r3 &= 0x3ffffff;
r4 = h4 + c - (1 << 26);
/* select h if h < p, or h + -p if h >= p */
mask = (r4 >> ((sizeof(unsigned long) * 8) - 1)) - 1;
r0 &= mask;
r1 &= mask;
r2 &= mask;
r3 &= mask;
r4 &= mask;
mask = ~mask;
h0 = (h0 & mask) | r0;
h1 = (h1 & mask) | r1;
h2 = (h2 & mask) | r2;
h3 = (h3 & mask) | r3;
h4 = (h4 & mask) | r4;
/* h = h % (2^128) */
h0 = ((h0 ) | (h1 << 26)) & 0xffffffff;
h1 = ((h1 >> 6) | (h2 << 20)) & 0xffffffff;
h2 = ((h2 >> 12) | (h3 << 14)) & 0xffffffff;
h3 = ((h3 >> 18) | (h4 << 8)) & 0xffffffff;
/* mac = (h + pad) % (2^128) */
f = (unsigned long long)h0 + unpack(k + 16) ; h0 = (unsigned long)f;
f = (unsigned long long)h1 + unpack(k + 20) + (f >> 32); h1 = (unsigned long)f;
f = (unsigned long long)h2 + unpack(k + 24) + (f >> 32); h2 = (unsigned long)f;
f = (unsigned long long)h3 + unpack(k + 28) + (f >> 32); h3 = (unsigned long)f;
pack(o + 0, h0);
pack(o + 4, h1);
pack(o + 8, h2);
pack(o + 12, h3);
return 0;
}
int crypto_onetimeauth_poly1305_tinynacl_verify(const unsigned char *h, const unsigned char *in, unsigned long long l, const unsigned char *k) {
unsigned char correct[16];
unsigned int d = 0;
long long i;
crypto_onetimeauth_poly1305(correct, in, l, k);
for (i = 0; i < 16; ++i) d |= correct[i] ^ h[i];
return (1 & ((d - 1) >> 8)) - 1;
}
tinyssh-20190101/crypto/crypto_onetimeauth_poly1305.h 0000664 0000000 0000000 00000001622 13412736503 0022446 0 ustar 00root root 0000000 0000000 #ifndef crypto_onetimeauth_poly1305_H
#define crypto_onetimeauth_poly1305_H
#define crypto_onetimeauth_poly1305_tinynacl_BYTES 16
#define crypto_onetimeauth_poly1305_tinynacl_KEYBYTES 32
extern int crypto_onetimeauth_poly1305_tinynacl(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *);
extern int crypto_onetimeauth_poly1305_tinynacl_verify(const unsigned char *,const unsigned char *,unsigned long long,const unsigned char *);
#define crypto_onetimeauth_poly1305 crypto_onetimeauth_poly1305_tinynacl
#define crypto_onetimeauth_poly1305_verify crypto_onetimeauth_poly1305_tinynacl_verify
#define crypto_onetimeauth_poly1305_BYTES crypto_onetimeauth_poly1305_tinynacl_BYTES
#define crypto_onetimeauth_poly1305_KEYBYTES crypto_onetimeauth_poly1305_tinynacl_KEYBYTES
#define crypto_onetimeauth_poly1305_IMPLEMENTATION "tinynacl"
#define crypto_onetimeauth_poly1305_VERSION "-"
#endif
tinyssh-20190101/crypto/crypto_scalarmult_curve25519.c 0000664 0000000 0000000 00000003561 13412736503 0022530 0 ustar 00root root 0000000 0000000 #include "cleanup.h"
#include "fe25519.h"
#include "crypto_scalarmult_curve25519.h"
int crypto_scalarmult_curve25519_tinynacl(unsigned char *q, const unsigned char *n, const unsigned char *p) {
unsigned char e[32];
fe x1, x2, z2, x3, z3, tmp0, tmp1;
long long i;
unsigned int d = 0;
int pos;
crypto_uint32 swap, b;
for (i = 0; i < 32; ++i) e[i] = n[i];
e[0] &= 248;
e[31] &= 127;
e[31] |= 64;
fe25519_frombytes(x1, p);
fe_1(x2);
fe_0(z2);
fe_copy(x3, x1);
fe_1(z3);
swap = 0;
for (pos = 254; pos >= 0; --pos) {
b = e[pos / 8] >> (pos & 7);
b &= 1;
swap ^= b;
fe_cswap(x2, x3, swap);
fe_cswap(z2, z3, swap);
swap = b;
fe25519_sub(tmp0, x3, z3);
fe25519_sub(tmp1, x2, z2);
fe25519_add(x2, x2, z2);
fe25519_add(z2, x3, z3);
fe25519_mul(z3, tmp0, x2);
fe25519_mul(z2, z2, tmp1);
fe25519_sq(tmp0, tmp1);
fe25519_sq(tmp1, x2);
fe25519_add(x3, z3, z2);
fe25519_sub(z2, z3, z2);
fe25519_mul(x2, tmp1, tmp0);
fe25519_sub(tmp1, tmp1, tmp0);
fe25519_sq(z2, z2);
fe25519_mul121666(z3, tmp1);
fe25519_sq(x3, x3);
fe25519_add(tmp0, tmp0, z3);
fe25519_mul(z3, x1, z2);
fe25519_mul(z2, tmp1, tmp0);
}
fe_cswap(x2, x3, swap);
fe_cswap(z2, z3, swap);
fe25519_inv(z2, z2);
fe25519_mul(x2, x2, z2);
fe25519_tobytes(q, x2);
cleanup(e);
cleanup(tmp0); cleanup(tmp1);
cleanup(x1); cleanup(x2); cleanup(x3);
cleanup(z2); cleanup(z3);
for (i = 0; i < 32; ++i) d |= q[i];
return -(1 & ((d - 1) >> 8));
}
static const unsigned char basepoint[32] = {9};
int crypto_scalarmult_curve25519_tinynacl_base(unsigned char *q, const unsigned char *n) {
return crypto_scalarmult_curve25519_tinynacl(q, n, basepoint);
}
tinyssh-20190101/crypto/crypto_scalarmult_curve25519.h 0000664 0000000 0000000 00000001543 13412736503 0022533 0 ustar 00root root 0000000 0000000 #ifndef crypto_scalarmult_curve25519_H
#define crypto_scalarmult_curve25519_H
#define crypto_scalarmult_curve25519_tinynacl_BYTES 32
#define crypto_scalarmult_curve25519_tinynacl_SCALARBYTES 32
extern int crypto_scalarmult_curve25519_tinynacl(unsigned char *,const unsigned char *,const unsigned char *);
extern int crypto_scalarmult_curve25519_tinynacl_base(unsigned char *,const unsigned char *);
#define crypto_scalarmult_curve25519 crypto_scalarmult_curve25519_tinynacl
#define crypto_scalarmult_curve25519_base crypto_scalarmult_curve25519_tinynacl_base
#define crypto_scalarmult_curve25519_BYTES crypto_scalarmult_curve25519_tinynacl_BYTES
#define crypto_scalarmult_curve25519_SCALARBYTES crypto_scalarmult_curve25519_tinynacl_SCALARBYTES
#define crypto_scalarmult_curve25519_IMPLEMENTATION "tinynacl"
#define crypto_scalarmult_curve25519_VERSION "-"
#endif
tinyssh-20190101/crypto/crypto_sign_ed25519.c 0000664 0000000 0000000 00000006322 13412736503 0020563 0 ustar 00root root 0000000 0000000 #include "randombytes.h"
#include "cleanup.h"
#include "crypto_hash_sha512.h"
#include "crypto_verify_32.h"
#include "ge25519.h"
#include "sc25519.h"
#include "crypto_sign_ed25519.h"
int crypto_sign_ed25519_tinynacl(unsigned char *sm, unsigned long long *smlen, const unsigned char *m, unsigned long long n, const unsigned char *skorig) {
long long i;
unsigned char nonce[64], hram[64], sk[64], pk[32];
ge25519 R;
/* compute secret key from seed sk = H(skorig), H = sha512 */
crypto_hash_sha512(sk, skorig, 32);
sk[0] &= 248;
sk[31] &= 63;
sk[31] |= 64;
/* copy m to sm, copy secret key and public key */
*smlen = n + 64;
for (i = 31; i >= 0; --i) pk[i ] = skorig[i + 32];
for (i = n - 1; i >= 0; --i) sm[i + 64] = m[i];
for (i = 31; i >= 0; --i) sm[i + 32] = sk[i + 32];
/* get pseudorandom nonce = H(sk2, m) */
crypto_hash_sha512(nonce, sm + 32, n + 32);
sc25519_reduce(nonce);
/* copy pk to sm */
for (i = 31; i >= 0; --i) sm[i + 32] = pk[i];
/* compute R */
ge25519_scalarmult_base(R, nonce);
ge25519_tobytes(sm, R);
/* calculate hram = H(r, a, m) */
crypto_hash_sha512(hram, sm, n + 64);
sc25519_reduce(hram);
/* compute S */
sc25519_muladd(sm + 32, hram, sk, nonce);
/* cleanup */
cleanup(nonce); cleanup(hram); cleanup(sk); cleanup(pk); cleanup(R);
return 0;
}
int crypto_sign_ed25519_tinynacl_open(unsigned char *m, unsigned long long *mlen, const unsigned char *sm, unsigned long long n, const unsigned char *pk) {
long long i;
unsigned char pkcopy[32], rcopy[32], scopy[32], hram[64], rcheck[32];
ge25519 R, S, A;
int ret = -1;
/* check input */
if (n < 64) goto fail;
if (sm[63] & 224) goto fail;
/* unpack pk */
if (ge25519_frombytes_negate_vartime(A, pk) != 0) goto fail;
/* copy pk, r, s */
for (i = 0; i < 32; ++i) pkcopy[i] = pk[i];
for (i = 0; i < 32; ++i) rcopy[i] = sm[i];
for (i = 0; i < 32; ++i) scopy[i] = sm[i + 32];
/* copy sm to m and copy pk to m */
for (i = n - 1; i >= 0; --i) m[i] = sm[i];
for (i = 0; i < 32; ++i) m[i + 32] = pkcopy[i];
/* calculate hram = H(r, a, m) */
crypto_hash_sha512(hram, m, n);
sc25519_reduce(hram);
/* compute R */
ge25519_scalarmult(A, A, hram);
ge25519_scalarmult_base(S, scopy);
ge25519_add(R, S, A);
/* check R */
ge25519_tobytes(rcheck, R);
if (crypto_verify_32(rcheck, rcopy) != 0) goto fail;
/* copy message */
n -= 64; *mlen = n;
for (i = 0; i < n; ++i) m[i] = m[i + 64];
for (i = 0; i < 64; ++i) m[i + n] = 0;
ret = 0;
goto cleanup;
fail:
for (i = 0; i < n; ++i) m[i] = 0;
cleanup:
cleanup(pkcopy); cleanup(rcopy); cleanup(scopy);
cleanup(hram); cleanup(rcheck);
cleanup(R); cleanup(S); cleanup(A);
return ret;
}
int crypto_sign_ed25519_tinynacl_keypair(unsigned char *pk, unsigned char *sk) {
unsigned char h[64];
ge25519 A;
long long i;
randombytes(sk, 32);
crypto_hash_sha512(h, sk, 32);
h[0] &= 248;
h[31] &= 63;
h[31] |= 64;
ge25519_scalarmult_base(A, h);
ge25519_tobytes(pk, A);
for (i = 31; i >= 0; --i) sk[i + 32] = pk[i];
cleanup(h); cleanup(A);
return 0;
}
tinyssh-20190101/crypto/crypto_sign_ed25519.h 0000664 0000000 0000000 00000002153 13412736503 0020566 0 ustar 00root root 0000000 0000000 #ifndef crypto_sign_ed25519_H
#define crypto_sign_ed25519_H
#define crypto_sign_ed25519_tinynacl_SECRETKEYBYTES 64
#define crypto_sign_ed25519_tinynacl_PUBLICKEYBYTES 32
#define crypto_sign_ed25519_tinynacl_BYTES 64
extern int crypto_sign_ed25519_tinynacl(unsigned char *,unsigned long long *,const unsigned char *,unsigned long long,const unsigned char *);
extern int crypto_sign_ed25519_tinynacl_open(unsigned char *,unsigned long long *,const unsigned char *,unsigned long long,const unsigned char *);
extern int crypto_sign_ed25519_tinynacl_keypair(unsigned char *,unsigned char *);
#define crypto_sign_ed25519 crypto_sign_ed25519_tinynacl
#define crypto_sign_ed25519_open crypto_sign_ed25519_tinynacl_open
#define crypto_sign_ed25519_keypair crypto_sign_ed25519_tinynacl_keypair
#define crypto_sign_ed25519_BYTES crypto_sign_ed25519_tinynacl_BYTES
#define crypto_sign_ed25519_PUBLICKEYBYTES crypto_sign_ed25519_tinynacl_PUBLICKEYBYTES
#define crypto_sign_ed25519_SECRETKEYBYTES crypto_sign_ed25519_tinynacl_SECRETKEYBYTES
#define crypto_sign_ed25519_IMPLEMENTATION "tinynacl"
#define crypto_sign_ed25519_VERSION "-"
#endif
tinyssh-20190101/crypto/crypto_stream_chacha20.c 0000664 0000000 0000000 00000016025 13412736503 0021472 0 ustar 00root root 0000000 0000000 /*
20180104
Jan Mojzis
Public domain.
*/
#include "crypto_stream_chacha20.h"
static unsigned long unpack32(const unsigned char *x) {
return
(unsigned long) (x[0]) \
| (((unsigned long) (x[1])) << 8) \
| (((unsigned long) (x[2])) << 16) \
| (((unsigned long) (x[3])) << 24);
}
static void pack32(unsigned char *x, unsigned long u) {
x[0] = u; u >>= 8;
x[1] = u; u >>= 8;
x[2] = u; u >>= 8;
x[3] = u;
}
#define ROTATE32(x, c) ((x) << (c)) | (((x) & 0xffffffff) >> (32 - (c)))
#define QUARTERROUND(a, b, c, d) \
a += b; d = ROTATE32(d ^ a, 16); \
c += d; b = ROTATE32(b ^ c, 12); \
a += b; d = ROTATE32(d ^ a, 8); \
c += d; b = ROTATE32(b ^ c, 7);
#define TWOROUNDS \
QUARTERROUND( x0, x4, x8, x12) \
QUARTERROUND( x1, x5, x9, x13) \
QUARTERROUND( x2, x6, x10, x14) \
QUARTERROUND( x3, x7, x11, x15) \
QUARTERROUND( x0, x5, x10, x15) \
QUARTERROUND( x1, x6, x11, x12) \
QUARTERROUND( x2, x7, x8, x13) \
QUARTERROUND( x3, x4, x9, x14)
#define XORBLOCK(o, i) \
x0 = s0; \
x1 = s1; \
x2 = s2; \
x3 = s3; \
x4 = k0; \
x5 = k1; \
x6 = k2; \
x7 = k3; \
x8 = k4; \
x9 = k5; \
x10 = k6; \
x11 = k7; \
x12 = n0; \
x13 = n1; \
x14 = n2; \
x15 = n3; \
\
TWOROUNDS /* round 1, 2 */ \
TWOROUNDS /* round 3, 4 */ \
TWOROUNDS /* round 5, 6 */ \
TWOROUNDS /* round 7, 8 */ \
TWOROUNDS /* round 9, 10 */ \
TWOROUNDS /* round 11, 12 */ \
TWOROUNDS /* round 13, 14 */ \
TWOROUNDS /* round 15, 16 */ \
TWOROUNDS /* round 17, 18 */ \
TWOROUNDS /* round 19, 20 */ \
\
pack32(o , (x0 + s0) ^ unpack32(i )); \
pack32(o + 4, (x1 + s1) ^ unpack32(i + 4)); \
pack32(o + 8, (x2 + s2) ^ unpack32(i + 8)); \
pack32(o + 12, (x3 + s3) ^ unpack32(i + 12)); \
pack32(o + 16, (x4 + k0) ^ unpack32(i + 16)); \
pack32(o + 20, (x5 + k1) ^ unpack32(i + 20)); \
pack32(o + 24, (x6 + k2) ^ unpack32(i + 24)); \
pack32(o + 28, (x7 + k3) ^ unpack32(i + 28)); \
pack32(o + 32, (x8 + k4) ^ unpack32(i + 32)); \
pack32(o + 36, (x9 + k5) ^ unpack32(i + 36)); \
pack32(o + 40, (x10 + k6) ^ unpack32(i + 40)); \
pack32(o + 44, (x11 + k7) ^ unpack32(i + 44)); \
pack32(o + 48, (x12 + n0) ^ unpack32(i + 48)); \
pack32(o + 52, (x13 + n1) ^ unpack32(i + 52)); \
pack32(o + 56, (x14 + n2) ^ unpack32(i + 56)); \
pack32(o + 60, (x15 + n3) ^ unpack32(i + 60));
#define _CRYPTO_STREAM_XOR(inttype, fcename) \
static int fcename( unsigned char *c, \
const unsigned char *m, \
unsigned long long l, \
const unsigned char *n, \
const unsigned char *k) { \
\
inttype x0, x1, x2, x3, x4, x5, x6, x7; \
inttype x8, x9, x10, x11, x12, x13, x14, x15; \
inttype k0 = unpack32(k ); \
inttype k1 = unpack32(k + 4); \
inttype k2 = unpack32(k + 8); \
inttype k3 = unpack32(k + 12); \
inttype k4 = unpack32(k + 16); \
inttype k5 = unpack32(k + 20); \
inttype k6 = unpack32(k + 24); \
inttype k7 = unpack32(k + 28); \
inttype n0 = 0; \
inttype n1 = 0; \
inttype n2 = unpack32(n ); \
inttype n3 = unpack32(n + 4); \
inttype s0 = 0x61707865; \
inttype s1 = 0x3320646E; \
inttype s2 = 0x79622D32; \
inttype s3 = 0x6B206574; \
unsigned long long u = 0; \
\
if (!l) return 0; \
\
while (l >= 64) { \
XORBLOCK(c, m); \
\
++u; \
if (!u) return -1; \
n0 = (inttype)(u & 0xffffffff); \
n1 = (inttype)(u >> 32); \
\
l -= 64; \
c += 64; \
m += 64; \
} \
if (l) { \
unsigned char b[64] = {0}; \
long long j; \
\
for (j = 0; j < l; ++j) b[j] = m[j]; \
XORBLOCK(b, b); \
for (j = 0; j < l; ++j) c[j] = b[j]; \
} \
return 0; \
}
_CRYPTO_STREAM_XOR(unsigned int, int_crypto_stream_xor)
_CRYPTO_STREAM_XOR(unsigned long, long_crypto_stream_xor)
int crypto_stream_chacha20_tinynacl_xor(unsigned char *c, const unsigned char *m, unsigned long long l, const unsigned char *n, const unsigned char *k) {
if (sizeof(int) == 4) return int_crypto_stream_xor(c, m, l, n, k);
return long_crypto_stream_xor(c, m, l, n, k);
}
int crypto_stream_chacha20_tinynacl(unsigned char *c, unsigned long long l, const unsigned char *n, const unsigned char *k) {
long long j;
unsigned char ncopy[8], kcopy[32];
for (j = 0; j < 32; ++j) kcopy[j] = k[j];
for (j = 0; j < 8; ++j) ncopy[j] = n[j];
for (j = 0; j < l; ++j) c[j] = 0;
return crypto_stream_chacha20_tinynacl_xor(c, c, l, ncopy, kcopy);
}
tinyssh-20190101/crypto/crypto_stream_chacha20.h 0000664 0000000 0000000 00000001536 13412736503 0021500 0 ustar 00root root 0000000 0000000 #ifndef crypto_stream_chacha20_H
#define crypto_stream_chacha20_H
#define crypto_stream_chacha20_tinynacl_KEYBYTES 32
#define crypto_stream_chacha20_tinynacl_NONCEBYTES 8
extern int crypto_stream_chacha20_tinynacl(unsigned char *, unsigned long long, const unsigned char *, const unsigned char *);
extern int crypto_stream_chacha20_tinynacl_xor(unsigned char *, const unsigned char *, unsigned long long, const unsigned char *, const unsigned char *);
#define crypto_stream_chacha20 crypto_stream_chacha20_tinynacl
#define crypto_stream_chacha20_xor crypto_stream_chacha20_tinynacl_xor
#define crypto_stream_chacha20_KEYBYTES crypto_stream_chacha20_tinynacl_KEYBYTES
#define crypto_stream_chacha20_NONCEBYTES crypto_stream_chacha20_tinynacl_NONCEBYTES
#define crypto_stream_chacha20_IMPLEMENTATION "tinynacl"
#define crypto_stream_chacha20_VERSION "-"
#endif
tinyssh-20190101/crypto/crypto_uint16.h 0000664 0000000 0000000 00000000156 13412736503 0017677 0 ustar 00root root 0000000 0000000 #ifndef crypto_uint16_h
#define crypto_uint16_h
#include
typedef uint16_t crypto_uint16;
#endif
tinyssh-20190101/crypto/crypto_uint32.h 0000664 0000000 0000000 00000000156 13412736503 0017675 0 ustar 00root root 0000000 0000000 #ifndef crypto_uint32_h
#define crypto_uint32_h
#include
typedef uint32_t crypto_uint32;
#endif
tinyssh-20190101/crypto/crypto_uint64.h 0000664 0000000 0000000 00000000156 13412736503 0017702 0 ustar 00root root 0000000 0000000 #ifndef crypto_uint64_h
#define crypto_uint64_h
#include
typedef uint64_t crypto_uint64;
#endif
tinyssh-20190101/crypto/crypto_uint8.h 0000664 0000000 0000000 00000000152 13412736503 0017614 0 ustar 00root root 0000000 0000000 #ifndef crypto_uint8_h
#define crypto_uint8_h
#include
typedef uint8_t crypto_uint8;
#endif
tinyssh-20190101/crypto/crypto_verify_16.c 0000664 0000000 0000000 00000000242 13412736503 0020352 0 ustar 00root root 0000000 0000000 #include "verify.h"
#include "crypto_verify_16.h"
int crypto_verify_16_tinynacl(const unsigned char *x, const unsigned char *y) {
return verify(x, y, 16);
}
tinyssh-20190101/crypto/crypto_verify_16.h 0000664 0000000 0000000 00000000611 13412736503 0020357 0 ustar 00root root 0000000 0000000 #ifndef crypto_verify_16_H
#define crypto_verify_16_H
#define crypto_verify_16_tinynacl_BYTES 16
extern int crypto_verify_16_tinynacl(const unsigned char *, const unsigned char *);
#define crypto_verify_16 crypto_verify_16_tinynacl
#define crypto_verify_16_BYTES crypto_verify_16_tinynacl_BYTES
#define crypto_verify_16_IMPLEMENTATION "tinynacl"
#define crypto_verify_16_VERSION "-"
#endif
tinyssh-20190101/crypto/crypto_verify_32.c 0000664 0000000 0000000 00000000242 13412736503 0020350 0 ustar 00root root 0000000 0000000 #include "verify.h"
#include "crypto_verify_32.h"
int crypto_verify_32_tinynacl(const unsigned char *x, const unsigned char *y) {
return verify(x, y, 32);
}
tinyssh-20190101/crypto/crypto_verify_32.h 0000664 0000000 0000000 00000000611 13412736503 0020355 0 ustar 00root root 0000000 0000000 #ifndef crypto_verify_32_H
#define crypto_verify_32_H
#define crypto_verify_32_tinynacl_BYTES 32
extern int crypto_verify_32_tinynacl(const unsigned char *, const unsigned char *);
#define crypto_verify_32 crypto_verify_32_tinynacl
#define crypto_verify_32_BYTES crypto_verify_32_tinynacl_BYTES
#define crypto_verify_32_IMPLEMENTATION "tinynacl"
#define crypto_verify_32_VERSION "-"
#endif
tinyssh-20190101/crypto/fe.c 0000664 0000000 0000000 00000007571 13412736503 0015546 0 ustar 00root root 0000000 0000000 /*
20140918
Jan Mojzis
Public domain.
*/
#include "fe.h"
/*
o = 0
*/
void fe_0(fe o) {
long long i;
for (i = 0; i < 8; ++i) o[i] = 0;
}
/*
o = 1
*/
void fe_1(fe o) {
fe_0(o);
o[0] = 1;
}
/*
o = x
*/
void fe_copy(fe o, const fe x) {
long long i;
for (i = 0; i < 8; ++i) o[i] = x[i];
}
/*
if (b) swap(f, g)
*/
void fe_cswap(fe f, fe g, crypto_uint32 b) {
long long i;
fe t;
b = -b;
for (i = 0; i < 8; ++i) t[i] = b & (f[i] ^ g[i]);
for (i = 0; i < 8; ++i) f[i] ^= t[i];
for (i = 0; i < 8; ++i) g[i] ^= t[i];
fe_0(t);
}
/*
if (b) f = g
*/
void fe_cmov(fe f, const fe g, crypto_uint32 b) {
long long i;
fe t;
b = -b;
for (i = 0; i < 8; ++i) t[i] = b & (f[i] ^ g[i]);
for (i = 0; i < 8; ++i) f[i] ^= t[i];
fe_0(t);
}
/*
o = a * b
*/
/*
Implementation note: fe_mul_() is unrolled version of:
void fe_mul_(fel o, const fe a, const fe b) {
crypto_uint64 u;
long long i, j;
for (i = 0; i < 16; ++i) o[i] = 0;
for (i = 0; i < 8; ++i) for (j = 0; j < 8; ++j) {
u = (crypto_uint64)a[i] * (crypto_uint64)b[j];
o[i + j ] += u & 0xffffffff;
o[i + j + 1] += u >> 32;
}
}
*/
#define M(i, j) u = (crypto_uint64)a[i] * (crypto_uint64)b[j]; \
o[i + j ] += u & 0xffffffff; \
o[i + j + 1] += u >> 32;
void fe_mul_(fel o, const fe a, const fe b) {
crypto_uint64 u;
long long i;
for (i = 0; i < 16; ++i) o[i] = 0;
M(0, 0); M(0, 1); M(0, 2); M(0, 3); M(0, 4); M(0, 5); M(0, 6); M(0, 7);
M(1, 0); M(1, 1); M(1, 2); M(1, 3); M(1, 4); M(1, 5); M(1, 6); M(1, 7);
M(2, 0); M(2, 1); M(2, 2); M(2, 3); M(2, 4); M(2, 5); M(2, 6); M(2, 7);
M(3, 0); M(3, 1); M(3, 2); M(3, 3); M(3, 4); M(3, 5); M(3, 6); M(3, 7);
M(4, 0); M(4, 1); M(4, 2); M(4, 3); M(4, 4); M(4, 5); M(4, 6); M(4, 7);
M(5, 0); M(5, 1); M(5, 2); M(5, 3); M(5, 4); M(5, 5); M(5, 6); M(5, 7);
M(6, 0); M(6, 1); M(6, 2); M(6, 3); M(6, 4); M(6, 5); M(6, 6); M(6, 7);
M(7, 0); M(7, 1); M(7, 2); M(7, 3); M(7, 4); M(7, 5); M(7, 6); M(7, 7);
}
/*
o = x ^ 2
*/
/*
Implementation note: fe_sq_() is unrolled version of:
void fe_sq_(fel o, const fe a) {
crypto_uint64 u;
long long i, j;
for (i = 0; i < 16; ++i) o[i] = 0;
for (i = 0; i < 8; ++i) for (j = i + 1; j < 8; ++j) {
u = (crypto_uint64)a[i] * (crypto_uint64)a[j];
o[i + j ] += 2 * (u & 0xffffffff);
o[i + j + 1] += 2 * (u >> 32);
}
for (i = 0; i < 8; ++i) {
u = (crypto_uint64)a[i] * (crypto_uint64)a[i];
o[2 * i ] += (u & 0xffffffff);
o[2 * i + 1] += (u >> 32);
}
}
*/
#define M2(i, j) u = (crypto_uint64)a[i] * (crypto_uint64)a[j]; \
o[i + j ] += 2 * (u & 0xffffffff); \
o[i + j + 1] += 2 * (u >> 32);
#define SQ(i) u = (crypto_uint64)a[i] * (crypto_uint64)a[i]; \
o[2 * i ] += (u & 0xffffffff); \
o[2 * i + 1] += (u >> 32)
void fe_sq_(fel o, const fe a) {
crypto_uint64 u;
long long i;
for (i = 0; i < 16; ++i) o[i] = 0;
M2(0, 1); M2(0, 2); M2(0, 3); M2(0, 4); M2(0, 5); M2(0, 6); M2(0, 7);
M2(1, 2); M2(1, 3); M2(1, 4); M2(1, 5); M2(1, 6); M2(1, 7);
M2(2, 3); M2(2, 4); M2(2, 5); M2(2, 6); M2(2, 7);
M2(3, 4); M2(3, 5); M2(3, 6); M2(3, 7);
M2(4, 5); M2(4, 6); M2(4, 7);
M2(5, 6); M2(5, 7);
M2(6, 7);
SQ(0); SQ(1); SQ(2); SQ(3); SQ(4); SQ(5); SQ(6); SQ(7);
}
/*
if (p < r) r -= p
*/
void fe_reducesmall(fe r, const fe p, const crypto_uint64 carry) {
crypto_uint64 pb = 0, b;
long long i;
fe t;
for (i = 0; i < 8; ++i) {
pb += (crypto_uint64)p[i];
b = (crypto_uint64)r[i] - pb; b >>= 63;
t[i] = (crypto_uint64)r[i] - pb + (b << 32);
pb = b;
}
b = carry - pb; b >>= 63;
b -= 1;
for (i = 0; i < 8; ++i) r[i] ^= b & (r[i] ^ t[i]);
fe_0(t);
}
tinyssh-20190101/crypto/fe.h 0000664 0000000 0000000 00000000741 13412736503 0015543 0 ustar 00root root 0000000 0000000 #ifndef _FE_H____
#define _FE_H____
#include "crypto_uint32.h"
#include "crypto_uint64.h"
typedef crypto_uint32 fe[8];
typedef crypto_uint64 fel[16];
extern void fe_0(fe);
extern void fe_1(fe);
extern void fe_copy(fe, const fe);
extern void fe_cswap(fe, fe, crypto_uint32);
extern void fe_cmov(fe, const fe, crypto_uint32);
extern void fe_mul_(fel, const fe, const fe);
extern void fe_sq_(fel, const fe);
extern void fe_reducesmall(fe, const fe, const crypto_uint64);
#endif
tinyssh-20190101/crypto/fe25519.c 0000664 0000000 0000000 00000013434 13412736503 0016147 0 ustar 00root root 0000000 0000000 #include "uint32_pack.h"
#include "uint32_unpack.h"
#include "crypto_verify_32.h"
#include "cleanup.h"
#include "fe.h"
#include "fe25519.h"
/*
p = 2^255 - 19
*/
static const fe p = {
0xffffffed, 0xffffffff, 0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff, 0xffffffff, 0x7fffffff
};
/*
p3 = 3 * p
*/
static const crypto_uint64 p3[8] = {
0x2ffffffc7ULL, 0x2fffffffdULL, 0x2fffffffdULL, 0x2fffffffdULL,
0x2fffffffdULL, 0x2fffffffdULL, 0x2fffffffdULL, 0x17ffffffdULL
};
/*
reduction modulo p: 16 limbs -> 8 limbs
*/
static void fe25519_reducebig(fe o, fel t) {
crypto_uint64 u = 0;
long long i;
for (i = 0; i < 7; ++i) { u += t[i] + 38ULL * t[i + 8]; t[i] = u & 0xffffffff; u >>= 32; }
u += t[i] + 38ULL * t[i + 8]; t[i] = u & 0x7fffffff; u >>= 31;
u *= 19ULL;
for (i = 0; i < 8; ++i) { u += t[i]; o[i] = u & 0xffffffff; u >>= 32; }
}
/*
o = (a * b) % p
*/
void fe25519_mul(fe o, const fe a, const fe b) {
fel t;
fe_mul_(t, a, b);
fe25519_reducebig(o, t);
cleanup(t);
}
/*
o = (a ^ 2) % p
*/
void fe25519_sq(fe o, const fe a) {
fel t;
fe_sq_(t, a);
fe25519_reducebig(o, t);
cleanup(t);
}
/*
o = (121666 * f) % p;
*/
void fe25519_mul121666(fe o, const fe f) {
crypto_uint64 u = 0;
long long i;
for (i = 0; i < 7; ++i) { u += (crypto_uint64)121666 * (crypto_uint64)f[i]; o[i] = u & 0xffffffff; u >>= 32; }
u += (crypto_uint64)121666 * (crypto_uint64)f[i]; o[i] = u & 0x7fffffff; u >>= 31;
u *= 19ULL;
for (i = 0; i < 8; ++i) { u += o[i]; o[i] = u & 0xffffffff; u >>= 32; }
}
/*
o = (x + y) % p
*/
void fe25519_add(fe o, const fe x, const fe y) {
crypto_uint64 u = 0;
long long i;
for (i = 0; i < 7; ++i) { u += (crypto_uint64)x[i] + (crypto_uint64)y[i]; o[i] = u & 0xffffffff; u >>= 32; }
u += (crypto_uint64)x[i] + (crypto_uint64)y[i]; o[i] = u & 0x7fffffff; u >>= 31;
u *= 19ULL;
for (i = 0; i < 8; ++i) { u += o[i]; o[i] = u & 0xffffffff; u >>= 32; }
}
/*
o = (x - y) % p
*/
void fe25519_sub(fe o, const fe x, const fe y) {
crypto_uint64 u = 0;
long long i;
for (i = 0; i < 7; ++i) { u += p3[i] - (crypto_uint64)y[i] + (crypto_uint64)x[i]; o[i] = u & 0xffffffff; u >>= 32; }
u += p3[i] - (crypto_uint64)y[i] + (crypto_uint64)x[i]; o[i] = u & 0x7fffffff; u >>= 31;
u *= 19ULL;
for (i = 0; i < 8; ++i) { u += o[i]; o[i] = u & 0xffffffff; u >>= 32; }
}
/*
o = -x % p
*/
void fe25519_neg(fe o, const fe x) {
fe t;
fe_0(t);
fe25519_sub(o, t, x);
}
/*
o = (1 / z) % p
... using Fermat's Little Theorem
*/
void fe25519_inv(fe o, const fe z) {
fe t0, t1, t2, t3;
long long i;
fe25519_sq(t0, z); for (i = 1; i < 1; ++i) fe25519_sq(t0, t0);
fe25519_sq(t1,t0); for (i = 1; i < 2; ++i) fe25519_sq(t1, t1);
fe25519_mul(t1, z, t1);
fe25519_mul(t0, t0, t1);
fe25519_sq(t2, t0); for (i = 1; i < 1; ++i) fe25519_sq(t2, t2);
fe25519_mul(t1, t1, t2);
fe25519_sq(t2, t1); for (i = 1; i < 5; ++i) fe25519_sq(t2, t2);
fe25519_mul(t1, t2, t1);
fe25519_sq(t2, t1); for (i = 1; i < 10; ++i) fe25519_sq(t2, t2);
fe25519_mul(t2, t2, t1);
fe25519_sq(t3, t2); for (i = 1; i < 20; ++i) fe25519_sq(t3, t3);
fe25519_mul(t2, t3, t2);
fe25519_sq(t2, t2); for (i = 1; i < 10; ++i) fe25519_sq(t2, t2);
fe25519_mul(t1, t2, t1);
fe25519_sq(t2, t1); for (i = 1; i < 50; ++i) fe25519_sq(t2, t2);
fe25519_mul(t2, t2, t1);
fe25519_sq(t3, t2); for (i = 1; i < 100; ++i) fe25519_sq(t3, t3);
fe25519_mul(t2, t3, t2);
fe25519_sq(t2, t2); for (i = 1; i < 50; ++i) fe25519_sq(t2, t2);
fe25519_mul(t1, t2, t1);
fe25519_sq(t1, t1); for (i = 1; i < 5; ++i) fe25519_sq(t1, t1);
fe25519_mul(o, t1, t0);
cleanup(t0); cleanup(t1); cleanup(t2); cleanup(t3);
}
void fe25519_pow22523(fe out, const fe z) {
fe t0, t1, t2;
long long i;
fe25519_sq(t0, z); for (i = 1; i < 1; ++i) fe25519_sq(t0, t0);
fe25519_sq(t1, t0); for (i = 1; i < 2; ++i) fe25519_sq(t1, t1);
fe25519_mul(t1, z, t1);
fe25519_mul(t0, t0, t1);
fe25519_sq(t0, t0); for (i = 1; i < 1; ++i) fe25519_sq(t0, t0);
fe25519_mul(t0, t1, t0);
fe25519_sq(t1, t0); for (i = 1; i < 5; ++i) fe25519_sq(t1, t1);
fe25519_mul(t0, t1, t0);
fe25519_sq(t1, t0); for (i = 1; i < 10; ++i) fe25519_sq(t1, t1);
fe25519_mul(t1, t1, t0);
fe25519_sq(t2, t1); for (i = 1; i < 20; ++i) fe25519_sq(t2, t2);
fe25519_mul(t1, t2, t1);
fe25519_sq(t1, t1); for (i = 1; i < 10; ++i) fe25519_sq(t1, t1);
fe25519_mul(t0, t1, t0);
fe25519_sq(t1, t0); for (i = 1; i < 50; ++i) fe25519_sq(t1, t1);
fe25519_mul(t1, t1, t0);
fe25519_sq(t2, t1); for (i = 1; i < 100; ++i) fe25519_sq(t2, t2);
fe25519_mul(t1, t2, t1);
fe25519_sq(t1, t1); for (i = 1; i < 50; ++i) fe25519_sq(t1, t1);
fe25519_mul(t0, t1, t0);
fe25519_sq(t0, t0); for (i = 1; i < 2; ++i) fe25519_sq(t0, t0);
fe25519_mul(out, t0, z);
cleanup(t0); cleanup(t1); cleanup(t2);
}
/*
converts field-element into byte-array
*/
void fe25519_tobytes(unsigned char *out, const fe in) {
long long i;
fe x;
fe_copy(x, in);
fe_reducesmall(x, p, 0);
for (i = 0; i < 8; ++i) uint32_pack(out + 4 * i, x[i]);
cleanup(x);
}
/*
converts byte-array into field-element
*/
void fe25519_frombytes(fe out, const unsigned char *in) {
long long i;
for (i = 0; i < 8; ++i) out[i] = uint32_unpack(in + 4 * i);
out[7] &= 0x7fffffff;
}
/*
if (f == 0) return 0;
else return -1;
*/
static const unsigned char zero[32] = {0};
int fe25519_isnonzero(const fe f) {
unsigned char s[32];
int r;
fe25519_tobytes(s, f);
r = crypto_verify_32(s, zero);
cleanup(s);
return r;
}
/*
if (f >= 0) return 0;
else return -1;
*/
int fe25519_isnegative(const fe f) {
unsigned char s[32];
int r;
fe25519_tobytes(s,f);
r = s[0] & 1;
cleanup(s);
return r;
}
tinyssh-20190101/crypto/fe25519.h 0000664 0000000 0000000 00000001156 13412736503 0016152 0 ustar 00root root 0000000 0000000 #ifndef _FE25519_H____
#define _FE25519_H____
#include "fe.h"
extern void fe25519_mul(fe, const fe, const fe);
extern void fe25519_sq(fe, const fe);
extern void fe25519_add(fe, const fe, const fe);
extern void fe25519_mul121666(fe, const fe);
extern void fe25519_sub(fe, const fe, const fe);
extern void fe25519_neg(fe, const fe);
extern void fe25519_inv(fe, const fe);
extern void fe25519_pow22523(fe, const fe);
extern void fe25519_tobytes(unsigned char *, const fe);
extern void fe25519_frombytes(fe, const unsigned char *);
extern int fe25519_isnonzero(const fe);
extern int fe25519_isnegative(const fe);
#endif
tinyssh-20190101/crypto/ge25519.c 0000664 0000000 0000000 00000013100 13412736503 0016136 0 ustar 00root root 0000000 0000000 #include "fe25519.h"
#include "cleanup.h"
#include "ge25519.h"
/* D = -121665/121666 */
static fe D = {
0x135978a3, 0x75eb4dca, 0x4141d8ab, 0x00700a4d,
0x7779e898, 0x8cc74079, 0x2b6ffe73, 0x52036cee
};
/* D2 = 2 * -121665/121666 */
static fe D2 = {
0x26b2f159, 0xebd69b94, 0x8283b156, 0x00e0149a,
0xeef3d130, 0x198e80f2, 0x56dffce7, 0x2406d9dc
};
static fe sqrtm1 = {
0x4a0ea0b0, 0xc4ee1b27, 0xad2fe478, 0x2f431806,
0x3dfbd7a7, 0x2b4d0099, 0x4fc1df0b, 0x2b832480,
};
static void neutral(ge25519 p) {
fe_0(p[0]);
fe_1(p[1]);
fe_1(p[2]);
fe_0(p[3]);
}
/*
p = q
*/
static void copy(ge25519 p, ge25519 q) {
fe_copy(p[0], q[0]);
fe_copy(p[1], q[1]);
fe_copy(p[2], q[2]);
fe_copy(p[3], q[3]);
}
/*
if (b) p = q;
*/
static void cmov(ge25519 p, ge25519 q, crypto_uint32 b) {
fe_cmov(p[0], q[0], b);
fe_cmov(p[1], q[1], b);
fe_cmov(p[2], q[2], b);
fe_cmov(p[3], q[3], b);
}
void ge25519_add(ge25519 o, ge25519 p, ge25519 q) {
fe a, b, c, d, t, e, f, g, h;
fe25519_sub(a, p[1], p[0]);
fe25519_sub(t, q[1], q[0]);
fe25519_mul(a, a, t);
fe25519_add(b, p[0], p[1]);
fe25519_add(t, q[0], q[1]);
fe25519_mul(b, b, t);
fe25519_mul(c, p[3], q[3]);
fe25519_mul(c, c, D2);
fe25519_mul(d, p[2], q[2]);
fe25519_add(d, d, d);
fe25519_sub(e, b, a);
fe25519_sub(f, d, c);
fe25519_add(g, d, c);
fe25519_add(h, b, a);
fe25519_mul(o[0], e, f);
fe25519_mul(o[1], h, g);
fe25519_mul(o[2], g, f);
fe25519_mul(o[3], e, h);
cleanup(a); cleanup(b); cleanup(c); cleanup(d); cleanup(t);
cleanup(e); cleanup(f); cleanup(g); cleanup(h);
}
/* https://hyperelliptic.org/EFD/g1p/auto-code/twisted/extended/doubling/dbl-2008-hwcd.op3 */
static void dbl(ge25519 o, ge25519 p) {
fe a, b, c, d, e, f, g, h;
fe25519_sq(a, p[0]); /* A = X1^2 */
fe25519_sq(b, p[1]); /* B = Y1^2 */
fe25519_sq(c, p[2]); /* t0 = Z1^2 */
fe25519_add(c, c, c); /* C = 2*t0 */
fe25519_neg(d, a); /* D = a*A */
fe25519_add(e, p[0], p[1]); /* t1 = X1+Y1 */
fe25519_sq(e, e); /* t2 = t1^2 */
fe25519_sub(e, e, a); /* t3 = t2-A */
fe25519_sub(e, e, b); /* E = t3-B */
fe25519_add(g, d, b); /* G = D+B */
fe25519_sub(f, g, c); /* F = G-C */
fe25519_sub(h, d, b); /* H = D-B */
fe25519_mul(o[0], e, f); /* X3 = E*F */
fe25519_mul(o[1], g, h); /* Y3 = G*H */
fe25519_mul(o[2], f, g); /* Z3 = F*G */
fe25519_mul(o[3], e, h); /* T3 = E*H */
cleanup(a); cleanup(b); cleanup(c); cleanup(d);
cleanup(e); cleanup(f); cleanup(g); cleanup(h);
}
void ge25519_tobytes(unsigned char *s, ge25519 h) {
fe x, y, z;
fe25519_inv(z, h[2]);
fe25519_mul(x, h[0], z);
fe25519_mul(y, h[1], z);
fe25519_tobytes(s, y);
s[31] ^= fe25519_isnegative(x) << 7;
cleanup(x); cleanup(y); cleanup(z);
}
int ge25519_frombytes_negate_vartime(ge25519 h, const unsigned char *s) {
fe u, v, v3, vxx, check;
int ret = -1;
fe25519_frombytes(h[1], s);
fe_1(h[2]);
fe25519_sq(u,h[1]);
fe25519_mul(v,u,D);
fe25519_sub(u,u,h[2]); /* u = y^2-1 */
fe25519_add(v,v,h[2]); /* v = dy^2+1 */
fe25519_sq(v3,v);
fe25519_mul(v3,v3,v); /* v3 = v^3 */
fe25519_sq(h[0],v3);
fe25519_mul(h[0],h[0],v);
fe25519_mul(h[0],h[0],u); /* x = uv^7 */
fe25519_pow22523(h[0],h[0]); /* x = (uv^7)^((q-5)/8) */
fe25519_mul(h[0],h[0],v3);
fe25519_mul(h[0],h[0],u); /* x = uv^3(uv^7)^((q-5)/8) */
fe25519_sq(vxx,h[0]);
fe25519_mul(vxx,vxx,v);
fe25519_sub(check,vxx,u); /* vx^2-u */
if (fe25519_isnonzero(check)) {
fe25519_add(check,vxx,u); /* vx^2+u */
if (fe25519_isnonzero(check)) {
goto cleanup;
}
fe25519_mul(h[0],h[0],sqrtm1);
}
if (fe25519_isnegative(h[0]) == (s[31] >> 7))
fe25519_neg(h[0], h[0]);
fe25519_mul(h[3],h[0],h[1]);
ret = 0;
cleanup:
cleanup(u); cleanup(v); cleanup(v3);
cleanup(vxx); cleanup(check);
return ret;
}
/*
if (a == b) return 1;
else return 0;
*/
static unsigned char equal(unsigned char a, unsigned char b) {
unsigned char x = a ^ b;
crypto_uint32 y = x;
y -= 1;
y >>= 31;
return y;
}
/*
point multiplication using windowed method
*/
void ge25519_scalarmult(ge25519 o, ge25519 q, const unsigned char *a) {
long long i, j;
ge25519 t[16], sp, p;
unsigned char e[64];
for (i = 0; i < 32; ++i) {
e[2 * i + 0] = (a[i] >> 0) & 0x0f;
e[2 * i + 1] = (a[i] >> 4) & 0x0f;
}
neutral(p);
/* precompute points */
copy(t[0], p);
copy(t[1], q);
for (i = 2; i < 16; ++i) {
if ((i & 1) == 0) dbl(t[i], t[i / 2]);
else ge25519_add(t[i], t[i - 1], q);
}
for (i = 63; i >= 0; --i) {
for (j = 0; j < 4; ++j) dbl(p, p);
for (j = 0; j < 16; ++j) cmov(sp, t[j], equal(e[i], j));
ge25519_add(p, p, sp);
}
copy(o, p);
cleanup(p); cleanup(t); cleanup(sp); cleanup(e);
}
static ge25519 baseq = {
{ 0x8f25d51a,0xc9562d60,0x9525a7b2,0x692cc760,0xfdd6dc5c,0xc0a4e231,0xcd6e53fe,0x216936d3 },
{ 0x66666658,0x66666666,0x66666666,0x66666666,0x66666666,0x66666666,0x66666666,0x66666666 },
{ 0x00000001,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 },
{ 0xa5b7dda3,0x6dde8ab3,0x775152f5,0x20f09f80,0x64abe37d,0x66ea4e8e,0xd78b7665,0x67875f0f },
};
void ge25519_scalarmult_base(ge25519 p, const unsigned char *a) {
ge25519_scalarmult(p, baseq, a);
}
tinyssh-20190101/crypto/ge25519.h 0000664 0000000 0000000 00000000700 13412736503 0016145 0 ustar 00root root 0000000 0000000 #ifndef _GE25519_H____
#define _GE25519_H____
#include "fe.h"
typedef fe ge25519[4]; /* X, Y, Z, T */
extern void ge25519_tobytes(unsigned char *, ge25519);
extern int ge25519_frombytes_negate_vartime(ge25519, const unsigned char *);
extern void ge25519_add(ge25519, ge25519, ge25519);
extern void ge25519_scalarmult(ge25519, ge25519, const unsigned char *);
extern void ge25519_scalarmult_base(ge25519, const unsigned char *);
#endif
tinyssh-20190101/crypto/randombytes.c 0000664 0000000 0000000 00000001404 13412736503 0017470 0 ustar 00root root 0000000 0000000 /* taken from nacl-20110221, from randombytes/devurandom.c, added close-on-exec */
#include
#include
#include
#include
#include "randombytes.h"
/* it's really stupid that there isn't a syscall for this */
static int fd = -1;
void randombytes(unsigned char *x,unsigned long long xlen)
{
int i;
if (fd == -1) {
for (;;) {
#ifdef O_CLOEXEC
fd = open("/dev/urandom",O_RDONLY | O_CLOEXEC);
#else
fd = open("/dev/urandom",O_RDONLY);
fcntl(fd,F_SETFD,1);
#endif
if (fd != -1) break;
sleep(1);
}
}
while (xlen > 0) {
if (xlen < 1048576) i = xlen; else i = 1048576;
i = read(fd,x,i);
if (i < 1) {
sleep(1);
continue;
}
x += i;
xlen -= i;
}
}
tinyssh-20190101/crypto/randombytes.h 0000664 0000000 0000000 00000000326 13412736503 0017477 0 ustar 00root root 0000000 0000000 #ifndef _RANDOMBYTES_H____
#define _RANDOMBYTES_H____
extern void randombytes(unsigned char *, unsigned long long);
#ifndef randombytes_implementation
#define randombytes_implementation "tinynacl"
#endif
#endif
tinyssh-20190101/crypto/sc25519.c 0000664 0000000 0000000 00000002774 13412736503 0016167 0 ustar 00root root 0000000 0000000 /*
- based on tweetnacl 20140427 (http://tweetnacl.cr.yp.to/software.html)
*/
#include "crypto_int64.h"
#include "crypto_uint32.h"
#include "crypto_uint64.h"
#include "cleanup.h"
#include "sc25519.h"
#define FOR(i,n) for (i = 0;i < n;++i)
static const crypto_uint64 L[32] = {0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10};
static void modL(unsigned char *r,crypto_int64 x[64])
{
crypto_int64 carry,i,j;
for (i = 63;i >= 32;--i) {
carry = 0;
for (j = i - 32;j < i - 12;++j) {
x[j] += carry - 16 * x[i] * L[j - (i - 32)];
carry = (x[j] + 128) >> 8;
x[j] -= carry << 8;
}
x[j] += carry;
x[i] = 0;
}
carry = 0;
FOR(j,32) {
x[j] += carry - (x[31] >> 4) * L[j];
carry = x[j] >> 8;
x[j] &= 255;
}
FOR(j,32) x[j] -= carry * L[j];
FOR(i,32) {
x[i+1] += x[i] >> 8;
r[i] = x[i] & 255;
}
}
void sc25519_reduce(unsigned char *s) {
crypto_int64 t[64], i;
for (i = 0; i < 64; ++i) t[i] = s[i];
for (i = 0; i < 64; ++i) s[i] = 0;
modL(s, t);
cleanup(t);
}
void sc25519_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b, const unsigned char *c) {
crypto_int64 t[64], i, j;
for (i = 0; i < 64; ++i) t[i] = 0;
for (i = 0; i < 32; ++i) for (j = 0; j < 32; ++j) {
t[i + j] += (crypto_int64)a[i] * (crypto_int64)b[j];
}
for (i = 0; i < 32; ++i) t[i] += c[i];
modL(s, t);
cleanup(t);
}
tinyssh-20190101/crypto/sc25519.h 0000664 0000000 0000000 00000000326 13412736503 0016163 0 ustar 00root root 0000000 0000000 #ifndef _SC25519_H____
#define _SC25519_H____
extern void sc25519_reduce(unsigned char *);
extern void sc25519_muladd(unsigned char *, const unsigned char *, const unsigned char *, const unsigned char *);
#endif
tinyssh-20190101/crypto/uint32_pack.c 0000664 0000000 0000000 00000000405 13412736503 0017263 0 ustar 00root root 0000000 0000000 #include "uint32_pack.h"
/*
The 'uint32_pack' function converts 32-bit unsigned
integer into 4 bytes stored in little-endian format
*/
void uint32_pack(unsigned char *y, crypto_uint32 x) {
long long i;
for (i = 0; i < 4; ++i) { y[i] = x; x >>= 8; }
}
tinyssh-20190101/crypto/uint32_pack.h 0000664 0000000 0000000 00000000224 13412736503 0017267 0 ustar 00root root 0000000 0000000 #ifndef _UINT32_PACK_H____
#define _UINT32_PACK_H____
#include "crypto_uint32.h"
extern void uint32_pack(unsigned char *, crypto_uint32);
#endif
tinyssh-20190101/crypto/uint32_pack_big.c 0000664 0000000 0000000 00000000420 13412736503 0020101 0 ustar 00root root 0000000 0000000 #include "uint32_pack_big.h"
/*
The 'uint32_pack_big' function converts 32-bit unsigned
integer into 4 bytes stored in big-endian format
*/
void uint32_pack_big(unsigned char *y, crypto_uint32 x) {
long long i;
for (i = 3; i >= 0; --i) { y[i] = x; x >>= 8; }
}
tinyssh-20190101/crypto/uint32_pack_big.h 0000664 0000000 0000000 00000000237 13412736503 0020114 0 ustar 00root root 0000000 0000000 #ifndef _UINT32_PACK_BIG____
#define _UINT32_PACK_BIG____
#include "crypto_uint32.h"
extern void uint32_pack_big(unsigned char *y, crypto_uint32 x);
#endif
tinyssh-20190101/crypto/uint32_unpack.c 0000664 0000000 0000000 00000000451 13412736503 0017627 0 ustar 00root root 0000000 0000000 #include "uint32_unpack.h"
/*
The 'uint32_unpack' function converts 4 bytes
in little-endian format into 32-bit unsigned integer.
*/
crypto_uint32 uint32_unpack(const unsigned char *x) {
crypto_uint32 y = 0;
long long i;
for (i = 3; i >= 0; --i) y = (y << 8) | x[i];
return y;
}
tinyssh-20190101/crypto/uint32_unpack.h 0000664 0000000 0000000 00000000232 13412736503 0017631 0 ustar 00root root 0000000 0000000 #ifndef _UINT32_UNPACK_H____
#define _UINT32_UNPACK_H____
#include "crypto_uint32.h"
extern crypto_uint32 uint32_unpack(const unsigned char *);
#endif
tinyssh-20190101/crypto/uint32_unpack_big.c 0000664 0000000 0000000 00000000462 13412736503 0020452 0 ustar 00root root 0000000 0000000 #include "uint32_unpack_big.h"
/*
The 'uint32_unpack_big' function converts 4 bytes
in big-endian format into 32-bit unsigned integer.
*/
crypto_uint32 uint32_unpack_big(const unsigned char *x) {
crypto_uint32 y = 0;
long long i;
for (i = 0; i < 4; ++i) y = (y << 8) | x[i];
return y;
}
tinyssh-20190101/crypto/uint32_unpack_big.h 0000664 0000000 0000000 00000000242 13412736503 0020453 0 ustar 00root root 0000000 0000000 #ifndef _UINT32_UNPACK_BIG____
#define _UINT32_UNPACK_BIG____
#include "crypto_uint32.h"
extern crypto_uint32 uint32_unpack_big(const unsigned char *);
#endif
tinyssh-20190101/crypto/verify.c 0000664 0000000 0000000 00000000337 13412736503 0016451 0 ustar 00root root 0000000 0000000 #include "verify.h"
int verify(const unsigned char *x, const unsigned char *y, long long n) {
unsigned int d = 0;
long long i;
for (i = 0; i < n; ++i) d |= x[i] ^ y[i];
return (1 & ((d - 1) >> 8)) - 1;
}
tinyssh-20190101/crypto/verify.h 0000664 0000000 0000000 00000000201 13412736503 0016444 0 ustar 00root root 0000000 0000000 #ifndef _VERIFY_H____
#define _VERIFY_H____
extern int verify(const unsigned char *, const unsigned char *, long long);
#endif
tinyssh-20190101/make-install.sh 0000775 0000000 0000000 00000002546 13412736503 0016405 0 ustar 00root root 0000000 0000000 #!/bin/sh -e
build="`pwd`/build"
source="`pwd`"
bin="${build}/bin"
man="${build}/man"
installcmd="${bin}/_tinysshd-install"
cat "${source}/tinyssh/TARGETS" |\
while read x
do
[ -x "${bin}/${x}" ] || \
(
echo "=== `date` === $x not compiled, compile first!"
exit 111;
) || exit 111
done || exit 111
[ -x "${installcmd}" ] || \
(
echo "=== `date` === ${installcmd} not compiled, compile first!"
exit 111;
) || exit 111
#bin
confbin="`head -1 conf-bin`"
bindir=`echo "$1/${confbin}" | sed 's,//,/,g'`
echo "=== `date` === installing bin directory ${bindir}"
mkdir -p "${bindir}" || exit 111
cat "${source}/tinyssh/TARGETS" |\
while read x
do
"${installcmd}" "${bin}/${x}" "${bindir}" "${x}.tmp" "${x}" 1 || exit 111
echo "=== `date` === installing ${bin}/${x} -> ${bindir}/${x}"
done || exit 111
echo "=== `date` === finishing"
#man
confman="`head -1 conf-man`"
mandir=`echo "$1/${confman}" | sed 's,//,/,g'`
echo "=== `date` === installing man directory ${mandir}"
mkdir -p "${mandir}" || exit 111
ls "${man}" | sort |\
while read x
do
n=`echo "${x}" | cut -d'.' -f2`
mkdir -p "${mandir}/man${n}" || exit 111
"${installcmd}" "${man}/${x}" "${mandir}/man${n}" "${x}.tmp" "${x}" || exit 111
echo "=== `date` === installing ${man}/${x} -> ${mandir}/man${n}/${x}"
done || exit 111
echo "=== `date` === finishing"
exit 0
tinyssh-20190101/make-tinyssh.sh 0000775 0000000 0000000 00000022202 13412736503 0016427 0 ustar 00root root 0000000 0000000 #!/bin/sh -e
top="`pwd`"
build="`pwd`/build"
bin="${build}/bin"
man="${build}/man"
lib="${build}/lib"
include="${build}/include"
log="${build}/log"
work="${build}/work"
contribdir="`pwd`/build-contrib"
rm -rf "${build}"
mkdir -p "${build}"
mkdir -p "${bin}"
mkdir -p "${man}"
mkdir -p "${lib}"
mkdir -p "${include}"
exec 5>"${log}"
exec 2>&5
exec &5
}
log1() {
echo "=== `date` === $@"
echo "=== `date` === $@" >&5
}
log2() {
echo "=== `date` === $@"
echo "=== `date` === $@" >&5
}
version=`head -1 "${top}/debian/changelog" | cut -d '(' -f2 | cut -d ')' -f1` #XXX
if [ x"${version}" = x ]; then
version=noversion
fi
LANG=C
export LANG
log0 "uname -a: `uname -a || :`"
log0 "uname -F: `uname -F || :`"
log0 "uname -M: `uname -M || :`"
log0 "ulimit -a: `echo; ulimit -a || :`"
log1 "obtaining compiler"
rm -rf "${work}"
mkdir -p "${work}"
(
cd "${work}"
(
if [ x"${CC}" != x ]; then
echo "${CC} "
fi
cat "${top}/conf-cc"
) | while read compiler
do
echo 'int main(void) { return 0; }' > try.c
${compiler} -o try try.c || { log2 "${compiler} failed"; continue; }
log2 "${compiler} ok"
echo "${compiler}" > compiler
break
done
)
compiler=`head -1 "${work}/compiler"`
log1 "finishing"
log1 "checking compiler options"
rm -rf "${work}"
mkdir -p "${work}"
(
cd "${work}"
cflags=`cat "${top}/conf-cflags" || :`
cflags="${CPPFLAGS} ${CFLAGS} ${LDFLAGS} ${cflags}"
for i in ${cflags}; do
echo 'int main(void) { return 0; }' > try.c
${compiler} ${options} "${i}" -o try try.c || { log2 "${i} failed"; continue; }
options="${options} ${i}"
log2 "${i} ok"
done
echo ${options} > options
)
compilerorig=${compiler}
compiler="${compiler} `cat ${work}/options`"
log2 "${compiler}"
log1 "finishing"
log1 "checking libs"
rm -rf "${work}"
mkdir -p "${work}"
(
cd "${work}"
(
cat "${top}/conf-libs" || :
) | (
exec 9>syslibs
while read i; do
echo 'int main(void) { return 0; }' > try.c
${compiler} ${i} -o try try.c || { log2 "${i} failed"; continue; }
echo "${i}" >&9
log2 "${i} ok"
done
)
)
libs=`cat "${work}/syslibs"`
log1 "finishing"
log1 "checking \$LIBS"
if [ x"${LIBS}" != x ]; then
rm -rf "${work}"
mkdir -p "${work}"
(
cd "${work}"
for i in ${LIBS}; do
echo 'int main(void) { return 0; }' > try.c
${compiler} ${i} -o try try.c || { log2 "${i} failed"; continue; }
syslibs="${i} ${syslibs}"
log2 "${i} ok"
done
echo ${syslibs} > syslibs
)
fi
libsorig=${libs}
libs="${libs} `cat ${work}/syslibs`"
log1 "finishing"
log1 "building sysdep headers"
rm -rf "${work}"
mkdir -p "${work}"
cp -pr sysdep/* "${work}"
(
cd "${work}"
sh list | (
while read target source
do
[ -f "${include}/${target}" ] && continue
rm -f "${source}" "${target}.tmp"
${compiler} -O0 -o "${source}" "${source}.c" ${libs} || continue
"./${source}" > "${target}.tmp" 2>/dev/null || continue
if [ -f "${source}.out" ]; then
cp "${source}.out" "${include}/${target}"
else
#runtime
cp "${target}.tmp" "${include}/${target}"
fi
log2 "${target} ${source}"
done
)
)
log1 "finishing"
log1 "starting crypto lib"
rm -rf "${work}"
mkdir -p "${work}"
cp -pr crypto/* "${work}"
(
cd "${work}"
cat CRYPTOSOURCES\
| while read x
do
${compiler} -I"${include}" -c "${x}.c" || { log2 "libtinynacl.a failed ... see the log ${log}"; exit 111; }
done || exit 111
ar cr "${lib}/libtinynacl.a" `cat CRYPTOLIBS` || exit 0
)
log2 "libtinynacl.a ok"
log1 "finishing"
origlibs="${origlibs} ${lib}/libtinynacl.a"
libs="${libs} ${lib}/libtinynacl.a"
log1 "starting crypto headers"
rm -rf "${work}"
mkdir -p "${work}"
cp -p crypto/CRYPTOPRIMITIVES "${work}"
cp -pr crypto-tests/*test.c "${work}"
cp -pr crypto-tests/*.h "${work}"
cp -pr crypto-tests/*.data "${work}" 2>/dev/null || :
(
cd "${work}"
cat CRYPTOPRIMITIVES\
| while read primitive checkflag
do
if [ "x${checkflag}" = x0 ]; then
cp -p "${top}/crypto/${primitive}.h" "${include}"
continue;
fi
testf=`echo "${primitive}" | sed 's/$/test/'`
(
echo '#include '
echo "#include <${primitive}.h>"
echo 'int main(void) {'
echo "#ifdef ${primitive}_PRIMITIVE"
echo "printf(\"%s\\\\n\", ${primitive}_PRIMITIVE);"
echo '#else'
echo "#ifdef ${primitive}_IMPLEMENTATION"
echo "printf(\"%s\\\\n\", ${primitive}_IMPLEMENTATION);"
echo '#endif'
echo "#ifdef ${primitive}_implementation"
echo "printf(\"%s\\\\n\", ${primitive}_implementation);"
echo '#endif'
echo '#endif'
echo 'return 0; }'
) > try.c
#try ext. crypto library
log0 "trying: ext. ${primitive}:"
if ${compiler} -c "${testf}.c" ${libs}; then
if ${compiler} -o "${testf}" "${testf}.o" ${libs}; then
if ${compiler} -o try try.c; then
if /bin/sh -ec "./${testf}"; then
log2 "${primitive}.h (`./try`) ok"
echo "#include <${primitive}.h>" >> crypto.h
continue
else
log2 "${primitive}.h (`./try`) failed"
fi
fi
fi
fi
#try int. crypto library
log0 "trying: int. ${primitive}:"
if cp -p "${top}/crypto/${primitive}.h" . ; then
if ${compilerorig} -I. -I"$include" -o "${testf}" "${testf}.c" ${origlibs}; then
if ${compilerorig} -I. -I"$include" -o try try.c; then
if /bin/sh -ec "./${testf}"; then
log2 "${primitive}.h (`./try`) ok"
echo "#include \"${primitive}.h\"" >> crypto.h
cp -p "${primitive}.h" "${include}"
continue
fi
fi
fi
fi
log2 "${primitive}.h failed ... see the log ${log}"
exit 111
done || exit 111
cp crypto.h "${include}/crypto.h"
)
log1 "finishing"
rm -rf "${work}"
mkdir -p "${work}"
cp -pr tinyssh/* "${work}"
cp -pr tinyssh-tests/*test.c "${work}"
cp -pr tinyssh-tests/*.h "${work}"
cp -pr _tinyssh/* "${work}" 2>/dev/null || :
(
cd "${work}"
log1 "starting tinyssh objects"
touch SOURCES TARGETS _TARGETS
cat SOURCES TARGETS _TARGETS\
| while read x
do
${compiler} "-DCOMPILER=\"${compilerorig}\"" "-DVERSION=\"${version}\"" -I"${include}" -c "${x}.c" || { log2 "${x}.o failed ... see the log ${log}"; exit 111; }
log2 "${x}.o ok"
done || exit 111
ar cr libtinyssh.a `cat LIBS` || exit 111
log1 "finishing"
#tests
log1 "starting tinyssh-tests"
cat LIBS \
| while read x
do
t=`echo ${x} | sed 's/.o$/test/'`
if [ ! -h "${t}.c" ]; then
${compiler} -I"${include}" -c "${t}.c" || { log2 "${t} failed ... see the log ${log}"; exit 111; }
${compiler} -I"${include}" -o "${t}" "${t}.o" libtinyssh.a ${libs} || { log2 "${t} failed ... see the log ${log}"; exit 111; }
"./${t}" || { log2 "${t} failed ... see the log ${log}"; exit 111; }
log2 "${t} ok"
fi
done || exit 111
log1 "finishing"
log1 "starting _tinyssh"
cat _TARGETS \
| while read x
do
${compiler} -I"${include}" -o "${x}" "${x}.o" libtinyssh.a ${libs} || { log2 "${x} failed ... see the log ${log}"; exit 111; }
log2 "${x} ok"
cp -p "${x}" "${bin}/${x}";
done || exit 111
log1 "finishing"
log1 "starting tinyssh"
cat TARGETS \
| while read x
do
${compiler} -I"${include}" -o "${x}" "${x}.o" libtinyssh.a ${libs} || { log2 "${x} failed ... see the log ${log}"; exit 111; }
log2 "${x} ok"
done || exit 111
log1 "finishing"
log1 "starting tinyssh regression tests"
cat TARGETS \
| while read x
do
sh ${x}.rts > ${x}.out
cmp "${x}.out" "${x}.exp" || { log2 "${x} regression test failed ... see the difference `pwd`/${x}.out `pwd`/${x}.exp"; exit 111; }
log2 "${x} ok"
cp -p "${x}" "${bin}/${x}";
done || exit 111
log1 "finishing"
) || exit 111
log1 "starting manpages"
cp -pr man/* "${man}"
log1 "finishing"
log1 "counting words of code - tests"
rm -rf "${work}"
mkdir -p "${work}"
for dir in tinyssh-tests crypto-tests _tinyssh; do
(
touch "${work}/${dir}"
[ -d "${dir}" ] || exit 0
cd "${dir}"
cat *.c *.h > "${work}/${dir}" || :
)
(
cd "${work}"
cat "${dir}" \
| (
cpp -fpreprocessed || gcpp -fpreprocessed
) | (
x=`sed 's/[_a-zA-Z0-9][_a-zA-Z0-9]*/x/g' | tr -d ' \012' | wc -c | tr -d ' '`
log2 "${dir} ${x}"
)
)
done
(
cd "${work}"
cat * \
| (
cpp -fpreprocessed || gcpp -fpreprocessed
) | (
x=`sed 's/[_a-zA-Z0-9][_a-zA-Z0-9]*/x/g' | tr -d ' \012' | wc -c | tr -d ' '`
log2 "$x words of code"
)
)
log1 "finishing"
echo "=== `date` === counting words of code"
rm -rf "${work}"
mkdir -p "${work}"
for dir in sysdep tinyssh crypto; do
(
cd "${dir}"
cat *.c *.h > "${work}/${dir}" || :
)
(
cd "${work}"
cat "${dir}" \
| (
cpp -fpreprocessed || gcpp -fpreprocessed
) | (
x=`sed 's/[_a-zA-Z0-9][_a-zA-Z0-9]*/x/g' | tr -d ' \012' | wc -c | tr -d ' '`
log2 "${dir} ${x}"
)
)
done
(
cd "${work}"
cat * \
| (
cpp -fpreprocessed || gcpp -fpreprocessed
) | (
x=`sed 's/[_a-zA-Z0-9][_a-zA-Z0-9]*/x/g' | tr -d ' \012' | wc -c | tr -d ' '`
log2 "${x} words of code"
)
)
log1 "finishing"
exit 0
tinyssh-20190101/make-tinysshcc.sh 0000775 0000000 0000000 00000011263 13412736503 0016742 0 ustar 00root root 0000000 0000000 #!/bin/sh -e
top="`pwd`"
build="`pwd`/build"
bin="${build}/bin"
man="${build}/man"
lib="${build}/lib"
include="${build}/include"
log="${build}/log"
work="${build}/work"
contribdir="`pwd`/build-contrib"
rm -rf "${build}"
mkdir -p "${build}"
mkdir -p "${bin}"
mkdir -p "${man}"
mkdir -p "${lib}"
mkdir -p "${include}"
exec 5>"${log}"
exec 2>&5
exec &5
}
log1() {
echo "=== `date` === $@"
echo "=== `date` === $@" >&5
}
log2() {
echo "=== `date` === $@"
echo "=== `date` === $@" >&5
}
version=`head -1 "${top}/debian/changelog" | cut -d '(' -f2 | cut -d ')' -f1` #XXX
if [ x"${version}" = x ]; then
version=noversion
fi
LANG=C
export LANG
log0 "uname -a: `uname -a || :`"
log0 "uname -F: `uname -F || :`"
log0 "uname -M: `uname -M || :`"
log1 "obtaining compiler"
rm -rf "${work}"
mkdir -p "${work}"
(
cd "${work}"
(
if [ x"${CC}" != x ]; then
echo "${CC} "
fi
cat "${top}/conf-cc"
) | while read compiler
do
echo 'int main(void) { return 0; }' > try.c
${compiler} -o try try.c || { log2 "${compiler} failed"; continue; }
log2 "${compiler} ok"
echo "${compiler}" > compiler
break
done
)
compiler=`head -1 "${work}/compiler"`
log1 "finishing"
log1 "checking compiler options"
rm -rf "${work}"
mkdir -p "${work}"
(
cd "${work}"
cflags=`cat "${top}/conf-cflags" || :`
cflags="${CPPFLAGS} ${CFLAGS} ${LDFLAGS} ${cflags}"
for i in ${cflags}; do
echo 'int main(void) { return 0; }' > try.c
${compiler} ${options} "${i}" -o try try.c || { log2 "${i} failed"; continue; }
options="${options} ${i}"
log2 "${i} ok"
done
echo ${options} > options
)
compilerorig=${compiler}
compiler="${compiler} `cat ${work}/options`"
log2 "${compiler}"
log1 "finishing"
log1 "checking libs"
rm -rf "${work}"
mkdir -p "${work}"
(
cd "${work}"
(
cat "${top}/conf-libs" || :
) | (
exec 9>syslibs
while read i; do
echo 'int main(void) { return 0; }' > try.c
${compiler} ${i} -o try try.c || { log2 "${i} failed"; continue; }
echo "${i}" >&9
log2 "${i} ok"
done
)
)
libs=`cat "${work}/syslibs"`
log1 "finishing"
log1 "checking \$LIBS"
if [ x"${LIBS}" != x ]; then
rm -rf "${work}"
mkdir -p "${work}"
(
cd "${work}"
for i in ${LIBS}; do
echo 'int main(void) { return 0; }' > try.c
${compiler} ${i} -o try try.c || { log2 "${i} failed"; continue; }
syslibs="${i} ${syslibs}"
log2 "${i} ok"
done
echo ${syslibs} > syslibs
)
fi
libsorig=${libs}
libs="${libs} `cat ${work}/syslibs`"
log1 "finishing"
log1 "building sysdep headers"
rm -rf "${work}"
mkdir -p "${work}"
cp -pr sysdep/* "${work}"
(
cd "${work}"
sh list | (
while read target source
do
[ -f "${include}/${target}" ] && continue
rm -f "${source}" "${target}.tmp"
[ -f "${source}.out" ] || continue
${compiler} -O0 -o "${source}" "${source}.c" ${libs} || continue
cp "${source}.out" "${include}/${target}"
log2 "${target} ${source}"
done
)
)
log1 "finishing"
log1 "starting crypto lib"
rm -rf "${work}"
mkdir -p "${work}"
cp -pr crypto/* "${work}"
(
cd "${work}"
cat CRYPTOSOURCES\
| while read x
do
${compiler} -I"${include}" -c "${x}.c" || { log2 "libtinynacl.a failed ... see the log ${log}"; exit 111; }
done || exit 111
ar cr "${lib}/libtinynacl.a" `cat CRYPTOLIBS` || exit 0
)
log2 "libtinynacl.a ok"
log1 "finishing"
origlibs="${origlibs} ${lib}/libtinynacl.a"
libs="${libs} ${lib}/libtinynacl.a"
log1 "starting crypto headers"
rm -rf "${work}"
mkdir -p "${work}"
cp -p crypto/CRYPTOPRIMITIVES "${work}"
(
cd "${work}"
cat CRYPTOPRIMITIVES\
| while read primitive checkflag
do
if [ "x${checkflag}" != x0 ]; then
echo "#include \"${primitive}.h\"" >> crypto.h
fi
cp -p "${top}/crypto/${primitive}.h" "${include}"
done || exit 111
cp crypto.h "${include}/crypto.h"
)
log1 "finishing"
rm -rf "${work}"
mkdir -p "${work}"
cp -pr tinyssh/* "${work}"
(
cd "${work}"
log1 "starting tinyssh objects"
touch SOURCES TARGETS
cat SOURCES TARGETS\
| while read x
do
${compiler} "-DCOMPILER=\"${compilerorig}\"" "-DVERSION=\"${version}\"" -I"${include}" -c "${x}.c" || { log2 "${x}.o failed ... see the log ${log}"; exit 111; }
log2 "${x}.o ok"
done || exit 111
ar cr libtinyssh.a `cat LIBS` || exit 111
log1 "finishing"
log1 "starting tinyssh"
cat TARGETS \
| while read x
do
${compiler} -I"${include}" -o "${x}" "${x}.o" libtinyssh.a ${libs} || { log2 "${x} failed ... see the log ${log}"; exit 111; }
cp -p "${x}" "${bin}/${x}"
log2 "${x} ok"
done || exit 111
log1 "finishing"
) || exit 111
log1 "starting manpages"
cp -pr man/* "${man}"
log1 "finishing"
exit 0
tinyssh-20190101/man/ 0000775 0000000 0000000 00000000000 13412736503 0014231 5 ustar 00root root 0000000 0000000 tinyssh-20190101/man/tinysshd-makekey.1 0000664 0000000 0000000 00000001063 13412736503 0017604 0 ustar 00root root 0000000 0000000 .TH tinysshd\-makekey 1
.SH NAME
tinysshd\-makekey \- create TinySSH key\-directory
.SH SYNOPSIS
.B tinysshd\-makekey
[ options ]
.I keydir
.SH DESCRIPTION
.B tinysshd\-makekey
safely creates secret\-keys and appropriate public\-keys in directory
.I keydir
.SH OPTIONS
.TP
.B \-q
no error messages
.TP
.B \-Q
print error messages (default)
.TP
.TP
.I keydir
directory for TinySSH keys, typically /etc/tinyssh/sshkeydir
.SH EXAMPLE
tinysshd\-makekey /etc/tinyssh/sshkeydir
.SH SEE ALSO
.BR tinysshd (8),
.BR tinysshd\-printkey (1)
.sp
.nf
https://tinyssh.org/
.fi
tinyssh-20190101/man/tinysshd-printkey.1 0000664 0000000 0000000 00000000701 13412736503 0020021 0 ustar 00root root 0000000 0000000 .TH tinysshd\-printkey 1
.SH NAME
tinysshd\-printkey \- print TinySSH public\-keys
.SH SYNOPSIS
.B tinysshd\-printkey
.I keydir
.SH DESCRIPTION
.B tinysshd\-printkey
prints TinySSH public\-keys in base64 format
.SH OPTIONS
.TP
.I keydir
directory containing TinySSH keys, typically /etc/tinyssh/sshkeydir
.SH EXAMPLE
tinysshd\-printkey /etc/tinyssh/sshkeydir
.SH SEE ALSO
.BR tinysshd (8),
.BR tinysshd\-makekey (1)
.sp
.nf
https://tinyssh.org/
.fi
tinyssh-20190101/man/tinysshd.8 0000664 0000000 0000000 00000005576 13412736503 0016204 0 ustar 00root root 0000000 0000000 .TH tinysshd 8
.SH NAME
tinysshd \- Tiny SSH daemon
.SH SYNOPSIS
.B tinysshd
[ options ]
.I keydir
.SH DESCRIPTION
.B tinysshd
is a minimalistic SSH server which implements only a subset of SSHv2 features.
.sp
.B tinysshd
supports only secure cryptography (minimum 128\-bit security, protected against cache\-timing attacks)
.sp
.B tinysshd
doesn't implement unnecessary features (such as SSH1 protocol, compression, ...)
.sp
.B tinysshd
doesn't implement older crypto (such as RSA, DSA, HMAC\-MD5, HMAC\-SHA1, 3DES, RC4, ...)
.sp
.B tinysshd
doesn't implement unsafe features (such as password or hostbased authentication)
.sp
.B tinysshd
doesn't use dynamic memory allocation (no allocation failures, etc.)
.SH OPTIONS
.TP
.B \-q
no error messages
.TP
.B \-Q
print error messages (default)
.TP
.B \-v
print extra information
.TP
.B \-s
enable state\-of\-the\-art crypto \- ssh\-ed25519, curve25519\-sha256, chacha20\-poly1305@openssh.com (default)
.TP
.B \-S
disable state\-of\-the\-art crypto
.TP
.B \-p
enable post\-quantum crypto \- TODO, sntrup4591761x25519-sha512@tinyssh.org, chacha20\-poly1305@openssh.com (default)
.TP
.B \-P
disable post\-quantum crypto
.TP
.B \-l
use syslog instead of standard error output (useful for running from inetd)
.TP
.B \-L
don't use syslog, use standard error output (default)
.TP
.B \-x \fIname=command
add subsystem command (e.g.: sftp=/usr/libexec/openssh/sftp\-server)
.TP
.I keydir
directory containing TinySSH keys, typically /etc/tinyssh/sshkeydir
.SH AUTHORIZATION
.B tinysshd
supports only public-key authorization via
.B AuthorizedKeysFile
~/.ssh/authorized_keys. Each line of the file contains one key in format "keytype base64-encoded-key comment".
.B tinyssh
supports only "ssh-ed25519" keytype.
.sp
~/.ssh/authorized_keys example:
.nf
.RS 2
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILV5AGhGQ1QVXjBWhTKJP3vrqE3isL4ivisBailQ14gS comment
.RE
.SH RUNNING
.TP
.B TCPSERVER
tcpserver \-HRDl0 0.0.0.0 22 /usr/sbin/tinysshd \-v /etc/tinyssh/sshkeydir &
.TP
.B BUSYBOX
busybox tcpsvd 0 22 tinysshd \-v /etc/tinyssh/sshkeydir &
.TP
.B INETD
.RS 4
/etc/inetd.conf:
.RS 4
ssh stream tcp nowait root /usr/sbin/tinysshd tinysshd \-l \-v /etc/tinyssh/sshkeydir
.RE
.RE
.TP
.B SYSTEMD
.RS 4
tinysshd.socket:
.RS 4
.nf
[Unit]
Description=TinySSH server socket
ConditionPathExists=!/etc/tinyssh/disable_tinysshd
[Socket]
ListenStream=22
Accept=yes
[Install]
WantedBy=sockets.target
.fi
.RE
.RE
.sp
.RS 4
tinysshd@.service:
.RS 4
.nf
[Unit]
Description=Tiny SSH server
After=network.target auditd.service
[Service]
ExecStartPre=\-/usr/sbin/tinysshd\-makekey \-q /etc/tinyssh/sshkeydir
EnvironmentFile=\-/etc/default/tinysshd
ExecStart=/usr/sbin/tinysshd ${TINYSSHDOPTS} \-\- /etc/tinyssh/sshkeydir
KillMode=process
StandardInput=socket
StandardError=journal
[Install]
WantedBy=multi\-user.target
.fi
.RE
.RE
.SH SEE ALSO
.BR tinysshd\-makekey (1),
.BR tinysshd\-printkey (1)
.sp
.nf
https://tinyssh.org/
.fi
tinyssh-20190101/sysdep/ 0000775 0000000 0000000 00000000000 13412736503 0014765 5 ustar 00root root 0000000 0000000 tinyssh-20190101/sysdep/default.h-no.c 0000664 0000000 0000000 00000000066 13412736503 0017417 0 ustar 00root root 0000000 0000000 /* Public domain. */
int main(void) {
return 0;
}
tinyssh-20190101/sysdep/default.h-no.out 0000664 0000000 0000000 00000000000 13412736503 0017770 0 ustar 00root root 0000000 0000000 tinyssh-20190101/sysdep/hasasmvolatilememory.h-yes.c 0000664 0000000 0000000 00000000376 13412736503 0022430 0 ustar 00root root 0000000 0000000 /* Public domain. */
static void foo(void *yv, long long ylen) {
char *y = yv;
while (ylen > 0) { *y++ = 0; --ylen; }
__asm__ __volatile__("" : : "r"(yv) : "memory");
}
int main(void) {
char x[16];
foo(x, sizeof x);
return 0;
}
tinyssh-20190101/sysdep/hasasmvolatilememory.h-yes.out 0000664 0000000 0000000 00000000037 13412736503 0023007 0 ustar 00root root 0000000 0000000 #define HASASMVOLATILEMEMORY 1
tinyssh-20190101/sysdep/haslibutilh.h-yes.c 0000664 0000000 0000000 00000000114 13412736503 0020461 0 ustar 00root root 0000000 0000000 /* Public domain. */
#include
int main(void) {
return 0;
}
tinyssh-20190101/sysdep/haslibutilh.h-yes.out 0000664 0000000 0000000 00000000026 13412736503 0021050 0 ustar 00root root 0000000 0000000 #define HASLIBUTILH 1
tinyssh-20190101/sysdep/haslimits.h-yes.c 0000664 0000000 0000000 00000000113 13412736503 0020145 0 ustar 00root root 0000000 0000000 /* Public domain. */
#include
int main(void) {
return 0;
}
tinyssh-20190101/sysdep/haslimits.h-yes.out 0000664 0000000 0000000 00000000024 13412736503 0020533 0 ustar 00root root 0000000 0000000 #define HASLIMITS 1
tinyssh-20190101/sysdep/haslogintty.h-yes.c 0000664 0000000 0000000 00000000177 13412736503 0020527 0 ustar 00root root 0000000 0000000 /* Public domain. */
extern int login_tty(int);
static void foo(void) {
login_tty(0);
}
int main(void) {
return 0;
}
tinyssh-20190101/sysdep/haslogintty.h-yes.out 0000664 0000000 0000000 00000000026 13412736503 0021105 0 ustar 00root root 0000000 0000000 #define HASLOGINTTY 1
tinyssh-20190101/sysdep/hasmlock.h-yes.c 0000664 0000000 0000000 00000000217 13412736503 0017756 0 ustar 00root root 0000000 0000000 /* Public domain. */
#include
int main(void) {
char x[16];
mlock(x, sizeof x);
munlock(x, sizeof x);
return 0;
}
tinyssh-20190101/sysdep/hasmlock.h-yes.out 0000664 0000000 0000000 00000000023 13412736503 0020336 0 ustar 00root root 0000000 0000000 #define HASMLOCK 1
tinyssh-20190101/sysdep/hasopenpty.h-yes.c 0000664 0000000 0000000 00000000442 13412736503 0020347 0 ustar 00root root 0000000 0000000 /* Public domain. */
#include
#include
#include
extern int openpty(int *, int *, char *, struct termios *, struct winsize *);
static void foo(void) {
int master, slave;
openpty(&master, &slave, 0, 0, 0);
}
int main(void) {
return 0;
}
tinyssh-20190101/sysdep/hasopenpty.h-yes.out 0000664 0000000 0000000 00000000025 13412736503 0020731 0 ustar 00root root 0000000 0000000 #define HASOPENPTY 1
tinyssh-20190101/sysdep/hasutilh.h-yes.c 0000664 0000000 0000000 00000000111 13412736503 0017767 0 ustar 00root root 0000000 0000000 /* Public domain. */
#include
int main(void) {
return 0;
}
tinyssh-20190101/sysdep/hasutilh.h-yes.out 0000664 0000000 0000000 00000000023 13412736503 0020356 0 ustar 00root root 0000000 0000000 #define HASUTILH 1
tinyssh-20190101/sysdep/hasutmp.h-yes.c 0000664 0000000 0000000 00000000214 13412736503 0017633 0 ustar 00root root 0000000 0000000 /* Public domain. */
#include
#include
#include
int main(void) {
struct utmp ut = {0};
return 0;
}
tinyssh-20190101/sysdep/hasutmp.h-yes.out 0000664 0000000 0000000 00000000022 13412736503 0020215 0 ustar 00root root 0000000 0000000 #define HASUTMP 1
tinyssh-20190101/sysdep/hasutmphost.h-yes.c 0000664 0000000 0000000 00000000261 13412736503 0020533 0 ustar 00root root 0000000 0000000 /* Public domain. */
#include
#include
#include
int main(void) {
struct utmp ut;
if (sizeof ut.ut_host < 8) return 111;
return 0;
}
tinyssh-20190101/sysdep/hasutmphost.h-yes.out 0000664 0000000 0000000 00000000026 13412736503 0021117 0 ustar 00root root 0000000 0000000 #define HASUTMPHOST 1
tinyssh-20190101/sysdep/hasutmploginlogout.h-yes.c 0000664 0000000 0000000 00000000430 13412736503 0022116 0 ustar 00root root 0000000 0000000 /* Public domain. */
#include
#include
#include
extern void login(const struct utmp *);
extern int logout(const char *);
static void foo(void) {
struct utmp ut = {0};
login(&ut);
logout(ut.ut_line);
}
int main(void) {
return 0;
}
tinyssh-20190101/sysdep/hasutmploginlogout.h-yes.out 0000664 0000000 0000000 00000000035 13412736503 0022504 0 ustar 00root root 0000000 0000000 #define HASUTMPLOGINLOGOUT 1
tinyssh-20190101/sysdep/hasutmplogwtmp.h-yes.c 0000664 0000000 0000000 00000000253 13412736503 0021250 0 ustar 00root root 0000000 0000000 /* Public domain. */
extern void logwtmp(const char *, const char *, const char *);
static void foo(void) {
logwtmp("", "", "");
}
int main(void) {
return 0;
}
tinyssh-20190101/sysdep/hasutmplogwtmp.h-yes.out 0000664 0000000 0000000 00000000031 13412736503 0021627 0 ustar 00root root 0000000 0000000 #define HASUTMPLOGWTMP 1
tinyssh-20190101/sysdep/hasutmpname.h-yes.c 0000664 0000000 0000000 00000000261 13412736503 0020476 0 ustar 00root root 0000000 0000000 /* Public domain. */
#include
#include
#include
int main(void) {
struct utmp ut;
if (sizeof ut.ut_name < 8) return 111;
return 0;
}
tinyssh-20190101/sysdep/hasutmpname.h-yes.out 0000664 0000000 0000000 00000000026 13412736503 0021062 0 ustar 00root root 0000000 0000000 #define HASUTMPNAME 1
tinyssh-20190101/sysdep/hasutmppid.h-yes.c 0000664 0000000 0000000 00000000224 13412736503 0020331 0 ustar 00root root 0000000 0000000 /* Public domain. */
#include
#include
#include
int main(void) {
struct utmp ut = {0};
return ut.ut_pid;
}
tinyssh-20190101/sysdep/hasutmppid.h-yes.out 0000664 0000000 0000000 00000000025 13412736503 0020715 0 ustar 00root root 0000000 0000000 #define HASUTMPPID 1
tinyssh-20190101/sysdep/hasutmptime.h-yes.c 0000664 0000000 0000000 00000000224 13412736503 0020513 0 ustar 00root root 0000000 0000000 /* Public domain. */
#include
#include
#include
int main(void) {
struct utmp ut = {0};
return ut.ut_time;
}
tinyssh-20190101/sysdep/hasutmptime.h-yes.out 0000664 0000000 0000000 00000000026 13412736503 0021100 0 ustar 00root root 0000000 0000000 #define HASUTMPTIME 1
tinyssh-20190101/sysdep/hasutmptv.h-yes.c 0000664 0000000 0000000 00000000255 13412736503 0020212 0 ustar 00root root 0000000 0000000 /* Public domain. */
#include
#include
#include
int main(void) {
struct utmp ut = {0};
return ut.ut_tv.tv_sec + ut.ut_tv.tv_usec;
}
tinyssh-20190101/sysdep/hasutmptv.h-yes.out 0000664 0000000 0000000 00000000024 13412736503 0020571 0 ustar 00root root 0000000 0000000 #define HASUTMPTV 1
tinyssh-20190101/sysdep/hasutmptype.h-yes.c 0000664 0000000 0000000 00000000264 13412736503 0020542 0 ustar 00root root 0000000 0000000 /* Public domain. */
#include
#include
#include
int main(void) {
struct utmp ut;
ut.ut_type = USER_PROCESS | DEAD_PROCESS;
return 0;
}
tinyssh-20190101/sysdep/hasutmptype.h-yes.out 0000664 0000000 0000000 00000000026 13412736503 0021123 0 ustar 00root root 0000000 0000000 #define HASUTMPTYPE 1
tinyssh-20190101/sysdep/hasutmpuser.h-yes.c 0000664 0000000 0000000 00000000261 13412736503 0020534 0 ustar 00root root 0000000 0000000 /* Public domain. */
#include
#include
#include
int main(void) {
struct utmp ut;
if (sizeof ut.ut_user < 8) return 111;
return 0;
}
tinyssh-20190101/sysdep/hasutmpuser.h-yes.out 0000664 0000000 0000000 00000000026 13412736503 0021120 0 ustar 00root root 0000000 0000000 #define HASUTMPUSER 1
tinyssh-20190101/sysdep/hasutmpx.h-yes.c 0000664 0000000 0000000 00000000407 13412736503 0020027 0 ustar 00root root 0000000 0000000 /* Public domain. */
#include
static void foo(void) {
struct utmpx ut;
ut.ut_type = DEAD_PROCESS;
ut.ut_type = USER_PROCESS;
ut.ut_type = 0;
setutxent();
pututxline(&ut);
endutxent();
}
int main(void) {
return 0;
}
tinyssh-20190101/sysdep/hasutmpx.h-yes.out 0000664 0000000 0000000 00000000023 13412736503 0020406 0 ustar 00root root 0000000 0000000 #define HASUTMPX 1
tinyssh-20190101/sysdep/hasutmpxsyslen.h-yes.c 0000664 0000000 0000000 00000000161 13412736503 0021262 0 ustar 00root root 0000000 0000000 /* Public domain. */
#include
int main(void) {
struct utmpx ut = {0};
return ut.ut_syslen;
}
tinyssh-20190101/sysdep/hasutmpxsyslen.h-yes.out 0000664 0000000 0000000 00000000031 13412736503 0021643 0 ustar 00root root 0000000 0000000 #define HASUTMPXSYSLEN 1
tinyssh-20190101/sysdep/hasutmpxupdwtmpx.h-yes.c 0000664 0000000 0000000 00000000243 13412736503 0021636 0 ustar 00root root 0000000 0000000 /* Public domain. */
#include
static void foo(void) {
struct utmpx ut = {0};
updwtmpx("/nonexistent", &ut);
}
int main(void) {
return 0;
}
tinyssh-20190101/sysdep/hasutmpxupdwtmpx.h-yes.out 0000664 0000000 0000000 00000000033 13412736503 0022220 0 ustar 00root root 0000000 0000000 #define HASUTMPXUPDWTMPX 1
tinyssh-20190101/sysdep/list 0000664 0000000 0000000 00000003073 13412736503 0015666 0 ustar 00root root 0000000 0000000 #!/bin/sh -e
#__asm__ __volatile__ ...
echo 'hasasmvolatilememory.h hasasmvolatilememory.h-yes'
echo 'hasasmvolatilememory.h default.h-no'
#mlock
echo 'hasmlock.h hasmlock.h-yes'
echo 'hasmlock.h default.h-no'
#util/libutil
echo 'haslibutilh.h haslibutilh.h-yes'
echo 'haslibutilh.h default.h-no'
echo 'hasutilh.h hasutilh.h-yes'
echo 'hasutilh.h default.h-no'
#openpty/login_tty
echo 'hasopenpty.h hasopenpty.h-yes'
echo 'hasopenpty.h default.h-no'
echo 'haslogintty.h haslogintty.h-yes'
echo 'haslogintty.h default.h-no'
#utmpx
echo 'hasutmpx.h hasutmpx.h-yes'
echo 'hasutmpx.h default.h-no'
echo 'hasutmpxupdwtmpx.h hasutmpxupdwtmpx.h-yes'
echo 'hasutmpxupdwtmpx.h default.h-no'
echo 'hasutmpxsyslen.h hasutmpxsyslen.h-yes'
echo 'hasutmpxsyslen.h default.h-no'
#utmp
echo 'hasutmp.h hasutmp.h-yes'
echo 'hasutmp.h default.h-no'
echo 'hasutmpname.h hasutmpname.h-yes'
echo 'hasutmpname.h default.h-no'
echo 'hasutmpuser.h hasutmpuser.h-yes'
echo 'hasutmpuser.h default.h-no'
echo 'hasutmphost.h hasutmphost.h-yes'
echo 'hasutmphost.h default.h-no'
echo 'hasutmptime.h hasutmptime.h-yes'
echo 'hasutmptime.h default.h-no'
echo 'hasutmptv.h hasutmptv.h-yes'
echo 'hasutmptv.h default.h-no'
echo 'hasutmppid.h hasutmppid.h-yes'
echo 'hasutmppid.h default.h-no'
echo 'hasutmptype.h hasutmptype.h-yes'
echo 'hasutmptype.h default.h-no'
echo 'hasutmplogwtmp.h hasutmplogwtmp.h-yes'
echo 'hasutmplogwtmp.h default.h-no'
echo 'hasutmploginlogout.h hasutmploginlogout.h-yes'
echo 'hasutmploginlogout.h default.h-no'
#limits
echo 'haslimits.h haslimits.h-yes'
echo 'haslimits.h default.h-no'
tinyssh-20190101/tinyssh-tests/ 0000775 0000000 0000000 00000000000 13412736503 0016317 5 ustar 00root root 0000000 0000000 tinyssh-20190101/tinyssh-tests/blockingtest.c 0000664 0000000 0000000 00000001066 13412736503 0021156 0 ustar 00root root 0000000 0000000 /*
20140302
Jan Mojzis
Public domain.
*/
#include
#include
#include
#include "fail.h"
#include "blocking.h"
int main(void) {
int pi[2];
long long i;
if (pipe(pi) == -1) fail("failure");
for (i = 0; i < 2; ++i) {
if ((fcntl(pi[i], F_GETFL) & O_NONBLOCK) != 0) fail("failure");
blocking_disable(pi[i]);
if ((fcntl(pi[i], F_GETFL) & O_NONBLOCK) == 0) fail("failure");
blocking_enable(pi[i]);
if ((fcntl(pi[i], F_GETFL) & O_NONBLOCK) != 0) fail("failure");
}
_exit(0);
}
tinyssh-20190101/tinyssh-tests/buftest.c 0000664 0000000 0000000 00000050601 13412736503 0020141 0 ustar 00root root 0000000 0000000 /*
20140303
Jan Mojzis
Public domain.
*/
#include
#include
#include
#include
#include "fail.h"
#include "byte.h"
#include "buf.h"
#include "str.h"
#include "crypto_uint32.h"
#include "crypto_uint8.h"
/* XXX */
static int xbuf_putnum8_(const char *fn, unsigned long long line,
struct buf *b, long long uu) {
crypto_uint8 u = uu;
return buf_putnum8_(fn, line, b, u);
}
static int xbuf_putnum32_(const char *fn, unsigned long long line,
struct buf *b, long long uu) {
crypto_uint32 u = uu;
return buf_putnum32_(fn, line, b, u);
}
struct vectors1 {
int (*op)(const char *, unsigned long long, struct buf *, long long);
long long spacelen;
long long xlen;
} testvectors1[] = {
{ buf_putzerobytes_, 5, 4 },
{ buf_putrandombytes_, 5, 4 },
{ buf_putpadding_, 5, 4 },
{ xbuf_putnum32_, 5, 0 },
{ xbuf_putnum8_, 2, 0 },
{ 0, 0, 0 }
};
struct vectors2 {
int (*op)(const char *, unsigned long long, struct buf *, const unsigned char *, long long);
long long spacelen;
const unsigned char *x;
long long xlen;
} testvectors2[] = {
{ buf_put_, 1, (unsigned char *)"", 0 },
{ buf_put_, 5, (unsigned char *)"ahoj", 4 },
{ buf_putstringlen_, 5, (unsigned char *)"", 0 },
{ buf_putstringlen_, 9, (unsigned char *)"ahoj", 4 },
{ 0, 0, 0, 0 }
};
struct vectors3 {
int (*op)(const char *, unsigned long long, struct buf *, const char *);
long long spacelen;
const char *x;
} testvectors3[] = {
{ buf_puts_, 1, "" },
{ buf_puts_, 5, "ahoj" },
{ buf_putstring_, 5, "" },
{ buf_putstring_, 9, "ahoj" },
{ 0, 0, 0 }
};
static int _test1a1(long long spacelen, int (*op)(const char *, unsigned long long, struct buf *, long long), long long xlen) {
pid_t pid;
int status;
unsigned char bspace[10];
struct buf b;
pid = fork();
if (pid == -1) return -1;
if (pid == 0) {
close(2);
buf_init(&b, bspace, spacelen);
op(__FILE__, __LINE__, &b, xlen);
buf_put(&b, (unsigned char *)"", 1); /* overflow */
_exit(0);
}
while (waitpid(pid, &status, 0) != pid) {};
if (!WIFEXITED(status)) return -1;
return WEXITSTATUS(status);
}
static int _test1a2(long long spacelen, int (*op)(const char *, unsigned long long, struct buf *, const unsigned char *, long long), const unsigned char *x, long long xlen) {
pid_t pid;
int status;
unsigned char bspace[10];
struct buf b;
pid = fork();
if (pid == -1) return -1;
if (pid == 0) {
close(2);
buf_init(&b, bspace, spacelen);
op(__FILE__, __LINE__, &b, x, xlen);
buf_put(&b, (unsigned char *)"", 1); /* overflow */
_exit(0);
}
while (waitpid(pid, &status, 0) != pid) {};
if (!WIFEXITED(status)) return -1;
return WEXITSTATUS(status);
}
static int _test1a3(long long spacelen, int (*op)(const char *, unsigned long long, struct buf *, const char *), const char *x) {
pid_t pid;
int status;
unsigned char bspace[10];
struct buf b;
pid = fork();
if (pid == -1) return -1;
if (pid == 0) {
close(2);
buf_init(&b, bspace, spacelen);
op(__FILE__, __LINE__, &b, x);
buf_put(&b, (unsigned char *)"", 1); /* overflow */
_exit(0);
}
while (waitpid(pid, &status, 0) != pid) {};
if (!WIFEXITED(status)) return -1;
return WEXITSTATUS(status);
}
static void _test1b1(long long spacelen, int (*op)(const char *, unsigned long long, struct buf *, long long), long long xlen) {
unsigned char bspace[10];
struct buf b;
buf_init(&b, bspace, spacelen);
op(__FILE__, __LINE__, &b, xlen);
}
static void _test1b2(long long spacelen, int (*op)(const char *, unsigned long long, struct buf *, const unsigned char *, long long), const unsigned char *x, long long xlen) {
unsigned char bspace[10];
struct buf b;
buf_init(&b, bspace, spacelen);
op(__FILE__, __LINE__, &b, x, xlen);
}
static void _test1b3(long long spacelen, int (*op)(const char *, unsigned long long, struct buf *, const char *), const char *x) {
unsigned char bspace[10];
struct buf b;
buf_init(&b, bspace, spacelen);
op(__FILE__, __LINE__, &b, x);
}
static void test1(void) {
long long i;
int r;
for (i = 0; testvectors1[i].op; ++i) {
r = _test1a1(testvectors1[i].spacelen, testvectors1[i].op, testvectors1[i].xlen);
if (r == 0) fail("failure");
_test1b1(testvectors1[i].spacelen, testvectors1[i].op, testvectors1[i].xlen);
}
for (i = 0; testvectors2[i].op; ++i) {
r = _test1a2(testvectors2[i].spacelen, testvectors2[i].op, testvectors2[i].x, testvectors2[i].xlen);
if (r == 0) fail("failure");
_test1b2(testvectors2[i].spacelen, testvectors2[i].op, testvectors2[i].x, testvectors2[i].xlen);
}
for (i = 0; testvectors3[i].op; ++i) {
r = _test1a3(testvectors3[i].spacelen, testvectors3[i].op, testvectors3[i].x);
if (r == 0) fail("failure");
_test1b3(testvectors3[i].spacelen, testvectors3[i].op, testvectors3[i].x);
}
}
static void test2(void) {
unsigned char bspace[2];
struct buf b;
unsigned char ch = 0;
long long i;
buf_init(&b, bspace, sizeof bspace);
for (i = 0; i < 10; ++i) {
buf_put(&b, &ch, 1);
buf_purge(&b);
}
}
struct vectors64 {
const char *in;
long long inlen;
const char *out;
} testvectors64[] = {
{ "\107\303\221\307\306\077\106\014\235\115\356\215\375", 13, "R8ORx8Y/RgydTe6N/Q==" },
{ "\133\253\044\246\070\374", 6, "W6skpjj8" },
{ "\253\374\323\142\326", 5, "q/zTYtY=" },
{ "\335\251\125\150\245\321\040\143\174\152", 10, "3alVaKXRIGN8ag==" },
{ "\155\065\344\122\353", 5, "bTXkUus=" },
{ "\266\071\073\373\072\035\270\151\201", 9, "tjk7+zoduGmB" },
{ "\302\373\135\206\370\012\365", 7, "wvtdhvgK9Q==" },
{ "\071\203", 2, "OYM=" },
{ "\210\236\076\336\014\122\125\050\016\076\063", 11, "iJ4+3gxSVSgOPjM=" },
{ "\241\330\251\122\325\061\142\167\174\315\201\000\275\157\056", 15, "odipUtUxYnd8zYEAvW8u" },
{ "\334\306\014\014\021\323\000\120\347\363\335", 11, "3MYMDBHTAFDn890=" },
{ "\356\243\102\105\343\146\154\064\006\316\360\301\256\164", 14, "7qNCReNmbDQGzvDBrnQ=" },
{ "\250\211\165\344\276\224\031\205\162\315", 10, "qIl15L6UGYVyzQ==" },
{ "\356\104\051\125\022\121\070\074\332\301\014\377\303\254\140", 15, "7kQpVRJRODzawQz/w6xg" },
{ "\065\340\116\113\133\334\100", 7, "NeBOS1vcQA==" },
{ "\151\340\101\120\376", 5, "aeBBUP4=" },
{ "\345", 1, "5Q==" },
{ "\010\134", 2, "CFw=" },
{ "\221\044\355\143\047\351\127\165\314\370\017\347\365", 13, "kSTtYyfpV3XM+A/n9Q==" },
{ "\222\237\301\021\214\011\002\367", 8, "kp/BEYwJAvc=" },
{ "\235\245\251\304\303\232\223\046\063\062\252\366", 12, "naWpxMOakyYzMqr2" },
{ "\215\267\333\017\237\313\210\114\067\164\067\337\024\211\174", 15, "jbfbD5/LiEw3dDffFIl8" },
{ "\344\122\212\142\231\251\146\253", 8, "5FKKYpmpZqs=" },
{ "\147\105", 2, "Z0U=" },
{ "\013\235\177\100\212\167\123\172\201", 9, "C51/QIp3U3qB" },
{ "\102\136\120\260\230\125\046\253\323\305\044", 11, "Ql5QsJhVJqvTxSQ=" },
{ "\101\152\200\060\134\014\124\202\023\057\250\115\341", 13, "QWqAMFwMVIITL6hN4Q==" },
{ "\012\310\224\166\265\072\072\270\052\262\147\145\022", 13, "CsiUdrU6OrgqsmdlEg==" },
{ "\021\131\104\067\051\316", 6, "EVlENynO" },
{ "\104\323", 2, "RNM=" },
{ "\070\274\150\150\014\077", 6, "OLxoaAw/" },
{ "\100\132\201\357\023\222\243\301\357", 9, "QFqB7xOSo8Hv" },
{ "\225\244", 2, "laQ=" },
{ "\212\270\067\052\145\203", 6, "irg3KmWD" },
{ "\363\252\326\213\370\065\072\154\077\335\202\242\236\274", 14, "86rWi/g1Omw/3YKinrw=" },
{ "\141\041\315\033", 4, "YSHNGw==" },
{ "\216\257\025\305\362\044\264\133", 8, "jq8VxfIktFs=" },
{ "\342\377\135\236", 4, "4v9dng==" },
{ "\121\100\077\162\374\162\274\121\100", 9, "UUA/cvxyvFFA" },
{ "\204", 1, "hA==" },
{ "\306\345\332\023\241\273\064\227\020\326\102\123\003", 13, "xuXaE6G7NJcQ1kJTAw==" },
{ "\227\142\207\137\322\344\074\317\007\245\120", 11, "l2KHX9LkPM8HpVA=" },
{ "\267\051\051", 3, "tykp" },
{ "\005\244", 2, "BaQ=" },
{ "\215\060\165\046\210", 5, "jTB1Jog=" },
{ "\100\376\271\317\250\013\264\360\330\012\325\103", 12, "QP65z6gLtPDYCtVD" },
{ "\233\340\212\127\160\167\077", 7, "m+CKV3B3Pw==" },
{ "\200\041\036\206\273\067", 6, "gCEehrs3" },
{ "\207\067\003\324\025\351\033\223\226\300\002\255\167\342\316", 15, "hzcD1BXpG5OWwAKtd+LO" },
{ "\263\364\115\054\347\350", 6, "s/RNLOfo" },
{ "\211\252\065\167\224", 5, "iao1d5Q=" },
{ "\024\327\120\076\031\035\104\003\247", 9, "FNdQPhkdRAOn" },
{ "\143\302\131\030\204\134\036\023\305\203\010\236\204\303", 14, "Y8JZGIRcHhPFgwiehMM=" },
{ "\124\225\066\007", 4, "VJU2Bw==" },
{ "\173\043\162\031\330\351", 6, "eyNyGdjp" },
{ "\323\112\227\176\021\120\311\202\035\041\153\326\137", 13, "00qXfhFQyYIdIWvWXw==" },
{ "\235\006\017\301\200\121\013\230\373\264\215\256\322\126\111", 15, "nQYPwYBRC5j7tI2u0lZJ" },
{ "\317\113\144\056\014\120\246\143\325\272", 10, "z0tkLgxQpmPVug==" },
{ "\106\136\226\023\146\054\366\070\007\270\345\321\245\304\177\147", 16, "Rl6WE2Ys9jgHuOXRpcR/Zw==" },
{ "\042\163\374\234\332\173\055\166", 8, "InP8nNp7LXY=" },
{ "\375\011\321\370\300", 5, "/QnR+MA=" },
{ "\034", 1, "HA==" },
{ "\350", 1, "6A==" },
{ "\147\136\210\264\353\267\311\341\073\110\270\071\033", 13, "Z16ItOu3yeE7SLg5Gw==" },
{ "\133\341\131\206\211\171", 6, "W+FZhol5" },
{ "\146\176\236\340\264\370\270\313\261\304\217", 11, "Zn6e4LT4uMuxxI8=" },
{ "\347\111\263\244\131\103\022\272\163\100\337\324\340\247\006", 15, "50mzpFlDErpzQN/U4KcG" },
{ "\132\167\314\125\023\172\223\140\264\146\167\156\245", 13, "WnfMVRN6k2C0ZndupQ==" },
{ "\206", 1, "hg==" },
{ "\000\346\367\051\051\116", 6, "AOb3KSlO" },
{ "\253\117\134\331", 4, "q09c2Q==" },
{ "\267\130\307\170", 4, "t1jHeA==" },
{ "\252\367\311\250\126\031\001\065\107", 9, "qvfJqFYZATVH" },
{ "\204\011\351\022\206\076\056\334\100", 9, "hAnpEoY+LtxA" },
{ "\004\302\141\333\230\255\215", 7, "BMJh25itjQ==" },
{ "\052\357\233\266\237\017\260\101\000", 9, "Ku+btp8PsEEA" },
{ "\302\024\373\144\071\312\012\044\304\340\026\222\066\216", 14, "whT7ZDnKCiTE4BaSNo4=" },
{ "\342\054\344\331\312\200\052", 7, "4izk2cqAKg==" },
{ "\156\234\310\023\077\041\310\005\137\175\034\307\247", 13, "bpzIEz8hyAVffRzHpw==" },
{ "\051\316\243\225\076\257", 6, "Kc6jlT6v" },
{ "\275\263\026\127\315\140\172\110\002\365\067\061\270\331", 14, "vbMWV81gekgC9TcxuNk=" },
{ "\240\021", 2, "oBE=" },
{ "\125\161\171\026\354", 5, "VXF5Fuw=" },
{ "\052\131", 2, "Klk=" },
{ "\335\234\230\006\054\265\273\124\147\131\015\054\036\335\353", 15, "3ZyYBiy1u1RnWQ0sHt3r" },
{ "\073\126\160\312\341\345\234\353\264\245\115\220\316\063\102", 15, "O1ZwyuHlnOu0pU2QzjNC" },
{ "\200\070\242\226\226\027\147", 7, "gDiilpYXZw==" },
{ "\132\111\013\325\224\115\107\236\124\310\144\262\156\001\004\227", 16, "WkkL1ZRNR55UyGSybgEElw==" },
{ "\340\357\121\156\255\173\153\221\125\024", 10, "4O9Rbq17a5FVFA==" },
{ "\060\037\251\063\073\022\206\033", 8, "MB+pMzsShhs=" },
{ "\355\241", 2, "7aE=" },
{ "\144\033\132\321\153\017\244\145\211\027\313\067\166\167\104", 15, "ZBta0WsPpGWJF8s3dndE" },
{ "\073\227\264\070\151\002", 6, "O5e0OGkC" },
{ "\201\364\206\002\033\125\075\110\036\152\347\011\146\077\023\354", 16, "gfSGAhtVPUgeaucJZj8T7A==" },
{ "\232\205\305\006\214\266\355\107\007\314\223\254\142\055\045\260", 16, "moXFBoy27UcHzJOsYi0lsA==" },
{ "\053\221\122\341\163", 5, "K5FS4XM=" },
{ "\245\113\335\066\012\245\334\335\006\350\373\254\121\346", 14, "pUvdNgql3N0G6PusUeY=" },
{ "\250\126\360\135\053\301\342\200", 8, "qFbwXSvB4oA=" },
{ "\154\323\054\236\175\252\270\270\220", 9, "bNMsnn2quLiQ" },
{ "\322\260\320\175\263", 5, "0rDQfbM=" },
{ "\136\073\307\102\376\033\002\243", 8, "XjvHQv4bAqM=" },
{ "\361\323\236", 3, "8dOe" },
{ "\143\007\375\015", 4, "Ywf9DQ==" },
{ "\122\240\036\350\132\212\037\134\114", 9, "UqAe6FqKH1xM" },
{ "\213\004\377\313\312\314\144\350\055\147\062\064\270\273\150\221", 16, "iwT/y8rMZOgtZzI0uLtokQ==" },
{ "\246\346\106\301\277\300\100", 7, "puZGwb/AQA==" },
{ "\176\034\360\143\160\016\072\017\322", 9, "fhzwY3AOOg/S" },
{ "\046\335\103\356\145\364\266\165\356\146", 10, "Jt1D7mX0tnXuZg==" },
{ "\147\231\300\372\053\373\375\363\257\071", 10, "Z5nA+iv7/fOvOQ==" },
{ "\241", 1, "oQ==" },
{ "\044\231\150\021\346\347", 6, "JJloEebn" },
{ "\026\361\151\071\101", 5, "FvFpOUE=" },
{ "\274\021\324\260\123\343", 6, "vBHUsFPj" },
{ "\255\312", 2, "rco=" },
{ "\012\362\172\166", 4, "CvJ6dg==" },
{ "\223\117\213\351\120\321", 6, "k0+L6VDR" },
{ "\314\150\017\355\321\372", 6, "zGgP7dH6" },
{ "\262\152\141\170\227\353\363\162\116\327\247\342\302\326\255\245", 16, "smpheJfr83JO16fiwtatpQ==" },
{ "\276\336\043\244\015\360\114\273\113", 9, "vt4jpA3wTLtL" },
{ "\307\075\305\152\226\265\045\170", 8, "xz3Fapa1JXg=" },
{ "\342\210\307\244\132\345", 6, "4ojHpFrl" },
{ "\370\125\040\013\267\004\057\371\155\321\107\174\241\041", 14, "+FUgC7cEL/lt0Ud8oSE=" },
{ "\327\111\202\040\314\147\164\116\217\217\220", 11, "10mCIMxndE6Pj5A=" },
{ "\176", 1, "fg==" },
{ "\107\326\002\256\146\112\137\304\013\020\020\163\264\213\145\141", 16, "R9YCrmZKX8QLEBBztItlYQ==" },
{ "\216", 1, "jg==" },
{ "\327\246\371\266\023", 5, "16b5thM=" },
{ "\027\352\164\125\266\241\266\272", 8, "F+p0Vbahtro=" },
{ "\001\135\250\345", 4, "AV2o5Q==" },
{ "\237\302\312\152\355\022\161\240\000\151\330", 11, "n8LKau0ScaAAadg=" },
{ "\343\144\171\236\255\261\275\315\300\026\346", 11, "42R5nq2xvc3AFuY=" },
{ "\371\206\264\033\200\232\373\003\237\061\120\051\353", 13, "+Ya0G4Ca+wOfMVAp6w==" },
{ "\315\220\061\106", 4, "zZAxRg==" },
{ "\007", 1, "Bw==" },
{ "\125\217\033\216\066\340\143\254\133\004\165\110\143\117\146", 15, "VY8bjjbgY6xbBHVIY09m" },
{ "\050\073\200\116\346\355\073\205\061\266\161\033\125\301", 14, "KDuATubtO4UxtnEbVcE=" },
{ "\233\140\272\145\333", 5, "m2C6Zds=" },
{ "\045\256\173\034\034\373\051\205\041\016\070\212\023\073\204\267", 16, "Ja57HBz7KYUhDjiKEzuEtw==" },
{ "\342\254\000\251\017\204\350\152\211\106\116\323\146\262\067\031", 16, "4qwAqQ+E6GqJRk7TZrI3GQ==" },
{ "\100\246\015\313\000\366\205\367\273\053", 10, "QKYNywD2hfe7Kw==" },
{ "\353\127\334\173\217\266\372\214\374", 9, "61fce4+2+oz8" },
{ "\144\243\162\123\006\211\035\337\342\174\071\157\244\316\063\154", 16, "ZKNyUwaJHd/ifDlvpM4zbA==" },
{ "\013\371\150\050", 4, "C/loKA==" },
{ "\340\214\237\210\113\145\007\077\136\351", 10, "4IyfiEtlBz9e6Q==" },
{ "\336\055\356\341\212\040", 6, "3i3u4Yog" },
{ "\354\316\211\157\113\304\374\267\010\137\264\043\220\306\210\125", 16, "7M6Jb0vE/LcIX7QjkMaIVQ==" },
{ "\355\116\363\331\314\366\005\230\253\137", 10, "7U7z2cz2BZirXw==" },
{ "\017\353\200\145\335\054\106\231", 8, "D+uAZd0sRpk=" },
{ "\017\146\253\337\150\156\326\076\105\040\026\154\133", 13, "D2ar32hu1j5FIBZsWw==" },
{ "\072", 1, "Og==" },
{ "\163\107\062\261\176\103\261\267\031\214\346\350\124\101\257", 15, "c0cysX5DsbcZjOboVEGv" },
{ "\333\005\104\376\205\323\203", 7, "2wVE/oXTgw==" },
{ "\072", 1, "Og==" },
{ "\246\270\237\262\261\252\220\273", 8, "prifsrGqkLs=" },
{ "\076\140", 2, "PmA=" },
{ "\343\043\335\346\134\003\240\244\067\271\105\311", 12, "4yPd5lwDoKQ3uUXJ" },
{ "\327\375\152\126", 4, "1/1qVg==" },
{ "\103\231\176\252\263\126\047\356\370\266\027\072\003\162", 14, "Q5l+qrNWJ+74thc6A3I=" },
{ "\373\321", 2, "+9E=" },
{ "\127\052\054\340\245\243\261", 7, "Vyos4KWjsQ==" },
{ "\027\236\317\116\373\155\111\057\026\371\247\227\055\242", 14, "F57PTvttSS8W+aeXLaI=" },
{ "\175\166\256\272\045\302\221\306\237\151\116\031\223\233", 14, "fXauuiXCkcafaU4Zk5s=" },
{ "\140\241", 2, "YKE=" },
{ "\064\332\317\246\113\370\276\341\302", 9, "NNrPpkv4vuHC" },
{ "\245\306\176\341\217\000\073\265\237\124", 10, "pcZ+4Y8AO7WfVA==" },
{ "\026\173\274\034\340\061\376\246\233\375\326\250\164\313\304\353", 16, "Fnu8HOAx/qab/daodMvE6w==" },
{ "\277\034", 2, "vxw=" },
{ "\215\120\005\160\173\000\153\373\026\123\045\074\142\337", 14, "jVAFcHsAa/sWUyU8Yt8=" },
{ "\221\122\070\352\346\035\227\270\342\066\237\170\266", 13, "kVI46uYdl7jiNp94tg==" },
{ "\274\270", 2, "vLg=" },
{ "\341\155\367\111\106\042\036\112\242\262\004\354\131\153", 14, "4W33SUYiHkqisgTsWWs=" },
{ "\254\103\176\060", 4, "rEN+MA==" },
{ "\277\305\046\061\037\111\121\315", 8, "v8UmMR9JUc0=" },
{ "\220\155\334\167\323\340\065\301\101\014\101\277", 12, "kG3cd9PgNcFBDEG/" },
{ "\117", 1, "Tw==" },
{ "\152\165\104\351\003\100\006\311\061\045", 10, "anVE6QNABskxJQ==" },
{ "\171\020\056\304\213", 5, "eRAuxIs=" },
{ "\263\317\223\332\321\036\203\241\016\355\173\163\060\121", 14, "s8+T2tEeg6EO7XtzMFE=" },
{ "\051\046\035\170\002", 5, "KSYdeAI=" },
{ "\214\324\001\125\062\247\010\122\147\376\021\031", 12, "jNQBVTKnCFJn/hEZ" },
{ "\035\126\117\235\225\176\135\370\347", 9, "HVZPnZV+Xfjn" },
{ "\334", 1, "3A==" },
{ "\203\117\166\021\144\257", 6, "g092EWSv" },
{ "\262\155", 2, "sm0=" },
{ "\241\242\031\110\014\223\340\175\311", 9, "oaIZSAyT4H3J" },
{ "\074\373\225\217\164\140\125\353\300\256\146\202\301\133", 14, "PPuVj3RgVevArmaCwVs=" },
{ "\336\354\143\220\367\007\342\114\007\040\331\362\245", 13, "3uxjkPcH4kwHINnypQ==" },
{ "\144\107\331\316\274\005\264", 7, "ZEfZzrwFtA==" },
{ "\027\371\125\116\174\275\160\220\306\266", 10, "F/lVTny9cJDGtg==" },
{ "\155\315\167\325\171\213\242\064\211\122\217\335\250\154", 14, "bc131XmLojSJUo/dqGw=" },
{ "\126\075\332\131\265\225\065\337\130\133\314\337", 12, "Vj3aWbWVNd9YW8zf" },
{ "\051\032\131\176\353\047\001\037\304\170\136\155\222\344", 14, "KRpZfusnAR/EeF5tkuQ=" },
{ "\323\011\213\013\160\037\274\235\026\155\352\234", 12, "0wmLC3AfvJ0Wbeqc" },
{ "\174\260\057\114\125\272\330\213\141\034\130\277", 12, "fLAvTFW62IthHFi/" },
{ "\234\376\012\217\376\061\152\202\177", 9, "nP4Kj/4xaoJ/" },
{ "\162\267\211\246\213\237\325\136\140\143\173", 11, "creJpouf1V5gY3s=" },
{ "\224\317\166\131\020\266\045", 7, "lM92WRC2JQ==" },
{ "\075\002\145\273\112\375\070\101\311\125\337\070\003\336\363", 15, "PQJlu0r9OEHJVd84A97z" },
{ "\177\105\134\344\106\350\034\205", 8, "f0Vc5EboHIU=" },
{ "\130\336\125\300\053\331\050", 7, "WN5VwCvZKA==" },
{ 0, 0, 0 }
};
static void test3(void) {
unsigned char bspace[100];
struct buf b;
long long i, outlen;
buf_init(&b, bspace, sizeof bspace);
for (i = 0; testvectors64[i].in; ++i) {
buf_purge(&b);
outlen = str_len(testvectors64[i].out);
buf_putbase64(&b, (unsigned char *)testvectors64[i].in, testvectors64[i].inlen);
if (b.len != outlen || !byte_isequal(b.buf, outlen, testvectors64[i].out)) {
fail("buf_putbase64 failed");
}
}
}
static void test4(void) {
unsigned char bspace[2];
struct buf b;
buf_init(&b, bspace, 1);
if (buf_ready(&b, 1)) fail("buf_ready failed");
buf_init(&b, bspace, 2);
if (!buf_ready(&b, 1)) fail("buf_ready failed");
}
struct vectorssh {
const char *in;
long long inlen;
const char *out;
long long outlen;
} testvectorssh[] = {
{ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 32, "\0\0\0\0" , 4},
{ "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1", 32, "\0\0\0\040\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1" , 36},
{ "\377\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1", 32, "\0\0\0\041\0\377\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1" , 37},
{ 0, 0, 0, 0},
};
static unsigned char bspacesh[64];
static struct buf b;
static void test5(void) {
long long i;
buf_init(&b, bspacesh, sizeof bspacesh);
for (i = 0; testvectorssh[i].in; ++i) {
buf_purge(&b);
buf_putsharedsecret(&b, (unsigned char *)testvectorssh[i].in, testvectorssh[i].inlen);
if (b.len != testvectorssh[i].outlen || !byte_isequal(b.buf, b.len, testvectorssh[i].out)) {
fail("buf_putbasesharedsecret failed");
}
}
}
int main(void) {
test1();
test2();
test3();
test4();
test5();
_exit(0);
}
tinyssh-20190101/tinyssh-tests/bytetest.c 0000664 0000000 0000000 00000003407 13412736503 0020332 0 ustar 00root root 0000000 0000000 /*
20140302
Jan Mojzis
Public domain.
*/
/*
XXX TODO
- check if byte_isequal is constant-time
*/
#include
#include "fail.h"
#include "byte.h"
int main(void) {
unsigned char b1[32];
unsigned char b2[32];
long long i, j;
const char *x = "abcdefgh";
char y[8];
/* byte_zero test */
for (i = 0; i < 32; ++i) {
for (j = 0; j < sizeof b1; ++j) b1[j] = 0;
for (j = 0; j < sizeof b2; ++j) b2[j] = 0;
b1[i] = 0xff; b2[i] = 0xff;
byte_zero(b1, sizeof b1);
if (byte_isequal(b1, 32, b2) != 0) fail("byte_zero failure");
}
/* byte_isequal test */
for (i = 0; i < sizeof b1; ++i) b1[i] = 0xff;
for (i = 0; i < sizeof b2; ++i) b2[i] = 0xff;
if (byte_isequal(b1, 32, b2) == 0) fail("byte_isequal failure");
for (i = 0; i < 32; ++i) {
b1[i] = 0;
if (byte_isequal(b1, 32, b2) != 0) fail("byte_isequal failure");
b1[i] = 0xff;
}
/* byte_copy test */
for (i = 0; i < sizeof b1; ++i) b1[i] = 0xff;
for (i = 0; i < sizeof b2; ++i) b2[i] = 0x00;
byte_copy(b1, 32, b2);
if (byte_isequal(b1, 32, b2) == 0) fail("byte_copy failure");
for (i = 0; i < 32; ++i) {
b1[i] = 0;
byte_copy(b1, 32, b2);
if (byte_isequal(b1, 32, b2) == 0) fail("byte_copy failure");
b1[i] = 0xff;
}
byte_zero(y, 8);
if (!byte_isequal(y, 8, "\0\0\0\0\0\0\0\0")) fail("byte_zero/byte_isequal failure");
byte_copy(y, 8, x);
if (!byte_isequal(y, 8, x)) fail("byte_copy/byte_isequal failure");
byte_copy(y, 7, y + 1);
if (!byte_isequal(y, 8, "bcdefghh")) fail("byte_copy/byte_isequal failure");
byte_zero(y, 8);
if (!byte_isequal(y, 8, "\0\0\0\0\0\0\0\0")) fail("byte_zero/byte_isequal failure");
return 0;
}
tinyssh-20190101/tinyssh-tests/channel_droptest.c 0000777 0000000 0000000 00000000000 13412736503 0024214 2emptytest.c ustar 00root root 0000000 0000000 tinyssh-20190101/tinyssh-tests/channel_forkptytest.c 0000777 0000000 0000000 00000000000 13412736503 0024746 2emptytest.c ustar 00root root 0000000 0000000 tinyssh-20190101/tinyssh-tests/channel_forktest.c 0000664 0000000 0000000 00000004105 13412736503 0022014 0 ustar 00root root 0000000 0000000 /*
20140416
Jan Mojzis
Public domain.
*/
#include
#include
#include
#include
#include
#include "fail.h"
#include "writeall.h"
#include "readall.h"
#include "byte.h"
#include "channel.h"
/* test if channel_fork pipes works from child to parent */
static void test1(void) {
int fd[3];
pid_t pid;
int status;
char buf[5];
pid = channel_fork(fd);
if (pid == -1) fail("channel_fork failure");
if (pid == 0) {
if (writeall(1, "ahoj1", 5) == -1) fail("writeall failure");
if (writeall(2, "ahoj2", 5) == -1) fail("writeall failure");
_exit(0);
}
if (fd[0] == -1) fail("channel_fork failure");
if (fd[1] == -1) fail("channel_fork failure");
if (fd[2] == -1) fail("channel_fork failure");
if (readall(fd[1], buf, 5) == -1) fail("readall failure");
if (!byte_isequal(buf, 5, "ahoj1")) fail("readall failure");
if (readall(fd[2], buf, 5) == -1) fail("readall failure");
if (!byte_isequal(buf, 5, "ahoj2")) fail("readall failure");
while (waitpid(pid, &status, 0) != pid) {};
if (!WIFEXITED(status)) fail("process killed");
if (WEXITSTATUS(status)) fail("process exited with status != 0");
}
/* test if channel_fork pipes works from parent to child */
static void test2(void) {
int fd[3];
pid_t pid;
int status;
char buf[5];
pid = channel_fork(fd);
if (pid == -1) fail("channel_fork failure");
if (pid == 0) {
if (readall(0, buf, 5) == -1) fail("readall failure");
if (!byte_isequal(buf, 5, "ahoj0")) fail("readall failure");
_exit(0);
}
if (fd[0] == -1) fail("channel_fork failure");
if (fd[1] == -1) fail("channel_fork failure");
if (fd[2] == -1) fail("channel_fork failure");
if (writeall(fd[0], "ahoj0", 5) == -1) fail("writeall failure");
while (waitpid(pid, &status, 0) != pid) {};
if (!WIFEXITED(status)) fail("process killed");
if (WEXITSTATUS(status)) fail("process exited with status != 0");
}
int main(void) {
alarm(10);
test1();
test2();
_exit(0);
}
tinyssh-20190101/tinyssh-tests/channel_subsystemtest.c 0000664 0000000 0000000 00000003463 13412736503 0023117 0 ustar 00root root 0000000 0000000 /*
20150113
Jan Mojzis
Public domain.
*/
#include
#include "fail.h"
#include "numtostr.h"
#include "channel.h"
const char *vector[] = {
"0=0",
"1=1",
"2=2",
"3=3",
"4=4",
"5=5",
"6=6",
"7=7",
"8=8",
"9=9",
"10=10",
"11=11",
"12=12",
"13=13",
"14=14",
"15=15",
"16=16",
"17=17",
"18=18",
"19=19",
"20=20",
"21=21",
"22=22",
"23=23",
"24=24",
"25=25",
"26=26",
"27=27",
"28=28",
"29=29",
"30=30",
"31=31",
"32=32",
"33=33",
"34=34",
"35=35",
"36=36",
"37=37",
"38=38",
"39=39",
"40=40",
"41=41",
"42=42",
"43=43",
"44=44",
"45=45",
"46=46",
"47=47",
"48=48",
"49=49",
"50=50",
"51=51",
"52=52",
"53=53",
"54=54",
"55=55",
"56=56",
"57=57",
"58=58",
"59=59",
"60=60",
"61=61",
"62x=62",
"63=63x",
"64=64"
};
#if CHANNEL_SUBSYSTEM_MAX != 64
error !
#endif
static void test1(void) {
long long i;
for (i = 0; i < 64; ++i) {
if (!channel_subsystem_add(vector[i])) fail("failure");
}
if (channel_subsystem_add(vector[i])) fail("failure");
}
static void test2(void) {
long long i;
char *x, *n;
for (i = 0; i < 62; ++i) {
n = numtostr(0, i);
x = channel_subsystem_get(n);
if (!x) fail("failure");
if (strcmp(x, n)) fail("failure");
}
n = numtostr(0, 62);
x = channel_subsystem_get(n);
if (x) fail("failure");
n = numtostr(0, 63);
x = channel_subsystem_get(n);
if (!x) fail("failure");
if (!strcmp(x, n)) fail("failure");
n = numtostr(0, 64);
x = channel_subsystem_get(n);
if (x) fail("failure");
}
int main(void) {
test1();
test2();
_exit(0);
}
tinyssh-20190101/tinyssh-tests/channeltest.c 0000664 0000000 0000000 00000012236 13412736503 0020777 0 ustar 00root root 0000000 0000000 /*
20140423
Jan Mojzis
Public domain.
*/
#include
#include
#include
#include
#include "crypto_uint32.h"
#include "fail.h"
#include "run.h"
#include "byte.h"
#include "channel.h"
const char *user = "user";
const char *termname = "xterm";
crypto_uint32 id = 0;
crypto_uint32 remotewindow = 100;
crypto_uint32 maxpacket = 100;
crypto_uint32 localwindow;
unsigned char ch = 'x';
static char *name(void) {
struct passwd *pw;
pw = getpwuid(geteuid());
return pw->pw_name;
}
/* channel can't be opened 2x */
static void testopen1(void) {
channel_open(user, id, remotewindow, maxpacket, &localwindow);
channel_open(user, id, remotewindow, maxpacket, &localwindow);
}
/* *localwindow can't be 0 */
static void testopen2(void) {
channel_open(user, id, remotewindow, maxpacket, 0);
}
/* maxpacket can't be 0 */
static void testopen3(void) {
channel_open(user, id, remotewindow, 0, &localwindow);
}
/* remotewindow can't be 0 */
static void testopen4(void) {
channel_open(user, id, 0, maxpacket, &localwindow);
}
/* channel_openterminal() can't be called before channel_open() */
static void testtermopen1(void) {
channel_openterminal(termname, 0, 0, 0, 0);
}
/* channel_env() can't be called before channel_open() */
static void testenv1(void) {
channel_env("a", "b");
}
/* channel_env() can't be called after channel_exec() */
static void testenv2(void) {
channel_open(name(), id, remotewindow, maxpacket, &localwindow);
channel_exec("exit 0");
channel_env("a", "b");
}
/* channel_exec() can't be called before channel_open() */
static void testexec1(void) {
channel_exec("true");
}
/* channel_put() can't be called before channel_exec() */
static void testput1(void) {
channel_open(user, id, remotewindow, maxpacket, &localwindow);
channel_put(&ch, 1);
}
/* channel_puteof() can't be called before channel_exec() */
static void testputeof1(void) {
channel_open(user, id, remotewindow, maxpacket, &localwindow);
channel_puteof();
}
/* channel_read() can't be called before channel_exec() */
static void testread1(void) {
channel_open(user, id, remotewindow, maxpacket, &localwindow);
channel_read(&ch, 1);
}
/* channel_extendedread() can't be called before channel_exec() */
static void testextendedread1(void) {
channel_open(user, id, remotewindow, maxpacket, &localwindow);
channel_extendedread(&ch, 1);
}
/* channel_write() can't be called before channel_exec() */
static void testwrite1(void) {
channel_open(user, id, remotewindow, maxpacket, &localwindow);
channel_write();
}
/* OK - tests */
static void testok1(void) {
int r, s, e;
channel_open(name(), id, remotewindow, maxpacket, &localwindow);
channel_exec("exit 0");
do {
r = channel_waitnohang(&s, &e);
} while (r == 0);
if (s != 0) fail("process killed");
if (e != 0) fail("bad status");
_exit(0);
}
static void testok2(void) {
int r, s, e;
channel_open(name(), id, remotewindow, maxpacket, &localwindow);
channel_exec("exit 1");
do {
r = channel_waitnohang(&s, &e);
} while (r == 0);
if (s != 0) fail("process killed");
if (e != 1) fail("bad status");
_exit(0);
}
static void testok3(void) {
int r, s, e;
channel_open(name(), id, remotewindow, maxpacket, &localwindow);
channel_exec("kill -9 $$");
do {
r = channel_waitnohang(&s, &e);
} while (r == 0);
if (s != 9) fail("bad exit signal");
_exit(0);
}
static void testok4(void) {
int r, s, e;
unsigned char buf[10];
channel_open(name(), id, remotewindow, maxpacket, &localwindow);
channel_exec("cat");
ch = 'a';
channel_put(&ch, 1);
do {
r = channel_write();
} while (r == 0);
do {
r = channel_read(buf, sizeof buf);
} while (r == 0);
if (r != 1) fail("channel_write()/channel_read() failure");
if (buf[0] != 'a') fail("channel_write()/channel_read() failure");
channel_puteof();
do {
r = channel_waitnohang(&s, &e);
} while (r == 0);
if (s != 0) fail("process killed");
if (e != 0) fail("bad status");
_exit(0);
}
#define warn_(a, b, x) do { fprintf(stderr, "%s:%llu: warning: %s\n", (a), (unsigned long long)(b), (x)); fflush(stderr); _exit(0); } while (0);
#define warn(x) warn_(__FILE__, __LINE__, (x))
static int homedir(void) {
struct passwd *pw;
struct stat st;
pw = getpwuid(geteuid());
if (!pw) return 0;
return 1 + stat(pw->pw_dir, &st);
}
int main(void) {
/* don't run check when homedir not exist */
if (!homedir()) {
warn("homedir not exist - skipping tests")
_exit(0);
}
run_mustfail(testopen1);
run_mustfail(testopen2);
run_mustfail(testopen3);
run_mustfail(testopen4);
run_mustfail(testtermopen1);
run_mustfail(testenv1);
run_mustfail(testenv2);
run_mustfail(testexec1);
run_mustfail(testput1);
run_mustfail(testputeof1);
run_mustfail(testread1);
run_mustfail(testextendedread1);
run_mustfail(testwrite1);
run_mustpass(testok1);
run_mustpass(testok2);
run_mustpass(testok3);
run_mustpass(testok4);
;
_exit(0);
}
tinyssh-20190101/tinyssh-tests/coetest.c 0000664 0000000 0000000 00000000773 13412736503 0020140 0 ustar 00root root 0000000 0000000 /*
20140302
Jan Mojzis
Public domain.
*/
#include
#include
#include
#include "fail.h"
#include "coe.h"
int main(void) {
int pi[2];
long long i;
if (pipe(pi) == -1) fail("failure");
for (i = 0; i < 2; ++i) {
if (fcntl(pi[i], F_GETFD) != 0) fail("failure");
coe_enable(pi[i]);
if (fcntl(pi[i], F_GETFD) == 0) fail("failure");
coe_disable(pi[i]);
if (fcntl(pi[i], F_GETFD) != 0) fail("failure");
}
_exit(0);
}
tinyssh-20190101/tinyssh-tests/connectioninfotest.c 0000664 0000000 0000000 00000012622 13412736503 0022401 0 ustar 00root root 0000000 0000000 /*
20140302
Jan Mojzis
Public domain.
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "fail.h"
#include "porttostr.h"
#include "iptostr.h"
#include "connectioninfo.h"
#include "byte.h"
static void connectioninfotest_empty(void) {
char localip[IPTOSTR_LEN];
char localport[PORTTOSTR_LEN];
char remoteip[IPTOSTR_LEN];
char remoteport[PORTTOSTR_LEN];
connectioninfo(localip, localport, remoteip, remoteport);
if (strcmp(localip, "unknown")) fail("connectioninfo failed");
if (strcmp(localport, "0")) fail("connectioninfo failed");
if (strcmp(remoteip, "unknown")) fail("connectioninfo failed");
if (strcmp(remoteport, "0")) fail("connectioninfo failed");
}
static void connectioninfotest_tcpserverenv(void) {
char localip[IPTOSTR_LEN];
char localport[PORTTOSTR_LEN];
char remoteip[IPTOSTR_LEN];
char remoteport[PORTTOSTR_LEN];
if (setenv("TCPLOCALIP", "aaax", 1) == -1) fail("setenv failed")
if (setenv("TCPLOCALPORT", "bbbx", 1) == -1) fail("setenv failed")
if (setenv("TCPREMOTEIP", "cccx", 1) == -1) fail("setenv failed")
if (setenv("TCPREMOTEPORT", "dddx", 1) == -1) fail("setenv failed")
connectioninfo(localip, localport, remoteip, remoteport);
if (strcmp(localip, "aaax")) fail("connectioninfo failed");
if (strcmp(localport, "bbbx")) fail("connectioninfo failed");
if (strcmp(remoteip, "cccx")) fail("connectioninfo failed");
if (strcmp(remoteport, "dddx")) fail("connectioninfo failed");
if (unsetenv("TCPLOCALIP") == -1) fail("unsetenv failed")
if (unsetenv("TCPLOCALPORT") == -1) fail("unsetenv failed")
if (unsetenv("TCPREMOTEIP") == -1) fail("unsetenv failed")
if (unsetenv("TCPREMOTEPORT") == -1) fail("unsetenv failed")
}
static void connectioninfotest_curvecpserverenv(void) {
#ifdef TODO
char localip[IPTOSTR_LEN];
char localport[PORTTOSTR_LEN];
char remoteip[IPTOSTR_LEN];
char remoteport[PORTTOSTR_LEN];
if (setenv("CURVECPLOCALIP", "aaay", 1) == -1) fail("setenv failed")
if (setenv("CURVECPLOCALPORT", "bbby", 1) == -1) fail("setenv failed")
if (setenv("CURVECPREMOTEIP", "cccy", 1) == -1) fail("setenv failed")
if (setenv("CURVECPREMOTEPORT", "dddy", 1) == -1) fail("setenv failed")
connectioninfo(localip, localport, remoteip, remoteport);
if (strcmp(localip, "aaay")) fail("connectioninfo failed");
if (strcmp(localport, "bbby")) fail("connectioninfo failed");
if (strcmp(remoteip, "cccy")) fail("connectioninfo failed");
if (strcmp(remoteport, "dddy")) fail("connectioninfo failed");
if (unsetenv("CURVECPLOCALIP") == -1) fail("unsetenv failed")
if (unsetenv("CURVECPLOCALPORT") == -1) fail("unsetenv failed")
if (unsetenv("CURVECPREMOTEIP") == -1) fail("unsetenv failed")
if (unsetenv("CURVECPREMOTEPORT") == -1) fail("unsetenv failed")
#endif
}
static struct vectors {
const char *port;
const char *portstr;
} testvectors[] = {
{ "\377\000", "65280" },
{ "\377\001", "65281" },
{ "\377\002", "65282" },
{ "\377\003", "65283" },
{ "\377\004", "65284" },
{ "\377\005", "65285" },
{ "\377\006", "65286" },
{ "\377\007", "65287" },
{ "\377\010", "65288" },
{ "\377\011", "65289" },
{ "\377\012", "65290" },
{ "\377\013", "65291" },
{ "\377\014", "65292" },
{ "\377\015", "65293" },
{ "\377\016", "65294" },
{ "\377\017", "65295" },
{ "\377\020", "65296" },
{ "\377\021", "65297" },
{ "\377\022", "65298" },
{ "\377\023", "65299" },
{ 0, 0 }
};
static void connectioninfotest_fromfd(void) {
int fd;
struct sockaddr_in sa;
long long i, j;
char localip[IPTOSTR_LEN];
char localport[PORTTOSTR_LEN];
char remoteip[IPTOSTR_LEN];
char remoteport[PORTTOSTR_LEN];
/* create socket */
fd = socket(PF_INET, SOCK_DGRAM, 0);
if (fd == -1) fail("socket failed");
/* bind */
for (i = 0; testvectors[i].port; ++i) {
byte_zero(&sa, sizeof sa);
sa.sin_family = PF_INET;
byte_copy(&sa.sin_addr, 4, "\177\0\0\1");
byte_copy(&sa.sin_port, 2, testvectors[i].port);
if (bind(fd, (struct sockaddr *)&sa, sizeof sa) == 0) goto bind;
}
fail("bind failed");
bind:
/* connect */
for (j = i; testvectors[j].port; ++j) {
byte_zero(&sa, sizeof sa);
sa.sin_family = PF_INET;
byte_copy(&sa.sin_addr, 4, "\177\0\0\1");
byte_copy(&sa.sin_port, 2, testvectors[i].port);
if (connect(fd, (struct sockaddr *)&sa, sizeof sa) == 0) goto connect;
}
fail("connect failed");
connect:
close(0);
if (dup(fd) != 0) fail("dup failed");
close(fd);
connectioninfo(localip, localport, remoteip, remoteport);
if (strcmp(localip, "127.0.0.1")) fail("connectioninfo failed");
if (strcmp(localport, testvectors[i].portstr)) fail("connectioninfo failed");
if (strcmp(remoteip, "127.0.0.1")) fail("connectioninfo failed");
if (strcmp(remoteport, testvectors[j].portstr)) fail("connectioninfo failed");
close(0);
}
int main(void) {
connectioninfotest_empty();
connectioninfotest_tcpserverenv();
connectioninfotest_empty();
connectioninfotest_curvecpserverenv();
connectioninfotest_empty();
connectioninfotest_fromfd();
connectioninfotest_empty();
_exit(0);
}
tinyssh-20190101/tinyssh-tests/dietest.c 0000777 0000000 0000000 00000000000 13412736503 0022321 2emptytest.c ustar 00root root 0000000 0000000 tinyssh-20190101/tinyssh-tests/dropuidgidtest.c 0000664 0000000 0000000 00000001405 13412736503 0021515 0 ustar 00root root 0000000 0000000 /*
20140320
Jan Mojzis
Public domain.
*/
#include
#include "run.h"
#include "fail.h"
#include "dropuidgid.h"
static void droproot(void) {
if (geteuid() == 0) {
if (!dropuidgid(0, 1230, 1230)) _exit(111);
}
if (geteuid() == 0) _exit(111);
}
static void test1(void) {
droproot();
if (dropuidgid(0, 1231, getegid())) _exit(111);
_exit(0);
}
static void test2(void) {
droproot();
if (!dropuidgid(0, geteuid(), getegid())) _exit(111);
if (!dropuidgid(0, geteuid(), getegid())) _exit(111);
_exit(0);
}
static void test3(void) {
droproot();
if (!dropuidgid(0, 0, 0)) _exit(111);
_exit(0);
}
int main(void) {
run_mustpass(test1);
run_mustpass(test2);
run_mustfail(test3);
_exit(0);
}
tinyssh-20190101/tinyssh-tests/emptytest.c 0000664 0000000 0000000 00000000141 13412736503 0020515 0 ustar 00root root 0000000 0000000 /*
20140319
Jan Mojzis
Public domain.
*/
#include
int main(void) {
_exit(0);
}
tinyssh-20190101/tinyssh-tests/envtest.c 0000664 0000000 0000000 00000002177 13412736503 0020162 0 ustar 00root root 0000000 0000000 /*
20130606
Jan Mojzis
Public domain.
*/
#include
#include
#include
#include
#include "fail.h"
#include "env.h"
static void test_zero(void) {
if (env_get(0)) fail("env_get accepts zero input");
}
static void doit(const char *d0, const char *d) {
char *s;
s = env_get(d0);
if (!s) {
if (d) fail("env_get failure");
return;
}
if (!s) fail("env_get failure");
if (strcmp(s, d)) fail("env_get failure");
return;
}
static void test_setunset(void) {
setenv("x","x",1);
doit("x", "x");
setenv("x","y",1);
doit("x", "y");
unsetenv("x");
doit("x", 0);
}
static void test_env(void) {
const char *env[10];
env[0] = "a=1";
env[1] = "a=2";
env[2] = "b=b=1";
env[3] = "c=";
env[4] = "d";
env[5] = "=null";
env[6] = "e==";
env[7] = 0;
environ = (char **)env;
doit("a", "1");
doit("b", "b=1");
doit("b=b", "1");
doit("c", "");
doit("d", 0);
doit("e", "=");
doit("", "null");
}
int main(void) {
test_zero();
test_setunset();
test_env();
_exit(0);
}
tinyssh-20190101/tinyssh-tests/etest.c 0000664 0000000 0000000 00000000216 13412736503 0017606 0 ustar 00root root 0000000 0000000 /*
20140417
Jan Mojzis
Public domain.
*/
#include
#include "e.h"
#ifndef EPROTO
error!
#endif
int main(void) {
_exit(0);
}
tinyssh-20190101/tinyssh-tests/fail.h 0000664 0000000 0000000 00000001344 13412736503 0017405 0 ustar 00root root 0000000 0000000 #ifndef _FAIL_H____
#define _FAIL_H____
#include
#include
#include "fail.h"
#define fail_(a, b, x) do { fprintf(stderr, "%s:%llu: %s\n", (a), (unsigned long long)(b), (x)); fflush(stderr); _exit(111); } while (0);
#define fail(x) fail_(__FILE__, __LINE__, (x))
static void fail_printdata(char *text, unsigned char *data, long long len) {
long long i;
fprintf(stderr, "%s = {\n ", text);
for (i = 0; i < len; ++i) {
if (i == len - 1) {
fprintf(stderr, "0x%02x", data[i]);
}
else {
fprintf(stderr, "0x%02x, ", data[i]);
if (i % 8 == 7) fprintf(stderr, "\n ");
}
}
fprintf(stderr, "\n};\n");
fflush(stderr);
}
#endif
tinyssh-20190101/tinyssh-tests/forkptytest.c 0000777 0000000 0000000 00000000000 13412736503 0023256 2emptytest.c ustar 00root root 0000000 0000000 tinyssh-20190101/tinyssh-tests/getlntest.c 0000664 0000000 0000000 00000004015 13412736503 0020474 0 ustar 00root root 0000000 0000000 /*
20140323
Jan Mojzis
Public domain.
*/
#include
#include
#include "fail.h"
#include "savesync.h"
#include "str.h"
#include "byte.h"
#include "open.h"
#include "getln.h"
int main(void) {
char buf[6];
int fd;
int r;
/* create test file */
if (savesync("getlntest.txt", "ab\ncd", 5) == -1) fail("savesync() failure");
/* ok test */
fd = open_read("getlntest.txt");
if (fd == -1) fail("open_read() failure");
r = getln(fd, buf, sizeof buf);
if (r != 1) fail("getln() failure");
if (str_len(buf) != 3) fail("getln() failure");
if (!byte_isequal(buf, 3, "ab\n")) fail("getln() failure");
r = getln(fd, buf, sizeof buf);
if (r != 0) fail("getln() failure");
if (str_len(buf) != 2) fail("getln() failure");
if (!byte_isequal(buf, 2, "cd")) fail("getln() failure");
close(fd);
/* overflow test */
fd = open_read("getlntest.txt");
if (fd == -1) fail("open_read() failure");
r = getln(fd, buf, 3);
if (r != -1) fail("getln() failure");
close(fd);
if (unlink("getlntest.txt") == -1) fail("unlink() failure");
/* empty test */
if (savesync("getlntest.txt", "", 0) == -1) fail("savesync() failure");
fd = open_read("getlntest.txt");
if (fd == -1) fail("open_read() failure");
r = getln(fd, buf, sizeof buf);
if (r != 0) fail("getln() failure");
if (str_len(buf) != 0) fail("getln() failure");
close(fd);
if (unlink("getlntest.txt") == -1) fail("unlink() failure");
/* empty line test */
if (savesync("getlntest.txt", "\n", 1) == -1) fail("savesync() failure");
fd = open_read("getlntest.txt");
if (fd == -1) fail("open_read() failure");
r = getln(fd, buf, sizeof buf);
if (r != 1) fail("getln() failure");
if (str_len(buf) != 1) fail("getln() failure");
r = getln(fd, buf, sizeof buf);
if (r != 0) fail("getln() failure");
if (str_len(buf) != 0) fail("getln() failure");
close(fd);
if (unlink("getlntest.txt") == -1) fail("unlink() failure");
_exit(0);
}
tinyssh-20190101/tinyssh-tests/globaltest.c 0000664 0000000 0000000 00000000414 13412736503 0020622 0 ustar 00root root 0000000 0000000 /*
20140304
Jan Mojzis
Public domain.
*/
#include
#include "global.h"
#ifndef GLOBAL_BSIZE
error!
#endif
int main(void) {
global_init();
global_init();
global_purge();
global_purge();
global_init();
global_init();
_exit(0);
}
tinyssh-20190101/tinyssh-tests/iptostrtest.c 0000664 0000000 0000000 00000145314 13412736503 0021077 0 ustar 00root root 0000000 0000000 /*
20130605
Jan Mojzis
Public domain.
*/
#include
#include "fail.h"
#include "iptostr.h"
struct vectors {
const char *ip;
const char *ipstr;
} testvectors[] = {
{ "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", "::" },
{ "\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000", "1::" },
{ "\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000", "0:1::" },
{ "\000\001\000\001\000\000\000\000\000\000\000\000\000\000\000\000", "1:1::" },
{ "\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000", "0:0:1::" },
{ "\000\001\000\000\000\001\000\000\000\000\000\000\000\000\000\000", "1:0:1::" },
{ "\000\000\000\001\000\001\000\000\000\000\000\000\000\000\000\000", "0:1:1::" },
{ "\000\001\000\001\000\001\000\000\000\000\000\000\000\000\000\000", "1:1:1::" },
{ "\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000", "0:0:0:1::" },
{ "\000\001\000\000\000\000\000\001\000\000\000\000\000\000\000\000", "1:0:0:1::" },
{ "\000\000\000\001\000\000\000\001\000\000\000\000\000\000\000\000", "0:1:0:1::" },
{ "\000\001\000\001\000\000\000\001\000\000\000\000\000\000\000\000", "1:1:0:1::" },
{ "\000\000\000\000\000\001\000\001\000\000\000\000\000\000\000\000", "0:0:1:1::" },
{ "\000\001\000\000\000\001\000\001\000\000\000\000\000\000\000\000", "1:0:1:1::" },
{ "\000\000\000\001\000\001\000\001\000\000\000\000\000\000\000\000", "0:1:1:1::" },
{ "\000\001\000\001\000\001\000\001\000\000\000\000\000\000\000\000", "1:1:1:1::" },
{ "\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000", "::1:0:0:0" },
{ "\000\001\000\000\000\000\000\000\000\001\000\000\000\000\000\000", "1::1:0:0:0" },
{ "\000\000\000\001\000\000\000\000\000\001\000\000\000\000\000\000", "0:1:0:0:1::" },
{ "\000\001\000\001\000\000\000\000\000\001\000\000\000\000\000\000", "1:1:0:0:1::" },
{ "\000\000\000\000\000\001\000\000\000\001\000\000\000\000\000\000", "0:0:1:0:1::" },
{ "\000\001\000\000\000\001\000\000\000\001\000\000\000\000\000\000", "1:0:1:0:1::" },
{ "\000\000\000\001\000\001\000\000\000\001\000\000\000\000\000\000", "0:1:1:0:1::" },
{ "\000\001\000\001\000\001\000\000\000\001\000\000\000\000\000\000", "1:1:1:0:1::" },
{ "\000\000\000\000\000\000\000\001\000\001\000\000\000\000\000\000", "::1:1:0:0:0" },
{ "\000\001\000\000\000\000\000\001\000\001\000\000\000\000\000\000", "1:0:0:1:1::" },
{ "\000\000\000\001\000\000\000\001\000\001\000\000\000\000\000\000", "0:1:0:1:1::" },
{ "\000\001\000\001\000\000\000\001\000\001\000\000\000\000\000\000", "1:1:0:1:1::" },
{ "\000\000\000\000\000\001\000\001\000\001\000\000\000\000\000\000", "0:0:1:1:1::" },
{ "\000\001\000\000\000\001\000\001\000\001\000\000\000\000\000\000", "1:0:1:1:1::" },
{ "\000\000\000\001\000\001\000\001\000\001\000\000\000\000\000\000", "0:1:1:1:1::" },
{ "\000\001\000\001\000\001\000\001\000\001\000\000\000\000\000\000", "1:1:1:1:1::" },
{ "\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000", "::1:0:0" },
{ "\000\001\000\000\000\000\000\000\000\000\000\001\000\000\000\000", "1::1:0:0" },
{ "\000\000\000\001\000\000\000\000\000\000\000\001\000\000\000\000", "0:1::1:0:0" },
{ "\000\001\000\001\000\000\000\000\000\000\000\001\000\000\000\000", "1:1::1:0:0" },
{ "\000\000\000\000\000\001\000\000\000\000\000\001\000\000\000\000", "::1:0:0:1:0:0" },
{ "\000\001\000\000\000\001\000\000\000\000\000\001\000\000\000\000", "1:0:1::1:0:0" },
{ "\000\000\000\001\000\001\000\000\000\000\000\001\000\000\000\000", "0:1:1::1:0:0" },
{ "\000\001\000\001\000\001\000\000\000\000\000\001\000\000\000\000", "1:1:1::1:0:0" },
{ "\000\000\000\000\000\000\000\001\000\000\000\001\000\000\000\000", "::1:0:1:0:0" },
{ "\000\001\000\000\000\000\000\001\000\000\000\001\000\000\000\000", "1::1:0:1:0:0" },
{ "\000\000\000\001\000\000\000\001\000\000\000\001\000\000\000\000", "0:1:0:1:0:1::" },
{ "\000\001\000\001\000\000\000\001\000\000\000\001\000\000\000\000", "1:1:0:1:0:1::" },
{ "\000\000\000\000\000\001\000\001\000\000\000\001\000\000\000\000", "::1:1:0:1:0:0" },
{ "\000\001\000\000\000\001\000\001\000\000\000\001\000\000\000\000", "1:0:1:1:0:1::" },
{ "\000\000\000\001\000\001\000\001\000\000\000\001\000\000\000\000", "0:1:1:1:0:1::" },
{ "\000\001\000\001\000\001\000\001\000\000\000\001\000\000\000\000", "1:1:1:1:0:1::" },
{ "\000\000\000\000\000\000\000\000\000\001\000\001\000\000\000\000", "::1:1:0:0" },
{ "\000\001\000\000\000\000\000\000\000\001\000\001\000\000\000\000", "1::1:1:0:0" },
{ "\000\000\000\001\000\000\000\000\000\001\000\001\000\000\000\000", "0:1::1:1:0:0" },
{ "\000\001\000\001\000\000\000\000\000\001\000\001\000\000\000\000", "1:1::1:1:0:0" },
{ "\000\000\000\000\000\001\000\000\000\001\000\001\000\000\000\000", "::1:0:1:1:0:0" },
{ "\000\001\000\000\000\001\000\000\000\001\000\001\000\000\000\000", "1:0:1:0:1:1::" },
{ "\000\000\000\001\000\001\000\000\000\001\000\001\000\000\000\000", "0:1:1:0:1:1::" },
{ "\000\001\000\001\000\001\000\000\000\001\000\001\000\000\000\000", "1:1:1:0:1:1::" },
{ "\000\000\000\000\000\000\000\001\000\001\000\001\000\000\000\000", "::1:1:1:0:0" },
{ "\000\001\000\000\000\000\000\001\000\001\000\001\000\000\000\000", "1::1:1:1:0:0" },
{ "\000\000\000\001\000\000\000\001\000\001\000\001\000\000\000\000", "0:1:0:1:1:1::" },
{ "\000\001\000\001\000\000\000\001\000\001\000\001\000\000\000\000", "1:1:0:1:1:1::" },
{ "\000\000\000\000\000\001\000\001\000\001\000\001\000\000\000\000", "::1:1:1:1:0:0" },
{ "\000\001\000\000\000\001\000\001\000\001\000\001\000\000\000\000", "1:0:1:1:1:1::" },
{ "\000\000\000\001\000\001\000\001\000\001\000\001\000\000\000\000", "0:1:1:1:1:1::" },
{ "\000\001\000\001\000\001\000\001\000\001\000\001\000\000\000\000", "1:1:1:1:1:1::" },
{ "\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000", "::1:0" }, /* inet_ntop incompatible: ::0.1.0.0 */
{ "\000\001\000\000\000\000\000\000\000\000\000\000\000\001\000\000", "1::1:0" },
{ "\000\000\000\001\000\000\000\000\000\000\000\000\000\001\000\000", "0:1::1:0" },
{ "\000\001\000\001\000\000\000\000\000\000\000\000\000\001\000\000", "1:1::1:0" },
{ "\000\000\000\000\000\001\000\000\000\000\000\000\000\001\000\000", "0:0:1::1:0" },
{ "\000\001\000\000\000\001\000\000\000\000\000\000\000\001\000\000", "1:0:1::1:0" },
{ "\000\000\000\001\000\001\000\000\000\000\000\000\000\001\000\000", "0:1:1::1:0" },
{ "\000\001\000\001\000\001\000\000\000\000\000\000\000\001\000\000", "1:1:1::1:0" },
{ "\000\000\000\000\000\000\000\001\000\000\000\000\000\001\000\000", "::1:0:0:1:0" },
{ "\000\001\000\000\000\000\000\001\000\000\000\000\000\001\000\000", "1::1:0:0:1:0" },
{ "\000\000\000\001\000\000\000\001\000\000\000\000\000\001\000\000", "0:1:0:1::1:0" },
{ "\000\001\000\001\000\000\000\001\000\000\000\000\000\001\000\000", "1:1:0:1::1:0" },
{ "\000\000\000\000\000\001\000\001\000\000\000\000\000\001\000\000", "::1:1:0:0:1:0" },
{ "\000\001\000\000\000\001\000\001\000\000\000\000\000\001\000\000", "1:0:1:1::1:0" },
{ "\000\000\000\001\000\001\000\001\000\000\000\000\000\001\000\000", "0:1:1:1::1:0" },
{ "\000\001\000\001\000\001\000\001\000\000\000\000\000\001\000\000", "1:1:1:1::1:0" },
{ "\000\000\000\000\000\000\000\000\000\001\000\000\000\001\000\000", "::1:0:1:0" },
{ "\000\001\000\000\000\000\000\000\000\001\000\000\000\001\000\000", "1::1:0:1:0" },
{ "\000\000\000\001\000\000\000\000\000\001\000\000\000\001\000\000", "0:1::1:0:1:0" },
{ "\000\001\000\001\000\000\000\000\000\001\000\000\000\001\000\000", "1:1::1:0:1:0" },
{ "\000\000\000\000\000\001\000\000\000\001\000\000\000\001\000\000", "::1:0:1:0:1:0" },
{ "\000\001\000\000\000\001\000\000\000\001\000\000\000\001\000\000", "1:0:1:0:1:0:1:0" },
{ "\000\000\000\001\000\001\000\000\000\001\000\000\000\001\000\000", "0:1:1:0:1:0:1:0" },
{ "\000\001\000\001\000\001\000\000\000\001\000\000\000\001\000\000", "1:1:1:0:1:0:1:0" },
{ "\000\000\000\000\000\000\000\001\000\001\000\000\000\001\000\000", "::1:1:0:1:0" },
{ "\000\001\000\000\000\000\000\001\000\001\000\000\000\001\000\000", "1::1:1:0:1:0" },
{ "\000\000\000\001\000\000\000\001\000\001\000\000\000\001\000\000", "0:1:0:1:1:0:1:0" },
{ "\000\001\000\001\000\000\000\001\000\001\000\000\000\001\000\000", "1:1:0:1:1:0:1:0" },
{ "\000\000\000\000\000\001\000\001\000\001\000\000\000\001\000\000", "::1:1:1:0:1:0" },
{ "\000\001\000\000\000\001\000\001\000\001\000\000\000\001\000\000", "1:0:1:1:1:0:1:0" },
{ "\000\000\000\001\000\001\000\001\000\001\000\000\000\001\000\000", "0:1:1:1:1:0:1:0" },
{ "\000\001\000\001\000\001\000\001\000\001\000\000\000\001\000\000", "1:1:1:1:1:0:1:0" },
{ "\000\000\000\000\000\000\000\000\000\000\000\001\000\001\000\000", "::1:1:0" },
{ "\000\001\000\000\000\000\000\000\000\000\000\001\000\001\000\000", "1::1:1:0" },
{ "\000\000\000\001\000\000\000\000\000\000\000\001\000\001\000\000", "0:1::1:1:0" },
{ "\000\001\000\001\000\000\000\000\000\000\000\001\000\001\000\000", "1:1::1:1:0" },
{ "\000\000\000\000\000\001\000\000\000\000\000\001\000\001\000\000", "::1:0:0:1:1:0" },
{ "\000\001\000\000\000\001\000\000\000\000\000\001\000\001\000\000", "1:0:1::1:1:0" },
{ "\000\000\000\001\000\001\000\000\000\000\000\001\000\001\000\000", "0:1:1::1:1:0" },
{ "\000\001\000\001\000\001\000\000\000\000\000\001\000\001\000\000", "1:1:1::1:1:0" },
{ "\000\000\000\000\000\000\000\001\000\000\000\001\000\001\000\000", "::1:0:1:1:0" },
{ "\000\001\000\000\000\000\000\001\000\000\000\001\000\001\000\000", "1::1:0:1:1:0" },
{ "\000\000\000\001\000\000\000\001\000\000\000\001\000\001\000\000", "0:1:0:1:0:1:1:0" },
{ "\000\001\000\001\000\000\000\001\000\000\000\001\000\001\000\000", "1:1:0:1:0:1:1:0" },
{ "\000\000\000\000\000\001\000\001\000\000\000\001\000\001\000\000", "::1:1:0:1:1:0" },
{ "\000\001\000\000\000\001\000\001\000\000\000\001\000\001\000\000", "1:0:1:1:0:1:1:0" },
{ "\000\000\000\001\000\001\000\001\000\000\000\001\000\001\000\000", "0:1:1:1:0:1:1:0" },
{ "\000\001\000\001\000\001\000\001\000\000\000\001\000\001\000\000", "1:1:1:1:0:1:1:0" },
{ "\000\000\000\000\000\000\000\000\000\001\000\001\000\001\000\000", "::1:1:1:0" },
{ "\000\001\000\000\000\000\000\000\000\001\000\001\000\001\000\000", "1::1:1:1:0" },
{ "\000\000\000\001\000\000\000\000\000\001\000\001\000\001\000\000", "0:1::1:1:1:0" },
{ "\000\001\000\001\000\000\000\000\000\001\000\001\000\001\000\000", "1:1::1:1:1:0" },
{ "\000\000\000\000\000\001\000\000\000\001\000\001\000\001\000\000", "::1:0:1:1:1:0" },
{ "\000\001\000\000\000\001\000\000\000\001\000\001\000\001\000\000", "1:0:1:0:1:1:1:0" },
{ "\000\000\000\001\000\001\000\000\000\001\000\001\000\001\000\000", "0:1:1:0:1:1:1:0" },
{ "\000\001\000\001\000\001\000\000\000\001\000\001\000\001\000\000", "1:1:1:0:1:1:1:0" },
{ "\000\000\000\000\000\000\000\001\000\001\000\001\000\001\000\000", "::1:1:1:1:0" },
{ "\000\001\000\000\000\000\000\001\000\001\000\001\000\001\000\000", "1::1:1:1:1:0" },
{ "\000\000\000\001\000\000\000\001\000\001\000\001\000\001\000\000", "0:1:0:1:1:1:1:0" },
{ "\000\001\000\001\000\000\000\001\000\001\000\001\000\001\000\000", "1:1:0:1:1:1:1:0" },
{ "\000\000\000\000\000\001\000\001\000\001\000\001\000\001\000\000", "::1:1:1:1:1:0" },
{ "\000\001\000\000\000\001\000\001\000\001\000\001\000\001\000\000", "1:0:1:1:1:1:1:0" },
{ "\000\000\000\001\000\001\000\001\000\001\000\001\000\001\000\000", "0:1:1:1:1:1:1:0" },
{ "\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\000", "1:1:1:1:1:1:1:0" },
{ "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001", "::1" },
{ "\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\001", "1::1" },
{ "\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\001", "0:1::1" },
{ "\000\001\000\001\000\000\000\000\000\000\000\000\000\000\000\001", "1:1::1" },
{ "\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\001", "0:0:1::1" },
{ "\000\001\000\000\000\001\000\000\000\000\000\000\000\000\000\001", "1:0:1::1" },
{ "\000\000\000\001\000\001\000\000\000\000\000\000\000\000\000\001", "0:1:1::1" },
{ "\000\001\000\001\000\001\000\000\000\000\000\000\000\000\000\001", "1:1:1::1" },
{ "\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\001", "::1:0:0:0:1" },
{ "\000\001\000\000\000\000\000\001\000\000\000\000\000\000\000\001", "1:0:0:1::1" },
{ "\000\000\000\001\000\000\000\001\000\000\000\000\000\000\000\001", "0:1:0:1::1" },
{ "\000\001\000\001\000\000\000\001\000\000\000\000\000\000\000\001", "1:1:0:1::1" },
{ "\000\000\000\000\000\001\000\001\000\000\000\000\000\000\000\001", "0:0:1:1::1" },
{ "\000\001\000\000\000\001\000\001\000\000\000\000\000\000\000\001", "1:0:1:1::1" },
{ "\000\000\000\001\000\001\000\001\000\000\000\000\000\000\000\001", "0:1:1:1::1" },
{ "\000\001\000\001\000\001\000\001\000\000\000\000\000\000\000\001", "1:1:1:1::1" },
{ "\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\001", "::1:0:0:1" },
{ "\000\001\000\000\000\000\000\000\000\001\000\000\000\000\000\001", "1::1:0:0:1" },
{ "\000\000\000\001\000\000\000\000\000\001\000\000\000\000\000\001", "0:1::1:0:0:1" },
{ "\000\001\000\001\000\000\000\000\000\001\000\000\000\000\000\001", "1:1::1:0:0:1" },
{ "\000\000\000\000\000\001\000\000\000\001\000\000\000\000\000\001", "::1:0:1:0:0:1" },
{ "\000\001\000\000\000\001\000\000\000\001\000\000\000\000\000\001", "1:0:1:0:1::1" },
{ "\000\000\000\001\000\001\000\000\000\001\000\000\000\000\000\001", "0:1:1:0:1::1" },
{ "\000\001\000\001\000\001\000\000\000\001\000\000\000\000\000\001", "1:1:1:0:1::1" },
{ "\000\000\000\000\000\000\000\001\000\001\000\000\000\000\000\001", "::1:1:0:0:1" },
{ "\000\001\000\000\000\000\000\001\000\001\000\000\000\000\000\001", "1::1:1:0:0:1" },
{ "\000\000\000\001\000\000\000\001\000\001\000\000\000\000\000\001", "0:1:0:1:1::1" },
{ "\000\001\000\001\000\000\000\001\000\001\000\000\000\000\000\001", "1:1:0:1:1::1" },
{ "\000\000\000\000\000\001\000\001\000\001\000\000\000\000\000\001", "::1:1:1:0:0:1" },
{ "\000\001\000\000\000\001\000\001\000\001\000\000\000\000\000\001", "1:0:1:1:1::1" },
{ "\000\000\000\001\000\001\000\001\000\001\000\000\000\000\000\001", "0:1:1:1:1::1" },
{ "\000\001\000\001\000\001\000\001\000\001\000\000\000\000\000\001", "1:1:1:1:1::1" },
{ "\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\001", "::1:0:1" },
{ "\000\001\000\000\000\000\000\000\000\000\000\001\000\000\000\001", "1::1:0:1" },
{ "\000\000\000\001\000\000\000\000\000\000\000\001\000\000\000\001", "0:1::1:0:1" },
{ "\000\001\000\001\000\000\000\000\000\000\000\001\000\000\000\001", "1:1::1:0:1" },
{ "\000\000\000\000\000\001\000\000\000\000\000\001\000\000\000\001", "::1:0:0:1:0:1" },
{ "\000\001\000\000\000\001\000\000\000\000\000\001\000\000\000\001", "1:0:1::1:0:1" },
{ "\000\000\000\001\000\001\000\000\000\000\000\001\000\000\000\001", "0:1:1::1:0:1" },
{ "\000\001\000\001\000\001\000\000\000\000\000\001\000\000\000\001", "1:1:1::1:0:1" },
{ "\000\000\000\000\000\000\000\001\000\000\000\001\000\000\000\001", "::1:0:1:0:1" },
{ "\000\001\000\000\000\000\000\001\000\000\000\001\000\000\000\001", "1::1:0:1:0:1" },
{ "\000\000\000\001\000\000\000\001\000\000\000\001\000\000\000\001", "0:1:0:1:0:1:0:1" },
{ "\000\001\000\001\000\000\000\001\000\000\000\001\000\000\000\001", "1:1:0:1:0:1:0:1" },
{ "\000\000\000\000\000\001\000\001\000\000\000\001\000\000\000\001", "::1:1:0:1:0:1" },
{ "\000\001\000\000\000\001\000\001\000\000\000\001\000\000\000\001", "1:0:1:1:0:1:0:1" },
{ "\000\000\000\001\000\001\000\001\000\000\000\001\000\000\000\001", "0:1:1:1:0:1:0:1" },
{ "\000\001\000\001\000\001\000\001\000\000\000\001\000\000\000\001", "1:1:1:1:0:1:0:1" },
{ "\000\000\000\000\000\000\000\000\000\001\000\001\000\000\000\001", "::1:1:0:1" },
{ "\000\001\000\000\000\000\000\000\000\001\000\001\000\000\000\001", "1::1:1:0:1" },
{ "\000\000\000\001\000\000\000\000\000\001\000\001\000\000\000\001", "0:1::1:1:0:1" },
{ "\000\001\000\001\000\000\000\000\000\001\000\001\000\000\000\001", "1:1::1:1:0:1" },
{ "\000\000\000\000\000\001\000\000\000\001\000\001\000\000\000\001", "::1:0:1:1:0:1" },
{ "\000\001\000\000\000\001\000\000\000\001\000\001\000\000\000\001", "1:0:1:0:1:1:0:1" },
{ "\000\000\000\001\000\001\000\000\000\001\000\001\000\000\000\001", "0:1:1:0:1:1:0:1" },
{ "\000\001\000\001\000\001\000\000\000\001\000\001\000\000\000\001", "1:1:1:0:1:1:0:1" },
{ "\000\000\000\000\000\000\000\001\000\001\000\001\000\000\000\001", "::1:1:1:0:1" },
{ "\000\001\000\000\000\000\000\001\000\001\000\001\000\000\000\001", "1::1:1:1:0:1" },
{ "\000\000\000\001\000\000\000\001\000\001\000\001\000\000\000\001", "0:1:0:1:1:1:0:1" },
{ "\000\001\000\001\000\000\000\001\000\001\000\001\000\000\000\001", "1:1:0:1:1:1:0:1" },
{ "\000\000\000\000\000\001\000\001\000\001\000\001\000\000\000\001", "::1:1:1:1:0:1" },
{ "\000\001\000\000\000\001\000\001\000\001\000\001\000\000\000\001", "1:0:1:1:1:1:0:1" },
{ "\000\000\000\001\000\001\000\001\000\001\000\001\000\000\000\001", "0:1:1:1:1:1:0:1" },
{ "\000\001\000\001\000\001\000\001\000\001\000\001\000\000\000\001", "1:1:1:1:1:1:0:1" },
{ "\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\001", "::1:1" }, /* inet_ntop incompatible: ::0.1.0.1 */
{ "\000\001\000\000\000\000\000\000\000\000\000\000\000\001\000\001", "1::1:1" },
{ "\000\000\000\001\000\000\000\000\000\000\000\000\000\001\000\001", "0:1::1:1" },
{ "\000\001\000\001\000\000\000\000\000\000\000\000\000\001\000\001", "1:1::1:1" },
{ "\000\000\000\000\000\001\000\000\000\000\000\000\000\001\000\001", "0:0:1::1:1" },
{ "\000\001\000\000\000\001\000\000\000\000\000\000\000\001\000\001", "1:0:1::1:1" },
{ "\000\000\000\001\000\001\000\000\000\000\000\000\000\001\000\001", "0:1:1::1:1" },
{ "\000\001\000\001\000\001\000\000\000\000\000\000\000\001\000\001", "1:1:1::1:1" },
{ "\000\000\000\000\000\000\000\001\000\000\000\000\000\001\000\001", "::1:0:0:1:1" },
{ "\000\001\000\000\000\000\000\001\000\000\000\000\000\001\000\001", "1::1:0:0:1:1" },
{ "\000\000\000\001\000\000\000\001\000\000\000\000\000\001\000\001", "0:1:0:1::1:1" },
{ "\000\001\000\001\000\000\000\001\000\000\000\000\000\001\000\001", "1:1:0:1::1:1" },
{ "\000\000\000\000\000\001\000\001\000\000\000\000\000\001\000\001", "::1:1:0:0:1:1" },
{ "\000\001\000\000\000\001\000\001\000\000\000\000\000\001\000\001", "1:0:1:1::1:1" },
{ "\000\000\000\001\000\001\000\001\000\000\000\000\000\001\000\001", "0:1:1:1::1:1" },
{ "\000\001\000\001\000\001\000\001\000\000\000\000\000\001\000\001", "1:1:1:1::1:1" },
{ "\000\000\000\000\000\000\000\000\000\001\000\000\000\001\000\001", "::1:0:1:1" },
{ "\000\001\000\000\000\000\000\000\000\001\000\000\000\001\000\001", "1::1:0:1:1" },
{ "\000\000\000\001\000\000\000\000\000\001\000\000\000\001\000\001", "0:1::1:0:1:1" },
{ "\000\001\000\001\000\000\000\000\000\001\000\000\000\001\000\001", "1:1::1:0:1:1" },
{ "\000\000\000\000\000\001\000\000\000\001\000\000\000\001\000\001", "::1:0:1:0:1:1" },
{ "\000\001\000\000\000\001\000\000\000\001\000\000\000\001\000\001", "1:0:1:0:1:0:1:1" },
{ "\000\000\000\001\000\001\000\000\000\001\000\000\000\001\000\001", "0:1:1:0:1:0:1:1" },
{ "\000\001\000\001\000\001\000\000\000\001\000\000\000\001\000\001", "1:1:1:0:1:0:1:1" },
{ "\000\000\000\000\000\000\000\001\000\001\000\000\000\001\000\001", "::1:1:0:1:1" },
{ "\000\001\000\000\000\000\000\001\000\001\000\000\000\001\000\001", "1::1:1:0:1:1" },
{ "\000\000\000\001\000\000\000\001\000\001\000\000\000\001\000\001", "0:1:0:1:1:0:1:1" },
{ "\000\001\000\001\000\000\000\001\000\001\000\000\000\001\000\001", "1:1:0:1:1:0:1:1" },
{ "\000\000\000\000\000\001\000\001\000\001\000\000\000\001\000\001", "::1:1:1:0:1:1" },
{ "\000\001\000\000\000\001\000\001\000\001\000\000\000\001\000\001", "1:0:1:1:1:0:1:1" },
{ "\000\000\000\001\000\001\000\001\000\001\000\000\000\001\000\001", "0:1:1:1:1:0:1:1" },
{ "\000\001\000\001\000\001\000\001\000\001\000\000\000\001\000\001", "1:1:1:1:1:0:1:1" },
{ "\000\000\000\000\000\000\000\000\000\000\000\001\000\001\000\001", "::1:1:1" },
{ "\000\001\000\000\000\000\000\000\000\000\000\001\000\001\000\001", "1::1:1:1" },
{ "\000\000\000\001\000\000\000\000\000\000\000\001\000\001\000\001", "0:1::1:1:1" },
{ "\000\001\000\001\000\000\000\000\000\000\000\001\000\001\000\001", "1:1::1:1:1" },
{ "\000\000\000\000\000\001\000\000\000\000\000\001\000\001\000\001", "::1:0:0:1:1:1" },
{ "\000\001\000\000\000\001\000\000\000\000\000\001\000\001\000\001", "1:0:1::1:1:1" },
{ "\000\000\000\001\000\001\000\000\000\000\000\001\000\001\000\001", "0:1:1::1:1:1" },
{ "\000\001\000\001\000\001\000\000\000\000\000\001\000\001\000\001", "1:1:1::1:1:1" },
{ "\000\000\000\000\000\000\000\001\000\000\000\001\000\001\000\001", "::1:0:1:1:1" },
{ "\000\001\000\000\000\000\000\001\000\000\000\001\000\001\000\001", "1::1:0:1:1:1" },
{ "\000\000\000\001\000\000\000\001\000\000\000\001\000\001\000\001", "0:1:0:1:0:1:1:1" },
{ "\000\001\000\001\000\000\000\001\000\000\000\001\000\001\000\001", "1:1:0:1:0:1:1:1" },
{ "\000\000\000\000\000\001\000\001\000\000\000\001\000\001\000\001", "::1:1:0:1:1:1" },
{ "\000\001\000\000\000\001\000\001\000\000\000\001\000\001\000\001", "1:0:1:1:0:1:1:1" },
{ "\000\000\000\001\000\001\000\001\000\000\000\001\000\001\000\001", "0:1:1:1:0:1:1:1" },
{ "\000\001\000\001\000\001\000\001\000\000\000\001\000\001\000\001", "1:1:1:1:0:1:1:1" },
{ "\000\000\000\000\000\000\000\000\000\001\000\001\000\001\000\001", "::1:1:1:1" },
{ "\000\001\000\000\000\000\000\000\000\001\000\001\000\001\000\001", "1::1:1:1:1" },
{ "\000\000\000\001\000\000\000\000\000\001\000\001\000\001\000\001", "0:1::1:1:1:1" },
{ "\000\001\000\001\000\000\000\000\000\001\000\001\000\001\000\001", "1:1::1:1:1:1" },
{ "\000\000\000\000\000\001\000\000\000\001\000\001\000\001\000\001", "::1:0:1:1:1:1" },
{ "\000\001\000\000\000\001\000\000\000\001\000\001\000\001\000\001", "1:0:1:0:1:1:1:1" },
{ "\000\000\000\001\000\001\000\000\000\001\000\001\000\001\000\001", "0:1:1:0:1:1:1:1" },
{ "\000\001\000\001\000\001\000\000\000\001\000\001\000\001\000\001", "1:1:1:0:1:1:1:1" },
{ "\000\000\000\000\000\000\000\001\000\001\000\001\000\001\000\001", "::1:1:1:1:1" },
{ "\000\001\000\000\000\000\000\001\000\001\000\001\000\001\000\001", "1::1:1:1:1:1" },
{ "\000\000\000\001\000\000\000\001\000\001\000\001\000\001\000\001", "0:1:0:1:1:1:1:1" },
{ "\000\001\000\001\000\000\000\001\000\001\000\001\000\001\000\001", "1:1:0:1:1:1:1:1" },
{ "\000\000\000\000\000\001\000\001\000\001\000\001\000\001\000\001", "::1:1:1:1:1:1" },
{ "\000\001\000\000\000\001\000\001\000\001\000\001\000\001\000\001", "1:0:1:1:1:1:1:1" },
{ "\000\000\000\001\000\001\000\001\000\001\000\001\000\001\000\001", "0:1:1:1:1:1:1:1" },
{ "\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\001", "1:1:1:1:1:1:1:1" },
{ "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", "::" },
{ "\377\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000", "ffff::" },
{ "\000\000\377\377\000\000\000\000\000\000\000\000\000\000\000\000", "0:ffff::" },
{ "\377\377\377\377\000\000\000\000\000\000\000\000\000\000\000\000", "ffff:ffff::" },
{ "\000\000\000\000\377\377\000\000\000\000\000\000\000\000\000\000", "0:0:ffff::" },
{ "\377\377\000\000\377\377\000\000\000\000\000\000\000\000\000\000", "ffff:0:ffff::" },
{ "\000\000\377\377\377\377\000\000\000\000\000\000\000\000\000\000", "0:ffff:ffff::" },
{ "\377\377\377\377\377\377\000\000\000\000\000\000\000\000\000\000", "ffff:ffff:ffff::" },
{ "\000\000\000\000\000\000\377\377\000\000\000\000\000\000\000\000", "0:0:0:ffff::" },
{ "\377\377\000\000\000\000\377\377\000\000\000\000\000\000\000\000", "ffff:0:0:ffff::" },
{ "\000\000\377\377\000\000\377\377\000\000\000\000\000\000\000\000", "0:ffff:0:ffff::" },
{ "\377\377\377\377\000\000\377\377\000\000\000\000\000\000\000\000", "ffff:ffff:0:ffff::" },
{ "\000\000\000\000\377\377\377\377\000\000\000\000\000\000\000\000", "0:0:ffff:ffff::" },
{ "\377\377\000\000\377\377\377\377\000\000\000\000\000\000\000\000", "ffff:0:ffff:ffff::" },
{ "\000\000\377\377\377\377\377\377\000\000\000\000\000\000\000\000", "0:ffff:ffff:ffff::" },
{ "\377\377\377\377\377\377\377\377\000\000\000\000\000\000\000\000", "ffff:ffff:ffff:ffff::" },
{ "\000\000\000\000\000\000\000\000\377\377\000\000\000\000\000\000", "::ffff:0:0:0" },
{ "\377\377\000\000\000\000\000\000\377\377\000\000\000\000\000\000", "ffff::ffff:0:0:0" },
{ "\000\000\377\377\000\000\000\000\377\377\000\000\000\000\000\000", "0:ffff:0:0:ffff::" },
{ "\377\377\377\377\000\000\000\000\377\377\000\000\000\000\000\000", "ffff:ffff:0:0:ffff::" },
{ "\000\000\000\000\377\377\000\000\377\377\000\000\000\000\000\000", "0:0:ffff:0:ffff::" },
{ "\377\377\000\000\377\377\000\000\377\377\000\000\000\000\000\000", "ffff:0:ffff:0:ffff::" },
{ "\000\000\377\377\377\377\000\000\377\377\000\000\000\000\000\000", "0:ffff:ffff:0:ffff::" },
{ "\377\377\377\377\377\377\000\000\377\377\000\000\000\000\000\000", "ffff:ffff:ffff:0:ffff::" },
{ "\000\000\000\000\000\000\377\377\377\377\000\000\000\000\000\000", "::ffff:ffff:0:0:0" },
{ "\377\377\000\000\000\000\377\377\377\377\000\000\000\000\000\000", "ffff:0:0:ffff:ffff::" },
{ "\000\000\377\377\000\000\377\377\377\377\000\000\000\000\000\000", "0:ffff:0:ffff:ffff::" },
{ "\377\377\377\377\000\000\377\377\377\377\000\000\000\000\000\000", "ffff:ffff:0:ffff:ffff::" },
{ "\000\000\000\000\377\377\377\377\377\377\000\000\000\000\000\000", "0:0:ffff:ffff:ffff::" },
{ "\377\377\000\000\377\377\377\377\377\377\000\000\000\000\000\000", "ffff:0:ffff:ffff:ffff::" },
{ "\000\000\377\377\377\377\377\377\377\377\000\000\000\000\000\000", "0:ffff:ffff:ffff:ffff::" },
{ "\377\377\377\377\377\377\377\377\377\377\000\000\000\000\000\000", "ffff:ffff:ffff:ffff:ffff::" },
{ "\000\000\000\000\000\000\000\000\000\000\377\377\000\000\000\000", "0.0.0.0" }, /* inet_ntop incompatible: ::ffff:0.0.0.0 */
{ "\377\377\000\000\000\000\000\000\000\000\377\377\000\000\000\000", "ffff::ffff:0:0" },
{ "\000\000\377\377\000\000\000\000\000\000\377\377\000\000\000\000", "0:ffff::ffff:0:0" },
{ "\377\377\377\377\000\000\000\000\000\000\377\377\000\000\000\000", "ffff:ffff::ffff:0:0" },
{ "\000\000\000\000\377\377\000\000\000\000\377\377\000\000\000\000", "::ffff:0:0:ffff:0:0" },
{ "\377\377\000\000\377\377\000\000\000\000\377\377\000\000\000\000", "ffff:0:ffff::ffff:0:0" },
{ "\000\000\377\377\377\377\000\000\000\000\377\377\000\000\000\000", "0:ffff:ffff::ffff:0:0" },
{ "\377\377\377\377\377\377\000\000\000\000\377\377\000\000\000\000", "ffff:ffff:ffff::ffff:0:0" },
{ "\000\000\000\000\000\000\377\377\000\000\377\377\000\000\000\000", "::ffff:0:ffff:0:0" },
{ "\377\377\000\000\000\000\377\377\000\000\377\377\000\000\000\000", "ffff::ffff:0:ffff:0:0" },
{ "\000\000\377\377\000\000\377\377\000\000\377\377\000\000\000\000", "0:ffff:0:ffff:0:ffff::" },
{ "\377\377\377\377\000\000\377\377\000\000\377\377\000\000\000\000", "ffff:ffff:0:ffff:0:ffff::" },
{ "\000\000\000\000\377\377\377\377\000\000\377\377\000\000\000\000", "::ffff:ffff:0:ffff:0:0" },
{ "\377\377\000\000\377\377\377\377\000\000\377\377\000\000\000\000", "ffff:0:ffff:ffff:0:ffff::" },
{ "\000\000\377\377\377\377\377\377\000\000\377\377\000\000\000\000", "0:ffff:ffff:ffff:0:ffff::" },
{ "\377\377\377\377\377\377\377\377\000\000\377\377\000\000\000\000", "ffff:ffff:ffff:ffff:0:ffff::" },
{ "\000\000\000\000\000\000\000\000\377\377\377\377\000\000\000\000", "::ffff:ffff:0:0" },
{ "\377\377\000\000\000\000\000\000\377\377\377\377\000\000\000\000", "ffff::ffff:ffff:0:0" },
{ "\000\000\377\377\000\000\000\000\377\377\377\377\000\000\000\000", "0:ffff::ffff:ffff:0:0" },
{ "\377\377\377\377\000\000\000\000\377\377\377\377\000\000\000\000", "ffff:ffff::ffff:ffff:0:0" },
{ "\000\000\000\000\377\377\000\000\377\377\377\377\000\000\000\000", "::ffff:0:ffff:ffff:0:0" },
{ "\377\377\000\000\377\377\000\000\377\377\377\377\000\000\000\000", "ffff:0:ffff:0:ffff:ffff::" },
{ "\000\000\377\377\377\377\000\000\377\377\377\377\000\000\000\000", "0:ffff:ffff:0:ffff:ffff::" },
{ "\377\377\377\377\377\377\000\000\377\377\377\377\000\000\000\000", "ffff:ffff:ffff:0:ffff:ffff::" },
{ "\000\000\000\000\000\000\377\377\377\377\377\377\000\000\000\000", "::ffff:ffff:ffff:0:0" },
{ "\377\377\000\000\000\000\377\377\377\377\377\377\000\000\000\000", "ffff::ffff:ffff:ffff:0:0" },
{ "\000\000\377\377\000\000\377\377\377\377\377\377\000\000\000\000", "0:ffff:0:ffff:ffff:ffff::" },
{ "\377\377\377\377\000\000\377\377\377\377\377\377\000\000\000\000", "ffff:ffff:0:ffff:ffff:ffff::" },
{ "\000\000\000\000\377\377\377\377\377\377\377\377\000\000\000\000", "::ffff:ffff:ffff:ffff:0:0" },
{ "\377\377\000\000\377\377\377\377\377\377\377\377\000\000\000\000", "ffff:0:ffff:ffff:ffff:ffff::" },
{ "\000\000\377\377\377\377\377\377\377\377\377\377\000\000\000\000", "0:ffff:ffff:ffff:ffff:ffff::" },
{ "\377\377\377\377\377\377\377\377\377\377\377\377\000\000\000\000", "ffff:ffff:ffff:ffff:ffff:ffff::" },
{ "\000\000\000\000\000\000\000\000\000\000\000\000\377\377\000\000", "::ffff:0" }, /* inet_ntop incompatible: ::255.255.0.0 */
{ "\377\377\000\000\000\000\000\000\000\000\000\000\377\377\000\000", "ffff::ffff:0" },
{ "\000\000\377\377\000\000\000\000\000\000\000\000\377\377\000\000", "0:ffff::ffff:0" },
{ "\377\377\377\377\000\000\000\000\000\000\000\000\377\377\000\000", "ffff:ffff::ffff:0" },
{ "\000\000\000\000\377\377\000\000\000\000\000\000\377\377\000\000", "0:0:ffff::ffff:0" },
{ "\377\377\000\000\377\377\000\000\000\000\000\000\377\377\000\000", "ffff:0:ffff::ffff:0" },
{ "\000\000\377\377\377\377\000\000\000\000\000\000\377\377\000\000", "0:ffff:ffff::ffff:0" },
{ "\377\377\377\377\377\377\000\000\000\000\000\000\377\377\000\000", "ffff:ffff:ffff::ffff:0" },
{ "\000\000\000\000\000\000\377\377\000\000\000\000\377\377\000\000", "::ffff:0:0:ffff:0" },
{ "\377\377\000\000\000\000\377\377\000\000\000\000\377\377\000\000", "ffff::ffff:0:0:ffff:0" },
{ "\000\000\377\377\000\000\377\377\000\000\000\000\377\377\000\000", "0:ffff:0:ffff::ffff:0" },
{ "\377\377\377\377\000\000\377\377\000\000\000\000\377\377\000\000", "ffff:ffff:0:ffff::ffff:0" },
{ "\000\000\000\000\377\377\377\377\000\000\000\000\377\377\000\000", "::ffff:ffff:0:0:ffff:0" },
{ "\377\377\000\000\377\377\377\377\000\000\000\000\377\377\000\000", "ffff:0:ffff:ffff::ffff:0" },
{ "\000\000\377\377\377\377\377\377\000\000\000\000\377\377\000\000", "0:ffff:ffff:ffff::ffff:0" },
{ "\377\377\377\377\377\377\377\377\000\000\000\000\377\377\000\000", "ffff:ffff:ffff:ffff::ffff:0" },
{ "\000\000\000\000\000\000\000\000\377\377\000\000\377\377\000\000", "::ffff:0:ffff:0" },
{ "\377\377\000\000\000\000\000\000\377\377\000\000\377\377\000\000", "ffff::ffff:0:ffff:0" },
{ "\000\000\377\377\000\000\000\000\377\377\000\000\377\377\000\000", "0:ffff::ffff:0:ffff:0" },
{ "\377\377\377\377\000\000\000\000\377\377\000\000\377\377\000\000", "ffff:ffff::ffff:0:ffff:0" },
{ "\000\000\000\000\377\377\000\000\377\377\000\000\377\377\000\000", "::ffff:0:ffff:0:ffff:0" },
{ "\377\377\000\000\377\377\000\000\377\377\000\000\377\377\000\000", "ffff:0:ffff:0:ffff:0:ffff:0" },
{ "\000\000\377\377\377\377\000\000\377\377\000\000\377\377\000\000", "0:ffff:ffff:0:ffff:0:ffff:0" },
{ "\377\377\377\377\377\377\000\000\377\377\000\000\377\377\000\000", "ffff:ffff:ffff:0:ffff:0:ffff:0" },
{ "\000\000\000\000\000\000\377\377\377\377\000\000\377\377\000\000", "::ffff:ffff:0:ffff:0" },
{ "\377\377\000\000\000\000\377\377\377\377\000\000\377\377\000\000", "ffff::ffff:ffff:0:ffff:0" },
{ "\000\000\377\377\000\000\377\377\377\377\000\000\377\377\000\000", "0:ffff:0:ffff:ffff:0:ffff:0" },
{ "\377\377\377\377\000\000\377\377\377\377\000\000\377\377\000\000", "ffff:ffff:0:ffff:ffff:0:ffff:0" },
{ "\000\000\000\000\377\377\377\377\377\377\000\000\377\377\000\000", "::ffff:ffff:ffff:0:ffff:0" },
{ "\377\377\000\000\377\377\377\377\377\377\000\000\377\377\000\000", "ffff:0:ffff:ffff:ffff:0:ffff:0" },
{ "\000\000\377\377\377\377\377\377\377\377\000\000\377\377\000\000", "0:ffff:ffff:ffff:ffff:0:ffff:0" },
{ "\377\377\377\377\377\377\377\377\377\377\000\000\377\377\000\000", "ffff:ffff:ffff:ffff:ffff:0:ffff:0" },
{ "\000\000\000\000\000\000\000\000\000\000\377\377\377\377\000\000", "255.255.0.0" }, /* inet_ntop incompatible: ::ffff:255.255.0.0 */
{ "\377\377\000\000\000\000\000\000\000\000\377\377\377\377\000\000", "ffff::ffff:ffff:0" },
{ "\000\000\377\377\000\000\000\000\000\000\377\377\377\377\000\000", "0:ffff::ffff:ffff:0" },
{ "\377\377\377\377\000\000\000\000\000\000\377\377\377\377\000\000", "ffff:ffff::ffff:ffff:0" },
{ "\000\000\000\000\377\377\000\000\000\000\377\377\377\377\000\000", "::ffff:0:0:ffff:ffff:0" },
{ "\377\377\000\000\377\377\000\000\000\000\377\377\377\377\000\000", "ffff:0:ffff::ffff:ffff:0" },
{ "\000\000\377\377\377\377\000\000\000\000\377\377\377\377\000\000", "0:ffff:ffff::ffff:ffff:0" },
{ "\377\377\377\377\377\377\000\000\000\000\377\377\377\377\000\000", "ffff:ffff:ffff::ffff:ffff:0" },
{ "\000\000\000\000\000\000\377\377\000\000\377\377\377\377\000\000", "::ffff:0:ffff:ffff:0" },
{ "\377\377\000\000\000\000\377\377\000\000\377\377\377\377\000\000", "ffff::ffff:0:ffff:ffff:0" },
{ "\000\000\377\377\000\000\377\377\000\000\377\377\377\377\000\000", "0:ffff:0:ffff:0:ffff:ffff:0" },
{ "\377\377\377\377\000\000\377\377\000\000\377\377\377\377\000\000", "ffff:ffff:0:ffff:0:ffff:ffff:0" },
{ "\000\000\000\000\377\377\377\377\000\000\377\377\377\377\000\000", "::ffff:ffff:0:ffff:ffff:0" },
{ "\377\377\000\000\377\377\377\377\000\000\377\377\377\377\000\000", "ffff:0:ffff:ffff:0:ffff:ffff:0" },
{ "\000\000\377\377\377\377\377\377\000\000\377\377\377\377\000\000", "0:ffff:ffff:ffff:0:ffff:ffff:0" },
{ "\377\377\377\377\377\377\377\377\000\000\377\377\377\377\000\000", "ffff:ffff:ffff:ffff:0:ffff:ffff:0" },
{ "\000\000\000\000\000\000\000\000\377\377\377\377\377\377\000\000", "::ffff:ffff:ffff:0" },
{ "\377\377\000\000\000\000\000\000\377\377\377\377\377\377\000\000", "ffff::ffff:ffff:ffff:0" },
{ "\000\000\377\377\000\000\000\000\377\377\377\377\377\377\000\000", "0:ffff::ffff:ffff:ffff:0" },
{ "\377\377\377\377\000\000\000\000\377\377\377\377\377\377\000\000", "ffff:ffff::ffff:ffff:ffff:0" },
{ "\000\000\000\000\377\377\000\000\377\377\377\377\377\377\000\000", "::ffff:0:ffff:ffff:ffff:0" },
{ "\377\377\000\000\377\377\000\000\377\377\377\377\377\377\000\000", "ffff:0:ffff:0:ffff:ffff:ffff:0" },
{ "\000\000\377\377\377\377\000\000\377\377\377\377\377\377\000\000", "0:ffff:ffff:0:ffff:ffff:ffff:0" },
{ "\377\377\377\377\377\377\000\000\377\377\377\377\377\377\000\000", "ffff:ffff:ffff:0:ffff:ffff:ffff:0" },
{ "\000\000\000\000\000\000\377\377\377\377\377\377\377\377\000\000", "::ffff:ffff:ffff:ffff:0" },
{ "\377\377\000\000\000\000\377\377\377\377\377\377\377\377\000\000", "ffff::ffff:ffff:ffff:ffff:0" },
{ "\000\000\377\377\000\000\377\377\377\377\377\377\377\377\000\000", "0:ffff:0:ffff:ffff:ffff:ffff:0" },
{ "\377\377\377\377\000\000\377\377\377\377\377\377\377\377\000\000", "ffff:ffff:0:ffff:ffff:ffff:ffff:0" },
{ "\000\000\000\000\377\377\377\377\377\377\377\377\377\377\000\000", "::ffff:ffff:ffff:ffff:ffff:0" },
{ "\377\377\000\000\377\377\377\377\377\377\377\377\377\377\000\000", "ffff:0:ffff:ffff:ffff:ffff:ffff:0" },
{ "\000\000\377\377\377\377\377\377\377\377\377\377\377\377\000\000", "0:ffff:ffff:ffff:ffff:ffff:ffff:0" },
{ "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\000\000", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:0" },
{ "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\377", "::ffff" },
{ "\377\377\000\000\000\000\000\000\000\000\000\000\000\000\377\377", "ffff::ffff" },
{ "\000\000\377\377\000\000\000\000\000\000\000\000\000\000\377\377", "0:ffff::ffff" },
{ "\377\377\377\377\000\000\000\000\000\000\000\000\000\000\377\377", "ffff:ffff::ffff" },
{ "\000\000\000\000\377\377\000\000\000\000\000\000\000\000\377\377", "0:0:ffff::ffff" },
{ "\377\377\000\000\377\377\000\000\000\000\000\000\000\000\377\377", "ffff:0:ffff::ffff" },
{ "\000\000\377\377\377\377\000\000\000\000\000\000\000\000\377\377", "0:ffff:ffff::ffff" },
{ "\377\377\377\377\377\377\000\000\000\000\000\000\000\000\377\377", "ffff:ffff:ffff::ffff" },
{ "\000\000\000\000\000\000\377\377\000\000\000\000\000\000\377\377", "::ffff:0:0:0:ffff" },
{ "\377\377\000\000\000\000\377\377\000\000\000\000\000\000\377\377", "ffff:0:0:ffff::ffff" },
{ "\000\000\377\377\000\000\377\377\000\000\000\000\000\000\377\377", "0:ffff:0:ffff::ffff" },
{ "\377\377\377\377\000\000\377\377\000\000\000\000\000\000\377\377", "ffff:ffff:0:ffff::ffff" },
{ "\000\000\000\000\377\377\377\377\000\000\000\000\000\000\377\377", "0:0:ffff:ffff::ffff" },
{ "\377\377\000\000\377\377\377\377\000\000\000\000\000\000\377\377", "ffff:0:ffff:ffff::ffff" },
{ "\000\000\377\377\377\377\377\377\000\000\000\000\000\000\377\377", "0:ffff:ffff:ffff::ffff" },
{ "\377\377\377\377\377\377\377\377\000\000\000\000\000\000\377\377", "ffff:ffff:ffff:ffff::ffff" },
{ "\000\000\000\000\000\000\000\000\377\377\000\000\000\000\377\377", "::ffff:0:0:ffff" },
{ "\377\377\000\000\000\000\000\000\377\377\000\000\000\000\377\377", "ffff::ffff:0:0:ffff" },
{ "\000\000\377\377\000\000\000\000\377\377\000\000\000\000\377\377", "0:ffff::ffff:0:0:ffff" },
{ "\377\377\377\377\000\000\000\000\377\377\000\000\000\000\377\377", "ffff:ffff::ffff:0:0:ffff" },
{ "\000\000\000\000\377\377\000\000\377\377\000\000\000\000\377\377", "::ffff:0:ffff:0:0:ffff" },
{ "\377\377\000\000\377\377\000\000\377\377\000\000\000\000\377\377", "ffff:0:ffff:0:ffff::ffff" },
{ "\000\000\377\377\377\377\000\000\377\377\000\000\000\000\377\377", "0:ffff:ffff:0:ffff::ffff" },
{ "\377\377\377\377\377\377\000\000\377\377\000\000\000\000\377\377", "ffff:ffff:ffff:0:ffff::ffff" },
{ "\000\000\000\000\000\000\377\377\377\377\000\000\000\000\377\377", "::ffff:ffff:0:0:ffff" },
{ "\377\377\000\000\000\000\377\377\377\377\000\000\000\000\377\377", "ffff::ffff:ffff:0:0:ffff" },
{ "\000\000\377\377\000\000\377\377\377\377\000\000\000\000\377\377", "0:ffff:0:ffff:ffff::ffff" },
{ "\377\377\377\377\000\000\377\377\377\377\000\000\000\000\377\377", "ffff:ffff:0:ffff:ffff::ffff" },
{ "\000\000\000\000\377\377\377\377\377\377\000\000\000\000\377\377", "::ffff:ffff:ffff:0:0:ffff" },
{ "\377\377\000\000\377\377\377\377\377\377\000\000\000\000\377\377", "ffff:0:ffff:ffff:ffff::ffff" },
{ "\000\000\377\377\377\377\377\377\377\377\000\000\000\000\377\377", "0:ffff:ffff:ffff:ffff::ffff" },
{ "\377\377\377\377\377\377\377\377\377\377\000\000\000\000\377\377", "ffff:ffff:ffff:ffff:ffff::ffff" },
{ "\000\000\000\000\000\000\000\000\000\000\377\377\000\000\377\377", "0.0.255.255" }, /* inet_ntop incompatible: ::ffff:0.0.255.255 */
{ "\377\377\000\000\000\000\000\000\000\000\377\377\000\000\377\377", "ffff::ffff:0:ffff" },
{ "\000\000\377\377\000\000\000\000\000\000\377\377\000\000\377\377", "0:ffff::ffff:0:ffff" },
{ "\377\377\377\377\000\000\000\000\000\000\377\377\000\000\377\377", "ffff:ffff::ffff:0:ffff" },
{ "\000\000\000\000\377\377\000\000\000\000\377\377\000\000\377\377", "::ffff:0:0:ffff:0:ffff" },
{ "\377\377\000\000\377\377\000\000\000\000\377\377\000\000\377\377", "ffff:0:ffff::ffff:0:ffff" },
{ "\000\000\377\377\377\377\000\000\000\000\377\377\000\000\377\377", "0:ffff:ffff::ffff:0:ffff" },
{ "\377\377\377\377\377\377\000\000\000\000\377\377\000\000\377\377", "ffff:ffff:ffff::ffff:0:ffff" },
{ "\000\000\000\000\000\000\377\377\000\000\377\377\000\000\377\377", "::ffff:0:ffff:0:ffff" },
{ "\377\377\000\000\000\000\377\377\000\000\377\377\000\000\377\377", "ffff::ffff:0:ffff:0:ffff" },
{ "\000\000\377\377\000\000\377\377\000\000\377\377\000\000\377\377", "0:ffff:0:ffff:0:ffff:0:ffff" },
{ "\377\377\377\377\000\000\377\377\000\000\377\377\000\000\377\377", "ffff:ffff:0:ffff:0:ffff:0:ffff" },
{ "\000\000\000\000\377\377\377\377\000\000\377\377\000\000\377\377", "::ffff:ffff:0:ffff:0:ffff" },
{ "\377\377\000\000\377\377\377\377\000\000\377\377\000\000\377\377", "ffff:0:ffff:ffff:0:ffff:0:ffff" },
{ "\000\000\377\377\377\377\377\377\000\000\377\377\000\000\377\377", "0:ffff:ffff:ffff:0:ffff:0:ffff" },
{ "\377\377\377\377\377\377\377\377\000\000\377\377\000\000\377\377", "ffff:ffff:ffff:ffff:0:ffff:0:ffff" },
{ "\000\000\000\000\000\000\000\000\377\377\377\377\000\000\377\377", "::ffff:ffff:0:ffff" },
{ "\377\377\000\000\000\000\000\000\377\377\377\377\000\000\377\377", "ffff::ffff:ffff:0:ffff" },
{ "\000\000\377\377\000\000\000\000\377\377\377\377\000\000\377\377", "0:ffff::ffff:ffff:0:ffff" },
{ "\377\377\377\377\000\000\000\000\377\377\377\377\000\000\377\377", "ffff:ffff::ffff:ffff:0:ffff" },
{ "\000\000\000\000\377\377\000\000\377\377\377\377\000\000\377\377", "::ffff:0:ffff:ffff:0:ffff" },
{ "\377\377\000\000\377\377\000\000\377\377\377\377\000\000\377\377", "ffff:0:ffff:0:ffff:ffff:0:ffff" },
{ "\000\000\377\377\377\377\000\000\377\377\377\377\000\000\377\377", "0:ffff:ffff:0:ffff:ffff:0:ffff" },
{ "\377\377\377\377\377\377\000\000\377\377\377\377\000\000\377\377", "ffff:ffff:ffff:0:ffff:ffff:0:ffff" },
{ "\000\000\000\000\000\000\377\377\377\377\377\377\000\000\377\377", "::ffff:ffff:ffff:0:ffff" },
{ "\377\377\000\000\000\000\377\377\377\377\377\377\000\000\377\377", "ffff::ffff:ffff:ffff:0:ffff" },
{ "\000\000\377\377\000\000\377\377\377\377\377\377\000\000\377\377", "0:ffff:0:ffff:ffff:ffff:0:ffff" },
{ "\377\377\377\377\000\000\377\377\377\377\377\377\000\000\377\377", "ffff:ffff:0:ffff:ffff:ffff:0:ffff" },
{ "\000\000\000\000\377\377\377\377\377\377\377\377\000\000\377\377", "::ffff:ffff:ffff:ffff:0:ffff" },
{ "\377\377\000\000\377\377\377\377\377\377\377\377\000\000\377\377", "ffff:0:ffff:ffff:ffff:ffff:0:ffff" },
{ "\000\000\377\377\377\377\377\377\377\377\377\377\000\000\377\377", "0:ffff:ffff:ffff:ffff:ffff:0:ffff" },
{ "\377\377\377\377\377\377\377\377\377\377\377\377\000\000\377\377", "ffff:ffff:ffff:ffff:ffff:ffff:0:ffff" },
{ "\000\000\000\000\000\000\000\000\000\000\000\000\377\377\377\377", "::ffff:ffff" }, /* inet_ntop incompatible: ::255.255.255.255 */
{ "\377\377\000\000\000\000\000\000\000\000\000\000\377\377\377\377", "ffff::ffff:ffff" },
{ "\000\000\377\377\000\000\000\000\000\000\000\000\377\377\377\377", "0:ffff::ffff:ffff" },
{ "\377\377\377\377\000\000\000\000\000\000\000\000\377\377\377\377", "ffff:ffff::ffff:ffff" },
{ "\000\000\000\000\377\377\000\000\000\000\000\000\377\377\377\377", "0:0:ffff::ffff:ffff" },
{ "\377\377\000\000\377\377\000\000\000\000\000\000\377\377\377\377", "ffff:0:ffff::ffff:ffff" },
{ "\000\000\377\377\377\377\000\000\000\000\000\000\377\377\377\377", "0:ffff:ffff::ffff:ffff" },
{ "\377\377\377\377\377\377\000\000\000\000\000\000\377\377\377\377", "ffff:ffff:ffff::ffff:ffff" },
{ "\000\000\000\000\000\000\377\377\000\000\000\000\377\377\377\377", "::ffff:0:0:ffff:ffff" },
{ "\377\377\000\000\000\000\377\377\000\000\000\000\377\377\377\377", "ffff::ffff:0:0:ffff:ffff" },
{ "\000\000\377\377\000\000\377\377\000\000\000\000\377\377\377\377", "0:ffff:0:ffff::ffff:ffff" },
{ "\377\377\377\377\000\000\377\377\000\000\000\000\377\377\377\377", "ffff:ffff:0:ffff::ffff:ffff" },
{ "\000\000\000\000\377\377\377\377\000\000\000\000\377\377\377\377", "::ffff:ffff:0:0:ffff:ffff" },
{ "\377\377\000\000\377\377\377\377\000\000\000\000\377\377\377\377", "ffff:0:ffff:ffff::ffff:ffff" },
{ "\000\000\377\377\377\377\377\377\000\000\000\000\377\377\377\377", "0:ffff:ffff:ffff::ffff:ffff" },
{ "\377\377\377\377\377\377\377\377\000\000\000\000\377\377\377\377", "ffff:ffff:ffff:ffff::ffff:ffff" },
{ "\000\000\000\000\000\000\000\000\377\377\000\000\377\377\377\377", "::ffff:0:ffff:ffff" },
{ "\377\377\000\000\000\000\000\000\377\377\000\000\377\377\377\377", "ffff::ffff:0:ffff:ffff" },
{ "\000\000\377\377\000\000\000\000\377\377\000\000\377\377\377\377", "0:ffff::ffff:0:ffff:ffff" },
{ "\377\377\377\377\000\000\000\000\377\377\000\000\377\377\377\377", "ffff:ffff::ffff:0:ffff:ffff" },
{ "\000\000\000\000\377\377\000\000\377\377\000\000\377\377\377\377", "::ffff:0:ffff:0:ffff:ffff" },
{ "\377\377\000\000\377\377\000\000\377\377\000\000\377\377\377\377", "ffff:0:ffff:0:ffff:0:ffff:ffff" },
{ "\000\000\377\377\377\377\000\000\377\377\000\000\377\377\377\377", "0:ffff:ffff:0:ffff:0:ffff:ffff" },
{ "\377\377\377\377\377\377\000\000\377\377\000\000\377\377\377\377", "ffff:ffff:ffff:0:ffff:0:ffff:ffff" },
{ "\000\000\000\000\000\000\377\377\377\377\000\000\377\377\377\377", "::ffff:ffff:0:ffff:ffff" },
{ "\377\377\000\000\000\000\377\377\377\377\000\000\377\377\377\377", "ffff::ffff:ffff:0:ffff:ffff" },
{ "\000\000\377\377\000\000\377\377\377\377\000\000\377\377\377\377", "0:ffff:0:ffff:ffff:0:ffff:ffff" },
{ "\377\377\377\377\000\000\377\377\377\377\000\000\377\377\377\377", "ffff:ffff:0:ffff:ffff:0:ffff:ffff" },
{ "\000\000\000\000\377\377\377\377\377\377\000\000\377\377\377\377", "::ffff:ffff:ffff:0:ffff:ffff" },
{ "\377\377\000\000\377\377\377\377\377\377\000\000\377\377\377\377", "ffff:0:ffff:ffff:ffff:0:ffff:ffff" },
{ "\000\000\377\377\377\377\377\377\377\377\000\000\377\377\377\377", "0:ffff:ffff:ffff:ffff:0:ffff:ffff" },
{ "\377\377\377\377\377\377\377\377\377\377\000\000\377\377\377\377", "ffff:ffff:ffff:ffff:ffff:0:ffff:ffff" },
{ "\000\000\000\000\000\000\000\000\000\000\377\377\377\377\377\377", "255.255.255.255" }, /* inet_ntop incompatible: ::ffff:255.255.255.255 */
{ "\377\377\000\000\000\000\000\000\000\000\377\377\377\377\377\377", "ffff::ffff:ffff:ffff" },
{ "\000\000\377\377\000\000\000\000\000\000\377\377\377\377\377\377", "0:ffff::ffff:ffff:ffff" },
{ "\377\377\377\377\000\000\000\000\000\000\377\377\377\377\377\377", "ffff:ffff::ffff:ffff:ffff" },
{ "\000\000\000\000\377\377\000\000\000\000\377\377\377\377\377\377", "::ffff:0:0:ffff:ffff:ffff" },
{ "\377\377\000\000\377\377\000\000\000\000\377\377\377\377\377\377", "ffff:0:ffff::ffff:ffff:ffff" },
{ "\000\000\377\377\377\377\000\000\000\000\377\377\377\377\377\377", "0:ffff:ffff::ffff:ffff:ffff" },
{ "\377\377\377\377\377\377\000\000\000\000\377\377\377\377\377\377", "ffff:ffff:ffff::ffff:ffff:ffff" },
{ "\000\000\000\000\000\000\377\377\000\000\377\377\377\377\377\377", "::ffff:0:ffff:ffff:ffff" },
{ "\377\377\000\000\000\000\377\377\000\000\377\377\377\377\377\377", "ffff::ffff:0:ffff:ffff:ffff" },
{ "\000\000\377\377\000\000\377\377\000\000\377\377\377\377\377\377", "0:ffff:0:ffff:0:ffff:ffff:ffff" },
{ "\377\377\377\377\000\000\377\377\000\000\377\377\377\377\377\377", "ffff:ffff:0:ffff:0:ffff:ffff:ffff" },
{ "\000\000\000\000\377\377\377\377\000\000\377\377\377\377\377\377", "::ffff:ffff:0:ffff:ffff:ffff" },
{ "\377\377\000\000\377\377\377\377\000\000\377\377\377\377\377\377", "ffff:0:ffff:ffff:0:ffff:ffff:ffff" },
{ "\000\000\377\377\377\377\377\377\000\000\377\377\377\377\377\377", "0:ffff:ffff:ffff:0:ffff:ffff:ffff" },
{ "\377\377\377\377\377\377\377\377\000\000\377\377\377\377\377\377", "ffff:ffff:ffff:ffff:0:ffff:ffff:ffff" },
{ "\000\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377", "::ffff:ffff:ffff:ffff" },
{ "\377\377\000\000\000\000\000\000\377\377\377\377\377\377\377\377", "ffff::ffff:ffff:ffff:ffff" },
{ "\000\000\377\377\000\000\000\000\377\377\377\377\377\377\377\377", "0:ffff::ffff:ffff:ffff:ffff" },
{ "\377\377\377\377\000\000\000\000\377\377\377\377\377\377\377\377", "ffff:ffff::ffff:ffff:ffff:ffff" },
{ "\000\000\000\000\377\377\000\000\377\377\377\377\377\377\377\377", "::ffff:0:ffff:ffff:ffff:ffff" },
{ "\377\377\000\000\377\377\000\000\377\377\377\377\377\377\377\377", "ffff:0:ffff:0:ffff:ffff:ffff:ffff" },
{ "\000\000\377\377\377\377\000\000\377\377\377\377\377\377\377\377", "0:ffff:ffff:0:ffff:ffff:ffff:ffff" },
{ "\377\377\377\377\377\377\000\000\377\377\377\377\377\377\377\377", "ffff:ffff:ffff:0:ffff:ffff:ffff:ffff" },
{ "\000\000\000\000\000\000\377\377\377\377\377\377\377\377\377\377", "::ffff:ffff:ffff:ffff:ffff" },
{ "\377\377\000\000\000\000\377\377\377\377\377\377\377\377\377\377", "ffff::ffff:ffff:ffff:ffff:ffff" },
{ "\000\000\377\377\000\000\377\377\377\377\377\377\377\377\377\377", "0:ffff:0:ffff:ffff:ffff:ffff:ffff" },
{ "\377\377\377\377\000\000\377\377\377\377\377\377\377\377\377\377", "ffff:ffff:0:ffff:ffff:ffff:ffff:ffff" },
{ "\000\000\000\000\377\377\377\377\377\377\377\377\377\377\377\377", "::ffff:ffff:ffff:ffff:ffff:ffff" },
{ "\377\377\000\000\377\377\377\377\377\377\377\377\377\377\377\377", "ffff:0:ffff:ffff:ffff:ffff:ffff:ffff" },
{ "\000\000\377\377\377\377\377\377\377\377\377\377\377\377\377\377", "0:ffff:ffff:ffff:ffff:ffff:ffff:ffff" },
{ "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" },
{ 0, 0 }
};
static void test_compress(void) {
long long i, j;
char *buf0;
char buf1[IPTOSTR_LEN];
char buf2[IPTOSTR_LEN];
for (i = 0;testvectors[i].ip; ++i) {
for (j = 0; j < IPTOSTR_LEN; ++j) { buf1[j] = (char)0xff; buf2[j] = 0; }
buf0 = iptostr(0, (unsigned char *)testvectors[i].ip);
iptostr(buf1, (unsigned char *)testvectors[i].ip);
for (j = 0; j < IPTOSTR_LEN; ++j) {
buf2[j] = testvectors[i].ipstr[j];
if (!buf2[j]) break;
}
for (j = 0; j < IPTOSTR_LEN; ++j) {
if (buf0[j] != buf2[j]) fail("bad output");
if (buf1[j] != buf2[j]) fail("bad output");
}
}
}
static void test_bufferoverflow(void) {
char buf[IPTOSTR_LEN + 16];
long long i, j;
unsigned char ip[16];
char ch[2] = {0x00, (char)0xff };
if ((IPTOSTR_LEN) < sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")) fail("IPTOSTR_LEN too small");
for (i = 0; i < 16; ++i) ip[i] = 0x11;
for (j = 0; j < 2; ++j) {
for (i = 0; i < sizeof buf; ++i) buf[i] = ch[j];
iptostr(buf + 8, ip);
for (i = 0; i < 8; ++i) if (buf[i] != ch[j]) fail("iptostr writes before output");
for (i = 0; i < 8; ++i) if (buf[i + IPTOSTR_LEN + 8] != ch[j]) fail("iptostr writes after output");
}
}
int main(void) {
test_compress();
test_bufferoverflow();
_exit(0);
}
tinyssh-20190101/tinyssh-tests/loadtest.c 0000664 0000000 0000000 00000001401 13412736503 0020276 0 ustar 00root root 0000000 0000000 /*
20140417
Jan Mojzis
Public domain.
*/
#include
#include
#include
#include
#include "fail.h"
#include "open.h"
#include "randombytes.h"
#include "byte.h"
#include "load.h"
#include "writeall.h"
#define SPACELEN 1048577
unsigned char space1[SPACELEN];
unsigned char space2[SPACELEN];
static void test1(void) {
int fd;
fd = open_write("loadtest.data");
if (fd == -1) fail("failure");
randombytes(space1, sizeof space1);
if (writeall(fd, space1, sizeof space1) == -1) fail("failure");
close(fd);
if (load("loadtest.data", space2, sizeof space2) == -1) fail("failure");
if (!byte_isequal(space1, SPACELEN, space2)) fail("failure");
}
int main(void) {
test1();
_exit(0);
}
tinyssh-20190101/tinyssh-tests/loginshelltest.c 0000664 0000000 0000000 00000002510 13412736503 0021521 0 ustar 00root root 0000000 0000000 /*
20140429
Jan Mojzis
Public domain.
*/
#include "str.h"
#include "byte.h"
#include "fail.h"
#include "loginshell.h"
static char buf[10];
static struct vector {
const char *in;
const char *out;
} vectors[] = {
{ "", "-" },
{ "/", "-" },
{ "//", "-" },
{ "///", "-" },
{ "////", "-" },
{ "/////", "-" },
{ "/a/b/c/d/", "-" },
{ "/a///d/", "-" },
{ "//b/c//", "-" },
{ "x/", "-" },
{ "x/x/xx/xxx/", "-" },
{ "sh", "-sh" },
{ "/bin/bash", "-bash" },
{ "///////dash", "-dash" },
{ "///////-ksh", "--ksh" },
/* truncation */
{ "longlongsh", "-longlong" },
{ 0, 0 }
};
static void testok(void) {
long long i, len;
for (i = 0; vectors[i].in; ++i) {
if (!loginshell(buf, sizeof buf, vectors[i].in)) fail("loginshell failure");
len = str_len(vectors[i].out);
if (str_len(buf) != len) fail("loginshell failure");
if (!byte_isequal(buf, len, vectors[i].out)) fail("loginshell failure");
}
}
static void testbad(void) {
if (loginshell(buf, -1, "")) fail("loginshell failure");
if (loginshell(buf, 0, "")) fail("loginshell failure");
if (loginshell(buf, 1, "")) fail("loginshell failure");
if (loginshell(buf, 1, "//")) fail("loginshell failure");
}
int main(void) {
testok();
testbad();
_exit(0);
}
tinyssh-20190101/tinyssh-tests/logsystest.c 0000777 0000000 0000000 00000000000 13412736503 0023100 2emptytest.c ustar 00root root 0000000 0000000 tinyssh-20190101/tinyssh-tests/logtest.c 0000664 0000000 0000000 00000005037 13412736503 0020151 0 ustar 00root root 0000000 0000000 /*
20140319
Jan Mojzis
Public domain.
*/
#include
#include
#include
#include
#include "fail.h"
#include "byte.h"
#include "log.h"
static int readall(int fd, unsigned char *x, long long xlen) {
long long r;
long long len = 0;
while (xlen > 0) {
r = read(fd, x, xlen);
if (r == 0) break;
if (r <= 0) return -1;
x += r;
len += r;
xlen -= r;
}
return len;
}
static unsigned char buf[1024];
#define LINE_EXP "?????????\n????????????????????? !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????"
static void run(void (*op)(void)) {
pid_t pid;
int status, fromchild[2];
long long r, i, j;
if (pipe(fromchild) == -1) fail("pipe() failure");
pid = fork();
if (pid == -1) fail("fork() failure");
if (pid == 0) {
close(fromchild[0]);
if (dup2(fromchild[1], 2) == -1) _exit(111);
op();
_exit(0);
}
close(fromchild[1]);
r = readall(fromchild[0], buf, sizeof buf);
if (r == -1) fail("read() failure");
j = 0;
for (i = 0; i < r; ++i) {
if (buf[i] == ' ') ++j;
if (j == 3) break;
}
r -= i + 1;
byte_copy(buf, r, buf + i + 1);
for (r = r - 1; r > 0; --r) {
if (buf[r] == ' ') {
buf[r] = 0;
break;
}
}
while (waitpid(pid, &status, 0) != pid) {};
if (!WIFEXITED(status)) fail("process killed");
if (WEXITSTATUS(status)) fail("process exited with status != 0");
if (r < sizeof(LINE_EXP) - 1) fail("failure");
if (!byte_isequal(buf, sizeof(LINE_EXP) - 1, LINE_EXP)) fail("failure");
}
static char line[256];
static void feed(void) {
unsigned long long i;
for (i = 0; i < 256; ++i) line[i] = (unsigned char)(i + 1);
}
static void test_fatal(void) {
log_init(0, "x", 1, 0);
log_d1("hidden");
log_i1("hidden");
log_w1("hidden");
log_f1(line);
}
static void test_warning(void) {
log_init(1, "x", 1, 0);
log_d1("hidden");
log_i1("hidden");
log_w1(line);
}
static void test_info(void) {
log_init(1, "x", 1, 0);
log_d1("hidden");
log_i1(line);
}
static void test_debug(void) {
log_init(2, "x", 1, 0);
log_d1(line);
}
int main(void) {
return 0;
feed();
run(test_fatal);
run(test_warning);
run(test_info);
run(test_debug);
_exit(0);
}
tinyssh-20190101/tinyssh-tests/main_tinysshd_makekeytest.c 0000777 0000000 0000000 00000000000 13412736503 0026137 2emptytest.c ustar 00root root 0000000 0000000 tinyssh-20190101/tinyssh-tests/main_tinysshd_printkeytest.c 0000777 0000000 0000000 00000000000 13412736503 0026356 2emptytest.c ustar 00root root 0000000 0000000 tinyssh-20190101/tinyssh-tests/main_tinysshdtest.c 0000777 0000000 0000000 00000000000 13412736503 0024431 2emptytest.c ustar 00root root 0000000 0000000 tinyssh-20190101/tinyssh-tests/newenvtest.c 0000664 0000000 0000000 00000006657 13412736503 0020703 0 ustar 00root root 0000000 0000000 /*
20140129
Jan Mojzis
Public domain.
*/
#include
#include
#include
#include "run.h"
#include "fail.h"
#include "newenv.h"
#define SCRIPT1 "\
err='newenvtest: failed: newenv_env does not set correcty variable'\n\
[ x\"$AA1\" = x ] || ( echo $err; exit 111; ) \n\
[ x\"$AA3\" = x ] || ( echo $err; exit 111; ) \n\
[ x\"$BBB\" = xok ] || ( echo $err; exit 111; ) \n\
[ x\"$CC1\" = xok ] || ( echo $err; exit 111; ) \n\
[ x\"$CC3\" = x ] || ( echo $err; exit 111; ) \n\
[ x\"$DD1\" = xok ] || ( echo $err; exit 111; ) \n\
[ x\"$DD3\" = xok ] || ( echo $err; exit 111; ) \n\
[ x\"$EE1\" = xok ] || ( echo $err; exit 111; ) \n\
[ x\"$FF1\" = xok ] || ( echo $err; exit 111; ) \n\
[ x\"$YY1\" = xok ] || ( echo $err; exit 111; ) \n\
[ x\"$ZZ1\" = x ] || ( echo $err; exit 111; ) \n\
[ x\"$ZZ3\" = x ] || ( echo $err; exit 111; ) \n\
exit 0 \n\
"
static void test1(void) {
char *run[4];
long long i;
char buf[100];
/* normal setenv */
if (setenv("BBB", "ok", 1) == -1) fail("setenv failure");
if (!newenv_copyenv("BBB")) fail("newenv_copyenv failure");
/* normal env */
if (!newenv_env("CC1", "ok")) fail("newenv_env failure");
if (newenv_copyenv("CC3")) fail("newenv_copyenv failure");
/* replaced env */
if (!newenv_env("DD1", "failed")) fail("newenv_env failure");
if (!newenv_env("DD1", "ok")) fail("newenv_env failure");
if (setenv("DD3", "failed", 1) == -1) fail("setenv failure");
if (!newenv_copyenv("DD3")) fail("newenv_copyenv failure");
if (setenv("DD3", "ok", 1) == -1) fail("setenv failure");
if (!newenv_copyenv("DD3")) fail("newenv_copyenv failure");
/* setenv first */
if (setenv("EE1", "failed", 1) == -1) fail("setenv failure");
if (!newenv_env("EE1", "ok")) fail("newenv_env failure");
/* setenv last */
if (!newenv_env("FF1", "ok")) fail("newenv_env failure");
if (setenv("FF1", "failed", 1) == -1) fail("setenv failure");
/* replaced env - ok */
if (!newenv_env("YY1", "ok")) fail("newenv_env failure");
for (i = 0; i < 200; ++i) {
snprintf(buf, sizeof buf, "%lld", i);
newenv_env(buf, buf);
}
if (!newenv_env("YY1", "ok")) fail("newenv_env failure");
/* replaced env - overflow */
for (i = 0; i < 200; ++i) {
snprintf(buf, sizeof buf, "%lld", i);
newenv_env(buf, buf);
}
if (newenv_env("ZZ1", "failed")) fail("newenv_env failure");
if (setenv("ZZ3", "failed", 1) == -1) fail("setenv failure");
if (newenv_copyenv("ZZ3")) fail("newenv_copyenv failure");
run[0] = (char *)"/bin/sh";
run[1] = (char *)"-ec";
run[2] = (char *)SCRIPT1;
run[3] = (char *)0;
newenv_exec(*run, run);
fail("failure");
}
#define SCRIPT2 "\
err='newenvtest2: failed: environment should be empty'\n\
[ x\"$AAAA\" = x ] || ( echo $err; exit 111; ) \n\
exit 0 \n\
"
static void test2(void) {
char *run[4];
/* setenv */
if (setenv("AAAA", "failed", 1) == -1) fail("setenv failure");
run[0] = (char *)"/bin/sh";
run[1] = (char *)"-ec";
run[2] = (char *)SCRIPT2;
run[3] = 0;
newenv_exec(*run, run);
}
static void test3(void) {
for (;;) {
if (newenv_lowenv("XXX", "YYY")) break;
}
if (!newenv_env("XXX", "YYY")) fail("newenv_env failure");
}
static void testdummy(void) {
_exit(111);
}
int main(void) {
run_mustpass(test1);
run_mustpass(test2);
test3();
run_mustfail(testdummy);
_exit(0);
}
tinyssh-20190101/tinyssh-tests/numtostrtest.c 0000664 0000000 0000000 00000022773 13412736503 0021271 0 ustar 00root root 0000000 0000000 /*
20140201
Jan Mojzis
Public domain.
*/
#include
#include
#include
#include "fail.h"
#include "numtostr.h"
static long long int128max(void) {
long long x = 9223372036854775807LL;
x <<= 32;
x <<= 32;
x += 9223372036854775807LL;
x += 9223372036854775807LL;
x += 1;
return x;
}
static void test_bufferoverflow(void) {
char buf[NUMTOSTR_LEN + 16];
long long i, j;
char ch[2] = {0x00, (char)0xff };
long long llmaxnum;
long long llminnum;
long long numlen = sizeof(long long);
if (numlen == 16) {
llmaxnum = int128max();
llminnum = -llmaxnum - 1LL;
}
else if (numlen == 8) {
llmaxnum = 9223372036854775807LL;
llminnum = -llmaxnum - 1LL;
}
else {
fail("unsupported size for 'num'");
}
if ((NUMTOSTR_LEN) < sizeof("-170141183460469231731687303715884105728")) fail("NUMTOSTR_LEN too small");
for (j = 0; j < 2; ++j) {
for (i = 0; i < sizeof buf; ++i) buf[i] = ch[j];
numtostr(buf + 8, llminnum);
for (i = 0; i < 8; ++i) if (buf[i] != ch[j]) fail("numtostr() writes before output");
for (i = 0; i < 8; ++i) if (buf[i + NUMTOSTR_LEN + 8] != ch[j]) fail("numtostr() writes after output");
for (i = 0; i < sizeof buf; ++i) buf[i] = ch[j];
numtostr(buf + 8, llmaxnum);
for (i = 0; i < 8; ++i) if (buf[i] != ch[j]) fail("numtostr() writes before output");
for (i = 0; i < 8; ++i) if (buf[i + NUMTOSTR_LEN + 8] != ch[j]) fail("numtostr() writes after output");
}
}
static void test_minmax(void) {
const char *llmax;
const char *llmin;
long long llmaxnum;
long long llminnum;
char *x;
long long numlen = sizeof(long long);
if (numlen == 16) {
llmax = "170141183460469231731687303715884105727";
llmin = "-170141183460469231731687303715884105728";
llmaxnum = int128max();
llminnum = -llmaxnum - 1LL;
}
else if (numlen == 8) {
llmax = "9223372036854775807";
llmin = "-9223372036854775808";
llmaxnum = 9223372036854775807LL;
llminnum = -llmaxnum - 1LL;
}
else {
fail("unsupported size for 'num'");
}
x = numtostr(0, llmaxnum);
if (strcmp(x, llmax)) fail("numtostr() failure");
x = numtostr(0, llminnum);
if (strcmp(x, llmin)) fail("numtostr() failure");
}
struct vectors {
long long num;
const char *strnum;
} testvectors[] = {
{ -100, "-100" },
{ -99, "-99" },
{ -98, "-98" },
{ -97, "-97" },
{ -96, "-96" },
{ -95, "-95" },
{ -94, "-94" },
{ -93, "-93" },
{ -92, "-92" },
{ -91, "-91" },
{ -90, "-90" },
{ -89, "-89" },
{ -88, "-88" },
{ -87, "-87" },
{ -86, "-86" },
{ -85, "-85" },
{ -84, "-84" },
{ -83, "-83" },
{ -82, "-82" },
{ -81, "-81" },
{ -80, "-80" },
{ -79, "-79" },
{ -78, "-78" },
{ -77, "-77" },
{ -76, "-76" },
{ -75, "-75" },
{ -74, "-74" },
{ -73, "-73" },
{ -72, "-72" },
{ -71, "-71" },
{ -70, "-70" },
{ -69, "-69" },
{ -68, "-68" },
{ -67, "-67" },
{ -66, "-66" },
{ -65, "-65" },
{ -64, "-64" },
{ -63, "-63" },
{ -62, "-62" },
{ -61, "-61" },
{ -60, "-60" },
{ -59, "-59" },
{ -58, "-58" },
{ -57, "-57" },
{ -56, "-56" },
{ -55, "-55" },
{ -54, "-54" },
{ -53, "-53" },
{ -52, "-52" },
{ -51, "-51" },
{ -50, "-50" },
{ -49, "-49" },
{ -48, "-48" },
{ -47, "-47" },
{ -46, "-46" },
{ -45, "-45" },
{ -44, "-44" },
{ -43, "-43" },
{ -42, "-42" },
{ -41, "-41" },
{ -40, "-40" },
{ -39, "-39" },
{ -38, "-38" },
{ -37, "-37" },
{ -36, "-36" },
{ -35, "-35" },
{ -34, "-34" },
{ -33, "-33" },
{ -32, "-32" },
{ -31, "-31" },
{ -30, "-30" },
{ -29, "-29" },
{ -28, "-28" },
{ -27, "-27" },
{ -26, "-26" },
{ -25, "-25" },
{ -24, "-24" },
{ -23, "-23" },
{ -22, "-22" },
{ -21, "-21" },
{ -20, "-20" },
{ -19, "-19" },
{ -18, "-18" },
{ -17, "-17" },
{ -16, "-16" },
{ -15, "-15" },
{ -14, "-14" },
{ -13, "-13" },
{ -12, "-12" },
{ -11, "-11" },
{ -10, "-10" },
{ -9, "-9" },
{ -8, "-8" },
{ -7, "-7" },
{ -6, "-6" },
{ -5, "-5" },
{ -4, "-4" },
{ -3, "-3" },
{ -2, "-2" },
{ -1, "-1" },
{ 0, "0" },
{ 1, "1" },
{ 2, "2" },
{ 3, "3" },
{ 4, "4" },
{ 5, "5" },
{ 6, "6" },
{ 7, "7" },
{ 8, "8" },
{ 9, "9" },
{ 10, "10" },
{ 11, "11" },
{ 12, "12" },
{ 13, "13" },
{ 14, "14" },
{ 15, "15" },
{ 16, "16" },
{ 17, "17" },
{ 18, "18" },
{ 19, "19" },
{ 20, "20" },
{ 21, "21" },
{ 22, "22" },
{ 23, "23" },
{ 24, "24" },
{ 25, "25" },
{ 26, "26" },
{ 27, "27" },
{ 28, "28" },
{ 29, "29" },
{ 30, "30" },
{ 31, "31" },
{ 32, "32" },
{ 33, "33" },
{ 34, "34" },
{ 35, "35" },
{ 36, "36" },
{ 37, "37" },
{ 38, "38" },
{ 39, "39" },
{ 40, "40" },
{ 41, "41" },
{ 42, "42" },
{ 43, "43" },
{ 44, "44" },
{ 45, "45" },
{ 46, "46" },
{ 47, "47" },
{ 48, "48" },
{ 49, "49" },
{ 50, "50" },
{ 51, "51" },
{ 52, "52" },
{ 53, "53" },
{ 54, "54" },
{ 55, "55" },
{ 56, "56" },
{ 57, "57" },
{ 58, "58" },
{ 59, "59" },
{ 60, "60" },
{ 61, "61" },
{ 62, "62" },
{ 63, "63" },
{ 64, "64" },
{ 65, "65" },
{ 66, "66" },
{ 67, "67" },
{ 68, "68" },
{ 69, "69" },
{ 70, "70" },
{ 71, "71" },
{ 72, "72" },
{ 73, "73" },
{ 74, "74" },
{ 75, "75" },
{ 76, "76" },
{ 77, "77" },
{ 78, "78" },
{ 79, "79" },
{ 80, "80" },
{ 81, "81" },
{ 82, "82" },
{ 83, "83" },
{ 84, "84" },
{ 85, "85" },
{ 86, "86" },
{ 87, "87" },
{ 88, "88" },
{ 89, "89" },
{ 90, "90" },
{ 91, "91" },
{ 92, "92" },
{ 93, "93" },
{ 94, "94" },
{ 95, "95" },
{ 96, "96" },
{ 97, "97" },
{ 98, "98" },
{ 99, "99" },
{ 100, "100" },
{ -9223372036854775808LL, "-9223372036854775808" },
{ -9223372036854775807LL, "-9223372036854775807" },
{ -9223372036854775806LL, "-9223372036854775806" },
{ -9223372036854775805LL, "-9223372036854775805" },
{ -9223372036854775804LL, "-9223372036854775804" },
{ -9223372036854775803LL, "-9223372036854775803" },
{ -9223372036854775802LL, "-9223372036854775802" },
{ -9223372036854775801LL, "-9223372036854775801" },
{ -9223372036854775800LL, "-9223372036854775800" },
{ -9223372036854775799LL, "-9223372036854775799" },
{ -9223372036854775798LL, "-9223372036854775798" },
{ -9223372036854775797LL, "-9223372036854775797" },
{ -9223372036854775796LL, "-9223372036854775796" },
{ -9223372036854775795LL, "-9223372036854775795" },
{ -9223372036854775794LL, "-9223372036854775794" },
{ -9223372036854775793LL, "-9223372036854775793" },
{ -9223372036854775792LL, "-9223372036854775792" },
{ -9223372036854775791LL, "-9223372036854775791" },
{ -9223372036854775790LL, "-9223372036854775790" },
{ -9223372036854775789LL, "-9223372036854775789" },
{ -9223372036854775788LL, "-9223372036854775788" },
{ -9223372036854775787LL, "-9223372036854775787" },
{ -9223372036854775786LL, "-9223372036854775786" },
{ -9223372036854775785LL, "-9223372036854775785" },
{ -9223372036854775784LL, "-9223372036854775784" },
{ -9223372036854775783LL, "-9223372036854775783" },
{ -9223372036854775782LL, "-9223372036854775782" },
{ -9223372036854775781LL, "-9223372036854775781" },
{ 9223372036854775780LL, "9223372036854775780" },
{ 9223372036854775781LL, "9223372036854775781" },
{ 9223372036854775782LL, "9223372036854775782" },
{ 9223372036854775783LL, "9223372036854775783" },
{ 9223372036854775784LL, "9223372036854775784" },
{ 9223372036854775785LL, "9223372036854775785" },
{ 9223372036854775786LL, "9223372036854775786" },
{ 9223372036854775787LL, "9223372036854775787" },
{ 9223372036854775788LL, "9223372036854775788" },
{ 9223372036854775789LL, "9223372036854775789" },
{ 9223372036854775790LL, "9223372036854775790" },
{ 9223372036854775791LL, "9223372036854775791" },
{ 9223372036854775792LL, "9223372036854775792" },
{ 9223372036854775793LL, "9223372036854775793" },
{ 9223372036854775794LL, "9223372036854775794" },
{ 9223372036854775795LL, "9223372036854775795" },
{ 9223372036854775796LL, "9223372036854775796" },
{ 9223372036854775797LL, "9223372036854775797" },
{ 9223372036854775798LL, "9223372036854775798" },
{ 9223372036854775799LL, "9223372036854775799" },
{ 9223372036854775800LL, "9223372036854775800" },
{ 9223372036854775801LL, "9223372036854775801" },
{ 9223372036854775802LL, "9223372036854775802" },
{ 9223372036854775803LL, "9223372036854775803" },
{ 9223372036854775804LL, "9223372036854775804" },
{ 9223372036854775805LL, "9223372036854775805" },
{ 9223372036854775806LL, "9223372036854775806" },
{ 9223372036854775807LL, "9223372036854775807" },
{ 0, 0 }
};
static void test_vector(void) {
long long i;
char *x;
for (i = 0; testvectors[i].strnum; ++i) {
x = numtostr(0, testvectors[i].num);
if (strcmp(x, testvectors[i].strnum)) fail("numtostr() failure");
}
}
int main(void) {
test_bufferoverflow();
test_minmax();
test_vector();
_exit(0);
}
tinyssh-20190101/tinyssh-tests/opentest.c 0000664 0000000 0000000 00000002260 13412736503 0020324 0 ustar 00root root 0000000 0000000 /*
20140410
Jan Mojzis
Public domain.
*/
#include
#include
#include "run.h"
#include "fail.h"
#include "open.h"
static void cat(void) {
char *catcmd[2] = { (char *)"cat", 0 };
execvp(*catcmd, catcmd);
}
/* test if close-on-exec works for open_read() */
static void test1(void) {
int fd;
close(0);
fd = open_read("opentest.c");
if (fd != 0) fail("unable to open opentest.c for reading");
cat();
}
/* test if close-on-exec works for open_write() */
static void test2(void) {
int fd;
close(1);
fd = open_write("opentest.data");
if (fd != 1) fail("unable to open opentest.data for writing");
cat();
}
/* test if close-on-exec works for open_pipe() */
static void test3(void) {
int fd, pi[2];
close(0);
close(1);
fd = open_pipe(pi);
if (fd == -1) fail("unable to open pipe");
if (pi[0] != 0) fail("unable to open pipe");
if (pi[1] != 1) fail("unable to open pipe");
cat();
}
/* dummy test */
static void testdummy(void) {
_exit(0);
}
int main(void) {
alarm(10);
run_mustfail(test1);
run_mustfail(test2);
run_mustfail(test3);
run_mustpass(testdummy);
_exit(0);
}
tinyssh-20190101/tinyssh-tests/packet_authtest.c 0000777 0000000 0000000 00000000000 13412736503 0024050 2emptytest.c ustar 00root root 0000000 0000000 tinyssh-20190101/tinyssh-tests/packet_channel_opentest.c 0000777 0000000 0000000 00000000000 13412736503 0025540 2emptytest.c ustar 00root root 0000000 0000000 tinyssh-20190101/tinyssh-tests/packet_channel_recvtest.c 0000777 0000000 0000000 00000000000 13412736503 0025536 2emptytest.c ustar 00root root 0000000 0000000 tinyssh-20190101/tinyssh-tests/packet_channel_requesttest.c 0000777 0000000 0000000 00000000000 13412736503 0026267 2emptytest.c ustar 00root root 0000000 0000000 tinyssh-20190101/tinyssh-tests/packet_channel_sendtest.c 0000777 0000000 0000000 00000000000 13412736503 0025530 2emptytest.c ustar 00root root 0000000 0000000 tinyssh-20190101/tinyssh-tests/packet_gettest.c 0000777 0000000 0000000 00000000000 13412736503 0023666 2emptytest.c ustar 00root root 0000000 0000000 tinyssh-20190101/tinyssh-tests/packet_hellotest.c 0000777 0000000 0000000 00000000000 13412736503 0024212 2emptytest.c ustar 00root root 0000000 0000000 tinyssh-20190101/tinyssh-tests/packet_kexdhtest.c 0000777 0000000 0000000 00000000000 13412736503 0024212 2emptytest.c ustar 00root root 0000000 0000000 tinyssh-20190101/tinyssh-tests/packet_kextest.c 0000777 0000000 0000000 00000000000 13412736503 0023676 2emptytest.c ustar 00root root 0000000 0000000 tinyssh-20190101/tinyssh-tests/packet_puttest.c 0000777 0000000 0000000 00000000000 13412736503 0023717 2emptytest.c ustar 00root root 0000000 0000000 tinyssh-20190101/tinyssh-tests/packet_recvtest.c 0000777 0000000 0000000 00000000000 13412736503 0024046 2emptytest.c ustar 00root root 0000000 0000000 tinyssh-20190101/tinyssh-tests/packet_sendtest.c 0000777 0000000 0000000 00000000000 13412736503 0024040 2emptytest.c ustar 00root root 0000000 0000000 tinyssh-20190101/tinyssh-tests/packet_unimplementedtest.c 0000777 0000000 0000000 00000000000 13412736503 0025755 2emptytest.c ustar 00root root 0000000 0000000 tinyssh-20190101/tinyssh-tests/packetparsertest.c 0000664 0000000 0000000 00000011314 13412736503 0022047 0 ustar 00root root 0000000 0000000 /*
20140303
Jan Mojzis
Public domain.
*/
#include
#include "run.h"
#include "fail.h"
#include "byte.h"
#include "packetparser.h"
/*
checks packetparser_uint8(), packetparser_uint32() function
and packetparser_end called more than once
*/
static void test1(void) {
unsigned char buf[4];
crypto_uint8 ch;
crypto_uint32 u;
long long i, pos = 0;
byte_copy(buf, 4, "abcd");
/* uint8 */
pos = 0;
for (i = 0; i < sizeof buf; ++i) {
pos = packetparser_uint8(buf, sizeof buf, pos, &ch);
if (ch != buf[i]) fail("failure");
}
if (pos != sizeof buf) fail("failure");
/* uint32 */
pos = 0;
pos = packetparser_uint8(buf, sizeof buf, 0, &ch);
pos = packetparser_uint32(buf, sizeof buf, 0, &u);
if (pos != sizeof buf) fail("failure");
pos = packetparser_end(buf, sizeof buf, pos);
pos = packetparser_end(buf, sizeof buf, pos);
pos = packetparser_end(buf, sizeof buf, pos);
}
/* checks if packetparser_skip() skips 0 bytes */
static void test2(void) {
unsigned char buf[5];
crypto_uint8 ch;
crypto_uint32 len;
long long i, pos = 0;
for (i = 0; i < sizeof buf; ++i) buf[i] = 0;
pos = packetparser_uint32(buf, sizeof buf, pos, &len);
if (len != 0) fail("failure");
pos = packetparser_skip(buf, sizeof buf, pos, len);
pos = packetparser_uint8(buf, sizeof buf, pos, &ch);
if (ch) fail("failure");
if (pos != sizeof buf) fail("failure");
pos = packetparser_end(buf, sizeof buf, pos);
pos = packetparser_end(buf, sizeof buf, pos);
pos = packetparser_end(buf, sizeof buf, pos);
}
/* checks if packetparser_copy() accepts 0 bytes */
static void test4(void) {
unsigned char buf[5];
unsigned char buf2[6];
crypto_uint8 ch;
crypto_uint32 len;
long long i, pos = 0;
for (i = 0; i < sizeof buf; ++i) buf[i] = 0;
pos = packetparser_uint32(buf, sizeof buf, pos, &len);
if (len != 0) fail("failure");
pos = packetparser_copy(buf, sizeof buf, pos, buf2, len);
pos = packetparser_uint8(buf, sizeof buf, pos, &ch);
if (ch) fail("failure");
if (pos != sizeof buf) fail("failure");
pos = packetparser_end(buf, sizeof buf, pos);
pos = packetparser_end(buf, sizeof buf, pos);
pos = packetparser_end(buf, sizeof buf, pos);
}
/* packetparser_skip() overflow */
static void _test3a(void) {
unsigned char buf[5];
long long pos = 0;
pos = packetparser_skip(buf, sizeof buf, pos, 6);
}
static void _test3aa(void) {
unsigned char buf[5];
long long len, pos;
len = pos = 9223372036854775807LL;
pos = packetparser_skip(buf, len, pos, 1);
}
/* packetparser_uint32() overflow */
static void _test3b(void) {
unsigned char buf[3];
crypto_uint32 u;
long long pos = 0;
pos = packetparser_uint32(buf, sizeof buf, pos, &u);
}
static void _test3bb(void) {
unsigned char buf[4];
crypto_uint32 u;
long long len, pos;
len = pos = 9223372036854775807LL;
pos = packetparser_uint32(buf, len, pos, &u);
}
/* packetparser_uint8() overflow */
static void _test3c(void) {
unsigned char buf[3];
crypto_uint8 ch;
long long pos = 0;
pos = packetparser_uint8(buf, sizeof buf, pos, &ch);
pos = packetparser_uint8(buf, sizeof buf, pos, &ch);
pos = packetparser_uint8(buf, sizeof buf, pos, &ch);
pos = packetparser_uint8(buf, sizeof buf, pos, &ch);
}
static void _test3cc(void) {
unsigned char buf[3];
crypto_uint8 ch;
long long len, pos;
len = pos = 9223372036854775807LL;
pos = packetparser_uint8(buf, len, pos, &ch);
}
/* packetparser_copy() overflow */
static void _test3d(void) {
unsigned char buf1[10];
unsigned char buf2[11];
long long pos = 0;
pos = packetparser_copy(buf1, sizeof buf1, pos, buf2, sizeof buf2);
}
static void _test3dd(void) {
unsigned char buf1[10];
unsigned char buf2[10];
long long len, pos;
len = pos = 9223372036854775807LL;
pos = packetparser_copy(buf1, len, pos, buf2, sizeof buf2);
}
/* packetparser_end() failure */
static void _test3e(void) {
unsigned char buf[1];
packetparser_end(buf, 0, 1);
}
static void _test3ee(void) {
unsigned char buf[1];
long long pos = 9223372036854775807LL;
packetparser_end(buf, pos, pos);
}
static void test3(void) {
run_mustfail(_test3a);
run_mustfail(_test3aa);
run_mustfail(_test3b);
run_mustfail(_test3bb);
run_mustfail(_test3c);
run_mustfail(_test3cc);
run_mustfail(_test3d);
run_mustfail(_test3dd);
run_mustfail(_test3e);
run_mustfail(_test3ee);
}
/* dummy test */
static void testdummy(void) {
_exit(0);
}
int main(void) {
test1();
test2();
test3();
test4();
run_mustpass(testdummy);
_exit(0);
}
tinyssh-20190101/tinyssh-tests/packettest.c 0000777 0000000 0000000 00000000000 13412736503 0023027 2emptytest.c ustar 00root root 0000000 0000000 tinyssh-20190101/tinyssh-tests/porttostrtest.c 0000664 0000000 0000000 00000004605 13412736503 0021450 0 ustar 00root root 0000000 0000000 /*
20140201
Jan Mojzis
Public domain.
*/
#include
#include
#include "fail.h"
#include "porttostr.h"
#include "crypto_uint16.h"
static void porttostr_bufferoverflow(void) {
char buf[PORTTOSTR_LEN + 16];
long long i, j;
unsigned char port[2] = { 5, 5 };
char ch[2] = {0x00, (char)0xff };
if ((PORTTOSTR_LEN) < sizeof("65535")) fail("PORTTOSTR_LEN too small");
for (j = 0; j < 2; ++j) {
for (i = 0; i < sizeof buf; ++i) buf[i] = ch[j];
porttostr(buf + 8, port);
for (i = 0; i < 8; ++i) if (buf[i] != ch[j]) fail("porttostr writes before output");
for (i = 0; i < 8; ++i) if (buf[i + PORTTOSTR_LEN + 8] != ch[j]) fail("porttostr writes after output");
}
}
static struct vectors {
const char *port;
const char *portstr;
} testvectors[] = {
{ "\377\377", "65535" },
{ "\000\000", "0\0\0\0\0" },
{ 0, 0 }
};
static void porttostr_testvectors(void) {
char *x, *y, *z;
long long i, j;
char buf[PORTTOSTR_LEN];
for (i = 0; testvectors[i].port; ++i) {
for (j = 0; j < sizeof buf; ++j) buf[j] = (char)0xff;
x = porttostr(buf, (unsigned char *)testvectors[i].port);
y = porttostr(0, (unsigned char *)testvectors[i].port);
z = (char *)testvectors[i].portstr;
for (j = 0; j < PORTTOSTR_LEN; ++j) {
if (buf[j] != z[j]) fail("bad output");
if (x[j] != z[j]) fail("bad output");
if (y[j] != z[j]) fail("bad output");
}
}
}
static void packport(unsigned char *y, crypto_uint16 x) {
y[1] = x & 255; x >>= 8;
y[0] = x & 255;
}
static void porttostr_full(void) {
long long i, j;
unsigned char port[2];
char *x, *y;
char buf[PORTTOSTR_LEN];
char buf2[PORTTOSTR_LEN + 10];
for (i = 0; i < 65536; ++i) {
for (j = 0; j < sizeof buf; ++j) buf[j] = (char)0xff;
for (j = 0; j < sizeof buf; ++j) buf2[j] = 0;
packport(port, i);
x = porttostr(buf, port);
y = porttostr(0, port);
snprintf(buf2, sizeof buf2, "%lld", i);
for (j = 0; j < PORTTOSTR_LEN; ++j) {
if (buf[j] != buf2[j]) fail("bad output");
if (x[j] != buf2[j]) fail("bad output");
if (y[j] != buf2[j]) fail("bad output");
}
}
}
int main(void) {
porttostr_bufferoverflow();
porttostr_testvectors();
porttostr_full();
_exit(0);
}
tinyssh-20190101/tinyssh-tests/randommodtest.c 0000664 0000000 0000000 00000001054 13412736503 0021343 0 ustar 00root root 0000000 0000000 /*
20140416
Jan Mojzis
Public domain.
*/
#include
#include
#include "fail.h"
#include "randommod.h"
int main(void) {
long long i, r;
if (randommod(-1) != 0) fail("failure");
if (randommod(0) != 0) fail("failure");
if (randommod(1) != 0) fail("failure");
for (i = 2; i < 10; ++i) {
r = randommod(i);
if (r > i - 1 || r < 0) fail("failure");
}
for (i = 18014398509481984ULL; i < 18014398509481994ULL; ++i) {
if (randommod(i) == randommod(i)) fail("failure");
}
_exit(0);
}
tinyssh-20190101/tinyssh-tests/readalltest.c 0000664 0000000 0000000 00000001454 13412736503 0020773 0 ustar 00root root 0000000 0000000 /*
20140417
Jan Mojzis
Public domain.
*/
#include
#include
#include
#include
#include "fail.h"
#include "open.h"
#include "randombytes.h"
#include "byte.h"
#include "readall.h"
#include "writeall.h"
#define SPACELEN 1048577
unsigned char space1[SPACELEN];
unsigned char space2[SPACELEN];
static void test1(void) {
int fd;
fd = open_write("readall.data");
if (fd == -1) fail("failure");
randombytes(space1, sizeof space1);
if (writeall(fd, space1, sizeof space1) == -1) fail("failure");
close(fd);
fd = open_read("readall.data");
if (readall(fd, space2, sizeof space2) == -1) fail("failure");
close(fd);
if (!byte_isequal(space1, SPACELEN, space2)) fail("failure");
}
int main(void) {
test1();
_exit(0);
}
tinyssh-20190101/tinyssh-tests/run.h 0000664 0000000 0000000 00000006420 13412736503 0017276 0 ustar 00root root 0000000 0000000 #ifndef _RUN_H____
#define _RUN_H____
#include
#include
#include
#include
#include "fail.h"
static void _run_mustfail(const char *file, unsigned long long line, void (*op)(void)) {\
\
pid_t pid; \
int status; \
\
pid = fork(); \
if (pid == -1) fail_(file, line, "unable to fork"); \
\
if (pid == 0) { \
close(2); \
op(); \
_exit(0); \
} \
\
while (waitpid(pid, &status, 0) != pid) {}; \
if (!WIFEXITED(status)) fail_(file, line, "process killed"); \
if (!WEXITSTATUS(status)) fail_(file, line, "process exited with status = 0"); \
}
static void _run_mustpass(const char *file, unsigned long long line, void (*op)(void)) {\
\
pid_t pid; \
int status; \
\
pid = fork(); \
if (pid == -1) fail_(file, line, "unable to fork"); \
\
if (pid == 0) { \
close(2); \
op(); \
_exit(111); \
} \
\
while (waitpid(pid, &status, 0) != pid) {}; \
if (!WIFEXITED(status)) fail_(file, line, "process killed"); \
if (WEXITSTATUS(status)) fail_(file, line, "process exited with status != 0"); \
}
#define run_mustfail(x) _run_mustfail(__FILE__, __LINE__, (x));
#define run_mustpass(x) _run_mustpass(__FILE__, __LINE__, (x));
#endif
tinyssh-20190101/tinyssh-tests/savesynctest.c 0000664 0000000 0000000 00000001330 13412736503 0021213 0 ustar 00root root 0000000 0000000 /*
20140417
Jan Mojzis
Public domain.
*/
#include
#include
#include
#include
#include "fail.h"
#include "randombytes.h"
#include "byte.h"
#include "load.h"
#include "savesync.h"
#include "writeall.h"
#define SPACELEN 1048577
unsigned char space1[SPACELEN];
unsigned char space2[SPACELEN];
static void test1(void) {
randombytes(space1, sizeof space1);
if (savesync("savesynctest.data", space1, sizeof space1) == -1) fail("savesync() failure");
if (load("savesynctest.data", space2, sizeof space2) == -1) fail("load() failure");
if (!byte_isequal(space1, SPACELEN, space2)) fail("load()/savesync() failure");
}
int main(void) {
test1();
_exit(0);
}
tinyssh-20190101/tinyssh-tests/sshcrypto_cipher_chachapolytest.c 0000777 0000000 0000000 00000000000 13412736503 0027343 2emptytest.c ustar 00root root 0000000 0000000 tinyssh-20190101/tinyssh-tests/sshcrypto_ciphertest.c 0000777 0000000 0000000 00000000000 13412736503 0025150 2emptytest.c ustar 00root root 0000000 0000000 tinyssh-20190101/tinyssh-tests/sshcrypto_kex_curve25519test.c 0000777 0000000 0000000 00000000000 13412736503 0026277 2emptytest.c ustar 00root root 0000000 0000000 tinyssh-20190101/tinyssh-tests/sshcrypto_kex_sntrup4591761x25519test.c 0000777 0000000 0000000 00000000000 13412736503 0027457 2emptytest.c ustar 00root root 0000000 0000000 tinyssh-20190101/tinyssh-tests/sshcrypto_kextest.c 0000777 0000000 0000000 00000000000 13412736503 0024465 2emptytest.c ustar 00root root 0000000 0000000 tinyssh-20190101/tinyssh-tests/sshcrypto_key_ed25519test.c 0000777 0000000 0000000 00000000000 13412736503 0025544 2emptytest.c ustar 00root root 0000000 0000000 tinyssh-20190101/tinyssh-tests/sshcrypto_keytest.c 0000777 0000000 0000000 00000000000 13412736503 0024466 2emptytest.c ustar 00root root 0000000 0000000 tinyssh-20190101/tinyssh-tests/sshcryptotest.c 0000664 0000000 0000000 00000002104 13412736503 0021416 0 ustar 00root root 0000000 0000000 /*
20140417
Jan Mojzis
Public domain.
*/
#include
#include "sshcrypto.h"
/* grep "define sshcrypto_" source/tinyssh/sshcrypto.h | cut -d ' ' -f2 | while read x; do echo \#ifndef $x; echo error! ;echo \#endif; done */
#ifndef sshcrypto_kem_PUBLICKEYMAX
error!
#endif
#ifndef sshcrypto_kem_CIPHERTEXTMAX
error!
#endif
#ifndef sshcrypto_kem_MAX
error!
#endif
#ifndef sshcrypto_hash_MAX
error!
#endif
#ifndef sshcrypto_sign_PUBLICKEYMAX
error!
#endif
#ifndef sshcrypto_sign_SECRETKEYMAX
error!
#endif
#ifndef sshcrypto_sign_MAX
error!
#endif
#ifndef sshcrypto_sign_BASE64PUBLICKEYMAX
error!
#endif
#ifndef sshcrypto_sign_BASE64PUBLICKEYMIN
error!
#endif
#ifndef sshcrypto_cipher_KEYMAX
error!
#endif
int main(void) {
/* check sshcrypto_init() called called more than once */
sshcrypto_init();
sshcrypto_init();
/* check sshcrypto_purge() called called more than once */
sshcrypto_purge();
sshcrypto_purge();
/* check sshcrypto_init() called called more than once after sshcrypto_purge() */
sshcrypto_init();
sshcrypto_init();
_exit(0);
}
tinyssh-20190101/tinyssh-tests/sshtest.c 0000664 0000000 0000000 00000003450 13412736503 0020162 0 ustar 00root root 0000000 0000000 /*
20140319
Jan Mojzis
Public domain.
*/
#include
#include
#include
#include "fail.h"
#include "ssh.h"
/*
grep SSH_ * | sed 's/.*SSH_/SSH_/g' | cut -d ',' -f1 | cut -d ' ' -f1 | cut -d ')' -f1 | cut -d ':' -f1 | cut -d '"' -f1 | cut -d ';' -f1 | sort -u | grep -v 'SSH_TTY\|SSH_CONNECTION'| while read x; do echo \#ifndef $x; echo error! ;echo \#endif; done
*/
#ifndef SSH_MSG_CHANNEL_CLOSE
error!
#endif
#ifndef SSH_MSG_CHANNEL_DATA
error!
#endif
#ifndef SSH_MSG_CHANNEL_EOF
error!
#endif
#ifndef SSH_MSG_CHANNEL_EXTENDED_DATA
error!
#endif
#ifndef SSH_MSG_CHANNEL_OPEN
error!
#endif
#ifndef SSH_MSG_CHANNEL_OPEN_CONFIRMATION
error!
#endif
#ifndef SSH_MSG_CHANNEL_OPEN_FAILURE
error!
#endif
#ifndef SSH_MSG_CHANNEL_REQUEST
error!
#endif
#ifndef SSH_MSG_CHANNEL_SUCCESS
error!
#endif
#ifndef SSH_MSG_CHANNEL_WINDOW_ADJUST
error!
#endif
#ifndef SSH_MSG_DEBUG
error!
#endif
#ifndef SSH_MSG_DISCONNECT
error!
#endif
#ifndef SSH_MSG_IGNORE
error!
#endif
#ifndef SSH_MSG_KEXDH_INIT
error!
#endif
#ifndef SSH_MSG_KEXDH_REPLY
error!
#endif
#ifndef SSH_MSG_KEXINIT
error!
#endif
#ifndef SSH_MSG_NEWKEYS
error!
#endif
#ifndef SSH_MSG_SERVICE_ACCEPT
error!
#endif
#ifndef SSH_MSG_SERVICE_REQUEST
error!
#endif
#ifndef SSH_MSG_UNIMPLEMENTED
error!
#endif
#ifndef SSH_MSG_USERAUTH_FAILURE
error!
#endif
#ifndef SSH_MSG_USERAUTH_PK_OK
error!
#endif
#ifndef SSH_MSG_USERAUTH_REQUEST
error!
#endif
#ifndef SSH_MSG_USERAUTH_SUCCESS
error!
#endif
#ifndef SSH_OPEN_ADMINISTRATIVELY_PROHIBITED
error!
#endif
int main(void) {
if (strcmp(ssh_sigstr(SIGTERM), "TERM")) fail("failure")
if (strcmp(ssh_sigstrlong(SIGTERM), "SIGTERM (termination)")) fail("failure")
if (strcmp(ssh_sigstr(-1), "UNKNOWN")) fail("failure")
if (strcmp(ssh_sigstrlong(-1), "UNKNOWN SIGNAL")) fail("failure")
_exit(0);
}
tinyssh-20190101/tinyssh-tests/stringparsertest.c 0000664 0000000 0000000 00000004022 13412736503 0022104 0 ustar 00root root 0000000 0000000 /*
20140204
Jan Mojzis
Public domain.
*/
#include
#include
#include "fail.h"
#include "str.h"
#include "byte.h"
#include "stringparser.h"
static struct vectors {
const char *buf;
} testvectors[] = {
{ "aaa,bb,c" },
{ ",aaa,bb,c" },
{ "aaa,bb,c," },
{ "aaa,,,,bb,,,,c" },
{ ",,,aaa,,,,bb,,,,c" },
{ ",,,aaa,,,,bb,,,,c,,," },
{ "aaa,bb,,c," },
{ 0 }
};
static void stringstringparser_test1(void) {
unsigned char *buf;
long long i, pos = 0;
unsigned char *x;
long long xlen, len;
for (i = 0; testvectors[i].buf; ++i) {
buf = (unsigned char *)testvectors[i].buf;
len = str_len(testvectors[i].buf);
pos = 0;
pos = stringparser(buf, len, pos, &x, &xlen); if (!pos) fail("parsing error");
if (xlen != 3) fail("parsing error");
if (!byte_isequal(x, xlen, "aaa")) fail("parsing error");
pos = stringparser(buf, len, pos, &x, &xlen); if (!pos) fail("parsing error");
if (xlen != 2) fail("parsing error");
if (!byte_isequal(x, xlen, "bb")) fail("parsing error");
pos = stringparser(buf, len, pos, &x, &xlen); if (!pos) fail("parsing error");
if (xlen != 1) fail("parsing error");
if (!byte_isequal(x, xlen, "c")) fail("parsing error");
if (stringparser(buf, len, pos, &x, &xlen)) fail("overflow");
}
}
static void stringstringparser_test2(void) {
unsigned char *buf;
long long pos = 0;
unsigned char *x;
long long xlen, len;
buf = (unsigned char *)"";
len = str_len((char *)buf);
pos = 0;
if (stringparser(buf, len, pos, &x, &xlen)) fail("overflow");
buf = (unsigned char *)",";
len = str_len((char *)buf);
pos = 0;
if (stringparser(buf, len, pos, &x, &xlen)) fail("overflow");
buf = (unsigned char *)",,,,,,,,";
len = str_len((char *)buf);
pos = 0;
if (stringparser(buf, len, pos, &x, &xlen)) fail("overflow");
}
int main(void) {
stringstringparser_test1();
stringstringparser_test2();
_exit(0);
}
tinyssh-20190101/tinyssh-tests/strtest.c 0000664 0000000 0000000 00000005635 13412736503 0020204 0 ustar 00root root 0000000 0000000 /*
20130610
Jan Mojzis
Public domain.
*/
#include
#include
#include
#include "fail.h"
#include "str.h"
static void test_len(void) {
if (str_len("") != 0) fail("str_len return's bad length");
if (str_len("\0ahoj") != 0) fail("str_len return's bad length");
if (str_len("a\0hoj") != 1) fail("str_len return's bad length");
if (str_len("ahoj\0") != 4) fail("str_len return's bad length");
if (str_len("ahoj") != 4) fail("str_len return's bad length");
}
static void test_start(void) {
if (!str_start("","")) fail("str_start failure");
if (!str_start("x","")) fail("str_start failure");
if (str_start("","x")) fail("str_start failure");
if (!str_start("ahojx","ahoj")) fail("str_start failure");
if (str_start("ahoj","ahojx")) fail("str_start failure");
}
static void test_equal(void) {
#ifdef TODO
/* equal */
if (!str_equal("","")) fail("str_equal failure");
if (!str_equal("\0","\0")) fail("str_equal failure");
if (!str_equal("","\0")) fail("str_equal failure");
if (!str_equal("\0","")) fail("str_equal failure");
if (!str_equal("ahoj","ahoj")) fail("str_equal failure");
if (!str_equal("ahoj","ahoj\0")) fail("str_equal failure");
if (!str_equal("ahoj\0","ahoj")) fail("str_equal failure");
/* not equal */
if (str_equal("x","")) fail("str_equal failure");
if (str_equal("","x")) fail("str_equal failure");
if (str_equal("xx","x")) fail("str_equal failure");
if (str_equal("x","xx")) fail("str_equal failure");
if (str_equal("ahojx","ahoj")) fail("str_equal failure");
if (str_equal("ahoj","ahojx")) fail("str_equal failure");
#endif
}
static void test_equaln(void) {
char buf[5];
/* not equal */
if (str_equaln(buf, 0, "a")) fail("str_equaln failure");
if (str_equaln("ahoj", 4, "aho")) fail("str_equaln failure");
if (str_equaln("ahoj", 4, "ahoj!")) fail("str_equaln failure");
if (str_equaln("ahoj", 4, "ahox")) fail("str_equaln failure");
/* equal */
if (!str_equaln(buf, 0, "")) fail("str_equaln failure");
if (strncmp(buf, "", 0)) fail("strncmp failure");
if (!str_equaln("ahoj", 4, "ahoj")) fail("str_equaln failure");
if (strncmp("ahoj", "ahoj", 4)) fail("strncmp failure");
}
static void test_copyn(void) {
char buf[5];
/* bad */
if (str_copyn(buf, 0, "")) fail("str_copyn failure");
if (str_copyn(buf, 1, "a")) fail("str_copyn failure");
if (str_copyn(buf, sizeof buf, "ahoj!")) fail("str_copyn failure");
if (strcmp(buf, "ahoj")) fail("str_copyn failure");
/* ok */
if (!str_copyn(buf, sizeof buf, "ahoj")) fail("str_copyn failure");
if (strcmp(buf, "ahoj")) fail("str_copyn failure");
if (!str_copyn(buf, sizeof buf, "")) fail("str_copyn failure");
if (strcmp(buf, "")) fail("str_copyn failure");
}
int main(void) {
test_len();
test_start();
test_equal();
test_equaln();
test_copyn();
_exit(0);
}
tinyssh-20190101/tinyssh-tests/subprocess_authtest.c 0000664 0000000 0000000 00000044701 13412736503 0022602 0 ustar 00root root 0000000 0000000 /*
20140321
Jan Mojzis
Public domain.
*/
#include
#include
#include
#include
#include
#include "fail.h"
#include "dropuidgid.h"
#include "savesync.h"
#include "open.h"
#include "global.h"
#include "byte.h"
#include "str.h"
#include "log.h"
#include "subprocess.h"
static int readall(int fd, unsigned char *x, long long xlen) {
long long r;
long long len = 0;
while (xlen > 0) {
r = read(fd, x, xlen);
if (r == 0) break;
if (r <= 0) return -1;
x += r;
len += r;
xlen -= r;
}
return len;
}
static unsigned char logbuf[1024];
static char globalpath[4096];
static long long globalpathlen;
static void run(void (*op)(void), const char *exp) {
pid_t pid;
int status, fromchild[2];
long long r, i;
if (pipe(fromchild) == -1) fail("pipe() failure");
pid = fork();
if (pid == -1) fail("fork() failure");
if (pid == 0) {
close(fromchild[0]);
if (dup2(fromchild[1], 2) == -1) _exit(111);
op();
_exit(0);
}
close(fromchild[1]);
r = readall(fromchild[0], logbuf, sizeof logbuf);
if (r == -1) fail("read() failure");
for (i = 0; i < r; ++i) if (logbuf[i] == '\n') break;
r = i;
for (i = 0; i < r; ++i) if (logbuf[i] == '/') break;
r -= i;
byte_copy(logbuf, r, logbuf + i);
/* fprintf(stderr, "xxx: %s\n", logbuf); fflush(stderr); */
if (r < globalpathlen + 1) fail("log error");
if (!byte_isequal(globalpath, globalpathlen, logbuf)) fail("log error");
r -= globalpathlen + 1;
byte_copy(logbuf, r, logbuf + globalpathlen + 1);
for (i = 0; i < r; ++i) if (logbuf[i] == '{') break;
r = i;
logbuf[r] = 0;
while (waitpid(pid, &status, 0) != pid) {};
if (!WIFEXITED(status)) fail("process killed");
if (WEXITSTATUS(status)) fail("process exited with status != 0");
i = str_len(exp);
if (r != i) fail("failed");
if (!byte_isequal(logbuf, i, exp)) fail("failed");
}
static int run2(void (*op)(void)) {
pid_t pid;
int status;
pid = fork();
if (pid == -1) return -1;
if (pid == 0) {
close(2);
op();
_exit(0);
}
while (waitpid(pid, &status, 0) != pid) {};
if (!WIFEXITED(status)) return -1;
return WEXITSTATUS(status);
}
static void test_usernotexist(void) {
const char *account = "21ecdfcc00506bc138d004a0c04139442e24b02ac456bf05601f1e8f645baa2";
const char *keyname = "ssh-ed25519";
const char *key = "key1";
if (subprocess_auth(account, keyname, key) == 0) fail("subprocess_auth() failure");
}
static void test_usertoolong(void) {
const char *account = "21ecdfcc00506bc138d004a0c04139442e24b02ac456bf05601f1e8f645baa25";
const char *keyname = "ssh-ed25519";
const char *key = "key1";
if (subprocess_auth(account, keyname, key) == 0) fail("subprocess_auth() failure");
}
static void test_keytooshort(void) {
const char *account = "21ecdfcc00506bc138d004a0c04139442e24b02ac456bf05601f1e8f645baa2";
const char *keyname = "ssh-ed25519";
const char *key = "AAAAC3NzaC1lZDI1NTE5AAAAICj44ZR+OCpjuLbOwqys2MKHroSvAWGgEE1o7yq+UVe";
if (subprocess_auth(account, keyname, key) == 0) fail("subprocess_auth() failure");
}
static struct passwd *pw;
static void droproot(void) {
uid_t uid;
uid = geteuid();
if (uid == 0) {
pw = getpwnam("nobody");
if (!pw) fail("getpwnam() failure")
if (!dropuidgid(pw->pw_name, pw->pw_uid, pw->pw_gid)) fail("dropuidgid() failure");
}
else {
pw = getpwuid(uid);
if (!pw) fail("getpwuid() failure")
}
if (geteuid() == 0) fail("dropuidgid() failure");
}
static void test_root(void) {
const char *account = "root";
const char *keyname = "ssh-ed25519";
const char *key = "key1";
if (subprocess_auth(account, keyname, key) == 0) fail("subprocess_auth() failure");
}
#define path global_bspace2 /* reusing global buffer */
#define buf global_bspace1 /* reusing global buffer */
static void test_path_authorizedkeys_ne(void) {
umask(000);
if (mkdir("d1", 0755) == -1) fail("mkdir() failure");
if (chdir("d1") == -1) fail("chdir() failure");
if (subprocess_auth_checkpath_((char *)path, sizeof path, geteuid())) fail("subprocess_auth_checkpath_() failure");
if (chdir("..") == -1) fail("chdir() failure");
if (rmdir("d1") == -1) fail("rmdir() failure");
}
static void test_path_authorizedkeys_fifo(void) {
umask(000);
if (mkdir("d1", 0755) == -1) fail("mkdir() failure");
if (chdir("d1") == -1) fail("chdir() failure");
if (mkfifo("authorized_keys", 0644) == -1) fail("mkfifo() failure");
if (subprocess_auth_checkpath_((char *)path, sizeof path, geteuid())) fail("subprocess_auth_checkpath_() failure");
if (unlink("authorized_keys") == -1) fail("unlink() failure");
if (chdir("..") == -1) fail("chdir() failure");
if (rmdir("d1") == -1) fail("rmdir() failure");
}
static void test_path_authorizedkeys_perm1(void) {
umask(000);
if (mkdir("d1", 0755) == -1) fail("mkdir() failure");
if (chdir("d1") == -1) fail("chdir() failure");
if (savesync("authorized_keys", "", 0) == -1) fail("savesync() failure");
if (chmod("authorized_keys", 0777) == -1) fail("chmod() failure");
if (subprocess_auth_checkpath_((char *)path, sizeof path, geteuid())) fail("subprocess_auth_checkpath_() failure");
if (unlink("authorized_keys") == -1) fail("unlink() failure");
if (chdir("..") == -1) fail("chdir() failure");
if (rmdir("d1") == -1) fail("rmdir() failure");
}
static void test_path_authorizedkeys_perm2(void) {
umask(000);
if (mkdir("d1", 0755) == -1) fail("mkdir() failure");
if (chdir("d1") == -1) fail("chdir() failure");
if (savesync("authorized_keys", "", 0) == -1) fail("savesync() failure");
if (chmod("authorized_keys", 0775) == -1) fail("chmod() failure");
if (subprocess_auth_checkpath_((char *)path, sizeof path, geteuid())) fail("subprocess_auth_checkpath_() failure");
if (unlink("authorized_keys") == -1) fail("unlink() failure");
if (chdir("..") == -1) fail("chdir() failure");
if (rmdir("d1") == -1) fail("rmdir() failure");
}
static void test_path_authorizedkeys_perm3(void) {
umask(000);
if (mkdir("d1", 0755) == -1) fail("mkdir() failure");
if (chdir("d1") == -1) fail("chdir() failure");
if (savesync("authorized_keys", "", 0) == -1) fail("savesync() failure");
if (chmod("authorized_keys", 0757) == -1) fail("chmod() failure");
if (subprocess_auth_checkpath_((char *)path, sizeof path, geteuid())) fail("subprocess_auth_checkpath_() failure");
if (unlink("authorized_keys") == -1) fail("unlink() failure");
if (chdir("..") == -1) fail("chdir() failure");
if (rmdir("d1") == -1) fail("rmdir() failure");
}
static void test_path_dir_perm1(void) {
umask(000);
if (mkdir("d1", 0775) == -1) fail("mkdir() failure");
if (chdir("d1") == -1) fail("chdir() failure");
if (savesync("authorized_keys", "", 0) == -1) fail("savesync() failure");
if (subprocess_auth_checkpath_((char *)path, sizeof path, geteuid())) fail("subprocess_auth_checkpath_() failure");
if (unlink("authorized_keys") == -1) fail("unlink() failure");
if (chdir("..") == -1) fail("chdir() failure");
if (rmdir("d1") == -1) fail("rmdir() failure");
}
static void test_path_dir_perm2(void) {
umask(000);
if (mkdir("d1", 0777) == -1) fail("mkdir() failure");
if (chdir("d1") == -1) fail("chdir() failure");
if (savesync("authorized_keys", "", 0) == -1) fail("savesync() failure");
if (subprocess_auth_checkpath_((char *)path, sizeof path, geteuid())) fail("subprocess_auth_checkpath_() failure");
if (unlink("authorized_keys") == -1) fail("unlink() failure");
if (chdir("..") == -1) fail("chdir() failure");
if (rmdir("d1") == -1) fail("rmdir() failure");
}
static void test_path_dir_perm3(void) {
umask(000);
if (mkdir("d1", 0757) == -1) fail("mkdir() failure");
if (chdir("d1") == -1) fail("chdir() failure");
if (savesync("authorized_keys", "", 0) == -1) fail("savesync() failure");
if (subprocess_auth_checkpath_((char *)path, sizeof path, geteuid())) fail("subprocess_auth_checkpath_() failure");
if (unlink("authorized_keys") == -1) fail("unlink() failure");
if (chdir("..") == -1) fail("chdir() failure");
if (rmdir("d1") == -1) fail("rmdir() failure");
}
static void test_path_dir2_perm1(void) {
umask(000);
if (mkdir("d1", 0777) == -1) fail("mkdir() failure");
if (chdir("d1") == -1) fail("chdir() failure");
if (mkdir("d2", 0777) == -1) fail("mkdir() failure");
if (chdir("d2") == -1) fail("chdir() failure");
if (savesync("authorized_keys", "", 0) == -1) fail("savesync() failure");
if (subprocess_auth_checkpath_((char *)path, sizeof path, geteuid())) fail("subprocess_auth_checkpath_() failure");
if (unlink("authorized_keys") == -1) fail("unlink() failure");
if (chdir("..") == -1) fail("chdir() failure");
if (rmdir("d2") == -1) fail("rmdir() failure");
if (chdir("..") == -1) fail("chdir() failure");
if (rmdir("d1") == -1) fail("rmdir() failure");
}
static void test_path_dir2_perm2(void) {
umask(000);
if (mkdir("d1", 0777) == -1) fail("mkdir() failure");
if (chdir("d1") == -1) fail("chdir() failure");
if (mkdir("d2", 0775) == -1) fail("mkdir() failure");
if (chdir("d2") == -1) fail("chdir() failure");
if (savesync("authorized_keys", "", 0) == -1) fail("savesync() failure");
if (subprocess_auth_checkpath_((char *)path, sizeof path, geteuid())) fail("subprocess_auth_checkpath_() failure");
if (unlink("authorized_keys") == -1) fail("unlink() failure");
if (chdir("..") == -1) fail("chdir() failure");
if (rmdir("d2") == -1) fail("rmdir() failure");
if (chdir("..") == -1) fail("chdir() failure");
if (rmdir("d1") == -1) fail("rmdir() failure");
}
static void test_path_dir2_perm3(void) {
umask(000);
if (mkdir("d1", 0777) == -1) fail("mkdir() failure");
if (chdir("d1") == -1) fail("chdir() failure");
if (mkdir("d2", 0757) == -1) fail("mkdir() failure");
if (chdir("d2") == -1) fail("chdir() failure");
if (savesync("authorized_keys", "", 0) == -1) fail("savesync() failure");
if (subprocess_auth_checkpath_((char *)path, sizeof path, geteuid())) fail("subprocess_auth_checkpath_() failure");
if (unlink("authorized_keys") == -1) fail("unlink() failure");
if (chdir("..") == -1) fail("chdir() failure");
if (rmdir("d2") == -1) fail("rmdir() failure");
if (chdir("..") == -1) fail("chdir() failure");
if (rmdir("d1") == -1) fail("rmdir() failure");
}
static void test_path_dir3_perm1(void) {
umask(000);
if (mkdir("d1", 0777) == -1) fail("mkdir() failure");
if (chdir("d1") == -1) fail("chdir() failure");
if (mkdir("d2", 0755) == -1) fail("mkdir() failure");
if (chdir("d2") == -1) fail("chdir() failure");
if (savesync("authorized_keys", "", 0) == -1) fail("savesync() failure");
if (subprocess_auth_checkpath_((char *)path, sizeof path, geteuid())) fail("subprocess_auth_checkpath_() failure");
if (unlink("authorized_keys") == -1) fail("unlink() failure");
if (chdir("..") == -1) fail("chdir() failure");
if (rmdir("d2") == -1) fail("rmdir() failure");
if (chdir("..") == -1) fail("chdir() failure");
if (rmdir("d1") == -1) fail("rmdir() failure");
}
static void test_path_dir3_perm2(void) {
umask(000);
if (mkdir("d1", 0775) == -1) fail("mkdir() failure");
if (chdir("d1") == -1) fail("chdir() failure");
if (mkdir("d2", 0755) == -1) fail("mkdir() failure");
if (chdir("d2") == -1) fail("chdir() failure");
if (savesync("authorized_keys", "", 0) == -1) fail("savesync() failure");
if (subprocess_auth_checkpath_((char *)path, sizeof path, geteuid())) fail("subprocess_auth_checkpath_() failure");
if (unlink("authorized_keys") == -1) fail("unlink() failure");
if (chdir("..") == -1) fail("chdir() failure");
if (rmdir("d2") == -1) fail("rmdir() failure");
if (chdir("..") == -1) fail("chdir() failure");
if (rmdir("d1") == -1) fail("rmdir() failure");
}
static void test_path_dir3_perm3(void) {
umask(000);
if (mkdir("d1", 0757) == -1) fail("mkdir() failure");
if (chdir("d1") == -1) fail("chdir() failure");
if (mkdir("d2", 0755) == -1) fail("mkdir() failure");
if (chdir("d2") == -1) fail("chdir() failure");
if (savesync("authorized_keys", "", 0) == -1) fail("savesync() failure");
if (subprocess_auth_checkpath_((char *)path, sizeof path, geteuid())) fail("subprocess_auth_checkpath_() failure");
if (unlink("authorized_keys") == -1) fail("unlink() failure");
if (chdir("..") == -1) fail("chdir() failure");
if (rmdir("d2") == -1) fail("rmdir() failure");
if (chdir("..") == -1) fail("chdir() failure");
if (rmdir("d1") == -1) fail("rmdir() failure");
}
static void test_path_dir_symlink(void) {
umask(000);
if (mkdir("d1", 0775) == -1) fail("mkdir() failure");
if (symlink("d1", "d2") == -1) fail("symlink() failure");
if (chdir("d2") == -1) fail("chdir() failure");
if (savesync("authorized_keys", "", 0) == -1) fail("savesync() failure");
if (subprocess_auth_checkpath_((char *)path, sizeof path, geteuid())) fail("subprocess_auth_checkpath_() failure");
if (unlink("authorized_keys") == -1) fail("unlink() failure");
if (chdir("..") == -1) fail("chdir() failure");
if (unlink("d2") == -1) fail("rmdir() failure");
if (rmdir("d1") == -1) fail("rmdir() failure");
}
static void test_authorizedkeys_ne(void) {
const char *keyname = "";
const char *key = "";
if (!getcwd((char *)path, sizeof path)) fail("getcwd() failure");
if (subprocess_auth_authorizedkeys_((char *)keyname, (char *)key, (char *)path, (char *)buf, sizeof buf))
fail("subprocess_auth_authorizedkeys_() failure");
}
#define AUTHORIZED_KEYS "\
\n\
\n\
###\n\
\n\
\n\
\n\
\n\
ssh-rsa AAAAB3Nza...LiPk== user@example.net\n\
from=\"*.sales.example.net,!pc.sales.example.net\" ssh-rsa AAAAB2...19Q== john@example.net\n\
command=\"dump /home\",no-pty,no-port-forwarding ssh-dss AAAAC3...51R== example.net\n\
permitopen=\"192.0.2.1:80\",permitopen=\"192.0.2.2:25\" ssh-dss AAAAB5...21S==\n\
tunnel=\"0\",command=\"sh /etc/netstart tun0\" ssh-rsa AAAA...== jane@example.net\n\
ecdsa-sha2-nistp256 ecdsakey1 apache@apache\n\
\n\
\n\
ssh-ed25519 badkey1 note - extra ' ' before keyname\n\
ssh-ed25519 badkey2. note - '.' as separator\n\
ssh-ed255191 badkey3\n\
ssh-ed25519\tbadkey4\n\
ssh-ed25519 badkey5\n\
\n\
\n\
ssh-ed25519 key1\n\
ssh-ed25519 key2\r\n\
ssh-ed25519 key3 note - ' ' as separator\n\
ssh-ed25519 key4\0note - '\0' as separator\n\
ssh-ed25519 key5 note - last line"
static void authorizedkeys(void) {
if (savesync("authorized_keys", AUTHORIZED_KEYS, sizeof(AUTHORIZED_KEYS) - 1) == -1) fail("savesync() failure");
}
static void test_authorizedkeys_ok(void) {
const char *keyname, *key;
if (!getcwd((char *)path, sizeof path)) fail("getcwd() failure");
keyname = "ssh-ed25519"; key = "key1";
if (!subprocess_auth_authorizedkeys_((char *)keyname, (char *)key, (char *)path, (char *)buf, sizeof buf))
fail("subprocess_auth_authorizedkeys_() failure");
keyname = "ssh-ed25519"; key = "key2";
if (!subprocess_auth_authorizedkeys_((char *)keyname, (char *)key, (char *)path, (char *)buf, sizeof buf))
fail("subprocess_auth_authorizedkeys_() failure");
keyname = "ssh-ed25519"; key = "key3";
if (!subprocess_auth_authorizedkeys_((char *)keyname, (char *)key, (char *)path, (char *)buf, sizeof buf))
fail("subprocess_auth_authorizedkeys_() failure");
keyname = "ssh-ed25519"; key = "key4";
if (!subprocess_auth_authorizedkeys_((char *)keyname, (char *)key, (char *)path, (char *)buf, sizeof buf))
fail("subprocess_auth_authorizedkeys_() failure");
keyname = "ssh-ed25519"; key = "key5";
if (!subprocess_auth_authorizedkeys_((char *)keyname, (char *)key, (char *)path, (char *)buf, sizeof buf))
fail("subprocess_auth_authorizedkeys_() failure");
}
static void test_authorizedkeys_bad(void) {
const char *keyname, *key;
if (!getcwd((char *)path, sizeof path)) fail("getcwd() failure");
keyname = "ssh-ed25519"; key = "badkey1";
if (subprocess_auth_authorizedkeys_((char *)keyname, (char *)key, (char *)path, (char *)buf, sizeof buf))
fail("subprocess_auth_authorizedkeys_() failure");
keyname = "ssh-ed25519"; key = "badkey2";
if (subprocess_auth_authorizedkeys_((char *)keyname, (char *)key, (char *)path, (char *)buf, sizeof buf))
fail("subprocess_auth_authorizedkeys_() failure");
keyname = "ssh-ed25519"; key = "badkey3";
if (subprocess_auth_authorizedkeys_((char *)keyname, (char *)key, (char *)path, (char *)buf, sizeof buf))
fail("subprocess_auth_authorizedkeys_() failure");
keyname = "ssh-ed25519"; key = "badkey4";
if (subprocess_auth_authorizedkeys_((char *)keyname, (char *)key, (char *)path, (char *)buf, sizeof buf))
fail("subprocess_auth_authorizedkeys_() failure");
keyname = "ssh-ed25519"; key = "badkey5";
if (subprocess_auth_authorizedkeys_((char *)keyname, (char *)key, (char *)path, (char *)buf, sizeof buf))
fail("subprocess_auth_authorizedkeys_() failure");
}
int main(void) {
if (!getcwd(globalpath, sizeof globalpath)) fail("getcwd() failure");
globalpathlen = str_len(globalpath);
log_init(2, "xxx", 1, 0);
run(test_path_authorizedkeys_ne, "d1/authorized_keys (file does not exist)");
run(test_path_authorizedkeys_fifo, "d1/authorized_keys (access denied)");
run(test_path_authorizedkeys_perm1, "d1/authorized_keys (access denied)");
run(test_path_authorizedkeys_perm2, "d1/authorized_keys (access denied)");
run(test_path_authorizedkeys_perm3, "d1/authorized_keys (access denied)");
run(test_path_dir_perm1, "d1/ (access denied)");
run(test_path_dir_perm2, "d1/ (access denied)");
run(test_path_dir_perm3, "d1/ (access denied)");
run(test_path_dir2_perm1, "d1/d2/ (access denied)");
run(test_path_dir2_perm2, "d1/d2/ (access denied)");
run(test_path_dir2_perm3, "d1/d2/ (access denied)");
run(test_path_dir3_perm1, "d1/ (access denied)");
run(test_path_dir3_perm2, "d1/ (access denied)");
run(test_path_dir3_perm3, "d1/ (access denied)");
run(test_path_dir_symlink, "d1/ (access denied)");
log_init(-1, "xxx", 1, 0);
test_authorizedkeys_ne();
authorizedkeys();
test_authorizedkeys_ok();
test_authorizedkeys_bad();
droproot();
run2(test_usernotexist);
run2(test_usertoolong);
run2(test_keytooshort);
run2(test_root);
_exit(0);
}
tinyssh-20190101/tinyssh-tests/subprocess_signtest.c 0000664 0000000 0000000 00000005702 13412736503 0022577 0 ustar 00root root 0000000 0000000 /*
20140321
Jan Mojzis
Public domain.
*/
#include
#include
#include
#include "fail.h"
#include "savesync.h"
#include "sshcrypto.h"
#include "open.h"
#include "purge.h"
#include "byte.h"
#include "randommod.h"
#include "crypto_uint32.h"
#include "subprocess.h"
unsigned char sh[sshcrypto_hash_MAX];
unsigned char sm[sshcrypto_sign_MAX + sshcrypto_hash_MAX];
unsigned char m[sshcrypto_sign_MAX + sshcrypto_hash_MAX];
unsigned long long mlen;
unsigned char sk[sshcrypto_sign_SECRETKEYMAX];
const char *keydir = "./keydir";
static void create(const char *fn, const unsigned char *x, long long xlen) {
if (savesync(fn, x, xlen) == -1) fail("unable to create test directory");
}
int main(void) {
long long i, j;
int fd;
fd = open_cwd();
if (fd == -1) fail("open_cwd() failure");
/* make keydir */
umask(022);
if (mkdir(keydir, 0755) == -1) fail("unable to create test directory");
if (chdir(keydir) == -1) fail("unable to chdir to directory");
for (i = 0; sshcrypto_keys[i].name; ++i) {
if (sshcrypto_keys[i].sign_keypair(sshcrypto_keys[i].sign_publickey, sk) != 0) fail("unable to generate key pair");
umask(022);
create(sshcrypto_keys[i].sign_publickeyfilename, sshcrypto_keys[i].sign_publickey, sshcrypto_keys[i].sign_publickeybytes);
umask(077);
create(sshcrypto_keys[i].sign_secretkeyfilename, sk, sshcrypto_keys[i].sign_secretkeybytes);
purge(sk, sizeof sk);
}
if (fchdir(fd) == -1) fail("fchdir() failure");
for (i = 0; sshcrypto_keys[i].name; ++i) {
/* set globals */
sshcrypto_key_name = sshcrypto_keys[i].name;
sshcrypto_sign = sshcrypto_keys[i].sign;
sshcrypto_sign_publickey = sshcrypto_keys[i].sign_publickey;
sshcrypto_sign_publickeybytes = sshcrypto_keys[i].sign_publickeybytes;
sshcrypto_sign_secretkeybytes = sshcrypto_keys[i].sign_secretkeybytes;
sshcrypto_sign_bytes = sshcrypto_keys[i].sign_bytes;
sshcrypto_sign_secretkeyfilename = sshcrypto_keys[i].sign_secretkeyfilename;
sshcrypto_hash_bytes = 64;
for (j = 0; j < 100; ++j) {
/* sign */
purge(sh, sizeof sh);
if (subprocess_sign(sm, sshcrypto_sign_bytes, keydir, sh, sshcrypto_hash_bytes) != 0)
fail("unable to sign");
byte_copy(sm + sshcrypto_sign_bytes, sshcrypto_hash_bytes, sh);
/* verify */
if (sshcrypto_keys[i].sign_open(m, &mlen, sm, sshcrypto_hash_bytes + sshcrypto_sign_bytes, sshcrypto_keys[i].sign_publickey) != 0)
fail("unable to open signed box");
#if 0
/* forgery */
sm[randommod(sshcrypto_sign_bytes + sshcrypto_hash_bytes)] += 1 + randommod(255);
if (sshcrypto_keys[i].sign_open(m, &mlen, sm, sshcrypto_hash_bytes + sshcrypto_sign_bytes, sshcrypto_keys[i].sign_publickey) == 0)
fail("forgery");
#endif
}
}
_exit(0);
}
tinyssh-20190101/tinyssh-tests/trymlocktest.c 0000664 0000000 0000000 00000000323 13412736503 0021225 0 ustar 00root root 0000000 0000000 /*
20140303
Jan Mojzis
Public domain.
*/
#include
#include "trymlock.h"
unsigned char buf[100];
int main(void) {
long long i;
for (i = 81; i < 100; ++i) trymlock(buf, i);
_exit(0);
}
tinyssh-20190101/tinyssh-tests/writealltest.c 0000664 0000000 0000000 00000001411 13412736503 0021203 0 ustar 00root root 0000000 0000000 /*
20140417
Jan Mojzis
Public domain.
*/
#include
#include
#include
#include
#include "fail.h"
#include "open.h"
#include "randombytes.h"
#include "byte.h"
#include "load.h"
#include "writeall.h"
#define SPACELEN 1048577
unsigned char space1[SPACELEN];
unsigned char space2[SPACELEN];
static void test1(void) {
int fd;
fd = open_write("writealltest.data");
if (fd == -1) fail("failure");
randombytes(space1, sizeof space1);
if (writeall(fd, space1, sizeof space1) == -1) fail("failure");
close(fd);
if (load("writealltest.data", space2, sizeof space2) == -1) fail("failure");
if (!byte_isequal(space1, SPACELEN, space2)) fail("failure");
}
int main(void) {
test1();
_exit(0);
}
tinyssh-20190101/tinyssh/ 0000775 0000000 0000000 00000000000 13412736503 0015157 5 ustar 00root root 0000000 0000000 tinyssh-20190101/tinyssh/LIBS 0000664 0000000 0000000 00000001543 13412736503 0015636 0 ustar 00root root 0000000 0000000 blocking.o
buf.o
byte.o
channel.o
channel_drop.o
channel_fork.o
channel_forkpty.o
channel_subsystem.o
coe.o
connectioninfo.o
die.o
dropuidgid.o
e.o
env.o
getln.o
global.o
iptostr.o
load.o
log.o
loginshell.o
logsys.o
main_tinysshd.o
main_tinysshd_makekey.o
main_tinysshd_printkey.o
newenv.o
numtostr.o
open.o
packet.o
packet_auth.o
packet_channel_open.o
packet_channel_recv.o
packet_channel_request.o
packet_channel_send.o
packet_get.o
packet_hello.o
packet_kex.o
packet_kexdh.o
packet_put.o
packet_recv.o
packet_send.o
packet_unimplemented.o
packetparser.o
porttostr.o
randommod.o
readall.o
savesync.o
ssh.o
sshcrypto.o
sshcrypto_cipher.o
sshcrypto_cipher_chachapoly.o
sshcrypto_kex.o
sshcrypto_kex_curve25519.o
sshcrypto_kex_sntrup4591761x25519.o
sshcrypto_key.o
sshcrypto_key_ed25519.o
str.o
stringparser.o
subprocess_auth.o
subprocess_sign.o
trymlock.o
writeall.o
tinyssh-20190101/tinyssh/SOURCES 0000664 0000000 0000000 00000001425 13412736503 0016227 0 ustar 00root root 0000000 0000000 blocking
buf
byte
channel
channel_drop
channel_fork
channel_forkpty
channel_subsystem
coe
connectioninfo
die
dropuidgid
e
env
getln
global
iptostr
load
log
loginshell
logsys
main_tinysshd
main_tinysshd_makekey
main_tinysshd_printkey
newenv
numtostr
open
packet
packet_auth
packet_channel_open
packet_channel_recv
packet_channel_request
packet_channel_send
packet_get
packet_hello
packet_kex
packet_kexdh
packet_put
packet_recv
packet_send
packet_unimplemented
packetparser
porttostr
randommod
readall
savesync
ssh
sshcrypto
sshcrypto_cipher
sshcrypto_cipher_chachapoly
sshcrypto_kex
sshcrypto_kex_curve25519
sshcrypto_kex_sntrup4591761x25519
sshcrypto_key
sshcrypto_key_ed25519
str
stringparser
subprocess_auth
subprocess_sign
tinysshd
tinysshd-makekey
tinysshd-printkey
trymlock
writeall
tinyssh-20190101/tinyssh/TARGETS 0000664 0000000 0000000 00000000054 13412736503 0016212 0 ustar 00root root 0000000 0000000 tinysshd
tinysshd-makekey
tinysshd-printkey
tinyssh-20190101/tinyssh/blocking.c 0000664 0000000 0000000 00000000423 13412736503 0017112 0 ustar 00root root 0000000 0000000 /* taken from nacl-20110221, from curvecp/blocking.c */
#include
#include "blocking.h"
void blocking_enable(int fd)
{
fcntl(fd,F_SETFL,fcntl(fd,F_GETFL,0) & ~O_NONBLOCK);
}
void blocking_disable(int fd)
{
fcntl(fd,F_SETFL,fcntl(fd,F_GETFL,0) | O_NONBLOCK);
}
tinyssh-20190101/tinyssh/blocking.h 0000664 0000000 0000000 00000000164 13412736503 0017121 0 ustar 00root root 0000000 0000000 #ifndef BLOCKING_H
#define BLOCKING_H
extern void blocking_enable(int);
extern void blocking_disable(int);
#endif
tinyssh-20190101/tinyssh/buf.c 0000664 0000000 0000000 00000013442 13412736503 0016103 0 ustar 00root root 0000000 0000000 /*
20140108
Jan Mojzis
Public domain.
The 'buf' library holds a string in allocated space.
The string length is limited by allocated memory.
All 'buf_put*' functions checks the limit and if
the string exceeds the limit, 'buf_put*' function
immediately exits with 111 status code.
*/
#include "byte.h"
#include "str.h"
#include "purge.h"
#include "randombytes.h"
#include "uint32_pack_big.h"
#include "bug.h"
#include "buf.h"
/*
Initialize 'b' structure.
*/
void buf_init_(const char *fn, unsigned long long line,
struct buf *b, unsigned char *buf, long long alloc) {
if (!b || !buf || alloc <= 0 || alloc > 1073741824) bug_inval_(fn, line);
b->buf = buf;
b->len = 0;
b->alloc = alloc;
purge(b->buf, b->alloc);
}
/*
Remove content of 'b'.
*/
void buf_purge_(const char *fn, unsigned long long line,
struct buf *b) {
if (!b || b->len < 0 || b->len > 1073741824 || b->alloc <= 0 || b->alloc > 1073741824 || !b->buf) bug_inval_(fn, line);
purge(b->buf, b->len);
b->len = 0;
}
/*
Retun if 'b' has available space for string of length 'len'.
*/
int buf_ready_(const char *fn, unsigned long long line,
struct buf *b, long long len) {
if (!b || b->len < 0 || b->len > 1073741824 || b->alloc <= 0 || b->alloc > 1073741824 || !b->buf || len < 0 || len > 1073741824) bug_inval_(fn, line);
return (b->len + len < b->alloc);
}
/*
Put string 'x' of length 'len'.
*/
int buf_put_(const char *fn, unsigned long long line,
struct buf *b, const unsigned char *x, long long len) {
if (!b || b->len < 0 || b->len > 1073741824 || b->alloc <= 0 || b->alloc > 1073741824 || !b->buf || !x || len < 0 || len > 1073741824) bug_inval_(fn, line);
if (b->len + len >= b->alloc) bug_nomem_(fn, line);
byte_copy(b->buf + b->len, len, x);
b->len += len;
return 1;
}
/*
Put 0-terminated string 'x'.
*/
int buf_puts_(const char *fn, unsigned long long line,
struct buf *b, const char *x) {
return buf_put_(fn, line, b, (const unsigned char *)x, str_len(x));
}
/*
Put zero bytes of length 'len'.
*/
int buf_putzerobytes_(const char *fn, unsigned long long line,
struct buf *b, long long len) {
if (!b || b->len < 0 || b->len > 1073741824 || b->alloc <= 0 || b->alloc > 1073741824 || !b->buf || len < 0 || len > 1073741824) bug_inval_(fn, line);
if (b->len + len >= b->alloc) bug_nomem_(fn, line);
byte_zero(b->buf + b->len, len);
b->len += len;
return 1;
}
/*
Put random bytes of length 'len'.
*/
int buf_putrandombytes_(const char *fn, unsigned long long line,
struct buf *b, long long len) {
if (!b || b->len < 0 || b->len > 1073741824 || b->alloc <= 0 || b->alloc > 1073741824 || !b->buf || len < 0 || len > 1073741824) bug_inval_(fn, line);
if (b->len + len >= b->alloc) bug_nomem_(fn, line);
randombytes(b->buf + b->len, len);
b->len += len;
return 1;
}
/*
Put padding of length 'len'.
*/
int buf_putpadding_(const char *fn, unsigned long long line,
struct buf *b, long long len) {
if (!b || b->len < 0 || b->len > 1073741824 || b->alloc <= 0 || b->alloc > 1073741824 || !b->buf || len < 0 || len > 1073741824) bug_inval_(fn, line);
if (b->len + len >= b->alloc) bug_nomem_(fn, line);
purge(b->buf + b->len, len);
b->len += len;
return 1;
}
/*
Put 32-bit unsigned integer in big-endian format.
*/
int buf_putnum32_(const char *fn, unsigned long long line,
struct buf *b, crypto_uint32 x) {
unsigned char s[4];
uint32_pack_big(s, x);
return buf_put_(fn, line, b, s, sizeof s);
}
/*
Put 8-bit unsigned integer.
*/
int buf_putnum8_(const char *fn, unsigned long long line,
struct buf *b, crypto_uint8 u) {
return buf_put_(fn, line, b, &u, 1);
}
/*
Put string 'x' of length 'len' and format it as a SSH-string.
*/
int buf_putstringlen_(const char *fn, unsigned long long line,
struct buf *b, const unsigned char *x, long long len) {
if (!buf_putnum32_(fn, line, b, len)) return 0;
return buf_put_(fn, line, b, x, len);
}
/*
Put 0-terminated string 'x' and format it as a SSH-string.
*/
int buf_putstring_(const char *fn, unsigned long long line,
struct buf *b, const char *x) {
return buf_putstringlen_(fn, line, b, (unsigned char *)x, str_len(x));
}
/*
Put SSH shared secret (bignum formated into wire format)
*/
int buf_putsharedsecret_(const char *fn, unsigned long long line,
struct buf *b, const unsigned char *x, long long len) {
long long pos;
if (len < 0 || len > 1073741824 || !b || !x) bug_inval_(fn, line);
for (pos = 0; pos < len; ++pos) if (x[pos]) break;
if (x[pos] & 0x80) {
buf_putnum32_(fn, line, b, len - pos + 1);
buf_putnum8_(fn, line, b, 0);
}
else {
buf_putnum32_(fn, line, b, len - pos + 0);
}
return buf_put_(fn, line, b, x + pos, len - pos);
}
/*
Put string 'x' of length 'len' and encode it into base64.
*/
static const unsigned char b64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int buf_putbase64_(const char *fn, unsigned long long line,
struct buf *b, const unsigned char *x, long long len) {
long long i;
unsigned long long bits = 0, v = 0;
unsigned char ch;
if (len < 0 || len > 1073741824 || !b || !x) bug_inval_(fn, line);
for (i = 0; i < len; ++i) {
v <<= 8; v += x[i]; bits += 8;
while (bits > 6) {
ch = b64chars[((v >> (bits - 6)) & 63)];
buf_putnum8_(fn, line, b, ch);
bits -= 6;
}
}
if (bits) {
v <<= (6 - bits);
ch = b64chars[v & 63];
buf_putnum8_(fn, line, b, ch);
}
while (b->len & 3) {
buf_putnum8_(fn, line, b, '=');
}
return 1;
}
tinyssh-20190101/tinyssh/buf.h 0000664 0000000 0000000 00000005035 13412736503 0016107 0 ustar 00root root 0000000 0000000 /*
20140108
Jan Mojzis
Public domain.
*/
#ifndef _BUF_H____
#define _BUF_H____
#include "crypto_uint8.h"
#include "crypto_uint32.h"
struct buf {
unsigned char *buf;
long long len;
long long alloc;
};
extern void buf_init_(const char *, unsigned long long, struct buf *, unsigned char *, long long);
extern void buf_purge_(const char *, unsigned long long, struct buf *);
extern int buf_ready_(const char *, unsigned long long, struct buf *, long long);
extern int buf_put_(const char *, unsigned long long, struct buf *, const unsigned char *, long long);
extern int buf_puts_(const char *, unsigned long long, struct buf *, const char *);
extern int buf_putzerobytes_(const char *, unsigned long long, struct buf *, long long);
extern int buf_putrandombytes_(const char *, unsigned long long, struct buf *, long long);
extern int buf_putpadding_(const char *, unsigned long long, struct buf *, long long);
extern int buf_putnum32_(const char *, unsigned long long, struct buf *, crypto_uint32);
extern int buf_putnum8_(const char *, unsigned long long, struct buf *, crypto_uint8);
extern int buf_putstringlen_(const char *, unsigned long long, struct buf *, const unsigned char *, long long);
extern int buf_putstring_(const char *, unsigned long long, struct buf *, const char *);
extern int buf_putsharedsecret_(const char *, unsigned long long, struct buf *, const unsigned char *, long long);
extern int buf_putbase64_(const char *, unsigned long long, struct buf *, const unsigned char *, long long);
#define buf_init(a, b, c) buf_init_(__FILE__, __LINE__, (a), (b), (c))
#define buf_purge(a) buf_purge_(__FILE__, __LINE__, (a))
#define buf_ready(a, b) buf_ready_(__FILE__, __LINE__, (a), (b))
#define buf_put(a, b, c) buf_put_(__FILE__, __LINE__, (a), (b), (c))
#define buf_puts(a, b) buf_puts_(__FILE__, __LINE__, (a), (b))
#define buf_putzerobytes(a, b) buf_putzerobytes_(__FILE__, __LINE__, (a), (b))
#define buf_putrandombytes(a, b) buf_putrandombytes_(__FILE__, __LINE__, (a), (b))
#define buf_putpadding(a, b) buf_putpadding_(__FILE__, __LINE__, (a), (b))
#define buf_putnum32(a, b) buf_putnum32_(__FILE__, __LINE__, (a), (b))
#define buf_putnum8(a, b) buf_putnum8_(__FILE__, __LINE__, (a), (b))
#define buf_putstringlen(a, b, c) buf_putstringlen_(__FILE__, __LINE__, (a), (b), (c))
#define buf_putstring(a, b) buf_putstring_(__FILE__, __LINE__, (a), (b))
#define buf_putsharedsecret(a, b, c) buf_putsharedsecret_(__FILE__, __LINE__, (a), (b), (c))
#define buf_putbase64(a, b, c) buf_putbase64_(__FILE__, __LINE__, (a), (b), (c))
#endif
tinyssh-20190101/tinyssh/bug.h 0000664 0000000 0000000 00000001223 13412736503 0016103 0 ustar 00root root 0000000 0000000 #ifndef _BUG_H____
#define _BUG_H____
#include
#include "global.h"
#include "e.h"
#include "log.h"
#define bug_(a, b) do { log_9_(-1, 0, a, b, 0, 0, 0, 0, 0, 0, 0, 0, 0); global_die(111); } while (0);
#define bug() bug_(__FILE__, __LINE__)
#define bug_nomem() do { errno = ENOMEM; bug(); } while (0);
#define bug_proto() do { errno = EPROTO; bug(); } while (0);
#define bug_inval() do { errno = EINVAL; bug(); } while (0);
#define bug_nomem_(a, b) do { errno = ENOMEM; bug_(a, b); } while (0);
#define bug_proto_(a, b) do { errno = EPROTO; bug_(a, b); } while (0);
#define bug_inval_(a, b) do { errno = EINVAL; bug_(a, b); } while (0);
#endif
tinyssh-20190101/tinyssh/byte.c 0000664 0000000 0000000 00000001263 13412736503 0016270 0 ustar 00root root 0000000 0000000 /* taken from nacl-20110221, from curvecp/byte_copy.c curvecp/byte_isequal.c curvecp/byte_zero.c */
#include "byte.h"
void byte_copy(void *yv,long long ylen,const void *xv)
{
char *y = (char *)yv;
const char *x = (const char *)xv;
while (ylen > 0) { *y++ = *x++; --ylen; }
}
int byte_isequal(const void *yv,long long ylen,const void *xv)
{
const unsigned char *y = (const unsigned char *)yv;
const unsigned char *x = (const unsigned char *)xv;
unsigned char diff = 0;
while (ylen > 0) { diff |= (*y++ ^ *x++); --ylen; }
return (256 - (unsigned int) diff) >> 8;
}
void byte_zero(void *yv,long long ylen)
{
char *y = (char *)yv;
while (ylen > 0) { *y++ = 0; --ylen; }
}
tinyssh-20190101/tinyssh/byte.h 0000664 0000000 0000000 00000000304 13412736503 0016270 0 ustar 00root root 0000000 0000000 #ifndef BYTE_H
#define BYTE_H
extern void byte_zero(void *,long long);
extern void byte_copy(void *,long long,const void *);
extern int byte_isequal(const void *,long long,const void *);
#endif
tinyssh-20190101/tinyssh/channel.c 0000664 0000000 0000000 00000027232 13412736503 0016741 0 ustar 00root root 0000000 0000000 /*
20140124
Jan Mojzis
Public domain.
The 'channel' library is used to handle data from/to SSH channel (rfc4254).
*/
#include
#include
#include
#include
#include
#include
#include
extern char *ptsname(int);
#include "byte.h"
#include "bug.h"
#include "newenv.h"
#include "e.h"
#include "purge.h"
#include "connectioninfo.h"
#include "iptostr.h"
#include "porttostr.h"
#include "buf.h"
#include "str.h"
#include "logsys.h"
#include "loginshell.h"
#include "trymlock.h"
#include "limit.h"
#include "channel.h"
/*
1. channel not open: maxpacket == 0, pid == 0
2. channel open: maxpacket != 0, pid == 0
3. child executed: maxpacket != 0, pid > 0, fd[01] != -1
4. child eof: maxpacket != 0, pid > 0, fd[12] == -1
5. child died: maxpacket != 0, pid == -1
*/
struct channel channel = {0};
/*
The 'channel_open' function opens the channel.
It sets 'localwindow' and maxpacket, values obtained from
from SSH_MSG_CHANNEL_OPEN message.
Function also obtaines connection information and sets
environment variables PATH, SSH_CONNECTION and MAIL.
*/
int channel_open(const char *user, crypto_uint32 id, crypto_uint32 remotewindow, crypto_uint32 maxpacket, crypto_uint32 *localwindow) {
struct buf b = { channel.buf0, 0, CHANNEL_BUFSIZE };
if (!localwindow) bug_inval();
if (!maxpacket) bug_inval();
if (!remotewindow) bug_inval();
if (channel.maxpacket != 0) bug_proto();
if (channel.pid != 0) bug_proto();
/* copy user-name */
if (!str_copyn(channel.user, sizeof channel.user, user)) bug_nomem();
/* set id, maxpacket, remotewindow, localwindow */
channel.id = id;
channel.maxpacket = maxpacket;
channel.remotewindow = remotewindow;
channel.localwindow = *localwindow = CHANNEL_BUFSIZE;
/* copy PATH */
if (!newenv_copyenv("PATH")) if (!newenv_env("PATH", "/bin:/usr/bin")) return 0;
/* create env. SSH_CONNECTION */
connectioninfo(channel.localip, channel.localport, channel.remoteip, channel.remoteport);
buf_purge(&b);
buf_puts(&b, channel.remoteip);
buf_puts(&b, " ");
buf_puts(&b, channel.remoteport);
buf_puts(&b, " ");
buf_puts(&b, channel.localip);
buf_puts(&b, " ");
buf_puts(&b, channel.localport);
buf_putnum8(&b, 0);
if (!newenv_env("SSH_CONNECTION", (char *)b.buf)) return 0;
/* create env. MAIL */
#ifdef _PATH_MAILDIR
buf_purge(&b);
buf_puts(&b, _PATH_MAILDIR);
buf_puts(&b, "/");
buf_puts(&b, user);
buf_putnum8(&b, 0);
if (!newenv_env("MAIL", (char *)b.buf)) return 0;
#endif
purge(channel.buf0, sizeof channel.buf0);
return 1;
}
/*
The 'channel_openterminal' function opens terminal,
sets environment variable TERM and initial terminal windowsize.
*/
int channel_openterminal(const char *name, crypto_uint32 a, crypto_uint32 b, crypto_uint32 x, crypto_uint32 y) {
if (channel.maxpacket == 0) bug_proto();
if (channel.pid != 0) bug_proto();
if (channel.flagterminal == 1) bug_proto();
if (!channel_openpty(&channel.master, &channel.slave)) return 0;
if (!newenv_env("TERM", name)) return 0;
channel.flagterminal = 1;
channel.a = a;
channel.b = b;
channel.x = x;
channel.y = y;
return 1;
}
/*
The 'channel_ptyresize' function sets new
terminal windowsize.
*/
void channel_ptyresize(crypto_uint32 a, crypto_uint32 b, crypto_uint32 x, crypto_uint32 y) {
struct winsize w;
if (channel.maxpacket == 0) bug_proto();
if (channel.pid <= 0) bug_proto();
if (!a && !b && !x && !y) return;
w.ws_col = a;
w.ws_row = b;
w.ws_xpixel = x;
w.ws_ypixel = y;
ioctl(channel.fd0, TIOCSWINSZ, &w);
}
/*
The 'channel_env' adds new environment variable
sent from client.
*/
int channel_env(const char *x, const char *y) {
if (channel.maxpacket == 0) bug_proto();
if (channel.pid != 0) bug_proto();
if (!x || !y) bug_inval();
return newenv_lowenv(x, y);
}
/*
The 'channel_exec' function executes new process.
If terminal is requsted, than users shell is executed,
if exec is requested, than command 'cmd' is executed.
Process is executed under appropriate users UID.
*/
int channel_exec(const char *cmd) {
char *run[4];
char *shell;
char *name;
int fd[3];
char ln[NAME_MAX + 2];
if (channel.maxpacket == 0) bug_proto();
if (channel.pid != 0 ) bug_proto();
if (channel.flagterminal) {
channel.pid = channel_forkpty(fd, channel.master, channel.slave);
if (channel.pid > 0) {
name = ptsname(fd[0]);
if (!name) bug();
if (!str_copyn(channel.termname, sizeof channel.termname, name)) bug_nomem();
}
}
else {
channel.pid = channel_fork(fd);
}
if (channel.pid == -1) return 0;
if (channel.pid == 0) {
logsys_login(channel.user, channel.remoteip, 0, 0);
if (!channel_droppriv(channel.user, &shell)) _exit(111);
if (cmd) {
run[0] = shell;
run[1] = (char *)"-c";
run[2] = (char *)cmd;
run[3] = 0;
}
else {
if (!loginshell(ln, sizeof ln, shell)) bug();
run[0] = ln;
run[1] = 0;
}
signal(SIGPIPE, SIG_DFL);
newenv_exec(shell, run);
_exit(111);
}
channel.fd0 = fd[0];
channel.fd1 = fd[1];
channel.fd2 = fd[2];
channel.len0 = 0;
newenv_purge();
if (channel.flagterminal && channel.pid > 0) channel_ptyresize(channel.a, channel.b, channel.x, channel.y);
return 1;
}
/*
The 'channel_put' function adds data from
client to childs buffer.
*/
void channel_put(unsigned char *buf, long long len) {
if (channel.maxpacket == 0) bug_proto();
if (channel.pid <= 0 ) bug_proto();
if (channel.fd0 == -1) bug_proto();
if (!buf || len < 0) bug_inval();
if (channel.len0 + len > CHANNEL_BUFSIZE) bug_nomem();
byte_copy(channel.buf0 + channel.len0, len, buf);
channel.len0 += len;
channel.localwindow -= len;
}
/*
The 'channel_puteof' function adds information
that remote side closed standard output.
*/
void channel_puteof(void) {
if (channel.maxpacket == 0) bug_proto();
if (channel.pid == 0) bug_proto();
if (channel.fd0 == -1) bug_proto();
channel.remoteeof = 1;
if (channel.len0 == 0) {
close(channel.fd0);
channel.fd0 = -1;
}
}
/*
The 'channel_putisready' function returns
if child is ready accept data.
*/
int channel_putisready(void) {
if (channel.maxpacket == 0) return 0;
if (channel.pid <= 0) return 0;
if (channel.fd0 == -1) return 0;
return (CHANNEL_BUFSIZE > channel.len0);
}
/*
The 'channel_read' function reads
data from childs standard output.
*/
long long channel_read(unsigned char *buf, long long len) {
long long r;
if (channel.maxpacket == 0) bug_proto();
if (channel.pid <= 0 ) bug_proto();
if (channel.fd1 == -1) bug_proto();
if (!buf || len < 0) bug_inval();
if (channel.remotewindow <= 0) return 0;
r = len;
if (r > 1048576) r = 1048576;
if (r > channel.remotewindow) r = channel.remotewindow;
r = read(channel.fd1, buf, r);
if (r == -1) {
if (errno == EINTR) return 0;
if (errno == EAGAIN) return 0;
if (errno == EWOULDBLOCK) return 0;
}
if (r <= 0) {
channel.fd1 = -1;
return 0;
}
channel.remotewindow -= r;
return r;
}
/*
The 'channel_extendedread' function reads
data from childs error output.
*/
long long channel_extendedread(unsigned char *buf, long long len) {
long long r;
if (channel.maxpacket == 0) bug_proto();
if (channel.pid <= 0 ) bug_proto();
if (channel.fd2 == -1) bug_proto();
if (!buf || len < 0) bug_inval();
if (channel.remotewindow <= 0) return 0;
r = len;
if (r > 1048576) r = 1048576;
if (r > channel.remotewindow) r = channel.remotewindow;
r = read(channel.fd2, buf, r);
if (r == -1) {
if (errno == EINTR) return 0;
if (errno == EAGAIN) return 0;
if (errno == EWOULDBLOCK) return 0;
}
if (r <= 0) {
channel.fd2 = -1;
return 0;
}
channel.remotewindow -= r;
return r;
}
/*
The 'channel_readisready' function returns
if we can read data from childs standard output.
*/
int channel_readisready(void) {
if (channel.maxpacket == 0 || channel.pid == 0) return 0;
if (channel.fd1 == -1) return 0;
return (channel.remotewindow > 0);
}
/*
The 'channel_extendedreadisready' function returns
if we can read data from childs error output.
*/
int channel_extendedreadisready(void) {
if (channel.maxpacket == 0 || channel.pid == 0) return 0;
if (channel.fd2 == -1) return 0;
return (channel.remotewindow > 0);
}
/*
The 'channel_write' function writes
data to childs standard input.
*/
int channel_write(void) {
long long w;
if (channel.maxpacket == 0) bug_proto();
if (channel.pid <= 0 ) bug_proto();
if (channel.fd0 == -1) bug_proto();
if (channel.len0 <= 0) return 1;
w = write(channel.fd0, channel.buf0, channel.len0);
if (w == -1) {
if (errno == EINTR) return 1;
if (errno == EAGAIN) return 1;
if (errno == EWOULDBLOCK) return 1;
}
if (w <= 0) {
channel.fd0 = -1;
return 0;
}
byte_copy(channel.buf0, channel.len0 - w, channel.buf0 + w);
purge(channel.buf0 + channel.len0 - w, w);
channel.len0 -= w;
if (channel.remoteeof && channel.len0 == 0) { close(channel.fd0); channel.fd0 = -1; }
return 1;
}
/*
The 'channel_writeisready' function returns
if we can write data to childs standard input.
*/
int channel_writeisready(void) {
if (channel.maxpacket == 0) return 0;
if (channel.pid <= 0 ) return 0;
if (channel.fd0 == -1) return 0;
return (channel.len0 > 0);
}
/*
The 'channel_iseof' function returns
if child closed standard and error output.
*/
int channel_iseof(void) {
if (channel.maxpacket == 0) return 0;
if (channel.pid == 0) return 0;
if (channel.pid == -1) return 1;
return (channel.fd1 == -1 && channel.fd2 == -1);
}
/*
The 'channel_waitnohang' function returns
if child exited or was killed.
*/
int channel_waitnohang(int *s, int *e) {
int r, status;
if (!s || !e) bug_inval();
if (channel.maxpacket == 0) bug_proto();
if (channel.pid <= 0 ) return 0;
do {
r = waitpid(channel.pid, &status, WNOHANG);
} while (r == -1 && errno == EINTR);
if (r <= 0) return 0;
if (channel.flagterminal) logsys_logout(channel.user, channel.remoteip, channel.termname, channel.pid);
if (WIFEXITED(status)) {
*e = WEXITSTATUS(status);
*s = 0;
}
else if (WIFSIGNALED(status)) {
*e = 0;
*s = WTERMSIG(status);
}
else {
*e = *s = -1;
}
channel.pid = -1;
return 1;
}
/*
Remove sentitive data from allocated memory.
*/
void channel_purge(void) {
purge(&channel, sizeof channel);
trymunlock(&channel, sizeof channel);
}
/*
Initialize channel structure.
*/
void channel_init(void) {
trymlock(&channel, sizeof channel);
purge(&channel, sizeof channel);
channel.maxpacket = 0;
channel.remoteeof = 0;
channel.len0 = 0;
channel.pid = 0;
channel.flagterminal = 0;
channel.master = -1;
channel.slave = -1;
}
int channel_getfd0(void) { return channel.fd0; }
int channel_getfd1(void) { return channel.fd1; }
int channel_getfd2(void) { return channel.fd2; }
long long channel_getlen0(void) { return channel.len0; }
crypto_uint32 channel_getid(void) { return channel.id; }
crypto_uint32 channel_getlocalwindow(void) { return channel.localwindow; }
void channel_incrementremotewindow(crypto_uint32 x) { channel.remotewindow += x; }
void channel_incrementlocalwindow(crypto_uint32 x) { channel.localwindow += x; }
tinyssh-20190101/tinyssh/channel.h 0000664 0000000 0000000 00000005156 13412736503 0016747 0 ustar 00root root 0000000 0000000 #ifndef _CHANNEL_H____
#define _CHANNEL_H____
#include "crypto_uint32.h"
#include "iptostr.h"
#include "porttostr.h"
#include "limit.h"
#define CHANNEL_BUFSIZE 131072
struct channel {
/* channel */
crypto_uint32 maxpacket;
crypto_uint32 id;
crypto_uint32 localwindow;
crypto_uint32 remotewindow;
/* child */
unsigned char buf0[CHANNEL_BUFSIZE];
long long len0;
long long pid;
int fd0;
int fd1;
int fd2;
int status;
/* ip */
char localip[IPTOSTR_LEN];
char localport[PORTTOSTR_LEN];
char remoteip[IPTOSTR_LEN];
char remoteport[PORTTOSTR_LEN];
/* terminal */
char user[LOGIN_NAME_MAX + 1];
char termname[TTY_NAME_MAX + 1];
int flagterminal;
int master;
int slave;
int a;
int b;
int x;
int y;
/* channel */
int remoteeof;
};
extern struct channel channel;
/* channel_drop.c */
extern int channel_droppriv(char *, char **);
/* channel_fork.c */
extern long long channel_fork(int *);
/* channel_forkpty.c */
extern long long channel_forkpty(int *, int, int);
extern int channel_openpty(int *, int *);
/* channel.c */
extern void channel_purge(void);
extern int channel_open(const char *, crypto_uint32, crypto_uint32, crypto_uint32, crypto_uint32 *);
extern int channel_openterminal(const char *, crypto_uint32, crypto_uint32, crypto_uint32, crypto_uint32);
extern void channel_ptyresize(crypto_uint32, crypto_uint32, crypto_uint32, crypto_uint32);
extern int channel_env(const char *, const char *);
extern int channel_exec(const char *);
extern void channel_put(unsigned char *, long long);
extern void channel_puteof(void);
extern int channel_putisready(void);
extern long long channel_read(unsigned char *, long long);
extern long long channel_extendedread(unsigned char *, long long);
extern int channel_readisready(void);
extern int channel_extendedreadisready(void);
extern int channel_write(void);
extern int channel_writeisready(void);
extern int channel_iseof(void);
extern int channel_waitnohang(int *, int *);
extern void channel_purge(void);
extern void channel_init(void);
extern int channel_getfd0(void);
extern int channel_getfd1(void);
extern int channel_getfd2(void);
extern long long channel_getlen0(void);
extern crypto_uint32 channel_getid(void);
extern crypto_uint32 channel_getlocalwindow(void);
extern void channel_incrementremotewindow(crypto_uint32);
extern void channel_incrementlocalwindow(crypto_uint32);
/* channel subsystem.c */
#define CHANNEL_SUBSYSTEM_MAX 64
extern int channel_subsystem_add(const char *);
extern char *channel_subsystem_get(const char *);
extern void channel_subsystem_log(void);
#endif
tinyssh-20190101/tinyssh/channel_drop.c 0000664 0000000 0000000 00000002000 13412736503 0017747 0 ustar 00root root 0000000 0000000 /*
20140129
Jan Mojzis
Public domain.
*/
#include
#include
#include
#include "dropuidgid.h"
#include "newenv.h"
#include "channel.h"
int channel_droppriv(char *user, char **shell) {
struct passwd *pw;
char *name;
pw = getpwnam(user);
if (!pw) return 0;
if (isatty(0)) {
name = ttyname(0);
if (!name) return 0;
if (!newenv_env("SSH_TTY", name)) return 0;
/* setowner */
if (chown(name, pw->pw_uid, pw->pw_gid) == -1) return 0;
if (chmod(name, 0600) == -1) return 0;
}
/* drop privileges */
if (!dropuidgid(pw->pw_name, pw->pw_uid, pw->pw_gid)) return 0;
if (chdir(pw->pw_dir) == -1) return 0;
if (!newenv_env("HOME", pw->pw_dir)) return 0;
if (!newenv_env("USER", pw->pw_name)) return 0;
if (!newenv_env("LOGNAME", pw->pw_name)) return 0;
if (!newenv_env("LOGIN", pw->pw_name)) return 0;
if (!newenv_env("SHELL", pw->pw_shell)) return 0;
*shell = pw->pw_shell;
return 1;
}
tinyssh-20190101/tinyssh/channel_fork.c 0000664 0000000 0000000 00000002135 13412736503 0017755 0 ustar 00root root 0000000 0000000 /*
20140129
Jan Mojzis
Public domain.
*/
#include
#include "blocking.h"
#include "open.h"
#include "channel.h"
/*
The 'channel_fork' function is used to create a new process.
Function creates 3 pipes from/to child:
fd[0] is pipe to childs standard input
fd[1] is pipe from childs standard output
fd[2] is pipe from childs error output
Function returns also childs PID.
*/
long long channel_fork(int fd[3]) {
int pi[2], pa[3], ch[3];
long long i, pid;
for (i = 0; i < 3; ++i) pa[i] = ch[i] = fd[i] = -1;
for (i = 0; i < 3; ++i) {
if (open_pipe(pi) == -1) goto cleanup;
pa[i] = pi[i ? 0 : 1];
ch[i] = pi[i ? 1 : 0];
}
pid = fork();
if (pid == -1) goto cleanup;
if (pid == 0) {
for (i = 0; i < 3; ++i) {
close(pa[i]); close(i);
blocking_enable(ch[i]);
if (dup(ch[i]) != i) _exit(111);
}
return 0;
}
for (i = 0; i < 3; ++i) {
close(ch[i]);
fd[i] = pa[i];
}
return pid;
cleanup:
for (i = 0; i < 3; ++i) { close(pa[i]); close(ch[i]); }
return -1;
}
tinyssh-20190101/tinyssh/channel_forkpty.c 0000664 0000000 0000000 00000006226 13412736503 0020517 0 ustar 00root root 0000000 0000000 /*
20150212
Jan Mojzis
Public domain.
*/
#include
#if defined(sun) || defined(__hpux)
#include
#endif
#include
#include
#include
#include
#include
extern char *ptsname(int);
extern int grantpt(int);
extern int unlockpt(int);
#include "hasopenpty.h"
#ifdef HASOPENPTY
extern int openpty(int *, int *, char *, struct termios *, struct winsize *);
#endif
#include "haslogintty.h"
#ifdef HASLOGINTTY
extern int login_tty(int);
#endif
#include "coe.h"
#include "blocking.h"
#include "global.h"
#include "channel.h"
static int _login_tty(int fd) {
char *name;
setsid();
#ifdef TIOCSCTTY
if (ioctl(fd, TIOCSCTTY, (char *)0) == -1) return -1;
#endif
name = ttyname(fd);
if (!name) return -1;
#ifndef TIOCSCTTY
if (fd != 0) close(0);
if (fd != 1) close(1);
if (fd != 2) close(2);
close(open(name, O_RDWR));
#endif
if (dup2(fd, 0) == -1) return -1;
if (dup2(fd, 1) == -1) return -1;
if (dup2(fd, 2) == -1) return -1;
if (fd > 2) close(fd);
return 0;
}
static int _openpty(int *amaster, int *aslave) {
int master = -1, slave = -1;
char *slave_name;
static const char *fn[] = { "/dev/ptmx", "/dev/ptc", 0 };
long long i;
for (i = 0; fn[i]; ++i) {
master = open(fn[i], O_RDWR | O_NOCTTY);
if (master != -1) break;
}
if (master == -1) return -1;
if (grantpt(master) == -1) { close(master); return -1; }
if (unlockpt(master) == -1) { close(master); return -1; }
slave_name = ptsname(master);
if (!slave_name) { close(master); return -1; }
slave = open(slave_name, O_RDWR | O_NOCTTY);
if (slave == -1) { close(master); return -1; }
#if defined(sun) || defined(__hpux)
ioctl(slave, I_PUSH, "ptem");
ioctl(slave, I_PUSH, "ldterm");
#endif
#if defined(sun)
ioctl(slave, I_PUSH, "ttcompat");
#endif
if (amaster) *amaster = master;
if (aslave) *aslave = slave;
return 0;
}
int channel_openpty(int *amaster, int *aslave) {
#ifdef HASOPENPTY
if (openpty(amaster, aslave, 0, 0, 0) == -1) return 0;
#else
if (_openpty(amaster, aslave) == -1) return 0;
#endif
if (!ttyname(*aslave)) {
close(*amaster);
close(*aslave);
return 0;
}
return 1;
}
/*
The 'channel_forkpty' function is used to create a new process
operating in a pseudoterminal. Function sets 3 integers in 'fd[3]':
fd[0] and fd[1] is pseudoterminal fd
fd[2] is always -1
*/
long long channel_forkpty(int fd[3], int master, int slave) {
long long pid;
if (!ttyname(slave)) return -1;
fd[0] = fd[1] = master;
fd[2] = -1;
pid = fork();
switch (pid) {
case -1:
close(slave);
close(master);
return -1;
case 0:
close(master);
#ifdef HASLOGINTTY
if (!ttyname(slave)) global_die(111);
if (login_tty(slave) == -1) global_die(111);
#else
if (_login_tty(slave) == -1) global_die(111);
#endif
return 0;
default:
coe_enable(master);
blocking_disable(master);
close(slave);
return pid;
}
}
tinyssh-20190101/tinyssh/channel_subsystem.c 0000664 0000000 0000000 00000001742 13412736503 0021055 0 ustar 00root root 0000000 0000000 /*
20150114
Jan Mojzis
Public domain.
*/
#include "str.h"
#include "log.h"
#include "e.h"
#include "channel.h"
static long long channel_subsystem_pos = 0;
static char *channel_subsystem[CHANNEL_SUBSYSTEM_MAX] = {0};
int channel_subsystem_add(const char *x) {
if (channel_subsystem_pos >= CHANNEL_SUBSYSTEM_MAX) return 0;
channel_subsystem[channel_subsystem_pos++] = (char *)x;
return 1;
}
char *channel_subsystem_get(const char *x) {
long long len, i;
if (!x) return 0;
len = str_len(x);
for (i = 0; i < CHANNEL_SUBSYSTEM_MAX; ++i) {
if (!channel_subsystem[i]) break;
if (str_start(channel_subsystem[i], x) && (channel_subsystem[i][len] == '='))
return channel_subsystem[i] + len + 1;
}
return 0;
}
void channel_subsystem_log(void) {
long long i;
for (i = 0; i < CHANNEL_SUBSYSTEM_MAX; ++i) {
if (!channel_subsystem[i]) break;
log_d3("subsystem: ", channel_subsystem[i], " registered");
}
}
tinyssh-20190101/tinyssh/coe.c 0000664 0000000 0000000 00000000575 13412736503 0016100 0 ustar 00root root 0000000 0000000 /*
20140414
Jan Mojzis
Public domain.
*/
#include
#include "coe.h"
/*
The 'coe_enable(fd)' function enables
the close-on-exec flag on a file-descriptor 'fd'.
*/
void coe_enable(int fd) {
fcntl(fd, F_SETFD, 1);
}
/*
The 'coe_disable(fd)' function disables
the close-on-exec flag on a file-descriptor 'fd'.
*/
void coe_disable(int fd) {
fcntl(fd, F_SETFD, 0);
}
tinyssh-20190101/tinyssh/coe.h 0000664 0000000 0000000 00000000152 13412736503 0016074 0 ustar 00root root 0000000 0000000 #ifndef _COE_H____
#define _COE_H____
extern void coe_enable(int);
extern void coe_disable(int);
#endif
tinyssh-20190101/tinyssh/connectioninfo.c 0000664 0000000 0000000 00000007037 13412736503 0020345 0 ustar 00root root 0000000 0000000 /*
20140131
Jan Mojzis
Public domain.
*/
#include
#include
#include
#include
#include
#include "e.h"
#include "byte.h"
#include "iptostr.h"
#include "porttostr.h"
#include "env.h"
#include "str.h"
#include "connectioninfo.h"
/*
The connectioninfo_fromfd function gets
informations about TCP connection from
getsockname(), getpeername() libc functions.
*/
static int connectioninfo_fromfd(char *localip, char *localport, char *remoteip, char *remoteport) {
long long i;
struct sockaddr_storage sa;
socklen_t salen;
int fd = 0;
unsigned char ip[16];
unsigned char port[2];
char *ipstr[2];
char *portstr[2];
int (*op[2])(int, struct sockaddr *, socklen_t *) = { getsockname, getpeername };
ipstr[0] = localip; portstr[0] = localport;
ipstr[1] = remoteip; portstr[1] = remoteport;
for (i = 0; i < 2; ++i) {
salen = sizeof sa;
if (op[i](fd, (struct sockaddr *)&sa, &salen) == -1) return 0;
if (sa.ss_family == PF_INET) {
struct sockaddr_in *sin = (struct sockaddr_in *)&sa;
byte_copy(ip, 12, "\0\0\0\0\0\0\0\0\0\0\377\377");
byte_copy(ip + 12, 4, &sin->sin_addr);
byte_copy(port, 2, &sin->sin_port);
}
#ifdef PF_INET6
else if (sa.ss_family == PF_INET6) {
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&sa;
byte_copy(ip, 16, &sin6->sin6_addr);
byte_copy(port, 2, &sin6->sin6_port);
}
#endif
else {
errno = EPROTONOSUPPORT;
return 0;
}
iptostr(ipstr[i], ip);
porttostr(portstr[i], port);
}
return 1;
}
static int env(char *y, long long ylen, const char *e) {
char *x;
x = env_get(e);
if (!x) return 0;
if (!str_copyn(y, ylen, x)) return 0;
return 1;
}
/*
The connectioninfo_fromtcpserverenv function gets
informations about TCP connection from environment.
*/
static int connectioninfo_fromtcpserverenv(char *localip, char *localport, char *remoteip, char *remoteport) {
if (!env(localip, IPTOSTR_LEN, "TCPLOCALIP")) return 0;
if (!env(localport, PORTTOSTR_LEN, "TCPLOCALPORT")) return 0;
if (!env(remoteip, IPTOSTR_LEN, "TCPREMOTEIP")) return 0;
if (!env(remoteport, PORTTOSTR_LEN, "TCPREMOTEPORT")) return 0;
return 1;
}
/*
The connectioninfo_fromcurvecpserverenv function gets
informations about CurveCP connection from environment.
*/
static int connectioninfo_fromcurvecpserverenv(char *localip, char *localport, char *remoteip, char *remoteport) {
if (!env(localip, IPTOSTR_LEN, "CURVECPLOCALIP")) return 0;
if (!env(localport, PORTTOSTR_LEN, "CURVECPLOCALPORT")) return 0;
if (!env(remoteip, IPTOSTR_LEN, "CURVECPREMOTEIP")) return 0;
if (!env(remoteport, PORTTOSTR_LEN, "CURVECPREMOTEPORT")) return 0;
return 1;
}
#define unknown "unknown"
#define port0 "0"
/*
The connectioninfo function gets informations about TCP/CurveCP connection.
*/
void connectioninfo(char *localip, char *localport, char *remoteip, char *remoteport) {
if (connectioninfo_fromtcpserverenv(localip, localport, remoteip, remoteport)) return;
if (connectioninfo_fromcurvecpserverenv(localip, localport, remoteip, remoteport)) return;
if (connectioninfo_fromfd(localip, localport, remoteip, remoteport)) return;
byte_copy(localip, sizeof unknown, unknown);
byte_copy(remoteip, sizeof unknown, unknown);
byte_copy(localport, sizeof port0, port0);
byte_copy(remoteport, sizeof port0, port0);
return;
}
tinyssh-20190101/tinyssh/connectioninfo.h 0000664 0000000 0000000 00000000201 13412736503 0020334 0 ustar 00root root 0000000 0000000 #ifndef _CONNECTIONINFO_H____
#define _CONNECTIONINFO_H____
extern void connectioninfo(char *, char *, char *, char *);
#endif
tinyssh-20190101/tinyssh/die.c 0000664 0000000 0000000 00000000776 13412736503 0016076 0 ustar 00root root 0000000 0000000 #include "global.h"
#include "log.h"
#include "die.h"
void die_usage(const char *x) {
log_u1(x);
global_die(100);
}
void die_fatal_(const char *fn, unsigned long long line, const char *trouble, const char *d, const char *f) {
if (d) {
if (f) log_9_(1, 0, fn, line, trouble, " ", d, "/", f, 0, 0, 0, 0);
else log_9_(1, 0, fn, line, trouble, " ", d, 0, 0, 0, 0, 0, 0);
}
else {
log_9_(1, 0, fn, line, trouble, 0, 0, 0, 0, 0, 0, 0, 0);
}
global_die(111);
}
tinyssh-20190101/tinyssh/die.h 0000664 0000000 0000000 00000000402 13412736503 0016065 0 ustar 00root root 0000000 0000000 #ifndef _DIE_H____
#define _DIE_H____
extern void die_usage(const char *);
extern void die_fatal_(const char *, unsigned long long, const char *, const char *, const char *);
#define die_fatal(a, b, c) die_fatal_(__FILE__, __LINE__, (a), (b), (c))
#endif
tinyssh-20190101/tinyssh/dropuidgid.c 0000664 0000000 0000000 00000001524 13412736503 0017457 0 ustar 00root root 0000000 0000000 /*
20140420
Jan Mojzis
Public domain.
*/
#include
#include
#include
#include "e.h"
#include "dropuidgid.h"
/*
The 'dropuidgid' function is used to drop root privileges.
If the process has appropriate permittions, the 'dropuidgid'
function sets user ID and group ID of calling process to
uid and gid.
The 'dropuidgid' function also initialize supplementary group IDs.
*/
int dropuidgid(const char *name, uid_t uid, gid_t gid) {
/* we can change group only as the root */
if (geteuid() == 0) {
if (setgid(gid) == -1) return 0;
if (getgid() != gid) { errno = EPERM; return 0; }
if (name) if (initgroups(name, gid) == -1) return 0;
}
if (geteuid() != uid) {
if (setuid(uid) == -1) return 0;
if (getuid() != uid) { errno = EPERM; return 0; }
}
return 1;
}
tinyssh-20190101/tinyssh/dropuidgid.h 0000664 0000000 0000000 00000000207 13412736503 0017461 0 ustar 00root root 0000000 0000000 #ifndef _DROPUIDGID_H____
#define _DROPUIDGID_H____
#include
extern int dropuidgid(const char *, uid_t, gid_t);
#endif
tinyssh-20190101/tinyssh/e.c 0000664 0000000 0000000 00000007030 13412736503 0015547 0 ustar 00root root 0000000 0000000 /* taken from nacl-20110221, from curvecp/e.c */
#include "e.h"
#define X(e,s) if (i == e) return s;
const char *e_str(int i)
{
X(0,"no error");
X(EINTR,"interrupted system call")
X(ENOMEM,"out of memory")
X(ENOENT,"file does not exist")
X(ETXTBSY,"text busy")
X(EIO,"input/output error")
X(EEXIST,"file already exists")
X(ETIMEDOUT,"timed out")
X(EINPROGRESS,"operation in progress")
X(EAGAIN,"temporary failure")
X(EWOULDBLOCK,"input/output would block")
X(EPIPE,"broken pipe")
X(EPERM,"permission denied")
X(EACCES,"access denied")
X(ENODEV,"device not configured")
X(EPROTO,"protocol error")
X(EISDIR,"is a directory")
X(ESRCH,"no such process")
X(E2BIG,"argument list too long")
X(ENOEXEC,"exec format error")
X(EBADF,"file descriptor not open")
X(ECHILD,"no child processes")
X(EDEADLK,"operation would cause deadlock")
X(EFAULT,"bad address")
X(ENOTBLK,"not a block device")
X(EBUSY,"device busy")
X(EXDEV,"cross-device link")
X(ENODEV,"device does not support operation")
X(ENOTDIR,"not a directory")
X(EINVAL,"invalid argument")
X(ENFILE,"system cannot open more files")
X(EMFILE,"process cannot open more files")
X(ENOTTY,"not a tty")
X(EFBIG,"file too big")
X(ENOSPC,"out of disk space")
X(ESPIPE,"unseekable descriptor")
X(EROFS,"read-only file system")
X(EMLINK,"too many links")
X(EDOM,"input out of range")
X(ERANGE,"output out of range")
X(EALREADY,"operation already in progress")
X(ENOTSOCK,"not a socket")
X(EDESTADDRREQ,"destination address required")
X(EMSGSIZE,"message too long")
X(EPROTOTYPE,"incorrect protocol type")
X(ENOPROTOOPT,"protocol not available")
X(EPROTONOSUPPORT,"protocol not supported")
X(ESOCKTNOSUPPORT,"socket type not supported")
X(EOPNOTSUPP,"operation not supported")
X(EPFNOSUPPORT,"protocol family not supported")
X(EAFNOSUPPORT,"address family not supported")
X(EADDRINUSE,"address already used")
X(EADDRNOTAVAIL,"address not available")
X(ENETDOWN,"network down")
X(ENETUNREACH,"network unreachable")
X(ENETRESET,"network reset")
X(ECONNABORTED,"connection aborted")
X(ECONNRESET,"connection reset")
X(ENOBUFS,"out of buffer space")
X(EISCONN,"already connected")
X(ENOTCONN,"not connected")
X(ESHUTDOWN,"socket shut down")
X(ETOOMANYREFS,"too many references")
X(ECONNREFUSED,"connection refused")
X(ELOOP,"symbolic link loop")
X(ENAMETOOLONG,"file name too long")
X(EHOSTDOWN,"host down")
X(EHOSTUNREACH,"host unreachable")
X(ENOTEMPTY,"directory not empty")
X(EPROCLIM,"too many processes")
X(EUSERS,"too many users")
X(EDQUOT,"disk quota exceeded")
X(ESTALE,"stale NFS file handle")
X(EREMOTE,"too many levels of remote in path")
X(EBADRPC,"RPC structure is bad")
X(ERPCMISMATCH,"RPC version mismatch")
X(EPROGUNAVAIL,"RPC program unavailable")
X(EPROGMISMATCH,"program version mismatch")
X(EPROCUNAVAIL,"bad procedure for program")
X(ENOLCK,"no locks available")
X(ENOSYS,"system call not available")
X(EFTYPE,"bad file type")
X(EAUTH,"authentication error")
X(ENEEDAUTH,"not authenticated")
X(ENOSTR,"not a stream device")
X(ETIME,"timer expired")
X(ENOSR,"out of stream resources")
X(ENOMSG,"no message of desired type")
X(EBADMSG,"bad message type")
X(EIDRM,"identifier removed")
X(ENONET,"machine not on network")
X(EREMOTE,"object not local")
X(ENOLINK,"link severed")
X(EADV,"advertise error")
X(ESRMNT,"srmount error")
X(ECOMM,"communication error")
X(EMULTIHOP,"multihop attempted")
X(EREMCHG,"remote address changed")
return "unknown error";
}
tinyssh-20190101/tinyssh/e.h 0000664 0000000 0000000 00000015506 13412736503 0015563 0 ustar 00root root 0000000 0000000 #ifndef E_H
#define E_H
#include
extern const char *e_str(int);
#ifndef EPERM
#define EPERM (-5001)
#endif
#ifndef ENOENT
#define ENOENT (-5002)
#endif
#ifndef ESRCH
#define ESRCH (-5003)
#endif
#ifndef EINTR
#define EINTR (-5004)
#endif
#ifndef EIO
#define EIO (-5005)
#endif
#ifndef ENXIO
#define ENXIO (-5006)
#endif
#ifndef E2BIG
#define E2BIG (-5007)
#endif
#ifndef ENOEXEC
#define ENOEXEC (-5008)
#endif
#ifndef EBADF
#define EBADF (-5009)
#endif
#ifndef ECHILD
#define ECHILD (-5010)
#endif
#ifndef EAGAIN
#define EAGAIN (-5011)
#endif
#ifndef EWOULDBLOCK
#define EWOULDBLOCK (-7011)
#endif
#ifndef ENOMEM
#define ENOMEM (-5012)
#endif
#ifndef EACCES
#define EACCES (-5013)
#endif
#ifndef EFAULT
#define EFAULT (-5014)
#endif
#ifndef ENOTBLK
#define ENOTBLK (-5015)
#endif
#ifndef EBUSY
#define EBUSY (-5016)
#endif
#ifndef EEXIST
#define EEXIST (-5017)
#endif
#ifndef EXDEV
#define EXDEV (-5018)
#endif
#ifndef ENODEV
#define ENODEV (-5019)
#endif
#ifndef ENOTDIR
#define ENOTDIR (-5020)
#endif
#ifndef EISDIR
#define EISDIR (-5021)
#endif
#ifndef EINVAL
#define EINVAL (-5022)
#endif
#ifndef ENFILE
#define ENFILE (-5023)
#endif
#ifndef EMFILE
#define EMFILE (-5024)
#endif
#ifndef ENOTTY
#define ENOTTY (-5025)
#endif
#ifndef ETXTBSY
#define ETXTBSY (-5026)
#endif
#ifndef EFBIG
#define EFBIG (-5027)
#endif
#ifndef ENOSPC
#define ENOSPC (-5028)
#endif
#ifndef ESPIPE
#define ESPIPE (-5029)
#endif
#ifndef EROFS
#define EROFS (-5030)
#endif
#ifndef EMLINK
#define EMLINK (-5031)
#endif
#ifndef EPIPE
#define EPIPE (-5032)
#endif
#ifndef EDOM
#define EDOM (-5033)
#endif
#ifndef ERANGE
#define ERANGE (-5034)
#endif
#ifndef EDEADLK
#define EDEADLK (-5035)
#endif
#ifndef EDEADLOCK
#define EDEADLOCK (-7035)
#endif
#ifndef ENAMETOOLONG
#define ENAMETOOLONG (-5036)
#endif
#ifndef ENOLCK
#define ENOLCK (-5037)
#endif
#ifndef ENOSYS
#define ENOSYS (-5038)
#endif
#ifndef ENOTEMPTY
#define ENOTEMPTY (-5039)
#endif
#ifndef ELOOP
#define ELOOP (-5040)
#endif
#ifndef ENOMSG
#define ENOMSG (-5042)
#endif
#ifndef EIDRM
#define EIDRM (-5043)
#endif
#ifndef ECHRNG
#define ECHRNG (-5044)
#endif
#ifndef EL2NSYNC
#define EL2NSYNC (-5045)
#endif
#ifndef EL3HLT
#define EL3HLT (-5046)
#endif
#ifndef EL3RST
#define EL3RST (-5047)
#endif
#ifndef ELNRNG
#define ELNRNG (-5048)
#endif
#ifndef EUNATCH
#define EUNATCH (-5049)
#endif
#ifndef ENOCSI
#define ENOCSI (-5050)
#endif
#ifndef EL2HLT
#define EL2HLT (-5051)
#endif
#ifndef EBADE
#define EBADE (-5052)
#endif
#ifndef EBADR
#define EBADR (-5053)
#endif
#ifndef EXFULL
#define EXFULL (-5054)
#endif
#ifndef ENOANO
#define ENOANO (-5055)
#endif
#ifndef EBADRQC
#define EBADRQC (-5056)
#endif
#ifndef EBADSLT
#define EBADSLT (-5057)
#endif
#ifndef EBFONT
#define EBFONT (-5059)
#endif
#ifndef ENOSTR
#define ENOSTR (-5060)
#endif
#ifndef ENODATA
#define ENODATA (-5061)
#endif
#ifndef ETIME
#define ETIME (-5062)
#endif
#ifndef ENOSR
#define ENOSR (-5063)
#endif
#ifndef ENONET
#define ENONET (-5064)
#endif
#ifndef ENOPKG
#define ENOPKG (-5065)
#endif
#ifndef EREMOTE
#define EREMOTE (-5066)
#endif
#ifndef ENOLINK
#define ENOLINK (-5067)
#endif
#ifndef EADV
#define EADV (-5068)
#endif
#ifndef ESRMNT
#define ESRMNT (-5069)
#endif
#ifndef ECOMM
#define ECOMM (-5070)
#endif
#ifndef EPROTO
#define EPROTO (-5071)
#endif
#ifndef EMULTIHOP
#define EMULTIHOP (-5072)
#endif
#ifndef EDOTDOT
#define EDOTDOT (-5073)
#endif
#ifndef EBADMSG
#define EBADMSG (-5074)
#endif
#ifndef EOVERFLOW
#define EOVERFLOW (-5075)
#endif
#ifndef ENOTUNIQ
#define ENOTUNIQ (-5076)
#endif
#ifndef EBADFD
#define EBADFD (-5077)
#endif
#ifndef EREMCHG
#define EREMCHG (-5078)
#endif
#ifndef ELIBACC
#define ELIBACC (-5079)
#endif
#ifndef ELIBBAD
#define ELIBBAD (-5080)
#endif
#ifndef ELIBSCN
#define ELIBSCN (-5081)
#endif
#ifndef ELIBMAX
#define ELIBMAX (-5082)
#endif
#ifndef ELIBEXEC
#define ELIBEXEC (-5083)
#endif
#ifndef EILSEQ
#define EILSEQ (-5084)
#endif
#ifndef ERESTART
#define ERESTART (-5085)
#endif
#ifndef ESTRPIPE
#define ESTRPIPE (-5086)
#endif
#ifndef EUSERS
#define EUSERS (-5087)
#endif
#ifndef ENOTSOCK
#define ENOTSOCK (-5088)
#endif
#ifndef EDESTADDRREQ
#define EDESTADDRREQ (-5089)
#endif
#ifndef EMSGSIZE
#define EMSGSIZE (-5090)
#endif
#ifndef EPROTOTYPE
#define EPROTOTYPE (-5091)
#endif
#ifndef ENOPROTOOPT
#define ENOPROTOOPT (-5092)
#endif
#ifndef EPROTONOSUPPORT
#define EPROTONOSUPPORT (-5093)
#endif
#ifndef ESOCKTNOSUPPORT
#define ESOCKTNOSUPPORT (-5094)
#endif
#ifndef EOPNOTSUPP
#define EOPNOTSUPP (-5095)
#endif
#ifndef EPFNOSUPPORT
#define EPFNOSUPPORT (-5096)
#endif
#ifndef EAFNOSUPPORT
#define EAFNOSUPPORT (-5097)
#endif
#ifndef EADDRINUSE
#define EADDRINUSE (-5098)
#endif
#ifndef EADDRNOTAVAIL
#define EADDRNOTAVAIL (-5099)
#endif
#ifndef ENETDOWN
#define ENETDOWN (-5100)
#endif
#ifndef ENETUNREACH
#define ENETUNREACH (-5101)
#endif
#ifndef ENETRESET
#define ENETRESET (-5102)
#endif
#ifndef ECONNABORTED
#define ECONNABORTED (-5103)
#endif
#ifndef ECONNRESET
#define ECONNRESET (-5104)
#endif
#ifndef ENOBUFS
#define ENOBUFS (-5105)
#endif
#ifndef EISCONN
#define EISCONN (-5106)
#endif
#ifndef ENOTCONN
#define ENOTCONN (-5107)
#endif
#ifndef ESHUTDOWN
#define ESHUTDOWN (-5108)
#endif
#ifndef ETOOMANYREFS
#define ETOOMANYREFS (-5109)
#endif
#ifndef ETIMEDOUT
#define ETIMEDOUT (-5110)
#endif
#ifndef ECONNREFUSED
#define ECONNREFUSED (-5111)
#endif
#ifndef EHOSTDOWN
#define EHOSTDOWN (-5112)
#endif
#ifndef EHOSTUNREACH
#define EHOSTUNREACH (-5113)
#endif
#ifndef EALREADY
#define EALREADY (-5114)
#endif
#ifndef EINPROGRESS
#define EINPROGRESS (-5115)
#endif
#ifndef ESTALE
#define ESTALE (-5116)
#endif
#ifndef EUCLEAN
#define EUCLEAN (-5117)
#endif
#ifndef ENOTNAM
#define ENOTNAM (-5118)
#endif
#ifndef ENAVAIL
#define ENAVAIL (-5119)
#endif
#ifndef EISNAM
#define EISNAM (-5120)
#endif
#ifndef EREMOTEIO
#define EREMOTEIO (-5121)
#endif
#ifndef EDQUOT
#define EDQUOT (-5122)
#endif
#ifndef ENOMEDIUM
#define ENOMEDIUM (-5123)
#endif
#ifndef EMEDIUMTYPE
#define EMEDIUMTYPE (-5124)
#endif
#ifndef ECANCELED
#define ECANCELED (-5125)
#endif
#ifndef ENOKEY
#define ENOKEY (-5126)
#endif
#ifndef EKEYEXPIRED
#define EKEYEXPIRED (-5127)
#endif
#ifndef EKEYREVOKED
#define EKEYREVOKED (-5128)
#endif
#ifndef EKEYREJECTED
#define EKEYREJECTED (-5129)
#endif
#ifndef EOWNERDEAD
#define EOWNERDEAD (-5130)
#endif
#ifndef ENOTRECOVERABLE
#define ENOTRECOVERABLE (-5131)
#endif
#ifndef ERFKILL
#define ERFKILL (-5132)
#endif
#ifndef EPROCLIM
#define EPROCLIM (-6067)
#endif
#ifndef EBADRPC
#define EBADRPC (-6072)
#endif
#ifndef ERPCMISMATCH
#define ERPCMISMATCH (-6073)
#endif
#ifndef EPROGUNAVAIL
#define EPROGUNAVAIL (-6074)
#endif
#ifndef EPROGMISMATCH
#define EPROGMISMATCH (-6075)
#endif
#ifndef EPROCUNAVAIL
#define EPROCUNAVAIL (-6076)
#endif
#ifndef EFTYPE
#define EFTYPE (-6079)
#endif
#ifndef EAUTH
#define EAUTH (-6080)
#endif
#ifndef ENEEDAUTH
#define ENEEDAUTH (-6081)
#endif
#ifndef ENOATTR
#define ENOATTR (-6087)
#endif
#ifndef ENOTCAPABLE
#define ENOTCAPABLE (-6093)
#endif
#endif
tinyssh-20190101/tinyssh/env.c 0000664 0000000 0000000 00000000676 13412736503 0016124 0 ustar 00root root 0000000 0000000 #include "str.h"
#include "env.h"
/*
The 'env_get(name)' function returns the value of the first environment
variable whose name is 'name', or 0 if there is no such variable.
*/
char *env_get(const char *name) {
long long len, i;
if (!name) return 0;
len = str_len(name);
for (i = 0; environ[i]; ++i)
if (str_start(environ[i], name) && (environ[i][len] == '='))
return environ[i] + len + 1;
return 0;
}
tinyssh-20190101/tinyssh/env.h 0000664 0000000 0000000 00000000420 13412736503 0016114 0 ustar 00root root 0000000 0000000 #ifndef _ENV_H____
#define _ENV_H____
/*
The environment 'environ', is a 0-terminated array
of 0-terminated strings, called environment variables.
Each environment variable is of the form name=value.
*/
extern char **environ;
extern char *env_get(const char *);
#endif
tinyssh-20190101/tinyssh/getln.c 0000664 0000000 0000000 00000002210 13412736503 0016427 0 ustar 00root root 0000000 0000000 /*
20140323
Jan Mojzis
Public domain.
*/
#include
#include
#include "e.h"
#include "getln.h"
static int getch(int fd, char *x) {
int r;
struct pollfd p;
for (;;) {
r = read(fd, x, 1);
if (r == -1) {
if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) {
p.fd = fd;
p.events = POLLIN | POLLERR;
poll(&p, 1, -1);
continue;
}
}
break;
}
return r;
}
/*
The function 'getln' reads line from filedescriptor 'fd' into
buffer 'xv' of length 'xmax'.
*/
int getln(int fd, void *xv, long long xmax) {
long long xlen;
int r;
char ch;
char *x = (char *)xv;
if (xmax < 1) { errno = EINVAL; return -1; }
x[0] = 0;
if (fd < 0) { errno = EBADF; return -1; }
xlen = 0;
for (;;) {
if (xlen >= xmax - 1) { x[xmax - 1] = 0; errno = ENOMEM; return -1; }
r = getch(fd, &ch);
if (r != 1) { close(fd); fd = -1; break; }
if (ch == 0) ch = '\n';
x[xlen++] = ch;
if (ch == '\n') break;
}
x[xlen] = 0;
return r;
}
tinyssh-20190101/tinyssh/getln.h 0000664 0000000 0000000 00000000135 13412736503 0016440 0 ustar 00root root 0000000 0000000 #ifndef _GETLN_H____
#define _GETLN_H____
extern int getln(int, void *, long long);
#endif
tinyssh-20190101/tinyssh/global.c 0000664 0000000 0000000 00000002537 13412736503 0016572 0 ustar 00root root 0000000 0000000 /*
20140214
Jan Mojzis
Public domain.
The 'global' library is used for global memory
initializition and global memory cleanup.
The 'global' library also has space
for 2 versatile buffers.
*/
#include
#include "newenv.h"
#include "channel.h"
#include "packet.h"
#include "sshcrypto.h"
#include "purge.h"
#include "trymlock.h"
#include "global.h"
unsigned char global_bspace1[GLOBAL_BSIZE];
unsigned char global_bspace2[GLOBAL_BSIZE];
/*
Initialize memory space.
*/
void global_init(void) {
packet_init();
channel_init();
newenv_init();
sshcrypto_init();
trymlock(global_bspace1, sizeof global_bspace1);
trymlock(global_bspace2, sizeof global_bspace2);
purge(global_bspace1, sizeof global_bspace1);
purge(global_bspace2, sizeof global_bspace2);
}
/*
Remove sentitive data from allocated memory.
*/
void global_purge(void) {
unsigned char stack[4096];
purge(stack, sizeof stack);
packet_purge();
channel_purge();
newenv_purge();
sshcrypto_purge();
purge(global_bspace1, sizeof global_bspace1);
purge(global_bspace2, sizeof global_bspace2);
trymunlock(global_bspace1, sizeof global_bspace1);
trymunlock(global_bspace2, sizeof global_bspace2);
}
/*
Remove sentitive data from allocated memory
and exit with status 'x'.
*/
void global_die(int x) {
global_purge();
_exit(x);
}
tinyssh-20190101/tinyssh/global.h 0000664 0000000 0000000 00000000423 13412736503 0016567 0 ustar 00root root 0000000 0000000 #ifndef _GLOBAL_H____
#define _GLOBAL_H____
#define GLOBAL_BSIZE 65536
extern unsigned char global_bspace1[GLOBAL_BSIZE];
extern unsigned char global_bspace2[GLOBAL_BSIZE];
extern void global_init(void);
extern void global_purge(void);
extern void global_die(int);
#endif
tinyssh-20190101/tinyssh/iptostr.c 0000664 0000000 0000000 00000005573 13412736503 0017041 0 ustar 00root root 0000000 0000000 /*
20130604
Jan Mojzis
Public domain.
*/
#include "byte.h"
#include "iptostr.h"
static char *iptostr4(char *, const unsigned char *);
static char *iptostr6(char *, const unsigned char *);
/*
The 'iptostr(strbuf,ip)' function converts IP address 'ip'
from network byte order into the 0-terminated string.
The 'ip' length is always 16 bytes. The caller must
allocate at least IPTOSTR_LEN bytes for 'strbuf'.
*/
char *iptostr(char *strbuf, const unsigned char *ip) {
static char staticbuf[IPTOSTR_LEN];
if (!strbuf) strbuf = staticbuf; /* not thread-safe */
if (byte_isequal("\0\0\0\0\0\0\0\0\0\0\377\377", 12, ip)) {
return iptostr4(strbuf, ip + 12);
}
return iptostr6(strbuf, ip);
}
/* convert IPv4 address */
static char *iptostr4(char *strbuf, const unsigned char *ip) {
long long i, len = 0;
unsigned long long num;
for (i = 3; i >= 0; --i) {
num = ip[i];
do {
num /= 10; ++len;
} while (num);
if (i > 0) ++len;
}
strbuf += len;
for (i = 3; i >= 0; --i) {
num = ip[i];
do {
*--strbuf = '0' + (num % 10);
num /= 10;
} while (num);
if (i > 0) *--strbuf = '.';
}
while (len < IPTOSTR_LEN) strbuf[len++] = 0;
return strbuf;
}
/*
The 'ip' is splited into 8 16-bit blocks and
the 'countz' function counts successive zeros and
searches for largest zero-block.
'first' ... first position of the zero-block
'last' ... last position of the zero-block
*/
static void countz(long long *first, long long *last, const unsigned long long *ip) {
long long i, j, e;
long long count[8];
for (i = 7; i >= 0; --i) count[i] = 0;
e = 8;
for (i = 7; i >= 0; --i) {
if (!ip[i]) {
for (j = i; j < e; ++j) ++count[j];
}
else {
e = i;
}
}
e = 0; j = 0;
for (i = 7; i >= 0; --i) {
if (count[i]) {
if (count[i] >= e) { e = count[i]; j = i; }
}
}
*first = j - count[j] + 1;
*last = j;
}
/* convert IPv6 address */
static char *iptostr6(char *strbuf, const unsigned char *ip) {
long long first, last, i;
unsigned long long ip2[8];
char *s = strbuf;
for (i = 7; i >= 0; --i) {
ip2[i] = ip[2 * i];
ip2[i] <<= 8;
ip2[i] += ip[2 * i + 1];
}
countz(&first, &last, ip2);
strbuf += IPTOSTR_LEN - 1;
*strbuf = 0;
for (i = 7; i >= 0; --i) {
if (i <= last && i >= first && first != last) {
if (i == last) *--strbuf = ':';
if (i == 7) *--strbuf = ':';
continue;
}
do {
*--strbuf = "0123456789abcdef"[ip2[i] & 15];
ip2[i] >>= 4;
} while (ip2[i]);
if (i > 0) *--strbuf = ':';
}
i = strbuf - s;
byte_copy(s, IPTOSTR_LEN - i, strbuf);
byte_zero(s + IPTOSTR_LEN - i, i);
return s;
}
tinyssh-20190101/tinyssh/iptostr.h 0000664 0000000 0000000 00000000204 13412736503 0017030 0 ustar 00root root 0000000 0000000 #ifndef _IPTOSTR_H____
#define _IPTOSTR_H____
#define IPTOSTR_LEN 46
extern char *iptostr(char *, const unsigned char *);
#endif
tinyssh-20190101/tinyssh/limit.h 0000664 0000000 0000000 00000000423 13412736503 0016445 0 ustar 00root root 0000000 0000000 #ifndef _LIMIT_H____
#define _LIMIT_H____
#include "haslimits.h"
#ifdef HASLIMITS
#include
#endif
#ifndef LOGIN_NAME_MAX
#define LOGIN_NAME_MAX 256
#endif
#ifndef NAME_MAX
#define NAME_MAX 255
#endif
#ifndef TTY_NAME_MAX
#define TTY_NAME_MAX 32
#endif
#endif
tinyssh-20190101/tinyssh/load.c 0000664 0000000 0000000 00000000474 13412736503 0016247 0 ustar 00root root 0000000 0000000 /* taken from nacl-20110221, from curvecp/load.c */
#include
#include "readall.h"
#include "open.h"
#include "e.h"
#include "load.h"
int load(const char *fn,void *x,long long xlen)
{
int fd;
int r;
fd = open_read(fn);
if (fd == -1) return -1;
r = readall(fd,x,xlen);
close(fd);
return r;
}
tinyssh-20190101/tinyssh/load.h 0000664 0000000 0000000 00000000127 13412736503 0016247 0 ustar 00root root 0000000 0000000 #ifndef LOAD_H
#define LOAD_H
extern int load(const char *,void *,long long);
#endif
tinyssh-20190101/tinyssh/log.c 0000664 0000000 0000000 00000010003 13412736503 0016076 0 ustar 00root root 0000000 0000000 /*
20140202
Jan Mojzis
Public domain.
The 'log' library is used to write log messages
on standard error output including source file,
function and line number.
Non-printable characters are replaced using '?'.
The 'log' library also supports syslog.
*/
#include
#include "writeall.h"
#include "randommod.h"
#include "purge.h"
#include "numtostr.h"
#include "e.h"
#include "log.h"
static const char *logtext = "x";
static char logstring[9] = "________";
static int loglevel = 1;
static int logflagfnln = 1;
static int logflagsyslog = 0;
static char chars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRTSUVWXYZ0123456789";
void log_init(int level, const char *text, int line, int flagsyslog) {
long long i;
loglevel = level;
logtext = text;
logflagfnln = line;
for (i = 0; i < sizeof logstring; ++i) {
logstring[i] = chars[randommod(sizeof chars - 1)];
}
logstring[sizeof logstring - 1] = 0;
if (flagsyslog) {
openlog(text, 0, LOG_DAEMON);
logflagsyslog = 1;
}
errno = 0;
}
char *log_string(void) {
return logstring;
}
static char buf[257];
static long long buflen = 0;
static void flush(void) {
if (logflagsyslog) {
buf[buflen] = 0;
syslog(LOG_INFO, "%s", buf);
}
else {
writeall(2, buf, buflen);
}
buflen = 0;
purge(buf, buflen);
}
static void outs(const char *x) {
long long i;
for(i = 0; x[i]; ++i) {
if (buflen >= sizeof buf - 1) flush();
if (x[i] == '\n') buf[buflen++] = '\n';
else if (x[i] < 32) buf[buflen++] = '?';
else if (x[i] > 126) buf[buflen++] = '?';
else buf[buflen++] = x[i];
}
}
static void outnum(unsigned long long n) {
char b[NUMTOSTR_LEN];
outs(numtostr(b, n));
}
void log_9_(
int level
,int ignoreerrno
,const char *f
,unsigned long long l
,const char *s0
,const char *s1
,const char *s2
,const char *s3
,const char *s4
,const char *s5
,const char *s6
,const char *s7
,const char *s8
)
{
const char *s[9];
long long i;
const char *m;
if (level > loglevel) return;
s[0] = s0; s[1] = s1; s[2] = s2; s[3] = s3;
s[4] = s4; s[5] = s5; s[6] = s6; s[7] = s7;
s[8] = s8;
switch (level) {
case -1:
m = "BUG";
break;
case 0:
m = "usage";
break;
case 1:
m = "fatal";
break;
case 2:
if (!ignoreerrno) m = "warning";
else m = "info";
break;
case 3:
m = "debug";
break;
default:
m = "unknown";
break;
}
/* name: session: level: message (error){file:line} */
/* 'name:' */
do {
if (level == 0) break; /* don't print in usage level */
if (logflagsyslog) break; /* don't print in syslog mode */
outs(logtext); outs(": ");
} while (0);
/* 'session:' */
do {
if (level == 0) break; /* don't print in usage level */
if (!logflagfnln) break; /* don't print when disabled */
outs(logstring); outs(": ");
} while (0);
/* 'level:' */
do {
if (level == 0) break; /* don't print in usage level */
outs(m); outs(": ");
} while (0);
/* 'message' */
for (i = 0; i < 9 && s[i]; ++i) outs(s[i]);
outs(" ");
/* '(error)' */
do {
if (!errno) break; /* don't print when errno = 0 */
if (ignoreerrno) break; /* don't print when disabled */
outs("("); outs(e_str(errno)); outs(")");
} while (0);
/* {file:line} */
do {
if (level == 0) break; /* don't print in usage level */
if (!f) break; /* don't print when no f */
if (!l) break; /* don't print when no l */
if (!logflagfnln && level != -1) break; /* don't print when disabled */
outs("{"); outs(f); outs(":"); outnum(l); outs("}");
} while (0);
outs("\n");
flush();
return;
}
tinyssh-20190101/tinyssh/log.h 0000664 0000000 0000000 00000005231 13412736503 0016112 0 ustar 00root root 0000000 0000000 #ifndef _LOG_H____
#define _LOG_H____
extern void log_init(int, const char *, int, int);
extern char *log_string(void);
extern void log_9_(
int,
int,
const char *,
unsigned long long,
const char *,
const char *,
const char *,
const char *,
const char *,
const char *,
const char *,
const char *,
const char *);
/* usage */
#define log_u9(a,b,c,d,e,f,g,h,i) log_9_(0,1,__FILE__,__LINE__,a,b,c,d,e,f,g,h,i)
#define log_u8(a,b,c,d,e,f,g,h) log_u9(a,b,c,d,e,f,g,h,0)
#define log_u7(a,b,c,d,e,f,g) log_u8(a,b,c,d,e,f,g,0)
#define log_u6(a,b,c,d,e,f) log_u7(a,b,c,d,e,f,0)
#define log_u5(a,b,c,d,e) log_u6(a,b,c,d,e,0)
#define log_u4(a,b,c,d) log_u5(a,b,c,d,0)
#define log_u3(a,b,c) log_u4(a,b,c,0)
#define log_u2(a,b) log_u3(a,b,0)
#define log_u1(a) log_u2(a,0)
/* fatal */
#define log_f9(a,b,c,d,e,f,g,h,i) log_9_(1,0,__FILE__,__LINE__,a,b,c,d,e,f,g,h,i)
#define log_f8(a,b,c,d,e,f,g,h) log_f9(a,b,c,d,e,f,g,h,0)
#define log_f7(a,b,c,d,e,f,g) log_f8(a,b,c,d,e,f,g,0)
#define log_f6(a,b,c,d,e,f) log_f7(a,b,c,d,e,f,0)
#define log_f5(a,b,c,d,e) log_f6(a,b,c,d,e,0)
#define log_f4(a,b,c,d) log_f5(a,b,c,d,0)
#define log_f3(a,b,c) log_f4(a,b,c,0)
#define log_f2(a,b) log_f3(a,b,0)
#define log_f1(a) log_f2(a,0)
/* warning */
#define log_w9(a,b,c,d,e,f,g,h,i) log_9_(2,0,__FILE__,__LINE__,a,b,c,d,e,f,g,h,i)
#define log_w8(a,b,c,d,e,f,g,h) log_w9(a,b,c,d,e,f,g,h,0)
#define log_w7(a,b,c,d,e,f,g) log_w8(a,b,c,d,e,f,g,0)
#define log_w6(a,b,c,d,e,f) log_w7(a,b,c,d,e,f,0)
#define log_w5(a,b,c,d,e) log_w6(a,b,c,d,e,0)
#define log_w4(a,b,c,d) log_w5(a,b,c,d,0)
#define log_w3(a,b,c) log_w4(a,b,c,0)
#define log_w2(a,b) log_w3(a,b,0)
#define log_w1(a) log_w2(a,0)
/* info */
#define log_i9(a,b,c,d,e,f,g,h,i) log_9_(2,1,__FILE__,__LINE__,a,b,c,d,e,f,g,h,i)
#define log_i8(a,b,c,d,e,f,g,h) log_i9(a,b,c,d,e,f,g,h,0)
#define log_i7(a,b,c,d,e,f,g) log_i8(a,b,c,d,e,f,g,0)
#define log_i6(a,b,c,d,e,f) log_i7(a,b,c,d,e,f,0)
#define log_i5(a,b,c,d,e) log_i6(a,b,c,d,e,0)
#define log_i4(a,b,c,d) log_i5(a,b,c,d,0)
#define log_i3(a,b,c) log_i4(a,b,c,0)
#define log_i2(a,b) log_i3(a,b,0)
#define log_i1(a) log_i2(a,0)
/* debug */
#define log_d9(a,b,c,d,e,f,g,h,i) log_9_(3,1,__FILE__,__LINE__,a,b,c,d,e,f,g,h,i)
#define log_d8(a,b,c,d,e,f,g,h) log_d9(a,b,c,d,e,f,g,h,0)
#define log_d7(a,b,c,d,e,f,g) log_d8(a,b,c,d,e,f,g,0)
#define log_d6(a,b,c,d,e,f) log_d7(a,b,c,d,e,f,0)
#define log_d5(a,b,c,d,e) log_d6(a,b,c,d,e,0)
#define log_d4(a,b,c,d) log_d5(a,b,c,d,0)
#define log_d3(a,b,c) log_d4(a,b,c,0)
#define log_d2(a,b) log_d3(a,b,0)
#define log_d1(a) log_d2(a,0)
#endif
tinyssh-20190101/tinyssh/loginshell.c 0000664 0000000 0000000 00000001202 13412736503 0017456 0 ustar 00root root 0000000 0000000 /*
20140429
Jan Mojzis
Public domain.
*/
#include "e.h"
#include "loginshell.h"
/*
The 'loginshell()' function converts shell path
into -shell name. For example:
'/bin/sh' -> '-sh'
'/usr/pkg/bin/bash' -> '-bash'
*/
int loginshell(char *out, long long outlen, const char *in) {
long long len, pos = -1;
if (!out || !in || outlen < 2) { errno = EINVAL; return 0; }
for (len = 0; in[len]; ++len) if (in[len] == '/') pos = len;
in += pos + 1;
len -= pos + 1;
if (len > outlen - 2) len = outlen - 2; /* truncate name */
*out++ = '-';
while (len > 0) { *out++ = *in++; --len; }
*out = 0;
return 1;
}
tinyssh-20190101/tinyssh/loginshell.h 0000664 0000000 0000000 00000000165 13412736503 0017472 0 ustar 00root root 0000000 0000000 #ifndef _LOGINSHELL_H____
#define _LOGINSHELL_H____
extern int loginshell(char *, long long, const char *);
#endif
tinyssh-20190101/tinyssh/logsys.c 0000664 0000000 0000000 00000007212 13412736503 0016645 0 ustar 00root root 0000000 0000000 /*
20140212
Jan Mojzis
Public domain.
The 'logsys' library is used to login recording
and logout recording in the system using
utmp/utmpx ...
Portability - HELL !!
*/
/*
tested on:
FreeBSD 9.2
OpenBSD 5.3
NetBSD 6.1.2
Linux Debian 7.0
SunOS 5.11
*/
#include
#include
#include
#include
#include "hasutilh.h"
#ifdef HASUTILH
#include
#endif
#include "hasutmpx.h"
#ifdef HASUTMPX
#include
#endif
#include "hasutmpxupdwtmpx.h"
#include "hasutmpxsyslen.h"
#include "hasutmp.h"
#ifdef HASUTMP
#include
#endif
#include "hasutmpname.h"
#include "hasutmppid.h"
#include "hasutmptime.h"
#include "hasutmptv.h"
#include "hasutmptype.h"
#include "hasutmphost.h"
#include "hasutmpuser.h"
#include "hasutmplogwtmp.h"
#include "hasutmploginlogout.h"
#include "str.h"
#include "byte.h"
#include "logsys.h"
static void logsys_utmpx(const char *user, const char *host, const char *name, long long pid, int flaglogin) {
#ifdef HASUTMPX
struct timeval tv;
struct utmpx ut;
byte_zero(&ut, sizeof ut);
/* line */
if (!name) name = ttyname(0);
if (!name) return;
if (str_start(name, "/dev/")) name += 5;
str_copyn(ut.ut_line, sizeof ut.ut_line, name);
/* host */
str_copyn(ut.ut_host, sizeof ut.ut_host, host);
#ifdef HASUTMPXSYSLEN
ut.ut_syslen = str_len(ut.ut_host) + 1;
#endif
/* user */
str_copyn(ut.ut_user, sizeof ut.ut_user, user);
/* time */
gettimeofday(&tv, 0);
ut.ut_tv.tv_sec = tv.tv_sec;
ut.ut_tv.tv_usec = tv.tv_usec;
/* pid */
if (pid == 0) pid = getpid();
ut.ut_pid = pid;
/* type */
if (flaglogin) ut.ut_type = USER_PROCESS;
else ut.ut_type = DEAD_PROCESS;
/* update utmpx */
setutxent();
pututxline(&ut);
endutxent();
/* update wtmpx */
#if defined(_PATH_WTMPX) && defined(HASUTMPXUPDWTMPX)
updwtmpx(_PATH_WTMPX, &ut);
#endif
#endif
}
static void logsys_utmp(const char *user, const char *host, const char *name, long long pid, int flaglogin) {
#ifdef HASUTMP
struct timeval tv;
struct utmp ut;
byte_zero(&ut, sizeof ut);
/* line */
if (!name) name = ttyname(0);
if (!name) return;
if (str_start(name, "/dev/")) name += 5;
str_copyn(ut.ut_line, sizeof ut.ut_line, name);
/* host */
#ifdef HASUTMPHOST
str_copyn(ut.ut_host, sizeof ut.ut_host, host);
#endif
/* user */
#ifdef HASUTMPNAME
str_copyn(ut.ut_name, sizeof ut.ut_name, user);
#endif
#ifdef HASUTMPUSER
str_copyn(ut.ut_user, sizeof ut.ut_user, user);
#endif
/* time */
gettimeofday(&tv, 0);
#ifdef HASUTMPTIME
ut.ut_time = tv.tv_sec;
#endif
#ifdef HASUTMPTV
ut.ut_tv.tv_sec = tv.tv_sec;
ut.ut_tv.tv_usec = tv.tv_usec;
#endif
/* pid */
#ifdef HASUTMPPID
if (pid == 0) pid = getpid();
ut.ut_pid = pid;
#endif
/* type */
#ifdef HASUTMPTYPE
if (flaglogin) ut.ut_type = USER_PROCESS;
else ut.ut_type = DEAD_PROCESS;
#endif
if (flaglogin) {
#ifdef HASUTMPLOGINLOGOUT
login(&ut);
#else
setutent();
pututline(&ut);
endutent();
#endif
}
else {
#ifdef HASUTMPLOGINLOGOUT
logout(ut.ut_line);
#else
setutent();
pututline(&ut);
endutent();
#endif
#if defined(HASUTMPLOGWTMP)
logwtmp(ut.ut_line, "", "");
#endif
}
#endif
}
void logsys_login(const char *user, const char *host, const char *name, long long pid) {
logsys_utmp(user, host, name, pid, 1);
logsys_utmpx(user, host, name, pid, 1);
}
void logsys_logout(const char *user, const char *host, const char *name, long long pid) {
logsys_utmp(user, host, name, pid, 0);
logsys_utmpx(user, host, name, pid, 0);
}
tinyssh-20190101/tinyssh/logsys.h 0000664 0000000 0000000 00000000334 13412736503 0016650 0 ustar 00root root 0000000 0000000 /* Public domain. */
#ifndef _LOGSYS_H____
#define _LOGSYS_H____
void logsys_login(const char *, const char *, const char *, long long);
void logsys_logout(const char *, const char *, const char *, long long);
#endif
tinyssh-20190101/tinyssh/main.h 0000664 0000000 0000000 00000000272 13412736503 0016255 0 ustar 00root root 0000000 0000000 #ifndef _MAIN_H____
#define _MAIN_H____
extern int main_tinysshd(int, char **);
extern int main_tinysshd_printkey(int, char **);
extern int main_tinysshd_makekey(int, char **);
#endif
tinyssh-20190101/tinyssh/main_tinysshd.c 0000664 0000000 0000000 00000024720 13412736503 0020201 0 ustar 00root root 0000000 0000000 /*
20140107
Jan Mojzis
Public domain.
*/
#include
#include
#include
#include
#include
#include "blocking.h"
#include "ssh.h"
#include "purge.h"
#include "open.h"
#include "load.h"
#include "e.h"
#include "byte.h"
#include "buf.h"
#include "packet.h"
#include "channel.h"
#include "log.h"
#include "sshcrypto.h"
#include "subprocess.h"
#include "global.h"
#include "connectioninfo.h"
#include "die.h"
#include "main.h"
#define USAGE "usage: tinysshd [options] keydir"
static unsigned int cryptotypeselected = sshcrypto_TYPENEWCRYPTO | sshcrypto_TYPEPQCRYPTO;
static int flagverbose = 1;
static int fdwd;
static int flaglogger = 0;
static struct buf b1 = {global_bspace1, 0, sizeof global_bspace1};
static struct buf b2 = {global_bspace2, 0, sizeof global_bspace2};
static void timeout(int x) {
errno = x = ETIMEDOUT;
die_fatal("closing connection", 0, 0);
}
static int selfpipe[2] = { -1, -1 };
static void trigger(int x) {
errno = 0;
x = write(selfpipe[1], "", 1);
}
int main_tinysshd(int argc, char **argv) {
char *x;
const char *keydir = 0;
long long i;
struct pollfd p[6];
struct pollfd *q;
struct pollfd *watch0;
struct pollfd *watch1;
struct pollfd *watchtochild;
struct pollfd *watchfromchild1;
struct pollfd *watchfromchild2;
struct pollfd *watchselfpipe;
int exitsignal, exitcode;
signal(SIGPIPE, SIG_IGN);
signal(SIGALRM, timeout);
log_init(0, "tinysshd", 0, 0);
if (argc < 2) die_usage(USAGE);
if (!argv[0]) die_usage(USAGE);
for (;;) {
if (!argv[1]) break;
if (argv[1][0] != '-') break;
x = *++argv;
if (x[0] == '-' && x[1] == 0) break;
if (x[0] == '-' && x[1] == '-' && x[2] == 0) break;
while (*++x) {
if (*x == 'q') { flagverbose = 0; continue; }
if (*x == 'Q') { flagverbose = 1; continue; }
if (*x == 'v') { if (flagverbose >= 2) flagverbose = 3; else flagverbose = 2; continue; }
if (*x == 'o') { cryptotypeselected |= sshcrypto_TYPEOLDCRYPTO; continue; }
if (*x == 'O') { cryptotypeselected &= ~sshcrypto_TYPEOLDCRYPTO; continue; }
if (*x == 's') { cryptotypeselected |= sshcrypto_TYPENEWCRYPTO; continue; }
if (*x == 'S') { cryptotypeselected &= ~sshcrypto_TYPENEWCRYPTO; continue; }
if (*x == 'p') { cryptotypeselected |= sshcrypto_TYPEPQCRYPTO; continue; }
if (*x == 'P') { cryptotypeselected &= ~sshcrypto_TYPEPQCRYPTO; continue; }
if (*x == 'l') { flaglogger = 1; continue; }
if (*x == 'L') { flaglogger = 0; continue; }
if (*x == 'x') {
if (x[1]) { channel_subsystem_add(x + 1); break; }
if (argv[1]) { channel_subsystem_add(*++argv); break; }
}
die_usage(USAGE);
}
}
keydir = *++argv; if (!keydir) die_usage(USAGE);
log_init(flagverbose, "tinysshd", 1, flaglogger);
connectioninfo(channel.localip, channel.localport, channel.remoteip, channel.remoteport);
log_i4("connection from ", channel.remoteip, ":", channel.remoteport);
channel_subsystem_log();
global_init();
blocking_disable(0);
blocking_disable(1);
blocking_disable(2);
/* get server longterm keys */
fdwd = open_cwd();
if (fdwd == -1) die_fatal("unable to open current directory", 0, 0);
if (chdir(keydir) == -1) die_fatal("unable to chdir to", keydir, 0);
for (i = 0; sshcrypto_keys[i].name; ++i) sshcrypto_keys[i].sign_flagserver |= sshcrypto_keys[i].cryptotype & cryptotypeselected;
for (i = 0; sshcrypto_keys[i].name; ++i) sshcrypto_keys[i].sign_flagclient |= sshcrypto_keys[i].cryptotype & cryptotypeselected;
for (i = 0; sshcrypto_kexs[i].name; ++i) sshcrypto_kexs[i].flagenabled |= sshcrypto_kexs[i].cryptotype & cryptotypeselected;
for (i = 0; sshcrypto_ciphers[i].name; ++i) sshcrypto_ciphers[i].flagenabled |= sshcrypto_ciphers[i].cryptotype & cryptotypeselected;
/* read public keys */
for (i = 0; sshcrypto_keys[i].name; ++i) {
if (!sshcrypto_keys[i].sign_flagserver) continue;
if (load(sshcrypto_keys[i].sign_publickeyfilename, sshcrypto_keys[i].sign_publickey, sshcrypto_keys[i].sign_publickeybytes) == -1) {
sshcrypto_keys[i].sign_flagserver = 0;
if (errno == ENOENT) continue;
die_fatal("unable to read public key from file", keydir, sshcrypto_keys[i].sign_publickeyfilename);
}
}
if (fchdir(fdwd) == -1) die_fatal("unable to change directory to working directory", 0, 0);
close(fdwd);
/* set timeout */
alarm(60);
/* send and receive hello */
if (!packet_hello_send()) die_fatal("unable to send hello-string", 0, 0);
if (!packet_hello_receive()) die_fatal("unable to receive hello-string", 0, 0);
/* send and receive kex */
if (!packet_kex_send()) die_fatal("unable to send kex-message", 0, 0);
if (!packet_kex_receive()) die_fatal("unable to receive kex-message", 0, 0);
rekeying:
/* rekeying */
alarm(60);
if (packet.flagrekeying == 1) {
buf_purge(&packet.kexrecv);
buf_put(&packet.kexrecv, b1.buf, b1.len);
if (!packet_kex_send()) die_fatal("unable to send kex-message", 0, 0);
}
/* send and receive kexdh */
if (!packet_kexdh(keydir, &b1, &b2)) die_fatal("unable to subprocess kexdh", 0, 0);
if (packet.flagkeys) log_d1("rekeying: done");
packet.flagkeys = 1;
/* note: communication is encrypted */
/* authentication + authorization */
if (packet.flagauthorized == 0) {
if (!packet_auth(&b1, &b2)) die_fatal("authentication failed", 0, 0);
packet.flagauthorized = 1;
}
/* note: user is authenticated and authorized */
alarm(3600);
/* main loop */
for (;;) {
if (channel_iseof())
if (!packet.sendbuf.len)
if (packet.flagchanneleofreceived)
break;
watch0 = watch1 = 0;
watchtochild = watchfromchild1 = watchfromchild2 = 0;
watchselfpipe = 0;
q = p;
if (packet_sendisready()) { watch1 = q; q->fd = 1; q->events = POLLOUT; ++q; }
if (packet_recvisready()) { watch0 = q; q->fd = 0; q->events = POLLIN; ++q; }
if (channel_writeisready()) { watchtochild = q; q->fd = channel_getfd0(); q->events = POLLOUT; ++q; }
if (channel_readisready() && packet_putisready()) { watchfromchild1 = q; q->fd = channel_getfd1(); q->events = POLLIN; ++q; }
if (channel_extendedreadisready() && packet_putisready()) { watchfromchild2 = q; q->fd = channel_getfd2(); q->events = POLLIN; ++q; }
if (selfpipe[0] != -1) { watchselfpipe = q; q->fd = selfpipe[0]; q->events = POLLIN; ++q; }
if (poll(p, q - p, 60000) < 0) {
watch0 = watch1 = 0;
watchtochild = watchfromchild1 = watchfromchild2 = 0;
watchselfpipe = 0;
}
else {
if (watch0) if (!watch0->revents) watch0 = 0;
if (watch1) if (!watch1->revents) watch1 = 0;
if (watchfromchild1) if (!watchfromchild1->revents) watchfromchild1 = 0;
if (watchfromchild2) if (!watchfromchild2->revents) watchfromchild2 = 0;
if (watchtochild) if (!watchtochild->revents) watchtochild = 0;
if (watchselfpipe) if (!watchselfpipe->revents) watchselfpipe = 0;
}
if (watchtochild) {
/* write data to child */
if (!channel_write()) die_fatal("unable to write data to child", 0, 0);
/* try to adjust window */
if (!packet_channel_send_windowadjust(&b1)) die_fatal("unable to send data to network", 0, 0);
}
/* read data from child */
if (watchfromchild1) packet_channel_send_data(&b2);
if (watchfromchild2) packet_channel_send_extendeddata(&b2);
/* check child */
if (channel_iseof()) {
if (selfpipe[0] == -1) if (open_pipe(selfpipe) == -1) die_fatal("unable to open pipe", 0, 0);
signal(SIGCHLD, trigger);
if (channel_waitnohang(&exitsignal, &exitcode)) {
packet_channel_send_eof(&b2);
if (!packet_channel_send_close(&b2, exitsignal, exitcode)) die_fatal("unable to close channel", 0, 0);
}
}
/* send data to network */
if (watch1) if (!packet_send()) die_fatal("unable to send data to network", 0, 0);
/* receive data from network */
if (watch0) {
alarm(3600); /* refresh timeout */
if (!packet_recv()) {
if (channel_iseof()) break; /* XXX */
die_fatal("unable to receive data from network", 0, 0);
}
}
/* process packets */
for (;;) {
if (!packet_get(&b1, 0)) {
if (!errno) break;
die_fatal("unable to get packets from network", 0, 0);
}
if (b1.len < 1) break; /* XXX */
switch (b1.buf[0]) {
case SSH_MSG_CHANNEL_OPEN:
if (!packet_channel_open(&b1, &b2)) die_fatal("unable to open channel", 0, 0);
break;
case SSH_MSG_CHANNEL_REQUEST:
if (!packet_channel_request(&b1, &b2)) die_fatal("unable to handle channel-request", 0, 0);
break;
case SSH_MSG_CHANNEL_DATA:
if (!packet_channel_recv_data(&b1)) die_fatal("unable to handle channel-data", 0, 0);
break;
case SSH_MSG_CHANNEL_EXTENDED_DATA:
if (!packet_channel_recv_extendeddata(&b1)) die_fatal("unable to handle channel-extended-data", 0, 0);
break;
case SSH_MSG_CHANNEL_WINDOW_ADJUST:
if (!packet_channel_recv_windowadjust(&b1)) die_fatal("unable to handle channel-window-adjust", 0, 0);
break;
case SSH_MSG_CHANNEL_EOF:
if (!packet_channel_recv_eof(&b1)) die_fatal("unable to handle channel-eof", 0, 0);
break;
case SSH_MSG_CHANNEL_CLOSE:
if (!packet_channel_recv_close(&b1)) die_fatal("unable to handle channel-close", 0, 0);
break;
case SSH_MSG_KEXINIT:
goto rekeying;
default:
if (!packet_unimplemented(&b1)) die_fatal("unable to send SSH_MSG_UNIMPLEMENTED message", 0, 0);
}
}
}
log_i1("finished");
global_die(0); return 111;
}
tinyssh-20190101/tinyssh/main_tinysshd_makekey.c 0000664 0000000 0000000 00000003537 13412736503 0021712 0 ustar 00root root 0000000 0000000 /*
20121022
Jan Mojzis
Public domain.
*/
#include
#include
#include
#include "savesync.h"
#include "log.h"
#include "sshcrypto.h"
#include "global.h"
#include "die.h"
#include "main.h"
#define sk global_bspace1 /* reusing global buffer */
#define pk global_bspace2 /* reusing global buffer */
#define USAGE "usage: tinysshd-makekey keydir"
static void create(const char *d, const char *fn, const unsigned char *x, long long xlen) {
if (savesync(fn, x, xlen) == -1) die_fatal("unable to create", d, fn);
}
static int flagverbose = 1;
int main_tinysshd_makekey(int argc, char **argv) {
char *x;
long long i;
log_init(flagverbose, "tinysshd-makekey", 0, 0);
if (argc < 2) die_usage(USAGE);
if (!argv[0]) die_usage(USAGE);
for (;;) {
if (!argv[1]) break;
if (argv[1][0] != '-') break;
x = *++argv;
if (x[0] == '-' && x[1] == 0) break;
if (x[0] == '-' && x[1] == '-' && x[2] == 0) break;
while (*++x) {
if (*x == 'q') { flagverbose = 0; continue; }
if (*x == 'Q') { flagverbose = 1; continue; }
die_usage(USAGE);
}
}
x = *++argv; if (!x) die_usage(USAGE);
log_init(flagverbose, "tinysshd-makekey", 0, 0);
umask(022);
if (mkdir(x, 0755) == -1) die_fatal("unable to create directory", x, 0);
if (chdir(x) == -1) die_fatal("unable to chdir to directory", x, 0);
for (i = 0; sshcrypto_keys[i].name; ++i) {
if (sshcrypto_keys[i].sign_keypair(pk, sk) != 0) die_fatal("unable to generate key pair", x, 0);
umask(022);
create(x, sshcrypto_keys[i].sign_publickeyfilename, pk, sshcrypto_keys[i].sign_publickeybytes);
umask(077);
create(x, sshcrypto_keys[i].sign_secretkeyfilename, sk, sshcrypto_keys[i].sign_secretkeybytes);
}
global_die(0); return 111;
}
tinyssh-20190101/tinyssh/main_tinysshd_printkey.c 0000664 0000000 0000000 00000003654 13412736503 0022131 0 ustar 00root root 0000000 0000000 /*
20150124
Jan Mojzis
Public domain.
*/
#include
#include "e.h"
#include "load.h"
#include "sshcrypto.h"
#include "crypto.h"
#include "global.h"
#include "buf.h"
#include "log.h"
#include "writeall.h"
#include "die.h"
#include "main.h"
static struct buf b1 = { global_bspace1, 0, sizeof global_bspace1 }; /* reusing global buffer */
static struct buf b2 = { global_bspace2, 0, sizeof global_bspace2 }; /* reusing global buffer */
static unsigned char pk[sshcrypto_sign_PUBLICKEYMAX];
#define USAGE "usage: tinysshd-printkey keydir"
int main_tinysshd_printkey(int argc, char **argv) {
char *x;
long long i;
log_init(3, "tinysshd-printkey", 0, 0);
if (argc < 2) die_usage(USAGE);
if (!argv[0]) die_usage(USAGE);
for (;;) {
if (!argv[1]) break;
if (argv[1][0] != '-') break;
x = *++argv;
if (x[0] == '-' && x[1] == 0) break;
if (x[0] == '-' && x[1] == '-' && x[2] == 0) break;
while (*++x) {
die_usage(USAGE);
}
}
x = *++argv; if (!x) die_usage(USAGE);
if (chdir(x) == -1) die_fatal("unable to chdir to directory", x, 0);
/* read public keys */
for (i = 0; sshcrypto_keys[i].name; ++i) {
if (load(sshcrypto_keys[i].sign_publickeyfilename, pk, sshcrypto_keys[i].sign_publickeybytes) == -1) {
if (errno == ENOENT) continue;
die_fatal("unable to read public key from file", x, sshcrypto_keys[i].sign_publickeyfilename);
}
buf_purge(&b1);
sshcrypto_keys[i].buf_putsignpk(&b1, pk);
if (b1.len < 4) die_fatal("unable to get publickey", 0, 0);
/* base64 */
buf_purge(&b2);
buf_puts(&b2, sshcrypto_keys[i].name);
buf_puts(&b2, " ");
buf_putbase64(&b2, b1.buf + 4, b1.len - 4);
buf_puts(&b2, "\n");
if (writeall(1, b2.buf, b2.len) == -1) die_fatal("unable to write output", 0, 0);
}
global_die(0); return 111;
}
tinyssh-20190101/tinyssh/newenv.c 0000664 0000000 0000000 00000004372 13412736503 0016633 0 ustar 00root root 0000000 0000000 /*
20140215
Jan Mojzis
Public domain.
The 'newenv' library is used to execute process in completely new environment.
*/
#include
#include "e.h"
#include "byte.h"
#include "str.h"
#include "purge.h"
#include "bug.h"
#include "env.h"
#include "trymlock.h"
#include "newenv.h"
#define NEWENV_LEN 128
#define NEWENV_SPACE 2048
static struct newenv {
char *e[NEWENV_LEN];
long long elen;
char es[NEWENV_SPACE];
long long eslen;
} n = { {0}, 0, {0}, 0 };
/*
Remove sentitive data from allocated memory.
*/
void newenv_purge(void) {
purge(&n, sizeof n);
n.elen = NEWENV_LEN;
n.eslen = NEWENV_SPACE;
trymunlock(&n, sizeof n);
}
/*
Initialize newenv structure.
*/
void newenv_init(void) {
trymlock(&n, sizeof n);
purge(&n, sizeof n);
n.e[0] = 0;
n.elen = n.eslen = 0;
}
/*
The 'newenv_env/newenv_lowenv' function adds the variable
into new environment.
The newenv_lowenv is limited to a half of the buffer-space.
*/
int newenv_env_(int x, const char *s, const char *t) {
long long slen, tlen, len, i;
if (!x || !s || !t) bug_inval();
if (n.elen < 0) bug_inval();
if (n.eslen < 0) bug_inval();
slen = str_len(s);
tlen = str_len(t);
len = slen + tlen + 2;
if (!n.elen) newenv_init();
for (i = 0; n.e[i]; ++i) {
if (str_start(n.e[i], s) && (n.e[i][slen] == '=')) {
n.e[i] = n.e[--n.elen];
break;
}
}
if (n.elen + 2 > NEWENV_LEN / x) { errno = ENOMEM; return 0; }
if (n.eslen + len > NEWENV_SPACE / x) { errno = ENOMEM; return 0; }
byte_copy(n.es + n.eslen, slen, s); n.eslen += slen; n.es[n.eslen++] = '=';
byte_copy(n.es + n.eslen, tlen, t); n.eslen += tlen; n.es[n.eslen++] = 0;
n.e[n.elen++] = n.es + n.eslen - len;
n.e[n.elen] = 0;
return 1;
}
/*
The 'newenv_copyenv' function copies the variable
from current environment into new environment.
*/
int newenv_copyenv(const char *s) {
char *t;
if (!s) bug_inval();
t = env_get(s);
if (!t) { errno = ENOENT; return 0; }
return newenv_env_(1, s, t);
}
/*
The 'newenv_exec' function executes the command
in new environment.
*/
void newenv_exec(char *filename, char **argv) {
if (!argv || !filename) bug_inval();
execve(filename, argv, n.e);
}
tinyssh-20190101/tinyssh/newenv.h 0000664 0000000 0000000 00000000550 13412736503 0016632 0 ustar 00root root 0000000 0000000 #ifndef _NEWENV_H____
#define _NEWENV_H____
extern int newenv_env_(int, const char *, const char *);
#define newenv_env(x, y) newenv_env_(1, (x), (y))
#define newenv_lowenv(x, y) newenv_env_(2, (x), (y))
extern int newenv_copyenv(const char *);
extern void newenv_exec(char *, char **);
extern void newenv_init(void);
extern void newenv_purge(void);
#endif
tinyssh-20190101/tinyssh/numtostr.c 0000664 0000000 0000000 00000001632 13412736503 0017220 0 ustar 00root root 0000000 0000000 /*
20130604
Jan Mojzis
Public domain.
*/
#include "numtostr.h"
/*
The 'numtostr(strbuf,n)' converts number 'n' into the 0-terminated string.
The caller must allocate at least NUMTOSTR_LEN bytes for 'strbuf'.
The 'numtostr' function is ready for 128-bit integer.
*/
char *numtostr(char *strbuf, long long n) {
long long len = 0;
unsigned long long n1, n2;
static char staticbuf[NUMTOSTR_LEN];
int flagsign = 0;
if (!strbuf) strbuf = staticbuf; /* not thread-safe */
if (n < 0) {
n1 = n2 = -(unsigned long long)n;
flagsign = 1;
}
else {
n1 = n2 = (unsigned long long)n;
}
do {
n1 /= 10; ++len;
} while (n1);
if (flagsign) ++len;
strbuf += len;
do {
*--strbuf = '0' + (n2 % 10);
n2 /= 10;
} while (n2);
if (flagsign) *--strbuf = '-';
while (len < NUMTOSTR_LEN) strbuf[len++] = 0;
return strbuf;
}
tinyssh-20190101/tinyssh/numtostr.h 0000664 0000000 0000000 00000000174 13412736503 0017225 0 ustar 00root root 0000000 0000000 #ifndef _NUMTOSTR_H____
#define _NUMTOSTR_H____
#define NUMTOSTR_LEN 41
extern char *numtostr(char *, long long);
#endif
tinyssh-20190101/tinyssh/open.c 0000664 0000000 0000000 00000001653 13412736503 0016271 0 ustar 00root root 0000000 0000000 /* taken from nacl-20110221, from curvecp/open_cwd.c curvecp/open_pipe.c curvecp/open_read.c curvecp/open_write.c */
#include
#include
#include
#include
#include "blocking.h"
#include "open.h"
int open_cwd(void)
{
return open_read(".");
}
int open_pipe(int *fd)
{
int i;
if (pipe(fd) == -1) return -1;
for (i = 0;i < 2;++i) {
fcntl(fd[i],F_SETFD,1);
blocking_disable(fd[i]);
}
return 0;
}
int open_read(const char *fn)
{
#ifdef O_CLOEXEC
return open(fn,O_RDONLY | O_NONBLOCK | O_CLOEXEC);
#else
int fd = open(fn,O_RDONLY | O_NONBLOCK);
if (fd == -1) return -1;
fcntl(fd,F_SETFD,1);
return fd;
#endif
}
int open_write(const char *fn)
{
#ifdef O_CLOEXEC
return open(fn,O_CREAT | O_WRONLY | O_NONBLOCK | O_CLOEXEC,0644);
#else
int fd = open(fn,O_CREAT | O_WRONLY | O_NONBLOCK,0644);
if (fd == -1) return -1;
fcntl(fd,F_SETFD,1);
return fd;
#endif
}
tinyssh-20190101/tinyssh/open.h 0000664 0000000 0000000 00000000314 13412736503 0016267 0 ustar 00root root 0000000 0000000 #ifndef OPEN_H
#define OPEN_H
extern int open_read(const char *);
extern int open_write(const char *);
extern int open_lock(const char *);
extern int open_cwd(void);
extern int open_pipe(int *);
#endif
tinyssh-20190101/tinyssh/packet.c 0000664 0000000 0000000 00000002253 13412736503 0016574 0 ustar 00root root 0000000 0000000 /*
20140222
Jan Mojzis
Public domain.
*/
#include "purge.h"
#include "trymlock.h"
#include "packet.h"
struct packet packet = {0};
void packet_purge(void) {
purge(&packet, sizeof packet);
trymunlock(&packet, sizeof packet);
}
void packet_init(void) {
trymlock(&packet, sizeof packet);
purge(&packet, sizeof packet);
packet.flagkeys = 0;
packet.flagauthorized = 0;
packet.flagrekeying = 0;
packet.flagclosesent = 0;
packet.flageofsent = 0;
packet.flagchanneleofreceived = 0;
packet.sendpacketid = 0;
packet.receivepacketid = 0;
packet.packet_length = 0;
buf_init(&packet.hellosend, packet.hellosendspace, sizeof packet.hellosendspace);
buf_init(&packet.helloreceive, packet.helloreceivespace, sizeof packet.helloreceivespace);
buf_init(&packet.kexsend, packet.kexsendspace, sizeof packet.kexsendspace);
buf_init(&packet.kexrecv, packet.kexrecvspace, sizeof packet.kexrecvspace);
buf_init(&packet.hashbuf, packet.hashbufspace, sizeof packet.hashbufspace);
buf_init(&packet.sendbuf, packet.sendbufspace, sizeof packet.sendbufspace);
buf_init(&packet.recvbuf, packet.recvbufspace, sizeof packet.recvbufspace);
}
tinyssh-20190101/tinyssh/packet.h 0000664 0000000 0000000 00000006673 13412736503 0016613 0 ustar 00root root 0000000 0000000 /*
20140108
Jan Mojzis
Public domain.
*/
#ifndef _PACKET_H____
#define _PACKET_H____
#include "buf.h"
#include "crypto_uint32.h"
#include "crypto_uint8.h"
#include "sshcrypto.h"
#include "limit.h"
#include "channel.h"
#define PACKET_UNAUTHENTICATED_MESSAGES 30
#define PACKET_LIMIT 32768
#define PACKET_FULLLIMIT 35000
#define PACKET_RECVLIMIT 131072
#define PACKET_ZEROBYTES 64
struct packet {
/* flags */
int flagkeys;
int flagauthorized;
int flagrekeying;
/* channel */
int flageofsent;
int flagclosesent;
int flagchanneleofreceived;
/* packet id */
crypto_uint32 sendpacketid;
crypto_uint32 receivepacketid;
/* keys */
unsigned char serverkey[sshcrypto_cipher_KEYMAX];
unsigned char clientkey[sshcrypto_cipher_KEYMAX];
unsigned char servermackey[sshcrypto_cipher_KEYMAX];
unsigned char clientmackey[sshcrypto_cipher_KEYMAX];
unsigned char servernonce[sshcrypto_cipher_KEYMAX];
unsigned char clientnonce[sshcrypto_cipher_KEYMAX];
unsigned char sessionid[sshcrypto_hash_MAX];
char name[LOGIN_NAME_MAX + 1];
crypto_uint8 kex_packet_follows;
crypto_uint8 kex_guess;
/* buffers */
unsigned char hellosendspace[256];
unsigned char helloreceivespace[256];
unsigned char kexsendspace[1024];
unsigned char kexrecvspace[65536];
unsigned char hashbufspace[65536];
struct buf hellosend;
struct buf helloreceive;
struct buf kexsend;
struct buf kexrecv;
struct buf hashbuf;
/* send/recv */
unsigned char recvbufspace[4 * PACKET_FULLLIMIT + 1 + PACKET_ZEROBYTES];
unsigned char sendbufspace[4 * PACKET_FULLLIMIT + 1];
struct buf recvbuf;
struct buf sendbuf;
crypto_uint32 packet_length;
};
/* packet.c */
extern struct packet packet;
extern void packet_purge(void);
extern void packet_init(void);
/* packet_send.c */
extern int packet_sendisready(void);
extern int packet_send(void);
extern int packet_sendall(void);
/* packet_recv.c */
extern int packet_recvisready(void);
extern int packet_recv(void);
/* packet_get.c */
extern int packet_get(struct buf *, crypto_uint8);
extern int packet_getall(struct buf *, crypto_uint8);
/* packet_put.c */
extern void packet_put(struct buf *);
extern int packet_putisready(void);
/* packet_hello.c */
extern int packet_hello_send(void);
extern int packet_hello_receive(void);
/* packet_kex.c */
extern int packet_kex_send(void);
extern int packet_kex_receive(void);
/* packet_kexdh.c */
extern int packet_kexdh(const char *, struct buf *, struct buf *);
/* packet_auth.c */
extern int packet_auth(struct buf *, struct buf *);
/* packet_channel_open.c */
extern int packet_channel_open(struct buf *, struct buf *);
/* packet_channel_request.c */
extern int packet_channel_request(struct buf *, struct buf *);
/* packet_channel_recv.c */
extern int packet_channel_recv_data(struct buf *);
extern int packet_channel_recv_extendeddata(struct buf *);
extern int packet_channel_recv_windowadjust(struct buf *);
extern int packet_channel_recv_eof(struct buf *);
extern int packet_channel_recv_close(struct buf *);
/* packet_channel_send.c */
extern void packet_channel_send_data(struct buf *);
extern void packet_channel_send_extendeddata(struct buf *);
extern int packet_channel_send_windowadjust(struct buf *);
extern void packet_channel_send_eof(struct buf *);
extern int packet_channel_send_close(struct buf *, int, int);
/* packet_unimplemented.c */
extern int packet_unimplemented(struct buf *);
#endif
tinyssh-20190101/tinyssh/packet_auth.c 0000664 0000000 0000000 00000015245 13412736503 0017622 0 ustar 00root root 0000000 0000000 /*
20140110
Jan Mojzis
Public domain.
*/
#include "buf.h"
#include "ssh.h"
#include "e.h"
#include "str.h"
#include "packetparser.h"
#include "subprocess.h"
#include "sshcrypto.h"
#include "bug.h"
#include "purge.h"
#include "log.h"
#include "packet.h"
int packet_auth(struct buf *b, struct buf *b2) {
crypto_uint8 ch, flagsignature;
long long pos, i, count, sign_bytes = 0;
crypto_uint32 len;
const char *pkname;
int (*sign_open)(unsigned char *,unsigned long long *,const unsigned char *,unsigned long long,const unsigned char *) = 0;
int (*parsesignpk)(unsigned char *, const unsigned char *, long long) = 0;
int (*parsesignature)(unsigned char *, const unsigned char *, long long) = 0;
void (*putsignpk)(struct buf *, const unsigned char *) = 0;
void (*putsignpkbase64)(struct buf *, const unsigned char *) = 0;
unsigned char pk[sshcrypto_sign_PUBLICKEYMAX];
unsigned char sig[sshcrypto_sign_MAX];
unsigned long long smlen;
buf_purge(b);
/* parse "ssh-userauth" */
pos = 0;
if (!packet_getall(b, SSH_MSG_SERVICE_REQUEST)) bug();
pos = packetparser_uint8(b->buf, b->len, pos, &ch); /* SSH_MSG_SERVICE_REQUEST */
if (ch != SSH_MSG_SERVICE_REQUEST) bug_proto();
pos = packetparser_uint32(b->buf, b->len, pos, &len); /* "ssh-userauth" */
pos = packetparser_skip(b->buf, b->len, pos, len);
if (!str_equaln((char *)b->buf + pos - len, len, "ssh-userauth")) bug_proto();
pos = packetparser_end(b->buf, b->len, pos);
/* send service accept */
b->buf[0] = SSH_MSG_SERVICE_ACCEPT;
packet_put(b);
if (!packet_sendall()) bug();
for (count = 0; count < 32; ++count) {
/* receive userauth request */
pkname = "unknown";
pos = 0;
buf_purge(b);
if (!packet_getall(b, SSH_MSG_USERAUTH_REQUEST)) bug();
pos = packetparser_uint8(b->buf, b->len, pos, &ch); /* SSH_MSG_USERAUTH_REQUEST */
if (ch != SSH_MSG_USERAUTH_REQUEST) bug_proto();
pos = packetparser_uint32(b->buf, b->len, pos, &len); /* name */
if (len >= sizeof packet.name) bug_proto();
pos = packetparser_copy(b->buf, b->len, pos, (unsigned char *)packet.name, len);
packet.name[len] = 0;
pos = packetparser_uint32(b->buf, b->len, pos, &len); /* "ssh-connection" */
pos = packetparser_skip(b->buf, b->len, pos, len);
if (!str_equaln((char *)b->buf + pos - len, len, "ssh-connection")) bug_proto();
pos = packetparser_uint32(b->buf, b->len, pos, &len); /* publickey/password/hostbased/none */
pos = packetparser_skip(b->buf, b->len, pos, len);
if (str_equaln((char *)b->buf + pos - len, len, "none")) pkname = "none";
if (str_equaln((char *)b->buf + pos - len, len, "password")) pkname = "password";
if (str_equaln((char *)b->buf + pos - len, len, "hostbased")) pkname = "hostbased";
if (str_equaln((char *)b->buf + pos - len, len, "publickey")) {
pos = packetparser_uint8(b->buf, b->len, pos, &flagsignature);
pos = packetparser_uint32(b->buf, b->len, pos, &len); /* public key algorithm name */
pos = packetparser_skip(b->buf, b->len, pos, len);
if (b->buf[pos] != 0) bug_proto();
pkname = (char *)b->buf + pos - len; /* XXX */
sign_open = 0; parsesignpk = 0; putsignpk = 0; putsignpkbase64 = 0; parsesignature = 0; sign_bytes = 0;
for (i = 0; sshcrypto_keys[i].name; ++i) {
if (!sshcrypto_keys[i].sign_flagclient) continue;
if (!str_equaln(pkname, len, sshcrypto_keys[i].name)) continue;
pkname = sshcrypto_keys[i].name;
sign_open = sshcrypto_keys[i].sign_open;
parsesignature = sshcrypto_keys[i].parsesignature;
parsesignpk = sshcrypto_keys[i].parsesignpk;
putsignpk = sshcrypto_keys[i].buf_putsignpk;
putsignpkbase64 = sshcrypto_keys[i].buf_putsignpkbase64;
sign_bytes = sshcrypto_keys[i].sign_bytes;
break;
}
if (sign_open && parsesignpk && putsignpk && putsignpkbase64 && parsesignature) {
pos = packetparser_uint32(b->buf, b->len, pos, &len); /* public key blob */
pos = packetparser_skip(b->buf, b->len, pos, len);
if (!parsesignpk(pk, b->buf + pos - len, len)) bug_proto();
if (!flagsignature) {
/* 'publickey' ... without signature */
buf_purge(b);
buf_putnum8(b, SSH_MSG_USERAUTH_PK_OK);
buf_putstring(b, pkname);
putsignpk(b, pk);
packet_put(b);
if (!packet_sendall()) bug();
continue;
}
/* 'publickey' ... with signature */
pos = packetparser_uint32(b->buf, b->len, pos, &len); /* signature blob */
pos = packetparser_skip(b->buf, b->len, pos, len);
if (!parsesignature(sig, b->buf + pos - len, len)) bug_proto();
pos = packetparser_end(b->buf, b->len, pos);
purge(b->buf + b->len - len - 4, len + 4);
b->len -= len + 4;
/* authenticate user - verify signature */
buf_purge(b2);
buf_put(b2, sig, sign_bytes);
buf_putstringlen(b2, packet.sessionid, sshcrypto_hash_bytes);
buf_put(b2, b->buf, b->len);
buf_purge(b);
if (b->alloc <= b2->len) bug_nomem();
if (sign_open(b->buf, &smlen, b2->buf, b2->len, pk) != 0) { errno = EAUTH; bug(); }
b->len = smlen; buf_purge(b);
/* authorize user - using authorized_keys */
buf_purge(b);
putsignpkbase64(b, pk);
buf_putnum8(b, 0);
if (subprocess_auth(packet.name, pkname, (char *)b->buf) == 0) goto authorized;
}
}
/* reject */
log_d5("auth: ", packet.name, ": ", pkname, " rejected");
buf_purge(b);
buf_putnum8(b, SSH_MSG_USERAUTH_FAILURE);
buf_putstring(b,"publickey");
buf_putnum8(b, 0);
packet_put(b);
if (!packet_sendall()) bug();
}
log_w1("auth: too many authentication tries");
return 0;
authorized:
/* authenticated + authorized */
log_i7("auth: ", packet.name, ": ", pkname, " ", (char *)b->buf, " accepted");
buf_purge(b);
buf_putnum8(b, SSH_MSG_USERAUTH_SUCCESS);
buf_putstring(b,"ssh-connection");
packet_put(b);
if (!packet_sendall()) bug();
purge(pk, sizeof pk);
purge(sig, sizeof sig);
return 1;
}
tinyssh-20190101/tinyssh/packet_channel_open.c 0000664 0000000 0000000 00000005463 13412736503 0021313 0 ustar 00root root 0000000 0000000 /*
20140120
Jan Mojzis
Public domain.
*/
#include "buf.h"
#include "ssh.h"
#include "e.h"
#include "bug.h"
#include "packetparser.h"
#include "str.h"
#include "packet.h"
int packet_channel_open(struct buf *b1, struct buf *b2) {
crypto_uint32 id, remotewindow, localwindow, maxpacket, chanlen;
long long pos = 0;
crypto_uint8 ch;
char *chan = (char *)b1->buf + pos;
/* parse packet */
pos = packetparser_uint8(b1->buf, b1->len, pos, &ch); /* byte SSH_MSG_CHANNEL_OPEN */
if (ch != SSH_MSG_CHANNEL_OPEN) bug_proto();
pos = packetparser_uint32(b1->buf, b1->len, pos, &chanlen); /* string channel type in US-ASCII only */
chan = (char *)b1->buf + pos;
pos = packetparser_skip(b1->buf, b1->len, pos, chanlen);
pos = packetparser_uint32(b1->buf, b1->len, pos, &id); /* uint32 sender channel */
pos = packetparser_uint32(b1->buf, b1->len, pos, &remotewindow); /* uint32 initial window size */
pos = packetparser_uint32(b1->buf, b1->len, pos, &maxpacket); /* uint32 maximum packet size */
if (maxpacket > PACKET_LIMIT) maxpacket = PACKET_LIMIT;
if (str_equaln(chan, chanlen, "session")) {
/* byte SSH_MSG_CHANNEL_OPEN
string "session"
uint32 sender channel
uint32 initial window size
uint32 maximum packet size
*/
pos = packetparser_end(b1->buf, b1->len, pos);
/* send confirmation */
buf_purge(b1);
if (channel_open(packet.name, id, remotewindow, maxpacket, &localwindow)) {
buf_purge(b2);
buf_putnum8(b2, SSH_MSG_CHANNEL_OPEN_CONFIRMATION); /* byte SSH_MSG_CHANNEL_OPEN_CONFIRMATION */
buf_putnum32(b2, id); /* uint32 recipient channel */
buf_putnum32(b2, id); /* uint32 sender channel */
buf_putnum32(b2, localwindow); /* uint32 initial window size */
buf_putnum32(b2, PACKET_LIMIT); /* uint32 maximum packet size */
packet_put(b2);
buf_purge(b2);
return 1;
}
}
/* reject channel */
buf_purge(b2);
buf_putnum8(b2, SSH_MSG_CHANNEL_OPEN_FAILURE); /* byte SSH_MSG_CHANNEL_OPEN_FAILURE */
buf_putnum32(b2, id); /* uint32 recipient channel */
buf_putnum32(b2, SSH_OPEN_ADMINISTRATIVELY_PROHIBITED); /* uint32 reason code */
buf_putstring(b2, "only one 'session' channel allowed"); /* string description in ISO-10646 UTF-8 encoding [RFC3629] */
buf_putstring(b2, ""); /* string language tag [RFC3066] */
packet_put(b2);
buf_purge(b1); buf_purge(b2);
return 1;
}
tinyssh-20190101/tinyssh/packet_channel_recv.c 0000664 0000000 0000000 00000005252 13412736503 0021305 0 ustar 00root root 0000000 0000000 /*
20140210
Jan Mojzis
Public domain.
*/
#include "bug.h"
#include "buf.h"
#include "channel.h"
#include "ssh.h"
#include "packetparser.h"
#include "packet.h"
int packet_channel_recv_data(struct buf *b) {
long long pos = 0;
crypto_uint32 len, id;
crypto_uint8 ch;
pos = packetparser_uint8(b->buf, b->len, pos, &ch); /* byte SSH_MSG_CHANNEL_DATA */
if (ch != SSH_MSG_CHANNEL_DATA) bug_proto();
pos = packetparser_uint32(b->buf, b->len, pos, &id); /* uint32 recipient channel */
if (id != channel_getid()) bug_proto();
pos = packetparser_uint32(b->buf, b->len, pos, &len); /* string data */
pos = packetparser_skip(b->buf, b->len, pos, len);
pos = packetparser_end(b->buf, b->len, pos);
channel_put(b->buf + pos - len, len);
buf_purge(b);
return 1;
}
int packet_channel_recv_extendeddata(struct buf *b) {
/* ignore extended data */
buf_purge(b);
return 1;
}
int packet_channel_recv_windowadjust(struct buf *b) {
long long pos = 0;
crypto_uint32 len, id;
crypto_uint8 ch;
pos = packetparser_uint8(b->buf, b->len, pos, &ch); /* byte SSH_MSG_CHANNEL_WINDOW_ADJUST */
if (ch != SSH_MSG_CHANNEL_WINDOW_ADJUST) bug_proto();
pos = packetparser_uint32(b->buf, b->len, pos, &id); /* uint32 recipient channel */
if (id != channel_getid()) bug_proto();
pos = packetparser_uint32(b->buf, b->len, pos, &len); /* uint32 bytes to add */
pos = packetparser_end(b->buf, b->len, pos);
channel_incrementremotewindow(len);
buf_purge(b);
return 1;
}
int packet_channel_recv_eof(struct buf *b) {
long long pos = 0;
crypto_uint32 id;
crypto_uint8 ch;
pos = packetparser_uint8(b->buf, b->len, pos, &ch); /* byte SSH_MSG_CHANNEL_EOF */
if (ch != SSH_MSG_CHANNEL_EOF) bug_proto();
pos = packetparser_uint32(b->buf, b->len, pos, &id); /* uint32 recipient channel */
if (id != channel_getid()) bug_proto();
pos = packetparser_end(b->buf, b->len, pos);
channel_puteof();
buf_purge(b);
return 1;
}
int packet_channel_recv_close(struct buf *b) {
long long pos = 0;
crypto_uint32 id;
crypto_uint8 ch;
pos = packetparser_uint8(b->buf, b->len, pos, &ch); /* byte SSH_MSG_CHANNEL_CLOSE */
if (ch != SSH_MSG_CHANNEL_CLOSE) bug_proto();
pos = packetparser_uint32(b->buf, b->len, pos, &id); /* uint32 recipient channel */
if (id != channel_getid()) bug_proto();
pos = packetparser_end(b->buf, b->len, pos);
packet_channel_send_eof(b);
packet.flagchanneleofreceived = 1;
buf_purge(b);
return 1;
}
tinyssh-20190101/tinyssh/packet_channel_request.c 0000664 0000000 0000000 00000015745 13412736503 0022046 0 ustar 00root root 0000000 0000000 /*
20140120
Jan Mojzis
Public domain.
*/
#include "buf.h"
#include "ssh.h"
#include "e.h"
#include "bug.h"
#include "str.h"
#include "log.h"
#include "packetparser.h"
#include "packet.h"
int packet_channel_request(struct buf *b1, struct buf *b2) {
long long pos = 0;
crypto_uint8 ch, wantreply;
crypto_uint32 id, a, b, x, y;
char *cmd;
crypto_uint32 cmdlen;
char *p1, *p2;
crypto_uint32 plen1, plen2;
pos = packetparser_uint8(b1->buf, b1->len, pos, &ch); /* byte SSH_MSG_CHANNEL_REQUEST */
if (ch != SSH_MSG_CHANNEL_REQUEST) bug_proto();
pos = packetparser_uint32(b1->buf, b1->len, pos, &id); /* uint32 recipient channel */
if (id != channel_getid()) bug_proto();
pos = packetparser_uint32(b1->buf, b1->len, pos, &cmdlen); /* string request type in US-ASCII characters only */
cmd = (char *)b1->buf + pos;
pos = packetparser_skip(b1->buf, b1->len, pos, cmdlen);
pos = packetparser_uint8(b1->buf, b1->len, pos, &wantreply); /* boolean want reply */
cmd[cmdlen] = 0;
if (str_equaln(cmd, cmdlen, "exec")) {
/* byte SSH_MSG_CHANNEL_REQUEST
uint32 recipient channel
string "exec"
boolean want reply
string command
*/
pos = packetparser_uint32(b1->buf, b1->len, pos, &plen1);
p1 = (char *)b1->buf + pos;
pos = packetparser_skip(b1->buf, b1->len, pos, plen1);
pos = packetparser_end(b1->buf, b1->len, pos);
buf_putnum8(b1, 0);
p1[plen1] = 0;
if (!channel_exec(p1)) bug();
log_d3("packet=SSH_MSG_CHANNEL_REQUEST, exec ", p1, ", accepted");
goto accept;
}
if (str_equaln(cmd, cmdlen, "subsystem")) {
/* byte SSH_MSG_CHANNEL_REQUEST
uint32 recipient channel
string "subsystem"
boolean want reply
string subsystem name
*/
pos = packetparser_uint32(b1->buf, b1->len, pos, &plen1);
p1 = (char *)b1->buf + pos;
pos = packetparser_skip(b1->buf, b1->len, pos, plen1);
pos = packetparser_end(b1->buf, b1->len, pos);
buf_putnum8(b1, 0);
p1[plen1] = 0;
p2 = channel_subsystem_get(p1);
if (!p2) {
log_d3("packet=SSH_MSG_CHANNEL_REQUEST, subsystem ", p1, ", rejected");
goto reject;
}
if (!channel_exec(p2)) bug();
log_d5("packet=SSH_MSG_CHANNEL_REQUEST, subsystem ", p1, "=", p2, ", accepted");
goto accept;
}
if (str_equaln(cmd, cmdlen, "shell")) {
/* byte SSH_MSG_CHANNEL_REQUEST
uint32 recipient channel
string "shell"
boolean want reply
*/
pos = packetparser_end(b1->buf, b1->len, pos);
if (!channel_exec(0)) bug();
log_d1("packet=SSH_MSG_CHANNEL_REQUEST, shell, accepted");
goto accept;
}
if (str_equaln(cmd, cmdlen, "env")) {
/* byte SSH_MSG_CHANNEL_REQUEST
uint32 recipient channel
string "env"
boolean want reply
string variable name
string variable value
*/
/**/
pos = packetparser_uint32(b1->buf, b1->len, pos, &plen1); /* string variable name */
p1 = (char *)b1->buf + pos;
pos = packetparser_skip(b1->buf, b1->len, pos, plen1);
pos = packetparser_uint32(b1->buf, b1->len, pos, &plen2); /* string variable value */
p2 = (char *)b1->buf + pos;
pos = packetparser_skip(b1->buf, b1->len, pos, plen2);
pos = packetparser_end(b1->buf, b1->len, pos);
buf_putnum8(b1, 0);
p1[plen1] = 0;
p2[plen2] = 0;
if (channel_env(p1, p2)) {
log_d5("packet=SSH_MSG_CHANNEL_REQUEST, env ", p1, "=", p2, ", accepted");
goto accept;
}
else {
log_d5("packet=SSH_MSG_CHANNEL_REQUEST, env ", p1, "=", p2, ", rejected");
goto reject;
}
}
if (str_equaln(cmd, cmdlen, "pty-req")) {
/*
byte SSH_MSG_CHANNEL_REQUEST
uint32 recipient channel
string "pty-req"
boolean want_reply
string TERM environment variable value (e.g., vt100)
uint32 terminal width, characters (e.g., 80)
uint32 terminal height, rows (e.g., 24)
uint32 terminal width, pixels (e.g., 640)
uint32 terminal height, pixels (e.g., 480)
string encoded terminal modes
*/
pos = packetparser_uint32(b1->buf, b1->len, pos, &plen1);
p1 = (char *)b1->buf + pos;
pos = packetparser_skip(b1->buf, b1->len, pos, plen1);
pos = packetparser_uint32(b1->buf, b1->len, pos, &a);
pos = packetparser_uint32(b1->buf, b1->len, pos, &b);
pos = packetparser_uint32(b1->buf, b1->len, pos, &x);
pos = packetparser_uint32(b1->buf, b1->len, pos, &y);
pos = packetparser_uint32(b1->buf, b1->len, pos, &plen2);
p2 = (char *)b1->buf + pos;
pos = packetparser_skip(b1->buf, b1->len, pos, plen2);
pos = packetparser_end(b1->buf, b1->len, pos);
buf_putnum8(b1, 0);
/* XXX TODO encoded terminal modes (p2, plen2) */
p1[plen1] = 0;
p2[plen2] = 0;
if (!channel_openterminal(p1, a, b, x, y)) {
log_w1("unable to open terminal");
log_d3("packet=SSH_MSG_CHANNEL_REQUEST, pty-req ", p1, ", rejected");
goto reject;
}
log_d3("packet=SSH_MSG_CHANNEL_REQUEST, pty-req ", p1, ", accepted");
goto accept;
}
if (str_equaln(cmd, cmdlen, "window-change")) {
/*
byte SSH_MSG_CHANNEL_REQUEST
uint32 recipient channel
string "window-change"
boolean FALSE
uint32 terminal width, columns
uint32 terminal height, rows
uint32 terminal width, pixels
uint32 terminal height, pixels
*/
pos = packetparser_uint32(b1->buf, b1->len, pos, &a);
pos = packetparser_uint32(b1->buf, b1->len, pos, &b);
pos = packetparser_uint32(b1->buf, b1->len, pos, &x);
pos = packetparser_uint32(b1->buf, b1->len, pos, &y);
pos = packetparser_end(b1->buf, b1->len, pos);
channel_ptyresize(a, b, x, y);
log_d1("packet=SSH_MSG_CHANNEL_REQUEST, window-change, accepted");
goto accept;
}
log_d3("packet=SSH_MSG_CHANNEL_REQUEST, ", cmd, ", rejected or ignored");
reject:
/* reject channel request */
if (!wantreply) goto done;
buf_purge(b2);
buf_putnum8(b2, SSH_MSG_CHANNEL_FAILURE); /* byte SSH_MSG_CHANNEL_SUCCESS */
buf_putnum32(b2, id); /* uint32 recipient channel */
packet_put(b2);
buf_purge(b1); buf_purge(b2);
return 1;
accept:
if (!wantreply) goto done;
buf_purge(b2);
buf_putnum8(b2, SSH_MSG_CHANNEL_SUCCESS); /* byte SSH_MSG_CHANNEL_SUCCESS */
buf_putnum32(b2, id); /* uint32 recipient channel */
packet_put(b2);
buf_purge(b1); buf_purge(b2);
return 1;
done:
buf_purge(b1); buf_purge(b2);
return 1;
}
tinyssh-20190101/tinyssh/packet_channel_send.c 0000664 0000000 0000000 00000010163 13412736503 0021274 0 ustar 00root root 0000000 0000000 /*
20140211
Jan Mojzis
Public domain.
*/
#include "bug.h"
#include "buf.h"
#include "channel.h"
#include "ssh.h"
#include "bug.h"
#include "uint32_pack_big.h"
#include "packet.h"
void packet_channel_send_data(struct buf *b) {
long long r;
buf_purge(b);
if (b->alloc <= PACKET_LIMIT) bug_nomem();
if (!packet_putisready()) return;
r = channel_read(b->buf + 9, PACKET_LIMIT - 9);
if (r == 0) return;
b->len = r + 9;
b->buf[0] = SSH_MSG_CHANNEL_DATA; /* byte SSH_MSG_CHANNEL_DATA */
uint32_pack_big(b->buf + 1, channel_getid()); /* uint32 recipient channel */
uint32_pack_big(b->buf + 5, r); /* string data */
packet_put(b);
buf_purge(b);
return;
}
void packet_channel_send_extendeddata(struct buf *b) {
long long r;
buf_purge(b);
if (b->alloc <= PACKET_LIMIT) bug_nomem();
if (!packet_putisready()) return;
r = channel_extendedread(b->buf + 13, PACKET_LIMIT - 13);
if (r == 0) return;
b->len = r + 13;
b->buf[0] = SSH_MSG_CHANNEL_EXTENDED_DATA; /* byte SSH_MSG_CHANNEL_EXTENDED_DATA */
uint32_pack_big(b->buf + 1, channel_getid()); /* uint32 recipient channel */
uint32_pack_big(b->buf + 5, 1); /* uint32 data_type_code (1 = stderr) */
uint32_pack_big(b->buf + 9, r); /* string data */
packet_put(b);
buf_purge(b);
return;
}
int packet_channel_send_windowadjust(struct buf *b) {
crypto_uint32 plus;
if (channel_getlen0() > CHANNEL_BUFSIZE / 2) return 1;
if (channel_getlocalwindow() > CHANNEL_BUFSIZE / 2) return 1;
buf_purge(b);
buf_putnum8(b, SSH_MSG_CHANNEL_WINDOW_ADJUST);
buf_putnum32(b, channel_getid());
plus = CHANNEL_BUFSIZE - channel_getlen0() - channel_getlocalwindow();
buf_putnum32(b, plus);
channel_incrementlocalwindow(plus);
packet_put(b);
buf_purge(b);
return 1;
}
void packet_channel_send_eof(struct buf *b) {
if (packet.flageofsent) return;
buf_purge(b);
buf_putnum8(b, SSH_MSG_CHANNEL_EOF);
buf_putnum32(b, channel_getid());
packet_put(b);
buf_purge(b);
packet.flageofsent = 1;
}
int packet_channel_send_close(struct buf *b, int exitsignal, int exitcode) {
packet_channel_send_eof(b);
if (packet.flagclosesent) return 1;
if (exitsignal > 0) {
buf_purge(b);
buf_putnum8(b, SSH_MSG_CHANNEL_REQUEST); /* byte SSH_MSG_CHANNEL_REQUEST */
buf_putnum32(b, channel_getid()); /* uint32 recipient channel */
buf_putstring(b, "exit-signal"); /* string "exit-signal" */
buf_putnum8(b, 0); /* boolean FALSE */
buf_putstring(b, ssh_sigstr(exitsignal)); /* string signal name (without the "SIG" prefix) */
buf_putnum8(b, 0); /* boolean core dumped */
buf_putstring(b, ssh_sigstrlong(exitsignal)); /* string error message in ISO-10646 UTF-8 encoding */
buf_putstring(b, ""); /* string language tag [RFC3066] */
packet_put(b);
buf_purge(b);
if (!packet_sendall()) return 0;
}
else {
buf_purge(b);
buf_putnum8(b, SSH_MSG_CHANNEL_REQUEST); /* byte SSH_MSG_CHANNEL_REQUEST */
buf_putnum32(b, channel_getid()); /* uint32 recipient channel */
buf_putstring(b, "exit-status"); /* string "exit-status" */
buf_putnum8(b, 0); /* boolean FALSE */
buf_putnum32(b, exitcode); /* uint32 exit_status */
packet_put(b);
buf_purge(b);
if (!packet_sendall()) return 0;
}
buf_purge(b);
buf_putnum8(b, SSH_MSG_CHANNEL_CLOSE); /* byte SSH_MSG_CHANNEL_CLOSE */
buf_putnum32(b, channel_getid()); /* uint32 recipient channel */
packet_put(b);
if (!packet_sendall()) return 0;
buf_purge(b);
packet.flagclosesent = 1;
return 1;
}
tinyssh-20190101/tinyssh/packet_get.c 0000664 0000000 0000000 00000005520 13412736503 0017433 0 ustar 00root root 0000000 0000000 /*
20140126
Jan Mojzis
Public domain.
*/
#include
#include
#include "byte.h"
#include "e.h"
#include "bug.h"
#include "uint32_unpack_big.h"
#include "purge.h"
#include "ssh.h"
#include "sshcrypto.h"
#include "numtostr.h"
#include "packet.h"
static int packet_get_plain_(struct buf *b) {
crypto_uint32 packet_length;
long long len;
struct buf *recvbuf = &packet.recvbuf;
unsigned char *pp;
long long l;
pp = recvbuf->buf + PACKET_ZEROBYTES;
l = recvbuf->len - PACKET_ZEROBYTES;
/* we need at least 4 bytes */
if (l < 4) return 1;
/* parse length */
packet_length = uint32_unpack_big(pp);
if (packet_length > PACKET_LIMIT) {
char buf1[NUMTOSTR_LEN];
char buf2[NUMTOSTR_LEN];
errno = EPROTO;
log_f4("packet length ", numtostr(buf1, packet_length), " > PACKET_LIMIT ", numtostr(buf2, PACKET_LIMIT));
global_die(111);
}
if (packet_length + 4 > l) return 1;
/* we have full packet */
len = packet_length;
len -= recvbuf->buf[PACKET_ZEROBYTES + 4] + 1;
if (len <= 0) bug_proto();
buf_put(b, recvbuf->buf + PACKET_ZEROBYTES + 5, len);
byte_copy(pp, l - packet_length + 4, pp + packet_length + 4);
purge(pp + l - packet_length + 4, packet_length + 4);
recvbuf->len -= packet_length + 4;
packet.receivepacketid++;
return 1;
}
static int packet_get_(struct buf *b) {
if (packet.flagkeys) {
return sshcrypto_packet_get(b);
}
else {
return packet_get_plain_(b);
}
}
int packet_get(struct buf *b, crypto_uint8 x) {
buf_purge(b);
if (!packet_get_(b)) return 0;
if (b->len <= 0) return 1;
if (!packet.flagauthorized) if (packet.receivepacketid > PACKET_UNAUTHENTICATED_MESSAGES) {
errno = EPROTO;
log_f1("too many unauthenticated messages");
global_die(111);
}
switch (b->buf[0]) {
case SSH_MSG_DISCONNECT:
errno = 0;
return 0;
case SSH_MSG_IGNORE:
case SSH_MSG_DEBUG:
buf_purge(b);
break;
default:
if (x && x != b->buf[0]) {
char buf1[NUMTOSTR_LEN];
char buf2[NUMTOSTR_LEN];
errno = EPROTO;
log_f4("expected packet type ", numtostr(buf1, x), ", got ", numtostr(buf2, b->buf[0]));
global_die(111);
}
break;
}
return 1;
}
int packet_getall(struct buf *b, crypto_uint8 ch) {
struct pollfd x;
long long before;
buf_purge(b);
for (;;) {
before = packet.recvbuf.len;
if (!packet_get(b, ch)) return 0;
if (b->len > 0) break;
if (before != packet.recvbuf.len) continue;
x.fd = 0;
x.events = POLLIN | POLLERR;
poll(&x, 1, -1);
if (!packet_recv()) return 0;
}
return 1;
}
tinyssh-20190101/tinyssh/packet_hello.c 0000664 0000000 0000000 00000003222 13412736503 0017754 0 ustar 00root root 0000000 0000000 /*
20140125
Jan Mojzis
Public domain.
*/
#include "buf.h"
#include "byte.h"
#include "writeall.h"
#include "purge.h"
#include "log.h"
#include "str.h"
#include "getln.h"
#include "e.h"
#include "packet.h"
/*
The 'packet_hello_send()' function sends SSH hello string to the client.
See RFC 4253 4.2. Protocol Version Exchange.
Example: SSH-2.0-tinyssh_20160201 iX512l8j
*/
int packet_hello_send(void) {
struct buf *b = &packet.hellosend;
buf_purge(b);
buf_puts(b, "SSH-2.0-tinyssh");
#ifdef VERSION
buf_puts(b, "_");
buf_puts(b, VERSION);
#endif
buf_puts(b, " ");
buf_puts(b, log_string());
buf_puts(b, "\r\n");
if (writeall(1, b->buf, b->len) == -1) return 0;
b->len -= 2; /* remove "\r\n" */
b->buf[b->len] = 0;
log_d2("hello: server: ", (char *)(b->buf));
purge(b->buf + b->len, b->alloc - b->len);
return 1;
}
/*
The 'packet_hello_receive()' function receives SSH hello string from the client.
See RFC 4253 4.2. Protocol Version Exchange.
Example: SSH-2.0-OpenSSH_6.6.1p1 Debian-4~bpo70+1
*/
int packet_hello_receive(void) {
int r;
struct buf *b = &packet.helloreceive;
r = getln(0, b->buf, b->alloc);
if (r == 0) { errno = ECONNRESET; return 0; }
if (r != 1) return 0;
b->len = str_len((char *)b->buf);
if (b->len < 6) { errno = EPROTO; return 0; }
if (b->buf[b->len - 1] == '\n') --(b->len); /* remove '\n' */
if (b->buf[b->len - 1] == '\r') --(b->len); /* remove '\r' */
b->buf[b->len] = 0;
if (!byte_isequal(b->buf, 4, "SSH-")) { errno = EPROTO; return 0; }
log_d2("hello: client: ", (char *)b->buf);
purge(b->buf + b->len, b->alloc - b->len);
return 1;
}
tinyssh-20190101/tinyssh/packet_kex.c 0000664 0000000 0000000 00000007753 13412736503 0017455 0 ustar 00root root 0000000 0000000 /*
20140110
Jan Mojzis
Public domain.
*/
#include "buf.h"
#include "ssh.h"
#include "sshcrypto.h"
#include "packetparser.h"
#include "bug.h"
#include "packet.h"
int packet_kex_send(void) {
struct buf *b = &packet.kexsend;
/* send server kex_init */
buf_purge(b);
buf_putnum8(b, SSH_MSG_KEXINIT); /* SSH_MSG_KEXINIT */
buf_putrandombytes(b, 16); /* cookie */
sshcrypto_kex_put(b); /* kex algorithms */
sshcrypto_key_put(b); /* server host key algorithms */
sshcrypto_cipher_put(b); /* encryption algorithms client to server */
sshcrypto_cipher_put(b); /* encryption algorithms server to client */
sshcrypto_cipher_macput(b); /* mac algorithms client to server */
sshcrypto_cipher_macput(b); /* mac algorithms server to client */
buf_putstring(b, "none"); /* compress algorithms client to server */
buf_putstring(b, "none"); /* compress algorithms server to client */
buf_putstring(b, ""); /* languages client to server */
buf_putstring(b, ""); /* languages server to client */
buf_putnum8(b, 0); /* kex first packet follows */
buf_putnum32(b, 0); /* reserved */
packet_put(b);
return packet_sendall();
}
int packet_kex_receive(void) {
struct buf *b = &packet.kexrecv;
long long pos = 0;
crypto_uint8 ch;
crypto_uint32 len;
if (!packet_getall(b, SSH_MSG_KEXINIT)) return 0;
/* parse packet */
pos = packetparser_uint8(b->buf, b->len, pos, &ch); /* SSH_MSG_KEXINIT */
if (ch != SSH_MSG_KEXINIT) bug_proto();
pos = packetparser_skip(b->buf, b->len, pos, 16); /* cookie */
pos = packetparser_uint32(b->buf, b->len, pos, &len); /* kex algorithms */
pos = packetparser_skip(b->buf, b->len, pos, len);
if (!sshcrypto_kex_select(b->buf + pos - len, len, &packet.kex_guess)) return 0;
pos = packetparser_uint32(b->buf, b->len, pos, &len); /* server host key algorithms */
pos = packetparser_skip(b->buf, b->len, pos, len);
if (!sshcrypto_key_select(b->buf + pos - len, len)) return 0;
pos = packetparser_uint32(b->buf, b->len, pos, &len); /* encryption algorithms client to server */
pos = packetparser_skip(b->buf, b->len, pos, len);
if (!sshcrypto_cipher_select(b->buf + pos - len, len)) return 0;
pos = packetparser_uint32(b->buf, b->len, pos, &len); /* encryption algorithms server to client */
pos = packetparser_skip(b->buf, b->len, pos, len);
/* XXX assuming same as encryption algorithms client to server */
pos = packetparser_uint32(b->buf, b->len, pos, &len); /* mac algorithms client to server */
pos = packetparser_skip(b->buf, b->len, pos, len);
if (!sshcrypto_cipher_macselect(b->buf + pos - len, len)) return 0;
pos = packetparser_uint32(b->buf, b->len, pos, &len); /* mac algorithms server to client */
pos = packetparser_skip(b->buf, b->len, pos, len);
pos = packetparser_uint32(b->buf, b->len, pos, &len); /* compress algorithms client to server */
pos = packetparser_skip(b->buf, b->len, pos, len);
pos = packetparser_uint32(b->buf, b->len, pos, &len); /* compress algorithms server to client */
pos = packetparser_skip(b->buf, b->len, pos, len);
pos = packetparser_uint32(b->buf, b->len, pos, &len); /* languages client to server */
pos = packetparser_skip(b->buf, b->len, pos, len);
pos = packetparser_uint32(b->buf, b->len, pos, &len); /* languages server to client */
pos = packetparser_skip(b->buf, b->len, pos, len);
pos = packetparser_uint8(b->buf, b->len, pos, &ch); /* kex first packet follows */
packet.kex_packet_follows = ch;
pos = packetparser_uint32(b->buf, b->len, pos, &len); /* reserved */
pos = packetparser_end(b->buf, b->len, pos);
return 1;
}
tinyssh-20190101/tinyssh/packet_kexdh.c 0000664 0000000 0000000 00000011200 13412736503 0017747 0 ustar 00root root 0000000 0000000 /*
20141025
Jan Mojzis
Public domain.
*/
#include "buf.h"
#include "ssh.h"
#include "e.h"
#include "uint32_unpack_big.h"
#include "byte.h"
#include "sshcrypto.h"
#include "packetparser.h"
#include "bug.h"
#include "log.h"
#include "purge.h"
#include "subprocess.h"
#include "packet.h"
int packet_kexdh(const char *keydir, struct buf *b1, struct buf *b2) {
unsigned char clientpk[sshcrypto_kem_PUBLICKEYMAX];
unsigned char serverpk[sshcrypto_kem_CIPHERTEXTMAX];
unsigned char sharedsecret[sshcrypto_kem_MAX];
unsigned char sm[sshcrypto_sign_MAX];
unsigned char key[sshcrypto_cipher_KEYMAX];
unsigned char hash[sshcrypto_hash_MAX];
long long pos = 0;
crypto_uint8 ch;
crypto_uint32 len;
long long i;
if (packet.kex_packet_follows && !packet.kex_guess) {
buf_purge(b1);
if (!packet_getall(b1, SSH_MSG_KEXDH_INIT)) bug_proto();
}
buf_purge(b1);
if (!packet_getall(b1, SSH_MSG_KEXDH_INIT)) bug_proto();
pos = packetparser_uint8(b1->buf, b1->len, pos, &ch); /* byte SSH_MSG_KEXDH_INIT */
if (ch != SSH_MSG_KEXDH_INIT) bug_proto();
pos = packetparser_uint32(b1->buf, b1->len, pos, &len); /* string client's public key */
if (len != sshcrypto_kem_publickeybytes) bug_proto();
pos = packetparser_copy(b1->buf, b1->len, pos, clientpk, len);
pos = packetparser_end(b1->buf, b1->len, pos);
buf_purge(b1);
/* generate key and compute shared secret */
do {
/* XXX - workaroud for bug in OpenSSH 6.5 - 6.6 */
if (sshcrypto_enc(serverpk, sharedsecret, clientpk) != 0) bug_proto();
} while(sharedsecret[0] == 0 && sshcrypto_kem_publickeybytes == 32);
/* create hash */
buf_purge(&packet.hashbuf);
buf_putstringlen(&packet.hashbuf, packet.helloreceive.buf, packet.helloreceive.len);
buf_putstringlen(&packet.hashbuf, packet.hellosend.buf, packet.hellosend.len);
buf_putstringlen(&packet.hashbuf, packet.kexrecv.buf, packet.kexrecv.len);
buf_putstringlen(&packet.hashbuf, packet.kexsend.buf, packet.kexsend.len);
sshcrypto_buf_putsignpk(&packet.hashbuf, sshcrypto_sign_publickey);
buf_putstringlen(&packet.hashbuf, clientpk, sshcrypto_kem_publickeybytes);
buf_putstringlen(&packet.hashbuf, serverpk, sshcrypto_kem_ciphertextbytes);
sshcrypto_buf_putkemkey(&packet.hashbuf, sharedsecret);
sshcrypto_hash(hash, packet.hashbuf.buf, packet.hashbuf.len);
/* session id */
if (!packet.flagrekeying) byte_copy(packet.sessionid, sshcrypto_hash_bytes, hash);
packet.flagrekeying = 1;
/* signature */
if (subprocess_sign(sm, sshcrypto_sign_bytes, keydir, hash, sshcrypto_hash_bytes) != 0) bug();
buf_purge(b1); buf_purge(b2);
/* send server kex_ecdh_reply */
buf_putnum8(b2, SSH_MSG_KEXDH_REPLY); /* SSH_MSG_KEXDH_REPLY */
sshcrypto_buf_putsignpk(b2, sshcrypto_sign_publickey); /* public key */
buf_putstringlen(b2, serverpk, sshcrypto_kem_ciphertextbytes); /* servers's public key */
sshcrypto_buf_putsignature(b2, sm); /* signature */
packet_put(b2);
/* send server newkeys */
buf_purge(b2);
buf_putnum8(b2, SSH_MSG_NEWKEYS);
packet_put(b2);
if (!packet_sendall()) bug();
/* receive new keys */
do {
buf_purge(b2);
if (!packet_getall(b2, 0)) bug();
} while (b2->buf[0] != SSH_MSG_NEWKEYS);
/* key derivation */
for(i = 0; i < 6; ++i) {
buf_purge(b1);
sshcrypto_buf_putkemkey(b1, sharedsecret);
buf_put(b1, hash, sshcrypto_hash_bytes);
buf_putnum8(b1, 'A' + i);
buf_put(b1, packet.sessionid, sshcrypto_hash_bytes);
sshcrypto_hash(key, b1->buf, b1->len);
/* one extend */
buf_purge(b1);
sshcrypto_buf_putkemkey(b1, sharedsecret);
buf_put(b1, hash, sshcrypto_hash_bytes);
buf_put(b1, key, sshcrypto_hash_bytes);
sshcrypto_hash(key + sshcrypto_hash_bytes, b1->buf, b1->len);
if (i == 0) byte_copy(packet.clientnonce, sshcrypto_cipher_KEYMAX, key);
if (i == 1) byte_copy(packet.servernonce, sshcrypto_cipher_KEYMAX, key);
if (i == 2) byte_copy(packet.clientkey, sshcrypto_cipher_KEYMAX, key);
if (i == 3) byte_copy(packet.serverkey, sshcrypto_cipher_KEYMAX, key);
if (i == 4) byte_copy(packet.clientmackey, sshcrypto_cipher_KEYMAX, key);
if (i == 5) byte_copy(packet.servermackey, sshcrypto_cipher_KEYMAX, key);
}
purge(clientpk, sizeof clientpk);
purge(serverpk, sizeof serverpk);
purge(sharedsecret, sizeof sharedsecret);
purge(sm, sizeof sm);
purge(key, sizeof key);
purge(hash, sizeof hash);
return 1;
}
tinyssh-20190101/tinyssh/packet_put.c 0000664 0000000 0000000 00000002005 13412736503 0017457 0 ustar 00root root 0000000 0000000 /*
20140207
Jan Mojzis
Public domain.
*/
#include "uint32_pack_big.h"
#include "buf.h"
#include "packet.h"
static void packet_put_plain_(struct buf *b) {
long long pos;
crypto_uint8 paddinglen;
struct buf *sendbuf = &packet.sendbuf;
pos = sendbuf->len; /* get position */
buf_putnum32(sendbuf, 0); /* length */
buf_putnum8(sendbuf, 0); /* padding length */
buf_put(sendbuf, b->buf, b->len); /* add data */
packet.sendpacketid++; /* increment id */
/* padding */
paddinglen = 2 * 8 - ((sendbuf->len - pos) % 8);
buf_putzerobytes(sendbuf, paddinglen);
sendbuf->buf[pos + 4] = paddinglen;
/* add packet length */
uint32_pack_big(sendbuf->buf + pos, sendbuf->len - pos - 4);
}
int packet_putisready(void) {
return buf_ready(&packet.sendbuf, PACKET_FULLLIMIT);
}
void packet_put(struct buf *b) {
if (packet.flagkeys) {
sshcrypto_packet_put(b);
}
else {
packet_put_plain_(b);
}
}
tinyssh-20190101/tinyssh/packet_recv.c 0000664 0000000 0000000 00000001376 13412736503 0017620 0 ustar 00root root 0000000 0000000 /*
20140120
Jan Mojzis
Public domain.
*/
#include
#include "e.h"
#include "buf.h"
#include "purge.h"
#include "packet.h"
int packet_recvisready(void) {
return buf_ready(&packet.recvbuf, PACKET_FULLLIMIT);
}
int packet_recv(void) {
long long r;
struct buf *b = &packet.recvbuf;
if (b->len < PACKET_ZEROBYTES) {
b->len = PACKET_ZEROBYTES;
purge(b->buf, PACKET_ZEROBYTES);
}
if (!packet_recvisready()) return 1;
r = read(0, b->buf + b->len, PACKET_FULLLIMIT);
if (r == 0) { errno = ECONNRESET; return 0; }
if (r == -1) {
if (errno == EINTR) return 1;
if (errno == EAGAIN) return 1;
if (errno == EWOULDBLOCK) return 1;
return 0;
}
b->len += r;
return 1;
}
tinyssh-20190101/tinyssh/packet_send.c 0000664 0000000 0000000 00000001617 13412736503 0017610 0 ustar 00root root 0000000 0000000 /*
20140120
Jan Mojzis
Public domain.
*/
#include
#include "writeall.h"
#include "e.h"
#include "byte.h"
#include "purge.h"
#include "packet.h"
int packet_sendisready(void) {
return (packet.sendbuf.len > 0);
}
int packet_send(void) {
struct buf *sendbuf = &packet.sendbuf;
long long w;
if (sendbuf->len <= 0) return 1;
w = write(1, sendbuf->buf, sendbuf->len);
if (w == -1) {
if (errno == EINTR) return 1;
if (errno == EAGAIN) return 1;
if (errno == EWOULDBLOCK) return 1;
return 0;
}
byte_copy(sendbuf->buf, sendbuf->len - w, sendbuf->buf + w);
sendbuf->len -= w;
purge(sendbuf->buf + sendbuf->len, w);
return 1;
}
int packet_sendall(void) {
if (writeall(1, packet.sendbuf.buf, packet.sendbuf.len) == -1) return 0;
purge(packet.sendbuf.buf, packet.sendbuf.len);
packet.sendbuf.len = 0;
return 1;
}
tinyssh-20190101/tinyssh/packet_unimplemented.c 0000664 0000000 0000000 00000001062 13412736503 0021517 0 ustar 00root root 0000000 0000000 /*
20150719
Jan Mojzis
Public domain.
*/
#include "buf.h"
#include "ssh.h"
#include "log.h"
#include "numtostr.h"
#include "packet.h"
int packet_unimplemented(struct buf *b) {
char strnum[NUMTOSTR_LEN];
/* note that b->buf[0] contains packetid */
log_d3("packet=", numtostr(strnum, b->buf[0]),", sending SSH_MSG_UNIMPLEMENTED message");
buf_purge(b);
buf_putnum8(b, SSH_MSG_UNIMPLEMENTED); /* SSH_MSG_UNIMPLEMENTED */
buf_putnum32(b, packet.receivepacketid); /* packeid */
packet_put(b);
return packet_sendall();
}
tinyssh-20190101/tinyssh/packetparser.c 0000664 0000000 0000000 00000005014 13412736503 0020007 0 ustar 00root root 0000000 0000000 /*
20140210
Jan Mojzis
Public domain.
The 'packetparser' library is used to parse SSH packets.
The 'packetparser_*' function has always information about buffer, buffer length
and position in the buffer. Before parsing checks if the position
is not exceeding the buffer length. If the position exceeds the buffer length,
packetparser_* function immediately exits with 111 status code.
*/
#include "e.h"
#include "uint32_unpack_big.h"
#include "bug.h"
#include "byte.h"
#include "packetparser.h"
/*
Parse one-byte character.
*/
long long packetparser_uint8_(const char *fn, unsigned long long line,
const unsigned char *buf, long long len, long long pos, crypto_uint8 *out) {
if (!buf || len < 0 || len > 1073741824 || pos < 0 || pos > 1073741824 || !out) bug_inval_(fn, line);
if (pos + 1 > len) bug_proto_(fn, line);
*out = buf[pos];
return pos + 1;
}
/*
Parse the unsigned 32-bit number.
*/
long long packetparser_uint32_(const char *fn, unsigned long long line,
const unsigned char *buf, long long len, long long pos, crypto_uint32 *out) {
if (!buf || len < 0 || len > 1073741824 || pos < 0 || pos > 1073741824 || !out) bug_inval_(fn, line);
if (pos + 4 > len) bug_proto_(fn, line);
*out = uint32_unpack_big(buf + pos);
return pos + 4;
}
/*
Parse the string and copy it.
*/
long long packetparser_copy_(const char *fn, unsigned long long line,
const unsigned char *buf, long long len, long long pos, unsigned char *out, long long outlen) {
if (!buf || len < 0 || len > 1073741824 || pos < 0 || pos > 1073741824 || !out || outlen < 0 || outlen > 1073741824) bug_inval_(fn, line);
if (pos + outlen > len) bug_proto_(fn, line);
byte_copy(out, outlen, buf + pos);
return pos + outlen;
}
/*
Skip 'len' bytes.
*/
long long packetparser_skip_(const char *fn, unsigned long long line,
const unsigned char *buf, long long len, long long pos, long long skip) {
if (!buf || len < 0 || len > 1073741824 || pos < 0 || pos > 1073741824 || skip < 0 || skip > 1073741824) bug_inval_(fn, line);
if (pos + skip > len) bug_proto_(fn, line);
return pos + skip;
}
/*
Check if the position is end-position.
*/
long long packetparser_end_(const char *fn, unsigned long long line,
const unsigned char *buf, long long len, long long pos) {
if (!buf || len < 0 || len > 1073741824 || pos < 0 || pos > 1073741824) bug_inval_(fn, line);
if (pos != len) bug_proto_(fn, line);
return pos;
}
tinyssh-20190101/tinyssh/packetparser.h 0000664 0000000 0000000 00000002365 13412736503 0020022 0 ustar 00root root 0000000 0000000 #ifndef _PACKETPARSER_H____
#define _PACKETPARSER_H____
#include "crypto_uint32.h"
#include "crypto_uint8.h"
extern long long packetparser_uint8_(const char *, unsigned long long, const unsigned char *, long long, long long, crypto_uint8 *);
extern long long packetparser_uint32_(const char *, unsigned long long, const unsigned char *, long long, long long, crypto_uint32 *);
extern long long packetparser_copy_(const char *, unsigned long long, const unsigned char *, long long, long long, unsigned char *, long long);
extern long long packetparser_skip_(const char *, unsigned long long, const unsigned char *, long long, long long, long long);
extern long long packetparser_end_(const char *, unsigned long long, const unsigned char *, long long, long long);
#define packetparser_uint8(a, b, c, d) packetparser_uint8_(__FILE__, __LINE__, (a), (b), (c), (d))
#define packetparser_uint32(a, b, c, d) packetparser_uint32_(__FILE__, __LINE__, (a), (b), (c), (d))
#define packetparser_copy(a, b, c, d, e)packetparser_copy_(__FILE__, __LINE__, (a), (b), (c), (d), (e))
#define packetparser_skip(a, b, c, d) packetparser_skip_(__FILE__, __LINE__, (a), (b), (c), (d))
#define packetparser_end(a, b, c) packetparser_end_(__FILE__, __LINE__, (a), (b), (c))
#endif
tinyssh-20190101/tinyssh/porttostr.c 0000664 0000000 0000000 00000001504 13412736503 0017403 0 ustar 00root root 0000000 0000000 /*
20130604
Jan Mojzis
Public domain.
*/
#include "crypto_uint16.h"
#include "porttostr.h"
/*
The 'porttostr(strbuf,port)' converts 'port' from network byte order
into the 0-terminated string. The 'port' length is always 2 bytes.
The caller must allocate at least PORTTOSTR_LEN bytes for 'strbuf'.
*/
char *porttostr(char *strbuf, const unsigned char *port) {
long long len = 0;
crypto_uint16 num;
static char staticbuf[PORTTOSTR_LEN];
if (!strbuf) strbuf = staticbuf; /* not thread-safe */
num = port[0]; num <<= 8; num |= port[1];
do {
num /= 10; ++len;
} while (num);
strbuf += len;
num = port[0]; num <<= 8; num |= port[1];
do {
*--strbuf = '0' + (num % 10);
num /= 10;
} while (num);
while (len < PORTTOSTR_LEN) strbuf[len++] = 0;
return strbuf;
}
tinyssh-20190101/tinyssh/porttostr.h 0000664 0000000 0000000 00000000213 13412736503 0017404 0 ustar 00root root 0000000 0000000 #ifndef _PORTTOSTR_H____
#define _PORTTOSTR_H____
#define PORTTOSTR_LEN 6
extern char *porttostr(char *, const unsigned char *);
#endif
tinyssh-20190101/tinyssh/purge.h 0000664 0000000 0000000 00000000137 13412736503 0016453 0 ustar 00root root 0000000 0000000 #ifndef _PURGE_H____
#define _PURGE_H____
#include "cleanup.h"
#define purge cleanup_
#endif
tinyssh-20190101/tinyssh/randommod.c 0000664 0000000 0000000 00000000625 13412736503 0017306 0 ustar 00root root 0000000 0000000 /* taken from nacl-20110221, from curvecp/randommod.c */
#include "randombytes.h"
#include "randommod.h"
/* XXX: current implementation is limited to n<2^55 */
long long randommod(long long n)
{
long long result = 0;
long long j;
unsigned char r[32];
if (n <= 1) return 0;
randombytes(r,32);
for (j = 0;j < 32;++j) result = (result * 256 + (unsigned long long) r[j]) % n;
return result;
}
tinyssh-20190101/tinyssh/randommod.h 0000664 0000000 0000000 00000000142 13412736503 0017305 0 ustar 00root root 0000000 0000000 #ifndef _RANDOMMOD_H____
#define _RANDOMMOD_H____
extern long long randommod(long long);
#endif
tinyssh-20190101/tinyssh/readall.c 0000664 0000000 0000000 00000001060 13412736503 0016724 0 ustar 00root root 0000000 0000000 /* taken from nacl-20110221, from curvecp/load.c */
#include
#include "e.h"
#include "readall.h"
int readall(int fd, void *xv, long long xlen) {
long long r;
unsigned char *x = (unsigned char *)xv;
while (xlen > 0) {
r = xlen;
if (r > 1048576) r = 1048576;
r = read(fd, x, r);
if (r == 0) errno = EPROTO;
if (r <= 0) {
if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) continue;
return -1;
}
x += r;
xlen -= r;
}
return 0;
}
tinyssh-20190101/tinyssh/readall.h 0000664 0000000 0000000 00000000143 13412736503 0016732 0 ustar 00root root 0000000 0000000 #ifndef _READALL_H____
#define _READALL_H____
extern int readall(int, void *, long long);
#endif
tinyssh-20190101/tinyssh/savesync.c 0000664 0000000 0000000 00000001002 13412736503 0017147 0 ustar 00root root 0000000 0000000 /* taken from nacl-20110221, from curvecp/savesync.c */
#include
#include
#include
#include
#include "open.h"
#include "savesync.h"
#include "writeall.h"
static int writesync(int fd,const void *x,long long xlen)
{
if (writeall(fd,x,xlen) == -1) return -1;
return fsync(fd);
}
int savesync(const char *fn,const void *x,long long xlen)
{
int fd;
int r;
fd = open_write(fn);
if (fd == -1) return -1;
r = writesync(fd,x,xlen);
close(fd);
return r;
}
tinyssh-20190101/tinyssh/savesync.h 0000664 0000000 0000000 00000000151 13412736503 0017160 0 ustar 00root root 0000000 0000000 #ifndef SAVESYNC_H
#define SAVESYNC_H
extern int savesync(const char *,const void *,long long);
#endif
tinyssh-20190101/tinyssh/ssh.c 0000664 0000000 0000000 00000003142 13412736503 0016120 0 ustar 00root root 0000000 0000000 #include
#include "ssh.h"
#define X(e,s) if (i == e) return s;
/*
Return short name of signal.
*/
const char *ssh_sigstr(int i) {
#ifdef SIGABRT
X(SIGABRT, "ABRT");
#endif
#ifdef SIGALRM
X(SIGALRM, "ALRM");
#endif
#ifdef SIGFPE
X(SIGFPE, "FPE");
#endif
#ifdef SIGHUP
X(SIGHUP, "HUP");
#endif
#ifdef SIGILL
X(SIGILL, "ILL");
#endif
#ifdef SIGINT
X(SIGINT, "INT");
#endif
#ifdef SIGKILL
X(SIGKILL, "KILL");
#endif
#ifdef SIGPIPE
X(SIGPIPE, "PIPE");
#endif
#ifdef SIGQUIT
X(SIGQUIT, "QUIT");
#endif
#ifdef SIGSEGV
X(SIGSEGV, "SEGV");
#endif
#ifdef SIGTERM
X(SIGTERM, "TERM");
#endif
#ifdef SIGUSR1
X(SIGUSR1, "USR1");
#endif
#ifdef SIGUSR2
X(SIGUSR2, "USR2");
#endif
return "UNKNOWN";
}
/*
Return long name of signal.
*/
const char *ssh_sigstrlong(int i) {
#ifdef SIGABRT
X(SIGABRT, "SIGABRT (abort)")
#endif
#ifdef SIGALRM
X(SIGALRM, "SIGALRM (alarm clock)")
#endif
#ifdef SIGFPE
X(SIGFPE, "SIGFPE (floating-point exception)")
#endif
#ifdef SIGILL
X(SIGILL, "SIGILL (illegal instruction)")
#endif
#ifdef SIGINT
X(SIGINT, "SIGINT (interrupt)")
#endif
#ifdef SIGKILL
X(SIGKILL, "SIGKILL (kill, unblockable)")
#endif
#ifdef SIGPIPE
X(SIGPIPE, "SIGPIPE (broken pipe)")
#endif
#ifdef SIGQUIT
X(SIGQUIT, "SIGQUIT (quit)")
#endif
#ifdef SIGSEGV
X(SIGSEGV, "SIGSEGV (segment violation)")
#endif
#ifdef SIGTERM
X(SIGTERM, "SIGTERM (termination)")
#endif
#ifdef SIGUSR1
X(SIGUSR1, "SIGUSR1 (user defined signal 1)")
#endif
#ifdef SIGUSR2
X(SIGUSR2, "SIGUSR2 (user defined signal 2)")
#endif
return "UNKNOWN SIGNAL";
}
tinyssh-20190101/tinyssh/ssh.h 0000664 0000000 0000000 00000010336 13412736503 0016130 0 ustar 00root root 0000000 0000000 #ifndef _SSH_H____
#define _SSH_H____
extern const char *ssh_sigstr(int);
extern const char *ssh_sigstrlong(int);
#define SSH_MSG_DISCONNECT 1 /* 0x1 */
#define SSH_MSG_IGNORE 2 /* 0x2 */
#define SSH_MSG_UNIMPLEMENTED 3 /* 0x3 */
#define SSH_MSG_DEBUG 4 /* 0x4 */
#define SSH_MSG_SERVICE_REQUEST 5 /* 0x5 */
#define SSH_MSG_SERVICE_ACCEPT 6 /* 0x6 */
#define SSH_MSG_KEXINIT 20 /* 0x14 */
#define SSH_MSG_NEWKEYS 21 /* 0x15 */
#define SSH_MSG_KEXDH_INIT 30 /* 0x1e */
#define SSH_MSG_KEXDH_REPLY 31 /* 0x1f */
#define SSH_MSG_KEX_DH_GEX_REQUEST 30 /* 0x1e */
#define SSH_MSG_KEX_DH_GEX_GROUP 31 /* 0x1f */
#define SSH_MSG_KEX_DH_GEX_INIT 32 /* 0x20 */
#define SSH_MSG_KEX_DH_GEX_REPLY 33 /* 0x21 */
#define SSH_MSG_KEXRSA_PUBKEY 30 /* 0x1e */
#define SSH_MSG_KEXRSA_SECRET 31 /* 0x1f */
#define SSH_MSG_KEXRSA_DONE 32 /* 0x20 */
#define SSH_MSG_USERAUTH_REQUEST 50 /* 0x32 */
#define SSH_MSG_USERAUTH_FAILURE 51 /* 0x33 */
#define SSH_MSG_USERAUTH_SUCCESS 52 /* 0x34 */
#define SSH_MSG_USERAUTH_BANNER 53 /* 0x35 */
#define SSH_MSG_USERAUTH_PK_OK 60 /* 0x3c */
#define SSH_MSG_USERAUTH_PASSWD_CHANGEREQ 60 /* 0x3c */
#define SSH_MSG_USERAUTH_INFO_REQUEST 60 /* 0x3c */
#define SSH_MSG_USERAUTH_INFO_RESPONSE 61 /* 0x3d */
#define SSH_MSG_GLOBAL_REQUEST 80 /* 0x50 */
#define SSH_MSG_REQUEST_SUCCESS 81 /* 0x51 */
#define SSH_MSG_REQUEST_FAILURE 82 /* 0x52 */
#define SSH_MSG_CHANNEL_OPEN 90 /* 0x5a */
#define SSH_MSG_CHANNEL_OPEN_CONFIRMATION 91 /* 0x5b */
#define SSH_MSG_CHANNEL_OPEN_FAILURE 92 /* 0x5c */
#define SSH_MSG_CHANNEL_WINDOW_ADJUST 93 /* 0x5d */
#define SSH_MSG_CHANNEL_DATA 94 /* 0x5e */
#define SSH_MSG_CHANNEL_EXTENDED_DATA 95 /* 0x5f */
#define SSH_MSG_CHANNEL_EOF 96 /* 0x60 */
#define SSH_MSG_CHANNEL_CLOSE 97 /* 0x61 */
#define SSH_MSG_CHANNEL_REQUEST 98 /* 0x62 */
#define SSH_MSG_CHANNEL_SUCCESS 99 /* 0x63 */
#define SSH_MSG_CHANNEL_FAILURE 100 /* 0x64 */
#define SSH_MSG_USERAUTH_GSSAPI_RESPONSE 60
#define SSH_MSG_USERAUTH_GSSAPI_TOKEN 61
#define SSH_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE 63
#define SSH_MSG_USERAUTH_GSSAPI_ERROR 64
#define SSH_MSG_USERAUTH_GSSAPI_ERRTOK 65
#define SSH_MSG_USERAUTH_GSSAPI_MIC 66
#define SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT 1
#define SSH_DISCONNECT_PROTOCOL_ERROR 2
#define SSH_DISCONNECT_KEY_EXCHANGE_FAILED 3
#define SSH_DISCONNECT_RESERVED 4
#define SSH_DISCONNECT_MAC_ERROR 5
#define SSH_DISCONNECT_COMPRESSION_ERROR 6
#define SSH_DISCONNECT_SERVICE_NOT_AVAILABLE 7
#define SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED 8
#define SSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE 9
#define SSH_DISCONNECT_CONNECTION_LOST 10
#define SSH_DISCONNECT_BY_APPLICATION 11
#define SSH_DISCONNECT_TOO_MANY_CONNECTIONS 12
#define SSH_DISCONNECT_AUTH_CANCELLED_BY_USER 13
#define SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE 14
#define SSH_DISCONNECT_ILLEGAL_USER_NAME 15
#define SSH_OPEN_ADMINISTRATIVELY_PROHIBITED 1
#define SSH_OPEN_CONNECT_FAILED 2
#define SSH_OPEN_UNKNOWN_CHANNEL_TYPE 3
#define SSH_OPEN_RESOURCE_SHORTAGE 4
#endif
tinyssh-20190101/tinyssh/sshcrypto.c 0000664 0000000 0000000 00000003255 13412736503 0017366 0 ustar 00root root 0000000 0000000 /*
20140225
Jan Mojzis
Public domain.
*/
#include "purge.h"
#include "bug.h"
#include "str.h"
#include "sshcrypto.h"
/*
Initialize and check *MAX constants
*/
void sshcrypto_init(void) {
long long i;
/* kex */
for (i = 0; sshcrypto_kexs[i].name; ++i) {
if (sshcrypto_kexs[i].kem_publickeybytes > sshcrypto_kem_PUBLICKEYMAX) bug_inval();
if (sshcrypto_kexs[i].kem_ciphertextbytes > sshcrypto_kem_CIPHERTEXTMAX) bug_inval();
if (sshcrypto_kexs[i].kem_bytes > sshcrypto_kem_MAX) bug_inval();
if (sshcrypto_kexs[i].hash_bytes > sshcrypto_hash_MAX) bug_inval();
}
/* key */
for (i = 0; sshcrypto_keys[i].name; ++i) {
if (sshcrypto_keys[i].sign_publickeybytes > sshcrypto_sign_PUBLICKEYMAX) bug_inval();
if (sshcrypto_keys[i].sign_secretkeybytes > sshcrypto_sign_SECRETKEYMAX) bug_inval();
if (sshcrypto_keys[i].sign_bytes > sshcrypto_sign_MAX) bug_inval();
if (str_len(sshcrypto_keys[i].name) + 1 > sshcrypto_sign_NAMEMAX) bug_inval();
}
/* cipher */
for (i = 0; sshcrypto_ciphers[i].name; ++i) {
if (sshcrypto_ciphers[i].stream_keybytes > sshcrypto_cipher_KEYMAX) bug_inval();
}
}
/*
Remove sentitive data from allocated memory.
*/
void sshcrypto_purge(void) {
long long i;
/* kex */
for (i = 0; sshcrypto_kexs[i].name; ++i) {
purge(&sshcrypto_kexs[i], sizeof(struct sshcrypto_kex));
}
/* key */
for (i = 0; sshcrypto_keys[i].name; ++i) {
purge(&sshcrypto_keys[i], sizeof(struct sshcrypto_key));
}
/* cipher */
for (i = 0; sshcrypto_ciphers[i].name; ++i) {
purge(&sshcrypto_ciphers[i], sizeof(struct sshcrypto_cipher));
}
}
tinyssh-20190101/tinyssh/sshcrypto.h 0000664 0000000 0000000 00000014741 13412736503 0017375 0 ustar 00root root 0000000 0000000 #ifndef _SSHCRYPTO_H____
#define _SSHCRYPTO_H____
#include "buf.h"
#include "crypto.h"
/* crypto type */
#define sshcrypto_TYPEOLDCRYPTO 0x1 /* oldcrypto removed */
#define sshcrypto_TYPENEWCRYPTO 0x2 /* ssh-ed25519, curve25519-sha256@libssh.org, chacha20-poly1305@openssh.com */
#define sshcrypto_TYPEPQCRYPTO 0x4 /* TODO, TODO, chacha20-poly1305@openssh.com */
/* kex - kem + hash */
#define sshcrypto_kem_PUBLICKEYMAX crypto_kem_sntrup4591761x25519_PUBLICKEYBYTES
#define sshcrypto_kem_CIPHERTEXTMAX crypto_kem_sntrup4591761x25519_CIPHERTEXTBYTES
#define sshcrypto_kem_MAX crypto_kem_sntrup4591761x25519_BYTES
#define sshcrypto_hash_MAX crypto_hash_sha512_BYTES
struct sshcrypto_kex {
const char *name;
int (*enc)(unsigned char *, unsigned char *, const unsigned char *);
long long kem_publickeybytes;
long long kem_ciphertextbytes;
long long kem_bytes;
int (*hash)(unsigned char *, const unsigned char *, unsigned long long);
long long hash_bytes;
void (*buf_putkemkey)(struct buf *, const unsigned char *);
unsigned int cryptotype;
int flagenabled;
};
extern struct sshcrypto_kex sshcrypto_kexs[];
extern const char *sshcrypto_kex_name;
extern int (*sshcrypto_enc)(unsigned char *, unsigned char *, const unsigned char *);
extern long long sshcrypto_kem_publickeybytes;
extern long long sshcrypto_kem_ciphertextbytes;
extern long long sshcrypto_kem_bytes;
extern int (*sshcrypto_hash)(unsigned char *, const unsigned char *, unsigned long long);
extern long long sshcrypto_hash_bytes;
extern void (*sshcrypto_buf_putkemkey)(struct buf *, const unsigned char *);
extern int sshcrypto_kex_select(const unsigned char *, long long, crypto_uint8 *);
extern void sshcrypto_kex_put(struct buf *);
#if defined(crypto_scalarmult_curve25519_BYTES) && defined(crypto_hash_sha256_BYTES)
/* sshcrypto_kex_curve25519.c */
extern int curve25519_enc(unsigned char *, unsigned char *, const unsigned char *);
extern void curve25519_putkemkey(struct buf *, const unsigned char *);
#endif
#if defined(crypto_kem_sntrup4591761x25519_BYTES) && defined(crypto_hash_sha512_BYTES)
/* sshcrypto_kex_sntrup4591761x25519.c */
extern void sntrup4591761x25519_putkemkey(struct buf *, const unsigned char *);
#endif
/* key - sign */
#define sshcrypto_sign_PUBLICKEYMAX 32 /* space for ed25519 pk */
#define sshcrypto_sign_SECRETKEYMAX 64 /* space for ed25519 sk */
#define sshcrypto_sign_MAX 64 /* space for ed25519 sig */
#define sshcrypto_sign_BASE64PUBLICKEYMAX 69 /* space for ed25519 in base64 + 0-terminator */
#define sshcrypto_sign_BASE64PUBLICKEYMIN 69 /* space for ed25519 in base64 + 0-terminator */
#define sshcrypto_sign_NAMEMAX 12 /* space for string ssh-ed25519 + 0-terminator */
struct sshcrypto_key {
const char *name;
int (*sign)(unsigned char *,unsigned long long *,const unsigned char *,unsigned long long,const unsigned char *);
int (*sign_open)(unsigned char *,unsigned long long *,const unsigned char *,unsigned long long,const unsigned char *);
int (*sign_keypair)(unsigned char *, unsigned char *);
unsigned char sign_publickey[sshcrypto_sign_PUBLICKEYMAX];
long long sign_publickeybytes;
long long sign_secretkeybytes;
long long sign_bytes;
const char *sign_publickeyfilename;
const char *sign_secretkeyfilename;
unsigned int cryptotype;
int sign_flagserver;
int sign_flagclient;
void (*buf_putsignature)(struct buf *, const unsigned char *);
void (*buf_putsignpk)(struct buf *, const unsigned char *);
void (*buf_putsignpkbase64)(struct buf *, const unsigned char *);
int (*parsesignature)(unsigned char *, const unsigned char *, long long);
int (*parsesignpk)(unsigned char *, const unsigned char *, long long);
};
extern struct sshcrypto_key sshcrypto_keys[];
extern const char *sshcrypto_key_name;
extern int (*sshcrypto_sign)(unsigned char *,unsigned long long *,const unsigned char *,unsigned long long,const unsigned char *);
extern unsigned char *sshcrypto_sign_publickey;
extern long long sshcrypto_sign_publickeybytes;
extern long long sshcrypto_sign_secretkeybytes;
extern long long sshcrypto_sign_bytes;
extern const char *sshcrypto_sign_secretkeyfilename;
extern void (*sshcrypto_buf_putsignature)(struct buf *, const unsigned char *);
extern void (*sshcrypto_buf_putsignpk)(struct buf *, const unsigned char *);
extern int sshcrypto_key_select(const unsigned char *, long long);
extern void sshcrypto_key_put(struct buf *);
#ifdef crypto_sign_ed25519_BYTES
/* sshcrypto_key_ed25519.c */
extern void ed25519_putsignature(struct buf *, const unsigned char *);
extern void ed25519_putsignpk(struct buf *, const unsigned char *);
extern void ed25519_putsignpkbase64(struct buf *, const unsigned char *);
extern int ed25519_parsesignpk(unsigned char *, const unsigned char *, long long);
extern int ed25519_parsesignature(unsigned char *, const unsigned char *, long long);
#endif
/* cipher + mac */
#define sshcrypto_cipher_KEYMAX 128 /* space for 2 x sha512 */
struct sshcrypto_cipher {
const char *name;
int (*stream_xor)(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
int (*auth)(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *);
long long stream_keybytes;
long long cipher_blockbytes;
long long auth_bytes;
void (*packet_put)(struct buf *);
int (*packet_get)(struct buf *);
unsigned int cryptotype;
int flagenabled;
};
extern struct sshcrypto_cipher sshcrypto_ciphers[];
extern const char *sshcrypto_cipher_name;
extern int (*sshcrypto_stream_xor)(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
extern int (*sshcrypto_auth)(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *);
extern long long sshcrypto_stream_keybytes;
extern long long sshcrypto_cipher_blockbytes;
extern long long sshcrypto_auth_bytes;
extern void (*sshcrypto_packet_put)(struct buf *);
extern int (*sshcrypto_packet_get)(struct buf *);
extern int sshcrypto_cipher_select(const unsigned char *, long long);
extern int sshcrypto_cipher_macselect(const unsigned char *, long long);
extern void sshcrypto_cipher_put(struct buf *);
extern void sshcrypto_cipher_macput(struct buf *b);
/* from sshcrypto_cipher_chachapoly.c */
extern void chachapoly_packet_put(struct buf *);
extern int chachapoly_packet_get(struct buf *);
/* init/purge */
extern void sshcrypto_init(void);
extern void sshcrypto_purge(void);
#endif
tinyssh-20190101/tinyssh/sshcrypto_cipher.c 0000664 0000000 0000000 00000007525 13412736503 0020724 0 ustar 00root root 0000000 0000000 /*
20140207
Jan Mojzis
Public domain.
*/
#include "crypto.h"
#include "stringparser.h"
#include "e.h"
#include "log.h"
#include "bug.h"
#include "str.h"
#include "byte.h"
#include "packet.h"
#include "sshcrypto.h"
struct sshcrypto_cipher sshcrypto_ciphers[] = {
#if defined(crypto_stream_chacha20_KEYBYTES) && defined(crypto_onetimeauth_poly1305_BYTES)
{ "chacha20-poly1305@openssh.com",
crypto_stream_chacha20_xor,
crypto_onetimeauth_poly1305,
crypto_stream_chacha20_KEYBYTES * 2,
8,
crypto_onetimeauth_poly1305_BYTES,
chachapoly_packet_put,
chachapoly_packet_get,
sshcrypto_TYPENEWCRYPTO | sshcrypto_TYPEPQCRYPTO,
0
},
#endif
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
const char *sshcrypto_cipher_name = 0;
int (*sshcrypto_stream_xor)(unsigned char *, const unsigned char *, unsigned long long, const unsigned char *, const unsigned char *) = 0;
int (*sshcrypto_stream_beforenm)(unsigned char *, const unsigned char *) = 0;
int (*sshcrypto_auth)(unsigned char *, const unsigned char *, unsigned long long, const unsigned char *) = 0;
long long sshcrypto_stream_keybytes = 0;
long long sshcrypto_cipher_blockbytes = 0;
long long sshcrypto_auth_bytes = 0;
void (*sshcrypto_packet_put)(struct buf *) = 0;
int (*sshcrypto_packet_get)(struct buf *) = 0;
int sshcrypto_cipher_select(const unsigned char *buf, long long len) {
long long i, pos = 0;
unsigned char *x;
long long xlen;
if (sshcrypto_cipher_name) return 1;
if (buf[len] != 0) bug_proto();
log_d2("kex: client: cipher algorithms: ", (char *)buf);
for (;;) {
pos = stringparser(buf, len, pos, &x, &xlen);
if (!pos) break;
for (i = 0; sshcrypto_ciphers[i].name; ++i) {
if (!sshcrypto_ciphers[i].flagenabled) continue;
if (str_equaln((char *)x, xlen, sshcrypto_ciphers[i].name)) {
sshcrypto_cipher_name = sshcrypto_ciphers[i].name;
sshcrypto_stream_xor = sshcrypto_ciphers[i].stream_xor;
sshcrypto_auth = sshcrypto_ciphers[i].auth;
sshcrypto_stream_keybytes = sshcrypto_ciphers[i].stream_keybytes;
sshcrypto_cipher_blockbytes = sshcrypto_ciphers[i].cipher_blockbytes;
sshcrypto_auth_bytes = sshcrypto_ciphers[i].auth_bytes;
sshcrypto_packet_get = sshcrypto_ciphers[i].packet_get;
sshcrypto_packet_put = sshcrypto_ciphers[i].packet_put;
log_d2("kex: cipher selected: ", sshcrypto_ciphers[i].name);
return 1;
}
}
}
log_d2("kex: cipher not available ", (char *)buf);
errno = EPROTO;
return 0;
}
int sshcrypto_cipher_macselect(const unsigned char *buf, long long len) {
if (buf[len] != 0) bug_proto();
log_d2("kex: client: mac algorithms: ", (char *)buf);
log_d1("kex: mac selected: hmac-sha2-256 (ignored for chacha20-poly1305@openssh.com)");
return 1;
}
void sshcrypto_cipher_put(struct buf *b) {
crypto_uint32 len = 0;
long long i, j, start;
j = 0;
for (i = 0; sshcrypto_ciphers[i].name; ++i) {
if (!sshcrypto_ciphers[i].flagenabled) continue;
if (j++) ++len;
len += str_len(sshcrypto_ciphers[i].name);
}
buf_putnum32(b, len);
start = b->len;
j = 0;
for (i = 0; sshcrypto_ciphers[i].name; ++i) {
if (!sshcrypto_ciphers[i].flagenabled) continue;
if (j++) buf_puts(b, ",");
buf_puts(b, sshcrypto_ciphers[i].name);
}
b->buf[b->len] = 0;
log_d2("kex: server: cipher algorithms: ", (char *)b->buf + start);
}
/*
XXX some clients doesn't accept empty mac,
we send hmac-sha2-256
(for chacha20-poly1305@openssh.com is hmac-sha2-256 string ignored)
*/
void sshcrypto_cipher_macput(struct buf *b) {
buf_putstring(b, "hmac-sha2-256");
log_d1("kex: server: mac algorithms: hmac-sha2-256");
}
tinyssh-20190101/tinyssh/sshcrypto_cipher_chachapoly.c 0000664 0000000 0000000 00000007520 13412736503 0023112 0 ustar 00root root 0000000 0000000 /*
20140207
Jan Mojzis
Public domain.
*/
#include "uint32_pack_big.h"
#include "uint32_unpack_big.h"
#include "crypto_verify_16.h"
#include "randommod.h"
#include "e.h"
#include "byte.h"
#include "purge.h"
#include "sshcrypto.h"
#include "bug.h"
#include "packet.h"
#define BB sshcrypto_cipher_blockbytes
#define AB sshcrypto_auth_bytes
#define ZB 60
void chachapoly_packet_put(struct buf *b) {
long long pos;
crypto_uint8 paddinglen;
struct buf *sendbuf = &packet.sendbuf;
unsigned char n[8];
pos = sendbuf->len; /* get position */
buf_putzerobytes(sendbuf, ZB); /* zero bytes */
buf_putnum32(sendbuf, 0); /* the length */
buf_putnum8(sendbuf, 0); /* padding length */
buf_put(sendbuf, b->buf, b->len); /* add data */
/* pack nonce */
byte_zero(n, 4);
uint32_pack_big(n + 4, packet.sendpacketid++);
/* padding */
paddinglen = 2 * BB - ((sendbuf->len - pos - ZB) % BB) + 4;
paddinglen += randommod(2) * BB;
buf_putpadding(sendbuf, paddinglen);
sendbuf->buf[pos + ZB + 4] = paddinglen;
/* space for mac */
buf_putzerobytes(sendbuf, AB);
/* encrypt data */
sshcrypto_stream_xor(sendbuf->buf + pos, sendbuf->buf + pos, sendbuf->len - pos - AB, n, packet.serverkey);
/* add packet length */
uint32_pack_big(sendbuf->buf + pos + ZB, sendbuf->len - pos - AB - 4 - ZB);
/* encrypt the length */
sshcrypto_stream_xor(sendbuf->buf + pos + ZB, sendbuf->buf + pos + ZB, 4, n, packet.serverkey + 32);
purge(n, sizeof n);
/* authenticate data */
sshcrypto_auth(sendbuf->buf + sendbuf->len - AB, sendbuf->buf + pos + ZB, sendbuf->len - AB - pos - ZB, sendbuf->buf + pos);
/* remove zerobytes */
byte_copy(sendbuf->buf + pos, sendbuf->len - pos - ZB, sendbuf->buf + pos + ZB);
sendbuf->len -= ZB;
purge(sendbuf->buf + sendbuf->len, ZB);
}
int chachapoly_packet_get(struct buf *b) {
long long len;
struct buf *recvbuf = &packet.recvbuf;
unsigned char buf[16];
unsigned char *pp;
long long l;
unsigned char n[8];
/* we need at least 4 bytes */
if (recvbuf->len - PACKET_ZEROBYTES < 4) { packet.packet_length = 0; return 1; }
/* parse length */
byte_zero(n, 4);
uint32_pack_big(n + 4, packet.receivepacketid);
if (packet.packet_length == 0) {
sshcrypto_stream_xor(buf, recvbuf->buf + PACKET_ZEROBYTES, 4, n, packet.clientkey + 32);
packet.packet_length = uint32_unpack_big(buf);
}
if (packet.packet_length > PACKET_LIMIT) bug_proto();
if (packet.packet_length + AB + 4 > recvbuf->len - PACKET_ZEROBYTES) return 1;
/* verify and decrypt packet */
byte_zero(recvbuf->buf, 32);
sshcrypto_stream_xor(recvbuf->buf, recvbuf->buf, 32, n, packet.clientkey);
sshcrypto_auth(buf, recvbuf->buf + PACKET_ZEROBYTES, packet.packet_length + 4, recvbuf->buf);
if (crypto_verify_16(buf, recvbuf->buf + PACKET_ZEROBYTES + packet.packet_length + 4) != 0) bug_proto();
purge(buf, sizeof buf);
sshcrypto_stream_xor(recvbuf->buf + 4, recvbuf->buf + 4, packet.packet_length + PACKET_ZEROBYTES, n, packet.clientkey);
purge(n, sizeof n);
/* process packet */
len = packet.packet_length;
len -= recvbuf->buf[PACKET_ZEROBYTES + 4] + 1;
if (len <= 0) bug_proto();
buf_put(b, recvbuf->buf + PACKET_ZEROBYTES + 5, len);
pp = recvbuf->buf + PACKET_ZEROBYTES;
l = recvbuf->len - PACKET_ZEROBYTES;
byte_copy(pp, l - packet.packet_length + AB + 4, pp + packet.packet_length + AB + 4);
purge(pp + l - packet.packet_length + AB + 4, packet.packet_length + AB + 4);
recvbuf->len -= packet.packet_length + AB + 4;
/* packetid */
packet.receivepacketid++;
/* cleanup */
packet.packet_length = 0;
purge(recvbuf->buf, PACKET_ZEROBYTES);
return 1;
}
tinyssh-20190101/tinyssh/sshcrypto_kex.c 0000664 0000000 0000000 00000010012 13412736503 0020222 0 ustar 00root root 0000000 0000000 /*
20140203
Jan Mojzis
Public domain.
*/
#include "crypto.h"
#include "stringparser.h"
#include "str.h"
#include "byte.h"
#include "e.h"
#include "log.h"
#include "bug.h"
#include "sshcrypto.h"
struct sshcrypto_kex sshcrypto_kexs[] = {
#if defined(crypto_scalarmult_curve25519_BYTES) && defined(crypto_hash_sha256_BYTES)
{ "curve25519-sha256",
curve25519_enc,
crypto_scalarmult_curve25519_BYTES, /* pk */
crypto_scalarmult_curve25519_BYTES, /* c */
crypto_scalarmult_curve25519_BYTES, /* k */
crypto_hash_sha256,
crypto_hash_sha256_BYTES,
curve25519_putkemkey,
sshcrypto_TYPENEWCRYPTO,
0,
},
{ "curve25519-sha256@libssh.org",
curve25519_enc,
crypto_scalarmult_curve25519_BYTES, /* pk */
crypto_scalarmult_curve25519_BYTES, /* c */
crypto_scalarmult_curve25519_BYTES, /* k */
crypto_hash_sha256,
crypto_hash_sha256_BYTES,
curve25519_putkemkey,
sshcrypto_TYPENEWCRYPTO,
0,
},
#endif
#if defined(crypto_kem_sntrup4591761x25519_BYTES) && defined(crypto_hash_sha512_BYTES)
{ "sntrup4591761x25519-sha512@tinyssh.org",
crypto_kem_sntrup4591761x25519_enc,
crypto_kem_sntrup4591761x25519_PUBLICKEYBYTES, /* pk */
crypto_kem_sntrup4591761x25519_CIPHERTEXTBYTES, /* c */
crypto_kem_sntrup4591761x25519_BYTES, /* k */
crypto_hash_sha512,
crypto_hash_sha512_BYTES,
sntrup4591761x25519_putkemkey,
sshcrypto_TYPEPQCRYPTO,
0,
},
#endif
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
const char *sshcrypto_kex_name = 0;
int (*sshcrypto_enc)(unsigned char *, unsigned char *, const unsigned char *) = 0;
long long sshcrypto_kem_publickeybytes = 0;
long long sshcrypto_kem_ciphertextbytes = 0;
long long sshcrypto_kem_bytes = 0;
int (*sshcrypto_hash)(unsigned char *, const unsigned char *, unsigned long long) = 0;
long long sshcrypto_hash_bytes = 0;
void (*sshcrypto_buf_putkemkey)(struct buf *, const unsigned char *) = 0;
int sshcrypto_kex_select(const unsigned char *buf, long long len, crypto_uint8 *kex_guess) {
long long i, pos = 0;
unsigned char *x;
long long xlen;
if (sshcrypto_kex_name) return 1;
if (buf[len] != 0) bug_proto();
log_d2("kex: client: kex algorithms: ", (char *)buf);
*kex_guess = 1;
for (;;) {
pos = stringparser(buf, len, pos, &x, &xlen);
if (!pos) break;
for (i = 0; sshcrypto_kexs[i].name; ++i) {
if (!sshcrypto_kexs[i].flagenabled) continue;
if (str_equaln((char *)x, xlen, sshcrypto_kexs[i].name)) {
sshcrypto_kex_name = sshcrypto_kexs[i].name;
sshcrypto_enc = sshcrypto_kexs[i].enc;
sshcrypto_kem_publickeybytes = sshcrypto_kexs[i].kem_publickeybytes;
sshcrypto_kem_ciphertextbytes = sshcrypto_kexs[i].kem_ciphertextbytes;
sshcrypto_kem_bytes = sshcrypto_kexs[i].kem_bytes;
sshcrypto_hash = sshcrypto_kexs[i].hash;
sshcrypto_hash_bytes = sshcrypto_kexs[i].hash_bytes;
sshcrypto_buf_putkemkey = sshcrypto_kexs[i].buf_putkemkey;
log_d2("kex: kex selected: ", sshcrypto_kexs[i].name);
return 1;
}
}
*kex_guess = 0;
}
log_d2("kex: kex not available ", (char *)buf);
errno = EPROTO;
return 0;
}
void sshcrypto_kex_put(struct buf *b) {
crypto_uint32 len = 0;
long long i, j, start;
j = 0;
for (i = 0; sshcrypto_kexs[i].name; ++i) {
if (!sshcrypto_kexs[i].flagenabled) continue;
if (j++) ++len;
len += str_len(sshcrypto_kexs[i].name);
}
buf_putnum32(b, len);
start = b->len;
j = 0;
for (i = 0; sshcrypto_kexs[i].name; ++i) {
if (!sshcrypto_kexs[i].flagenabled) continue;
if (j++) buf_puts(b, ",");
buf_puts(b, sshcrypto_kexs[i].name);
}
b->buf[b->len] = 0;
log_d2("kex: server: kex algorithms: ", (char *)b->buf + start);
}
tinyssh-20190101/tinyssh/sshcrypto_kex_curve25519.c 0000664 0000000 0000000 00000001632 13412736503 0022044 0 ustar 00root root 0000000 0000000 /*
20140203
Jan Mojzis
Public domain.
*/
#include "buf.h"
#include "crypto.h"
#include "randombytes.h"
#include "purge.h"
#include "sshcrypto.h"
#if defined(crypto_scalarmult_curve25519_BYTES) && defined(crypto_hash_sha256_BYTES)
int curve25519_enc(unsigned char *c, unsigned char *k, const unsigned char *pk) {
unsigned char onetimesk[crypto_scalarmult_curve25519_SCALARBYTES];
int r = 0;
long long i;
unsigned int d = 0;
randombytes(onetimesk, sizeof onetimesk);
r |= crypto_scalarmult_curve25519_base(/*onetimepk*/ c, onetimesk);
r |= crypto_scalarmult_curve25519(k, onetimesk, pk);
for (i = 0; i < crypto_scalarmult_curve25519_BYTES; ++i) d |= k[i];
r |= -(1 & ((d - 1) >> 8));
purge(onetimesk, sizeof onetimesk);
return r;
}
void curve25519_putkemkey(struct buf *b, const unsigned char *x) {
buf_putsharedsecret(b, x, crypto_scalarmult_curve25519_BYTES);
}
#endif
tinyssh-20190101/tinyssh/sshcrypto_kex_sntrup4591761x25519.c 0000664 0000000 0000000 00000000525 13412736503 0023224 0 ustar 00root root 0000000 0000000 /*
20181225
Jan Mojzis
Public domain.
*/
#include "buf.h"
#include "crypto.h"
#include "sshcrypto.h"
#if defined(crypto_kem_sntrup4591761x25519_BYTES) && defined(crypto_hash_sha512_BYTES)
void sntrup4591761x25519_putkemkey(struct buf *b, const unsigned char *x) {
buf_putstringlen(b, x, crypto_kem_sntrup4591761x25519_BYTES);
}
#endif
tinyssh-20190101/tinyssh/sshcrypto_key.c 0000664 0000000 0000000 00000007741 13412736503 0020242 0 ustar 00root root 0000000 0000000 /*
20140204
Jan Mojzis
Public domain.
*/
#include "crypto.h"
#include "packetparser.h"
#include "stringparser.h"
#include "str.h"
#include "byte.h"
#include "e.h"
#include "log.h"
#include "bug.h"
#include "purge.h"
#include "sshcrypto.h"
struct sshcrypto_key sshcrypto_keys[] = {
#ifdef crypto_sign_ed25519_BYTES
{ "ssh-ed25519",
crypto_sign_ed25519,
crypto_sign_ed25519_open,
crypto_sign_ed25519_keypair,
{0},
crypto_sign_ed25519_PUBLICKEYBYTES,
crypto_sign_ed25519_SECRETKEYBYTES,
crypto_sign_ed25519_BYTES,
"ed25519.pk",
".ed25519.sk",
sshcrypto_TYPENEWCRYPTO,
0,
0,
ed25519_putsignature,
ed25519_putsignpk,
ed25519_putsignpkbase64,
ed25519_parsesignature,
ed25519_parsesignpk,
},
#endif
#if 0
{ "pqkeyTODO",
crypto_sign_ed25519,
crypto_sign_ed25519_open,
crypto_sign_ed25519_keypair,
{0},
crypto_sign_ed25519_PUBLICKEYBYTES,
crypto_sign_ed25519_SECRETKEYBYTES,
crypto_sign_ed25519_BYTES,
"pqkeyTODO.pk",
".pqkeyTODO.sk",
sshcrypto_TYPEPQCRYPTO,
0,
0,
ed25519_putsignature,
ed25519_putsignpk,
ed25519_putsignpkbase64,
ed25519_parsesignature,
ed25519_parsesignpk,
},
#endif
{ 0, 0, 0, 0, {0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
const char *sshcrypto_key_name = 0;
int (*sshcrypto_sign)(unsigned char *,unsigned long long *,const unsigned char *,unsigned long long,const unsigned char *) = 0;
unsigned char *sshcrypto_sign_publickey = 0;
long long sshcrypto_sign_publickeybytes = 0;
long long sshcrypto_sign_secretkeybytes = 0;
long long sshcrypto_sign_bytes = 0;
const char *sshcrypto_sign_secretkeyfilename = 0;
void (*sshcrypto_buf_putsignature)(struct buf *, const unsigned char *) = 0;
void (*sshcrypto_buf_putsignpk)(struct buf *, const unsigned char *) = 0;
int sshcrypto_key_select(const unsigned char *buf, long long len) {
long long i, pos = 0;
unsigned char *x;
long long xlen;
if (sshcrypto_key_name) return 1;
if (buf[len] != 0) bug_proto();
log_d2("kex: client: key algorithms: ", (char *)buf);
for (;;) {
pos = stringparser(buf, len, pos, &x, &xlen);
if (!pos) break;
for (i = 0; sshcrypto_keys[i].name; ++i) {
if (!sshcrypto_keys[i].sign_flagserver) continue;
if (str_equaln((char *)x, xlen, sshcrypto_keys[i].name)) {
sshcrypto_key_name = sshcrypto_keys[i].name;
sshcrypto_sign = sshcrypto_keys[i].sign;
sshcrypto_sign_publickey = sshcrypto_keys[i].sign_publickey;
sshcrypto_sign_publickeybytes = sshcrypto_keys[i].sign_publickeybytes;
sshcrypto_sign_secretkeybytes = sshcrypto_keys[i].sign_secretkeybytes;
sshcrypto_sign_bytes = sshcrypto_keys[i].sign_bytes;
sshcrypto_sign_secretkeyfilename = sshcrypto_keys[i].sign_secretkeyfilename;
sshcrypto_buf_putsignature = sshcrypto_keys[i].buf_putsignature;
sshcrypto_buf_putsignpk = sshcrypto_keys[i].buf_putsignpk;
log_d2("kex: key selected: ", sshcrypto_keys[i].name);
return 1;
}
}
}
log_d2("kex: key not available ", (char *)buf);
errno = EPROTO;
return 0;
}
void sshcrypto_key_put(struct buf *b) {
crypto_uint32 len = 0;
long long i, j, start;
j = 0;
for (i = 0; sshcrypto_keys[i].name; ++i) {
if (!sshcrypto_keys[i].sign_flagserver) continue;
if (j++) ++len;
len += str_len(sshcrypto_keys[i].name);
}
buf_putnum32(b, len);
start = b->len;
j = 0;
for (i = 0; sshcrypto_keys[i].name; ++i) {
if (!sshcrypto_keys[i].sign_flagserver) continue;
if (j++) buf_puts(b, ",");
buf_puts(b, sshcrypto_keys[i].name);
}
b->buf[b->len] = 0;
log_d2("kex: server: key algorithms: ", (char *)b->buf + start);
}
tinyssh-20190101/tinyssh/sshcrypto_key_ed25519.c 0000664 0000000 0000000 00000004134 13412736503 0021311 0 ustar 00root root 0000000 0000000 /*
20140204
Jan Mojzis
Public domain.
*/
#include "crypto.h"
#include "packetparser.h"
#include "buf.h"
#include "byte.h"
#include "str.h"
#include "purge.h"
#include "sshcrypto.h"
#ifdef crypto_sign_ed25519_BYTES
void ed25519_putsignature(struct buf *b, const unsigned char *x) {
const char *name = "ssh-ed25519";
long long len = crypto_sign_ed25519_BYTES;
buf_putnum32(b, len + str_len(name) + 8);
buf_putstring(b, name);
buf_putstringlen(b, x, len);
}
void ed25519_putsignpk(struct buf *b, const unsigned char *x) {
const char *name = "ssh-ed25519";
long long len = crypto_sign_ed25519_PUBLICKEYBYTES;
buf_putnum32(b, len + str_len(name) + 8);
buf_putstring(b, name);
buf_putstringlen(b, x, len);
}
void ed25519_putsignpkbase64(struct buf *b, const unsigned char *x) {
unsigned char buf[19 + crypto_sign_ed25519_PUBLICKEYBYTES];
byte_copy(buf, 19, "\0\0\0\013ssh-ed25519\0\0\0\040");
byte_copy(buf + 19, crypto_sign_ed25519_PUBLICKEYBYTES, x);
buf_putbase64(b, buf, sizeof buf);
purge(buf, sizeof buf);
}
int ed25519_parsesignpk(unsigned char *buf, const unsigned char *x, long long xlen) {
long long pos = 0;
crypto_uint32 len;
pos = packetparser_uint32(x, xlen, pos, &len);
pos = packetparser_skip(x, xlen, pos, len);
if (!str_equaln((char *)x + pos - len, len, "ssh-ed25519")) return 0;
pos = packetparser_uint32(x, xlen, pos, &len);
if (len != crypto_sign_ed25519_PUBLICKEYBYTES) return 0;
pos = packetparser_copy(x, xlen, pos, buf, len);
pos = packetparser_end(x, xlen, pos);
return 1;
}
int ed25519_parsesignature(unsigned char *buf, const unsigned char *x, long long xlen) {
long long pos = 0;
crypto_uint32 len;
pos = packetparser_uint32(x, xlen, pos, &len);
pos = packetparser_skip(x, xlen, pos, len);
if (!str_equaln((char *)x + pos - len, len, "ssh-ed25519")) return 0;
pos = packetparser_uint32(x, xlen, pos, &len);
if (len != crypto_sign_ed25519_BYTES) return 0;
pos = packetparser_copy(x, xlen, pos, buf, len);
pos = packetparser_end(x, xlen, pos);
return 1;
}
#endif
tinyssh-20190101/tinyssh/str.c 0000664 0000000 0000000 00000002577 13412736503 0016146 0 ustar 00root root 0000000 0000000 #include "str.h"
/*
The 'str_len(s)' function calculates the length of the string 's'.
*/
long long str_len(const char *s) {
long long i;
for (i = 0; s[i]; ++i);
return i;
}
/*
The 'str_start(s,t)' function returns 1 if t is a prefix of s, 0 otherwise.
*/
int str_start(const char *s, const char *t) {
char x;
for (;;) {
x = *t++;
if (!x) return 1;
if (x != *s++) return 0;
}
}
/*
The 'str_equaln(y,ylen,x)' function returns 1 if the length of string 'x' is ylen and
if y and x match up to, 0 otherwise.
*/
int str_equaln(const char *y, long long ylen, const char *x) {
long long i;
if (str_len(x) != ylen) return 0;
for (i = 0; i < ylen; ++i) if (y[i] != x[i]) return 0;
return 1;
}
/*
The 'str_copyn(y,ylen,x)' function copies the string pointed to by 'x' (including \0) to the buffer pointed to by 'y'.
If the length of string x is smaller than ylen or equal, then function returns 1.
If the length of string x is biger than ylen, then only ylen - 1 bytes of 'x' are copied and function returns 0.
The 'y' string is always \0 terminated.
*/
int str_copyn(char *y, long long ylen, const char *x) {
long long len = str_len(x);
int ret = 1;
if (ylen <= 0) return 0;
if (ylen - 1 < len) {
len = ylen - 1;
ret = 0;
}
y[len] = 0;
while (len > 0) { *y++ = *x++; --len; }
return ret;
}
tinyssh-20190101/tinyssh/str.h 0000664 0000000 0000000 00000000376 13412736503 0016146 0 ustar 00root root 0000000 0000000 #ifndef _STR_H____
#define _STR_H____
extern long long str_len(const char *);
extern int str_start(const char *, const char *);
extern int str_equaln(const char *, long long, const char *);
extern int str_copyn(char *, long long, const char *);
#endif
tinyssh-20190101/tinyssh/stringparser.c 0000664 0000000 0000000 00000001330 13412736503 0020043 0 ustar 00root root 0000000 0000000 /*
20140203
Jan Mojzis
Public domain.
*/
#include "byte.h"
#include "e.h"
#include "bug.h"
#include "stringparser.h"
/*
The 'stringparser' function parses items from
comma-separated list. Empty strings are ignored.
*/
long long stringparser(const unsigned char *buf, long long len, long long pos, unsigned char **x, long long *xlen) {
long long i;
if (!buf || len < 0 || len > 1073741824 || pos < 0 || pos > 1073741824 || !x || !xlen) bug_inval();
for (;;) {
if (pos >= len) return 0;
for (i = pos; i < len; ++i) {
if (buf[i] == ',') break;
}
*x = (unsigned char *)buf + pos;
*xlen = i - pos;
pos = i + 1;
if (*xlen != 0) return pos;
}
}
tinyssh-20190101/tinyssh/stringparser.h 0000664 0000000 0000000 00000000255 13412736503 0020055 0 ustar 00root root 0000000 0000000 #ifndef _STRINGPARSER_H____
#define _STRINGPARSER_H____
extern long long stringparser(const unsigned char *, long long, long long, unsigned char **, long long *);
#endif
tinyssh-20190101/tinyssh/subprocess.h 0000664 0000000 0000000 00000000650 13412736503 0017521 0 ustar 00root root 0000000 0000000 #ifndef _SUBPROCESS_H____
#define _SUBPROCESS_H____
#include