diff -ruN pppowap-0.1.10-pre7+drg/main-client.c pppowap-0.1.10-pre7+drg-matchrequest+password/main-client.c --- pppowap-0.1.10-pre7+drg/main-client.c 2005-06-22 22:19:11.000000000 +0200 +++ pppowap-0.1.10-pre7+drg-matchrequest+password/main-client.c 2005-06-25 00:46:38.293326072 +0200 @@ -43,6 +43,8 @@ #include #include +#include + #include #ifdef Linux @@ -63,6 +65,7 @@ #include "memops.h" #include "tun.h" #include "http.h" +#include "sha1/sha1.h" #include "conn.h" @@ -84,7 +87,7 @@ void usage(char * s) { fprintf(stderr, "Usage:\n"); - fprintf(stderr, "\t%s [-bhrwz] [ -U http://uri/ ] [ -M mtu ] [ -S bufsize ] host_address [port]\n", s); + fprintf(stderr, "\t%s [-bhrwz] [ -U http://uri/ ] [ -p password ] [ -M mtu ] [ -S bufsize ] host_address [port]\n", s); exit(1); } @@ -103,7 +106,7 @@ int wap=0; int tmpfd; - char * optstring="+hrbwU:M:S:z"; + char * optstring="+hrbwU:M:S:zp:"; char optchar; /* WAP */ @@ -122,6 +125,11 @@ char puturi[128]; char http_puturi[128]; + char *password = NULL; + char *sha1sum = NULL; + char *sha1msg = NULL; + char *magic = NULL; + puturi[0]='\0'; http_puturi[0]='\0'; @@ -147,10 +155,11 @@ case 'b' : drop_term=1; break; case 'w' : wap=1; break; case 'r' : vectorized_io=1; break; - case 'U' : strncpy(puturi, optarg, 127); break; + case 'U' : strncpy(puturi, optarg, 127); break; case 'M' : vio_pack_size=atoi(optarg); break; case 'S' : vio_spacelimit=atoi(optarg); break; case 'z' : zcomp=1; break; + case 'p' : password=optarg; break; } } while (optchar != -1); @@ -164,6 +173,19 @@ if (wap) dport=9201; else dport=80; } else dport=atoi(av[i]); + if (puturi[0] == '\0' && password != NULL) + panic("if you use -p switch, you must use -U also.\n"); + + + if (password) { + if ((sha1sum=(char*)malloc(sizeof(char)*41)) == NULL) + panic("Can't allocate memory for sha1sum.\n"); + if ((sha1msg=(char*)malloc(sizeof(char)*64)) == NULL) + panic("Can't allocate memory for sha1msg.\n"); + if ((magic=(char*)malloc(sizeof(char)*16)) == NULL) + panic("Can't allocate memory for magic.\n"); + } + #ifdef DEFAULT_WAP_PUTURI if (wap == 1 && puturi[0] == '\0') strncpy(puturi, DEFAULT_WAP_PUTURI, 127); #endif @@ -268,7 +290,13 @@ } else { rcvcontent = NULL; - do_http_put(puturi, buf, buflen, &rcvcontent, &rcvcontentlen); + if (password) { + snprintf(magic, 16, "%d", (int)time(NULL)); + snprintf(sha1msg, 64, "%s%s", magic, password); + sha1_calculate_string(sha1msg, sha1sum); + snprintf(http_puturi, 127, "%s/%s/%s", puturi, magic, sha1sum); + } + do_http_put(http_puturi, buf, buflen, &rcvcontent, &rcvcontentlen); close(sk); } } diff -ruN pppowap-0.1.10-pre7+drg/main-server.c pppowap-0.1.10-pre7+drg-matchrequest+password/main-server.c --- pppowap-0.1.10-pre7+drg/main-server.c 2005-06-22 22:41:07.000000000 +0200 +++ pppowap-0.1.10-pre7+drg-matchrequest+password/main-server.c 2005-06-25 10:07:44.213328296 +0200 @@ -58,6 +58,8 @@ #include "error.h" #include "io.h" +#include "sha1/sha1.h" + #include "server.h" #include "log.h" #include "memops.h" @@ -68,6 +70,10 @@ #define NOTICE_NO_LONGER "Function not implemented. mailto:kszysiu@jaszczur.org for support\n" +#define RESPONSE_REQUEST_NOT_MATCH "HTTP/1.1 404 Not Found\r\n" +#define NOTICE_REQUEST_NOT_MATCH "404 Not Found\n" +#define NOTICE_BAD_PASSWORD NOTICE_REQUEST_NOT_MATCH + void sighandler(int n) { synclog(); @@ -84,7 +90,7 @@ void usage(char * s) { fprintf(stderr, "Usage:\n"); - fprintf(stderr, "\t%s [-bhrz] [ -M mtu ] [ -S bufsize ] [port]\n", s); + fprintf(stderr, "\t%s [-bhrz] [ -M mtu ] [ -S bufsize ] [ -m matchrequest ] [ -p password ] [port]\n", s); exit(1); } @@ -120,8 +126,19 @@ int zcomp=0; /* */ - char * optstring="+hrbM:S:z"; + char * optstring="+hrbM:S:zm:p:"; char optchar; + + char *matchrequest = NULL; + +/* to calculate sha1 */ + char *password = NULL; + char *r; + char *reqsha1 = NULL; + char *reqpass = NULL; + char *sha1sum = NULL; + char *sha1msg = NULL; +/* */ openlog(LOGFILE, LOGMODE); @@ -148,6 +165,8 @@ case 'M' : vio_pack_size=atoi(optarg); break; case 'S' : vio_spacelimit=atoi(optarg); break; case 'z' : zcomp=1; break; + case 'm' : matchrequest=optarg; break; + case 'p' : password=optarg; break; } } while (optchar != -1); @@ -176,9 +195,18 @@ sndbuf=xmalloc(vio_spacelimit); assert(sndbuf); + if (password) { + if ((sha1sum = (char*)malloc(sizeof(char)*41)) == NULL) + fatal("Can't allocate memory for sha1sum.\n"); + if ((sha1msg = (char*)malloc(sizeof(char)*64)) == NULL) + fatal("Can't allocate memory for sha1msg.\n"); + } + log("Interface: 0.0.0.0:%d\n", port); log("Dropping terminal: %s\n", ((drop_term) ? "Yes" : "No")); log("Vectorized IO mode: %s\n", ((vectorized_io) ? "Yes" : "No")); + log("Match request: %s\n", ((matchrequest) ? matchrequest : "(NULL)")); + log("Password: %s\n", ((password) ? password : "(NULL")); log("Allocating tun device.\n"); devname[0]='\0'; @@ -228,15 +256,123 @@ close(connsk); continue; } - if (!nextline) panic("NO INPUT DATA!\n"); + if (!nextline) { + log("NO INPUT DATA!\n"); + close(connsk); + continue; + } + if (!strncasecmp("PUT", rcvbuf, 3) || !strncasecmp("POST", rcvbuf, 4)) { log("PUT/POST request.\n"); + if (matchrequest && (!strstr(rcvbuf, matchrequest))) { + r = rcvbuf; + while (r && *r != '\r' && *r != '\n') + r++; + *r = '\0'; + + log("request '%s' not matched to '%s'.\n", rcvbuf, matchrequest); + + buflen=strlen(NOTICE_REQUEST_NOT_MATCH); + strcpy(sndbuf, NOTICE_REQUEST_NOT_MATCH); + } + else if (matchrequest) + log("request matched.\n"); + + if (buflen == -1 && password) { + *sha1msg = 0; + *sha1sum = 0; + reqsha1 = NULL; + reqpass = NULL; + + r = rindex(rcvbuf, ' '); + if (r == NULL) { + log("No ' ' in request.\n"); + goto badpassword; + } + *r = 0; + + r = rindex(rcvbuf, '/'); + if (r == NULL) { + log("No '/' in uri.\n"); + goto badpassword; + } + *r = 0; + reqsha1 = r + 1; + + r = rindex(rcvbuf, '/'); + if (r == NULL) { + log("No second '/' in uri.\n"); + goto badpassword; + } + reqpass = r + 1; + + snprintf(sha1msg, 64, "%s%s", reqpass, password); + + sha1_calculate_string(sha1msg, sha1sum); + +badpassword: + if (!*sha1msg || !reqsha1 || !reqpass || strcmp(sha1sum, reqsha1)) { + if (*sha1msg && reqsha1 && reqpass) + log("Wrong sha1 (%s, should be %s).\n", reqsha1, sha1sum); + + buflen = strlen(NOTICE_BAD_PASSWORD); + strcpy(sndbuf, NOTICE_BAD_PASSWORD); + } + else + log("SHA1 correct!\n"); + } + + if (buflen != -1) { /* request not matched or bad password (sha1) */ + /* + s/RESPONSE_REQUEST_NOT_MATCH/HTTP_NOTFOUNDRESPONSE/g ? + */ + retval=write(connsk, RESPONSE_REQUEST_NOT_MATCH, strlen(RESPONSE_REQUEST_NOT_MATCH)); + if ((retval == -1) && (errno == EPIPE)) { + log("Connection Lost.\n"); + close(connsk); + continue; + } + + retval=write(connsk, HTTP_PUTHEADERS, HTTP_PUTHEADERS_LEN); + if ((retval == -1) && (errno == EPIPE)) { + log("Connection Lost.\n"); + close(connsk); + continue; + } + + sprintf(contentlen, "%d\r\n", buflen); + + retval=write(connsk, contentlen, strlen(contentlen)); + if ((retval == -1) && (errno == EPIPE)) { + log("Connection Lost.\n"); + close(connsk); + continue; + } + + retval=write(connsk, "\r\n", 2); + if ((retval == -1) && (errno == EPIPE)) { + log("Connection Lost.\n"); + close(connsk); + continue; + } + + retval=write(connsk, sndbuf, buflen); + if ((retval == -1) && (errno == EPIPE)) { + log("Connection Lost.\n"); + close(connsk); + continue; + } + + close(connsk); + continue; + } + scrollbuf(rcvbuf, &bufpos, &nextline); retval=getline(connsk, rcvbuf, &bufpos, RECV_BUFSIZE, &nextline); if (retval == -1) { log("Read timeout. Client disconnect.\n"); close(connsk); - break; + continue; } log("skipping headers: ["); while ((rcvbuf[0] != '\0')) { @@ -253,8 +389,15 @@ } } logs("]\n"); - if (retval == -1) continue; - if (buflen == -1) fatal("Content-Length header NOT provided in PUT request!\n"); + if (retval == -1) { + close(connsk); + continue; + } + if (buflen == -1) { + log("Content-Length header NOT provided in PUT/POST request!\n"); + close(connsk); + continue; + } log("Content-Length: %d\n", buflen); scrollbuf(rcvbuf, &bufpos, &nextline); fill_buffer(connsk, rcvbuf, &bufpos, &buflen, RECV_BUFSIZE); diff -ruN pppowap-0.1.10-pre7+drg/Makefile pppowap-0.1.10-pre7+drg-matchrequest+password/Makefile --- pppowap-0.1.10-pre7+drg/Makefile 2005-06-22 22:19:25.000000000 +0200 +++ pppowap-0.1.10-pre7+drg-matchrequest+password/Makefile 2005-06-24 23:47:50.150685280 +0200 @@ -3,11 +3,11 @@ DEF=-DVERBOSE -DDEBUG -DNB_DEBUG -SRCS=net.c error.c io.c log.c tun.c vio.c memops.c +SRCS=net.c error.c io.c log.c tun.c vio.c memops.c sha1/sha1.c SRCS_CLIENT=wtp.c wsp.c main-client.c conn.c http.c SRCS_SERVER=server.c main-server.c -OBJS=net.o error.o io.o log.o tun.o vio.o memops.o +OBJS=net.o error.o io.o log.o tun.o vio.o memops.o sha1/sha1.o OBJS_CLIENT=wtp.o wsp.o main-client.o conn.o http.o OBJS_SERVER=server.o main-server.o diff -ruN pppowap-0.1.10-pre7+drg/sha1/sha1.c pppowap-0.1.10-pre7+drg-matchrequest+password/sha1/sha1.c --- pppowap-0.1.10-pre7+drg/sha1/sha1.c 1970-01-01 01:00:00.000000000 +0100 +++ pppowap-0.1.10-pre7+drg-matchrequest+password/sha1/sha1.c 2005-06-24 23:03:01.511420576 +0200 @@ -0,0 +1,302 @@ +/* + * FIPS-180-1 compliant SHA-1 implementation + * + * Copyright (C) 2001-2003 Christophe Devine + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include + +#include "sha1.h" + +#define GET_UINT32(n,b,i) \ +{ \ + (n) = ( (uint32) (b)[(i) ] << 24 ) \ + | ( (uint32) (b)[(i) + 1] << 16 ) \ + | ( (uint32) (b)[(i) + 2] << 8 ) \ + | ( (uint32) (b)[(i) + 3] ); \ +} + +#define PUT_UINT32(n,b,i) \ +{ \ + (b)[(i) ] = (uint8) ( (n) >> 24 ); \ + (b)[(i) + 1] = (uint8) ( (n) >> 16 ); \ + (b)[(i) + 2] = (uint8) ( (n) >> 8 ); \ + (b)[(i) + 3] = (uint8) ( (n) ); \ +} + +void sha1_starts( sha1_context *ctx ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; + ctx->state[4] = 0xC3D2E1F0; +} + +void sha1_process( sha1_context *ctx, uint8 data[64] ) +{ + uint32 temp, W[16], A, B, C, D, E; + + GET_UINT32( W[0], data, 0 ); + GET_UINT32( W[1], data, 4 ); + GET_UINT32( W[2], data, 8 ); + GET_UINT32( W[3], data, 12 ); + GET_UINT32( W[4], data, 16 ); + GET_UINT32( W[5], data, 20 ); + GET_UINT32( W[6], data, 24 ); + GET_UINT32( W[7], data, 28 ); + GET_UINT32( W[8], data, 32 ); + GET_UINT32( W[9], data, 36 ); + GET_UINT32( W[10], data, 40 ); + GET_UINT32( W[11], data, 44 ); + GET_UINT32( W[12], data, 48 ); + GET_UINT32( W[13], data, 52 ); + GET_UINT32( W[14], data, 56 ); + GET_UINT32( W[15], data, 60 ); + +#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) + +#define R(t) \ +( \ + temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \ + W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \ + ( W[t & 0x0F] = S(temp,1) ) \ +) + +#define P(a,b,c,d,e,x) \ +{ \ + e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \ +} + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + E = ctx->state[4]; + +#define F(x,y,z) (z ^ (x & (y ^ z))) +#define K 0x5A827999 + + P( A, B, C, D, E, W[0] ); + P( E, A, B, C, D, W[1] ); + P( D, E, A, B, C, W[2] ); + P( C, D, E, A, B, W[3] ); + P( B, C, D, E, A, W[4] ); + P( A, B, C, D, E, W[5] ); + P( E, A, B, C, D, W[6] ); + P( D, E, A, B, C, W[7] ); + P( C, D, E, A, B, W[8] ); + P( B, C, D, E, A, W[9] ); + P( A, B, C, D, E, W[10] ); + P( E, A, B, C, D, W[11] ); + P( D, E, A, B, C, W[12] ); + P( C, D, E, A, B, W[13] ); + P( B, C, D, E, A, W[14] ); + P( A, B, C, D, E, W[15] ); + P( E, A, B, C, D, R(16) ); + P( D, E, A, B, C, R(17) ); + P( C, D, E, A, B, R(18) ); + P( B, C, D, E, A, R(19) ); + +#undef K +#undef F + +#define F(x,y,z) (x ^ y ^ z) +#define K 0x6ED9EBA1 + + P( A, B, C, D, E, R(20) ); + P( E, A, B, C, D, R(21) ); + P( D, E, A, B, C, R(22) ); + P( C, D, E, A, B, R(23) ); + P( B, C, D, E, A, R(24) ); + P( A, B, C, D, E, R(25) ); + P( E, A, B, C, D, R(26) ); + P( D, E, A, B, C, R(27) ); + P( C, D, E, A, B, R(28) ); + P( B, C, D, E, A, R(29) ); + P( A, B, C, D, E, R(30) ); + P( E, A, B, C, D, R(31) ); + P( D, E, A, B, C, R(32) ); + P( C, D, E, A, B, R(33) ); + P( B, C, D, E, A, R(34) ); + P( A, B, C, D, E, R(35) ); + P( E, A, B, C, D, R(36) ); + P( D, E, A, B, C, R(37) ); + P( C, D, E, A, B, R(38) ); + P( B, C, D, E, A, R(39) ); + +#undef K +#undef F + +#define F(x,y,z) ((x & y) | (z & (x | y))) +#define K 0x8F1BBCDC + + P( A, B, C, D, E, R(40) ); + P( E, A, B, C, D, R(41) ); + P( D, E, A, B, C, R(42) ); + P( C, D, E, A, B, R(43) ); + P( B, C, D, E, A, R(44) ); + P( A, B, C, D, E, R(45) ); + P( E, A, B, C, D, R(46) ); + P( D, E, A, B, C, R(47) ); + P( C, D, E, A, B, R(48) ); + P( B, C, D, E, A, R(49) ); + P( A, B, C, D, E, R(50) ); + P( E, A, B, C, D, R(51) ); + P( D, E, A, B, C, R(52) ); + P( C, D, E, A, B, R(53) ); + P( B, C, D, E, A, R(54) ); + P( A, B, C, D, E, R(55) ); + P( E, A, B, C, D, R(56) ); + P( D, E, A, B, C, R(57) ); + P( C, D, E, A, B, R(58) ); + P( B, C, D, E, A, R(59) ); + +#undef K +#undef F + +#define F(x,y,z) (x ^ y ^ z) +#define K 0xCA62C1D6 + + P( A, B, C, D, E, R(60) ); + P( E, A, B, C, D, R(61) ); + P( D, E, A, B, C, R(62) ); + P( C, D, E, A, B, R(63) ); + P( B, C, D, E, A, R(64) ); + P( A, B, C, D, E, R(65) ); + P( E, A, B, C, D, R(66) ); + P( D, E, A, B, C, R(67) ); + P( C, D, E, A, B, R(68) ); + P( B, C, D, E, A, R(69) ); + P( A, B, C, D, E, R(70) ); + P( E, A, B, C, D, R(71) ); + P( D, E, A, B, C, R(72) ); + P( C, D, E, A, B, R(73) ); + P( B, C, D, E, A, R(74) ); + P( A, B, C, D, E, R(75) ); + P( E, A, B, C, D, R(76) ); + P( D, E, A, B, C, R(77) ); + P( C, D, E, A, B, R(78) ); + P( B, C, D, E, A, R(79) ); + +#undef K +#undef F + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; + ctx->state[4] += E; +} + +void sha1_update( sha1_context *ctx, uint8 *input, uint32 length ) +{ + uint32 left, fill; + + if( ! length ) return; + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += length; + ctx->total[0] &= 0xFFFFFFFF; + + if( ctx->total[0] < length ) + ctx->total[1]++; + + if( left && length >= fill ) + { + memcpy( (void *) (ctx->buffer + left), + (void *) input, fill ); + sha1_process( ctx, ctx->buffer ); + length -= fill; + input += fill; + left = 0; + } + + while( length >= 64 ) + { + sha1_process( ctx, input ); + length -= 64; + input += 64; + } + + if( length ) + { + memcpy( (void *) (ctx->buffer + left), + (void *) input, length ); + } +} + +static uint8 sha1_padding[64] = +{ + 0x80, 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, 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 +}; + +void sha1_finish( sha1_context *ctx, uint8 digest[20] ) +{ + uint32 last, padn; + uint32 high, low; + uint8 msglen[8]; + + high = ( ctx->total[0] >> 29 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_UINT32( high, msglen, 0 ); + PUT_UINT32( low, msglen, 4 ); + + last = ctx->total[0] & 0x3F; + padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + + sha1_update( ctx, sha1_padding, padn ); + sha1_update( ctx, msglen, 8 ); + + PUT_UINT32( ctx->state[0], digest, 0 ); + PUT_UINT32( ctx->state[1], digest, 4 ); + PUT_UINT32( ctx->state[2], digest, 8 ); + PUT_UINT32( ctx->state[3], digest, 12 ); + PUT_UINT32( ctx->state[4], digest, 16 ); +} + +int sha1_calculate_string(char *msg, char *output) +{ + int j; + + //char output[41]; + sha1_context ctx; + unsigned char sha1sum[20]; + + sha1_starts(&ctx); + + sha1_update(&ctx, (uint8 *) msg, strlen(msg)); + + sha1_finish(&ctx, sha1sum); + + for (j = 0; j < 20; j++) + sprintf(output + j * 2, "%02x", sha1sum[j]); + + return 0; +} + diff -ruN pppowap-0.1.10-pre7+drg/sha1/sha1.h pppowap-0.1.10-pre7+drg-matchrequest+password/sha1/sha1.h --- pppowap-0.1.10-pre7+drg/sha1/sha1.h 1970-01-01 01:00:00.000000000 +0100 +++ pppowap-0.1.10-pre7+drg-matchrequest+password/sha1/sha1.h 2005-06-24 23:48:26.862104296 +0200 @@ -0,0 +1,25 @@ +#ifndef _SHA1_H +#define _SHA1_H + +#ifndef uint8 +#define uint8 unsigned char +#endif + +#ifndef uint32 +#define uint32 unsigned long int +#endif + +typedef struct +{ + uint32 total[2]; + uint32 state[5]; + uint8 buffer[64]; +} +sha1_context; + +void sha1_starts( sha1_context *ctx ); +void sha1_update( sha1_context *ctx, uint8 *input, uint32 length ); +void sha1_finish( sha1_context *ctx, uint8 digest[20] ); + +int sha1_calculate_string(char *msg, char *output); +#endif /* sha1.h */