/* Return the mailbox (local-part@domain) form a standard user id. All plain ASCII characters in the result are converted to lowercase. Caller must free the result. Returns NULL if no valid mailbox was found (or we are out of memory). */ char * mailbox_from_userid (const char *userid) { const char *s, *s_end; size_t len; char *result = NULL; s = strchr (userid, '<'); if (s) { /* Seems to be a standard user id. */ s++; s_end = strchr (s, '>'); if (s_end && s_end > s) { len = s_end - s; result = xtrymalloc (len + 1); if (!result) return NULL; /* Ooops - out of core. */ strncpy (result, s, len); result[len] = 0; /* Apply some basic checks on the address. We do not use is_valid_mailbox because those checks are too strict. */ if (string_count_chr (result, '@') != 1 /* Need exactly one '@. */ || *result == '@' /* local-part missing. */ || result[len-1] == '@' /* domain missing. */ || result[len-1] == '.' /* ends with a dot. */ || string_has_ctrl_or_space (result) || has_dotdot_after_at (result)) { xfree (result); result = NULL; errno = EINVAL; } } else errno = EINVAL; } else if (is_valid_mailbox (userid)) { /* The entire user id is a mailbox. Return that one. Note that this fallback method has some restrictions on the valid syntax of the mailbox. However, those who want weird addresses should know about it and use the regular <...> syntax. */ result = xtrystrdup (userid); } else errno = EINVAL; return result? ascii_strlwr (result): NULL; }
/* Ask the dirmngr for the submission address of a WKD server for the * mail address ADDRSPEC. On success the submission address is stored * at R_ADDRSPEC. */ gpg_error_t wkd_get_submission_address (const char *addrspec, char **r_addrspec) { gpg_error_t err; assuan_context_t ctx; struct wkd_get_parm_s parm; char *line = NULL; void *vp; char *buffer = NULL; char *p; memset (&parm, 0, sizeof parm); *r_addrspec = NULL; err = connect_dirmngr (&ctx); if (err) return err; line = es_bsprintf ("WKD_GET --submission-address -- %s", addrspec); if (!line) { err = gpg_error_from_syserror (); goto leave; } if (strlen (line) + 2 >= ASSUAN_LINELENGTH) { err = gpg_error (GPG_ERR_TOO_LARGE); goto leave; } parm.memfp = es_fopenmem (0, "rwb"); if (!parm.memfp) { err = gpg_error_from_syserror (); goto leave; } err = assuan_transact (ctx, line, wkd_get_data_cb, &parm, NULL, NULL, wkd_get_status_cb, &parm); if (err) goto leave; es_fputc (0, parm.memfp); if (es_fclose_snatch (parm.memfp, &vp, NULL)) { err = gpg_error_from_syserror (); goto leave; } buffer = vp; parm.memfp = NULL; p = strchr (buffer, '\n'); if (p) *p = 0; trim_spaces (buffer); if (!is_valid_mailbox (buffer)) { err = gpg_error (GPG_ERR_INV_USER_ID); goto leave; } *r_addrspec = xtrystrdup (buffer); if (!*r_addrspec) err = gpg_error_from_syserror (); leave: es_free (buffer); es_fclose (parm.memfp); xfree (line); assuan_release (ctx); return err; }