コード例 #1
0
ファイル: command.c プロジェクト: cyrusimap/cyrus-imapd
EXPORTED int command_pclose(struct command **cmdp)
{
    struct command *cmd = (cmdp ? *cmdp : NULL);
    int r;

    if (!cmd) return 0;

    if (cmd->stdin_prot) {
        prot_flush(cmd->stdin_prot);
        close(cmd->stdin_prot->fd);
        prot_free(cmd->stdin_prot);
    }

    if (cmd->stdout_prot) {
        close(cmd->stdout_prot->fd);
        prot_free(cmd->stdout_prot);
    }

    r = wait_for_child(cmd->argv0, cmd->pid);

    free(cmd->argv0);
    free(cmd);
    *cmdp = NULL;

    return r;
}
コード例 #2
0
ファイル: request.c プロジェクト: JensErat/cyrus-imapd
int deleteascript(int version, struct protstream *pout,
                  struct protstream *pin, const char *name,
                  char **refer_to, char **errstrp)
{
  lexstate_t state;
  int res;
  int ret;
  char *errstr = NULL;

  prot_printf(pout,"DELETESCRIPT \"%s\"\r\n",name);
  prot_flush(pout);

  res=yylex(&state, pin);

  ret = handle_response(res,version,pin,refer_to,&errstr);

  if(ret == -2 && *refer_to) {
      return -2;
  } else if (ret!=0) {
      *errstrp = strconcat("Deleting script: ",
                           errstr,
                           (char *)NULL);
      return -1;
  }

  return 0;
}
コード例 #3
0
ファイル: imap_proxy.c プロジェクト: JensErat/cyrus-imapd
/* Proxy GETANNOTATION commands to backend */
int annotate_fetch_proxy(const char *server, const char *mbox_pat,
                         const strarray_t *entry_pat,
                         const strarray_t *attribute_pat)
{
    struct backend *be;
    int i;
    char mytag[128];

    assert(server && mbox_pat && entry_pat && attribute_pat);

    be = proxy_findserver(server, &imap_protocol,
                          proxy_userid, &backend_cached,
                          &backend_current, &backend_inbox, imapd_in);
    if (!be) return IMAP_SERVER_UNAVAILABLE;

    /* Send command to remote */
    proxy_gentag(mytag, sizeof(mytag));
    prot_printf(be->out, "%s GETANNOTATION \"%s\" (", mytag, mbox_pat);
    for (i = 0 ; i < entry_pat->count ; i++) {
        prot_printf(be->out, "%s\"%s\"", i ? " " : "", entry_pat->data[i]);
    }
    prot_printf(be->out, ") (");
    for (i = 0 ; i < attribute_pat->count ; i++) {
        prot_printf(be->out, "%s\"%s\"", i ? " " : "", attribute_pat->data[i]);
    }
    prot_printf(be->out, ")\r\n");
    prot_flush(be->out);

    /* Pipe the results.  Note that backend-current may also pipe us other
       messages. */
    pipe_until_tag(be, mytag, 0);

    return 0;
}
コード例 #4
0
ファイル: http_proxy.c プロジェクト: JensErat/cyrus-imapd
static int ping(struct backend *s, const char *userid)
{
    unsigned code = 0;
    const char *errstr;
    hdrcache_t resp_hdrs = NULL;
    struct body_t resp_body;

    /* Send Authorization request to server */
    prot_puts(s->out, "OPTIONS * HTTP/1.1\r\n");
    prot_printf(s->out, "Host: %s\r\n", s->hostname);
    prot_printf(s->out, "User-Agent: %s\r\n", buf_cstring(&serverinfo));
    prot_printf(s->out, "Authorize-As: %s\r\n", userid ? userid : "anonymous");
    prot_puts(s->out, "\r\n");
    prot_flush(s->out);

    /* Read response(s) from backend until final response or error */
    do {
        resp_body.flags = BODY_DISCARD;
        if (http_read_response(s, METH_OPTIONS, &code, NULL,
                               &resp_hdrs, &resp_body, &errstr)) {
            break;
        }
    } while (code < 200);

    if (resp_hdrs) spool_free_hdrcache(resp_hdrs);

    return (code != 200);
}
コード例 #5
0
ファイル: request.c プロジェクト: JensErat/cyrus-imapd
int installdata(int version,struct protstream *pout, struct protstream *pin,
                char *scriptname, char *data, int len,
                char **refer_to, char **errstrp)
{
  int res;
  int ret;
  char *errstr=NULL;
  lexstate_t state;

  prot_printf(pout, "PUTSCRIPT \"%s\" ",scriptname);

  prot_printf(pout, "{%d+}\r\n",len);

  prot_write(pout, data, len);

  prot_printf(pout,"\r\n");
  prot_flush(pout);

  /* now let's see what the server said */
  res=yylex(&state,pin);

  ret = handle_response(res,version,pin,refer_to,&errstr);

  /* if command failed */
  if(ret == -2 && *refer_to) {
      return -2;
  } else if (ret!=0) {
      *errstrp = strconcat("Putting script: ",
                           errstr,
                           (char *)NULL);
      return -1;
  }

  return 0;
}
コード例 #6
0
ファイル: timsieved.c プロジェクト: cyberpear/cyrus-imapd
void shut_down(int code)
{
    /* free interpreter */
    if (interp) sieve_interp_free(&interp);

    /* close backend connection */
    if (backend) {
	backend_disconnect(backend);
	free(backend);
    }

    /* close mailboxes */
    mboxlist_close();
    mboxlist_done();

    /* cleanup */
    if (sieved_out) {
	prot_flush(sieved_out);
	prot_free(sieved_out);
    }
    if (sieved_in) prot_free(sieved_in);

    if (sieved_logfd != -1) close(sieved_logfd);

#ifdef HAVE_SSL
    tls_shutdown_serverengine();
#endif

    cyrus_done();

    cyrus_reset_stdio();
    
    /* done */
    exit(code);
}
コード例 #7
0
ファイル: isieve.c プロジェクト: cyberpear/cyrus-imapd
int detect_mitm(isieve_t *obj, char *mechlist)
{
    char *new_mechlist;
    int ch, r = 0;

    /* wait and probe for possible automatic capability response */
    usleep(250000);
    prot_NONBLOCK(obj->pin);
    if ((ch = prot_getc(obj->pin)) != EOF) {
	/* automatic capability response */
	prot_ungetc(ch, obj->pin);
    } else {
	/* manually ask for capabilities */
	prot_printf(obj->pout, "CAPABILITY\r\n");
	prot_flush(obj->pout);
    }
    prot_BLOCK(obj->pin);

    if ((new_mechlist = read_capability(obj))) {
	/* if the server still advertises SASL mechs, compare lists */
	r = strcmp(new_mechlist, mechlist);
	free(new_mechlist);
    }

    return r;
}
コード例 #8
0
ファイル: backend.c プロジェクト: ipeukes/debian_cyrus_imapd
EXPORTED int backend_ping(struct backend *s, const char *userid)
{
    char buf[1024];
    struct simple_cmd_t *ping_cmd;

    if (!s) return 0;
    if (s->sock == -1) return -1; /* Disconnected Socket */

    if (s->prot->type == TYPE_SPEC) return s->prot->u.spec.ping(s, userid);

    ping_cmd = &s->prot->u.std.ping_cmd;
    if (!ping_cmd->cmd) return 0;

    prot_printf(s->out, "%s\r\n", ping_cmd->cmd);
    prot_flush(s->out);

    for (;;) {
	if (!prot_fgets(buf, sizeof(buf), s->in)) {
	    /* connection closed? */
	    return -1;
	} else if (ping_cmd->unsol &&
		   !strncmp(ping_cmd->unsol, buf,
			    strlen(ping_cmd->unsol))) {
	    /* unsolicited response */
	    continue;
	} else {
	    /* success/fail response */
	    return strncmp(ping_cmd->ok, buf, strlen(ping_cmd->ok));
	}
    }
}
コード例 #9
0
ファイル: request.c プロジェクト: JensErat/cyrus-imapd
int setscriptactive(int version, struct protstream *pout,
                    struct protstream *pin,char *name,
                    char **refer_to, char **errstrp)
{
  lexstate_t state;
  int res;
  int ret;
  char *errstr=NULL;

  /* tell server we want "name" to be the active script */
  prot_printf(pout, "SETACTIVE \"%s\"\r\n",name);
  prot_flush(pout);

  /* now let's see what the server said */
  res=yylex(&state, pin);

  ret = handle_response(res, version, pin, refer_to, &errstr);

  /* if command failed */
  if(ret == -2 && *refer_to) {
      return -2;
  } else if (ret != 0) {
      *errstrp = strconcat("Setting script active: ",
                           errstr,
                           (char *)NULL);
      return -1;
  }
  return 0;
}
コード例 #10
0
ファイル: backend.c プロジェクト: pmhahn/cyrus-imapd
int backend_ping(struct backend *s)
{
    char buf[1024];

    if (!s || !s->prot->ping_cmd.cmd) return 0;
    if (s->sock == -1) return -1; /* Disconnected Socket */
    
    prot_printf(s->out, "%s\r\n", s->prot->ping_cmd.cmd);
    prot_flush(s->out);

    for (;;) {
	if (!prot_fgets(buf, sizeof(buf), s->in)) {
	    /* connection closed? */
	    return -1;
	} else if (s->prot->ping_cmd.unsol &&
		   !strncmp(s->prot->ping_cmd.unsol, buf,
			    strlen(s->prot->ping_cmd.unsol))) {
	    /* unsolicited response */
	    continue;
	} else {
	    /* success/fail response */
	    return strncmp(s->prot->ping_cmd.ok, buf,
			   strlen(s->prot->ping_cmd.ok));
	}
    }
}
コード例 #11
0
ファイル: backend.c プロジェクト: pmhahn/cyrus-imapd
void backend_disconnect(struct backend *s)
{
    char buf[1024];

    if (!s || s->sock == -1) return;
    
    if (!prot_error(s->in)) {
	if (s->prot->logout_cmd.cmd) {
	    prot_printf(s->out, "%s\r\n", s->prot->logout_cmd.cmd);
	    prot_flush(s->out);

	    for (;;) {
		if (!prot_fgets(buf, sizeof(buf), s->in)) {
		    /* connection closed? */
		    break;
		} else if (s->prot->logout_cmd.unsol &&
			   !strncmp(s->prot->logout_cmd.unsol, buf,
				    strlen(s->prot->logout_cmd.unsol))) {
		    /* unsolicited response */
		    continue;
		} else {
		    /* success/fail response -- don't care either way */
		    break;
		}
	    }
	}
    }

    /* Flush the incoming buffer */
    prot_NONBLOCK(s->in);
    prot_fill(s->in);

#ifdef HAVE_SSL
    /* Free tlsconn */
    if (s->tlsconn) {
	tls_reset_servertls(&s->tlsconn);
	s->tlsconn = NULL;
    }
#endif /* HAVE_SSL */

    /* close/free socket & prot layer */
    cyrus_close_sock(s->sock);
    s->sock = -1;
    
    prot_free(s->in);
    prot_free(s->out);
    s->in = s->out = NULL;

    /* Free saslconn */
    if(s->saslconn) {
	sasl_dispose(&(s->saslconn));
	s->saslconn = NULL;
    }

    /* free last_result buffer */
    buf_free(&s->last_result);

    forget_capabilities(s);
}
コード例 #12
0
ファイル: dlist.c プロジェクト: JensErat/cyrus-imapd
EXPORTED void dlist_printbuf(const struct dlist *dl, int printkeys, struct buf *outbuf)
{
    struct protstream *outstream;

    outstream = prot_writebuf(outbuf);
    dlist_print(dl, printkeys, outstream);
    prot_flush(outstream);
    prot_free(outstream);
}
コード例 #13
0
ファイル: deliver.c プロジェクト: pmhahn/cyrus-imapd
/*
 * Here we're just an intermediatory piping stdin to lmtp socket
 * and lmtp socket to stdout
 */
void pipe_through(struct backend *conn)
{
    struct protgroup *protin = protgroup_new(2);

    protgroup_insert(protin, deliver_in);
    protgroup_insert(protin, conn->in);

    do {
	/* Flush any buffered output */
	prot_flush(deliver_out);
	prot_flush(conn->out);

    } while (!proxy_check_input(protin, deliver_in, deliver_out,
				conn->in, conn->out, 0));

    /* ok, we're done. */
    protgroup_free(protin);

    return;
}
コード例 #14
0
ファイル: isieve.c プロジェクト: cyberpear/cyrus-imapd
int isieve_logout(isieve_t **obj) 
{
    prot_printf((*obj)->pout, "LOGOUT");
    prot_flush((*obj)->pout);

    close((*obj)->sock);
    
    sieve_free_net(*obj);
    *obj = NULL;

    return STAT_OK;
}
コード例 #15
0
ファイル: sync_client.c プロジェクト: martinpal/cyrus-imapd
static int do_restart()
{
    static int restartcnt = 0;

    if (sync_out->userdata) {
	/* IMAP flavor (w/ tag) */
	prot_printf(sync_out, "R%d SYNC", restartcnt++);
    }
    prot_printf(sync_out, "RESTART\r\n");
    prot_flush(sync_out);
    return sync_parse_response("RESTART", sync_in, NULL);
}
コード例 #16
0
ファイル: request.c プロジェクト: JensErat/cyrus-imapd
int list_wcb(int version, struct protstream *pout,
             struct protstream *pin,isieve_listcb_t *cb ,void *rock,
             char **refer_to)
{
  lexstate_t state;
  int end=0;
  int res;
  int ret = 0;

  prot_printf(pout, "LISTSCRIPTS\r\n");
  prot_flush(pout);

  do {

    if ((res=yylex(&state, pin))==STRING)
    {
      char *str=state.str;

      if (yylex(&state, pin)==' ')
      {
          if (yylex(&state, pin)!=TOKEN_ACTIVE)
              printf("Expected ACTIVE\n");
          if (yylex(&state, pin)!=EOL)
              printf("Expected EOL\n");

          cb(str, 1, rock);
      } else {

          /* in old version we had that '*' means active script thing */
          if (version == OLD_VERSION) {

              if (str[strlen(str)-1]=='*') {
                  str[strlen(str)-1]='\0';
                  cb(str, 1, rock);
              } else {
                  cb(str, 0, rock);
              }

          } else { /* NEW_VERSION */
              /* assume it's a EOL */
              cb(str, 0, rock);
          }
      }

    } else {
        ret = handle_response(res,version,pin,refer_to,NULL);

        end=1;
    }
  } while (end==0);

  return ret;
}
コード例 #17
0
ファイル: command.c プロジェクト: cyrusimap/cyrus-imapd
EXPORTED int command_done_stdin(struct command *cmd)
{
    int r = 0;

    if (cmd->stdin_prot) {
        r = prot_flush(cmd->stdin_prot);
        close(cmd->stdin_prot->fd);
        prot_free(cmd->stdin_prot);
        cmd->stdin_prot = NULL;
    }
    return r;
}
コード例 #18
0
ファイル: deliver.c プロジェクト: pmhahn/cyrus-imapd
void fatal(const char* s, int code)
{
    static int recurse_code = 0;
    
    if(recurse_code) exit(code);
    else recurse_code = 0;
    
    prot_printf(deliver_out,"421 4.3.0 deliver: %s\r\n", s);
    prot_flush(deliver_out);
    cyrus_done();
    exit(code);
}
コード例 #19
0
ファイル: sync_server.c プロジェクト: cyrusimap/cyrus-imapd
static void sync_reset(void)
{
    proc_cleanup();

    if (sync_in) {
        prot_NONBLOCK(sync_in);
        prot_fill(sync_in);

        prot_free(sync_in);
    }

    if (sync_out) {
        prot_flush(sync_out);
        prot_free(sync_out);
    }

    sync_in = sync_out = NULL;

#ifdef HAVE_SSL
    if (tls_conn) {
        tls_reset_servertls(&tls_conn);
        tls_conn = NULL;
    }
#endif

    cyrus_reset_stdio();

    sync_clienthost = "[local]";
    if (sync_logfd != -1) {
        close(sync_logfd);
        sync_logfd = -1;
    }
    if (sync_userid != NULL) {
        free(sync_userid);
        sync_userid = NULL;
    }
    if (sync_authstate) {
        auth_freestate(sync_authstate);
        sync_authstate = NULL;
    }
    if (sync_saslconn) {
        sasl_dispose(&sync_saslconn);
        sync_saslconn = NULL;
    }
    sync_starttls_done = 0;
    sync_compress_done = 0;

    saslprops_reset(&saslprops);
}
コード例 #20
0
ファイル: backend.c プロジェクト: ipeukes/debian_cyrus_imapd
EXPORTED int backend_starttls(	struct backend *s,
				struct tls_cmd_t *tls_cmd,
				const char *c_cert_file,
				const char *c_key_file)
{
#ifndef HAVE_SSL
    return -1;
#else
    char *auth_id = NULL;
    int *layerp = NULL;
    int r = 0;

    if (tls_cmd) {
	char buf[2048];
	/* send starttls command */
	prot_printf(s->out, "%s\r\n", tls_cmd->cmd);
	prot_flush(s->out);

	/* check response */
	if (!prot_fgets(buf, sizeof(buf), s->in) ||
	    strncmp(buf, tls_cmd->ok, strlen(tls_cmd->ok)))
	    return -1;
    }

    r = tls_init_clientengine(5, c_cert_file, c_key_file);
    if (r == -1) return -1;

    /* SASL and openssl have different ideas about whether ssf is signed */
    layerp = (int *) &s->ext_ssf;
    r = tls_start_clienttls(s->in->fd, s->out->fd, layerp, &auth_id,
			    &s->tlsconn, &s->tlssess);
    if (r == -1) return -1;

    if (s->saslconn) {
	r = sasl_setprop(s->saslconn, SASL_SSF_EXTERNAL, &s->ext_ssf);
	if (r == SASL_OK)
	    r = sasl_setprop(s->saslconn, SASL_AUTH_EXTERNAL, auth_id);
	if (auth_id) free(auth_id);
	if (r != SASL_OK) return -1;
    }

    prot_settls(s->in,  s->tlsconn);
    prot_settls(s->out, s->tlsconn);

    ask_capability(s, /*dobanner*/1, tls_cmd->auto_capa);

    return 0;
#endif /* HAVE_SSL */
}
コード例 #21
0
ファイル: timsieved.c プロジェクト: cyberpear/cyrus-imapd
EXPORTED void fatal(const char *s, int code)
{
    static int recurse_code = 0;

    if (recurse_code) {
	/* We were called recursively. Just give up */
	exit(recurse_code);
    }
    recurse_code = code;

    prot_printf(sieved_out, "NO Fatal error: %s\r\n", s);
    prot_flush(sieved_out);

    shut_down(EC_TEMPFAIL);
}
コード例 #22
0
ファイル: sync_client.c プロジェクト: thomasjfox/cyrus-imapd
static int do_restart()
{
    static int restartcnt = 0;

    if (sync_out->userdata) {
        /* IMAP flavor (w/ tag) */
        struct buf *tag = (struct buf *) sync_out->userdata;
        buf_reset(tag);
        buf_printf(tag, "R%d", restartcnt++);
        prot_printf(sync_out, "%s SYNC", buf_cstring(tag));
    }
    prot_printf(sync_out, "RESTART\r\n");
    prot_flush(sync_out);
    return sync_parse_response("RESTART", sync_in, NULL);
}
コード例 #23
0
ファイル: backend.c プロジェクト: pmhahn/cyrus-imapd
static int do_starttls(struct backend *s)
{
#ifndef HAVE_SSL
    return -1;
#else
    const struct tls_cmd_t *tls_cmd = &s->prot->tls_cmd;
    char buf[2048];
    int r;
    int *layerp;
    char *auth_id;
    sasl_ssf_t ssf;

    /* send starttls command */
    prot_printf(s->out, "%s\r\n", tls_cmd->cmd);
    prot_flush(s->out);

    /* check response */
    if (!prot_fgets(buf, sizeof(buf), s->in) ||
	strncmp(buf, tls_cmd->ok, strlen(tls_cmd->ok)))
	return -1;

    r = tls_init_clientengine(5, "", "");
    if (r == -1) return -1;

    /* SASL and openssl have different ideas about whether ssf is signed */
    layerp = (int *) &ssf;
    r = tls_start_clienttls(s->in->fd, s->out->fd, layerp, &auth_id,
			    &s->tlsconn, &s->tlssess);
    if (r == -1) return -1;

    r = sasl_setprop(s->saslconn, SASL_SSF_EXTERNAL, &ssf);
    if (r == SASL_OK)
	r = sasl_setprop(s->saslconn, SASL_AUTH_EXTERNAL, auth_id);
    if (auth_id) free(auth_id);
    if (r != SASL_OK) return -1;

    prot_settls(s->in,  s->tlsconn);
    prot_settls(s->out, s->tlsconn);

    ask_capability(s, /*dobanner*/1, s->prot->tls_cmd.auto_capa);

    return 0;
#endif /* HAVE_SSL */
}
コード例 #24
0
ファイル: backend.c プロジェクト: pmhahn/cyrus-imapd
/*
 * Get capabilities from the server, and parse them according to
 * details in the protocol_t, so that the CAPA() macro and perhaps
 * the backend_get_cap_params() function will notice them.  Any
 * capabilities previously parsed are forgotten.
 *
 * The server might give us capabilities for free just because we
 * connected (or did a STARTTLS or logged in); in this case, call
 * with a non-zero value for @automatic.  Otherwise, we send a
 * protocol-specific command to the server to tickle it into
 * disgorging some capabilities.
 *
 * Returns: 1 if any capabilities were found, 0 otherwise.
 */
static int ask_capability(struct backend *s, int dobanner, int automatic)
{
    struct protstream *pout = s->out, *pin = s->in;
    const struct protocol_t *prot = s->prot;
    int matches = 0;
    char str[4096];
    const char *resp;

    resp = (automatic == AUTO_CAPA_BANNER) ?
	prot->banner.resp : prot->capa_cmd.resp;

    if (!automatic) {
	/* no capability command */
	if (!prot->capa_cmd.cmd) return -1;
	
	/* request capabilities of server */
	prot_printf(pout, "%s", prot->capa_cmd.cmd);
	if (prot->capa_cmd.arg) prot_printf(pout, " %s", prot->capa_cmd.arg);
	prot_printf(pout, "\r\n");
	prot_flush(pout);
    }

    forget_capabilities(s);

    do {
	if (prot_fgets(str, sizeof(str), pin) == NULL) break;

	matches |= parse_capability(s, str);

	if (!resp) {
	    /* multiline response with no distinct end (IMAP banner) */
	    prot_NONBLOCK(pin);
	}

	if (dobanner) strncpy(s->banner, str, sizeof(s->banner));

	/* look for the end of the capabilities */
    } while (!resp || strncasecmp(str, resp, strlen(resp)));
    
    prot_BLOCK(pin);
    post_parse_capability(s);
    return matches;
}
コード例 #25
0
ファイル: backupd.c プロジェクト: cyrusimap/cyrus-imapd
EXPORTED void fatal(const char* s, int code)
{
    static int recurse_code = 0;

    if (recurse_code) {
        /* We were called recursively. Just give up */
        proc_cleanup();
        exit(recurse_code);
    }
    recurse_code = code;

    open_backups_list_close(&backupd_open_backups, 0);

    if (backupd_out) {
        prot_printf(backupd_out, "* Fatal error: %s\r\n", s);
        prot_flush(backupd_out);
    }
    syslog(LOG_ERR, "Fatal error: %s", s);
    shut_down(code);
}
コード例 #26
0
ファイル: backend.c プロジェクト: pmhahn/cyrus-imapd
static int do_compress(struct backend *s, struct simple_cmd_t *compress_cmd)
{
#ifndef HAVE_ZLIB
    return -1;
#else
    char buf[1024];

    /* send compress command */
    prot_printf(s->out, "%s\r\n", compress_cmd->cmd);
    prot_flush(s->out);

    /* check response */
    if (!prot_fgets(buf, sizeof(buf), s->in) ||
	strncmp(buf, compress_cmd->ok, strlen(compress_cmd->ok)))
	return -1;

    prot_setcompress(s->in);
    prot_setcompress(s->out);

    return 0;
#endif /* HAVE_ZLIB */
}
コード例 #27
0
ファイル: imap_proxy.c プロジェクト: JensErat/cyrus-imapd
/* Proxy SETANNOTATION commands to backend */
int annotate_store_proxy(const char *server, const char *mbox_pat,
                         struct entryattlist *entryatts)
{
    struct backend *be;
    struct entryattlist *e;
    struct attvaluelist *av;
    char mytag[128];

    assert(server && mbox_pat && entryatts);

    be = proxy_findserver(server, &imap_protocol,
                          proxy_userid, &backend_cached,
                          &backend_current, &backend_inbox, imapd_in);
    if (!be) return IMAP_SERVER_UNAVAILABLE;

    /* Send command to remote */
    proxy_gentag(mytag, sizeof(mytag));
    prot_printf(be->out, "%s SETANNOTATION \"%s\" (", mytag, mbox_pat);
    for (e = entryatts; e; e = e->next) {
        prot_printf(be->out, "\"%s\" (", e->entry);

        for (av = e->attvalues; av; av = av->next) {
            prot_printf(be->out, "\"%s\" ", av->attrib);
            prot_printmap(be->out, av->value.s, av->value.len);
            prot_printf(be->out, "%s", av->next ? " " : "");
        }
        prot_printf(be->out, ")");
        if (e->next) prot_printf(be->out, " ");
    }
    prot_printf(be->out, ")\r\n");
    prot_flush(be->out);

    /* Pipe the results.  Note that backend-current may also pipe us other
       messages. */
    pipe_until_tag(be, mytag, 0);

    return 0;
}
コード例 #28
0
ファイル: prot.c プロジェクト: gnb/cyrus-imapd
static void test_printstring(void)
{
    PROLOG;
    struct protstream *p;
    int len;
    struct buf b = BUF_INITIALIZER;
    int i;
    char str[2600];

    p = prot_new(_fd, 1);
    CU_ASSERT_PTR_NOT_NULL_FATAL(p);

    /* NULL string */
    BEGIN;
    prot_printstring(p, NULL);
    prot_flush(p);
    END(str, len);
    CU_ASSERT_EQUAL(len, 3);
    CU_ASSERT_STRING_EQUAL(str, "NIL");

    /* Zero length string */
    BEGIN;
    prot_printstring(p, "");
    prot_flush(p);
    END(str, len);
    CU_ASSERT_EQUAL(len, 2);
    CU_ASSERT_STRING_EQUAL(str, "\"\"");

    /* Boring string */
    BEGIN;
    prot_printstring(p, "Hello");
    prot_flush(p);
    END(str, len);
    CU_ASSERT_EQUAL(len, 7);
    CU_ASSERT_STRING_EQUAL(str, "\"Hello\"");

    /* String with non-dangerous whitespace */
    BEGIN;
    prot_printstring(p, "Hello World\tagain");
    prot_flush(p);
    END(str, len);
    CU_ASSERT_EQUAL(len, 19);
    CU_ASSERT_STRING_EQUAL(str, "\"Hello World\tagain\"");

    /* String with dangerous whitespace */
    BEGIN;
    prot_printstring(p, "Good\rBye\nEarth");
    prot_flush(p);
    END(str, len);
    CU_ASSERT_EQUAL(len, 20);
    CU_ASSERT_STRING_EQUAL(str, "{14}\r\nGood\rBye\nEarth");

    /* String with embedded dquote */
    BEGIN;
    prot_printstring(p, "Quot\"able");
    prot_flush(p);
    END(str, len);
    CU_ASSERT_EQUAL(len, 14);
    CU_ASSERT_STRING_EQUAL(str, "{9}\r\nQuot\"able");

    /* String with embedded percent */
    BEGIN;
    prot_printstring(p, "per%ent");
    prot_flush(p);
    END(str, len);
    CU_ASSERT_EQUAL(len, 12);
    CU_ASSERT(!strcmp(str, "{7}\r\nper%ent"));

    /* String with embedded backslash */
    BEGIN;
    prot_printstring(p, "slash\\dot");
    prot_flush(p);
    END(str, len);
    CU_ASSERT_EQUAL(len, 14);
    CU_ASSERT_STRING_EQUAL(str, "{9}\r\nslash\\dot");

    /* String with embedded 8-bit chars */
    BEGIN;
    prot_printstring(p, "Hi I'm \330l\345f");
    prot_flush(p);
    END(str, len);
    CU_ASSERT_EQUAL(len, 17);
    CU_ASSERT_STRING_EQUAL(str, "{11}\r\nHi I'm \330l\345f");

    /* Boring but overly long string */
    for (i = 0 ; i<500 ; i++)
	buf_appendcstr(&b, "blah ");
    buf_cstring(&b);
    BEGIN;
    prot_printstring(p, b.s);
    prot_flush(p);
    END(str, len);
    CU_ASSERT_EQUAL(len, b.len+8);
    CU_ASSERT_STRING_EQUAL(str+8, b.s);
    str[8] = '\0';
    CU_ASSERT_STRING_EQUAL(str, "{2500}\r\n");

    buf_free(&b);
    prot_free(p);
    EPILOG;
}
コード例 #29
0
ファイル: saslserver.c プロジェクト: pmhahn/cyrus-imapd
/* NOTE: success_data will need to be free()d by the caller */
int saslserver(sasl_conn_t *conn, const char *mech,
	       const char *init_resp, const char *resp_prefix,
	       const char *continuation, const char *empty_chal,
               struct protstream *pin, struct protstream *pout,
	       int *sasl_result, char **success_data)
{
    char base64[BASE64_BUF_SIZE+1];
    char *clientin = NULL;
    unsigned int clientinlen = 0;
    const char *serverout = NULL;
    unsigned int serveroutlen = 0;
    int r = SASL_OK;

    if (success_data) *success_data = NULL;

    /* initial response */
    if (init_resp) {
	clientin = base64;
	if (!strcmp(init_resp, "=")) {
	    /* zero-length initial response */
	    base64[0] = '\0';
	}
	else {
	    r = sasl_decode64(init_resp, strlen(init_resp),
			      clientin, BASE64_BUF_SIZE, &clientinlen);
	}
    }

    /* start the exchange */
    if (r == SASL_OK)
	r = sasl_server_start(conn, mech, clientin, clientinlen,
			      &serverout, &serveroutlen);

    while (r == SASL_CONTINUE) {
	char *p;

	/* send the challenge to the client */
	if (serveroutlen) {
	    r = sasl_encode64(serverout, serveroutlen,
			      base64, BASE64_BUF_SIZE, NULL);
	    if (r != SASL_OK) break;
	    serverout = base64;
	}
	else {
	    serverout = empty_chal;
	}

	prot_printf(pout, "%s%s\r\n", continuation, serverout);
	prot_flush(pout);

	/* get response from the client */
	if (!prot_fgets(base64, BASE64_BUF_SIZE, pin) ||
	    strncasecmp(base64, resp_prefix, strlen(resp_prefix))) {
	    if (sasl_result) *sasl_result = SASL_FAIL;
	    return IMAP_SASL_PROTERR;
	}

	/* trim CRLF */
	p = base64 + strlen(base64) - 1;
	if (p >= base64 && *p == '\n') *p-- = '\0';
	if (p >= base64 && *p == '\r') *p-- = '\0';

	/* trim prefix */
	p = base64 + strlen(resp_prefix);

	/* check if client cancelled */
	if (p[0] == '*') {
	    if(sasl_result) *sasl_result = SASL_BADPROT;
	    return IMAP_SASL_CANCEL;
	}

	/* decode the response */
	clientin = base64;
	r = sasl_decode64(p, strlen(p),
			  clientin, BASE64_BUF_SIZE, &clientinlen);
	if (r != SASL_OK) break;

	/* do the next step */
	r = sasl_server_step(conn, clientin, clientinlen,
			     &serverout, &serveroutlen);
    }

    /* success data */
    if (r == SASL_OK && serverout && success_data) {
	r = sasl_encode64(serverout, serveroutlen,
			  base64, BASE64_BUF_SIZE, NULL);
	if (r == SASL_OK)
	    *success_data = (char *) xstrdup(base64);
    }

    if (sasl_result) *sasl_result = r;
    return (r == SASL_OK ? 0 : IMAP_SASL_FAIL);
}
コード例 #30
0
ファイル: request.c プロジェクト: JensErat/cyrus-imapd
int installafile(int version,struct protstream *pout, struct protstream *pin,
                 char *filename, char *destname,
                 char **refer_to, char **errstrp)
{
  FILE *stream;
  struct stat filestats;  /* returned by stat */
  int size;     /* size of the file */
  int result;
  int cnt;
  int res;
  int ret;
  char *errstr=NULL;
  lexstate_t state;
  char *sievename;

  if(!destname) destname = filename;

  result=stat(filename,&filestats);

  if (result!=0) {
      *errstrp = xstrdup(strerror(errno));
      return -1;
  }

  size=filestats.st_size;

  stream=fopen(filename, "r");

  if (stream==NULL)
  {
      *errstrp = xstrdup(
        "put script: internal error: couldn't open temporary file");
      return -1;
  }

  sievename=getsievename(destname);

  prot_printf(pout, "PUTSCRIPT \"%s\" ",sievename);

  prot_printf(pout, "{%d+}\r\n",size);

  cnt=0;

  while (cnt < size)
  {
    char buf[BLOCKSIZE];
    int amount=BLOCKSIZE;
    int n;

    if (size-cnt < BLOCKSIZE)
      amount=size-cnt;

    n = fread(buf, 1, BLOCKSIZE, stream);
    if (!n) {
      *errstrp = xstrdup("put script: failed to finish reading");
      fclose(stream);
      free(sievename);
      return -1;
    }

    prot_write(pout, buf, n);

    cnt+=amount;
  }

  prot_printf(pout,"\r\n");
  prot_flush(pout);

  fclose(stream);
  free(sievename);

  /* now let's see what the server said */
  res=yylex(&state,pin);

  ret = handle_response(res,version,pin,refer_to,&errstr);

  /* if command failed */
  if(ret == -2 && *refer_to) {
      return -2;
  } else if (ret!=0) {
      *errstrp = strconcat("put script: ",
                           errstr,
                           (char *)NULL);
      return -1;
  }

  return 0;
}