~ubuntu-branches/ubuntu/natty/curl/natty-security

« back to all changes in this revision

Viewing changes to lib/security.c

  • Committer: Bazaar Package Importer
  • Author(s): Artur Rona
  • Date: 2011-01-26 02:50:18 UTC
  • mfrom: (3.4.13 sid)
  • Revision ID: james.westby@ubuntu.com-20110126025018-dzgm2m2t5d1vc9y4
Tags: 7.21.3-1ubuntu1
* Merge from debian unstable.  Remaining changes: (LP: #707756)
  - debian/control:
    + Build-Depends: Replace libssh2-1-dev with openssh-server.
      Drop stunnel since it's in universe, as well.
    + Drop libssh2-1-dev from libcurl4-openssl-dev's Depends.
    Above changes are necessary to be independent from the universe.

Show diffs side-by-side

added added

removed removed

Lines of Context:
72
72
  enum protection_level level;
73
73
  const char *name;
74
74
} level_names[] = {
75
 
  { prot_clear, "clear" },
76
 
  { prot_safe, "safe" },
77
 
  { prot_confidential, "confidential" },
78
 
  { prot_private, "private" }
 
75
  { PROT_CLEAR, "clear" },
 
76
  { PROT_SAFE, "safe" },
 
77
  { PROT_CONFIDENTIAL, "confidential" },
 
78
  { PROT_PRIVATE, "private" }
79
79
};
80
80
 
81
81
static enum protection_level
85
85
  for(i = 0; i < (int)sizeof(level_names)/(int)sizeof(level_names[0]); i++)
86
86
    if(checkprefix(name, level_names[i].name))
87
87
      return level_names[i].level;
88
 
  return (enum protection_level)-1;
 
88
  return PROT_NONE;
89
89
}
90
90
 
91
91
/* Convert a protocol |level| to its char representation.
92
92
   We take an int to catch programming mistakes. */
93
93
static char level_to_char(int level) {
94
94
  switch(level) {
95
 
  case prot_clear:
 
95
  case PROT_CLEAR:
96
96
    return 'C';
97
 
  case prot_safe:
 
97
  case PROT_SAFE:
98
98
    return 'S';
99
 
  case prot_confidential:
 
99
  case PROT_CONFIDENTIAL:
100
100
    return 'E';
101
 
  case prot_private:
 
101
  case PROT_PRIVATE:
102
102
    return 'P';
103
 
  case prot_cmd:
 
103
  case PROT_CMD:
104
104
    /* Fall through */
105
105
  default:
106
106
    /* Those 2 cases should not be reached! */
247
247
  *err = CURLE_OK;
248
248
 
249
249
  /* Handle clear text response. */
250
 
  if(conn->sec_complete == 0 || conn->data_prot == prot_clear)
 
250
  if(conn->sec_complete == 0 || conn->data_prot == PROT_CLEAR)
251
251
      return read(fd, buffer, len);
252
252
 
253
253
  if(conn->in_buffer.eof_flag) {
288
288
  char *buffer;
289
289
  char *cmd_buffer;
290
290
  enum protection_level prot_level = conn->data_prot;
291
 
  bool iscmd = prot_level == prot_cmd;
 
291
  bool iscmd = prot_level == PROT_CMD;
 
292
 
 
293
  DEBUGASSERT(prot_level > PROT_NONE && prot_level < PROT_LAST);
292
294
 
293
295
  if(iscmd) {
294
296
    if(!strncmp(from, "PASS ", 5) || !strncmp(from, "ACCT ", 5))
295
 
      prot_level = prot_private;
 
297
      prot_level = PROT_PRIVATE;
296
298
    else
297
299
      prot_level = conn->command_prot;
298
300
  }
303
305
    if(bytes > 0) {
304
306
      static const char *enc = "ENC ";
305
307
      static const char *mic = "MIC ";
306
 
      if(prot_level == prot_private)
 
308
      if(prot_level == PROT_PRIVATE)
307
309
        socket_write(conn, fd, enc, 4);
308
310
      else
309
311
        socket_write(conn, fd, mic, 4);
310
312
 
311
313
      socket_write(conn, fd, cmd_buffer, bytes);
312
314
      socket_write(conn, fd, "\r\n", 2);
313
 
      infof(conn->data, "Send: %s%s\n", prot_level == prot_private?enc:mic,
 
315
      infof(conn->data, "Send: %s%s\n", prot_level == PROT_PRIVATE?enc:mic,
314
316
            cmd_buffer);
315
317
      free(cmd_buffer);
316
318
    }
355
357
  return sec_write(conn, fd, buffer, len);
356
358
}
357
359
 
358
 
/* FIXME: |level| should not be an int but a struct protection_level */
359
 
int Curl_sec_read_msg(struct connectdata *conn, char *buffer, int level)
 
360
int Curl_sec_read_msg(struct connectdata *conn, char *buffer,
 
361
                      enum protection_level level)
360
362
{
361
363
  /* decoded_len should be size_t or ssize_t but conn->mech->decode returns an
362
364
     int */
364
366
  char *buf;
365
367
  int ret_code;
366
368
 
 
369
  DEBUGASSERT(level > PROT_NONE && level < PROT_LAST);
 
370
 
367
371
  decoded_len = Curl_base64_decode(buffer + 4, (unsigned char **)&buf);
368
372
  if(decoded_len <= 0) {
369
373
    free(buf);
399
403
  return ret_code;
400
404
}
401
405
 
402
 
enum protection_level
403
 
Curl_set_command_prot(struct connectdata *conn, enum protection_level level)
404
 
{
405
 
  enum protection_level old = conn->command_prot;
406
 
  conn->command_prot = level;
407
 
  return old;
408
 
}
409
 
 
410
406
/* FIXME: The error code returned here is never checked. */
411
 
int Curl_sec_set_protection_level(struct connectdata *conn)
 
407
static int sec_set_protection_level(struct connectdata *conn)
412
408
{
413
409
  int code;
414
410
  char* pbsz;
415
411
  static unsigned int buffer_size = 1 << 20; /* 1048576 */
416
412
  enum protection_level level = conn->request_data_prot;
417
413
 
 
414
  DEBUGASSERT(level > PROT_NONE && level < PROT_LAST);
 
415
 
418
416
  if(!conn->sec_complete) {
419
417
    infof(conn->data, "Trying to change the protection level after the"
420
418
                      "completion of the data exchange.\n");
457
455
  }
458
456
 
459
457
  conn->data_prot = level;
460
 
  if(level == prot_private)
 
458
  if(level == PROT_PRIVATE)
461
459
    conn->command_prot = level;
462
460
 
463
461
  return 0;
466
464
int
467
465
Curl_sec_request_prot(struct connectdata *conn, const char *level)
468
466
{
469
 
  int l = name_to_level(level);
470
 
  if(l == -1)
 
467
  enum protection_level l = name_to_level(level);
 
468
  if(l == PROT_NONE)
471
469
    return -1;
472
 
  conn->request_data_prot = (enum protection_level)l;
 
470
  DEBUGASSERT(l > PROT_NONE && l < PROT_LAST);
 
471
  conn->request_data_prot = l;
473
472
  return 0;
474
473
}
475
474
 
498
497
    conn->app_data = tmp_allocation;
499
498
 
500
499
    if((*mech)->init) {
501
 
      ret = (*mech)->init(conn);
 
500
      ret = (*mech)->init(conn->app_data);
502
501
      if(ret != 0) {
503
502
        infof(data, "Failed initialization for %s. Skipping it.\n", mech_name);
504
503
        continue;
548
547
    conn->send[FIRSTSOCKET] = sec_send;
549
548
    conn->recv[SECONDARYSOCKET] = sec_recv;
550
549
    conn->send[SECONDARYSOCKET] = sec_send;
551
 
    conn->command_prot = prot_safe;
 
550
    conn->command_prot = PROT_SAFE;
552
551
    /* Set the requested protection level */
553
552
    /* BLOCKING */
554
 
    Curl_sec_set_protection_level(conn);
 
553
    (void)sec_set_protection_level(conn);
555
554
    break;
556
555
  }
557
556
 
583
582
    conn->in_buffer.eof_flag = 0;
584
583
  }
585
584
  conn->sec_complete = 0;
586
 
  conn->data_prot = (enum protection_level)0;
 
585
  conn->data_prot = PROT_CLEAR;
587
586
  conn->mech = NULL;
588
587
}
589
588