2
* ProFTPD - mod_sftp date(1) simulation
3
* Copyright (c) 2011 TJ Saunders
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
19
* As a special exemption, TJ Saunders and other respective copyright holders
20
* give permission to link this program with OpenSSL, and distribute the
21
* resulting executable, without including the source code for OpenSSL in the
22
* source distribution.
24
* $Id: date.c,v 1.1 2011/05/24 20:55:50 castaglia Exp $
34
#include "disconnect.h"
36
static pool *date_pool = NULL;
37
static int date_use_gmt = FALSE;
39
/* Use a struct to maintain the per-channel date-specific values. */
41
struct date_session *next, *prev;
48
static struct date_session *date_sessions = NULL;
50
static const char *trace_channel = "ssh2";
52
static struct date_session *date_get_session(uint32_t channel_id) {
53
struct date_session *sess;
59
if (sess->channel_id == channel_id) {
70
/* Main entry point */
71
int sftp_date_handle_packet(pool *p, void *ssh2, uint32_t channel_id,
72
char *data, uint32_t datalen) {
79
/* This callback should never be called; the client will request an
80
* 'exec date' command, and mod_sftp should send the channel data back
81
* immediately, without needing anything more from the client.
83
* Thus this is essentially a no-op.
89
int sftp_date_set_params(pool *p, uint32_t channel_id, array_header *req) {
90
char **reqargv = NULL;
92
const char *opts = "u";
94
if (!(sftp_services & SFTP_SERVICE_FL_DATE)) {
95
(void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION, "%s",
96
"'date' exec request denied by Protocols config");
101
reqargv = (char **) req->elts;
103
if (pr_trace_get_level(trace_channel) >= 5) {
104
register unsigned int i;
106
for (i = 0; i < req->nelts; i++) {
108
pr_trace_msg(trace_channel, 5, "reqargv[%u] = '%s'", i, reqargv[i]);
113
/* Possible options are:
120
while ((optc = getopt(req->nelts-1, reqargv, opts)) != -1) {
127
/* Ignore unsupported options */
128
(void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
129
"ingoring supported date(1) option '%c'", (char) optopt);
134
date_pool = make_sub_pool(sftp_pool);
135
pr_pool_tag(date_pool, "SSH2 Date Pool");
140
int sftp_date_postopen_session(uint32_t channel_id) {
141
struct date_session *sess;
143
const char *date_str;
144
uint32_t buflen, bufsz;
147
sess = date_get_session(channel_id);
149
(void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
150
"no existing date(1) session for channel ID %lu, rejecting request",
151
(unsigned long) channel_id);
156
date_str = pr_strtime2(now, sess->use_gmt);
158
/* XXX Is this big enough? Too big? */
159
buflen = bufsz = 128;
160
buf = ptr = palloc(sess->pool, bufsz);
162
/* pr_strtime() trims off the trailing newline, so add it back in. */
163
sftp_msg_write_string(&buf, &buflen,
164
pstrcat(sess->pool, date_str, "\n", NULL));
166
if (sftp_channel_write_data(sess->pool, channel_id, ptr,
167
(bufsz - buflen)) < 0) {
171
/* Return 1 to indicate that we're already done with this channel. */
175
int sftp_date_open_session(uint32_t channel_id) {
177
struct date_session *sess, *last;
179
/* Check to see if we already have an date session opened for the given
182
sess = last = date_sessions;
186
if (sess->channel_id == channel_id) {
191
if (sess->next == NULL) {
192
/* This is the last item in the list. */
199
/* Looks like we get to allocate a new one. */
200
sub_pool = make_sub_pool(date_pool);
201
pr_pool_tag(sub_pool, "date session pool");
203
sess = pcalloc(sub_pool, sizeof(struct date_session));
204
sess->pool = sub_pool;
205
sess->channel_id = channel_id;
206
sess->use_gmt = date_use_gmt;
213
date_sessions = sess;
219
int sftp_date_close_session(uint32_t channel_id) {