/*****************************************************************************\
* Copyright (c) 2002 Pelle Johansson. *
* All rights reserved. *
* *
* This file is part of the moftpd package. Use and distribution of *
* this software is governed by the terms in the file LICENCE, which *
* should have come with this package. *
\*****************************************************************************/
/* $moftpd: com_security.c 1249 2004-12-09 15:14:38Z morth $ */
#include "system.h"
#include "commands.h"
#include "connection.h"
#ifdef USE_TLS
extern char *sslCertsPath;
#endif
/* Security commands */
int command_auth (connection_t *conn, const char *arg, int expected)
{
if (!strlen (arg))
{
reply (conn, "501 Argument missing.");
return 0;
}
if (conn->authed)
{
reply (conn, "534 Can't start encryption when logged in.");
return 0;
}
#ifdef USE_TLS
if (conn->tlsControl)
{
reply (conn, "534 Authentication already negotiated.");
return 0;
}
if (!strcasecmp (arg, "TLS") || !strcasecmp (arg, "TLC-C"))
{
if (!conn->server->tlsCert)
{
reply (conn, "534 This server does not allow encryption.");
return 0;
}
conn->tlsControl = tls_open (conn->sock, conn->server->tlsOptions, conn->server->tlsCert,
conn->server->tlsKey);
if (!conn->tlsControl)
{
reply (conn, "431 TLS initialisation failed.");
return 0;
}
reply (conn, "234 Waiting for TLS handshake.");
tls_start (conn->tlsControl);
conn->tlsState = 0;
conn->pbsz = -1;
return 0;
}
#endif
reply (conn, "504 Unknown authentication method.");
return 0;
}
int command_adat (connection_t *conn, const char *arg, int expected)
{
reply (conn, "502 ADAT not yet implemented.");
return 0;
}
int command_prot (connection_t *conn, const char *arg, int expected)
{
int lvl;
if (!strlen (arg))
{
reply (conn, "501 Argument missing.");
return 0;
}
if (conn->dataSock >= 0)
{
reply (conn, "503 Can't change protection level with open data socket.");
return 0;
}
#ifdef USE_TLS
if (!conn->tlsControl)
#endif
{
reply (conn, "536 Need to establish a secure connection first.");
return 0;
}
if (conn->pbsz == -1)
{
reply (conn, "503 Need to negotiate buffer size first.");
return 0;
}
switch (arg[0])
{
case 'C':
case 'c':
lvl = 0;
break;
case 'S':
case 's':
case 'E':
case 'e':
reply (conn, "536 TLS does not support this protection level.");
return 0;
case 'P':
case 'p':
lvl = acEncrypted | acSigned;
break;
default:
reply (conn, "504 Unknown protection level.");
return 0;
}
conn->protLevel = lvl;
reply (conn, "200 Protection level set.");
return 0;
}
int command_pbsz (connection_t *conn, const char *arg, int expected)
{
char *ep;
/*unsigned long l = */strtoul (arg, &ep, 10);
if (!strlen (arg))
{
reply (conn, "501 Argument missing.");
return 0;
}
if (ep && *ep)
{
reply (conn, "501 Numerical argument expected.");
return 0;
}
#ifdef USE_TLS
if (conn->tlsControl)
{
conn->pbsz = 0;
reply (conn, "200 PBSZ=0");
}
else
#endif
reply (conn, "533 Need to establish a secure connection first.");
return 0;
}
int command_ccc (connection_t *conn, const char *arg, int expected)
{
#ifdef USE_TLS
if (conn->tlsControl)
{
if (!conn->authed || (conn->server->loginTLS && conn->server->tlsNoLogout))
{
reply (conn, "534 Won't turn off TLS protection.");
return 0;
}
reply (conn, "200 Shutting down TLS protection.");
tls_stop (conn->tlsControl);
conn->tlsState = 2;
}
else
#endif
reply (conn, "533 Need to establish a secure connection first.");
return 0;
}
int command_mic (connection_t *conn, const char *arg, int expected)
{
reply (conn, "502 MIC not yet implemented.");
return 0;
}
int command_conf (connection_t *conn, const char *arg, int expected)
{
reply (conn, "502 CONF not yet implemented.");
return 0;
}
int command_enc (connection_t *conn, const char *arg, int expected)
{
reply (conn, "502 ENC not yet implemented.");
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1