/*****************************************************************************\ * 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; }