~ubuntu-branches/ubuntu/precise/wget/precise-proposed

« back to all changes in this revision

Viewing changes to src/ftp-opie.c

  • Committer: Bazaar Package Importer
  • Author(s): Noèl Köthe
  • Date: 2005-06-26 16:46:25 UTC
  • mfrom: (1.1.1 upstream) (2.1.1 sarge)
  • Revision ID: james.westby@ubuntu.com-20050626164625-jjcde8hyztx7xq7o
Tags: 1.10-2
* wget-fix_error--save-headers patch from upstream
  (closes: Bug#314728)
* don't pattern-match server redirects patch from upstream
  (closes: Bug#163243)
* correct de.po typos
  (closes: Bug#313883)
* wget-E_html_behind_file_counting fix problem with adding the
  numbers after the html extension
* updated Standards-Version: to 3.6.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
39
39
 
40
40
#include "wget.h"
41
41
#include "gen-md5.h"
 
42
#include "ftp.h"
42
43
 
43
 
/* Dictionary for integer-word translations.  */
44
 
static char Wp[2048][4] = {
 
44
/* Dictionary for integer-word translations.  Available in appendix D
 
45
   of rfc2289.  */
 
46
 static char Wp[2048][4] = {
45
47
  { 'A', '\0', '\0', '\0' },
46
48
  { 'A', 'B', 'E', '\0' },
47
49
  { 'A', 'C', 'E', '\0' },
2093
2095
};
2094
2096
 
2095
2097
/* Extract LENGTH bits from the char array S starting with bit number
2096
 
   START.  */
2097
 
static unsigned long
2098
 
extract (const char *s, int start, int length)
 
2098
   START.  It always reads three consecutive octects, which means it
 
2099
   can read past end of data when START is at the edge of the region. */
 
2100
 
 
2101
static uint32_t
 
2102
extract (const unsigned char *s, int start, int length)
2099
2103
{
2100
2104
  unsigned char cl = s[start / 8];
2101
2105
  unsigned char cc = s[start / 8 + 1];
2102
2106
  unsigned char cr = s[start / 8 + 2];
2103
 
  unsigned long x = ((long)(cl << 8 | cc) << 8 | cr);
2104
 
 
2105
 
  x = x >> (24 - (length + (start % 8)));
2106
 
  x = (x & (0xffff >> (16 - length)));
 
2107
  uint32_t x;
 
2108
  x   = (uint32_t)(cl << 8 | cc) << 8 | cr;
 
2109
  x >>= 24 - (length + (start % 8));
 
2110
  x  &= (0xffff >> (16 - length));
2107
2111
  return x;
2108
2112
}
2109
2113
 
2110
 
#define STRLEN4(s) (!*(s) ? 0 :                 \
2111
 
                    (!*(s + 1) ? 1 :            \
2112
 
                     (!*(s + 2) ? 2 :           \
2113
 
                      (!*(s + 3) ? 3 : 4))))
 
2114
/* Length of a string known to be at least 1 and at most 4 chars
 
2115
   long.  */
 
2116
 
 
2117
#define STRLEN_1_4(s) (!(s)[1] ? 1 : !(s)[2] ? 2 : !(s)[3] ? 3 : 4)
2114
2118
 
2115
2119
/* Encode 8 bytes in C as a string of English words and store them to
2116
2120
   STORE.  Returns STORE.  */
 
2121
 
2117
2122
static char *
2118
 
btoe (char *store, const char *c)
 
2123
btoe (char *store, const unsigned char *c)
2119
2124
{
2120
 
  char cp[10];                  /* add in room for the parity 2 bits +
 
2125
  unsigned char cp[10];         /* add in room for the parity 2 bits +
2121
2126
                                   extract() slop.  */
2122
2127
  int p, i;
2123
 
  char *ostore = store;
 
2128
  char *store_beg = store;
2124
2129
 
2125
2130
  *store = '\0';
 
2131
 
2126
2132
  /* Workaround for extract() reads beyond end of data */
2127
 
  memset (cp, 0, sizeof(cp));
 
2133
  xzero (cp);
2128
2134
  memcpy (cp, c, 8);
2129
 
  /* Compute parity.  */
 
2135
 
 
2136
  /* Compute parity and append it to CP.  */
2130
2137
  for (p = 0, i = 0; i < 64; i += 2)
2131
2138
    p += extract (cp, i, 2);
2132
 
 
2133
2139
  cp[8] = (char)p << 6;
 
2140
 
 
2141
  /* The 64 bits of input and the two parity bits comprise 66 bits of
 
2142
     data that are now in CP.  We convert that information, 11 bits at
 
2143
     a time, to English words indexed from Wp.  Since there are 2048
 
2144
     (2^11) words in Wp, every 11-bit combination corresponds to a
 
2145
     distinct word.  */
2134
2146
  memcpy (store, &Wp[extract (cp,  0, 11)][0], 4);
2135
 
  store += STRLEN4 (store);
 
2147
  store += STRLEN_1_4 (store);
2136
2148
  *store++ = ' ';
2137
2149
  memcpy (store, &Wp[extract (cp, 11, 11)][0], 4);
2138
 
  store += STRLEN4 (store);
 
2150
  store += STRLEN_1_4 (store);
2139
2151
  *store++ = ' ';
2140
2152
  memcpy (store, &Wp[extract (cp, 22, 11)][0], 4);
2141
 
  store += STRLEN4 (store);
 
2153
  store += STRLEN_1_4 (store);
2142
2154
  *store++ = ' ';
2143
2155
  memcpy (store, &Wp[extract (cp, 33, 11)][0], 4);
2144
 
  store += STRLEN4 (store);
 
2156
  store += STRLEN_1_4 (store);
2145
2157
  *store++ = ' ';
2146
2158
  memcpy (store, &Wp[extract (cp, 44, 11)][0], 4);
2147
 
  store += STRLEN4 (store);
 
2159
  store += STRLEN_1_4 (store);
2148
2160
  *store++ = ' ';
2149
2161
  memcpy (store, &Wp[extract (cp, 55, 11)][0], 4);
2150
 
 
2151
 
  store[4] = '\0';              /* make sure the string is zero-terminated */
2152
 
 
2153
 
  DEBUGP (("store is `%s'\n", ostore));
2154
 
 
2155
 
  return ostore;
 
2162
  store[4] = '\0';              /* make sure the string is terminated */
 
2163
 
 
2164
  DEBUGP (("wrote `%s' to STORE\n", store_beg));
 
2165
  return store_beg;
2156
2166
}
2157
2167
 
2158
 
/* #### Document me!  */
 
2168
/* Calculate the SKEY response, based on the sequence, seed
 
2169
   (challenge), and the secret password.  The calculated response is
 
2170
   used instead of the real password when logging in to SKEY-enabled
 
2171
   servers.
 
2172
 
 
2173
   The result is calculated like this:
 
2174
 
 
2175
   + Concatenate SEED and PASS and calculate the 16-byte MD5 checksum.
 
2176
 
 
2177
   + Shorten the checksum to eight bytes by folding the second eight
 
2178
     bytes onto the first eight using XOR.  The resulting eight-byte
 
2179
     sequence is the key.
 
2180
 
 
2181
   + MD5-process the key, fold the checksum to eight bytes and store
 
2182
     it back to the key.  Repeat this crunching SEQUENCE times.
 
2183
     (Sequence is a number that gets decremented every time the user
 
2184
     logs in to the server.  Therefore an eavesdropper would have to
 
2185
     invert the hash function in order to guess the next one-time
 
2186
     password.)
 
2187
 
 
2188
   + Convert the resulting 64-bit key to 6 English words separated by
 
2189
     spaces (see btoe for details) and return the resulting ASCII
 
2190
     string.
 
2191
 
 
2192
   All this is described in section 6 of rfc2289 in more detail.  */
 
2193
 
2159
2194
const char *
2160
 
calculate_skey_response (int sequence, const char *seed, const char *pass)
 
2195
skey_response (int sequence, const char *seed, const char *pass)
2161
2196
{
2162
 
  char key[8];
2163
 
  static char buf[33];
2164
 
 
2165
 
  ALLOCA_MD5_CONTEXT (ctx);
2166
 
  unsigned long results[4];     /* #### this looks 32-bit-minded */
2167
 
  char *feed = (char *) alloca (strlen (seed) + strlen (pass) + 1);
2168
 
 
2169
 
  strcpy (feed, seed);
2170
 
  strcat (feed, pass);
2171
 
 
2172
 
  gen_md5_init (ctx);
2173
 
  gen_md5_update ((unsigned char *)feed, strlen (feed), ctx);
2174
 
  gen_md5_finish (ctx, (unsigned char *)results);
2175
 
 
2176
 
  results[0] ^= results[2];
2177
 
  results[1] ^= results[3];
2178
 
  memcpy (key, (char *) results, 8);
2179
 
 
2180
 
  while (0 < sequence--)
 
2197
  unsigned char key[8];
 
2198
 
 
2199
  /* Room to hold 6 four-letter words (heh), 5 space separators, and
 
2200
     the terminating \0.  24+5+1 == 30  */
 
2201
  static char english[30];
 
2202
 
 
2203
  ALLOCA_MD5_CONTEXT (md5_ctx);
 
2204
  uint32_t checksum[4];
 
2205
 
 
2206
  gen_md5_init (md5_ctx);
 
2207
  gen_md5_update ((const unsigned char *)seed, strlen(seed), md5_ctx);
 
2208
  gen_md5_update ((const unsigned char *)pass, strlen(pass), md5_ctx);
 
2209
  gen_md5_finish (md5_ctx, (unsigned char *)checksum);
 
2210
  checksum[0] ^= checksum[2];
 
2211
  checksum[1] ^= checksum[3];
 
2212
  memcpy (key, checksum, 8);
 
2213
 
 
2214
  while (sequence-- > 0)
2181
2215
    {
2182
 
      gen_md5_init (ctx);
2183
 
      gen_md5_update ((unsigned char *)key, 8, ctx);
2184
 
      gen_md5_finish (ctx, (unsigned char *)results);
2185
 
      results[0] ^= results[2];
2186
 
      results[1] ^= results[3];
2187
 
      memcpy (key, (char *) results, 8);
 
2216
      gen_md5_init (md5_ctx);
 
2217
      gen_md5_update ((unsigned char *) key, 8, md5_ctx);
 
2218
      gen_md5_finish (md5_ctx, (unsigned char *) checksum);
 
2219
      checksum[0] ^= checksum[2];
 
2220
      checksum[1] ^= checksum[3];
 
2221
      memcpy (key, checksum, 8);
2188
2222
    }
2189
 
  btoe (buf, key);
2190
 
  return buf;
 
2223
  return btoe (english, key);
2191
2224
}